]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge branch 'x86-txt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 18 May 2010 16:28:24 +0000 (09:28 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 18 May 2010 16:28:24 +0000 (09:28 -0700)
* 'x86-txt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86, tboot: Add support for S3 memory integrity protection

6112 files changed:
Documentation/ABI/testing/sysfs-bus-usb
Documentation/DMA-API-HOWTO.txt [moved from Documentation/PCI/PCI-DMA-mapping.txt with 100% similarity]
Documentation/DocBook/libata.tmpl
Documentation/DocBook/tracepoint.tmpl
Documentation/HOWTO
Documentation/RCU/NMI-RCU.txt
Documentation/RCU/checklist.txt
Documentation/RCU/lockdep.txt
Documentation/RCU/stallwarn.txt
Documentation/RCU/torture.txt
Documentation/RCU/trace.txt
Documentation/RCU/whatisRCU.txt
Documentation/block/biodoc.txt
Documentation/cgroups/cgroups.txt
Documentation/cgroups/memory.txt
Documentation/circular-buffers.txt [new file with mode: 0644]
Documentation/connector/cn_test.c
Documentation/fb/efifb.txt [moved from Documentation/fb/imacfb.txt with 66% similarity]
Documentation/feature-removal-schedule.txt
Documentation/filesystems/00-INDEX
Documentation/filesystems/9p.txt
Documentation/filesystems/ceph.txt [new file with mode: 0644]
Documentation/filesystems/proc.txt
Documentation/filesystems/tmpfs.txt
Documentation/i2c/writing-clients
Documentation/input/elantech.txt
Documentation/input/multi-touch-protocol.txt
Documentation/ioctl/ioctl-number.txt
Documentation/kernel-parameters.txt
Documentation/kobject.txt
Documentation/kprobes.txt
Documentation/memory-barriers.txt
Documentation/networking/Makefile
Documentation/networking/stmmac.txt [new file with mode: 0644]
Documentation/networking/timestamping.txt
Documentation/networking/timestamping/Makefile
Documentation/networking/timestamping/timestamping.c
Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt
Documentation/rbtree.txt
Documentation/scheduler/sched-design-CFS.txt
Documentation/scheduler/sched-rt-group.txt
Documentation/sound/alsa/HD-Audio.txt
Documentation/spi/spidev_test.c
Documentation/stable_kernel_rules.txt
Documentation/trace/events.txt
Documentation/trace/ftrace.txt
Documentation/trace/kprobetrace.txt
Documentation/volatile-considered-harmful.txt
Documentation/watchdog/src/watchdog-simple.c
Documentation/watchdog/src/watchdog-test.c
Documentation/watchdog/watchdog-api.txt
MAINTAINERS
Makefile
arch/Kconfig
arch/alpha/boot/bootp.c
arch/alpha/boot/bootpz.c
arch/alpha/boot/main.c
arch/alpha/boot/misc.c
arch/alpha/include/asm/atomic.h
arch/alpha/include/asm/bitops.h
arch/alpha/include/asm/core_marvel.h
arch/alpha/include/asm/core_mcpcia.h
arch/alpha/include/asm/core_titan.h
arch/alpha/include/asm/core_tsunami.h
arch/alpha/kernel/irq.c
arch/alpha/kernel/osf_sys.c
arch/alpha/kernel/pci-noop.c
arch/alpha/kernel/pci-sysfs.c
arch/alpha/kernel/pci_iommu.c
arch/alpha/kernel/process.c
arch/alpha/kernel/ptrace.c
arch/alpha/kernel/smc37c669.c
arch/alpha/kernel/smc37c93x.c
arch/alpha/kernel/srm_env.c
arch/alpha/kernel/sys_dp264.c
arch/alpha/kernel/sys_titan.c
arch/alpha/kernel/traps.c
arch/alpha/mm/init.c
arch/arm/Kconfig
arch/arm/boot/compressed/decompress.c
arch/arm/boot/compressed/head.S
arch/arm/boot/compressed/misc.c
arch/arm/common/clkdev.c
arch/arm/common/it8152.c
arch/arm/common/locomo.c
arch/arm/configs/bcmring_defconfig
arch/arm/configs/cm_t35_defconfig
arch/arm/configs/imote2_defconfig
arch/arm/configs/n770_defconfig
arch/arm/configs/n8x0_defconfig
arch/arm/configs/omap3_beagle_defconfig
arch/arm/configs/omap3_defconfig
arch/arm/configs/omap3_evm_defconfig
arch/arm/configs/omap3_touchbook_defconfig
arch/arm/configs/omap_3430sdp_defconfig
arch/arm/configs/omap_3630sdp_defconfig
arch/arm/configs/omap_h2_1610_defconfig
arch/arm/configs/omap_zoom2_defconfig
arch/arm/configs/omap_zoom3_defconfig
arch/arm/configs/rx51_defconfig
arch/arm/include/asm/assembler.h
arch/arm/include/asm/atomic.h
arch/arm/include/asm/cacheflush.h
arch/arm/include/asm/clkdev.h
arch/arm/include/asm/elf.h
arch/arm/include/asm/futex.h
arch/arm/include/asm/highmem.h
arch/arm/include/asm/irq.h
arch/arm/include/asm/kmap_types.h
arch/arm/include/asm/outercache.h [new file with mode: 0644]
arch/arm/include/asm/pgtable-nommu.h
arch/arm/include/asm/smp_twd.h
arch/arm/include/asm/system.h
arch/arm/include/asm/tlbflush.h
arch/arm/include/asm/uaccess.h
arch/arm/include/asm/ucontext.h
arch/arm/include/asm/user.h
arch/arm/kernel/entry-armv.S
arch/arm/kernel/entry-header.S
arch/arm/kernel/ftrace.c
arch/arm/kernel/irq.c
arch/arm/kernel/kgdb.c
arch/arm/kernel/kprobes.c
arch/arm/kernel/module.c
arch/arm/kernel/perf_event.c
arch/arm/kernel/process.c
arch/arm/kernel/signal.c
arch/arm/kernel/smp.c
arch/arm/kernel/smp_twd.c
arch/arm/kernel/sys_arm.c
arch/arm/lib/backtrace.S
arch/arm/lib/clear_user.S
arch/arm/lib/copy_from_user.S
arch/arm/lib/copy_to_user.S
arch/arm/lib/csumpartialcopyuser.S
arch/arm/lib/getuser.S
arch/arm/lib/memmove.S
arch/arm/lib/putuser.S
arch/arm/lib/strncpy_from_user.S
arch/arm/lib/strnlen_user.S
arch/arm/lib/uaccess.S
arch/arm/lib/uaccess_with_memcpy.c
arch/arm/mach-aaec2000/core.c
arch/arm/mach-at91/Makefile
arch/arm/mach-at91/board-sam9g20ek.c
arch/arm/mach-at91/pm_slowclock.S
arch/arm/mach-bcmring/dma.c
arch/arm/mach-davinci/board-dm365-evm.c
arch/arm/mach-davinci/da830.c
arch/arm/mach-davinci/dm365.c
arch/arm/mach-davinci/dma.c
arch/arm/mach-davinci/include/mach/da8xx.h
arch/arm/mach-davinci/time.c
arch/arm/mach-ep93xx/gpio.c
arch/arm/mach-h720x/common.c
arch/arm/mach-integrator/cpu.c
arch/arm/mach-integrator/impd1.c
arch/arm/mach-integrator/integrator_cp.c
arch/arm/mach-integrator/pci_v3.c
arch/arm/mach-iop13xx/pci.c
arch/arm/mach-iop32x/glantank.c
arch/arm/mach-iop32x/iq31244.c
arch/arm/mach-iop32x/iq80321.c
arch/arm/mach-iop32x/n2100.c
arch/arm/mach-iop33x/iq80331.c
arch/arm/mach-iop33x/iq80332.c
arch/arm/mach-ixp2000/enp2611.c
arch/arm/mach-ixp2000/ixdp2400.c
arch/arm/mach-ixp2000/ixdp2800.c
arch/arm/mach-ixp2000/ixdp2x00.c
arch/arm/mach-ixp2000/ixdp2x01.c
arch/arm/mach-ixp2000/pci.c
arch/arm/mach-ixp23xx/include/mach/memory.h
arch/arm/mach-ixp23xx/pci.c
arch/arm/mach-ixp4xx/avila-setup.c
arch/arm/mach-ixp4xx/coyote-setup.c
arch/arm/mach-ixp4xx/gateway7001-setup.c
arch/arm/mach-ixp4xx/gtwx5715-setup.c
arch/arm/mach-ixp4xx/ixdp425-setup.c
arch/arm/mach-ixp4xx/ixp4xx_npe.c
arch/arm/mach-ixp4xx/wg302v2-setup.c
arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
arch/arm/mach-kirkwood/pcie.c
arch/arm/mach-lh7a40x/clcd.c
arch/arm/mach-mmp/include/mach/uncompress.h
arch/arm/mach-mx3/Kconfig
arch/arm/mach-mx3/clock-imx31.c
arch/arm/mach-mx3/devices.c
arch/arm/mach-mx3/devices.h
arch/arm/mach-mx3/mach-armadillo5x0.c
arch/arm/mach-mx3/mach-mx31_3ds.c
arch/arm/mach-mx3/mach-mx31moboard.c
arch/arm/mach-mx3/mach-pcm037.c
arch/arm/mach-mx3/mx31lite-db.c
arch/arm/mach-mx3/mx31moboard-devboard.c
arch/arm/mach-mx3/mx31moboard-marxbot.c
arch/arm/mach-mx5/clock-mx51.c
arch/arm/mach-mx5/cpu.c
arch/arm/mach-mx5/mm.c
arch/arm/mach-netx/fb.c
arch/arm/mach-netx/xc.c
arch/arm/mach-nomadik/gpio.c
arch/arm/mach-ns9xxx/plat-serial8250.c
arch/arm/mach-ns9xxx/processor-ns9360.c
arch/arm/mach-omap1/mcbsp.c
arch/arm/mach-omap1/timer32k.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/board-3430sdp.c
arch/arm/mach-omap2/board-3630sdp.c
arch/arm/mach-omap2/board-4430sdp.c
arch/arm/mach-omap2/board-am3517evm.c
arch/arm/mach-omap2/board-cm-t35.c
arch/arm/mach-omap2/board-devkit8000.c
arch/arm/mach-omap2/board-igep0020.c
arch/arm/mach-omap2/board-n8x0.c
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-omap2/board-omap3evm.c
arch/arm/mach-omap2/board-omap3pandora.c
arch/arm/mach-omap2/board-omap3touchbook.c
arch/arm/mach-omap2/board-overo.c
arch/arm/mach-omap2/board-sdp-flash.c
arch/arm/mach-omap2/board-zoom-debugboard.c
arch/arm/mach-omap2/board-zoom-peripherals.c
arch/arm/mach-omap2/board-zoom3.c
arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
arch/arm/mach-omap2/clock2420_data.c
arch/arm/mach-omap2/clock3xxx_data.c
arch/arm/mach-omap2/clock44xx_data.c
arch/arm/mach-omap2/clockdomain.c
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/gpmc-nand.c
arch/arm/mach-omap2/include/mach/entry-macro.S
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/iommu2.c
arch/arm/mach-omap2/mailbox.c
arch/arm/mach-omap2/mcbsp.c
arch/arm/mach-omap2/mux.c
arch/arm/mach-omap2/omap-headsmp.S
arch/arm/mach-omap2/omap44xx-smc.S [new file with mode: 0644]
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/pm-debug.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/powerdomain.c
arch/arm/mach-omap2/prcm.c
arch/arm/mach-omap2/serial.c
arch/arm/mach-omap2/usb-ehci.c
arch/arm/mach-orion5x/pci.c
arch/arm/mach-orion5x/wrt350n-v2-setup.c
arch/arm/mach-pnx4008/dma.c
arch/arm/mach-pnx4008/pm.c
arch/arm/mach-pxa/Kconfig
arch/arm/mach-pxa/corgi_ssp.c
arch/arm/mach-pxa/cpufreq-pxa3xx.c
arch/arm/mach-pxa/imote2.c
arch/arm/mach-pxa/include/mach/colibri.h
arch/arm/mach-pxa/include/mach/hardware.h
arch/arm/mach-pxa/include/mach/regs-u2d.h
arch/arm/mach-pxa/include/mach/uncompress.h
arch/arm/mach-pxa/mioa701.c
arch/arm/mach-pxa/pm.c
arch/arm/mach-pxa/raumfeld.c
arch/arm/mach-pxa/spitz.c
arch/arm/mach-pxa/stargate2.c
arch/arm/mach-pxa/viper.c
arch/arm/mach-realview/core.c
arch/arm/mach-rpc/dma.c
arch/arm/mach-rpc/include/mach/uncompress.h
arch/arm/mach-s3c2440/s3c2440-cpufreq.c [moved from arch/arm/plat-s3c24xx/s3c2440-cpufreq.c with 100% similarity]
arch/arm/mach-s3c64xx/dma.c
arch/arm/mach-s3c64xx/include/mach/debug-macro.S
arch/arm/mach-s5p6440/include/mach/debug-macro.S
arch/arm/mach-s5p6442/include/mach/debug-macro.S
arch/arm/mach-sa1100/Kconfig
arch/arm/mach-sa1100/cpu-sa1110.c
arch/arm/mach-sa1100/jornada720_ssp.c
arch/arm/mach-sa1100/neponset.c
arch/arm/mach-shmobile/board-ap4evb.c
arch/arm/mach-shmobile/board-g3evm.c
arch/arm/mach-shmobile/board-g4evm.c
arch/arm/mach-shmobile/clock-sh7367.c
arch/arm/mach-shmobile/intc-sh7367.c
arch/arm/mach-shmobile/intc-sh7372.c
arch/arm/mach-shmobile/intc-sh7377.c
arch/arm/mach-u300/dummyspichip.c
arch/arm/mach-u300/mmc.c
arch/arm/mach-versatile/core.c
arch/arm/mach-versatile/pci.c
arch/arm/mach-w90x900/dev.c
arch/arm/mm/Kconfig
arch/arm/mm/alignment.c
arch/arm/mm/cache-l2x0.c
arch/arm/mm/cache-v6.S
arch/arm/mm/cache-v7.S
arch/arm/mm/copypage-v6.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/fault-armv.c
arch/arm/mm/flush.c
arch/arm/mm/highmem.c
arch/arm/mm/init.c
arch/arm/mm/mmu.c
arch/arm/mm/nommu.c
arch/arm/mm/pgd.c
arch/arm/mm/proc-sa1100.S
arch/arm/mm/tlb-v7.S
arch/arm/nwfpe/entry.S
arch/arm/plat-mxc/audmux-v2.c
arch/arm/plat-mxc/include/mach/board-mx31_3ds.h [moved from arch/arm/plat-mxc/include/mach/board-mx31pdk.h with 93% similarity]
arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h
arch/arm/plat-mxc/include/mach/mx51.h
arch/arm/plat-mxc/include/mach/uncompress.h
arch/arm/plat-mxc/pwm.c
arch/arm/plat-omap/common.c
arch/arm/plat-omap/devices.c
arch/arm/plat-omap/dma.c
arch/arm/plat-omap/gpio.c
arch/arm/plat-omap/include/plat/blizzard.h
arch/arm/plat-omap/include/plat/cpu.h
arch/arm/plat-omap/include/plat/irqs.h
arch/arm/plat-omap/include/plat/mcbsp.h
arch/arm/plat-omap/include/plat/nand.h
arch/arm/plat-omap/include/plat/omap44xx.h
arch/arm/plat-omap/include/plat/omap_hwmod.h
arch/arm/plat-omap/include/plat/prcm.h
arch/arm/plat-omap/include/plat/system.h
arch/arm/plat-omap/include/plat/usb.h
arch/arm/plat-omap/iommu-debug.c
arch/arm/plat-omap/iommu.c
arch/arm/plat-omap/iovmm.c
arch/arm/plat-omap/mailbox.c
arch/arm/plat-omap/mcbsp.c
arch/arm/plat-omap/omap_device.c
arch/arm/plat-pxa/dma.c
arch/arm/plat-pxa/pwm.c
arch/arm/plat-s3c24xx/cpu-freq.c
arch/arm/plat-s3c24xx/devs.c
arch/arm/plat-s3c24xx/s3c2410-iotiming.c
arch/arm/plat-s3c24xx/s3c2412-iotiming.c
arch/arm/plat-samsung/adc.c
arch/arm/plat-samsung/dev-fb.c
arch/arm/plat-samsung/dev-i2c0.c
arch/arm/plat-samsung/dev-i2c1.c
arch/arm/plat-samsung/dev-nand.c
arch/arm/plat-samsung/dev-usb.c
arch/arm/plat-samsung/include/plat/uncompress.h
arch/arm/plat-samsung/pm-check.c
arch/arm/plat-samsung/pwm.c
arch/arm/plat-stmp3xxx/dma.c
arch/arm/tools/mach-types
arch/arm/vfp/vfpmodule.c
arch/avr32/include/asm/atomic.h
arch/avr32/kernel/process.c
arch/avr32/kernel/ptrace.c
arch/avr32/mach-at32ap/at32ap700x.c
arch/avr32/mach-at32ap/extint.c
arch/avr32/mach-at32ap/hsmc.c
arch/avr32/mm/dma-coherent.c
arch/avr32/mm/init.c
arch/avr32/mm/ioremap.c
arch/blackfin/Kconfig
arch/blackfin/Kconfig.debug
arch/blackfin/Makefile
arch/blackfin/boot/Makefile
arch/blackfin/configs/BF518F-EZBRD_defconfig
arch/blackfin/configs/BF526-EZBRD_defconfig
arch/blackfin/configs/BF527-EZKIT-V2_defconfig [new file with mode: 0644]
arch/blackfin/configs/BF527-EZKIT_defconfig
arch/blackfin/configs/BF533-EZKIT_defconfig
arch/blackfin/configs/BF533-STAMP_defconfig
arch/blackfin/configs/BF537-STAMP_defconfig
arch/blackfin/configs/BF538-EZKIT_defconfig
arch/blackfin/configs/BF548-EZKIT_defconfig
arch/blackfin/configs/BF561-ACVILON_defconfig
arch/blackfin/configs/BF561-EZKIT_defconfig
arch/blackfin/configs/H8606_defconfig
arch/blackfin/configs/PNAV-10_defconfig
arch/blackfin/configs/TCM-BF518_defconfig [new file with mode: 0644]
arch/blackfin/include/asm/bfin-lq035q1.h
arch/blackfin/include/asm/bfin_can.h [new file with mode: 0644]
arch/blackfin/include/asm/bfin_sport.h
arch/blackfin/include/asm/bfin_watchdog.h [new file with mode: 0644]
arch/blackfin/include/asm/bitops.h
arch/blackfin/include/asm/context.S
arch/blackfin/include/asm/cpu.h
arch/blackfin/include/asm/def_LPBlackfin.h
arch/blackfin/include/asm/delay.h
arch/blackfin/include/asm/dma-mapping.h
arch/blackfin/include/asm/dma.h
arch/blackfin/include/asm/dpmc.h
arch/blackfin/include/asm/elf.h
arch/blackfin/include/asm/ftrace.h
arch/blackfin/include/asm/gpio.h
arch/blackfin/include/asm/irq.h
arch/blackfin/include/asm/mmu_context.h
arch/blackfin/include/asm/nmi.h [new file with mode: 0644]
arch/blackfin/include/asm/page.h
arch/blackfin/include/asm/ptrace.h
arch/blackfin/include/asm/sections.h
arch/blackfin/include/asm/smp.h
arch/blackfin/include/asm/syscall.h [new file with mode: 0644]
arch/blackfin/include/asm/thread_info.h
arch/blackfin/include/asm/time.h
arch/blackfin/kernel/Makefile
arch/blackfin/kernel/bfin_dma_5xx.c
arch/blackfin/kernel/bfin_gpio.c
arch/blackfin/kernel/cplb-mpu/cplbinit.c
arch/blackfin/kernel/cplb-mpu/cplbmgr.c
arch/blackfin/kernel/cplb-nompu/cplbinit.c
arch/blackfin/kernel/dma-mapping.c
arch/blackfin/kernel/entry.S
arch/blackfin/kernel/ftrace-entry.S
arch/blackfin/kernel/ftrace.c
arch/blackfin/kernel/init_task.c
arch/blackfin/kernel/ipipe.c
arch/blackfin/kernel/kgdb.c
arch/blackfin/kernel/nmi.c [new file with mode: 0644]
arch/blackfin/kernel/process.c
arch/blackfin/kernel/ptrace.c
arch/blackfin/kernel/setup.c
arch/blackfin/kernel/signal.c
arch/blackfin/kernel/time-ts.c
arch/blackfin/kernel/traps.c
arch/blackfin/kernel/vmlinux.lds.S
arch/blackfin/mach-bf518/boards/Kconfig
arch/blackfin/mach-bf518/boards/Makefile
arch/blackfin/mach-bf518/boards/ezbrd.c
arch/blackfin/mach-bf518/boards/tcm-bf518.c [new file with mode: 0644]
arch/blackfin/mach-bf518/include/mach/irq.h
arch/blackfin/mach-bf518/include/mach/mem_map.h
arch/blackfin/mach-bf527/boards/Kconfig
arch/blackfin/mach-bf527/boards/Makefile
arch/blackfin/mach-bf527/boards/cm_bf527.c
arch/blackfin/mach-bf527/boards/ezbrd.c
arch/blackfin/mach-bf527/boards/ezkit.c
arch/blackfin/mach-bf527/include/mach/irq.h
arch/blackfin/mach-bf533/boards/H8606.c
arch/blackfin/mach-bf533/boards/blackstamp.c
arch/blackfin/mach-bf533/boards/cm_bf533.c
arch/blackfin/mach-bf533/boards/ezkit.c
arch/blackfin/mach-bf533/boards/ip0x.c
arch/blackfin/mach-bf533/boards/stamp.c
arch/blackfin/mach-bf533/include/mach/irq.h
arch/blackfin/mach-bf537/boards/cm_bf537e.c
arch/blackfin/mach-bf537/boards/cm_bf537u.c
arch/blackfin/mach-bf537/boards/minotaur.c
arch/blackfin/mach-bf537/boards/pnav10.c
arch/blackfin/mach-bf537/boards/stamp.c
arch/blackfin/mach-bf537/boards/tcm_bf537.c
arch/blackfin/mach-bf537/include/mach/irq.h
arch/blackfin/mach-bf538/boards/ezkit.c
arch/blackfin/mach-bf538/include/mach/irq.h
arch/blackfin/mach-bf548/boards/cm_bf548.c
arch/blackfin/mach-bf548/boards/ezkit.c
arch/blackfin/mach-bf548/include/mach/irq.h
arch/blackfin/mach-bf561/Makefile
arch/blackfin/mach-bf561/boards/acvilon.c
arch/blackfin/mach-bf561/boards/cm_bf561.c
arch/blackfin/mach-bf561/boards/ezkit.c
arch/blackfin/mach-bf561/boards/tepla.c
arch/blackfin/mach-bf561/hotplug.c [new file with mode: 0644]
arch/blackfin/mach-bf561/include/mach/irq.h
arch/blackfin/mach-bf561/include/mach/smp.h
arch/blackfin/mach-bf561/secondary.S
arch/blackfin/mach-bf561/smp.c
arch/blackfin/mach-common/cpufreq.c
arch/blackfin/mach-common/entry.S
arch/blackfin/mach-common/head.S
arch/blackfin/mach-common/interrupt.S
arch/blackfin/mach-common/ints-priority.c
arch/blackfin/mach-common/pm.c
arch/blackfin/mach-common/smp.c
arch/blackfin/mm/init.c
arch/blackfin/mm/isram-driver.c
arch/blackfin/mm/sram-alloc.c
arch/cris/arch-v10/drivers/i2c.c
arch/cris/arch-v10/drivers/sync_serial.c
arch/cris/arch-v10/kernel/process.c
arch/cris/arch-v32/drivers/i2c.c
arch/cris/arch-v32/drivers/pci/bios.c
arch/cris/arch-v32/drivers/pci/dma.c
arch/cris/arch-v32/drivers/sync_serial.c
arch/cris/arch-v32/kernel/process.c
arch/cris/arch-v32/kernel/signal.c
arch/cris/include/asm/atomic.h
arch/cris/kernel/irq.c
arch/cris/kernel/module.c
arch/cris/kernel/profile.c
arch/cris/mm/init.c
arch/frv/include/asm/atomic.h
arch/frv/include/asm/segment.h
arch/frv/include/asm/uaccess.h
arch/frv/kernel/irq.c
arch/frv/kernel/sysctl.c
arch/frv/mb93090-mb00/pci-dma.c
arch/frv/mb93090-mb00/pci-frv.c
arch/frv/mb93090-mb00/pci-irq.c
arch/frv/mb93090-mb00/pci-vdk.c
arch/frv/mm/dma-alloc.c
arch/frv/mm/init.c
arch/frv/mm/pgalloc.c
arch/h8300/include/asm/atomic.h
arch/h8300/kernel/process.c
arch/h8300/mm/init.c
arch/h8300/mm/kmap.c
arch/h8300/mm/memory.c
arch/ia64/include/asm/atomic.h
arch/ia64/include/asm/bitops.h
arch/ia64/include/asm/dmi.h
arch/ia64/kernel/acpi-ext.c
arch/ia64/kernel/acpi.c
arch/ia64/kernel/cpufreq/acpi-cpufreq.c
arch/ia64/kernel/efi.c
arch/ia64/kernel/iosapic.c
arch/ia64/kernel/irq_ia64.c
arch/ia64/kernel/mca.c
arch/ia64/kernel/mca_drv.c
arch/ia64/kernel/pci-swiotlb.c
arch/ia64/kernel/perfmon.c
arch/ia64/kernel/process.c
arch/ia64/kernel/ptrace.c
arch/ia64/kernel/topology.c
arch/ia64/kernel/uncached.c
arch/ia64/kvm/kvm-ia64.c
arch/ia64/mm/discontig.c
arch/ia64/mm/hugetlbpage.c
arch/ia64/mm/tlb.c
arch/ia64/sn/kernel/bte.c
arch/ia64/sn/kernel/io_acpi_init.c
arch/ia64/sn/kernel/io_common.c
arch/ia64/sn/kernel/io_init.c
arch/ia64/sn/kernel/irq.c
arch/ia64/sn/kernel/msi_sn.c
arch/ia64/sn/pci/pci_dma.c
arch/ia64/sn/pci/pcibr/pcibr_provider.c
arch/ia64/sn/pci/tioca_provider.c
arch/ia64/sn/pci/tioce_provider.c
arch/ia64/xen/grant-table.c
arch/m32r/include/asm/atomic.h
arch/m32r/kernel/process.c
arch/m32r/mm/init.c
arch/m68k/amiga/Makefile
arch/m68k/amiga/platform.c [new file with mode: 0644]
arch/m68k/bvme6000/rtc.c
arch/m68k/hp300/time.h
arch/m68k/include/asm/atomic_mm.h
arch/m68k/include/asm/atomic_no.h
arch/m68k/include/asm/bitops_mm.h
arch/m68k/include/asm/mcfuart.h
arch/m68k/include/asm/param.h
arch/m68k/include/asm/sigcontext.h
arch/m68k/kernel/dma.c
arch/m68k/kernel/process.c
arch/m68k/kernel/traps.c
arch/m68k/mac/config.c
arch/m68k/mac/misc.c
arch/m68k/mm/fault.c
arch/m68k/mm/init.c
arch/m68k/mm/memory.c
arch/m68k/mm/motorola.c
arch/m68k/mvme16x/rtc.c
arch/m68k/q40/config.c
arch/m68k/sun3/sun3dvma.c
arch/m68k/sun3x/dvma.c
arch/m68knommu/Makefile
arch/m68knommu/kernel/dma.c
arch/m68knommu/kernel/entry.S
arch/m68knommu/kernel/process.c
arch/m68knommu/mm/init.c
arch/m68knommu/mm/kmap.c
arch/m68knommu/mm/memory.c
arch/m68knommu/platform/68360/ints.c
arch/microblaze/Kconfig
arch/microblaze/Makefile
arch/microblaze/boot/Makefile
arch/microblaze/configs/mmu_defconfig
arch/microblaze/configs/nommu_defconfig
arch/microblaze/include/asm/cache.h
arch/microblaze/include/asm/device.h
arch/microblaze/include/asm/dma-mapping.h
arch/microblaze/include/asm/dma.h
arch/microblaze/include/asm/exceptions.h
arch/microblaze/include/asm/futex.h
arch/microblaze/include/asm/io.h
arch/microblaze/include/asm/irq.h
arch/microblaze/include/asm/page.h
arch/microblaze/include/asm/pci-bridge.h
arch/microblaze/include/asm/pci.h
arch/microblaze/include/asm/pgalloc.h
arch/microblaze/include/asm/pgtable.h
arch/microblaze/include/asm/processor.h
arch/microblaze/include/asm/prom.h
arch/microblaze/include/asm/segment.h [deleted file]
arch/microblaze/include/asm/system.h
arch/microblaze/include/asm/thread_info.h
arch/microblaze/include/asm/tlbflush.h
arch/microblaze/include/asm/uaccess.h
arch/microblaze/kernel/Makefile
arch/microblaze/kernel/asm-offsets.c
arch/microblaze/kernel/cpu/cache.c
arch/microblaze/kernel/cpu/cpuinfo.c
arch/microblaze/kernel/cpu/mb.c
arch/microblaze/kernel/dma.c [new file with mode: 0644]
arch/microblaze/kernel/entry-nommu.S
arch/microblaze/kernel/entry.S
arch/microblaze/kernel/exceptions.c
arch/microblaze/kernel/ftrace.c
arch/microblaze/kernel/head.S
arch/microblaze/kernel/hw_exception_handler.S
arch/microblaze/kernel/irq.c
arch/microblaze/kernel/microblaze_ksyms.c
arch/microblaze/kernel/misc.S
arch/microblaze/kernel/module.c
arch/microblaze/kernel/of_platform.c
arch/microblaze/kernel/process.c
arch/microblaze/kernel/ptrace.c
arch/microblaze/kernel/setup.c
arch/microblaze/kernel/sys_microblaze.c
arch/microblaze/kernel/traps.c
arch/microblaze/kernel/vmlinux.lds.S
arch/microblaze/lib/Makefile
arch/microblaze/lib/fastcopy.S
arch/microblaze/lib/memcpy.c
arch/microblaze/lib/memset.c
arch/microblaze/lib/uaccess.c [deleted file]
arch/microblaze/lib/uaccess_old.S
arch/microblaze/mm/Makefile
arch/microblaze/mm/consistent.c [new file with mode: 0644]
arch/microblaze/mm/fault.c
arch/microblaze/mm/init.c
arch/microblaze/mm/pgtable.c
arch/microblaze/pci/Makefile [new file with mode: 0644]
arch/microblaze/pci/indirect_pci.c [new file with mode: 0644]
arch/microblaze/pci/iomap.c [new file with mode: 0644]
arch/microblaze/pci/pci-common.c [new file with mode: 0644]
arch/microblaze/pci/pci_32.c [new file with mode: 0644]
arch/microblaze/pci/xilinx_pci.c [new file with mode: 0644]
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/alchemy/devboards/db1200/setup.c
arch/mips/ar7/platform.c
arch/mips/bcm63xx/boards/board_bcm963xx.c
arch/mips/bcm63xx/cpu.c
arch/mips/bcm63xx/dev-uart.c
arch/mips/bcm63xx/gpio.c
arch/mips/cavium-octeon/setup.c
arch/mips/cavium-octeon/smp.c
arch/mips/configs/bcm63xx_defconfig
arch/mips/configs/bigsur_defconfig
arch/mips/include/asm/abi.h
arch/mips/include/asm/atomic.h
arch/mips/include/asm/cmpxchg.h
arch/mips/include/asm/elf.h
arch/mips/include/asm/fpu_emulator.h
arch/mips/include/asm/i8253.h
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
arch/mips/include/asm/mach-loongson/loongson.h
arch/mips/include/asm/mach-sibyte/war.h
arch/mips/include/asm/mipsregs.h
arch/mips/include/asm/mmu.h
arch/mips/include/asm/mmu_context.h
arch/mips/include/asm/page.h
arch/mips/include/asm/pgtable-64.h
arch/mips/include/asm/processor.h
arch/mips/include/asm/ptrace.h
arch/mips/include/asm/stackframe.h
arch/mips/include/asm/uasm.h
arch/mips/include/asm/vdso.h [new file with mode: 0644]
arch/mips/jazz/jazzdma.c
arch/mips/jazz/setup.c
arch/mips/kernel/Makefile
arch/mips/kernel/cpufreq/loongson2_clock.c
arch/mips/kernel/i8253.c
arch/mips/kernel/irq.c
arch/mips/kernel/linux32.c
arch/mips/kernel/process.c
arch/mips/kernel/rtlx.c
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/signal-common.h
arch/mips/kernel/signal.c
arch/mips/kernel/signal32.c
arch/mips/kernel/signal_n32.c
arch/mips/kernel/smtc.c
arch/mips/kernel/syscall.c
arch/mips/kernel/traps.c
arch/mips/kernel/vdso.c [new file with mode: 0644]
arch/mips/lib/delay.c
arch/mips/lib/libgcc.h
arch/mips/loongson/common/machtype.c
arch/mips/loongson/common/mem.c
arch/mips/loongson/common/reset.c
arch/mips/loongson/common/setup.c
arch/mips/loongson/lemote-2f/irq.c
arch/mips/math-emu/cp1emu.c
arch/mips/mipssim/sim_int.c
arch/mips/mm/cache.c
arch/mips/mm/dma-default.c
arch/mips/mm/hugetlbpage.c
arch/mips/mm/init.c
arch/mips/mm/ioremap.c
arch/mips/mm/tlbex.c
arch/mips/mm/uasm.c
arch/mips/mti-malta/malta-int.c
arch/mips/nxp/pnx833x/common/reset.c
arch/mips/nxp/pnx8550/common/int.c
arch/mips/nxp/pnx8550/common/proc.c
arch/mips/nxp/pnx8550/common/reset.c
arch/mips/oprofile/op_model_loongson2.c
arch/mips/pci/ops-loongson2.c
arch/mips/pci/ops-titan-ht.c
arch/mips/pci/pci-sb1250.c
arch/mips/pmc-sierra/msp71xx/msp_prom.c
arch/mips/pmc-sierra/yosemite/ht.c
arch/mips/pmc-sierra/yosemite/irq.c
arch/mips/powertv/asic/asic_devices.c
arch/mips/powertv/asic/asic_int.c
arch/mips/rb532/irq.c
arch/mips/sgi-ip22/ip22-berr.c
arch/mips/sgi-ip22/ip28-berr.c
arch/mips/sgi-ip27/ip27-irq.c
arch/mips/sgi-ip32/ip32-irq.c
arch/mips/sibyte/bcm1480/irq.c
arch/mips/sibyte/common/sb_tbprof.c
arch/mips/sibyte/sb1250/irq.c
arch/mips/sibyte/sb1250/setup.c
arch/mips/sibyte/swarm/setup.c
arch/mips/txx9/generic/pci.c
arch/mips/txx9/generic/setup.c
arch/mips/txx9/generic/spi_eeprom.c
arch/mips/txx9/rbtx4939/setup.c
arch/mn10300/include/asm/atomic.h
arch/mn10300/kernel/process.c
arch/mn10300/kernel/setup.c
arch/mn10300/mm/dma-alloc.c
arch/mn10300/mm/init.c
arch/mn10300/mm/pgtable.c
arch/mn10300/unit-asb2305/pci-irq.c
arch/parisc/hpux/fs.c
arch/parisc/include/asm/atomic.h
arch/parisc/kernel/module.c
arch/parisc/kernel/pci-dma.c
arch/parisc/kernel/pci.c
arch/parisc/kernel/process.c
arch/parisc/kernel/signal32.c
arch/parisc/kernel/smp.c
arch/parisc/mm/init.c
arch/powerpc/Kconfig
arch/powerpc/configs/52xx/cm5200_defconfig
arch/powerpc/configs/52xx/lite5200b_defconfig
arch/powerpc/configs/52xx/motionpro_defconfig
arch/powerpc/configs/52xx/pcm030_defconfig
arch/powerpc/configs/52xx/tqm5200_defconfig
arch/powerpc/configs/83xx/asp8347_defconfig
arch/powerpc/configs/83xx/kmeter1_defconfig
arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
arch/powerpc/configs/83xx/mpc832x_mds_defconfig
arch/powerpc/configs/83xx/mpc832x_rdb_defconfig
arch/powerpc/configs/83xx/mpc834x_itx_defconfig
arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig
arch/powerpc/configs/83xx/mpc834x_mds_defconfig
arch/powerpc/configs/83xx/mpc836x_mds_defconfig
arch/powerpc/configs/83xx/mpc836x_rdk_defconfig
arch/powerpc/configs/83xx/mpc837x_mds_defconfig
arch/powerpc/configs/83xx/mpc837x_rdb_defconfig
arch/powerpc/configs/83xx/sbc834x_defconfig
arch/powerpc/configs/85xx/ksi8560_defconfig
arch/powerpc/configs/85xx/mpc8540_ads_defconfig
arch/powerpc/configs/85xx/mpc8560_ads_defconfig
arch/powerpc/configs/85xx/mpc85xx_cds_defconfig
arch/powerpc/configs/85xx/sbc8548_defconfig
arch/powerpc/configs/85xx/sbc8560_defconfig
arch/powerpc/configs/85xx/socrates_defconfig
arch/powerpc/configs/85xx/stx_gp3_defconfig
arch/powerpc/configs/85xx/tqm8540_defconfig
arch/powerpc/configs/85xx/tqm8541_defconfig
arch/powerpc/configs/85xx/tqm8548_defconfig
arch/powerpc/configs/85xx/tqm8555_defconfig
arch/powerpc/configs/85xx/tqm8560_defconfig
arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
arch/powerpc/configs/86xx/gef_ppc9a_defconfig
arch/powerpc/configs/86xx/gef_sbc310_defconfig
arch/powerpc/configs/86xx/gef_sbc610_defconfig
arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
arch/powerpc/configs/86xx/sbc8641d_defconfig
arch/powerpc/configs/adder875_defconfig
arch/powerpc/configs/c2k_defconfig
arch/powerpc/configs/ep8248e_defconfig
arch/powerpc/configs/ep88xc_defconfig
arch/powerpc/configs/linkstation_defconfig
arch/powerpc/configs/mgcoge_defconfig
arch/powerpc/configs/mgsuvd_defconfig
arch/powerpc/configs/mpc5200_defconfig
arch/powerpc/configs/mpc7448_hpc2_defconfig
arch/powerpc/configs/mpc8272_ads_defconfig
arch/powerpc/configs/mpc83xx_defconfig
arch/powerpc/configs/mpc85xx_defconfig
arch/powerpc/configs/mpc85xx_smp_defconfig
arch/powerpc/configs/mpc866_ads_defconfig
arch/powerpc/configs/mpc86xx_defconfig
arch/powerpc/configs/mpc885_ads_defconfig
arch/powerpc/configs/pq2fads_defconfig
arch/powerpc/configs/prpmc2800_defconfig
arch/powerpc/configs/ps3_defconfig
arch/powerpc/configs/storcenter_defconfig
arch/powerpc/include/asm/asm-compat.h
arch/powerpc/include/asm/hw_irq.h
arch/powerpc/include/asm/page.h
arch/powerpc/include/asm/ppc-opcode.h
arch/powerpc/include/asm/syscall.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/cacheinfo.c
arch/powerpc/kernel/dma-swiotlb.c
arch/powerpc/kernel/dma.c
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/head_fsl_booke.S
arch/powerpc/kernel/ibmebus.c
arch/powerpc/kernel/iommu.c
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/kprobes.c
arch/powerpc/kernel/lparcfg.c
arch/powerpc/kernel/misc.S
arch/powerpc/kernel/of_platform.c
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/pci_32.c
arch/powerpc/kernel/pci_dn.c
arch/powerpc/kernel/perf_event.c
arch/powerpc/kernel/proc_powerpc.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/rtas.c
arch/powerpc/kernel/rtas_flash.c
arch/powerpc/kernel/rtasd.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/smp-tbsync.c
arch/powerpc/kernel/softemu8xx.c
arch/powerpc/kernel/sys_ppc32.c
arch/powerpc/kernel/time.c
arch/powerpc/kernel/traps.c
arch/powerpc/kernel/vio.c
arch/powerpc/kvm/44x.c
arch/powerpc/kvm/44x_tlb.c
arch/powerpc/kvm/book3s.c
arch/powerpc/kvm/booke.c
arch/powerpc/kvm/e500.c
arch/powerpc/kvm/e500_tlb.c
arch/powerpc/kvm/powerpc.c
arch/powerpc/lib/devres.c
arch/powerpc/mm/dma-noncoherent.c
arch/powerpc/mm/fsl_booke_mmu.c
arch/powerpc/mm/hugetlbpage.c
arch/powerpc/mm/init_32.c
arch/powerpc/mm/init_64.c
arch/powerpc/mm/mem.c
arch/powerpc/mm/mmu_context_hash64.c
arch/powerpc/mm/mmu_context_nohash.c
arch/powerpc/mm/numa.c
arch/powerpc/mm/pgtable.c
arch/powerpc/mm/pgtable_32.c
arch/powerpc/mm/pgtable_64.c
arch/powerpc/mm/subpage-prot.c
arch/powerpc/oprofile/cell/spu_task_sync.c
arch/powerpc/oprofile/cell/vma_map.c
arch/powerpc/platforms/44x/warp.c
arch/powerpc/platforms/52xx/mpc52xx_gpio.c
arch/powerpc/platforms/52xx/mpc52xx_gpt.c
arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
arch/powerpc/platforms/82xx/ep8248e.c
arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/86xx/Kconfig
arch/powerpc/platforms/86xx/gef_gpio.c
arch/powerpc/platforms/8xx/m8xx_setup.c
arch/powerpc/platforms/cell/axon_msi.c
arch/powerpc/platforms/cell/celleb_pci.c
arch/powerpc/platforms/cell/celleb_scc_pciex.c
arch/powerpc/platforms/cell/iommu.c
arch/powerpc/platforms/cell/ras.c
arch/powerpc/platforms/cell/setup.c
arch/powerpc/platforms/cell/spider-pci.c
arch/powerpc/platforms/cell/spu_manage.c
arch/powerpc/platforms/cell/spu_priv1_mmio.c
arch/powerpc/platforms/cell/spufs/coredump.c
arch/powerpc/platforms/cell/spufs/file.c
arch/powerpc/platforms/cell/spufs/lscsa_alloc.c
arch/powerpc/platforms/cell/spufs/sched.c
arch/powerpc/platforms/cell/spufs/syscalls.c
arch/powerpc/platforms/chrp/nvram.c
arch/powerpc/platforms/chrp/setup.c
arch/powerpc/platforms/iseries/iommu.c
arch/powerpc/platforms/iseries/mf.c
arch/powerpc/platforms/iseries/pci.c
arch/powerpc/platforms/iseries/vio.c
arch/powerpc/platforms/iseries/viopath.c
arch/powerpc/platforms/maple/setup.c
arch/powerpc/platforms/pasemi/dma_lib.c
arch/powerpc/platforms/pasemi/gpio_mdio.c
arch/powerpc/platforms/pasemi/setup.c
arch/powerpc/platforms/powermac/cpufreq_32.c
arch/powerpc/platforms/powermac/cpufreq_64.c
arch/powerpc/platforms/powermac/low_i2c.c
arch/powerpc/platforms/powermac/nvram.c
arch/powerpc/platforms/powermac/pfunc_core.c
arch/powerpc/platforms/powermac/setup.c
arch/powerpc/platforms/ps3/device-init.c
arch/powerpc/platforms/ps3/mm.c
arch/powerpc/platforms/ps3/os-area.c
arch/powerpc/platforms/ps3/spu.c
arch/powerpc/platforms/ps3/system-bus.c
arch/powerpc/platforms/pseries/cmm.c
arch/powerpc/platforms/pseries/dlpar.c
arch/powerpc/platforms/pseries/dtl.c
arch/powerpc/platforms/pseries/eeh_cache.c
arch/powerpc/platforms/pseries/eeh_event.c
arch/powerpc/platforms/pseries/hotplug-memory.c
arch/powerpc/platforms/pseries/nvram.c
arch/powerpc/platforms/pseries/phyp_dump.c
arch/powerpc/platforms/pseries/ras.c
arch/powerpc/platforms/pseries/reconfig.c
arch/powerpc/platforms/pseries/scanlog.c
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/sysdev/cpm1.c
arch/powerpc/sysdev/cpm2.c
arch/powerpc/sysdev/cpm_common.c
arch/powerpc/sysdev/dart_iommu.c
arch/powerpc/sysdev/fsl_gtm.c
arch/powerpc/sysdev/fsl_msi.c
arch/powerpc/sysdev/fsl_pci.c
arch/powerpc/sysdev/fsl_rio.c
arch/powerpc/sysdev/mpc8xxx_gpio.c
arch/powerpc/sysdev/mpic.c
arch/powerpc/sysdev/msi_bitmap.c
arch/powerpc/sysdev/of_rtc.c
arch/powerpc/sysdev/pmi.c
arch/powerpc/sysdev/ppc4xx_gpio.c
arch/powerpc/sysdev/ppc4xx_pci.c
arch/powerpc/sysdev/qe_lib/gpio.c
arch/powerpc/sysdev/qe_lib/ucc.c
arch/powerpc/sysdev/simple_gpio.c
arch/powerpc/sysdev/tsi108_pci.c
arch/s390/appldata/appldata_mem.c
arch/s390/appldata/appldata_net_sum.c
arch/s390/boot/compressed/misc.c
arch/s390/crypto/prng.c
arch/s390/defconfig
arch/s390/hypfs/hypfs_diag.c
arch/s390/hypfs/inode.c
arch/s390/include/asm/pgtable.h
arch/s390/include/asm/system.h
arch/s390/include/asm/vdso.h
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/compat_linux.c
arch/s390/kernel/early.c
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/head.S
arch/s390/kernel/head31.S
arch/s390/kernel/head64.S
arch/s390/kernel/ipl.c
arch/s390/kernel/kprobes.c
arch/s390/kernel/process.c
arch/s390/kernel/ptrace.c
arch/s390/kernel/setup.c
arch/s390/kernel/smp.c
arch/s390/kernel/swsusp_asm64.S
arch/s390/kernel/sysinfo.c
arch/s390/kernel/time.c
arch/s390/kernel/topology.c
arch/s390/kernel/vdso32/clock_gettime.S
arch/s390/kernel/vdso32/gettimeofday.S
arch/s390/kernel/vdso64/clock_gettime.S
arch/s390/kernel/vdso64/gettimeofday.S
arch/s390/kvm/interrupt.c
arch/s390/kvm/priv.c
arch/s390/kvm/sigp.c
arch/s390/mm/cmm.c
arch/s390/mm/init.c
arch/s390/mm/maccess.c
arch/s390/mm/page-states.c
arch/s390/mm/pgtable.c
arch/s390/mm/vmem.c
arch/score/kernel/sys_score.c
arch/score/mm/init.c
arch/sh/Kconfig
arch/sh/boards/mach-ecovec24/setup.c
arch/sh/boards/mach-se/7724/setup.c
arch/sh/configs/ecovec24_defconfig
arch/sh/configs/rts7751r2d1_defconfig
arch/sh/configs/rts7751r2dplus_defconfig
arch/sh/drivers/dma/dma-api.c
arch/sh/drivers/dma/dmabrg.c
arch/sh/drivers/heartbeat.c
arch/sh/drivers/pci/pci-sh7751.c
arch/sh/drivers/pci/pcie-sh7786.c
arch/sh/drivers/push-switch.c
arch/sh/include/asm/atomic.h
arch/sh/include/asm/elf.h
arch/sh/include/asm/hw_breakpoint.h
arch/sh/include/asm/mmu.h
arch/sh/include/cpu-sh4/cpu/dma-register.h
arch/sh/include/cpu-sh4/cpu/mmu_context.h
arch/sh/include/cpu-sh4/cpu/watchdog.h
arch/sh/kernel/cpu/fpu.c
arch/sh/kernel/cpu/hwblk.c
arch/sh/kernel/cpufreq.c
arch/sh/kernel/dwarf.c
arch/sh/kernel/hw_breakpoint.c
arch/sh/kernel/idle.c
arch/sh/kernel/kprobes.c
arch/sh/kernel/perf_event.c
arch/sh/kernel/process.c
arch/sh/kernel/process_32.c
arch/sh/kernel/process_64.c
arch/sh/kernel/ptrace_32.c
arch/sh/kernel/return_address.c
arch/sh/kernel/smp.c
arch/sh/kernel/vsyscall/vsyscall.c
arch/sh/mm/consistent.c
arch/sh/mm/hugetlbpage.c
arch/sh/mm/init.c
arch/sh/mm/ioremap.c
arch/sh/mm/ioremap_fixed.c
arch/sh/mm/pgtable.c
arch/sh/mm/pmb.c
arch/sh/mm/tlb-pteaex.c
arch/sh/mm/tlb-sh3.c
arch/sh/mm/tlb-sh4.c
arch/sh/mm/tlb-urb.c
arch/sh/mm/tlbflush_32.c
arch/sh/mm/uncached.c
arch/sparc/Kconfig
arch/sparc/Kconfig.debug
arch/sparc/configs/sparc64_defconfig
arch/sparc/include/asm/atomic_32.h
arch/sparc/include/asm/atomic_64.h
arch/sparc/include/asm/bitops_64.h
arch/sparc/include/asm/cpudata_64.h
arch/sparc/include/asm/irqflags_64.h
arch/sparc/include/asm/stat.h
arch/sparc/include/asm/thread_info_64.h
arch/sparc/kernel/Makefile
arch/sparc/kernel/central.c
arch/sparc/kernel/cpumap.c
arch/sparc/kernel/ftrace.c
arch/sparc/kernel/helpers.S
arch/sparc/kernel/hvapi.c
arch/sparc/kernel/iommu.c
arch/sparc/kernel/irq_64.c
arch/sparc/kernel/kgdb_64.c
arch/sparc/kernel/kprobes.c
arch/sparc/kernel/kstack.h
arch/sparc/kernel/led.c
arch/sparc/kernel/leon_kernel.c
arch/sparc/kernel/leon_smp.c
arch/sparc/kernel/module.c
arch/sparc/kernel/nmi.c
arch/sparc/kernel/of_device_common.c
arch/sparc/kernel/pci_common.c
arch/sparc/kernel/pci_msi.c
arch/sparc/kernel/pcr.c
arch/sparc/kernel/perf_event.c
arch/sparc/kernel/process_32.c
arch/sparc/kernel/ptrace_32.c
arch/sparc/kernel/ptrace_64.c
arch/sparc/kernel/rtrap_64.S
arch/sparc/kernel/setup_64.c
arch/sparc/kernel/smp_64.c
arch/sparc/kernel/sun4c_irq.c
arch/sparc/kernel/sun4m_irq.c
arch/sparc/kernel/sys_sparc32.c
arch/sparc/kernel/sysfs.c
arch/sparc/kernel/time_64.c
arch/sparc/kernel/traps_64.c
arch/sparc/kernel/unaligned_64.c
arch/sparc/kernel/us2e_cpufreq.c
arch/sparc/kernel/us3_cpufreq.c
arch/sparc/kernel/vio.c
arch/sparc/kernel/vmlinux.lds.S
arch/sparc/lib/mcount.S
arch/sparc/mm/hugetlbpage.c
arch/sparc/mm/init_32.c
arch/sparc/mm/init_64.c
arch/sparc/mm/srmmu.c
arch/sparc/mm/sun4c.c
arch/sparc/mm/tsb.c
arch/um/drivers/line.c
arch/um/drivers/net_kern.c
arch/um/drivers/port_kern.c
arch/um/drivers/ubd_kern.c
arch/um/kernel/exec.c
arch/um/kernel/irq.c
arch/um/kernel/mem.c
arch/um/kernel/process.c
arch/um/kernel/reboot.c
arch/um/kernel/skas/mmu.c
arch/um/sys-i386/ldt.c
arch/x86/Kconfig
arch/x86/Kconfig.cpu
arch/x86/Kconfig.debug
arch/x86/Makefile
arch/x86/crypto/fpu.c
arch/x86/ia32/ia32_aout.c
arch/x86/ia32/ia32entry.S
arch/x86/ia32/sys_ia32.c
arch/x86/include/asm/alternative-asm.h
arch/x86/include/asm/alternative.h
arch/x86/include/asm/amd_iommu_types.h
arch/x86/include/asm/apic.h
arch/x86/include/asm/arch_hweight.h [new file with mode: 0644]
arch/x86/include/asm/atomic.h
arch/x86/include/asm/atomic64_32.h
arch/x86/include/asm/atomic64_64.h
arch/x86/include/asm/bitops.h
arch/x86/include/asm/boot.h
arch/x86/include/asm/cacheflush.h
arch/x86/include/asm/cmpxchg_32.h
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/ds.h [deleted file]
arch/x86/include/asm/dwarf2.h
arch/x86/include/asm/fixmap.h
arch/x86/include/asm/hardirq.h
arch/x86/include/asm/hw_breakpoint.h
arch/x86/include/asm/hw_irq.h
arch/x86/include/asm/hyperv.h
arch/x86/include/asm/hypervisor.h
arch/x86/include/asm/i387.h
arch/x86/include/asm/i8253.h
arch/x86/include/asm/insn.h
arch/x86/include/asm/io.h
arch/x86/include/asm/io_apic.h
arch/x86/include/asm/k8.h
arch/x86/include/asm/kprobes.h
arch/x86/include/asm/lguest_hcall.h
arch/x86/include/asm/mpspec.h
arch/x86/include/asm/mshyperv.h [new file with mode: 0644]
arch/x86/include/asm/msr-index.h
arch/x86/include/asm/percpu.h
arch/x86/include/asm/perf_event.h
arch/x86/include/asm/perf_event_p4.h [new file with mode: 0644]
arch/x86/include/asm/pgtable_32.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/ptrace-abi.h
arch/x86/include/asm/ptrace.h
arch/x86/include/asm/thread_info.h
arch/x86/include/asm/traps.h
arch/x86/include/asm/vmware.h [deleted file]
arch/x86/include/asm/xsave.h
arch/x86/kernel/Makefile
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/alternative.c
arch/x86/kernel/amd_iommu.c
arch/x86/kernel/amd_iommu_init.c
arch/x86/kernel/apb_timer.c
arch/x86/kernel/aperture_64.c
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/es7000_32.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/apic/nmi.c
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/apm_32.c
arch/x86/kernel/bootflag.c
arch/x86/kernel/cpu/Makefile
arch/x86/kernel/cpu/addon_cpuid_features.c
arch/x86/kernel/cpu/bugs.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/cpufreq/Makefile
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
arch/x86/kernel/cpu/cpufreq/elanfreq.c
arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
arch/x86/kernel/cpu/cpufreq/longrun.c
arch/x86/kernel/cpu/cpufreq/mperf.c [new file with mode: 0644]
arch/x86/kernel/cpu/cpufreq/mperf.h [new file with mode: 0644]
arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c
arch/x86/kernel/cpu/cpufreq/powernow-k6.c
arch/x86/kernel/cpu/cpufreq/powernow-k8.c
arch/x86/kernel/cpu/cpufreq/powernow-k8.h
arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
arch/x86/kernel/cpu/hypervisor.c
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/intel_cacheinfo.c
arch/x86/kernel/cpu/mcheck/mce-inject.c
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/cpu/mcheck/mce_amd.c
arch/x86/kernel/cpu/mcheck/mce_intel.c
arch/x86/kernel/cpu/mshyperv.c [new file with mode: 0644]
arch/x86/kernel/cpu/mtrr/generic.c
arch/x86/kernel/cpu/mtrr/if.c
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/cpu/perf_event_amd.c
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/cpu/perf_event_intel_ds.c [new file with mode: 0644]
arch/x86/kernel/cpu/perf_event_intel_lbr.c [new file with mode: 0644]
arch/x86/kernel/cpu/perf_event_p4.c [new file with mode: 0644]
arch/x86/kernel/cpu/perf_event_p6.c
arch/x86/kernel/cpu/vmware.c
arch/x86/kernel/cpuid.c
arch/x86/kernel/crash.c
arch/x86/kernel/crash_dump_32.c
arch/x86/kernel/ds.c [deleted file]
arch/x86/kernel/ds_selftest.c [deleted file]
arch/x86/kernel/ds_selftest.h [deleted file]
arch/x86/kernel/dumpstack.c
arch/x86/kernel/dumpstack.h
arch/x86/kernel/dumpstack_64.c
arch/x86/kernel/e820.c
arch/x86/kernel/entry_32.S
arch/x86/kernel/head32.c
arch/x86/kernel/head64.c
arch/x86/kernel/hpet.c
arch/x86/kernel/hw_breakpoint.c
arch/x86/kernel/i387.c
arch/x86/kernel/i8253.c
arch/x86/kernel/i8259.c
arch/x86/kernel/irqinit.c
arch/x86/kernel/k8.c
arch/x86/kernel/kdebugfs.c
arch/x86/kernel/kgdb.c
arch/x86/kernel/kprobes.c
arch/x86/kernel/ldt.c
arch/x86/kernel/machine_kexec_64.c
arch/x86/kernel/mca_32.c
arch/x86/kernel/microcode_core.c
arch/x86/kernel/microcode_intel.c
arch/x86/kernel/module.c
arch/x86/kernel/mpparse.c
arch/x86/kernel/mrst.c
arch/x86/kernel/msr.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/pci-gart_64.c
arch/x86/kernel/pci-nommu.c
arch/x86/kernel/process.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/ptrace.c
arch/x86/kernel/setup.c
arch/x86/kernel/sfi.c
arch/x86/kernel/smp.c
arch/x86/kernel/smpboot.c
arch/x86/kernel/step.c
arch/x86/kernel/tlb_uv.c
arch/x86/kernel/traps.c
arch/x86/kernel/uv_irq.c
arch/x86/kernel/uv_time.c
arch/x86/kernel/vmi_32.c
arch/x86/kernel/vmlinux.lds.S
arch/x86/kernel/x8664_ksyms_64.c
arch/x86/kernel/xsave.c
arch/x86/kvm/i8254.c
arch/x86/kvm/i8259.c
arch/x86/kvm/lapic.c
arch/x86/kvm/mmu.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/kvm/x86.h
arch/x86/lguest/boot.c
arch/x86/lguest/i386_head.S
arch/x86/lib/Makefile
arch/x86/lib/atomic64_32.c
arch/x86/lib/atomic64_386_32.S [new file with mode: 0644]
arch/x86/lib/atomic64_cx8_32.S [new file with mode: 0644]
arch/x86/lib/rwsem_64.S
arch/x86/math-emu/fpu_aux.c
arch/x86/math-emu/fpu_entry.c
arch/x86/math-emu/fpu_system.h
arch/x86/mm/Makefile
arch/x86/mm/hugetlbpage.c
arch/x86/mm/init.c
arch/x86/mm/init_32.c
arch/x86/mm/init_64.c
arch/x86/mm/ioremap.c
arch/x86/mm/kmmio.c
arch/x86/mm/mmio-mod.c
arch/x86/mm/pageattr.c
arch/x86/mm/pat.c
arch/x86/mm/pat_internal.h [new file with mode: 0644]
arch/x86/mm/pat_rbtree.c [new file with mode: 0644]
arch/x86/mm/pgtable.c
arch/x86/mm/pgtable_32.c
arch/x86/mm/srat_64.c
arch/x86/oprofile/nmi_int.c
arch/x86/oprofile/op_model_amd.c
arch/x86/oprofile/op_model_p4.c
arch/x86/oprofile/op_model_ppro.c
arch/x86/oprofile/op_x86_model.h
arch/x86/pci/acpi.c
arch/x86/pci/common.c
arch/x86/pci/i386.c
arch/x86/pci/irq.c
arch/x86/pci/mmconfig-shared.c
arch/x86/pci/mrst.c
arch/x86/pci/pcbios.c
arch/x86/power/hibernate_32.c
arch/x86/power/hibernate_64.c
arch/x86/power/hibernate_asm_32.S
arch/x86/vdso/vma.c
arch/x86/xen/debugfs.c
arch/x86/xen/enlighten.c
arch/x86/xen/mmu.c
arch/x86/xen/smp.c
arch/x86/xen/spinlock.c
arch/x86/xen/time.c
arch/xtensa/include/asm/atomic.h
arch/xtensa/kernel/pci-dma.c
arch/xtensa/kernel/process.c
arch/xtensa/mm/init.c
arch/xtensa/platforms/iss/console.c
block/Kconfig
block/blk-barrier.c
block/blk-cgroup.c
block/blk-integrity.c
block/blk-ioc.c
block/blk-settings.c
block/blk-sysfs.c
block/blk-tag.c
block/blk-timeout.c
block/bsg.c
block/cfq-iosched.c
block/compat_ioctl.c
block/elevator.c
block/ioctl.c
block/noop-iosched.c
crypto/algapi.c
crypto/algboss.c
crypto/async_tx/async_pq.c
crypto/async_tx/async_raid6_recov.c
crypto/async_tx/raid6test.c
crypto/authenc.c
crypto/hmac.c
crypto/rng.c
crypto/seqiv.c
crypto/tcrypt.c
crypto/xor.c
drivers/Makefile
drivers/acpi/ac.c
drivers/acpi/acpi_memhotplug.c
drivers/acpi/acpi_pad.c
drivers/acpi/acpica/evgpe.c
drivers/acpi/acpica/exprep.c
drivers/acpi/battery.c
drivers/acpi/bus.c
drivers/acpi/button.c
drivers/acpi/container.c
drivers/acpi/debug.c
drivers/acpi/dock.c
drivers/acpi/ec.c
drivers/acpi/event.c
drivers/acpi/glue.c
drivers/acpi/hest.c
drivers/acpi/numa.c
drivers/acpi/osl.c
drivers/acpi/pci_irq.c
drivers/acpi/pci_link.c
drivers/acpi/pci_root.c
drivers/acpi/pci_slot.c
drivers/acpi/power.c
drivers/acpi/power_meter.c
drivers/acpi/processor_core.c
drivers/acpi/processor_driver.c
drivers/acpi/processor_idle.c
drivers/acpi/processor_perflib.c
drivers/acpi/processor_throttling.c
drivers/acpi/sbs.c
drivers/acpi/sbshc.c
drivers/acpi/scan.c
drivers/acpi/sleep.c
drivers/acpi/system.c
drivers/acpi/thermal.c
drivers/acpi/utils.c
drivers/acpi/video.c
drivers/ata/ahci.c
drivers/ata/ata_piix.c
drivers/ata/libata-acpi.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-pmp.c
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/pata_acpi.c
drivers/ata/pata_at32.c
drivers/ata/pata_at91.c
drivers/ata/pata_atp867x.c
drivers/ata/pata_cmd640.c
drivers/ata/pata_icside.c
drivers/ata/pata_it821x.c
drivers/ata/pata_macio.c
drivers/ata/pata_mpc52xx.c
drivers/ata/pata_octeon_cf.c
drivers/ata/pata_pcmcia.c
drivers/ata/pata_rb532_cf.c
drivers/ata/pata_rdc.c
drivers/ata/pata_via.c
drivers/ata/pdc_adma.c
drivers/ata/sata_fsl.c
drivers/ata/sata_inic162x.c
drivers/ata/sata_mv.c
drivers/ata/sata_nv.c
drivers/ata/sata_promise.c
drivers/ata/sata_qstor.c
drivers/ata/sata_sil24.c
drivers/ata/sata_sx4.c
drivers/ata/sata_uli.c
drivers/atm/adummy.c
drivers/atm/ambassador.c
drivers/atm/atmtcp.c
drivers/atm/eni.c
drivers/atm/firestream.c
drivers/atm/he.c
drivers/atm/horizon.c
drivers/atm/idt77105.c
drivers/atm/idt77252.c
drivers/atm/iphase.c
drivers/atm/lanai.c
drivers/atm/nicstar.c
drivers/atm/solos-pci.c
drivers/atm/suni.c
drivers/atm/uPD98402.c
drivers/atm/zatm.c
drivers/auxdisplay/cfag12864b.c
drivers/auxdisplay/cfag12864bfb.c
drivers/base/attribute_container.c
drivers/base/bus.c
drivers/base/class.c
drivers/base/core.c
drivers/base/cpu.c
drivers/base/devres.c
drivers/base/devtmpfs.c
drivers/base/dma-coherent.c
drivers/base/dma-mapping.c
drivers/base/driver.c
drivers/base/firmware_class.c
drivers/base/iommu.c
drivers/base/memory.c
drivers/base/module.c
drivers/base/node.c
drivers/base/platform.c
drivers/base/power/main.c
drivers/base/sys.c
drivers/block/DAC960.c
drivers/block/amiflop.c
drivers/block/aoe/aoeblk.c
drivers/block/aoe/aoechr.c
drivers/block/aoe/aoecmd.c
drivers/block/aoe/aoedev.c
drivers/block/aoe/aoenet.c
drivers/block/brd.c
drivers/block/cciss.c
drivers/block/drbd/drbd_actlog.c
drivers/block/drbd/drbd_bitmap.c
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_main.c
drivers/block/drbd/drbd_nl.c
drivers/block/drbd/drbd_proc.c
drivers/block/drbd/drbd_receiver.c
drivers/block/drbd/drbd_worker.c
drivers/block/hd.c
drivers/block/loop.c
drivers/block/mg_disk.c
drivers/block/nbd.c
drivers/block/osdblk.c
drivers/block/paride/pcd.c
drivers/block/paride/pd.c
drivers/block/paride/pf.c
drivers/block/paride/pt.c
drivers/block/pktcdvd.c
drivers/block/ps3disk.c
drivers/block/ps3vram.c
drivers/block/swim.c
drivers/block/ub.c
drivers/block/umem.c
drivers/block/virtio_blk.c
drivers/block/xd.c
drivers/block/xen-blkfront.c
drivers/block/z2ram.c
drivers/bluetooth/btmrvl_debugfs.c
drivers/bluetooth/btmrvl_drv.h
drivers/bluetooth/btmrvl_sdio.c
drivers/char/agp/amd-k7-agp.c
drivers/char/agp/backend.c
drivers/char/agp/compat_ioctl.c
drivers/char/agp/generic.c
drivers/char/agp/hp-agp.c
drivers/char/agp/intel-agp.c
drivers/char/agp/nvidia-agp.c
drivers/char/agp/sgi-agp.c
drivers/char/agp/uninorth-agp.c
drivers/char/amiserial.c
drivers/char/bfin_jtag_comm.c
drivers/char/briq_panel.c
drivers/char/bsr.c
drivers/char/cyclades.c
drivers/char/dsp56k.c
drivers/char/epca.c
drivers/char/generic_serial.c
drivers/char/hpet.c
drivers/char/hvc_console.c
drivers/char/hvc_iucv.c
drivers/char/hvcs.c
drivers/char/hw_random/intel-rng.c
drivers/char/hw_random/octeon-rng.c
drivers/char/hw_random/tx4939-rng.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/isicom.c
drivers/char/istallion.c
drivers/char/mbcs.c
drivers/char/mem.c
drivers/char/misc.c
drivers/char/mmtimer.c
drivers/char/moxa.c
drivers/char/mxser.c
drivers/char/nozomi.c
drivers/char/nvram.c
drivers/char/pcmcia/cm4000_cs.c
drivers/char/pcmcia/ipwireless/network.c
drivers/char/ppdev.c
drivers/char/ps3flash.c
drivers/char/pty.c
drivers/char/raw.c
drivers/char/rio/rioinit.c
drivers/char/rio/riointr.c
drivers/char/rio/rioparam.c
drivers/char/rio/rioroute.c
drivers/char/rio/riotty.c
drivers/char/riscom8.c
drivers/char/serial167.c
drivers/char/snsc_event.c
drivers/char/sonypi.c
drivers/char/specialix.c
drivers/char/stallion.c
drivers/char/sysrq.c
drivers/char/tpm/tpm.c
drivers/char/tpm/tpm_bios.c
drivers/char/tpm/tpm_nsc.c
drivers/char/tpm/tpm_tis.c
drivers/char/tty_audit.c
drivers/char/tty_buffer.c
drivers/char/tty_io.c
drivers/char/tty_port.c
drivers/char/viotape.c
drivers/char/virtio_console.c
drivers/char/vme_scc.c
drivers/char/vt_ioctl.c
drivers/char/xilinx_hwicap/xilinx_hwicap.c
drivers/clocksource/sh_cmt.c
drivers/clocksource/sh_mtu2.c
drivers/clocksource/sh_tmu.c
drivers/connector/cn_proc.c
drivers/connector/connector.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_conservative.c
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpufreq/cpufreq_stats.c
drivers/cpuidle/governors/menu.c
drivers/cpuidle/sysfs.c
drivers/crypto/amcc/crypto4xx_core.c
drivers/crypto/ixp4xx_crypto.c
drivers/crypto/mv_cesa.c
drivers/crypto/padlock-aes.c
drivers/crypto/talitos.c
drivers/dca/dca-core.c
drivers/dca/dca-sysfs.c
drivers/dma/at_hdmac.c
drivers/dma/coh901318_lli.c
drivers/dma/dmaengine.c
drivers/dma/dmatest.c
drivers/dma/fsldma.c
drivers/dma/ioat/dma.c
drivers/dma/ioat/dma_v2.c
drivers/dma/ioat/dma_v3.c
drivers/dma/ioat/pci.c
drivers/dma/iop-adma.c
drivers/dma/iovlock.c
drivers/dma/mpc512x_dma.c
drivers/dma/mv_xor.c
drivers/dma/ppc4xx/adma.c
drivers/dma/shdma.c
drivers/dma/txx9dmac.c
drivers/edac/amd76x_edac.c
drivers/edac/cpc925_edac.c
drivers/edac/e752x_edac.c
drivers/edac/e7xxx_edac.c
drivers/edac/edac_device_sysfs.c
drivers/edac/edac_mc_sysfs.c
drivers/edac/edac_mce_amd.c
drivers/edac/edac_pci_sysfs.c
drivers/edac/i3000_edac.c
drivers/edac/i3200_edac.c
drivers/edac/i5100_edac.c
drivers/edac/i82443bxgx_edac.c
drivers/edac/i82860_edac.c
drivers/edac/i82875p_edac.c
drivers/edac/i82975x_edac.c
drivers/edac/mpc85xx_edac.c
drivers/edac/mv64x60_edac.c
drivers/edac/pasemi_edac.c
drivers/edac/r82600_edac.c
drivers/edac/x38_edac.c
drivers/firewire/core-cdev.c
drivers/firewire/core-device.c
drivers/firewire/core-iso.c
drivers/firewire/net.c
drivers/firewire/ohci.c
drivers/firmware/dcdbas.c
drivers/firmware/dell_rbu.c
drivers/firmware/dmi-id.c
drivers/firmware/dmi_scan.c
drivers/firmware/efivars.c
drivers/firmware/iscsi_ibft_find.c
drivers/firmware/memmap.c
drivers/gpio/adp5520-gpio.c
drivers/gpio/adp5588-gpio.c
drivers/gpio/bt8xxgpio.c
drivers/gpio/gpiolib.c
drivers/gpio/it8761e_gpio.c
drivers/gpio/langwell_gpio.c
drivers/gpio/max7300.c
drivers/gpio/max7301.c
drivers/gpio/max730x.c
drivers/gpio/mc33880.c
drivers/gpio/mcp23s08.c
drivers/gpio/pca953x.c
drivers/gpio/pl061.c
drivers/gpio/timbgpio.c
drivers/gpio/twl4030-gpio.c
drivers/gpio/wm831x-gpio.c
drivers/gpio/wm8350-gpiolib.c
drivers/gpio/wm8994-gpio.c
drivers/gpio/xilinx_gpio.c
drivers/gpu/drm/drm_agpsupport.c
drivers/gpu/drm/drm_bufs.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/drm_debugfs.c
drivers/gpu/drm/drm_dp_i2c_helper.c
drivers/gpu/drm/drm_drv.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/drm_fops.c
drivers/gpu/drm/drm_hashtab.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/drm_memory.c
drivers/gpu/drm/drm_pci.c
drivers/gpu/drm/drm_proc.c
drivers/gpu/drm/drm_scatter.c
drivers/gpu/drm/drm_stub.c
drivers/gpu/drm/drm_sysfs.c
drivers/gpu/drm/drm_vm.c
drivers/gpu/drm/i810/i810_dma.c
drivers/gpu/drm/i830/i830_dma.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_debug.c
drivers/gpu/drm/i915/i915_gem_tiling.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_opregion.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_dvo.c
drivers/gpu/drm/i915/intel_fb.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_modes.c
drivers/gpu/drm/i915/intel_overlay.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_tv.c
drivers/gpu/drm/nouveau/Makefile
drivers/gpu/drm/nouveau/nouveau_acpi.c
drivers/gpu/drm/nouveau/nouveau_backlight.c
drivers/gpu/drm/nouveau/nouveau_bios.c
drivers/gpu/drm/nouveau/nouveau_bios.h
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/nouveau/nouveau_channel.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_debugfs.c
drivers/gpu/drm/nouveau/nouveau_dma.c
drivers/gpu/drm/nouveau/nouveau_dp.c
drivers/gpu/drm/nouveau/nouveau_drv.c
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_encoder.h
drivers/gpu/drm/nouveau/nouveau_fbcon.c
drivers/gpu/drm/nouveau/nouveau_gem.c
drivers/gpu/drm/nouveau/nouveau_grctx.c
drivers/gpu/drm/nouveau/nouveau_irq.c
drivers/gpu/drm/nouveau/nouveau_mem.c
drivers/gpu/drm/nouveau/nouveau_sgdma.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nv04_crtc.c
drivers/gpu/drm/nouveau/nv04_fbcon.c
drivers/gpu/drm/nouveau/nv40_fifo.c
drivers/gpu/drm/nouveau/nv40_graph.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nv50_display.h
drivers/gpu/drm/nouveau/nv50_fb.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/nv50_fbcon.c
drivers/gpu/drm/nouveau/nv50_gpio.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/nv50_graph.c
drivers/gpu/drm/nouveau/nv50_grctx.c
drivers/gpu/drm/nouveau/nv50_instmem.c
drivers/gpu/drm/nouveau/nv50_sor.c
drivers/gpu/drm/r128/r128_cce.c
drivers/gpu/drm/radeon/Makefile
drivers/gpu/drm/radeon/atom.c
drivers/gpu/drm/radeon/atom.h
drivers/gpu/drm/radeon/atombios.h
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/atombios_dp.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r100_track.h
drivers/gpu/drm/radeon/r200.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r300_cmdbuf.c
drivers/gpu/drm/radeon/r420.c
drivers/gpu/drm/radeon/r520.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_audio.c
drivers/gpu/drm/radeon/r600_blit_shaders.c
drivers/gpu/drm/radeon/r600_cp.c
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/r600_hdmi.c
drivers/gpu/drm/radeon/r600_reg.h
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_agp.c
drivers/gpu/drm/radeon/radeon_asic.c [new file with mode: 0644]
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_atpx_handler.c
drivers/gpu/drm/radeon/radeon_bios.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_cp.c
drivers/gpu/drm/radeon/radeon_cs.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_drv.h
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_family.h
drivers/gpu/drm/radeon/radeon_fb.c
drivers/gpu/drm/radeon/radeon_fence.c
drivers/gpu/drm/radeon/radeon_i2c.c
drivers/gpu/drm/radeon/radeon_irq_kms.c
drivers/gpu/drm/radeon/radeon_kms.c
drivers/gpu/drm/radeon/radeon_legacy_crtc.c
drivers/gpu/drm/radeon/radeon_legacy_encoders.c
drivers/gpu/drm/radeon/radeon_legacy_tv.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/radeon_reg.h
drivers/gpu/drm/radeon/radeon_ring.c
drivers/gpu/drm/radeon/radeon_state.c
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/radeon/reg_srcs/r300
drivers/gpu/drm/radeon/reg_srcs/r420
drivers/gpu/drm/radeon/reg_srcs/r600
drivers/gpu/drm/radeon/reg_srcs/rs600
drivers/gpu/drm/radeon/reg_srcs/rv515
drivers/gpu/drm/radeon/rs400.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rs600d.h
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/radeon/rs690d.h
drivers/gpu/drm/radeon/rv515.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/ttm/ttm_agp_backend.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/ttm/ttm_bo_util.c
drivers/gpu/drm/ttm/ttm_lock.c
drivers/gpu/drm/ttm/ttm_memory.c
drivers/gpu/drm/ttm/ttm_tt.c
drivers/gpu/drm/via/via_dmablit.c
drivers/gpu/drm/via/via_video.c
drivers/gpu/drm/vmwgfx/Kconfig
drivers/gpu/vga/vga_switcheroo.c
drivers/gpu/vga/vgaarb.c
drivers/hid/hid-3m-pct.c
drivers/hid/hid-a4tech.c
drivers/hid/hid-apple.c
drivers/hid/hid-cherry.c
drivers/hid/hid-core.c
drivers/hid/hid-debug.c
drivers/hid/hid-drff.c
drivers/hid/hid-gaff.c
drivers/hid/hid-gyration.c
drivers/hid/hid-ids.h
drivers/hid/hid-lg2ff.c
drivers/hid/hid-magicmouse.c
drivers/hid/hid-mosart.c
drivers/hid/hid-ntrig.c
drivers/hid/hid-pl.c
drivers/hid/hid-quanta.c
drivers/hid/hid-sjoy.c
drivers/hid/hid-sony.c
drivers/hid/hid-stantum.c
drivers/hid/hid-tmff.c
drivers/hid/hid-wacom.c
drivers/hid/hid-zpff.c
drivers/hid/hidraw.c
drivers/hid/usbhid/hid-core.c
drivers/hid/usbhid/hid-pidff.c
drivers/hid/usbhid/hid-quirks.c
drivers/hwmon/Kconfig
drivers/hwmon/ad7414.c
drivers/hwmon/ad7418.c
drivers/hwmon/adcxx.c
drivers/hwmon/adt7411.c
drivers/hwmon/adt7462.c
drivers/hwmon/adt7470.c
drivers/hwmon/applesmc.c
drivers/hwmon/asc7621.c
drivers/hwmon/asus_atk0110.c
drivers/hwmon/atxp1.c
drivers/hwmon/coretemp.c
drivers/hwmon/f75375s.c
drivers/hwmon/hp_accel.c
drivers/hwmon/i5k_amb.c
drivers/hwmon/ibmaem.c
drivers/hwmon/ibmpex.c
drivers/hwmon/it87.c
drivers/hwmon/lm70.c
drivers/hwmon/lm73.c
drivers/hwmon/max1111.c
drivers/hwmon/mc13783-adc.c
drivers/hwmon/sht15.c
drivers/hwmon/w83793.c
drivers/hwmon/wm831x-hwmon.c
drivers/i2c/algos/i2c-algo-bit.c
drivers/i2c/algos/i2c-algo-pcf.c
drivers/i2c/busses/i2c-amd8111.c
drivers/i2c/busses/i2c-bfin-twi.c
drivers/i2c/busses/i2c-davinci.c
drivers/i2c/busses/i2c-designware.c
drivers/i2c/busses/i2c-elektor.c
drivers/i2c/busses/i2c-gpio.c
drivers/i2c/busses/i2c-highlander.c
drivers/i2c/busses/i2c-imx.c
drivers/i2c/busses/i2c-ixp2000.c
drivers/i2c/busses/i2c-mpc.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-nforce2.c
drivers/i2c/busses/i2c-nomadik.c
drivers/i2c/busses/i2c-ocores.c
drivers/i2c/busses/i2c-octeon.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-parport.c
drivers/i2c/busses/i2c-pasemi.c
drivers/i2c/busses/i2c-pnx.c
drivers/i2c/busses/i2c-pxa.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/busses/i2c-scmi.c
drivers/i2c/busses/i2c-sh_mobile.c
drivers/i2c/busses/i2c-simtec.c
drivers/i2c/busses/i2c-stu300.c
drivers/i2c/busses/i2c-tiny-usb.c
drivers/i2c/busses/i2c-versatile.c
drivers/i2c/busses/i2c-xiic.c
drivers/i2c/busses/scx200_acb.c
drivers/i2c/i2c-boardinfo.c
drivers/i2c/i2c-core.c
drivers/i2c/i2c-smbus.c
drivers/ide/hpt366.c
drivers/ide/ide-acpi.c
drivers/ide/ide-atapi.c
drivers/ide/ide-cd_ioctl.c
drivers/ide/ide-cs.c
drivers/ide/ide-devsets.c
drivers/ide/ide-disk_proc.c
drivers/ide/ide-dma.c
drivers/ide/ide-floppy.c
drivers/ide/ide-gd.c
drivers/ide/ide-io.c
drivers/ide/ide-ioctls.c
drivers/ide/ide-park.c
drivers/ide/ide-pm.c
drivers/ide/ide-probe.c
drivers/ide/ide-proc.c
drivers/ide/ide-taskfile.c
drivers/ide/ide.c
drivers/ide/it821x.c
drivers/ide/pmac.c
drivers/ide/rapide.c
drivers/ide/sc1200.c
drivers/ide/via82cxxx.c
drivers/idle/i7300_idle.c
drivers/ieee1394/dma.c
drivers/ieee1394/sbp2.c
drivers/infiniband/core/addr.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/iwcm.c
drivers/infiniband/core/mad.c
drivers/infiniband/core/mad_rmpp.c
drivers/infiniband/core/multicast.c
drivers/infiniband/core/sysfs.c
drivers/infiniband/core/ucm.c
drivers/infiniband/core/ucma.c
drivers/infiniband/core/umem.c
drivers/infiniband/core/user_mad.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/uverbs_main.c
drivers/infiniband/hw/amso1100/c2.c
drivers/infiniband/hw/amso1100/c2_alloc.c
drivers/infiniband/hw/amso1100/c2_cm.c
drivers/infiniband/hw/amso1100/c2_cq.c
drivers/infiniband/hw/amso1100/c2_mm.c
drivers/infiniband/hw/amso1100/c2_pd.c
drivers/infiniband/hw/amso1100/c2_provider.c
drivers/infiniband/hw/amso1100/c2_qp.c
drivers/infiniband/hw/amso1100/c2_rnic.c
drivers/infiniband/hw/cxgb3/cxio_dbg.c
drivers/infiniband/hw/cxgb3/cxio_hal.c
drivers/infiniband/hw/cxgb3/iwch_cm.c
drivers/infiniband/hw/cxgb3/iwch_ev.c
drivers/infiniband/hw/cxgb3/iwch_mem.c
drivers/infiniband/hw/cxgb3/iwch_provider.c
drivers/infiniband/hw/cxgb3/iwch_qp.c
drivers/infiniband/hw/ehca/ehca_av.c
drivers/infiniband/hw/ehca/ehca_cq.c
drivers/infiniband/hw/ehca/ehca_hca.c
drivers/infiniband/hw/ehca/ehca_irq.c
drivers/infiniband/hw/ehca/ehca_mrmw.c
drivers/infiniband/hw/ehca/ehca_pd.c
drivers/infiniband/hw/ehca/ehca_qp.c
drivers/infiniband/hw/ehca/ehca_uverbs.c
drivers/infiniband/hw/ehca/ipz_pt_fn.c
drivers/infiniband/hw/ipath/ipath_cq.c
drivers/infiniband/hw/ipath/ipath_dma.c
drivers/infiniband/hw/ipath/ipath_driver.c
drivers/infiniband/hw/ipath/ipath_file_ops.c
drivers/infiniband/hw/ipath/ipath_fs.c
drivers/infiniband/hw/ipath/ipath_init_chip.c
drivers/infiniband/hw/ipath/ipath_mmap.c
drivers/infiniband/hw/ipath/ipath_mr.c
drivers/infiniband/hw/ipath/ipath_qp.c
drivers/infiniband/hw/ipath/ipath_sdma.c
drivers/infiniband/hw/ipath/ipath_srq.c
drivers/infiniband/hw/ipath/ipath_user_pages.c
drivers/infiniband/hw/ipath/ipath_verbs.c
drivers/infiniband/hw/ipath/ipath_verbs_mcast.c
drivers/infiniband/hw/mlx4/ah.c
drivers/infiniband/hw/mlx4/cq.c
drivers/infiniband/hw/mlx4/mad.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx4/mr.c
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/mlx4/srq.c
drivers/infiniband/hw/mthca/mthca_cmd.c
drivers/infiniband/hw/mthca/mthca_cq.c
drivers/infiniband/hw/mthca/mthca_eq.c
drivers/infiniband/hw/mthca/mthca_main.c
drivers/infiniband/hw/mthca/mthca_mcg.c
drivers/infiniband/hw/mthca/mthca_memfree.c
drivers/infiniband/hw/mthca/mthca_provider.c
drivers/infiniband/hw/nes/nes.c
drivers/infiniband/hw/nes/nes_cm.c
drivers/infiniband/hw/nes/nes_hw.c
drivers/infiniband/hw/nes/nes_nic.c
drivers/infiniband/hw/nes/nes_utils.c
drivers/infiniband/hw/nes/nes_verbs.c
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/infiniband/ulp/ipoib/ipoib_fs.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/infiniband/ulp/ipoib/ipoib_verbs.c
drivers/infiniband/ulp/ipoib/ipoib_vlan.c
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/infiniband/ulp/iser/iser_verbs.c
drivers/input/ff-core.c
drivers/input/ff-memless.c
drivers/input/gameport/gameport.c
drivers/input/gameport/lightning.c
drivers/input/input-polldev.c
drivers/input/input.c
drivers/input/joydev.c
drivers/input/joystick/analog.c
drivers/input/joystick/db9.c
drivers/input/joystick/gamecon.c
drivers/input/joystick/iforce/iforce-main.c
drivers/input/joystick/iforce/iforce-usb.c
drivers/input/joystick/turbografx.c
drivers/input/keyboard/adp5520-keys.c
drivers/input/keyboard/adp5588-keys.c
drivers/input/keyboard/bf54x-keys.c
drivers/input/keyboard/davinci_keyscan.c
drivers/input/keyboard/ep93xx_keypad.c
drivers/input/keyboard/gpio_keys.c
drivers/input/keyboard/imx_keypad.c
drivers/input/keyboard/jornada680_kbd.c
drivers/input/keyboard/jornada720_kbd.c
drivers/input/keyboard/lm8323.c
drivers/input/keyboard/matrix_keypad.c
drivers/input/keyboard/max7359_keypad.c
drivers/input/keyboard/omap-keypad.c
drivers/input/keyboard/opencores-kbd.c
drivers/input/keyboard/pxa27x_keypad.c
drivers/input/keyboard/pxa930_rotary.c
drivers/input/keyboard/sh_keysc.c
drivers/input/keyboard/tosakbd.c
drivers/input/keyboard/twl4030_keypad.c
drivers/input/keyboard/w90p910_keypad.c
drivers/input/misc/88pm860x_onkey.c
drivers/input/misc/ati_remote.c
drivers/input/misc/ati_remote2.c
drivers/input/misc/bfin_rotary.c
drivers/input/misc/cobalt_btns.c
drivers/input/misc/dm355evm_keys.c
drivers/input/misc/pcap_keys.c
drivers/input/misc/pcf50633-input.c
drivers/input/misc/pcspkr.c
drivers/input/misc/rotary_encoder.c
drivers/input/misc/sgi_btns.c
drivers/input/misc/sparcspkr.c
drivers/input/misc/twl4030-vibra.c
drivers/input/misc/winbond-cir.c
drivers/input/misc/wistron_btns.c
drivers/input/misc/wm831x-on.c
drivers/input/mouse/alps.c
drivers/input/mouse/bcm5974.c
drivers/input/mouse/elantech.c
drivers/input/mouse/elantech.h
drivers/input/mouse/hgpk.c
drivers/input/mouse/lifebook.c
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/psmouse.h
drivers/input/mouse/pxa930_trkball.c
drivers/input/mouse/sentelic.c
drivers/input/mouse/synaptics.c
drivers/input/mouse/synaptics.h
drivers/input/mouse/synaptics_i2c.c
drivers/input/mouse/touchkit_ps2.c
drivers/input/mouse/trackpoint.c
drivers/input/serio/altera_ps2.c
drivers/input/serio/at32psif.c
drivers/input/serio/ct82c710.c
drivers/input/serio/gscps2.c
drivers/input/serio/hil_mlc.c
drivers/input/serio/i8042.c
drivers/input/serio/libps2.c
drivers/input/serio/parkbd.c
drivers/input/serio/pcips2.c
drivers/input/serio/q40kbd.c
drivers/input/serio/rpckbd.c
drivers/input/serio/xilinx_ps2.c
drivers/input/sparse-keymap.c
drivers/input/tablet/wacom_sys.c
drivers/input/tablet/wacom_wac.c
drivers/input/touchscreen/88pm860x-ts.c
drivers/input/touchscreen/ad7877.c
drivers/input/touchscreen/atmel-wm97xx.c
drivers/input/touchscreen/da9034-ts.c
drivers/input/touchscreen/eeti_ts.c
drivers/input/touchscreen/jornada720_ts.c
drivers/input/touchscreen/mc13783_ts.c
drivers/input/touchscreen/mcs5000_ts.c
drivers/input/touchscreen/migor_ts.c
drivers/input/touchscreen/pcap_ts.c
drivers/input/touchscreen/s3c2410_ts.c
drivers/input/touchscreen/ucb1400_ts.c
drivers/input/touchscreen/w90p910_ts.c
drivers/input/touchscreen/wm97xx-core.c
drivers/input/xen-kbdfront.c
drivers/isdn/act2000/module.c
drivers/isdn/capi/capifs.c
drivers/isdn/capi/capilib.c
drivers/isdn/capi/capiutil.c
drivers/isdn/capi/kcapi.c
drivers/isdn/divert/divert_procfs.c
drivers/isdn/divert/isdn_divert.c
drivers/isdn/gigaset/bas-gigaset.c
drivers/isdn/gigaset/capi.c
drivers/isdn/gigaset/common.c
drivers/isdn/gigaset/dummyll.c
drivers/isdn/gigaset/ev-layer.c
drivers/isdn/gigaset/gigaset.h
drivers/isdn/gigaset/i4l.c
drivers/isdn/gigaset/interface.c
drivers/isdn/gigaset/proc.c
drivers/isdn/gigaset/ser-gigaset.c
drivers/isdn/gigaset/usb-gigaset.c
drivers/isdn/hardware/avm/b1.c
drivers/isdn/hardware/avm/b1dma.c
drivers/isdn/hardware/avm/c4.c
drivers/isdn/hardware/avm/t1isa.c
drivers/isdn/hardware/eicon/capimain.c
drivers/isdn/hardware/eicon/message.c
drivers/isdn/hardware/mISDN/avmfritz.c
drivers/isdn/hardware/mISDN/hfcmulti.c
drivers/isdn/hardware/mISDN/hfcpci.c
drivers/isdn/hardware/mISDN/hfcsusb.c
drivers/isdn/hardware/mISDN/mISDNinfineon.c
drivers/isdn/hardware/mISDN/mISDNipac.c
drivers/isdn/hardware/mISDN/mISDNisar.c
drivers/isdn/hardware/mISDN/netjet.c
drivers/isdn/hardware/mISDN/speedfax.c
drivers/isdn/hardware/mISDN/w6692.c
drivers/isdn/hisax/amd7930_fn.c
drivers/isdn/hisax/avm_pci.c
drivers/isdn/hisax/avma1_cs.c
drivers/isdn/hisax/callc.c
drivers/isdn/hisax/config.c
drivers/isdn/hisax/elsa.c
drivers/isdn/hisax/elsa_cs.c
drivers/isdn/hisax/elsa_ser.c
drivers/isdn/hisax/fsm.c
drivers/isdn/hisax/hfc4s8s_l1.c
drivers/isdn/hisax/hfc_2bds0.c
drivers/isdn/hisax/hfc_2bs0.c
drivers/isdn/hisax/hfc_sx.c
drivers/isdn/hisax/hfc_usb.c
drivers/isdn/hisax/hisax_isac.c
drivers/isdn/hisax/hscx.c
drivers/isdn/hisax/icc.c
drivers/isdn/hisax/ipacx.c
drivers/isdn/hisax/isac.c
drivers/isdn/hisax/isar.c
drivers/isdn/hisax/isdnl1.c
drivers/isdn/hisax/isdnl2.c
drivers/isdn/hisax/isdnl3.c
drivers/isdn/hisax/jade.c
drivers/isdn/hisax/l3dss1.c
drivers/isdn/hisax/l3ni1.c
drivers/isdn/hisax/netjet.c
drivers/isdn/hisax/sedlbauer_cs.c
drivers/isdn/hisax/st5481_b.c
drivers/isdn/hisax/st5481_d.c
drivers/isdn/hisax/tei.c
drivers/isdn/hisax/teles_cs.c
drivers/isdn/hisax/w6692.c
drivers/isdn/hysdn/hycapi.c
drivers/isdn/hysdn/hysdn_boot.c
drivers/isdn/hysdn/hysdn_procconf.c
drivers/isdn/hysdn/hysdn_proclog.c
drivers/isdn/i4l/isdn_audio.c
drivers/isdn/i4l/isdn_common.c
drivers/isdn/i4l/isdn_net.c
drivers/isdn/i4l/isdn_ppp.c
drivers/isdn/i4l/isdn_tty.c
drivers/isdn/i4l/isdn_x25iface.c
drivers/isdn/icn/icn.c
drivers/isdn/isdnloop/isdnloop.c
drivers/isdn/mISDN/clock.c
drivers/isdn/mISDN/core.c
drivers/isdn/mISDN/dsp_cmx.c
drivers/isdn/mISDN/dsp_core.c
drivers/isdn/mISDN/dsp_pipeline.c
drivers/isdn/mISDN/dsp_tones.c
drivers/isdn/mISDN/hwchannel.c
drivers/isdn/mISDN/l1oip_core.c
drivers/isdn/mISDN/layer1.c
drivers/isdn/mISDN/layer2.c
drivers/isdn/mISDN/socket.c
drivers/isdn/mISDN/stack.c
drivers/isdn/mISDN/tei.c
drivers/isdn/mISDN/timerdev.c
drivers/isdn/pcbit/callbacks.c
drivers/isdn/pcbit/edss1.c
drivers/isdn/sc/init.c
drivers/leds/Kconfig
drivers/leds/Makefile
drivers/leds/dell-led.c [new file with mode: 0644]
drivers/leds/led-class.c
drivers/leds/led-triggers.c
drivers/leds/leds-88pm860x.c
drivers/leds/leds-adp5520.c
drivers/leds/leds-atmel-pwm.c
drivers/leds/leds-bd2802.c
drivers/leds/leds-da903x.c
drivers/leds/leds-dac124s085.c
drivers/leds/leds-gpio.c
drivers/leds/leds-lp3944.c
drivers/leds/leds-lt3593.c
drivers/leds/leds-pca9532.c
drivers/leds/leds-pca955x.c
drivers/leds/leds-pwm.c
drivers/leds/leds-regulator.c
drivers/leds/leds-s3c24xx.c
drivers/leds/leds-ss4200.c
drivers/leds/leds-sunfire.c
drivers/leds/leds-wm831x-status.c
drivers/leds/leds-wm8350.c
drivers/leds/ledtrig-backlight.c
drivers/leds/ledtrig-gpio.c
drivers/leds/ledtrig-heartbeat.c
drivers/leds/ledtrig-timer.c
drivers/lguest/core.c
drivers/lguest/lg.h
drivers/lguest/lguest_device.c
drivers/lguest/lguest_user.c
drivers/lguest/page_tables.c
drivers/lguest/x86/core.c
drivers/macintosh/mac_hid.c
drivers/macintosh/rack-meter.c
drivers/macintosh/smu.c
drivers/macintosh/therm_pm72.c
drivers/macintosh/therm_windtunnel.c
drivers/macintosh/via-pmu-backlight.c
drivers/macintosh/via-pmu68k.c
drivers/macintosh/windfarm_core.c
drivers/md/dm-log-userspace-base.c
drivers/md/dm-log-userspace-transfer.c
drivers/md/dm-region-hash.c
drivers/md/dm-service-time.c
drivers/md/dm-target.c
drivers/md/faulty.c
drivers/md/linear.c
drivers/md/md.c
drivers/md/multipath.c
drivers/md/raid0.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/md/raid6algos.c
drivers/media/IR/ir-keytable.c
drivers/media/IR/ir-sysfs.c
drivers/media/common/saa7146_fops.c
drivers/media/common/saa7146_video.c
drivers/media/common/tuners/max2165.c
drivers/media/common/tuners/mc44s803.c
drivers/media/common/tuners/mt2060.c
drivers/media/common/tuners/mt20xx.c
drivers/media/common/tuners/mt2131.c
drivers/media/common/tuners/mt2266.c
drivers/media/common/tuners/tda827x.c
drivers/media/common/tuners/tda8290.c
drivers/media/common/tuners/tda9887.c
drivers/media/common/tuners/tea5761.c
drivers/media/common/tuners/tea5767.c
drivers/media/common/tuners/tuner-i2c.h
drivers/media/common/tuners/tuner-xc2028.c
drivers/media/dvb/bt8xx/dst_ca.c
drivers/media/dvb/dm1105/dm1105.c
drivers/media/dvb/dvb-core/dmxdev.h
drivers/media/dvb/dvb-core/dvb_frontend.h
drivers/media/dvb/dvb-usb/af9015.c
drivers/media/dvb/dvb-usb/cxusb.c
drivers/media/dvb/firewire/firedtv-1394.c
drivers/media/dvb/firewire/firedtv-rc.c
drivers/media/dvb/frontends/au8522_dig.c
drivers/media/dvb/frontends/dib0070.c
drivers/media/dvb/frontends/dib0090.c
drivers/media/dvb/frontends/dib3000mc.c
drivers/media/dvb/frontends/dib7000m.c
drivers/media/dvb/frontends/dib7000p.c
drivers/media/dvb/frontends/dib8000.c
drivers/media/dvb/frontends/drx397xD.c
drivers/media/dvb/frontends/dvb-pll.c
drivers/media/dvb/frontends/itd1000.c
drivers/media/dvb/frontends/lgdt3304.c
drivers/media/dvb/frontends/lgdt3305.c
drivers/media/dvb/frontends/mb86a16.c
drivers/media/dvb/frontends/s921_module.c
drivers/media/dvb/frontends/stb0899_drv.c
drivers/media/dvb/frontends/stb6000.c
drivers/media/dvb/frontends/stb6100.c
drivers/media/dvb/frontends/stv090x.c
drivers/media/dvb/frontends/stv6110.c
drivers/media/dvb/frontends/stv6110x.c
drivers/media/dvb/frontends/tda665x.c
drivers/media/dvb/frontends/tda8261.c
drivers/media/dvb/frontends/tda826x.c
drivers/media/dvb/frontends/tua6100.c
drivers/media/dvb/frontends/zl10036.c
drivers/media/dvb/mantis/hopper_cards.c
drivers/media/dvb/mantis/mantis_ca.c
drivers/media/dvb/mantis/mantis_cards.c
drivers/media/dvb/ngene/ngene-core.c
drivers/media/dvb/pluto2/pluto2.c
drivers/media/dvb/pt1/pt1.c
drivers/media/dvb/siano/smscoreapi.c
drivers/media/dvb/siano/smsdvb.c
drivers/media/dvb/siano/smssdio.c
drivers/media/dvb/siano/smsusb.c
drivers/media/dvb/ttpci/av7110.c
drivers/media/dvb/ttpci/av7110_ca.c
drivers/media/dvb/ttpci/budget.c
drivers/media/radio/radio-gemtek-pci.c
drivers/media/radio/radio-maestro.c
drivers/media/radio/radio-maxiradio.c
drivers/media/radio/radio-si4713.c
drivers/media/radio/radio-tea5764.c
drivers/media/radio/radio-timb.c
drivers/media/radio/saa7706h.c
drivers/media/radio/si470x/radio-si470x-i2c.c
drivers/media/radio/si470x/radio-si470x-usb.c
drivers/media/radio/si4713-i2c.c
drivers/media/radio/tef6862.c
drivers/media/video/Kconfig
drivers/media/video/Makefile
drivers/media/video/adv7170.c
drivers/media/video/adv7175.c
drivers/media/video/adv7180.c
drivers/media/video/adv7343.c
drivers/media/video/au0828/au0828-core.c
drivers/media/video/au0828/au0828-dvb.c
drivers/media/video/au0828/au0828-video.c
drivers/media/video/bt819.c
drivers/media/video/bt856.c
drivers/media/video/bt866.c
drivers/media/video/bt8xx/bttv-driver.c
drivers/media/video/bt8xx/bttv-gpio.c
drivers/media/video/bt8xx/bttv-input.c
drivers/media/video/bt8xx/bttv-risc.c
drivers/media/video/cafe_ccic.c
drivers/media/video/cpia_pp.c
drivers/media/video/cs5345.c
drivers/media/video/cs53l32a.c
drivers/media/video/cx18/cx18-alsa-main.c
drivers/media/video/cx18/cx18-controls.c
drivers/media/video/cx18/cx18-driver.h
drivers/media/video/cx231xx/cx231xx-cards.c
drivers/media/video/cx231xx/cx231xx-core.c
drivers/media/video/cx231xx/cx231xx-dvb.c
drivers/media/video/cx231xx/cx231xx-input.c
drivers/media/video/cx231xx/cx231xx-vbi.c
drivers/media/video/cx231xx/cx231xx-video.c
drivers/media/video/cx23885/cx23885-417.c
drivers/media/video/cx23885/cx23885-input.c
drivers/media/video/cx23885/cx23885-vbi.c
drivers/media/video/cx23885/cx23885.h
drivers/media/video/cx23885/cx23888-ir.c
drivers/media/video/cx88/cx88-alsa.c
drivers/media/video/cx88/cx88-blackbird.c
drivers/media/video/cx88/cx88-cards.c
drivers/media/video/cx88/cx88-dsp.c
drivers/media/video/cx88/cx88-input.c
drivers/media/video/cx88/cx88-mpeg.c
drivers/media/video/cx88/cx88-tvaudio.c
drivers/media/video/cx88/cx88-vbi.c
drivers/media/video/cx88/cx88-vp3054-i2c.c
drivers/media/video/davinci/dm644x_ccdc.c
drivers/media/video/davinci/vpfe_capture.c
drivers/media/video/davinci/vpif_capture.c
drivers/media/video/davinci/vpif_display.c
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/em28xx/em28xx-core.c
drivers/media/video/em28xx/em28xx-dvb.c
drivers/media/video/em28xx/em28xx-input.c
drivers/media/video/em28xx/em28xx-vbi.c
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/gspca/gspca.h
drivers/media/video/gspca/jeilinj.c
drivers/media/video/gspca/m5602/m5602_s5k83a.c
drivers/media/video/gspca/sn9c20x.c
drivers/media/video/gspca/sonixj.c
drivers/media/video/gspca/spca508.c
drivers/media/video/gspca/spca561.c
drivers/media/video/gspca/sq905.c
drivers/media/video/gspca/sq905c.c
drivers/media/video/gspca/stv06xx/stv06xx.c
drivers/media/video/gspca/zc3xx.c
drivers/media/video/hdpvr/hdpvr-i2c.c
drivers/media/video/hexium_gemini.c
drivers/media/video/hexium_orion.c
drivers/media/video/ivtv/ivtv-controls.c
drivers/media/video/ivtv/ivtv-driver.h
drivers/media/video/ivtv/ivtvfb.c
drivers/media/video/ks0127.c
drivers/media/video/m52790.c
drivers/media/video/meye.c
drivers/media/video/msp3400-kthreads.c
drivers/media/video/mt9v011.c
drivers/media/video/mx1_camera.c
drivers/media/video/mxb.c
drivers/media/video/omap24xxcam.c
drivers/media/video/ov7670.c
drivers/media/video/pms.c
drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
drivers/media/video/pvrusb2/pvrusb2-debugifc.c
drivers/media/video/pvrusb2/pvrusb2-dvb.c
drivers/media/video/pvrusb2/pvrusb2-eeprom.c
drivers/media/video/pvrusb2/pvrusb2-main.c
drivers/media/video/pvrusb2/pvrusb2-sysfs.c
drivers/media/video/pvrusb2/pvrusb2-v4l2.c
drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
drivers/media/video/pvrusb2/pvrusb2-wm8775.c
drivers/media/video/pwc/pwc-dec23.c
drivers/media/video/pwc/pwc-v4l.c
drivers/media/video/pwc/pwc.h
drivers/media/video/pxa_camera.c
drivers/media/video/s2255drv.c
drivers/media/video/saa5246a.c
drivers/media/video/saa5249.c
drivers/media/video/saa7134/saa7134-dvb.c
drivers/media/video/saa7134/saa7134-empress.c
drivers/media/video/saa7134/saa7134-i2c.c
drivers/media/video/saa7134/saa7134-input.c
drivers/media/video/saa7134/saa7134-ts.c
drivers/media/video/saa7134/saa7134-tvaudio.c
drivers/media/video/saa7134/saa7134-vbi.c
drivers/media/video/saa7164/saa7164-api.c
drivers/media/video/saa7164/saa7164-buffer.c
drivers/media/video/saa7164/saa7164-fw.c
drivers/media/video/saa717x.c
drivers/media/video/saa7185.c
drivers/media/video/sh_mobile_ceu_camera.c
drivers/media/video/soc_camera.c
drivers/media/video/tda9840.c
drivers/media/video/tea6415c.c
drivers/media/video/tea6420.c
drivers/media/video/ths7303.c
drivers/media/video/tlg2300/pd-alsa.c
drivers/media/video/tlg2300/pd-dvb.c
drivers/media/video/tlg2300/pd-video.c
drivers/media/video/tlv320aic23b.c
drivers/media/video/tvp514x.c
drivers/media/video/tvp5150.c
drivers/media/video/tvp7002.c
drivers/media/video/upd64031a.c
drivers/media/video/upd64083.c
drivers/media/video/usbvideo/konicawc.c
drivers/media/video/usbvideo/quickcam_messenger.c
drivers/media/video/usbvision/usbvision-core.c
drivers/media/video/usbvision/usbvision-i2c.c
drivers/media/video/uvc/uvc_ctrl.c
drivers/media/video/uvc/uvc_driver.c
drivers/media/video/uvc/uvc_status.c
drivers/media/video/uvc/uvc_v4l2.c
drivers/media/video/uvc/uvc_video.c
drivers/media/video/v4l2-ioctl.c
drivers/media/video/videobuf-dma-contig.c
drivers/media/video/videobuf-dvb.c
drivers/media/video/vino.c
drivers/media/video/vp27smpx.c
drivers/media/video/vpx3220.c
drivers/media/video/w9966.c
drivers/media/video/wm8739.c
drivers/media/video/wm8775.c
drivers/media/video/zoran/zoran_card.c
drivers/memstick/core/memstick.c
drivers/memstick/core/mspro_block.c
drivers/memstick/host/jmb38x_ms.c
drivers/message/fusion/mptfc.c
drivers/message/fusion/mptlan.c
drivers/message/fusion/mptsas.c
drivers/message/fusion/mptscsih.c
drivers/message/fusion/mptspi.c
drivers/message/i2o/i2o_block.c
drivers/message/i2o/i2o_config.c
drivers/message/i2o/i2o_proc.c
drivers/message/i2o/iop.c
drivers/message/i2o/pci.c
drivers/mfd/88pm860x-i2c.c
drivers/mfd/ab3100-core.c
drivers/mfd/ab3100-otp.c
drivers/mfd/ab4500-core.c
drivers/mfd/adp5520.c
drivers/mfd/asic3.c
drivers/mfd/da903x.c
drivers/mfd/ezx-pcap.c
drivers/mfd/htc-egpio.c
drivers/mfd/htc-i2cpld.c
drivers/mfd/htc-pasic3.c
drivers/mfd/max8925-i2c.c
drivers/mfd/mc13783-core.c
drivers/mfd/mcp-sa11x0.c
drivers/mfd/menelaus.c
drivers/mfd/mfd-core.c
drivers/mfd/pcf50633-adc.c
drivers/mfd/pcf50633-core.c
drivers/mfd/sh_mobile_sdhi.c
drivers/mfd/sm501.c
drivers/mfd/t7l66xb.c
drivers/mfd/tc6387xb.c
drivers/mfd/tc6393xb.c
drivers/mfd/timberdale.c
drivers/mfd/twl4030-codec.c
drivers/mfd/twl4030-irq.c
drivers/mfd/ucb1400_core.c
drivers/mfd/wm831x-core.c
drivers/mfd/wm8350-core.c
drivers/mfd/wm8350-i2c.c
drivers/mfd/wm8400-core.c
drivers/mfd/wm8994-core.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/atmel-ssc.c
drivers/misc/atmel_pwm.c
drivers/misc/atmel_tclib.c
drivers/misc/c2port/core.c
drivers/misc/cb710/core.c
drivers/misc/cb710/debug.c
drivers/misc/cs5535-mfgpt.c
drivers/misc/ds1682.c
drivers/misc/enclosure.c
drivers/misc/ep93xx_pwm.c
drivers/misc/hpilo.c
drivers/misc/ibmasm/command.c
drivers/misc/ibmasm/event.c
drivers/misc/ibmasm/ibmasmfs.c
drivers/misc/ibmasm/module.c
drivers/misc/ics932s401.c
drivers/misc/ioc4.c
drivers/misc/iwmc3200top/debugfs.c
drivers/misc/iwmc3200top/fw-download.c
drivers/misc/iwmc3200top/log.c
drivers/misc/iwmc3200top/main.c
drivers/misc/kgdbts.c
drivers/misc/lkdtm.c
drivers/misc/phantom.c
drivers/misc/sgi-xp/xpc_main.c
drivers/misc/sgi-xp/xpc_partition.c
drivers/misc/sgi-xp/xpc_sn2.c
drivers/misc/sgi-xp/xpc_uv.c
drivers/misc/sgi-xp/xpnet.c
drivers/misc/tifm_core.c
drivers/misc/vmware_balloon.c [new file with mode: 0644]
drivers/mmc/card/block.c
drivers/mmc/card/mmc_test.c
drivers/mmc/card/queue.c
drivers/mmc/card/sdio_uart.c
drivers/mmc/core/bus.c
drivers/mmc/core/debugfs.c
drivers/mmc/core/host.c
drivers/mmc/core/mmc.c
drivers/mmc/core/mmc_ops.c
drivers/mmc/core/sd.c
drivers/mmc/core/sdio_bus.c
drivers/mmc/core/sdio_cis.c
drivers/mmc/host/at91_mci.c
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/au1xmmc.c
drivers/mmc/host/bfin_sdh.c
drivers/mmc/host/cb710-mmc.c
drivers/mmc/host/mmc_spi.c
drivers/mmc/host/msm_sdcc.c
drivers/mmc/host/of_mmc_spi.c
drivers/mmc/host/omap.c
drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/pxamci.c
drivers/mmc/host/sdhci-pci.c
drivers/mmc/host/sdhci-s3c.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/wbsd.c
drivers/mtd/Makefile
drivers/mtd/devices/block2mtd.c
drivers/mtd/devices/m25p80.c
drivers/mtd/devices/sst25l.c
drivers/mtd/internal.h [deleted file]
drivers/mtd/lpddr/lpddr_cmds.c
drivers/mtd/maps/amd76xrom.c
drivers/mtd/maps/bfin-async-flash.c
drivers/mtd/maps/ck804xrom.c
drivers/mtd/maps/esb2rom.c
drivers/mtd/maps/gpio-addr-flash.c
drivers/mtd/maps/ichxrom.c
drivers/mtd/maps/intel_vr_nor.c
drivers/mtd/maps/octagon-5066.c
drivers/mtd/maps/omap_nor.c [deleted file]
drivers/mtd/maps/physmap_of.c
drivers/mtd/maps/pismo.c
drivers/mtd/maps/pmcmsp-flash.c
drivers/mtd/maps/pxa2xx-flash.c
drivers/mtd/maps/sbc_gxx.c
drivers/mtd/maps/sun_uflash.c
drivers/mtd/maps/vmax301.c
drivers/mtd/maps/vmu-flash.c
drivers/mtd/mtdbdi.c [deleted file]
drivers/mtd/mtdcore.c
drivers/mtd/mtdsuper.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/bcm_umi_nand.c
drivers/mtd/nand/cafe_nand.c
drivers/mtd/nand/cmx270_nand.c
drivers/mtd/nand/davinci_nand.c
drivers/mtd/nand/diskonchip.c
drivers/mtd/nand/fsl_upm.c
drivers/mtd/nand/ndfc.c
drivers/mtd/nand/nomadik_nand.c
drivers/mtd/nand/omap2.c
drivers/mtd/nand/orion_nand.c
drivers/mtd/nand/pxa3xx_nand.c
drivers/mtd/nand/sh_flctl.c
drivers/mtd/nand/tmio_nand.c
drivers/mtd/ofpart.c
drivers/mtd/onenand/omap2.c
drivers/mtd/onenand/onenand_base.c
drivers/mtd/onenand/onenand_sim.c
drivers/mtd/tests/mtd_nandecctest.c
drivers/mtd/tests/mtd_oobtest.c
drivers/mtd/tests/mtd_pagetest.c
drivers/mtd/tests/mtd_readtest.c
drivers/mtd/tests/mtd_speedtest.c
drivers/mtd/tests/mtd_stresstest.c
drivers/mtd/tests/mtd_subpagetest.c
drivers/mtd/tests/mtd_torturetest.c
drivers/mtd/ubi/build.c
drivers/mtd/ubi/cdev.c
drivers/mtd/ubi/gluebi.c
drivers/mtd/ubi/io.c
drivers/mtd/ubi/kapi.c
drivers/mtd/ubi/scan.c
drivers/mtd/ubi/ubi.h
drivers/mtd/ubi/vmt.c
drivers/mtd/ubi/vtbl.c
drivers/net/3c501.c
drivers/net/3c505.c
drivers/net/3c507.c
drivers/net/3c509.c
drivers/net/3c515.c
drivers/net/3c523.c
drivers/net/3c59x.c
drivers/net/7990.c
drivers/net/8139cp.c
drivers/net/8139too.c
drivers/net/82596.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/a2065.c
drivers/net/acenic.c
drivers/net/amd8111e.c
drivers/net/appletalk/cops.c
drivers/net/appletalk/ipddp.c
drivers/net/appletalk/ltpc.c
drivers/net/arcnet/arc-rawmode.c
drivers/net/arcnet/arc-rimi.c
drivers/net/arcnet/capmode.c
drivers/net/arcnet/com20020-isa.c
drivers/net/arcnet/com20020-pci.c
drivers/net/arcnet/com20020.c
drivers/net/arcnet/com90io.c
drivers/net/arcnet/com90xx.c
drivers/net/arcnet/rfc1051.c
drivers/net/arcnet/rfc1201.c
drivers/net/ariadne.c
drivers/net/arm/at91_ether.c
drivers/net/arm/ep93xx_eth.c
drivers/net/arm/etherh.c
drivers/net/arm/ixp4xx_eth.c
drivers/net/arm/ks8695net.c
drivers/net/arm/w90p910_ether.c
drivers/net/at1700.c
drivers/net/atarilance.c
drivers/net/atl1c/atl1c_ethtool.c
drivers/net/atl1e/atl1e_ethtool.c
drivers/net/atlx/atl1.c
drivers/net/atlx/atl2.c
drivers/net/atp.c
drivers/net/ax88796.c
drivers/net/b44.c
drivers/net/bcm63xx_enet.c
drivers/net/benet/be.h
drivers/net/benet/be_cmds.c
drivers/net/benet/be_ethtool.c
drivers/net/benet/be_main.c
drivers/net/bmac.c
drivers/net/bnx2.c
drivers/net/bnx2x_main.c
drivers/net/bonding/bond_main.c
drivers/net/can/bfin_can.c
drivers/net/can/dev.c
drivers/net/can/mcp251x.c
drivers/net/can/sja1000/ems_pci.c
drivers/net/can/sja1000/plx_pci.c
drivers/net/can/usb/ems_usb.c
drivers/net/can/vcan.c
drivers/net/chelsio/common.h
drivers/net/chelsio/pm3393.c
drivers/net/chelsio/sge.c
drivers/net/cnic.c
drivers/net/cris/eth_v10.c
drivers/net/cs89x0.c
drivers/net/cxgb3/ael1002.c
drivers/net/cxgb3/cxgb3_main.c
drivers/net/cxgb3/cxgb3_offload.c
drivers/net/cxgb3/l2t.c
drivers/net/cxgb3/sge.c
drivers/net/cxgb4/Makefile [new file with mode: 0644]
drivers/net/cxgb4/cxgb4.h [new file with mode: 0644]
drivers/net/cxgb4/cxgb4_main.c [new file with mode: 0644]
drivers/net/cxgb4/cxgb4_uld.h [new file with mode: 0644]
drivers/net/cxgb4/l2t.c [new file with mode: 0644]
drivers/net/cxgb4/l2t.h [new file with mode: 0644]
drivers/net/cxgb4/sge.c [new file with mode: 0644]
drivers/net/cxgb4/t4_hw.c [new file with mode: 0644]
drivers/net/cxgb4/t4_hw.h [new file with mode: 0644]
drivers/net/cxgb4/t4_msg.h [new file with mode: 0644]
drivers/net/cxgb4/t4_regs.h [new file with mode: 0644]
drivers/net/cxgb4/t4fw_api.h [new file with mode: 0644]
drivers/net/davinci_emac.c
drivers/net/dm9000.c
drivers/net/e100.c
drivers/net/e1000/e1000.h
drivers/net/e1000/e1000_main.c
drivers/net/e1000e/82571.c
drivers/net/e1000e/e1000.h
drivers/net/e1000e/ethtool.c
drivers/net/e1000e/netdev.c
drivers/net/eepro.c
drivers/net/eexpress.c
drivers/net/ehea/ehea_main.c
drivers/net/ehea/ehea_qmr.c
drivers/net/enc28j60.c
drivers/net/enic/vnic_dev.c
drivers/net/enic/vnic_rq.c
drivers/net/enic/vnic_wq.c
drivers/net/epic100.c
drivers/net/eql.c
drivers/net/eth16i.c
drivers/net/ethoc.c
drivers/net/fealnx.c
drivers/net/fec.c
drivers/net/fec_mpc52xx.c
drivers/net/fec_mpc52xx_phy.c
drivers/net/forcedeth.c
drivers/net/fs_enet/mac-fcc.c
drivers/net/fs_enet/mac-fec.c
drivers/net/fs_enet/mac-scc.c
drivers/net/fsl_pq_mdio.c
drivers/net/gianfar.c
drivers/net/gianfar.h
drivers/net/gianfar_ethtool.c
drivers/net/gianfar_sysfs.c
drivers/net/greth.c
drivers/net/hamachi.c
drivers/net/hamradio/6pack.c
drivers/net/hamradio/bpqether.c
drivers/net/hamradio/dmascc.c
drivers/net/hamradio/hdlcdrv.c
drivers/net/hamradio/mkiss.c
drivers/net/hamradio/scc.c
drivers/net/hp100.c
drivers/net/hplance.c
drivers/net/hydra.c
drivers/net/ibm_newemac/core.c
drivers/net/ibm_newemac/core.h
drivers/net/ibm_newemac/mal.c
drivers/net/ibm_newemac/rgmii.c
drivers/net/ibm_newemac/zmii.c
drivers/net/ibmlana.c
drivers/net/ibmveth.c
drivers/net/igb/e1000_82575.c
drivers/net/igb/e1000_hw.h
drivers/net/igb/e1000_mac.c
drivers/net/igb/igb.h
drivers/net/igb/igb_ethtool.c
drivers/net/igb/igb_main.c
drivers/net/igbvf/igbvf.h
drivers/net/igbvf/netdev.c
drivers/net/ioc3-eth.c
drivers/net/ipg.c
drivers/net/irda/ali-ircc.c
drivers/net/irda/bfin_sir.h
drivers/net/irda/irtty-sir.c
drivers/net/irda/nsc-ircc.c
drivers/net/irda/pxaficp_ir.c
drivers/net/irda/sh_sir.c
drivers/net/irda/sir_dev.c
drivers/net/irda/smsc-ircc2.c
drivers/net/irda/via-ircc.c
drivers/net/irda/w83977af_ir.c
drivers/net/iseries_veth.c
drivers/net/ixgbe/ixgbe.h
drivers/net/ixgbe/ixgbe_82599.c
drivers/net/ixgbe/ixgbe_ethtool.c
drivers/net/ixgbe/ixgbe_fcoe.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ixgbe/ixgbe_type.h
drivers/net/ixgbevf/ethtool.c
drivers/net/ixgbevf/ixgbevf_main.c
drivers/net/ixgbevf/vf.h
drivers/net/ixp2000/ixpdev.c
drivers/net/jazzsonic.c
drivers/net/jme.c
drivers/net/jme.h
drivers/net/ks8851.c
drivers/net/ks8851_mll.c
drivers/net/ksz884x.c
drivers/net/lasi_82596.c
drivers/net/lib82596.c
drivers/net/ll_temac_main.c
drivers/net/ll_temac_mdio.c
drivers/net/mac8390.c
drivers/net/mac89x0.c
drivers/net/mace.c
drivers/net/macmace.c
drivers/net/macsonic.c
drivers/net/macvtap.c
drivers/net/mlx4/cmd.c
drivers/net/mlx4/cq.c
drivers/net/mlx4/en_main.c
drivers/net/mlx4/en_netdev.c
drivers/net/mlx4/en_resources.c
drivers/net/mlx4/en_rx.c
drivers/net/mlx4/en_tx.c
drivers/net/mlx4/eq.c
drivers/net/mlx4/icm.c
drivers/net/mlx4/intf.c
drivers/net/mlx4/main.c
drivers/net/mlx4/mcg.c
drivers/net/mlx4/mr.c
drivers/net/mlx4/profile.c
drivers/net/mlx4/qp.c
drivers/net/mlx4/srq.c
drivers/net/mv643xx_eth.c
drivers/net/mvme147.c
drivers/net/myri10ge/myri10ge.c
drivers/net/myri_sbus.c
drivers/net/ne.c
drivers/net/ne2.c
drivers/net/netconsole.c
drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_ctx.c
drivers/net/netxen/netxen_nic_hw.c
drivers/net/netxen/netxen_nic_init.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/ni5010.c
drivers/net/ni52.c
drivers/net/niu.c
drivers/net/ns83820.c
drivers/net/octeon/octeon_mgmt.c
drivers/net/pasemi_mac.c
drivers/net/pcmcia/3c574_cs.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pcmcia/smc91c92_cs.c
drivers/net/phy/Kconfig
drivers/net/phy/Makefile
drivers/net/phy/cicada.c
drivers/net/phy/davicom.c
drivers/net/phy/et1011c.c
drivers/net/phy/fixed.c
drivers/net/phy/icplus.c
drivers/net/phy/lxt.c
drivers/net/phy/marvell.c
drivers/net/phy/mdio-bitbang.c
drivers/net/phy/mdio-octeon.c
drivers/net/phy/micrel.c [new file with mode: 0644]
drivers/net/phy/phy.c
drivers/net/phy/qsemi.c
drivers/net/plip.c
drivers/net/ppp_async.c
drivers/net/ppp_generic.c
drivers/net/ppp_synctty.c
drivers/net/pppol2tp.c
drivers/net/pppox.c
drivers/net/ps3_gelic_net.c
drivers/net/ps3_gelic_wireless.c
drivers/net/qlcnic/qlcnic_hw.c
drivers/net/qlcnic/qlcnic_init.c
drivers/net/qlcnic/qlcnic_main.c
drivers/net/qlge/qlge_dbg.c
drivers/net/qlge/qlge_ethtool.c
drivers/net/r6040.c
drivers/net/r8169.c
drivers/net/rionet.c
drivers/net/rrunner.c
drivers/net/s2io.c
drivers/net/sb1000.c
drivers/net/sb1250-mac.c
drivers/net/seeq8005.c
drivers/net/sfc/efx.c
drivers/net/sfc/falcon.c
drivers/net/sfc/falcon_boards.c
drivers/net/sfc/mcdi_phy.c
drivers/net/sfc/mtd.c
drivers/net/sfc/nic.h
drivers/net/sfc/qt202x_phy.c
drivers/net/sfc/rx.c
drivers/net/sfc/selftest.c
drivers/net/sfc/siena.c
drivers/net/sfc/tenxpress.c
drivers/net/sfc/tx.c
drivers/net/sgiseeq.c
drivers/net/sh_eth.c
drivers/net/sis190.c
drivers/net/skfp/skfddi.c
drivers/net/skge.c
drivers/net/sky2.c
drivers/net/slhc.c
drivers/net/slip.c
drivers/net/smc911x.c
drivers/net/smc9194.c
drivers/net/smc91x.c
drivers/net/smsc911x.c
drivers/net/smsc9420.c
drivers/net/sni_82596.c
drivers/net/spider_net.c
drivers/net/stmmac/Kconfig
drivers/net/stmmac/dwmac100.c
drivers/net/stmmac/dwmac1000_core.c
drivers/net/stmmac/stmmac_main.c
drivers/net/stmmac/stmmac_mdio.c
drivers/net/sun3_82586.c
drivers/net/sun3lance.c
drivers/net/sunbmac.c
drivers/net/sundance.c
drivers/net/sungem.c
drivers/net/sunlance.c
drivers/net/tehuti.h
drivers/net/tg3.c
drivers/net/tokenring/3c359.c
drivers/net/tokenring/lanstreamer.c
drivers/net/tokenring/madgemc.c
drivers/net/tokenring/smctr.c
drivers/net/tokenring/tms380tr.c
drivers/net/tsi108_eth.c
drivers/net/tulip/de2104x.c
drivers/net/tulip/de4x5.c
drivers/net/tulip/dmfe.c
drivers/net/tulip/eeprom.c
drivers/net/tulip/tulip_core.c
drivers/net/tulip/uli526x.c
drivers/net/tulip/winbond-840.c
drivers/net/tun.c
drivers/net/typhoon.c
drivers/net/ucc_geth_ethtool.c
drivers/net/usb/Kconfig
drivers/net/usb/Makefile
drivers/net/usb/asix.c
drivers/net/usb/catc.c
drivers/net/usb/cdc-phonet.c
drivers/net/usb/cdc_eem.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/dm9601.c
drivers/net/usb/gl620a.c
drivers/net/usb/hso.c
drivers/net/usb/int51x1.c
drivers/net/usb/ipheth.c [new file with mode: 0644]
drivers/net/usb/kaweth.c
drivers/net/usb/mcs7830.c
drivers/net/usb/net1080.c
drivers/net/usb/rndis_host.c
drivers/net/usb/sierra_net.c [new file with mode: 0644]
drivers/net/usb/smsc75xx.c [new file with mode: 0644]
drivers/net/usb/smsc75xx.h [new file with mode: 0644]
drivers/net/usb/smsc95xx.c
drivers/net/usb/usbnet.c
drivers/net/veth.c
drivers/net/via-rhine.c
drivers/net/via-velocity.c
drivers/net/virtio_net.c
drivers/net/vxge/vxge-config.c
drivers/net/vxge/vxge-config.h
drivers/net/vxge/vxge-ethtool.c
drivers/net/vxge/vxge-main.c
drivers/net/wan/dscc4.c
drivers/net/wan/farsync.c
drivers/net/wan/hd64570.c
drivers/net/wan/hd64572.c
drivers/net/wan/hdlc_cisco.c
drivers/net/wan/hdlc_ppp.c
drivers/net/wan/hdlc_raw.c
drivers/net/wan/hdlc_raw_eth.c
drivers/net/wan/hdlc_x25.c
drivers/net/wan/hostess_sv11.c
drivers/net/wan/ixp4xx_hss.c
drivers/net/wan/lapbether.c
drivers/net/wan/lmc/lmc_media.c
drivers/net/wan/lmc/lmc_proto.c
drivers/net/wan/pc300_drv.c
drivers/net/wan/sbni.c
drivers/net/wan/sealevel.c
drivers/net/wan/x25_asy.c
drivers/net/wan/z85230.c
drivers/net/wimax/i2400m/control.c
drivers/net/wimax/i2400m/driver.c
drivers/net/wimax/i2400m/fw.c
drivers/net/wimax/i2400m/netdev.c
drivers/net/wimax/i2400m/op-rfkill.c
drivers/net/wimax/i2400m/rx.c
drivers/net/wimax/i2400m/sdio-rx.c
drivers/net/wimax/i2400m/sdio.c
drivers/net/wimax/i2400m/tx.c
drivers/net/wimax/i2400m/usb-fw.c
drivers/net/wimax/i2400m/usb-notif.c
drivers/net/wimax/i2400m/usb-rx.c
drivers/net/wimax/i2400m/usb.c
drivers/net/wireless/adm8211.c
drivers/net/wireless/ath/ar9170/main.c
drivers/net/wireless/ath/ar9170/usb.c
drivers/net/wireless/ath/ar9170/usb.h
drivers/net/wireless/ath/ath5k/attach.c
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/eeprom.c
drivers/net/wireless/ath/ath5k/phy.c
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/phy.c
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/ath9k/virtual.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/regd.c
drivers/net/wireless/b43/dma.c
drivers/net/wireless/b43/lo.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/pcmcia.c
drivers/net/wireless/b43/phy_a.c
drivers/net/wireless/b43/phy_g.c
drivers/net/wireless/b43/phy_lp.c
drivers/net/wireless/b43/phy_n.c
drivers/net/wireless/b43/pio.c
drivers/net/wireless/b43/sdio.c
drivers/net/wireless/b43legacy/dma.c
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/b43legacy/phy.c
drivers/net/wireless/b43legacy/pio.c
drivers/net/wireless/hostap/hostap_80211_rx.c
drivers/net/wireless/hostap/hostap_80211_tx.c
drivers/net/wireless/hostap/hostap_ap.c
drivers/net/wireless/hostap/hostap_cs.c
drivers/net/wireless/hostap/hostap_info.c
drivers/net/wireless/hostap/hostap_ioctl.c
drivers/net/wireless/hostap/hostap_pci.c
drivers/net/wireless/hostap/hostap_plx.c
drivers/net/wireless/ipw2x00/ipw2200.c
drivers/net/wireless/ipw2x00/libipw_geo.c
drivers/net/wireless/ipw2x00/libipw_rx.c
drivers/net/wireless/ipw2x00/libipw_wx.c
drivers/net/wireless/iwlwifi/iwl-3945-rs.c
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-calib.c
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-debugfs.c
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-devtrace.c
drivers/net/wireless/iwlwifi/iwl-devtrace.h
drivers/net/wireless/iwlwifi/iwl-eeprom.c
drivers/net/wireless/iwlwifi/iwl-eeprom.h
drivers/net/wireless/iwlwifi/iwl-io.h
drivers/net/wireless/iwlwifi/iwl-power.c
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/iwmc3200wifi/cfg80211.c
drivers/net/wireless/iwmc3200wifi/commands.c
drivers/net/wireless/iwmc3200wifi/debugfs.c
drivers/net/wireless/iwmc3200wifi/eeprom.c
drivers/net/wireless/iwmc3200wifi/hal.c
drivers/net/wireless/iwmc3200wifi/main.c
drivers/net/wireless/iwmc3200wifi/netdev.c
drivers/net/wireless/iwmc3200wifi/rx.c
drivers/net/wireless/iwmc3200wifi/sdio.c
drivers/net/wireless/iwmc3200wifi/tx.c
drivers/net/wireless/libertas/assoc.c
drivers/net/wireless/libertas/cfg.c
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/cmdresp.c
drivers/net/wireless/libertas/debugfs.c
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/if_cs.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/libertas/if_spi.c
drivers/net/wireless/libertas/if_usb.c
drivers/net/wireless/libertas/main.c
drivers/net/wireless/libertas/rx.c
drivers/net/wireless/libertas/scan.c
drivers/net/wireless/libertas/wext.c
drivers/net/wireless/libertas_tf/cmd.c
drivers/net/wireless/libertas_tf/if_usb.c
drivers/net/wireless/libertas_tf/main.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mwl8k.c
drivers/net/wireless/orinoco/fw.c
drivers/net/wireless/orinoco/main.c
drivers/net/wireless/orinoco/scan.c
drivers/net/wireless/orinoco/wext.c
drivers/net/wireless/p54/eeprom.c
drivers/net/wireless/p54/fwio.c
drivers/net/wireless/p54/main.c
drivers/net/wireless/p54/p54pci.c
drivers/net/wireless/p54/p54spi.c
drivers/net/wireless/p54/p54usb.c
drivers/net/wireless/prism54/isl_ioctl.c
drivers/net/wireless/prism54/islpci_dev.c
drivers/net/wireless/prism54/islpci_eth.c
drivers/net/wireless/prism54/islpci_mgt.c
drivers/net/wireless/prism54/islpci_mgt.h
drivers/net/wireless/prism54/oid_mgt.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/rndis_wlan.c
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rt2x00/rt2x00debug.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00pci.c
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rt2x00/rt2x00soc.c
drivers/net/wireless/rt2x00/rt2x00usb.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rtl818x/rtl8180_dev.c
drivers/net/wireless/rtl818x/rtl8187_dev.c
drivers/net/wireless/wl12xx/wl1251_acx.c
drivers/net/wireless/wl12xx/wl1251_boot.c
drivers/net/wireless/wl12xx/wl1251_cmd.c
drivers/net/wireless/wl12xx/wl1251_debugfs.c
drivers/net/wireless/wl12xx/wl1251_init.c
drivers/net/wireless/wl12xx/wl1251_main.c
drivers/net/wireless/wl12xx/wl1251_rx.c
drivers/net/wireless/wl12xx/wl1251_spi.c
drivers/net/wireless/wl12xx/wl1271_acx.c
drivers/net/wireless/wl12xx/wl1271_boot.c
drivers/net/wireless/wl12xx/wl1271_cmd.c
drivers/net/wireless/wl12xx/wl1271_debugfs.c
drivers/net/wireless/wl12xx/wl1271_init.c
drivers/net/wireless/wl12xx/wl1271_main.c
drivers/net/wireless/wl12xx/wl1271_rx.c
drivers/net/wireless/wl12xx/wl1271_spi.c
drivers/net/wireless/wl12xx/wl1271_testmode.c
drivers/net/wireless/zd1201.c
drivers/net/wireless/zd1211rw/zd_chip.c
drivers/net/wireless/zd1211rw/zd_mac.c
drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
drivers/net/wireless/zd1211rw/zd_usb.c
drivers/net/xen-netfront.c
drivers/net/xilinx_emaclite.c
drivers/net/xtsonic.c
drivers/net/yellowfin.c
drivers/net/znet.c
drivers/net/zorro8390.c
drivers/nubus/nubus.c
drivers/of/base.c
drivers/of/fdt.c
drivers/of/gpio.c
drivers/of/of_mdio.c
drivers/oprofile/buffer_sync.c
drivers/oprofile/cpu_buffer.c
drivers/oprofile/oprof.c
drivers/oprofile/oprof.h
drivers/oprofile/timer_int.c
drivers/parisc/asp.c
drivers/parisc/ccio-rm-dma.c
drivers/parisc/gsc.c
drivers/parport/daisy.c
drivers/parport/parport_ax88796.c
drivers/parport/parport_ip32.c
drivers/parport/parport_serial.c
drivers/parport/probe.c
drivers/pci/Makefile
drivers/pci/access.c
drivers/pci/bus.c
drivers/pci/dmar.c
drivers/pci/hotplug/acpi_pcihp.c
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/acpiphp_ibm.c
drivers/pci/hotplug/cpqphp_sysfs.c
drivers/pci/hotplug/fakephp.c
drivers/pci/hotplug/pci_hotplug_core.c
drivers/pci/hotplug/pciehp_acpi.c
drivers/pci/hotplug/pciehp_core.c
drivers/pci/hotplug/pciehp_ctrl.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/hotplug/rpadlpar_core.c
drivers/pci/hotplug/rpaphp_core.c
drivers/pci/hotplug/sgi_hotplug.c
drivers/pci/hotplug/shpchp_core.c
drivers/pci/hotplug/shpchp_ctrl.c
drivers/pci/htirq.c
drivers/pci/intel-iommu.c
drivers/pci/intr_remapping.c
drivers/pci/ioapic.c
drivers/pci/iov.c
drivers/pci/msi.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/pcie/aer/aer_inject.c
drivers/pci/pcie/aer/aerdrv.c
drivers/pci/pcie/aer/aerdrv_core.c
drivers/pci/pcie/pme/pcie_pme.c
drivers/pci/pcie/portdrv_pci.c
drivers/pci/probe.c
drivers/pci/proc.c
drivers/pci/quirks.c
drivers/pci/search.c
drivers/pci/setup-bus.c
drivers/pci/setup-res.c
drivers/pci/slot.c
drivers/pcmcia/at91_cf.c
drivers/pcmcia/au1000_generic.c
drivers/pcmcia/bcm63xx_pcmcia.c
drivers/pcmcia/bfin_cf_pcmcia.c
drivers/pcmcia/cistpl.c
drivers/pcmcia/cs.c
drivers/pcmcia/db1xxx_ss.c
drivers/pcmcia/ds.c
drivers/pcmcia/electra_cf.c
drivers/pcmcia/i82092.c
drivers/pcmcia/i82365.c
drivers/pcmcia/i82365.h
drivers/pcmcia/m32r_cfc.c
drivers/pcmcia/m32r_pcc.c
drivers/pcmcia/m8xx_pcmcia.c
drivers/pcmcia/omap_cf.c
drivers/pcmcia/pcmcia_ioctl.c
drivers/pcmcia/pcmcia_resource.c
drivers/pcmcia/pd6729.c
drivers/pcmcia/pxa2xx_base.c
drivers/pcmcia/rsrc_mgr.c
drivers/pcmcia/rsrc_nonstatic.c
drivers/pcmcia/sa1100_generic.c
drivers/pcmcia/sa1111_generic.c
drivers/pcmcia/sa11xx_base.c
drivers/pcmcia/socket_sysfs.c
drivers/pcmcia/tcic.c
drivers/pcmcia/ti113x.h
drivers/pcmcia/vrc4171_card.c
drivers/pcmcia/xxs1500_ss.c
drivers/pcmcia/yenta_socket.c
drivers/platform/x86/Kconfig
drivers/platform/x86/Makefile
drivers/platform/x86/acer-wmi.c
drivers/platform/x86/asus-laptop.c
drivers/platform/x86/asus_acpi.c
drivers/platform/x86/classmate-laptop.c
drivers/platform/x86/compal-laptop.c
drivers/platform/x86/dell-laptop.c
drivers/platform/x86/dell-wmi.c
drivers/platform/x86/eeepc-laptop.c
drivers/platform/x86/eeepc-wmi.c [new file with mode: 0644]
drivers/platform/x86/fujitsu-laptop.c
drivers/platform/x86/hp-wmi.c
drivers/platform/x86/intel_menlow.c
drivers/platform/x86/msi-laptop.c
drivers/platform/x86/msi-wmi.c
drivers/platform/x86/panasonic-laptop.c
drivers/platform/x86/sony-laptop.c
drivers/platform/x86/tc1100-wmi.c
drivers/platform/x86/thinkpad_acpi.c
drivers/platform/x86/topstar-laptop.c
drivers/platform/x86/toshiba_acpi.c
drivers/platform/x86/wmi.c
drivers/pnp/isapnp/core.c
drivers/pnp/manager.c
drivers/pnp/pnpacpi/core.c
drivers/pnp/pnpacpi/rsparser.c
drivers/pnp/pnpbios/bioscalls.c
drivers/pnp/pnpbios/rsparser.c
drivers/pnp/resource.c
drivers/power/bq27x00_battery.c
drivers/power/da9030_battery.c
drivers/power/ds2760_battery.c
drivers/power/ds2782_battery.c
drivers/power/max17040_battery.c
drivers/power/max8925_power.c
drivers/power/pcf50633-charger.c
drivers/power/pmu_battery.c
drivers/power/power_supply_leds.c
drivers/power/power_supply_sysfs.c
drivers/power/wm831x_backup.c
drivers/power/wm831x_power.c
drivers/power/wm97xx_battery.c
drivers/pps/kapi.c
drivers/ps3/ps3-lpm.c
drivers/ps3/ps3-vuart.c
drivers/ps3/ps3av.c
drivers/regulator/core.c
drivers/regulator/fixed.c
drivers/regulator/lp3971.c
drivers/regulator/max1586.c
drivers/regulator/max8649.c
drivers/regulator/max8660.c
drivers/regulator/max8925-regulator.c
drivers/regulator/mc13783-regulator.c
drivers/regulator/tps65023-regulator.c
drivers/regulator/tps6507x-regulator.c
drivers/regulator/userspace-consumer.c
drivers/regulator/virtual.c
drivers/regulator/wm831x-dcdc.c
drivers/regulator/wm831x-isink.c
drivers/regulator/wm831x-ldo.c
drivers/regulator/wm8994-regulator.c
drivers/rtc/class.c
drivers/rtc/rtc-at32ap700x.c
drivers/rtc/rtc-at91sam9.c
drivers/rtc/rtc-bfin.c
drivers/rtc/rtc-bq4802.c
drivers/rtc/rtc-coh901331.c
drivers/rtc/rtc-ds1216.c
drivers/rtc/rtc-ds1286.c
drivers/rtc/rtc-ds1305.c
drivers/rtc/rtc-ds1374.c
drivers/rtc/rtc-ds1390.c
drivers/rtc/rtc-ds1511.c
drivers/rtc/rtc-ds1553.c
drivers/rtc/rtc-ds1742.c
drivers/rtc/rtc-ep93xx.c
drivers/rtc/rtc-fm3130.c
drivers/rtc/rtc-m48t35.c
drivers/rtc/rtc-m48t59.c
drivers/rtc/rtc-max8925.c
drivers/rtc/rtc-mc13783.c
drivers/rtc/rtc-mpc5121.c
drivers/rtc/rtc-msm6242.c
drivers/rtc/rtc-mv.c
drivers/rtc/rtc-mxc.c
drivers/rtc/rtc-nuc900.c
drivers/rtc/rtc-pcap.c
drivers/rtc/rtc-pcf2123.c
drivers/rtc/rtc-pcf50633.c
drivers/rtc/rtc-pcf8563.c
drivers/rtc/rtc-pl030.c
drivers/rtc/rtc-pl031.c
drivers/rtc/rtc-pxa.c
drivers/rtc/rtc-rp5c01.c
drivers/rtc/rtc-rs5c348.c
drivers/rtc/rtc-rs5c372.c
drivers/rtc/rtc-rx8025.c
drivers/rtc/rtc-s3c.c
drivers/rtc/rtc-sh.c
drivers/rtc/rtc-stk17ta8.c
drivers/rtc/rtc-stmp3xxx.c
drivers/rtc/rtc-tx4939.c
drivers/rtc/rtc-v3020.c
drivers/rtc/rtc-wm831x.c
drivers/s390/block/dasd.c
drivers/s390/block/dasd_3990_erp.c
drivers/s390/block/dasd_alias.c
drivers/s390/block/dasd_devmap.c
drivers/s390/block/dasd_eckd.c
drivers/s390/block/dasd_eer.c
drivers/s390/block/dasd_ioctl.c
drivers/s390/block/dasd_proc.c
drivers/s390/block/xpram.c
drivers/s390/char/con3270.c
drivers/s390/char/fs3270.c
drivers/s390/char/keyboard.c
drivers/s390/char/monreader.c
drivers/s390/char/monwriter.c
drivers/s390/char/sclp_async.c
drivers/s390/char/sclp_cmd.c
drivers/s390/char/sclp_con.c
drivers/s390/char/sclp_tty.c
drivers/s390/char/sclp_vt220.c
drivers/s390/char/tape_34xx.c
drivers/s390/char/tape_3590.c
drivers/s390/char/tape_class.c
drivers/s390/char/tape_core.c
drivers/s390/char/vmcp.c
drivers/s390/char/vmlogrdr.c
drivers/s390/char/vmur.c
drivers/s390/char/vmwatchdog.c
drivers/s390/char/zcore.c
drivers/s390/cio/blacklist.c
drivers/s390/cio/chp.c
drivers/s390/cio/chsc.c
drivers/s390/cio/chsc_sch.c
drivers/s390/cio/cio.c
drivers/s390/cio/css.c
drivers/s390/cio/device_fsm.c
drivers/s390/cio/qdio_main.c
drivers/s390/cio/qdio_thinint.c
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/zcrypt_api.c
drivers/s390/crypto/zcrypt_cex2a.c
drivers/s390/crypto/zcrypt_pcica.c
drivers/s390/crypto/zcrypt_pcicc.c
drivers/s390/crypto/zcrypt_pcixcc.c
drivers/s390/kvm/kvm_virtio.c
drivers/s390/net/ctcm_dbug.c
drivers/s390/net/ctcm_sysfs.c
drivers/s390/net/fsm.c
drivers/s390/net/lcs.c
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/qeth_l3_main.c
drivers/s390/net/qeth_l3_sys.c
drivers/s390/net/smsgiucv.c
drivers/s390/net/smsgiucv_app.c
drivers/s390/scsi/zfcp_aux.c
drivers/s390/scsi/zfcp_cfdc.c
drivers/s390/scsi/zfcp_dbf.c
drivers/s390/scsi/zfcp_fc.c
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_qdio.c
drivers/s390/scsi/zfcp_scsi.c
drivers/s390/scsi/zfcp_sysfs.c
drivers/sbus/char/bbc_envctrl.c
drivers/sbus/char/display7seg.c
drivers/sbus/char/envctrl.c
drivers/sbus/char/flash.c
drivers/sbus/char/jsflash.c
drivers/scsi/3w-9xxx.c
drivers/scsi/3w-sas.c
drivers/scsi/3w-xxxx.c
drivers/scsi/53c700.c
drivers/scsi/BusLogic.c
drivers/scsi/Kconfig
drivers/scsi/NCR_D700.c
drivers/scsi/NCR_Q720.c
drivers/scsi/a100u2w.c
drivers/scsi/a2091.c
drivers/scsi/a3000.c
drivers/scsi/a4000t.c
drivers/scsi/aacraid/rx.c
drivers/scsi/aacraid/sa.c
drivers/scsi/advansys.c
drivers/scsi/aha152x.c
drivers/scsi/aha1542.c
drivers/scsi/aha1740.c
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/aic94xx/aic94xx_hwi.c
drivers/scsi/aic94xx/aic94xx_init.c
drivers/scsi/aic94xx/aic94xx_scb.c
drivers/scsi/aic94xx/aic94xx_sds.c
drivers/scsi/aic94xx/aic94xx_seq.c
drivers/scsi/aic94xx/aic94xx_tmf.c
drivers/scsi/arcmsr/arcmsr_hba.c
drivers/scsi/atari_NCR5380.c
drivers/scsi/atp870u.c
drivers/scsi/be2iscsi/be_cmds.c
drivers/scsi/be2iscsi/be_iscsi.c
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/be2iscsi/be_main.h
drivers/scsi/be2iscsi/be_mgmt.c
drivers/scsi/be2iscsi/be_mgmt.h
drivers/scsi/bfa/Makefile
drivers/scsi/bfa/bfa_core.c
drivers/scsi/bfa/bfa_fcport.c
drivers/scsi/bfa/bfa_fcs.c
drivers/scsi/bfa/bfa_fcs_lport.c
drivers/scsi/bfa/bfa_fcs_port.c
drivers/scsi/bfa/bfa_fcs_uf.c
drivers/scsi/bfa/bfa_hw_cb.c
drivers/scsi/bfa/bfa_hw_ct.c
drivers/scsi/bfa/bfa_intr.c
drivers/scsi/bfa/bfa_ioc.c
drivers/scsi/bfa/bfa_ioc.h
drivers/scsi/bfa/bfa_ioc_cb.c [new file with mode: 0644]
drivers/scsi/bfa/bfa_ioc_ct.c [new file with mode: 0644]
drivers/scsi/bfa/bfa_iocfc.c
drivers/scsi/bfa/bfa_iocfc.h
drivers/scsi/bfa/bfa_ioim.c
drivers/scsi/bfa/bfa_itnim.c
drivers/scsi/bfa/bfa_lps.c
drivers/scsi/bfa/bfa_module.c
drivers/scsi/bfa/bfa_modules_priv.h
drivers/scsi/bfa/bfa_port_priv.h
drivers/scsi/bfa/bfa_priv.h
drivers/scsi/bfa/bfa_rport.c
drivers/scsi/bfa/bfa_trcmod_priv.h
drivers/scsi/bfa/bfa_tskim.c
drivers/scsi/bfa/bfad.c
drivers/scsi/bfa/bfad_attr.c
drivers/scsi/bfa/bfad_attr.h
drivers/scsi/bfa/bfad_drv.h
drivers/scsi/bfa/bfad_im.c
drivers/scsi/bfa/bfad_im.h
drivers/scsi/bfa/bfad_intr.c
drivers/scsi/bfa/fabric.c
drivers/scsi/bfa/fcbuild.h
drivers/scsi/bfa/fcpim.c
drivers/scsi/bfa/fcs_fabric.h
drivers/scsi/bfa/fcs_fcpim.h
drivers/scsi/bfa/fcs_lport.h
drivers/scsi/bfa/fcs_port.h
drivers/scsi/bfa/fcs_rport.h
drivers/scsi/bfa/fcs_uf.h
drivers/scsi/bfa/fcs_vport.h
drivers/scsi/bfa/fdmi.c
drivers/scsi/bfa/include/aen/bfa_aen.h
drivers/scsi/bfa/include/bfa.h
drivers/scsi/bfa/include/bfa_svc.h
drivers/scsi/bfa/include/bfa_timer.h
drivers/scsi/bfa/include/bfi/bfi.h
drivers/scsi/bfa/include/bfi/bfi_cbreg.h
drivers/scsi/bfa/include/bfi/bfi_ctreg.h
drivers/scsi/bfa/include/bfi/bfi_ioc.h
drivers/scsi/bfa/include/bfi/bfi_lps.h
drivers/scsi/bfa/include/bfi/bfi_pport.h
drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h
drivers/scsi/bfa/include/cs/bfa_log.h
drivers/scsi/bfa/include/cs/bfa_plog.h
drivers/scsi/bfa/include/cs/bfa_sm.h
drivers/scsi/bfa/include/defs/bfa_defs_aen.h
drivers/scsi/bfa/include/defs/bfa_defs_auth.h
drivers/scsi/bfa/include/defs/bfa_defs_cee.h
drivers/scsi/bfa/include/defs/bfa_defs_driver.h
drivers/scsi/bfa/include/defs/bfa_defs_ethport.h
drivers/scsi/bfa/include/defs/bfa_defs_fcport.h [new file with mode: 0644]
drivers/scsi/bfa/include/defs/bfa_defs_im_common.h [deleted file]
drivers/scsi/bfa/include/defs/bfa_defs_im_team.h [deleted file]
drivers/scsi/bfa/include/defs/bfa_defs_ioc.h
drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h
drivers/scsi/bfa/include/defs/bfa_defs_lport.h
drivers/scsi/bfa/include/defs/bfa_defs_mfg.h
drivers/scsi/bfa/include/defs/bfa_defs_port.h
drivers/scsi/bfa/include/defs/bfa_defs_pport.h
drivers/scsi/bfa/include/defs/bfa_defs_status.h
drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h
drivers/scsi/bfa/include/fcs/bfa_fcs.h
drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
drivers/scsi/bfa/include/log/bfa_log_hal.h
drivers/scsi/bfa/include/log/bfa_log_linux.h
drivers/scsi/bfa/include/protocol/fc.h
drivers/scsi/bfa/include/protocol/pcifw.h [deleted file]
drivers/scsi/bfa/loop.c
drivers/scsi/bfa/lport_api.c
drivers/scsi/bfa/ms.c
drivers/scsi/bfa/ns.c
drivers/scsi/bfa/rport.c
drivers/scsi/bfa/rport_api.c
drivers/scsi/bfa/rport_ftrs.c
drivers/scsi/bfa/scn.c
drivers/scsi/bfa/vport.c
drivers/scsi/bnx2i/bnx2i.h
drivers/scsi/bnx2i/bnx2i_hwi.c
drivers/scsi/bnx2i/bnx2i_init.c
drivers/scsi/bnx2i/bnx2i_iscsi.c
drivers/scsi/bvme6000_scsi.c
drivers/scsi/ch.c
drivers/scsi/cxgb3i/cxgb3i_ddp.c
drivers/scsi/cxgb3i/cxgb3i_ddp.h
drivers/scsi/cxgb3i/cxgb3i_iscsi.c
drivers/scsi/cxgb3i/cxgb3i_offload.c
drivers/scsi/cxgb3i/cxgb3i_pdu.c
drivers/scsi/dc395x.c
drivers/scsi/device_handler/scsi_dh.c
drivers/scsi/device_handler/scsi_dh_alua.c
drivers/scsi/device_handler/scsi_dh_emc.c
drivers/scsi/device_handler/scsi_dh_hp_sw.c
drivers/scsi/device_handler/scsi_dh_rdac.c
drivers/scsi/dpt_i2o.c
drivers/scsi/eata.c
drivers/scsi/eata_pio.c
drivers/scsi/fcoe/fcoe.c
drivers/scsi/fcoe/libfcoe.c
drivers/scsi/fd_mcs.c
drivers/scsi/fdomain.c
drivers/scsi/fnic/fnic_fcs.c
drivers/scsi/fnic/fnic_main.c
drivers/scsi/fnic/fnic_scsi.c
drivers/scsi/fnic/vnic_dev.c
drivers/scsi/fnic/vnic_rq.c
drivers/scsi/fnic/vnic_wq.c
drivers/scsi/gdth.c
drivers/scsi/gdth_proc.c
drivers/scsi/gvp11.c
drivers/scsi/hosts.c
drivers/scsi/hpsa.c
drivers/scsi/hpsa.h
drivers/scsi/hpsa_cmd.h
drivers/scsi/hptiop.c
drivers/scsi/ibmvscsi/ibmvfc.c
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/ibmvscsi/ibmvscsi.h
drivers/scsi/ibmvscsi/ibmvstgt.c
drivers/scsi/ibmvscsi/iseries_vscsi.c
drivers/scsi/ibmvscsi/rpa_vscsi.c
drivers/scsi/imm.c
drivers/scsi/ipr.c
drivers/scsi/ipr.h
drivers/scsi/iscsi_tcp.c
drivers/scsi/jazz_esp.c
drivers/scsi/lasi700.c
drivers/scsi/libfc/fc_disc.c
drivers/scsi/libfc/fc_exch.c
drivers/scsi/libfc/fc_fcp.c
drivers/scsi/libfc/fc_frame.c
drivers/scsi/libfc/fc_lport.c
drivers/scsi/libfc/fc_rport.c
drivers/scsi/libiscsi.c
drivers/scsi/libiscsi_tcp.c
drivers/scsi/libsas/sas_ata.c
drivers/scsi/libsas/sas_discover.c
drivers/scsi/libsas/sas_expander.c
drivers/scsi/libsas/sas_host_smp.c
drivers/scsi/libsas/sas_init.c
drivers/scsi/libsas/sas_scsi_host.c
drivers/scsi/libsrp.c
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_bsg.c
drivers/scsi/lpfc/lpfc_bsg.h
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_ct.c
drivers/scsi/lpfc/lpfc_debugfs.c
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_logmsg.h
drivers/scsi/lpfc/lpfc_mbox.c
drivers/scsi/lpfc/lpfc_mem.c
drivers/scsi/lpfc/lpfc_nportdisc.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/lpfc/lpfc_sli.h
drivers/scsi/lpfc/lpfc_sli4.h
drivers/scsi/lpfc/lpfc_version.h
drivers/scsi/lpfc/lpfc_vport.c
drivers/scsi/mac_esp.c
drivers/scsi/megaraid.c
drivers/scsi/megaraid/megaraid_mbox.c
drivers/scsi/megaraid/megaraid_mm.c
drivers/scsi/megaraid/megaraid_sas.c
drivers/scsi/mesh.c
drivers/scsi/mpt2sas/mpt2sas_config.c
drivers/scsi/mpt2sas/mpt2sas_scsih.c
drivers/scsi/mpt2sas/mpt2sas_transport.c
drivers/scsi/mvme16x_scsi.c
drivers/scsi/mvsas/mv_sas.h
drivers/scsi/ncr53c8xx.c
drivers/scsi/nsp32.c
drivers/scsi/osd/osd_initiator.c
drivers/scsi/osd/osd_uld.c
drivers/scsi/osst.c
drivers/scsi/pcmcia/nsp_cs.c
drivers/scsi/pm8001/pm8001_ctl.c
drivers/scsi/pm8001/pm8001_hwi.c
drivers/scsi/pm8001/pm8001_init.c
drivers/scsi/pm8001/pm8001_sas.c
drivers/scsi/pmcraid.c
drivers/scsi/ppa.c
drivers/scsi/ps3rom.c
drivers/scsi/qla1280.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_fw.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_mid.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_sup.c
drivers/scsi/qla2xxx/qla_version.h
drivers/scsi/qla4xxx/ql4_mbx.c
drivers/scsi/qla4xxx/ql4_os.c
drivers/scsi/qlogicpti.c
drivers/scsi/raid_class.c
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_devinfo.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_netlink.c
drivers/scsi/scsi_proc.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_tgt_if.c
drivers/scsi/scsi_tgt_lib.c
drivers/scsi/scsi_transport_fc.c
drivers/scsi/scsi_transport_iscsi.c
drivers/scsi/scsi_transport_spi.c
drivers/scsi/scsicam.c
drivers/scsi/sd.c
drivers/scsi/ses.c
drivers/scsi/sg.c
drivers/scsi/sim710.c
drivers/scsi/sni_53c710.c
drivers/scsi/sr.c
drivers/scsi/sr_ioctl.c
drivers/scsi/sr_vendor.c
drivers/scsi/st.c
drivers/scsi/stex.c
drivers/scsi/sun3_NCR5380.c
drivers/scsi/sun3x_esp.c
drivers/scsi/sun_esp.c
drivers/scsi/tmscsim.c
drivers/scsi/u14-34f.c
drivers/scsi/vmw_pvscsi.c
drivers/scsi/wd7000.c
drivers/scsi/zorro7xx.c
drivers/serial/68328serial.c
drivers/serial/8250.c
drivers/serial/8250_gsc.c
drivers/serial/8250_hp300.c
drivers/serial/8250_pnp.c
drivers/serial/amba-pl010.c
drivers/serial/amba-pl011.c
drivers/serial/bfin_5xx.c
drivers/serial/bfin_sport_uart.c
drivers/serial/cpm_uart/cpm_uart_cpm1.c
drivers/serial/cpm_uart/cpm_uart_cpm2.c
drivers/serial/imx.c
drivers/serial/ioc3_serial.c
drivers/serial/ioc4_serial.c
drivers/serial/jsm/jsm_driver.c
drivers/serial/jsm/jsm_tty.c
drivers/serial/max3100.c
drivers/serial/mcf.c
drivers/serial/mpc52xx_uart.c
drivers/serial/mpsc.c
drivers/serial/mux.c
drivers/serial/of_serial.c
drivers/serial/pmac_zilog.c
drivers/serial/pxa.c
drivers/serial/serial_cs.c
drivers/serial/serial_ks8695.c
drivers/serial/sh-sci.c
drivers/serial/sh-sci.h
drivers/serial/sunsab.c
drivers/serial/sunsu.c
drivers/serial/timbuart.c
drivers/serial/uartlite.c
drivers/serial/ucc_uart.c
drivers/sh/intc.c
drivers/sn/ioc3.c
drivers/spi/amba-pl022.c
drivers/spi/atmel_spi.c
drivers/spi/au1550_spi.c
drivers/spi/davinci_spi.c
drivers/spi/dw_spi.c
drivers/spi/dw_spi_mmio.c
drivers/spi/dw_spi_pci.c
drivers/spi/mpc52xx_psc_spi.c
drivers/spi/mpc52xx_spi.c
drivers/spi/omap2_mcspi.c
drivers/spi/omap_spi_100k.c
drivers/spi/omap_uwire.c
drivers/spi/pxa2xx_spi.c
drivers/spi/spi.c
drivers/spi/spi_bfin5xx.c
drivers/spi/spi_bitbang.c
drivers/spi/spi_imx.c
drivers/spi/spi_mpc8xxx.c
drivers/spi/spi_nuc900.c
drivers/spi/spi_ppc4xx.c
drivers/spi/spi_s3c24xx.c
drivers/spi/tle62x0.c
drivers/spi/xilinx_spi_of.c
drivers/ssb/driver_gige.c
drivers/ssb/driver_pcicore.c
drivers/ssb/main.c
drivers/ssb/pci.c
drivers/ssb/pcihost_wrapper.c
drivers/ssb/sprom.c
drivers/staging/batman-adv/device.c
drivers/staging/batman-adv/main.h
drivers/staging/batman-adv/soft-interface.c
drivers/staging/comedi/drivers/8255.c
drivers/staging/comedi/drivers/addi-data/addi_common.c
drivers/staging/comedi/drivers/adl_pci9118.c
drivers/staging/comedi/drivers/amplc_dio200.c
drivers/staging/comedi/drivers/amplc_pci224.c
drivers/staging/comedi/drivers/cb_das16_cs.c
drivers/staging/comedi/drivers/comedi_bond.c
drivers/staging/comedi/drivers/das08_cs.c
drivers/staging/comedi/drivers/das16.c
drivers/staging/comedi/drivers/das1800.c
drivers/staging/comedi/drivers/dt282x.c
drivers/staging/comedi/drivers/jr3_pci.c
drivers/staging/comedi/drivers/ni_65xx.c
drivers/staging/comedi/drivers/ni_670x.c
drivers/staging/comedi/drivers/ni_at_a2150.c
drivers/staging/comedi/drivers/ni_daq_700.c
drivers/staging/comedi/drivers/ni_daq_dio24.c
drivers/staging/comedi/drivers/ni_labpc.c
drivers/staging/comedi/drivers/ni_labpc_cs.c
drivers/staging/comedi/drivers/pcl812.c
drivers/staging/comedi/drivers/pcl816.c
drivers/staging/comedi/drivers/pcl818.c
drivers/staging/comedi/drivers/pcmmio.c
drivers/staging/comedi/drivers/pcmuio.c
drivers/staging/comedi/drivers/serial2002.c
drivers/staging/comedi/drivers/unioxx5.c
drivers/staging/comedi/kcomedilib/kcomedilib_main.c
drivers/staging/comedi/kcomedilib/ksyms.c
drivers/staging/crystalhd/crystalhd_hw.c
drivers/staging/crystalhd/crystalhd_lnx.c
drivers/staging/crystalhd/crystalhd_misc.c
drivers/staging/cx25821/cx25821-alsa.c
drivers/staging/cx25821/cx25821-audio-upstream.c
drivers/staging/cx25821/cx25821-audups11.c
drivers/staging/cx25821/cx25821-core.c
drivers/staging/cx25821/cx25821-video-upstream-ch2.c
drivers/staging/cx25821/cx25821-video-upstream.c
drivers/staging/dream/camera/msm_camera.c
drivers/staging/dream/camera/msm_v4l2.c
drivers/staging/dream/camera/msm_vfe7x.c
drivers/staging/dream/camera/msm_vfe8x.c
drivers/staging/dream/camera/mt9d112.c
drivers/staging/dream/camera/mt9p012_fox.c
drivers/staging/dream/camera/mt9t013.c
drivers/staging/dream/camera/s5k3e2fx.c
drivers/staging/dream/gpio_axis.c
drivers/staging/dream/gpio_event.c
drivers/staging/dream/gpio_input.c
drivers/staging/dream/gpio_matrix.c
drivers/staging/dream/pmem.c
drivers/staging/dream/qdsp5/adsp.c
drivers/staging/dream/qdsp5/adsp_driver.c
drivers/staging/dream/qdsp5/audio_aac.c
drivers/staging/dream/qdsp5/audio_amrnb.c
drivers/staging/dream/qdsp5/audio_evrc.c
drivers/staging/dream/qdsp5/audio_in.c
drivers/staging/dream/qdsp5/audio_mp3.c
drivers/staging/dream/qdsp5/audio_out.c
drivers/staging/dream/qdsp5/audio_qcelp.c
drivers/staging/dream/qdsp5/audmgr.c
drivers/staging/dream/smd/smd_rpcrouter.c
drivers/staging/dream/smd/smd_rpcrouter_device.c
drivers/staging/dream/smd/smd_rpcrouter_servers.c
drivers/staging/dream/synaptics_i2c_rmi.c
drivers/staging/dt3155/allocator.c
drivers/staging/dt3155/dt3155_drv.c
drivers/staging/dt3155/dt3155_isr.c
drivers/staging/et131x/et1310_eeprom.c
drivers/staging/et131x/et1310_mac.c
drivers/staging/et131x/et1310_phy.c
drivers/staging/et131x/et1310_pm.c
drivers/staging/et131x/et131x_initpci.c
drivers/staging/et131x/et131x_isr.c
drivers/staging/et131x/et131x_netdev.c
drivers/staging/go7007/go7007-driver.c
drivers/staging/go7007/go7007-fw.c
drivers/staging/go7007/go7007-v4l2.c
drivers/staging/go7007/s2250-board.c
drivers/staging/go7007/s2250-loader.c
drivers/staging/go7007/snd-go7007.c
drivers/staging/go7007/wis-saa7113.c
drivers/staging/go7007/wis-saa7115.c
drivers/staging/go7007/wis-sony-tuner.c
drivers/staging/go7007/wis-tw2804.c
drivers/staging/go7007/wis-tw9903.c
drivers/staging/hv/Channel.c
drivers/staging/hv/ChannelMgmt.c
drivers/staging/hv/Connection.c
drivers/staging/hv/Hv.c
drivers/staging/hv/NetVsc.c
drivers/staging/hv/RndisFilter.c
drivers/staging/hv/StorVsc.c
drivers/staging/hv/Vmbus.c
drivers/staging/hv/blkvsc_drv.c
drivers/staging/hv/netvsc_drv.c
drivers/staging/hv/osd.c
drivers/staging/hv/storvsc_drv.c
drivers/staging/hv/vmbus_drv.c
drivers/staging/iio/accel/kxsd9.c
drivers/staging/iio/accel/lis3l02dq_core.c
drivers/staging/iio/accel/lis3l02dq_ring.c
drivers/staging/iio/accel/sca3000_core.c
drivers/staging/iio/accel/sca3000_ring.c
drivers/staging/iio/adc/max1363_core.c
drivers/staging/iio/adc/max1363_ring.c
drivers/staging/iio/industrialio-core.c
drivers/staging/iio/industrialio-ring.c
drivers/staging/iio/industrialio-trigger.c
drivers/staging/iio/light/tsl2563.c
drivers/staging/iio/ring_sw.c
drivers/staging/iio/trigger/iio-trig-gpio.c
drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
drivers/staging/line6/capture.c
drivers/staging/line6/driver.c
drivers/staging/line6/dumprequest.c
drivers/staging/line6/midi.c
drivers/staging/line6/pcm.c
drivers/staging/line6/playback.c
drivers/staging/line6/pod.c
drivers/staging/line6/variax.c
drivers/staging/netwave/netwave_cs.c
drivers/staging/octeon/cvmx-helper-board.c
drivers/staging/octeon/ethernet-mem.c
drivers/staging/octeon/ethernet.c
drivers/staging/otus/ioctl.c
drivers/staging/otus/usbdrv.c
drivers/staging/otus/usbdrv.h
drivers/staging/otus/wrap_mem.c
drivers/staging/otus/wrap_pkt.c
drivers/staging/otus/wrap_usb.c
drivers/staging/otus/wwrap.c
drivers/staging/otus/zdusb.c
drivers/staging/poch/poch.c
drivers/staging/pohmelfs/config.c
drivers/staging/pohmelfs/dir.c
drivers/staging/pohmelfs/lock.c
drivers/staging/pohmelfs/net.c
drivers/staging/pohmelfs/path_entry.c
drivers/staging/ramzswap/ramzswap_drv.c
drivers/staging/rt2860/pci_main_dev.c
drivers/staging/rt2860/rt_linux.c
drivers/staging/rt2860/usb_main_dev.c
drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
drivers/staging/rtl8187se/r8180_core.c
drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c
drivers/staging/rtl8192e/r8192E_core.c
drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c
drivers/staging/rtl8192su/r8192U_core.c
drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
drivers/staging/rtl8192u/r8192U_core.c
drivers/staging/samsung-laptop/samsung-laptop.c
drivers/staging/sep/sep_driver.c
drivers/staging/sm7xx/smtcfb.c
drivers/staging/strip/strip.c
drivers/staging/udlfb/udlfb.c
drivers/staging/usbip/stub_dev.c
drivers/staging/usbip/stub_main.c
drivers/staging/usbip/stub_rx.c
drivers/staging/usbip/stub_tx.c
drivers/staging/usbip/usbip_common.c
drivers/staging/usbip/usbip_event.c
drivers/staging/usbip/vhci_hcd.c
drivers/staging/usbip/vhci_rx.c
drivers/staging/usbip/vhci_tx.c
drivers/staging/vme/bridges/vme_ca91cx42.c
drivers/staging/vme/bridges/vme_tsi148.c
drivers/staging/vme/devices/vme_user.c
drivers/staging/vme/vme.c
drivers/staging/vt6655/device_main.c
drivers/staging/winbond/wb35reg.c
drivers/staging/winbond/wb35rx.c
drivers/staging/winbond/wb35tx.c
drivers/staging/wlags49_h2/wl_cs.c
drivers/staging/wlags49_h2/wl_netdev.c
drivers/staging/wlags49_h2/wl_pci.c
drivers/staging/wlags49_h2/wl_priv.c
drivers/staging/wlan-ng/p80211req.c
drivers/staging/wlan-ng/p80211wep.c
drivers/staging/wlan-ng/p80211wext.c
drivers/staging/wlan-ng/prism2fw.c
drivers/staging/wlan-ng/prism2mgmt.c
drivers/staging/wlan-ng/prism2mib.c
drivers/tc/tc.c
drivers/thermal/thermal_sys.c
drivers/uio/uio.c
drivers/uio/uio_aec.c
drivers/uio/uio_cif.c
drivers/uio/uio_netx.c
drivers/uio/uio_pci_generic.c
drivers/uio/uio_pdrv.c
drivers/uio/uio_pdrv_genirq.c
drivers/uio/uio_sercos3.c
drivers/usb/atm/speedtch.c
drivers/usb/atm/ueagle-atm.c
drivers/usb/c67x00/c67x00-drv.c
drivers/usb/c67x00/c67x00-sched.c
drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-wdm.c
drivers/usb/class/usbtmc.c
drivers/usb/core/Kconfig
drivers/usb/core/devices.c
drivers/usb/core/devio.c
drivers/usb/core/driver.c
drivers/usb/core/endpoint.c
drivers/usb/core/file.c
drivers/usb/core/generic.c
drivers/usb/core/inode.c
drivers/usb/core/urb.c
drivers/usb/core/usb.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/atmel_usba_udc.c
drivers/usb/gadget/ci13xxx_udc.c
drivers/usb/gadget/config.c
drivers/usb/gadget/epautoconf.c
drivers/usb/gadget/f_acm.c
drivers/usb/gadget/f_audio.c
drivers/usb/gadget/f_ecm.c
drivers/usb/gadget/f_eem.c
drivers/usb/gadget/f_loopback.c
drivers/usb/gadget/f_mass_storage.c
drivers/usb/gadget/f_obex.c
drivers/usb/gadget/f_phonet.c
drivers/usb/gadget/f_rndis.c
drivers/usb/gadget/f_serial.c
drivers/usb/gadget/f_sourcesink.c
drivers/usb/gadget/f_subset.c
drivers/usb/gadget/gadget_chips.h
drivers/usb/gadget/gmidi.c
drivers/usb/gadget/goku_udc.c
drivers/usb/gadget/imx_udc.c
drivers/usb/gadget/lh7a40x_udc.c
drivers/usb/gadget/m66592-udc.c
drivers/usb/gadget/multi.c
drivers/usb/gadget/pxa27x_udc.c
drivers/usb/gadget/r8a66597-udc.c
drivers/usb/gadget/rndis.c
drivers/usb/gadget/s3c-hsotg.c
drivers/usb/gadget/u_audio.c
drivers/usb/gadget/u_ether.c
drivers/usb/gadget/u_serial.c
drivers/usb/gadget/zero.c
drivers/usb/host/Makefile
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-mem.c
drivers/usb/host/ehci-mxc.c
drivers/usb/host/ehci-omap.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci.h
drivers/usb/host/fhci-hcd.c
drivers/usb/host/fhci-mem.c
drivers/usb/host/fhci-q.c
drivers/usb/host/fhci-tds.c
drivers/usb/host/hwa-hc.c
drivers/usb/host/imx21-hcd.c
drivers/usb/host/isp116x-hcd.c
drivers/usb/host/ohci-at91.c
drivers/usb/host/ohci-da8xx.c
drivers/usb/host/ohci-hub.c
drivers/usb/host/ohci-q.c
drivers/usb/host/oxu210hp-hcd.c
drivers/usb/host/r8a66597-hcd.c
drivers/usb/host/sl811-hcd.c
drivers/usb/host/uhci-debug.c
drivers/usb/host/whci/asl.c
drivers/usb/host/whci/debug.c
drivers/usb/host/whci/init.c
drivers/usb/host/whci/pzl.c
drivers/usb/host/whci/qset.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c [moved from drivers/usb/host/xhci-hcd.c with 99% similarity]
drivers/usb/host/xhci.h
drivers/usb/misc/appledisplay.c
drivers/usb/misc/cypress_cy7c63.c
drivers/usb/misc/cytherm.c
drivers/usb/misc/isight_firmware.c
drivers/usb/misc/sisusbvga/sisusb_con.c
drivers/usb/misc/sisusbvga/sisusb_init.c
drivers/usb/misc/trancevibrator.c
drivers/usb/misc/usbsevseg.c
drivers/usb/misc/uss720.c
drivers/usb/mon/mon_bin.c
drivers/usb/mon/mon_main.c
drivers/usb/mon/mon_stat.c
drivers/usb/mon/mon_text.c
drivers/usb/musb/Kconfig
drivers/usb/musb/Makefile
drivers/usb/musb/blackfin.c
drivers/usb/musb/cppi_dma.c
drivers/usb/musb/davinci.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_gadget.c
drivers/usb/musb/musb_host.c
drivers/usb/musb/musb_regs.h
drivers/usb/musb/musb_virthub.c
drivers/usb/musb/musbhsdma.c
drivers/usb/musb/omap2430.c
drivers/usb/musb/tusb6010.c
drivers/usb/musb/tusb6010_omap.c
drivers/usb/otg/gpio_vbus.c
drivers/usb/otg/nop-usb-xceiv.c
drivers/usb/otg/twl4030-usb.c
drivers/usb/otg/ulpi.c
drivers/usb/serial/Kconfig
drivers/usb/serial/aircable.c
drivers/usb/serial/ark3116.c
drivers/usb/serial/bus.c
drivers/usb/serial/ch341.c
drivers/usb/serial/console.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/generic.c
drivers/usb/serial/navman.c
drivers/usb/serial/opticon.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.h
drivers/usb/serial/qcaux.c
drivers/usb/serial/qcserial.c
drivers/usb/serial/safe_serial.c
drivers/usb/serial/sierra.c
drivers/usb/serial/symbolserial.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/ti_usb_3410_5052.h
drivers/usb/serial/usb_debug.c
drivers/usb/storage/alauda.c
drivers/usb/storage/karma.c
drivers/usb/storage/option_ms.c
drivers/usb/storage/scsiglue.c
drivers/usb/storage/sierra_ms.c
drivers/usb/storage/transport.c
drivers/usb/storage/unusual_devs.h
drivers/usb/wusbcore/cbaf.c
drivers/usb/wusbcore/crypto.c
drivers/usb/wusbcore/devconnect.c
drivers/usb/wusbcore/mmc.c
drivers/usb/wusbcore/rh.c
drivers/usb/wusbcore/security.c
drivers/usb/wusbcore/wa-hc.c
drivers/usb/wusbcore/wa-nep.c
drivers/usb/wusbcore/wa-rpipe.c
drivers/usb/wusbcore/wa-xfer.c
drivers/uwb/address.c
drivers/uwb/allocator.c
drivers/uwb/beacon.c
drivers/uwb/drp-ie.c
drivers/uwb/drp.c
drivers/uwb/est.c
drivers/uwb/hwa-rc.c
drivers/uwb/i1480/dfu/mac.c
drivers/uwb/i1480/dfu/usb.c
drivers/uwb/i1480/i1480u-wlp/lc.c
drivers/uwb/i1480/i1480u-wlp/netdev.c
drivers/uwb/i1480/i1480u-wlp/rx.c
drivers/uwb/i1480/i1480u-wlp/tx.c
drivers/uwb/ie.c
drivers/uwb/lc-dev.c
drivers/uwb/lc-rc.c
drivers/uwb/neh.c
drivers/uwb/reset.c
drivers/uwb/rsv.c
drivers/uwb/scan.c
drivers/uwb/umc-dev.c
drivers/uwb/uwbd.c
drivers/uwb/whc-rc.c
drivers/uwb/whci.c
drivers/uwb/wlp/eda.c
drivers/uwb/wlp/messages.c
drivers/uwb/wlp/txrx.c
drivers/uwb/wlp/wlp-lc.c
drivers/uwb/wlp/wss-lc.c
drivers/vhost/net.c
drivers/vhost/vhost.c
drivers/video/68328fb.c
drivers/video/Kconfig
drivers/video/acornfb.c
drivers/video/amba-clcd.c
drivers/video/amifb.c
drivers/video/arcfb.c
drivers/video/asiliantfb.c
drivers/video/atafb.c
drivers/video/atmel_lcdfb.c
drivers/video/aty/aty128fb.c
drivers/video/aty/atyfb_base.c
drivers/video/aty/mach64_cursor.c
drivers/video/aty/radeon_backlight.c
drivers/video/aty/radeon_monitor.c
drivers/video/au1100fb.c
drivers/video/au1200fb.c
drivers/video/backlight/88pm860x_bl.c
drivers/video/backlight/Kconfig
drivers/video/backlight/Makefile
drivers/video/backlight/adp5520_bl.c
drivers/video/backlight/adx_bl.c
drivers/video/backlight/atmel-pwm-bl.c
drivers/video/backlight/backlight.c
drivers/video/backlight/corgi_lcd.c
drivers/video/backlight/cr_bllcd.c
drivers/video/backlight/da903x_bl.c
drivers/video/backlight/generic_bl.c
drivers/video/backlight/hp680_bl.c
drivers/video/backlight/ili9320.c
drivers/video/backlight/jornada720_bl.c
drivers/video/backlight/kb3886_bl.c
drivers/video/backlight/l4f00242t03.c [new file with mode: 0644]
drivers/video/backlight/lcd.c
drivers/video/backlight/lms283gf05.c
drivers/video/backlight/locomolcd.c
drivers/video/backlight/ltv350qv.c
drivers/video/backlight/max8925_bl.c
drivers/video/backlight/mbp_nvidia_bl.c
drivers/video/backlight/omap1_bl.c
drivers/video/backlight/platform_lcd.c
drivers/video/backlight/progear_bl.c
drivers/video/backlight/pwm_bl.c
drivers/video/backlight/tdo24m.c
drivers/video/backlight/tosa_bl.c
drivers/video/backlight/tosa_lcd.c
drivers/video/backlight/wm831x_bl.c
drivers/video/bf54x-lq043fb.c
drivers/video/bfin-lq035q1-fb.c
drivers/video/bfin-t350mcqb-fb.c
drivers/video/bw2.c
drivers/video/carminefb.c
drivers/video/cfbcopyarea.c
drivers/video/cg14.c
drivers/video/cg3.c
drivers/video/cg6.c
drivers/video/chipsfb.c
drivers/video/cirrusfb.c
drivers/video/console/bitblit.c
drivers/video/console/fbcon_ccw.c
drivers/video/console/fbcon_cw.c
drivers/video/console/fbcon_rotate.c
drivers/video/console/fbcon_ud.c
drivers/video/console/mdacon.c
drivers/video/da8xx-fb.c
drivers/video/display/display-sysfs.c
drivers/video/dnfb.c
drivers/video/efifb.c
drivers/video/ep93xx-fb.c
drivers/video/epson1355fb.c
drivers/video/fb_ddc.c
drivers/video/fb_defio.c
drivers/video/fbcvt.c
drivers/video/fbmon.c
drivers/video/fbsysfs.c
drivers/video/ffb.c
drivers/video/fm2fb.c
drivers/video/fsl-diu-fb.c
drivers/video/g364fb.c
drivers/video/gbefb.c
drivers/video/geode/gx1fb_core.c
drivers/video/geode/gxfb_core.c
drivers/video/geode/lxfb.h
drivers/video/geode/lxfb_core.c
drivers/video/geode/lxfb_ops.c
drivers/video/hecubafb.c
drivers/video/hgafb.c
drivers/video/hitfb.c
drivers/video/hpfb.c
drivers/video/i810/i810-i2c.c
drivers/video/imsttfb.c
drivers/video/intelfb/intelfbhw.c
drivers/video/leo.c
drivers/video/matrox/i2c-matroxfb.c
drivers/video/matrox/matroxfb_base.c
drivers/video/matrox/matroxfb_crtc2.c
drivers/video/matrox/matroxfb_maven.c
drivers/video/maxinefb.c
drivers/video/mb862xx/mb862xxfb_accel.c
drivers/video/mbx/mbxdebugfs.c
drivers/video/metronomefb.c
drivers/video/modedb.c
drivers/video/msm/mddi.c
drivers/video/msm/mddi_client_dummy.c
drivers/video/msm/mddi_client_nt35399.c
drivers/video/msm/mddi_client_toshiba.c
drivers/video/msm/mdp.c
drivers/video/msm/msm_fb.c
drivers/video/nvidia/nv_backlight.c
drivers/video/nvidia/nv_i2c.c
drivers/video/nvidia/nv_of.c
drivers/video/nvidia/nv_setup.c
drivers/video/offb.c
drivers/video/omap/dispc.c
drivers/video/omap/lcd_mipid.c
drivers/video/omap/lcdc.c
drivers/video/omap/omapfb_main.c
drivers/video/omap2/displays/panel-generic.c
drivers/video/omap2/displays/panel-taal.c
drivers/video/omap2/displays/panel-tpo-td043mtea1.c
drivers/video/omap2/dss/dss.c
drivers/video/omap2/dss/manager.c
drivers/video/omap2/dss/overlay.c
drivers/video/omap2/omapfb/omapfb-main.c
drivers/video/omap2/vram.c
drivers/video/output.c
drivers/video/p9100.c
drivers/video/platinumfb.c
drivers/video/pmag-aa-fb.c
drivers/video/pnx4008/pnxrgbfb.c
drivers/video/pnx4008/sdum.c
drivers/video/pxa168fb.c
drivers/video/q40fb.c
drivers/video/riva/fbdev.c
drivers/video/s1d13xxxfb.c
drivers/video/s3c-fb.c
drivers/video/s3fb.c
drivers/video/savage/savagefb-i2c.c
drivers/video/sh7760fb.c
drivers/video/sh_mobile_lcdcfb.c
drivers/video/sstfb.c
drivers/video/sunxvr1000.c
drivers/video/sunxvr2500.c
drivers/video/sunxvr500.c
drivers/video/svgalib.c
drivers/video/syscopyarea.c
drivers/video/tcx.c
drivers/video/tgafb.c
drivers/video/tridentfb.c
drivers/video/uvesafb.c
drivers/video/vermilion/vermilion.c
drivers/video/vesafb.c
drivers/video/vfb.c
drivers/video/vga16fb.c
drivers/video/via/viafbdev.c
drivers/video/vt8623fb.c
drivers/video/w100fb.c
drivers/video/xen-fbfront.c
drivers/video/xilinxfb.c
drivers/virtio/virtio_balloon.c
drivers/virtio/virtio_pci.c
drivers/virtio/virtio_ring.c
drivers/vlynq/vlynq.c
drivers/w1/masters/ds1wm.c
drivers/w1/masters/ds2490.c
drivers/w1/masters/mxc_w1.c
drivers/w1/masters/omap_hdq.c
drivers/w1/masters/w1-gpio.c
drivers/w1/slaves/w1_ds2433.c
drivers/w1/slaves/w1_ds2760.c
drivers/w1/slaves/w1_therm.c
drivers/w1/w1_int.c
drivers/w1/w1_netlink.c
drivers/watchdog/Kconfig
drivers/watchdog/adx_wdt.c
drivers/watchdog/at32ap700x_wdt.c
drivers/watchdog/booke_wdt.c
drivers/watchdog/cpwd.c
drivers/watchdog/davinci_wdt.c
drivers/watchdog/ep93xx_wdt.c
drivers/watchdog/hpwdt.c
drivers/watchdog/iTCO_wdt.c
drivers/watchdog/ibmasr.c
drivers/watchdog/max63xx_wdt.c
drivers/watchdog/mpcore_wdt.c
drivers/watchdog/nuc900_wdt.c
drivers/watchdog/omap_wdt.c
drivers/watchdog/pika_wdt.c
drivers/watchdog/pnx4008_wdt.c
drivers/watchdog/riowd.c
drivers/watchdog/s3c2410_wdt.c
drivers/watchdog/sb_wdog.c
drivers/watchdog/sbc_fitpc2_wdt.c
drivers/watchdog/ts72xx_wdt.c
drivers/watchdog/twl4030_wdt.c
drivers/xen/balloon.c
drivers/xen/events.c
drivers/xen/evtchn.c
drivers/xen/grant-table.c
drivers/xen/manage.c
drivers/xen/sys-hypervisor.c
drivers/xen/xenbus/xenbus_client.c
drivers/xen/xenbus/xenbus_probe.c
drivers/xen/xencomm.c
drivers/xen/xenfs/xenbus.c
drivers/zorro/proc.c
drivers/zorro/zorro-driver.c
drivers/zorro/zorro-sysfs.c
drivers/zorro/zorro.c
fs/9p/cache.c
fs/9p/fid.c
fs/9p/v9fs.c
fs/9p/v9fs.h
fs/9p/vfs_dentry.c
fs/9p/vfs_dir.c
fs/9p/vfs_inode.c
fs/9p/vfs_super.c
fs/Kconfig
fs/Makefile
fs/adfs/super.c
fs/affs/bitmap.c
fs/affs/inode.c
fs/affs/super.c
fs/afs/cache.c
fs/afs/cmservice.c
fs/afs/dir.c
fs/afs/file.c
fs/afs/fsclient.c
fs/afs/inode.c
fs/afs/internal.h
fs/afs/mntpt.c
fs/afs/rxrpc.c
fs/afs/security.c
fs/afs/super.c
fs/afs/vlclient.c
fs/afs/vlocation.c
fs/afs/vnode.c
fs/afs/volume.c
fs/anon_inodes.c
fs/autofs/root.c
fs/autofs4/dev-ioctl.c
fs/autofs4/root.c
fs/befs/datastream.c
fs/binfmt_aout.c
fs/binfmt_elf_fdpic.c
fs/binfmt_em86.c
fs/binfmt_flat.c
fs/binfmt_script.c
fs/bio-integrity.c
fs/bio.c
fs/block_dev.c
fs/btrfs/acl.c
fs/btrfs/async-thread.c
fs/btrfs/btrfs_inode.h
fs/btrfs/compression.c
fs/btrfs/ctree.c
fs/btrfs/ctree.h
fs/btrfs/delayed-ref.c
fs/btrfs/disk-io.c
fs/btrfs/export.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h
fs/btrfs/extent_map.c
fs/btrfs/file-item.c
fs/btrfs/file.c
fs/btrfs/free-space-cache.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/ioctl.h
fs/btrfs/locking.c
fs/btrfs/ordered-data.c
fs/btrfs/ordered-data.h
fs/btrfs/ref-cache.c
fs/btrfs/relocation.c
fs/btrfs/super.c
fs/btrfs/transaction.c
fs/btrfs/tree-log.c
fs/btrfs/volumes.c
fs/cachefiles/interface.c
fs/cachefiles/internal.h
fs/cachefiles/namei.c
fs/cachefiles/rdwr.c
fs/cachefiles/security.c
fs/cachefiles/xattr.c
fs/ceph/Kconfig [new file with mode: 0644]
fs/ceph/Makefile [new file with mode: 0644]
fs/ceph/README [new file with mode: 0644]
fs/ceph/addr.c [new file with mode: 0644]
fs/ceph/armor.c [new file with mode: 0644]
fs/ceph/auth.c [new file with mode: 0644]
fs/ceph/auth.h [new file with mode: 0644]
fs/ceph/auth_none.c [new file with mode: 0644]
fs/ceph/auth_none.h [new file with mode: 0644]
fs/ceph/auth_x.c [new file with mode: 0644]
fs/ceph/auth_x.h [new file with mode: 0644]
fs/ceph/auth_x_protocol.h [new file with mode: 0644]
fs/ceph/buffer.c [new file with mode: 0644]
fs/ceph/buffer.h [new file with mode: 0644]
fs/ceph/caps.c [new file with mode: 0644]
fs/ceph/ceph_debug.h [new file with mode: 0644]
fs/ceph/ceph_frag.c [new file with mode: 0644]
fs/ceph/ceph_frag.h [new file with mode: 0644]
fs/ceph/ceph_fs.c [new file with mode: 0644]
fs/ceph/ceph_fs.h [new file with mode: 0644]
fs/ceph/ceph_hash.c [new file with mode: 0644]
fs/ceph/ceph_hash.h [new file with mode: 0644]
fs/ceph/ceph_strings.c [new file with mode: 0644]
fs/ceph/crush/crush.c [new file with mode: 0644]
fs/ceph/crush/crush.h [new file with mode: 0644]
fs/ceph/crush/hash.c [new file with mode: 0644]
fs/ceph/crush/hash.h [new file with mode: 0644]
fs/ceph/crush/mapper.c [new file with mode: 0644]
fs/ceph/crush/mapper.h [new file with mode: 0644]
fs/ceph/crypto.c [new file with mode: 0644]
fs/ceph/crypto.h [new file with mode: 0644]
fs/ceph/debugfs.c [new file with mode: 0644]
fs/ceph/decode.h [new file with mode: 0644]
fs/ceph/dir.c [new file with mode: 0644]
fs/ceph/export.c [new file with mode: 0644]
fs/ceph/file.c [new file with mode: 0644]
fs/ceph/inode.c [new file with mode: 0644]
fs/ceph/ioctl.c [new file with mode: 0644]
fs/ceph/ioctl.h [new file with mode: 0644]
fs/ceph/mds_client.c [new file with mode: 0644]
fs/ceph/mds_client.h [new file with mode: 0644]
fs/ceph/mdsmap.c [new file with mode: 0644]
fs/ceph/mdsmap.h [new file with mode: 0644]
fs/ceph/messenger.c [new file with mode: 0644]
fs/ceph/messenger.h [new file with mode: 0644]
fs/ceph/mon_client.c [new file with mode: 0644]
fs/ceph/mon_client.h [new file with mode: 0644]
fs/ceph/msgpool.c [new file with mode: 0644]
fs/ceph/msgpool.h [new file with mode: 0644]
fs/ceph/msgr.h [new file with mode: 0644]
fs/ceph/osd_client.c [new file with mode: 0644]
fs/ceph/osd_client.h [new file with mode: 0644]
fs/ceph/osdmap.c [new file with mode: 0644]
fs/ceph/osdmap.h [new file with mode: 0644]
fs/ceph/pagelist.c [new file with mode: 0644]
fs/ceph/pagelist.h [new file with mode: 0644]
fs/ceph/rados.h [new file with mode: 0644]
fs/ceph/snap.c [new file with mode: 0644]
fs/ceph/super.c [new file with mode: 0644]
fs/ceph/super.h [new file with mode: 0644]
fs/ceph/types.h [new file with mode: 0644]
fs/ceph/xattr.c [new file with mode: 0644]
fs/cifs/asn1.c
fs/cifs/cifs_debug.c
fs/cifs/cifs_debug.h
fs/cifs/cifs_dfs_ref.c
fs/cifs/cifs_fs_sb.h
fs/cifs/cifs_spnego.c
fs/cifs/cifs_unicode.c
fs/cifs/cifsacl.c
fs/cifs/cifsencrypt.c
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/dir.c
fs/cifs/dns_resolve.c
fs/cifs/export.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/ioctl.c
fs/cifs/link.c
fs/cifs/misc.c
fs/cifs/netmisc.c
fs/cifs/readdir.c
fs/cifs/sess.c
fs/cifs/smbencrypt.c
fs/cifs/transport.c
fs/cifs/xattr.c
fs/coda/dir.c
fs/coda/file.c
fs/coda/inode.c
fs/coda/upcall.c
fs/compat.c
fs/compat_ioctl.c
fs/configfs/dir.c
fs/configfs/inode.c
fs/configfs/mount.c
fs/configfs/symlink.c
fs/debugfs/inode.c
fs/devpts/inode.c
fs/dlm/config.c
fs/dlm/debug_fs.c
fs/dlm/lock.c
fs/dlm/lowcomms.c
fs/dlm/netlink.c
fs/dlm/plock.c
fs/dlm/user.c
fs/ecryptfs/crypto.c
fs/ecryptfs/dentry.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/file.c
fs/ecryptfs/inode.c
fs/ecryptfs/keystore.c
fs/ecryptfs/kthread.c
fs/ecryptfs/main.c
fs/ecryptfs/messaging.c
fs/ecryptfs/miscdev.c
fs/ecryptfs/mmap.c
fs/ecryptfs/super.c
fs/eventfd.c
fs/eventpoll.c
fs/exec.c
fs/exofs/exofs.h
fs/exofs/inode.c
fs/exofs/ios.c
fs/exofs/super.c
fs/ext2/balloc.c
fs/ext2/symlink.c
fs/ext2/xattr_security.c
fs/ext3/balloc.c
fs/ext3/ialloc.c
fs/ext3/inode.c
fs/ext3/symlink.c
fs/ext3/xattr_security.c
fs/ext4/block_validity.c
fs/ext4/extents.c
fs/ext4/ialloc.c
fs/ext4/inode.c
fs/ext4/mballoc.c
fs/ext4/migrate.c
fs/ext4/move_extent.c
fs/ext4/super.c
fs/ext4/xattr_security.c
fs/fat/cache.c
fs/fat/namei_vfat.c
fs/fifo.c
fs/filesystems.c
fs/freevxfs/vxfs_subr.c
fs/fs-writeback.c
fs/fscache/object-list.c
fs/fscache/object.c
fs/fscache/operation.c
fs/fscache/page.c
fs/fscache/stats.c
fs/fuse/cuse.c
fs/generic_acl.c
fs/gfs2/bmap.c
fs/gfs2/dentry.c
fs/gfs2/export.c
fs/gfs2/glops.c
fs/gfs2/lock_dlm.c
fs/gfs2/rgrp.h
fs/gfs2/sys.c
fs/gfs2/util.c
fs/hfs/bnode.c
fs/hfs/btree.c
fs/hfs/mdb.c
fs/hfs/super.c
fs/hfsplus/options.c
fs/hostfs/hostfs_kern.c
fs/hpfs/buffer.c
fs/hpfs/dir.c
fs/hpfs/inode.c
fs/hpfs/super.c
fs/ioctl.c
fs/ioprio.c
fs/isofs/dir.c
fs/isofs/namei.c
fs/jbd/commit.c
fs/jbd/recovery.c
fs/jbd2/recovery.c
fs/jffs2/compr_lzo.c
fs/jffs2/compr_zlib.c
fs/jffs2/debug.c
fs/jffs2/file.c
fs/jffs2/nodelist.c
fs/jffs2/nodemgmt.c
fs/jffs2/readinode.c
fs/jffs2/symlink.c
fs/jffs2/write.c
fs/jfs/acl.c
fs/jfs/inode.c
fs/jfs/jfs_dmap.c
fs/jfs/jfs_dmap.h
fs/jfs/jfs_dtree.c
fs/jfs/jfs_imap.c
fs/jfs/jfs_inode.h
fs/jfs/jfs_logmgr.c
fs/jfs/jfs_metapage.c
fs/jfs/jfs_unicode.h
fs/jfs/namei.c
fs/jfs/resize.c
fs/jfs/super.c
fs/jfs/symlink.c
fs/jfs/xattr.c
fs/libfs.c
fs/lockd/clntlock.c
fs/lockd/clntproc.c
fs/lockd/mon.c
fs/lockd/svc.c
fs/lockd/svc4proc.c
fs/lockd/svclock.c
fs/lockd/svcproc.c
fs/lockd/svcsubs.c
fs/logfs/dev_bdev.c
fs/logfs/dev_mtd.c
fs/logfs/dir.c
fs/logfs/file.c
fs/logfs/gc.c
fs/logfs/inode.c
fs/logfs/journal.c
fs/logfs/logfs.h
fs/logfs/readwrite.c
fs/logfs/segment.c
fs/logfs/super.c
fs/minix/itree_v1.c
fs/mpage.c
fs/namei.c
fs/namespace.c
fs/ncpfs/dir.c
fs/ncpfs/file.c
fs/ncpfs/inode.c
fs/ncpfs/ioctl.c
fs/ncpfs/mmap.c
fs/ncpfs/sock.c
fs/ncpfs/symlink.c
fs/nfs/cache_lib.c
fs/nfs/callback_proc.c
fs/nfs/callback_xdr.c
fs/nfs/client.c
fs/nfs/delegation.c
fs/nfs/delegation.h
fs/nfs/dir.c
fs/nfs/direct.c
fs/nfs/dns_resolve.c
fs/nfs/file.c
fs/nfs/fscache.c
fs/nfs/inode.c
fs/nfs/namespace.c
fs/nfs/nfs2xdr.c
fs/nfs/nfs3acl.c
fs/nfs/nfs3proc.c
fs/nfs/nfs3xdr.c
fs/nfs/nfs4namespace.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
fs/nfs/pagelist.c
fs/nfs/proc.c
fs/nfs/super.c
fs/nfs/symlink.c
fs/nfs/write.c
fs/nfs_common/nfsacl.c
fs/nfsd/export.c
fs/nfsd/nfs2acl.c
fs/nfsd/nfs3acl.c
fs/nfsd/nfs4acl.c
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4idmap.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4recover.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfscache.c
fs/nfsd/nfsctl.c
fs/nfsd/vfs.c
fs/nilfs2/alloc.c
fs/nilfs2/btnode.c
fs/nilfs2/btree.c
fs/nilfs2/gcinode.c
fs/nilfs2/inode.c
fs/nilfs2/ioctl.c
fs/nilfs2/mdt.c
fs/nilfs2/page.c
fs/nilfs2/recovery.c
fs/nilfs2/segbuf.c
fs/nilfs2/segment.c
fs/nilfs2/super.c
fs/nilfs2/the_nilfs.h
fs/notify/fsnotify.c
fs/notify/inode_mark.c
fs/notify/inotify/Kconfig
fs/notify/inotify/inotify_fsnotify.c
fs/notify/inotify/inotify_user.c
fs/ntfs/aops.c
fs/ntfs/attrib.c
fs/ntfs/compress.c
fs/ntfs/dir.c
fs/ntfs/file.c
fs/ntfs/index.c
fs/ntfs/mft.c
fs/ntfs/namei.c
fs/ntfs/super.c
fs/ocfs2/acl.c
fs/ocfs2/buffer_head_io.c
fs/ocfs2/cluster/heartbeat.c
fs/ocfs2/cluster/nodemanager.c
fs/ocfs2/cluster/quorum.c
fs/ocfs2/dlm/dlmast.c
fs/ocfs2/dlm/dlmconvert.c
fs/ocfs2/dlm/dlmmaster.c
fs/ocfs2/dlm/dlmthread.c
fs/ocfs2/dlm/dlmunlock.c
fs/ocfs2/dlmfs/dlmfs.c
fs/ocfs2/extent_map.c
fs/ocfs2/file.c
fs/ocfs2/heartbeat.c
fs/ocfs2/inode.c
fs/ocfs2/inode.h
fs/ocfs2/localalloc.c
fs/ocfs2/locks.c
fs/ocfs2/mmap.c
fs/ocfs2/namei.c
fs/ocfs2/ocfs2.h
fs/ocfs2/quota_global.c
fs/ocfs2/quota_local.c
fs/ocfs2/refcounttree.c
fs/ocfs2/stack_o2cb.c
fs/ocfs2/stack_user.c
fs/ocfs2/suballoc.c
fs/ocfs2/suballoc.h
fs/ocfs2/sysfile.c
fs/ocfs2/xattr.c
fs/omfs/inode.c
fs/open.c
fs/partitions/check.c
fs/partitions/efi.c
fs/partitions/msdos.c
fs/proc/array.c
fs/proc/base.c
fs/proc/generic.c
fs/proc/inode.c
fs/proc/kcore.c
fs/proc/nommu.c
fs/proc/proc_devtree.c
fs/proc/proc_net.c
fs/proc/stat.c
fs/proc/task_mmu.c
fs/proc/task_nommu.c
fs/proc/vmcore.c
fs/quota/Kconfig
fs/quota/dquot.c
fs/quota/netlink.c
fs/ramfs/file-nommu.c
fs/ramfs/inode.c
fs/read_write.c
fs/reiserfs/dir.c
fs/reiserfs/fix_node.c
fs/reiserfs/inode.c
fs/reiserfs/journal.c
fs/reiserfs/namei.c
fs/reiserfs/super.c
fs/reiserfs/xattr.c
fs/reiserfs/xattr_acl.c
fs/reiserfs/xattr_security.c
fs/signalfd.c
fs/smbfs/file.c
fs/smbfs/inode.c
fs/smbfs/smbiod.c
fs/smbfs/symlink.c
fs/splice.c
fs/squashfs/block.c
fs/squashfs/super.c
fs/squashfs/symlink.c
fs/squashfs/zlib_wrapper.c
fs/super.c
fs/sync.c
fs/sysfs/inode.c
fs/sysfs/mount.c
fs/sysfs/symlink.c
fs/sysv/dir.c
fs/timerfd.c
fs/ubifs/commit.c
fs/ubifs/debug.c
fs/ubifs/file.c
fs/ubifs/gc.c
fs/ubifs/io.c
fs/ubifs/lpt.c
fs/ubifs/lpt_commit.c
fs/ubifs/recovery.c
fs/ubifs/sb.c
fs/ubifs/tnc.c
fs/ubifs/ubifs.h
fs/ubifs/xattr.c
fs/udf/balloc.c
fs/udf/file.c
fs/udf/inode.c
fs/udf/namei.c
fs/udf/partition.c
fs/udf/symlink.c
fs/udf/udfdecl.h
fs/udf/unicode.c
fs/xattr_acl.c
fs/xfs/linux-2.6/kmem.c
fs/xfs/linux-2.6/xfs_acl.c
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_buf.c
fs/xfs/linux-2.6/xfs_ioctl.c
fs/xfs/linux-2.6/xfs_ioctl32.c
fs/xfs/linux-2.6/xfs_iops.c
fs/xfs/linux-2.6/xfs_super.c
fs/xfs/linux-2.6/xfs_sync.c
fs/xfs/linux-2.6/xfs_sync.h
fs/xfs/quota/xfs_qm_syscalls.c
fs/xfs/xfs_ag.h
fs/xfs/xfs_dfrag.c
fs/xfs/xfs_log.c
fs/xfs/xfs_mount.h
include/acpi/acpi_drivers.h
include/asm-generic/atomic.h
include/asm-generic/bitops/arch_hweight.h [new file with mode: 0644]
include/asm-generic/bitops/const_hweight.h [new file with mode: 0644]
include/asm-generic/bitops/hweight.h
include/asm-generic/dma-mapping-common.h
include/drm/drmP.h
include/drm/drm_mem_util.h [new file with mode: 0644]
include/drm/drm_pciids.h
include/drm/ttm/ttm_bo_driver.h
include/linux/acpi.h
include/linux/amba/bus.h
include/linux/amba/clcd.h
include/linux/amba/pl061.h
include/linux/ata.h
include/linux/backing-dev.h
include/linux/backlight.h
include/linux/bitops.h
include/linux/blkdev.h
include/linux/cgroup.h
include/linux/circ_buf.h
include/linux/clockchips.h
include/linux/coda_psdev.h
include/linux/cpufreq.h
include/linux/cpuset.h
include/linux/dcache.h
include/linux/debugobjects.h
include/linux/delayacct.h
include/linux/drbd.h
include/linux/drbd_nl.h
include/linux/ext3_fs.h
include/linux/ext3_fs_i.h
include/linux/firewire-cdev.h
include/linux/firewire-constants.h
include/linux/freezer.h
include/linux/fs.h
include/linux/fscache-cache.h
include/linux/fsnotify.h
include/linux/ftrace.h
include/linux/ftrace_event.h
include/linux/gameport.h
include/linux/genhd.h
include/linux/hw_breakpoint.h
include/linux/i2c.h
include/linux/i2o.h
include/linux/ide.h
include/linux/if_link.h
include/linux/if_tunnel.h
include/linux/init_task.h
include/linux/input/matrix_keypad.h
include/linux/io-mapping.h
include/linux/iommu.h
include/linux/ioport.h
include/linux/iscsi_ibft.h
include/linux/jbd.h
include/linux/jbd2.h
include/linux/kernel.h
include/linux/kfifo.h
include/linux/kvm_host.h
include/linux/lcm.h [new file with mode: 0644]
include/linux/libata.h
include/linux/memory.h
include/linux/mm.h
include/linux/mmc/mmc.h
include/linux/mod_devicetable.h
include/linux/module.h
include/linux/ncp_fs_sb.h
include/linux/netdevice.h
include/linux/netfilter/nfnetlink.h
include/linux/netfilter_ipv6.h
include/linux/netlink.h
include/linux/nfs_fs.h
include/linux/nfs_fs_sb.h
include/linux/of.h
include/linux/page_cgroup.h
include/linux/percpu.h
include/linux/perf_event.h
include/linux/platform_device.h
include/linux/poison.h
include/linux/ptrace.h
include/linux/radix-tree.h
include/linux/rbtree.h
include/linux/rcupdate.h
include/linux/rcutiny.h
include/linux/rcutree.h
include/linux/regulator/consumer.h
include/linux/reiserfs_xattr.h
include/linux/ring_buffer.h
include/linux/sched.h
include/linux/security.h
include/linux/serial_sci.h
include/linux/skbuff.h
include/linux/slab.h
include/linux/smb_fs_sb.h
include/linux/socket.h
include/linux/spi/l4f00242t03.h [new file with mode: 0644]
include/linux/spi/spi.h
include/linux/srcu.h
include/linux/stop_machine.h
include/linux/sunrpc/bc_xprt.h
include/linux/syscalls.h
include/linux/taskstats_kern.h
include/linux/tick.h
include/linux/tracepoint.h
include/linux/tty.h
include/linux/types.h
include/linux/usb.h
include/linux/usb/gadget.h
include/linux/virtio_console.h
include/linux/vt.h
include/linux/wait.h
include/linux/wimax/debug.h
include/linux/writeback.h
include/linux/zorro.h
include/media/saa7146_vv.h
include/net/9p/client.h
include/net/ax25.h
include/net/bluetooth/bluetooth.h
include/net/fib_rules.h
include/net/ipx.h
include/net/iucv/iucv.h
include/net/netfilter/nf_conntrack_extend.h
include/net/netlabel.h
include/net/netlink.h
include/net/netrom.h
include/net/sctp/command.h
include/net/sctp/sctp.h
include/net/sctp/sm.h
include/net/sctp/structs.h
include/net/sock.h
include/net/tcp.h
include/net/x25.h
include/net/xfrm.h
include/pcmcia/ds.h
include/pcmcia/ss.h
include/scsi/libiscsi.h
include/scsi/libsas.h
include/sound/ak4113.h
include/sound/soc-dai.h
include/sound/soc.h
include/trace/define_trace.h
include/trace/events/block.h
include/trace/events/lock.h
include/trace/events/module.h
include/trace/events/napi.h
include/trace/events/sched.h
include/trace/events/signal.h
include/trace/ftrace.h
include/trace/syscall.h
include/xen/xenbus.h
init/Kconfig
init/do_mounts.c
init/do_mounts_rd.c
init/initramfs.c
init/main.c
ipc/compat.c
ipc/mqueue.c
ipc/msg.c
ipc/syscall.c
kernel/Makefile
kernel/acct.c
kernel/async.c
kernel/audit.c
kernel/audit_tree.c
kernel/audit_watch.c
kernel/auditfilter.c
kernel/auditsc.c
kernel/capability.c
kernel/cgroup.c
kernel/cgroup_freezer.c
kernel/compat.c
kernel/cpu.c
kernel/cpuset.c
kernel/cred-internals.h [deleted file]
kernel/cred.c
kernel/early_res.c
kernel/exit.c
kernel/fork.c
kernel/hw_breakpoint.c
kernel/irq/chip.c
kernel/irq/manage.c
kernel/irq/numa_migrate.c
kernel/irq/proc.c
kernel/kallsyms.c
kernel/kexec.c
kernel/kgdb.c
kernel/kprobes.c
kernel/kthread.c
kernel/latencytop.c
kernel/lockdep.c
kernel/lockdep_internals.h
kernel/lockdep_proc.c
kernel/module.c
kernel/nsproxy.c
kernel/padata.c
kernel/perf_event.c
kernel/pid_namespace.c
kernel/posix-cpu-timers.c
kernel/power/hibernate.c
kernel/power/hibernate_nvs.c
kernel/power/process.c
kernel/power/snapshot.c
kernel/power/suspend.c
kernel/power/swap.c
kernel/power/user.c
kernel/profile.c
kernel/ptrace.c
kernel/rcupdate.c
kernel/rcutiny.c
kernel/rcutiny_plugin.h [new file with mode: 0644]
kernel/rcutorture.c
kernel/rcutree.c
kernel/rcutree.h
kernel/rcutree_plugin.h
kernel/rcutree_trace.c
kernel/res_counter.c
kernel/resource.c
kernel/sched.c
kernel/sched_cpupri.c
kernel/sched_debug.c
kernel/sched_fair.c
kernel/sched_features.h
kernel/sched_idletask.c
kernel/sched_rt.c
kernel/slow-work.c
kernel/slow-work.h
kernel/smp.c
kernel/softirq.c
kernel/softlockup.c
kernel/srcu.c
kernel/stop_machine.c
kernel/sys.c
kernel/sysctl_binary.c
kernel/taskstats.c
kernel/time.c
kernel/time/tick-oneshot.c
kernel/time/tick-sched.c
kernel/time/timecompare.c
kernel/time/timekeeping.c
kernel/time/timer_list.c
kernel/timer.c
kernel/trace/Kconfig
kernel/trace/Makefile
kernel/trace/blktrace.c
kernel/trace/ftrace.c
kernel/trace/power-traces.c
kernel/trace/ring_buffer.c
kernel/trace/ring_buffer_benchmark.c
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_clock.c
kernel/trace/trace_entries.h
kernel/trace/trace_event_perf.c [moved from kernel/trace/trace_event_profile.c with 63% similarity]
kernel/trace/trace_events.c
kernel/trace/trace_events_filter.c
kernel/trace/trace_functions_graph.c
kernel/trace/trace_hw_branches.c [deleted file]
kernel/trace/trace_irqsoff.c
kernel/trace/trace_kprobe.c
kernel/trace/trace_ksym.c
kernel/trace/trace_mmiotrace.c
kernel/trace/trace_output.c
kernel/trace/trace_sched_switch.c
kernel/trace/trace_sched_wakeup.c
kernel/trace/trace_selftest.c
kernel/trace/trace_stat.c
kernel/trace/trace_syscalls.c
kernel/trace/trace_workqueue.c
kernel/user.c
kernel/workqueue.c
lib/Kconfig.debug
lib/Makefile
lib/atomic64.c
lib/atomic64_test.c [new file with mode: 0644]
lib/btree.c
lib/cpumask.c
lib/crc32.c
lib/debugobjects.c
lib/decompress_unlzo.c
lib/devres.c
lib/dma-debug.c
lib/dynamic_debug.c
lib/flex_array.c
lib/genalloc.c
lib/hweight.c
lib/inflate.c
lib/kasprintf.c
lib/kobject_uevent.c
lib/kref.c
lib/lcm.c [new file with mode: 0644]
lib/radix-tree.c
lib/ratelimit.c
lib/rbtree.c
lib/rwsem-spinlock.c
lib/rwsem.c
lib/scatterlist.c
lib/swiotlb.c
lib/textsearch.c
lib/vsprintf.c
mm/Makefile
mm/backing-dev.c
mm/bootmem.c
mm/bounce.c
mm/failslab.c
mm/filemap.c
mm/filemap_xip.c
mm/hugetlb.c
mm/kmemleak.c
mm/ksm.c
mm/memcontrol.c
mm/memory-failure.c
mm/memory.c
mm/mempolicy.c
mm/migrate.c
mm/mincore.c
mm/mlock.c
mm/mmap.c
mm/mmu_context.c
mm/mmu_notifier.c
mm/mprotect.c
mm/mremap.c
mm/nommu.c
mm/oom_kill.c
mm/page_cgroup.c
mm/page_io.c
mm/pagewalk.c
mm/percpu.c
mm/percpu_up.c [new file with mode: 0644]
mm/quicklist.c
mm/readahead.c
mm/rmap.c
mm/slab.c
mm/slub.c
mm/sparse-vmemmap.c
mm/sparse.c
mm/swap.c
mm/swap_state.c
mm/truncate.c
mm/util.c
mm/vmscan.c
mm/vmstat.c
net/802/garp.c
net/802/p8022.c
net/802/p8023.c
net/802/psnap.c
net/802/stp.c
net/802/tr.c
net/8021q/vlan.c
net/8021q/vlan_core.c
net/8021q/vlan_dev.c
net/9p/client.c
net/9p/protocol.c
net/9p/trans_fd.c
net/9p/trans_rdma.c
net/9p/trans_virtio.c
net/9p/util.c
net/appletalk/aarp.c
net/appletalk/ddp.c
net/atm/addr.c
net/atm/atm_sysfs.c
net/atm/br2684.c
net/atm/clip.c
net/atm/common.c
net/atm/lec.c
net/atm/mpc.c
net/atm/mpoa_caches.c
net/atm/mpoa_proc.c
net/atm/pppoatm.c
net/atm/proc.c
net/atm/raw.c
net/atm/resources.c
net/atm/signaling.c
net/ax25/af_ax25.c
net/ax25/ax25_dev.c
net/ax25/ax25_ds_subr.c
net/ax25/ax25_iface.c
net/ax25/ax25_in.c
net/ax25/ax25_ip.c
net/ax25/ax25_out.c
net/ax25/ax25_route.c
net/ax25/ax25_subr.c
net/ax25/ax25_uid.c
net/ax25/sysctl_net_ax25.c
net/bluetooth/af_bluetooth.c
net/bluetooth/bnep/core.c
net/bluetooth/bnep/netdev.c
net/bluetooth/bnep/sock.c
net/bluetooth/cmtp/sock.c
net/bluetooth/hci_sysfs.c
net/bluetooth/hidp/sock.c
net/bluetooth/l2cap.c
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c
net/bridge/br_device.c
net/bridge/br_fdb.c
net/bridge/br_forward.c
net/bridge/br_if.c
net/bridge/br_input.c
net/bridge/br_ioctl.c
net/bridge/br_multicast.c
net/bridge/br_netfilter.c
net/bridge/br_netlink.c
net/bridge/br_private.h
net/bridge/br_stp_bpdu.c
net/bridge/netfilter/ebt_ulog.c
net/bridge/netfilter/ebtables.c
net/can/bcm.c
net/can/raw.c
net/compat.c
net/core/datagram.c
net/core/dev.c
net/core/drop_monitor.c
net/core/dst.c
net/core/ethtool.c
net/core/fib_rules.c
net/core/filter.c
net/core/gen_estimator.c
net/core/iovec.c
net/core/link_watch.c
net/core/neighbour.c
net/core/net-sysfs.c
net/core/net-traces.c
net/core/netpoll.c
net/core/rtnetlink.c
net/core/scm.c
net/core/sysctl_net_core.c
net/dcb/dcbnl.c
net/dccp/ccid.c
net/dccp/ccids/ccid2.c
net/dccp/feat.c
net/dccp/input.c
net/dccp/ipv4.c
net/dccp/ipv6.c
net/dccp/minisocks.c
net/dccp/output.c
net/dccp/probe.c
net/dccp/proto.c
net/decnet/dn_dev.c
net/decnet/dn_fib.c
net/decnet/dn_neigh.c
net/decnet/dn_nsp_in.c
net/decnet/dn_nsp_out.c
net/decnet/dn_route.c
net/decnet/dn_table.c
net/decnet/netfilter/dn_rtmsg.c
net/dsa/dsa.c
net/dsa/tag_dsa.c
net/dsa/tag_edsa.c
net/dsa/tag_trailer.c
net/econet/af_econet.c
net/ethernet/pe2.c
net/ieee802154/af_ieee802154.c
net/ieee802154/dgram.c
net/ieee802154/netlink.c
net/ieee802154/nl-mac.c
net/ieee802154/nl-phy.c
net/ieee802154/raw.c
net/ieee802154/wpan-class.c
net/ipv4/af_inet.c
net/ipv4/ah4.c
net/ipv4/arp.c
net/ipv4/cipso_ipv4.c
net/ipv4/devinet.c
net/ipv4/fib_frontend.c
net/ipv4/fib_hash.c
net/ipv4/fib_semantics.c
net/ipv4/fib_trie.c
net/ipv4/icmp.c
net/ipv4/igmp.c
net/ipv4/inet_diag.c
net/ipv4/inet_fragment.c
net/ipv4/inet_timewait_sock.c
net/ipv4/ip_forward.c
net/ipv4/ip_fragment.c
net/ipv4/ip_gre.c
net/ipv4/ip_input.c
net/ipv4/ip_options.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/ipconfig.c
net/ipv4/ipip.c
net/ipv4/ipmr.c
net/ipv4/netfilter.c
net/ipv4/netfilter/arptable_filter.c
net/ipv4/netfilter/ip_queue.c
net/ipv4/netfilter/ipt_CLUSTERIP.c
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/netfilter/ipt_ULOG.c
net/ipv4/netfilter/iptable_filter.c
net/ipv4/netfilter/iptable_mangle.c
net/ipv4/netfilter/iptable_raw.c
net/ipv4/netfilter/iptable_security.c
net/ipv4/netfilter/nf_nat_core.c
net/ipv4/netfilter/nf_nat_helper.c
net/ipv4/netfilter/nf_nat_rule.c
net/ipv4/netfilter/nf_nat_snmp_basic.c
net/ipv4/netfilter/nf_nat_standalone.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_cong.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_output.c
net/ipv4/tcp_probe.c
net/ipv4/tcp_timer.c
net/ipv4/tunnel4.c
net/ipv4/udp.c
net/ipv4/xfrm4_input.c
net/ipv4/xfrm4_mode_tunnel.c
net/ipv6/addrconf.c
net/ipv6/addrlabel.c
net/ipv6/af_inet6.c
net/ipv6/ah6.c
net/ipv6/anycast.c
net/ipv6/datagram.c
net/ipv6/exthdrs.c
net/ipv6/icmp.c
net/ipv6/inet6_connection_sock.c
net/ipv6/ip6_fib.c
net/ipv6/ip6_flowlabel.c
net/ipv6/ip6_input.c
net/ipv6/ip6_output.c
net/ipv6/ip6_tunnel.c
net/ipv6/ip6mr.c
net/ipv6/ipv6_sockglue.c
net/ipv6/mcast.c
net/ipv6/ndisc.c
net/ipv6/netfilter/ip6_queue.c
net/ipv6/netfilter/ip6t_REJECT.c
net/ipv6/netfilter/ip6table_filter.c
net/ipv6/netfilter/ip6table_mangle.c
net/ipv6/netfilter/ip6table_raw.c
net/ipv6/netfilter/ip6table_security.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/raw.c
net/ipv6/reassembly.c
net/ipv6/route.c
net/ipv6/sit.c
net/ipv6/sysctl_net_ipv6.c
net/ipv6/tcp_ipv6.c
net/ipv6/tunnel6.c
net/ipv6/udp.c
net/ipv6/xfrm6_mode_tunnel.c
net/ipv6/xfrm6_policy.c
net/ipv6/xfrm6_tunnel.c
net/ipx/af_ipx.c
net/ipx/ipx_route.c
net/irda/af_irda.c
net/irda/discovery.c
net/irda/ircomm/ircomm_core.c
net/irda/ircomm/ircomm_lmp.c
net/irda/ircomm/ircomm_param.c
net/irda/ircomm/ircomm_tty.c
net/irda/irda_device.c
net/irda/iriap.c
net/irda/iriap_event.c
net/irda/irias_object.c
net/irda/irlan/irlan_client.c
net/irda/irlan/irlan_common.c
net/irda/irlan/irlan_provider.c
net/irda/irlap_event.c
net/irda/irlap_frame.c
net/irda/irnet/irnet_irda.c
net/irda/irnet/irnet_ppp.c
net/irda/irnetlink.c
net/irda/irqueue.c
net/irda/irttp.c
net/key/af_key.c
net/lapb/lapb_iface.c
net/lapb/lapb_in.c
net/lapb/lapb_out.c
net/lapb/lapb_subr.c
net/llc/af_llc.c
net/llc/llc_c_ac.c
net/llc/llc_conn.c
net/llc/llc_if.c
net/llc/llc_input.c
net/llc/llc_sap.c
net/llc/llc_station.c
net/mac80211/agg-rx.c
net/mac80211/agg-tx.c
net/mac80211/cfg.c
net/mac80211/debugfs_key.c
net/mac80211/debugfs_netdev.c
net/mac80211/ibss.c
net/mac80211/iface.c
net/mac80211/key.c
net/mac80211/led.c
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mesh_hwmp.c
net/mac80211/mesh_pathtbl.c
net/mac80211/mesh_plink.c
net/mac80211/mlme.c
net/mac80211/rate.c
net/mac80211/rc80211_minstrel.c
net/mac80211/rc80211_minstrel_debugfs.c
net/mac80211/rc80211_pid_algo.c
net/mac80211/rc80211_pid_debugfs.c
net/mac80211/rx.c
net/mac80211/scan.c
net/mac80211/sta_info.c
net/mac80211/tx.c
net/mac80211/util.c
net/mac80211/wep.c
net/mac80211/work.c
net/mac80211/wpa.c
net/netfilter/core.c
net/netfilter/ipvs/ip_vs_app.c
net/netfilter/ipvs/ip_vs_conn.c
net/netfilter/ipvs/ip_vs_core.c
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/ipvs/ip_vs_dh.c
net/netfilter/ipvs/ip_vs_est.c
net/netfilter/ipvs/ip_vs_ftp.c
net/netfilter/ipvs/ip_vs_lblc.c
net/netfilter/ipvs/ip_vs_lblcr.c
net/netfilter/ipvs/ip_vs_proto.c
net/netfilter/ipvs/ip_vs_sh.c
net/netfilter/ipvs/ip_vs_wrr.c
net/netfilter/ipvs/ip_vs_xmit.c
net/netfilter/nf_conntrack_acct.c
net/netfilter/nf_conntrack_amanda.c
net/netfilter/nf_conntrack_ecache.c
net/netfilter/nf_conntrack_ftp.c
net/netfilter/nf_conntrack_h323_main.c
net/netfilter/nf_conntrack_helper.c
net/netfilter/nf_conntrack_irc.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_proto.c
net/netfilter/nf_conntrack_proto_dccp.c
net/netfilter/nf_conntrack_proto_gre.c
net/netfilter/nf_conntrack_sane.c
net/netfilter/nf_conntrack_standalone.c
net/netfilter/nf_queue.c
net/netfilter/nfnetlink.c
net/netfilter/nfnetlink_log.c
net/netfilter/nfnetlink_queue.c
net/netfilter/x_tables.c
net/netfilter/xt_CT.c
net/netfilter/xt_LED.c
net/netfilter/xt_RATEEST.c
net/netfilter/xt_TCPMSS.c
net/netfilter/xt_connlimit.c
net/netfilter/xt_dccp.c
net/netfilter/xt_hashlimit.c
net/netfilter/xt_limit.c
net/netfilter/xt_quota.c
net/netfilter/xt_recent.c
net/netfilter/xt_statistic.c
net/netfilter/xt_string.c
net/netlabel/netlabel_cipso_v4.c
net/netlabel/netlabel_domainhash.c
net/netlabel/netlabel_kapi.c
net/netlabel/netlabel_mgmt.c
net/netlabel/netlabel_unlabeled.c
net/netlabel/netlabel_user.c
net/netlink/af_netlink.c
net/netlink/genetlink.c
net/netrom/af_netrom.c
net/netrom/nr_dev.c
net/netrom/nr_in.c
net/netrom/nr_loopback.c
net/netrom/nr_out.c
net/netrom/nr_route.c
net/netrom/nr_subr.c
net/packet/af_packet.c
net/phonet/af_phonet.c
net/phonet/datagram.c
net/phonet/pep.c
net/phonet/pn_dev.c
net/phonet/pn_netlink.c
net/phonet/socket.c
net/rds/af_rds.c
net/rds/cong.c
net/rds/connection.c
net/rds/ib.c
net/rds/ib_cm.c
net/rds/ib_rdma.c
net/rds/ib_recv.c
net/rds/info.c
net/rds/iw.c
net/rds/iw_cm.c
net/rds/iw_rdma.c
net/rds/iw_recv.c
net/rds/loop.c
net/rds/message.c
net/rds/page.c
net/rds/rdma.c
net/rds/rdma_transport.c
net/rds/recv.c
net/rds/send.c
net/rds/tcp.c
net/rds/tcp_listen.c
net/rds/tcp_recv.c
net/rfkill/core.c
net/rose/af_rose.c
net/rose/rose_dev.c
net/rose/rose_link.c
net/rose/rose_loopback.c
net/rose/rose_out.c
net/rose/rose_route.c
net/rose/rose_subr.c
net/rxrpc/af_rxrpc.c
net/rxrpc/ar-accept.c
net/rxrpc/ar-ack.c
net/rxrpc/ar-call.c
net/rxrpc/ar-connection.c
net/rxrpc/ar-input.c
net/rxrpc/ar-key.c
net/rxrpc/ar-local.c
net/rxrpc/ar-output.c
net/rxrpc/ar-peer.c
net/rxrpc/ar-transport.c
net/rxrpc/rxkad.c
net/sched/Kconfig
net/sched/act_api.c
net/sched/act_ipt.c
net/sched/act_mirred.c
net/sched/act_pedit.c
net/sched/act_police.c
net/sched/act_simple.c
net/sched/cls_api.c
net/sched/cls_basic.c
net/sched/cls_cgroup.c
net/sched/cls_flow.c
net/sched/cls_fw.c
net/sched/cls_route.c
net/sched/cls_tcindex.c
net/sched/cls_u32.c
net/sched/em_meta.c
net/sched/em_nbyte.c
net/sched/em_text.c
net/sched/ematch.c
net/sched/sch_api.c
net/sched/sch_atm.c
net/sched/sch_cbq.c
net/sched/sch_drr.c
net/sched/sch_dsmark.c
net/sched/sch_fifo.c
net/sched/sch_generic.c
net/sched/sch_gred.c
net/sched/sch_htb.c
net/sched/sch_mq.c
net/sched/sch_multiq.c
net/sched/sch_netem.c
net/sched/sch_prio.c
net/sched/sch_sfq.c
net/sched/sch_teql.c
net/sctp/associola.c
net/sctp/auth.c
net/sctp/bind_addr.c
net/sctp/chunk.c
net/sctp/endpointola.c
net/sctp/input.c
net/sctp/inqueue.c
net/sctp/ipv6.c
net/sctp/output.c
net/sctp/outqueue.c
net/sctp/primitive.c
net/sctp/protocol.c
net/sctp/sm_make_chunk.c
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c
net/sctp/socket.c
net/sctp/ssnmap.c
net/sctp/transport.c
net/sctp/tsnmap.c
net/sctp/ulpevent.c
net/sctp/ulpqueue.c
net/socket.c
net/sunrpc/addr.c
net/sunrpc/auth.c
net/sunrpc/auth_generic.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/auth_gss/gss_generic_token.c
net/sunrpc/auth_gss/gss_krb5_crypto.c
net/sunrpc/auth_gss/gss_krb5_seal.c
net/sunrpc/auth_gss/gss_krb5_seqnum.c
net/sunrpc/auth_gss/gss_krb5_unseal.c
net/sunrpc/auth_gss/gss_krb5_wrap.c
net/sunrpc/auth_gss/gss_spkm3_seal.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/auth_unix.c
net/sunrpc/backchannel_rqst.c
net/sunrpc/bc_svc.c
net/sunrpc/clnt.c
net/sunrpc/rpc_pipe.c
net/sunrpc/rpcb_clnt.c
net/sunrpc/socklib.c
net/sunrpc/stats.c
net/sunrpc/svc.c
net/sunrpc/svc_xprt.c
net/sunrpc/svcauth_unix.c
net/sunrpc/xdr.c
net/sunrpc/xprt.c
net/sunrpc/xprtrdma/svc_rdma.c
net/sunrpc/xprtrdma/svc_rdma_transport.c
net/sunrpc/xprtrdma/transport.c
net/sunrpc/xprtrdma/verbs.c
net/sunrpc/xprtsock.c
net/tipc/core.h
net/tipc/eth_media.c
net/tipc/ref.c
net/tipc/socket.c
net/unix/garbage.c
net/unix/sysctl_net_unix.c
net/wimax/op-msg.c
net/wimax/stack.c
net/wireless/core.c
net/wireless/debugfs.c
net/wireless/ibss.c
net/wireless/mlme.c
net/wireless/nl80211.c
net/wireless/reg.c
net/wireless/scan.c
net/wireless/sme.c
net/wireless/util.c
net/wireless/wext-compat.c
net/wireless/wext-core.c
net/wireless/wext-priv.c
net/wireless/wext-sme.c
net/x25/af_x25.c
net/x25/x25_dev.c
net/x25/x25_facilities.c
net/x25/x25_forward.c
net/x25/x25_in.c
net/x25/x25_link.c
net/x25/x25_out.c
net/x25/x25_route.c
net/x25/x25_subr.c
net/xfrm/xfrm_ipcomp.c
net/xfrm/xfrm_output.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_sysctl.c
samples/kobject/kset-example.c
scripts/Makefile.lib
scripts/get_maintainer.pl
scripts/kernel-doc
scripts/mod/file2alias.c
security/device_cgroup.c
security/inode.c
security/integrity/ima/ima_api.c
security/integrity/ima/ima_audit.c
security/integrity/ima/ima_crypto.c
security/integrity/ima/ima_fs.c
security/integrity/ima/ima_iint.c
security/integrity/ima/ima_init.c
security/integrity/ima/ima_main.c
security/integrity/ima/ima_policy.c
security/integrity/ima/ima_queue.c
security/keys/gc.c
security/keys/keyring.c
security/keys/proc.c
security/keys/process_keys.c
security/keys/request_key.c
security/keys/user_defined.c
security/lsm_audit.c
security/min_addr.c
security/selinux/netif.c
security/selinux/netlabel.c
security/selinux/netlink.c
security/selinux/netnode.c
security/selinux/netport.c
security/selinux/ss/avtab.h
security/selinux/ss/symtab.c
security/selinux/xfrm.c
security/smack/smack_access.c
security/smack/smack_lsm.c
security/smack/smackfs.c
security/tomoyo/common.c
security/tomoyo/domain.c
security/tomoyo/file.c
security/tomoyo/gc.c
security/tomoyo/realpath.c
sound/aoa/codecs/onyx.c
sound/aoa/codecs/tas.c
sound/aoa/codecs/toonie.c
sound/aoa/core/gpio-pmf.c
sound/aoa/fabrics/layout.c
sound/aoa/soundbus/i2sbus/control.c
sound/aoa/soundbus/i2sbus/core.c
sound/aoa/soundbus/i2sbus/pcm.c
sound/arm/aaci.c
sound/arm/pxa2xx-pcm-lib.c
sound/core/control_compat.c
sound/core/hrtimer.c
sound/core/info.c
sound/core/jack.c
sound/core/misc.c
sound/core/oss/route.c
sound/core/pcm_compat.c
sound/core/pcm_lib.c
sound/core/pcm_memory.c
sound/core/pcm_native.c
sound/core/seq/oss/seq_oss_init.c
sound/core/seq/oss/seq_oss_midi.c
sound/core/seq/oss/seq_oss_readq.c
sound/core/seq/oss/seq_oss_synth.c
sound/core/seq/oss/seq_oss_timer.c
sound/core/seq/oss/seq_oss_writeq.c
sound/core/seq/seq_compat.c
sound/core/seq/seq_system.c
sound/core/timer.c
sound/drivers/ml403-ac97cr.c
sound/drivers/mtpav.c
sound/drivers/mts64.c
sound/drivers/opl3/opl3_oss.c
sound/drivers/opl3/opl3_synth.c
sound/drivers/opl4/opl4_lib.c
sound/drivers/pcsp/pcsp.h
sound/drivers/pcsp/pcsp_input.c
sound/drivers/pcsp/pcsp_lib.c
sound/drivers/portman2x4.c
sound/drivers/vx/vx_hwdep.c
sound/i2c/other/ak4113.c
sound/i2c/other/tea575x-tuner.c
sound/isa/cmi8330.c
sound/isa/cs423x/cs4236.c
sound/isa/es18xx.c
sound/isa/gus/interwave.c
sound/isa/msnd/msnd_midi.c
sound/isa/opl3sa2.c
sound/isa/opti9xx/miro.c
sound/isa/opti9xx/opti92x-ad1848.c
sound/isa/sb/emu8000_pcm.c
sound/isa/sb/es968.c
sound/isa/sb/sb16.c
sound/isa/sb/sb8.c
sound/isa/wavefront/wavefront.c
sound/isa/wavefront/wavefront_fx.c
sound/isa/wavefront/wavefront_synth.c
sound/mips/hal2.c
sound/mips/sgio2audio.c
sound/oss/ad1848.c
sound/oss/dmabuf.c
sound/oss/dmasound/dmasound_paula.c
sound/oss/kahlua.c
sound/oss/mpu401.c
sound/oss/msnd.c
sound/oss/msnd_pinnacle.c
sound/oss/opl3.c
sound/oss/sb_card.c
sound/oss/sb_common.c
sound/oss/sb_midi.c
sound/oss/sb_mixer.c
sound/oss/sequencer.c
sound/oss/soundcard.c
sound/oss/uart401.c
sound/oss/v_midi.c
sound/oss/vidc.c
sound/oss/vwsnd.c
sound/oss/waveartist.c
sound/pci/ac97/ac97_patch.c
sound/pci/ac97/ac97_proc.c
sound/pci/als4000.c
sound/pci/aw2/aw2-saa7146.c
sound/pci/ca0106/ca0106_mixer.c
sound/pci/ca0106/ca0106_proc.c
sound/pci/cmipci.c
sound/pci/cs5530.c
sound/pci/cs5535audio/cs5535audio_pcm.c
sound/pci/cs5535audio/cs5535audio_pm.c
sound/pci/ctxfi/ctatc.c
sound/pci/ctxfi/ctpcm.c
sound/pci/echoaudio/darla20.c
sound/pci/echoaudio/darla24.c
sound/pci/echoaudio/echo3g.c
sound/pci/echoaudio/echoaudio.c
sound/pci/echoaudio/gina20.c
sound/pci/echoaudio/gina24.c
sound/pci/echoaudio/indigo.c
sound/pci/echoaudio/indigodj.c
sound/pci/echoaudio/indigodjx.c
sound/pci/echoaudio/indigoio.c
sound/pci/echoaudio/indigoiox.c
sound/pci/echoaudio/layla20.c
sound/pci/echoaudio/layla24.c
sound/pci/echoaudio/mia.c
sound/pci/echoaudio/mona.c
sound/pci/emu10k1/memory.c
sound/pci/hda/hda_beep.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_eld.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_cirrus.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_nvhdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_via.c
sound/pci/ice1712/ak4xxx.c
sound/pci/ice1712/amp.c
sound/pci/ice1712/maya44.c
sound/pci/ice1712/vt1720_mobo.c
sound/pci/ice1712/wtm.c
sound/pci/lx6464es/lx6464es.c
sound/pci/maestro3.c
sound/pci/mixart/mixart.c
sound/pci/mixart/mixart_hwdep.c
sound/pci/oxygen/oxygen_lib.c
sound/pci/oxygen/xonar_cs43xx.c
sound/pci/rme32.c
sound/pci/rme96.c
sound/pci/rme9652/hdsp.c
sound/pci/rme9652/rme9652.c
sound/pci/sis7019.c
sound/pcmcia/pdaudiocf/pdaudiocf_core.c
sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
sound/pcmcia/vx/vxpocket.c
sound/ppc/burgundy.c
sound/ppc/keywest.c
sound/ppc/snd_ps3.c
sound/sh/sh_dac_audio.c
sound/soc/atmel/atmel-pcm.c
sound/soc/atmel/atmel_ssc_dai.c
sound/soc/au1x/psc-ac97.c
sound/soc/au1x/psc-i2s.c
sound/soc/blackfin/bf5xx-ac97-pcm.c
sound/soc/blackfin/bf5xx-ac97.c
sound/soc/blackfin/bf5xx-i2s-pcm.c
sound/soc/blackfin/bf5xx-tdm-pcm.c
sound/soc/codecs/ac97.c
sound/soc/codecs/ad1836.c
sound/soc/codecs/ad1938.c
sound/soc/codecs/ad1980.c
sound/soc/codecs/ad73311.c
sound/soc/codecs/ads117x.c
sound/soc/codecs/ak4104.c
sound/soc/codecs/ak4535.c
sound/soc/codecs/ak4642.c
sound/soc/codecs/ak4671.c
sound/soc/codecs/cs4270.c
sound/soc/codecs/cx20442.c
sound/soc/codecs/da7210.c
sound/soc/codecs/pcm3008.c
sound/soc/codecs/ssm2602.c
sound/soc/codecs/stac9766.c
sound/soc/codecs/tlv320aic23.c
sound/soc/codecs/tlv320aic26.c
sound/soc/codecs/tlv320aic3x.c
sound/soc/codecs/tlv320dac33.c
sound/soc/codecs/tpa6130a2.c
sound/soc/codecs/twl4030.c
sound/soc/codecs/uda134x.c
sound/soc/codecs/wm2000.c
sound/soc/codecs/wm8350.c
sound/soc/codecs/wm8400.c
sound/soc/codecs/wm8510.c
sound/soc/codecs/wm8523.c
sound/soc/codecs/wm8580.c
sound/soc/codecs/wm8711.c
sound/soc/codecs/wm8727.c
sound/soc/codecs/wm8728.c
sound/soc/codecs/wm8731.c
sound/soc/codecs/wm8750.c
sound/soc/codecs/wm8753.c
sound/soc/codecs/wm8776.c
sound/soc/codecs/wm8900.c
sound/soc/codecs/wm8903.c
sound/soc/codecs/wm8904.c
sound/soc/codecs/wm8940.c
sound/soc/codecs/wm8955.c
sound/soc/codecs/wm8960.c
sound/soc/codecs/wm8961.c
sound/soc/codecs/wm8971.c
sound/soc/codecs/wm8974.c
sound/soc/codecs/wm8978.c
sound/soc/codecs/wm8988.c
sound/soc/codecs/wm8990.c
sound/soc/codecs/wm8993.c
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm9081.c
sound/soc/codecs/wm9705.c
sound/soc/codecs/wm9712.c
sound/soc/codecs/wm9713.c
sound/soc/codecs/wm_hubs.c
sound/soc/codecs/wm_hubs.h
sound/soc/davinci/davinci-i2s.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/davinci/davinci-pcm.c
sound/soc/fsl/fsl_dma.c
sound/soc/fsl/fsl_ssi.c
sound/soc/fsl/mpc5200_dma.c
sound/soc/fsl/mpc8610_hpcd.c
sound/soc/fsl/soc-of-simple.c
sound/soc/imx/Kconfig
sound/soc/imx/imx-pcm-dma-mx2.c
sound/soc/imx/imx-pcm-fiq.c
sound/soc/imx/imx-ssi.c
sound/soc/omap/mcpdm.c
sound/soc/omap/omap-mcbsp.c
sound/soc/omap/omap-mcpdm.c
sound/soc/omap/omap-pcm.c
sound/soc/pxa/pxa-ssp.c
sound/soc/pxa/pxa2xx-ac97.c
sound/soc/pxa/pxa2xx-i2s.c
sound/soc/pxa/pxa2xx-pcm.c
sound/soc/s3c24xx/s3c-ac97.c
sound/soc/s3c24xx/s3c-dma.c
sound/soc/s3c24xx/s3c-i2s-v2.c
sound/soc/s3c24xx/s3c-pcm.c
sound/soc/s3c24xx/s3c24xx-i2s.c
sound/soc/s6000/s6000-i2s.c
sound/soc/s6000/s6000-pcm.c
sound/soc/sh/Kconfig
sound/soc/sh/dma-sh7760.c
sound/soc/sh/fsi.c
sound/soc/sh/siu_dai.c
sound/soc/sh/siu_pcm.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/soc/txx9/txx9aclc-ac97.c
sound/soc/txx9/txx9aclc-generic.c
sound/soc/txx9/txx9aclc.c
sound/sound_firmware.c
sound/sparc/cs4231.c
sound/sparc/dbri.c
sound/synth/emux/emux_proc.c
sound/usb/caiaq/audio.c
sound/usb/caiaq/device.c
sound/usb/caiaq/midi.c
sound/usb/usbmidi.c
sound/usb/usx2y/us122l.c
sound/usb/usx2y/usX2Yhwdep.c
sound/usb/usx2y/usb_stream.c
sound/usb/usx2y/usbusx2y.c
sound/usb/usx2y/usbusx2yaudio.c
sound/usb/usx2y/usx2yhwdeppcm.c
tools/perf/Documentation/Makefile
tools/perf/Documentation/perf-annotate.txt
tools/perf/Documentation/perf-bench.txt
tools/perf/Documentation/perf-buildid-cache.txt
tools/perf/Documentation/perf-diff.txt
tools/perf/Documentation/perf-inject.txt [new file with mode: 0644]
tools/perf/Documentation/perf-kmem.txt
tools/perf/Documentation/perf-kvm.txt [new file with mode: 0644]
tools/perf/Documentation/perf-list.txt
tools/perf/Documentation/perf-probe.txt
tools/perf/Documentation/perf-record.txt
tools/perf/Documentation/perf-sched.txt
tools/perf/Documentation/perf-stat.txt
tools/perf/Documentation/perf-test.txt [new file with mode: 0644]
tools/perf/Documentation/perf-trace-perl.txt
tools/perf/Documentation/perf-trace-python.txt
tools/perf/Documentation/perf-trace.txt
tools/perf/Makefile
tools/perf/arch/powerpc/Makefile [new file with mode: 0644]
tools/perf/arch/powerpc/util/dwarf-regs.c [new file with mode: 0644]
tools/perf/arch/x86/Makefile [new file with mode: 0644]
tools/perf/arch/x86/util/dwarf-regs.c [new file with mode: 0644]
tools/perf/bench/mem-memcpy.c
tools/perf/bench/sched-messaging.c
tools/perf/bench/sched-pipe.c
tools/perf/builtin-annotate.c
tools/perf/builtin-bench.c
tools/perf/builtin-buildid-cache.c
tools/perf/builtin-buildid-list.c
tools/perf/builtin-diff.c
tools/perf/builtin-help.c
tools/perf/builtin-inject.c [new file with mode: 0644]
tools/perf/builtin-kmem.c
tools/perf/builtin-kvm.c [new file with mode: 0644]
tools/perf/builtin-lock.c
tools/perf/builtin-probe.c
tools/perf/builtin-record.c
tools/perf/builtin-report.c
tools/perf/builtin-sched.c
tools/perf/builtin-stat.c
tools/perf/builtin-test.c [new file with mode: 0644]
tools/perf/builtin-timechart.c
tools/perf/builtin-top.c
tools/perf/builtin-trace.c
tools/perf/builtin.h
tools/perf/command-list.txt
tools/perf/perf-archive.sh
tools/perf/perf.c
tools/perf/perf.h
tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm
tools/perf/scripts/perl/bin/check-perf-trace-record
tools/perf/scripts/perl/bin/failed-syscalls-record
tools/perf/scripts/perl/bin/failed-syscalls-report
tools/perf/scripts/perl/bin/rw-by-file-record
tools/perf/scripts/perl/bin/rw-by-file-report
tools/perf/scripts/perl/bin/rw-by-pid-record
tools/perf/scripts/perl/bin/rw-by-pid-report
tools/perf/scripts/perl/bin/rwtop-record [new file with mode: 0644]
tools/perf/scripts/perl/bin/rwtop-report [new file with mode: 0644]
tools/perf/scripts/perl/bin/wakeup-latency-record
tools/perf/scripts/perl/bin/wakeup-latency-report
tools/perf/scripts/perl/bin/workqueue-stats-record
tools/perf/scripts/perl/bin/workqueue-stats-report
tools/perf/scripts/perl/failed-syscalls.pl
tools/perf/scripts/perl/rw-by-pid.pl
tools/perf/scripts/perl/rwtop.pl [new file with mode: 0644]
tools/perf/scripts/perl/wakeup-latency.pl
tools/perf/scripts/perl/workqueue-stats.pl
tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py
tools/perf/scripts/python/bin/failed-syscalls-by-pid-record
tools/perf/scripts/python/bin/failed-syscalls-by-pid-report
tools/perf/scripts/python/bin/sctop-record [new file with mode: 0644]
tools/perf/scripts/python/bin/sctop-report [new file with mode: 0644]
tools/perf/scripts/python/bin/syscall-counts-by-pid-record
tools/perf/scripts/python/bin/syscall-counts-by-pid-report
tools/perf/scripts/python/bin/syscall-counts-record
tools/perf/scripts/python/bin/syscall-counts-report
tools/perf/scripts/python/sctop.py [new file with mode: 0644]
tools/perf/util/PERF-VERSION-GEN
tools/perf/util/bitmap.c [new file with mode: 0644]
tools/perf/util/build-id.c
tools/perf/util/cache.h
tools/perf/util/callchain.c
tools/perf/util/callchain.h
tools/perf/util/color.c
tools/perf/util/color.h
tools/perf/util/cpumap.c [new file with mode: 0644]
tools/perf/util/cpumap.h [new file with mode: 0644]
tools/perf/util/debug.c
tools/perf/util/debug.h
tools/perf/util/event.c
tools/perf/util/event.h
tools/perf/util/header.c
tools/perf/util/header.h
tools/perf/util/hist.c
tools/perf/util/hist.h
tools/perf/util/hweight.c [new file with mode: 0644]
tools/perf/util/include/asm/bitops.h [deleted file]
tools/perf/util/include/asm/hweight.h [new file with mode: 0644]
tools/perf/util/include/dwarf-regs.h [new file with mode: 0644]
tools/perf/util/include/linux/bitmap.h
tools/perf/util/include/linux/bitops.h
tools/perf/util/include/linux/compiler.h
tools/perf/util/include/linux/kernel.h
tools/perf/util/map.c
tools/perf/util/map.h
tools/perf/util/newt.c [new file with mode: 0644]
tools/perf/util/parse-events.c
tools/perf/util/parse-events.h
tools/perf/util/parse-options.c
tools/perf/util/parse-options.h
tools/perf/util/probe-event.c
tools/perf/util/probe-event.h
tools/perf/util/probe-finder.c
tools/perf/util/probe-finder.h
tools/perf/util/pstack.c [new file with mode: 0644]
tools/perf/util/pstack.h [new file with mode: 0644]
tools/perf/util/scripting-engines/trace-event-perl.c
tools/perf/util/scripting-engines/trace-event-python.c
tools/perf/util/session.c
tools/perf/util/session.h
tools/perf/util/sort.c
tools/perf/util/sort.h
tools/perf/util/string.c
tools/perf/util/string.h [deleted file]
tools/perf/util/symbol.c
tools/perf/util/symbol.h
tools/perf/util/thread.c
tools/perf/util/thread.h
tools/perf/util/trace-event-info.c
tools/perf/util/trace-event-parse.c
tools/perf/util/trace-event-read.c
tools/perf/util/trace-event.h
tools/perf/util/util.c
tools/perf/util/util.h
virt/kvm/assigned-dev.c
virt/kvm/coalesced_mmio.c
virt/kvm/eventfd.c
virt/kvm/ioapic.c
virt/kvm/ioapic.h
virt/kvm/iommu.c
virt/kvm/irq_comm.c
virt/kvm/kvm_main.c

index a986e9bbba3d2972770f9e2a8196bea6eb119a0f..bcebb9eaedce04da1d4040450bc38878b208428b 100644 (file)
@@ -160,7 +160,7 @@ Description:
                match the driver to the device.  For example:
                # echo "046d c315" > /sys/bus/usb/drivers/foo/remove_id
 
-What:          /sys/bus/usb/device/.../avoid_reset
+What:          /sys/bus/usb/device/.../avoid_reset_quirk
 Date:          December 2009
 Contact:       Oliver Neukum <oliver@neukum.org>
 Description:
index ba997577150369c5d7bc655c82704e01567e685d..ff3e5bec1c24509d76f1e1bc8e8d5379c4a54a60 100644 (file)
@@ -107,10 +107,6 @@ void (*dev_config) (struct ata_port *, struct ata_device *);
        issue of SET FEATURES - XFER MODE, and prior to operation.
        </para>
        <para>
-       Called by ata_device_add() after ata_dev_identify() determines
-       a device is present.
-       </para>
-       <para>
        This entry may be specified as NULL in ata_port_operations.
        </para>
 
@@ -154,8 +150,8 @@ unsigned int (*mode_filter) (struct ata_port *, struct ata_device *, unsigned in
 
        <sect2><title>Taskfile read/write</title>
        <programlisting>
-void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
-void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
+void (*sff_tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
+void (*sff_tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
        </programlisting>
 
        <para>
@@ -164,36 +160,35 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
        hardware registers / DMA buffers, to obtain the current set of
        taskfile register values.
        Most drivers for taskfile-based hardware (PIO or MMIO) use
-       ata_tf_load() and ata_tf_read() for these hooks.
+       ata_sff_tf_load() and ata_sff_tf_read() for these hooks.
        </para>
 
        </sect2>
 
        <sect2><title>PIO data read/write</title>
        <programlisting>
-void (*data_xfer) (struct ata_device *, unsigned char *, unsigned int, int);
+void (*sff_data_xfer) (struct ata_device *, unsigned char *, unsigned int, int);
        </programlisting>
 
        <para>
 All bmdma-style drivers must implement this hook.  This is the low-level
 operation that actually copies the data bytes during a PIO data
 transfer.
-Typically the driver
-will choose one of ata_pio_data_xfer_noirq(), ata_pio_data_xfer(), or
-ata_mmio_data_xfer().
+Typically the driver will choose one of ata_sff_data_xfer_noirq(),
+ata_sff_data_xfer(), or ata_sff_data_xfer32().
        </para>
 
        </sect2>
 
        <sect2><title>ATA command execute</title>
        <programlisting>
-void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
+void (*sff_exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
        </programlisting>
 
        <para>
        causes an ATA command, previously loaded with
        ->tf_load(), to be initiated in hardware.
-       Most drivers for taskfile-based hardware use ata_exec_command()
+       Most drivers for taskfile-based hardware use ata_sff_exec_command()
        for this hook.
        </para>
 
@@ -218,8 +213,8 @@ command.
 
        <sect2><title>Read specific ATA shadow registers</title>
        <programlisting>
-u8   (*check_status)(struct ata_port *ap);
-u8   (*check_altstatus)(struct ata_port *ap);
+u8   (*sff_check_status)(struct ata_port *ap);
+u8   (*sff_check_altstatus)(struct ata_port *ap);
        </programlisting>
 
        <para>
@@ -227,20 +222,14 @@ u8   (*check_altstatus)(struct ata_port *ap);
        hardware.  On some hardware, reading the Status register has
        the side effect of clearing the interrupt condition.
        Most drivers for taskfile-based hardware use
-       ata_check_status() for this hook.
-       </para>
-       <para>
-       Note that because this is called from ata_device_add(), at
-       least a dummy function that clears device interrupts must be
-       provided for all drivers, even if the controller doesn't
-       actually have a taskfile status register.
+       ata_sff_check_status() for this hook.
        </para>
 
        </sect2>
 
        <sect2><title>Select ATA device on bus</title>
        <programlisting>
-void (*dev_select)(struct ata_port *ap, unsigned int device);
+void (*sff_dev_select)(struct ata_port *ap, unsigned int device);
        </programlisting>
 
        <para>
@@ -251,9 +240,7 @@ void (*dev_select)(struct ata_port *ap, unsigned int device);
        </para>
        <para>
        Most drivers for taskfile-based hardware use
-       ata_std_dev_select() for this hook.  Controllers which do not
-       support second drives on a port (such as SATA contollers) will
-       use ata_noop_dev_select().
+       ata_sff_dev_select() for this hook.
        </para>
 
        </sect2>
@@ -441,13 +428,13 @@ void (*irq_clear) (struct ata_port *);
        to struct ata_host_set.
        </para>
        <para>
-       Most legacy IDE drivers use ata_interrupt() for the
+       Most legacy IDE drivers use ata_sff_interrupt() for the
        irq_handler hook, which scans all ports in the host_set,
        determines which queued command was active (if any), and calls
-       ata_host_intr(ap,qc).
+       ata_sff_host_intr(ap,qc).
        </para>
        <para>
-       Most legacy IDE drivers use ata_bmdma_irq_clear() for the
+       Most legacy IDE drivers use ata_sff_irq_clear() for the
        irq_clear() hook, which simply clears the interrupt and error
        flags in the DMA status register.
        </para>
@@ -496,10 +483,6 @@ void (*host_stop) (struct ata_host_set *host_set);
        data from port at this time.
        </para>
        <para>
-       Many drivers use ata_port_stop() as this hook, which frees the
-       PRD table.
-       </para>
-       <para>
        ->host_stop() is called after all ->port_stop() calls
 have completed.  The hook must finalize hardware shutdown, release DMA
 and other resources, etc.
index 8bca1d5cec09a8bf6c8c5f0e6f159d770fcf806c..e8473eae2a2064ecef2afadf2e92551dc327bea3 100644 (file)
      </address>
     </affiliation>
    </author>
+   <author>
+    <firstname>William</firstname>
+    <surname>Cohen</surname>
+    <affiliation>
+     <address>
+      <email>wcohen@redhat.com</email>
+     </address>
+    </affiliation>
+   </author>
   </authorgroup>
 
   <legalnotice>
 !Iinclude/trace/events/signal.h
   </chapter>
 
+  <chapter id="block">
+   <title>Block IO</title>
+!Iinclude/trace/events/block.h
+  </chapter>
 </book>
index f5395af88a41bfc49c987aabe378e51fc04e2b41..40ada93b820af1efe7842dd35a04f77d6610948c 100644 (file)
@@ -234,7 +234,7 @@ process is as follows:
     Linus, usually the patches that have already been included in the
     -next kernel for a few weeks.  The preferred way to submit big changes
     is using git (the kernel's source management tool, more information
-    can be found at http://git.or.cz/) but plain patches are also just
+    can be found at http://git-scm.com/) but plain patches are also just
     fine.
   - After two weeks a -rc1 kernel is released it is now possible to push
     only patches that do not include new features that could affect the
index a6d32e65d222bbea68cba1c133db87c459c99dec..a8536cb88091744128d7b6f1d51e93304029bd30 100644 (file)
@@ -34,7 +34,7 @@ NMI handler.
                cpu = smp_processor_id();
                ++nmi_count(cpu);
 
-               if (!rcu_dereference(nmi_callback)(regs, cpu))
+               if (!rcu_dereference_sched(nmi_callback)(regs, cpu))
                        default_do_nmi(regs);
 
                nmi_exit();
@@ -47,12 +47,13 @@ function pointer.  If this handler returns zero, do_nmi() invokes the
 default_do_nmi() function to handle a machine-specific NMI.  Finally,
 preemption is restored.
 
-Strictly speaking, rcu_dereference() is not needed, since this code runs
-only on i386, which does not need rcu_dereference() anyway.  However,
-it is a good documentation aid, particularly for anyone attempting to
-do something similar on Alpha.
+In theory, rcu_dereference_sched() is not needed, since this code runs
+only on i386, which in theory does not need rcu_dereference_sched()
+anyway.  However, in practice it is a good documentation aid, particularly
+for anyone attempting to do something similar on Alpha or on systems
+with aggressive optimizing compilers.
 
-Quick Quiz:  Why might the rcu_dereference() be necessary on Alpha,
+Quick Quiz:  Why might the rcu_dereference_sched() be necessary on Alpha,
             given that the code referenced by the pointer is read-only?
 
 
@@ -99,17 +100,21 @@ invoke irq_enter() and irq_exit() on NMI entry and exit, respectively.
 
 Answer to Quick Quiz
 
-       Why might the rcu_dereference() be necessary on Alpha, given
+       Why might the rcu_dereference_sched() be necessary on Alpha, given
        that the code referenced by the pointer is read-only?
 
        Answer: The caller to set_nmi_callback() might well have
-               initialized some data that is to be used by the
-               new NMI handler.  In this case, the rcu_dereference()
-               would be needed, because otherwise a CPU that received
-               an NMI just after the new handler was set might see
-               the pointer to the new NMI handler, but the old
-               pre-initialized version of the handler's data.
-
-               More important, the rcu_dereference() makes it clear
-               to someone reading the code that the pointer is being
-               protected by RCU.
+               initialized some data that is to be used by the new NMI
+               handler.  In this case, the rcu_dereference_sched() would
+               be needed, because otherwise a CPU that received an NMI
+               just after the new handler was set might see the pointer
+               to the new NMI handler, but the old pre-initialized
+               version of the handler's data.
+
+               This same sad story can happen on other CPUs when using
+               a compiler with aggressive pointer-value speculation
+               optimizations.
+
+               More important, the rcu_dereference_sched() makes it
+               clear to someone reading the code that the pointer is
+               being protected by RCU-sched.
index cbc180f90194fcb01bc273f8b953d91b28a79fae..790d1a8123760211bdcb6427b75c1b4abf2b7210 100644 (file)
@@ -260,7 +260,8 @@ over a rather long period of time, but improvements are always welcome!
        The reason that it is permissible to use RCU list-traversal
        primitives when the update-side lock is held is that doing so
        can be quite helpful in reducing code bloat when common code is
-       shared between readers and updaters.
+       shared between readers and updaters.  Additional primitives
+       are provided for this case, as discussed in lockdep.txt.
 
 10.    Conversely, if you are in an RCU read-side critical section,
        and you don't hold the appropriate update-side lock, you -must-
@@ -344,8 +345,8 @@ over a rather long period of time, but improvements are always welcome!
        requiring SRCU's read-side deadlock immunity or low read-side
        realtime latency.
 
-       Note that, rcu_assign_pointer() and rcu_dereference() relate to
-       SRCU just as they do to other forms of RCU.
+       Note that, rcu_assign_pointer() relates to SRCU just as they do
+       to other forms of RCU.
 
 15.    The whole point of call_rcu(), synchronize_rcu(), and friends
        is to wait until all pre-existing readers have finished before
index fe24b58627bdde8f6a5d0b331436408f1d43d3ea..d7a49b2f6994c68ced38075000ccbc07803ba413 100644 (file)
@@ -32,9 +32,20 @@ checking of rcu_dereference() primitives:
        srcu_dereference(p, sp):
                Check for SRCU read-side critical section.
        rcu_dereference_check(p, c):
-               Use explicit check expression "c".
+               Use explicit check expression "c".  This is useful in
+               code that is invoked by both readers and updaters.
        rcu_dereference_raw(p)
                Don't check.  (Use sparingly, if at all.)
+       rcu_dereference_protected(p, c):
+               Use explicit check expression "c", and omit all barriers
+               and compiler constraints.  This is useful when the data
+               structure cannot change, for example, in code that is
+               invoked only by updaters.
+       rcu_access_pointer(p):
+               Return the value of the pointer and omit all barriers,
+               but retain the compiler constraints that prevent duplicating
+               or coalescsing.  This is useful when when testing the
+               value of the pointer itself, for example, against NULL.
 
 The rcu_dereference_check() check expression can be any boolean
 expression, but would normally include one of the rcu_read_lock_held()
@@ -59,7 +70,20 @@ In case (1), the pointer is picked up in an RCU-safe manner for vanilla
 RCU read-side critical sections, in case (2) the ->file_lock prevents
 any change from taking place, and finally, in case (3) the current task
 is the only task accessing the file_struct, again preventing any change
-from taking place.
+from taking place.  If the above statement was invoked only from updater
+code, it could instead be written as follows:
+
+       file = rcu_dereference_protected(fdt->fd[fd],
+                                        lockdep_is_held(&files->file_lock) ||
+                                        atomic_read(&files->count) == 1);
+
+This would verify cases #2 and #3 above, and furthermore lockdep would
+complain if this was used in an RCU read-side critical section unless one
+of these two cases held.  Because rcu_dereference_protected() omits all
+barriers and compiler constraints, it generates better code than do the
+other flavors of rcu_dereference().  On the other hand, it is illegal
+to use rcu_dereference_protected() if either the RCU-protected pointer
+or the RCU-protected data that it points to can change concurrently.
 
 There are currently only "universal" versions of the rcu_assign_pointer()
 and RCU list-/tree-traversal primitives, which do not (yet) check for
index 1423d2570d78833b8421f51e248f4dabbd3f5bc5..44c6dcc93d6dad8e9cee2cadb9f49fa992c5eb00 100644 (file)
@@ -3,35 +3,79 @@ Using RCU's CPU Stall Detector
 The CONFIG_RCU_CPU_STALL_DETECTOR kernel config parameter enables
 RCU's CPU stall detector, which detects conditions that unduly delay
 RCU grace periods.  The stall detector's idea of what constitutes
-"unduly delayed" is controlled by a pair of C preprocessor macros:
+"unduly delayed" is controlled by a set of C preprocessor macros:
 
 RCU_SECONDS_TILL_STALL_CHECK
 
        This macro defines the period of time that RCU will wait from
        the beginning of a grace period until it issues an RCU CPU
-       stall warning.  It is normally ten seconds.
+       stall warning.  This time period is normally ten seconds.
 
 RCU_SECONDS_TILL_STALL_RECHECK
 
        This macro defines the period of time that RCU will wait after
-       issuing a stall warning until it issues another stall warning.
-       It is normally set to thirty seconds.
+       issuing a stall warning until it issues another stall warning
+       for the same stall.  This time period is normally set to thirty
+       seconds.
 
 RCU_STALL_RAT_DELAY
 
-       The CPU stall detector tries to make the offending CPU rat on itself,
-       as this often gives better-quality stack traces.  However, if
-       the offending CPU does not detect its own stall in the number
-       of jiffies specified by RCU_STALL_RAT_DELAY, then other CPUs will
-       complain.  This is normally set to two jiffies.
+       The CPU stall detector tries to make the offending CPU print its
+       own warnings, as this often gives better-quality stack traces.
+       However, if the offending CPU does not detect its own stall in
+       the number of jiffies specified by RCU_STALL_RAT_DELAY, then
+       some other CPU will complain.  This delay is normally set to
+       two jiffies.
 
-The following problems can result in an RCU CPU stall warning:
+When a CPU detects that it is stalling, it will print a message similar
+to the following:
+
+INFO: rcu_sched_state detected stall on CPU 5 (t=2500 jiffies)
+
+This message indicates that CPU 5 detected that it was causing a stall,
+and that the stall was affecting RCU-sched.  This message will normally be
+followed by a stack dump of the offending CPU.  On TREE_RCU kernel builds,
+RCU and RCU-sched are implemented by the same underlying mechanism,
+while on TREE_PREEMPT_RCU kernel builds, RCU is instead implemented
+by rcu_preempt_state.
+
+On the other hand, if the offending CPU fails to print out a stall-warning
+message quickly enough, some other CPU will print a message similar to
+the following:
+
+INFO: rcu_bh_state detected stalls on CPUs/tasks: { 3 5 } (detected by 2, 2502 jiffies)
+
+This message indicates that CPU 2 detected that CPUs 3 and 5 were both
+causing stalls, and that the stall was affecting RCU-bh.  This message
+will normally be followed by stack dumps for each CPU.  Please note that
+TREE_PREEMPT_RCU builds can be stalled by tasks as well as by CPUs,
+and that the tasks will be indicated by PID, for example, "P3421".
+It is even possible for a rcu_preempt_state stall to be caused by both
+CPUs -and- tasks, in which case the offending CPUs and tasks will all
+be called out in the list.
+
+Finally, if the grace period ends just as the stall warning starts
+printing, there will be a spurious stall-warning message:
+
+INFO: rcu_bh_state detected stalls on CPUs/tasks: { } (detected by 4, 2502 jiffies)
+
+This is rare, but does happen from time to time in real life.
+
+So your kernel printed an RCU CPU stall warning.  The next question is
+"What caused it?"  The following problems can result in RCU CPU stall
+warnings:
 
 o      A CPU looping in an RCU read-side critical section.
        
-o      A CPU looping with interrupts disabled.
+o      A CPU looping with interrupts disabled.  This condition can
+       result in RCU-sched and RCU-bh stalls.
 
-o      A CPU looping with preemption disabled.
+o      A CPU looping with preemption disabled.  This condition can
+       result in RCU-sched stalls and, if ksoftirqd is in use, RCU-bh
+       stalls.
+
+o      A CPU looping with bottom halves disabled.  This condition can
+       result in RCU-sched and RCU-bh stalls.
 
 o      For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel
        without invoking schedule().
@@ -39,20 +83,24 @@ o   For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel
 o      A bug in the RCU implementation.
 
 o      A hardware failure.  This is quite unlikely, but has occurred
-       at least once in a former life.  A CPU failed in a running system,
+       at least once in real life.  A CPU failed in a running system,
        becoming unresponsive, but not causing an immediate crash.
        This resulted in a series of RCU CPU stall warnings, eventually
        leading the realization that the CPU had failed.
 
-The RCU, RCU-sched, and RCU-bh implementations have CPU stall warning.
-SRCU does not do so directly, but its calls to synchronize_sched() will
-result in RCU-sched detecting any CPU stalls that might be occurring.
-
-To diagnose the cause of the stall, inspect the stack traces.  The offending
-function will usually be near the top of the stack.  If you have a series
-of stall warnings from a single extended stall, comparing the stack traces
-can often help determine where the stall is occurring, which will usually
-be in the function nearest the top of the stack that stays the same from
-trace to trace.
+The RCU, RCU-sched, and RCU-bh implementations have CPU stall
+warning.  SRCU does not have its own CPU stall warnings, but its
+calls to synchronize_sched() will result in RCU-sched detecting
+RCU-sched-related CPU stalls.  Please note that RCU only detects
+CPU stalls when there is a grace period in progress.  No grace period,
+no CPU stall warnings.
+
+To diagnose the cause of the stall, inspect the stack traces.
+The offending function will usually be near the top of the stack.
+If you have a series of stall warnings from a single extended stall,
+comparing the stack traces can often help determine where the stall
+is occurring, which will usually be in the function nearest the top of
+that portion of the stack which remains the same from trace to trace.
+If you can reliably trigger the stall, ftrace can be quite helpful.
 
 RCU bugs can often be debugged with the help of CONFIG_RCU_TRACE.
index 0e50bc2aa1e2e4f4682f5b5540a49987bfb00884..5d9016795fd825a43f2a4093e4edd870cb92e42c 100644 (file)
@@ -182,16 +182,6 @@ Similarly, sched_expedited RCU provides the following:
        sched_expedited-torture: Reader Pipe:  12660320201 95875 0 0 0 0 0 0 0 0 0
        sched_expedited-torture: Reader Batch:  12660424885 0 0 0 0 0 0 0 0 0 0
        sched_expedited-torture: Free-Block Circulation:  1090795 1090795 1090794 1090793 1090792 1090791 1090790 1090789 1090788 1090787 0
-       state: -1 / 0:0 3:0 4:0
-
-As before, the first four lines are similar to those for RCU.
-The last line shows the task-migration state.  The first number is
--1 if synchronize_sched_expedited() is idle, -2 if in the process of
-posting wakeups to the migration kthreads, and N when waiting on CPU N.
-Each of the colon-separated fields following the "/" is a CPU:state pair.
-Valid states are "0" for idle, "1" for waiting for quiescent state,
-"2" for passed through quiescent state, and "3" when a race with a
-CPU-hotplug event forces use of the synchronize_sched() primitive.
 
 
 USAGE
index 8608fd85e921844ab33406c7f7d32ae7ea6c7d18..efd8cc95c06b1470db165a74a0d99fd33ee17dea 100644 (file)
@@ -256,23 +256,23 @@ o Each element of the form "1/1 0:127 ^0" represents one struct
 The output of "cat rcu/rcu_pending" looks as follows:
 
 rcu_sched:
-  0 np=255892 qsp=53936 cbr=0 cng=14417 gpc=10033 gps=24320 nf=6445 nn=146741
-  1 np=261224 qsp=54638 cbr=0 cng=25723 gpc=16310 gps=2849 nf=5912 nn=155792
-  2 np=237496 qsp=49664 cbr=0 cng=2762 gpc=45478 gps=1762 nf=1201 nn=136629
-  3 np=236249 qsp=48766 cbr=0 cng=286 gpc=48049 gps=1218 nf=207 nn=137723
-  4 np=221310 qsp=46850 cbr=0 cng=26 gpc=43161 gps=4634 nf=3529 nn=123110
-  5 np=237332 qsp=48449 cbr=0 cng=54 gpc=47920 gps=3252 nf=201 nn=137456
-  6 np=219995 qsp=46718 cbr=0 cng=50 gpc=42098 gps=6093 nf=4202 nn=120834
-  7 np=249893 qsp=49390 cbr=0 cng=72 gpc=38400 gps=17102 nf=41 nn=144888
+  0 np=255892 qsp=53936 rpq=85 cbr=0 cng=14417 gpc=10033 gps=24320 nf=6445 nn=146741
+  1 np=261224 qsp=54638 rpq=33 cbr=0 cng=25723 gpc=16310 gps=2849 nf=5912 nn=155792
+  2 np=237496 qsp=49664 rpq=23 cbr=0 cng=2762 gpc=45478 gps=1762 nf=1201 nn=136629
+  3 np=236249 qsp=48766 rpq=98 cbr=0 cng=286 gpc=48049 gps=1218 nf=207 nn=137723
+  4 np=221310 qsp=46850 rpq=7 cbr=0 cng=26 gpc=43161 gps=4634 nf=3529 nn=123110
+  5 np=237332 qsp=48449 rpq=9 cbr=0 cng=54 gpc=47920 gps=3252 nf=201 nn=137456
+  6 np=219995 qsp=46718 rpq=12 cbr=0 cng=50 gpc=42098 gps=6093 nf=4202 nn=120834
+  7 np=249893 qsp=49390 rpq=42 cbr=0 cng=72 gpc=38400 gps=17102 nf=41 nn=144888
 rcu_bh:
-  0 np=146741 qsp=1419 cbr=0 cng=6 gpc=0 gps=0 nf=2 nn=145314
-  1 np=155792 qsp=12597 cbr=0 cng=0 gpc=4 gps=8 nf=3 nn=143180
-  2 np=136629 qsp=18680 cbr=0 cng=0 gpc=7 gps=6 nf=0 nn=117936
-  3 np=137723 qsp=2843 cbr=0 cng=0 gpc=10 gps=7 nf=0 nn=134863
-  4 np=123110 qsp=12433 cbr=0 cng=0 gpc=4 gps=2 nf=0 nn=110671
-  5 np=137456 qsp=4210 cbr=0 cng=0 gpc=6 gps=5 nf=0 nn=133235
-  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
+  0 np=146741 qsp=1419 rpq=6 cbr=0 cng=6 gpc=0 gps=0 nf=2 nn=145314
+  1 np=155792 qsp=12597 rpq=3 cbr=0 cng=0 gpc=4 gps=8 nf=3 nn=143180
+  2 np=136629 qsp=18680 rpq=1 cbr=0 cng=0 gpc=7 gps=6 nf=0 nn=117936
+  3 np=137723 qsp=2843 rpq=0 cbr=0 cng=0 gpc=10 gps=7 nf=0 nn=134863
+  4 np=123110 qsp=12433 rpq=0 cbr=0 cng=0 gpc=4 gps=2 nf=0 nn=110671
+  5 np=137456 qsp=4210 rpq=1 cbr=0 cng=0 gpc=6 gps=5 nf=0 nn=133235
+  6 np=120834 qsp=9902 rpq=2 cbr=0 cng=0 gpc=6 gps=3 nf=2 nn=110921
+  7 np=144888 qsp=26336 rpq=0 cbr=0 cng=0 gpc=8 gps=2 nf=0 nn=118542
 
 As always, this is once again split into "rcu_sched" and "rcu_bh"
 portions, with CONFIG_TREE_PREEMPT_RCU kernels having an additional
@@ -284,6 +284,9 @@ o   "np" is the number of times that __rcu_pending() has been invoked
 o      "qsp" is the number of times that the RCU was waiting for a
        quiescent state from this CPU.
 
+o      "rpq" is the number of times that the CPU had passed through
+       a quiescent state, but not yet reported it to RCU.
+
 o      "cbr" is the number of times that this CPU had RCU callbacks
        that had passed through a grace period, and were thus ready
        to be invoked.
index 1dc00ee97163261bb3390e21499e45b9a44bde20..cfaac34c4557b83c87178efd0fdf8801a92132ea 100644 (file)
@@ -840,6 +840,12 @@ SRCU:      Initialization/cleanup
        init_srcu_struct
        cleanup_srcu_struct
 
+All:  lockdep-checked RCU-protected pointer access
+
+       rcu_dereference_check
+       rcu_dereference_protected
+       rcu_access_pointer
+
 See the comment headers in the source code (or the docbook generated
 from them) for more information.
 
index 6fab97ea7e6b0ecd4b3973cd0787257f14647617..508b5b2b0289dd88215a26301aa633d4c45821e8 100644 (file)
@@ -1162,8 +1162,8 @@ where a driver received a request ala this before:
 
 As mentioned, there is no virtual mapping of a bio. For DMA, this is
 not a problem as the driver probably never will need a virtual mapping.
-Instead it needs a bus mapping (pci_map_page for a single segment or
-use blk_rq_map_sg for scatter gather) to be able to ship it to the driver. For
+Instead it needs a bus mapping (dma_map_page for a single segment or
+use dma_map_sg for scatter gather) to be able to ship it to the driver. For
 PIO drivers (or drivers that need to revert to PIO transfer once in a
 while (IDE for example)), where the CPU is doing the actual data
 transfer a virtual mapping is needed. If the driver supports highmem I/O,
index fd588ff0e2965311f319d07161f15d6b42f166c8..a1ca5924faff1df145a6dbb094a862c77313da1f 100644 (file)
@@ -235,8 +235,7 @@ containing the following files describing that cgroup:
  - cgroup.procs: list of tgids in the cgroup.  This list is not
    guaranteed to be sorted or free of duplicate tgids, and userspace
    should sort/uniquify the list if this property is required.
-   Writing a tgid into this file moves all threads with that tgid into
-   this cgroup.
+   This is a read-only file, for now.
  - notify_on_release flag: run the release agent on exit?
  - release_agent: the path to use for release notifications (this file
    exists in the top cgroup only)
index f8bc802d70b92d05545a87974af9e2645d6af6c6..3a6aecd078ba95c4d5a58e0ffb34ba8048cc879d 100644 (file)
@@ -340,7 +340,7 @@ Note:
 5.3 swappiness
   Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only.
 
-  Following cgroups' swapiness can't be changed.
+  Following cgroups' swappiness can't be changed.
   - root cgroup (uses /proc/sys/vm/swappiness).
   - a cgroup which uses hierarchy and it has child cgroup.
   - a cgroup which uses hierarchy and not the root of hierarchy.
diff --git a/Documentation/circular-buffers.txt b/Documentation/circular-buffers.txt
new file mode 100644 (file)
index 0000000..8117e5b
--- /dev/null
@@ -0,0 +1,234 @@
+                              ================
+                              CIRCULAR BUFFERS
+                              ================
+
+By: David Howells <dhowells@redhat.com>
+    Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+
+
+Linux provides a number of features that can be used to implement circular
+buffering.  There are two sets of such features:
+
+ (1) Convenience functions for determining information about power-of-2 sized
+     buffers.
+
+ (2) Memory barriers for when the producer and the consumer of objects in the
+     buffer don't want to share a lock.
+
+To use these facilities, as discussed below, there needs to be just one
+producer and just one consumer.  It is possible to handle multiple producers by
+serialising them, and to handle multiple consumers by serialising them.
+
+
+Contents:
+
+ (*) What is a circular buffer?
+
+ (*) Measuring power-of-2 buffers.
+
+ (*) Using memory barriers with circular buffers.
+     - The producer.
+     - The consumer.
+
+
+==========================
+WHAT IS A CIRCULAR BUFFER?
+==========================
+
+First of all, what is a circular buffer?  A circular buffer is a buffer of
+fixed, finite size into which there are two indices:
+
+ (1) A 'head' index - the point at which the producer inserts items into the
+     buffer.
+
+ (2) A 'tail' index - the point at which the consumer finds the next item in
+     the buffer.
+
+Typically when the tail pointer is equal to the head pointer, the buffer is
+empty; and the buffer is full when the head pointer is one less than the tail
+pointer.
+
+The head index is incremented when items are added, and the tail index when
+items are removed.  The tail index should never jump the head index, and both
+indices should be wrapped to 0 when they reach the end of the buffer, thus
+allowing an infinite amount of data to flow through the buffer.
+
+Typically, items will all be of the same unit size, but this isn't strictly
+required to use the techniques below.  The indices can be increased by more
+than 1 if multiple items or variable-sized items are to be included in the
+buffer, provided that neither index overtakes the other.  The implementer must
+be careful, however, as a region more than one unit in size may wrap the end of
+the buffer and be broken into two segments.
+
+
+============================
+MEASURING POWER-OF-2 BUFFERS
+============================
+
+Calculation of the occupancy or the remaining capacity of an arbitrarily sized
+circular buffer would normally be a slow operation, requiring the use of a
+modulus (divide) instruction.  However, if the buffer is of a power-of-2 size,
+then a much quicker bitwise-AND instruction can be used instead.
+
+Linux provides a set of macros for handling power-of-2 circular buffers.  These
+can be made use of by:
+
+       #include <linux/circ_buf.h>
+
+The macros are:
+
+ (*) Measure the remaining capacity of a buffer:
+
+       CIRC_SPACE(head_index, tail_index, buffer_size);
+
+     This returns the amount of space left in the buffer[1] into which items
+     can be inserted.
+
+
+ (*) Measure the maximum consecutive immediate space in a buffer:
+
+       CIRC_SPACE_TO_END(head_index, tail_index, buffer_size);
+
+     This returns the amount of consecutive space left in the buffer[1] into
+     which items can be immediately inserted without having to wrap back to the
+     beginning of the buffer.
+
+
+ (*) Measure the occupancy of a buffer:
+
+       CIRC_CNT(head_index, tail_index, buffer_size);
+
+     This returns the number of items currently occupying a buffer[2].
+
+
+ (*) Measure the non-wrapping occupancy of a buffer:
+
+       CIRC_CNT_TO_END(head_index, tail_index, buffer_size);
+
+     This returns the number of consecutive items[2] that can be extracted from
+     the buffer without having to wrap back to the beginning of the buffer.
+
+
+Each of these macros will nominally return a value between 0 and buffer_size-1,
+however:
+
+ [1] CIRC_SPACE*() are intended to be used in the producer.  To the producer
+     they will return a lower bound as the producer controls the head index,
+     but the consumer may still be depleting the buffer on another CPU and
+     moving the tail index.
+
+     To the consumer it will show an upper bound as the producer may be busy
+     depleting the space.
+
+ [2] CIRC_CNT*() are intended to be used in the consumer.  To the consumer they
+     will return a lower bound as the consumer controls the tail index, but the
+     producer may still be filling the buffer on another CPU and moving the
+     head index.
+
+     To the producer it will show an upper bound as the consumer may be busy
+     emptying the buffer.
+
+ [3] To a third party, the order in which the writes to the indices by the
+     producer and consumer become visible cannot be guaranteed as they are
+     independent and may be made on different CPUs - so the result in such a
+     situation will merely be a guess, and may even be negative.
+
+
+===========================================
+USING MEMORY BARRIERS WITH CIRCULAR BUFFERS
+===========================================
+
+By using memory barriers in conjunction with circular buffers, you can avoid
+the need to:
+
+ (1) use a single lock to govern access to both ends of the buffer, thus
+     allowing the buffer to be filled and emptied at the same time; and
+
+ (2) use atomic counter operations.
+
+There are two sides to this: the producer that fills the buffer, and the
+consumer that empties it.  Only one thing should be filling a buffer at any one
+time, and only one thing should be emptying a buffer at any one time, but the
+two sides can operate simultaneously.
+
+
+THE PRODUCER
+------------
+
+The producer will look something like this:
+
+       spin_lock(&producer_lock);
+
+       unsigned long head = buffer->head;
+       unsigned long tail = ACCESS_ONCE(buffer->tail);
+
+       if (CIRC_SPACE(head, tail, buffer->size) >= 1) {
+               /* insert one item into the buffer */
+               struct item *item = buffer[head];
+
+               produce_item(item);
+
+               smp_wmb(); /* commit the item before incrementing the head */
+
+               buffer->head = (head + 1) & (buffer->size - 1);
+
+               /* wake_up() will make sure that the head is committed before
+                * waking anyone up */
+               wake_up(consumer);
+       }
+
+       spin_unlock(&producer_lock);
+
+This will instruct the CPU that the contents of the new item must be written
+before the head index makes it available to the consumer and then instructs the
+CPU that the revised head index must be written before the consumer is woken.
+
+Note that wake_up() doesn't have to be the exact mechanism used, but whatever
+is used must guarantee a (write) memory barrier between the update of the head
+index and the change of state of the consumer, if a change of state occurs.
+
+
+THE CONSUMER
+------------
+
+The consumer will look something like this:
+
+       spin_lock(&consumer_lock);
+
+       unsigned long head = ACCESS_ONCE(buffer->head);
+       unsigned long tail = buffer->tail;
+
+       if (CIRC_CNT(head, tail, buffer->size) >= 1) {
+               /* read index before reading contents at that index */
+               smp_read_barrier_depends();
+
+               /* extract one item from the buffer */
+               struct item *item = buffer[tail];
+
+               consume_item(item);
+
+               smp_mb(); /* finish reading descriptor before incrementing tail */
+
+               buffer->tail = (tail + 1) & (buffer->size - 1);
+       }
+
+       spin_unlock(&consumer_lock);
+
+This will instruct the CPU to make sure the index is up to date before reading
+the new item, and then it shall make sure the CPU has finished reading the item
+before it writes the new tail pointer, which will erase the item.
+
+
+Note the use of ACCESS_ONCE() in both algorithms to read the opposition index.
+This prevents the compiler from discarding and reloading its cached value -
+which some compilers will do across smp_read_barrier_depends().  This isn't
+strictly needed if you can be sure that the opposition index will _only_ be
+used the once.
+
+
+===============
+FURTHER READING
+===============
+
+See also Documentation/memory-barriers.txt for a description of Linux's memory
+barrier facilities.
index b07add3467f1b4d84e07d95a43fece6b8ec7f83e..7764594778d43650afe3423055cd4bcabaf77c17 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 
 #include <linux/connector.h>
similarity index 66%
rename from Documentation/fb/imacfb.txt
rename to Documentation/fb/efifb.txt
index 316ec9bb7debd5f79ac76e9cbbea5f957ba25e74..a59916c29b3312cd4946a1d9a8da2331819e7845 100644 (file)
@@ -1,9 +1,9 @@
 
-What is imacfb?
+What is efifb?
 ===============
 
 This is a generic EFI platform driver for Intel based Apple computers.
-Imacfb is only for EFI booted Intel Macs.
+efifb is only for EFI booted Intel Macs.
 
 Supported Hardware
 ==================
@@ -16,16 +16,16 @@ MacMini
 How to use it?
 ==============
 
-Imacfb does not have any kind of autodetection of your machine.
+efifb does not have any kind of autodetection of your machine.
 You have to add the following kernel parameters in your elilo.conf:
        Macbook :
-               video=imacfb:macbook
+               video=efifb:macbook
        MacMini :
-               video=imacfb:mini
+               video=efifb:mini
        Macbook Pro 15", iMac 17" :
-               video=imacfb:i17
+               video=efifb:i17
        Macbook Pro 17", iMac 20" :
-               video=imacfb:i20
+               video=efifb:i20
 
 --
 Edgar Hucek <gimli@dark-green.com>
index ed511af0f79a5697d560a00d37ee26f601198673..05df0b7514b6b884d38c545f8bb838cdfeb1d162 100644 (file)
@@ -589,3 +589,26 @@ Why:       Useful in 2003, implementation is a hack.
        Generally invoked by accident today.
        Seen as doing more harm than good.
 Who:   Len Brown <len.brown@intel.com>
+
+----------------------------
+
+What:  video4linux /dev/vtx teletext API support
+When:  2.6.35
+Files: drivers/media/video/saa5246a.c drivers/media/video/saa5249.c
+       include/linux/videotext.h
+Why:   The vtx device nodes have been superseded by vbi device nodes
+       for many years. No applications exist that use the vtx support.
+       Of the two i2c drivers that actually support this API the saa5249
+       has been impossible to use for a year now and no known hardware
+       that supports this device exists. The saa5246a is theoretically
+       supported by the old mxb boards, but it never actually worked.
+
+       In summary: there is no hardware that can use this API and there
+       are no applications actually implementing this API.
+
+       The vtx support still reserves minors 192-223 and we would really
+       like to reuse those for upcoming new functionality. In the unlikely
+       event that new hardware appears that wants to use the functionality
+       provided by the vtx API, then that functionality should be build
+       around the sliced VBI API instead.
+Who:   Hans Verkuil <hverkuil@xs4all.nl>
index 3bae418c6ad3d51e8597485f15ef014a553a22b2..4303614b5add04f91461453882ecc77d719b32df 100644 (file)
@@ -16,6 +16,8 @@ befs.txt
        - information about the BeOS filesystem for Linux.
 bfs.txt
        - info for the SCO UnixWare Boot Filesystem (BFS).
+ceph.txt
+       - info for the Ceph Distributed File System
 cifs.txt
        - description of the CIFS filesystem.
 coda.txt
index 57e0b80a52747c8ef9af5ddad113802e1c972c37..c0236e753bc854a5a26a9a514465e81819564ccd 100644 (file)
@@ -37,6 +37,15 @@ For Plan 9 From User Space applications (http://swtch.com/plan9)
 
        mount -t 9p `namespace`/acme /mnt/9 -o trans=unix,uname=$USER
 
+For server running on QEMU host with virtio transport:
+
+       mount -t 9p -o trans=virtio <mount_tag> /mnt/9
+
+where mount_tag is the tag associated by the server to each of the exported
+mount points. Each 9P export is seen by the client as a virtio device with an
+associated "mount_tag" property. Available mount tags can be
+seen by reading /sys/bus/virtio/drivers/9pnet_virtio/virtio<n>/mount_tag files.
+
 OPTIONS
 =======
 
@@ -47,7 +56,7 @@ OPTIONS
                        fd      - used passed file descriptors for connection
                                 (see rfdno and wfdno)
                        virtio  - connect to the next virtio channel available
-                               (from lguest or KVM with trans_virtio module)
+                               (from QEMU with trans_virtio module)
                        rdma    - connect to a specified RDMA channel
 
   uname=name   user name to attempt mount as on the remote server.  The
@@ -85,7 +94,12 @@ OPTIONS
 
   port=n       port to connect to on the remote server
 
-  noextend     force legacy mode (no 9p2000.u semantics)
+  noextend     force legacy mode (no 9p2000.u or 9p2000.L semantics)
+
+  version=name Select 9P protocol version. Valid options are:
+                       9p2000          - Legacy mode (same as noextend)
+                       9p2000.u        - Use 9P2000.u protocol
+                       9p2000.L        - Use 9P2000.L protocol
 
   dfltuid      attempt to mount as a particular uid
 
diff --git a/Documentation/filesystems/ceph.txt b/Documentation/filesystems/ceph.txt
new file mode 100644 (file)
index 0000000..0660c9f
--- /dev/null
@@ -0,0 +1,140 @@
+Ceph Distributed File System
+============================
+
+Ceph is a distributed network file system designed to provide good
+performance, reliability, and scalability.
+
+Basic features include:
+
+ * POSIX semantics
+ * Seamless scaling from 1 to many thousands of nodes
+ * High availability and reliability.  No single point of failure.
+ * N-way replication of data across storage nodes
+ * Fast recovery from node failures
+ * Automatic rebalancing of data on node addition/removal
+ * Easy deployment: most FS components are userspace daemons
+
+Also,
+ * Flexible snapshots (on any directory)
+ * Recursive accounting (nested files, directories, bytes)
+
+In contrast to cluster filesystems like GFS, OCFS2, and GPFS that rely
+on symmetric access by all clients to shared block devices, Ceph
+separates data and metadata management into independent server
+clusters, similar to Lustre.  Unlike Lustre, however, metadata and
+storage nodes run entirely as user space daemons.  Storage nodes
+utilize btrfs to store data objects, leveraging its advanced features
+(checksumming, metadata replication, etc.).  File data is striped
+across storage nodes in large chunks to distribute workload and
+facilitate high throughputs.  When storage nodes fail, data is
+re-replicated in a distributed fashion by the storage nodes themselves
+(with some minimal coordination from a cluster monitor), making the
+system extremely efficient and scalable.
+
+Metadata servers effectively form a large, consistent, distributed
+in-memory cache above the file namespace that is extremely scalable,
+dynamically redistributes metadata in response to workload changes,
+and can tolerate arbitrary (well, non-Byzantine) node failures.  The
+metadata server takes a somewhat unconventional approach to metadata
+storage to significantly improve performance for common workloads.  In
+particular, inodes with only a single link are embedded in
+directories, allowing entire directories of dentries and inodes to be
+loaded into its cache with a single I/O operation.  The contents of
+extremely large directories can be fragmented and managed by
+independent metadata servers, allowing scalable concurrent access.
+
+The system offers automatic data rebalancing/migration when scaling
+from a small cluster of just a few nodes to many hundreds, without
+requiring an administrator carve the data set into static volumes or
+go through the tedious process of migrating data between servers.
+When the file system approaches full, new nodes can be easily added
+and things will "just work."
+
+Ceph includes flexible snapshot mechanism that allows a user to create
+a snapshot on any subdirectory (and its nested contents) in the
+system.  Snapshot creation and deletion are as simple as 'mkdir
+.snap/foo' and 'rmdir .snap/foo'.
+
+Ceph also provides some recursive accounting on directories for nested
+files and bytes.  That is, a 'getfattr -d foo' on any directory in the
+system will reveal the total number of nested regular files and
+subdirectories, and a summation of all nested file sizes.  This makes
+the identification of large disk space consumers relatively quick, as
+no 'du' or similar recursive scan of the file system is required.
+
+
+Mount Syntax
+============
+
+The basic mount syntax is:
+
+ # mount -t ceph monip[:port][,monip2[:port]...]:/[subdir] mnt
+
+You only need to specify a single monitor, as the client will get the
+full list when it connects.  (However, if the monitor you specify
+happens to be down, the mount won't succeed.)  The port can be left
+off if the monitor is using the default.  So if the monitor is at
+1.2.3.4,
+
+ # mount -t ceph 1.2.3.4:/ /mnt/ceph
+
+is sufficient.  If /sbin/mount.ceph is installed, a hostname can be
+used instead of an IP address.
+
+
+
+Mount Options
+=============
+
+  ip=A.B.C.D[:N]
+       Specify the IP and/or port the client should bind to locally.
+       There is normally not much reason to do this.  If the IP is not
+       specified, the client's IP address is determined by looking at the
+       address it's connection to the monitor originates from.
+
+  wsize=X
+       Specify the maximum write size in bytes.  By default there is no
+       maximum.  Ceph will normally size writes based on the file stripe
+       size.
+
+  rsize=X
+       Specify the maximum readahead.
+
+  mount_timeout=X
+       Specify the timeout value for mount (in seconds), in the case
+       of a non-responsive Ceph file system.  The default is 30
+       seconds.
+
+  rbytes
+       When stat() is called on a directory, set st_size to 'rbytes',
+       the summation of file sizes over all files nested beneath that
+       directory.  This is the default.
+
+  norbytes
+       When stat() is called on a directory, set st_size to the
+       number of entries in that directory.
+
+  nocrc
+       Disable CRC32C calculation for data writes.  If set, the storage node
+       must rely on TCP's error correction to detect data corruption
+       in the data payload.
+
+  noasyncreaddir
+       Disable client's use its local cache to satisfy readdir
+       requests.  (This does not change correctness; the client uses
+       cached metadata only when a lease or capability ensures it is
+       valid.)
+
+
+More Information
+================
+
+For more information on Ceph, see the home page at
+       http://ceph.newdream.net/
+
+The Linux kernel client source tree is available at
+       git://ceph.newdream.net/git/ceph-client.git
+       git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git
+
+and the source for the full system is at
+       git://ceph.newdream.net/git/ceph.git
index a4f30faa4f1f73ad4622b333007525f9134c21c4..1e359b62c40a2eb67e04ab299012760587cab29a 100644 (file)
@@ -316,7 +316,7 @@ address           perms offset  dev   inode      pathname
 08049000-0804a000 rw-p 00001000 03:00 8312       /opt/test
 0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
 a7cb1000-a7cb2000 ---p 00000000 00:00 0
-a7cb2000-a7eb2000 rw-p 00000000 00:00 0          [threadstack:001ff4b4]
+a7cb2000-a7eb2000 rw-p 00000000 00:00 0
 a7eb2000-a7eb3000 ---p 00000000 00:00 0
 a7eb3000-a7ed5000 rw-p 00000000 00:00 0
 a7ed5000-a8008000 r-xp 00000000 03:00 4222       /lib/libc.so.6
@@ -352,7 +352,6 @@ is not associated with a file:
  [stack]                  = the stack of the main process
  [vdso]                   = the "virtual dynamic shared object",
                             the kernel system call handler
- [threadstack:xxxxxxxx]   = the stack of the thread, xxxxxxxx is the stack size
 
  or if empty, the mapping is anonymous.
 
index 3015da0c6b2a253c4a1b65559a8a8ec82b24e3e9..fe09a2cb1858de038b39746bdc862af3f6dc21bc 100644 (file)
@@ -82,11 +82,13 @@ tmpfs has a mount option to set the NUMA memory allocation policy for
 all files in that instance (if CONFIG_NUMA is enabled) - which can be
 adjusted on the fly via 'mount -o remount ...'
 
-mpol=default             prefers to allocate memory from the local node
+mpol=default             use the process allocation policy
+                         (see set_mempolicy(2))
 mpol=prefer:Node         prefers to allocate memory from the given Node
 mpol=bind:NodeList       allocates memory only from nodes in NodeList
 mpol=interleave          prefers to allocate from each node in turn
 mpol=interleave:NodeList allocates from each node of NodeList in turn
+mpol=local              prefers to allocate memory from the local node
 
 NodeList format is a comma-separated list of decimal numbers and ranges,
 a range being two hyphen-separated decimal numbers, the smallest and
@@ -134,3 +136,5 @@ Author:
    Christoph Rohland <cr@sap.com>, 1.12.01
 Updated:
    Hugh Dickins, 4 June 2007
+Updated:
+   KOSAKI Motohiro, 16 Mar 2010
index 3219ee0dbfef1eab9493253d6307acd7bb282019..5ebf5af1d71606ae3d6d31557f97ce7f3077add7 100644 (file)
@@ -74,6 +74,11 @@ structure at all.  You should use this to keep device-specific data.
        /* retrieve the value */
        void *i2c_get_clientdata(const struct i2c_client *client);
 
+Note that starting with kernel 2.6.34, you don't have to set the `data' field
+to NULL in remove() or if probe() failed anymore. The i2c-core does this
+automatically on these occasions. Those are also the only times the core will
+touch this field.
+
 
 Accessing the client
 ====================
index a10c3b6ba7c427152706811ab960bb17a0d53290..56941ae1f5dbd2b161f7871ad3959f46ae227f89 100644 (file)
@@ -333,14 +333,14 @@ byte 0:
 byte 1:
 
    bit   7   6   5   4   3   2   1   0
-        x15 x14 x13 x12 x11 x10 x9  x8
+         .   .   .   .   .  x10 x9  x8
 
 byte 2:
 
    bit   7   6   5   4   3   2   1   0
         x7  x6  x5  x4  x4  x2  x1  x0
 
-         x15..x0 = absolute x value (horizontal)
+         x10..x0 = absolute x value (horizontal)
 
 byte 3:
 
@@ -350,14 +350,14 @@ byte 3:
 byte 4:
 
    bit   7   6   5   4   3   2   1   0
-        y15 y14 y13 y12 y11 y10 y8  y8
+         .   .   .   .   .   .  y9  y8
 
 byte 5:
 
    bit   7   6   5   4   3   2   1   0
         y7  y6  y5  y4  y3  y2  y1  y0
 
-         y15..y0 = absolute y value (vertical)
+         y9..y0 = absolute y value (vertical)
 
 
 4.2.2 Two finger touch
index 8490480ce4327beb95bb5936c8d55609a7ce7c82..c0fc1c75fd88654ad7dc3a901381bf01124cdca7 100644 (file)
@@ -68,6 +68,22 @@ like:
    SYN_MT_REPORT
    SYN_REPORT
 
+Here is the sequence after lifting one of the fingers:
+
+   ABS_MT_POSITION_X
+   ABS_MT_POSITION_Y
+   SYN_MT_REPORT
+   SYN_REPORT
+
+And here is the sequence after lifting the remaining finger:
+
+   SYN_MT_REPORT
+   SYN_REPORT
+
+If the driver reports one of BTN_TOUCH or ABS_PRESSURE in addition to the
+ABS_MT events, the last SYN_MT_REPORT event may be omitted. Otherwise, the
+last SYN_REPORT will be dropped by the input core, resulting in no
+zero-finger event reaching userland.
 
 Event Semantics
 ---------------
@@ -217,11 +233,6 @@ where examples can be found.
 difference between the contact position and the approaching tool position
 could be used to derive tilt.
 [2] The list can of course be extended.
-[3] The multi-touch X driver is currently in the prototyping stage. At the
-time of writing (April 2009), the MT protocol is not yet merged, and the
-prototype implements finger matching, basic mouse support and two-finger
-scrolling. The project aims at improving the quality of current multi-touch
-functionality available in the Synaptics X driver, and in addition
-implement more advanced gestures.
+[3] Multitouch X driver project: http://bitmath.org/code/multitouch/.
 [4] See the section on event computation.
 [5] See the section on finger tracking.
index 35c9b51d20ea850b9ae58f16413e5a7595bcdb45..dd5806f4fcc448cdbc7d369e5bcd225d5aa2e0be 100644 (file)
@@ -291,6 +291,7 @@ Code  Seq#(hex)     Include File            Comments
 0x92   00-0F   drivers/usb/mon/mon_bin.c
 0x93   60-7F   linux/auto_fs.h
 0x94   all     fs/btrfs/ioctl.h
+0x97   00-7F   fs/ceph/ioctl.h         Ceph file system
 0x99   00-0F                           537-Addinboard driver
                                        <mailto:buk@buks.ipn.de>
 0xA0   all     linux/sdp/sdp.h         Industrial Device Project
index e4cbca58536c9f3ab4236f4db78eb22cacc993af..567b7a8eb878e74bd064c6ab71c36325e045f4d8 100644 (file)
@@ -320,15 +320,12 @@ and is between 256 and 4096 characters. It is defined in the file
        amd_iommu=      [HW,X86-84]
                        Pass parameters to the AMD IOMMU driver in the system.
                        Possible values are:
-                       isolate - enable device isolation (each device, as far
-                                 as possible, will get its own protection
-                                 domain) [default]
-                       share - put every device behind one IOMMU into the
-                               same protection domain
                        fullflush - enable flushing of IO/TLB entries when
                                    they are unmapped. Otherwise they are
                                    flushed before they will be reused, which
                                    is a lot of faster
+                       off       - do not initialize any AMD IOMMU found in
+                                   the system
 
        amijoy.map=     [HW,JOY] Amiga joystick support
                        Map of devices attached to JOY0DAT and JOY1DAT
@@ -789,8 +786,12 @@ and is between 256 and 4096 characters. It is defined in the file
                        as early as possible in order to facilitate early
                        boot debugging.
 
-       ftrace_dump_on_oops
+       ftrace_dump_on_oops[=orig_cpu]
                        [FTRACE] will dump the trace buffers on oops.
+                       If no parameter is passed, ftrace will dump
+                       buffers of all CPUs, but if you pass orig_cpu, it will
+                       dump only the buffer of the CPU that triggered the
+                       oops.
 
        ftrace_filter=[function-list]
                        [FTRACE] Limit the functions traced by the function
@@ -1199,7 +1200,7 @@ and is between 256 and 4096 characters. It is defined in the file
 
        libata.force=   [LIBATA] Force configurations.  The format is comma
                        separated list of "[ID:]VAL" where ID is
-                       PORT[:DEVICE].  PORT and DEVICE are decimal numbers
+                       PORT[.DEVICE].  PORT and DEVICE are decimal numbers
                        matching port, link or device.  Basically, it matches
                        the ATA ID string printed on console by libata.  If
                        the whole ID part is omitted, the last PORT and DEVICE
index bdb13817e1e9ebc0ad667482deb4e2107361961b..3ab2472509cbbc86996b31d809543ca2dd93f2c9 100644 (file)
@@ -59,37 +59,56 @@ nice to have in other objects.  The C language does not allow for the
 direct expression of inheritance, so other techniques - such as structure
 embedding - must be used.
 
-So, for example, the UIO code has a structure that defines the memory
-region associated with a uio device:
+(As an aside, for those familiar with the kernel linked list implementation,
+this is analogous as to how "list_head" structs are rarely useful on
+their own, but are invariably found embedded in the larger objects of
+interest.)
 
-struct uio_mem {
+So, for example, the UIO code in drivers/uio/uio.c has a structure that
+defines the memory region associated with a uio device:
+
+    struct uio_map {
        struct kobject kobj;
-       unsigned long addr;
-       unsigned long size;
-       int memtype;
-       void __iomem *internal_addr;
-};
+       struct uio_mem *mem;
+    };
 
-If you have a struct uio_mem structure, finding its embedded kobject is
+If you have a struct uio_map structure, finding its embedded kobject is
 just a matter of using the kobj member.  Code that works with kobjects will
 often have the opposite problem, however: given a struct kobject pointer,
 what is the pointer to the containing structure?  You must avoid tricks
 (such as assuming that the kobject is at the beginning of the structure)
 and, instead, use the container_of() macro, found in <linux/kernel.h>:
 
-       container_of(pointer, type, member)
+    container_of(pointer, type, member)
+
+where:
+
+  * "pointer" is the pointer to the embedded kobject,
+  * "type" is the type of the containing structure, and
+  * "member" is the name of the structure field to which "pointer" points.
+
+The return value from container_of() is a pointer to the corresponding
+container type. So, for example, a pointer "kp" to a struct kobject
+embedded *within* a struct uio_map could be converted to a pointer to the
+*containing* uio_map structure with:
+
+    struct uio_map *u_map = container_of(kp, struct uio_map, kobj);
+
+For convenience, programmers often define a simple macro for "back-casting"
+kobject pointers to the containing type.  Exactly this happens in the
+earlier drivers/uio/uio.c, as you can see here:
+
+    struct uio_map {
+        struct kobject kobj;
+        struct uio_mem *mem;
+    };
 
-where pointer is the pointer to the embedded kobject, type is the type of
-the containing structure, and member is the name of the structure field to
-which pointer points.  The return value from container_of() is a pointer to
-the given type. So, for example, a pointer "kp" to a struct kobject
-embedded within a struct uio_mem could be converted to a pointer to the
-containing uio_mem structure with:
+    #define to_map(map) container_of(map, struct uio_map, kobj)
 
-    struct uio_mem *u_mem = container_of(kp, struct uio_mem, kobj);
+where the macro argument "map" is a pointer to the struct kobject in
+question.  That macro is subsequently invoked with:
 
-Programmers often define a simple macro for "back-casting" kobject pointers
-to the containing type.
+    struct uio_map *map = to_map(kobj);
 
 
 Initialization of kobjects
@@ -387,4 +406,5 @@ called, and the objects in the former circle release each other.
 Example code to copy from
 
 For a more complete example of using ksets and kobjects properly, see the
-sample/kobject/kset-example.c code.
+example programs samples/kobject/{kobject-example.c,kset-example.c},
+which will be built as loadable modules if you select CONFIG_SAMPLE_KOBJECT.
index 2f9115c0ae627f044f4a22266cd7037c9ba10fd8..61c291cddf1873f1a17ac7d65e4404d6612b7b0d 100644 (file)
@@ -165,8 +165,8 @@ the user entry_handler invocation is also skipped.
 
 1.4 How Does Jump Optimization Work?
 
-If you configured your kernel with CONFIG_OPTPROBES=y (currently
-this option is supported on x86/x86-64, non-preemptive kernel) and
+If your kernel is built with CONFIG_OPTPROBES=y (currently this flag
+is automatically set 'y' on x86/x86-64, non-preemptive kernel) and
 the "debug.kprobes_optimization" kernel parameter is set to 1 (see
 sysctl(8)), Kprobes tries to reduce probe-hit overhead by using a jump
 instruction instead of a breakpoint instruction at each probepoint.
@@ -271,8 +271,6 @@ tweak the kernel's execution path, you need to suppress optimization,
 using one of the following techniques:
 - Specify an empty function for the kprobe's post_handler or break_handler.
  or
-- Config CONFIG_OPTPROBES=n.
- or
 - Execute 'sysctl -w debug.kprobes_optimization=n'
 
 2. Architectures Supported
@@ -307,10 +305,6 @@ it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO),
 so you can use "objdump -d -l vmlinux" to see the source-to-object
 code mapping.
 
-If you want to reduce probing overhead, set "Kprobes jump optimization
-support" (CONFIG_OPTPROBES) to "y". You can find this option under the
-"Kprobes" line.
-
 4. API Reference
 
 The Kprobes API includes a "register" function and an "unregister"
index 7f5809eddee62eaf524103eeda485f5e553d5a01..631ad2f1b229c1d020a9a8b746d8f6cbe72f4531 100644 (file)
@@ -3,6 +3,7 @@
                         ============================
 
 By: David Howells <dhowells@redhat.com>
+    Paul E. McKenney <paulmck@linux.vnet.ibm.com>
 
 Contents:
 
@@ -60,6 +61,10 @@ Contents:
 
      - And then there's the Alpha.
 
+ (*) Example uses.
+
+     - Circular buffers.
+
  (*) References.
 
 
@@ -2226,6 +2231,21 @@ The Alpha defines the Linux kernel's memory barrier model.
 See the subsection on "Cache Coherency" above.
 
 
+============
+EXAMPLE USES
+============
+
+CIRCULAR BUFFERS
+----------------
+
+Memory barriers can be used to implement circular buffering without the need
+of a lock to serialise the producer with the consumer.  See:
+
+       Documentation/circular-buffers.txt
+
+for details.
+
+
 ==========
 REFERENCES
 ==========
index 6d8af1ac56c410f11d0e85863a180884082c21ee..5aba7a33aeeb7bacedb28a596e4cdaed848d0162 100644 (file)
@@ -6,3 +6,5 @@ hostprogs-y := ifenslave
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
+
+obj-m := timestamping/
diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
new file mode 100644 (file)
index 0000000..7ee770b
--- /dev/null
@@ -0,0 +1,143 @@
+       STMicroelectronics 10/100/1000 Synopsys Ethernet driver
+
+Copyright (C) 2007-2010  STMicroelectronics Ltd
+Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+
+This is the driver for the MAC 10/100/1000 on-chip Ethernet controllers
+(Synopsys IP blocks); it has been fully tested on STLinux platforms.
+
+Currently this network device driver is for all STM embedded MAC/GMAC
+(7xxx SoCs).
+
+DWC Ether MAC 10/100/1000 Universal version 3.41a and DWC Ether MAC 10/100
+Universal version 4.0 have been used for developing the first code
+implementation.
+
+Please, for more information also visit: www.stlinux.com
+
+1) Kernel Configuration
+The kernel configuration option is STMMAC_ETH:
+ Device Drivers ---> Network device support ---> Ethernet (1000 Mbit) --->
+ STMicroelectronics 10/100/1000 Ethernet driver (STMMAC_ETH)
+
+2) Driver parameters list:
+       debug: message level (0: no output, 16: all);
+       phyaddr: to manually provide the physical address to the PHY device;
+       dma_rxsize: DMA rx ring size;
+       dma_txsize: DMA tx ring size;
+       buf_sz: DMA buffer size;
+       tc: control the HW FIFO threshold;
+       tx_coe: Enable/Disable Tx Checksum Offload engine;
+       watchdog: transmit timeout (in milliseconds);
+       flow_ctrl: Flow control ability [on/off];
+       pause: Flow Control Pause Time;
+       tmrate: timer period (only if timer optimisation is configured).
+
+3) Command line options
+Driver parameters can be also passed in command line by using:
+       stmmaceth=dma_rxsize:128,dma_txsize:512
+
+4) Driver information and notes
+
+4.1) Transmit process
+The xmit method is invoked when the kernel needs to transmit a packet; it sets
+the descriptors in the ring and informs the DMA engine that there is a packet
+ready to be transmitted.
+Once the controller has finished transmitting the packet, an interrupt is
+triggered; So the driver will be able to release the socket buffers.
+By default, the driver sets the NETIF_F_SG bit in the features field of the
+net_device structure enabling the scatter/gather feature.
+
+4.2) Receive process
+When one or more packets are received, an interrupt happens. The interrupts
+are not queued so the driver has to scan all the descriptors in the ring during
+the receive process.
+This is based on NAPI so the interrupt handler signals only if there is work to be
+done, and it exits.
+Then the poll method will be scheduled at some future point.
+The incoming packets are stored, by the DMA, in a list of pre-allocated socket
+buffers in order to avoid the memcpy (Zero-copy).
+
+4.3) Timer-Driver Interrupt
+Instead of having the device that asynchronously notifies the frame receptions, the
+driver configures a timer to generate an interrupt at regular intervals.
+Based on the granularity of the timer, the frames that are received by the device
+will experience different levels of latency. Some NICs have dedicated timer
+device to perform this task. STMMAC can use either the RTC device or the TMU
+channel 2  on STLinux platforms.
+The timers frequency can be passed to the driver as parameter; when change it,
+take care of both hardware capability and network stability/performance impact.
+Several performance tests on STM platforms showed this optimisation allows to spare
+the CPU while having the maximum throughput.
+
+4.4) WOL
+Wake up on Lan feature through Magic Frame is only supported for the GMAC
+core.
+
+4.5) DMA descriptors
+Driver handles both normal and enhanced descriptors. The latter has been only
+tested on DWC Ether MAC 10/100/1000 Universal version 3.41a.
+
+4.6) Ethtool support
+Ethtool is supported. Driver statistics and internal errors can be taken using:
+ethtool -S ethX command. It is possible to dump registers etc.
+
+4.7) Jumbo and Segmentation Offloading
+Jumbo frames are supported and tested for the GMAC.
+The GSO has been also added but it's performed in software.
+LRO is not supported.
+
+4.8) Physical
+The driver is compatible with PAL to work with PHY and GPHY devices.
+
+4.9) Platform information
+Several information came from the platform; please refer to the
+driver's Header file in include/linux directory.
+
+struct plat_stmmacenet_data {
+        int bus_id;
+        int pbl;
+        int has_gmac;
+        void (*fix_mac_speed)(void *priv, unsigned int speed);
+        void (*bus_setup)(unsigned long ioaddr);
+#ifdef CONFIG_STM_DRIVERS
+        struct stm_pad_config *pad_config;
+#endif
+        void *bsp_priv;
+};
+
+Where:
+- pbl (Programmable Burst Length) is maximum number of
+  beats to be transferred in one DMA transaction.
+  GMAC also enables the 4xPBL by default.
+- fix_mac_speed and bus_setup are used to configure internal target
+  registers (on STM platforms);
+- has_gmac: GMAC core is on board (get it at run-time in the next step);
+- bus_id: bus identifier.
+
+struct plat_stmmacphy_data {
+        int bus_id;
+        int phy_addr;
+        unsigned int phy_mask;
+        int interface;
+        int (*phy_reset)(void *priv);
+        void *priv;
+};
+
+Where:
+- bus_id: bus identifier;
+- phy_addr: physical address used for the attached phy device;
+            set it to -1 to get it at run-time;
+- interface: physical MII interface mode;
+- phy_reset: hook to reset HW function.
+
+TODO:
+- Continue to make the driver more generic and suitable for other Synopsys
+  Ethernet controllers used on other architectures (i.e. ARM).
+- 10G controllers are not supported.
+- MAC uses Normal descriptors and GMAC uses enhanced ones.
+  This is a limit that should be reviewed. MAC could want to
+  use the enhanced structure.
+- Checksumming: Rx/Tx csum is done in HW in case of GMAC only.
+- Review the timer optimisation code to use an embedded device that seems to be
+  available in new chip generations.
index 0e58b4539176a7e04c78c15bdcfde7b14e3f7c64..e8c8f4f06c67f104523ae9c4f9bafbf659d5e139 100644 (file)
@@ -41,11 +41,12 @@ SOF_TIMESTAMPING_SOFTWARE:     return system time stamp generated in
 SOF_TIMESTAMPING_TX/RX determine how time stamps are generated.
 SOF_TIMESTAMPING_RAW/SYS determine how they are reported in the
 following control message:
-    struct scm_timestamping {
-           struct timespec systime;
-           struct timespec hwtimetrans;
-           struct timespec hwtimeraw;
-    };
+
+struct scm_timestamping {
+       struct timespec systime;
+       struct timespec hwtimetrans;
+       struct timespec hwtimeraw;
+};
 
 recvmsg() can be used to get this control message for regular incoming
 packets. For send time stamps the outgoing packet is looped back to
@@ -87,12 +88,13 @@ by the network device and will be empty without that support.
 SIOCSHWTSTAMP:
 
 Hardware time stamping must also be initialized for each device driver
-that is expected to do hardware time stamping. The parameter is:
+that is expected to do hardware time stamping. The parameter is defined in
+/include/linux/net_tstamp.h as:
 
 struct hwtstamp_config {
-    int flags;           /* no flags defined right now, must be zero */
-    int tx_type;         /* HWTSTAMP_TX_* */
-    int rx_filter;       /* HWTSTAMP_FILTER_* */
+       int flags;      /* no flags defined right now, must be zero */
+       int tx_type;    /* HWTSTAMP_TX_* */
+       int rx_filter;  /* HWTSTAMP_FILTER_* */
 };
 
 Desired behavior is passed into the kernel and to a specific device by
@@ -139,42 +141,56 @@ enum {
        /* time stamp any incoming packet */
        HWTSTAMP_FILTER_ALL,
 
-        /* return value: time stamp all packets requested plus some others */
-        HWTSTAMP_FILTER_SOME,
+       /* return value: time stamp all packets requested plus some others */
+       HWTSTAMP_FILTER_SOME,
 
        /* PTP v1, UDP, any kind of event packet */
        HWTSTAMP_FILTER_PTP_V1_L4_EVENT,
 
-        ...
+       /* for the complete list of values, please check
+        * the include file /include/linux/net_tstamp.h
+        */
 };
 
 
 DEVICE IMPLEMENTATION
 
 A driver which supports hardware time stamping must support the
-SIOCSHWTSTAMP ioctl. Time stamps for received packets must be stored
-in the skb with skb_hwtstamp_set().
+SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with
+the actual values as described in the section on SIOCSHWTSTAMP.
+
+Time stamps for received packets must be stored in the skb. To get a pointer
+to the shared time stamp structure of the skb call skb_hwtstamps(). Then
+set the time stamps in the structure:
+
+struct skb_shared_hwtstamps {
+       /* hardware time stamp transformed into duration
+        * since arbitrary point in time
+        */
+       ktime_t hwtstamp;
+       ktime_t syststamp; /* hwtstamp transformed to system time base */
+};
 
 Time stamps for outgoing packets are to be generated as follows:
-- In hard_start_xmit(), check if skb_hwtstamp_check_tx_hardware()
-  returns non-zero. If yes, then the driver is expected
-  to do hardware time stamping.
+- In hard_start_xmit(), check if skb_tx(skb)->hardware is set no-zero.
+  If yes, then the driver is expected to do hardware time stamping.
 - If this is possible for the skb and requested, then declare
-  that the driver is doing the time stamping by calling
-  skb_hwtstamp_tx_in_progress(). A driver not supporting
-  hardware time stamping doesn't do that. A driver must never
-  touch sk_buff::tstamp! It is used to store how time stamping
-  for an outgoing packets is to be done.
+  that the driver is doing the time stamping by setting the field
+  skb_tx(skb)->in_progress non-zero. You might want to keep a pointer
+  to the associated skb for the next step and not free the skb. A driver
+  not supporting hardware time stamping doesn't do that. A driver must
+  never touch sk_buff::tstamp! It is used to store software generated
+  time stamps by the network subsystem.
 - As soon as the driver has sent the packet and/or obtained a
   hardware time stamp for it, it passes the time stamp back by
   calling skb_hwtstamp_tx() with the original skb, the raw
-  hardware time stamp and a handle to the device (necessary
-  to convert the hardware time stamp to system time). If obtaining
-  the hardware time stamp somehow fails, then the driver should
-  not fall back to software time stamping. The rationale is that
-  this would occur at a later time in the processing pipeline
-  than other software time stamping and therefore could lead
-  to unexpected deltas between time stamps.
-- If the driver did not call skb_hwtstamp_tx_in_progress(), then
+  hardware time stamp. skb_hwtstamp_tx() clones the original skb and
+  adds the timestamps, therefore the original skb has to be freed now.
+  If obtaining the hardware time stamp somehow fails, then the driver
+  should not fall back to software time stamping. The rationale is that
+  this would occur at a later time in the processing pipeline than other
+  software time stamping and therefore could lead to unexpected deltas
+  between time stamps.
+- If the driver did not call set skb_tx(skb)->in_progress, then
   dev_hard_start_xmit() checks whether software time stamping
   is wanted as fallback and potentially generates the time stamp.
index 2a1489fdc0361b8e6b134981645800ba05e7e628..e79973443e9fdcbe096445f4a13b102435a20ac6 100644 (file)
@@ -1,6 +1,13 @@
-CPPFLAGS = -I../../../include
+# kbuild trick to avoid linker error. Can be omitted if a module is built.
+obj- := dummy.o
 
-timestamping: timestamping.c
+# List of programs to build
+hostprogs-y := timestamping
+
+# Tell kbuild to always build the programs
+always := $(hostprogs-y)
+
+HOSTCFLAGS_timestamping.o += -I$(objtree)/usr/include
 
 clean:
        rm -f timestamping
index bab619a482145e9a08ecc62f674d9c6bb05110cc..8ba82bfe6a33c57d54adcde8d7c3e1977926d565 100644 (file)
@@ -41,9 +41,9 @@
 #include <arpa/inet.h>
 #include <net/if.h>
 
-#include "asm/types.h"
-#include "linux/net_tstamp.h"
-#include "linux/errqueue.h"
+#include <asm/types.h>
+#include <linux/net_tstamp.h>
+#include <linux/errqueue.h>
 
 #ifndef SO_TIMESTAMPING
 # define SO_TIMESTAMPING         37
@@ -164,7 +164,7 @@ static void printpacket(struct msghdr *msg, int res,
 
        gettimeofday(&now, 0);
 
-       printf("%ld.%06ld: received %s data, %d bytes from %s, %d bytes control messages\n",
+       printf("%ld.%06ld: received %s data, %d bytes from %s, %zu bytes control messages\n",
               (long)now.tv_sec, (long)now.tv_usec,
               (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
               res,
@@ -173,7 +173,7 @@ static void printpacket(struct msghdr *msg, int res,
        for (cmsg = CMSG_FIRSTHDR(msg);
             cmsg;
             cmsg = CMSG_NXTHDR(msg, cmsg)) {
-               printf("   cmsg len %d: ", cmsg->cmsg_len);
+               printf("   cmsg len %zu: ", cmsg->cmsg_len);
                switch (cmsg->cmsg_level) {
                case SOL_SOCKET:
                        printf("SOL_SOCKET ");
index 6e37be1eeb2d2cc190780db3d01829acabbf950f..4f8930263dd98035593628228bcfad8b4bcddee7 100644 (file)
@@ -21,6 +21,15 @@ Required properties:
 - fsl,qe-num-snums: define how many serial number(SNUM) the QE can use for the
   threads.
 
+Optional properties:
+- fsl,firmware-phandle:
+    Usage: required only if there is no fsl,qe-firmware child node
+    Value type: <phandle>
+    Definition: Points to a firmware node (see "QE Firmware Node" below)
+        that contains the firmware that should be uploaded for this QE.
+        The compatible property for the firmware node should say,
+        "fsl,qe-firmware".
+
 Recommended properties
 - brg-frequency : the internal clock source frequency for baud-rate
   generators in Hz.
@@ -59,3 +68,48 @@ Example:
                reg = <0 c000>;
        };
      };
+
+* QE Firmware Node
+
+This node defines a firmware binary that is embedded in the device tree, for
+the purpose of passing the firmware from bootloader to the kernel, or from
+the hypervisor to the guest.
+
+The firmware node itself contains the firmware binary contents, a compatible
+property, and any firmware-specific properties.  The node should be placed
+inside a QE node that needs it.  Doing so eliminates the need for a
+fsl,firmware-phandle property.  Other QE nodes that need the same firmware
+should define an fsl,firmware-phandle property that points to the firmware node
+in the first QE node.
+
+The fsl,firmware property can be specified in the DTS (possibly using incbin)
+or can be inserted by the boot loader at boot time.
+
+Required properties:
+  - compatible
+      Usage: required
+      Value type: <string>
+      Definition: A standard property.  Specify a string that indicates what
+          kind of firmware it is.  For QE, this should be "fsl,qe-firmware".
+
+   - fsl,firmware
+      Usage: required
+      Value type: <prop-encoded-array>, encoded as an array of bytes
+      Definition: A standard property.  This property contains the firmware
+          binary "blob".
+
+Example:
+       qe1@e0080000 {
+               compatible = "fsl,qe";
+               qe_firmware:qe-firmware {
+                       compatible = "fsl,qe-firmware";
+                       fsl,firmware = [0x70 0xcd 0x00 0x00 0x01 0x46 0x45 ...];
+               };
+               ...
+       };
+
+       qe2@e0090000 {
+               compatible = "fsl,qe";
+               fsl,firmware-phandle = <&qe_firmware>;
+               ...
+       };
index aae8355d3166ddde11436ca5a21bd7e234e68806..221f38be98f47be1e682876ef55c2984a8484e76 100644 (file)
@@ -190,3 +190,61 @@ Example:
   for (node = rb_first(&mytree); node; node = rb_next(node))
        printk("key=%s\n", rb_entry(node, struct mytype, node)->keystring);
 
+Support for Augmented rbtrees
+-----------------------------
+
+Augmented rbtree is an rbtree with "some" additional data stored in each node.
+This data can be used to augment some new functionality to rbtree.
+Augmented rbtree is an optional feature built on top of basic rbtree
+infrastructure. rbtree user who wants this feature will have an augment
+callback function in rb_root initialized.
+
+This callback function will be called from rbtree core routines whenever
+a node has a change in one or both of its children. It is the responsibility
+of the callback function to recalculate the additional data that is in the
+rb node using new children information. Note that if this new additional
+data affects the parent node's additional data, then callback function has
+to handle it and do the recursive updates.
+
+
+Interval tree is an example of augmented rb tree. Reference -
+"Introduction to Algorithms" by Cormen, Leiserson, Rivest and Stein.
+More details about interval trees:
+
+Classical rbtree has a single key and it cannot be directly used to store
+interval ranges like [lo:hi] and do a quick lookup for any overlap with a new
+lo:hi or to find whether there is an exact match for a new lo:hi.
+
+However, rbtree can be augmented to store such interval ranges in a structured
+way making it possible to do efficient lookup and exact match.
+
+This "extra information" stored in each node is the maximum hi
+(max_hi) value among all the nodes that are its descendents. This
+information can be maintained at each node just be looking at the node
+and its immediate children. And this will be used in O(log n) lookup
+for lowest match (lowest start address among all possible matches)
+with something like:
+
+find_lowest_match(lo, hi, node)
+{
+       lowest_match = NULL;
+       while (node) {
+               if (max_hi(node->left) > lo) {
+                       // Lowest overlap if any must be on left side
+                       node = node->left;
+               } else if (overlap(lo, hi, node)) {
+                       lowest_match = node;
+                       break;
+               } else if (lo > node->lo) {
+                       // Lowest overlap if any must be on right side
+                       node = node->right;
+               } else {
+                       break;
+               }
+       }
+       return lowest_match;
+}
+
+Finding exact match will be to first find lowest match and then to follow
+successor nodes looking for exact match, until the start of a node is beyond
+the hi value we are looking for.
index 6f33593e59e21d898fa38fd59ce297a438dfbdf1..8239ebbcddce1d9b84689b8e1be530243bee5f83 100644 (file)
@@ -211,7 +211,7 @@ provide fair CPU time to each such task group.  For example, it may be
 desirable to first provide fair CPU time to each user on the system and then to
 each task belonging to a user.
 
-CONFIG_GROUP_SCHED strives to achieve exactly that.  It lets tasks to be
+CONFIG_CGROUP_SCHED strives to achieve exactly that.  It lets tasks to be
 grouped and divides CPU time fairly among such groups.
 
 CONFIG_RT_GROUP_SCHED permits to group real-time (i.e., SCHED_FIFO and
@@ -220,38 +220,11 @@ SCHED_RR) tasks.
 CONFIG_FAIR_GROUP_SCHED permits to group CFS (i.e., SCHED_NORMAL and
 SCHED_BATCH) tasks.
 
-At present, there are two (mutually exclusive) mechanisms to group tasks for
-CPU bandwidth control purposes:
-
- - Based on user id (CONFIG_USER_SCHED)
-
-   With this option, tasks are grouped according to their user id.
-
- - Based on "cgroup" pseudo filesystem (CONFIG_CGROUP_SCHED)
-
-   This options needs CONFIG_CGROUPS to be defined, and lets the administrator
+   These options need CONFIG_CGROUPS to be defined, and let the administrator
    create arbitrary groups of tasks, using the "cgroup" pseudo filesystem.  See
    Documentation/cgroups/cgroups.txt for more information about this filesystem.
 
-Only one of these options to group tasks can be chosen and not both.
-
-When CONFIG_USER_SCHED is defined, a directory is created in sysfs for each new
-user and a "cpu_share" file is added in that directory.
-
-       # cd /sys/kernel/uids
-       # cat 512/cpu_share             # Display user 512's CPU share
-       1024
-       # echo 2048 > 512/cpu_share     # Modify user 512's CPU share
-       # cat 512/cpu_share             # Display user 512's CPU share
-       2048
-       #
-
-CPU bandwidth between two users is divided in the ratio of their CPU shares.
-For example: if you would like user "root" to get twice the bandwidth of user
-"guest," then set the cpu_share for both the users such that "root"'s cpu_share
-is twice "guest"'s cpu_share.
-
-When CONFIG_CGROUP_SCHED is defined, a "cpu.shares" file is created for each
+When CONFIG_FAIR_GROUP_SCHED is defined, a "cpu.shares" file is created for each
 group created using the pseudo filesystem.  See example steps below to create
 task groups and modify their CPU share using the "cgroups" pseudo filesystem.
 
@@ -273,24 +246,3 @@ task groups and modify their CPU share using the "cgroups" pseudo filesystem.
 
        # #Launch gmplayer (or your favourite movie player)
        # echo <movie_player_pid> > multimedia/tasks
-
-8. Implementation note: user namespaces
-
-User namespaces are intended to be hierarchical.  But they are currently
-only partially implemented.  Each of those has ramifications for CFS.
-
-First, since user namespaces are hierarchical, the /sys/kernel/uids
-presentation is inadequate.  Eventually we will likely want to use sysfs
-tagging to provide private views of /sys/kernel/uids within each user
-namespace.
-
-Second, the hierarchical nature is intended to support completely
-unprivileged use of user namespaces.  So if using user groups, then
-we want the users in a user namespace to be children of the user
-who created it.
-
-That is currently unimplemented.  So instead, every user in a new
-user namespace will receive 1024 shares just like any user in the
-initial user namespace.  Note that at the moment creation of a new
-user namespace requires each of CAP_SYS_ADMIN, CAP_SETUID, and
-CAP_SETGID.
index 86eabe6c3419fd4f26aba47a090ecc1caff9a1fd..605b0d40329d843f6c3b838cd4afa5e38438d31e 100644 (file)
@@ -126,23 +126,12 @@ priority!
 2.3 Basis for grouping tasks
 ----------------------------
 
-There are two compile-time settings for allocating CPU bandwidth. These are
-configured using the "Basis for grouping tasks" multiple choice menu under
-General setup > Group CPU Scheduler:
-
-a. CONFIG_USER_SCHED (aka "Basis for grouping tasks" =  "user id")
-
-This lets you use the virtual files under
-"/sys/kernel/uids/<uid>/cpu_rt_runtime_us" to control he CPU time reserved for
-each user .
-
-The other option is:
-
-.o CONFIG_CGROUP_SCHED (aka "Basis for grouping tasks" = "Control groups")
+Enabling CONFIG_RT_GROUP_SCHED lets you explicitly allocate real
+CPU bandwidth to task groups.
 
 This uses the /cgroup virtual file system and
 "/cgroup/<cgroup>/cpu.rt_runtime_us" to control the CPU time reserved for each
-control group instead.
+control group.
 
 For more information on working with control groups, you should read
 Documentation/cgroups/cgroups.txt as well.
@@ -161,8 +150,7 @@ For now, this can be simplified to just the following (but see Future plans):
 ===============
 
 There is work in progress to make the scheduling period for each group
-("/sys/kernel/uids/<uid>/cpu_rt_period_us" or
-"/cgroup/<cgroup>/cpu.rt_period_us" respectively) configurable as well.
+("/cgroup/<cgroup>/cpu.rt_period_us") configurable as well.
 
 The constraint on the period is that a subgroup must have a smaller or
 equal period to its parent. But realistically its not very useful _yet_
index f4dd3bf99d126e01e2150b0623f8264baede76f3..98d14cb8a85daf825af4b5e84f3396aa32b6fab6 100644 (file)
@@ -119,10 +119,18 @@ the codec slots 0 and 1 no matter what the hardware reports.
 
 Interrupt Handling
 ~~~~~~~~~~~~~~~~~~
-In rare but some cases, the interrupt isn't properly handled as
-default.  You would notice this by the DMA transfer error reported by
-ALSA PCM core, for example.  Using MSI might help in such a case.
-Pass `enable_msi=1` option for enabling MSI.
+HD-audio driver uses MSI as default (if available) since 2.6.33
+kernel as MSI works better on some machines, and in general, it's
+better for performance.  However, Nvidia controllers showed bad
+regressions with MSI (especially in a combination with AMD chipset),
+thus we disabled MSI for them.
+
+There seem also still other devices that don't work with MSI.  If you
+see a regression wrt the sound quality (stuttering, etc) or a lock-up
+in the recent kernel, try to pass `enable_msi=0` option to disable
+MSI.  If it works, you can add the known bad device to the blacklist
+defined in hda_intel.c.  In such a case, please report and give the
+patch back to the upstream developer. 
 
 
 HD-AUDIO CODEC
index 10abd3773e49122aab0dfad27f7cb2c91b8d5d08..16feda9014692a87a4996bf51d759ab9e7500ee5 100644 (file)
@@ -58,7 +58,7 @@ static void transfer(int fd)
        };
 
        ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
-       if (ret == 1)
+       if (ret < 1)
                pabort("can't send spi message");
 
        for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {
index 5effa5bd993bb47fd9d02d4acd7d4e5c75cb6b78..e213f45cf9d7505c9c9e1fbd088eb91cd83292f4 100644 (file)
@@ -18,16 +18,15 @@ Rules on what kind of patches are accepted, and which ones are not, into the
  - It cannot contain any "trivial" fixes in it (spelling changes,
    whitespace cleanups, etc).
  - It must follow the Documentation/SubmittingPatches rules.
- - It or an equivalent fix must already exist in Linus' tree.  Quote the
-   respective commit ID in Linus' tree in your patch submission to -stable.
+ - It or an equivalent fix must already exist in Linus' tree (upstream).
 
 
 Procedure for submitting patches to the -stable tree:
 
  - Send the patch, after verifying that it follows the above rules, to
-   stable@kernel.org.
- - To have the patch automatically included in the stable tree, add the
  the tag
+   stable@kernel.org.  You must note the upstream commit ID in the changelog
+   of your submission.
- To have the patch automatically included in the stable tree, add the tag
      Cc: stable@kernel.org
    in the sign-off area. Once the patch is merged it will be applied to
    the stable tree without anything else needing to be done by the author
index 02ac6ed38b2d0ba73c44298484b7d7bac540dae2..778ddf38b82cab70ecacf5739f723cfd45a64673 100644 (file)
@@ -90,7 +90,8 @@ In order to facilitate early boot debugging, use boot option:
 
        trace_event=[event-list]
 
-The format of this boot option is the same as described in section 2.1.
+event-list is a comma separated list of events. See section 2.1 for event
+format.
 
 3. Defining an event-enabled tracepoint
 =======================================
index 03485bfbd7975792f50d54dabf77533938f255c9..557c1edeccaf72535464298743cddd3c8eb01bea 100644 (file)
@@ -155,6 +155,9 @@ of ftrace. Here is a list of some of the key files:
        to be traced. Echoing names of functions into this file
        will limit the trace to only those functions.
 
+       This interface also allows for commands to be used. See the
+       "Filter commands" section for more details.
+
   set_ftrace_notrace:
 
        This has an effect opposite to that of
@@ -1337,12 +1340,14 @@ ftrace_dump_on_oops must be set. To set ftrace_dump_on_oops, one
 can either use the sysctl function or set it via the proc system
 interface.
 
-  sysctl kernel.ftrace_dump_on_oops=1
+  sysctl kernel.ftrace_dump_on_oops=n
 
 or
 
-  echo 1 > /proc/sys/kernel/ftrace_dump_on_oops
+  echo n > /proc/sys/kernel/ftrace_dump_on_oops
 
+If n = 1, ftrace will dump buffers of all CPUs, if n = 2 ftrace will
+only dump the buffer of the CPU that triggered the oops.
 
 Here's an example of such a dump after a null pointer
 dereference in a kernel module:
@@ -1822,6 +1827,47 @@ this special filter via:
  echo > set_graph_function
 
 
+Filter commands
+---------------
+
+A few commands are supported by the set_ftrace_filter interface.
+Trace commands have the following format:
+
+<function>:<command>:<parameter>
+
+The following commands are supported:
+
+- mod
+  This command enables function filtering per module. The
+  parameter defines the module. For example, if only the write*
+  functions in the ext3 module are desired, run:
+
+   echo 'write*:mod:ext3' > set_ftrace_filter
+
+  This command interacts with the filter in the same way as
+  filtering based on function names. Thus, adding more functions
+  in a different module is accomplished by appending (>>) to the
+  filter file. Remove specific module functions by prepending
+  '!':
+
+   echo '!writeback*:mod:ext3' >> set_ftrace_filter
+
+- traceon/traceoff
+  These commands turn tracing on and off when the specified
+  functions are hit. The parameter determines how many times the
+  tracing system is turned on and off. If unspecified, there is
+  no limit. For example, to disable tracing when a schedule bug
+  is hit the first 5 times, run:
+
+   echo '__schedule_bug:traceoff:5' > set_ftrace_filter
+
+  These commands are cumulative whether or not they are appended
+  to set_ftrace_filter. To remove a command, prepend it by '!'
+  and drop the parameter:
+
+   echo '!__schedule_bug:traceoff' > set_ftrace_filter
+
+
 trace_pipe
 ----------
 
index a9100b28eb844da1974dd24dcaa2a320887eddda..ec94748ae65bf1c55c1359c5c9d71aac714b2e5e 100644 (file)
@@ -40,7 +40,9 @@ Synopsis of kprobe_events
   $stack       : Fetch stack address.
   $retval      : Fetch return value.(*)
   +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**)
-  NAME=FETCHARG: Set NAME as the argument name of FETCHARG.
+  NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
+  FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
+                 (u8/u16/u32/u64/s8/s16/s32/s64) are supported.
 
   (*) only for return probe.
   (**) this is useful for fetching a field of data structures.
index 991c26a6ef64fcfdef0fc870d3ed404f55751407..db0cb228d64aa4a80a4fe380be3e46439de810e6 100644 (file)
@@ -63,9 +63,9 @@ way to perform a busy wait is:
         cpu_relax();
 
 The cpu_relax() call can lower CPU power consumption or yield to a
-hyperthreaded twin processor; it also happens to serve as a memory barrier,
-so, once again, volatile is unnecessary.  Of course, busy-waiting is
-generally an anti-social act to begin with.
+hyperthreaded twin processor; it also happens to serve as a compiler
+barrier, so, once again, volatile is unnecessary.  Of course, busy-
+waiting is generally an anti-social act to begin with.
 
 There are still a few rare situations where volatile makes sense in the
 kernel:
index 4cf72f3fa8e91b1b725ba3e2af92dc68e4693394..ba45803a2216a88ff406aca0093c32c9d2d109eb 100644 (file)
@@ -17,9 +17,6 @@ int main(void)
                        ret = -1;
                        break;
                }
-               ret = fsync(fd);
-               if (ret)
-                       break;
                sleep(10);
        }
        close(fd);
index a750532ffcf8e36d8b5be5ce5324a13384546a7b..63fdc34ceb984733416d7113caf336cb9eb2556e 100644 (file)
@@ -31,6 +31,8 @@ static void keep_alive(void)
  */
 int main(int argc, char *argv[])
 {
+    int flags;
+
     fd = open("/dev/watchdog", O_WRONLY);
 
     if (fd == -1) {
@@ -41,12 +43,14 @@ int main(int argc, char *argv[])
 
     if (argc > 1) {
        if (!strncasecmp(argv[1], "-d", 2)) {
-           ioctl(fd, WDIOC_SETOPTIONS, WDIOS_DISABLECARD);
+           flags = WDIOS_DISABLECARD;
+           ioctl(fd, WDIOC_SETOPTIONS, &flags);
            fprintf(stderr, "Watchdog card disabled.\n");
            fflush(stderr);
            exit(0);
        } else if (!strncasecmp(argv[1], "-e", 2)) {
-           ioctl(fd, WDIOC_SETOPTIONS, WDIOS_ENABLECARD);
+           flags = WDIOS_ENABLECARD;
+           ioctl(fd, WDIOC_SETOPTIONS, &flags);
            fprintf(stderr, "Watchdog card enabled.\n");
            fflush(stderr);
            exit(0);
index 4cc4ba9d71500a4b5dd55b70ed9f54dc099b4ddd..eb7132ed8bbcb7650bdc20e6a43e3c9222d6621b 100644 (file)
@@ -222,11 +222,10 @@ returned value is the temperature in degrees fahrenheit.
     ioctl(fd, WDIOC_GETTEMP, &temperature);
 
 Finally the SETOPTIONS ioctl can be used to control some aspects of
-the cards operation; right now the pcwd driver is the only one
-supporting this ioctl.
+the cards operation.
 
     int options = 0;
-    ioctl(fd, WDIOC_SETOPTIONS, options);
+    ioctl(fd, WDIOC_SETOPTIONS, &options);
 
 The following options are available:
 
index d3072cb8805d25058e73ffe995c82312d1975e73..3d2651bffaddb0ff1c5111e7ea04f5933d726d1f 100644 (file)
@@ -485,8 +485,8 @@ S:  Maintained
 F:     drivers/input/mouse/bcm5974.c
 
 APPLE SMC DRIVER
-M:     Nicolas Boichat <nicolas@boichat.ch>
-L:     mactel-linux-devel@lists.sourceforge.net
+M:     Henrik Rydberg <rydberg@euromail.se>
+L:     lm-sensors@lm-sensors.org
 S:     Maintained
 F:     drivers/hwmon/applesmc.c
 
@@ -797,12 +797,12 @@ M:        Michael Petchkovsky <mkpetch@internode.on.net>
 S:     Maintained
 
 ARM/NOMADIK ARCHITECTURE
-M:     Alessandro Rubini <rubini@unipv.it>
-M:     STEricsson <STEricsson_nomadik_linux@list.st.com>
-L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S:     Maintained
-F:     arch/arm/mach-nomadik/
-F:     arch/arm/plat-nomadik/
+M:     Alessandro Rubini <rubini@unipv.it>
+M:     STEricsson <STEricsson_nomadik_linux@list.st.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     arch/arm/mach-nomadik/
+F:     arch/arm/plat-nomadik/
 
 ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
 M:     Nelson Castillo <arhuaco@freaks-unidos.net>
@@ -971,6 +971,16 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:     http://www.mcuos.com
 S:     Maintained
 
+ARM/U300 MACHINE SUPPORT
+M:     Linus Walleij <linus.walleij@stericsson.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Supported
+F:     arch/arm/mach-u300/
+F:     drivers/i2c/busses/i2c-stu300.c
+F:     drivers/rtc/rtc-coh901331.c
+F:     drivers/watchdog/coh901327_wdt.c
+F:     drivers/dma/coh901318*
+
 ARM/U8500 ARM ARCHITECTURE
 M:     Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1441,6 +1451,15 @@ F:       arch/powerpc/include/asm/spu*.h
 F:     arch/powerpc/oprofile/*cell*
 F:     arch/powerpc/platforms/cell/
 
+CEPH DISTRIBUTED FILE SYSTEM CLIENT
+M:     Sage Weil <sage@newdream.net>
+L:     ceph-devel@vger.kernel.org
+W:     http://ceph.newdream.net/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git
+S:     Supported
+F:     Documentation/filesystems/ceph.txt
+F:     fs/ceph
+
 CERTIFIED WIRELESS USB (WUSB) SUBSYSTEM:
 M:     David Vrabel <david.vrabel@csr.com>
 L:     linux-usb@vger.kernel.org
@@ -1917,17 +1936,17 @@ F:      drivers/scsi/dpt*
 F:     drivers/scsi/dpt/
 
 DRBD DRIVER
-P:     Philipp Reisner
-P:     Lars Ellenberg
-M:     drbd-dev@lists.linbit.com
-L:     drbd-user@lists.linbit.com
-W:     http://www.drbd.org
-T:     git git://git.drbd.org/linux-2.6-drbd.git drbd
-T:     git git://git.drbd.org/drbd-8.3.git
-S:     Supported
-F:     drivers/block/drbd/
-F:     lib/lru_cache.c
-F:     Documentation/blockdev/drbd/
+P:     Philipp Reisner
+P:     Lars Ellenberg
+M:     drbd-dev@lists.linbit.com
+L:     drbd-user@lists.linbit.com
+W:     http://www.drbd.org
+T:     git git://git.drbd.org/linux-2.6-drbd.git drbd
+T:     git git://git.drbd.org/drbd-8.3.git
+S:     Supported
+F:     drivers/block/drbd/
+F:     lib/lru_cache.c
+F:     Documentation/blockdev/drbd/
 
 DRIVER CORE, KOBJECTS, AND SYSFS
 M:     Greg Kroah-Hartman <gregkh@suse.de>
@@ -1941,7 +1960,7 @@ F:        lib/kobj*
 
 DRM DRIVERS
 M:     David Airlie <airlied@linux.ie>
-L:     dri-devel@lists.sourceforge.net
+L:     dri-devel@lists.freedesktop.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6.git
 S:     Maintained
 F:     drivers/gpu/drm/
@@ -2465,12 +2484,6 @@ L:       linuxppc-dev@ozlabs.org
 S:     Odd Fixes
 F:     drivers/char/hvc_*
 
-VIRTIO CONSOLE DRIVER
-M:     Amit Shah <amit.shah@redhat.com>
-L:     virtualization@lists.linux-foundation.org
-S:     Maintained
-F:     drivers/char/virtio_console.c
-
 iSCSI BOOT FIRMWARE TABLE (iBFT) DRIVER
 M:     Peter Jones <pjones@redhat.com>
 M:     Konrad Rzeszutek Wilk <konrad@kernel.org>
@@ -3085,6 +3098,7 @@ F:        include/scsi/*iscsi*
 ISDN SUBSYSTEM
 M:     Karsten Keil <isdn@linux-pingi.de>
 L:     isdn4linux@listserv.isdn4linux.de (subscribers-only)
+L:     netdev@vger.kernel.org
 W:     http://www.isdn4linux.de
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kkeil/isdn-2.6.git
 S:     Maintained
@@ -3271,6 +3285,16 @@ S:       Maintained
 F:     include/linux/kexec.h
 F:     kernel/kexec.c
 
+KEYS/KEYRINGS:
+M:     David Howells <dhowells@redhat.com>
+L:     keyrings@linux-nfs.org
+S:     Maintained
+F:     Documentation/keys.txt
+F:     include/linux/key.h
+F:     include/linux/key-type.h
+F:     include/keys/
+F:     security/keys/
+
 KGDB
 M:     Jason Wessel <jason.wessel@windriver.com>
 L:     kgdb-bugreport@lists.sourceforge.net
@@ -3520,8 +3544,8 @@ F:        drivers/scsi/sym53c8xx_2/
 LTP (Linux Test Project)
 M:     Rishikesh K Rajak <risrajak@linux.vnet.ibm.com>
 M:     Garrett Cooper <yanegomi@gmail.com>
-M:     Mike Frysinger <vapier@gentoo.org>
-M:     Subrata Modak <subrata@linux.vnet.ibm.com>
+M:     Mike Frysinger <vapier@gentoo.org>
+M:     Subrata Modak <subrata@linux.vnet.ibm.com>
 L:     ltp-list@lists.sourceforge.net (subscribers-only)
 W:     http://ltp.sourceforge.net/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/galak/ltp.git
@@ -4152,6 +4176,7 @@ OPROFILE
 M:     Robert Richter <robert.richter@amd.com>
 L:     oprofile-list@lists.sf.net
 S:     Maintained
+F:     arch/*/include/asm/oprofile*.h
 F:     arch/*/oprofile/
 F:     drivers/oprofile/
 F:     include/linux/oprofile.h
@@ -4340,13 +4365,13 @@ M:      Paul Mackerras <paulus@samba.org>
 M:     Ingo Molnar <mingo@elte.hu>
 M:     Arnaldo Carvalho de Melo <acme@redhat.com>
 S:     Supported
-F:     kernel/perf_event.c
+F:     kernel/perf_event*.c
 F:     include/linux/perf_event.h
-F:     arch/*/kernel/perf_event.c
-F:     arch/*/kernel/*/perf_event.c
-F:     arch/*/kernel/*/*/perf_event.c
+F:     arch/*/kernel/perf_event*.c
+F:     arch/*/kernel/*/perf_event*.c
+F:     arch/*/kernel/*/*/perf_event*.c
 F:     arch/*/include/asm/perf_event.h
-F:     arch/*/lib/perf_event.c
+F:     arch/*/lib/perf_event*.c
 F:     arch/*/kernel/perf_callchain.c
 F:     tools/perf/
 
@@ -4469,17 +4494,17 @@ S:      Maintained
 F:     drivers/ata/sata_promise.*
 
 PS3 NETWORK SUPPORT
-M:     Geoff Levand <geoffrey.levand@am.sony.com>
+M:     Geoff Levand <geoff@infradead.org>
 L:     netdev@vger.kernel.org
 L:     cbe-oss-dev@ozlabs.org
-S:     Supported
+S:     Maintained
 F:     drivers/net/ps3_gelic_net.*
 
 PS3 PLATFORM SUPPORT
-M:     Geoff Levand <geoffrey.levand@am.sony.com>
+M:     Geoff Levand <geoff@infradead.org>
 L:     linuxppc-dev@ozlabs.org
 L:     cbe-oss-dev@ozlabs.org
-S:     Supported
+S:     Maintained
 F:     arch/powerpc/boot/ps3*
 F:     arch/powerpc/include/asm/lv1call.h
 F:     arch/powerpc/include/asm/ps3*.h
@@ -4778,12 +4803,11 @@ F:      drivers/s390/crypto/
 
 S390 ZFCP DRIVER
 M:     Christof Schmitt <christof.schmitt@de.ibm.com>
-M:     Martin Peschke <mp3@de.ibm.com>
+M:     Swen Schillig <swen@vnet.ibm.com>
 M:     linux390@de.ibm.com
 L:     linux-s390@vger.kernel.org
 W:     http://www.ibm.com/developerworks/linux/linux390/
 S:     Supported
-F:     Documentation/s390/zfcpdump.txt
 F:     drivers/s390/scsi/zfcp_*
 
 S390 IUCV NETWORK LAYER
@@ -5225,6 +5249,21 @@ T:       git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git
 S:     Maintained
 F:     arch/sparc/
 
+SPARC SERIAL DRIVERS
+M:     "David S. Miller" <davem@davemloft.net>
+L:     sparclinux@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git
+S:     Maintained
+F:     drivers/serial/suncore.c
+F:     drivers/serial/suncore.h
+F:     drivers/serial/sunhv.c
+F:     drivers/serial/sunsab.c
+F:     drivers/serial/sunsab.h
+F:     drivers/serial/sunsu.c
+F:     drivers/serial/sunzilog.c
+F:     drivers/serial/sunzilog.h
+
 SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
 M:     Roger Wolff <R.E.Wolff@BitWizard.nl>
 S:     Supported
@@ -5410,7 +5449,6 @@ S:        Maintained
 F:     sound/soc/codecs/twl4030*
 
 TIPC NETWORK LAYER
-M:     Per Liden <per.liden@ericsson.com>
 M:     Jon Maloy <jon.maloy@ericsson.com>
 M:     Allan Stephens <allan.stephens@windriver.com>
 L:     tipc-discussion@lists.sourceforge.net
@@ -5466,7 +5504,7 @@ S:        Maintained
 F:     drivers/mmc/host/tmio_mmc.*
 
 TMPFS (SHMEM FILESYSTEM)
-M:     Hugh Dickins <hugh.dickins@tiscali.co.uk>
+M:     Hugh Dickins <hughd@google.com>
 L:     linux-mm@kvack.org
 S:     Maintained
 F:     include/linux/shmem_fs.h
@@ -5948,6 +5986,13 @@ S:       Maintained
 F:     Documentation/filesystems/vfat.txt
 F:     fs/fat/
 
+VIRTIO CONSOLE DRIVER
+M:     Amit Shah <amit.shah@redhat.com>
+L:     virtualization@lists.linux-foundation.org
+S:     Maintained
+F:     drivers/char/virtio_console.c
+F:     include/linux/virtio_console.h
+
 VIRTIO HOST (VHOST)
 M:     "Michael S. Tsirkin" <mst@redhat.com>
 L:     kvm@vger.kernel.org
@@ -6188,7 +6233,7 @@ F:        arch/x86/
 X86 PLATFORM DRIVERS
 M:     Matthew Garrett <mjg@redhat.com>
 L:     platform-driver-x86@vger.kernel.org
-T:      git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git
 S:     Maintained
 F:     drivers/platform/x86
 
index 08ff02da7ce365dc4a3d88964deda0147e1b8001..ebc8225f7a96734d316b67de361caa446830033b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 34
-EXTRAVERSION = -rc1
-NAME = Man-Eating Seals of Antiquity
+EXTRAVERSION =
+NAME = Sheep on Meth
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
index e5eb1337a5377f5b131b2ba70efd8263b8057404..acda512da2e21b52a972bb4255404fab3fce7015 100644 (file)
@@ -42,15 +42,10 @@ config KPROBES
          If in doubt, say "N".
 
 config OPTPROBES
-       bool "Kprobes jump optimization support (EXPERIMENTAL)"
-       default y
-       depends on KPROBES
+       def_bool y
+       depends on KPROBES && HAVE_OPTPROBES
        depends on !PREEMPT
-       depends on HAVE_OPTPROBES
        select KALLSYMS_ALL
-       help
-         This option will allow kprobes to optimize breakpoint to
-         a jump for reducing its overhead.
 
 config HAVE_EFFICIENT_UNALIGNED_ACCESS
        bool
@@ -142,6 +137,17 @@ config HAVE_HW_BREAKPOINT
        bool
        depends on PERF_EVENTS
 
+config HAVE_MIXED_BREAKPOINTS_REGS
+       bool
+       depends on HAVE_HW_BREAKPOINT
+       help
+         Depending on the arch implementation of hardware breakpoints,
+         some of them have separate registers for data and instruction
+         breakpoints addresses, others have mixed registers to store
+         them but define the access type in a control register.
+         Select this option if your arch implements breakpoints under the
+         latter fashion.
+
 config HAVE_USER_RETURN_NOTIFIER
        bool
 
index 3c8d1b25c66105b3fb34f9b693c712d9b3d05d52..be61670d40963c78fa52e9d2cfef36b15abafe8f 100644 (file)
@@ -8,6 +8,7 @@
  * based significantly on the arch/alpha/boot/main.c of Linus Torvalds
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <generated/utsrelease.h>
 #include <linux/mm.h>
index ade3f129dc2722e26168495bdc28066d24fcd609..c98865f21423016cd8220a574da6d69ca5cc42c4 100644 (file)
@@ -10,6 +10,7 @@
  * and the decompression code from MILO.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <generated/utsrelease.h>
 #include <linux/mm.h>
index 644b7db55438f4f1d1b8136bd9f680bbcf4f75a8..ded57d9a80e1adee23896c9a296476e383bcc2c5 100644 (file)
@@ -6,6 +6,7 @@
  * This file is the bootloader for the Linux/AXP kernel
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <generated/utsrelease.h>
 #include <linux/mm.h>
index 3047a1b3a517160f4c016c032f30549e3c20ca19..3ff9a957a25cdc8b89e3eda0656e54a5a3af79ec 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
index 610dff44d94b9bfae101f76149f965b4400d07ff..e756d04b6cd5dcdf07b4f394b8be15f1814c4849 100644 (file)
@@ -17,8 +17,8 @@
 #define ATOMIC_INIT(i)         ( (atomic_t) { (i) } )
 #define ATOMIC64_INIT(i)       ( (atomic64_t) { (i) } )
 
-#define atomic_read(v)         ((v)->counter + 0)
-#define atomic64_read(v)       ((v)->counter + 0)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
+#define atomic64_read(v)       (*(volatile long *)&(v)->counter)
 
 #define atomic_set(v,i)                ((v)->counter = (i))
 #define atomic64_set(v,i)      ((v)->counter = (i))
index 15f3ae25c51137bb8af4a67b5d5e8cbbea328241..296da1d5ed57a5caff0fa2111545ef44d9ede953 100644 (file)
@@ -405,29 +405,31 @@ static inline int fls(int x)
 
 #if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
 /* Whee.  EV67 can calculate it directly.  */
-static inline unsigned long hweight64(unsigned long w)
+static inline unsigned long __arch_hweight64(unsigned long w)
 {
        return __kernel_ctpop(w);
 }
 
-static inline unsigned int hweight32(unsigned int w)
+static inline unsigned int __arch_weight32(unsigned int w)
 {
-       return hweight64(w);
+       return __arch_hweight64(w);
 }
 
-static inline unsigned int hweight16(unsigned int w)
+static inline unsigned int __arch_hweight16(unsigned int w)
 {
-       return hweight64(w & 0xffff);
+       return __arch_hweight64(w & 0xffff);
 }
 
-static inline unsigned int hweight8(unsigned int w)
+static inline unsigned int __arch_hweight8(unsigned int w)
 {
-       return hweight64(w & 0xff);
+       return __arch_hweight64(w & 0xff);
 }
 #else
-#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/arch_hweight.h>
 #endif
 
+#include <asm-generic/bitops/const_hweight.h>
+
 #endif /* __KERNEL__ */
 
 #include <asm-generic/bitops/find.h>
index 30d55fe7aaf6a60333d9c0b2c4e5ce3925ecb299..dad300fa14ce3778d3e89419d34fbb8498bdbd64 100644 (file)
@@ -12,7 +12,6 @@
 #define __ALPHA_MARVEL__H__
 
 #include <linux/types.h>
-#include <linux/pci.h>
 #include <linux/spinlock.h>
 
 #include <asm/compiler.h>
index acf55b48347207550edadb3691081bf1df1d251e..21ac53383b37eca3cea4e4ff3ac9b0c6d7989d67 100644 (file)
@@ -6,7 +6,6 @@
 #define MCPCIA_ONE_HAE_WINDOW 1
 
 #include <linux/types.h>
-#include <linux/pci.h>
 #include <asm/compiler.h>
 
 /*
index a17f6f33b68ec6f339199ed4371307cf20999d2d..8cf79d1219e159ccda9985df9f4511c04dc78fc1 100644 (file)
@@ -2,7 +2,6 @@
 #define __ALPHA_TITAN__H__
 
 #include <linux/types.h>
-#include <linux/pci.h>
 #include <asm/compiler.h>
 
 /*
index 58d4fe48742c49c09b03657c97d6269d7e930d02..8e39ecf09419c890c8b8ec4e30b44e53eff3a11a 100644 (file)
@@ -2,7 +2,6 @@
 #define __ALPHA_TSUNAMI__H__
 
 #include <linux/types.h>
-#include <linux/pci.h>
 #include <asm/compiler.h>
 
 /*
index 5f2cf23c4648f9d7173fe047448459fc8ff6d752..7f912ba3d9ad79ee9f333f14dfcd0f3dc7bb59c5 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/sched.h>
 #include <linux/ptrace.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/init.h>
 #include <linux/irq.h>
index 53c213f70fcbc8151b42fea8b50998bf509e5fea..de9d397178085a9b7cb4482d487e2f9379824bbc 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/syscalls.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/utsname.h>
 #include <linux/time.h>
@@ -37,6 +36,7 @@
 #include <linux/uio.h>
 #include <linux/vfs.h>
 #include <linux/rcupdate.h>
+#include <linux/slab.h>
 
 #include <asm/fpu.h>
 #include <asm/io.h>
index 823a540f9f5b15b51fd84c300c9d9526598c3847..246100ef07c2474fa5213163b0e1b899d10198a6 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/gfp.h>
 #include <linux/capability.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
index 6ea822e7f724dfbbf26e4b0692e7377ee58a0c6b..d979e7c7bc4b898be20d445c36e8b93ecb990ffa 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 
 static int hose_mmap_page_range(struct pci_controller *hose,
index ce9e54c887fa01aa9c15583bb246d48e1b627f23..d1dbd9acd1df47d8bbf2046720a3b5c2792d4076 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/bootmem.h>
 #include <linux/scatterlist.h>
 #include <linux/log2.h>
index 289039bb6bb2a07f91b81b2848d035cc39083d88..395a464353b8e48ac4e18ecb725fc0a960809898 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/time.h>
 #include <linux/major.h>
@@ -28,6 +27,7 @@
 #include <linux/reboot.h>
 #include <linux/tty.h>
 #include <linux/console.h>
+#include <linux/slab.h>
 
 #include <asm/reg.h>
 #include <asm/uaccess.h>
index 9acadc6b16a0f8c53f60eb6e3f3019c5e1cbb3d1..baa903602f6a03c86a8d841ba3ce751c3ece0cb9 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
-#include <linux/slab.h>
 #include <linux/security.h>
 #include <linux/signal.h>
 
index bca5bda90cde75407940f0f238d3099c29ca0567..0435921d41c6be15370b58210d8aaaaa2866ea9a 100644 (file)
@@ -3,7 +3,6 @@
  */
 #include <linux/kernel.h>
 
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index 2636cc028d06af7d120282eda93c8ea32a6e41af..3e6a2893af9f6e87122ca0e872ec95282cdf3fde 100644 (file)
@@ -4,7 +4,6 @@
 
 #include <linux/kernel.h>
 
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index dbbf04f9230ed0890011e8c63a2db30f8e8d94fe..4afc1a1e2e5a055ccda3d11a7d2f1b96c3670235 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
index d64e1e497e76a1edd304d4036f3f1d7a5a41c83a..4026502ab7077d639b37de28a07dafcc08cb94cd 100644 (file)
@@ -224,7 +224,7 @@ static void
 dp264_device_interrupt(unsigned long vector)
 {
 #if 1
-       printk("dp264_device_interrupt: NOT IMPLEMENTED YET!! \n");
+       printk("dp264_device_interrupt: NOT IMPLEMENTED YET!!\n");
 #else
        unsigned long pld;
        unsigned int i;
index 288053342c83b5e951df1e4a68eb81ba2bd3ad62..9008d0f20c534dcb4ed20a73e2c5f21581df393a 100644 (file)
@@ -171,7 +171,7 @@ titan_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
 static void
 titan_device_interrupt(unsigned long vector)
 {
-       printk("titan_device_interrupt: NOT IMPLEMENTED YET!! \n");
+       printk("titan_device_interrupt: NOT IMPLEMENTED YET!!\n");
 }
 
 static void 
index 6ee7655b7568bf36719f2447e389831244721f01..b14f015008ada5e90d580b0589d4ff5144a1602e 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kallsyms.h>
+#include <linux/ratelimit.h>
 
 #include <asm/gentrap.h>
 #include <asm/uaccess.h>
@@ -771,8 +772,7 @@ asmlinkage void
 do_entUnaUser(void __user * va, unsigned long opcode,
              unsigned long reg, struct pt_regs *regs)
 {
-       static int cnt = 0;
-       static unsigned long last_time;
+       static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5);
 
        unsigned long tmp1, tmp2, tmp3, tmp4;
        unsigned long fake_reg, *reg_addr = &fake_reg;
@@ -783,15 +783,11 @@ do_entUnaUser(void __user * va, unsigned long opcode,
           with the unaliged access.  */
 
        if (!test_thread_flag (TIF_UAC_NOPRINT)) {
-               if (cnt >= 5 && time_after(jiffies, last_time + 5 * HZ)) {
-                       cnt = 0;
-               }
-               if (++cnt < 5) {
+               if (__ratelimit(&ratelimit)) {
                        printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n",
                               current->comm, task_pid_nr(current),
                               regs->pc - 4, va, opcode, reg);
                }
-               last_time = jiffies;
        }
        if (test_thread_flag (TIF_UAC_SIGBUS))
                goto give_sigbus;
index a0902c20d6778edce8dd57deccd70ec7c54a36b8..86425ab53bf5d1afa9bd0d4dddcb2e8543b621e4 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h> /* max_low_pfn */
 #include <linux/vmalloc.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
index cadfe2ee66a55554d885d587b3b111f6559c629c..92622eb5cc0da6f651c31cdaf0ff55f8bba16977 100644 (file)
@@ -218,6 +218,10 @@ config MMU
          Select if you want MMU-based virtualised addressing space
          support by paged memory management. If unsure, say 'Y'.
 
+#
+# The "ARM system type" choice list is ordered alphabetically by option
+# text.  Please add new entries in the option alphabetic order.
+#
 choice
        prompt "ARM system type"
        default ARCH_VERSATILE
@@ -249,6 +253,7 @@ config ARCH_REALVIEW
        select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select ARCH_WANT_OPTIONAL_GPIOLIB
+       select GPIO_PL061 if GPIOLIB
        help
          This enables support for ARM Ltd RealView boards.
 
@@ -274,6 +279,18 @@ config ARCH_AT91
          This enables support for systems based on the Atmel AT91RM9200,
          AT91SAM9 and AT91CAP9 processors.
 
+config ARCH_BCMRING
+       bool "Broadcom BCMRING"
+       depends on MMU
+       select CPU_V6
+       select ARM_AMBA
+       select COMMON_CLKDEV
+       select GENERIC_TIME
+       select GENERIC_CLOCKEVENTS
+       select ARCH_WANT_OPTIONAL_GPIOLIB
+       help
+         Support for Broadcom's BCMRing platform.
+
 config ARCH_CLPS711X
        bool "Cirrus Logic CLPS711x/EP721x-based"
        select CPU_ARM720T
@@ -359,20 +376,6 @@ config ARCH_H720X
        help
          This enables support for systems based on the Hynix HMS720x
 
-config ARCH_NOMADIK
-       bool "STMicroelectronics Nomadik"
-       select ARM_AMBA
-       select ARM_VIC
-       select CPU_ARM926T
-       select HAVE_CLK
-       select COMMON_CLKDEV
-       select GENERIC_TIME
-       select GENERIC_CLOCKEVENTS
-       select GENERIC_GPIO
-       select ARCH_REQUIRE_GPIOLIB
-       help
-         Support for the Nomadik platform by ST-Ericsson
-
 config ARCH_IOP13XX
        bool "IOP13xx-based"
        depends on MMU
@@ -747,6 +750,30 @@ config ARCH_U300
        help
          Support for ST-Ericsson U300 series mobile platforms.
 
+config ARCH_U8500
+       bool "ST-Ericsson U8500 Series"
+       select CPU_V7
+       select ARM_AMBA
+       select GENERIC_TIME
+       select GENERIC_CLOCKEVENTS
+       select COMMON_CLKDEV
+       help
+         Support for ST-Ericsson's Ux500 architecture
+
+config ARCH_NOMADIK
+       bool "STMicroelectronics Nomadik"
+       select ARM_AMBA
+       select ARM_VIC
+       select CPU_ARM926T
+       select HAVE_CLK
+       select COMMON_CLKDEV
+       select GENERIC_TIME
+       select GENERIC_CLOCKEVENTS
+       select GENERIC_GPIO
+       select ARCH_REQUIRE_GPIOLIB
+       help
+         Support for the Nomadik platform by ST-Ericsson
+
 config ARCH_DAVINCI
        bool "TI DaVinci"
        select CPU_ARM926T
@@ -775,30 +802,13 @@ config ARCH_OMAP
        help
          Support for TI's OMAP platform (OMAP1 and OMAP2).
 
-config ARCH_BCMRING
-       bool "Broadcom BCMRING"
-       depends on MMU
-       select CPU_V6
-       select ARM_AMBA
-       select COMMON_CLKDEV
-       select GENERIC_TIME
-       select GENERIC_CLOCKEVENTS
-       select ARCH_WANT_OPTIONAL_GPIOLIB
-       help
-         Support for Broadcom's BCMRing platform.
-
-config ARCH_U8500
-       bool "ST-Ericsson U8500 Series"
-       select CPU_V7
-       select ARM_AMBA
-       select GENERIC_TIME
-       select GENERIC_CLOCKEVENTS
-       select COMMON_CLKDEV
-       help
-         Support for ST-Ericsson's Ux500 architecture
-
 endchoice
 
+#
+# This is sorted alphabetically by mach-* pathname.  However, plat-*
+# Kconfigs may be included either alphabetically (according to the
+# plat- suffix) or along side the corresponding mach-* source.
+#
 source "arch/arm/mach-aaec2000/Kconfig"
 
 source "arch/arm/mach-at91/Kconfig"
index 0da382f33157a32c084aa6f1c36743b51526263e..9c097073ce4c979a3be2dc13515b6cdc2f943e86 100644 (file)
@@ -11,6 +11,7 @@ extern unsigned long free_mem_end_ptr;
 extern void error(char *);
 
 #define STATIC static
+#define STATIC_RW_DATA /* non-static please */
 
 #define ARCH_HAS_DECOMP_WDOG
 
index 535a91daaa533b9ff91193bb2f5cfb7f3e6a41a9..c5191b1532e8284cbeac17cef819522863a90743 100644 (file)
@@ -172,7 +172,7 @@ not_angel:
                adr     r0, LC0
  ARM(          ldmia   r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp})
  THUMB(                ldmia   r0, {r1, r2, r3, r4, r5, r6, r11, ip}   )
- THUMB(                ldr     sp, [r0, #28]                           )
+ THUMB(                ldr     sp, [r0, #32]                           )
                subs    r0, r0, r1              @ calculate the delta offset
 
                                                @ if delta is zero, we are
@@ -685,8 +685,8 @@ proc_types:
                W(b)    __armv4_mmu_cache_off
                W(b)    __armv4_mmu_cache_flush
 
-               .word   0x56056930
-               .word   0xff0ffff0              @ PXA935
+               .word   0x56056900
+               .word   0xffffff00              @ PXA9xx
                W(b)    __armv4_mmu_cache_on
                W(b)    __armv4_mmu_cache_off
                W(b)    __armv4_mmu_cache_flush
@@ -697,12 +697,6 @@ proc_types:
                W(b)    __armv4_mmu_cache_off
                W(b)    __armv5tej_mmu_cache_flush
 
-               .word   0x56056930
-               .word   0xff0ffff0              @ PXA935
-               W(b)    __armv4_mmu_cache_on
-               W(b)    __armv4_mmu_cache_off
-               W(b)    __armv4_mmu_cache_flush
-
                .word   0x56050000              @ Feroceon
                .word   0xff0f0000
                W(b)    __armv4_mmu_cache_on
@@ -742,7 +736,7 @@ proc_types:
                .word   0x000f0000
                W(b)    __armv4_mmu_cache_on
                W(b)    __armv4_mmu_cache_off
-               W(b)    __armv4_mmu_cache_flush
+               W(b)    __armv5tej_mmu_cache_flush
 
                .word   0x0007b000              @ ARMv6
                .word   0x000ff000
index d32bc71c1f787d8887b2a0d1c9a6cf41730dc23c..d2b2ef41cd4ff7ac32bf91e4e947cc57993cbb2d 100644 (file)
@@ -33,6 +33,7 @@ unsigned int __machine_arch_type;
 #else
 
 static void putstr(const char *ptr);
+extern void error(char *x);
 
 #include <mach/uncompress.h>
 
index 6416d5b5020d221514b7d8d8eca6bbb3ac2be991..dba4c1da63ed84fffca55fcf6ab44c75064d1654 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/string.h>
 #include <linux/mutex.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #include <asm/clkdev.h>
 #include <mach/clkdev.h>
index ee1d3b85eb659376c5daa37b7bf07396857b85fd..7974baacafcea74ec055a46ee0f6cea496f24e6f 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/ptrace.h>
 #include <linux/interrupt.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
index 90ae00b631c269c4ad5c15117055335e092865c1..9dff07c80ddb2eceec0a864275023a8d7a606636 100644 (file)
@@ -290,7 +290,7 @@ static int locomo_suspend(struct platform_device *dev, pm_message_t state)
        save->LCM_GPO     = locomo_readl(lchip->base + LOCOMO_GPO);     /* GPIO */
        locomo_writel(0x00, lchip->base + LOCOMO_GPO);
        save->LCM_SPICT   = locomo_readl(lchip->base + LOCOMO_SPI + LOCOMO_SPICT);      /* SPI */
-       locomo_writel(0x40, lchip->base + LOCOMO_SPICT);
+       locomo_writel(0x40, lchip->base + LOCOMO_SPI + LOCOMO_SPICT);
        save->LCM_GPE     = locomo_readl(lchip->base + LOCOMO_GPE);     /* GPIO */
        locomo_writel(0x00, lchip->base + LOCOMO_GPE);
        save->LCM_ASD     = locomo_readl(lchip->base + LOCOMO_ASD);     /* ADSTART */
@@ -418,7 +418,7 @@ __locomo_probe(struct device *me, struct resource *mem, int irq)
        /* Longtime timer */
        locomo_writel(0, lchip->base + LOCOMO_LTINT);
        /* SPI */
-       locomo_writel(0, lchip->base + LOCOMO_SPIIE);
+       locomo_writel(0, lchip->base + LOCOMO_SPI + LOCOMO_SPIIE);
 
        locomo_writel(6 + 8 + 320 + 30 - 10, lchip->base + LOCOMO_ASD);
        r = locomo_readl(lchip->base + LOCOMO_ASD);
@@ -707,7 +707,7 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
        udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */
        if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {   /* High is error */
                printk(KERN_WARNING "locomo: m62332_senddata Error 1\n");
-               return;
+               goto out;
        }
 
        /* Send Sub address (LSB is channel select) */
@@ -735,7 +735,7 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
        udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */
        if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {   /* High is error */
                printk(KERN_WARNING "locomo: m62332_senddata Error 2\n");
-               return;
+               goto out;
        }
 
        /* Send DAC data */
@@ -760,9 +760,9 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
        udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */
        if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {   /* High is error */
                printk(KERN_WARNING "locomo: m62332_senddata Error 3\n");
-               return;
        }
 
+out:
        /* stop */
        r = locomo_readl(mapbase + LOCOMO_DAC);
        r &=  ~(LOCOMO_DAC_SCLOEB);
index 1e12167c89b7210abad6f3a789cdc4d595d89fd7..6ac6693299bc0937c0dcb42e410f21f019375488 100644 (file)
@@ -1,13 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc3
-# Fri Jul 17 12:07:28 2009
+# Linux kernel version: 2.6.34-rc2
+# Mon Mar 29 12:01:41 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
+CONFIG_HAVE_PROC_CPU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,6 +18,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -32,6 +33,12 @@ CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -43,21 +50,22 @@ 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_TINY_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 is not set
-# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -75,19 +83,21 @@ CONFIG_FUTEX=y
 # CONFIG_EVENTFD is not set
 CONFIG_SHMEM=y
 # CONFIG_AIO is not set
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
+CONFIG_PERF_EVENTS=y
+CONFIG_PERF_COUNTERS=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_SLUB_DEBUG is not set
-# 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_KPROBES=y
@@ -115,24 +125,53 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
 # 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_BCMRING=y
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
@@ -149,6 +188,7 @@ CONFIG_DEFAULT_IOSCHED="noop"
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
 # CONFIG_ARCH_KIRKWOOD is not set
 # CONFIG_ARCH_LOKI is not set
 # CONFIG_ARCH_MV78XX0 is not set
@@ -157,19 +197,26 @@ CONFIG_DEFAULT_IOSCHED="noop"
 # CONFIG_ARCH_KS8695 is not set
 # CONFIG_ARCH_NS9XXX is not set
 # CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE 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_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_S5PV210 is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-CONFIG_ARCH_BCMRING=y
 # CONFIG_ARCH_FPGA11107 is not set
 CONFIG_ARCH_BCM11107=y
 
@@ -185,7 +232,7 @@ CONFIG_CPU_V6=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_32v6=y
 CONFIG_CPU_ABRT_EV6=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_V6=y
 CONFIG_CPU_CACHE_V6=y
 CONFIG_CPU_CACHE_VIPT=y
 CONFIG_CPU_COPY_V6=y
@@ -201,6 +248,8 @@ CONFIG_ARM_THUMB=y
 # CONFIG_CPU_ICACHE_DISABLE is not set
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_CPU_HAS_PMU=y
 # CONFIG_ARM_ERRATA_411920 is not set
 CONFIG_COMMON_CLKDEV=y
 
@@ -222,6 +271,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
@@ -229,6 +280,7 @@ CONFIG_AEABI=y
 # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
 # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
 # CONFIG_HIGHMEM is not set
+CONFIG_HW_PERF_EVENTS=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -240,8 +292,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 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=y
@@ -335,9 +386,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_AFS_PARTS is not set
@@ -433,6 +484,10 @@ CONFIG_MTD_NAND_BCM_UMI_HWCS=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
@@ -444,6 +499,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -452,6 +508,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
@@ -459,6 +516,7 @@ CONFIG_HAVE_IDE=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -508,6 +566,7 @@ CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -519,13 +578,17 @@ CONFIG_LEGACY_PTY_COUNT=64
 # CONFIG_TCG_TPM is not set
 # CONFIG_I2C 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
 
@@ -541,6 +604,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
 #
@@ -566,14 +630,17 @@ CONFIG_DUMMY_CONSOLE=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES 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
 
 #
@@ -589,9 +656,12 @@ 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 is not set
 # CONFIG_FSNOTIFY is not set
+# CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
@@ -647,6 +717,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -657,7 +728,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
 
 #
@@ -675,11 +745,12 @@ CONFIG_MSDOS_PARTITION=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=y
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -693,6 +764,7 @@ CONFIG_TRACING_SUPPORT=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_ARM_UNWIND is not set
 # CONFIG_DEBUG_USER is not set
+# CONFIG_OC_ETM is not set
 
 #
 # Security options
@@ -700,7 +772,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_BINARY_PRINTF is not set
 
index 893cd267e075267a1fd6714057b8490857112ce1..032b49bad91f58654180f79f9eabfc252c2afb87 100644 (file)
@@ -358,7 +358,7 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
-# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
index 95d2becfc6641efc5d6bb399c4ad0d949c901552..21f2bff8a363aa9728c77b81d9f7eddb135c6c6d 100644 (file)
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc8
-# Sat Feb 13 21:48:53 2010
+# Linux kernel version: 2.6.34-rc2
+# Thu Apr  8 14:49:08 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -19,6 +20,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_ARCH_HAS_CPUFREQ=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_ARCH_MTD_XIP=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
@@ -60,11 +62,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -97,10 +94,14 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
 #
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
@@ -184,6 +185,7 @@ CONFIG_MMU=y
 # CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
@@ -193,7 +195,6 @@ CONFIG_MMU=y
 # 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
@@ -210,21 +211,26 @@ CONFIG_MMU=y
 # CONFIG_ARCH_KS8695 is not set
 # CONFIG_ARCH_NS9XXX is not set
 # CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
 # CONFIG_ARCH_PNX4008 is not set
 CONFIG_ARCH_PXA=y
 # CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE 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_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
 # CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_S5PV210 is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_BCMRING is not set
-# CONFIG_ARCH_U8500 is not set
 
 #
 # Intel PXA2xx/PXA3xx Implementations
@@ -253,6 +259,7 @@ CONFIG_ARCH_PXA=y
 # CONFIG_MACH_EM_X270 is not set
 # CONFIG_MACH_EXEDA is not set
 # CONFIG_MACH_CM_X300 is not set
+# CONFIG_MACH_CAPC7117 is not set
 # CONFIG_ARCH_GUMSTIX is not set
 CONFIG_MACH_INTELMOTE2=y
 # CONFIG_MACH_STARGATE2 is not set
@@ -275,7 +282,11 @@ CONFIG_MACH_INTELMOTE2=y
 # CONFIG_PXA_EZX is not set
 # CONFIG_MACH_MP900C is not set
 # CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_MACH_RAUMFELD_RC is not set
+# CONFIG_MACH_RAUMFELD_CONNECTOR is not set
+# CONFIG_MACH_RAUMFELD_SPEAKER is not set
 # CONFIG_PXA_SHARPSL is not set
+# CONFIG_MACH_ICONTROL is not set
 # CONFIG_ARCH_PXA_ESERIES is not set
 CONFIG_PXA27x=y
 CONFIG_PXA_SSP=y
@@ -302,6 +313,7 @@ CONFIG_ARM_THUMB=y
 CONFIG_ARM_L1_CACHE_SHIFT=5
 CONFIG_IWMMXT=y
 CONFIG_XSCALE_PMU=y
+CONFIG_CPU_HAS_PMU=y
 CONFIG_COMMON_CLKDEV=y
 
 #
@@ -352,7 +364,7 @@ CONFIG_ALIGNMENT_TRAP=y
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=tty1 root=/dev/mmcblk0p2 rootfstype=ext2 rootdelay=3 ip=192.168.0.202:192.168.0.200:192.168.0.200:255.255.255.0 debug"
+CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=jffs2 console=ttyS2,115200 mem=32M"
 # CONFIG_XIP_KERNEL is not set
 CONFIG_KEXEC=y
 CONFIG_ATAGS_PROC=y
@@ -360,24 +372,8 @@ CONFIG_ATAGS_PROC=y
 #
 # CPU Power Management
 #
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_TABLE=y
-CONFIG_CPU_FREQ_DEBUG=y
-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=m
-CONFIG_CPU_FREQ_GOV_USERSPACE=m
-CONFIG_CPU_FREQ_GOV_ONDEMAND=m
-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_IDLE_GOV_MENU=y
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
 
 #
 # Floating point emulation
@@ -409,6 +405,7 @@ CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 CONFIG_APM_EMULATION=y
 CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -416,7 +413,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -506,6 +502,7 @@ CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 # CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_CT is not set
 # CONFIG_NETFILTER_XT_TARGET_DSCP is not set
 CONFIG_NETFILTER_XT_TARGET_HL=m
 CONFIG_NETFILTER_XT_TARGET_LED=m
@@ -622,6 +619,7 @@ CONFIG_IP6_NF_RAW=m
 # CONFIG_ATM is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+# CONFIG_BRIDGE_IGMP_SNOOPING is not set
 # CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
@@ -646,32 +644,7 @@ CONFIG_NET_CLS_ROUTE=y
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
-CONFIG_BT=y
-CONFIG_BT_L2CAP=y
-CONFIG_BT_SCO=y
-CONFIG_BT_RFCOMM=y
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=y
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_HIDP=y
-
-#
-# Bluetooth device drivers
-#
-CONFIG_BT_HCIBTUSB=m
-CONFIG_BT_HCIBTSDIO=m
-CONFIG_BT_HCIUART=y
-CONFIG_BT_HCIUART_H4=y
-# CONFIG_BT_HCIUART_BCSP is not set
-# CONFIG_BT_HCIUART_LL is not set
-CONFIG_BT_HCIBCM203X=m
-CONFIG_BT_HCIBPA10X=m
-CONFIG_BT_HCIBFUSB=m
-CONFIG_BT_HCIVHCI=m
-CONFIG_BT_MRVL=m
-CONFIG_BT_MRVL_SDIO=m
-# CONFIG_BT_ATH3K is not set
+# CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_FIB_RULES=y
 # CONFIG_WIRELESS is not set
@@ -687,7 +660,8 @@ CONFIG_FIB_RULES=y
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_DEVTMPFS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
@@ -703,9 +677,9 @@ CONFIG_MTD=y
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
-# CONFIG_MTD_AR7_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_AFS_PARTS=y
+CONFIG_MTD_AR7_PARTS=y
 
 #
 # User Modules And Translation Layers
@@ -812,6 +786,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -965,6 +940,7 @@ CONFIG_SERIAL_PXA=y
 CONFIG_SERIAL_PXA_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -993,6 +969,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_PXA=y
 # CONFIG_I2C_PXA_SLAVE is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1006,15 +983,9 @@ CONFIG_I2C_PXA=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
 # CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
@@ -1046,10 +1017,12 @@ CONFIG_GPIO_SYSFS=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
@@ -1093,10 +1066,12 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
@@ -1105,22 +1080,25 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TC6393XB is not set
 CONFIG_PMIC_DA903X=y
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 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_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_DEBUG=y
+# CONFIG_REGULATOR_DUMMY is not set
 # CONFIG_REGULATOR_FIXED_VOLTAGE is not set
 CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
 CONFIG_REGULATOR_USERSPACE_CONSUMER=y
 # CONFIG_REGULATOR_BQ24022 is not set
 # CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_MAX8649 is not set
 # CONFIG_REGULATOR_MAX8660 is not set
 CONFIG_REGULATOR_DA903X=y
 # CONFIG_REGULATOR_LP3971 is not set
@@ -1218,6 +1196,7 @@ CONFIG_VIDEO_IR_I2C=y
 # CONFIG_VIDEO_SAA7191 is not set
 # CONFIG_VIDEO_TVP514X is not set
 # CONFIG_VIDEO_TVP5150 is not set
+# CONFIG_VIDEO_TVP7002 is not set
 # CONFIG_VIDEO_VPX3220 is not set
 
 #
@@ -1264,15 +1243,7 @@ CONFIG_SOC_CAMERA_MT9M111=y
 CONFIG_VIDEO_PXA27x=y
 # CONFIG_VIDEO_SH_MOBILE_CEU is not set
 # CONFIG_V4L_USB_DRIVERS is not set
-CONFIG_RADIO_ADAPTERS=y
-# CONFIG_I2C_SI4713 is not set
-# CONFIG_RADIO_SI4713 is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_RADIO_SI470X is not set
-# CONFIG_USB_MR800 is not set
-CONFIG_RADIO_TEA5764=y
-CONFIG_RADIO_TEA5764_XTAL=y
-# CONFIG_RADIO_TEF6862 is not set
+# CONFIG_RADIO_ADAPTERS is not set
 # CONFIG_DAB is not set
 
 #
@@ -1398,8 +1369,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_APPLE=m
-# CONFIG_HID_WACOM is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1477,7 +1446,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # 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
@@ -1489,7 +1457,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # 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=y
 # CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
@@ -1529,6 +1496,7 @@ CONFIG_USB_ETH=y
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -1555,8 +1523,6 @@ CONFIG_SDIO_UART=m
 #
 CONFIG_MMC_PXA=y
 # CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_AT91 is not set
-# CONFIG_MMC_ATMELMCI is not set
 CONFIG_MMC_SPI=y
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
@@ -1574,11 +1540,11 @@ CONFIG_LEDS_LP3944=y
 # CONFIG_LEDS_REGULATOR is not set
 # CONFIG_LEDS_BD2802 is not set
 # CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_TRIGGERS=y
 
 #
 # LED Triggers
 #
-CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_BACKLIGHT=y
@@ -1656,7 +1622,7 @@ CONFIG_RTC_INTF_DEV=y
 # on-CPU RTC drivers
 #
 # CONFIG_RTC_DRV_SA1100 is not set
-# CONFIG_RTC_DRV_PXA is not set
+CONFIG_RTC_DRV_PXA=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
@@ -1681,19 +1647,10 @@ CONFIG_EXT3_FS_XATTR=y
 CONFIG_JBD=m
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=m
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
-CONFIG_XFS_FS=m
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_DEBUG is not set
+# CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
 # CONFIG_NILFS2_FS is not set
@@ -1716,9 +1673,7 @@ CONFIG_CUSE=m
 #
 # CD-ROM/DVD Filesystems
 #
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
+# CONFIG_ISO9660_FS is not set
 # CONFIG_UDF_FS is not set
 
 #
@@ -1750,12 +1705,14 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
-# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
-# CONFIG_JFFS2_SUMMARY is not set
-# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
 CONFIG_JFFS2_COMPRESSION_OPTIONS=y
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_LZO=y
@@ -1765,6 +1722,7 @@ CONFIG_JFFS2_RUBIN=y
 CONFIG_JFFS2_CMODE_PRIORITY=y
 # CONFIG_JFFS2_CMODE_SIZE is not set
 # CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=m
 CONFIG_SQUASHFS=m
 # CONFIG_SQUASHFS_EMBEDDED is not set
@@ -1802,6 +1760,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 CONFIG_CIFS_STATS=y
 # CONFIG_CIFS_STATS2 is not set
@@ -1895,6 +1854,7 @@ CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
 CONFIG_DEBUG_LOCK_ALLOC=y
 CONFIG_PROVE_LOCKING=y
+# CONFIG_PROVE_RCU is not set
 CONFIG_LOCKDEP=y
 # CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_LOCKDEP is not set
@@ -1918,6 +1878,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # 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
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
@@ -2061,9 +2022,9 @@ CONFIG_CRC32=y
 CONFIG_CRC7=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_LZO_COMPRESS=m
-CONFIG_LZO_DECOMPRESS=m
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
@@ -2075,3 +2036,4 @@ CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
index 75cae18fbcb6d218a3fe30618c2a3be22f9432eb..de0c28aa43e7fed0ec065363b22b0dcead8acbb5 100644 (file)
@@ -308,6 +308,7 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND_UP_POSSIBLE=y
 CONFIG_SUSPEND=y
 # CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 
 #
 # Networking
index e6f667c5e58a20bf6ccb88272d3f1f5a805e6c98..9405e32783de81d5d986a5d839d6b72580ac8f9b 100644 (file)
@@ -191,6 +191,7 @@ CONFIG_ARCH_OMAP=y
 #
 CONFIG_ARCH_OMAP_OTG=y
 # CONFIG_ARCH_OMAP1 is not set
+CONFIG_ARCH_OMAP2PLUS=y
 CONFIG_ARCH_OMAP2=y
 # CONFIG_ARCH_OMAP3 is not set
 # CONFIG_ARCH_OMAP4 is not set
@@ -198,8 +199,6 @@ CONFIG_ARCH_OMAP2=y
 #
 # OMAP Feature Selections
 #
-# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
-# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
 CONFIG_OMAP_RESET_CLOCKS=y
 # CONFIG_OMAP_MUX is not set
 # CONFIG_OMAP_MCBSP is not set
@@ -208,15 +207,13 @@ CONFIG_OMAP_MBOX_FWK=y
 CONFIG_OMAP_32K_TIMER=y
 CONFIG_OMAP_32K_TIMER_HZ=128
 CONFIG_OMAP_DM_TIMER=y
-# CONFIG_OMAP_LL_DEBUG_UART1 is not set
-# CONFIG_OMAP_LL_DEBUG_UART2 is not set
-CONFIG_OMAP_LL_DEBUG_UART3=y
+# CONFIG_OMAP_PM_NONE is not set
+CONFIG_OMAP_PM_NOOP=y
 # CONFIG_MACH_OMAP_GENERIC is not set
 
 #
 # OMAP Core Type
 #
-CONFIG_ARCH_OMAP24XX=y
 CONFIG_ARCH_OMAP2420=y
 # CONFIG_ARCH_OMAP2430 is not set
 
@@ -227,6 +224,9 @@ CONFIG_MACH_OMAP2_TUSB6010=y
 # CONFIG_MACH_OMAP_H4 is not set
 # CONFIG_MACH_OMAP_APOLLON is not set
 # CONFIG_MACH_OMAP_2430SDP is not set
+CONFIG_MACH_NOKIA_N800=y
+CONFIG_MACH_NOKIA_N810=y
+CONFIG_MACH_NOKIA_N810_WIMAX=y
 CONFIG_MACH_NOKIA_N8X0=y
 
 #
@@ -303,7 +303,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=ttyS2,115200n8"
+CONFIG_CMDLINE="root=/dev/mmcblk0p2 console=ttyS2,115200n8 debug earlyprintk rootwait"
 # CONFIG_XIP_KERNEL is not set
 # CONFIG_KEXEC is not set
 
@@ -337,7 +337,14 @@ CONFIG_HAVE_AOUT=y
 #
 # Power management options
 #
-# CONFIG_PM is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -617,7 +624,55 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+# CONFIG_I2C_CHARDEV is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX 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
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# 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=y
 # CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
@@ -673,15 +728,44 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_HTC_I2CPLD is not set
+# CONFIG_TPS65010 is not set
+CONFIG_MENELAUS=y
+# CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_T7L66XB is not set
 # CONFIG_MFD_TC6387XB is not set
 # CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 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_AB4500_CORE is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_DUMMY 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_MAX8649 is not set
+# CONFIG_REGULATOR_MAX8660 is not set
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
 #
@@ -718,7 +802,10 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_DEVICEFS=y
 CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_OTG is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
 # CONFIG_USB_MON is not set
 # CONFIG_USB_WUSB is not set
 # CONFIG_USB_WUSB_CBAF is not set
@@ -737,9 +824,10 @@ CONFIG_USB_DEVICE_CLASS=y
 CONFIG_USB_MUSB_HDRC=y
 CONFIG_USB_TUSB6010=y
 # CONFIG_USB_MUSB_HOST is not set
-CONFIG_USB_MUSB_PERIPHERAL=y
-# CONFIG_USB_MUSB_OTG is not set
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+CONFIG_USB_MUSB_OTG=y
 CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_USB_MUSB_HDRC_HCD=y
 # CONFIG_MUSB_PIO_ONLY is not set
 # CONFIG_USB_INVENTRA_DMA is not set
 # CONFIG_USB_TI_CPPI_DMA is not set
@@ -824,44 +912,77 @@ CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_ZERO is not set
 # CONFIG_USB_AUDIO is not set
 CONFIG_USB_ETH=y
-# CONFIG_USB_ETH_RNDIS is not set
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_ETH_EEM=y
 # CONFIG_USB_GADGETFS is not set
 # CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
 # CONFIG_USB_G_SERIAL is not set
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
+# CONFIG_USB_G_MULTI is not set
 
 #
 # OTG and related infrastructure
 #
 CONFIG_USB_OTG_UTILS=y
 # CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_ISP1301_OMAP is not set
+# CONFIG_USB_ULPI is not set
 CONFIG_NOP_USB_XCEIV=y
-# CONFIG_MMC is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_OMAP=y
+# CONFIG_MMC_SPI is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES 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
 
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
-# CONFIG_EXT3_FS 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_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # 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=y
@@ -886,8 +1007,11 @@ CONFIG_INOTIFY_USER=y
 #
 # DOS/FAT/NT Filesystems
 #
+CONFIG_FAT_FS=y
 # CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
@@ -934,7 +1058,6 @@ CONFIG_JFFS2_CMODE_PRIORITY=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 is not set
 # CONFIG_NFSD is not set
index c7999f5b1c9a7a6c37d0673f203d719ded08d5c8..5a9e95fa728bab42dbe7b6b54ef697ce609892ea 100644 (file)
@@ -324,6 +324,7 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
index 714835e5ebecd15287f48a9cc8deea3cbb58fef5..d6ad92177324c88c13b81a9c505a03c37347fc3a 100644 (file)
@@ -450,7 +450,7 @@ CONFIG_SUSPEND=y
 # CONFIG_PM_TEST_SUSPEND is not set
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
-# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
index e2ad859fbec6379bff23dbd3a2b99612d2b64573..a6dd6d1af8060c1dc2257dc6e8921e4d03b63116 100644 (file)
@@ -340,6 +340,7 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
index 74fe6be9c5ecbd5967ee90cc2da8a3655812f3a0..968fbaa8f04d5999c6142ce31b816c3b6541dde9 100644 (file)
@@ -368,7 +368,7 @@ CONFIG_SUSPEND=y
 # CONFIG_PM_TEST_SUSPEND is not set
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
-# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
index bb2917e5cb478776c083361e2a6eff763355a55d..ddde429a7d9bde5812fa46f9b42163446f66adca 100644 (file)
@@ -363,6 +363,7 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
index d25c3d4424ca9c9dba76751e078169a2a4eaf08e..609f348b1055f7289447b8edf759807357ede5bc 100644 (file)
@@ -361,7 +361,7 @@ CONFIG_SUSPEND=y
 # CONFIG_PM_TEST_SUSPEND is not set
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
-# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
index 523189586a4bf62cd00a0c2bbbb903c35d36c212..91ef2ed0f80a5c97086db918ed67b10c87183211 100644 (file)
@@ -331,6 +331,7 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 
 #
index a82e81332a030a714a9e2f0e159f6bd172e47047..881faea03d794c89938775a8375035745e8597be 100644 (file)
@@ -343,6 +343,7 @@ CONFIG_SUSPEND=y
 # CONFIG_PM_TEST_SUSPEND is not set
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -660,7 +661,7 @@ CONFIG_DEVKMEM=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
index ff8ac3dcc31d8c62a0d3262435323cbb9a4f8b51..5e55b550a40858276e7d7b46e50765882166f576 100644 (file)
@@ -361,7 +361,7 @@ CONFIG_SUSPEND=y
 # CONFIG_PM_TEST_SUSPEND is not set
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
-# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -680,7 +680,7 @@ CONFIG_DEVKMEM=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
index 193bd334fbbffbfd08c18955107339040980c962..473f9e13f08b3ea98fb0a8fb04661c1693b75cff 100644 (file)
@@ -59,8 +59,6 @@ CONFIG_FAIR_GROUP_SCHED=y
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -322,6 +320,7 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -479,7 +478,6 @@ CONFIG_BT_HIDP=m
 # CONFIG_BT_HCIBFUSB is not set
 # CONFIG_BT_HCIVHCI is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 CONFIG_CFG80211=y
 # CONFIG_CFG80211_REG_DEBUG is not set
index 00f46d9ce299310360ed89a8c19e2521db58e118..6e8f05c8a1c8f61efbffbb8cab303dd28e36efc0 100644 (file)
 
 #define USER(x...)                             \
 9999:  x;                                      \
-       .section __ex_table,"a";                \
+       .pushsection __ex_table,"a";            \
        .align  3;                              \
        .long   9999b,9001f;                    \
-       .previous
+       .popsection
 
 /*
  * SMP data memory barrier
        .error  "Unsupported inc macro argument"
        .endif
 
-       .section __ex_table,"a"
+       .pushsection __ex_table,"a"
        .align  3
        .long   9999b, \abort
-       .previous
+       .popsection
        .endm
 
        .macro  usracc, instr, reg, ptr, inc, cond, rept, abort
        .error  "Unsupported inc macro argument"
        .endif
 
-       .section __ex_table,"a"
+       .pushsection __ex_table,"a"
        .align  3
        .long   9999b, \abort
-       .previous
+       .popsection
        .endr
        .endm
 
index e8ddec2cb158763d5d0a7741d44ee9e25d90696d..a0162fa9456496662adb28898fcb44776e628414 100644 (file)
@@ -24,7 +24,7 @@
  * strex/ldrex monitor on some implementations. The reason we can use it for
  * atomic_set() is the clrex or dummy strex done on every exception return.
  */
-#define atomic_read(v) ((v)->counter)
+#define atomic_read(v) (*(volatile int *)&(v)->counter)
 #define atomic_set(v,i)        (((v)->counter) = (i))
 
 #if __LINUX_ARM_ARCH__ >= 6
index 72da7e045c6b306e4d2d40bbad1db22a603f4ed7..4656a24058d21f75d30097ae5b06a1b66863bdd9 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/glue.h>
 #include <asm/shmparam.h>
 #include <asm/cachetype.h>
+#include <asm/outercache.h>
 
 #define CACHE_COLOUR(vaddr)    ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
 
@@ -219,12 +220,6 @@ struct cpu_cache_fns {
        void (*dma_flush_range)(const void *, const void *);
 };
 
-struct outer_cache_fns {
-       void (*inv_range)(unsigned long, unsigned long);
-       void (*clean_range)(unsigned long, unsigned long);
-       void (*flush_range)(unsigned long, unsigned long);
-};
-
 /*
  * Select the calling method
  */
@@ -281,37 +276,6 @@ extern void dmac_flush_range(const void *, const void *);
 
 #endif
 
-#ifdef CONFIG_OUTER_CACHE
-
-extern struct outer_cache_fns outer_cache;
-
-static inline void outer_inv_range(unsigned long start, unsigned long end)
-{
-       if (outer_cache.inv_range)
-               outer_cache.inv_range(start, end);
-}
-static inline void outer_clean_range(unsigned long start, unsigned long end)
-{
-       if (outer_cache.clean_range)
-               outer_cache.clean_range(start, end);
-}
-static inline void outer_flush_range(unsigned long start, unsigned long end)
-{
-       if (outer_cache.flush_range)
-               outer_cache.flush_range(start, end);
-}
-
-#else
-
-static inline void outer_inv_range(unsigned long start, unsigned long end)
-{ }
-static inline void outer_clean_range(unsigned long start, unsigned long end)
-{ }
-static inline void outer_flush_range(unsigned long start, unsigned long end)
-{ }
-
-#endif
-
 /*
  * Copy user data from/to a page which is mapped into a different
  * processes address space.  Really, we want to allow our "user
@@ -407,6 +371,10 @@ static inline void __flush_icache_all(void)
 #ifdef CONFIG_ARM_ERRATA_411920
        extern void v6_icache_inval_all(void);
        v6_icache_inval_all();
+#elif defined(CONFIG_SMP) && __LINUX_ARM_ARCH__ >= 7
+       asm("mcr        p15, 0, %0, c7, c1, 0   @ invalidate I-cache inner shareable\n"
+           :
+           : "r" (0));
 #else
        asm("mcr        p15, 0, %0, c7, c5, 0   @ invalidate I-cache\n"
            :
index 7a0690da5e63235b6a8b1345adc2f396b29287c8..b56c1389b6fa49da16bb940a04931480a4466c84 100644 (file)
@@ -13,6 +13,7 @@
 #define __ASM_CLKDEV_H
 
 struct clk;
+struct device;
 
 struct clk_lookup {
        struct list_head        node;
index a399bb5730f15210aa2b6b42527ea6ada7d19f15..51662feb9f1dd03b8e1c8a3f7d208c063208aa89 100644 (file)
@@ -9,6 +9,8 @@
 #include <asm/ptrace.h>
 #include <asm/user.h>
 
+struct task_struct;
+
 typedef unsigned long elf_greg_t;
 typedef unsigned long elf_freg_t[3];
 
@@ -98,6 +100,7 @@ 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)
 
+struct task_struct;
 int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
 #define ELF_CORE_COPY_TASK_REGS dump_task_regs
 
index bfcc15929a7fcd9833d4abc41e4f164645ccb133..540a044153a54ce1ffc8bed90a6bf7cee59631d8 100644 (file)
        "2:     strt    %0, [%2]\n"                             \
        "       mov     %0, #0\n"                               \
        "3:\n"                                                  \
-       "       .section __ex_table,\"a\"\n"                    \
+       "       .pushsection __ex_table,\"a\"\n"                \
        "       .align  3\n"                                    \
        "       .long   1b, 4f, 2b, 4f\n"                       \
-       "       .previous\n"                                    \
-       "       .section .fixup,\"ax\"\n"                       \
+       "       .popsection\n"                                  \
+       "       .pushsection .fixup,\"ax\"\n"                   \
        "4:     mov     %0, %4\n"                               \
        "       b       3b\n"                                   \
-       "       .previous"                                      \
+       "       .popsection"                                    \
        : "=&r" (ret), "=&r" (oldval)                           \
        : "r" (uaddr), "r" (oparg), "Ir" (-EFAULT)              \
        : "cc", "memory")
@@ -102,14 +102,14 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
        "       it      eq      @ explicit IT needed for the 2b label\n"
        "2:     streqt  %2, [%3]\n"
        "3:\n"
-       "       .section __ex_table,\"a\"\n"
+       "       .pushsection __ex_table,\"a\"\n"
        "       .align  3\n"
        "       .long   1b, 4f, 2b, 4f\n"
-       "       .previous\n"
-       "       .section .fixup,\"ax\"\n"
+       "       .popsection\n"
+       "       .pushsection .fixup,\"ax\"\n"
        "4:     mov     %0, %4\n"
        "       b       3b\n"
-       "       .previous"
+       "       .popsection"
        : "=&r" (val)
        : "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
        : "cc", "memory");
index 7f36d00600b43da38ba4fda7fa59aa61da7d60ab..feb988a7ec37dcf2336d7a908e5561b0cc3ee7d5 100644 (file)
 
 #define kmap_prot              PAGE_KERNEL
 
-#define flush_cache_kmaps()    flush_cache_all()
+#define flush_cache_kmaps() \
+       do { \
+               if (cache_is_vivt()) \
+                       flush_cache_all(); \
+       } while (0)
 
 extern pte_t *pkmap_page_table;
 
@@ -21,11 +25,20 @@ extern void *kmap_high(struct page *page);
 extern void *kmap_high_get(struct page *page);
 extern void kunmap_high(struct page *page);
 
+extern void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte);
+extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte);
+
+/*
+ * The following functions are already defined by <linux/highmem.h>
+ * when CONFIG_HIGHMEM is not set.
+ */
+#ifdef CONFIG_HIGHMEM
 extern void *kmap(struct page *page);
 extern void kunmap(struct page *page);
 extern void *kmap_atomic(struct page *page, enum km_type type);
 extern void kunmap_atomic(void *kvaddr, enum km_type type);
 extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
 extern struct page *kmap_atomic_to_page(const void *ptr);
+#endif
 
 #endif
index 328f14a8b79034a3d71e713780a0d8caed9279d6..237282f7c762f3056b2ce76ab1a0e18d75a1499c 100644 (file)
@@ -17,6 +17,7 @@
 
 #ifndef __ASSEMBLY__
 struct irqaction;
+struct pt_regs;
 extern void migrate_irqs(void);
 
 extern void asm_do_IRQ(unsigned int, struct pt_regs *);
index c019949a5189dc725a937006eb8445c18d0ad2ef..c4b2ea3fbe4249c886fad25593553502e63f5796 100644 (file)
@@ -18,6 +18,7 @@ enum km_type {
        KM_IRQ1,
        KM_SOFTIRQ0,
        KM_SOFTIRQ1,
+       KM_L1_CACHE,
        KM_L2_CACHE,
        KM_TYPE_NR
 };
diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
new file mode 100644 (file)
index 0000000..25f76ba
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * arch/arm/include/asm/outercache.h
+ *
+ * Copyright (C) 2010 ARM Ltd.
+ * Written by Catalin Marinas <catalin.marinas@arm.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_OUTERCACHE_H
+#define __ASM_OUTERCACHE_H
+
+struct outer_cache_fns {
+       void (*inv_range)(unsigned long, unsigned long);
+       void (*clean_range)(unsigned long, unsigned long);
+       void (*flush_range)(unsigned long, unsigned long);
+#ifdef CONFIG_OUTER_CACHE_SYNC
+       void (*sync)(void);
+#endif
+};
+
+#ifdef CONFIG_OUTER_CACHE
+
+extern struct outer_cache_fns outer_cache;
+
+static inline void outer_inv_range(unsigned long start, unsigned long end)
+{
+       if (outer_cache.inv_range)
+               outer_cache.inv_range(start, end);
+}
+static inline void outer_clean_range(unsigned long start, unsigned long end)
+{
+       if (outer_cache.clean_range)
+               outer_cache.clean_range(start, end);
+}
+static inline void outer_flush_range(unsigned long start, unsigned long end)
+{
+       if (outer_cache.flush_range)
+               outer_cache.flush_range(start, end);
+}
+
+#else
+
+static inline void outer_inv_range(unsigned long start, unsigned long end)
+{ }
+static inline void outer_clean_range(unsigned long start, unsigned long end)
+{ }
+static inline void outer_flush_range(unsigned long start, unsigned long end)
+{ }
+
+#endif
+
+#ifdef CONFIG_OUTER_CACHE_SYNC
+static inline void outer_sync(void)
+{
+       if (outer_cache.sync)
+               outer_cache.sync();
+}
+#else
+static inline void outer_sync(void)
+{ }
+#endif
+
+#endif /* __ASM_OUTERCACHE_H */
index 013cfcdc4839a2df6b5f0e842515c0a0c166f524..ffc0e85775b4cff15586897cac32758dc0dda687 100644 (file)
@@ -67,6 +67,7 @@ static inline int pte_file(pte_t pte) { return 0; }
  */
 #define pgprot_noncached(prot) __pgprot(0)
 #define pgprot_writecombine(prot) __pgprot(0)
+#define pgprot_dmacoherent(prot) __pgprot(0)
 
 
 /*
index 7be0978b2625c9e365fde3d28ca4679d1e9c4933..634f357be6bb787d8a578cfa90a99b7742529b19 100644 (file)
@@ -1,6 +1,23 @@
 #ifndef __ASMARM_SMP_TWD_H
 #define __ASMARM_SMP_TWD_H
 
+#define TWD_TIMER_LOAD                 0x00
+#define TWD_TIMER_COUNTER              0x04
+#define TWD_TIMER_CONTROL              0x08
+#define TWD_TIMER_INTSTAT              0x0C
+
+#define TWD_WDOG_LOAD                  0x20
+#define TWD_WDOG_COUNTER               0x24
+#define TWD_WDOG_CONTROL               0x28
+#define TWD_WDOG_INTSTAT               0x2C
+#define TWD_WDOG_RESETSTAT             0x30
+#define TWD_WDOG_DISABLE               0x34
+
+#define TWD_TIMER_CONTROL_ENABLE       (1 << 0)
+#define TWD_TIMER_CONTROL_ONESHOT      (0 << 1)
+#define TWD_TIMER_CONTROL_PERIODIC     (1 << 1)
+#define TWD_TIMER_CONTROL_IT_ENABLE    (1 << 2)
+
 struct clock_event_device;
 
 extern void __iomem *twd_base;
index ca88e6a84707350bad0b1ab3bd7eefcd116be506..4ace45ec3ef84f5d15d72db4b96f89a5e87fa3be 100644 (file)
@@ -60,6 +60,8 @@
 #include <linux/linkage.h>
 #include <linux/irqflags.h>
 
+#include <asm/outercache.h>
+
 #define __exception    __attribute__((section(".exception.text")))
 
 struct thread_info;
@@ -137,10 +139,12 @@ extern unsigned int user_debug;
 #define dmb() __asm__ __volatile__ ("" : : : "memory")
 #endif
 
-#if __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP)
-#define mb()           dmb()
+#ifdef CONFIG_ARCH_HAS_BARRIERS
+#include <mach/barriers.h>
+#elif __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP)
+#define mb()           do { dsb(); outer_sync(); } while (0)
 #define rmb()          dmb()
-#define wmb()          dmb()
+#define wmb()          mb()
 #else
 #define mb()   do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
 #define rmb()  do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
@@ -152,9 +156,9 @@ extern unsigned int user_debug;
 #define smp_rmb()      barrier()
 #define smp_wmb()      barrier()
 #else
-#define smp_mb()       mb()
-#define smp_rmb()      rmb()
-#define smp_wmb()      wmb()
+#define smp_mb()       dmb()
+#define smp_rmb()      dmb()
+#define smp_wmb()      dmb()
 #endif
 
 #define read_barrier_depends()         do { } while(0)
index e085e2c545ebabad792dfa6e25fb149eb3cada27..bd863d8608cd04013e76e9b6ebde8225e0c078d7 100644 (file)
@@ -46,6 +46,9 @@
 #define TLB_V7_UIS_FULL (1 << 20)
 #define TLB_V7_UIS_ASID (1 << 21)
 
+/* Inner Shareable BTB operation (ARMv7 MP extensions) */
+#define TLB_V7_IS_BTB  (1 << 22)
+
 #define TLB_L2CLEAN_FR (1 << 29)               /* Feroceon */
 #define TLB_DCLEAN     (1 << 30)
 #define TLB_WB         (1 << 31)
 #endif
 
 #ifdef CONFIG_SMP
-#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \
+#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \
                         TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID)
 #else
 #define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \
@@ -339,6 +342,12 @@ static inline void local_flush_tlb_all(void)
                dsb();
                isb();
        }
+       if (tlb_flag(TLB_V7_IS_BTB)) {
+               /* flush the branch target cache */
+               asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+               dsb();
+               isb();
+       }
 }
 
 static inline void local_flush_tlb_mm(struct mm_struct *mm)
@@ -376,6 +385,12 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
                asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
                dsb();
        }
+       if (tlb_flag(TLB_V7_IS_BTB)) {
+               /* flush the branch target cache */
+               asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+               dsb();
+               isb();
+       }
 }
 
 static inline void
@@ -416,6 +431,12 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
                asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
                dsb();
        }
+       if (tlb_flag(TLB_V7_IS_BTB)) {
+               /* flush the branch target cache */
+               asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+               dsb();
+               isb();
+       }
 }
 
 static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
@@ -454,6 +475,12 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
                dsb();
                isb();
        }
+       if (tlb_flag(TLB_V7_IS_BTB)) {
+               /* flush the branch target cache */
+               asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+               dsb();
+               isb();
+       }
 }
 
 /*
index 1d6bd40a4322e9d7196d96f5054f8d1bc6e1cd5b..33e4a48fe1037575d4d6e212000a8aa01303f7fc 100644 (file)
@@ -229,16 +229,16 @@ do {                                                                      \
        __asm__ __volatile__(                                   \
        "1:     ldrbt   %1,[%2]\n"                              \
        "2:\n"                                                  \
-       "       .section .fixup,\"ax\"\n"                       \
+       "       .pushsection .fixup,\"ax\"\n"                   \
        "       .align  2\n"                                    \
        "3:     mov     %0, %3\n"                               \
        "       mov     %1, #0\n"                               \
        "       b       2b\n"                                   \
-       "       .previous\n"                                    \
-       "       .section __ex_table,\"a\"\n"                    \
+       "       .popsection\n"                                  \
+       "       .pushsection __ex_table,\"a\"\n"                \
        "       .align  3\n"                                    \
        "       .long   1b, 3b\n"                               \
-       "       .previous"                                      \
+       "       .popsection"                                    \
        : "+r" (err), "=&r" (x)                                 \
        : "r" (addr), "i" (-EFAULT)                             \
        : "cc")
@@ -265,16 +265,16 @@ do {                                                                      \
        __asm__ __volatile__(                                   \
        "1:     ldrt    %1,[%2]\n"                              \
        "2:\n"                                                  \
-       "       .section .fixup,\"ax\"\n"                       \
+       "       .pushsection .fixup,\"ax\"\n"                   \
        "       .align  2\n"                                    \
        "3:     mov     %0, %3\n"                               \
        "       mov     %1, #0\n"                               \
        "       b       2b\n"                                   \
-       "       .previous\n"                                    \
-       "       .section __ex_table,\"a\"\n"                    \
+       "       .popsection\n"                                  \
+       "       .pushsection __ex_table,\"a\"\n"                \
        "       .align  3\n"                                    \
        "       .long   1b, 3b\n"                               \
-       "       .previous"                                      \
+       "       .popsection"                                    \
        : "+r" (err), "=&r" (x)                                 \
        : "r" (addr), "i" (-EFAULT)                             \
        : "cc")
@@ -310,15 +310,15 @@ do {                                                                      \
        __asm__ __volatile__(                                   \
        "1:     strbt   %1,[%2]\n"                              \
        "2:\n"                                                  \
-       "       .section .fixup,\"ax\"\n"                       \
+       "       .pushsection .fixup,\"ax\"\n"                   \
        "       .align  2\n"                                    \
        "3:     mov     %0, %3\n"                               \
        "       b       2b\n"                                   \
-       "       .previous\n"                                    \
-       "       .section __ex_table,\"a\"\n"                    \
+       "       .popsection\n"                                  \
+       "       .pushsection __ex_table,\"a\"\n"                \
        "       .align  3\n"                                    \
        "       .long   1b, 3b\n"                               \
-       "       .previous"                                      \
+       "       .popsection"                                    \
        : "+r" (err)                                            \
        : "r" (x), "r" (__pu_addr), "i" (-EFAULT)               \
        : "cc")
@@ -343,15 +343,15 @@ do {                                                                      \
        __asm__ __volatile__(                                   \
        "1:     strt    %1,[%2]\n"                              \
        "2:\n"                                                  \
-       "       .section .fixup,\"ax\"\n"                       \
+       "       .pushsection .fixup,\"ax\"\n"                   \
        "       .align  2\n"                                    \
        "3:     mov     %0, %3\n"                               \
        "       b       2b\n"                                   \
-       "       .previous\n"                                    \
-       "       .section __ex_table,\"a\"\n"                    \
+       "       .popsection\n"                                  \
+       "       .pushsection __ex_table,\"a\"\n"                \
        "       .align  3\n"                                    \
        "       .long   1b, 3b\n"                               \
-       "       .previous"                                      \
+       "       .popsection"                                    \
        : "+r" (err)                                            \
        : "r" (x), "r" (__pu_addr), "i" (-EFAULT)               \
        : "cc")
@@ -371,16 +371,16 @@ do {                                                                      \
  THUMB(        "1:     strt    " __reg_oper1 ", [%1]\n"        )       \
  THUMB(        "2:     strt    " __reg_oper0 ", [%1, #4]\n"    )       \
        "3:\n"                                                  \
-       "       .section .fixup,\"ax\"\n"                       \
+       "       .pushsection .fixup,\"ax\"\n"                   \
        "       .align  2\n"                                    \
        "4:     mov     %0, %3\n"                               \
        "       b       3b\n"                                   \
-       "       .previous\n"                                    \
-       "       .section __ex_table,\"a\"\n"                    \
+       "       .popsection\n"                                  \
+       "       .pushsection __ex_table,\"a\"\n"                \
        "       .align  3\n"                                    \
        "       .long   1b, 4b\n"                               \
        "       .long   2b, 4b\n"                               \
-       "       .previous"                                      \
+       "       .popsection"                                    \
        : "+r" (err), "+r" (__pu_addr)                          \
        : "r" (x), "i" (-EFAULT)                                \
        : "cc")
index bf65e9f4525d04f78dacff51b229ee7f767b0432..47f023aa849587d89dc194f1aed5365cf7d81a92 100644 (file)
@@ -59,23 +59,22 @@ struct iwmmxt_sigframe {
 #endif /* CONFIG_IWMMXT */
 
 #ifdef CONFIG_VFP
-#if __LINUX_ARM_ARCH__ < 6
-/* For ARM pre-v6, we use fstmiax and fldmiax.  This adds one extra
- * word after the registers, and a word of padding at the end for
- * alignment.  */
 #define VFP_MAGIC              0x56465001
-#define VFP_STORAGE_SIZE       152
-#else
-#define VFP_MAGIC              0x56465002
-#define VFP_STORAGE_SIZE       144
-#endif
 
 struct vfp_sigframe
 {
        unsigned long           magic;
        unsigned long           size;
-       union vfp_state         storage;
-};
+       struct user_vfp         ufp;
+       struct user_vfp_exc     ufp_exc;
+} __attribute__((__aligned__(8)));
+
+/*
+ *  8 byte for magic and size, 264 byte for ufp, 12 bytes for ufp_exc,
+ *  4 bytes padding.
+ */
+#define VFP_STORAGE_SIZE       sizeof(struct vfp_sigframe)
+
 #endif /* CONFIG_VFP */
 
 /*
@@ -91,7 +90,7 @@ struct aux_sigframe {
 #ifdef CONFIG_IWMMXT
        struct iwmmxt_sigframe  iwmmxt;
 #endif
-#if 0 && defined CONFIG_VFP /* Not yet saved.  */
+#ifdef CONFIG_VFP
        struct vfp_sigframe     vfp;
 #endif
        /* Something that isn't a valid magic number for any coprocessor.  */
index df95e050f9dd75ea6305417e221574e55993bd9c..05ac4b06876a0c30b3f49dc2ad9652f20a63f9e5 100644 (file)
@@ -83,11 +83,21 @@ struct user{
 
 /*
  * User specific VFP registers. If only VFPv2 is present, registers 16 to 31
- * are ignored by the ptrace system call.
+ * are ignored by the ptrace system call and the signal handler.
  */
 struct user_vfp {
        unsigned long long fpregs[32];
        unsigned long fpscr;
 };
 
+/*
+ * VFP exception registers exposed to user space during signal delivery.
+ * Fields not relavant to the current VFP architecture are ignored.
+ */
+struct user_vfp_exc {
+       unsigned long   fpexc;
+       unsigned long   fpinst;
+       unsigned long   fpinst2;
+};
+
 #endif /* _ARM_USER_H */
index 6c5cf369183b414dee5e8685be889cd646d77a7e..7ee48e7f8f318a7b453e12849b60a6832bb85770 100644 (file)
@@ -523,16 +523,16 @@ ENDPROC(__und_usr)
 /*
  * The out of line fixup for the ldrt above.
  */
-       .section .fixup, "ax"
+       .pushsection .fixup, "ax"
 4:     mov     pc, r9
-       .previous
-       .section __ex_table,"a"
+       .popsection
+       .pushsection __ex_table,"a"
        .long   1b, 4b
 #if __LINUX_ARM_ARCH__ >= 7
        .long   2b, 4b
        .long   3b, 4b
 #endif
-       .previous
+       .popsection
 
 /*
  * Check whether the instruction is a co-processor instruction.
@@ -676,10 +676,10 @@ do_fpe:
  *  lr  = unrecognised FP instruction return address
  */
 
-       .data
+       .pushsection .data
 ENTRY(fp_enter)
        .word   no_fp
-       .previous
+       .popsection
 
 ENTRY(no_fp)
        mov     pc, lr
index 7e9ed1eea40a63d3a72e898b46278ef38911c741..d93f976fb3893638900e8ff4660f1c6891a21457 100644 (file)
        .else
        ldmdb   sp, {r0 - lr}^                  @ get calling r0 - lr
        .endif
+       mov     r0, r0                          @ ARMv5T and earlier require a nop
+                                               @ after ldm {}^
        add     sp, sp, #S_FRAME_SIZE - S_PC
        movs    pc, lr                          @ return & move spsr_svc into cpsr
        .endm
index c638427662291c2fbd28d259b6121286d245d1d3..0298286ad4ad5971302a6690c5046e66826bccb2 100644 (file)
@@ -62,15 +62,15 @@ int ftrace_modify_code(unsigned long pc, unsigned char *old_code,
                "    movne  %0, #2    \n"
                "3:\n"
 
-               ".section .fixup, \"ax\"\n"
+               ".pushsection .fixup, \"ax\"\n"
                "4:  mov  %0, #1  \n"
                "    b    3b      \n"
-               ".previous\n"
+               ".popsection\n"
 
-               ".section __ex_table, \"a\"\n"
+               ".pushsection __ex_table, \"a\"\n"
                "    .long 1b, 4b \n"
                "    .long 2b, 4b \n"
-               ".previous\n"
+               ".popsection\n"
 
                : "=r"(err), "=r"(replaced)
                : "r"(pc), "r"(new), "r"(old), "0"(err), "1"(replaced)
index b7cb45bb91e8f1cb80eeb18bb05d477aa57fcdc1..3b3d2c80509c0bb4c3499f944414a11425f6e5e6 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/smp.h>
 #include <linux/init.h>
index ba8ccfede964d93a81c061633bd969916d85ebd5..a5b846b9895d6f414c5bf646cd39ebdc7c86078f 100644 (file)
@@ -9,6 +9,7 @@
  * Authors:  George Davis <davis_g@mvista.com>
  *           Deepak Saxena <dsaxena@plexity.net>
  */
+#include <linux/irq.h>
 #include <linux/kgdb.h>
 #include <asm/traps.h>
 
@@ -158,6 +159,18 @@ static struct undef_hook kgdb_compiled_brkpt_hook = {
        .fn                     = kgdb_compiled_brk_fn
 };
 
+static void kgdb_call_nmi_hook(void *ignored)
+{
+       kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
+}
+
+void kgdb_roundup_cpus(unsigned long flags)
+{
+       local_irq_enable();
+       smp_call_function(kgdb_call_nmi_hook, NULL, 0);
+       local_irq_disable();
+}
+
 /**
  *     kgdb_arch_init - Perform any architecture specific initalization.
  *
index 60c62c377fa91bffe0de06e14a3b8a4187343240..2ba7deb3072e5962c6cd3de55d4a2ed2594c1589 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/stop_machine.h>
 #include <linux/stringify.h>
 #include <asm/traps.h>
@@ -393,6 +394,14 @@ void __kprobes jprobe_return(void)
                /*
                 * Setup an empty pt_regs. Fill SP and PC fields as
                 * they're needed by longjmp_break_handler.
+                *
+                * We allocate some slack between the original SP and start of
+                * our fabricated regs. To be precise we want to have worst case
+                * covered which is STMFD with all 16 regs so we allocate 2 *
+                * sizeof(struct_pt_regs)).
+                *
+                * This is to prevent any simulated instruction from writing
+                * over the regs when they are accessing the stack.
                 */
                "sub    sp, %0, %1              \n\t"
                "ldr    r0, ="__stringify(JPROBE_MAGIC_ADDR)"\n\t"
@@ -410,7 +419,7 @@ void __kprobes jprobe_return(void)
                "ldmia  sp, {r0 - pc}           \n\t"
                :
                : "r" (kcb->jprobe_saved_regs.ARM_sp),
-                 "I" (sizeof(struct pt_regs)),
+                 "I" (sizeof(struct pt_regs) * 2),
                  "J" (offsetof(struct pt_regs, ARM_sp)),
                  "J" (offsetof(struct pt_regs, ARM_pc)),
                  "J" (offsetof(struct pt_regs, ARM_cpsr))
index f28c5e9c51ea5e33967186ff07123262e8d0adf0..c628bdf6c4308edbb7517664641a308fdd2164c8 100644 (file)
@@ -16,9 +16,9 @@
 #include <linux/mm.h>
 #include <linux/elf.h>
 #include <linux/vmalloc.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/string.h>
+#include <linux/gfp.h>
 
 #include <asm/pgtable.h>
 #include <asm/sections.h>
index 3875d99cc40f1f2ad63c09001ea202fdf5520e38..9e70f2053f9aaa0446d603142f23933a3ac02448 100644 (file)
@@ -332,7 +332,8 @@ armpmu_reserve_hardware(void)
 
        for (i = 0; i < pmu_irqs->num_irqs; ++i) {
                err = request_irq(pmu_irqs->irqs[i], armpmu->handle_irq,
-                                 IRQF_DISABLED, "armpmu", NULL);
+                                 IRQF_DISABLED | IRQF_NOBALANCING,
+                                 "armpmu", NULL);
                if (err) {
                        pr_warning("unable to request IRQ%d for ARM "
                                   "perf counters\n", pmu_irqs->irqs[i]);
@@ -1624,7 +1625,7 @@ enum armv7_counters {
 /*
  * EVTSEL: Event selection reg
  */
-#define        ARMV7_EVTSEL_MASK       0x7f            /* Mask for writable bits */
+#define        ARMV7_EVTSEL_MASK       0xff            /* Mask for writable bits */
 
 /*
  * SELECT: Counter selection reg
index ba2adefa53f764200cc31f5ce29f28ddaa62ef97..acf5e6fdb6dcbe991d7bed5d63c7a77f38c16e34 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/mm.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/delay.h>
 #include <linux/reboot.h>
@@ -356,7 +355,7 @@ EXPORT_SYMBOL(dump_fpu);
  * the thread function, and r3 points to the exit function.
  */
 extern void kernel_thread_helper(void);
-asm(   ".section .text\n"
+asm(   ".pushsection .text\n"
 "      .align\n"
 "      .type   kernel_thread_helper, #function\n"
 "kernel_thread_helper:\n"
@@ -364,11 +363,11 @@ asm(      ".section .text\n"
 "      mov     lr, r3\n"
 "      mov     pc, r2\n"
 "      .size   kernel_thread_helper, . - kernel_thread_helper\n"
-"      .previous");
+"      .popsection");
 
 #ifdef CONFIG_ARM_UNWIND
 extern void kernel_thread_exit(long code);
-asm(   ".section .text\n"
+asm(   ".pushsection .text\n"
 "      .align\n"
 "      .type   kernel_thread_exit, #function\n"
 "kernel_thread_exit:\n"
@@ -378,7 +377,7 @@ asm(        ".section .text\n"
 "      nop\n"
 "      .fnend\n"
 "      .size   kernel_thread_exit, . - kernel_thread_exit\n"
-"      .previous");
+"      .popsection");
 #else
 #define kernel_thread_exit     do_exit
 #endif
index e7714f367eb83aa0a4b0224e5129ec94c87c3391..907d5a620bca2655a68a29fa004bc9445ae78543 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/cacheflush.h>
 #include <asm/ucontext.h>
 #include <asm/unistd.h>
+#include <asm/vfp.h>
 
 #include "ptrace.h"
 #include "signal.h"
@@ -175,6 +176,90 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
 
 #endif
 
+#ifdef CONFIG_VFP
+
+static int preserve_vfp_context(struct vfp_sigframe __user *frame)
+{
+       struct thread_info *thread = current_thread_info();
+       struct vfp_hard_struct *h = &thread->vfpstate.hard;
+       const unsigned long magic = VFP_MAGIC;
+       const unsigned long size = VFP_STORAGE_SIZE;
+       int err = 0;
+
+       vfp_sync_hwstate(thread);
+       __put_user_error(magic, &frame->magic, err);
+       __put_user_error(size, &frame->size, err);
+
+       /*
+        * Copy the floating point registers. There can be unused
+        * registers see asm/hwcap.h for details.
+        */
+       err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs,
+                             sizeof(h->fpregs));
+       /*
+        * Copy the status and control register.
+        */
+       __put_user_error(h->fpscr, &frame->ufp.fpscr, err);
+
+       /*
+        * Copy the exception registers.
+        */
+       __put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err);
+       __put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
+       __put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
+
+       return err ? -EFAULT : 0;
+}
+
+static int restore_vfp_context(struct vfp_sigframe __user *frame)
+{
+       struct thread_info *thread = current_thread_info();
+       struct vfp_hard_struct *h = &thread->vfpstate.hard;
+       unsigned long magic;
+       unsigned long size;
+       unsigned long fpexc;
+       int err = 0;
+
+       __get_user_error(magic, &frame->magic, err);
+       __get_user_error(size, &frame->size, err);
+
+       if (err)
+               return -EFAULT;
+       if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
+               return -EINVAL;
+
+       /*
+        * Copy the floating point registers. There can be unused
+        * registers see asm/hwcap.h for details.
+        */
+       err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs,
+                               sizeof(h->fpregs));
+       /*
+        * Copy the status and control register.
+        */
+       __get_user_error(h->fpscr, &frame->ufp.fpscr, err);
+
+       /*
+        * Sanitise and restore the exception registers.
+        */
+       __get_user_error(fpexc, &frame->ufp_exc.fpexc, err);
+       /* Ensure the VFP is enabled. */
+       fpexc |= FPEXC_EN;
+       /* Ensure FPINST2 is invalid and the exception flag is cleared. */
+       fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
+       h->fpexc = fpexc;
+
+       __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
+       __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
+
+       if (!err)
+               vfp_flush_hwstate(thread);
+
+       return err ? -EFAULT : 0;
+}
+
+#endif
+
 /*
  * Do a signal return; undo the signal stack.  These are aligned to 64-bit.
  */
@@ -233,8 +318,8 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
                err |= restore_iwmmxt_context(&aux->iwmmxt);
 #endif
 #ifdef CONFIG_VFP
-//     if (err == 0)
-//             err |= vfp_restore_state(&sf->aux.vfp);
+       if (err == 0)
+               err |= restore_vfp_context(&aux->vfp);
 #endif
 
        return err;
@@ -348,8 +433,8 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
                err |= preserve_iwmmxt_context(&aux->iwmmxt);
 #endif
 #ifdef CONFIG_VFP
-//     if (err == 0)
-//             err |= vfp_save_state(&sf->aux.vfp);
+       if (err == 0)
+               err |= preserve_vfp_context(&aux->vfp);
 #endif
        __put_user_error(0, &aux->end_magic, err);
 
index 57162af53dc982cc0911e09537915eb1eddc1cbb..a01194e583ff8000587ae9b8887e35fc15e60c59 100644 (file)
@@ -86,6 +86,12 @@ int __cpuinit __cpu_up(unsigned int cpu)
                        return PTR_ERR(idle);
                }
                ci->idle = idle;
+       } else {
+               /*
+                * Since this idle thread is being re-used, call
+                * init_idle() to reinitialize the thread structure.
+                */
+               init_idle(idle, cpu);
        }
 
        /*
@@ -99,6 +105,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
        *pmd = __pmd((PHYS_OFFSET & PGDIR_MASK) |
                     PMD_TYPE_SECT | PMD_SECT_AP_WRITE);
        flush_pmd_entry(pmd);
+       outer_clean_range(__pa(pmd), __pa(pmd + 1));
 
        /*
         * We need to tell the secondary core where to find
@@ -106,7 +113,8 @@ int __cpuinit __cpu_up(unsigned int cpu)
         */
        secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
        secondary_data.pgdir = virt_to_phys(pgd);
-       wmb();
+       __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data));
+       outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1));
 
        /*
         * Now bring the CPU into our world.
index ea02a7b1c244af0afd610f6fc00c7f836f72ae4d..7c5f0c024db7e468aba3a185bded3bf3fde7073a 100644 (file)
 #include <asm/smp_twd.h>
 #include <asm/hardware/gic.h>
 
-#define TWD_TIMER_LOAD                         0x00
-#define TWD_TIMER_COUNTER              0x04
-#define TWD_TIMER_CONTROL              0x08
-#define TWD_TIMER_INTSTAT              0x0C
-
-#define TWD_WDOG_LOAD                  0x20
-#define TWD_WDOG_COUNTER               0x24
-#define TWD_WDOG_CONTROL               0x28
-#define TWD_WDOG_INTSTAT               0x2C
-#define TWD_WDOG_RESETSTAT             0x30
-#define TWD_WDOG_DISABLE               0x34
-
-#define TWD_TIMER_CONTROL_ENABLE       (1 << 0)
-#define TWD_TIMER_CONTROL_ONESHOT      (0 << 1)
-#define TWD_TIMER_CONTROL_PERIODIC     (1 << 1)
-#define TWD_TIMER_CONTROL_IT_ENABLE    (1 << 2)
-
 /* set up by the platform code */
 void __iomem *twd_base;
 
index 4350f75e578c5815a8fe428aad512df27ca1e6e8..c23501842b98b06465d94071209e6fcc819a651c 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
@@ -27,6 +26,7 @@
 #include <linux/file.h>
 #include <linux/ipc.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 
 /* Fork a new task - this creates a new program thread.
  * This is called indirectly via a small wrapper
index aaf7220d9e30bd0f4cab505bf0aa3b3d44edfa73..a673297b0cf14c39acbbfa27dd57a034e7b02410 100644 (file)
@@ -110,13 +110,13 @@ no_frame: ldmfd   sp!, {r4 - r8, pc}
 ENDPROC(__backtrace)
 ENDPROC(c_backtrace)
                
-               .section __ex_table,"a"
+               .pushsection __ex_table,"a"
                .align  3
                .long   1001b, 1006b
                .long   1002b, 1006b
                .long   1003b, 1006b
                .long   1004b, 1006b
-               .previous
+               .popsection
 
 #define instr r4
 #define reg   r5
index 1279abd8b886b94a30007dbb874d89747b69e564..14a0d988c82cb41ab88acd4d924bf75aa87efce3 100644 (file)
@@ -45,9 +45,10 @@ USER(                strnebt r2, [r0])
                mov     r0, #0
                ldmfd   sp!, {r1, pc}
 ENDPROC(__clear_user)
+ENDPROC(__clear_user_std)
 
-               .section .fixup,"ax"
+               .pushsection .fixup,"ax"
                .align  0
 9001:          ldmfd   sp!, {r0, pc}
-               .previous
+               .popsection
 
index e4fe124acedc80e94e2edc37b7123cc0ef56ae5e..66a477a3e3cc6b039c3d48e2ec4d42c57651626a 100644 (file)
@@ -90,7 +90,7 @@ ENTRY(__copy_from_user)
 
 ENDPROC(__copy_from_user)
 
-       .section .fixup,"ax"
+       .pushsection .fixup,"ax"
        .align 0
        copy_abort_preamble
        ldmfd   sp!, {r1, r2}
@@ -100,5 +100,5 @@ ENDPROC(__copy_from_user)
        bl      __memzero
        ldr     r0, [sp], #4
        copy_abort_end
-       .previous
+       .popsection
 
index 1a71e15844428dd6c68bf32ac1cfe3514d34e31b..d066df686e17877c9e5efbbd57e07615398f6a0a 100644 (file)
@@ -93,13 +93,14 @@ WEAK(__copy_to_user)
 #include "copy_template.S"
 
 ENDPROC(__copy_to_user)
+ENDPROC(__copy_to_user_std)
 
-       .section .fixup,"ax"
+       .pushsection .fixup,"ax"
        .align 0
        copy_abort_preamble
        ldmfd   sp!, {r1, r2, r3}
        sub     r0, r0, r1
        rsb     r0, r0, r2
        copy_abort_end
-       .previous
+       .popsection
 
index fd0e9dcd9fdc3243de42c38bb655112cfd3bdec4..59ff6fdc1e634835575846693fb0828a05c66a55 100644 (file)
@@ -68,7 +68,7 @@
  * so properly, we would have to add in whatever registers were loaded before
  * the fault, which, with the current asm above is not predictable.
  */
-               .section .fixup,"ax"
+               .pushsection .fixup,"ax"
                .align  4
 9001:          mov     r4, #-EFAULT
                ldr     r5, [fp, #4]            @ *err_ptr
@@ -80,4 +80,4 @@
                strneb  r0, [r1], #1
                bne     9002b
                load_regs
-               .previous
+               .popsection
index a1814d927122aaa3ac74d4f34e78a6c9f3c92367..b1631a7dbe750dc4615e8d76f535e48fb2a0c52d 100644 (file)
@@ -64,9 +64,9 @@ __get_user_bad:
        mov     pc, lr
 ENDPROC(__get_user_bad)
 
-.section __ex_table, "a"
+.pushsection __ex_table, "a"
        .long   1b, __get_user_bad
        .long   2b, __get_user_bad
        .long   3b, __get_user_bad
        .long   4b, __get_user_bad
-.previous
+.popsection
index 5025c863713d60decb20d5924109bef0a7c48ef9..938fc14f962d35693cc96c9d3f8899ae1b5bd193 100644 (file)
@@ -74,7 +74,7 @@ ENTRY(memmove)
                rsb     ip, ip, #32
                addne   pc, pc, ip              @ C is always clear here
                b       7f
-6:             nop
+6:             W(nop)
                W(ldr)  r3, [r1, #-4]!
                W(ldr)  r4, [r1, #-4]!
                W(ldr)  r5, [r1, #-4]!
@@ -85,7 +85,7 @@ ENTRY(memmove)
 
                add     pc, pc, ip
                nop
-               nop
+               W(nop)
                W(str)  r3, [r0, #-4]!
                W(str)  r4, [r0, #-4]!
                W(str)  r5, [r0, #-4]!
index 02fedbf07c0d295cb192ce682bce65d503fe7d35..5a01a23c6c06f8315a571e93dde34a18dc744591 100644 (file)
@@ -81,11 +81,11 @@ __put_user_bad:
        mov     pc, lr
 ENDPROC(__put_user_bad)
 
-.section __ex_table, "a"
+.pushsection __ex_table, "a"
        .long   1b, __put_user_bad
        .long   2b, __put_user_bad
        .long   3b, __put_user_bad
        .long   4b, __put_user_bad
        .long   5b, __put_user_bad
        .long   6b, __put_user_bad
-.previous
+.popsection
index 1c9814f346c679b3ec708bbd47573033f34f8489..f202d7bd164785d51074b0d66ca5241948e05c99 100644 (file)
@@ -33,11 +33,11 @@ ENTRY(__strncpy_from_user)
        mov     pc, lr
 ENDPROC(__strncpy_from_user)
 
-       .section .fixup,"ax"
+       .pushsection .fixup,"ax"
        .align  0
 9001:  mov     r3, #0
        strb    r3, [r0, #0]    @ null terminate
        mov     r0, #-EFAULT
        mov     pc, lr
-       .previous
+       .popsection
 
index 7855b290665971f70cfe4ff1606787eb6ed4f941..0ecbb459c4f1e7c5c2b653db312291584ca10310 100644 (file)
@@ -33,8 +33,8 @@ ENTRY(__strnlen_user)
        mov     pc, lr
 ENDPROC(__strnlen_user)
 
-       .section .fixup,"ax"
+       .pushsection .fixup,"ax"
        .align  0
 9001:  mov     r0, #0
        mov     pc, lr
-       .previous
+       .popsection
index ffdd27498ceef69471f230317725ecea1951f111..fee9f6f88adb5eddf11f78ac8345423256381757 100644 (file)
@@ -279,10 +279,10 @@ USER(             strgtbt r3, [r0], #1)                   @ May fault
                b       .Lc2u_finished
 ENDPROC(__copy_to_user)
 
-               .section .fixup,"ax"
+               .pushsection .fixup,"ax"
                .align  0
 9001:          ldmfd   sp!, {r0, r4 - r7, pc}
-               .previous
+               .popsection
 
 /* Prototype: unsigned long __copy_from_user(void *to,const void *from,unsigned long n);
  * Purpose  : copy a block from user memory to kernel memory
@@ -545,7 +545,7 @@ USER(               ldrgtbt r3, [r1], #1)                   @ May fault
                b       .Lcfu_finished
 ENDPROC(__copy_from_user)
 
-               .section .fixup,"ax"
+               .pushsection .fixup,"ax"
                .align  0
                /*
                 * We took an exception.  r0 contains a pointer to
@@ -559,5 +559,5 @@ ENDPROC(__copy_from_user)
                blne    __memzero
                mov     r0, r4
                ldmfd   sp!, {r4 - r7, pc}
-               .previous
+               .popsection
 
index 6b967ffb6552525efdeb7c121cd5d00ddb3e75db..e2d2f2cd0c4f3b5c9b9c958aa65d073bcbbe722f 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/hardirq.h> /* for in_atomic() */
+#include <linux/gfp.h>
 #include <asm/current.h>
 #include <asm/page.h>
 
index b5c5fc6ba3a9d32d39a0d6e4379c8de5d2ffbd42..3ef68330452a7e9037bb9314362130046cead895 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/timex.h>
 #include <linux/signal.h>
 #include <linux/clk.h>
+#include <linux/gfp.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
index 027dd570dcc30231059d3530f5a33293f168dce7..d4004557532af48d0f119aff9d928c234dc35853 100644 (file)
@@ -16,8 +16,8 @@ obj-$(CONFIG_ARCH_AT91SAM9261)        += at91sam9261.o at91sam926x_time.o at91sam9261_d
 obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9RL)  += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
-obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o  sam9_smc.o
- obj-$(CONFIG_ARCH_AT91SAM9G45)        += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91CAP9)    += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT572D940HF)  += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91X40)     += at91x40.o at91x40_time.o
index 29cf83177484dff44dfc9b126146894e6204b783..c11fd47aec5d464a9f228f19a9ac79097ebcaf46 100644 (file)
@@ -271,10 +271,12 @@ static void __init ek_add_device_buttons(void) {}
 
 
 static struct i2c_board_info __initdata ek_i2c_devices[] = {
-       {
-               I2C_BOARD_INFO("24c512", 0x50),
-               I2C_BOARD_INFO("wm8731", 0x1b),
-       },
+        {
+                I2C_BOARD_INFO("24c512", 0x50)
+        },
+        {
+                I2C_BOARD_INFO("wm8731", 0x1b)
+        },
 };
 
 
index 987fab3d846a539441f3fbe435042d28b19bfd10..9c5b48e68a71343e26f2f17c4856886fc0509373 100644 (file)
@@ -175,8 +175,6 @@ ENTRY(at91_slow_clock)
        orr     r3, r3, #(1 << 29)              /* bit 29 always set */
        str     r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
 
-       wait_pllalock
-
        /* Save PLLB setting and disable it */
        ldr     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
        str     r3, .saved_pllbr
@@ -184,8 +182,6 @@ ENTRY(at91_slow_clock)
        mov     r3, #AT91_PMC_PLLCOUNT
        str     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
 
-       wait_pllblock
-
        /* Turn off the main oscillator */
        ldr     r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
        bic     r3, r3, #AT91_PMC_MOSCEN
@@ -205,13 +201,25 @@ ENTRY(at91_slow_clock)
        ldr     r3, .saved_pllbr
        str     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
 
+       tst     r3, #(AT91_PMC_MUL &  0xff0000)
+       bne     1f
+       tst     r3, #(AT91_PMC_MUL & ~0xff0000)
+       beq     2f
+1:
        wait_pllblock
+2:
 
        /* Restore PLLA setting */
        ldr     r3, .saved_pllar
        str     r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
 
+       tst     r3, #(AT91_PMC_MUL &  0xff0000)
+       bne     3f
+       tst     r3, #(AT91_PMC_MUL & ~0xff0000)
+       beq     4f
+3:
        wait_pllalock
+4:
 
 #ifdef SLOWDOWN_MASTER_CLOCK
        /*
index 7b20fccb9d4ee7715c513fb6d26f635cbe25b6e1..29c0a911df262f6d70b5c369afa4788c44f0c07a 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/interrupt.h>
 #include <linux/irqreturn.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 
 #include <mach/timer.h>
 
@@ -2220,11 +2221,15 @@ EXPORT_SYMBOL(dma_map_create_descriptor_ring);
 int dma_unmap(DMA_MemMap_t *memMap,    /* Stores state information about the map */
              int dirtied       /* non-zero if any of the pages were modified */
     ) {
+
+       int rc = 0;
        int regionIdx;
        int segmentIdx;
        DMA_Region_t *region;
        DMA_Segment_t *segment;
 
+       down(&memMap->lock);
+
        for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
                region = &memMap->region[regionIdx];
 
@@ -2238,7 +2243,8 @@ int dma_unmap(DMA_MemMap_t *memMap,       /* Stores state information about the map */
                                        printk(KERN_ERR
                                               "%s: vmalloc'd pages are not yet supported\n",
                                               __func__);
-                                       return -EINVAL;
+                                       rc = -EINVAL;
+                                       goto out;
                                }
 
                        case DMA_MEM_TYPE_KMALLOC:
@@ -2275,7 +2281,8 @@ int dma_unmap(DMA_MemMap_t *memMap,       /* Stores state information about the map */
                                        printk(KERN_ERR
                                               "%s: Unsupported memory type: %d\n",
                                               __func__, region->memType);
-                                       return -EINVAL;
+                                       rc = -EINVAL;
+                                       goto out;
                                }
                        }
 
@@ -2313,9 +2320,10 @@ int dma_unmap(DMA_MemMap_t *memMap,      /* Stores state information about the map */
        memMap->numRegionsUsed = 0;
        memMap->inUse = 0;
 
+out:
        up(&memMap->lock);
 
-       return 0;
+       return rc;
 }
 
 EXPORT_SYMBOL(dma_unmap);
index d15beceb632e9bcd784996dbd908ee1261d84994..df4ab2105869c284ae39902538d51fe1c6074f43 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/leds.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/slab.h>
 #include <linux/mtd/nand.h>
 #include <linux/input.h>
 #include <linux/spi/spi.h>
index 122e61a9f505a6e3142a8a203c765f879ad53802..e8cb982f5e8ebe932e4f2ba131e2a3812eea1bcd 100644 (file)
@@ -410,7 +410,7 @@ static struct clk_lookup da830_clks[] = {
        CLK("davinci-mcasp.0",  NULL,           &mcasp0_clk),
        CLK("davinci-mcasp.1",  NULL,           &mcasp1_clk),
        CLK("davinci-mcasp.2",  NULL,           &mcasp2_clk),
-       CLK("musb_hdrc",        NULL,           &usb20_clk),
+       CLK(NULL,               "usb20",        &usb20_clk),
        CLK(NULL,               "aemif",        &aemif_clk),
        CLK(NULL,               "aintc",        &aintc_clk),
        CLK(NULL,               "secu_mgr",     &secu_mgr_clk),
index 27772e18e45b948014b18e6294e08eaee1846afb..0d6ee583f65c6b3498111952e59ebda6c5fff036 100644 (file)
@@ -758,7 +758,6 @@ static u8 dm365_default_priorities[DAVINCI_N_AINTC_IRQ] = {
        [IRQ_MMCINT]                    = 7,
        [IRQ_DM365_MMCINT1]             = 7,
        [IRQ_DM365_PWMINT3]             = 7,
-       [IRQ_DDRINT]                    = 4,
        [IRQ_AEMIFINT]                  = 2,
        [IRQ_DM365_SDIOINT1]            = 2,
        [IRQ_TINT0_TINT12]              = 7,
index 15dd886df04ca08cec53abb11ed9a6105a3a81c8..53137387aee18b69a35526dacea7d9b0e1267f3c 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/edma.h>
 
@@ -1266,7 +1267,8 @@ int edma_start(unsigned channel)
                /* EDMA channel with event association */
                pr_debug("EDMA: ER%d %08x\n", j,
                        edma_shadow0_read_array(ctlr, SH_ER, j));
-               /* Clear any pending error */
+               /* Clear any pending event or error */
+               edma_write_array(ctlr, EDMA_ECR, j, mask);
                edma_write_array(ctlr, EDMA_EMCR, j, mask);
                /* Clear any SER */
                edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
index cc9be7fee6273e8534296c146d76b39d0f3c3e44..03acfd39042b92f2b7582272b5ce91b8371ba15d 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Author: Mark A. Greer <mgreer@mvista.com>
  *
- * 2007, 2009 (c) MontaVista Software, Inc. This file is licensed under
+ * 2007, 2009-2010 (c) MontaVista Software, Inc. This file is licensed under
  * the terms of the GNU General Public License version 2. This program
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
@@ -13,7 +13,9 @@
 
 #include <video/da8xx-fb.h>
 
+#include <linux/platform_device.h>
 #include <linux/davinci_emac.h>
+
 #include <mach/serial.h>
 #include <mach/edma.h>
 #include <mach/i2c.h>
@@ -144,6 +146,10 @@ extern const short da850_mmcsd0_pins[];
 extern const short da850_nand_pins[];
 extern const short da850_nor_pins[];
 
+#ifdef CONFIG_DAVINCI_MUX
 int da8xx_pinmux_setup(const short pins[]);
+#else
+static inline int da8xx_pinmux_setup(const short pins[]) { return 0; }
+#endif
 
 #endif /* __ASM_ARCH_DAVINCI_DA8XX_H */
index 42d985beece512bcccdf6d02e53b156d60b5bc9b..9e0b106b4f5f5895981f0b02a439a00e79565303 100644 (file)
@@ -253,8 +253,6 @@ static void __init timer_init(void)
                        irq = USING_COMPARE(t) ? dtip[i].cmp_irq : irq;
                        setup_irq(irq, &t->irqaction);
                }
-
-               timer32_config(&timers[i]);
        }
 }
 
@@ -331,6 +329,7 @@ static void __init davinci_timer_init(void)
        unsigned int clocksource_id;
        static char err[] __initdata = KERN_ERR
                "%s: can't register clocksource!\n";
+       int i;
 
        clockevent_id = soc_info->timer_info->clockevent_id;
        clocksource_id = soc_info->timer_info->clocksource_id;
@@ -389,6 +388,9 @@ static void __init davinci_timer_init(void)
 
        clockevent_davinci.cpumask = cpumask_of(0);
        clockevents_register_device(&clockevent_davinci);
+
+       for (i=0; i< ARRAY_SIZE(timers); i++)
+               timer32_config(&timers[i]);
 }
 
 struct sys_timer davinci_timer = {
index cc377ae8c4281324926f6d8f9c6ac645cd53b487..cf547ad7ebd441737fb3e6a47983c1d4643c090f 100644 (file)
@@ -25,7 +25,7 @@
 #include <mach/hardware.h>
 
 /*************************************************************************
- * GPIO handling for EP93xx
+ * Interrupt handling for EP93xx on-chip GPIOs
  *************************************************************************/
 static unsigned char gpio_int_unmasked[3];
 static unsigned char gpio_int_enabled[3];
@@ -40,7 +40,7 @@ static const u8 eoi_register_offset[3]                = { 0x98, 0xb4, 0x54 };
 static const u8 int_en_register_offset[3]      = { 0x9c, 0xb8, 0x58 };
 static const u8 int_debounce_register_offset[3]        = { 0xa8, 0xc4, 0x64 };
 
-void ep93xx_gpio_update_int_params(unsigned port)
+static void ep93xx_gpio_update_int_params(unsigned port)
 {
        BUG_ON(port > 2);
 
@@ -56,7 +56,7 @@ void ep93xx_gpio_update_int_params(unsigned port)
                EP93XX_GPIO_REG(int_en_register_offset[port]));
 }
 
-void ep93xx_gpio_int_mask(unsigned line)
+static inline void ep93xx_gpio_int_mask(unsigned line)
 {
        gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
 }
index 7a26148282176a68003467efe52f3609997e0f6d..bdb3f67068016c4b73770719114558c6f741babe 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/mman.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
index 44d4c2e8207b1b06a368fbe30b99ecc75f726302..f77f20255045aed83f8648bf1be2d0afbed5b7a3 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/cpufreq.h>
-#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/init.h>
index 0058c937719ed7f7400fe8a1388e9c9e8f73e777..41b10725cef73352526e7310d6ba287533e42b84 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/clcd.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/clkdev.h>
 #include <mach/clkdev.h>
index 66ef86d6d9e3d0d80aa46f2e6f09d4314a491426..15e6cc5a352f81e04b69ce27b37bd91978e98e78 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/list.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/sysdev.h>
 #include <linux/amba/bus.h>
@@ -21,6 +20,7 @@
 #include <linux/amba/clcd.h>
 #include <linux/amba/mmci.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 
 #include <asm/clkdev.h>
 #include <mach/clkdev.h>
index 148d25fc636fbe2c7d91596d4c312272e6460015..ffbd349363af0ec72810dfa5ee7c00bced887a74 100644 (file)
@@ -22,7 +22,6 @@
  */
 #include <linux/kernel.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
index 4873f26a42e114796bf660c45f238a466b854b75..6d5a90813d31b6b96532b3b1a5cdb555e972ec41 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
 #include <asm/irq.h>
index 93370a46b620972a66fc810b18dd71132efc426e..10384fc37cb29d4315931483151c961e63e2d033 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/pci.h>
 #include <linux/pm.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
index a7a08dda7f331c98f90b27ec17f5f5f9e14c0380..d6ac85ff109deef02935213bc33577f0be2da42a 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/pci.h>
 #include <linux/pm.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
index 0200f80c1e171d99f48233e3a98accaf97076928..c6a0e4ee9d911d1b5d311be33b0fd537f65d93c4 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
index 2a5c637639bb9984c4a3a4923f511a32cec67967..5d99039286eb86410ca72d5ddeb3bf1a2a083936 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/pci.h>
 #include <linux/pm.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
index 394e95a30b75f8a124dc2828401da7766fb118c1..c6ff5523b380f95e26fc4282d895d1e03c54614b 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
index a40badf126c29552b303bd0b8d6d7976a15e57a7..fbf55140939407f322af2f1c75441550edb37414 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 #include <linux/mtd/physmap.h>
index c84dfac13882a3b2838ba7b684a1531fa4e19fac..1a557e0d055b56626e5e0b37206b032a055c4818 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/bitops.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/serial.h>
 #include <linux/tty.h>
index 4467c4224d73f23723d9e43530ae822f663b7a13..55e5c69352ad4de2395659e8dccc3a1e4e00a637 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/bitops.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 
index 94f68ba9ea50905ba0023f52fd35bbb3b1b9ad79..237b61a85e9a397f6d398c53a686edbd186515ac 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/bitops.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 
index 30451300751beb360ca41cf6e6f46814db1215f9..91fffb9b208443be54be71e9ebfb9bb000daea90 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/bitops.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 
index 4a12327a09a3a5052caf71e3531ae1c4ba22fea6..0369ec4242a687e61c7c4305de54fcec5d4f696b 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/bitops.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/serial.h>
 #include <linux/tty.h>
index 60e9fd08ab803036c6655d6153a8c4b20aadf197..90771cad06f86f7fe3238021ce8ae39ce90cadc2 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 
index 94a3a86cfeb8be7ae854aa26162e33c7796683d0..6ef65d813f161f729fe8e8be91ef6e13deb35603 100644 (file)
@@ -19,7 +19,7 @@
  */
 #define PHYS_OFFSET            (0x00000000)
 
-#define IXP23XX_PCI_SDRAM_OFFSET (*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0))
+#define IXP23XX_PCI_SDRAM_OFFSET (*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0)
 
 #define __phys_to_bus(x)       ((x) + (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET))
 #define __bus_to_phys(x)       ((x) - (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET))
index 59022becb134c93526eab0c350ffef3efdcc4ff4..4b0e598a91c91f4573d927a8016d91aab0154f7d 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 
index 6e558a76457d154a5aa38d0c816b720b062cdc82..d8bc86d76f1d2248b0d936f5cd1413c0ce0ba469 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
-#include <linux/slab.h>
 #include <linux/i2c-gpio.h>
 #include <asm/types.h>
 #include <asm/setup.h>
index 25bf5ad770eaa14c6213e27579bd0b912691bd69..31a47f6a8939d8fc1bc0ce7c0e78db0495e5b5df 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
-#include <linux/slab.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
index 59b73a0ddfa93fba8b4ef21206566e190496cf6b..2583b2a13174ef02959fb62b70d96c68a978073a 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
-#include <linux/slab.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
index 0bc7185cb6f7282e7447ffe091ea9783f108c206..c67586b79400c8a02084389e297539208dcdb5c1 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
-#include <linux/slab.h>
 #include <asm/types.h>
 #include <asm/setup.h>
 #include <asm/memory.h>
index bbb768988845dae9dc5910acf3f245ba786a0ec4..827cbc4402f4dff37ce8b8dff110e45598d8b4e4 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
-#include <linux/slab.h>
 #include <linux/i2c-gpio.h>
 #include <linux/io.h>
 #include <linux/mtd/mtd.h>
index e8bb257781661da9424208d8f79862cc088e377f..a17ed79207a4fce30f67b405f758cd07b23f85ad 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <mach/npe.h>
 
 #define DEBUG_MSG                      0
index 7ea782021d1f56de331f24bef9cacf9d84f8d60c..4dd74863daa9cb4e56c074108436abd2ea39b33d 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
-#include <linux/slab.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
index 0358f45766cbe565c7571483bb251fc490f9f81f..5e6f711b1c6753713b8819078ec0bc053566f200 100644 (file)
@@ -74,9 +74,9 @@ static struct gpio_keys_button mv88f6281gtw_ge_button_pins[] = {
                .desc           = "SWR Button",
                .active_low     = 1,
        }, {
-               .code           = KEY_F1,
+               .code           = KEY_WPS_BUTTON,
                .gpio           = 46,
-               .desc           = "WPS Button(F1)",
+               .desc           = "WPS Button",
                .active_low     = 1,
        },
 };
index a604b2a701aa5408aa72d54e77af10bfedee23a5..dee1eff50d3933d2252a2f66aed2f1d7456d69c3 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/mbus.h>
 #include <asm/irq.h>
 #include <asm/mach/pci.h>
index c472b9e8b37cd3bf6710ae555b0e356b3ab9f01d..7fe4fd347c821c6b97e415e80ba696ddc7599e37 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/sysdev.h>
index a7dcc5307216524b4f2e57c05af043530be64f5a..85bd8a2d84b5e47cc3acc1a24192a8387c3d28ab 100644 (file)
@@ -14,7 +14,7 @@
 #define UART2_BASE     (APB_PHYS_BASE + 0x17000)
 #define UART3_BASE     (APB_PHYS_BASE + 0x18000)
 
-static volatile unsigned long *UART = (unsigned long *)UART2_BASE;
+static volatile unsigned long *UART;
 
 static inline void putc(char c)
 {
@@ -37,6 +37,9 @@ static inline void flush(void)
 
 static inline void arch_decomp_setup(void)
 {
+       /* default to UART2 */
+       UART = (unsigned long *)UART2_BASE;
+
        if (machine_is_avengers_lite())
                UART = (unsigned long *)UART3_BASE;
 }
index 3872af1cf2c322a7ac9494b31e6fbd06513bf68d..170f68e46dd5caceb5bd83bb000e5eaf846e538a 100644 (file)
@@ -62,6 +62,15 @@ config MACH_MX31_3DS
          Include support for MX31PDK (3DS) platform. This includes specific
          configurations for the board and its peripherals.
 
+config MACH_MX31_3DS_MXC_NAND_USE_BBT
+       bool "Make the MXC NAND driver use the in flash Bad Block Table"
+       depends on MACH_MX31_3DS
+       depends on MTD_NAND_MXC
+       help
+         Enable this if you want that the MXC NAND driver uses the in flash
+         Bad Block Table to know what blocks are bad instead of scanning the
+         entire flash looking for bad block markers.
+
 config MACH_MX31MOBOARD
        bool "Support mx31moboard platforms (EPFL Mobots group)"
        select ARCH_MX31
@@ -95,6 +104,7 @@ config MACH_PCM043
 config MACH_ARMADILLO5X0
        bool "Support Atmark Armadillo-500 Development Base Board"
        select ARCH_MX31
+       select MXC_ULPI if USB_ULPI
        help
          Include support for Atmark Armadillo-500 platform. This includes
          specific configurations for the board and its peripherals.
index 80dba9966b5e54a1f3d40bd5fbe82b3071b13772..9a9eb6de6127efd0b7a6241a17a5f9d88b4e09e1 100644 (file)
@@ -468,6 +468,7 @@ static struct clk ahb_clk = {
        }
 
 DEFINE_CLOCK(perclk_clk,  0, NULL,          0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ckil_clk,    0, NULL,          0, clk_ckil_get_rate, NULL, NULL);
 
 DEFINE_CLOCK(sdhc1_clk,   0, MXC_CCM_CGR0,  0, NULL, NULL, &perclk_clk);
 DEFINE_CLOCK(sdhc2_clk,   1, MXC_CCM_CGR0,  2, NULL, NULL, &perclk_clk);
@@ -490,7 +491,7 @@ DEFINE_CLOCK(mpeg4_clk,   0, MXC_CCM_CGR1,  0, NULL, NULL, &ahb_clk);
 DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1,  2, mstick1_get_rate, NULL, &usb_pll_clk);
 DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1,  4, mstick2_get_rate, NULL, &usb_pll_clk);
 DEFINE_CLOCK1(csi_clk,    0, MXC_CCM_CGR1,  6, csi, NULL, &serial_pll_clk);
-DEFINE_CLOCK(rtc_clk,     0, MXC_CCM_CGR1,  8, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(rtc_clk,     0, MXC_CCM_CGR1,  8, NULL, NULL, &ckil_clk);
 DEFINE_CLOCK(wdog_clk,    0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk);
 DEFINE_CLOCK(pwm_clk,     0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk);
 DEFINE_CLOCK(usb_clk2,    0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk);
@@ -514,7 +515,6 @@ DEFINE_CLOCK(usb_clk1,    0, NULL,          0, usb_get_rate, NULL, &usb_pll_clk)
 DEFINE_CLOCK(nfc_clk,     0, NULL,          0, nfc_get_rate, NULL, &ahb_clk);
 DEFINE_CLOCK(scc_clk,     0, NULL,          0, NULL, NULL, &ipg_clk);
 DEFINE_CLOCK(ipg_clk,     0, NULL,          0, ipg_get_rate, NULL, &ahb_clk);
-DEFINE_CLOCK(ckil_clk,    0, NULL,          0, clk_ckil_get_rate, NULL, NULL);
 
 #define _REGISTER_CLOCK(d, n, c) \
        { \
@@ -572,7 +572,6 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK(NULL, "iim", iim_clk)
        _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
        _REGISTER_CLOCK(NULL, "mbx", mbx_clk)
-       _REGISTER_CLOCK("mxc_rtc", NULL, ckil_clk)
 };
 
 int __init mx31_clocks_init(unsigned long fref)
index 6adb586515ea5412d7e1223c1768a59cf91237a9..f8911154a9fa8cac1badb0ab45c6265675d93a92 100644 (file)
@@ -575,11 +575,26 @@ struct platform_device imx_ssi_device1 = {
        .resource = imx_ssi_resources1,
 };
 
-static int mx3_devices_init(void)
+static struct resource imx_wdt_resources[] = {
+       {
+               .flags = IORESOURCE_MEM,
+       },
+};
+
+struct platform_device imx_wdt_device0 = {
+       .name           = "imx-wdt",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(imx_wdt_resources),
+       .resource       = imx_wdt_resources,
+};
+
+static int __init mx3_devices_init(void)
 {
        if (cpu_is_mx31()) {
                mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR;
                mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff;
+               imx_wdt_resources[0].start = MX31_WDOG_BASE_ADDR;
+               imx_wdt_resources[0].end = MX31_WDOG_BASE_ADDR + 0x3fff;
                mxc_register_device(&mxc_rnga_device, NULL);
        }
        if (cpu_is_mx35()) {
@@ -597,6 +612,8 @@ static int mx3_devices_init(void)
                imx_ssi_resources0[1].end = MX35_INT_SSI1;
                imx_ssi_resources1[1].start = MX35_INT_SSI2;
                imx_ssi_resources1[1].end = MX35_INT_SSI2;
+               imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR;
+               imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff;
        }
 
        return 0;
index 42cf175eac6bb8c141b668fab316eb8ec45c7234..4f77eb501274c0fcf5406252d158641de3efd159 100644 (file)
@@ -25,4 +25,5 @@ extern struct platform_device mxc_spi_device1;
 extern struct platform_device mxc_spi_device2;
 extern struct platform_device imx_ssi_device0;
 extern struct platform_device imx_ssi_device1;
-
+extern struct platform_device imx_ssi_device1;
+extern struct platform_device imx_wdt_device0;
index 3d72b0b89705991118d2282a943e1144c28c8a5e..5f72ec91af2d62c97acbdff70fbccd4988c292b5 100644 (file)
@@ -36,6 +36,9 @@
 #include <linux/input.h>
 #include <linux/gpio_keys.h>
 #include <linux/i2c.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/delay.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -52,6 +55,8 @@
 #include <mach/ipu.h>
 #include <mach/mx3fb.h>
 #include <mach/mxc_nand.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
 
 #include "devices.h"
 #include "crm_regs.h"
@@ -103,8 +108,158 @@ static int armadillo5x0_pins[] = {
        /* I2C2 */
        MX31_PIN_CSPI2_MOSI__SCL,
        MX31_PIN_CSPI2_MISO__SDA,
+       /* OTG */
+       MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+       MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+       MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+       MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+       MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+       MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+       MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+       MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+       MX31_PIN_USBOTG_CLK__USBOTG_CLK,
+       MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+       MX31_PIN_USBOTG_NXT__USBOTG_NXT,
+       MX31_PIN_USBOTG_STP__USBOTG_STP,
+       /* USB host 2 */
+       IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC),
 };
 
+/* USB */
+#if defined(CONFIG_USB_ULPI)
+
+#define OTG_RESET IOMUX_TO_GPIO(MX31_PIN_STXD4)
+#define USBH2_RESET IOMUX_TO_GPIO(MX31_PIN_SCK6)
+#define USBH2_CS IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+                       PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int usbotg_init(struct platform_device *pdev)
+{
+       int err;
+
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
+
+       /* Chip already enabled by hardware */
+       /* OTG phy reset*/
+       err = gpio_request(OTG_RESET, "USB-OTG-RESET");
+       if (err) {
+               pr_err("Failed to request the usb otg reset gpio\n");
+               return err;
+       }
+
+       err = gpio_direction_output(OTG_RESET, 1/*HIGH*/);
+       if (err) {
+               pr_err("Failed to reset the usb otg phy\n");
+               goto otg_free_reset;
+       }
+
+       gpio_set_value(OTG_RESET, 0/*LOW*/);
+       mdelay(5);
+       gpio_set_value(OTG_RESET, 1/*HIGH*/);
+
+       return 0;
+
+otg_free_reset:
+       gpio_free(OTG_RESET);
+       return err;
+}
+
+static int usbh2_init(struct platform_device *pdev)
+{
+       int err;
+
+       mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
+
+       mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+
+       /* Enable the chip */
+       err = gpio_request(USBH2_CS, "USB-H2-CS");
+       if (err) {
+               pr_err("Failed to request the usb host 2 CS gpio\n");
+               return err;
+       }
+
+       err = gpio_direction_output(USBH2_CS, 0/*Enabled*/);
+       if (err) {
+               pr_err("Failed to drive the usb host 2 CS gpio\n");
+               goto h2_free_cs;
+       }
+
+       /* H2 phy reset*/
+       err = gpio_request(USBH2_RESET, "USB-H2-RESET");
+       if (err) {
+               pr_err("Failed to request the usb host 2 reset gpio\n");
+               goto h2_free_cs;
+       }
+
+       err = gpio_direction_output(USBH2_RESET, 1/*HIGH*/);
+       if (err) {
+               pr_err("Failed to reset the usb host 2 phy\n");
+               goto h2_free_reset;
+       }
+
+       gpio_set_value(USBH2_RESET, 0/*LOW*/);
+       mdelay(5);
+       gpio_set_value(USBH2_RESET, 1/*HIGH*/);
+
+       return 0;
+
+h2_free_reset:
+       gpio_free(USBH2_RESET);
+h2_free_cs:
+       gpio_free(USBH2_CS);
+       return err;
+}
+
+static struct mxc_usbh_platform_data usbotg_pdata = {
+       .init   = usbotg_init,
+       .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+       .flags  = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+       .init   = usbh2_init,
+       .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+       .flags  = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+#endif /* CONFIG_USB_ULPI */
+
 /* RTC over I2C*/
 #define ARMADILLO5X0_RTC_GPIO  IOMUX_TO_GPIO(MX31_PIN_SRXD4)
 
@@ -393,6 +548,17 @@ static void __init armadillo5x0_init(void)
        if (armadillo5x0_i2c_rtc.irq == 0)
                pr_warning("armadillo5x0_init: failed to get RTC IRQ\n");
        i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1);
+
+       /* USB */
+#if defined(CONFIG_USB_ULPI)
+       usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+                       USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+       usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+                       USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+       mxc_register_device(&mxc_otg_host, &usbotg_pdata);
+       mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+#endif
 }
 
 static void __init armadillo5x0_timer_init(void)
index b88c18ad769819ba86852c02a97eb74e088203d2..f54af1e29ca48a9dfcb142887d5f85d1b770e6b6 100644 (file)
@@ -23,6 +23,9 @@
 #include <linux/gpio.h>
 #include <linux/smsc911x.h>
 #include <linux/platform_device.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/machine.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/memory.h>
 #include <asm/mach/map.h>
 #include <mach/common.h>
-#include <mach/board-mx31pdk.h>
+#include <mach/board-mx31_3ds.h>
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx3.h>
+#include <mach/mxc_nand.h>
+#include <mach/spi.h>
 #include "devices.h"
 
 /*!
- * @file mx31pdk.c
+ * @file mx31_3ds.c
  *
  * @brief This file contains the board-specific initialization routines.
  *
  * @ingroup System
  */
 
-static int mx31pdk_pins[] = {
+static int mx31_3ds_pins[] = {
        /* UART1 */
        MX31_PIN_CTS1__CTS1,
        MX31_PIN_RTS1__RTS1,
        MX31_PIN_TXD1__TXD1,
        MX31_PIN_RXD1__RXD1,
        IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO),
+       /* SPI 1 */
+       MX31_PIN_CSPI2_SCLK__SCLK,
+       MX31_PIN_CSPI2_MOSI__MOSI,
+       MX31_PIN_CSPI2_MISO__MISO,
+       MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
+       MX31_PIN_CSPI2_SS0__SS0,
+       MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */
+       /* MC13783 IRQ */
+       IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO),
+};
+
+/* Regulators */
+static struct regulator_init_data pwgtx_init = {
+       .constraints = {
+               .boot_on        = 1,
+               .always_on      = 1,
+       },
+};
+
+static struct mc13783_regulator_init_data mx31_3ds_regulators[] = {
+       {
+               .id = MC13783_REGU_PWGT1SPI, /* Power Gate for ARM core. */
+               .init_data = &pwgtx_init,
+       }, {
+               .id = MC13783_REGU_PWGT2SPI, /* Power Gate for L2 Cache. */
+               .init_data = &pwgtx_init,
+       },
+};
+
+/* MC13783 */
+static struct mc13783_platform_data mc13783_pdata __initdata = {
+       .regulators = mx31_3ds_regulators,
+       .num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
+       .flags  = MC13783_USE_REGULATOR,
+};
+
+/* SPI */
+static int spi1_internal_chipselect[] = {
+       MXC_SPI_CS(0),
+       MXC_SPI_CS(2),
+};
+
+static struct spi_imx_master spi1_pdata = {
+       .chipselect     = spi1_internal_chipselect,
+       .num_chipselect = ARRAY_SIZE(spi1_internal_chipselect),
+};
+
+static struct spi_board_info mx31_3ds_spi_devs[] __initdata = {
+       {
+               .modalias       = "mc13783",
+               .max_speed_hz   = 1000000,
+               .bus_num        = 1,
+               .chip_select    = 1, /* SS2 */
+               .platform_data  = &mc13783_pdata,
+               .irq            = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+               .mode = SPI_CS_HIGH,
+       },
+};
+
+/*
+ * NAND Flash
+ */
+static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = {
+       .width          = 1,
+       .hw_ecc         = 1,
+#ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT
+       .flash_bbt      = 1,
+#endif
 };
 
 static struct imxuart_platform_data uart_pdata = {
@@ -95,7 +168,7 @@ static struct platform_device smsc911x_device = {
  * LEDs, switches, interrupts for Ethernet.
  */
 
-static void mx31pdk_expio_irq_handler(uint32_t irq, struct irq_desc *desc)
+static void mx31_3ds_expio_irq_handler(uint32_t irq, struct irq_desc *desc)
 {
        uint32_t imr_val;
        uint32_t int_valid;
@@ -163,7 +236,7 @@ static struct irq_chip expio_irq_chip = {
        .unmask = expio_unmask_irq,
 };
 
-static int __init mx31pdk_init_expio(void)
+static int __init mx31_3ds_init_expio(void)
 {
        int i;
        int ret;
@@ -176,7 +249,7 @@ static int __init mx31pdk_init_expio(void)
                return -ENODEV;
        }
 
-       pr_info("i.MX31PDK Debug board detected, rev = 0x%04X\n",
+       pr_info("i.MX31 3DS Debug board detected, rev = 0x%04X\n",
                __raw_readw(CPLD_CODE_VER_REG));
 
        /*
@@ -201,7 +274,7 @@ static int __init mx31pdk_init_expio(void)
                set_irq_flags(i, IRQF_VALID);
        }
        set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_LOW);
-       set_irq_chained_handler(EXPIO_PARENT_INT, mx31pdk_expio_irq_handler);
+       set_irq_chained_handler(EXPIO_PARENT_INT, mx31_3ds_expio_irq_handler);
 
        return 0;
 }
@@ -209,7 +282,7 @@ static int __init mx31pdk_init_expio(void)
 /*
  * This structure defines the MX31 memory map.
  */
-static struct map_desc mx31pdk_io_desc[] __initdata = {
+static struct map_desc mx31_3ds_io_desc[] __initdata = {
        {
                .virtual = MX31_CS5_BASE_ADDR_VIRT,
                .pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR),
@@ -221,10 +294,10 @@ static struct map_desc mx31pdk_io_desc[] __initdata = {
 /*
  * Set up static virtual mappings.
  */
-static void __init mx31pdk_map_io(void)
+static void __init mx31_3ds_map_io(void)
 {
        mx31_map_io();
-       iotable_init(mx31pdk_io_desc, ARRAY_SIZE(mx31pdk_io_desc));
+       iotable_init(mx31_3ds_io_desc, ARRAY_SIZE(mx31_3ds_io_desc));
 }
 
 /*!
@@ -232,35 +305,40 @@ static void __init mx31pdk_map_io(void)
  */
 static void __init mxc_board_init(void)
 {
-       mxc_iomux_setup_multiple_pins(mx31pdk_pins, ARRAY_SIZE(mx31pdk_pins),
-                                     "mx31pdk");
+       mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins),
+                                     "mx31_3ds");
 
        mxc_register_device(&mxc_uart_device0, &uart_pdata);
+       mxc_register_device(&mxc_nand_device, &imx31_3ds_nand_flash_pdata);
+
+       mxc_register_device(&mxc_spi_device1, &spi1_pdata);
+       spi_register_board_info(mx31_3ds_spi_devs,
+                                               ARRAY_SIZE(mx31_3ds_spi_devs));
 
-       if (!mx31pdk_init_expio())
+       if (!mx31_3ds_init_expio())
                platform_device_register(&smsc911x_device);
 }
 
-static void __init mx31pdk_timer_init(void)
+static void __init mx31_3ds_timer_init(void)
 {
        mx31_clocks_init(26000000);
 }
 
-static struct sys_timer mx31pdk_timer = {
-       .init   = mx31pdk_timer_init,
+static struct sys_timer mx31_3ds_timer = {
+       .init   = mx31_3ds_timer_init,
 };
 
 /*
  * The following uses standard kernel macros defined in arch.h in order to
- * initialize __mach_desc_MX31PDK data structure.
+ * initialize __mach_desc_MX31_3DS data structure.
  */
 MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
        /* Maintainer: Freescale Semiconductor, Inc. */
        .phys_io        = MX31_AIPS1_BASE_ADDR,
        .io_pg_offst    = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
        .boot_params    = MX3x_PHYS_OFFSET + 0x100,
-       .map_io         = mx31pdk_map_io,
+       .map_io         = mx31_3ds_map_io,
        .init_irq       = mx31_init_irq,
        .init_machine   = mxc_board_init,
-       .timer          = &mx31pdk_timer,
+       .timer          = &mx31_3ds_timer,
 MACHINE_END
index a7dc5191bf5ea4de9ffaf09bc0397414ddd80745..fccb9207b78d75112bed0b7ac0d3d45a17367e1b 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/fsl_devices.h>
+#include <linux/gfp.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
index 11f5315591693380e6bd59c05d7449b6dbee1698..2df1ec55a97e6565980b27fd0ade0754921b20e1 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/can/platform/sja1000.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/ulpi.h>
-#include <linux/fsl_devices.h>
+#include <linux/gfp.h>
 
 #include <media/soc_camera.h>
 
index ccd874225c3b6b19d5a52008b6bffe0efd1fc69a..093c595ca58119e2fef5d7924b84c8e0d92c36d2 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
-#include <linux/platform_device.h>
 #include <linux/leds.h>
 #include <linux/platform_device.h>
 
@@ -206,5 +205,6 @@ void __init mx31lite_db_init(void)
        mxc_register_device(&mxcsdhc_device0, &mmc_pdata);
        mxc_register_device(&mxc_spi_device0, &spi0_pdata);
        platform_device_register(&litekit_led_device);
+       mxc_register_device(&imx_wdt_device0, NULL);
 }
 
index 9fbad2eb3a49786cd0f12037b63d31346de4969e..11b906ce7eae45c92c405b107412686043db4f0a 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #include <linux/usb/otg.h>
index 3958515d75bfd7a082dec42a33df40cdf7cc94fe..ffb105e14d88d10a77d54fa86267e04db8515d71 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/types.h>
 
index be90c03101cd8bd27c2d72653b5e8f5f64d9d922..1ee6ce4087b84cd001dce69600359a234a78102f 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/io.h>
 
 #include <asm/clkdev.h>
+#include <asm/div64.h>
 
 #include <mach/hardware.h>
 #include <mach/common.h>
@@ -757,7 +758,7 @@ DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
 
 /* GPT */
 DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
-       NULL,  NULL, &ipg_perclk, NULL);
+       NULL,  NULL, &ipg_clk, NULL);
 DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
        NULL,  NULL, &ipg_clk, NULL);
 
index 41c769f08c4dd42e5a4361b6ccc02b5d557b81bc..2d37785e3857d32575a5948f36574e4770a0b917 100644 (file)
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <mach/hardware.h>
 #include <asm/io.h>
 
+static int cpu_silicon_rev = -1;
+
+#define SI_REV 0x48
+
+static void query_silicon_parameter(void)
+{
+       void __iomem *rom = ioremap(MX51_IROM_BASE_ADDR, MX51_IROM_SIZE);
+       u32 rev;
+
+       if (!rom) {
+               cpu_silicon_rev = -EINVAL;
+               return;
+       }
+
+       rev = readl(rom + SI_REV);
+       switch (rev) {
+       case 0x1:
+               cpu_silicon_rev = MX51_CHIP_REV_1_0;
+               break;
+       case 0x2:
+               cpu_silicon_rev = MX51_CHIP_REV_1_1;
+               break;
+       case 0x10:
+               cpu_silicon_rev = MX51_CHIP_REV_2_0;
+               break;
+       case 0x20:
+               cpu_silicon_rev = MX51_CHIP_REV_3_0;
+               break;
+       default:
+               cpu_silicon_rev = 0;
+       }
+
+       iounmap(rom);
+}
+
+/*
+ * Returns:
+ *     the silicon revision of the cpu
+ *     -EINVAL - not a mx51
+ */
+int mx51_revision(void)
+{
+       if (!cpu_is_mx51())
+               return -EINVAL;
+
+       if (cpu_silicon_rev == -1)
+               query_silicon_parameter();
+
+       return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx51_revision);
+
 static int __init post_cpu_init(void)
 {
        unsigned int reg;
index c21e18be7af869082262d524a5d776df9a1a8f53..b7677ef80cc4388a4c414c4b7c8e1269137227a6 100644 (file)
@@ -34,11 +34,6 @@ static struct map_desc mxc_io_desc[] __initdata = {
                .pfn = __phys_to_pfn(MX51_DEBUG_BASE_ADDR),
                .length = MX51_DEBUG_SIZE,
                .type = MT_DEVICE
-       }, {
-               .virtual = MX51_TZIC_BASE_ADDR_VIRT,
-               .pfn = __phys_to_pfn(MX51_TZIC_BASE_ADDR),
-               .length = MX51_TZIC_SIZE,
-               .type = MT_DEVICE
        }, {
                .virtual = MX51_AIPS1_BASE_ADDR_VIRT,
                .pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR),
@@ -54,11 +49,6 @@ static struct map_desc mxc_io_desc[] __initdata = {
                .pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR),
                .length = MX51_AIPS2_SIZE,
                .type = MT_DEVICE
-       }, {
-               .virtual = MX51_NFC_AXI_BASE_ADDR_VIRT,
-               .pfn = __phys_to_pfn(MX51_NFC_AXI_BASE_ADDR),
-               .length = MX51_NFC_AXI_SIZE,
-               .type = MT_DEVICE
        },
 };
 
@@ -69,14 +59,6 @@ static struct map_desc mxc_io_desc[] __initdata = {
  */
 void __init mx51_map_io(void)
 {
-       u32 tzic_addr;
-
-       if (mx51_revision() < MX51_CHIP_REV_2_0)
-               tzic_addr = 0x8FFFC000;
-       else
-               tzic_addr = 0xE0003000;
-       mxc_io_desc[2].pfn =  __phys_to_pfn(tzic_addr);
-
        mxc_set_cpu_type(MXC_CPU_MX51);
        mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
        mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR));
@@ -85,5 +67,17 @@ void __init mx51_map_io(void)
 
 void __init mx51_init_irq(void)
 {
-       tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR));
+       unsigned long tzic_addr;
+       void __iomem *tzic_virt;
+
+       if (mx51_revision() < MX51_CHIP_REV_2_0)
+               tzic_addr = MX51_TZIC_BASE_ADDR_TO1;
+       else
+               tzic_addr = MX51_TZIC_BASE_ADDR;
+
+       tzic_virt = ioremap(tzic_addr, SZ_16K);
+       if (!tzic_virt)
+               panic("unable to map TZIC interrupt controller\n");
+
+       tzic_init_irq(tzic_virt);
 }
index 1d844e228ea92e6a674e92a6b0fcb3e2cb3eef42..5b84bcd30271321a17a38c7e0d2a2f51d4f286c2 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/clcd.h>
 #include <linux/err.h>
+#include <linux/gfp.h>
 
 #include <asm/irq.h>
 
index 181a78ba81654bdae53bda56c7ede38faad6063b..f009b54e8d20e37a33311eb39782c0076a99164e 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
index 9a09b2791e037248dfd949baeed5fdd2b7ebfa22..66b1c91ccc7482fb993cbfbb4f1986aa0d75fde2 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <mach/gpio.h>
index 795b15e8982a6e88e8742a186bcfb11e8d66e765..463e92465fda692566169e07c608f2b88a4853bf 100644 (file)
@@ -10,6 +10,7 @@
  */
 #include <linux/platform_device.h>
 #include <linux/serial_8250.h>
+#include <linux/slab.h>
 
 #include <mach/regs-board-a9m9750dev.h>
 #include <mach/board.h>
index abee8338735d471884dc057cfac76b3e5cab4790..aed1999d24fc9d16fbbc42b13b356f8420fecda9 100644 (file)
@@ -10,7 +10,6 @@
  */
 #include <linux/io.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 
 #include <asm/page.h>
 #include <asm/mach/map.h>
index f9a5cf750b59cb7bfc88769d2c1135eb0bd1d79e..e9bdff192f8261d39a7cac0a7ad351970b24d633 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <mach/irqs.h>
 #include <plat/dma.h>
index 9ad118563f7d8b8c88f01d6d5503d55a1f51f0a1..20cfbcc6c60ca08eb1c38f465adf09436a67dd81 100644 (file)
@@ -68,12 +68,6 @@ struct sys_timer omap_timer;
  * ---------------------------------------------------------------------------
  */
 
-#if defined(CONFIG_ARCH_OMAP16XX)
-#define TIMER_32K_SYNCHRONIZED         0xfffbc410
-#else
-#error OMAP 32KHz timer does not currently work on 15XX!
-#endif
-
 /* 16xx specific defines */
 #define OMAP1_32K_TIMER_BASE           0xfffb9000
 #define OMAP1_32K_TIMER_CR             0x08
@@ -150,15 +144,6 @@ static struct clock_event_device clockevent_32k_timer = {
        .set_mode       = omap_32k_timer_set_mode,
 };
 
-/*
- * The 32KHz synchronized timer is an additional timer on 16xx.
- * It is always running.
- */
-static inline unsigned long omap_32k_sync_timer_read(void)
-{
-       return omap_readl(TIMER_32K_SYNCHRONIZED);
-}
-
 static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
 {
        struct clock_event_device *evt = &clockevent_32k_timer;
index a8a3d1e23e26597be74ec1c921a2d28df682aa07..2455dcc744a0a50bac85f933772d92c9b1a7a5d5 100644 (file)
@@ -59,8 +59,10 @@ config MACH_OMAP3_BEAGLE
        select OMAP_PACKAGE_CBB
 
 config MACH_DEVKIT8000
-        bool "DEVKIT8000 board"
-        depends on ARCH_OMAP3
+       bool "DEVKIT8000 board"
+       depends on ARCH_OMAP3
+       select OMAP_PACKAGE_CUS
+       select OMAP_MUX
 
 config MACH_OMAP_LDP
        bool "OMAP3 LDP board"
index 2069fb33baaa411236d514d8f14b432f749318ba..4b9fc57770db71674d9d502d2b6e135eb90389c3 100644 (file)
@@ -22,6 +22,9 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 # SMP support ONLY available for OMAP4
 obj-$(CONFIG_SMP)                      += omap-smp.o omap-headsmp.o
 obj-$(CONFIG_LOCAL_TIMERS)             += timer-mpu.o
+obj-$(CONFIG_ARCH_OMAP4)               += omap44xx-smc.o
+
+AFLAGS_omap44xx-smc.o                  :=-Wa,-march=armv7-a
 
 # Functions loaded to SRAM
 obj-$(CONFIG_ARCH_OMAP2420)            += sram242x.o
index a101029ceb6f55e86feecbf9e9cc126d466ad0b3..5822bcf7b15fa07e588f5a51c342c8f38c62425d 100644 (file)
@@ -648,7 +648,7 @@ static void enable_board_wakeup_source(void)
                OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
 }
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
 
        .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
        .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
index 4386d2b4a785dcceaaecacb245024442312464d0..504d2bd222fe35ec02bb277f5f87d6af6f18e5e8 100644 (file)
@@ -54,7 +54,7 @@ static void enable_board_wakeup_source(void)
                OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
 }
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
 
        .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
        .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
@@ -96,6 +96,7 @@ static struct omap_board_mux board_mux[] __initdata = {
 static void __init omap_sdp_init(void)
 {
        omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
+       omap_serial_init();
        zoom_peripherals_init();
        board_smc91x_init();
        enable_board_wakeup_source();
index 180ac112e527b240099ba5daf9ce0d43d2a4ff48..b88f28c5814b4b5ce4aab290cc53ab79589afdd8 100644 (file)
@@ -50,33 +50,9 @@ static struct omap_board_config_kernel sdp4430_config[] __initdata = {
 };
 
 #ifdef CONFIG_CACHE_L2X0
-noinline void omap_smc1(u32 fn, u32 arg)
-{
-       register u32 r12 asm("r12") = fn;
-       register u32 r0 asm("r0") = arg;
-
-       /* This is common routine cache secure monitor API used to
-        * modify the PL310 secure registers.
-        * r0 contains the value to be modified and "r12" contains
-        * the monitor API number. It uses few CPU registers
-        * internally and hence they need be backed up including
-        * link register "lr".
-        * Explicitly save r11 and r12 the compiler generated code
-        * won't save it.
-        */
-       asm volatile(
-               "stmfd r13!, {r11,r12}\n"
-               "dsb\n"
-               "smc\n"
-               "ldmfd r13!, {r11,r12}\n"
-               : "+r" (r0), "+r" (r12)
-               :
-               : "r4", "r5", "r10", "lr", "cc");
-}
-EXPORT_SYMBOL(omap_smc1);
-
 static int __init omap_l2_cache_init(void)
 {
+       extern void omap_smc1(u32 fn, u32 arg);
        void __iomem *l2cache_base;
 
        /* To avoid code running on other OMAPs in
index 70c18614773c60cd119300ef51065e89fd9c8b8f..c1c4389fbd8f5294d599943e338cf5d6ca748c40 100644 (file)
@@ -273,7 +273,7 @@ static void __init am3517_evm_init_irq(void)
        omap_gpio_init();
 }
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
        .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
        .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
        .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
@@ -294,9 +294,9 @@ static struct omap_board_mux board_mux[] __initdata = {
 
 static void __init am3517_evm_init(void)
 {
-       am3517_evm_i2c_init();
-
        omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+
+       am3517_evm_i2c_init();
        platform_add_devices(am3517_evm_devices,
                                ARRAY_SIZE(am3517_evm_devices));
 
index afa77caaff4dece9cc58bc3b469735f4651aba39..2de4f79f03a0f226e7df5b4a1df20175e17c5965 100644 (file)
@@ -612,7 +612,7 @@ static struct omap2_hsmmc_info mmc[] = {
        {}      /* Terminator */
 };
 
-static struct ehci_hcd_omap_platform_data ehci_pdata = {
+static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = {
        .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
        .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
        .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
index 371019054b494c713f19de50310e7b521cc3459d..47e3af2166d4900807f67f9c40a04678956bf706 100644 (file)
@@ -50,7 +50,6 @@
 #include <linux/input/matrix_keypad.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
-#include <linux/usb/otg.h>
 #include <linux/dm9000.h>
 #include <linux/interrupt.h>
 
@@ -269,20 +268,6 @@ static int devkit8000_twl_gpio_setup(struct device *dev,
        devkit8000_vmmc1_supply.dev = mmc[0].dev;
        devkit8000_vsim_supply.dev = mmc[0].dev;
 
-       /* REVISIT: need ehci-omap hooks for external VBUS
-        * power switch and overcurrent detect
-        */
-
-       gpio_request(gpio + 1, "EHCI_nOC");
-       gpio_direction_input(gpio + 1);
-
-       /* 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);
-
-       /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
-       gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
-
        return 0;
 }
 
@@ -303,7 +288,7 @@ static struct regulator_consumer_supply devkit8000_vpll2_supplies[] = {
        .dev            = &devkit8000_lcd_device.dev,
        },
        {
-       .supply         = "vdss_dsi",
+       .supply         = "vdds_dsi",
        .dev            = &devkit8000_dss_device.dev,
        }
 };
@@ -636,20 +621,24 @@ static struct omap_musb_board_data musb_board_data = {
        .power                  = 100,
 };
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
 
        .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
-       .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+       .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
        .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
 
        .phy_reset  = true,
        .reset_gpio_port[0]  = -EINVAL,
-       .reset_gpio_port[1]  = 147,
+       .reset_gpio_port[1]  = -EINVAL,
        .reset_gpio_port[2]  = -EINVAL
 };
 
 static void __init devkit8000_init(void)
 {
+       omap_serial_init();
+
+       omap_dm9000_init();
+
        devkit8000_i2c_init();
        platform_add_devices(devkit8000_devices,
                        ARRAY_SIZE(devkit8000_devices));
@@ -659,25 +648,15 @@ static void __init devkit8000_init(void)
        spi_register_board_info(devkit8000_spi_board_info,
        ARRAY_SIZE(devkit8000_spi_board_info));
 
-       omap_serial_init();
-
-       omap_dm9000_init();
-
        devkit8000_ads7846_init();
 
-       omap_mux_init_gpio(170, OMAP_PIN_INPUT);
-
-       gpio_request(170, "DVI_nPD");
-       /* REVISIT leave DVI powered down until it's needed ... */
-       gpio_direction_output(170, true);
-
        usb_musb_init(&musb_board_data);
        usb_ehci_init(&ehci_pdata);
        devkit8000_flash_init();
 
        /* Ensure SDRC pins are mux'd for self-refresh */
-       omap_mux_init_signal("sdr_cke0", OMAP_PIN_OUTPUT);
-       omap_mux_init_signal("sdr_cke1", OMAP_PIN_OUTPUT);
+       omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+       omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
 }
 
 static void __init devkit8000_map_io(void)
index 9958987a3d0a8456761825c9577ddf0953355eb8..d55c57b761a988e3bb62cc2adeb999709861db2c 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
-#include <linux/leds.h>
 #include <linux/interrupt.h>
 
 #include <linux/regulator/machine.h>
@@ -39,8 +38,8 @@
 #define IGEP2_SMSC911X_CS       5
 #define IGEP2_SMSC911X_GPIO     176
 #define IGEP2_GPIO_USBH_NRESET  24
-#define IGEP2_GPIO_LED0_RED    26
-#define IGEP2_GPIO_LED0_GREEN  27
+#define IGEP2_GPIO_LED0_GREEN  26
+#define IGEP2_GPIO_LED0_RED    27
 #define IGEP2_GPIO_LED1_RED    28
 #define IGEP2_GPIO_DVI_PUP     170
 #define IGEP2_GPIO_WIFI_NPD    94
@@ -355,34 +354,50 @@ static void __init igep2_display_init(void)
            gpio_direction_output(IGEP2_GPIO_DVI_PUP, 1))
                pr_err("IGEP v2: Could not obtain gpio GPIO_DVI_PUP\n");
 }
-#ifdef CONFIG_LEDS_TRIGGERS
-static struct gpio_led gpio_leds[] = {
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+#include <linux/leds.h>
+
+static struct gpio_led igep2_gpio_leds[] = {
        {
-               .name = "GPIO_LED1_RED",
+               .name = "led0:red",
+               .gpio = IGEP2_GPIO_LED0_RED,
+       },
+       {
+               .name = "led0:green",
                .default_trigger = "heartbeat",
+               .gpio = IGEP2_GPIO_LED0_GREEN,
+       },
+       {
+               .name = "led1:red",
                .gpio = IGEP2_GPIO_LED1_RED,
        },
 };
 
-static struct gpio_led_platform_data gpio_leds_info = {
-       .leds           = gpio_leds,
-       .num_leds       = ARRAY_SIZE(gpio_leds),
+static struct gpio_led_platform_data igep2_led_pdata = {
+       .leds           = igep2_gpio_leds,
+       .num_leds       = ARRAY_SIZE(igep2_gpio_leds),
 };
 
-static struct platform_device leds_gpio = {
+static struct platform_device igep2_led_device = {
         .name   = "leds-gpio",
         .id     = -1,
         .dev    = {
-                .platform_data  =  &gpio_leds_info,
+                .platform_data  =  &igep2_led_pdata,
        },
 };
+
+static void __init igep2_init_led(void)
+{
+       platform_device_register(&igep2_led_device);
+}
+
+#else
+static inline void igep2_init_led(void) {}
 #endif
 
 static struct platform_device *igep2_devices[] __initdata = {
        &igep2_dss_device,
-#ifdef CONFIG_LEDS_TRIGGERS
-       &leds_gpio,
-#endif
 };
 
 static void __init igep2_init_irq(void)
@@ -442,14 +457,14 @@ static struct omap_musb_board_data musb_board_data = {
        .power                  = 100,
 };
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
-       .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
-       .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+       .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
+       .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
        .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
 
        .phy_reset = true,
-       .reset_gpio_port[0] = -EINVAL,
-       .reset_gpio_port[1] = IGEP2_GPIO_USBH_NRESET,
+       .reset_gpio_port[0] = IGEP2_GPIO_USBH_NRESET,
+       .reset_gpio_port[1] = -EINVAL,
        .reset_gpio_port[2] = -EINVAL,
 };
 
@@ -471,31 +486,34 @@ static void __init igep2_init(void)
        usb_ehci_init(&ehci_pdata);
 
        igep2_flash_init();
+       igep2_init_led();
        igep2_display_init();
        igep2_init_smsc911x();
 
        /* GPIO userspace leds */
-       if ((gpio_request(IGEP2_GPIO_LED0_RED, "GPIO_LED0_RED") == 0) &&
+#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
+       if ((gpio_request(IGEP2_GPIO_LED0_RED, "led0:red") == 0) &&
            (gpio_direction_output(IGEP2_GPIO_LED0_RED, 1) == 0)) {
                gpio_export(IGEP2_GPIO_LED0_RED, 0);
                gpio_set_value(IGEP2_GPIO_LED0_RED, 0);
        } else
                pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_RED\n");
 
-       if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "GPIO_LED0_GREEN") == 0) &&
+       if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "led0:green") == 0) &&
            (gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 1) == 0)) {
                gpio_export(IGEP2_GPIO_LED0_GREEN, 0);
                gpio_set_value(IGEP2_GPIO_LED0_GREEN, 0);
        } else
                pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_GREEN\n");
-#ifndef CONFIG_LEDS_TRIGGERS
-       if ((gpio_request(IGEP2_GPIO_LED1_RED, "GPIO_LED1_RED") == 0) &&
+
+       if ((gpio_request(IGEP2_GPIO_LED1_RED, "led1:red") == 0) &&
            (gpio_direction_output(IGEP2_GPIO_LED1_RED, 1) == 0)) {
                gpio_export(IGEP2_GPIO_LED1_RED, 0);
                gpio_set_value(IGEP2_GPIO_LED1_RED, 0);
        } else
                pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_RED\n");
 #endif
+
        /* GPIO W-LAN + Bluetooth combo module */
        if ((gpio_request(IGEP2_GPIO_WIFI_NPD, "GPIO_WIFI_NPD") == 0) &&
            (gpio_direction_output(IGEP2_GPIO_WIFI_NPD, 1) == 0)) {
index 4cab0522d7ce1e2ae701750fe8c565cbe15f0a30..3ccc34ebdcc79c11e021b4c80e9fca550bfea037 100644 (file)
@@ -37,6 +37,103 @@ static int slot1_cover_open;
 static int slot2_cover_open;
 static struct device *mmc_device;
 
+#define TUSB6010_ASYNC_CS      1
+#define TUSB6010_SYNC_CS       4
+#define TUSB6010_GPIO_INT      58
+#define TUSB6010_GPIO_ENABLE   0
+#define TUSB6010_DMACHAN       0x3f
+
+#if defined(CONFIG_USB_TUSB6010) || \
+       defined(CONFIG_USB_TUSB6010_MODULE)
+/*
+ * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
+ * 1.5 V voltage regulators of PM companion chip. Companion chip will then
+ * provide then PGOOD signal to TUSB6010 which will release it from reset.
+ */
+static int tusb_set_power(int state)
+{
+       int i, retval = 0;
+
+       if (state) {
+               gpio_set_value(TUSB6010_GPIO_ENABLE, 1);
+               msleep(1);
+
+               /* Wait until TUSB6010 pulls INT pin down */
+               i = 100;
+               while (i && gpio_get_value(TUSB6010_GPIO_INT)) {
+                       msleep(1);
+                       i--;
+               }
+
+               if (!i) {
+                       printk(KERN_ERR "tusb: powerup failed\n");
+                       retval = -ENODEV;
+               }
+       } else {
+               gpio_set_value(TUSB6010_GPIO_ENABLE, 0);
+               msleep(10);
+       }
+
+       return retval;
+}
+
+static struct musb_hdrc_config musb_config = {
+       .multipoint     = 1,
+       .dyn_fifo       = 1,
+       .num_eps        = 16,
+       .ram_bits       = 12,
+};
+
+static struct musb_hdrc_platform_data tusb_data = {
+#if defined(CONFIG_USB_MUSB_OTG)
+       .mode           = MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
+       .mode           = MUSB_PERIPHERAL,
+#else /* defined(CONFIG_USB_MUSB_HOST) */
+       .mode           = MUSB_HOST,
+#endif
+       .set_power      = tusb_set_power,
+       .min_power      = 25,   /* x2 = 50 mA drawn from VBUS as peripheral */
+       .power          = 100,  /* Max 100 mA VBUS for host mode */
+       .config         = &musb_config,
+};
+
+static void __init n8x0_usb_init(void)
+{
+       int ret = 0;
+       static char     announce[] __initdata = KERN_INFO "TUSB 6010\n";
+
+       /* PM companion chip power control pin */
+       ret = gpio_request(TUSB6010_GPIO_ENABLE, "TUSB6010 enable");
+       if (ret != 0) {
+               printk(KERN_ERR "Could not get TUSB power GPIO%i\n",
+                      TUSB6010_GPIO_ENABLE);
+               return;
+       }
+       gpio_direction_output(TUSB6010_GPIO_ENABLE, 0);
+
+       tusb_set_power(0);
+
+       ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2,
+                                       TUSB6010_ASYNC_CS, TUSB6010_SYNC_CS,
+                                       TUSB6010_GPIO_INT, TUSB6010_DMACHAN);
+       if (ret != 0)
+               goto err;
+
+       printk(announce);
+
+       return;
+
+err:
+       gpio_free(TUSB6010_GPIO_ENABLE);
+}
+#else
+
+static void __init n8x0_usb_init(void) {}
+
+#endif /*CONFIG_USB_TUSB6010 */
+
+
 static struct omap2_mcspi_device_config p54spi_mcspi_config = {
        .turbo_mode     = 0,
        .single_channel = 1,
@@ -119,7 +216,7 @@ static void __init n8x0_onenand_init(void) {}
  */
 #define N8X0_SLOT_SWITCH_GPIO  96
 #define N810_EMMC_VSD_GPIO     23
-#define NN810_EMMC_VIO_GPIO    9
+#define N810_EMMC_VIO_GPIO     9
 
 static int n8x0_mmc_switch_slot(struct device *dev, int slot)
 {
@@ -207,10 +304,10 @@ static void n810_set_power_emmc(struct device *dev,
        if (power_on) {
                gpio_set_value(N810_EMMC_VSD_GPIO, 1);
                msleep(1);
-               gpio_set_value(NN810_EMMC_VIO_GPIO, 1);
+               gpio_set_value(N810_EMMC_VIO_GPIO, 1);
                msleep(1);
        } else {
-               gpio_set_value(NN810_EMMC_VIO_GPIO, 0);
+               gpio_set_value(N810_EMMC_VIO_GPIO, 0);
                msleep(50);
                gpio_set_value(N810_EMMC_VSD_GPIO, 0);
                msleep(50);
@@ -371,7 +468,7 @@ static void n8x0_mmc_cleanup(struct device *dev)
 
        if (machine_is_nokia_n810()) {
                gpio_free(N810_EMMC_VSD_GPIO);
-               gpio_free(NN810_EMMC_VIO_GPIO);
+               gpio_free(N810_EMMC_VIO_GPIO);
        }
 }
 
@@ -432,7 +529,7 @@ void __init n8x0_mmc_init(void)
 
        err = gpio_request(N8X0_SLOT_SWITCH_GPIO, "MMC slot switch");
        if (err)
-               return err;
+               return;
 
        gpio_direction_output(N8X0_SLOT_SWITCH_GPIO, 0);
 
@@ -440,17 +537,17 @@ void __init n8x0_mmc_init(void)
                err = gpio_request(N810_EMMC_VSD_GPIO, "MMC slot 2 Vddf");
                if (err) {
                        gpio_free(N8X0_SLOT_SWITCH_GPIO);
-                       return err;
+                       return;
                }
                gpio_direction_output(N810_EMMC_VSD_GPIO, 0);
 
-               err = gpio_request(NN810_EMMC_VIO_GPIO, "MMC slot 2 Vdd");
+               err = gpio_request(N810_EMMC_VIO_GPIO, "MMC slot 2 Vdd");
                if (err) {
                        gpio_free(N8X0_SLOT_SWITCH_GPIO);
                        gpio_free(N810_EMMC_VSD_GPIO);
-                       return err;
+                       return;
                }
-               gpio_direction_output(NN810_EMMC_VIO_GPIO, 0);
+               gpio_direction_output(N810_EMMC_VIO_GPIO, 0);
        }
 
        mmc_data[0] = &mmc1_data;
@@ -562,6 +659,7 @@ static void __init n8x0_init_machine(void)
        n8x0_menelaus_init();
        n8x0_onenand_init();
        n8x0_mmc_init();
+       n8x0_usb_init();
 }
 
 MACHINE_START(NOKIA_N800, "Nokia N800")
index 6eb77e1f7c828b04c27f4742aff108f2f4c74eee..962d377970e9bb198d410abf1ac1b418d0658341 100644 (file)
@@ -410,7 +410,7 @@ static void __init omap3beagle_flash_init(void)
        }
 }
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
 
        .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
        .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
index d6bc88c426b560bace561b402e28d7817f7d457f..017bb2f4f7d292a65acda7aafb29e20e5d7bbfc7 100644 (file)
@@ -635,7 +635,7 @@ static struct platform_device *omap3_evm_devices[] __initdata = {
        &omap3_evm_dss_device,
 };
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = {
 
        .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
        .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
index 4827f4658df391ab3023c25e28d7ca7901628417..395d049bf010ad8f67e050cd4877ab7c54f4399e 100644 (file)
@@ -459,12 +459,20 @@ static struct i2c_board_info __initdata omap3pandora_i2c_boardinfo[] = {
        },
 };
 
+static struct i2c_board_info __initdata omap3pandora_i2c3_boardinfo[] = {
+       {
+               I2C_BOARD_INFO("bq27500", 0x55),
+               .flags = I2C_CLIENT_WAKE,
+       },
+};
+
 static int __init omap3pandora_i2c_init(void)
 {
        omap_register_i2c_bus(1, 2600, omap3pandora_i2c_boardinfo,
                        ARRAY_SIZE(omap3pandora_i2c_boardinfo));
        /* i2c2 pins are not connected */
-       omap_register_i2c_bus(3, 100, NULL, 0);
+       omap_register_i2c_bus(3, 100, omap3pandora_i2c3_boardinfo,
+                       ARRAY_SIZE(omap3pandora_i2c3_boardinfo));
        return 0;
 }
 
@@ -537,7 +545,7 @@ static struct platform_device *omap3pandora_devices[] __initdata = {
        &pandora_dss_device,
 };
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
 
        .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
        .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
index 3943d0f8322c68dd2ae95db6981b6a8c31a3a4f2..2504d41f923e01bcbf6dd82b92ceb03139c1c8bf 100644 (file)
@@ -493,7 +493,7 @@ static void __init omap3touchbook_flash_init(void)
        }
 }
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
 
        .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
        .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
@@ -518,14 +518,14 @@ static void omap3_touchbook_poweroff(void)
        gpio_direction_output(TB_KILL_POWER_GPIO, 0);
 }
 
-static void __init early_touchbook_revision(char **p)
+static int __init early_touchbook_revision(char *p)
 {
-       if (!*p)
-               return;
+       if (!p)
+               return 0;
 
-       strict_strtoul(*p, 10, &touchbook_revision);
+       return strict_strtoul(p, 10, &touchbook_revision);
 }
-__early_param("tbr=", early_touchbook_revision);
+early_param("tbr", early_touchbook_revision);
 
 static struct omap_musb_board_data musb_board_data = {
        .interface_type         = MUSB_INTERFACE_ULPI,
index 50872a42bec74c3dbafe6c686a8ad0c5ce2d9bbf..8848c7c5ce48d03a58bb8f758583b0ee0ab27b3e 100644 (file)
@@ -394,7 +394,7 @@ static struct platform_device *overo_devices[] __initdata = {
        &overo_lcd_device,
 };
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
        .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
        .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
        .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
index b1b88deec7f242275bf7bae4b0a1d227f7c9046d..2d026328e3852ec5dff0ad3be63a8f38a9c4b013 100644 (file)
@@ -253,20 +253,20 @@ void __init sdp_flash_init(struct flash_partitions sdp_partition_info[])
        }
 
        if (norcs > GPMC_CS_NUM)
-               printk(KERN_INFO "OneNAND: Unable to find configuration "
-                               " in GPMC\n ");
+               printk(KERN_INFO "NOR: Unable to find configuration "
+                               "in GPMC\n");
        else
                board_nor_init(sdp_partition_info[0], norcs);
 
        if (onenandcs > GPMC_CS_NUM)
                printk(KERN_INFO "OneNAND: Unable to find configuration "
-                               " in GPMC\n ");
+                               "in GPMC\n");
        else
                board_onenand_init(sdp_partition_info[1], onenandcs);
 
        if (nandcs > GPMC_CS_NUM)
                printk(KERN_INFO "NAND: Unable to find configuration "
-                               " in GPMC\n ");
+                               "in GPMC\n");
        else
                board_nand_init(sdp_partition_info[2], nandcs);
 }
index bb4018b6064295f2fb8776dcc31db430e28f3edf..e15d2e87cfc17570326a3711f37aba6c04946547 100644 (file)
@@ -96,7 +96,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 
 static struct platform_device zoom_debugboard_serial_device = {
        .name                   = "serial8250",
-       .id                     = 3,
+       .id                     = PLAT8250_DEV_PLATFORM,
        .dev                    = {
                .platform_data  = serial_platform_data,
        },
index ca95d8d64136d903036ef069785b61810a82c54e..6b3984964cc59696a98b21872f5f768eccac71d6 100644 (file)
@@ -280,7 +280,6 @@ static void enable_board_wakeup_source(void)
 void __init zoom_peripherals_init(void)
 {
        omap_i2c_init();
-       omap_serial_init();
        usb_musb_init(&musb_board_data);
        enable_board_wakeup_source();
 }
index d3e3cd5170d12b17ea18c98f4f496b0233c0c4d3..cd3e40cf3ac1f5df07576963ddf150593886477d 100644 (file)
@@ -52,7 +52,7 @@ static struct omap_board_mux board_mux[] __initdata = {
 #define board_mux      NULL
 #endif
 
-static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
        .port_mode[0]           = EHCI_HCD_OMAP_MODE_UNKNOWN,
        .port_mode[1]           = EHCI_HCD_OMAP_MODE_PHY,
        .port_mode[2]           = EHCI_HCD_OMAP_MODE_UNKNOWN,
index 3b1eac4d539037cd40404a852e5f13bea5415f46..e60ca4e47bbd8a1927e5c11e3e533d3ad5700faf 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/cpufreq.h>
+#include <linux/slab.h>
 
 #include <plat/clock.h>
 #include <plat/sram.h>
index f12af95ead45b509e066c2319d5139439164daef..d932b142d0b66e1b81dd3329c3491476e9ce8a3e 100644 (file)
@@ -1841,6 +1841,7 @@ static struct omap_clk omap2420_clks[] = {
        CLK(NULL,       "aes_ick",      &aes_ick,       CK_242X),
        CLK(NULL,       "pka_ick",      &pka_ick,       CK_242X),
        CLK(NULL,       "usb_fck",      &usb_fck,       CK_242X),
+       CLK("musb_hdrc",        "fck",  &osc_ck,        CK_242X),
 };
 
 /*
index d5153b6bd6cb3bf3ef502f780227913fac5af066..9cba5560519b544f91c4d071bbb6cf2520e43fb1 100644 (file)
@@ -895,7 +895,7 @@ static struct clk dpll4_m4x2_ck = {
        .ops            = &clkops_omap2_dflt_wait,
        .parent         = &dpll4_m4_ck,
        .enable_reg     = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-       .enable_bit     = OMAP3430_PWRDN_CAM_SHIFT,
+       .enable_bit     = OMAP3430_PWRDN_DSS1_SHIFT,
        .flags          = INVERT_ENABLE,
        .clkdm_name     = "dpll4_clkdm",
        .recalc         = &omap3_clkoutx2_recalc,
index 28b107967c861350502e920f8c9c182e3f983914..a5c0c9c8e4962dd97801246a68cefa3cd12adb5a 100644 (file)
@@ -2671,10 +2671,10 @@ static struct omap_clk omap44xx_clks[] = {
        CLK("omap-mcbsp.2",     "ick",                          &dummy_ck,      CK_443X),
        CLK("omap-mcbsp.3",     "ick",                          &dummy_ck,      CK_443X),
        CLK("omap-mcbsp.4",     "ick",                          &dummy_ck,      CK_443X),
-       CLK("omap-mcspi.1",     "ick",                          &dummy_ck,      CK_443X),
-       CLK("omap-mcspi.2",     "ick",                          &dummy_ck,      CK_443X),
-       CLK("omap-mcspi.3",     "ick",                          &dummy_ck,      CK_443X),
-       CLK("omap-mcspi.4",     "ick",                          &dummy_ck,      CK_443X),
+       CLK("omap2_mcspi.1",    "ick",                  &dummy_ck,      CK_443X),
+       CLK("omap2_mcspi.2",    "ick",                  &dummy_ck,      CK_443X),
+       CLK("omap2_mcspi.3",    "ick",                  &dummy_ck,      CK_443X),
+       CLK("omap2_mcspi.4",    "ick",                  &dummy_ck,      CK_443X),
        CLK(NULL,       "uart1_ick",                    &dummy_ck,      CK_443X),
        CLK(NULL,       "uart2_ick",                    &dummy_ck,      CK_443X),
        CLK(NULL,       "uart3_ick",                    &dummy_ck,      CK_443X),
index b87ad66f083ee12ae2a47066a6746faf7ee3a747..6e568ec995ee8946c477dc66b453c4a5d4912789 100644 (file)
@@ -240,7 +240,7 @@ static void _omap2_clkdm_set_hwsup(struct clockdomain *clkdm, int enable)
                        bits = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
                else
                        bits = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
-       } else if (cpu_is_omap34xx() | cpu_is_omap44xx()) {
+       } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
                if (enable)
                        bits = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
                else
@@ -812,7 +812,7 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm)
                cm_set_mod_reg_bits(OMAP24XX_FORCESTATE,
                            clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
 
-       } else if (cpu_is_omap34xx() | cpu_is_omap44xx()) {
+       } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
 
                u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_SLEEP <<
                         __ffs(clkdm->clktrctrl_mask));
@@ -856,7 +856,7 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
                cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE,
                              clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
 
-       } else if (cpu_is_omap34xx() | cpu_is_omap44xx()) {
+       } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
 
                u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_WAKEUP <<
                         __ffs(clkdm->clktrctrl_mask));
index 23e4d7733610c8d4ea7072e0eea8fa8215a66b6d..2271b9bd1f509fc1731aebc01f1a460561ce34eb 100644 (file)
@@ -726,7 +726,7 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
                        if (!cpu_is_omap44xx())
                                return;
                        base = OMAP4_MMC5_BASE + OMAP4_MMC_REG_OFFSET;
-                       irq = OMAP44XX_IRQ_MMC4;
+                       irq = OMAP44XX_IRQ_MMC5;
                        break;
                default:
                        continue;
index 64d74f05abbe8ff011a2325407d911d2f8607dee..e57fb29ff855b484e5339abfbb563259c7390140 100644 (file)
@@ -39,6 +39,9 @@ static int omap2_nand_gpmc_retime(void)
        struct gpmc_timings t;
        int err;
 
+       if (!gpmc_nand_data->gpmc_t)
+               return 0;
+
        memset(&t, 0, sizeof(t));
        t.sync_clk = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->sync_clk);
        t.cs_on = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->cs_on);
index ff25c7e4e6062e51e9a3a51087fbb6b5b5fdee35..50fd749166433f7ebadfa492a4ea136718660e7e 100644 (file)
@@ -52,7 +52,7 @@ omap_irq_base:        .word   0
 
                mrc     p15, 0, \tmp, c0, c0, 0 @ get processor revision
                and     \tmp, \tmp, #0x000f0000 @ only check architecture
-               cmp     \tmp, #0x00060000       @ is v6?
+               cmp     \tmp, #0x00070000       @ is v6?
                beq     2400f                   @ found v6 so it's omap24xx
                mrc     p15, 0, \tmp, c0, c0, 0 @ get processor revision
                and     \tmp, \tmp, #0x000000f0 @ check cortex 8 or 9
index 402e8f0d0f211085838d14f4cb3bf84c93ea25ed..87f676acf61d6e911a727a90791e0e188602302f 100644 (file)
@@ -237,7 +237,7 @@ static void __init _omap2_map_common_io(void)
 }
 
 #ifdef CONFIG_ARCH_OMAP2420
-void __init omap242x_map_common_io()
+void __init omap242x_map_common_io(void)
 {
        iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
        iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc));
@@ -246,7 +246,7 @@ void __init omap242x_map_common_io()
 #endif
 
 #ifdef CONFIG_ARCH_OMAP2430
-void __init omap243x_map_common_io()
+void __init omap243x_map_common_io(void)
 {
        iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
        iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc));
@@ -255,7 +255,7 @@ void __init omap243x_map_common_io()
 #endif
 
 #ifdef CONFIG_ARCH_OMAP3
-void __init omap34xx_map_common_io()
+void __init omap34xx_map_common_io(void)
 {
        iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc));
        _omap2_map_common_io();
@@ -263,7 +263,7 @@ void __init omap34xx_map_common_io()
 #endif
 
 #ifdef CONFIG_ARCH_OMAP4
-void __init omap44xx_map_common_io()
+void __init omap44xx_map_common_io(void)
 {
        iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc));
        _omap2_map_common_io();
@@ -309,7 +309,6 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
 {
        pwrdm_init(powerdomains_omap);
        clkdm_init(clockdomains_omap, clkdm_autodeps);
-#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */
        if (cpu_is_omap242x())
                omap2420_hwmod_init();
        else if (cpu_is_omap243x())
@@ -319,7 +318,6 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
        omap2_mux_init();
        /* The OPP tables have to be registered before a clk init */
        omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps);
-#endif
 
        if (cpu_is_omap2420())
                omap2420_clk_init();
@@ -333,11 +331,12 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
                pr_err("Could not init clock framework - unknown CPU\n");
 
        omap_serial_early_init();
-#ifndef CONFIG_ARCH_OMAP4
-       omap_hwmod_late_init();
+       if (cpu_is_omap24xx() || cpu_is_omap34xx())   /* FIXME: OMAP4 */
+               omap_hwmod_late_init();
        omap_pm_if_init();
-       omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
-       _omap2_init_reprogram_sdrc();
-#endif
+       if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+               omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
+               _omap2_init_reprogram_sdrc();
+       }
        gpmc_init();
 }
index 6f4b7cc8f4d18c0cbf2624f4b0f0aa9aba08e914..4f63dc6859a435f489544c9c241579c7da95a07e 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/device.h>
 #include <linux/jiffies.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/stringify.h>
 
 #include <plat/iommu.h>
index 52a981cb8fdd897e43a975050def3cae2150a1d9..318f3638653c1f97ce106d20ce4d2dd314d85c8d 100644 (file)
@@ -430,19 +430,19 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev)
                if (unlikely(!res)) {
                        dev_err(&pdev->dev, "invalid irq resource\n");
                        ret = -ENODEV;
-                       goto err_iva1;
+                       omap_mbox_unregister(&mbox_dsp_info);
+                       goto err_dsp;
                }
                mbox_iva_info.irq = res->start;
                ret = omap_mbox_register(&pdev->dev, &mbox_iva_info);
-               if (ret)
-                       goto err_iva1;
+               if (ret) {
+                       omap_mbox_unregister(&mbox_dsp_info);
+                       goto err_dsp;
+               }
        }
 #endif
        return 0;
 
-err_iva1:
-       omap_mbox_unregister(&mbox_dsp_info);
-
 err_dsp:
        iounmap(mbox_base);
        return ret;
index be8fce395a58bf1b76f1b2e3657366076cb8a7b3..2f3cad6f940237680920acc62306344c3524ff62 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <mach/irqs.h>
 #include <plat/dma.h>
index b4ca84ee0a95027b5ffd46d82347d4c5d87a7776..8b3d26935a39423c927b73287d1f60fec31ee996 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
 #include <linux/ctype.h>
index aa3f65c2ac973a70e562123d423fa70a3ddb933d..ef0e7a00dd6c6187732524cb1ecdcb1e6f74789e 100644 (file)
@@ -33,7 +33,7 @@
 ENTRY(omap_secondary_startup)
 hold:  ldr     r12,=0x103
        dsb
-       smc                             @ read from AuxCoreBoot0
+       smc     #0                      @ read from AuxCoreBoot0
        mov     r0, r0, lsr #9
        mrc     p15, 0, r4, c0, c0, 5
        and     r4, r4, #0x0f
@@ -52,7 +52,7 @@ ENTRY(omap_modify_auxcoreboot0)
        stmfd   sp!, {r1-r12, lr}
        ldr     r12, =0x104
        dsb
-       smc
+       smc     #0
        ldmfd   sp!, {r1-r12, pc}
 END(omap_modify_auxcoreboot0)
 
@@ -60,6 +60,6 @@ ENTRY(omap_auxcoreboot_addr)
        stmfd   sp!, {r2-r12, lr}
        ldr     r12, =0x105
        dsb
-       smc
+       smc     #0
        ldmfd   sp!, {r2-r12, pc}
 END(omap_auxcoreboot_addr)
diff --git a/arch/arm/mach-omap2/omap44xx-smc.S b/arch/arm/mach-omap2/omap44xx-smc.S
new file mode 100644 (file)
index 0000000..f61c777
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * OMAP44xx secure APIs file.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Written by Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ *
+ * This program is free software,you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+
+/*
+ * This is common routine to manage secure monitor API
+ * used to modify the PL310 secure registers.
+ * 'r0' contains the value to be modified and 'r12' contains
+ * the monitor API number. It uses few CPU registers
+ * internally and hence they need be backed up including
+ * link register "lr".
+ * Function signature : void omap_smc1(u32 fn, u32 arg)
+ */
+
+ENTRY(omap_smc1)
+       stmfd   sp!, {r2-r12, lr}
+       mov     r12, r0
+       mov     r0, r1
+       dsb
+       smc     #0
+       ldmfd   sp!, {r2-r12, pc}
+END(omap_smc1)
index c6649472ce0d1d74f4a3e02bd7f0d6d83acf5e22..e436dcb19795cd259f91faaad864adfe558705d2 100644 (file)
@@ -1511,6 +1511,9 @@ struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
                c = oh->slaves[oh->_mpu_port_index]->_clk;
        }
 
+       if (!c->clkdm)
+               return NULL;
+
        return c->clkdm->pwrdm.ptr;
 
 }
index c18f7f2f19bce28414084571fe3956803126a387..6cac9817c24394024914b08b6e06cc87d81dea4f 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <plat/clock.h>
 #include <plat/board.h>
index fee2efb172e74be9dd7ecb5aaccb51bc52f234de..ea0000bc5358e196df58e88da3f54dd71f0a4706 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <plat/sram.h>
 #include <plat/clockdomain.h>
index 9a0fb385622b90b6be2b429deb079b8961f89502..ebfce7d1a5d37a2e151d93062a5ea427da715233 100644 (file)
@@ -222,7 +222,7 @@ void pwrdm_init(struct powerdomain **pwrdm_list)
 {
        struct powerdomain **p = NULL;
 
-       if (cpu_is_omap24xx() | cpu_is_omap34xx()) {
+       if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
                pwrstctrl_reg_offs = OMAP2_PM_PWSTCTRL;
                pwrstst_reg_offs = OMAP2_PM_PWSTST;
        } else if (cpu_is_omap44xx()) {
index 81872aacb80121422f9a874a7676600623af8bba..07a60f1204ca897eece8c5ddbec243745dbb0323 100644 (file)
@@ -123,7 +123,7 @@ struct omap3_prcm_regs prcm_context;
 u32 omap_prcm_get_reset_sources(void)
 {
        /* XXX This presumably needs modification for 34XX */
-       if (cpu_is_omap24xx() | cpu_is_omap34xx())
+       if (cpu_is_omap24xx() || cpu_is_omap34xx())
                return prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST) & 0x7f;
        if (cpu_is_omap44xx())
                return prm_read_mod_reg(WKUP_MOD, OMAP4_RM_RSTST) & 0x7f;
@@ -133,7 +133,7 @@ u32 omap_prcm_get_reset_sources(void)
 EXPORT_SYMBOL(omap_prcm_get_reset_sources);
 
 /* Resets clock rates and reboots the system. Only called from system.h */
-void omap_prcm_arch_reset(char mode)
+void omap_prcm_arch_reset(char mode, const char *cmd)
 {
        s16 prcm_offs = 0;
 
@@ -145,7 +145,7 @@ void omap_prcm_arch_reset(char mode)
                u32 l;
 
                prcm_offs = OMAP3430_GR_MOD;
-               l = ('B' << 24) | ('M' << 16) | mode;
+               l = ('B' << 24) | ('M' << 16) | (cmd ? (u8)*cmd : 0);
                /* Reserve the first word in scratchpad for communicating
                 * with the boot ROM. A pointer to a data structure
                 * describing the boot process can be stored there,
@@ -157,7 +157,7 @@ void omap_prcm_arch_reset(char mode)
        else
                WARN_ON(1);
 
-       if (cpu_is_omap24xx() | cpu_is_omap34xx())
+       if (cpu_is_omap24xx() || cpu_is_omap34xx())
                prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs,
                                                 OMAP2_RM_RSTCTRL);
        if (cpu_is_omap44xx())
index b79bc8926cc9ad746ed15819c1b086f69e0f1967..3771254dfa811a45efda31a7afc7a0cc48ce86d5 100644 (file)
@@ -115,7 +115,6 @@ static struct plat_serial8250_port serial_platform_data2[] = {
        }
 };
 
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
 static struct plat_serial8250_port serial_platform_data3[] = {
        {
                .irq            = 70,
@@ -128,23 +127,12 @@ static struct plat_serial8250_port serial_platform_data3[] = {
        }
 };
 
-static inline void omap2_set_globals_uart4(struct omap_globals *omap2_globals)
-{
-       serial_platform_data3[0].mapbase = omap2_globals->uart4_phys;
-}
-#else
-static inline void omap2_set_globals_uart4(struct omap_globals *omap2_globals)
-{
-}
-#endif
-
 void __init omap2_set_globals_uart(struct omap_globals *omap2_globals)
 {
        serial_platform_data0[0].mapbase = omap2_globals->uart1_phys;
        serial_platform_data1[0].mapbase = omap2_globals->uart2_phys;
        serial_platform_data2[0].mapbase = omap2_globals->uart3_phys;
-       if (cpu_is_omap3630() || cpu_is_omap44xx())
-               omap2_set_globals_uart4(omap2_globals);
+       serial_platform_data3[0].mapbase = omap2_globals->uart4_phys;
 }
 
 static inline unsigned int __serial_read_reg(struct uart_port *up,
@@ -550,7 +538,7 @@ static ssize_t sleep_timeout_store(struct device *dev,
        unsigned int value;
 
        if (sscanf(buf, "%u", &value) != 1) {
-               printk(KERN_ERR "sleep_timeout_store: Invalid value\n");
+               dev_err(dev, "sleep_timeout_store: Invalid value\n");
                return -EINVAL;
        }
 
@@ -644,42 +632,53 @@ static void serial_out_override(struct uart_port *up, int offset, int value)
 }
 void __init omap_serial_early_init(void)
 {
-       int i;
+       int i, nr_ports;
        char name[16];
 
+       if (!(cpu_is_omap3630() || cpu_is_omap4430()))
+               nr_ports = 3;
+       else
+               nr_ports = ARRAY_SIZE(omap_uart);
+
        /*
         * Make sure the serial ports are muxed on at this point.
         * You have to mux them off in device drivers later on
         * if not needed.
         */
 
-       for (i = 0; i < ARRAY_SIZE(omap_uart); i++) {
+       for (i = 0; i < nr_ports; i++) {
                struct omap_uart_state *uart = &omap_uart[i];
                struct platform_device *pdev = &uart->pdev;
                struct device *dev = &pdev->dev;
                struct plat_serial8250_port *p = dev->platform_data;
 
+               /* Don't map zero-based physical address */
+               if (p->mapbase == 0) {
+                       dev_warn(dev, "no physical address for uart#%d,"
+                                " so skipping early_init...\n", i);
+                       continue;
+               }
                /*
                 * Module 4KB + L4 interconnect 4KB
                 * Static mapping, never released
                 */
                p->membase = ioremap(p->mapbase, SZ_8K);
                if (!p->membase) {
-                       printk(KERN_ERR "ioremap failed for uart%i\n", i + 1);
+                       dev_err(dev, "ioremap failed for uart%i\n", i + 1);
                        continue;
                }
 
-               sprintf(name, "uart%d_ick", i+1);
+               sprintf(name, "uart%d_ick", i + 1);
                uart->ick = clk_get(NULL, name);
                if (IS_ERR(uart->ick)) {
-                       printk(KERN_ERR "Could not get uart%d_ick\n", i+1);
+                       dev_err(dev, "Could not get uart%d_ick\n", i + 1);
                        uart->ick = NULL;
                }
 
                sprintf(name, "uart%d_fck", i+1);
                uart->fck = clk_get(NULL, name);
                if (IS_ERR(uart->fck)) {
-                       printk(KERN_ERR "Could not get uart%d_fck\n", i+1);
+                       dev_err(dev, "Could not get uart%d_fck\n", i + 1);
                        uart->fck = NULL;
                }
 
@@ -722,6 +721,13 @@ void __init omap_serial_init_port(int port)
        pdev = &uart->pdev;
        dev = &pdev->dev;
 
+       /* Don't proceed if there's no clocks available */
+       if (unlikely(!uart->ick || !uart->fck)) {
+               WARN(1, "%s: can't init uart%d, no clocks available\n",
+                    kobject_name(&dev->kobj), port);
+               return;
+       }
+
        omap_uart_enable_clocks(uart);
 
        omap_uart_reset(uart);
index f1df873d59dbf881b9d6a60e01ea9dab1fc1a845..ee9f548d5d8177cf839b333e97617966b01aa2b4 100644 (file)
@@ -70,7 +70,7 @@ static struct platform_device ehci_device = {
 /*
  * setup_ehci_io_mux - initialize IO pad mux for USBHOST
  */
-static void setup_ehci_io_mux(enum ehci_hcd_omap_mode *port_mode)
+static void setup_ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode)
 {
        switch (port_mode[0]) {
        case EHCI_HCD_OMAP_MODE_PHY:
@@ -213,7 +213,7 @@ static void setup_ehci_io_mux(enum ehci_hcd_omap_mode *port_mode)
        return;
 }
 
-void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata)
+void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata)
 {
        platform_device_add_data(&ehci_device, pdata, sizeof(*pdata));
 
@@ -229,7 +229,7 @@ void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata)
 
 #else
 
-void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata)
+void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata)
 
 {
 }
index bdf96eb523bc5f625de1ff18cf6029abba1d44f9..e8706f15a670638e90711f6cf4108076c8cf1cc9 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/mbus.h>
 #include <asm/irq.h>
 #include <asm/mach/pci.h>
index cb0feca193d442781ffeb887915b601554a5a99b..f9f222ebb7ed0c5b12064cebddfe63c9399b3846 100644 (file)
@@ -77,7 +77,7 @@ static struct gpio_keys_button wrt350n_v2_buttons[] = {
                .desc           = "Reset Button",
                .active_low     = 1,
        }, {
-               .code           = KEY_WLAN,
+               .code           = KEY_WPS_BUTTON,
                .gpio           = 2,
                .desc           = "WPS Button",
                .active_low     = 1,
index 425f7188505ed4bac57decaaa09b6fd1ab37e3f2..7fa4bf2e21259884e41d0c610bc09b815bd51e06 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <mach/hardware.h>
index 1f0585329be48a3e651a365a9bc05b42c60b532b..ee3c29c57ae3b3bb204a5da93705188af1ab09f9 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/cacheflush.h>
 
index 38fbd0a0e4022c1e9076fa43740b6468d50b8d19..5b6ee46fa7f6235b9203ae2b00a66453d28d2849 100644 (file)
@@ -272,7 +272,6 @@ config MACH_H5000
 config MACH_HIMALAYA
        bool "HTC Himalaya Support"
        select CPU_PXA26x
-       select FB_W100
 
 config MACH_MAGICIAN
        bool "Enable HTC Magician Support"
@@ -454,6 +453,13 @@ config PXA_SHARPSL
 config SHARPSL_PM
        bool
        select APM_EMULATION
+       select SHARPSL_PM_MAX1111
+
+config SHARPSL_PM_MAX1111
+       bool
+       depends on !CORGI_SSP_DEPRECATED
+       select HWMON
+       select SENSORS_MAX1111
 
 config CORGI_SSP_DEPRECATED
        bool
@@ -547,7 +553,6 @@ config MACH_E740
        bool "Toshiba e740"
        default y
        depends on ARCH_PXA_ESERIES
-       select FB_W100
        help
          Say Y here if you intend to run this kernel on a Toshiba
          e740 family PDA.
@@ -556,7 +561,6 @@ config MACH_E750
        bool "Toshiba e750"
        default y
        depends on ARCH_PXA_ESERIES
-       select FB_W100
        help
          Say Y here if you intend to run this kernel on a Toshiba
          e750 family PDA.
@@ -573,7 +577,6 @@ config MACH_E800
        bool "Toshiba e800"
        default y
        depends on ARCH_PXA_ESERIES
-       select FB_W100
        help
          Say Y here if you intend to run this kernel on a Toshiba
          e800 family PDA.
index 1d9bc118ee320f947d6b62fd92b1b78ce725f100..9347254f8bcf51f374ed51f9d77103d975b69559 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <mach/hardware.h>
index 149cdd9aee4d51d23977d769d1a3d041897f12ee..27fa329d9a8b7a5677c2cf75e25900797130eb46 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
+#include <linux/slab.h>
 
 #include <mach/pxa3xx-regs.h>
 
index b2f878bd460b5d136570560b8fe9f769ebb9d675..5161dca8ccc03d38bab8b92c4e1ed82ea2667ed6 100644 (file)
@@ -559,10 +559,6 @@ static void __init imote2_init(void)
        pxa_set_btuart_info(NULL);
        pxa_set_stuart_info(NULL);
 
-       /* SPI chip select directions - all other directions should
-        * be handled by drivers.*/
-       gpio_direction_output(37, 0);
-
        platform_add_devices(imote2_devices, ARRAY_SIZE(imote2_devices));
 
        pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info);
index 811743c5614769d5fb283201fe77e5c606633d98..5f2ba8d9015cfce31a02f901e7f41742dd1e1fa9 100644 (file)
@@ -2,6 +2,7 @@
 #define _COLIBRI_H_
 
 #include <net/ax88796.h>
+#include <mach/mfp.h>
 
 /*
  * common settings for all modules
index 7515757d6911b152c249d32d7784bcbb61d769a1..3d8d8cb09685ca9113da07bb04ecf1f755ea71f2 100644 (file)
 #define __cpu_is_pxa950(id)                             \
        ({                                              \
                unsigned int _id = (id) >> 4 & 0xfff;   \
-               id == 0x697;                            \
+               _id == 0x697;                           \
         })
 #else
 #define __cpu_is_pxa950(id)    (0)
index 44b0b20b69a42d12d04599da5cbe84ee70fd58c7..c15c0c57de08d857c4a9bc60b67c9d6bfd8b41a8 100644 (file)
 #define U2DMACSR_BUSERRTYPE    (7 << 10)       /* PX Bus Error Type */
 #define U2DMACSR_EORINTR       (1 << 9)        /* End Of Receive */
 #define U2DMACSR_REQPEND       (1 << 8)        /* Request Pending */
-#define U2DMACSR_RASINTR       (1 << 4)        /* Request After Channel Stopped (read / write 1 clear) */#define U2DMACSR_STOPINTR     (1 << 3)        /* Stop Interrupt (read only) */
+#define U2DMACSR_RASINTR       (1 << 4)        /* Request After Channel Stopped (read / write 1 clear) */
+#define U2DMACSR_STOPINTR      (1 << 3)        /* Stop Interrupt (read only) */
 #define U2DMACSR_ENDINTR       (1 << 2)        /* End Interrupt (read / write 1 clear) */
 #define U2DMACSR_STARTINTR     (1 << 1)        /* Start Interrupt (read / write 1 clear) */
 #define U2DMACSR_BUSERRINTR    (1 << 0)        /* Bus Error Interrupt (read / write 1 clear) */
index 5ef91d9d17e47fb08b7d810f4e739726d4802498..759b851ec985e02939d2b8f23cb7b9af8019a1c0 100644 (file)
@@ -16,9 +16,9 @@
 #define BTUART_BASE    (0x40200000)
 #define STUART_BASE    (0x40700000)
 
-static unsigned long uart_base = FFUART_BASE;
-static unsigned int uart_shift = 2;
-static unsigned int uart_is_pxa = 1;
+static unsigned long uart_base;
+static unsigned int uart_shift;
+static unsigned int uart_is_pxa;
 
 static inline unsigned char uart_read(int offset)
 {
@@ -56,6 +56,11 @@ static inline void flush(void)
 
 static inline void arch_decomp_setup(void)
 {
+       /* initialize to default */
+       uart_base = FFUART_BASE;
+       uart_shift = 2;
+       uart_is_pxa = 1;
+
        if (machine_is_littleton() || machine_is_intelmote2()
            || machine_is_csb726() || machine_is_stargate2()
            || machine_is_cm_x300() || machine_is_balloon3())
index 843fcca76e26dc4153cf79128f964f7c20eace94..7a50ed8fce94ddf84795b59531539c9fdc2dc6f3 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/mtd/physmap.h>
 #include <linux/usb/gpio_vbus.h>
 #include <linux/regulator/max1586.h>
+#include <linux/slab.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
index 7693355ee637a60a5496bd980580380c0d19df39..166c15f629162eeef0b45b356d9eedf32218d001 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/suspend.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 
 #include <mach/pm.h>
 
index 3184bdc14526bac6cdf762028f4980996fa8985d..d12667bd9ebe94e8f6064414b5b8b090728b81be 100644 (file)
@@ -37,8 +37,6 @@
 #include <linux/lis3lv02d.h>
 #include <linux/pda_power.h>
 #include <linux/power_supply.h>
-#include <linux/pda_power.h>
-#include <linux/power_supply.h>
 #include <linux/regulator/max8660.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
@@ -444,7 +442,7 @@ static struct gpio_keys_button gpio_keys_button[] = {
                .active_low             = 0,
                .wakeup                 = 0,
                .debounce_interval      = 5, /* ms */
-               .desc                   = "on/off button",
+               .desc                   = "on_off button",
        },
 };
 
@@ -985,7 +983,7 @@ static void __init raumfeld_common_init(void)
                int i;
 
                for (i = 0; i < ARRAY_SIZE(gpio_keys_button); i++)
-                       if (!strcmp(gpio_keys_button[i].desc, "on/off button"))
+                       if (!strcmp(gpio_keys_button[i].desc, "on_off button"))
                                gpio_keys_button[i].active_low = 1;
        }
 
@@ -1011,8 +1009,7 @@ static void __init raumfeld_common_init(void)
                gpio_direction_output(GPIO_W2W_PDN, 0);
 
        /* this can be used to switch off the device */
-       ret = gpio_request(GPIO_SHUTDOWN_SUPPLY,
-                               "supply shutdown");
+       ret = gpio_request(GPIO_SHUTDOWN_SUPPLY, "supply shutdown");
        if (ret < 0)
                pr_warning("Unable to request GPIO_SHUTDOWN_SUPPLY\n");
        else
index 19b5109d9808fae75972f6e1ac4b6250ec784ea7..01bdd7500df442edde598d1213dba9ca9402a83d 100644 (file)
@@ -363,7 +363,7 @@ static struct gpio_keys_button spitz_gpio_keys[] = {
                .type   = EV_PWR,
                .code   = KEY_SUSPEND,
                .gpio   = SPITZ_GPIO_ON_KEY,
-               .desc   = "On/Off",
+               .desc   = "On Off",
                .wakeup = 1,
        },
        /* Two buttons detecting the lid state */
index a98a434f011163321a6f1b79cc13e36b5159156f..2041eb1d90ba0be9582c843b241b318b0f8b611a 100644 (file)
@@ -764,11 +764,6 @@ static void __init stargate2_init(void)
        pxa_set_btuart_info(NULL);
        pxa_set_stuart_info(NULL);
 
-       /* spi chip selects */
-       gpio_direction_output(37, 0);
-       gpio_direction_output(24, 0);
-       gpio_direction_output(39, 0);
-
        platform_add_devices(ARRAY_AND_SIZE(stargate2_devices));
 
        pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info);
index 1dd13346f977a14ab0c39b59136a50ca8b2d5d59..e90114a7e246ad4627db5ece88d0b2d159b677fa 100644 (file)
 #include <linux/delay.h>
 #include <linux/fs.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/major.h>
 #include <linux/module.h>
 #include <linux/pm.h>
 #include <linux/sched.h>
 #include <linux/gpio.h>
+#include <linux/jiffies.h>
 #include <linux/i2c-gpio.h>
 #include <linux/serial_8250.h>
 #include <linux/smc91x.h>
@@ -453,7 +455,7 @@ static struct i2c_gpio_platform_data i2c_bus_data = {
        .sda_pin = VIPER_RTC_I2C_SDA_GPIO,
        .scl_pin = VIPER_RTC_I2C_SCL_GPIO,
        .udelay  = 10,
-       .timeout = 100,
+       .timeout = HZ,
 };
 
 static struct platform_device i2c_bus_device = {
@@ -778,7 +780,7 @@ static void __init viper_tpm_init(void)
                .sda_pin = VIPER_TPM_I2C_SDA_GPIO,
                .scl_pin = VIPER_TPM_I2C_SCL_GPIO,
                .udelay  = 10,
-               .timeout = 100,
+               .timeout = HZ,
        };
        char *errstr;
 
index 90bd4ef71b2cae9b426d0bf5e707c2a441a35e1c..d5a95738f85b027578e6f25ea9fffe216a023adf 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/smsc911x.h>
 #include <linux/ata_platform.h>
 #include <linux/amba/mmci.h>
+#include <linux/gfp.h>
 
 #include <asm/clkdev.h>
 #include <asm/system.h>
@@ -253,7 +254,7 @@ static unsigned int realview_mmc_status(struct device *dev)
        else
                mask = 2;
 
-       return readl(REALVIEW_SYSMCI) & mask;
+       return !(readl(REALVIEW_SYSMCI) & mask);
 }
 
 struct mmci_platform_data realview_mmc0_plat_data = {
index c47d974d52bdacbe5fddcc40b9a630c2f5a914f0..85883b2e0e49cdecb8eed50a3042842972de5a81 100644 (file)
@@ -9,7 +9,6 @@
  *
  *  DMA functions specific to RiscPC architecture
  */
-#include <linux/slab.h>
 #include <linux/mman.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
index d5862368c4f20853a8b333d8ca1ab68bf2771ac0..8c9e2c7161c6f70a03bd3968b7b07f40298a4b91 100644 (file)
@@ -109,8 +109,6 @@ static inline void flush(void)
 {
 }
 
-static void error(char *x);
-
 /*
  * Setup for decompression
  */
index b62bdf18dca4e156d1b00f3b4ea3c887281893a1..33ccf7bf766a961d35eb71cbae7107547bcf913e 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/dmapool.h>
 #include <linux/sysdev.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/err.h>
index b18ac5266dfc333d9196a564a565341bb4168cb9..f9ab5d26052a38762c1559b51dbe1d46ab7786cc 100644 (file)
@@ -21,7 +21,7 @@
         * aligned and add in the offset when we load the value here.
         */
 
-       .macro addruart, rx
+       .macro addruart, rx, rtmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1
                ldreq   \rx, = S3C_PA_UART
index 48cdb0da026c1c4939178b842e2838c94b2efbd3..1347d7f99079a1a3ff6ae4e92961f588724bebc2 100644 (file)
@@ -19,7 +19,7 @@
         * aligned and add in the offset when we load the value here.
         */
 
-       .macro addruart, rx
+       .macro addruart, rx, rtmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1
                ldreq   \rx, = S3C_PA_UART
index 1aae691e58ef3d4fc7b0b2c512cd4b87fe13b55b..bb6536147ffb0bd7c55c95d8eb796401824ceeb7 100644 (file)
@@ -15,7 +15,7 @@
 #include <mach/map.h>
 #include <plat/regs-serial.h>
 
-       .macro addruart, rx
+       .macro addruart, rx, rtmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1
                ldreq   \rx, = S3C_PA_UART
index b17d52f7cc48739b2d02d24e690021c4e28d69fc..fd4c52b7ccb68a499f28514a2d6ad80d01810073 100644 (file)
@@ -57,7 +57,7 @@ config SA1100_COLLIE
 config SA1100_H3100
        bool "Compaq iPAQ H3100"
        select HTC_EGPIO
-       select CPU_FREQ_SA1100
+       select CPU_FREQ_SA1110
        help
          Say Y here if you intend to run this kernel on the Compaq iPAQ
          H3100 handheld computer.  Information about this machine and the
@@ -68,7 +68,7 @@ config SA1100_H3100
 config SA1100_H3600
        bool "Compaq iPAQ H3600/H3700"
        select HTC_EGPIO
-       select CPU_FREQ_SA1100
+       select CPU_FREQ_SA1110
        help
          Say Y here if you intend to run this kernel on the Compaq iPAQ
          H3600 handheld computer.  Information about this machine and the
index 63b32b68b296969e73638e2e370bcc7322049ac7..7252874d328b59eb808110351aabeff2e4a9c11d 100644 (file)
@@ -363,6 +363,9 @@ static int __init sa1110_clk_init(void)
        struct sdram_params *sdram;
        const char *name = sdram_name;
 
+       if (!cpu_is_sa1110())
+               return -ENODEV;
+
        if (!name[0]) {
                if (machine_is_assabet())
                        name = "TC59SM716-CL3";
index 9b6dee5d16dbe859ac3ae2383bf08caf6e12947a..9d490c66891cfb0209e4a27646a758a9b2993428 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <mach/jornada720.h>
index 0b505d9f22d6e7fcc9c568d0dc2a0977fe25f0a6..c601a75a333d147bf138cba667e11b84b9871a14 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/ioport.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
-#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
index a0463d9264477272098ee1146768e8b7b66abf76..1c2ec96ce2610c88a9292b7edcf6adc1f390b808 100644 (file)
@@ -206,10 +206,32 @@ static struct platform_device keysc_device = {
        },
 };
 
+/* SDHI0 */
+static struct resource sdhi0_resources[] = {
+       [0] = {
+               .name   = "SDHI0",
+               .start  = 0xe6850000,
+               .end    = 0xe68501ff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = 96,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device sdhi0_device = {
+       .name           = "sh_mobile_sdhi",
+       .num_resources  = ARRAY_SIZE(sdhi0_resources),
+       .resource       = sdhi0_resources,
+       .id             = 0,
+};
+
 static struct platform_device *ap4evb_devices[] __initdata = {
        &nor_flash_device,
        &smc911x_device,
        &keysc_device,
+       &sdhi0_device,
 };
 
 static struct map_desc ap4evb_io_desc[] __initdata = {
@@ -286,6 +308,16 @@ static void __init ap4evb_init(void)
        gpio_request(GPIO_FN_KEYIN3_133, NULL);
        gpio_request(GPIO_FN_KEYIN4,     NULL);
 
+       /* SDHI0 */
+       gpio_request(GPIO_FN_SDHICD0, NULL);
+       gpio_request(GPIO_FN_SDHIWP0, NULL);
+       gpio_request(GPIO_FN_SDHICMD0, NULL);
+       gpio_request(GPIO_FN_SDHICLK0, NULL);
+       gpio_request(GPIO_FN_SDHID0_3, NULL);
+       gpio_request(GPIO_FN_SDHID0_2, NULL);
+       gpio_request(GPIO_FN_SDHID0_1, NULL);
+       gpio_request(GPIO_FN_SDHID0_0, NULL);
+
        sh7372_add_standard_devices();
 
        platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices));
index f36c9a94d32646dd19ce3a4f82c2606b11c4dfc0..9247503296c4135807fc1a19f24894413ccc7de1 100644 (file)
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
+#include <linux/mtd/sh_flctl.h>
 #include <linux/usb/r8a66597.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
 #include <mach/sh7367.h>
 #include <mach/common.h>
 #include <asm/mach-types.h>
@@ -127,9 +130,90 @@ static struct platform_device usb_host_device = {
        .resource       = usb_host_resources,
 };
 
+/* KEYSC */
+static struct sh_keysc_info keysc_info = {
+       .mode           = SH_KEYSC_MODE_5,
+       .scan_timing    = 3,
+       .delay          = 100,
+       .keycodes = {
+               KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G,
+               KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N,
+               KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U,
+               KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_HOME, KEY_SLEEP,
+               KEY_WAKEUP, KEY_COFFEE, KEY_0, KEY_1, KEY_2, KEY_3, KEY_4,
+               KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_STOP, KEY_COMPUTER,
+       },
+};
+
+static struct resource keysc_resources[] = {
+       [0] = {
+               .name   = "KEYSC",
+               .start  = 0xe61b0000,
+               .end    = 0xe61b000f,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = 79,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device keysc_device = {
+       .name           = "sh_keysc",
+       .num_resources  = ARRAY_SIZE(keysc_resources),
+       .resource       = keysc_resources,
+       .dev    = {
+               .platform_data  = &keysc_info,
+       },
+};
+
+static struct mtd_partition nand_partition_info[] = {
+       {
+               .name   = "system",
+               .offset = 0,
+               .size   = 64 * 1024 * 1024,
+       },
+       {
+               .name   = "userdata",
+               .offset = MTDPART_OFS_APPEND,
+               .size   = 128 * 1024 * 1024,
+       },
+       {
+               .name   = "cache",
+               .offset = MTDPART_OFS_APPEND,
+               .size   = 64 * 1024 * 1024,
+       },
+};
+
+static struct resource nand_flash_resources[] = {
+       [0] = {
+               .start  = 0xe6a30000,
+               .end    = 0xe6a3009b,
+               .flags  = IORESOURCE_MEM,
+       }
+};
+
+static struct sh_flctl_platform_data nand_flash_data = {
+       .parts          = nand_partition_info,
+       .nr_parts       = ARRAY_SIZE(nand_partition_info),
+       .flcmncr_val    = QTSEL_E | FCKSEL_E | TYPESEL_SET | NANWF_E
+                       | SHBUSSEL | SEL_16BIT,
+};
+
+static struct platform_device nand_flash_device = {
+       .name           = "sh_flctl",
+       .resource       = nand_flash_resources,
+       .num_resources  = ARRAY_SIZE(nand_flash_resources),
+       .dev            = {
+               .platform_data = &nand_flash_data,
+       },
+};
+
 static struct platform_device *g3evm_devices[] __initdata = {
        &nor_flash_device,
        &usb_host_device,
+       &keysc_device,
+       &nand_flash_device,
 };
 
 static struct map_desc g3evm_io_desc[] __initdata = {
@@ -196,6 +280,44 @@ static void __init g3evm_init(void)
        __raw_writew(0x6010, 0xe60581c6);       /* CGPOSR */
        __raw_writew(0x8a0a, 0xe605810c);       /* USBCR2 */
 
+       /* KEYSC @ CN7 */
+       gpio_request(GPIO_FN_PORT42_KEYOUT0, NULL);
+       gpio_request(GPIO_FN_PORT43_KEYOUT1, NULL);
+       gpio_request(GPIO_FN_PORT44_KEYOUT2, NULL);
+       gpio_request(GPIO_FN_PORT45_KEYOUT3, NULL);
+       gpio_request(GPIO_FN_PORT46_KEYOUT4, NULL);
+       gpio_request(GPIO_FN_PORT47_KEYOUT5, NULL);
+       gpio_request(GPIO_FN_PORT48_KEYIN0_PU, NULL);
+       gpio_request(GPIO_FN_PORT49_KEYIN1_PU, NULL);
+       gpio_request(GPIO_FN_PORT50_KEYIN2_PU, NULL);
+       gpio_request(GPIO_FN_PORT55_KEYIN3_PU, NULL);
+       gpio_request(GPIO_FN_PORT56_KEYIN4_PU, NULL);
+       gpio_request(GPIO_FN_PORT57_KEYIN5_PU, NULL);
+       gpio_request(GPIO_FN_PORT58_KEYIN6_PU, NULL);
+
+       /* FLCTL */
+       gpio_request(GPIO_FN_FCE0, NULL);
+       gpio_request(GPIO_FN_D0_ED0_NAF0, NULL);
+       gpio_request(GPIO_FN_D1_ED1_NAF1, NULL);
+       gpio_request(GPIO_FN_D2_ED2_NAF2, NULL);
+       gpio_request(GPIO_FN_D3_ED3_NAF3, NULL);
+       gpio_request(GPIO_FN_D4_ED4_NAF4, NULL);
+       gpio_request(GPIO_FN_D5_ED5_NAF5, NULL);
+       gpio_request(GPIO_FN_D6_ED6_NAF6, NULL);
+       gpio_request(GPIO_FN_D7_ED7_NAF7, NULL);
+       gpio_request(GPIO_FN_D8_ED8_NAF8, NULL);
+       gpio_request(GPIO_FN_D9_ED9_NAF9, NULL);
+       gpio_request(GPIO_FN_D10_ED10_NAF10, NULL);
+       gpio_request(GPIO_FN_D11_ED11_NAF11, NULL);
+       gpio_request(GPIO_FN_D12_ED12_NAF12, NULL);
+       gpio_request(GPIO_FN_D13_ED13_NAF13, NULL);
+       gpio_request(GPIO_FN_D14_ED14_NAF14, NULL);
+       gpio_request(GPIO_FN_D15_ED15_NAF15, NULL);
+       gpio_request(GPIO_FN_WE0_XWR0_FWE, NULL);
+       gpio_request(GPIO_FN_FRB, NULL);
+       /* FOE, FCDE, FSC on dedicated pins */
+       __raw_writel(__raw_readl(0xe6158048) & ~(1 << 15), 0xe6158048);
+
        sh7367_add_standard_devices();
 
        platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices));
index 5acd623f93e7929813c7887db6f56c5e7b1f69ff..10673a90be52946cd391adb2aa611f7e9e3ab18c 100644 (file)
@@ -28,6 +28,8 @@
 #include <linux/mtd/physmap.h>
 #include <linux/usb/r8a66597.h>
 #include <linux/io.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
 #include <linux/gpio.h>
 #include <mach/sh7377.h>
 #include <mach/common.h>
@@ -128,9 +130,49 @@ static struct platform_device usb_host_device = {
        .resource       = usb_host_resources,
 };
 
+/* KEYSC */
+static struct sh_keysc_info keysc_info = {
+       .mode           = SH_KEYSC_MODE_5,
+       .scan_timing    = 3,
+       .delay          = 100,
+       .keycodes = {
+               KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F,
+               KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L,
+               KEY_M, KEY_N, KEY_U, KEY_P, KEY_Q, KEY_R,
+               KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, KEY_X,
+               KEY_Y, KEY_Z, KEY_HOME, KEY_SLEEP, KEY_WAKEUP, KEY_COFFEE,
+               KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5,
+               KEY_6, KEY_7, KEY_8, KEY_9, KEY_STOP, KEY_COMPUTER,
+       },
+};
+
+static struct resource keysc_resources[] = {
+       [0] = {
+               .name   = "KEYSC",
+               .start  = 0xe61b0000,
+               .end    = 0xe61b000f,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = 79,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device keysc_device = {
+       .name           = "sh_keysc",
+       .id             = 0, /* keysc0 clock */
+       .num_resources  = ARRAY_SIZE(keysc_resources),
+       .resource       = keysc_resources,
+       .dev    = {
+               .platform_data  = &keysc_info,
+       },
+};
+
 static struct platform_device *g4evm_devices[] __initdata = {
        &nor_flash_device,
        &usb_host_device,
+       &keysc_device,
 };
 
 static struct map_desc g4evm_io_desc[] __initdata = {
@@ -196,6 +238,21 @@ static void __init g4evm_init(void)
        __raw_writew(0x6010, 0xe60581c6);       /* CGPOSR */
        __raw_writew(0x8a0a, 0xe605810c);       /* USBCR2 */
 
+       /* KEYSC @ CN31 */
+       gpio_request(GPIO_FN_PORT60_KEYOUT5, NULL);
+       gpio_request(GPIO_FN_PORT61_KEYOUT4, NULL);
+       gpio_request(GPIO_FN_PORT62_KEYOUT3, NULL);
+       gpio_request(GPIO_FN_PORT63_KEYOUT2, NULL);
+       gpio_request(GPIO_FN_PORT64_KEYOUT1, NULL);
+       gpio_request(GPIO_FN_PORT65_KEYOUT0, NULL);
+       gpio_request(GPIO_FN_PORT66_KEYIN0_PU, NULL);
+       gpio_request(GPIO_FN_PORT67_KEYIN1_PU, NULL);
+       gpio_request(GPIO_FN_PORT68_KEYIN2_PU, NULL);
+       gpio_request(GPIO_FN_PORT69_KEYIN3_PU, NULL);
+       gpio_request(GPIO_FN_PORT70_KEYIN4_PU, NULL);
+       gpio_request(GPIO_FN_PORT71_KEYIN5_PU, NULL);
+       gpio_request(GPIO_FN_PORT72_KEYIN6_PU, NULL);
+
        sh7377_add_standard_devices();
 
        platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices));
index 58bd54e1113a8f8ecac2b4d0e3a4b63cc765dfdc..bb940c6e4e6ca6f26ac87824b919a316aec732ed 100644 (file)
@@ -75,6 +75,11 @@ static struct clk usb0_clk = {
        .name       = "usb0",
 };
 
+/* a static keysc0 clk for now - enough to get sh_keysc working */
+static struct clk keysc0_clk = {
+       .name       = "keysc0",
+};
+
 static struct clk_lookup lookups[] = {
        {
                .clk = &peripheral_clk,
@@ -82,6 +87,8 @@ static struct clk_lookup lookups[] = {
                .clk = &r_clk,
        }, {
                .clk = &usb0_clk,
+       }, {
+               .clk = &keysc0_clk,
        }
 };
 
index 6a547b47aabbb346065c937ae1fa4350a968fc61..5ff70cadfc32045caf2d126e42a8c7c66df1e7a3 100644 (file)
@@ -27,6 +27,8 @@
 
 enum {
        UNUSED_INTCA = 0,
+       ENABLED,
+       DISABLED,
 
        /* interrupt sources INTCA */
        IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
@@ -46,8 +48,8 @@ enum {
        MSIOF2, MSIOF1,
        SCIFA4, SCIFA5, SCIFB,
        FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
-       SDHI0_SDHI0I0, SDHI0_SDHI0I1, SDHI0_SDHI0I2, SDHI0_SDHI0I3,
-       SDHI1_SDHI1I0, SDHI1_SDHI1I1, SDHI1_SDHI1I2, SDHI1_SDHI1I3,
+       SDHI0,
+       SDHI1,
        MSU_MSU, MSU_MSU2,
        IREM,
        SIU,
@@ -59,7 +61,7 @@ enum {
        TTI20,
        MISTY,
        DDM,
-       SDHI2_SDHI2I0, SDHI2_SDHI2I1, SDHI2_SDHI2I2, SDHI2_SDHI2I3,
+       SDHI2,
        RWDT0, RWDT1,
        DMAC_1_DEI0, DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3,
        DMAC_2_DEI4, DMAC_2_DEI5, DMAC_2_DADERR,
@@ -70,7 +72,7 @@ enum {
 
        /* interrupt groups INTCA */
        DMAC_1, DMAC_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2,
-       ETM11, ARM11, USBHS, FLCTL, IIC1, SDHI0, SDHI1, SDHI2,
+       ETM11, ARM11, USBHS, FLCTL, IIC1
 };
 
 static struct intc_vect intca_vectors[] = {
@@ -105,10 +107,10 @@ static struct intc_vect intca_vectors[] = {
        INTC_VECT(SCIFB, 0x0d60),
        INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0),
        INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0),
-       INTC_VECT(SDHI0_SDHI0I0, 0x0e00), INTC_VECT(SDHI0_SDHI0I1, 0x0e20),
-       INTC_VECT(SDHI0_SDHI0I2, 0x0e40), INTC_VECT(SDHI0_SDHI0I3, 0x0e60),
-       INTC_VECT(SDHI1_SDHI1I0, 0x0e80), INTC_VECT(SDHI1_SDHI1I1, 0x0ea0),
-       INTC_VECT(SDHI1_SDHI1I2, 0x0ec0), INTC_VECT(SDHI1_SDHI1I3, 0x0ee0),
+       INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20),
+       INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60),
+       INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0),
+       INTC_VECT(SDHI1, 0x0ec0), INTC_VECT(SDHI1, 0x0ee0),
        INTC_VECT(MSU_MSU, 0x0f20), INTC_VECT(MSU_MSU2, 0x0f40),
        INTC_VECT(IREM, 0x0f60),
        INTC_VECT(SIU, 0x0fa0),
@@ -122,8 +124,8 @@ static struct intc_vect intca_vectors[] = {
        INTC_VECT(TTI20, 0x1100),
        INTC_VECT(MISTY, 0x1120),
        INTC_VECT(DDM, 0x1140),
-       INTC_VECT(SDHI2_SDHI2I0, 0x1200), INTC_VECT(SDHI2_SDHI2I1, 0x1220),
-       INTC_VECT(SDHI2_SDHI2I2, 0x1240), INTC_VECT(SDHI2_SDHI2I3, 0x1260),
+       INTC_VECT(SDHI2, 0x1200), INTC_VECT(SDHI2, 0x1220),
+       INTC_VECT(SDHI2, 0x1240), INTC_VECT(SDHI2, 0x1260),
        INTC_VECT(RWDT0, 0x1280), INTC_VECT(RWDT1, 0x12a0),
        INTC_VECT(DMAC_1_DEI0, 0x2000), INTC_VECT(DMAC_1_DEI1, 0x2020),
        INTC_VECT(DMAC_1_DEI2, 0x2040), INTC_VECT(DMAC_1_DEI3, 0x2060),
@@ -158,12 +160,6 @@ static struct intc_group intca_groups[] __initdata = {
        INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
                   FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
        INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
-       INTC_GROUP(SDHI0, SDHI0_SDHI0I0, SDHI0_SDHI0I1,
-                  SDHI0_SDHI0I2, SDHI0_SDHI0I3),
-       INTC_GROUP(SDHI1, SDHI1_SDHI1I0, SDHI1_SDHI1I1,
-                  SDHI1_SDHI1I2, SDHI1_SDHI1I3),
-       INTC_GROUP(SDHI2, SDHI2_SDHI2I0, SDHI2_SDHI2I1,
-                  SDHI2_SDHI2I2, SDHI2_SDHI2I3),
 };
 
 static struct intc_mask_reg intca_mask_registers[] = {
@@ -193,10 +189,10 @@ static struct intc_mask_reg intca_mask_registers[] = {
          { SCIFB, SCIFA5, SCIFA4, MSIOF1,
            0, 0, MSIOF2, 0 } },
        { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
-         { SDHI0_SDHI0I3, SDHI0_SDHI0I2, SDHI0_SDHI0I1, SDHI0_SDHI0I0,
+         { DISABLED, DISABLED, ENABLED, ENABLED,
            FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
        { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
-         { SDHI1_SDHI1I3, SDHI1_SDHI1I2, SDHI1_SDHI1I1, SDHI1_SDHI1I0,
+         { DISABLED, DISABLED, ENABLED, ENABLED,
            TTI20, USBDMAC_USHDMI, SPU, SIU } },
        { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
          { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
@@ -211,7 +207,7 @@ static struct intc_mask_reg intca_mask_registers[] = {
          { 0, 0, TPU0, TPU1,
            TPU2, TPU3, TPU4, 0 } },
        { 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */
-         { SDHI2_SDHI2I3, SDHI2_SDHI2I2, SDHI2_SDHI2I1, SDHI2_SDHI2I0,
+         { DISABLED, DISABLED, ENABLED, ENABLED,
            MISTY, CMT3, RWDT1, RWDT0 } },
 };
 
@@ -258,10 +254,14 @@ static struct intc_mask_reg intca_ack_registers[] __initdata = {
          { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
 };
 
-static DECLARE_INTC_DESC_ACK(intca_desc, "sh7367-intca",
-                            intca_vectors, intca_groups,
-                            intca_mask_registers, intca_prio_registers,
-                            intca_sense_registers, intca_ack_registers);
+static struct intc_desc intca_desc __initdata = {
+       .name = "sh7367-intca",
+       .force_enable = ENABLED,
+       .force_disable = DISABLED,
+       .hw = INTC_HW_DESC(intca_vectors, intca_groups,
+                          intca_mask_registers, intca_prio_registers,
+                          intca_sense_registers, intca_ack_registers),
+};
 
 void __init sh7367_init_irq(void)
 {
index c57a923f97a6d2c835a1e2ae705bcc88b86ca587..3ce9d9bd5899e356d13917794fe8648c3f45426c 100644 (file)
@@ -27,6 +27,8 @@
 
 enum {
        UNUSED_INTCA = 0,
+       ENABLED,
+       DISABLED,
 
        /* interrupt sources INTCA */
        IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
@@ -47,14 +49,14 @@ enum {
        MSIOF2, MSIOF1,
        SCIFA4, SCIFA5, SCIFB,
        FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
-       SDHI0_SDHI0I0, SDHI0_SDHI0I1, SDHI0_SDHI0I2, SDHI0_SDHI0I3,
-       SDHI1_SDHI1I0, SDHI1_SDHI1I1, SDHI1_SDHI1I2,
+       SDHI0,
+       SDHI1,
        IRREM,
        IRDA,
        TPU0,
        TTI20,
        DDM,
-       SDHI2_SDHI2I0, SDHI2_SDHI2I1, SDHI2_SDHI2I2, SDHI2_SDHI2I3,
+       SDHI2,
        RWDT0,
        DMAC1_1_DEI0, DMAC1_1_DEI1, DMAC1_1_DEI2, DMAC1_1_DEI3,
        DMAC1_2_DEI4, DMAC1_2_DEI5, DMAC1_2_DADERR,
@@ -82,7 +84,7 @@ enum {
 
        /* interrupt groups INTCA */
        DMAC1_1, DMAC1_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2, SHWYSTAT,
-       AP_ARM1, AP_ARM2, SPU2, FLCTL, IIC1, SDHI0, SDHI1, SDHI2
+       AP_ARM1, AP_ARM2, SPU2, FLCTL, IIC1
 };
 
 static struct intc_vect intca_vectors[] __initdata = {
@@ -123,17 +125,17 @@ static struct intc_vect intca_vectors[] __initdata = {
        INTC_VECT(SCIFB, 0x0d60),
        INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0),
        INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0),
-       INTC_VECT(SDHI0_SDHI0I0, 0x0e00), INTC_VECT(SDHI0_SDHI0I1, 0x0e20),
-       INTC_VECT(SDHI0_SDHI0I2, 0x0e40), INTC_VECT(SDHI0_SDHI0I3, 0x0e60),
-       INTC_VECT(SDHI1_SDHI1I0, 0x0e80), INTC_VECT(SDHI1_SDHI1I1, 0x0ea0),
-       INTC_VECT(SDHI1_SDHI1I2, 0x0ec0),
+       INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20),
+       INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60),
+       INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0),
+       INTC_VECT(SDHI1, 0x0ec0),
        INTC_VECT(IRREM, 0x0f60),
        INTC_VECT(IRDA, 0x0480),
        INTC_VECT(TPU0, 0x04a0),
        INTC_VECT(TTI20, 0x1100),
        INTC_VECT(DDM, 0x1140),
-       INTC_VECT(SDHI2_SDHI2I0, 0x1200), INTC_VECT(SDHI2_SDHI2I1, 0x1220),
-       INTC_VECT(SDHI2_SDHI2I2, 0x1240), INTC_VECT(SDHI2_SDHI2I3, 0x1260),
+       INTC_VECT(SDHI2, 0x1200), INTC_VECT(SDHI2, 0x1220),
+       INTC_VECT(SDHI2, 0x1240), INTC_VECT(SDHI2, 0x1260),
        INTC_VECT(RWDT0, 0x1280),
        INTC_VECT(DMAC1_1_DEI0, 0x2000), INTC_VECT(DMAC1_1_DEI1, 0x2020),
        INTC_VECT(DMAC1_1_DEI2, 0x2040), INTC_VECT(DMAC1_1_DEI3, 0x2060),
@@ -193,12 +195,6 @@ static struct intc_group intca_groups[] __initdata = {
        INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
                   FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
        INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
-       INTC_GROUP(SDHI0, SDHI0_SDHI0I0, SDHI0_SDHI0I1,
-                  SDHI0_SDHI0I2, SDHI0_SDHI0I3),
-       INTC_GROUP(SDHI1, SDHI1_SDHI1I0, SDHI1_SDHI1I1,
-                  SDHI1_SDHI1I2),
-       INTC_GROUP(SDHI2, SDHI2_SDHI2I0, SDHI2_SDHI2I1,
-                  SDHI2_SDHI2I2, SDHI2_SDHI2I3),
        INTC_GROUP(SHWYSTAT, SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM),
 };
 
@@ -234,10 +230,10 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = {
          { SCIFB, SCIFA5, SCIFA4, MSIOF1,
            0, 0, MSIOF2, 0 } },
        { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
-         { SDHI0_SDHI0I3, SDHI0_SDHI0I2, SDHI0_SDHI0I1, SDHI0_SDHI0I0,
+         { DISABLED, DISABLED, ENABLED, ENABLED,
            FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
        { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
-         { 0, SDHI1_SDHI1I2, SDHI1_SDHI1I1, SDHI1_SDHI1I0,
+         { 0, DISABLED, ENABLED, ENABLED,
            TTI20, USBHSDMAC0_USHDMI, 0, 0 } },
        { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
          { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
@@ -252,7 +248,7 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = {
          { 0, 0, TPU0, 0,
            0, 0, 0, 0 } },
        { 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */
-         { SDHI2_SDHI2I3, SDHI2_SDHI2I2, SDHI2_SDHI2I1, SDHI2_SDHI2I0,
+         { DISABLED, DISABLED, ENABLED, ENABLED,
            0, CMT3, 0, RWDT0 } },
        { 0xe6950080, 0xe69500c0, 8, /* IMR0A3 / IMCR0A3 */
          { SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM, 0,
@@ -358,10 +354,14 @@ static struct intc_mask_reg intca_ack_registers[] __initdata = {
          { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
 };
 
-static DECLARE_INTC_DESC_ACK(intca_desc, "sh7372-intca",
-                            intca_vectors, intca_groups,
-                            intca_mask_registers, intca_prio_registers,
-                            intca_sense_registers, intca_ack_registers);
+static struct intc_desc intca_desc __initdata = {
+       .name = "sh7372-intca",
+       .force_enable = ENABLED,
+       .force_disable = DISABLED,
+       .hw = INTC_HW_DESC(intca_vectors, intca_groups,
+                          intca_mask_registers, intca_prio_registers,
+                          intca_sense_registers, intca_ack_registers),
+};
 
 void __init sh7372_init_irq(void)
 {
index 125021cfba5c63f132c6e34a66ad23cf6453d27a..5c781e2d1897e04ac4756fa2be4668087349cf1b 100644 (file)
@@ -27,6 +27,8 @@
 
 enum {
        UNUSED_INTCA = 0,
+       ENABLED,
+       DISABLED,
 
        /* interrupt sources INTCA */
        IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
@@ -49,8 +51,8 @@ enum {
        MSIOF2, MSIOF1,
        SCIFA4, SCIFA5, SCIFB,
        FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
-       SDHI0_SDHI0I0, SDHI0_SDHI0I1, SDHI0_SDHI0I2, SDHI0_SDHI0I3,
-       SDHI1_SDHI1I0, SDHI1_SDHI1I1, SDHI1_SDHI1I2, SDHI1_SDHI1I3,
+       SDHI0,
+       SDHI1,
        MSU_MSU, MSU_MSU2,
        IRREM,
        MSUG,
@@ -84,7 +86,7 @@ enum {
 
        /* interrupt groups INTCA */
        DMAC_1, DMAC_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2, SHWYSTAT,
-       AP_ARM1, AP_ARM2, USBHS, SPU2, FLCTL, IIC1, SDHI0, SDHI1,
+       AP_ARM1, AP_ARM2, USBHS, SPU2, FLCTL, IIC1,
        ICUSB, ICUDMC
 };
 
@@ -128,10 +130,10 @@ static struct intc_vect intca_vectors[] = {
        INTC_VECT(SCIFB, 0x0d60),
        INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0),
        INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0),
-       INTC_VECT(SDHI0_SDHI0I0, 0x0e00), INTC_VECT(SDHI0_SDHI0I1, 0x0e20),
-       INTC_VECT(SDHI0_SDHI0I2, 0x0e40), INTC_VECT(SDHI0_SDHI0I3, 0x0e60),
-       INTC_VECT(SDHI1_SDHI1I0, 0x0e80), INTC_VECT(SDHI1_SDHI1I1, 0x0ea0),
-       INTC_VECT(SDHI1_SDHI1I2, 0x0ec0), INTC_VECT(SDHI1_SDHI1I3, 0x0ee0),
+       INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20),
+       INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60),
+       INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0),
+       INTC_VECT(SDHI1, 0x0ec0), INTC_VECT(SDHI1, 0x0ee0),
        INTC_VECT(MSU_MSU, 0x0f20), INTC_VECT(MSU_MSU2, 0x0f40),
        INTC_VECT(IRREM, 0x0f60),
        INTC_VECT(MSUG, 0x0fa0),
@@ -195,10 +197,6 @@ static struct intc_group intca_groups[] __initdata = {
        INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
                   FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
        INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
-       INTC_GROUP(SDHI0, SDHI0_SDHI0I0, SDHI0_SDHI0I1,
-                  SDHI0_SDHI0I2, SDHI0_SDHI0I3),
-       INTC_GROUP(SDHI1, SDHI1_SDHI1I0, SDHI1_SDHI1I1,
-                  SDHI1_SDHI1I2, SDHI1_SDHI1I3),
        INTC_GROUP(SHWYSTAT, SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM),
        INTC_GROUP(ICUSB, ICUSB_ICUSB0, ICUSB_ICUSB1),
        INTC_GROUP(ICUDMC, ICUDMC_ICUDMC1, ICUDMC_ICUDMC2),
@@ -236,10 +234,10 @@ static struct intc_mask_reg intca_mask_registers[] = {
          { SCIFB, SCIFA5, SCIFA4, MSIOF1,
            0, 0, MSIOF2, 0 } },
        { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
-         { SDHI0_SDHI0I3, SDHI0_SDHI0I2, SDHI0_SDHI0I1, SDHI0_SDHI0I0,
+         { DISABLED, DISABLED, ENABLED, ENABLED,
            FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
        { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
-         { SDHI1_SDHI1I3, SDHI1_SDHI1I2, SDHI1_SDHI1I1, SDHI1_SDHI1I0,
+         { DISABLED, DISABLED, ENABLED, ENABLED,
            TTI20, USBDMAC_USHDMI, 0, MSUG } },
        { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
          { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
@@ -339,10 +337,14 @@ static struct intc_mask_reg intca_ack_registers[] __initdata = {
          { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
 };
 
-static DECLARE_INTC_DESC_ACK(intca_desc, "sh7377-intca",
-                            intca_vectors, intca_groups,
-                            intca_mask_registers, intca_prio_registers,
-                            intca_sense_registers, intca_ack_registers);
+static struct intc_desc intca_desc __initdata = {
+       .name = "sh7377-intca",
+       .force_enable = ENABLED,
+       .force_disable = DISABLED,
+       .hw = INTC_HW_DESC(intca_vectors, intca_groups,
+                          intca_mask_registers, intca_prio_registers,
+                          intca_sense_registers, intca_ack_registers),
+};
 
 void __init sh7377_init_irq(void)
 {
index 962f9de454deafb39b543b31b66c6f9e31d09485..5f55012b7c9edb99d32c5bcb89358686908773d7 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/mutex.h>
 #include <linux/spi/spi.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 /*
  * WARNING! Do not include this pl022-specific controller header
  * for any generic driver. It is only done in this dummy chip
index 109f5a6e71c75b48cc598a92d930026e85e99463..77fbb1e0e5281854b4bb7df2480c5a094b0998c5 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/gpio.h>
 #include <linux/amba/mmci.h>
+#include <linux/slab.h>
 
 #include "mmc.h"
 #include "padmux.h"
index 9ddb49b1cb719119c2df40c3e807a4c90b36e712..3b1a4ee01815044b965f109745e4d358c5d98c7c 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/clockchips.h>
 #include <linux/cnt32_to_63.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 
 #include <asm/clkdev.h>
 #include <asm/system.h>
index 7161ba23b58a6e2776852abf7eb5a8b857993cd5..334f0df4e948bc46c322c3ca0c50fe8002b676c0 100644 (file)
@@ -16,7 +16,6 @@
  */
 #include <linux/kernel.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
index 48876122df91796dcea6d0317554e8fcd37e7cf2..e2958eb567f9f1e5a2047f0dc4aebd7327adaba3 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/mtd.h>
index c4ed9f93f646be93fbdcc048a326c5d7db995bcd..5bd7c89a604515273212ea304a02353ab9af5c39 100644 (file)
@@ -736,6 +736,12 @@ config NEEDS_SYSCALL_FOR_CMPXCHG
 config OUTER_CACHE
        bool
 
+config OUTER_CACHE_SYNC
+       bool
+       help
+         The outer cache has a outer_cache_fns.sync function pointer
+         that can be used to drain the write buffer of the outer cache.
+
 config CACHE_FEROCEON_L2
        bool "Enable the Feroceon L2 cache controller"
        depends on ARCH_KIRKWOOD || ARCH_MV78XX0
@@ -757,6 +763,7 @@ config CACHE_L2X0
                   REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4
        default y
        select OUTER_CACHE
+       select OUTER_CACHE_SYNC
        help
          This option enables the L2x0 PrimeCell.
 
@@ -781,3 +788,9 @@ config ARM_L1_CACHE_SHIFT
        int
        default 6 if ARM_L1_CACHE_SHIFT_6
        default 5
+
+config ARCH_HAS_BARRIERS
+       bool
+       help
+         This option allows the use of custom mandatory barriers
+         included via the mach/barriers.h file.
index edddd66faac6bb9a1f08e8ca144b3677cb9fac3c..a2ab51fa73e2c1982df809af4750a19b124d227e 100644 (file)
@@ -166,15 +166,15 @@ union offset_union {
  THUMB(        "1:     "ins"   %1, [%2]\n"     )               \
  THUMB(        "       add     %2, %2, #1\n"   )               \
        "2:\n"                                          \
-       "       .section .fixup,\"ax\"\n"               \
+       "       .pushsection .fixup,\"ax\"\n"           \
        "       .align  2\n"                            \
        "3:     mov     %0, #1\n"                       \
        "       b       2b\n"                           \
-       "       .previous\n"                            \
-       "       .section __ex_table,\"a\"\n"            \
+       "       .popsection\n"                          \
+       "       .pushsection __ex_table,\"a\"\n"        \
        "       .align  3\n"                            \
        "       .long   1b, 3b\n"                       \
-       "       .previous\n"                            \
+       "       .popsection\n"                          \
        : "=r" (err), "=&r" (val), "=r" (addr)          \
        : "0" (err), "2" (addr))
 
@@ -226,16 +226,16 @@ union offset_union {
                "       mov     %1, %1, "NEXT_BYTE"\n"          \
                "2:     "ins"   %1, [%2]\n"                     \
                "3:\n"                                          \
-               "       .section .fixup,\"ax\"\n"               \
+               "       .pushsection .fixup,\"ax\"\n"           \
                "       .align  2\n"                            \
                "4:     mov     %0, #1\n"                       \
                "       b       3b\n"                           \
-               "       .previous\n"                            \
-               "       .section __ex_table,\"a\"\n"            \
+               "       .popsection\n"                          \
+               "       .pushsection __ex_table,\"a\"\n"        \
                "       .align  3\n"                            \
                "       .long   1b, 4b\n"                       \
                "       .long   2b, 4b\n"                       \
-               "       .previous\n"                            \
+               "       .popsection\n"                          \
                : "=r" (err), "=&r" (v), "=&r" (a)              \
                : "0" (err), "1" (v), "2" (a));                 \
                if (err)                                        \
@@ -266,18 +266,18 @@ union offset_union {
                "       mov     %1, %1, "NEXT_BYTE"\n"          \
                "4:     "ins"   %1, [%2]\n"                     \
                "5:\n"                                          \
-               "       .section .fixup,\"ax\"\n"               \
+               "       .pushsection .fixup,\"ax\"\n"           \
                "       .align  2\n"                            \
                "6:     mov     %0, #1\n"                       \
                "       b       5b\n"                           \
-               "       .previous\n"                            \
-               "       .section __ex_table,\"a\"\n"            \
+               "       .popsection\n"                          \
+               "       .pushsection __ex_table,\"a\"\n"        \
                "       .align  3\n"                            \
                "       .long   1b, 6b\n"                       \
                "       .long   2b, 6b\n"                       \
                "       .long   3b, 6b\n"                       \
                "       .long   4b, 6b\n"                       \
-               "       .previous\n"                            \
+               "       .popsection\n"                          \
                : "=r" (err), "=&r" (v), "=&r" (a)              \
                : "0" (err), "1" (v), "2" (a));                 \
                if (err)                                        \
index 07334632d3e2761293e1880b2486a2e85c3437e4..21ad68ba22bab8a3acd859cbba4df0fc36c93b72 100644 (file)
@@ -93,6 +93,15 @@ static inline void l2x0_flush_line(unsigned long addr)
 }
 #endif
 
+static void l2x0_cache_sync(void)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&l2x0_lock, flags);
+       cache_sync();
+       spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
 static inline void l2x0_inv_all(void)
 {
        unsigned long flags;
@@ -225,6 +234,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
        outer_cache.inv_range = l2x0_inv_range;
        outer_cache.clean_range = l2x0_clean_range;
        outer_cache.flush_range = l2x0_flush_range;
+       outer_cache.sync = l2x0_cache_sync;
 
        printk(KERN_INFO "L2X0 cache controller enabled\n");
 }
index 9d89c67a1cc3902c32b5aed501d27f28b091695c..e46ecd8471383102b52e5c6475873f3f4bdfc65d 100644 (file)
@@ -211,6 +211,9 @@ v6_dma_inv_range:
        mcrne   p15, 0, r1, c7, c15, 1          @ clean & invalidate unified line
 #endif
 1:
+#ifdef CONFIG_SMP
+       str     r0, [r0]                        @ write for ownership
+#endif
 #ifdef HARVARD_CACHE
        mcr     p15, 0, r0, c7, c6, 1           @ invalidate D line
 #else
@@ -231,6 +234,9 @@ v6_dma_inv_range:
 v6_dma_clean_range:
        bic     r0, r0, #D_CACHE_LINE_SIZE - 1
 1:
+#ifdef CONFIG_SMP
+       ldr     r2, [r0]                        @ read for ownership
+#endif
 #ifdef HARVARD_CACHE
        mcr     p15, 0, r0, c7, c10, 1          @ clean D line
 #else
@@ -251,6 +257,10 @@ v6_dma_clean_range:
 ENTRY(v6_dma_flush_range)
        bic     r0, r0, #D_CACHE_LINE_SIZE - 1
 1:
+#ifdef CONFIG_SMP
+       ldr     r2, [r0]                        @ read for ownership
+       str     r2, [r0]                        @ write for ownership
+#endif
 #ifdef HARVARD_CACHE
        mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D line
 #else
@@ -273,7 +283,9 @@ ENTRY(v6_dma_map_area)
        add     r1, r1, r0
        teq     r2, #DMA_FROM_DEVICE
        beq     v6_dma_inv_range
-       b       v6_dma_clean_range
+       teq     r2, #DMA_TO_DEVICE
+       beq     v6_dma_clean_range
+       b       v6_dma_flush_range
 ENDPROC(v6_dma_map_area)
 
 /*
@@ -283,9 +295,6 @@ ENDPROC(v6_dma_map_area)
  *     - dir   - DMA direction
  */
 ENTRY(v6_dma_unmap_area)
-       add     r1, r1, r0
-       teq     r2, #DMA_TO_DEVICE
-       bne     v6_dma_inv_range
        mov     pc, lr
 ENDPROC(v6_dma_unmap_area)
 
index bcd64f265870804532dc6012274bca6e398a0622..06a90dcfc60a6f0cc0b88d5a02bfefdbfeb8610a 100644 (file)
@@ -167,7 +167,11 @@ ENTRY(v7_coherent_user_range)
        cmp     r0, r1
        blo     1b
        mov     r0, #0
+#ifdef CONFIG_SMP
+       mcr     p15, 0, r0, c7, c1, 6           @ invalidate BTB Inner Shareable
+#else
        mcr     p15, 0, r0, c7, c5, 6           @ invalidate BTB
+#endif
        dsb
        isb
        mov     pc, lr
index 8bca4dea6dfa234bbcf0c343a70f87f751de3b66..f55fa1044f72b829d0c307683f9ab12d768a4893 100644 (file)
@@ -41,14 +41,7 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to,
        kfrom = kmap_atomic(from, KM_USER0);
        kto = kmap_atomic(to, KM_USER1);
        copy_page(kto, kfrom);
-#ifdef CONFIG_HIGHMEM
-       /*
-        * kmap_atomic() doesn't set the page virtual address, and
-        * kunmap_atomic() takes care of cache flushing already.
-        */
-       if (page_address(to) != NULL)
-#endif
-               __cpuc_flush_dcache_area(kto, PAGE_SIZE);
+       __cpuc_flush_dcache_area(kto, PAGE_SIZE);
        kunmap_atomic(kto, KM_USER1);
        kunmap_atomic(kfrom, KM_USER0);
 }
index 0da7eccf7749103d26e9545560256f0a8b47dce4..13fa536d82e695ff69b6e74f8e95853cf7199ede 100644 (file)
@@ -11,7 +11,7 @@
  */
 #include <linux/module.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/errno.h>
 #include <linux/list.h>
 #include <linux/init.h>
@@ -464,6 +464,11 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset,
                                vaddr += offset;
                                op(vaddr, len, dir);
                                kunmap_high(page);
+                       } else if (cache_is_vipt()) {
+                               pte_t saved_pte;
+                               vaddr = kmap_high_l1_vipt(page, &saved_pte);
+                               op(vaddr + offset, len, dir);
+                               kunmap_high_l1_vipt(page, saved_pte);
                        }
                } else {
                        vaddr = page_address(page) + offset;
index c9b97e9836a201ba752c069731afdf1a10b7cea1..0d414c28eb2c8e679d3a39563fb666753e4fcd3d 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <linux/pagemap.h>
+#include <linux/gfp.h>
 
 #include <asm/bugs.h>
 #include <asm/cacheflush.h>
index e34f095e2090517b8f968f4af6703e60dd371c8b..c6844cb9b508dde69c49af40bb0d2956b126b8d3 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <asm/cacheflush.h>
 #include <asm/cachetype.h>
+#include <asm/highmem.h>
 #include <asm/smp_plat.h>
 #include <asm/system.h>
 #include <asm/tlbflush.h>
@@ -152,21 +153,25 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
 
 void __flush_dcache_page(struct address_space *mapping, struct page *page)
 {
-       void *addr = page_address(page);
-
        /*
         * Writeback any data associated with the kernel mapping of this
         * page.  This ensures that data in the physical page is mutually
         * coherent with the kernels mapping.
         */
-#ifdef CONFIG_HIGHMEM
-       /*
-        * kmap_atomic() doesn't set the page virtual address, and
-        * kunmap_atomic() takes care of cache flushing already.
-        */
-       if (addr)
-#endif
-               __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+       if (!PageHighMem(page)) {
+               __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
+       } else {
+               void *addr = kmap_high_get(page);
+               if (addr) {
+                       __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+                       kunmap_high(page);
+               } else if (cache_is_vipt()) {
+                       pte_t saved_pte;
+                       addr = kmap_high_l1_vipt(page, &saved_pte);
+                       __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+                       kunmap_high_l1_vipt(page, saved_pte);
+               }
+       }
 
        /*
         * If this is a page cache page, and we have an aliasing VIPT cache,
index 2be1ec7c1b41acea66987a3ef532e96020b71c5b..77b030f5ec09fa2dfbbcc562f345eb0ec04e3092 100644 (file)
@@ -79,7 +79,8 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
        unsigned int idx = type + KM_TYPE_NR * smp_processor_id();
 
        if (kvaddr >= (void *)FIXADDR_START) {
-               __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
+               if (cache_is_vivt())
+                       __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
 #ifdef CONFIG_DEBUG_HIGHMEM
                BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
                set_pte_ext(TOP_PTE(vaddr), __pte(0), 0);
@@ -124,3 +125,87 @@ struct page *kmap_atomic_to_page(const void *ptr)
        pte = TOP_PTE(vaddr);
        return pte_page(*pte);
 }
+
+#ifdef CONFIG_CPU_CACHE_VIPT
+
+#include <linux/percpu.h>
+
+/*
+ * The VIVT cache of a highmem page is always flushed before the page
+ * is unmapped. Hence unmapped highmem pages need no cache maintenance
+ * in that case.
+ *
+ * However unmapped pages may still be cached with a VIPT cache, and
+ * it is not possible to perform cache maintenance on them using physical
+ * addresses unfortunately.  So we have no choice but to set up a temporary
+ * virtual mapping for that purpose.
+ *
+ * Yet this VIPT cache maintenance may be triggered from DMA support
+ * functions which are possibly called from interrupt context. As we don't
+ * want to keep interrupt disabled all the time when such maintenance is
+ * taking place, we therefore allow for some reentrancy by preserving and
+ * restoring the previous fixmap entry before the interrupted context is
+ * resumed.  If the reentrancy depth is 0 then there is no need to restore
+ * the previous fixmap, and leaving the current one in place allow it to
+ * be reused the next time without a TLB flush (common with DMA).
+ */
+
+static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth);
+
+void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte)
+{
+       unsigned int idx, cpu = smp_processor_id();
+       int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
+       unsigned long vaddr, flags;
+       pte_t pte, *ptep;
+
+       idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
+       vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+       ptep = TOP_PTE(vaddr);
+       pte = mk_pte(page, kmap_prot);
+
+       if (!in_interrupt())
+               preempt_disable();
+
+       raw_local_irq_save(flags);
+       (*depth)++;
+       if (pte_val(*ptep) == pte_val(pte)) {
+               *saved_pte = pte;
+       } else {
+               *saved_pte = *ptep;
+               set_pte_ext(ptep, pte, 0);
+               local_flush_tlb_kernel_page(vaddr);
+       }
+       raw_local_irq_restore(flags);
+
+       return (void *)vaddr;
+}
+
+void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte)
+{
+       unsigned int idx, cpu = smp_processor_id();
+       int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
+       unsigned long vaddr, flags;
+       pte_t pte, *ptep;
+
+       idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
+       vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+       ptep = TOP_PTE(vaddr);
+       pte = mk_pte(page, kmap_prot);
+
+       BUG_ON(pte_val(*ptep) != pte_val(pte));
+       BUG_ON(*depth <= 0);
+
+       raw_local_irq_save(flags);
+       (*depth)--;
+       if (*depth != 0 && pte_val(pte) != pte_val(saved_pte)) {
+               set_pte_ext(ptep, saved_pte, 0);
+               local_flush_tlb_kernel_page(vaddr);
+       }
+       raw_local_irq_restore(flags);
+
+       if (!in_interrupt())
+               preempt_enable();
+}
+
+#endif  /* CONFIG_CPU_CACHE_VIPT */
index 7829cb5425f56e460a62390158114db98f4acc10..0ed29bfeba1cc0d6896fe3877e8653c26d1867f8 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/initrd.h>
 #include <linux/sort.h>
 #include <linux/highmem.h>
+#include <linux/gfp.h>
 
 #include <asm/mach-types.h>
 #include <asm/sections.h>
@@ -85,9 +86,6 @@ void show_mem(void)
        printk("Mem-info:\n");
        show_free_areas();
        for_each_online_node(node) {
-               pg_data_t *n = NODE_DATA(node);
-               struct page *map = pgdat_page_nr(n, 0) - n->node_start_pfn;
-
                for_each_nodebank (i,mi,node) {
                        struct membank *bank = &mi->bank[i];
                        unsigned int pfn1, pfn2;
@@ -96,8 +94,8 @@ void show_mem(void)
                        pfn1 = bank_pfn_start(bank);
                        pfn2 = bank_pfn_end(bank);
 
-                       page = map + pfn1;
-                       end  = map + pfn2;
+                       page = pfn_to_page(pfn1);
+                       end  = pfn_to_page(pfn2 - 1) + 1;
 
                        do {
                                total++;
@@ -602,9 +600,6 @@ void __init mem_init(void)
        reserved_pages = free_pages = 0;
 
        for_each_online_node(node) {
-               pg_data_t *n = NODE_DATA(node);
-               struct page *map = pgdat_page_nr(n, 0) - n->node_start_pfn;
-
                for_each_nodebank(i, &meminfo, node) {
                        struct membank *bank = &meminfo.bank[i];
                        unsigned int pfn1, pfn2;
@@ -613,8 +608,8 @@ void __init mem_init(void)
                        pfn1 = bank_pfn_start(bank);
                        pfn2 = bank_pfn_end(bank);
 
-                       page = map + pfn1;
-                       end  = map + pfn2;
+                       page = pfn_to_page(pfn1);
+                       end  = pfn_to_page(pfn2 - 1) + 1;
 
                        do {
                                if (PageReserved(page))
index 9d4da6ac28ebf9fae8718de70af211beede72156..241c24a1c18f391b6795612786ef6139213b7cbf 100644 (file)
@@ -420,6 +420,10 @@ static void __init build_mem_type_table(void)
                user_pgprot |= L_PTE_SHARED;
                kern_pgprot |= L_PTE_SHARED;
                vecs_pgprot |= L_PTE_SHARED;
+               mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S;
+               mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED;
+               mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
+               mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
                mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
                mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
 #endif
@@ -1050,10 +1054,12 @@ void setup_mm_for_reboot(char mode)
        pgd_t *pgd;
        int i;
 
-       if (current->mm && current->mm->pgd)
-               pgd = current->mm->pgd;
-       else
-               pgd = init_mm.pgd;
+       /*
+        * We need to access to user-mode page tables here. For kernel threads
+        * we don't have any user-mode mappings so we use the context that we
+        * "borrowed".
+        */
+       pgd = current->active_mm->pgd;
 
        base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
        if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
index 9bfeb6b9509ad3480bd33a664e51b4f94311bfbb..33b327379f0756e14eff3d9f0cd23a2f022eb112 100644 (file)
@@ -65,6 +65,15 @@ void flush_dcache_page(struct page *page)
 }
 EXPORT_SYMBOL(flush_dcache_page);
 
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+                      unsigned long uaddr, void *dst, const void *src,
+                      unsigned long len)
+{
+       memcpy(dst, src, len);
+       if (vma->vm_flags & VM_EXEC)
+               __cpuc_coherent_user_range(uaddr, uaddr + len);
+}
+
 void __iomem *__arm_ioremap_pfn(unsigned long pfn, unsigned long offset,
                                size_t size, unsigned int mtype)
 {
@@ -87,8 +96,8 @@ void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size,
 }
 EXPORT_SYMBOL(__arm_ioremap);
 
-void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size,
-                           unsigned int mtype, void *caller)
+void __iomem *__arm_ioremap_caller(unsigned long phys_addr, size_t size,
+                                  unsigned int mtype, void *caller)
 {
        return __arm_ioremap(phys_addr, size, mtype);
 }
index 2690146161ba31e01236f6fe6d90d32e7bc76bf4..be5f58e153bf180d4df1da5037f26652cc7ca2cb 100644 (file)
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/mm.h>
+#include <linux/gfp.h>
 #include <linux/highmem.h>
 
 #include <asm/pgalloc.h>
index ee7700242c19567b94ad256984225c66d5e57872..5c47760c206437c0fbe7219aebae464b19929c7b 100644 (file)
@@ -45,7 +45,7 @@ ENTRY(cpu_sa1100_proc_init)
        mcr     p15, 0, r0, c9, c0, 5           @ Allow read-buffer operations from userland
        mov     pc, lr
 
-       .previous
+       .section .text
 
 /*
  * cpu_sa1100_proc_fin()
index 0cb1848bd876010a850edf2f9831cdf855f01c50..f3f288a9546d2a89f4f6d940c6387062ef8ff143 100644 (file)
@@ -50,7 +50,11 @@ ENTRY(v7wbi_flush_user_tlb_range)
        cmp     r0, r1
        blo     1b
        mov     ip, #0
+#ifdef CONFIG_SMP
+       mcr     p15, 0, ip, c7, c1, 6           @ flush BTAC/BTB Inner Shareable
+#else
        mcr     p15, 0, ip, c7, c5, 6           @ flush BTAC/BTB
+#endif
        dsb
        mov     pc, lr
 ENDPROC(v7wbi_flush_user_tlb_range)
@@ -79,7 +83,11 @@ ENTRY(v7wbi_flush_kern_tlb_range)
        cmp     r0, r1
        blo     1b
        mov     r2, #0
+#ifdef CONFIG_SMP
+       mcr     p15, 0, r2, c7, c1, 6           @ flush BTAC/BTB Inner Shareable
+#else
        mcr     p15, 0, r2, c7, c5, 6           @ flush BTAC/BTB
+#endif
        dsb
        isb
        mov     pc, lr
index 48bca0db4607d97a64b8ca26f75e18efc5d3f252..cafa1835433977808d47ce5900d85bbc19a3ea7f 100644 (file)
@@ -111,12 +111,12 @@ next:
        @ to fault.  Emit the appropriate exception gunk to fix things up.
        @ ??? For some reason, faults can happen at .Lx2 even with a
        @ plain LDR instruction.  Weird, but it seems harmless.
-       .section .fixup,"ax"
+       .pushsection .fixup,"ax"
        .align  2
 .Lfix: mov     pc, r9                  @ let the user eat segfaults
-       .previous
+       .popsection
 
-       .section __ex_table,"a"
+       .pushsection __ex_table,"a"
        .align  3
        .long   .Lx1, .Lfix
-       .previous
+       .popsection
index d983cd6c788cb89bb396785c1eedfd205fa2c5b9..0c2cc5cd4d83ac6ec5129dcba1a896eab8230f00 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include <mach/audmux.h>
 #include <mach/hardware.h>
 
similarity index 93%
rename from arch/arm/plat-mxc/include/mach/board-mx31pdk.h
rename to arch/arm/plat-mxc/include/mach/board-mx31_3ds.h
index 2bbd6ed17f50d0ca5bb5c70836344a054632b243..da92933a233bae5d2f45855df8a1e4d539a8e7b3 100644 (file)
@@ -8,8 +8,8 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef __ASM_ARCH_MXC_BOARD_MX31PDK_H__
-#define __ASM_ARCH_MXC_BOARD_MX31PDK_H__
+#ifndef __ASM_ARCH_MXC_BOARD_MX31_3DS_H__
+#define __ASM_ARCH_MXC_BOARD_MX31_3DS_H__
 
 /* Definitions for components on the Debug board */
 
@@ -56,4 +56,4 @@
 
 #define MXC_MAX_EXP_IO_LINES   16
 
-#endif /* __ASM_ARCH_MXC_BOARD_MX31PDK_H__ */
+#endif /* __ASM_ARCH_MXC_BOARD_MX31_3DS_H__ */
index 07be8ad7ec37b90a322e59e7e6d7af34f04d0b42..7c4870bd5a2144e39697501ce4b85e42e1e36459 100644 (file)
 #define DMA_MODE_WRITE         1
 #define DMA_MODE_MASK          1
 
-#define DMA_BASE IO_ADDRESS(DMA_BASE_ADDR)
+#define MX1_DMA_REG(offset)    MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR + (offset))
+
+/* DMA Interrupt Mask Register */
+#define MX1_DMA_DIMR           MX1_DMA_REG(0x08)
+
+/* Channel Control Register */
+#define MX1_DMA_CCR(x)         MX1_DMA_REG(0x8c + ((x) << 6))
 
 #define IMX_DMA_MEMSIZE_32     (0 << 4)
 #define IMX_DMA_MEMSIZE_8      (1 << 4)
index 771532b6b4a600300900e4403f379b471b16b26f..5aad344d56515c82a1ef7eaf0dd5e9248e15ab7c 100644 (file)
@@ -14,7 +14,7 @@
  * FB100000    70000000        1M      SPBA 0
  * FB000000    73F00000        1M      AIPS 1
  * FB200000    83F00000        1M      AIPS 2
- * FA100000    8FFFC000        16K     TZIC (interrupt controller)
+ *             8FFFC000        16K     TZIC (interrupt controller)
  *             90000000        256M    CSD0 SDRAM/DDR
  *             A0000000        256M    CSD1 SDRAM/DDR
  *             B0000000        128M    CS0 Flash
  *             C8000000        64M     CS3 Flash
  *             CC000000        32M     CS4 SRAM
  *             CE000000        32M     CS5 SRAM
- * F9000000    CFFF0000        64K     NFC (NAND Flash AXI)
+ *             CFFF0000        64K     NFC (NAND Flash AXI)
  *
  */
 
+/*
+ * IROM
+ */
+#define MX51_IROM_BASE_ADDR            0x0
+#define MX51_IROM_SIZE                 SZ_64K
+
 /*
  * IRAM
  */
@@ -40,7 +46,6 @@
  * NFC
  */
 #define MX51_NFC_AXI_BASE_ADDR         0xCFFF0000      /* NAND flash AXI */
-#define MX51_NFC_AXI_BASE_ADDR_VIRT    0xF9000000
 #define MX51_NFC_AXI_SIZE              SZ_64K
 
 /*
@@ -49,9 +54,8 @@
 #define MX51_GPU_BASE_ADDR             0x20000000
 #define MX51_GPU2D_BASE_ADDR           0xD0000000
 
-#define MX51_TZIC_BASE_ADDR            0x8FFFC000
-#define MX51_TZIC_BASE_ADDR_VIRT       0xFA100000
-#define MX51_TZIC_SIZE                 SZ_16K
+#define MX51_TZIC_BASE_ADDR_TO1                0x8FFFC000
+#define MX51_TZIC_BASE_ADDR            0xE0000000
 
 #define MX51_DEBUG_BASE_ADDR           0x60000000
 #define MX51_DEBUG_BASE_ADDR_VIRT      0xFA200000
 #define MX51_IO_ADDRESS(x)                                     \
        (void __iomem *)                                        \
        (MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) :    \
-       MX51_IS_MODULE(x, TZIC) ? MX51_TZIC_IO_ADDRESS(x) :     \
        MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) :   \
        MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) :   \
        MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) :   \
-       MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) :   \
-       MX51_IS_MODULE(x, NFC_AXI) ? MX51_NFC_AXI_IO_ADDRESS(x) : \
+       MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \
        0xDEADBEEF)
 
 /*
 #define MX51_IRAM_IO_ADDRESS(x)  \
        (((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT)
 
-#define MX51_TZIC_IO_ADDRESS(x)  \
-       (((x) - MX51_TZIC_BASE_ADDR) + MX51_TZIC_BASE_ADDR_VIRT)
-
 #define MX51_DEBUG_IO_ADDRESS(x)  \
        (((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT)
 
 #define MX51_AIPS2_IO_ADDRESS(x)  \
        (((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT)
 
-#define MX51_NFC_AXI_IO_ADDRESS(x) \
-       (((x) - MX51_NFC_AXI_BASE_ADDR) + MX51_NFC_AXI_BASE_ADDR_VIRT)
-
 #define MX51_IS_MEM_DEVICE_NONSHARED(x)                0
 
 /*
 
 #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
 
-extern unsigned int system_rev;
-
-static inline unsigned int mx51_revision(void)
-{
-       return system_rev;
-}
+extern int mx51_revision(void);
 #endif
 
 #endif /*  __ASM_ARCH_MXC_MX51_H__ */
index 52e476a150ca5f22caed350304eb481097f66541..b6d3d0fddc48aebb62763c2d364bed0103909063 100644 (file)
@@ -66,6 +66,7 @@ static inline void flush(void)
 #define MX2X_UART1_BASE_ADDR   0x1000a000
 #define MX3X_UART1_BASE_ADDR   0x43F90000
 #define MX3X_UART2_BASE_ADDR   0x43F94000
+#define MX51_UART1_BASE_ADDR   0x73fbc000
 
 static __inline__ void __arch_decomp_setup(unsigned long arch_id)
 {
@@ -101,6 +102,9 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id)
        case MACH_TYPE_MAGX_ZN5:
                uart_base = MX3X_UART2_BASE_ADDR;
                break;
+       case MACH_TYPE_MX51_BABBAGE:
+               uart_base = MX51_UART1_BASE_ADDR;
+               break;
        default:
                break;
        }
index 4ff6dfe0428376a1fdecafb9cb683cab8c53d2bf..c36f2630ed939add19c8afe72afbad86d777487b 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
index 088c1a03b9460124976232751d8ba56e5927214b..f12f0e39ddf2b75a98e887dc170a25ecfee4e22b 100644 (file)
@@ -44,9 +44,6 @@
 
 #define NO_LENGTH_CHECK 0xffffffff
 
-unsigned char omap_bootloader_tag[512];
-int omap_bootloader_tag_len;
-
 struct omap_board_config_kernel *omap_board_config;
 int omap_board_config_size;
 
@@ -100,10 +97,17 @@ EXPORT_SYMBOL(omap_get_var_config);
 
 #include <linux/clocksource.h>
 
+/*
+ * offset_32k holds the init time counter value. It is then subtracted
+ * from every counter read to achieve a counter that counts time from the
+ * kernel boot (needed for sched_clock()).
+ */
+static u32 offset_32k __read_mostly;
+
 #ifdef CONFIG_ARCH_OMAP16XX
 static cycle_t omap16xx_32k_read(struct clocksource *cs)
 {
-       return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED);
+       return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
 }
 #else
 #define omap16xx_32k_read      NULL
@@ -112,7 +116,7 @@ static cycle_t omap16xx_32k_read(struct clocksource *cs)
 #ifdef CONFIG_ARCH_OMAP2420
 static cycle_t omap2420_32k_read(struct clocksource *cs)
 {
-       return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10);
+       return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap2420_32k_read      NULL
@@ -121,7 +125,7 @@ static cycle_t omap2420_32k_read(struct clocksource *cs)
 #ifdef CONFIG_ARCH_OMAP2430
 static cycle_t omap2430_32k_read(struct clocksource *cs)
 {
-       return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10);
+       return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap2430_32k_read      NULL
@@ -130,7 +134,7 @@ static cycle_t omap2430_32k_read(struct clocksource *cs)
 #ifdef CONFIG_ARCH_OMAP3
 static cycle_t omap34xx_32k_read(struct clocksource *cs)
 {
-       return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10);
+       return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap34xx_32k_read      NULL
@@ -139,7 +143,7 @@ static cycle_t omap34xx_32k_read(struct clocksource *cs)
 #ifdef CONFIG_ARCH_OMAP4
 static cycle_t omap44xx_32k_read(struct clocksource *cs)
 {
-       return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10);
+       return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap44xx_32k_read      NULL
@@ -227,6 +231,8 @@ static int __init omap_init_clocksource_32k(void)
                clocksource_32k.mult = clocksource_hz2mult(32768,
                                            clocksource_32k.shift);
 
+               offset_32k = clocksource_32k.read(&clocksource_32k);
+
                if (clocksource_register(&clocksource_32k))
                        printk(err, clocksource_32k.name);
        }
index 4a4cd8774aaa74f440e4d0da6094e9d541d4aff6..95677d17cd1ca02e9626e41e57dae23d16024a7e 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
index 2ab224c8e16c450f6b2bd96fdff71b94aabf864d..1d959965ff524c2325e4d73ce2b1d5180dd4981e 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <mach/hardware.h>
@@ -936,6 +937,15 @@ void omap_start_dma(int lch)
 {
        u32 l;
 
+       /*
+        * The CPC/CDAC register needs to be initialized to zero
+        * before starting dma transfer.
+        */
+       if (cpu_is_omap15xx())
+               dma_write(0, CPC(lch));
+       else
+               dma_write(0, CDAC(lch));
+
        if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
                int next_lch, cur_lch;
                char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
index 337199ed3479db46bd8f44c0e7bf7d547c3f2e88..45a225d09125ca0b7c774d5eebeb4aa022b0fecb 100644 (file)
@@ -798,7 +798,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
        case METHOD_MPUIO:
                reg += OMAP_MPUIO_GPIO_INT_EDGE;
                l = __raw_readl(reg);
-               if (trigger & IRQ_TYPE_EDGE_BOTH)
+               if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
                        bank->toggle_mask |= 1 << gpio;
                if (trigger & IRQ_TYPE_EDGE_RISING)
                        l |= 1 << gpio;
@@ -812,7 +812,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
        case METHOD_GPIO_1510:
                reg += OMAP1510_GPIO_INT_CONTROL;
                l = __raw_readl(reg);
-               if (trigger & IRQ_TYPE_EDGE_BOTH)
+               if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
                        bank->toggle_mask |= 1 << gpio;
                if (trigger & IRQ_TYPE_EDGE_RISING)
                        l |= 1 << gpio;
@@ -846,7 +846,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
        case METHOD_GPIO_7XX:
                reg += OMAP7XX_GPIO_INT_CONTROL;
                l = __raw_readl(reg);
-               if (trigger & IRQ_TYPE_EDGE_BOTH)
+               if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
                        bank->toggle_mask |= 1 << gpio;
                if (trigger & IRQ_TYPE_EDGE_RISING)
                        l |= 1 << gpio;
@@ -2140,18 +2140,18 @@ void omap2_gpio_resume_after_retention(void)
                if (gen) {
                        u32 old0, old1;
 
-                       if (cpu_is_omap24xx() || cpu_is_omap44xx()) {
+                       if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
                                old0 = __raw_readl(bank->base +
                                        OMAP24XX_GPIO_LEVELDETECT0);
                                old1 = __raw_readl(bank->base +
                                        OMAP24XX_GPIO_LEVELDETECT1);
-                       __raw_writel(old0 | gen, bank->base +
+                               __raw_writel(old0 | gen, bank->base +
                                        OMAP24XX_GPIO_LEVELDETECT0);
-                       __raw_writel(old1 | gen, bank->base +
+                               __raw_writel(old1 | gen, bank->base +
                                        OMAP24XX_GPIO_LEVELDETECT1);
-                       __raw_writel(old0, bank->base +
+                               __raw_writel(old0, bank->base +
                                        OMAP24XX_GPIO_LEVELDETECT0);
-                       __raw_writel(old1, bank->base +
+                               __raw_writel(old1, bank->base +
                                        OMAP24XX_GPIO_LEVELDETECT1);
                        }
 
index 8d160f171372501b57175437a61aff498e4b6c9f..56e7f2e7d12feedab90915e9dc8b0e7eed3c063b 100644 (file)
@@ -6,7 +6,7 @@ struct blizzard_platform_data {
        void            (*power_down)(struct device *dev);
        unsigned long   (*get_clock_rate)(struct device *dev);
 
-       unsigned        te_connected : 1;
+       unsigned        te_connected:1;
 };
 
 #endif
index ed8786c41df2fd7543b59b6b8dd3a98e7d34d2d2..75141742300cfaca52494c0b767160d57ad617de 100644 (file)
@@ -167,10 +167,14 @@ IS_OMAP_SUBCLASS(443x, 0x443)
 #if defined(MULTI_OMAP2)
 # if defined(CONFIG_ARCH_OMAP2)
 #  undef  cpu_is_omap24xx
-#  undef  cpu_is_omap242x
-#  undef  cpu_is_omap243x
 #  define cpu_is_omap24xx()            is_omap24xx()
+# endif
+# if defined (CONFIG_ARCH_OMAP2420)
+#  undef  cpu_is_omap242x
 #  define cpu_is_omap242x()            is_omap242x()
+# endif
+# if defined (CONFIG_ARCH_OMAP2430)
+#  undef  cpu_is_omap243x
 #  define cpu_is_omap243x()            is_omap243x()
 # endif
 # if defined(CONFIG_ARCH_OMAP3)
index b65088a869e9ee79a19a031e8d0cc194c4eb9874..401701977dbb8aff2630d1a03b647556ab67a331 100644 (file)
 #define INT_34XX_MMC3_IRQ      94
 #define INT_34XX_GPT12_IRQ     95
 
-#define        INT_34XX_BENCH_MPU_EMUL 3
-
 #define INT_35XX_HECC0_IRQ             24
 #define INT_35XX_HECC1_IRQ             28
 #define INT_35XX_EMAC_C0_RXTHRESH_IRQ  67
index 39748354ce455f9d0f1fcbce915d36cd0758dc13..7de903d7c1ce06d87fd8e41b8bec7744fc35eb3f 100644 (file)
@@ -59,7 +59,7 @@
 #define OMAP44XX_MCBSP1_BASE   0x49022000
 #define OMAP44XX_MCBSP2_BASE   0x49024000
 #define OMAP44XX_MCBSP3_BASE   0x49026000
-#define OMAP44XX_MCBSP4_BASE   0x48074000
+#define OMAP44XX_MCBSP4_BASE   0x48096000
 
 #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
 
index 6ba88d2630d900c082938cec434c826c47720760..f8efd5466b1d07f61e08c7539e0e1e19db2f8ed4 100644 (file)
@@ -29,4 +29,11 @@ struct omap_nand_platform_data {
 /* size (4 KiB) for IO mapping */
 #define        NAND_IO_SIZE    SZ_4K
 
+#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
 extern int gpmc_nand_init(struct omap_nand_platform_data *d);
+#else
+static inline int gpmc_nand_init(struct omap_nand_platform_data *d)
+{
+       return 0;
+}
+#endif
index 2302474a374896c20849ba235c8f6d247cacdb42..b3ef1a7f53cc84f19e3901143fb8e14468db418e 100644 (file)
@@ -32,7 +32,7 @@
 #define OMAP4430_PRM_BASE              0x4a306000
 #define OMAP44XX_GPMC_BASE             0x50000000
 #define OMAP443X_SCM_BASE              0x4a002000
-#define OMAP443X_CTRL_BASE             OMAP443X_SCM_BASE
+#define OMAP443X_CTRL_BASE             0x4a100000
 #define OMAP44XX_IC_BASE               0x48200000
 #define OMAP44XX_IVA_INTC_BASE         0x40000000
 #define IRQ_SIR_IRQ                    0x0040
index 440b4164f2f65e8557713ce9fff2636ed02fe523..36d6ea56ab51267dbb27239dc64c8859f5d4f77e 100644 (file)
@@ -294,8 +294,8 @@ struct omap_hwmod_class_sysconfig {
        u16 rev_offs;
        u16 sysc_offs;
        u16 syss_offs;
+       u16 sysc_flags;
        u8 idlemodes;
-       u8 sysc_flags;
        u8 clockact;
        struct omap_hwmod_sysc_fields *sysc_fields;
 };
index d6a0e27d5a7f4d27ed8a821a603d928670fdce7e..9fbd91419cd15b2849460eed590165e47b820c2a 100644 (file)
@@ -24,7 +24,7 @@
 #define __ASM_ARM_ARCH_OMAP_PRCM_H
 
 u32 omap_prcm_get_reset_sources(void);
-void omap_prcm_arch_reset(char mode);
+void omap_prcm_arch_reset(char mode, const char *cmd);
 int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest,
                         const char *name);
 
index c58a4ef42a4594cee264502035aba26f5103d9c4..d0a119f735b45d3db8e8a2aa7073f41d188a7a6c 100644 (file)
@@ -22,7 +22,7 @@ static inline void arch_idle(void)
        cpu_do_idle();
 }
 
-static inline void omap1_arch_reset(char mode)
+static inline void omap1_arch_reset(char mode, const char *cmd)
 {
        /*
         * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28
@@ -43,9 +43,9 @@ static inline void omap1_arch_reset(char mode)
 static inline void arch_reset(char mode, const char *cmd)
 {
        if (!cpu_class_is_omap2())
-               omap1_arch_reset(mode);
+               omap1_arch_reset(mode, cmd);
        else
-               omap_prcm_arch_reset(mode);
+               omap_prcm_arch_reset(mode, cmd);
 }
 
 #endif
index 288e29e1c06f52f6c187b8681e75ef0586a82306..876ca8d5e927315bcc107a8a766f3d2f89d35878 100644 (file)
@@ -46,14 +46,14 @@ struct ehci_hcd_omap_platform_data {
 struct omap_musb_board_data {
        u8      interface_type;
        u8      mode;
-       u     power;
+       u16     power;
 };
 
 enum musb_interface    {MUSB_INTERFACE_ULPI, MUSB_INTERFACE_UTMI};
 
 extern void usb_musb_init(struct omap_musb_board_data *board_data);
 
-extern void usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata);
+extern void usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata);
 
 #endif
 
index afd1c27cff7c891066e738185e422b50a3df1858..e6c0d536899cb7a697e8db32e55bfa4301c93e53 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/platform_device.h>
 #include <linux/debugfs.h>
index 905ed832df569ad3c33a0fc7f482707def80e9b9..0e137663349ce59d60fe45a6c5b3408da64ffe08 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/err.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/clk.h>
index 936aef1971cd320afd086f099d59a4d0b9958281..65c6d1ff72370c37a9840ff2942f270de08d95f7 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/device.h>
 #include <linux/scatterlist.h>
index 4229cec531406df095055734ef955ae97152fc89..08a2df766289b0fc3af9927ab4ebfa560fee618b 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/device.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <plat/mailbox.h>
 
index e47686e0a63369e816ed965edf153e9667c660de..e1d0440fd4a88470481d163e661cd67ab8c1f309 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <plat/dma.h>
 #include <plat/mcbsp.h>
@@ -133,8 +134,7 @@ static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
                dev_err(mcbsp_tx->dev, "TX Frame Sync Error! : 0x%x\n",
                        irqst_spcr2);
                /* Writing zero to XSYNC_ERR clears the IRQ */
-               MCBSP_WRITE(mcbsp_tx, SPCR2,
-                           MCBSP_READ_CACHE(mcbsp_tx, SPCR2) & ~(XSYNC_ERR));
+               MCBSP_WRITE(mcbsp_tx, SPCR2, MCBSP_READ_CACHE(mcbsp_tx, SPCR2));
        } else {
                complete(&mcbsp_tx->tx_irq_completion);
        }
@@ -154,8 +154,7 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
                dev_err(mcbsp_rx->dev, "RX Frame Sync Error! : 0x%x\n",
                        irqst_spcr1);
                /* Writing zero to RSYNC_ERR clears the IRQ */
-               MCBSP_WRITE(mcbsp_rx, SPCR1,
-                           MCBSP_READ_CACHE(mcbsp_rx, SPCR1) & ~(RSYNC_ERR));
+               MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1));
        } else {
                complete(&mcbsp_rx->tx_irq_completion);
        }
@@ -934,8 +933,7 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
        /* if frame sync error - clear the error */
        if (MCBSP_READ(mcbsp, SPCR2) & XSYNC_ERR) {
                /* clear error */
-               MCBSP_WRITE(mcbsp, SPCR2,
-                               MCBSP_READ_CACHE(mcbsp, SPCR2) & (~XSYNC_ERR));
+               MCBSP_WRITE(mcbsp, SPCR2, MCBSP_READ_CACHE(mcbsp, SPCR2));
                /* resend */
                return -1;
        } else {
@@ -975,8 +973,7 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf)
        /* if frame sync error - clear the error */
        if (MCBSP_READ(mcbsp, SPCR1) & RSYNC_ERR) {
                /* clear error */
-               MCBSP_WRITE(mcbsp, SPCR1,
-                               MCBSP_READ_CACHE(mcbsp, SPCR1) & (~RSYNC_ERR));
+               MCBSP_WRITE(mcbsp, SPCR1, MCBSP_READ_CACHE(mcbsp, SPCR1));
                /* resend */
                return -1;
        } else {
index 590435894848e63c78a906d943bde61c72243cca..0f5197479513cff513b25cb49d2979aaee452d76 100644 (file)
@@ -79,6 +79,7 @@
 
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/io.h>
 
index 2975798d411fdbfc48021c4626d3593a69056dc7..2d3c19d7c7b1cd69a29c1796a913ee6e5a681c0c 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
@@ -244,7 +245,7 @@ static void pxa_dma_init_debugfs(void)
 
        dbgfs_chan = kmalloc(sizeof(*dbgfs_state) * num_dma_channels,
                             GFP_KERNEL);
-       if (!dbgfs_state)
+       if (!dbgfs_chan)
                goto err_alloc;
 
        chandir = debugfs_create_dir("channels", dbgfs_root);
index 51dc5c8106c0cc84dd38aa89faf176f46303f019..0732c6c8d511979e354cced2cd6987889702a1e7 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
index 2d42efb9f4e9facbc92c559d9605a04aa8b367f3..1ecc15bfe9d40b44a7d6225ba1b413640da2f460 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/sysdev.h>
 #include <linux/kobject.h>
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
index 8c6de1c9968f4bf22eb2ac78e3d0c676b1c8b8e1..9265f09bfa58e6b005f73fa0c9cf39dc11ec310e 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
index 963fb0b4379ec4f623050d6463945838c654a158..b1908e56da1b2cfea948efd8ab6e2db746802a71 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/cpufreq.h>
 #include <linux/seq_file.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/map.h>
 #include <mach/regs-mem.h>
index 24993dce10b51eafe1cd64b9b813dd72a09d6e4a..0b46d3895d62b9756a39b925fcb920b584185962 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <linux/amba/pl093.h>
 
index 0b5833b9ac5bcd9aad629b9a93209a58b848efbf..210030d5cfe13e3761e99f19732ab9a3b97a893c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/sched.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/interrupt.h>
index a90198fc4b0f3d31312c3314e4ffaed4186bf3e4..002a15f313f30bb7e1e798d78b60a287578b574e 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/string.h>
 #include <linux/platform_device.h>
 #include <linux/fb.h>
+#include <linux/gfp.h>
 
 #include <mach/irqs.h>
 #include <mach/map.h>
index 4c761529b949d02882d5cacfebca6841ac807891..3a601c16f03c78c4a40dcd81c70d24b503204c09 100644 (file)
@@ -11,6 +11,7 @@
  * published by the Free Software Foundation.
 */
 
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/platform_device.h>
index d44f79110506494fe37cda5575dd9d0a67f1ac45..858ee2a0414c57154129cbb07bb06ccd2aa9121c 100644 (file)
@@ -11,6 +11,7 @@
  * published by the Free Software Foundation.
 */
 
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/platform_device.h>
index a52fb6cf618fb93e77e1aae7a37a14a55efede77..3a7b8891ba4f54ee9c76133e00e14d4893a419bd 100644 (file)
@@ -6,6 +6,7 @@
  * published by the Free Software Foundation.
 */
 
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 
index 88165657fa5367ade7663cf786b7831a5dfe5719..0e0a3bf5c982121ea08021db043dccfaf7b7d3c1 100644 (file)
@@ -11,6 +11,7 @@
  * published by the Free Software Foundation.
 */
 
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/platform_device.h>
index e87ce8ffbbcdac18833d19aa98a253832a1ae6e4..7d6ed7263d578a70326a32961bcfdfd3125fa1e6 100644 (file)
@@ -140,8 +140,6 @@ static void arch_decomp_error(const char *x)
 #define arch_error arch_decomp_error
 #endif
 
-static void error(char *err);
-
 #ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO
 static inline void arch_enable_uart_fifo(void)
 {
index 0b5bb774192a59eef8c1af6c040a94ffd51296f6..e4baf76f374ada34260e37dc88916207ad75abf2 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/crc32.h>
 #include <linux/ioport.h>
+#include <linux/slab.h>
 
 #include <plat/pm.h>
 
index ef019f27b67d5822afc8c3e4fbdac17220eebbd6..2eeb49fa056d6413c1963abc6113fa0eff76caf8 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
@@ -379,6 +380,39 @@ static int __devexit s3c_pwm_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct pwm_device *pwm = platform_get_drvdata(pdev);
+
+       /* No one preserve these values during suspend so reset them
+        * Otherwise driver leaves PWM unconfigured if same values
+        * passed to pwm_config
+        */
+       pwm->period_ns = 0;
+       pwm->duty_ns = 0;
+
+       return 0;
+}
+
+static int s3c_pwm_resume(struct platform_device *pdev)
+{
+       struct pwm_device *pwm = platform_get_drvdata(pdev);
+       unsigned long tcon;
+
+       /* Restore invertion */
+       tcon = __raw_readl(S3C2410_TCON);
+       tcon |= pwm_tcon_invert(pwm);
+       __raw_writel(tcon, S3C2410_TCON);
+
+       return 0;
+}
+
+#else
+#define s3c_pwm_suspend NULL
+#define s3c_pwm_resume NULL
+#endif
+
 static struct platform_driver s3c_pwm_driver = {
        .driver         = {
                .name   = "s3c24xx-pwm",
@@ -386,6 +420,8 @@ static struct platform_driver s3c_pwm_driver = {
        },
        .probe          = s3c_pwm_probe,
        .remove         = __devexit_p(s3c_pwm_remove),
+       .suspend        = s3c_pwm_suspend,
+       .resume         = s3c_pwm_resume,
 };
 
 static int __init pwm_init(void)
index ef88f25fb870edac8424254161232da10f86fac2..b4dcf8c0477d9ef95a44a50d0848a6ebb12ae60b 100644 (file)
@@ -15,6 +15,7 @@
  * http://www.opensource.org/licenses/gpl-license.html
  * http://www.gnu.org/copyleft/gpl.html
  */
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/dmapool.h>
index 31c2f4c30a95b94631bc9e9568247e644b9d0eb2..8f10d24ae62540c5460eaf4b8e249c6ccd4ceac8 100644 (file)
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Sat Feb 20 14:16:15 2010
+# Last update: Sat May 1 10:36:42 2010
 #
 # machine_is_xxx       CONFIG_xxxx             MACH_TYPE_xxx           number
 #
@@ -2663,7 +2663,7 @@ reb01                     MACH_REB01              REB01                   2675
 aquila                 MACH_AQUILA             AQUILA                  2676
 spark_sls_hw2          MACH_SPARK_SLS_HW2      SPARK_SLS_HW2           2677
 sheeva_esata           MACH_ESATA_SHEEVAPLUG   ESATA_SHEEVAPLUG        2678
-surf7x30               MACH_SURF7X30           SURF7X30                2679
+msm7x30_surf           MACH_MSM7X30_SURF       MSM7X30_SURF            2679
 micro2440              MACH_MICRO2440          MICRO2440               2680
 am2440                 MACH_AM2440             AM2440                  2681
 tq2440                 MACH_TQ2440             TQ2440                  2682
@@ -2678,3 +2678,129 @@ vc088x                  MACH_VC088X             VC088X                  2690
 mioa702                        MACH_MIOA702            MIOA702                 2691
 hpmin                  MACH_HPMIN              HPMIN                   2692
 ak880xak               MACH_AK880XAK           AK880XAK                2693
+arm926tomap850         MACH_ARM926TOMAP850     ARM926TOMAP850          2694
+lkevm                  MACH_LKEVM              LKEVM                   2695
+mw6410                 MACH_MW6410             MW6410                  2696
+terastation_wxl                MACH_TERASTATION_WXL    TERASTATION_WXL         2697
+cpu8000e               MACH_CPU8000E           CPU8000E                2698
+catania                        MACH_CATANIA            CATANIA                 2699
+tokyo                  MACH_TOKYO              TOKYO                   2700
+msm7201a_surf          MACH_MSM7201A_SURF      MSM7201A_SURF           2701
+msm7201a_ffa           MACH_MSM7201A_FFA       MSM7201A_FFA            2702
+msm7x25_surf           MACH_MSM7X25_SURF       MSM7X25_SURF            2703
+msm7x25_ffa            MACH_MSM7X25_FFA        MSM7X25_FFA             2704
+msm7x27_surf           MACH_MSM7X27_SURF       MSM7X27_SURF            2705
+msm7x27_ffa            MACH_MSM7X27_FFA        MSM7X27_FFA             2706
+msm7x30_ffa            MACH_MSM7X30_FFA        MSM7X30_FFA             2707
+qsd8x50_surf           MACH_QSD8X50_SURF       QSD8X50_SURF            2708
+qsd8x50_comet          MACH_QSD8X50_COMET      QSD8X50_COMET           2709
+qsd8x50_ffa            MACH_QSD8X50_FFA        QSD8X50_FFA             2710
+qsd8x50a_surf          MACH_QSD8X50A_SURF      QSD8X50A_SURF           2711
+qsd8x50a_ffa           MACH_QSD8X50A_FFA       QSD8X50A_FFA            2712
+adx_xgcp10             MACH_ADX_XGCP10         ADX_XGCP10              2713
+mcgwumts2a             MACH_MCGWUMTS2A         MCGWUMTS2A              2714
+mobikt                 MACH_MOBIKT             MOBIKT                  2715
+mx53_evk               MACH_MX53_EVK           MX53_EVK                2716
+igep0030               MACH_IGEP0030           IGEP0030                2717
+axell_h40_h50_ctrl     MACH_AXELL_H40_H50_CTRL AXELL_H40_H50_CTRL      2718
+dtcommod               MACH_DTCOMMOD           DTCOMMOD                2719
+gould                  MACH_GOULD              GOULD                   2720
+siberia                        MACH_SIBERIA            SIBERIA                 2721
+sbc3530                        MACH_SBC3530            SBC3530                 2722
+qarm                   MACH_QARM               QARM                    2723
+mips                   MACH_MIPS               MIPS                    2724
+mx27grb                        MACH_MX27GRB            MX27GRB                 2725
+sbc8100                        MACH_SBC8100            SBC8100                 2726
+saarb                  MACH_SAARB              SAARB                   2727
+omap3mini              MACH_OMAP3MINI          OMAP3MINI               2728
+cnmbook7se             MACH_CNMBOOK7SE         CNMBOOK7SE              2729
+catan                  MACH_CATAN              CATAN                   2730
+harmony                        MACH_HARMONY            HARMONY                 2731
+tonga                  MACH_TONGA              TONGA                   2732
+cybook_orizon          MACH_CYBOOK_ORIZON      CYBOOK_ORIZON           2733
+htcrhodiumcdma         MACH_HTCRHODIUMCDMA     HTCRHODIUMCDMA          2734
+epc_g45                        MACH_EPC_G45            EPC_G45                 2735
+epc_lpc3250            MACH_EPC_LPC3250        EPC_LPC3250             2736
+mxc91341evb            MACH_MXC91341EVB        MXC91341EVB             2737
+rtw1000                        MACH_RTW1000            RTW1000                 2738
+bobcat                 MACH_BOBCAT             BOBCAT                  2739
+trizeps6               MACH_TRIZEPS6           TRIZEPS6                2740
+msm7x30_fluid          MACH_MSM7X30_FLUID      MSM7X30_FLUID           2741
+nedap9263              MACH_NEDAP9263          NEDAP9263               2742
+netgear_ms2110         MACH_NETGEAR_MS2110     NETGEAR_MS2110          2743
+bmx                    MACH_BMX                BMX                     2744
+netstream              MACH_NETSTREAM          NETSTREAM               2745
+vpnext_rcu             MACH_VPNEXT_RCU         VPNEXT_RCU              2746
+vpnext_mpu             MACH_VPNEXT_MPU         VPNEXT_MPU              2747
+bcmring_tablet_v1      MACH_BCMRING_TABLET_V1  BCMRING_TABLET_V1       2748
+sgarm10                        MACH_SGARM10            SGARM10                 2749
+cm_t3517               MACH_CM_T3517           CM_T3517                2750
+omap3_cps              MACH_OMAP3_CPS          OMAP3_CPS               2751
+axar1500_receiver      MACH_AXAR1500_RECEIVER  AXAR1500_RECEIVER       2752
+wbd222                 MACH_WBD222             WBD222                  2753
+mt65xx                 MACH_MT65XX             MT65XX                  2754
+msm8x60_surf           MACH_MSM8X60_SURF       MSM8X60_SURF            2755
+msm8x60_sim            MACH_MSM8X60_SIM        MSM8X60_SIM             2756
+vmc300                 MACH_VMC300             VMC300                  2757
+tcc8000_sdk            MACH_TCC8000_SDK        TCC8000_SDK             2758
+nanos                  MACH_NANOS              NANOS                   2759
+stamp9g10              MACH_STAMP9G10          STAMP9G10               2760
+stamp9g45              MACH_STAMP9G45          STAMP9G45               2761
+h6053                  MACH_H6053              H6053                   2762
+smint01                        MACH_SMINT01            SMINT01                 2763
+prtlvt2                        MACH_PRTLVT2            PRTLVT2                 2764
+ap420                  MACH_AP420              AP420                   2765
+htcshift               MACH_HTCSHIFT           HTCSHIFT                2766
+davinci_dm365_fc       MACH_DAVINCI_DM365_FC   DAVINCI_DM365_FC        2767
+msm8x55_surf           MACH_MSM8X55_SURF       MSM8X55_SURF            2768
+msm8x55_ffa            MACH_MSM8X55_FFA        MSM8X55_FFA             2769
+esl_vamana             MACH_ESL_VAMANA         ESL_VAMANA              2770
+sbc35                  MACH_SBC35              SBC35                   2771
+mpx6446                        MACH_MPX6446            MPX6446                 2772
+oreo_controller                MACH_OREO_CONTROLLER    OREO_CONTROLLER         2773
+kopin_models           MACH_KOPIN_MODELS       KOPIN_MODELS            2774
+ttc_vision2            MACH_TTC_VISION2        TTC_VISION2             2775
+cns3420vb              MACH_CNS3420VB          CNS3420VB               2776
+lpc2                   MACH_LPC2               LPC2                    2777
+olympus                        MACH_OLYMPUS            OLYMPUS                 2778
+vortex                 MACH_VORTEX             VORTEX                  2779
+s5pc200                        MACH_S5PC200            S5PC200                 2780
+ecucore_9263           MACH_ECUCORE_9263       ECUCORE_9263            2781
+smdkc200               MACH_SMDKC200           SMDKC200                2782
+emsiso_sx27            MACH_EMSISO_SX27        EMSISO_SX27             2783
+apx_som9g45_ek         MACH_APX_SOM9G45_EK     APX_SOM9G45_EK          2784
+songshan               MACH_SONGSHAN           SONGSHAN                2785
+tianshan               MACH_TIANSHAN           TIANSHAN                2786
+vpx500                 MACH_VPX500             VPX500                  2787
+am3517sam              MACH_AM3517SAM          AM3517SAM               2788
+skat91_sim508          MACH_SKAT91_SIM508      SKAT91_SIM508           2789
+skat91_s3e             MACH_SKAT91_S3E         SKAT91_S3E              2790
+omap4_panda            MACH_OMAP4_PANDA        OMAP4_PANDA             2791
+df7220                 MACH_DF7220             DF7220                  2792
+nemini                 MACH_NEMINI             NEMINI                  2793
+t8200                  MACH_T8200              T8200                   2794
+apf51                  MACH_APF51              APF51                   2795
+dr_rc_unit             MACH_DR_RC_UNIT         DR_RC_UNIT              2796
+bordeaux               MACH_BORDEAUX           BORDEAUX                2797
+catania_b              MACH_CATANIA_B          CATANIA_B               2798
+mx51_ocean             MACH_MX51_OCEAN         MX51_OCEAN              2799
+ti8168evm              MACH_TI8168EVM          TI8168EVM               2800
+neocoreomap            MACH_NEOCOREOMAP        NEOCOREOMAP             2801
+withings_wbp           MACH_WITHINGS_WBP       WITHINGS_WBP            2802
+dbps                   MACH_DBPS               DBPS                    2803
+sbc9261                        MACH_SBC9261            SBC9261                 2804
+pcbfp0001              MACH_PCBFP0001          PCBFP0001               2805
+speedy                 MACH_SPEEDY             SPEEDY                  2806
+chrysaor               MACH_CHRYSAOR           CHRYSAOR                2807
+tango                  MACH_TANGO              TANGO                   2808
+synology_dsx11         MACH_SYNOLOGY_DSX11     SYNOLOGY_DSX11          2809
+hanlin_v3ext           MACH_HANLIN_V3EXT       HANLIN_V3EXT            2810
+hanlin_v5              MACH_HANLIN_V5          HANLIN_V5               2811
+hanlin_v3plus          MACH_HANLIN_V3PLUS      HANLIN_V3PLUS           2812
+iriver_story           MACH_IRIVER_STORY       IRIVER_STORY            2813
+irex_iliad             MACH_IREX_ILIAD         IREX_ILIAD              2814
+irex_dr1000            MACH_IREX_DR1000        IREX_DR1000             2815
+teton_bga              MACH_TETON_BGA          TETON_BGA               2816
+snapper9g45            MACH_SNAPPER9G45        SNAPPER9G45             2817
+tam3517                        MACH_TAM3517            TAM3517                 2818
+pdc100                 MACH_PDC100             PDC100                  2819
index 7f3f59fcaa2199dda10eebd5b7bfa62348643342..315a540c7ce50370757320350ed07322d0f3bd86 100644 (file)
@@ -428,26 +428,6 @@ static void vfp_pm_init(void)
 static inline void vfp_pm_init(void) { }
 #endif /* CONFIG_PM */
 
-/*
- * Synchronise the hardware VFP state of a thread other than current with the
- * saved one. This function is used by the ptrace mechanism.
- */
-#ifdef CONFIG_SMP
-void vfp_sync_hwstate(struct thread_info *thread)
-{
-}
-
-void vfp_flush_hwstate(struct thread_info *thread)
-{
-       /*
-        * On SMP systems, the VFP state is automatically saved at every
-        * context switch. We mark the thread VFP state as belonging to a
-        * non-existent CPU so that the saved one will be reloaded when
-        * needed.
-        */
-       thread->vfpstate.hard.cpu = NR_CPUS;
-}
-#else
 void vfp_sync_hwstate(struct thread_info *thread)
 {
        unsigned int cpu = get_cpu();
@@ -490,9 +470,18 @@ void vfp_flush_hwstate(struct thread_info *thread)
                last_VFP_context[cpu] = NULL;
        }
 
+#ifdef CONFIG_SMP
+       /*
+        * For SMP we still have to take care of the case where the thread
+        * migrates to another CPU and then back to the original CPU on which
+        * the last VFP user is still the same thread. Mark the thread VFP
+        * state as belonging to a non-existent CPU so that the saved one will
+        * be reloaded in the above case.
+        */
+       thread->vfpstate.hard.cpu = NR_CPUS;
+#endif
        put_cpu();
 }
-#endif
 
 #include <linux/smp.h>
 
@@ -545,7 +534,7 @@ static int __init vfp_init(void)
                 */
                elf_hwcap |= HWCAP_VFP;
 #ifdef CONFIG_VFPv3
-               if (VFP_arch >= 3) {
+               if (VFP_arch >= 2) {
                        elf_hwcap |= HWCAP_VFPv3;
 
                        /*
index b131c27ddf5785883a1c28a3078cf6f1bd5a5c0e..bbce6a1c6bb67b873918a32fc68e9a6ea1e5890b 100644 (file)
@@ -19,7 +19,7 @@
 
 #define ATOMIC_INIT(i)  { (i) }
 
-#define atomic_read(v)         ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
 #define atomic_set(v, i)       (((v)->counter) = i)
 
 /*
index 93c0342530a0d02beb47f61f8e7e8a260fe67764..2d76515745a4f0edf28f7a09a53cfca093da4bda 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/fs.h>
 #include <linux/pm.h>
 #include <linux/ptrace.h>
+#include <linux/slab.h>
 #include <linux/reboot.h>
 #include <linux/tick.h>
 #include <linux/uaccess.h>
index dd5b882aab408fb9433ab6571139056f198f2810..5e73c25f8f85b2165652b30555c07813accfb0d1 100644 (file)
@@ -28,7 +28,7 @@ static struct pt_regs *get_user_regs(struct task_struct *tsk)
                                  THREAD_SIZE - sizeof(struct pt_regs));
 }
 
-static void user_enable_single_step(struct task_struct *tsk)
+void user_enable_single_step(struct task_struct *tsk)
 {
        pr_debug("user_enable_single_step: pid=%u, PC=0x%08lx, SR=0x%08lx\n",
                 tsk->pid, task_pt_regs(tsk)->pc, task_pt_regs(tsk)->sr);
index 3a4bc1a18433ff52ac5ba10565f70abee1b38028..e67c999454284f46dee1c3ba0742cbbe0221ba23 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/usb/atmel_usba_udc.h>
index 310477ba1bbf170a47af4e68bfc4bfa26d836a8d..e9d12058ffd379287bd4044e522a6a6736dd727c 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/irq.h>
 #include <linux/platform_device.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
index 2875c11be95d5f232d2970e204695fbc83a526d3..f7672d3e86b842b56e74cad31a4892ba42d05e2f 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <mach/smc.h>
index 6d8c794c3b81bbd528f170c9dba7fa46e50c525c..3c0042247ea93661adbf504237be51e3d7730cec 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <asm/addrspace.h>
 #include <asm/cacheflush.h>
index 94925641e53e64fbb87b2754b5d927be00a8b3ac..a7314d44b17ba5a2afd1bd83b3edaf8cea222c33 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
 #include <linux/init.h>
index f03b79f0e0ab0a75f631e7886ad41a7a855c518d..7def0d84cec63a763e219b53faad1f88b06b65ac 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/pgtable.h>
 #include <asm/addrspace.h>
index 53c1e1d45c684ee7f3d0d7ee7ada40c4be5780a4..c078849df7f9712349e0e5c1f721d977953f8e3f 100644 (file)
@@ -23,12 +23,15 @@ config RWSEM_XCHGADD_ALGORITHM
 
 config BLACKFIN
        def_bool y
+       select HAVE_ARCH_KGDB
+       select HAVE_ARCH_TRACEHOOK
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_FUNCTION_TRACER
+       select HAVE_FUNCTION_TRACE_MCOUNT_TEST
        select HAVE_IDE
-       select HAVE_KERNEL_GZIP
-       select HAVE_KERNEL_BZIP2
-       select HAVE_KERNEL_LZMA
+       select HAVE_KERNEL_GZIP if RAMKERNEL
+       select HAVE_KERNEL_BZIP2 if RAMKERNEL
+       select HAVE_KERNEL_LZMA if RAMKERNEL
        select HAVE_OPROFILE
        select ARCH_WANT_OPTIONAL_GPIOLIB
 
@@ -45,9 +48,6 @@ config ZONE_DMA
 config GENERIC_FIND_NEXT_BIT
        def_bool y
 
-config GENERIC_HWEIGHT
-       def_bool y
-
 config GENERIC_HARDIRQS
        def_bool y
 
@@ -239,7 +239,7 @@ endchoice
 
 config SMP
        depends on BF561
-       select GENERIC_CLOCKEVENTS
+       select TICKSOURCE_CORETMR
        bool "Symmetric multi-processing support"
        ---help---
          This enables support for systems with more than one CPU,
@@ -253,11 +253,20 @@ config NR_CPUS
        depends on SMP
        default 2 if BF561
 
+config HOTPLUG_CPU
+       bool "Support for hot-pluggable CPUs"
+       depends on SMP && HOTPLUG
+       default y
+
 config IRQ_PER_CPU
        bool
        depends on SMP
        default y
 
+config HAVE_LEGACY_PER_CPU_AREA
+       def_bool y
+       depends on SMP
+
 config BF_REV_MIN
        int
        default 0 if (BF51x || BF52x || (BF54x && !BF54xM))
@@ -349,7 +358,7 @@ config MEM_MT48LC8M32B2B5_7
 
 config MEM_MT48LC32M16A2TG_75
        bool
-       depends on (BFIN527_EZKIT || BFIN532_IP0X || BLACKSTAMP)
+       depends on (BFIN527_EZKIT || BFIN527_EZKIT_V2 || BFIN532_IP0X || BLACKSTAMP)
        default y
 
 config MEM_MT48LC32M8A2_75
@@ -401,10 +410,18 @@ config BOOT_LOAD
 config ROM_BASE
        hex "Kernel ROM Base"
        depends on ROMKERNEL
-       default "0x20040000"
+       default "0x20040040"
        range 0x20000000 0x20400000 if !(BF54x || BF561)
        range 0x20000000 0x30000000 if (BF54x || BF561)
        help
+         Make sure your ROM base does not include any file-header
+         information that is prepended to the kernel.
+
+         For example, the bootable U-Boot format (created with
+         mkimage) has a 64 byte header (0x40).  So while the image
+         you write to flash might start at say 0x20080000, you have
+         to add 0x40 to get the kernel's ROM base as it will come
+         after the header.
 
 comment "Clock/PLL Setup"
 
@@ -448,7 +465,7 @@ config VCO_MULT
        range 1 64
        default "22" if BFIN533_EZKIT
        default "45" if BFIN533_STAMP
-       default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM || BFIN538_EZKIT)
+       default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN527_EZKIT_V2 || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM || BFIN538_EZKIT)
        default "22" if BFIN533_BLUETECHNIX_CM
        default "20" if (BFIN537_BLUETECHNIX_CM_E || BFIN537_BLUETECHNIX_CM_U || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM)
        default "20" if BFIN561_EZKIT
@@ -609,23 +626,23 @@ config GENERIC_CLOCKEVENTS
        bool "Generic clock events"
        default y
 
-choice
-       prompt "Kernel Tick Source"
+menu "Clock event device"
        depends on GENERIC_CLOCKEVENTS
-       default TICKSOURCE_CORETMR
-
 config TICKSOURCE_GPTMR0
-       bool "Gptimer0 (SCLK domain)"
+       bool "GPTimer0"
+       depends on !SMP
        select BFIN_GPTIMERS
 
 config TICKSOURCE_CORETMR
-       bool "Core timer (CCLK domain)"
-
-endchoice
+       bool "Core timer"
+       default y
+endmenu
 
-config CYCLES_CLOCKSOURCE
-       bool "Use 'CYCLES' as a clocksource"
+menu "Clock souce"
        depends on GENERIC_CLOCKEVENTS
+config CYCLES_CLOCKSOURCE
+       bool "CYCLES"
+       default y
        depends on !BFIN_SCRATCH_REG_CYCLES
        depends on !SMP
        help
@@ -636,10 +653,10 @@ config CYCLES_CLOCKSOURCE
          writing the registers will most likely crash the kernel.
 
 config GPTMR0_CLOCKSOURCE
-       bool "Use GPTimer0 as a clocksource"
+       bool "GPTimer0"
        select BFIN_GPTIMERS
-       depends on GENERIC_CLOCKEVENTS
        depends on !TICKSOURCE_GPTMR0
+endmenu
 
 config ARCH_USES_GETTIMEOFFSET
        depends on !GENERIC_CLOCKEVENTS
@@ -1116,24 +1133,6 @@ config PCI
 
 source "drivers/pci/Kconfig"
 
-config HOTPLUG
-       bool "Support for hot-pluggable device"
-         help
-         Say Y here if you want to plug devices into your computer while
-         the system is running, and be able to use them quickly.  In many
-         cases, the devices can likewise be unplugged at any time too.
-
-         One well known example of this is PCMCIA- or PC-cards, credit-card
-         size devices such as network cards, modems or hard drives which are
-         plugged into slots found on all modern laptop computers.  Another
-         example, used on modern desktops as well as laptops, is USB.
-
-         Enable HOTPLUG and build a modular kernel.  Get agent software
-         (from <http://linux-hotplug.sourceforge.net/>) and install it.
-         Then your kernel will automatically call out to a user mode "policy
-         agent" (/sbin/hotplug) to load modules and set up software needed
-         to use devices as you hotplug them.
-
 source "drivers/pcmcia/Kconfig"
 
 source "drivers/pci/hotplug/Kconfig"
@@ -1147,7 +1146,6 @@ source "fs/Kconfig.binfmt"
 endmenu
 
 menu "Power management options"
-       depends on !SMP
 
 source "kernel/power/Kconfig"
 
@@ -1240,7 +1238,6 @@ config PM_BFIN_WAKE_GP
 endmenu
 
 menu "CPU Frequency scaling"
-       depends on !SMP
 
 source "drivers/cpufreq/Kconfig"
 
index 87f195ee2e06234e50399566b25243e8ca821bda..aec89a5280b2249ef8890c14ddd96918de36838b 100644 (file)
@@ -18,9 +18,6 @@ config DEBUG_STACK_USAGE
 
          This option will slow down process creation somewhat.
 
-config HAVE_ARCH_KGDB
-       def_bool y
-
 config DEBUG_VERBOSE
        bool "Verbose fault messages"
        default y
@@ -238,6 +235,15 @@ config EARLY_PRINTK
          all of this lives in the init section and is thrown away after the
          kernel boots completely.
 
+config NMI_WATCHDOG
+       bool "Enable NMI watchdog to help debugging lockup on SMP"
+       default n
+       depends on (SMP && !BFIN_SCRATCH_REG_RETN)
+       help
+         If any CPU in the system does not execute the period local timer
+         interrupt for more than 5 seconds, then the NMI handler dumps debug
+         information. This information can be used to debug the lockup.
+
 config CPLB_INFO
        bool "Display the CPLB information"
        help
index d4c7177e765649ec558db90bdc8a0ee1198ebf5b..5a97a31d4bbd55f7d16b1f3e78def86a19a66906 100644 (file)
@@ -14,6 +14,9 @@ OBJCOPYFLAGS     := -O binary -R .note -R .comment -S
 GZFLAGS          := -9
 
 KBUILD_CFLAGS           += $(call cc-option,-mno-fdpic)
+ifeq ($(CONFIG_ROMKERNEL),y)
+KBUILD_CFLAGS           += -mlong-calls
+endif
 KBUILD_AFLAGS           += $(call cc-option,-mno-fdpic)
 CFLAGS_MODULE    += -mlong-calls
 LDFLAGS_MODULE   += -m elf32bfin
@@ -130,7 +133,6 @@ KBUILD_CFLAGS += -Iarch/$(ARCH)/mach-$(MACHINE)/include
 KBUILD_CPPFLAGS        += $(patsubst %,-I$(srctree)/%include,$(machdirs))
 
 CLEAN_FILES += \
-       arch/$(ARCH)/include/asm/asm-offsets.h \
        arch/$(ARCH)/kernel/asm-offsets.s \
 
 archclean:
@@ -138,7 +140,7 @@ archclean:
 
 INSTALL_PATH ?= /tftpboot
 boot := arch/$(ARCH)/boot
-BOOT_TARGETS = vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma
+BOOT_TARGETS = vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma vmImage.xip
 PHONY += $(BOOT_TARGETS) install
 KBUILD_IMAGE := $(boot)/vmImage
 
@@ -156,6 +158,7 @@ define archhelp
   echo  '  vmImage.bz2     - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.bz2)'
   echo  '* vmImage.gz      - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.gz)'
   echo  '  vmImage.lzma    - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.lzma)'
+  echo  '  vmImage.xip     - XIP Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.xip)'
   echo  '  install         - Install kernel using'
   echo  '                     (your) ~/bin/$(INSTALLKERNEL) or'
   echo  '                     (distribution) PATH: $(INSTALLKERNEL) or'
index e9c48c6f8c1f5dbc633c26b03df394c7aec5560e..d1b3d6051fdfaf4a43f7cb72392c49787d634719 100644 (file)
@@ -8,14 +8,18 @@
 
 MKIMAGE := $(srctree)/scripts/mkuboot.sh
 
-targets := vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma
-extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma
+targets := vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma vmImage.xip
+extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.xip
+
+UIMAGE_OPTS-y :=
+UIMAGE_OPTS-$(CONFIG_RAMKERNEL) += -a $(CONFIG_BOOT_LOAD)
+UIMAGE_OPTS-$(CONFIG_ROMKERNEL) += -a $(CONFIG_ROM_BASE) -x
 
 quiet_cmd_uimage = UIMAGE  $@
       cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \
-                   -C $(2) -n '$(MACHINE)-$(KERNELRELEASE)' -a $(CONFIG_BOOT_LOAD) \
+                   -C $(2) -n '$(MACHINE)-$(KERNELRELEASE)' \
                    -e $(shell $(NM) vmlinux | awk '$$NF == "__start" {print $$1}') \
-                   -d $< $@
+                   $(UIMAGE_OPTS-y) -d $< $@
 
 $(obj)/vmlinux.bin: vmlinux FORCE
        $(call if_changed,objcopy)
@@ -29,6 +33,12 @@ $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
 $(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
        $(call if_changed,lzma)
 
+# The mkimage tool wants 64bytes prepended to the image
+quiet_cmd_mk_bin_xip = BIN     $@
+      cmd_mk_bin_xip = ( printf '%64s' | tr ' ' '\377' ; cat $< ) > $@
+$(obj)/vmlinux.bin.xip: $(obj)/vmlinux.bin FORCE
+       $(call if_changed,mk_bin_xip)
+
 $(obj)/vmImage.bin: $(obj)/vmlinux.bin
        $(call if_changed,uimage,none)
 
@@ -41,10 +51,15 @@ $(obj)/vmImage.gz: $(obj)/vmlinux.bin.gz
 $(obj)/vmImage.lzma: $(obj)/vmlinux.bin.lzma
        $(call if_changed,uimage,lzma)
 
+$(obj)/vmImage.xip: $(obj)/vmlinux.bin.xip
+       $(call if_changed,uimage,none)
+
 suffix-y                      := bin
 suffix-$(CONFIG_KERNEL_GZIP)  := gz
 suffix-$(CONFIG_KERNEL_BZIP2) := bz2
 suffix-$(CONFIG_KERNEL_LZMA)  := lzma
+suffix-$(CONFIG_ROMKERNEL)    := xip
+
 $(obj)/vmImage: $(obj)/vmImage.$(suffix-y)
        @ln -sf $(notdir $<) $@
 
index e31559419817336aa219d9ecc9154953ad6954f0..cf7c9bc94f1377ad8a1e53be9c063f91f7b2308e 100644 (file)
@@ -1,22 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+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_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # 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 is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=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_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -101,7 +130,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_BF518=y
 # CONFIG_BF537 is not set
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=0
@@ -154,8 +182,8 @@ CONFIG_BF_REV_0_0=y
 # CONFIG_BF_REV_0_6 is not set
 # CONFIG_BF_REV_ANY is not set
 # CONFIG_BF_REV_NONE is not set
-CONFIG_BF51x=y
 CONFIG_MEM_MT48LC32M8A2_75=y
+CONFIG_BF51x=y
 CONFIG_BFIN518F_EZBRD=y
 
 #
@@ -313,7 +341,6 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
@@ -322,16 +349,18 @@ CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -342,7 +371,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -398,11 +427,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -426,7 +450,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -437,6 +460,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
@@ -450,7 +474,10 @@ 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
@@ -461,13 +488,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -488,6 +510,7 @@ 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_REDBOOT_PARTS is not set
@@ -545,6 +568,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=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
@@ -559,6 +583,11 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
 # CONFIG_MTD_NAND is not set
 # CONFIG_MTD_ONENAND is not set
 
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
 #
 # UBI - Unsorted block images
 #
@@ -576,10 +605,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# 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_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -614,6 +653,9 @@ CONFIG_PHYLIB=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
@@ -622,10 +664,14 @@ CONFIG_BFIN_MAC=y
 CONFIG_BFIN_TX_DESC_NUM=10
 CONFIG_BFIN_RX_DESC_NUM=20
 # CONFIG_BFIN_MAC_RMII is not set
+CONFIG_BFIN_MAC_USE_HWSTAMP=y
 # CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -634,15 +680,16 @@ CONFIG_BFIN_RX_DESC_NUM=20
 # 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 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN 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
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -677,7 +724,10 @@ CONFIG_INPUT=y
 # CONFIG_INPUT_TOUCHSCREEN is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_UINPUT is not set
-# CONFIG_CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
 
 #
 # Hardware I/O ports
@@ -688,16 +738,13 @@ CONFIG_INPUT_MISC=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 # CONFIG_BFIN_SPORT is not set
-# CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
 CONFIG_VT=y
 CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
@@ -715,6 +762,7 @@ CONFIG_BFIN_JTAG_COMM=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -726,12 +774,10 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
+CONFIG_BFIN_OTP=y
+# CONFIG_BFIN_OTP_WRITE_ENABLE is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -739,6 +785,7 @@ CONFIG_UNIX98_PTYS=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
 
@@ -771,14 +818,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -795,13 +834,18 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_SPI_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -817,6 +861,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -827,11 +872,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # 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
 
@@ -853,28 +902,20 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 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_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 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 is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -912,10 +953,11 @@ CONFIG_MMC_BLOCK_BOUNCE=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_SPI is not set
 CONFIG_SDH_BFIN=m
 CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND=y
-# CONFIG_SDH_BFIN_ENABLE_SDIO_IRQ is not set
-# CONFIG_MMC_SPI is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
@@ -950,6 +992,7 @@ CONFIG_RTC_INTF_DEV=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
@@ -961,6 +1004,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
@@ -981,9 +1025,20 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
+#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
 #
 # File systems
 #
@@ -994,9 +1049,13 @@ CONFIG_EXT2_FS=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=y
 CONFIG_INOTIFY_USER=y
@@ -1005,6 +1064,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
 
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
 #
 # CD-ROM/DVD Filesystems
 #
@@ -1027,13 +1091,9 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1042,8 +1102,8 @@ CONFIG_SYSFS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
-# CONFIG_YAFFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1062,7 +1122,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1127,14 +1186,19 @@ 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
+CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 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 is not set
 # CONFIG_TIMER_STATS is not set
@@ -1142,31 +1206,39 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SLAB 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
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1191,6 +1263,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1199,14 +1272,14 @@ CONFIG_ACCESS_CHECK=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 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
@@ -1238,11 +1311,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
@@ -1279,6 +1354,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1286,11 +1362,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1299,6 +1377,8 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
index 075e0fdcb3992a182bfda7c100042542fa0701e7..31c2a6db6ec55e371021f232aae4de0a58e4aeb4 100644 (file)
@@ -1,22 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+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_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # 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 is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=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_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -101,7 +130,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_BF526=y
 # CONFIG_BF537 is not set
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=0
@@ -154,8 +182,7 @@ CONFIG_BF_REV_0_0=y
 # CONFIG_BF_REV_0_6 is not set
 # CONFIG_BF_REV_ANY is not set
 # CONFIG_BF_REV_NONE is not set
-CONFIG_BF52x=y
-CONFIG_MEM_MT48LC32M16A2TG_75=y
+CONFIG_MEM_MT48H32M16LFCJ_75=y
 CONFIG_IRQ_PLL_WAKEUP=7
 CONFIG_IRQ_DMA0_ERROR=7
 CONFIG_IRQ_DMAR0_BLK=7
@@ -200,7 +227,9 @@ CONFIG_IRQ_MEM_DMA1=13
 CONFIG_IRQ_WATCH=13
 CONFIG_IRQ_PORTF_INTA=13
 CONFIG_IRQ_PORTF_INTB=13
+CONFIG_BF52x=y
 # CONFIG_BFIN527_EZKIT is not set
+# CONFIG_BFIN527_EZKIT_V2 is not set
 # CONFIG_BFIN527_BLUETECHNIX_CM is not set
 CONFIG_BFIN526_EZBRD=y
 
@@ -318,7 +347,6 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
@@ -327,16 +355,18 @@ CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -346,6 +376,10 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 #
 # CONFIG_MPU is not set
 
+#
+# Asynchronous Memory Configuration
+#
+
 #
 # EBIU_AMGCTL Global Control
 #
@@ -399,11 +433,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -427,7 +456,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -438,6 +466,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
@@ -451,7 +480,10 @@ 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
@@ -462,13 +494,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -489,6 +516,7 @@ 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_REDBOOT_PARTS is not set
@@ -549,6 +577,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
@@ -564,11 +593,6 @@ 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_BFIN=m
-CONFIG_BFIN_NAND_BASE=0x20212000
-CONFIG_BFIN_NAND_CLE=2
-CONFIG_BFIN_NAND_ALE=1
-CONFIG_BFIN_NAND_READY=3
 CONFIG_MTD_NAND_IDS=m
 # CONFIG_MTD_NAND_BF5XX is not set
 # CONFIG_MTD_NAND_DISKONCHIP is not set
@@ -577,6 +601,11 @@ CONFIG_MTD_NAND_IDS=m
 # CONFIG_MTD_ALAUDA is not set
 # CONFIG_MTD_ONENAND is not set
 
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
 #
 # UBI - Unsorted block images
 #
@@ -595,10 +624,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# 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_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -622,10 +661,6 @@ CONFIG_BLK_DEV_SR=m
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 # CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -642,6 +677,7 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
@@ -666,6 +702,9 @@ CONFIG_PHYLIB=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
@@ -675,9 +714,12 @@ CONFIG_BFIN_TX_DESC_NUM=10
 CONFIG_BFIN_RX_DESC_NUM=20
 CONFIG_BFIN_MAC_RMII=y
 # CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -686,15 +728,16 @@ CONFIG_BFIN_MAC_RMII=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 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN 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
@@ -744,7 +787,11 @@ CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_YEALINK is not set
 # CONFIG_INPUT_CM109 is not set
 # CONFIG_INPUT_UINPUT is not set
-# CONFIG_CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_BFIN_ROTARY is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
 
 #
 # Hardware I/O ports
@@ -755,16 +802,13 @@ CONFIG_INPUT_MISC=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 # CONFIG_BFIN_SPORT is not set
-# CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
 CONFIG_VT=y
 CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
@@ -782,6 +826,7 @@ CONFIG_BFIN_JTAG_COMM=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -793,14 +838,10 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_OTP=y
 # CONFIG_BFIN_OTP_WRITE_ENABLE is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -808,6 +849,7 @@ CONFIG_BFIN_OTP=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=m
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -841,14 +883,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -865,13 +899,18 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -887,6 +926,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -897,11 +937,20 @@ CONFIG_GPIO_SYSFS=y
 #
 # 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_SENSORS_AD5252 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
@@ -914,11 +963,13 @@ CONFIG_HWMON=y
 # 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_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
@@ -934,17 +985,24 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LM90 is not set
 # 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_MAX1111 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_SHT15 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_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
@@ -954,9 +1012,8 @@ 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_SENSORS_LIS3_SPI is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -983,28 +1040,20 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 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_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 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 is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -1026,7 +1075,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
 
 #
@@ -1039,30 +1087,35 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
-CONFIG_HID_BRIGHT=y
 CONFIG_HID_CHERRY=y
 CONFIG_HID_CHICONY=y
 CONFIG_HID_CYPRESS=y
-CONFIG_HID_DELL=y
+# CONFIG_HID_DRAGONRISE is not set
 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
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
 CONFIG_HID_MICROSOFT=y
 CONFIG_HID_MONTEREY=y
+# CONFIG_HID_NTRIG is not set
 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_THRUSTMASTER_FF=m
-CONFIG_ZEROPLUS_FF=m
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED 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 is not set
@@ -1088,6 +1141,7 @@ CONFIG_USB_MON=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_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
@@ -1118,18 +1172,17 @@ CONFIG_USB_INVENTRA_DMA=y
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# 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
@@ -1165,7 +1218,6 @@ CONFIG_USB_STORAGE=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
@@ -1177,6 +1229,13 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+CONFIG_NOP_USB_XCEIV=y
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1212,6 +1271,7 @@ CONFIG_RTC_INTF_DEV=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
@@ -1223,6 +1283,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
@@ -1243,9 +1304,20 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
+#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
 #
 # File systems
 #
@@ -1256,9 +1328,13 @@ CONFIG_EXT2_FS=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=y
 CONFIG_INOTIFY_USER=y
@@ -1267,6 +1343,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
 
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
 #
 # CD-ROM/DVD Filesystems
 #
@@ -1291,13 +1372,9 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1316,17 +1393,8 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # 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
@@ -1345,7 +1413,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1360,7 +1427,7 @@ CONFIG_SMB_FS=m
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-CONFIG_NLS=m
+CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_NLS_CODEPAGE_437=m
 # CONFIG_NLS_CODEPAGE_737 is not set
@@ -1410,14 +1477,19 @@ 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
+CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 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 is not set
 # CONFIG_TIMER_STATS is not set
@@ -1425,31 +1497,39 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SLAB 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
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1474,6 +1554,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1482,15 +1563,15 @@ CONFIG_ACCESS_CHECK=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 # CONFIG_SECURITY_ROOTPLUG is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 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
@@ -1522,11 +1603,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
@@ -1563,6 +1646,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1570,11 +1654,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1584,6 +1670,8 @@ CONFIG_CRC32=y
 # 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/blackfin/configs/BF527-EZKIT-V2_defconfig b/arch/blackfin/configs/BF527-EZKIT-V2_defconfig
new file mode 100644 (file)
index 0000000..d2dfcb0
--- /dev/null
@@ -0,0 +1,1811 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32.2
+#
+# CONFIG_MMU is not set
+# CONFIG_FPU is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+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_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# 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 is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+CONFIG_EPOLL=y
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=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_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+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_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+# CONFIG_FREEZER is not set
+
+#
+# Blackfin Processor Options
+#
+
+#
+# Processor and Board Settings
+#
+# CONFIG_BF512 is not set
+# CONFIG_BF514 is not set
+# CONFIG_BF516 is not set
+# CONFIG_BF518 is not set
+# CONFIG_BF522 is not set
+# CONFIG_BF523 is not set
+# CONFIG_BF524 is not set
+# CONFIG_BF525 is not set
+# CONFIG_BF526 is not set
+CONFIG_BF527=y
+# CONFIG_BF531 is not set
+# CONFIG_BF532 is not set
+# CONFIG_BF533 is not set
+# CONFIG_BF534 is not set
+# CONFIG_BF536 is not set
+# CONFIG_BF537 is not set
+# CONFIG_BF538 is not set
+# CONFIG_BF539 is not set
+# CONFIG_BF542_std is not set
+# CONFIG_BF542M is not set
+# CONFIG_BF544_std is not set
+# CONFIG_BF544M is not set
+# CONFIG_BF547_std is not set
+# CONFIG_BF547M is not set
+# CONFIG_BF548_std is not set
+# CONFIG_BF548M is not set
+# CONFIG_BF549_std is not set
+# CONFIG_BF549M is not set
+# CONFIG_BF561 is not set
+CONFIG_BF_REV_MIN=0
+CONFIG_BF_REV_MAX=2
+# CONFIG_BF_REV_0_0 is not set
+# CONFIG_BF_REV_0_1 is not set
+CONFIG_BF_REV_0_2=y
+# CONFIG_BF_REV_0_3 is not set
+# CONFIG_BF_REV_0_4 is not set
+# CONFIG_BF_REV_0_5 is not set
+# CONFIG_BF_REV_0_6 is not set
+# CONFIG_BF_REV_ANY is not set
+# CONFIG_BF_REV_NONE is not set
+CONFIG_MEM_MT48LC32M16A2TG_75=y
+CONFIG_IRQ_PLL_WAKEUP=7
+CONFIG_IRQ_DMA0_ERROR=7
+CONFIG_IRQ_DMAR0_BLK=7
+CONFIG_IRQ_DMAR1_BLK=7
+CONFIG_IRQ_DMAR0_OVR=7
+CONFIG_IRQ_DMAR1_OVR=7
+CONFIG_IRQ_PPI_ERROR=7
+CONFIG_IRQ_MAC_ERROR=7
+CONFIG_IRQ_SPORT0_ERROR=7
+CONFIG_IRQ_SPORT1_ERROR=7
+CONFIG_IRQ_UART0_ERROR=7
+CONFIG_IRQ_UART1_ERROR=7
+CONFIG_IRQ_RTC=8
+CONFIG_IRQ_PPI=8
+CONFIG_IRQ_SPORT0_RX=9
+CONFIG_IRQ_SPORT0_TX=9
+CONFIG_IRQ_SPORT1_RX=9
+CONFIG_IRQ_SPORT1_TX=9
+CONFIG_IRQ_TWI=10
+CONFIG_IRQ_UART0_RX=10
+CONFIG_IRQ_UART0_TX=10
+CONFIG_IRQ_UART1_RX=10
+CONFIG_IRQ_UART1_TX=10
+CONFIG_IRQ_OPTSEC=11
+CONFIG_IRQ_CNT=11
+CONFIG_IRQ_MAC_RX=11
+CONFIG_IRQ_PORTH_INTA=11
+CONFIG_IRQ_MAC_TX=11
+CONFIG_IRQ_PORTH_INTB=11
+CONFIG_IRQ_TIMER0=8
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
+CONFIG_IRQ_TIMER3=12
+CONFIG_IRQ_TIMER4=12
+CONFIG_IRQ_TIMER5=12
+CONFIG_IRQ_TIMER6=12
+CONFIG_IRQ_TIMER7=12
+CONFIG_IRQ_PORTG_INTA=12
+CONFIG_IRQ_PORTG_INTB=12
+CONFIG_IRQ_MEM_DMA0=13
+CONFIG_IRQ_MEM_DMA1=13
+CONFIG_IRQ_WATCH=13
+CONFIG_IRQ_PORTF_INTA=13
+CONFIG_IRQ_PORTF_INTB=13
+CONFIG_BF52x=y
+# CONFIG_BFIN527_EZKIT is not set
+CONFIG_BFIN527_EZKIT_V2=y
+# CONFIG_BFIN527_BLUETECHNIX_CM is not set
+# CONFIG_BFIN526_EZBRD is not set
+
+#
+# BF527 Specific Configuration
+#
+
+#
+# Alternative Multiplexing Scheme
+#
+# CONFIG_BF527_SPORT0_PORTF is not set
+CONFIG_BF527_SPORT0_PORTG=y
+CONFIG_BF527_SPORT0_TSCLK_PG10=y
+# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set
+CONFIG_BF527_UART1_PORTF=y
+# CONFIG_BF527_UART1_PORTG is not set
+# CONFIG_BF527_NAND_D_PORTF is not set
+CONFIG_BF527_NAND_D_PORTH=y
+
+#
+# Interrupt Priority Assignment
+#
+
+#
+# Priority
+#
+CONFIG_IRQ_SPI=10
+CONFIG_IRQ_SPI_ERROR=7
+CONFIG_IRQ_NFC_ERROR=7
+CONFIG_IRQ_HDMA_ERROR=7
+CONFIG_IRQ_HDMA=7
+CONFIG_IRQ_USB_EINT=10
+CONFIG_IRQ_USB_INT0=11
+CONFIG_IRQ_USB_INT1=11
+CONFIG_IRQ_USB_INT2=11
+CONFIG_IRQ_USB_DMA=11
+
+#
+# Board customizations
+#
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_BOOT_LOAD=0x1000
+
+#
+# Clock/PLL Setup
+#
+CONFIG_CLKIN_HZ=25000000
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+CONFIG_MAX_VCO_HZ=600000000
+CONFIG_MIN_VCO_HZ=50000000
+CONFIG_MAX_SCLK_HZ=133333333
+CONFIG_MIN_SCLK_HZ=27000000
+
+#
+# Kernel Timer/Scheduler
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_TICKSOURCE_GPTMR0 is not set
+CONFIG_TICKSOURCE_CORETMR=y
+# CONFIG_CYCLES_CLOCKSOURCE is not set
+# CONFIG_GPTMR0_CLOCKSOURCE is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# Misc
+#
+CONFIG_BFIN_SCRATCH_REG_RETN=y
+# CONFIG_BFIN_SCRATCH_REG_RETE is not set
+# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
+#
+# Memory Optimizations
+#
+CONFIG_I_ENTRY_L1=y
+CONFIG_EXCPT_IRQ_SYSC_L1=y
+CONFIG_DO_IRQ_L1=y
+CONFIG_CORE_TIMER_IRQ_L1=y
+CONFIG_IDLE_L1=y
+# CONFIG_SCHEDULE_L1 is not set
+CONFIG_ARITHMETIC_OPS_L1=y
+CONFIG_ACCESS_OK_L1=y
+# CONFIG_MEMSET_L1 is not set
+# CONFIG_MEMCPY_L1 is not set
+# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set
+# CONFIG_IP_CHECKSUM_L1 is not set
+CONFIG_CACHELINE_ALIGNED_L1=y
+# CONFIG_SYSCALL_TAB_L1 is not set
+# CONFIG_CPLB_SWITCH_TAB_L1 is not set
+CONFIG_APP_STACK_L1=y
+
+#
+# Speed Optimizations
+#
+CONFIG_BFIN_INS_LOWOVERHEAD=y
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
+CONFIG_BFIN_GPTIMERS=y
+# CONFIG_DMA_UNCACHED_4M is not set
+# CONFIG_DMA_UNCACHED_2M is not set
+CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
+# CONFIG_DMA_UNCACHED_NONE is not set
+
+#
+# Cache Support
+#
+CONFIG_BFIN_ICACHE=y
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
+CONFIG_BFIN_DCACHE=y
+# CONFIG_BFIN_DCACHE_BANKA is not set
+CONFIG_BFIN_EXTMEM_DCACHEABLE=y
+CONFIG_BFIN_EXTMEM_WRITEBACK=y
+# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
+
+#
+# Memory Protection Unit
+#
+# CONFIG_MPU is not set
+
+#
+# Asynchronous Memory Configuration
+#
+
+#
+# EBIU_AMGCTL Global Control
+#
+CONFIG_C_AMCKEN=y
+CONFIG_C_CDPRIO=y
+# CONFIG_C_AMBEN is not set
+# CONFIG_C_AMBEN_B0 is not set
+# CONFIG_C_AMBEN_B0_B1 is not set
+# CONFIG_C_AMBEN_B0_B1_B2 is not set
+CONFIG_C_AMBEN_ALL=y
+
+#
+# EBIU_AMBCTL Control
+#
+CONFIG_BANK_0=0x7BB0
+CONFIG_BANK_1=0x7BB0
+CONFIG_BANK_2=0x7BB0
+CONFIG_BANK_3=0x99B2
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF_FDPIC=y
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# 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_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_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
+# 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_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+CONFIG_BFIN_SIR=m
+CONFIG_BFIN_SIR0=y
+CONFIG_SIR_BFIN_DMA=y
+# CONFIG_SIR_BFIN_PIO is not set
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+# CONFIG_KINGSUN_DONGLE is not set
+# CONFIG_KSDAZZLE_DONGLE is not set
+# CONFIG_KS959_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_MCS_FIR is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=m
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_GPIO_ADDR is not set
+# CONFIG_MTD_UCLINUX is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# 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
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=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_BF5XX is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_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_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# 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_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_BFIN_MAC=y
+CONFIG_BFIN_MAC_USE_L1=y
+CONFIG_BFIN_TX_DESC_NUM=10
+CONFIG_BFIN_RX_DESC_NUM=20
+CONFIG_BFIN_MAC_RMII=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ADP5520=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
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+CONFIG_TOUCHSCREEN_AD7879_I2C=y
+CONFIG_TOUCHSCREEN_AD7879=y
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# 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
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_WM97XX is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 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
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_BFIN_ROTARY is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_BFIN_DMA_INTERFACE=m
+# CONFIG_BFIN_PPI is not set
+# CONFIG_BFIN_PPIFCD is not set
+# CONFIG_BFIN_SIMPLE_TIMER is not set
+# CONFIG_BFIN_SPI_ADC is not set
+CONFIG_BFIN_SPORT=m
+# CONFIG_BFIN_TWI_LCD is not set
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_BFIN_JTAG_COMM=m
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_BFIN=y
+CONFIG_SERIAL_BFIN_CONSOLE=y
+CONFIG_SERIAL_BFIN_DMA=y
+# CONFIG_SERIAL_BFIN_PIO is not set
+# CONFIG_SERIAL_BFIN_UART0 is not set
+CONFIG_SERIAL_BFIN_UART1=y
+# CONFIG_BFIN_UART1_CTSRTS is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_BFIN_SPORT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_BFIN_OTP=y
+# CONFIG_BFIN_OTP_WRITE_ENABLE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_BLACKFIN_TWI=y
+CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# 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=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BFIN=y
+# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_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
+# CONFIG_GPIO_ADP5520 is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# 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_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_BFIN_WDT=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG 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_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+CONFIG_PMIC_ADP5520=y
+# 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
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# 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 is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_BFIN_T350MCQB is not set
+CONFIG_FB_BFIN_LQ035Q1=y
+# CONFIG_FB_BFIN_7393 is not set
+# CONFIG_FB_S1D13XXX 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=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
+# CONFIG_LCD_VGG2432A4 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_GENERIC=m
+# CONFIG_BACKLIGHT_ADP5520 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+# CONFIG_LOGO_BLACKFIN_VGA16 is not set
+CONFIG_LOGO_BLACKFIN_CLUT224=y
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS 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_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_SPI=y
+
+#
+# ALSA Blackfin devices
+#
+# CONFIG_SND_BFIN_AD73322 is not set
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_BF5XX_I2S=m
+CONFIG_SND_BF5XX_SOC_SSM2602=m
+# CONFIG_SND_BF5XX_SOC_AD73311 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1371 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set
+# CONFIG_SND_BF5XX_TDM is not set
+CONFIG_SND_BF5XX_AC97=m
+CONFIG_SND_BF5XX_MMAP_SUPPORT=y
+# CONFIG_SND_BF5XX_MULTICHAN_SUPPORT is not set
+# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+CONFIG_SND_BF5XX_SOC_AD1980=m
+CONFIG_SND_BF5XX_SOC_SPORT=m
+CONFIG_SND_BF5XX_SOC_I2S=m
+CONFIG_SND_BF5XX_SOC_AC97=m
+CONFIG_SND_BF5XX_SPORT_NUM=0
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_AD1980=m
+CONFIG_SND_SOC_SSM2602=m
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+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 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 is not set
+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
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_NTRIG is not set
+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 is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED 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 is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+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_OTG_WHITELIST is not set
+CONFIG_USB_OTG_BLACKLIST_HUB=y
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_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_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# Blackfin high speed USB Support
+#
+CONFIG_USB_MUSB_HOST=y
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+# CONFIG_USB_MUSB_OTG is not set
+CONFIG_USB_MUSB_HDRC_HCD=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+# CONFIG_USB_MUSB_DEBUG 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=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_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 is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+CONFIG_NOP_USB_XCEIV=y
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO 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
+CONFIG_LEDS_ADP5520=y
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGERS is not set
+# CONFIG_ACCESSIBILITY 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 is not set
+# 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
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_BFIN=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_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=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=m
+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_SYSCTL=y
+CONFIG_SYSFS=y
+# 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 is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR 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=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+CONFIG_NLS_CODEPAGE_936=m
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=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
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+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 is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB 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
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_VERBOSE=y
+CONFIG_DEBUG_MMRS=y
+CONFIG_DEBUG_HWERR=y
+CONFIG_EXACT_HWERR=y
+CONFIG_DEBUG_DOUBLEFAULT=y
+CONFIG_DEBUG_DOUBLEFAULT_PRINT=y
+# CONFIG_DEBUG_DOUBLEFAULT_RESET is not set
+# CONFIG_DEBUG_ICACHE_CHECK is not set
+CONFIG_DEBUG_HUNT_FOR_ZERO=y
+CONFIG_DEBUG_BFIN_HWTRACE_ON=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=1
+# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
+CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CPLB_INFO=y
+CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_TOMOYO is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# 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
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_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_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_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
index 6d1a623fb1498dca5a4760405ae488e44a55be23..edbb44d26bbf2a14f6a548445aab2b5dac058f5a 100644 (file)
@@ -1,22 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+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_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # 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 is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=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_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -101,7 +130,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -132,29 +160,28 @@ CONFIG_BF527=y
 # CONFIG_BF537 is not set
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=0
 CONFIG_BF_REV_MAX=2
 # CONFIG_BF_REV_0_0 is not set
-# CONFIG_BF_REV_0_1 is not set
-CONFIG_BF_REV_0_2=y
+CONFIG_BF_REV_0_1=y
+# CONFIG_BF_REV_0_2 is not set
 # CONFIG_BF_REV_0_3 is not set
 # CONFIG_BF_REV_0_4 is not set
 # CONFIG_BF_REV_0_5 is not set
 # CONFIG_BF_REV_0_6 is not set
 # CONFIG_BF_REV_ANY is not set
 # CONFIG_BF_REV_NONE is not set
-CONFIG_BF52x=y
 CONFIG_MEM_MT48LC32M16A2TG_75=y
 CONFIG_IRQ_PLL_WAKEUP=7
 CONFIG_IRQ_DMA0_ERROR=7
@@ -200,7 +227,9 @@ CONFIG_IRQ_MEM_DMA1=13
 CONFIG_IRQ_WATCH=13
 CONFIG_IRQ_PORTF_INTA=13
 CONFIG_IRQ_PORTF_INTB=13
+CONFIG_BF52x=y
 CONFIG_BFIN527_EZKIT=y
+# CONFIG_BFIN527_EZKIT_V2 is not set
 # CONFIG_BFIN527_BLUETECHNIX_CM is not set
 # CONFIG_BFIN526_EZBRD is not set
 
@@ -318,7 +347,6 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
@@ -327,16 +355,18 @@ CONFIG_BFIN_GPTIMERS=y
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -347,7 +377,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -403,11 +433,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -431,7 +456,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -442,6 +466,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
@@ -455,7 +480,10 @@ 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
@@ -508,13 +536,8 @@ CONFIG_SIR_BFIN_DMA=y
 # CONFIG_MCS_FIR is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -535,6 +558,7 @@ 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_REDBOOT_PARTS is not set
@@ -593,6 +617,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=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
@@ -608,11 +633,6 @@ 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_BFIN=m
-CONFIG_BFIN_NAND_BASE=0x20212000
-CONFIG_BFIN_NAND_CLE=2
-CONFIG_BFIN_NAND_ALE=1
-CONFIG_BFIN_NAND_READY=3
 CONFIG_MTD_NAND_IDS=m
 # CONFIG_MTD_NAND_BF5XX is not set
 # CONFIG_MTD_NAND_DISKONCHIP is not set
@@ -621,6 +641,11 @@ CONFIG_MTD_NAND_IDS=m
 # CONFIG_MTD_ALAUDA is not set
 # CONFIG_MTD_ONENAND is not set
 
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
 #
 # UBI - Unsorted block images
 #
@@ -639,10 +664,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# 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_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -666,10 +701,6 @@ CONFIG_BLK_DEV_SR=m
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 # CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -686,6 +717,7 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
@@ -710,6 +742,9 @@ CONFIG_PHYLIB=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
@@ -720,9 +755,12 @@ CONFIG_BFIN_TX_DESC_NUM=10
 CONFIG_BFIN_RX_DESC_NUM=20
 CONFIG_BFIN_MAC_RMII=y
 # CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -731,15 +769,16 @@ CONFIG_BFIN_MAC_RMII=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 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN 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
@@ -789,7 +828,11 @@ CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_YEALINK is not set
 # CONFIG_INPUT_CM109 is not set
 # CONFIG_INPUT_UINPUT is not set
-# CONFIG_CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_BFIN_ROTARY is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
 
 #
 # Hardware I/O ports
@@ -800,16 +843,13 @@ CONFIG_INPUT_MISC=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 CONFIG_BFIN_SPORT=m
-# CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
 CONFIG_VT=y
 CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
@@ -827,6 +867,7 @@ CONFIG_BFIN_JTAG_COMM=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -838,14 +879,10 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_OTP=y
 # CONFIG_BFIN_OTP_WRITE_ENABLE is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -853,6 +890,7 @@ CONFIG_BFIN_OTP=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=m
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -886,14 +924,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -910,13 +940,18 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -932,6 +967,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -942,11 +978,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # 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
 
@@ -973,28 +1013,21 @@ 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_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 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 is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -1030,15 +1063,18 @@ CONFIG_FB_BFIN_T350MCQB=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=m
+# CONFIG_LCD_LMS283GF05 is not set
 CONFIG_LCD_LTV350QV=m
 # CONFIG_LCD_ILI9320 is not set
 # CONFIG_LCD_TDO24M is not set
 # CONFIG_LCD_VGG2432A4 is not set
 # CONFIG_LCD_PLATFORM is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=m
-# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_GENERIC=m
+# CONFIG_BACKLIGHT_ADP8870 is not set
 
 #
 # Display device support
@@ -1066,6 +1102,7 @@ CONFIG_SOUND=m
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
+CONFIG_SND_JACK=y
 # CONFIG_SND_SEQUENCER is not set
 # CONFIG_SND_MIXER_OSS is not set
 # CONFIG_SND_PCM_OSS is not set
@@ -1074,6 +1111,11 @@ 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_MTPAV is not set
@@ -1084,7 +1126,6 @@ CONFIG_SND_SPI=y
 #
 # ALSA Blackfin devices
 #
-# CONFIG_SND_BLACKFIN_AD1836 is not set
 # CONFIG_SND_BFIN_AD73322 is not set
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
@@ -1094,15 +1135,19 @@ CONFIG_SND_SOC_AC97_BUS=y
 CONFIG_SND_BF5XX_I2S=m
 CONFIG_SND_BF5XX_SOC_SSM2602=m
 # CONFIG_SND_BF5XX_SOC_AD73311 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1371 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set
+# CONFIG_SND_BF5XX_TDM is not set
 CONFIG_SND_BF5XX_AC97=m
 CONFIG_SND_BF5XX_MMAP_SUPPORT=y
 # CONFIG_SND_BF5XX_MULTICHAN_SUPPORT is not set
+# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+CONFIG_SND_BF5XX_SOC_AD1980=m
 CONFIG_SND_BF5XX_SOC_SPORT=m
 CONFIG_SND_BF5XX_SOC_I2S=m
 CONFIG_SND_BF5XX_SOC_AC97=m
-CONFIG_SND_BF5XX_SOC_AD1980=m
 CONFIG_SND_BF5XX_SPORT_NUM=0
-# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
 # CONFIG_SND_SOC_ALL_CODECS is not set
 CONFIG_SND_SOC_AD1980=m
 CONFIG_SND_SOC_SSM2602=m
@@ -1110,7 +1155,6 @@ CONFIG_SND_SOC_SSM2602=m
 CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 
 #
@@ -1123,30 +1167,35 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
-CONFIG_HID_BRIGHT=y
 CONFIG_HID_CHERRY=y
 CONFIG_HID_CHICONY=y
 CONFIG_HID_CYPRESS=y
-CONFIG_HID_DELL=y
+# CONFIG_HID_DRAGONRISE is not set
 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
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
 CONFIG_HID_MICROSOFT=y
 CONFIG_HID_MONTEREY=y
+# CONFIG_HID_NTRIG is not set
 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_THRUSTMASTER_FF=m
-CONFIG_ZEROPLUS_FF=m
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED 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 is not set
@@ -1172,6 +1221,7 @@ CONFIG_USB_MON=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_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
@@ -1188,9 +1238,7 @@ CONFIG_USB_MUSB_HOST=y
 # CONFIG_USB_MUSB_PERIPHERAL is not set
 # CONFIG_USB_MUSB_OTG is not set
 CONFIG_USB_MUSB_HDRC_HCD=y
-# CONFIG_MUSB_PIO_ONLY is not set
-CONFIG_USB_INVENTRA_DMA=y
-# CONFIG_USB_TI_CPPI_DMA is not set
+CONFIG_MUSB_PIO_ONLY=y
 # CONFIG_USB_MUSB_DEBUG is not set
 
 #
@@ -1202,18 +1250,17 @@ CONFIG_USB_INVENTRA_DMA=y
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# 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
@@ -1249,7 +1296,6 @@ CONFIG_USB_STORAGE=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
@@ -1261,6 +1307,13 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+CONFIG_NOP_USB_XCEIV=y
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1296,6 +1349,7 @@ CONFIG_RTC_INTF_DEV=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
@@ -1307,6 +1361,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
@@ -1327,9 +1382,20 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
+#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
 #
 # File systems
 #
@@ -1340,9 +1406,13 @@ CONFIG_EXT2_FS=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=y
 CONFIG_INOTIFY_USER=y
@@ -1351,6 +1421,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
 
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
 #
 # CD-ROM/DVD Filesystems
 #
@@ -1376,13 +1451,9 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1401,17 +1472,8 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # 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
@@ -1430,7 +1492,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1445,7 +1506,7 @@ CONFIG_SMB_FS=m
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-CONFIG_NLS=m
+CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_NLS_CODEPAGE_437=m
 # CONFIG_NLS_CODEPAGE_737 is not set
@@ -1495,14 +1556,19 @@ 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
+CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 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 is not set
 # CONFIG_TIMER_STATS is not set
@@ -1510,31 +1576,39 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SLAB 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
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1559,6 +1633,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1567,15 +1642,15 @@ CONFIG_ACCESS_CHECK=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 # CONFIG_SECURITY_ROOTPLUG is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 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
@@ -1607,11 +1682,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
@@ -1648,6 +1725,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1655,11 +1733,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1669,6 +1749,8 @@ CONFIG_CRC32=y
 # 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
index 50f9a23ccdbde33d636fcccdd42cb4eeeea1482a..0b13d5836a487cc895348a0d9fd48d3db4ba806b 100644 (file)
@@ -1,22 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+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_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # 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 is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=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_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -101,7 +130,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_BF533=y
 # CONFIG_BF537 is not set
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=3
@@ -228,7 +256,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_TICKSOURCE_GPTMR0 is not set
 CONFIG_TICKSOURCE_CORETMR=y
-# CONFIG_CYCLES_CLOCKSOURCE is not set
+CONFIG_CYCLES_CLOCKSOURCE=y
 # CONFIG_GPTMR0_CLOCKSOURCE is not set
 CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
@@ -280,7 +308,6 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
@@ -289,19 +316,18 @@ CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
-#
-# Cache Support
-#
 #
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -312,7 +338,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -358,6 +384,7 @@ CONFIG_PM=y
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_PM_BFIN_SLEEP_DEEPER=y
 # CONFIG_PM_BFIN_SLEEP is not set
@@ -379,11 +406,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -407,7 +429,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -418,6 +439,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
@@ -431,7 +453,10 @@ 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
@@ -475,13 +500,8 @@ CONFIG_IRTTY_SIR=m
 #
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -502,6 +522,7 @@ 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_REDBOOT_PARTS is not set
@@ -559,6 +580,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=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
@@ -573,6 +595,11 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
 # CONFIG_MTD_NAND is not set
 # CONFIG_MTD_ONENAND is not set
 
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
 #
 # UBI - Unsorted block images
 #
@@ -590,9 +617,14 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -616,9 +648,12 @@ CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_SMC91X=y
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -627,15 +662,16 @@ CONFIG_SMC91X=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 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN 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
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -679,15 +715,12 @@ CONFIG_INPUT_EVDEV=m
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 CONFIG_BFIN_SPORT=y
-# CONFIG_BFIN_TIMER_LATENCY is not set
-CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_BFIN_JTAG_COMM=m
@@ -701,6 +734,7 @@ CONFIG_BFIN_JTAG_COMM=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -711,12 +745,8 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -734,13 +764,18 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -753,9 +788,6 @@ CONFIG_GPIO_SYSFS=y
 #
 # I2C GPIO expanders:
 #
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_PCA953X is not set
-# CONFIG_GPIO_PCF857X is not set
 
 #
 # PCI GPIO expanders:
@@ -766,11 +798,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # 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
 
@@ -793,23 +829,10 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 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
@@ -826,14 +849,12 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 # CONFIG_HID_PID is not set
 
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -864,6 +885,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
@@ -884,9 +906,19 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
+#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+
 #
 # File systems
 #
@@ -896,9 +928,13 @@ CONFIG_RTC_DRV_BFIN=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 is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -907,6 +943,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
 
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
 #
 # CD-ROM/DVD Filesystems
 #
@@ -926,13 +967,9 @@ CONFIG_INOTIFY_USER=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -951,17 +988,8 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # 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
@@ -980,7 +1008,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1045,14 +1072,19 @@ 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
+CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 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 is not set
 # CONFIG_TIMER_STATS is not set
@@ -1060,31 +1092,39 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SLAB 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
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1109,6 +1149,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1117,14 +1158,14 @@ CONFIG_ACCESS_CHECK=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 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
@@ -1156,11 +1197,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
@@ -1197,6 +1240,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1204,11 +1248,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1218,6 +1264,8 @@ CONFIG_CRC32=y
 # 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
index 6c60c8286318f48e24bb16ccc5e0c80a221c66e5..c3fe6e5b612f488abc2e7acb9c06e475fe686389 100644 (file)
@@ -1,22 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+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_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # 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 is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=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_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -101,7 +130,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_BF533=y
 # CONFIG_BF537 is not set
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=3
@@ -228,7 +256,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_TICKSOURCE_GPTMR0 is not set
 CONFIG_TICKSOURCE_CORETMR=y
-# CONFIG_CYCLES_CLOCKSOURCE is not set
+CONFIG_CYCLES_CLOCKSOURCE=y
 # CONFIG_GPTMR0_CLOCKSOURCE is not set
 CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
@@ -280,7 +308,6 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
@@ -289,16 +316,18 @@ CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -309,7 +338,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -355,6 +384,7 @@ CONFIG_PM=y
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_PM_BFIN_SLEEP_DEEPER=y
 # CONFIG_PM_BFIN_SLEEP is not set
@@ -376,11 +406,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -404,7 +429,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -415,6 +439,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
@@ -428,7 +453,10 @@ 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
@@ -474,13 +502,8 @@ CONFIG_SIR_BFIN_DMA=y
 #
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -501,6 +524,7 @@ 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_REDBOOT_PARTS is not set
@@ -560,6 +584,7 @@ CONFIG_MTD_BFIN_ASYNC=m
 #
 # 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
@@ -574,6 +599,11 @@ CONFIG_MTD_BFIN_ASYNC=m
 # CONFIG_MTD_NAND is not set
 # CONFIG_MTD_ONENAND is not set
 
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
 #
 # UBI - Unsorted block images
 #
@@ -591,10 +621,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# 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_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -618,9 +658,12 @@ CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_SMC91X=y
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -629,15 +672,16 @@ CONFIG_SMC91X=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 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN 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
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -672,7 +716,10 @@ CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_TOUCHSCREEN is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_UINPUT is not set
-CONFIG_CONFIG_INPUT_PCF8574=m
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
 
 #
 # Hardware I/O ports
@@ -683,16 +730,13 @@ CONFIG_CONFIG_INPUT_PCF8574=m
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 CONFIG_BFIN_SPORT=m
-# CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_BFIN_JTAG_COMM=m
@@ -706,6 +750,7 @@ CONFIG_BFIN_JTAG_COMM=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -716,12 +761,8 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -729,6 +770,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=m
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -759,14 +801,6 @@ CONFIG_I2C_HELPER_AUTO=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -783,13 +817,18 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -805,6 +844,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -815,11 +855,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # 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
 
@@ -841,26 +885,18 @@ 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_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_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 is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -904,6 +940,7 @@ CONFIG_ADV7393_1XMEM=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 is not set
 
 #
@@ -913,19 +950,27 @@ CONFIG_ADV7393_1XMEM=y
 # CONFIG_LOGO is not set
 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_JACK=y
 # CONFIG_SND_SEQUENCER is not set
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
 CONFIG_SND_PCM_OSS_PLUGINS=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_MTPAV is not set
@@ -936,13 +981,6 @@ CONFIG_SND_SPI=y
 #
 # ALSA Blackfin devices
 #
-CONFIG_SND_BLACKFIN_AD1836=m
-CONFIG_SND_BLACKFIN_AD1836_TDM=y
-# CONFIG_SND_BLACKFIN_AD1836_I2S is not set
-CONFIG_SND_BLACKFIN_AD1836_MULSUB=y
-# CONFIG_SND_BLACKFIN_AD1836_5P1 is not set
-CONFIG_SND_BLACKFIN_SPORT=0
-CONFIG_SND_BLACKFIN_SPI_PFBIT=4
 CONFIG_SND_BFIN_SPORT=0
 CONFIG_SND_BFIN_AD73322=m
 CONFIG_SND_BFIN_AD73322_SPORT0_SE=10
@@ -953,16 +991,20 @@ CONFIG_SND_SOC_AC97_BUS=y
 CONFIG_SND_BF5XX_I2S=m
 # CONFIG_SND_BF5XX_SOC_SSM2602 is not set
 CONFIG_SND_BF5XX_SOC_AD73311=m
+# CONFIG_SND_BF5XX_SOC_ADAU1371 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set
 CONFIG_SND_BFIN_AD73311_SE=4
+# CONFIG_SND_BF5XX_TDM is not set
 CONFIG_SND_BF5XX_AC97=m
 CONFIG_SND_BF5XX_MMAP_SUPPORT=y
 # CONFIG_SND_BF5XX_MULTICHAN_SUPPORT is not set
+# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+CONFIG_SND_BF5XX_SOC_AD1980=m
 CONFIG_SND_BF5XX_SOC_SPORT=m
 CONFIG_SND_BF5XX_SOC_I2S=m
 CONFIG_SND_BF5XX_SOC_AC97=m
-CONFIG_SND_BF5XX_SOC_AD1980=m
 CONFIG_SND_BF5XX_SPORT_NUM=0
-# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
 # CONFIG_SND_SOC_ALL_CODECS is not set
 CONFIG_SND_SOC_AD1980=m
 CONFIG_SND_SOC_AD73311=m
@@ -970,14 +1012,12 @@ CONFIG_SND_SOC_AD73311=m
 CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 # CONFIG_HID_PID is not set
 
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1014,6 +1054,7 @@ CONFIG_RTC_INTF_DEV=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
@@ -1025,6 +1066,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
@@ -1045,9 +1087,20 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
+#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
 #
 # File systems
 #
@@ -1057,9 +1110,13 @@ CONFIG_RTC_DRV_BFIN=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 is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1068,6 +1125,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
 
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
 #
 # CD-ROM/DVD Filesystems
 #
@@ -1087,13 +1149,9 @@ CONFIG_INOTIFY_USER=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1112,17 +1170,8 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # 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
@@ -1141,7 +1190,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1206,14 +1254,19 @@ 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
+CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 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 is not set
 # CONFIG_TIMER_STATS is not set
@@ -1221,31 +1274,39 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SLAB 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
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1270,6 +1331,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1278,14 +1340,14 @@ CONFIG_ACCESS_CHECK=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 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
@@ -1317,11 +1379,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
@@ -1358,6 +1422,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1365,11 +1430,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1379,6 +1446,8 @@ CONFIG_CRC32=y
 # 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
index 2908595b67c5ebb6abaa20cbd9f34fe7277707e0..7596cf7673f18170091d60984b64a708b2d59877 100644 (file)
@@ -1,22 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+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_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # 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 is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=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_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -101,7 +130,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_FREEZER=y
 CONFIG_BF537=y
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=2
@@ -184,7 +212,8 @@ CONFIG_IRQ_MEM_DMA1=13
 CONFIG_IRQ_WATCH=13
 CONFIG_IRQ_SPI=10
 CONFIG_BFIN537_STAMP=y
-# CONFIG_BFIN537_BLUETECHNIX_CM is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM_E is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM_U is not set
 # CONFIG_BFIN537_BLUETECHNIX_TCM is not set
 # CONFIG_PNAV10 is not set
 # CONFIG_CAMSIG_MINOTAUR is not set
@@ -235,7 +264,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_TICKSOURCE_GPTMR0 is not set
 CONFIG_TICKSOURCE_CORETMR=y
-# CONFIG_CYCLES_CLOCKSOURCE is not set
+CONFIG_CYCLES_CLOCKSOURCE=y
 # CONFIG_GPTMR0_CLOCKSOURCE is not set
 CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
@@ -287,7 +316,6 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
@@ -296,16 +324,18 @@ CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -316,7 +346,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -362,6 +392,7 @@ CONFIG_PM=y
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_PM_RUNTIME is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_PM_BFIN_SLEEP_DEEPER=y
 # CONFIG_PM_BFIN_SLEEP is not set
@@ -384,11 +415,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -412,7 +438,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -423,6 +448,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
@@ -436,14 +462,34 @@ 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_HAMRADIO is not set
-# CONFIG_CAN is not set
+CONFIG_CAN=m
+CONFIG_CAN_RAW=m
+CONFIG_CAN_BCM=m
+
+#
+# CAN Device Drivers
+#
+# CONFIG_CAN_VCAN is not set
+CONFIG_CAN_DEV=m
+# CONFIG_CAN_CALC_BITTIMING is not set
+CONFIG_CAN_BFIN=m
+# CONFIG_CAN_SJA1000 is not set
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_EMS_USB is not set
+# CONFIG_CAN_DEBUG_DEVICES is not set
 CONFIG_IRDA=m
 
 #
@@ -483,13 +529,8 @@ CONFIG_SIR_BFIN_DMA=y
 #
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -510,6 +551,7 @@ 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_REDBOOT_PARTS is not set
@@ -568,6 +610,7 @@ CONFIG_MTD_PHYSMAP=m
 #
 # 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
@@ -582,6 +625,11 @@ CONFIG_MTD_PHYSMAP=m
 # CONFIG_MTD_NAND is not set
 # CONFIG_MTD_ONENAND is not set
 
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
 #
 # UBI - Unsorted block images
 #
@@ -599,10 +647,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# 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_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -637,6 +695,9 @@ CONFIG_SMSC_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
@@ -647,9 +708,12 @@ CONFIG_BFIN_TX_DESC_NUM=10
 CONFIG_BFIN_RX_DESC_NUM=20
 # CONFIG_BFIN_MAC_RMII is not set
 # CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -658,15 +722,16 @@ CONFIG_BFIN_RX_DESC_NUM=20
 # 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 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN 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
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -701,7 +766,10 @@ CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_TOUCHSCREEN is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_UINPUT is not set
-CONFIG_CONFIG_INPUT_PCF8574=m
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
 
 #
 # Hardware I/O ports
@@ -712,16 +780,13 @@ CONFIG_CONFIG_INPUT_PCF8574=m
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 CONFIG_BFIN_SPORT=m
-# CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_BFIN_JTAG_COMM=m
@@ -735,6 +800,7 @@ CONFIG_BFIN_JTAG_COMM=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -746,17 +812,8 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-CONFIG_CAN4LINUX=y
-
-#
-# linux embedded drivers
-#
-CONFIG_CAN_BLACKFIN=m
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -764,6 +821,7 @@ CONFIG_CAN_BLACKFIN=m
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=m
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -796,14 +854,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-CONFIG_SENSORS_AD5252=m
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -820,13 +870,18 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -842,6 +897,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -852,11 +908,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # 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
 
@@ -878,26 +938,18 @@ 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_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_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 is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -929,9 +981,6 @@ CONFIG_FB_CFB_IMAGEBLIT=m
 # CONFIG_FB_BFIN_T350MCQB is not set
 # CONFIG_FB_BFIN_LQ035Q1 is not set
 CONFIG_FB_BF537_LQ035=m
-CONFIG_LQ035_SLAVE_ADDR=0x58
-# CONFIG_FB_BFIN_LANDSCAPE is not set
-# CONFIG_FB_BFIN_BGR is not set
 CONFIG_FB_BFIN_7393=m
 CONFIG_NTSC=y
 # CONFIG_PAL is not set
@@ -946,15 +995,18 @@ CONFIG_ADV7393_1XMEM=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=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
 # CONFIG_LCD_VGG2432A4 is not set
 # CONFIG_LCD_PLATFORM is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=m
-CONFIG_BACKLIGHT_CORGI=m
+CONFIG_BACKLIGHT_GENERIC=m
+# CONFIG_BACKLIGHT_ADP8870 is not set
 
 #
 # Display device support
@@ -963,19 +1015,27 @@ CONFIG_BACKLIGHT_CORGI=m
 # CONFIG_LOGO is not set
 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_JACK=y
 # CONFIG_SND_SEQUENCER is not set
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
 CONFIG_SND_PCM_OSS_PLUGINS=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_MTPAV is not set
@@ -986,13 +1046,6 @@ CONFIG_SND_SPI=y
 #
 # ALSA Blackfin devices
 #
-CONFIG_SND_BLACKFIN_AD1836=m
-CONFIG_SND_BLACKFIN_AD1836_TDM=y
-# CONFIG_SND_BLACKFIN_AD1836_I2S is not set
-CONFIG_SND_BLACKFIN_AD1836_MULSUB=y
-# CONFIG_SND_BLACKFIN_AD1836_5P1 is not set
-CONFIG_SND_BLACKFIN_SPORT=0
-CONFIG_SND_BLACKFIN_SPI_PFBIT=4
 CONFIG_SND_BFIN_SPORT=0
 CONFIG_SND_BFIN_AD73322=m
 CONFIG_SND_BFIN_AD73322_SPORT0_SE=10
@@ -1003,16 +1056,20 @@ CONFIG_SND_SOC_AC97_BUS=y
 CONFIG_SND_BF5XX_I2S=m
 # CONFIG_SND_BF5XX_SOC_SSM2602 is not set
 CONFIG_SND_BF5XX_SOC_AD73311=m
+# CONFIG_SND_BF5XX_SOC_ADAU1371 is not set
+# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set
 CONFIG_SND_BFIN_AD73311_SE=4
+# CONFIG_SND_BF5XX_TDM is not set
 CONFIG_SND_BF5XX_AC97=m
 CONFIG_SND_BF5XX_MMAP_SUPPORT=y
 # CONFIG_SND_BF5XX_MULTICHAN_SUPPORT is not set
+# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+CONFIG_SND_BF5XX_SOC_AD1980=m
 CONFIG_SND_BF5XX_SOC_SPORT=m
 CONFIG_SND_BF5XX_SOC_I2S=m
 CONFIG_SND_BF5XX_SOC_AC97=m
-CONFIG_SND_BF5XX_SOC_AD1980=m
 CONFIG_SND_BF5XX_SPORT_NUM=0
-# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+CONFIG_SND_SOC_I2C_AND_SPI=m
 # CONFIG_SND_SOC_ALL_CODECS is not set
 CONFIG_SND_SOC_AD1980=m
 CONFIG_SND_SOC_AD73311=m
@@ -1020,14 +1077,12 @@ CONFIG_SND_SOC_AD73311=m
 CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 # CONFIG_HID_PID is not set
 
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1064,6 +1119,7 @@ CONFIG_RTC_INTF_DEV=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
@@ -1075,6 +1131,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
@@ -1095,9 +1152,20 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
+#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
 #
 # File systems
 #
@@ -1107,9 +1175,13 @@ CONFIG_RTC_DRV_BFIN=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 is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1118,6 +1190,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
 
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
 #
 # CD-ROM/DVD Filesystems
 #
@@ -1137,13 +1214,9 @@ CONFIG_INOTIFY_USER=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1162,17 +1235,8 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # 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
@@ -1191,7 +1255,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1256,14 +1319,19 @@ 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
+CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 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 is not set
 # CONFIG_TIMER_STATS is not set
@@ -1271,31 +1339,39 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SLAB 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
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1320,6 +1396,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1328,14 +1405,14 @@ CONFIG_ACCESS_CHECK=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 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
@@ -1367,11 +1444,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
@@ -1408,6 +1487,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1415,11 +1495,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1429,6 +1511,8 @@ CONFIG_CRC32=y
 # 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
index 09ea2499555e1928f63aaa31c5f502f7ae8c0e39..bc1871d89fd5f034c7ab4cefd8ddd813cbde2efe 100644 (file)
@@ -1,22 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
-# Thu May 21 05:50:01 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+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_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # 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 is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -62,6 +86,10 @@ CONFIG_EPOLL=y
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -69,11 +97,15 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=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_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -101,7 +130,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -132,15 +160,15 @@ CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_BF537 is not set
 CONFIG_BF538=y
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=4
@@ -246,7 +274,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_TICKSOURCE_GPTMR0 is not set
 CONFIG_TICKSOURCE_CORETMR=y
-# CONFIG_CYCLES_CLOCKSOURCE is not set
+CONFIG_CYCLES_CLOCKSOURCE=y
 # CONFIG_GPTMR0_CLOCKSOURCE is not set
 CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
@@ -298,7 +326,6 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
@@ -307,16 +334,18 @@ CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -327,7 +356,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -383,11 +412,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -411,7 +435,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -422,6 +445,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
@@ -435,14 +459,34 @@ 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_HAMRADIO is not set
-# CONFIG_CAN is not set
+CONFIG_CAN=m
+CONFIG_CAN_RAW=m
+CONFIG_CAN_BCM=m
+
+#
+# CAN Device Drivers
+#
+# CONFIG_CAN_VCAN is not set
+CONFIG_CAN_DEV=m
+# CONFIG_CAN_CALC_BITTIMING is not set
+CONFIG_CAN_BFIN=m
+# CONFIG_CAN_SJA1000 is not set
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_EMS_USB is not set
+# CONFIG_CAN_DEBUG_DEVICES is not set
 CONFIG_IRDA=m
 
 #
@@ -481,13 +525,8 @@ CONFIG_SIR_BFIN_DMA=y
 #
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -508,6 +547,7 @@ 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_REDBOOT_PARTS is not set
@@ -566,6 +606,7 @@ CONFIG_MTD_PHYSMAP=m
 #
 # 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
@@ -581,17 +622,17 @@ 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_BFIN=m
-CONFIG_BFIN_NAND_BASE=0x20212000
-CONFIG_BFIN_NAND_CLE=2
-CONFIG_BFIN_NAND_ALE=1
-CONFIG_BFIN_NAND_READY=3
 CONFIG_MTD_NAND_IDS=m
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
 # CONFIG_MTD_NAND_PLATFORM is not set
 # CONFIG_MTD_ONENAND is not set
 
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
 #
 # UBI - Unsorted block images
 #
@@ -643,14 +684,20 @@ CONFIG_SMSC_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
 CONFIG_MII=y
 CONFIG_SMC91X=y
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -659,15 +706,16 @@ CONFIG_SMC91X=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 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN 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
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -700,14 +748,17 @@ CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
 # CONFIG_TOUCHSCREEN_AD7877 is not set
 # CONFIG_TOUCHSCREEN_AD7879_I2C is not set
 CONFIG_TOUCHSCREEN_AD7879_SPI=y
 CONFIG_TOUCHSCREEN_AD7879=y
-# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
 # CONFIG_TOUCHSCREEN_FUJITSU is not set
 # 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
@@ -715,9 +766,13 @@ CONFIG_TOUCHSCREEN_AD7879=y
 # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
 # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
 # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_UINPUT is not set
-# CONFIG_CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
 
 #
 # Hardware I/O ports
@@ -728,16 +783,13 @@ CONFIG_INPUT_MISC=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 CONFIG_BFIN_SPORT=m
-# CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_BFIN_TWI_LCD is not set
-CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_BFIN_JTAG_COMM=m
@@ -751,6 +803,7 @@ CONFIG_BFIN_JTAG_COMM=m
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -765,12 +818,8 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -778,6 +827,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 # CONFIG_I2C_CHARDEV is not set
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -810,14 +860,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -834,13 +876,18 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
@@ -856,6 +903,7 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -866,11 +914,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # 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
 
@@ -892,26 +944,17 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# 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_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 is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -947,6 +990,7 @@ CONFIG_FB_BFIN_LQ035Q1=m
 # 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 is not set
 
 #
@@ -957,14 +1001,12 @@ CONFIG_FB_BFIN_LQ035Q1=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
 
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1001,6 +1043,7 @@ CONFIG_RTC_INTF_DEV=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
@@ -1012,6 +1055,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
@@ -1032,9 +1076,20 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
+#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
 #
 # File systems
 #
@@ -1044,9 +1099,13 @@ CONFIG_RTC_DRV_BFIN=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 is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1055,6 +1114,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
 
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
 #
 # CD-ROM/DVD Filesystems
 #
@@ -1074,13 +1138,9 @@ CONFIG_INOTIFY_USER=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1099,17 +1159,8 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-CONFIG_YAFFS_FS=m
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # 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
@@ -1128,7 +1179,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1193,14 +1243,19 @@ 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
+CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 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 is not set
 # CONFIG_TIMER_STATS is not set
@@ -1208,31 +1263,39 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SLAB 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
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1257,6 +1320,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1265,14 +1329,14 @@ CONFIG_ACCESS_CHECK=y
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 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
@@ -1304,11 +1368,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
@@ -1345,6 +1411,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1352,11 +1419,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1366,6 +1435,8 @@ CONFIG_CRC32=y
 # 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
index eb3e98b6f3f076a58a60cc952bc844cb05e7ac3a..ca309cfc6ac483a920a7dec626fb82377b64b047 100644 (file)
@@ -1,7 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31.5
-# Mon Nov  2 22:02:56 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -12,7 +11,6 @@ CONFIG_GENERIC_CSUM=y
 CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
@@ -49,11 +47,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
@@ -89,24 +88,23 @@ CONFIG_EPOLL=y
 # CONFIG_AIO is not set
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
 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_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 
 #
 # GCOV-based kernel profiling
 #
 # CONFIG_GCOV_KERNEL is not set
-# CONFIG_SLOW_WORK is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_SLOW_WORK_DEBUG is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_BASE_SMALL=0
@@ -163,15 +161,15 @@ CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_BF537 is not set
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
 CONFIG_BF548_std=y
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=0
@@ -185,7 +183,6 @@ CONFIG_BF_REV_0_2=y
 # CONFIG_BF_REV_0_6 is not set
 # CONFIG_BF_REV_ANY is not set
 # CONFIG_BF_REV_NONE is not set
-CONFIG_BF54x=y
 CONFIG_IRQ_PLL_WAKEUP=7
 CONFIG_IRQ_RTC=8
 CONFIG_IRQ_SPORT0_RX=9
@@ -221,6 +218,8 @@ CONFIG_IRQ_SPI1=10
 CONFIG_IRQ_SPI2=10
 CONFIG_IRQ_TWI0=11
 CONFIG_IRQ_TWI1=11
+CONFIG_BF548=y
+CONFIG_BF54x=y
 CONFIG_BFIN548_EZKIT=y
 # CONFIG_BFIN548_BLUETECHNIX_CM is not set
 
@@ -387,12 +386,14 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 CONFIG_DMA_UNCACHED_2M=y
 # CONFIG_DMA_UNCACHED_1M is not set
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
@@ -505,6 +506,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
@@ -528,7 +530,24 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
+CONFIG_CAN=m
+CONFIG_CAN_RAW=m
+CONFIG_CAN_BCM=m
+
+#
+# CAN Device Drivers
+#
+# CONFIG_CAN_VCAN is not set
+CONFIG_CAN_DEV=m
+# CONFIG_CAN_CALC_BITTIMING is not set
+CONFIG_CAN_BFIN=m
+# CONFIG_CAN_SJA1000 is not set
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_EMS_USB is not set
+# CONFIG_CAN_DEBUG_DEVICES is not set
 CONFIG_IRDA=m
 
 #
@@ -663,6 +682,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
@@ -711,10 +731,10 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
-# CONFIG_AD525X_DPOT is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -767,7 +787,8 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
-CONFIG_SATA_PMP=y
+CONFIG_ATA_VERBOSE_ERROR=y
+# CONFIG_SATA_PMP is not set
 CONFIG_ATA_SFF=y
 # CONFIG_SATA_MV is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -808,6 +829,7 @@ CONFIG_MII=y
 # CONFIG_ETHOC is not set
 CONFIG_SMSC911X=y
 # CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -818,12 +840,10 @@ CONFIG_SMSC911X=y
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
 # CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL 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=y
 CONFIG_LIBERTAS=m
@@ -877,10 +897,12 @@ CONFIG_INPUT_EVBUG=m
 CONFIG_INPUT_KEYBOARD=y
 # CONFIG_KEYBOARD_ADP5588 is not set
 # CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_QT2160 is not set
 CONFIG_KEYBOARD_BFIN=y
 # 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
@@ -900,6 +922,7 @@ CONFIG_TOUCHSCREEN_AD7877=m
 # 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
@@ -910,7 +933,6 @@ CONFIG_TOUCHSCREEN_AD7877=m
 # 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=y
 # CONFIG_INPUT_ATI_REMOTE is not set
 # CONFIG_INPUT_ATI_REMOTE2 is not set
@@ -976,11 +998,6 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_OTP=y
 # CONFIG_BFIN_OTP_WRITE_ENABLE is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -988,6 +1005,7 @@ CONFIG_BFIN_OTP=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
 
@@ -1021,9 +1039,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # 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
@@ -1078,11 +1093,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # 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
 
@@ -1116,8 +1135,10 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 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
@@ -1192,6 +1213,7 @@ CONFIG_LOGO=y
 CONFIG_LOGO_BLACKFIN_CLUT224=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
@@ -1245,7 +1267,6 @@ CONFIG_SND_SOC_AD1980=y
 CONFIG_AC97_BUS=y
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 
 #
@@ -1268,6 +1289,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
@@ -1422,10 +1444,11 @@ CONFIG_MMC_BLOCK_BOUNCE=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_SPI is not set
 CONFIG_SDH_BFIN=y
 # CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND is not set
-# CONFIG_SDH_BFIN_ENABLE_SDIO_IRQ is not set
-# CONFIG_MMC_SPI is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
@@ -1472,6 +1495,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
@@ -1522,6 +1546,7 @@ CONFIG_FS_MBCACHE=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
@@ -1563,7 +1588,6 @@ CONFIG_NTFS_RW=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
 CONFIG_MISC_FILESYSTEMS=y
@@ -1595,7 +1619,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=m
 CONFIG_NFS_V3=y
@@ -1680,6 +1703,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
@@ -1714,12 +1738,14 @@ 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 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_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
@@ -1730,7 +1756,6 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_VERBOSE=y
@@ -1766,7 +1791,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
@@ -1798,11 +1822,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
index b9b0f93d0bd306025c35235a62e5757dc949b1c8..6a776ce75e9cdc5361d73b1e472e17fc827cbf1f 100644 (file)
@@ -114,7 +114,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBDAF=y
+# CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -1486,19 +1486,10 @@ CONFIG_DEBUG_INFO=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=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_FTRACE is not set
+# CONFIG_BRANCH_PROFILE_NONE is not set
 # 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_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
index e3ecdcc3e76b9079eb60bce9107f5912720cd6d6..792ff093883570b4841264c3a05f1a42551ca882 100644 (file)
@@ -1,7 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31.5
-# Mon Nov  2 21:59:31 2009
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -12,7 +11,6 @@ CONFIG_GENERIC_CSUM=y
 CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
@@ -49,11 +47,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
@@ -89,17 +88,15 @@ CONFIG_EPOLL=y
 # CONFIG_AIO is not set
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
 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_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 
 #
@@ -163,15 +160,15 @@ CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_BF537 is not set
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 CONFIG_BF561=y
 # CONFIG_SMP is not set
@@ -180,9 +177,9 @@ CONFIG_BF_REV_MAX=5
 # CONFIG_BF_REV_0_0 is not set
 # CONFIG_BF_REV_0_1 is not set
 # CONFIG_BF_REV_0_2 is not set
-# CONFIG_BF_REV_0_3 is not set
+CONFIG_BF_REV_0_3=y
 # CONFIG_BF_REV_0_4 is not set
-CONFIG_BF_REV_0_5=y
+# CONFIG_BF_REV_0_5 is not set
 # CONFIG_BF_REV_0_6 is not set
 # CONFIG_BF_REV_ANY is not set
 # CONFIG_BF_REV_NONE is not set
@@ -298,7 +295,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_TICKSOURCE_GPTMR0 is not set
 CONFIG_TICKSOURCE_CORETMR=y
-# CONFIG_CYCLES_CLOCKSOURCE is not set
+CONFIG_CYCLES_CLOCKSOURCE=y
 # CONFIG_GPTMR0_CLOCKSOURCE is not set
 CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
@@ -353,12 +350,14 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
@@ -370,9 +369,11 @@ CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
-CONFIG_BFIN_EXTMEM_WRITEBACK=y
-# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
-# CONFIG_BFIN_L2_DCACHEABLE is not set
+# CONFIG_BFIN_EXTMEM_WRITEBACK is not set
+CONFIG_BFIN_EXTMEM_WRITETHROUGH=y
+CONFIG_BFIN_L2_DCACHEABLE=y
+# CONFIG_BFIN_L2_WRITEBACK is not set
+CONFIG_BFIN_L2_WRITETHROUGH=y
 
 #
 # Memory Protection Unit
@@ -472,6 +473,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
@@ -613,6 +615,7 @@ CONFIG_MTD_PHYSMAP=m
 #
 # 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
@@ -685,6 +688,7 @@ CONFIG_SMC91X=y
 # CONFIG_ETHOC is not set
 # CONFIG_SMSC911X is not set
 # CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -695,14 +699,10 @@ CONFIG_SMC91X=y
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
 # CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_WLAN is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -782,11 +782,6 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-# CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -838,11 +833,15 @@ CONFIG_GPIO_SYSFS=y
 #
 # 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
 
@@ -865,6 +864,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 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
 # CONFIG_MEDIA_SUPPORT is not set
@@ -884,7 +884,6 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 # CONFIG_HID_PID is not set
 
@@ -923,6 +922,7 @@ CONFIG_HID=m
 # 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
@@ -957,7 +957,6 @@ CONFIG_INOTIFY_USER=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
 CONFIG_MISC_FILESYSTEMS=y
@@ -989,7 +988,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=m
 CONFIG_NFS_V3=y
@@ -1064,6 +1062,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
@@ -1098,26 +1097,24 @@ 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 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_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
-# CONFIG_BRANCH_PROFILE_NONE is not set
-# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
-# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_DYNAMIC_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_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_VERBOSE=y
@@ -1153,7 +1150,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
@@ -1185,11 +1181,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
index bc7fae3d8b8327521ef23586bb03807ea4228e61..ed0a7ebeb85cb49b1d0ab9c2225a7c1dee318f7d 100644 (file)
@@ -834,13 +834,6 @@ CONFIG_SND_VERBOSE_PROCFS=y
 #
 # ALSA Blackfin devices
 #
-CONFIG_SND_BLACKFIN_AD1836=m
-CONFIG_SND_BLACKFIN_AD1836_TDM=y
-# CONFIG_SND_BLACKFIN_AD1836_I2S is not set
-CONFIG_SND_BLACKFIN_AD1836_MULSUB=y
-# CONFIG_SND_BLACKFIN_AD1836_5P1 is not set
-CONFIG_SND_BLACKFIN_SPORT=0
-CONFIG_SND_BLACKFIN_SPI_PFBIT=4
 # CONFIG_SND_BFIN_AD73311 is not set
 
 #
index 67d12768602a6760010d0f64366d2deb6140e747..ad58fede1f4186165a57aa9227a3a12f92c51648 100644 (file)
@@ -1,21 +1,27 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28.10
+# Linux kernel version: 2.6.32.2
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -25,16 +31,32 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+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_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
@@ -58,6 +80,10 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -65,11 +91,14 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_MMAP_ALLOW_UNINITIALIZED=y
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -77,11 +106,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+# CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -97,7 +123,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
@@ -128,15 +153,15 @@ CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_BF537=y
 # CONFIG_BF538 is not set
 # CONFIG_BF539 is not set
-# CONFIG_BF542 is not set
+# CONFIG_BF542_std is not set
 # CONFIG_BF542M is not set
-# CONFIG_BF544 is not set
+# CONFIG_BF544_std is not set
 # CONFIG_BF544M is not set
-# CONFIG_BF547 is not set
+# CONFIG_BF547_std is not set
 # CONFIG_BF547M is not set
-# CONFIG_BF548 is not set
+# CONFIG_BF548_std is not set
 # CONFIG_BF548M is not set
-# CONFIG_BF549 is not set
+# CONFIG_BF549_std is not set
 # CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
 CONFIG_BF_REV_MIN=2
@@ -180,7 +205,8 @@ CONFIG_IRQ_MEM_DMA1=13
 CONFIG_IRQ_WATCH=13
 CONFIG_IRQ_SPI=10
 # CONFIG_BFIN537_STAMP is not set
-# CONFIG_BFIN537_BLUETECHNIX_CM is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM_E is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM_U is not set
 # CONFIG_BFIN537_BLUETECHNIX_TCM is not set
 CONFIG_PNAV10=y
 # CONFIG_CAMSIG_MINOTAUR is not set
@@ -282,7 +308,6 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
@@ -291,16 +316,18 @@ CONFIG_BFIN_GPTIMERS=y
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
 # CONFIG_DMA_UNCACHED_NONE is not set
 
 #
 # Cache Support
 #
 CONFIG_BFIN_ICACHE=y
-# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_DCACHE=y
 # CONFIG_BFIN_DCACHE_BANKA is not set
-CONFIG_BFIN_EXTMEM_ICACHEABLE=y
 CONFIG_BFIN_EXTMEM_DCACHEABLE=y
 CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
@@ -311,7 +338,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y
 # CONFIG_MPU is not set
 
 #
-# Asynchonous Memory Configuration
+# Asynchronous Memory Configuration
 #
 
 #
@@ -367,11 +394,6 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -395,7 +417,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -406,6 +427,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
@@ -419,7 +441,10 @@ 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
@@ -430,13 +455,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -455,6 +475,7 @@ 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_REDBOOT_PARTS is not set
@@ -506,6 +527,7 @@ CONFIG_MTD_UCLINUX=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
@@ -521,17 +543,17 @@ CONFIG_MTD_NAND=y
 # 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_BFIN=y
-CONFIG_BFIN_NAND_BASE=0x20100000
-CONFIG_BFIN_NAND_CLE=2
-CONFIG_BFIN_NAND_ALE=1
-CONFIG_BFIN_NAND_READY=44
 CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
 # CONFIG_MTD_NAND_PLATFORM is not set
 # CONFIG_MTD_ONENAND is not set
 
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
 #
 # UBI - Unsorted block images
 #
@@ -549,10 +571,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# 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_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -587,6 +619,9 @@ CONFIG_PHYLIB=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
@@ -597,9 +632,12 @@ CONFIG_BFIN_TX_DESC_NUM=100
 CONFIG_BFIN_RX_DESC_NUM=100
 CONFIG_BFIN_MAC_RMII=y
 # CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X 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
@@ -608,15 +646,16 @@ CONFIG_BFIN_MAC_RMII=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 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN 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
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -649,14 +688,17 @@ CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
 CONFIG_TOUCHSCREEN_AD7877=y
 # CONFIG_TOUCHSCREEN_AD7879_I2C is not set
 # CONFIG_TOUCHSCREEN_AD7879_SPI is not set
 # CONFIG_TOUCHSCREEN_AD7879 is not set
-# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
 # CONFIG_TOUCHSCREEN_FUJITSU is not set
 # 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
@@ -665,6 +707,7 @@ CONFIG_TOUCHSCREEN_AD7877=y
 # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
 # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
 # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_ATI_REMOTE is not set
 # CONFIG_INPUT_ATI_REMOTE2 is not set
@@ -673,7 +716,9 @@ CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_YEALINK is not set
 # CONFIG_INPUT_CM109 is not set
 CONFIG_INPUT_UINPUT=y
-# CONFIG_CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
 
 #
 # Hardware I/O ports
@@ -684,16 +729,13 @@ CONFIG_INPUT_UINPUT=y
 #
 # Character devices
 #
-# CONFIG_AD9960 is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 # CONFIG_BFIN_PPI is not set
 # CONFIG_BFIN_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BFIN_SPI_ADC is not set
 CONFIG_BFIN_SPORT=y
-# CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_BFIN_TWI_LCD is not set
-# CONFIG_SIMPLE_GPIO is not set
 # CONFIG_VT is not set
 CONFIG_DEVKMEM=y
 # CONFIG_BFIN_JTAG_COMM is not set
@@ -707,6 +749,7 @@ CONFIG_DEVKMEM=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_DMA=y
@@ -719,24 +762,17 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# CAN, the car bus and industrial fieldbus
-#
-CONFIG_CAN4LINUX=y
-
-#
-# linux embedded drivers
-#
-CONFIG_CAN_BLACKFIN=m
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_HELPER_AUTO=y
 
@@ -769,14 +805,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY is not set
-CONFIG_SENSORS_PCF8574=m
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
@@ -792,20 +820,29 @@ CONFIG_SPI_BFIN=y
 # CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BFIN_SPORT is not set
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 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_SENSORS_AD5252 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
@@ -818,11 +855,13 @@ CONFIG_HWMON=y
 # 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_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
@@ -838,17 +877,24 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LM90 is not set
 # 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_MAX1111 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_SHT15 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_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
@@ -858,9 +904,8 @@ 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_SENSORS_LIS3_SPI is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -875,28 +920,19 @@ CONFIG_SSB_POSSIBLE=y
 # 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_PMIC_ADP5520 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_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -928,24 +964,24 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_BFIN_T350MCQB is not set
 # CONFIG_FB_BFIN_LQ035Q1 is not set
 CONFIG_FB_BF537_LQ035=y
-CONFIG_LQ035_SLAVE_ADDR=0x58
-CONFIG_FB_BFIN_LANDSCAPE=y
-# CONFIG_FB_BFIN_BGR is not set
 # CONFIG_FB_BFIN_7393 is not set
 # CONFIG_FB_HITACHI_TX09 is not set
 # CONFIG_FB_S1D13XXX 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=y
+# CONFIG_LCD_LMS283GF05 is not set
 # CONFIG_LCD_LTV350QV is not set
 # CONFIG_LCD_ILI9320 is not set
 # CONFIG_LCD_TDO24M is not set
 # CONFIG_LCD_VGG2432A4 is not set
 # CONFIG_LCD_PLATFORM is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_GENERIC=y
+# CONFIG_BACKLIGHT_ADP8870 is not set
 
 #
 # Display device support
@@ -954,6 +990,7 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y
 # CONFIG_LOGO is not set
 CONFIG_SOUND=y
 CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
 CONFIG_SND=m
 # CONFIG_SND_SEQUENCER is not set
 # CONFIG_SND_MIXER_OSS is not set
@@ -963,6 +1000,11 @@ CONFIG_SND=m
 # CONFIG_SND_VERBOSE_PROCFS is not set
 # 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_MTPAV is not set
@@ -973,7 +1015,6 @@ CONFIG_SND_SPI=y
 #
 # ALSA Blackfin devices
 #
-# CONFIG_SND_BLACKFIN_AD1836 is not set
 # CONFIG_SND_BFIN_AD73322 is not set
 # CONFIG_SND_SOC is not set
 CONFIG_SOUND_PRIME=y
@@ -993,9 +1034,13 @@ CONFIG_USB_ARCH_HAS_HCD=y
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1031,6 +1076,7 @@ CONFIG_RTC_INTF_DEV=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
@@ -1042,6 +1088,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
@@ -1062,9 +1109,20 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_BFIN=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
+#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
 #
 # File systems
 #
@@ -1078,9 +1136,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 is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1089,6 +1151,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
 
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
 #
 # CD-ROM/DVD Filesystems
 #
@@ -1108,13 +1175,9 @@ CONFIG_INOTIFY_USER=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1123,17 +1186,8 @@ CONFIG_SYSFS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
-CONFIG_YAFFS_FS=y
-CONFIG_YAFFS_YAFFS1=y
-# CONFIG_YAFFS_9BYTE_TAGS is not set
-# CONFIG_YAFFS_DOES_ECC is not set
-CONFIG_YAFFS_YAFFS2=y
-CONFIG_YAFFS_AUTO_YAFFS2=y
-# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
-# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
-# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
-CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
 # 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
@@ -1152,7 +1206,6 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1217,18 +1270,19 @@ 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
+CONFIG_DEBUG_SECTION_MISMATCH=y
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_DEBUG_VERBOSE=y
@@ -1245,6 +1299,7 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
 # CONFIG_EARLY_PRINTK is not set
 # CONFIG_CPLB_INFO is not set
 # CONFIG_ACCESS_CHECK is not set
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
 
 #
 # Security options
@@ -1253,14 +1308,14 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
 CONFIG_SECURITY=y
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO is not set
 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
@@ -1292,11 +1347,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
@@ -1333,6 +1390,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1340,11 +1398,13 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1356,3 +1416,4 @@ CONFIG_ZLIB_INFLATE=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/blackfin/configs/TCM-BF518_defconfig b/arch/blackfin/configs/TCM-BF518_defconfig
new file mode 100644 (file)
index 0000000..4d31e2a
--- /dev/null
@@ -0,0 +1,1375 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32.3
+#
+# CONFIG_MMU is not set
+# CONFIG_FPU is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BLACKFIN=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_BUG=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+# CONFIG_KERNEL_GZIP is not set
+# CONFIG_KERNEL_BZIP2 is not set
+CONFIG_KERNEL_LZMA=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+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_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+CONFIG_EPOLL=y
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_MMAP_ALLOW_UNINITIALIZED=y
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=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_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+# CONFIG_FREEZER is not set
+
+#
+# Blackfin Processor Options
+#
+
+#
+# Processor and Board Settings
+#
+# CONFIG_BF512 is not set
+# CONFIG_BF514 is not set
+# CONFIG_BF516 is not set
+CONFIG_BF518=y
+# CONFIG_BF522 is not set
+# CONFIG_BF523 is not set
+# CONFIG_BF524 is not set
+# CONFIG_BF525 is not set
+# CONFIG_BF526 is not set
+# CONFIG_BF527 is not set
+# CONFIG_BF531 is not set
+# CONFIG_BF532 is not set
+# CONFIG_BF533 is not set
+# CONFIG_BF534 is not set
+# CONFIG_BF536 is not set
+# CONFIG_BF537 is not set
+# CONFIG_BF538 is not set
+# CONFIG_BF539 is not set
+# CONFIG_BF542_std is not set
+# CONFIG_BF542M is not set
+# CONFIG_BF544_std is not set
+# CONFIG_BF544M is not set
+# CONFIG_BF547_std is not set
+# CONFIG_BF547M is not set
+# CONFIG_BF548_std is not set
+# CONFIG_BF548M is not set
+# CONFIG_BF549_std is not set
+# CONFIG_BF549M is not set
+# CONFIG_BF561 is not set
+CONFIG_BF_REV_MIN=0
+CONFIG_BF_REV_MAX=2
+# CONFIG_BF_REV_0_0 is not set
+CONFIG_BF_REV_0_1=y
+# CONFIG_BF_REV_0_2 is not set
+# CONFIG_BF_REV_0_3 is not set
+# CONFIG_BF_REV_0_4 is not set
+# CONFIG_BF_REV_0_5 is not set
+# CONFIG_BF_REV_0_6 is not set
+# CONFIG_BF_REV_ANY is not set
+# CONFIG_BF_REV_NONE is not set
+CONFIG_BF51x=y
+# CONFIG_BFIN518F_EZBRD is not set
+CONFIG_BFIN518F_TCM=y
+
+#
+# BF518 Specific Configuration
+#
+
+#
+# Alternative Multiplexing Scheme
+#
+# CONFIG_BF518_SPORT0_PORTF is not set
+CONFIG_BF518_SPORT0_PORTG=y
+CONFIG_BF518_SPORT0_TSCLK_PG10=y
+# CONFIG_BF518_SPORT0_TSCLK_PG14 is not set
+CONFIG_BF518_UART1_PORTF=y
+# CONFIG_BF518_UART1_PORTG is not set
+
+#
+# Interrupt Priority Assignment
+#
+
+#
+# Priority
+#
+CONFIG_IRQ_PLL_WAKEUP=7
+CONFIG_IRQ_DMA0_ERROR=7
+CONFIG_IRQ_DMAR0_BLK=7
+CONFIG_IRQ_DMAR1_BLK=7
+CONFIG_IRQ_DMAR0_OVR=7
+CONFIG_IRQ_DMAR1_OVR=7
+CONFIG_IRQ_PPI_ERROR=7
+CONFIG_IRQ_MAC_ERROR=7
+CONFIG_IRQ_SPORT0_ERROR=7
+CONFIG_IRQ_SPORT1_ERROR=7
+CONFIG_IRQ_PTP_ERROR=7
+CONFIG_IRQ_UART0_ERROR=7
+CONFIG_IRQ_UART1_ERROR=7
+CONFIG_IRQ_RTC=8
+CONFIG_IRQ_PPI=8
+CONFIG_IRQ_SPORT0_RX=9
+CONFIG_IRQ_SPORT0_TX=9
+CONFIG_IRQ_SPORT1_RX=9
+CONFIG_IRQ_SPORT1_TX=9
+CONFIG_IRQ_TWI=10
+CONFIG_IRQ_SPI0=10
+CONFIG_IRQ_UART0_RX=10
+CONFIG_IRQ_UART0_TX=10
+CONFIG_IRQ_UART1_RX=10
+CONFIG_IRQ_UART1_TX=10
+CONFIG_IRQ_OPTSEC=11
+CONFIG_IRQ_CNT=11
+CONFIG_IRQ_MAC_RX=11
+CONFIG_IRQ_PORTH_INTA=11
+CONFIG_IRQ_MAC_TX=11
+CONFIG_IRQ_PORTH_INTB=11
+CONFIG_IRQ_TIMER0=12
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
+CONFIG_IRQ_TIMER3=12
+CONFIG_IRQ_TIMER4=12
+CONFIG_IRQ_TIMER5=12
+CONFIG_IRQ_TIMER6=12
+CONFIG_IRQ_TIMER7=12
+CONFIG_IRQ_PORTG_INTA=12
+CONFIG_IRQ_PORTG_INTB=12
+CONFIG_IRQ_MEM_DMA0=13
+CONFIG_IRQ_MEM_DMA1=13
+CONFIG_IRQ_WATCH=13
+CONFIG_IRQ_PORTF_INTA=13
+CONFIG_IRQ_PORTF_INTB=13
+CONFIG_IRQ_SPI0_ERROR=7
+CONFIG_IRQ_SPI1_ERROR=7
+CONFIG_IRQ_RSI_INT0=7
+CONFIG_IRQ_RSI_INT1=7
+CONFIG_IRQ_PWM_TRIP=10
+CONFIG_IRQ_PWM_SYNC=10
+CONFIG_IRQ_PTP_STAT=10
+
+#
+# Board customizations
+#
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_BOOT_LOAD=0x1000
+
+#
+# Clock/PLL Setup
+#
+CONFIG_CLKIN_HZ=25000000
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+CONFIG_MAX_VCO_HZ=400000000
+CONFIG_MIN_VCO_HZ=50000000
+CONFIG_MAX_SCLK_HZ=133333333
+CONFIG_MIN_SCLK_HZ=27000000
+
+#
+# Kernel Timer/Scheduler
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+
+#
+# Clock event device
+#
+# CONFIG_TICKSOURCE_GPTMR0 is not set
+CONFIG_TICKSOURCE_CORETMR=y
+
+#
+# Clock souce
+#
+# CONFIG_CYCLES_CLOCKSOURCE is not set
+# CONFIG_GPTMR0_CLOCKSOURCE is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# Misc
+#
+CONFIG_BFIN_SCRATCH_REG_RETN=y
+# CONFIG_BFIN_SCRATCH_REG_RETE is not set
+# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
+#
+# Memory Optimizations
+#
+CONFIG_I_ENTRY_L1=y
+CONFIG_EXCPT_IRQ_SYSC_L1=y
+CONFIG_DO_IRQ_L1=y
+CONFIG_CORE_TIMER_IRQ_L1=y
+CONFIG_IDLE_L1=y
+# CONFIG_SCHEDULE_L1 is not set
+CONFIG_ARITHMETIC_OPS_L1=y
+CONFIG_ACCESS_OK_L1=y
+# CONFIG_MEMSET_L1 is not set
+# CONFIG_MEMCPY_L1 is not set
+# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set
+# CONFIG_IP_CHECKSUM_L1 is not set
+CONFIG_CACHELINE_ALIGNED_L1=y
+# CONFIG_SYSCALL_TAB_L1 is not set
+# CONFIG_CPLB_SWITCH_TAB_L1 is not set
+CONFIG_APP_STACK_L1=y
+
+#
+# Speed Optimizations
+#
+CONFIG_BFIN_INS_LOWOVERHEAD=y
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
+CONFIG_BFIN_GPTIMERS=m
+# CONFIG_DMA_UNCACHED_4M is not set
+# CONFIG_DMA_UNCACHED_2M is not set
+CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_512K is not set
+# CONFIG_DMA_UNCACHED_256K is not set
+# CONFIG_DMA_UNCACHED_128K is not set
+# CONFIG_DMA_UNCACHED_NONE is not set
+
+#
+# Cache Support
+#
+CONFIG_BFIN_ICACHE=y
+CONFIG_BFIN_EXTMEM_ICACHEABLE=y
+CONFIG_BFIN_DCACHE=y
+# CONFIG_BFIN_DCACHE_BANKA is not set
+CONFIG_BFIN_EXTMEM_DCACHEABLE=y
+CONFIG_BFIN_EXTMEM_WRITEBACK=y
+# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set
+
+#
+# Memory Protection Unit
+#
+# CONFIG_MPU is not set
+
+#
+# Asynchronous Memory Configuration
+#
+
+#
+# EBIU_AMGCTL Global Control
+#
+CONFIG_C_AMCKEN=y
+CONFIG_C_CDPRIO=y
+# CONFIG_C_AMBEN is not set
+# CONFIG_C_AMBEN_B0 is not set
+# CONFIG_C_AMBEN_B0_B1 is not set
+# CONFIG_C_AMBEN_B0_B1_B2 is not set
+CONFIG_C_AMBEN_ALL=y
+
+#
+# EBIU_AMBCTL Control
+#
+CONFIG_BANK_0=0x7BB0
+CONFIG_BANK_1=0x7BB0
+CONFIG_BANK_2=0x7BB0
+CONFIG_BANK_3=0x99B2
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF_FDPIC=y
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# 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_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_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
+# 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_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+# CONFIG_MTD_CFI_I2 is not set
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=m
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_UCLINUX is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# 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
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# 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_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_BFIN_MAC=y
+CONFIG_BFIN_TX_DESC_NUM=10
+CONFIG_BFIN_RX_DESC_NUM=20
+# CONFIG_BFIN_MAC_RMII is not set
+CONFIG_BFIN_MAC_USE_HWSTAMP=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_ADF702X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_INPUT_PCF8574 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_BFIN_DMA_INTERFACE=m
+# CONFIG_BFIN_PPI is not set
+# CONFIG_BFIN_PPIFCD is not set
+# CONFIG_BFIN_SIMPLE_TIMER is not set
+# CONFIG_BFIN_SPI_ADC is not set
+# CONFIG_BFIN_SPORT is not set
+# CONFIG_BFIN_TWI_LCD is not set
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_BFIN_JTAG_COMM=m
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_BFIN=y
+CONFIG_SERIAL_BFIN_CONSOLE=y
+CONFIG_SERIAL_BFIN_DMA=y
+# CONFIG_SERIAL_BFIN_PIO is not set
+CONFIG_SERIAL_BFIN_UART0=y
+# CONFIG_BFIN_UART0_CTSRTS is not set
+# CONFIG_SERIAL_BFIN_UART1 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_BFIN_SPORT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_BFIN_OTP=y
+# CONFIG_BFIN_OTP_WRITE_ENABLE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_BLACKFIN_TWI=y
+CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM 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=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BFIN=y
+CONFIG_SPI_BFIN_LOCK=y
+# CONFIG_SPI_BFIN_SPORT is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_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
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# 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_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_BFIN_WDT=y
+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_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 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
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_DEBUG=y
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# 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_SPI=y
+# CONFIG_SDH_BFIN is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+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 is not set
+# 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
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_BFIN=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# Firmware Drivers
+#
+# CONFIG_FIRMWARE_MEMMAP is not set
+# CONFIG_SIGMA is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_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=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=m
+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_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=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
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+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 is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB 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
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+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_KGDB is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_VERBOSE=y
+CONFIG_DEBUG_MMRS=y
+CONFIG_DEBUG_HWERR=y
+CONFIG_EXACT_HWERR=y
+CONFIG_DEBUG_DOUBLEFAULT=y
+CONFIG_DEBUG_DOUBLEFAULT_PRINT=y
+# CONFIG_DEBUG_DOUBLEFAULT_RESET is not set
+# CONFIG_DEBUG_ICACHE_CHECK is not set
+CONFIG_DEBUG_HUNT_FOR_ZERO=y
+CONFIG_DEBUG_BFIN_HWTRACE_ON=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=1
+# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
+CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CPLB_INFO=y
+CONFIG_ACCESS_CHECK=y
+# CONFIG_BFIN_ISRAM_SELF_TEST is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITY_TOMOYO is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# 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
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_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_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
index 57bc21ac22968890dc1bfc1946d95708ccbd6054..836895156b5b6220ca25a41300313a2a8f2a1f1a 100644 (file)
@@ -8,6 +8,9 @@
 #ifndef BFIN_LQ035Q1_H
 #define BFIN_LQ035Q1_H
 
+/*
+ * LCD Modes
+ */
 #define LQ035_RL       (0 << 8)        /* Right -> Left Scan */
 #define LQ035_LR       (1 << 8)        /* Left -> Right Scan */
 #define LQ035_TB       (1 << 9)        /* Top -> Botton Scan */
 #define LQ035_NORM     (1 << 13)       /* Reversal */
 #define LQ035_REV      (0 << 13)       /* Reversal */
 
+/*
+ * PPI Modes
+ */
+
+#define USE_RGB565_16_BIT_PPI  1
+#define USE_RGB565_8_BIT_PPI   2
+#define USE_RGB888_8_BIT_PPI   3
+
 struct bfin_lq035q1fb_disp_info {
 
        unsigned        mode;
+       unsigned        ppi_mode;
        /* GPIOs */
        int             use_bl;
        unsigned        gpio_bl;
diff --git a/arch/blackfin/include/asm/bfin_can.h b/arch/blackfin/include/asm/bfin_can.h
new file mode 100644 (file)
index 0000000..eec0076
--- /dev/null
@@ -0,0 +1,725 @@
+/*
+ * bfin_can.h - interface to Blackfin CANs
+ *
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __ASM_BFIN_CAN_H__
+#define __ASM_BFIN_CAN_H__
+
+/*
+ * transmit and receive channels
+ */
+#define TRANSMIT_CHL            24
+#define RECEIVE_STD_CHL         0
+#define RECEIVE_EXT_CHL         4
+#define RECEIVE_RTR_CHL         8
+#define RECEIVE_EXT_RTR_CHL     12
+#define MAX_CHL_NUMBER          32
+
+/*
+ * All Blackfin system MMRs are padded to 32bits even if the register
+ * itself is only 16bits.  So use a helper macro to streamline this.
+ */
+#define __BFP(m) u16 m; u16 __pad_##m
+
+/*
+ * bfin can registers layout
+ */
+struct bfin_can_mask_regs {
+       __BFP(aml);
+       __BFP(amh);
+};
+
+struct bfin_can_channel_regs {
+       u16 data[8];
+       __BFP(dlc);
+       __BFP(tsv);
+       __BFP(id0);
+       __BFP(id1);
+};
+
+struct bfin_can_regs {
+       /*
+        * global control and status registers
+        */
+       __BFP(mc1);           /* offset 0x00 */
+       __BFP(md1);           /* offset 0x04 */
+       __BFP(trs1);          /* offset 0x08 */
+       __BFP(trr1);          /* offset 0x0c */
+       __BFP(ta1);           /* offset 0x10 */
+       __BFP(aa1);           /* offset 0x14 */
+       __BFP(rmp1);          /* offset 0x18 */
+       __BFP(rml1);          /* offset 0x1c */
+       __BFP(mbtif1);        /* offset 0x20 */
+       __BFP(mbrif1);        /* offset 0x24 */
+       __BFP(mbim1);         /* offset 0x28 */
+       __BFP(rfh1);          /* offset 0x2c */
+       __BFP(opss1);         /* offset 0x30 */
+       u32 __pad1[3];
+       __BFP(mc2);           /* offset 0x40 */
+       __BFP(md2);           /* offset 0x44 */
+       __BFP(trs2);          /* offset 0x48 */
+       __BFP(trr2);          /* offset 0x4c */
+       __BFP(ta2);           /* offset 0x50 */
+       __BFP(aa2);           /* offset 0x54 */
+       __BFP(rmp2);          /* offset 0x58 */
+       __BFP(rml2);          /* offset 0x5c */
+       __BFP(mbtif2);        /* offset 0x60 */
+       __BFP(mbrif2);        /* offset 0x64 */
+       __BFP(mbim2);         /* offset 0x68 */
+       __BFP(rfh2);          /* offset 0x6c */
+       __BFP(opss2);         /* offset 0x70 */
+       u32 __pad2[3];
+       __BFP(clock);         /* offset 0x80 */
+       __BFP(timing);        /* offset 0x84 */
+       __BFP(debug);         /* offset 0x88 */
+       __BFP(status);        /* offset 0x8c */
+       __BFP(cec);           /* offset 0x90 */
+       __BFP(gis);           /* offset 0x94 */
+       __BFP(gim);           /* offset 0x98 */
+       __BFP(gif);           /* offset 0x9c */
+       __BFP(control);       /* offset 0xa0 */
+       __BFP(intr);          /* offset 0xa4 */
+       u32 __pad3[1];
+       __BFP(mbtd);          /* offset 0xac */
+       __BFP(ewr);           /* offset 0xb0 */
+       __BFP(esr);           /* offset 0xb4 */
+       u32 __pad4[2];
+       __BFP(ucreg);         /* offset 0xc0 */
+       __BFP(uccnt);         /* offset 0xc4 */
+       __BFP(ucrc);          /* offset 0xc8 */
+       __BFP(uccnf);         /* offset 0xcc */
+       u32 __pad5[12];
+
+       /*
+        * channel(mailbox) mask and message registers
+        */
+       struct bfin_can_mask_regs msk[MAX_CHL_NUMBER];    /* offset 0x100 */
+       struct bfin_can_channel_regs chl[MAX_CHL_NUMBER]; /* offset 0x200 */
+};
+
+#undef __BFP
+
+/* CAN_CONTROL Masks */
+#define SRS                    0x0001  /* Software Reset */
+#define DNM                    0x0002  /* Device Net Mode */
+#define ABO                    0x0004  /* Auto-Bus On Enable */
+#define TXPRIO         0x0008  /* TX Priority (Priority/Mailbox*) */
+#define WBA                    0x0010  /* Wake-Up On CAN Bus Activity Enable */
+#define SMR                    0x0020  /* Sleep Mode Request */
+#define CSR                    0x0040  /* CAN Suspend Mode Request */
+#define CCR                    0x0080  /* CAN Configuration Mode Request */
+
+/* CAN_STATUS Masks */
+#define WT                     0x0001  /* TX Warning Flag */
+#define WR                     0x0002  /* RX Warning Flag */
+#define EP                     0x0004  /* Error Passive Mode */
+#define EBO                    0x0008  /* Error Bus Off Mode */
+#define SMA                    0x0020  /* Sleep Mode Acknowledge */
+#define CSA                    0x0040  /* Suspend Mode Acknowledge */
+#define CCA                    0x0080  /* Configuration Mode Acknowledge */
+#define MBPTR          0x1F00  /* Mailbox Pointer */
+#define TRM                    0x4000  /* Transmit Mode */
+#define REC                    0x8000  /* Receive Mode */
+
+/* CAN_CLOCK Masks */
+#define BRP                    0x03FF  /* Bit-Rate Pre-Scaler */
+
+/* CAN_TIMING Masks */
+#define TSEG1          0x000F  /* Time Segment 1 */
+#define TSEG2          0x0070  /* Time Segment 2 */
+#define SAM                    0x0080  /* Sampling */
+#define SJW                    0x0300  /* Synchronization Jump Width */
+
+/* CAN_DEBUG Masks */
+#define DEC                    0x0001  /* Disable CAN Error Counters */
+#define DRI                    0x0002  /* Disable CAN RX Input */
+#define DTO                    0x0004  /* Disable CAN TX Output */
+#define DIL                    0x0008  /* Disable CAN Internal Loop */
+#define MAA                    0x0010  /* Mode Auto-Acknowledge Enable */
+#define MRB                    0x0020  /* Mode Read Back Enable */
+#define CDE                    0x8000  /* CAN Debug Enable */
+
+/* CAN_CEC Masks */
+#define RXECNT         0x00FF  /* Receive Error Counter */
+#define TXECNT         0xFF00  /* Transmit Error Counter */
+
+/* CAN_INTR Masks */
+#define MBRIRQ 0x0001  /* Mailbox Receive Interrupt */
+#define MBTIRQ 0x0002  /* Mailbox Transmit Interrupt */
+#define GIRQ           0x0004  /* Global Interrupt */
+#define SMACK          0x0008  /* Sleep Mode Acknowledge */
+#define CANTX          0x0040  /* CAN TX Bus Value */
+#define CANRX          0x0080  /* CAN RX Bus Value */
+
+/* CAN_MBxx_ID1 and CAN_MBxx_ID0 Masks */
+#define DFC                    0xFFFF  /* Data Filtering Code (If Enabled) (ID0) */
+#define EXTID_LO       0xFFFF  /* Lower 16 Bits of Extended Identifier (ID0) */
+#define EXTID_HI       0x0003  /* Upper 2 Bits of Extended Identifier (ID1) */
+#define BASEID         0x1FFC  /* Base Identifier */
+#define IDE                    0x2000  /* Identifier Extension */
+#define RTR                    0x4000  /* Remote Frame Transmission Request */
+#define AME                    0x8000  /* Acceptance Mask Enable */
+
+/* CAN_MBxx_TIMESTAMP Masks */
+#define TSV                    0xFFFF  /* Timestamp */
+
+/* CAN_MBxx_LENGTH Masks */
+#define DLC                    0x000F  /* Data Length Code */
+
+/* CAN_AMxxH and CAN_AMxxL Masks */
+#define DFM                    0xFFFF  /* Data Field Mask (If Enabled) (CAN_AMxxL) */
+#define EXTID_LO       0xFFFF  /* Lower 16 Bits of Extended Identifier (CAN_AMxxL) */
+#define EXTID_HI       0x0003  /* Upper 2 Bits of Extended Identifier (CAN_AMxxH) */
+#define BASEID         0x1FFC  /* Base Identifier */
+#define AMIDE          0x2000  /* Acceptance Mask ID Extension Enable */
+#define FMD                    0x4000  /* Full Mask Data Field Enable */
+#define FDF                    0x8000  /* Filter On Data Field Enable */
+
+/* CAN_MC1 Masks */
+#define MC0                    0x0001  /* Enable Mailbox 0 */
+#define MC1                    0x0002  /* Enable Mailbox 1 */
+#define MC2                    0x0004  /* Enable Mailbox 2 */
+#define MC3                    0x0008  /* Enable Mailbox 3 */
+#define MC4                    0x0010  /* Enable Mailbox 4 */
+#define MC5                    0x0020  /* Enable Mailbox 5 */
+#define MC6                    0x0040  /* Enable Mailbox 6 */
+#define MC7                    0x0080  /* Enable Mailbox 7 */
+#define MC8                    0x0100  /* Enable Mailbox 8 */
+#define MC9                    0x0200  /* Enable Mailbox 9 */
+#define MC10           0x0400  /* Enable Mailbox 10 */
+#define MC11           0x0800  /* Enable Mailbox 11 */
+#define MC12           0x1000  /* Enable Mailbox 12 */
+#define MC13           0x2000  /* Enable Mailbox 13 */
+#define MC14           0x4000  /* Enable Mailbox 14 */
+#define MC15           0x8000  /* Enable Mailbox 15 */
+
+/* CAN_MC2 Masks */
+#define MC16           0x0001  /* Enable Mailbox 16 */
+#define MC17           0x0002  /* Enable Mailbox 17 */
+#define MC18           0x0004  /* Enable Mailbox 18 */
+#define MC19           0x0008  /* Enable Mailbox 19 */
+#define MC20           0x0010  /* Enable Mailbox 20 */
+#define MC21           0x0020  /* Enable Mailbox 21 */
+#define MC22           0x0040  /* Enable Mailbox 22 */
+#define MC23           0x0080  /* Enable Mailbox 23 */
+#define MC24           0x0100  /* Enable Mailbox 24 */
+#define MC25           0x0200  /* Enable Mailbox 25 */
+#define MC26           0x0400  /* Enable Mailbox 26 */
+#define MC27           0x0800  /* Enable Mailbox 27 */
+#define MC28           0x1000  /* Enable Mailbox 28 */
+#define MC29           0x2000  /* Enable Mailbox 29 */
+#define MC30           0x4000  /* Enable Mailbox 30 */
+#define MC31           0x8000  /* Enable Mailbox 31 */
+
+/* CAN_MD1 Masks */
+#define MD0                    0x0001  /* Enable Mailbox 0 For Receive */
+#define MD1                    0x0002  /* Enable Mailbox 1 For Receive */
+#define MD2                    0x0004  /* Enable Mailbox 2 For Receive */
+#define MD3                    0x0008  /* Enable Mailbox 3 For Receive */
+#define MD4                    0x0010  /* Enable Mailbox 4 For Receive */
+#define MD5                    0x0020  /* Enable Mailbox 5 For Receive */
+#define MD6                    0x0040  /* Enable Mailbox 6 For Receive */
+#define MD7                    0x0080  /* Enable Mailbox 7 For Receive */
+#define MD8                    0x0100  /* Enable Mailbox 8 For Receive */
+#define MD9                    0x0200  /* Enable Mailbox 9 For Receive */
+#define MD10           0x0400  /* Enable Mailbox 10 For Receive */
+#define MD11           0x0800  /* Enable Mailbox 11 For Receive */
+#define MD12           0x1000  /* Enable Mailbox 12 For Receive */
+#define MD13           0x2000  /* Enable Mailbox 13 For Receive */
+#define MD14           0x4000  /* Enable Mailbox 14 For Receive */
+#define MD15           0x8000  /* Enable Mailbox 15 For Receive */
+
+/* CAN_MD2 Masks */
+#define MD16           0x0001  /* Enable Mailbox 16 For Receive */
+#define MD17           0x0002  /* Enable Mailbox 17 For Receive */
+#define MD18           0x0004  /* Enable Mailbox 18 For Receive */
+#define MD19           0x0008  /* Enable Mailbox 19 For Receive */
+#define MD20           0x0010  /* Enable Mailbox 20 For Receive */
+#define MD21           0x0020  /* Enable Mailbox 21 For Receive */
+#define MD22           0x0040  /* Enable Mailbox 22 For Receive */
+#define MD23           0x0080  /* Enable Mailbox 23 For Receive */
+#define MD24           0x0100  /* Enable Mailbox 24 For Receive */
+#define MD25           0x0200  /* Enable Mailbox 25 For Receive */
+#define MD26           0x0400  /* Enable Mailbox 26 For Receive */
+#define MD27           0x0800  /* Enable Mailbox 27 For Receive */
+#define MD28           0x1000  /* Enable Mailbox 28 For Receive */
+#define MD29           0x2000  /* Enable Mailbox 29 For Receive */
+#define MD30           0x4000  /* Enable Mailbox 30 For Receive */
+#define MD31           0x8000  /* Enable Mailbox 31 For Receive */
+
+/* CAN_RMP1 Masks */
+#define RMP0           0x0001  /* RX Message Pending In Mailbox 0 */
+#define RMP1           0x0002  /* RX Message Pending In Mailbox 1 */
+#define RMP2           0x0004  /* RX Message Pending In Mailbox 2 */
+#define RMP3           0x0008  /* RX Message Pending In Mailbox 3 */
+#define RMP4           0x0010  /* RX Message Pending In Mailbox 4 */
+#define RMP5           0x0020  /* RX Message Pending In Mailbox 5 */
+#define RMP6           0x0040  /* RX Message Pending In Mailbox 6 */
+#define RMP7           0x0080  /* RX Message Pending In Mailbox 7 */
+#define RMP8           0x0100  /* RX Message Pending In Mailbox 8 */
+#define RMP9           0x0200  /* RX Message Pending In Mailbox 9 */
+#define RMP10          0x0400  /* RX Message Pending In Mailbox 10 */
+#define RMP11          0x0800  /* RX Message Pending In Mailbox 11 */
+#define RMP12          0x1000  /* RX Message Pending In Mailbox 12 */
+#define RMP13          0x2000  /* RX Message Pending In Mailbox 13 */
+#define RMP14          0x4000  /* RX Message Pending In Mailbox 14 */
+#define RMP15          0x8000  /* RX Message Pending In Mailbox 15 */
+
+/* CAN_RMP2 Masks */
+#define RMP16          0x0001  /* RX Message Pending In Mailbox 16 */
+#define RMP17          0x0002  /* RX Message Pending In Mailbox 17 */
+#define RMP18          0x0004  /* RX Message Pending In Mailbox 18 */
+#define RMP19          0x0008  /* RX Message Pending In Mailbox 19 */
+#define RMP20          0x0010  /* RX Message Pending In Mailbox 20 */
+#define RMP21          0x0020  /* RX Message Pending In Mailbox 21 */
+#define RMP22          0x0040  /* RX Message Pending In Mailbox 22 */
+#define RMP23          0x0080  /* RX Message Pending In Mailbox 23 */
+#define RMP24          0x0100  /* RX Message Pending In Mailbox 24 */
+#define RMP25          0x0200  /* RX Message Pending In Mailbox 25 */
+#define RMP26          0x0400  /* RX Message Pending In Mailbox 26 */
+#define RMP27          0x0800  /* RX Message Pending In Mailbox 27 */
+#define RMP28          0x1000  /* RX Message Pending In Mailbox 28 */
+#define RMP29          0x2000  /* RX Message Pending In Mailbox 29 */
+#define RMP30          0x4000  /* RX Message Pending In Mailbox 30 */
+#define RMP31          0x8000  /* RX Message Pending In Mailbox 31 */
+
+/* CAN_RML1 Masks */
+#define RML0           0x0001  /* RX Message Lost In Mailbox 0 */
+#define RML1           0x0002  /* RX Message Lost In Mailbox 1 */
+#define RML2           0x0004  /* RX Message Lost In Mailbox 2 */
+#define RML3           0x0008  /* RX Message Lost In Mailbox 3 */
+#define RML4           0x0010  /* RX Message Lost In Mailbox 4 */
+#define RML5           0x0020  /* RX Message Lost In Mailbox 5 */
+#define RML6           0x0040  /* RX Message Lost In Mailbox 6 */
+#define RML7           0x0080  /* RX Message Lost In Mailbox 7 */
+#define RML8           0x0100  /* RX Message Lost In Mailbox 8 */
+#define RML9           0x0200  /* RX Message Lost In Mailbox 9 */
+#define RML10          0x0400  /* RX Message Lost In Mailbox 10 */
+#define RML11          0x0800  /* RX Message Lost In Mailbox 11 */
+#define RML12          0x1000  /* RX Message Lost In Mailbox 12 */
+#define RML13          0x2000  /* RX Message Lost In Mailbox 13 */
+#define RML14          0x4000  /* RX Message Lost In Mailbox 14 */
+#define RML15          0x8000  /* RX Message Lost In Mailbox 15 */
+
+/* CAN_RML2 Masks */
+#define RML16          0x0001  /* RX Message Lost In Mailbox 16 */
+#define RML17          0x0002  /* RX Message Lost In Mailbox 17 */
+#define RML18          0x0004  /* RX Message Lost In Mailbox 18 */
+#define RML19          0x0008  /* RX Message Lost In Mailbox 19 */
+#define RML20          0x0010  /* RX Message Lost In Mailbox 20 */
+#define RML21          0x0020  /* RX Message Lost In Mailbox 21 */
+#define RML22          0x0040  /* RX Message Lost In Mailbox 22 */
+#define RML23          0x0080  /* RX Message Lost In Mailbox 23 */
+#define RML24          0x0100  /* RX Message Lost In Mailbox 24 */
+#define RML25          0x0200  /* RX Message Lost In Mailbox 25 */
+#define RML26          0x0400  /* RX Message Lost In Mailbox 26 */
+#define RML27          0x0800  /* RX Message Lost In Mailbox 27 */
+#define RML28          0x1000  /* RX Message Lost In Mailbox 28 */
+#define RML29          0x2000  /* RX Message Lost In Mailbox 29 */
+#define RML30          0x4000  /* RX Message Lost In Mailbox 30 */
+#define RML31          0x8000  /* RX Message Lost In Mailbox 31 */
+
+/* CAN_OPSS1 Masks */
+#define OPSS0          0x0001  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 0 */
+#define OPSS1          0x0002  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 1 */
+#define OPSS2          0x0004  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 2 */
+#define OPSS3          0x0008  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 3 */
+#define OPSS4          0x0010  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 4 */
+#define OPSS5          0x0020  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 5 */
+#define OPSS6          0x0040  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 6 */
+#define OPSS7          0x0080  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 7 */
+#define OPSS8          0x0100  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 8 */
+#define OPSS9          0x0200  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 9 */
+#define OPSS10         0x0400  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 10 */
+#define OPSS11         0x0800  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 11 */
+#define OPSS12         0x1000  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 12 */
+#define OPSS13         0x2000  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 13 */
+#define OPSS14         0x4000  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 14 */
+#define OPSS15         0x8000  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 15 */
+
+/* CAN_OPSS2 Masks */
+#define OPSS16         0x0001  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 16 */
+#define OPSS17         0x0002  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 17 */
+#define OPSS18         0x0004  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 18 */
+#define OPSS19         0x0008  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 19 */
+#define OPSS20         0x0010  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 20 */
+#define OPSS21         0x0020  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 21 */
+#define OPSS22         0x0040  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 22 */
+#define OPSS23         0x0080  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 23 */
+#define OPSS24         0x0100  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 24 */
+#define OPSS25         0x0200  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 25 */
+#define OPSS26         0x0400  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 26 */
+#define OPSS27         0x0800  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 27 */
+#define OPSS28         0x1000  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 28 */
+#define OPSS29         0x2000  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 29 */
+#define OPSS30         0x4000  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 30 */
+#define OPSS31         0x8000  /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 31 */
+
+/* CAN_TRR1 Masks */
+#define TRR0           0x0001  /* Deny But Don't Lock Access To Mailbox 0 */
+#define TRR1           0x0002  /* Deny But Don't Lock Access To Mailbox 1 */
+#define TRR2           0x0004  /* Deny But Don't Lock Access To Mailbox 2 */
+#define TRR3           0x0008  /* Deny But Don't Lock Access To Mailbox 3 */
+#define TRR4           0x0010  /* Deny But Don't Lock Access To Mailbox 4 */
+#define TRR5           0x0020  /* Deny But Don't Lock Access To Mailbox 5 */
+#define TRR6           0x0040  /* Deny But Don't Lock Access To Mailbox 6 */
+#define TRR7           0x0080  /* Deny But Don't Lock Access To Mailbox 7 */
+#define TRR8           0x0100  /* Deny But Don't Lock Access To Mailbox 8 */
+#define TRR9           0x0200  /* Deny But Don't Lock Access To Mailbox 9 */
+#define TRR10          0x0400  /* Deny But Don't Lock Access To Mailbox 10 */
+#define TRR11          0x0800  /* Deny But Don't Lock Access To Mailbox 11 */
+#define TRR12          0x1000  /* Deny But Don't Lock Access To Mailbox 12 */
+#define TRR13          0x2000  /* Deny But Don't Lock Access To Mailbox 13 */
+#define TRR14          0x4000  /* Deny But Don't Lock Access To Mailbox 14 */
+#define TRR15          0x8000  /* Deny But Don't Lock Access To Mailbox 15 */
+
+/* CAN_TRR2 Masks */
+#define TRR16          0x0001  /* Deny But Don't Lock Access To Mailbox 16 */
+#define TRR17          0x0002  /* Deny But Don't Lock Access To Mailbox 17 */
+#define TRR18          0x0004  /* Deny But Don't Lock Access To Mailbox 18 */
+#define TRR19          0x0008  /* Deny But Don't Lock Access To Mailbox 19 */
+#define TRR20          0x0010  /* Deny But Don't Lock Access To Mailbox 20 */
+#define TRR21          0x0020  /* Deny But Don't Lock Access To Mailbox 21 */
+#define TRR22          0x0040  /* Deny But Don't Lock Access To Mailbox 22 */
+#define TRR23          0x0080  /* Deny But Don't Lock Access To Mailbox 23 */
+#define TRR24          0x0100  /* Deny But Don't Lock Access To Mailbox 24 */
+#define TRR25          0x0200  /* Deny But Don't Lock Access To Mailbox 25 */
+#define TRR26          0x0400  /* Deny But Don't Lock Access To Mailbox 26 */
+#define TRR27          0x0800  /* Deny But Don't Lock Access To Mailbox 27 */
+#define TRR28          0x1000  /* Deny But Don't Lock Access To Mailbox 28 */
+#define TRR29          0x2000  /* Deny But Don't Lock Access To Mailbox 29 */
+#define TRR30          0x4000  /* Deny But Don't Lock Access To Mailbox 30 */
+#define TRR31          0x8000  /* Deny But Don't Lock Access To Mailbox 31 */
+
+/* CAN_TRS1 Masks */
+#define TRS0           0x0001  /* Remote Frame Request For Mailbox 0 */
+#define TRS1           0x0002  /* Remote Frame Request For Mailbox 1 */
+#define TRS2           0x0004  /* Remote Frame Request For Mailbox 2 */
+#define TRS3           0x0008  /* Remote Frame Request For Mailbox 3 */
+#define TRS4           0x0010  /* Remote Frame Request For Mailbox 4 */
+#define TRS5           0x0020  /* Remote Frame Request For Mailbox 5 */
+#define TRS6           0x0040  /* Remote Frame Request For Mailbox 6 */
+#define TRS7           0x0080  /* Remote Frame Request For Mailbox 7 */
+#define TRS8           0x0100  /* Remote Frame Request For Mailbox 8 */
+#define TRS9           0x0200  /* Remote Frame Request For Mailbox 9 */
+#define TRS10          0x0400  /* Remote Frame Request For Mailbox 10 */
+#define TRS11          0x0800  /* Remote Frame Request For Mailbox 11 */
+#define TRS12          0x1000  /* Remote Frame Request For Mailbox 12 */
+#define TRS13          0x2000  /* Remote Frame Request For Mailbox 13 */
+#define TRS14          0x4000  /* Remote Frame Request For Mailbox 14 */
+#define TRS15          0x8000  /* Remote Frame Request For Mailbox 15 */
+
+/* CAN_TRS2 Masks */
+#define TRS16          0x0001  /* Remote Frame Request For Mailbox 16 */
+#define TRS17          0x0002  /* Remote Frame Request For Mailbox 17 */
+#define TRS18          0x0004  /* Remote Frame Request For Mailbox 18 */
+#define TRS19          0x0008  /* Remote Frame Request For Mailbox 19 */
+#define TRS20          0x0010  /* Remote Frame Request For Mailbox 20 */
+#define TRS21          0x0020  /* Remote Frame Request For Mailbox 21 */
+#define TRS22          0x0040  /* Remote Frame Request For Mailbox 22 */
+#define TRS23          0x0080  /* Remote Frame Request For Mailbox 23 */
+#define TRS24          0x0100  /* Remote Frame Request For Mailbox 24 */
+#define TRS25          0x0200  /* Remote Frame Request For Mailbox 25 */
+#define TRS26          0x0400  /* Remote Frame Request For Mailbox 26 */
+#define TRS27          0x0800  /* Remote Frame Request For Mailbox 27 */
+#define TRS28          0x1000  /* Remote Frame Request For Mailbox 28 */
+#define TRS29          0x2000  /* Remote Frame Request For Mailbox 29 */
+#define TRS30          0x4000  /* Remote Frame Request For Mailbox 30 */
+#define TRS31          0x8000  /* Remote Frame Request For Mailbox 31 */
+
+/* CAN_AA1 Masks */
+#define AA0                    0x0001  /* Aborted Message In Mailbox 0 */
+#define AA1                    0x0002  /* Aborted Message In Mailbox 1 */
+#define AA2                    0x0004  /* Aborted Message In Mailbox 2 */
+#define AA3                    0x0008  /* Aborted Message In Mailbox 3 */
+#define AA4                    0x0010  /* Aborted Message In Mailbox 4 */
+#define AA5                    0x0020  /* Aborted Message In Mailbox 5 */
+#define AA6                    0x0040  /* Aborted Message In Mailbox 6 */
+#define AA7                    0x0080  /* Aborted Message In Mailbox 7 */
+#define AA8                    0x0100  /* Aborted Message In Mailbox 8 */
+#define AA9                    0x0200  /* Aborted Message In Mailbox 9 */
+#define AA10           0x0400  /* Aborted Message In Mailbox 10 */
+#define AA11           0x0800  /* Aborted Message In Mailbox 11 */
+#define AA12           0x1000  /* Aborted Message In Mailbox 12 */
+#define AA13           0x2000  /* Aborted Message In Mailbox 13 */
+#define AA14           0x4000  /* Aborted Message In Mailbox 14 */
+#define AA15           0x8000  /* Aborted Message In Mailbox 15 */
+
+/* CAN_AA2 Masks */
+#define AA16           0x0001  /* Aborted Message In Mailbox 16 */
+#define AA17           0x0002  /* Aborted Message In Mailbox 17 */
+#define AA18           0x0004  /* Aborted Message In Mailbox 18 */
+#define AA19           0x0008  /* Aborted Message In Mailbox 19 */
+#define AA20           0x0010  /* Aborted Message In Mailbox 20 */
+#define AA21           0x0020  /* Aborted Message In Mailbox 21 */
+#define AA22           0x0040  /* Aborted Message In Mailbox 22 */
+#define AA23           0x0080  /* Aborted Message In Mailbox 23 */
+#define AA24           0x0100  /* Aborted Message In Mailbox 24 */
+#define AA25           0x0200  /* Aborted Message In Mailbox 25 */
+#define AA26           0x0400  /* Aborted Message In Mailbox 26 */
+#define AA27           0x0800  /* Aborted Message In Mailbox 27 */
+#define AA28           0x1000  /* Aborted Message In Mailbox 28 */
+#define AA29           0x2000  /* Aborted Message In Mailbox 29 */
+#define AA30           0x4000  /* Aborted Message In Mailbox 30 */
+#define AA31           0x8000  /* Aborted Message In Mailbox 31 */
+
+/* CAN_TA1 Masks */
+#define TA0                    0x0001  /* Transmit Successful From Mailbox 0 */
+#define TA1                    0x0002  /* Transmit Successful From Mailbox 1 */
+#define TA2                    0x0004  /* Transmit Successful From Mailbox 2 */
+#define TA3                    0x0008  /* Transmit Successful From Mailbox 3 */
+#define TA4                    0x0010  /* Transmit Successful From Mailbox 4 */
+#define TA5                    0x0020  /* Transmit Successful From Mailbox 5 */
+#define TA6                    0x0040  /* Transmit Successful From Mailbox 6 */
+#define TA7                    0x0080  /* Transmit Successful From Mailbox 7 */
+#define TA8                    0x0100  /* Transmit Successful From Mailbox 8 */
+#define TA9                    0x0200  /* Transmit Successful From Mailbox 9 */
+#define TA10           0x0400  /* Transmit Successful From Mailbox 10 */
+#define TA11           0x0800  /* Transmit Successful From Mailbox 11 */
+#define TA12           0x1000  /* Transmit Successful From Mailbox 12 */
+#define TA13           0x2000  /* Transmit Successful From Mailbox 13 */
+#define TA14           0x4000  /* Transmit Successful From Mailbox 14 */
+#define TA15           0x8000  /* Transmit Successful From Mailbox 15 */
+
+/* CAN_TA2 Masks */
+#define TA16           0x0001  /* Transmit Successful From Mailbox 16 */
+#define TA17           0x0002  /* Transmit Successful From Mailbox 17 */
+#define TA18           0x0004  /* Transmit Successful From Mailbox 18 */
+#define TA19           0x0008  /* Transmit Successful From Mailbox 19 */
+#define TA20           0x0010  /* Transmit Successful From Mailbox 20 */
+#define TA21           0x0020  /* Transmit Successful From Mailbox 21 */
+#define TA22           0x0040  /* Transmit Successful From Mailbox 22 */
+#define TA23           0x0080  /* Transmit Successful From Mailbox 23 */
+#define TA24           0x0100  /* Transmit Successful From Mailbox 24 */
+#define TA25           0x0200  /* Transmit Successful From Mailbox 25 */
+#define TA26           0x0400  /* Transmit Successful From Mailbox 26 */
+#define TA27           0x0800  /* Transmit Successful From Mailbox 27 */
+#define TA28           0x1000  /* Transmit Successful From Mailbox 28 */
+#define TA29           0x2000  /* Transmit Successful From Mailbox 29 */
+#define TA30           0x4000  /* Transmit Successful From Mailbox 30 */
+#define TA31           0x8000  /* Transmit Successful From Mailbox 31 */
+
+/* CAN_MBTD Masks */
+#define TDPTR          0x001F  /* Mailbox To Temporarily Disable */
+#define TDA                    0x0040  /* Temporary Disable Acknowledge */
+#define TDR                    0x0080  /* Temporary Disable Request */
+
+/* CAN_RFH1 Masks */
+#define RFH0           0x0001  /* Enable Automatic Remote Frame Handling For Mailbox 0 */
+#define RFH1           0x0002  /* Enable Automatic Remote Frame Handling For Mailbox 1 */
+#define RFH2           0x0004  /* Enable Automatic Remote Frame Handling For Mailbox 2 */
+#define RFH3           0x0008  /* Enable Automatic Remote Frame Handling For Mailbox 3 */
+#define RFH4           0x0010  /* Enable Automatic Remote Frame Handling For Mailbox 4 */
+#define RFH5           0x0020  /* Enable Automatic Remote Frame Handling For Mailbox 5 */
+#define RFH6           0x0040  /* Enable Automatic Remote Frame Handling For Mailbox 6 */
+#define RFH7           0x0080  /* Enable Automatic Remote Frame Handling For Mailbox 7 */
+#define RFH8           0x0100  /* Enable Automatic Remote Frame Handling For Mailbox 8 */
+#define RFH9           0x0200  /* Enable Automatic Remote Frame Handling For Mailbox 9 */
+#define RFH10          0x0400  /* Enable Automatic Remote Frame Handling For Mailbox 10 */
+#define RFH11          0x0800  /* Enable Automatic Remote Frame Handling For Mailbox 11 */
+#define RFH12          0x1000  /* Enable Automatic Remote Frame Handling For Mailbox 12 */
+#define RFH13          0x2000  /* Enable Automatic Remote Frame Handling For Mailbox 13 */
+#define RFH14          0x4000  /* Enable Automatic Remote Frame Handling For Mailbox 14 */
+#define RFH15          0x8000  /* Enable Automatic Remote Frame Handling For Mailbox 15 */
+
+/* CAN_RFH2 Masks */
+#define RFH16          0x0001  /* Enable Automatic Remote Frame Handling For Mailbox 16 */
+#define RFH17          0x0002  /* Enable Automatic Remote Frame Handling For Mailbox 17 */
+#define RFH18          0x0004  /* Enable Automatic Remote Frame Handling For Mailbox 18 */
+#define RFH19          0x0008  /* Enable Automatic Remote Frame Handling For Mailbox 19 */
+#define RFH20          0x0010  /* Enable Automatic Remote Frame Handling For Mailbox 20 */
+#define RFH21          0x0020  /* Enable Automatic Remote Frame Handling For Mailbox 21 */
+#define RFH22          0x0040  /* Enable Automatic Remote Frame Handling For Mailbox 22 */
+#define RFH23          0x0080  /* Enable Automatic Remote Frame Handling For Mailbox 23 */
+#define RFH24          0x0100  /* Enable Automatic Remote Frame Handling For Mailbox 24 */
+#define RFH25          0x0200  /* Enable Automatic Remote Frame Handling For Mailbox 25 */
+#define RFH26          0x0400  /* Enable Automatic Remote Frame Handling For Mailbox 26 */
+#define RFH27          0x0800  /* Enable Automatic Remote Frame Handling For Mailbox 27 */
+#define RFH28          0x1000  /* Enable Automatic Remote Frame Handling For Mailbox 28 */
+#define RFH29          0x2000  /* Enable Automatic Remote Frame Handling For Mailbox 29 */
+#define RFH30          0x4000  /* Enable Automatic Remote Frame Handling For Mailbox 30 */
+#define RFH31          0x8000  /* Enable Automatic Remote Frame Handling For Mailbox 31 */
+
+/* CAN_MBTIF1 Masks */
+#define MBTIF0         0x0001  /* TX Interrupt Active In Mailbox 0 */
+#define MBTIF1         0x0002  /* TX Interrupt Active In Mailbox 1 */
+#define MBTIF2         0x0004  /* TX Interrupt Active In Mailbox 2 */
+#define MBTIF3         0x0008  /* TX Interrupt Active In Mailbox 3 */
+#define MBTIF4         0x0010  /* TX Interrupt Active In Mailbox 4 */
+#define MBTIF5         0x0020  /* TX Interrupt Active In Mailbox 5 */
+#define MBTIF6         0x0040  /* TX Interrupt Active In Mailbox 6 */
+#define MBTIF7         0x0080  /* TX Interrupt Active In Mailbox 7 */
+#define MBTIF8         0x0100  /* TX Interrupt Active In Mailbox 8 */
+#define MBTIF9         0x0200  /* TX Interrupt Active In Mailbox 9 */
+#define MBTIF10                0x0400  /* TX Interrupt Active In Mailbox 10 */
+#define MBTIF11                0x0800  /* TX Interrupt Active In Mailbox 11 */
+#define MBTIF12                0x1000  /* TX Interrupt Active In Mailbox 12 */
+#define MBTIF13                0x2000  /* TX Interrupt Active In Mailbox 13 */
+#define MBTIF14                0x4000  /* TX Interrupt Active In Mailbox 14 */
+#define MBTIF15                0x8000  /* TX Interrupt Active In Mailbox 15 */
+
+/* CAN_MBTIF2 Masks */
+#define MBTIF16                0x0001  /* TX Interrupt Active In Mailbox 16 */
+#define MBTIF17                0x0002  /* TX Interrupt Active In Mailbox 17 */
+#define MBTIF18                0x0004  /* TX Interrupt Active In Mailbox 18 */
+#define MBTIF19                0x0008  /* TX Interrupt Active In Mailbox 19 */
+#define MBTIF20                0x0010  /* TX Interrupt Active In Mailbox 20 */
+#define MBTIF21                0x0020  /* TX Interrupt Active In Mailbox 21 */
+#define MBTIF22                0x0040  /* TX Interrupt Active In Mailbox 22 */
+#define MBTIF23                0x0080  /* TX Interrupt Active In Mailbox 23 */
+#define MBTIF24                0x0100  /* TX Interrupt Active In Mailbox 24 */
+#define MBTIF25                0x0200  /* TX Interrupt Active In Mailbox 25 */
+#define MBTIF26                0x0400  /* TX Interrupt Active In Mailbox 26 */
+#define MBTIF27                0x0800  /* TX Interrupt Active In Mailbox 27 */
+#define MBTIF28                0x1000  /* TX Interrupt Active In Mailbox 28 */
+#define MBTIF29                0x2000  /* TX Interrupt Active In Mailbox 29 */
+#define MBTIF30                0x4000  /* TX Interrupt Active In Mailbox 30 */
+#define MBTIF31                0x8000  /* TX Interrupt Active In Mailbox 31 */
+
+/* CAN_MBRIF1 Masks */
+#define MBRIF0         0x0001  /* RX Interrupt Active In Mailbox 0 */
+#define MBRIF1         0x0002  /* RX Interrupt Active In Mailbox 1 */
+#define MBRIF2         0x0004  /* RX Interrupt Active In Mailbox 2 */
+#define MBRIF3         0x0008  /* RX Interrupt Active In Mailbox 3 */
+#define MBRIF4         0x0010  /* RX Interrupt Active In Mailbox 4 */
+#define MBRIF5         0x0020  /* RX Interrupt Active In Mailbox 5 */
+#define MBRIF6         0x0040  /* RX Interrupt Active In Mailbox 6 */
+#define MBRIF7         0x0080  /* RX Interrupt Active In Mailbox 7 */
+#define MBRIF8         0x0100  /* RX Interrupt Active In Mailbox 8 */
+#define MBRIF9         0x0200  /* RX Interrupt Active In Mailbox 9 */
+#define MBRIF10                0x0400  /* RX Interrupt Active In Mailbox 10 */
+#define MBRIF11                0x0800  /* RX Interrupt Active In Mailbox 11 */
+#define MBRIF12                0x1000  /* RX Interrupt Active In Mailbox 12 */
+#define MBRIF13                0x2000  /* RX Interrupt Active In Mailbox 13 */
+#define MBRIF14                0x4000  /* RX Interrupt Active In Mailbox 14 */
+#define MBRIF15                0x8000  /* RX Interrupt Active In Mailbox 15 */
+
+/* CAN_MBRIF2 Masks */
+#define MBRIF16                0x0001  /* RX Interrupt Active In Mailbox 16 */
+#define MBRIF17                0x0002  /* RX Interrupt Active In Mailbox 17 */
+#define MBRIF18                0x0004  /* RX Interrupt Active In Mailbox 18 */
+#define MBRIF19                0x0008  /* RX Interrupt Active In Mailbox 19 */
+#define MBRIF20                0x0010  /* RX Interrupt Active In Mailbox 20 */
+#define MBRIF21                0x0020  /* RX Interrupt Active In Mailbox 21 */
+#define MBRIF22                0x0040  /* RX Interrupt Active In Mailbox 22 */
+#define MBRIF23                0x0080  /* RX Interrupt Active In Mailbox 23 */
+#define MBRIF24                0x0100  /* RX Interrupt Active In Mailbox 24 */
+#define MBRIF25                0x0200  /* RX Interrupt Active In Mailbox 25 */
+#define MBRIF26                0x0400  /* RX Interrupt Active In Mailbox 26 */
+#define MBRIF27                0x0800  /* RX Interrupt Active In Mailbox 27 */
+#define MBRIF28                0x1000  /* RX Interrupt Active In Mailbox 28 */
+#define MBRIF29                0x2000  /* RX Interrupt Active In Mailbox 29 */
+#define MBRIF30                0x4000  /* RX Interrupt Active In Mailbox 30 */
+#define MBRIF31                0x8000  /* RX Interrupt Active In Mailbox 31 */
+
+/* CAN_MBIM1 Masks */
+#define MBIM0          0x0001  /* Enable Interrupt For Mailbox 0 */
+#define MBIM1          0x0002  /* Enable Interrupt For Mailbox 1 */
+#define MBIM2          0x0004  /* Enable Interrupt For Mailbox 2 */
+#define MBIM3          0x0008  /* Enable Interrupt For Mailbox 3 */
+#define MBIM4          0x0010  /* Enable Interrupt For Mailbox 4 */
+#define MBIM5          0x0020  /* Enable Interrupt For Mailbox 5 */
+#define MBIM6          0x0040  /* Enable Interrupt For Mailbox 6 */
+#define MBIM7          0x0080  /* Enable Interrupt For Mailbox 7 */
+#define MBIM8          0x0100  /* Enable Interrupt For Mailbox 8 */
+#define MBIM9          0x0200  /* Enable Interrupt For Mailbox 9 */
+#define MBIM10         0x0400  /* Enable Interrupt For Mailbox 10 */
+#define MBIM11         0x0800  /* Enable Interrupt For Mailbox 11 */
+#define MBIM12         0x1000  /* Enable Interrupt For Mailbox 12 */
+#define MBIM13         0x2000  /* Enable Interrupt For Mailbox 13 */
+#define MBIM14         0x4000  /* Enable Interrupt For Mailbox 14 */
+#define MBIM15         0x8000  /* Enable Interrupt For Mailbox 15 */
+
+/* CAN_MBIM2 Masks */
+#define MBIM16         0x0001  /* Enable Interrupt For Mailbox 16 */
+#define MBIM17         0x0002  /* Enable Interrupt For Mailbox 17 */
+#define MBIM18         0x0004  /* Enable Interrupt For Mailbox 18 */
+#define MBIM19         0x0008  /* Enable Interrupt For Mailbox 19 */
+#define MBIM20         0x0010  /* Enable Interrupt For Mailbox 20 */
+#define MBIM21         0x0020  /* Enable Interrupt For Mailbox 21 */
+#define MBIM22         0x0040  /* Enable Interrupt For Mailbox 22 */
+#define MBIM23         0x0080  /* Enable Interrupt For Mailbox 23 */
+#define MBIM24         0x0100  /* Enable Interrupt For Mailbox 24 */
+#define MBIM25         0x0200  /* Enable Interrupt For Mailbox 25 */
+#define MBIM26         0x0400  /* Enable Interrupt For Mailbox 26 */
+#define MBIM27         0x0800  /* Enable Interrupt For Mailbox 27 */
+#define MBIM28         0x1000  /* Enable Interrupt For Mailbox 28 */
+#define MBIM29         0x2000  /* Enable Interrupt For Mailbox 29 */
+#define MBIM30         0x4000  /* Enable Interrupt For Mailbox 30 */
+#define MBIM31         0x8000  /* Enable Interrupt For Mailbox 31 */
+
+/* CAN_GIM Masks */
+#define EWTIM          0x0001  /* Enable TX Error Count Interrupt */
+#define EWRIM          0x0002  /* Enable RX Error Count Interrupt */
+#define EPIM           0x0004  /* Enable Error-Passive Mode Interrupt */
+#define BOIM           0x0008  /* Enable Bus Off Interrupt */
+#define WUIM           0x0010  /* Enable Wake-Up Interrupt */
+#define UIAIM          0x0020  /* Enable Access To Unimplemented Address Interrupt */
+#define AAIM           0x0040  /* Enable Abort Acknowledge Interrupt */
+#define RMLIM          0x0080  /* Enable RX Message Lost Interrupt */
+#define UCEIM          0x0100  /* Enable Universal Counter Overflow Interrupt */
+#define EXTIM          0x0200  /* Enable External Trigger Output Interrupt */
+#define ADIM           0x0400  /* Enable Access Denied Interrupt */
+
+/* CAN_GIS Masks */
+#define EWTIS          0x0001  /* TX Error Count IRQ Status */
+#define EWRIS          0x0002  /* RX Error Count IRQ Status */
+#define EPIS           0x0004  /* Error-Passive Mode IRQ Status */
+#define BOIS           0x0008  /* Bus Off IRQ Status */
+#define WUIS           0x0010  /* Wake-Up IRQ Status */
+#define UIAIS          0x0020  /* Access To Unimplemented Address IRQ Status */
+#define AAIS           0x0040  /* Abort Acknowledge IRQ Status */
+#define RMLIS          0x0080  /* RX Message Lost IRQ Status */
+#define UCEIS          0x0100  /* Universal Counter Overflow IRQ Status */
+#define EXTIS          0x0200  /* External Trigger Output IRQ Status */
+#define ADIS           0x0400  /* Access Denied IRQ Status */
+
+/* CAN_GIF Masks */
+#define EWTIF          0x0001  /* TX Error Count IRQ Flag */
+#define EWRIF          0x0002  /* RX Error Count IRQ Flag */
+#define EPIF           0x0004  /* Error-Passive Mode IRQ Flag */
+#define BOIF           0x0008  /* Bus Off IRQ Flag */
+#define WUIF           0x0010  /* Wake-Up IRQ Flag */
+#define UIAIF          0x0020  /* Access To Unimplemented Address IRQ Flag */
+#define AAIF           0x0040  /* Abort Acknowledge IRQ Flag */
+#define RMLIF          0x0080  /* RX Message Lost IRQ Flag */
+#define UCEIF          0x0100  /* Universal Counter Overflow IRQ Flag */
+#define EXTIF          0x0200  /* External Trigger Output IRQ Flag */
+#define ADIF           0x0400  /* Access Denied IRQ Flag */
+
+/* CAN_UCCNF Masks */
+#define UCCNF          0x000F  /* Universal Counter Mode */
+#define UC_STAMP       0x0001  /*  Timestamp Mode */
+#define UC_WDOG                0x0002  /*  Watchdog Mode */
+#define UC_AUTOTX      0x0003  /*  Auto-Transmit Mode */
+#define UC_ERROR       0x0006  /*  CAN Error Frame Count */
+#define UC_OVER                0x0007  /*  CAN Overload Frame Count */
+#define UC_LOST                0x0008  /*  Arbitration Lost During TX Count */
+#define UC_AA          0x0009  /*  TX Abort Count */
+#define UC_TA          0x000A  /*  TX Successful Count */
+#define UC_REJECT      0x000B  /*  RX Message Rejected Count */
+#define UC_RML         0x000C  /*  RX Message Lost Count */
+#define UC_RX          0x000D  /*  Total Successful RX Messages Count */
+#define UC_RMP         0x000E  /*  Successful RX W/Matching ID Count */
+#define UC_ALL         0x000F  /*  Correct Message On CAN Bus Line Count */
+#define UCRC           0x0020  /* Universal Counter Reload/Clear */
+#define UCCT           0x0040  /* Universal Counter CAN Trigger */
+#define UCE                    0x0080  /* Universal Counter Enable */
+
+/* CAN_ESR Masks */
+#define ACKE           0x0004  /* Acknowledge Error */
+#define SER                    0x0008  /* Stuff Error */
+#define CRCE           0x0010  /* CRC Error */
+#define SA0                    0x0020  /* Stuck At Dominant Error */
+#define BEF                    0x0040  /* Bit Error Flag */
+#define FER                    0x0080  /* Form Error Flag */
+
+/* CAN_EWR Masks */
+#define EWLREC         0x00FF  /* RX Error Count Limit (For EWRIS) */
+#define EWLTEC         0xFF00  /* TX Error Count Limit (For EWTIS) */
+
+#endif
index b558908e1c794fea61e06f57a6b2ff0f8a30f378..9626cf7e4251d7c220534acc7343d4ffc16f3194 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * bfin_sport.h - userspace header for bfin sport driver
+ * bfin_sport.h - interface to Blackfin SPORTs
  *
- * Copyright 2004-2008 Analog Devices Inc.
+ * Copyright 2004-2009 Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later.
  */
@@ -9,16 +9,6 @@
 #ifndef __BFIN_SPORT_H__
 #define __BFIN_SPORT_H__
 
-#ifdef __KERNEL__
-#include <linux/cdev.h>
-#include <linux/mutex.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#endif
-
-#define SPORT_MAJOR    237
-#define SPORT_NR_DEVS  2
-
 /* Sport mode: it can be set to TDM, i2s or others */
 #define NORM_MODE      0x0
 #define TDM_MODE       0x1
@@ -35,7 +25,7 @@ struct sport_config {
        unsigned int mode:3;
 
        /* if TDM mode is selected, channels must be set */
-       int channels;           /* Must be in 8 units */
+       int channels;   /* Must be in 8 units */
        unsigned int frame_delay:4;     /* Delay between frame sync pulse and first bit */
 
        /* I2S mode */
@@ -69,94 +59,137 @@ struct sport_config {
 
 #ifdef __KERNEL__
 
-struct sport_register {
-       unsigned short tcr1;
-       unsigned short reserved0;
-       unsigned short tcr2;
-       unsigned short reserved1;
-       unsigned short tclkdiv;
-       unsigned short reserved2;
-       unsigned short tfsdiv;
-       unsigned short reserved3;
-       unsigned long tx;
-       unsigned long reserved_l0;
-       unsigned long rx;
-       unsigned long reserved_l1;
-       unsigned short rcr1;
-       unsigned short reserved4;
-       unsigned short rcr2;
-       unsigned short reserved5;
-       unsigned short rclkdiv;
-       unsigned short reserved6;
-       unsigned short rfsdiv;
-       unsigned short reserved7;
-       unsigned short stat;
-       unsigned short reserved8;
-       unsigned short chnl;
-       unsigned short reserved9;
-       unsigned short mcmc1;
-       unsigned short reserved10;
-       unsigned short mcmc2;
-       unsigned short reserved11;
-       unsigned long mtcs0;
-       unsigned long mtcs1;
-       unsigned long mtcs2;
-       unsigned long mtcs3;
-       unsigned long mrcs0;
-       unsigned long mrcs1;
-       unsigned long mrcs2;
-       unsigned long mrcs3;
-};
-
-struct sport_dev {
-       struct cdev cdev;       /* Char device structure */
-
-       int sport_num;
+#include <linux/types.h>
 
-       int dma_rx_chan;
-       int dma_tx_chan;
-
-       int rx_irq;
-       unsigned char *rx_buf;  /* Buffer store the received data */
-       int rx_len;             /* How many bytes will be received */
-       int rx_received;        /* How many bytes has been received */
-
-       int tx_irq;
-       const unsigned char *tx_buf;
-       int tx_len;
-       int tx_sent;
-
-       int err_irq;
-
-       struct mutex mutex;     /* mutual exclusion semaphore */
-       struct task_struct *task;
-
-       wait_queue_head_t waitq;
-       int     wait_con;
-       struct sport_register *regs;
-       struct sport_config config;
+/*
+ * All Blackfin system MMRs are padded to 32bits even if the register
+ * itself is only 16bits.  So use a helper macro to streamline this.
+ */
+#define __BFP(m) u16 m; u16 __pad_##m
+struct sport_register {
+       __BFP(tcr1);
+       __BFP(tcr2);
+       __BFP(tclkdiv);
+       __BFP(tfsdiv);
+       union {
+               u32 tx32;
+               u16 tx16;
+       };
+       u32 __pad_tx;
+       union {
+               u32 rx32;       /* use the anomaly wrapper below */
+               u16 rx16;
+       };
+       u32 __pad_rx;
+       __BFP(rcr1);
+       __BFP(rcr2);
+       __BFP(rclkdiv);
+       __BFP(rfsdiv);
+       __BFP(stat);
+       __BFP(chnl);
+       __BFP(mcmc1);
+       __BFP(mcmc2);
+       u32 mtcs0;
+       u32 mtcs1;
+       u32 mtcs2;
+       u32 mtcs3;
+       u32 mrcs0;
+       u32 mrcs1;
+       u32 mrcs2;
+       u32 mrcs3;
 };
+#undef __BFP
+
+#define bfin_read_sport_rx32(base) \
+({ \
+       struct sport_register *__mmrs = (void *)base; \
+       u32 __ret; \
+       unsigned long flags; \
+       if (ANOMALY_05000473) \
+               local_irq_save(flags); \
+       __ret = __mmrs->rx32; \
+       if (ANOMALY_05000473) \
+               local_irq_restore(flags); \
+       __ret; \
+})
 
 #endif
 
-#define SPORT_TCR1     0
-#define        SPORT_TCR2      1
-#define        SPORT_TCLKDIV   2
-#define        SPORT_TFSDIV    3
-#define        SPORT_RCR1      8
-#define        SPORT_RCR2      9
-#define SPORT_RCLKDIV  10
-#define        SPORT_RFSDIV    11
-#define SPORT_CHANNEL  13
-#define SPORT_MCMC1    14
-#define SPORT_MCMC2    15
-#define SPORT_MTCS0    16
-#define SPORT_MTCS1    17
-#define SPORT_MTCS2    18
-#define SPORT_MTCS3    19
-#define SPORT_MRCS0    20
-#define SPORT_MRCS1    21
-#define SPORT_MRCS2    22
-#define SPORT_MRCS3    23
+/* Workaround defBF*.h SPORT MMRs till they get cleansed */
+#undef DTYPE_NORM
+#undef SLEN
+#undef SP_WOFF
+#undef SP_WSIZE
+
+/* SPORT_TCR1 Masks */
+#define TSPEN          0x0001  /* TX enable */
+#define ITCLK          0x0002  /* Internal TX Clock Select */
+#define TDTYPE         0x000C  /* TX Data Formatting Select */
+#define DTYPE_NORM     0x0000  /* Data Format Normal */
+#define DTYPE_ULAW     0x0008  /* Compand Using u-Law */
+#define DTYPE_ALAW     0x000C  /* Compand Using A-Law */
+#define TLSBIT         0x0010  /* TX Bit Order */
+#define ITFS           0x0200  /* Internal TX Frame Sync Select */
+#define TFSR           0x0400  /* TX Frame Sync Required Select */
+#define DITFS          0x0800  /* Data Independent TX Frame Sync Select */
+#define LTFS           0x1000  /* Low TX Frame Sync Select */
+#define LATFS          0x2000  /* Late TX Frame Sync Select */
+#define TCKFE          0x4000  /* TX Clock Falling Edge Select */
+
+/* SPORT_TCR2 Masks */
+#define SLEN           0x001F  /* SPORT TX Word Length (2 - 31) */
+#define DP_SLEN(x)     BFIN_DEPOSIT(SLEN, x)
+#define EX_SLEN(x)     BFIN_EXTRACT(SLEN, x)
+#define TXSE           0x0100  /* TX Secondary Enable */
+#define TSFSE          0x0200  /* TX Stereo Frame Sync Enable */
+#define TRFST          0x0400  /* TX Right-First Data Order */
+
+/* SPORT_RCR1 Masks */
+#define RSPEN          0x0001  /* RX enable */
+#define IRCLK          0x0002  /* Internal RX Clock Select */
+#define RDTYPE         0x000C  /* RX Data Formatting Select */
+/* DTYPE_* defined above */
+#define RLSBIT         0x0010  /* RX Bit Order */
+#define IRFS           0x0200  /* Internal RX Frame Sync Select */
+#define RFSR           0x0400  /* RX Frame Sync Required Select */
+#define LRFS           0x1000  /* Low RX Frame Sync Select */
+#define LARFS          0x2000  /* Late RX Frame Sync Select */
+#define RCKFE          0x4000  /* RX Clock Falling Edge Select */
+
+/* SPORT_RCR2 Masks */
+/* SLEN defined above */
+#define RXSE           0x0100  /* RX Secondary Enable */
+#define RSFSE          0x0200  /* RX Stereo Frame Sync Enable */
+#define RRFST          0x0400  /* Right-First Data Order */
+
+/* SPORT_STAT Masks */
+#define RXNE           0x0001  /* RX FIFO Not Empty Status */
+#define RUVF           0x0002  /* RX Underflow Status */
+#define ROVF           0x0004  /* RX Overflow Status */
+#define TXF            0x0008  /* TX FIFO Full Status */
+#define TUVF           0x0010  /* TX Underflow Status */
+#define TOVF           0x0020  /* TX Overflow Status */
+#define TXHRE          0x0040  /* TX Hold Register Empty */
+
+/* SPORT_MCMC1 Masks */
+#define SP_WOFF                0x03FF  /* Multichannel Window Offset Field */
+#define DP_SP_WOFF(x)  BFIN_DEPOSIT(SP_WOFF, x)
+#define EX_SP_WOFF(x)  BFIN_EXTRACT(SP_WOFF, x)
+#define SP_WSIZE       0xF000  /* Multichannel Window Size Field */
+#define DP_SP_WSIZE(x) BFIN_DEPOSIT(SP_WSIZE, x)
+#define EX_SP_WSIZE(x) BFIN_EXTRACT(SP_WSIZE, x)
+
+/* SPORT_MCMC2 Masks */
+#define MCCRM          0x0003  /* Multichannel Clock Recovery Mode */
+#define REC_BYPASS     0x0000  /* Bypass Mode (No Clock Recovery) */
+#define REC_2FROM4     0x0002  /* Recover 2 MHz Clock from 4 MHz Clock */
+#define REC_8FROM16    0x0003  /* Recover 8 MHz Clock from 16 MHz Clock */
+#define MCDTXPE                0x0004  /* Multichannel DMA Transmit Packing */
+#define MCDRXPE                0x0008  /* Multichannel DMA Receive Packing */
+#define MCMEN          0x0010  /* Multichannel Frame Mode Enable */
+#define FSDR           0x0080  /* Multichannel Frame Sync to Data Relationship */
+#define MFD            0xF000  /* Multichannel Frame Delay */
+#define DP_MFD(x)      BFIN_DEPOSIT(MFD, x)
+#define EX_MFD(x)      BFIN_EXTRACT(MFD, x)
 
 #endif
diff --git a/arch/blackfin/include/asm/bfin_watchdog.h b/arch/blackfin/include/asm/bfin_watchdog.h
new file mode 100644 (file)
index 0000000..dce0982
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * bfin_watchdog.h - Blackfin watchdog definitions
+ *
+ * Copyright 2006-2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef _BFIN_WATCHDOG_H
+#define _BFIN_WATCHDOG_H
+
+/* Bit in SWRST that indicates boot caused by watchdog */
+#define SWRST_RESET_WDOG 0x4000
+
+/* Bit in WDOG_CTL that indicates watchdog has expired (WDR0) */
+#define WDOG_EXPIRED 0x8000
+
+/* Masks for WDEV field in WDOG_CTL register */
+#define ICTL_RESET   0x0
+#define ICTL_NMI     0x2
+#define ICTL_GPI     0x4
+#define ICTL_NONE    0x6
+#define ICTL_MASK    0x6
+
+/* Masks for WDEN field in WDOG_CTL register */
+#define WDEN_MASK    0x0FF0
+#define WDEN_ENABLE  0x0000
+#define WDEN_DISABLE 0x0AD0
+
+#endif
index a2ff3fb3568dcac95e486990e95c83ba36b4a66d..605ba8e9b2e4f879a9c0dcfd24267e8e46d648c3 100644 (file)
@@ -7,22 +7,41 @@
 #ifndef _BLACKFIN_BITOPS_H
 #define _BLACKFIN_BITOPS_H
 
-#ifndef CONFIG_SMP
-# include <asm-generic/bitops.h>
-#else
+#include <linux/compiler.h>
+
+#include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/fls.h>
+#include <asm-generic/bitops/__fls.h>
+#include <asm-generic/bitops/fls64.h>
+#include <asm-generic/bitops/find.h>
 
 #ifndef _LINUX_BITOPS_H
 #error only <linux/bitops.h> can be included directly
 #endif
 
-#include <linux/compiler.h>
-#include <asm/byteorder.h>     /* swab32 */
-
-#include <asm-generic/bitops/ffs.h>
-#include <asm-generic/bitops/__ffs.h>
 #include <asm-generic/bitops/sched.h>
-#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/ffs.h>
+#include <asm-generic/bitops/lock.h>
+#include <asm-generic/bitops/ext2-non-atomic.h>
+#include <asm-generic/bitops/ext2-atomic.h>
+#include <asm-generic/bitops/minix.h>
+
+#ifndef CONFIG_SMP
+#include <linux/irqflags.h>
+
+/*
+ * clear_bit may not imply a memory barrier
+ */
+#ifndef smp_mb__before_clear_bit
+#define smp_mb__before_clear_bit()     smp_mb()
+#define smp_mb__after_clear_bit()      smp_mb()
+#endif
+#include <asm-generic/bitops/atomic.h>
+#include <asm-generic/bitops/non-atomic.h>
+#else
 
+#include <asm/byteorder.h>     /* swab32 */
 #include <linux/linkage.h>
 
 asmlinkage int __raw_bit_set_asm(volatile unsigned long *addr, int nr);
@@ -89,19 +108,36 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
 
 #include <asm-generic/bitops/non-atomic.h>
 
-#include <asm-generic/bitops/find.h>
-#include <asm-generic/bitops/hweight.h>
-#include <asm-generic/bitops/lock.h>
+#endif /* CONFIG_SMP */
 
-#include <asm-generic/bitops/ext2-atomic.h>
-#include <asm-generic/bitops/ext2-non-atomic.h>
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
 
-#include <asm-generic/bitops/minix.h>
+static inline unsigned int hweight32(unsigned int w)
+{
+       unsigned int res;
 
-#include <asm-generic/bitops/fls.h>
-#include <asm-generic/bitops/__fls.h>
-#include <asm-generic/bitops/fls64.h>
+       __asm__ ("%0.l = ONES %0;"
+               "%0 = %0.l (Z);"
+               : "=d" (res) : "d" (w));
+       return res;
+}
 
-#endif /* CONFIG_SMP */
+static inline unsigned int hweight64(__u64 w)
+{
+       return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
+}
+
+static inline unsigned int hweight16(unsigned int w)
+{
+       return hweight32(w & 0xffff);
+}
+
+static inline unsigned int hweight8(unsigned int w)
+{
+       return hweight32(w & 0xff);
+}
 
 #endif                         /* _BLACKFIN_BITOPS_H */
index 5dffaf582a22e9b6b1d3f9d9f55a09ec3a5ef867..1f9060395a0a7f767e53bcea97f6f83fa6a787f1 100644 (file)
        sti r0;
 #else
        cli r0;
+#endif
+#ifdef CONFIG_TRACE_IRQFLAGS
+       sp += -12;
+       call _trace_hardirqs_off;
+       sp += 12;
 #endif
        [--sp] = RETI;  /*orig_pc*/
        /* Clear all L registers.  */
        RETN = [sp++];
        RETX = [sp++];
        RETI = [sp++];
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+       sp += -12;
+       call _trace_hardirqs_on;
+       sp += 12;
+#endif
+
        RETS = [sp++];
 
 #ifdef CONFIG_SMP
 
        (R7:0, P5:0) = [SP++];
 .endm
+
+.macro pseudo_long_call func:req, scratch:req
+#ifdef CONFIG_ROMKERNEL
+       \scratch\().l = \func;
+       \scratch\().h = \func;
+       call (\scratch);
+#else
+       call \func;
+#endif
+.endm
index b191dc662bd802076587e30a31cbca61beef7a7c..16883e582e3cd96ce9a914242837f877e3a77f16 100644 (file)
@@ -17,8 +17,6 @@ struct blackfin_cpudata {
        struct task_struct *idle;
        unsigned int imemctl;
        unsigned int dmemctl;
-       unsigned long dcache_invld_count;
-       unsigned long icache_invld_count;
 };
 
 DECLARE_PER_CPU(struct blackfin_cpudata, cpu_data);
index 25906468622fc76147c22fb19ee98edc8e15f340..f342ff0319df8f86d47aed829d5cd2543828826e 100644 (file)
@@ -12,6 +12,8 @@
 #include <mach/anomaly.h>
 
 #define MK_BMSK_(x) (1<<x)
+#define BFIN_DEPOSIT(mask, x)  (((x) << __ffs(mask)) & (mask))
+#define BFIN_EXTRACT(mask, x)  (((x) & (mask)) >> __ffs(mask))
 
 #ifndef __ASSEMBLY__
 
 # define NOP_PAD_ANOMALY_05000198
 #endif
 
-#define bfin_read8(addr) ({ \
-       uint32_t __v; \
+#define _bfin_readX(addr, size, asm_size, asm_ext) ({ \
+       u32 __v; \
        __asm__ __volatile__( \
                NOP_PAD_ANOMALY_05000198 \
-               "%0 = b[%1] (z);" \
+               "%0 = " #asm_size "[%1]" #asm_ext ";" \
                : "=d" (__v) \
                : "a" (addr) \
        ); \
        __v; })
-
-#define bfin_read16(addr) ({ \
-       uint32_t __v; \
-       __asm__ __volatile__( \
-               NOP_PAD_ANOMALY_05000198 \
-               "%0 = w[%1] (z);" \
-               : "=d" (__v) \
-               : "a" (addr) \
-       ); \
-       __v; })
-
-#define bfin_read32(addr) ({ \
-       uint32_t __v; \
-       __asm__ __volatile__( \
-               NOP_PAD_ANOMALY_05000198 \
-               "%0 = [%1];" \
-               : "=d" (__v) \
-               : "a" (addr) \
-       ); \
-       __v; })
-
-#define bfin_write8(addr, val) \
+#define _bfin_writeX(addr, val, size, asm_size) \
        __asm__ __volatile__( \
                NOP_PAD_ANOMALY_05000198 \
-               "b[%0] = %1;" \
+               #asm_size "[%0] = %1;" \
                : \
-               : "a" (addr), "d" ((uint8_t)(val)) \
+               : "a" (addr), "d" ((u##size)(val)) \
                : "memory" \
        )
 
-#define bfin_write16(addr, val) \
-       __asm__ __volatile__( \
-               NOP_PAD_ANOMALY_05000198 \
-               "w[%0] = %1;" \
-               : \
-               : "a" (addr), "d" ((uint16_t)(val)) \
-               : "memory" \
-       )
-
-#define bfin_write32(addr, val) \
-       __asm__ __volatile__( \
-               NOP_PAD_ANOMALY_05000198 \
-               "[%0] = %1;" \
-               : \
-               : "a" (addr), "d" (val) \
-               : "memory" \
-       )
+#define bfin_read8(addr)  _bfin_readX(addr,  8, b, (z))
+#define bfin_read16(addr) _bfin_readX(addr, 16, w, (z))
+#define bfin_read32(addr) _bfin_readX(addr, 32,  ,    )
+#define bfin_write8(addr, val)  _bfin_writeX(addr, val,  8, b)
+#define bfin_write16(addr, val) _bfin_writeX(addr, val, 16, w)
+#define bfin_write32(addr, val) _bfin_writeX(addr, val, 32,  )
 
 #endif /* __ASSEMBLY__ */
 
index c31f91cc1d5dbd5cd0677ed007c002313a784109..171d8deb04a5e0f431531e9ecaf7f57dbb2a58c5 100644 (file)
@@ -30,10 +30,22 @@ __asm__ __volatile__ (
 
 #define        HZSCALE         (268435456 / (1000000/HZ))
 
-static inline void udelay(unsigned long usecs)
+static inline unsigned long __to_delay(unsigned long scale)
 {
        extern unsigned long loops_per_jiffy;
-       __delay((((usecs * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6);
+       return (((scale * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6;
+}
+
+static inline void udelay(unsigned long usecs)
+{
+       __delay(__to_delay(usecs));
 }
 
+static inline void ndelay(unsigned long nsecs)
+{
+       __delay(__to_delay(1) * nsecs / 1000);
+}
+
+#define ndelay ndelay
+
 #endif
index 413a30314a6f6db4bfad27153077c304ec6d11e0..212cb80fd74b61ee1c8422c07522683a9eab47ea 100644 (file)
@@ -44,13 +44,8 @@ dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 extern void
 __dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir);
 static inline void
-_dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir)
+__dma_sync_inline(dma_addr_t addr, size_t size, enum dma_data_direction dir)
 {
-       if (!__builtin_constant_p(dir)) {
-               __dma_sync(addr, size, dir);
-               return;
-       }
-
        switch (dir) {
        case DMA_NONE:
                BUG();
@@ -64,6 +59,14 @@ _dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir)
                break;
        }
 }
+static inline void
+_dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir)
+{
+       if (__builtin_constant_p(dir))
+               __dma_sync_inline(addr, size, dir);
+       else
+               __dma_sync(addr, size, dir);
+}
 
 static inline dma_addr_t
 dma_map_single(struct device *dev, void *ptr, size_t size,
index bd2e62243abef01f2376eb3c7731153f9c795933..2c09b1d50ec99dbaae7afa7aad0d6caa623241ed 100644 (file)
@@ -262,6 +262,10 @@ static inline void dma_disable_irq(unsigned int channel)
 {
        disable_irq(dma_ch[channel].irq);
 }
+static inline void dma_disable_irq_nosync(unsigned int channel)
+{
+       disable_irq_nosync(dma_ch[channel].irq);
+}
 static inline void dma_enable_irq(unsigned int channel)
 {
        enable_irq(dma_ch[channel].irq);
index 1597ae5041ee4ae08ea017988f32862ffa6ac709..efcc3aebeae428aec5f43ca0b1fc9ee8ceee91cf 100644 (file)
@@ -75,7 +75,7 @@
 
 #define VLEV                   0x00F0  /* Internal Voltage Level */
 #ifdef __ADSPBF52x__
-#define VLEV_085               0x0040  /* VLEV = 0.85 V (-5% - +10% Accuracy) */
+#define VLEV_085               0x0040  /* VLEV = 0.85 V (-5% - +10% Accuracy) */
 #define VLEV_090               0x0050  /* VLEV = 0.90 V (-5% - +10% Accuracy) */
 #define VLEV_095               0x0060  /* VLEV = 0.95 V (-5% - +10% Accuracy) */
 #define VLEV_100               0x0070  /* VLEV = 1.00 V (-5% - +10% Accuracy) */
@@ -84,7 +84,7 @@
 #define VLEV_115               0x00A0  /* VLEV = 1.15 V (-5% - +10% Accuracy) */
 #define VLEV_120               0x00B0  /* VLEV = 1.20 V (-5% - +10% Accuracy) */
 #else
-#define VLEV_085               0x0060  /* VLEV = 0.85 V (-5% - +10% Accuracy) */
+#define VLEV_085               0x0060  /* VLEV = 0.85 V (-5% - +10% Accuracy) */
 #define VLEV_090               0x0070  /* VLEV = 0.90 V (-5% - +10% Accuracy) */
 #define VLEV_095               0x0080  /* VLEV = 0.95 V (-5% - +10% Accuracy) */
 #define VLEV_100               0x0090  /* VLEV = 1.00 V (-5% - +10% Accuracy) */
index 5b50f0ecacf8ebd77c0e4646c397fb2356034d80..117713adea7ff262f96a55527506c6bbb51da8b5 100644 (file)
 #define EF_BFIN_CODE_IN_L2     0x00000040      /* --code-in-l2 */
 #define EF_BFIN_DATA_IN_L2     0x00000080      /* --data-in-l2 */
 
+#if 1  /* core dumps not supported, but linux/elfcore.h needs these */
 typedef unsigned long elf_greg_t;
 
-#define ELF_NGREG 40 /* (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) */
+#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
 typedef struct { } elf_fpregset_t;
+#endif
+
 /*
  * This is used to ensure we don't load something for the wrong architecture.
  */
@@ -55,6 +58,9 @@ do {                                                                                  \
        _regs->p2       = _dynamic_addr;                                \
 } while(0)
 
+#if 0
+#define CORE_DUMP_USE_REGSET
+#endif
 #define ELF_FDPIC_CORE_EFLAGS  EF_BFIN_FDPIC
 #define ELF_EXEC_PAGESIZE      4096
 
index 90c9b400ba6d5e19872cd50e71c2fa51ea4ab11b..4cfe2d9ba7e86f192e0265fa2815e130bff5c593 100644 (file)
 
 #define MCOUNT_INSN_SIZE       6 /* sizeof "[++sp] = rets; call __mcount;" */
 
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_FRAME_POINTER
+#include <linux/mm.h>
+
+extern inline void *return_address(unsigned int level)
+{
+       unsigned long *endstack, *fp, *ret_addr;
+       unsigned int current_level = 0;
+
+       if (level == 0)
+               return __builtin_return_address(0);
+
+       fp = (unsigned long *)__builtin_frame_address(0);
+       endstack = (unsigned long *)PAGE_ALIGN((unsigned long)&level);
+
+       while (((unsigned long)fp & 0x3) == 0 && fp &&
+              (fp + 1) < endstack && current_level < level) {
+               fp = (unsigned long *)*fp;
+               current_level++;
+       }
+
+       if (((unsigned long)fp & 0x3) == 0 && fp &&
+           (fp + 1) < endstack)
+               ret_addr = (unsigned long *)*(fp + 1);
+       else
+               ret_addr = NULL;
+
+       return ret_addr;
+}
+
+#else
+
+extern inline void *return_address(unsigned int level)
+{
+       return NULL;
+}
+
+#endif /* CONFIG_FRAME_POINTER */
+
+#define HAVE_ARCH_CALLER_ADDR
+
+/* inline function or macro may lead to unexpected result */
+#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#define CALLER_ADDR1 ((unsigned long)return_address(1))
+#define CALLER_ADDR2 ((unsigned long)return_address(2))
+#define CALLER_ADDR3 ((unsigned long)return_address(3))
+#define CALLER_ADDR4 ((unsigned long)return_address(4))
+#define CALLER_ADDR5 ((unsigned long)return_address(5))
+#define CALLER_ADDR6 ((unsigned long)return_address(6))
+
+#endif /* __ASSEMBLY__ */
+
 #endif
index 539468a05057fad759fa88fc8ef7ea37931b0bc2..91bd2d7b9d5541fdb56271e94f1d9dcd68054be8 100644 (file)
@@ -70,6 +70,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/compiler.h>
+
 /***********************************************************
 *
 * FUNCTIONS: Blackfin General Purpose Ports Access Functions
@@ -223,6 +225,9 @@ int bfin_gpio_direction_output(unsigned gpio, int value);
 int bfin_gpio_get_value(unsigned gpio);
 void bfin_gpio_set_value(unsigned gpio, int value);
 
+#include <asm/irq.h>
+#include <asm/errno.h>
+
 #ifdef CONFIG_GPIOLIB
 #include <asm-generic/gpio.h>          /* cansleep wrappers */
 
@@ -247,6 +252,11 @@ static inline int gpio_cansleep(unsigned int gpio)
        return __gpio_cansleep(gpio);
 }
 
+static inline int gpio_to_irq(unsigned gpio)
+{
+       return __gpio_to_irq(gpio);
+}
+
 #else /* !CONFIG_GPIOLIB */
 
 static inline int gpio_request(unsigned gpio, const char *label)
@@ -279,10 +289,6 @@ static inline void gpio_set_value(unsigned gpio, int value)
        return bfin_gpio_set_value(gpio, value);
 }
 
-#include <asm-generic/gpio.h>          /* cansleep wrappers */
-#endif /* !CONFIG_GPIOLIB */
-#include <asm/irq.h>
-
 static inline int gpio_to_irq(unsigned gpio)
 {
        if (likely(gpio < MAX_BLACKFIN_GPIOS))
@@ -291,6 +297,9 @@ static inline int gpio_to_irq(unsigned gpio)
        return -EINVAL;
 }
 
+#include <asm-generic/gpio.h>          /* cansleep wrappers */
+#endif /* !CONFIG_GPIOLIB */
+
 static inline int irq_to_gpio(unsigned irq)
 {
        return (irq - GPIO_IRQ_BASE);
index e7c0623f90915b8929dd3a89923daaea9e38f099..12f4060a31b034e9cd7190b075da6f58d6d4abaa 100644 (file)
@@ -12,6 +12,9 @@
 
 #include <linux/irqflags.h>
 
+/* IRQs that may be used by external irq_chip controllers */
+#define NR_SPARE_IRQS  32
+
 #include <mach/anomaly.h>
 
 /* SYS_IRQS and NR_IRQS are defined in <mach-bf5xx/irq.h> */
@@ -35,4 +38,8 @@
 
 #include <asm-generic/irq.h>
 
+#ifdef CONFIG_NMI_WATCHDOG
+# define ARCH_HAS_NMI_WATCHDOG
+#endif
+
 #endif                         /* _BFIN_IRQ_H_ */
index ae8ef4ffd806d8078c0aec77525487ce1fbcf8df..e1a9b4624f919ddae4675b1a8ff122e89944c764 100644 (file)
@@ -7,12 +7,13 @@
 #ifndef __BLACKFIN_MMU_CONTEXT_H__
 #define __BLACKFIN_MMU_CONTEXT_H__
 
-#include <linux/gfp.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <asm/setup.h>
 #include <asm/page.h>
 #include <asm/pgalloc.h>
 #include <asm/cplbinit.h>
+#include <asm/sections.h>
 
 /* Note: L1 stacks are CPU-private things, so we bluntly disable this
    feature in SMP mode, and use the per-CPU scratch SRAM bank only to
@@ -117,9 +118,16 @@ static inline void protect_page(struct mm_struct *mm, unsigned long addr,
                                unsigned long flags)
 {
        unsigned long *mask = mm->context.page_rwx_mask;
-       unsigned long page = addr >> 12;
-       unsigned long idx = page >> 5;
-       unsigned long bit = 1 << (page & 31);
+       unsigned long page;
+       unsigned long idx;
+       unsigned long bit;
+
+       if (unlikely(addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE))
+               page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> 12;
+       else
+               page = addr >> 12;
+       idx = page >> 5;
+       bit = 1 << (page & 31);
 
        if (flags & VM_READ)
                mask[idx] |= bit;
diff --git a/arch/blackfin/include/asm/nmi.h b/arch/blackfin/include/asm/nmi.h
new file mode 100644 (file)
index 0000000..b9caac4
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2
+ */
+
+#ifndef _BFIN_NMI_H_
+#define _BFIN_NMI_H_
+
+#include <linux/nmi.h>
+
+#endif
index 1d04e4078340c5617f67ba7bbc92d6a4975dc06a..d0ce975bcd48f5f99b0ace777911e47a7d66378e 100644 (file)
@@ -15,4 +15,7 @@
        ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
                 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#include <asm-generic/memory_model.h>
+#include <asm-generic/getorder.h>
+
 #endif
index b33a4488f49856e53c804a260c7626ac08609ee7..aaa1c6c2bc19c494ad7ea474103d006209162cdb 100644 (file)
@@ -24,6 +24,8 @@
 
 #ifndef __ASSEMBLY__
 
+struct task_struct;
+
 /* this struct defines the way the registers are stored on the
    stack during a system call. */
 
@@ -101,9 +103,30 @@ struct pt_regs {
    master interrupt enable.  */
 #define user_mode(regs) (!(((regs)->ipend & ~0x10) & (((regs)->ipend & ~0x10) - 1)))
 #define instruction_pointer(regs) ((regs)->pc)
+#define user_stack_pointer(regs)  ((regs)->usp)
 #define profile_pc(regs) instruction_pointer(regs)
 extern void show_regs(struct pt_regs *);
 
+#define arch_has_single_step() (1)
+extern void user_enable_single_step(struct task_struct *child);
+extern void user_disable_single_step(struct task_struct *child);
+/* common code demands this function */
+#define ptrace_disable(child) user_disable_single_step(child)
+
+/*
+ * Get the address of the live pt_regs for the specified task.
+ * These are saved onto the top kernel stack when the process
+ * is not running.
+ *
+ * Note: if a user thread is execve'd from kernel space, the
+ * kernel stack will not be empty on entry to the kernel, so
+ * ptracing these tasks will fail.
+ */
+#define task_pt_regs(task) \
+       (struct pt_regs *) \
+           ((unsigned long)task_stack_page(task) + \
+            (THREAD_SIZE - sizeof(struct pt_regs)))
+
 #endif  /*  __KERNEL__  */
 
 #endif                         /* __ASSEMBLY__ */
@@ -173,4 +196,6 @@ extern void show_regs(struct pt_regs *);
 #define PT_FDPIC_EXEC 232
 #define PT_FDPIC_INTERP 236
 
+#define PT_LAST_PSEUDO PT_FDPIC_INTERP
+
 #endif                         /* _BFIN_PTRACE_H */
index 42f6c53c59c651301e8547f820f6dddf3aeb9d20..14a3e66d916784d5aa69126950bb013a92b15b78 100644 (file)
@@ -21,6 +21,9 @@ extern unsigned long memory_start, memory_end, physical_mem_end;
 extern char _stext_l1[], _etext_l1[], _text_l1_lma[], __weak _text_l1_len[];
 extern char _sdata_l1[], _edata_l1[], _sbss_l1[], _ebss_l1[],
        _data_l1_lma[], __weak _data_l1_len[];
+#ifdef CONFIG_ROMKERNEL
+extern char _data_lma[], _data_len[], _sinitdata[], _einitdata[], _init_data_lma[], _init_data_len[];
+#endif
 extern char _sdata_b_l1[], _edata_b_l1[], _sbss_b_l1[], _ebss_b_l1[],
        _data_b_l1_lma[], __weak _data_b_l1_len[];
 extern char _stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[],
index 6a0fe94b84a62a5aaa7ee22ec810812c3b8f170d..f5b537967116d151c828eac66b2166b3d5f179eb 100644 (file)
@@ -22,8 +22,23 @@ extern char coreb_trampoline_start, coreb_trampoline_end;
 struct corelock_slot {
        int lock;
 };
+extern struct corelock_slot corelock;
+
+#ifdef __ARCH_SYNC_CORE_ICACHE
+extern unsigned long icache_invld_count[NR_CPUS];
+#endif
+#ifdef __ARCH_SYNC_CORE_DCACHE
+extern unsigned long dcache_invld_count[NR_CPUS];
+#endif
 
 void smp_icache_flush_range_others(unsigned long start,
                                   unsigned long end);
+#ifdef CONFIG_HOTPLUG_CPU
+void coreb_sleep(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
+void cpu_die(void);
+void platform_cpu_die(void);
+int __cpu_disable(void);
+int __cpu_die(unsigned int cpu);
+#endif
 
 #endif /* !__ASM_BLACKFIN_SMP_H */
diff --git a/arch/blackfin/include/asm/syscall.h b/arch/blackfin/include/asm/syscall.h
new file mode 100644 (file)
index 0000000..4921a48
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Magic syscall break down functions
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __ASM_BLACKFIN_SYSCALL_H__
+#define __ASM_BLACKFIN_SYSCALL_H__
+
+/*
+ * Blackfin syscalls are simple:
+ *     enter:
+ *             p0: syscall number
+ *             r{0,1,2,3,4,5}: syscall args 0,1,2,3,4,5
+ *     exit:
+ *             r0: return/error value
+ */
+
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+static inline long
+syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+       return regs->p0;
+}
+
+static inline void
+syscall_rollback(struct task_struct *task, struct pt_regs *regs)
+{
+       regs->p0 = regs->orig_p0;
+}
+
+static inline long
+syscall_get_error(struct task_struct *task, struct pt_regs *regs)
+{
+       return IS_ERR_VALUE(regs->r0) ? regs->r0 : 0;
+}
+
+static inline long
+syscall_get_return_value(struct task_struct *task, struct pt_regs *regs)
+{
+       return regs->r0;
+}
+
+static inline void
+syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
+                         int error, long val)
+{
+       regs->r0 = error ? -error : val;
+}
+
+/**
+ *     syscall_get_arguments()
+ *     @task:   unused
+ *     @regs:   the register layout to extract syscall arguments from
+ *     @i:      first syscall argument to extract
+ *     @n:      number of syscall arguments to extract
+ *     @args:   array to return the syscall arguments in
+ *
+ * args[0] gets i'th argument, args[n - 1] gets the i+n-1'th argument
+ */
+static inline void
+syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
+                      unsigned int i, unsigned int n, unsigned long *args)
+{
+       /*
+        * Assume the ptrace layout doesn't change -- r5 is first in memory,
+        * then r4, ..., then r0.  So we simply reverse the ptrace register
+        * array in memory to store into the args array.
+        */
+       long *aregs = &regs->r0 - i;
+
+       BUG_ON(i > 5 || i + n > 6);
+
+       while (n--)
+               *args++ = *aregs--;
+}
+
+/* See syscall_get_arguments() comments */
+static inline void
+syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
+                      unsigned int i, unsigned int n, const unsigned long *args)
+{
+       long *aregs = &regs->r0 - i;
+
+       BUG_ON(i > 5 || i + n > 6);
+
+       while (n--)
+               *aregs-- = *args++;
+}
+
+#endif
index a40d9368c38a3c3e8a78b9d79b962150831abc2d..e9a5614cdbb15abb2a78412661c364e4af9f5e12 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2009 Analog Devices Inc.
+ * Copyright 2004-2010 Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later.
  */
@@ -17,7 +17,7 @@
 /* Thread Align Mask to reach to the top of the stack
  * for any process
  */
-#define ALIGN_PAGE_MASK         0xffffe000
+#define ALIGN_PAGE_MASK                0xffffe000
 
 /*
  * Size of kernel stack for each process. This must be a power of 2...
@@ -57,7 +57,7 @@ struct thread_info {
        .exec_domain    = &default_exec_domain, \
        .flags          = 0,                    \
        .cpu            = 0,                    \
-       .preempt_count  = INIT_PREEMPT_COUNT,   \
+       .preempt_count  = INIT_PREEMPT_COUNT,   \
        .restart_block  = {                     \
                .fn = do_no_restart_syscall,    \
        },                                      \
@@ -73,8 +73,7 @@ __attribute_const__
 static inline struct thread_info *current_thread_info(void)
 {
        struct thread_info *ti;
-      __asm__("%0 = sp;" : "=da"(ti) :
-       );
+       __asm__("%0 = sp;" : "=da"(ti));
        return (struct thread_info *)((long)ti & ~((long)THREAD_SIZE-1));
 }
 
@@ -99,21 +98,23 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_NEED_RESCHED       2       /* rescheduling necessary */
 #define TIF_POLLING_NRFLAG     3       /* true if poll_idle() is polling
                                           TIF_NEED_RESCHED */
-#define TIF_MEMDIE              4
+#define TIF_MEMDIE             4
 #define TIF_RESTORE_SIGMASK    5       /* restore signal mask in do_signal() */
-#define TIF_FREEZE              6       /* is freezing for suspend */
-#define TIF_IRQ_SYNC            7       /* sync pipeline stage */
-#define TIF_NOTIFY_RESUME       8       /* callback before returning to user */
+#define TIF_FREEZE             6       /* is freezing for suspend */
+#define TIF_IRQ_SYNC           7       /* sync pipeline stage */
+#define TIF_NOTIFY_RESUME      8       /* callback before returning to user */
+#define TIF_SINGLESTEP         9
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
-#define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 #define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
-#define _TIF_FREEZE             (1<<TIF_FREEZE)
-#define _TIF_IRQ_SYNC           (1<<TIF_IRQ_SYNC)
+#define _TIF_FREEZE            (1<<TIF_FREEZE)
+#define _TIF_IRQ_SYNC          (1<<TIF_IRQ_SYNC)
+#define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
+#define _TIF_SINGLESTEP                (1<<TIF_SINGLESTEP)
 
 #define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
 
index 589e937ed1ebedfd4e7802ff68316fad0255cc9e..9ca7db844d1075d56a2b4e4ba33d14cb1c631433 100644 (file)
@@ -23,9 +23,7 @@
  */
 
 #ifndef CONFIG_CPU_FREQ
-#define TIME_SCALE 1
-#define __bfin_cycles_off (0)
-#define __bfin_cycles_mod (0)
+# define TIME_SCALE 1
 #else
 /*
  * Blackfin CPU frequency scaling supports max Core Clock 1, 1/2 and 1/4 .
  * adjust the Core Timer Presale Register. This way we don't lose time.
  */
 #define TIME_SCALE 4
+
+# ifdef CONFIG_CYCLES_CLOCKSOURCE
 extern unsigned long long __bfin_cycles_off;
 extern unsigned int __bfin_cycles_mod;
+# endif
+#endif
+
+#if defined(CONFIG_TICKSOURCE_CORETMR)
+extern void bfin_coretmr_init(void);
+extern void bfin_coretmr_clockevent_init(void);
 #endif
 
-extern void __init setup_core_timer(void);
 #endif
index a8ddbc8ed5af6d430ce5da0bf42ec2cf6ddfb531..346a421f1562fad53d66485d3d8d7ea2b51935ff 100644 (file)
@@ -25,6 +25,7 @@ obj-$(CONFIG_CPLB_INFO)              += cplbinfo.o
 obj-$(CONFIG_MODULES)                += module.o
 obj-$(CONFIG_KGDB)                   += kgdb.o
 obj-$(CONFIG_KGDB_TESTS)             += kgdb_test.o
+obj-$(CONFIG_NMI_WATCHDOG)           += nmi.o
 obj-$(CONFIG_EARLY_PRINTK)           += early_printk.o
 obj-$(CONFIG_EARLY_PRINTK)           += shadow_console.o
 obj-$(CONFIG_STACKTRACE)             += stacktrace.o
index 924c00286bab84d87611bc8896df9ba85806fd09..26403d1c9e6524949a421673b690d7d41bf0efa3 100644 (file)
@@ -91,7 +91,7 @@ late_initcall(proc_dma_init);
  */
 int request_dma(unsigned int channel, const char *device_id)
 {
-       pr_debug("request_dma() : BEGIN \n");
+       pr_debug("request_dma() : BEGIN\n");
 
        if (device_id == NULL)
                printk(KERN_WARNING "request_dma(%u): no device_id given\n", channel);
@@ -107,7 +107,7 @@ int request_dma(unsigned int channel, const char *device_id)
 #endif
 
        if (atomic_cmpxchg(&dma_ch[channel].chan_status, 0, 1)) {
-               pr_debug("DMA CHANNEL IN USE  \n");
+               pr_debug("DMA CHANNEL IN USE\n");
                return -EBUSY;
        }
 
@@ -131,7 +131,7 @@ int request_dma(unsigned int channel, const char *device_id)
         * you have to request DMA, before doing any operations on
         * descriptor/channel
         */
-       pr_debug("request_dma() : END  \n");
+       pr_debug("request_dma() : END\n");
        return 0;
 }
 EXPORT_SYMBOL(request_dma);
@@ -171,7 +171,7 @@ static void clear_dma_buffer(unsigned int channel)
 
 void free_dma(unsigned int channel)
 {
-       pr_debug("freedma() : BEGIN \n");
+       pr_debug("freedma() : BEGIN\n");
        BUG_ON(channel >= MAX_DMA_CHANNELS ||
                        !atomic_read(&dma_ch[channel].chan_status));
 
@@ -185,7 +185,7 @@ void free_dma(unsigned int channel)
        /* Clear the DMA Variable in the Channel */
        atomic_set(&dma_ch[channel].chan_status, 0);
 
-       pr_debug("freedma() : END \n");
+       pr_debug("freedma() : END\n");
 }
 EXPORT_SYMBOL(free_dma);
 
index a174596cc009b513d5221bb222b43b0246255684..e35e20f00d9b3c864ec2a568afc86947f2a5681d 100644 (file)
@@ -1289,44 +1289,50 @@ __initcall(gpio_register_proc);
 #endif
 
 #ifdef CONFIG_GPIOLIB
-int bfin_gpiolib_direction_input(struct gpio_chip *chip, unsigned gpio)
+static int bfin_gpiolib_direction_input(struct gpio_chip *chip, unsigned gpio)
 {
        return bfin_gpio_direction_input(gpio);
 }
 
-int bfin_gpiolib_direction_output(struct gpio_chip *chip, unsigned gpio, int level)
+static int bfin_gpiolib_direction_output(struct gpio_chip *chip, unsigned gpio, int level)
 {
        return bfin_gpio_direction_output(gpio, level);
 }
 
-int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio)
+static int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio)
 {
        return bfin_gpio_get_value(gpio);
 }
 
-void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value)
+static void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value)
 {
        return bfin_gpio_set_value(gpio, value);
 }
 
-int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio)
+static int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio)
 {
        return bfin_gpio_request(gpio, chip->label);
 }
 
-void bfin_gpiolib_gpio_free(struct gpio_chip *chip, unsigned gpio)
+static void bfin_gpiolib_gpio_free(struct gpio_chip *chip, unsigned gpio)
 {
        return bfin_gpio_free(gpio);
 }
 
+static int bfin_gpiolib_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
+{
+       return gpio + GPIO_IRQ_BASE;
+}
+
 static struct gpio_chip bfin_chip = {
-       .label                  = "Blackfin-GPIOlib",
+       .label                  = "BFIN-GPIO",
        .direction_input        = bfin_gpiolib_direction_input,
        .get                    = bfin_gpiolib_get_value,
        .direction_output       = bfin_gpiolib_direction_output,
        .set                    = bfin_gpiolib_set_value,
        .request                = bfin_gpiolib_gpio_request,
        .free                   = bfin_gpiolib_gpio_free,
+       .to_irq                 = bfin_gpiolib_gpio_to_irq,
        .base                   = 0,
        .ngpio                  = MAX_BLACKFIN_GPIOS,
 };
index 8d42b9e50dfa16a21679674a63669762862800a3..30fd6417f0698f53d30fd263dd534fb6cc92e992 100644 (file)
@@ -64,6 +64,15 @@ void __init generate_cplb_tables_cpu(unsigned int cpu)
                icplb_tbl[cpu][i_i++].data = i_data | (addr == 0 ? CPLB_USER_RD : 0);
        }
 
+#ifdef CONFIG_ROMKERNEL
+       /* Cover kernel XIP flash area */
+       addr = CONFIG_ROM_BASE & ~(4 * 1024 * 1024 - 1);
+       dcplb_tbl[cpu][i_d].addr = addr;
+       dcplb_tbl[cpu][i_d++].data = d_data | CPLB_USER_RD;
+       icplb_tbl[cpu][i_i].addr = addr;
+       icplb_tbl[cpu][i_i++].data = i_data | CPLB_USER_RD;
+#endif
+
        /* Cover L1 memory.  One 4M area for code and data each is enough.  */
 #if L1_DATA_A_LENGTH > 0 || L1_DATA_B_LENGTH > 0
        dcplb_tbl[cpu][i_d].addr = get_l1_data_a_start_cpu(cpu);
index 930c01c0681348bd51f1ddc6a0d1e413cd9acad4..87b25b1b30ed6a317b6b57bf98d82de6241648a0 100644 (file)
@@ -31,6 +31,12 @@ int nr_dcplb_miss[NR_CPUS], nr_icplb_miss[NR_CPUS];
 int nr_icplb_supv_miss[NR_CPUS], nr_dcplb_prot[NR_CPUS];
 int nr_cplb_flush[NR_CPUS];
 
+#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
+#define MGR_ATTR __attribute__((l1_text))
+#else
+#define MGR_ATTR
+#endif
+
 /*
  * Given the contents of the status register, return the index of the
  * CPLB that caused the fault.
@@ -59,7 +65,7 @@ static int icplb_rr_index[NR_CPUS], dcplb_rr_index[NR_CPUS];
 /*
  * Find an ICPLB entry to be evicted and return its index.
  */
-static int evict_one_icplb(unsigned int cpu)
+MGR_ATTR static int evict_one_icplb(unsigned int cpu)
 {
        int i;
        for (i = first_switched_icplb; i < MAX_CPLBS; i++)
@@ -74,7 +80,7 @@ static int evict_one_icplb(unsigned int cpu)
        return i;
 }
 
-static int evict_one_dcplb(unsigned int cpu)
+MGR_ATTR static int evict_one_dcplb(unsigned int cpu)
 {
        int i;
        for (i = first_switched_dcplb; i < MAX_CPLBS; i++)
@@ -89,7 +95,7 @@ static int evict_one_dcplb(unsigned int cpu)
        return i;
 }
 
-static noinline int dcplb_miss(unsigned int cpu)
+MGR_ATTR static noinline int dcplb_miss(unsigned int cpu)
 {
        unsigned long addr = bfin_read_DCPLB_FAULT_ADDR();
        int status = bfin_read_DCPLB_STATUS();
@@ -114,10 +120,15 @@ static noinline int dcplb_miss(unsigned int cpu)
                d_data = L2_DMEMORY;
        } else if (addr >= physical_mem_end) {
                if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) {
-                       addr &= ~(4 * 1024 * 1024 - 1);
-                       d_data &= ~PAGE_SIZE_4KB;
-                       d_data |= PAGE_SIZE_4MB;
-                       d_data |= CPLB_USER_RD | CPLB_USER_WR;
+                       mask = current_rwx_mask[cpu];
+                       if (mask) {
+                               int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT;
+                               int idx = page >> 5;
+                               int bit = 1 << (page & 31);
+
+                               if (mask[idx] & bit)
+                                       d_data |= CPLB_USER_RD;
+                       }
                } else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH
                    && (status & (FAULT_RW | FAULT_USERSUPV)) == FAULT_USERSUPV) {
                        addr &= ~(1 * 1024 * 1024 - 1);
@@ -126,7 +137,9 @@ static noinline int dcplb_miss(unsigned int cpu)
                } else
                        return CPLB_PROT_VIOL;
        } else if (addr >= _ramend) {
-           d_data |= CPLB_USER_RD | CPLB_USER_WR;
+               d_data |= CPLB_USER_RD | CPLB_USER_WR;
+               if (reserved_mem_dcache_on)
+                       d_data |= CPLB_L1_CHBL;
        } else {
                mask = current_rwx_mask[cpu];
                if (mask) {
@@ -156,7 +169,7 @@ static noinline int dcplb_miss(unsigned int cpu)
        return 0;
 }
 
-static noinline int icplb_miss(unsigned int cpu)
+MGR_ATTR static noinline int icplb_miss(unsigned int cpu)
 {
        unsigned long addr = bfin_read_ICPLB_FAULT_ADDR();
        int status = bfin_read_ICPLB_STATUS();
@@ -204,10 +217,19 @@ static noinline int icplb_miss(unsigned int cpu)
                i_data = L2_IMEMORY;
        } else if (addr >= physical_mem_end) {
                if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) {
-                       addr &= ~(4 * 1024 * 1024 - 1);
-                       i_data &= ~PAGE_SIZE_4KB;
-                       i_data |= PAGE_SIZE_4MB;
-                       i_data |= CPLB_USER_RD;
+                       if (!(status & FAULT_USERSUPV)) {
+                               unsigned long *mask = current_rwx_mask[cpu];
+
+                               if (mask) {
+                                       int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT;
+                                       int idx = page >> 5;
+                                       int bit = 1 << (page & 31);
+
+                                       mask += 2 * page_mask_nelts;
+                                       if (mask[idx] & bit)
+                                               i_data |= CPLB_USER_RD;
+                               }
+                       }
                } else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH
                    && (status & FAULT_USERSUPV)) {
                        addr &= ~(1 * 1024 * 1024 - 1);
@@ -217,6 +239,8 @@ static noinline int icplb_miss(unsigned int cpu)
                    return CPLB_PROT_VIOL;
        } else if (addr >= _ramend) {
                i_data |= CPLB_USER_RD;
+               if (reserved_mem_icache_on)
+                       i_data |= CPLB_L1_CHBL;
        } else {
                /*
                 * Two cases to distinguish - a supervisor access must
@@ -251,7 +275,7 @@ static noinline int icplb_miss(unsigned int cpu)
        return 0;
 }
 
-static noinline int dcplb_protection_fault(unsigned int cpu)
+MGR_ATTR static noinline int dcplb_protection_fault(unsigned int cpu)
 {
        int status = bfin_read_DCPLB_STATUS();
 
@@ -271,7 +295,7 @@ static noinline int dcplb_protection_fault(unsigned int cpu)
        return CPLB_PROT_VIOL;
 }
 
-int cplb_hdr(int seqstat, struct pt_regs *regs)
+MGR_ATTR int cplb_hdr(int seqstat, struct pt_regs *regs)
 {
        int cause = seqstat & 0x3f;
        unsigned int cpu = raw_smp_processor_id();
index 282a7919821b0a8776dd9283bdca4e2677f893a0..bfe75af4e8bd71db8fbe50c7bfe2a30c8ba00723 100644 (file)
@@ -56,6 +56,15 @@ void __init generate_cplb_tables_cpu(unsigned int cpu)
                i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_4MB;
        }
 
+#ifdef CONFIG_ROMKERNEL
+       /* Cover kernel XIP flash area */
+       addr = CONFIG_ROM_BASE & ~(4 * 1024 * 1024 - 1);
+       d_tbl[i_d].addr = addr;
+       d_tbl[i_d++].data = SDRAM_DGENERIC | PAGE_SIZE_4MB;
+       i_tbl[i_i].addr = addr;
+       i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_4MB;
+#endif
+
        /* Cover L1 memory.  One 4M area for code and data each is enough.  */
        if (cpu == 0) {
                if (L1_DATA_A_LENGTH || L1_DATA_B_LENGTH) {
index e937f323d82c6f61dd4dc4309eabcb413fc99f76..04ddcfeb798140a3ffb465157948395577874ebd 100644 (file)
@@ -116,7 +116,7 @@ EXPORT_SYMBOL(dma_free_coherent);
 void __dma_sync(dma_addr_t addr, size_t size,
                enum dma_data_direction dir)
 {
-       _dma_sync(addr, size, dir);
+       __dma_sync_inline(addr, size, dir);
 }
 EXPORT_SYMBOL(__dma_sync);
 
index f27dc2292e1b5aae716cdb477cf44297c99f52b6..686478f5f66b90402ffad203bce6d2dc37b78e13 100644 (file)
@@ -44,7 +44,7 @@ ENTRY(_ret_from_fork)
        sti r4;
 #endif /* CONFIG_IPIPE */
        SP += -12;
-       call _schedule_tail;
+       pseudo_long_call _schedule_tail, p5;
        SP += 12;
        r0 = [sp + PT_IPEND];
        cc = bittst(r0,1);
@@ -79,7 +79,7 @@ ENTRY(_sys_vfork)
        r0 += 24;
        [--sp] = rets;
        SP += -12;
-       call _bfin_vfork;
+       pseudo_long_call _bfin_vfork, p2;
        SP += 12;
        rets = [sp++];
        rts;
@@ -90,7 +90,7 @@ ENTRY(_sys_clone)
        r0 += 24;
        [--sp] = rets;
        SP += -12;
-       call _bfin_clone;
+       pseudo_long_call _bfin_clone, p2;
        SP += 12;
        rets = [sp++];
        rts;
@@ -101,7 +101,7 @@ ENTRY(_sys_rt_sigreturn)
        r0 += 24;
        [--sp] = rets;
        SP += -12;
-       call _do_rt_sigreturn;
+       pseudo_long_call _do_rt_sigreturn, p2;
        SP += 12;
        rets = [sp++];
        rts;
index 76dd4fbcd17a2e8f7adc45f76237e0c2a4d19538..d66446b572c064b198e6f0efee79f1caf451d117 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * mcount and friends -- ftrace stuff
  *
- * Copyright (C) 2009 Analog Devices Inc.
+ * Copyright (C) 2009-2010 Analog Devices Inc.
  * Licensed under the GPL-2 or later.
  */
 
  * function will be waiting there.  mmmm pie.
  */
 ENTRY(__mcount)
+#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
+       /* optional micro optimization: return if stopped */
+       p1.l = _function_trace_stop;
+       p1.h = _function_trace_stop;
+       r3 = [p1];
+       cc = r3 == 0;
+       if ! cc jump _ftrace_stub (bp);
+#endif
+
        /* save third function arg early so we can do testing below */
        [--sp] = r2;
 
@@ -106,9 +115,12 @@ ENTRY(_ftrace_graph_caller)
        [--sp] = r1;
        [--sp] = rets;
 
-       /* prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) */
-       r0 = sp;
-       r1 = rets;
+       /* prepare_ftrace_return(parent, self_addr, frame_pointer) */
+       r0 = sp;        /* unsigned long *parent */
+       r1 = rets;      /* unsigned long self_addr */
+#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST
+       r2 = fp;        /* unsigned long frame_pointer */
+#endif
        r0 += 16;       /* skip the 4 local regs on stack */
        r1 += -MCOUNT_INSN_SIZE;
        call _prepare_ftrace_return;
@@ -127,6 +139,9 @@ ENTRY(_return_to_handler)
        [--sp] = r1;
 
        /* get original return address */
+#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST
+       r0 = fp;        /* Blackfin is sane, so omit this */
+#endif
        call _ftrace_return_to_handler;
        rets = r0;
 
index f2c85ac6f2daf7dcfa47628a893b3993a15eeedc..a61d948ea92531de3bf1662a3ae981e8b3782f97 100644 (file)
@@ -16,7 +16,8 @@
  * Hook the return address and push it in the stack of return addrs
  * in current thread info.
  */
-void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
+                           unsigned long frame_pointer)
 {
        struct ftrace_graph_ent trace;
        unsigned long return_hooker = (unsigned long)&return_to_handler;
@@ -24,7 +25,8 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
        if (unlikely(atomic_read(&current->tracing_graph_pause)))
                return;
 
-       if (ftrace_push_return_trace(*parent, self_addr, &trace.depth, 0) == -EBUSY)
+       if (ftrace_push_return_trace(*parent, self_addr, &trace.depth,
+                                    frame_pointer) == -EBUSY)
                return;
 
        trace.func = self_addr;
index 118c5b9dedacf9fdbb9ed719dffa4c430a4af2f9..d3970e8acd1a20bc541689ec8914330030118c22 100644 (file)
@@ -28,5 +28,5 @@ EXPORT_SYMBOL(init_task);
  * "init_task" linker map entry.
  */
 union thread_union init_thread_union
-    __attribute__ ((__section__(".init_task.data"))) = {
+    __init_task_data = {
 INIT_THREAD_INFO(init_task)};
index a77307a4473b3f6ab5395ffb8f1a337982f99483..1a496cd71ba2427fb7dffa75cbc331d522b39275 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/interrupt.h>
 #include <linux/percpu.h>
 #include <linux/bitops.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/kthread.h>
 #include <linux/unistd.h>
index 34c7c3ed2c9c5e7eafc7453c5a7a7bfacea5329a..2c501ceb1e557e4bc25a57d6ea611cb7806b06a5 100644 (file)
@@ -145,7 +145,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 #endif
 }
 
-struct hw_breakpoint {
+static struct hw_breakpoint {
        unsigned int occupied:1;
        unsigned int skip:1;
        unsigned int enabled:1;
@@ -155,7 +155,7 @@ struct hw_breakpoint {
        unsigned int addr;
 } breakinfo[HW_WATCHPOINT_NUM];
 
-int bfin_set_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
+static int bfin_set_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
 {
        int breakno;
        int bfin_type;
@@ -202,7 +202,7 @@ int bfin_set_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
        return -ENOSPC;
 }
 
-int bfin_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
+static int bfin_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
 {
        int breakno;
        int bfin_type;
@@ -230,7 +230,7 @@ int bfin_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
        return 0;
 }
 
-void bfin_remove_all_hw_break(void)
+static void bfin_remove_all_hw_break(void)
 {
        int breakno;
 
@@ -242,7 +242,7 @@ void bfin_remove_all_hw_break(void)
                breakinfo[breakno].type = TYPE_DATA_WATCHPOINT;
 }
 
-void bfin_correct_hw_break(void)
+static void bfin_correct_hw_break(void)
 {
        int breakno;
        unsigned int wpiactl = 0;
diff --git a/arch/blackfin/kernel/nmi.c b/arch/blackfin/kernel/nmi.c
new file mode 100644 (file)
index 0000000..0b5f72f
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * Blackfin nmi_watchdog Driver
+ *
+ * Originally based on bfin_wdt.c
+ * Copyright 2010-2010 Analog Devices Inc.
+ *             Graff Yang <graf.yang@analog.com>
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/bitops.h>
+#include <linux/hardirq.h>
+#include <linux/sysdev.h>
+#include <linux/pm.h>
+#include <linux/nmi.h>
+#include <linux/smp.h>
+#include <linux/timer.h>
+#include <asm/blackfin.h>
+#include <asm/atomic.h>
+#include <asm/cacheflush.h>
+#include <asm/bfin_watchdog.h>
+
+#define DRV_NAME "nmi-wdt"
+
+#define NMI_WDT_TIMEOUT 5          /* 5 seconds */
+#define NMI_CHECK_TIMEOUT (4 * HZ) /* 4 seconds in jiffies */
+static int nmi_wdt_cpu = 1;
+
+static unsigned int timeout = NMI_WDT_TIMEOUT;
+static int nmi_active;
+
+static unsigned short wdoga_ctl;
+static unsigned int wdoga_cnt;
+static struct corelock_slot saved_corelock;
+static atomic_t nmi_touched[NR_CPUS];
+static struct timer_list ntimer;
+
+enum {
+       COREA_ENTER_NMI = 0,
+       COREA_EXIT_NMI,
+       COREB_EXIT_NMI,
+
+       NMI_EVENT_NR,
+};
+static unsigned long nmi_event __attribute__ ((__section__(".l2.bss")));
+
+/* we are in nmi, non-atomic bit ops is safe */
+static inline void set_nmi_event(int event)
+{
+       __set_bit(event, &nmi_event);
+}
+
+static inline void wait_nmi_event(int event)
+{
+       while (!test_bit(event, &nmi_event))
+               barrier();
+       __clear_bit(event, &nmi_event);
+}
+
+static inline void send_corea_nmi(void)
+{
+       wdoga_ctl = bfin_read_WDOGA_CTL();
+       wdoga_cnt = bfin_read_WDOGA_CNT();
+
+       bfin_write_WDOGA_CTL(WDEN_DISABLE);
+       bfin_write_WDOGA_CNT(0);
+       bfin_write_WDOGA_CTL(WDEN_ENABLE | ICTL_NMI);
+}
+
+static inline void restore_corea_nmi(void)
+{
+       bfin_write_WDOGA_CTL(WDEN_DISABLE);
+       bfin_write_WDOGA_CTL(WDOG_EXPIRED | WDEN_DISABLE | ICTL_NONE);
+
+       bfin_write_WDOGA_CNT(wdoga_cnt);
+       bfin_write_WDOGA_CTL(wdoga_ctl);
+}
+
+static inline void save_corelock(void)
+{
+       saved_corelock = corelock;
+       corelock.lock = 0;
+}
+
+static inline void restore_corelock(void)
+{
+       corelock = saved_corelock;
+}
+
+
+static inline void nmi_wdt_keepalive(void)
+{
+       bfin_write_WDOGB_STAT(0);
+}
+
+static inline void nmi_wdt_stop(void)
+{
+       bfin_write_WDOGB_CTL(WDEN_DISABLE);
+}
+
+/* before calling this function, you must stop the WDT */
+static inline void nmi_wdt_clear(void)
+{
+       /* clear TRO bit, disable event generation */
+       bfin_write_WDOGB_CTL(WDOG_EXPIRED | WDEN_DISABLE | ICTL_NONE);
+}
+
+static inline void nmi_wdt_start(void)
+{
+       bfin_write_WDOGB_CTL(WDEN_ENABLE | ICTL_NMI);
+}
+
+static inline int nmi_wdt_running(void)
+{
+       return ((bfin_read_WDOGB_CTL() & WDEN_MASK) != WDEN_DISABLE);
+}
+
+static inline int nmi_wdt_set_timeout(unsigned long t)
+{
+       u32 cnt, max_t, sclk;
+       int run;
+
+       sclk = get_sclk();
+       max_t = -1 / sclk;
+       cnt = t * sclk;
+       if (t > max_t) {
+               pr_warning("NMI: timeout value is too large\n");
+               return -EINVAL;
+       }
+
+       run = nmi_wdt_running();
+       nmi_wdt_stop();
+       bfin_write_WDOGB_CNT(cnt);
+       if (run)
+               nmi_wdt_start();
+
+       timeout = t;
+
+       return 0;
+}
+
+int check_nmi_wdt_touched(void)
+{
+       unsigned int this_cpu = smp_processor_id();
+       unsigned int cpu;
+
+       cpumask_t mask = cpu_online_map;
+
+       if (!atomic_read(&nmi_touched[this_cpu]))
+               return 0;
+
+       atomic_set(&nmi_touched[this_cpu], 0);
+
+       cpu_clear(this_cpu, mask);
+       for_each_cpu_mask(cpu, mask) {
+               invalidate_dcache_range((unsigned long)(&nmi_touched[cpu]),
+                               (unsigned long)(&nmi_touched[cpu]));
+               if (!atomic_read(&nmi_touched[cpu]))
+                       return 0;
+               atomic_set(&nmi_touched[cpu], 0);
+       }
+
+       return 1;
+}
+
+static void nmi_wdt_timer(unsigned long data)
+{
+       if (check_nmi_wdt_touched())
+               nmi_wdt_keepalive();
+
+       mod_timer(&ntimer, jiffies + NMI_CHECK_TIMEOUT);
+}
+
+static int __init init_nmi_wdt(void)
+{
+       nmi_wdt_set_timeout(timeout);
+       nmi_wdt_start();
+       nmi_active = true;
+
+       init_timer(&ntimer);
+       ntimer.function = nmi_wdt_timer;
+       ntimer.expires = jiffies + NMI_CHECK_TIMEOUT;
+       add_timer(&ntimer);
+
+       pr_info("nmi_wdt: initialized: timeout=%d sec\n", timeout);
+       return 0;
+}
+device_initcall(init_nmi_wdt);
+
+void touch_nmi_watchdog(void)
+{
+       atomic_set(&nmi_touched[smp_processor_id()], 1);
+}
+
+/* Suspend/resume support */
+#ifdef CONFIG_PM
+static int nmi_wdt_suspend(struct sys_device *dev, pm_message_t state)
+{
+       nmi_wdt_stop();
+       return 0;
+}
+
+static int nmi_wdt_resume(struct sys_device *dev)
+{
+       if (nmi_active)
+               nmi_wdt_start();
+       return 0;
+}
+
+static struct sysdev_class nmi_sysclass = {
+       .name           = DRV_NAME,
+       .resume         = nmi_wdt_resume,
+       .suspend        = nmi_wdt_suspend,
+};
+
+static struct sys_device device_nmi_wdt = {
+       .id     = 0,
+       .cls    = &nmi_sysclass,
+};
+
+static int __init init_nmi_wdt_sysfs(void)
+{
+       int error;
+
+       if (!nmi_active)
+               return 0;
+
+       error = sysdev_class_register(&nmi_sysclass);
+       if (!error)
+               error = sysdev_register(&device_nmi_wdt);
+       return error;
+}
+late_initcall(init_nmi_wdt_sysfs);
+
+#endif /* CONFIG_PM */
+
+
+asmlinkage notrace void do_nmi(struct pt_regs *fp)
+{
+       unsigned int cpu = smp_processor_id();
+       nmi_enter();
+
+       cpu_pda[cpu].__nmi_count += 1;
+
+       if (cpu == nmi_wdt_cpu) {
+               /* CoreB goes here first */
+
+               /* reload the WDOG_STAT */
+               nmi_wdt_keepalive();
+
+               /* clear nmi interrupt for CoreB */
+               nmi_wdt_stop();
+               nmi_wdt_clear();
+
+               /* trigger NMI interrupt of CoreA */
+               send_corea_nmi();
+
+               /* waiting CoreB to enter NMI */
+               wait_nmi_event(COREA_ENTER_NMI);
+
+               /* recover WDOGA's settings */
+               restore_corea_nmi();
+
+               save_corelock();
+
+               /* corelock is save/cleared, CoreA is dummping messages */
+
+               wait_nmi_event(COREA_EXIT_NMI);
+       } else {
+               /* OK, CoreA entered NMI */
+               set_nmi_event(COREA_ENTER_NMI);
+       }
+
+       pr_emerg("\nNMI Watchdog detected LOCKUP, dump for CPU %d\n", cpu);
+       dump_bfin_process(fp);
+       dump_bfin_mem(fp);
+       show_regs(fp);
+       dump_bfin_trace_buffer();
+       show_stack(current, (unsigned long *)fp);
+
+       if (cpu == nmi_wdt_cpu) {
+               pr_emerg("This fault is not recoverable, sorry!\n");
+
+               /* CoreA dump finished, restore the corelock */
+               restore_corelock();
+
+               set_nmi_event(COREB_EXIT_NMI);
+       } else {
+               /* CoreB dump finished, notice the CoreA we are done */
+               set_nmi_event(COREA_EXIT_NMI);
+
+               /* synchronize with CoreA */
+               wait_nmi_event(COREB_EXIT_NMI);
+       }
+
+       nmi_exit();
+}
index b56b0e485e0bb3e8cb5e0ad79575d8e5eefad6de..93ec07da2e513866356aba2baedaa0739e1351f2 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/unistd.h>
 #include <linux/user.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/tick.h>
 #include <linux/fs.h>
@@ -98,13 +99,6 @@ void cpu_idle(void)
        }
 }
 
-/* Fill in the fpu structure for a core dump.  */
-
-int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpregs)
-{
-       return 1;
-}
-
 /*
  * This gets run with P1 containing the
  * function to call, and R1 containing
index 65567dc4b9f5a0b1a10c5b5cddafab9bbbc99cc2..43eb969405d1657bd0aba85b2528e9d28296bd55 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
- * these modifications are Copyright 2004-2009 Analog Devices Inc.
+ * these modifications are Copyright 2004-2010 Analog Devices Inc.
  *
  * Licensed under the GPL-2
  */
@@ -9,10 +9,13 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
+#include <linux/elf.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
+#include <linux/regset.h>
 #include <linux/signal.h>
+#include <linux/tracehook.h>
 #include <linux/uaccess.h>
 
 #include <asm/page.h>
 #include <asm/cacheflush.h>
 #include <asm/mem_map.h>
 
-#define TEXT_OFFSET 0
 /*
  * does not yet catch signals sent when the child dies.
  * in exit.c or in signal.c.
  */
 
-/* determines which bits in the SYSCFG reg the user has access to. */
-/* 1 = access 0 = no access */
-#define SYSCFG_MASK 0x0007     /* SYSCFG reg */
-/* sets the trace bits. */
-#define TRACE_BITS 0x0001
-
-/* Find the stack offset for a register, relative to thread.esp0. */
-#define PT_REG(reg)    ((long)&((struct pt_regs *)0)->reg)
-
-/*
- * Get the address of the live pt_regs for the specified task.
- * These are saved onto the top kernel stack when the process
- * is not running.
- *
- * Note: if a user thread is execve'd from kernel space, the
- * kernel stack will not be empty on entry to the kernel, so
- * ptracing these tasks will fail.
- */
-static inline struct pt_regs *get_user_regs(struct task_struct *task)
-{
-       return (struct pt_regs *)
-           ((unsigned long)task_stack_page(task) +
-            (THREAD_SIZE - sizeof(struct pt_regs)));
-}
-
-/*
- * Get all user integer registers.
- */
-static inline int ptrace_getregs(struct task_struct *tsk, void __user *uregs)
-{
-       struct pt_regs regs;
-       memcpy(&regs, get_user_regs(tsk), sizeof(regs));
-       regs.usp = tsk->thread.usp;
-       return copy_to_user(uregs, &regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
-}
-
-/* Mapping from PT_xxx to the stack offset at which the register is
- * saved.  Notice that usp has no stack-slot and needs to be treated
- * specially (see get_reg/put_reg below).
- */
-
 /*
  * Get contents of register REGNO in task TASK.
  */
-static inline long get_reg(struct task_struct *task, int regno)
+static inline long
+get_reg(struct task_struct *task, long regno, unsigned long __user *datap)
 {
-       unsigned char *reg_ptr;
+       long tmp;
+       struct pt_regs *regs = task_pt_regs(task);
 
-       struct pt_regs *regs =
-           (struct pt_regs *)((unsigned long)task_stack_page(task) +
-                              (THREAD_SIZE - sizeof(struct pt_regs)));
-       reg_ptr = (char *)regs;
+       if (regno & 3 || regno > PT_LAST_PSEUDO || regno < 0)
+               return -EIO;
 
        switch (regno) {
+       case PT_TEXT_ADDR:
+               tmp = task->mm->start_code;
+               break;
+       case PT_TEXT_END_ADDR:
+               tmp = task->mm->end_code;
+               break;
+       case PT_DATA_ADDR:
+               tmp = task->mm->start_data;
+               break;
        case PT_USP:
-               return task->thread.usp;
+               tmp = task->thread.usp;
+               break;
        default:
-               if (regno <= 216)
-                       return *(long *)(reg_ptr + regno);
+               if (regno < sizeof(*regs)) {
+                       void *reg_ptr = regs;
+                       tmp = *(long *)(reg_ptr + regno);
+               } else
+                       return -EIO;
        }
-       /* slight mystery ... never seems to come here but kernel misbehaves without this code! */
 
-       printk(KERN_WARNING "Request to get for unknown register %d\n", regno);
-       return 0;
+       return put_user(tmp, datap);
 }
 
 /*
  * Write contents of register REGNO in task TASK.
  */
 static inline int
-put_reg(struct task_struct *task, int regno, unsigned long data)
+put_reg(struct task_struct *task, long regno, unsigned long data)
 {
-       char *reg_ptr;
+       struct pt_regs *regs = task_pt_regs(task);
 
-       struct pt_regs *regs =
-           (struct pt_regs *)((unsigned long)task_stack_page(task) +
-                              (THREAD_SIZE - sizeof(struct pt_regs)));
-       reg_ptr = (char *)regs;
+       if (regno & 3 || regno > PT_LAST_PSEUDO || regno < 0)
+               return -EIO;
 
        switch (regno) {
        case PT_PC:
@@ -125,10 +95,18 @@ put_reg(struct task_struct *task, int regno, unsigned long data)
                regs->usp = data;
                task->thread.usp = data;
                break;
+       case PT_SYSCFG: /* don't let userspace screw with this */
+               if ((data & ~1) != 0x6)
+                       pr_warning("ptrace: ignore syscfg write of %#lx\n", data);
+               break;          /* regs->syscfg = data; break; */
        default:
-               if (regno <= 216)
-                       *(long *)(reg_ptr + regno) = data;
+               if (regno < sizeof(*regs)) {
+                       void *reg_offset = regs;
+                       *(long *)(reg_offset + regno) = data;
+               }
+               /* Ignore writes to pseudo registers */
        }
+
        return 0;
 }
 
@@ -160,24 +138,98 @@ static inline int is_user_addr_valid(struct task_struct *child,
        return -EIO;
 }
 
-void ptrace_enable(struct task_struct *child)
+/*
+ * retrieve the contents of Blackfin userspace general registers
+ */
+static int genregs_get(struct task_struct *target,
+                      const struct user_regset *regset,
+                      unsigned int pos, unsigned int count,
+                      void *kbuf, void __user *ubuf)
 {
-       unsigned long tmp;
-       tmp = get_reg(child, PT_SYSCFG) | (TRACE_BITS);
-       put_reg(child, PT_SYSCFG, tmp);
+       struct pt_regs *regs = task_pt_regs(target);
+       int ret;
+
+       /* This sucks ... */
+       regs->usp = target->thread.usp;
+
+       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+                                 regs, 0, sizeof(*regs));
+       if (ret < 0)
+               return ret;
+
+       return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+                                       sizeof(*regs), -1);
 }
 
 /*
- * Called by kernel/ptrace.c when detaching..
- *
- * Make sure the single step bit is not set.
+ * update the contents of the Blackfin userspace general registers
+ */
+static int genregs_set(struct task_struct *target,
+                      const struct user_regset *regset,
+                      unsigned int pos, unsigned int count,
+                      const void *kbuf, const void __user *ubuf)
+{
+       struct pt_regs *regs = task_pt_regs(target);
+       int ret;
+
+       /* Don't let people set SYSCFG (it's at the end of pt_regs) */
+       ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+                                regs, 0, PT_SYSCFG);
+       if (ret < 0)
+               return ret;
+
+       /* This sucks ... */
+       target->thread.usp = regs->usp;
+       /* regs->retx = regs->pc; */
+
+       return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+                                       PT_SYSCFG, -1);
+}
+
+/*
+ * Define the register sets available on the Blackfin under Linux
  */
-void ptrace_disable(struct task_struct *child)
+enum bfin_regset {
+       REGSET_GENERAL,
+};
+
+static const struct user_regset bfin_regsets[] = {
+       [REGSET_GENERAL] = {
+               .core_note_type = NT_PRSTATUS,
+               .n              = sizeof(struct pt_regs) / sizeof(long),
+               .size           = sizeof(long),
+               .align          = sizeof(long),
+               .get            = genregs_get,
+               .set            = genregs_set,
+       },
+};
+
+static const struct user_regset_view user_bfin_native_view = {
+       .name      = "Blackfin",
+       .e_machine = EM_BLACKFIN,
+       .regsets   = bfin_regsets,
+       .n         = ARRAY_SIZE(bfin_regsets),
+};
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *task)
+{
+       return &user_bfin_native_view;
+}
+
+void user_enable_single_step(struct task_struct *child)
+{
+       struct pt_regs *regs = task_pt_regs(child);
+       regs->syscfg |= SYSCFG_SSSTEP;
+
+       set_tsk_thread_flag(child, TIF_SINGLESTEP);
+}
+
+void user_disable_single_step(struct task_struct *child)
 {
-       unsigned long tmp;
-       /* make sure the single step bit is not set. */
-       tmp = get_reg(child, PT_SYSCFG) & ~TRACE_BITS;
-       put_reg(child, PT_SYSCFG, tmp);
+       struct pt_regs *regs = task_pt_regs(child);
+       regs->syscfg &= ~SYSCFG_SSSTEP;
+
+       clear_tsk_thread_flag(child, TIF_SINGLESTEP);
 }
 
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -240,40 +292,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        break;
                }
 
-               /* read the word at location addr in the USER area. */
-       case PTRACE_PEEKUSR:
-               {
-                       unsigned long tmp;
-                       ret = -EIO;
-                       tmp = 0;
-                       if ((addr & 3) || (addr > (sizeof(struct pt_regs) + 16))) {
-                               printk(KERN_WARNING "ptrace error : PEEKUSR : temporarily returning "
-                                                   "0 - %x sizeof(pt_regs) is %lx\n",
-                                    (int)addr, sizeof(struct pt_regs));
-                               break;
-                       }
-                       if (addr == sizeof(struct pt_regs)) {
-                               /* PT_TEXT_ADDR */
-                               tmp = child->mm->start_code + TEXT_OFFSET;
-                       } else if (addr == (sizeof(struct pt_regs) + 4)) {
-                               /* PT_TEXT_END_ADDR */
-                               tmp = child->mm->end_code;
-                       } else if (addr == (sizeof(struct pt_regs) + 8)) {
-                               /* PT_DATA_ADDR */
-                               tmp = child->mm->start_data;
-#ifdef CONFIG_BINFMT_ELF_FDPIC
-                       } else if (addr == (sizeof(struct pt_regs) + 12)) {
-                               goto case_PTRACE_GETFDPIC_EXEC;
-                       } else if (addr == (sizeof(struct pt_regs) + 16)) {
-                               goto case_PTRACE_GETFDPIC_INTERP;
-#endif
-                       } else {
-                               tmp = get_reg(child, addr);
-                       }
-                       ret = put_user(tmp, datap);
-                       break;
-               }
-
 #ifdef CONFIG_BINFMT_ELF_FDPIC
        case PTRACE_GETFDPIC: {
                unsigned long tmp = 0;
@@ -336,78 +354,36 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        break;
                }
 
-       case PTRACE_POKEUSR:    /* write the word at location addr in the USER area */
-               ret = -EIO;
-               if ((addr & 3) || (addr > (sizeof(struct pt_regs) + 16))) {
-                       printk(KERN_WARNING "ptrace error : POKEUSR: temporarily returning 0\n");
-                       break;
-               }
-
-               if (addr >= (sizeof(struct pt_regs))) {
-                       ret = 0;
-                       break;
-               }
-               if (addr == PT_SYSCFG) {
-                       data &= SYSCFG_MASK;
-                       data |= get_reg(child, PT_SYSCFG);
+       case PTRACE_PEEKUSR:
+               switch (addr) {
+#ifdef CONFIG_BINFMT_ELF_FDPIC /* backwards compat */
+               case PT_FDPIC_EXEC:   goto case_PTRACE_GETFDPIC_EXEC;
+               case PT_FDPIC_INTERP: goto case_PTRACE_GETFDPIC_INTERP;
+#endif
+               default:
+                       ret = get_reg(child, addr, datap);
                }
-               ret = put_reg(child, addr, data);
+               pr_debug("ptrace: PEEKUSR reg %li with %#lx = %i\n", addr, data, ret);
                break;
 
-       case PTRACE_SYSCALL:    /* continue and stop at next (return from) syscall */
-       case PTRACE_CONT:       /* restart after signal. */
-               pr_debug("ptrace: syscall/cont\n");
-
-               ret = -EIO;
-               if (!valid_signal(data))
-                       break;
-               if (request == PTRACE_SYSCALL)
-                       set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-               else
-                       clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-               child->exit_code = data;
-               ptrace_disable(child);
-               pr_debug("ptrace: before wake_up_process\n");
-               wake_up_process(child);
-               ret = 0;
-               break;
-
-       /*
-        * make the child exit.  Best I can do is send it a sigkill.
-        * perhaps it should be put in the status that it wants to
-        * exit.
-        */
-       case PTRACE_KILL:
-               ret = 0;
-               if (child->exit_state == EXIT_ZOMBIE)   /* already dead */
-                       break;
-               child->exit_code = SIGKILL;
-               ptrace_disable(child);
-               wake_up_process(child);
-               break;
-
-       case PTRACE_SINGLESTEP: /* set the trap flag. */
-               pr_debug("ptrace: single step\n");
-               ret = -EIO;
-               if (!valid_signal(data))
-                       break;
-               clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-               ptrace_enable(child);
-               child->exit_code = data;
-               wake_up_process(child);
-               ret = 0;
+       case PTRACE_POKEUSR:
+               ret = put_reg(child, addr, data);
+               pr_debug("ptrace: POKEUSR reg %li with %li = %i\n", addr, data, ret);
                break;
 
        case PTRACE_GETREGS:
-               /* Get all gp regs from the child. */
-               ret = ptrace_getregs(child, datap);
-               break;
+               pr_debug("ptrace: PTRACE_GETREGS\n");
+               return copy_regset_to_user(child, &user_bfin_native_view,
+                                          REGSET_GENERAL,
+                                          0, sizeof(struct pt_regs),
+                                          (void __user *)data);
 
        case PTRACE_SETREGS:
-               printk(KERN_WARNING "ptrace: SETREGS: **** NOT IMPLEMENTED ***\n");
-               /* Set all gp regs in the child. */
-               ret = 0;
-               break;
+               pr_debug("ptrace: PTRACE_SETREGS\n");
+               return copy_regset_from_user(child, &user_bfin_native_view,
+                                            REGSET_GENERAL,
+                                            0, sizeof(struct pt_regs),
+                                            (const void __user *)data);
 
        default:
                ret = ptrace_request(child, request, addr, data);
@@ -417,27 +393,21 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
        return ret;
 }
 
-asmlinkage void syscall_trace(void)
+asmlinkage int syscall_trace_enter(struct pt_regs *regs)
 {
-       if (!test_thread_flag(TIF_SYSCALL_TRACE))
-               return;
-
-       if (!(current->ptrace & PT_PTRACED))
-               return;
-
-       /* the 0x80 provides a way for the tracing parent to distinguish
-        * between a syscall stop and SIGTRAP delivery
-        */
-       ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-                                ? 0x80 : 0));
-
-       /*
-        * this isn't the same as continuing with a signal, but it will do
-        * for normal use.  strace only continues with a signal if the
-        * stopping signal is not SIGTRAP.  -brl
-        */
-       if (current->exit_code) {
-               send_sig(current->exit_code, current, 1);
-               current->exit_code = 0;
-       }
+       int ret = 0;
+
+       if (test_thread_flag(TIF_SYSCALL_TRACE))
+               ret = tracehook_report_syscall_entry(regs);
+
+       return ret;
+}
+
+asmlinkage void syscall_trace_leave(struct pt_regs *regs)
+{
+       int step;
+
+       step = test_thread_flag(TIF_SINGLESTEP);
+       if (step || test_thread_flag(TIF_SYSCALL_TRACE))
+               tracehook_report_syscall_exit(regs, step);
 }
index 95448ae9c43a79ff442fc67cb9a5bdf14a901316..8e2efceb364b8752b48ae63c97451ee0ee58a629 100644 (file)
@@ -220,6 +220,16 @@ void __init bfin_relocate_l1_mem(void)
                memcpy(_stext_l2, _l2_lma, l2_len);
 }
 
+#ifdef CONFIG_ROMKERNEL
+void __init bfin_relocate_xip_data(void)
+{
+       early_shadow_stamp();
+
+       memcpy(_sdata, _data_lma, (unsigned long)_data_len - THREAD_SIZE + sizeof(struct thread_info));
+       memcpy(_sinitdata, _init_data_lma, (unsigned long)_init_data_len);
+}
+#endif
+
 /* add_memory_region to memmap */
 static void __init add_memory_region(unsigned long long start,
                              unsigned long long size, int type)
@@ -504,7 +514,7 @@ static __init void memory_setup(void)
 #endif
        unsigned long max_mem;
 
-       _rambase = (unsigned long)_stext;
+       _rambase = CONFIG_BOOT_LOAD;
        _ramstart = (unsigned long)_end;
 
        if (DMA_UNCACHED_REGION > (_ramend - _ramstart)) {
@@ -597,7 +607,12 @@ static __init void memory_setup(void)
        }
 
 #ifdef CONFIG_MPU
+#if defined(CONFIG_ROMFS_ON_MTD) && defined(CONFIG_MTD_ROM)
+       page_mask_nelts = (((_ramend + ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE -
+                                       ASYNC_BANK0_BASE) >> PAGE_SHIFT) + 31) / 32;
+#else
        page_mask_nelts = ((_ramend >> PAGE_SHIFT) + 31) / 32;
+#endif
        page_mask_order = get_order(3 * page_mask_nelts * sizeof(long));
 #endif
 
@@ -630,7 +645,7 @@ static __init void memory_setup(void)
                __bss_start, __bss_stop,
                _sdata, _edata,
                (void *)&init_thread_union,
-               (void *)((int)(&init_thread_union) + 0x2000),
+               (void *)((int)(&init_thread_union) + THREAD_SIZE),
                __init_begin, __init_end,
                (void *)_ramstart, (void *)memory_end
 #ifdef CONFIG_MTD_UCLINUX
@@ -792,10 +807,17 @@ static inline int __init get_mem_size(void)
        BUG();
 }
 
+__attribute__((weak))
+void __init native_machine_early_platform_add_devices(void)
+{
+}
+
 void __init setup_arch(char **cmdline_p)
 {
        unsigned long sclk, cclk;
 
+       native_machine_early_platform_add_devices();
+
        enable_shadow_console();
 
        /* Check to make sure we are running on the right processor */
@@ -1217,10 +1239,10 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                   dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS,
                   BFIN_DLINES);
 #ifdef __ARCH_SYNC_CORE_DCACHE
-       seq_printf(m, "SMP Dcache Flushes\t: %lu\n\n", cpudata->dcache_invld_count);
+       seq_printf(m, "SMP Dcache Flushes\t: %lu\n\n", dcache_invld_count[cpu_num]);
 #endif
 #ifdef __ARCH_SYNC_CORE_ICACHE
-       seq_printf(m, "SMP Icache Flushes\t: %lu\n\n", cpudata->icache_invld_count);
+       seq_printf(m, "SMP Icache Flushes\t: %lu\n\n", icache_invld_count[cpu_num]);
 #endif
 
        if (cpu_num != num_possible_cpus() - 1)
@@ -1249,8 +1271,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        seq_printf(m, "board memory\t: %ld kB (0x%p -> 0x%p)\n",
                 physical_mem_end >> 10, (void *)0, (void *)physical_mem_end);
        seq_printf(m, "kernel memory\t: %d kB (0x%p -> 0x%p)\n",
-               ((int)memory_end - (int)_stext) >> 10,
-               _stext,
+               ((int)memory_end - (int)_rambase) >> 10,
+               (void *)_rambase,
                (void *)memory_end);
        seq_printf(m, "\n");
 
index e0fd63e9e38abdd469ece8f6203bec7b423f350c..d536f35d1f439475f6f658202a10bd8f544158d1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2009 Analog Devices Inc.
+ * Copyright 2004-2010 Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later
  */
@@ -17,6 +17,7 @@
 #include <asm/cacheflush.h>
 #include <asm/ucontext.h>
 #include <asm/fixed_code.h>
+#include <asm/syscall.h>
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
@@ -50,6 +51,9 @@ rt_restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *p
        unsigned long usp = 0;
        int err = 0;
 
+       /* Always make any pending restarted system calls return -EINTR */
+       current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
 #define RESTORE(x) err |= __get_user(regs->x, &sc->sc_##x)
 
        /* restore passed registers */
@@ -206,16 +210,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
        regs->r1 = (unsigned long)(&frame->info);
        regs->r2 = (unsigned long)(&frame->uc);
 
-       /*
-        * Clear the trace flag when entering the signal handler, but
-        * notify any tracer that was single-stepping it. The tracer
-        * may want to single-step inside the handler too.
-        */
-       if (regs->syscfg & TRACE_BITS) {
-               regs->syscfg &= ~TRACE_BITS;
-               ptrace_notify(SIGTRAP);
-       }
-
        return 0;
 
  give_sigsegv:
@@ -247,6 +241,11 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
                regs->r0 = regs->orig_r0;
                regs->pc -= 2;
                break;
+
+       case -ERESTART_RESTARTBLOCK:
+               regs->p0 = __NR_restart_syscall;
+               regs->pc -= 2;
+               break;
        }
 }
 
@@ -315,6 +314,9 @@ asmlinkage void do_signal(struct pt_regs *regs)
                         * clear the TIF_RESTORE_SIGMASK flag */
                        if (test_thread_flag(TIF_RESTORE_SIGMASK))
                                clear_thread_flag(TIF_RESTORE_SIGMASK);
+
+                       tracehook_signal_handler(signr, &info, &ka, regs,
+                               test_thread_flag(TIF_SINGLESTEP));
                }
 
                return;
index 17c38c5b5b22f60edd2273c5715888cc8eb45083..cb7a01d4f00924c47da598b7ea977241dae1e3e6 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/blackfin.h>
 #include <asm/time.h>
 #include <asm/gptimers.h>
+#include <asm/nmi.h>
 
 /* Accelerators for sched_clock()
  * convert from cycles(64bits) => nanoseconds (64bits)
 
 static notrace cycle_t bfin_read_cycles(struct clocksource *cs)
 {
+#ifdef CONFIG_CPU_FREQ
        return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod);
+#else
+       return get_cycles();
+#endif
 }
 
 static struct clocksource bfin_cs_cycles = {
@@ -132,7 +137,6 @@ static int __init bfin_cs_gptimer0_init(void)
 # define bfin_cs_gptimer0_init()
 #endif
 
-
 #if defined(CONFIG_GPTMR0_CLOCKSOURCE) || defined(CONFIG_CYCLES_CLOCKSOURCE)
 /* prefer to use cycles since it has higher rating */
 notrace unsigned long long sched_clock(void)
@@ -145,47 +149,8 @@ notrace unsigned long long sched_clock(void)
 }
 #endif
 
-#ifdef CONFIG_CORE_TIMER_IRQ_L1
-__attribute__((l1_text))
-#endif
-irqreturn_t timer_interrupt(int irq, void *dev_id);
-
-static int bfin_timer_set_next_event(unsigned long, \
-               struct clock_event_device *);
-
-static void bfin_timer_set_mode(enum clock_event_mode, \
-               struct clock_event_device *);
-
-static struct clock_event_device clockevent_bfin = {
-#if defined(CONFIG_TICKSOURCE_GPTMR0)
-       .name           = "bfin_gptimer0",
-       .rating         = 300,
-       .irq            = IRQ_TIMER0,
-#else
-       .name           = "bfin_core_timer",
-       .rating         = 350,
-       .irq            = IRQ_CORETMR,
-#endif
-       .shift          = 32,
-       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-       .set_next_event = bfin_timer_set_next_event,
-       .set_mode       = bfin_timer_set_mode,
-};
-
-static struct irqaction bfin_timer_irq = {
-#if defined(CONFIG_TICKSOURCE_GPTMR0)
-       .name           = "Blackfin GPTimer0",
-#else
-       .name           = "Blackfin CoreTimer",
-#endif
-       .flags          = IRQF_DISABLED | IRQF_TIMER | \
-                         IRQF_IRQPOLL | IRQF_PERCPU,
-       .handler        = timer_interrupt,
-       .dev_id         = &clockevent_bfin,
-};
-
 #if defined(CONFIG_TICKSOURCE_GPTMR0)
-static int bfin_timer_set_next_event(unsigned long cycles,
+static int bfin_gptmr0_set_next_event(unsigned long cycles,
                                      struct clock_event_device *evt)
 {
        disable_gptimers(TIMER0bit);
@@ -196,7 +161,7 @@ static int bfin_timer_set_next_event(unsigned long cycles,
        return 0;
 }
 
-static void bfin_timer_set_mode(enum clock_event_mode mode,
+static void bfin_gptmr0_set_mode(enum clock_event_mode mode,
                                struct clock_event_device *evt)
 {
        switch (mode) {
@@ -224,25 +189,65 @@ static void bfin_timer_set_mode(enum clock_event_mode mode,
        }
 }
 
-static void bfin_timer_ack(void)
+static void bfin_gptmr0_ack(void)
 {
        set_gptimer_status(TIMER_GROUP1, TIMER_STATUS_TIMIL0);
 }
 
-static void __init bfin_timer_init(void)
+static void __init bfin_gptmr0_init(void)
 {
        disable_gptimers(TIMER0bit);
 }
 
-static unsigned long  __init bfin_clockevent_check(void)
+#ifdef CONFIG_CORE_TIMER_IRQ_L1
+__attribute__((l1_text))
+#endif
+irqreturn_t bfin_gptmr0_interrupt(int irq, void *dev_id)
 {
-       setup_irq(IRQ_TIMER0, &bfin_timer_irq);
-       return get_sclk();
+       struct clock_event_device *evt = dev_id;
+       smp_mb();
+       evt->event_handler(evt);
+       bfin_gptmr0_ack();
+       return IRQ_HANDLED;
 }
 
-#else /* CONFIG_TICKSOURCE_CORETMR */
+static struct irqaction gptmr0_irq = {
+       .name           = "Blackfin GPTimer0",
+       .flags          = IRQF_DISABLED | IRQF_TIMER | \
+                         IRQF_IRQPOLL | IRQF_PERCPU,
+       .handler        = bfin_gptmr0_interrupt,
+};
 
-static int bfin_timer_set_next_event(unsigned long cycles,
+static struct clock_event_device clockevent_gptmr0 = {
+       .name           = "bfin_gptimer0",
+       .rating         = 300,
+       .irq            = IRQ_TIMER0,
+       .shift          = 32,
+       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+       .set_next_event = bfin_gptmr0_set_next_event,
+       .set_mode       = bfin_gptmr0_set_mode,
+};
+
+static void __init bfin_gptmr0_clockevent_init(struct clock_event_device *evt)
+{
+       unsigned long clock_tick;
+
+       clock_tick = get_sclk();
+       evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift);
+       evt->max_delta_ns = clockevent_delta2ns(-1, evt);
+       evt->min_delta_ns = clockevent_delta2ns(100, evt);
+
+       evt->cpumask = cpumask_of(0);
+
+       clockevents_register_device(evt);
+}
+#endif /* CONFIG_TICKSOURCE_GPTMR0 */
+
+#if defined(CONFIG_TICKSOURCE_CORETMR)
+/* per-cpu local core timer */
+static DEFINE_PER_CPU(struct clock_event_device, coretmr_events);
+
+static int bfin_coretmr_set_next_event(unsigned long cycles,
                                struct clock_event_device *evt)
 {
        bfin_write_TCNTL(TMPWR);
@@ -253,7 +258,7 @@ static int bfin_timer_set_next_event(unsigned long cycles,
        return 0;
 }
 
-static void bfin_timer_set_mode(enum clock_event_mode mode,
+static void bfin_coretmr_set_mode(enum clock_event_mode mode,
                                struct clock_event_device *evt)
 {
        switch (mode) {
@@ -285,19 +290,13 @@ static void bfin_timer_set_mode(enum clock_event_mode mode,
        }
 }
 
-static void bfin_timer_ack(void)
-{
-}
-
-static void __init bfin_timer_init(void)
+void bfin_coretmr_init(void)
 {
        /* power up the timer, but don't enable it just yet */
        bfin_write_TCNTL(TMPWR);
        CSYNC();
 
-       /*
-        * the TSCALE prescaler counter.
-        */
+       /* the TSCALE prescaler counter. */
        bfin_write_TSCALE(TIME_SCALE - 1);
        bfin_write_TPERIOD(0);
        bfin_write_TCOUNT(0);
@@ -305,48 +304,54 @@ static void __init bfin_timer_init(void)
        CSYNC();
 }
 
-static unsigned long  __init bfin_clockevent_check(void)
-{
-       setup_irq(IRQ_CORETMR, &bfin_timer_irq);
-       return get_cclk() / TIME_SCALE;
-}
-
-void __init setup_core_timer(void)
+#ifdef CONFIG_CORE_TIMER_IRQ_L1
+__attribute__((l1_text))
+#endif
+irqreturn_t bfin_coretmr_interrupt(int irq, void *dev_id)
 {
-       bfin_timer_init();
-       bfin_timer_set_mode(CLOCK_EVT_MODE_PERIODIC, NULL);
-}
-#endif /* CONFIG_TICKSOURCE_GPTMR0 */
+       int cpu = smp_processor_id();
+       struct clock_event_device *evt = &per_cpu(coretmr_events, cpu);
 
-/*
- * timer_interrupt() needs to keep up the real-time clock,
- * as well as call the "do_timer()" routine every clocktick
- */
-irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
-       struct clock_event_device *evt = dev_id;
        smp_mb();
        evt->event_handler(evt);
-       bfin_timer_ack();
-       return IRQ_HANDLED;
-}
-
-static int __init bfin_clockevent_init(void)
-{
-       unsigned long timer_clk;
 
-       timer_clk = bfin_clockevent_check();
+       touch_nmi_watchdog();
 
-       bfin_timer_init();
+       return IRQ_HANDLED;
+}
 
-       clockevent_bfin.mult = div_sc(timer_clk, NSEC_PER_SEC, clockevent_bfin.shift);
-       clockevent_bfin.max_delta_ns = clockevent_delta2ns(-1, &clockevent_bfin);
-       clockevent_bfin.min_delta_ns = clockevent_delta2ns(100, &clockevent_bfin);
-       clockevent_bfin.cpumask = cpumask_of(0);
-       clockevents_register_device(&clockevent_bfin);
+static struct irqaction coretmr_irq = {
+       .name           = "Blackfin CoreTimer",
+       .flags          = IRQF_DISABLED | IRQF_TIMER | \
+                         IRQF_IRQPOLL | IRQF_PERCPU,
+       .handler        = bfin_coretmr_interrupt,
+};
 
-       return 0;
+void bfin_coretmr_clockevent_init(void)
+{
+       unsigned long clock_tick;
+       unsigned int cpu = smp_processor_id();
+       struct clock_event_device *evt = &per_cpu(coretmr_events, cpu);
+
+       evt->name = "bfin_core_timer";
+       evt->rating = 350;
+       evt->irq = -1;
+       evt->shift = 32;
+       evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+       evt->set_next_event = bfin_coretmr_set_next_event;
+       evt->set_mode = bfin_coretmr_set_mode;
+
+       clock_tick = get_cclk() / TIME_SCALE;
+       evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift);
+       evt->max_delta_ns = clockevent_delta2ns(-1, evt);
+       evt->min_delta_ns = clockevent_delta2ns(100, evt);
+
+       evt->cpumask = cpumask_of(cpu);
+
+       clockevents_register_device(evt);
 }
+#endif /* CONFIG_TICKSOURCE_CORETMR */
+
 
 void __init time_init(void)
 {
@@ -370,5 +375,21 @@ void __init time_init(void)
 
        bfin_cs_cycles_init();
        bfin_cs_gptimer0_init();
-       bfin_clockevent_init();
+
+#if defined(CONFIG_TICKSOURCE_CORETMR)
+       bfin_coretmr_init();
+       setup_irq(IRQ_CORETMR, &coretmr_irq);
+       bfin_coretmr_clockevent_init();
+#endif
+
+#if defined(CONFIG_TICKSOURCE_GPTMR0)
+       bfin_gptmr0_init();
+       setup_irq(IRQ_TIMER0, &gptmr0_irq);
+       gptmr0_irq.dev_id = &clockevent_gptmr0;
+       bfin_gptmr0_clockevent_init(&clockevent_gptmr0);
+#endif
+
+#if !defined(CONFIG_TICKSOURCE_CORETMR) && !defined(CONFIG_TICKSOURCE_GPTMR0)
+# error at least one clock event device is required
+#endif
 }
index d3cbcd6bd985d6a5c517bba229e77474742d7393..ba70c4bc2699e7a288b36a591930106b23d84d32 100644 (file)
@@ -138,6 +138,12 @@ static void decode_address(char *buf, unsigned long address)
                if (!mm)
                        continue;
 
+               if (!down_read_trylock(&mm->mmap_sem)) {
+                       if (!in_atomic)
+                               mmput(mm);
+                       continue;
+               }
+
                for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) {
                        struct vm_area_struct *vma;
 
@@ -177,6 +183,7 @@ static void decode_address(char *buf, unsigned long address)
                                        sprintf(buf, "[ %s vma:0x%lx-0x%lx]",
                                                name, vma->vm_start, vma->vm_end);
 
+                               up_read(&mm->mmap_sem);
                                if (!in_atomic)
                                        mmput(mm);
 
@@ -186,11 +193,16 @@ static void decode_address(char *buf, unsigned long address)
                                goto done;
                        }
                }
+
+               up_read(&mm->mmap_sem);
                if (!in_atomic)
                        mmput(mm);
        }
 
-       /* we were unable to find this address anywhere */
+       /*
+        * we were unable to find this address anywhere,
+        * or some MMs were skipped because they were in use.
+        */
        sprintf(buf, "/* kernel dynamic memory */");
 
 done:
@@ -248,9 +260,7 @@ asmlinkage notrace void trap_c(struct pt_regs *fp)
 #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
        int j;
 #endif
-#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
        unsigned int cpu = raw_smp_processor_id();
-#endif
        const char *strerror = NULL;
        int sig = 0;
        siginfo_t info;
@@ -639,7 +649,17 @@ asmlinkage notrace void trap_c(struct pt_regs *fp)
        {
                info.si_signo = sig;
                info.si_errno = 0;
-               info.si_addr = (void __user *)fp->pc;
+               switch (trapnr) {
+               case VEC_CPLB_VL:
+               case VEC_MISALI_D:
+               case VEC_CPLB_M:
+               case VEC_CPLB_MHIT:
+                       info.si_addr = (void __user *)cpu_pda[cpu].dcplb_fault_addr;
+                       break;
+               default:
+                       info.si_addr = (void __user *)fp->pc;
+                       break;
+               }
                force_sig_info(sig, &info, current);
        }
 
@@ -712,7 +732,7 @@ static void decode_instruction(unsigned short *address)
                        verbose_printk("RTE");
                else if (opcode == 0x0025)
                        verbose_printk("EMUEXCPT");
-               else if (opcode == 0x0040 && opcode <= 0x0047)
+               else if (opcode >= 0x0040 && opcode <= 0x0047)
                        verbose_printk("STI R%i", opcode & 7);
                else if (opcode >= 0x0050 && opcode <= 0x0057)
                        verbose_printk("JUMP (P%i)", opcode & 7);
@@ -1096,7 +1116,7 @@ void dump_bfin_mem(struct pt_regs *fp)
                        /* And the last RETI points to the current userspace context */
                        if ((fp + 1)->pc >= current->mm->start_code &&
                            (fp + 1)->pc <= current->mm->end_code) {
-                               verbose_printk(KERN_NOTICE "It might be better to look around here : \n");
+                               verbose_printk(KERN_NOTICE "It might be better to look around here :\n");
                                verbose_printk(KERN_NOTICE "-------------------------------------------\n");
                                show_regs(fp + 1);
                                verbose_printk(KERN_NOTICE "-------------------------------------------\n");
index 66799e763dc93562513b8350c737e37fad282df8..984c78172397e0f44cf6b547d87b17e0d40e7bcf 100644 (file)
@@ -15,7 +15,12 @@ _jiffies = _jiffies_64;
 
 SECTIONS
 {
+#ifdef CONFIG_RAMKERNEL
        . = CONFIG_BOOT_LOAD;
+#else
+       . = CONFIG_ROM_BASE;
+#endif
+
        /* Neither the text, ro_data or bss section need to be aligned
         * So pack them back to back
         */
@@ -31,6 +36,12 @@ SECTIONS
                LOCK_TEXT
                IRQENTRY_TEXT
                KPROBES_TEXT
+#ifdef CONFIG_ROMKERNEL
+               __sinittext = .;
+               INIT_TEXT
+               __einittext = .;
+               EXIT_TEXT
+#endif
                *(.text.*)
                *(.fixup)
 
@@ -50,8 +61,14 @@ SECTIONS
 
        /* Just in case the first read only is a 32-bit access */
        RO_DATA(4)
+       __rodata_end = .;
 
+#ifdef CONFIG_ROMKERNEL
+       . = CONFIG_BOOT_LOAD;
+       .bss : AT(__rodata_end)
+#else
        .bss :
+#endif
        {
                . = ALIGN(4);
                ___bss_start = .;
@@ -67,7 +84,11 @@ SECTIONS
                ___bss_stop = .;
        }
 
+#if defined(CONFIG_ROMKERNEL)
+       .data : AT(LOADADDR(.bss) + SIZEOF(.bss))
+#else
        .data :
+#endif
        {
                __sdata = .;
                /* This gets done first, so the glob doesn't suck it in */
@@ -94,6 +115,8 @@ SECTIONS
 
                __edata = .;
        }
+       __data_lma = LOADADDR(.data);
+       __data_len = SIZEOF(.data);
 
        /* The init section should be last, so when we free it, it goes into
         * the general memory pool, and (hopefully) will decrease fragmentation
@@ -103,25 +126,58 @@ SECTIONS
        . = ALIGN(PAGE_SIZE);
        ___init_begin = .;
 
+#ifdef CONFIG_RAMKERNEL
        INIT_TEXT_SECTION(PAGE_SIZE)
-       . = ALIGN(16);
-       INIT_DATA_SECTION(16)
-       PERCPU(4)
 
-       /* we have to discard exit text and such at runtime, not link time, to
+       /* We have to discard exit text and such at runtime, not link time, to
         * handle embedded cross-section references (alt instructions, bug
-        * table, eh_frame, etc...)
+        * table, eh_frame, etc...).  We need all of our .text up front and
+        * .data after it for PCREL call issues.
         */
        .exit.text :
        {
                EXIT_TEXT
        }
+
+       . = ALIGN(16);
+       INIT_DATA_SECTION(16)
+       PERCPU(4)
+
        .exit.data :
        {
                EXIT_DATA
        }
 
        .text_l1 L1_CODE_START : AT(LOADADDR(.exit.data) + SIZEOF(.exit.data))
+#else
+       .init.data : AT(__data_lma + __data_len)
+       {
+               __sinitdata = .;
+               INIT_DATA
+               INIT_SETUP(16)
+               INIT_CALLS
+               CON_INITCALL
+               SECURITY_INITCALL
+               INIT_RAM_FS
+
+               . = ALIGN(4);
+               ___per_cpu_load = .;
+               ___per_cpu_start = .;
+               *(.data.percpu.first)
+               *(.data.percpu.page_aligned)
+               *(.data.percpu)
+               *(.data.percpu.shared_aligned)
+               ___per_cpu_end = .;
+
+               EXIT_DATA
+               __einitdata = .;
+       }
+       __init_data_lma = LOADADDR(.init.data);
+       __init_data_len = SIZEOF(.init.data);
+       __init_data_end = .;
+
+       .text_l1 L1_CODE_START : AT(__init_data_lma + __init_data_len)
+#endif
        {
                . = ALIGN(4);
                __stext_l1 = .;
@@ -202,7 +258,11 @@ SECTIONS
        /* Force trailing alignment of our init section so that when we
         * free our init memory, we don't leave behind a partial page.
         */
+#ifdef CONFIG_RAMKERNEL
        . = __l2_lma + __l2_len;
+#else
+       . = __init_data_end;
+#endif
        . = ALIGN(PAGE_SIZE);
        ___init_end = .;
 
index 96163514ed2231f68898b26101251b317f27ea96..252261ec04c483be21666a946d773cd20ab2ea0c 100644 (file)
@@ -9,4 +9,9 @@ config BFIN518F_EZBRD
        help
          BF518-EZBRD board support.
 
+config BFIN518F_TCM
+       bool "Bluetechnix TCM-BF518"
+       help
+         Bluetechnix TCM-BF518 board support.
+
 endchoice
index 172e859c3a7fd16e93abcb8ceae6b6007f4881ff..a9ef25c6b30243be2c19098fd260908719889e35 100644 (file)
@@ -3,3 +3,4 @@
 #
 
 obj-$(CONFIG_BFIN518F_EZBRD)            += ezbrd.o
+obj-$(CONFIG_BFIN518F_TCM)             += tcm-bf518.o
index 01975c0171168a656a558c423da183534e2549a7..44d6d5299022dbba305e8b83b8fa21c5c664dfd7 100644 (file)
@@ -382,30 +382,93 @@ static struct platform_device bfin_spi1_device = {
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = UART0_THR,
+               .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+       .name = "bfin-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
        {
-               .start = 0xFFC02000,
-               .end = 0xFFC020FF,
+               .start = UART1_THR,
+               .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
-#endif
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART1_ERROR,
+               .end = IRQ_UART1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_TX,
+               .end = CH_UART1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+       P_UART1_TX, P_UART1_RX, 0
 };
 
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart1_device = {
        .name = "bfin-uart",
        .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+       .resource = bfin_uart1_resources,
+       .dev = {
+               .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -499,16 +562,75 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 };
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+       {
+               .start = SPORT0_TCR1,
+               .end = SPORT0_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT0_RX,
+               .end = IRQ_SPORT0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT0_ERROR,
+               .end = IRQ_SPORT0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
        .name = "bfin-sport-uart",
        .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+       .resource = bfin_sport0_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+       {
+               .start = SPORT1_TCR1,
+               .end = SPORT1_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT1_RX,
+               .end = IRQ_SPORT1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT1_ERROR,
+               .end = IRQ_SPORT1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
        .name = "bfin-sport-uart",
        .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+       .resource = bfin_sport1_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 #include <linux/input.h>
@@ -593,7 +715,12 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -610,9 +737,13 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
        &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
        &bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
        &bfin_device_gpiokeys,
@@ -644,6 +775,33 @@ static int __init ezbrd_init(void)
 
 arch_initcall(ezbrd_init);
 
+static struct platform_device *ezbrd_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(ezbrd_early_devices,
+               ARRAY_SIZE(ezbrd_early_devices));
+}
+
 void native_machine_restart(char *cmd)
 {
        /* workaround reboot hang when booting from SPI */
diff --git a/arch/blackfin/mach-bf518/boards/tcm-bf518.c b/arch/blackfin/mach-bf518/boards/tcm-bf518.c
new file mode 100644 (file)
index 0000000..9b72e5c
--- /dev/null
@@ -0,0 +1,753 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *                2005 National ICT Australia (NICTA)
+ *                      Aidan Williams <aidan@nicta.com.au>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/device.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/dma.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/reboot.h>
+#include <asm/portmux.h>
+#include <asm/dpmc.h>
+#include <asm/bfin_sdh.h>
+#include <linux/spi/ad7877.h>
+#include <net/dsa.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+const char bfin_board_name[] = "Bluetechnix TCM-BF518";
+
+/*
+ *  Driver needs to know address, irq and flag pin.
+ */
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition tcm_partitions[] = {
+       {
+               .name       = "bootloader(nor)",
+               .size       = 0x40000,
+               .offset     = 0,
+       },
+       {
+               .name       = "linux(nor)",
+               .size       = 0x1C0000,
+               .offset     = MTDPART_OFS_APPEND,
+       }
+};
+
+static struct physmap_flash_data tcm_flash_data = {
+       .width      = 2,
+       .parts      = tcm_partitions,
+       .nr_parts   = ARRAY_SIZE(tcm_partitions),
+};
+
+static struct resource tcm_flash_resource = {
+       .start = 0x20000000,
+       .end   = 0x201fffff,
+       .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device tcm_flash_device = {
+       .name          = "physmap-flash",
+       .id            = 0,
+       .dev = {
+               .platform_data = &tcm_flash_data,
+       },
+       .num_resources = 1,
+       .resource      = &tcm_flash_resource,
+};
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+       .name = "rtc-bfin",
+       .id   = -1,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+       .name = "bfin_mii_bus",
+};
+
+static struct platform_device bfin_mac_device = {
+       .name = "bfin_mac",
+       .dev.platform_data = &bfin_mii_bus,
+};
+#endif
+
+#if defined(CONFIG_MTD_M25P80) \
+       || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+       {
+               .name = "bootloader(spi)",
+               .size = 0x00040000,
+               .offset = 0,
+               .mask_flags = MTD_CAP_ROM
+       }, {
+               .name = "linux kernel(spi)",
+               .size = MTDPART_SIZ_FULL,
+               .offset = MTDPART_OFS_APPEND,
+       }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+       .name = "m25p80",
+       .parts = bfin_spi_flash_partitions,
+       .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+       .type = "m25p16",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+       .enable_dma = 0,         /* use dma transfer with this chip*/
+       .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_BFIN_SPI_ADC) \
+       || defined(CONFIG_BFIN_SPI_ADC_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+       .enable_dma = 1,         /* use dma transfer with this chip*/
+       .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+static struct bfin5xx_spi_chip mmc_spi_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 16,
+};
+
+static const struct ad7877_platform_data bfin_ad7877_ts_info = {
+       .model                  = 7877,
+       .vref_delay_usecs       = 50,   /* internal, no capacitor */
+       .x_plate_ohms           = 419,
+       .y_plate_ohms           = 486,
+       .pressure_max           = 1000,
+       .pressure_min           = 0,
+       .stopacq_polarity       = 1,
+       .first_conversion_delay = 3,
+       .acquisition_time       = 1,
+       .averaging              = 1,
+       .pen_down_acc_interval  = 1,
+};
+#endif
+
+#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \
+        && defined(CONFIG_SND_SOC_WM8731_SPI)
+static struct bfin5xx_spi_chip spi_wm8731_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+static struct bfin5xx_spi_chip spidev_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 8,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) \
+       || defined(CONFIG_MTD_M25P80_MODULE)
+       {
+               /* the modalias must be the same as spi device driver name */
+               .modalias = "m25p80", /* Name of spi_driver for this device */
+               .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0, /* Framework bus number */
+               .chip_select = 2, /* SPI0_SSEL2 */
+               .platform_data = &bfin_spi_flash_data,
+               .controller_data = &spi_flash_chip_info,
+               .mode = SPI_MODE_3,
+       },
+#endif
+
+#if defined(CONFIG_BFIN_SPI_ADC) \
+       || defined(CONFIG_BFIN_SPI_ADC_MODULE)
+       {
+               .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+               .max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0, /* Framework bus number */
+               .chip_select = 1, /* Framework chip select. */
+               .platform_data = NULL, /* No spi_driver specific config */
+               .controller_data = &spi_adc_chip_info,
+       },
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+       {
+               .modalias = "mmc_spi",
+               .max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = 5,
+               .controller_data = &mmc_spi_chip_info,
+               .mode = SPI_MODE_3,
+       },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+       {
+               .modalias               = "ad7877",
+               .platform_data          = &bfin_ad7877_ts_info,
+               .irq                    = IRQ_PF8,
+               .max_speed_hz   = 12500000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num        = 0,
+               .chip_select  = 2,
+               .controller_data = &spi_ad7877_chip_info,
+       },
+#endif
+#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \
+        && defined(CONFIG_SND_SOC_WM8731_SPI)
+       {
+               .modalias       = "wm8731",
+               .max_speed_hz   = 3125000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num        = 0,
+               .chip_select    = 5,
+               .controller_data = &spi_wm8731_chip_info,
+               .mode = SPI_MODE_0,
+       },
+#endif
+#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+       {
+               .modalias = "spidev",
+               .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = 1,
+               .controller_data = &spidev_chip_info,
+       },
+#endif
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+       {
+               .modalias = "bfin-lq035q1-spi",
+               .max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = 1,
+               .controller_data = &lq035q1_spi_chip_info,
+               .mode = SPI_CPHA | SPI_CPOL,
+       },
+#endif
+};
+
+/* SPI controller data */
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* SPI (0) */
+static struct bfin5xx_spi_master bfin_spi0_info = {
+       .num_chipselect = 6,
+       .enable_dma = 1,  /* master has the ability to do dma transfer */
+       .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
+};
+
+static struct resource bfin_spi0_resource[] = {
+       [0] = {
+               .start = SPI0_REGBASE,
+               .end   = SPI0_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+               },
+       [1] = {
+               .start = CH_SPI0,
+               .end   = CH_SPI0,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = IRQ_SPI0,
+               .end   = IRQ_SPI0,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_spi0_device = {
+       .name = "bfin-spi",
+       .id = 0, /* Bus number */
+       .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+       .resource = bfin_spi0_resource,
+       .dev = {
+               .platform_data = &bfin_spi0_info, /* Passed to driver */
+       },
+};
+
+/* SPI (1) */
+static struct bfin5xx_spi_master bfin_spi1_info = {
+       .num_chipselect = 5,
+       .enable_dma = 1,  /* master has the ability to do dma transfer */
+       .pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0},
+};
+
+static struct resource bfin_spi1_resource[] = {
+       [0] = {
+               .start = SPI1_REGBASE,
+               .end   = SPI1_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+               },
+       [1] = {
+               .start = CH_SPI1,
+               .end   = CH_SPI1,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = IRQ_SPI1,
+               .end   = IRQ_SPI1,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_spi1_device = {
+       .name = "bfin-spi",
+       .id = 1, /* Bus number */
+       .num_resources = ARRAY_SIZE(bfin_spi1_resource),
+       .resource = bfin_spi1_resource,
+       .dev = {
+               .platform_data = &bfin_spi1_info, /* Passed to driver */
+       },
+};
+#endif  /* spi master and devices */
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
+       {
+               .start = UART0_THR,
+               .end = UART0_GCTL+2,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+       .name = "bfin-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+       {
+               .start = UART1_THR,
+               .end = UART1_GCTL+2,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART1_ERROR,
+               .end = IRQ_UART1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_TX,
+               .end = CH_UART1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+       P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
+       .name = "bfin-uart",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+       .resource = bfin_uart1_resources,
+       .dev = {
+               .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+static struct resource bfin_sir0_resources[] = {
+       {
+               .start = 0xFFC00400,
+               .end = 0xFFC004FF,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX+1,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+static struct platform_device bfin_sir0_device = {
+       .name = "bfin_sir",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sir0_resources),
+       .resource = bfin_sir0_resources,
+};
+#endif
+#ifdef CONFIG_BFIN_SIR1
+static struct resource bfin_sir1_resources[] = {
+       {
+               .start = 0xFFC02000,
+               .end = 0xFFC020FF,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX+1,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+static struct platform_device bfin_sir1_device = {
+       .name = "bfin_sir",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sir1_resources),
+       .resource = bfin_sir1_resources,
+};
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct resource bfin_twi0_resource[] = {
+       [0] = {
+               .start = TWI0_REGBASE,
+               .end   = TWI0_REGBASE,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_TWI,
+               .end   = IRQ_TWI,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device i2c_bfin_twi_device = {
+       .name = "i2c-bfin-twi",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_twi0_resource),
+       .resource = bfin_twi0_resource,
+};
+#endif
+
+static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
+#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
+       {
+               I2C_BOARD_INFO("pcf8574_lcd", 0x22),
+       },
+#endif
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
+       {
+               I2C_BOARD_INFO("pcf8574_keypad", 0x27),
+               .irq = IRQ_PF8,
+       },
+#endif
+};
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+       {
+               .start = SPORT0_TCR1,
+               .end = SPORT0_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT0_RX,
+               .end = IRQ_SPORT0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT0_ERROR,
+               .end = IRQ_SPORT0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
+static struct platform_device bfin_sport0_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+       .resource = bfin_sport0_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+       {
+               .start = SPORT1_TCR1,
+               .end = SPORT1_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT1_RX,
+               .end = IRQ_SPORT1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT1_ERROR,
+               .end = IRQ_SPORT1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+       .resource = bfin_sport1_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#endif
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+static struct gpio_keys_button bfin_gpio_keys_table[] = {
+       {BTN_0, GPIO_PG0, 1, "gpio-keys: BTN0"},
+       {BTN_1, GPIO_PG13, 1, "gpio-keys: BTN1"},
+};
+
+static struct gpio_keys_platform_data bfin_gpio_keys_data = {
+       .buttons        = bfin_gpio_keys_table,
+       .nbuttons       = ARRAY_SIZE(bfin_gpio_keys_table),
+};
+
+static struct platform_device bfin_device_gpiokeys = {
+       .name      = "gpio-keys",
+       .dev = {
+               .platform_data = &bfin_gpio_keys_data,
+       },
+};
+#endif
+
+#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN_MODULE)
+
+static struct bfin_sd_host bfin_sdh_data = {
+       .dma_chan = CH_RSI,
+       .irq_int0 = IRQ_RSI_INT0,
+       .pin_req = {P_RSI_DATA0, P_RSI_DATA1, P_RSI_DATA2, P_RSI_DATA3, P_RSI_CMD, P_RSI_CLK, 0},
+};
+
+static struct platform_device bf51x_sdh_device = {
+       .name = "bfin-sdh",
+       .id = 0,
+       .dev = {
+               .platform_data = &bfin_sdh_data,
+       },
+};
+#endif
+
+static const unsigned int cclk_vlev_datasheet[] =
+{
+       VRPAIR(VLEV_100, 400000000),
+       VRPAIR(VLEV_105, 426000000),
+       VRPAIR(VLEV_110, 500000000),
+       VRPAIR(VLEV_115, 533000000),
+       VRPAIR(VLEV_120, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+       .tuple_tab = cclk_vlev_datasheet,
+       .tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+       .vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+       .name = "bfin dpmc",
+       .dev = {
+               .platform_data = &bfin_dmpc_vreg_data,
+       },
+};
+
+static struct platform_device *tcm_devices[] __initdata = {
+
+       &bfin_dpmc,
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+       &rtc_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+       &bfin_mii_bus,
+       &bfin_mac_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+       &bfin_spi0_device,
+       &bfin_spi1_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+       &bfin_sir0_device,
+#endif
+#ifdef CONFIG_BFIN_SIR1
+       &bfin_sir1_device,
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+       &i2c_bfin_twi_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#endif
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+       &bfin_device_gpiokeys,
+#endif
+
+#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN_MODULE)
+       &bf51x_sdh_device,
+#endif
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+       &tcm_flash_device,
+#endif
+};
+
+static int __init tcm_init(void)
+{
+       printk(KERN_INFO "%s(): registering device resources\n", __func__);
+       i2c_register_board_info(0, bfin_i2c_board_info,
+                               ARRAY_SIZE(bfin_i2c_board_info));
+       platform_add_devices(tcm_devices, ARRAY_SIZE(tcm_devices));
+       spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+       return 0;
+}
+
+arch_initcall(tcm_init);
+
+static struct platform_device *tcm_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(tcm_early_devices,
+               ARRAY_SIZE(tcm_early_devices));
+}
+
+void native_machine_restart(char *cmd)
+{
+       /* workaround reboot hang when booting from SPI */
+       if ((bfin_read_SYSCR() & 0x7) == 0x3)
+               bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
+}
+
+void bfin_get_ether_addr(char *addr)
+{
+       random_ether_addr(addr);
+       printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
+}
+EXPORT_SYMBOL(bfin_get_ether_addr);
index 14e52ec7afa5093d643807361aaf33e3711268f3..435e76e31aaabd6c91145a1f3f6531e466841c16 100644 (file)
 
 #define GPIO_IRQ_BASE  IRQ_PF0
 
-#define NR_IRQS     (IRQ_PH15 + 1)
+#define IRQ_MAC_PHYINT         119 /* PHY_INT Interrupt */
+#define IRQ_MAC_MMCINT         120 /* MMC Counter Interrupt */
+#define IRQ_MAC_RXFSINT                121 /* RX Frame-Status Interrupt */
+#define IRQ_MAC_TXFSINT                122 /* TX Frame-Status Interrupt */
+#define IRQ_MAC_WAKEDET                123 /* Wake-Up Interrupt */
+#define IRQ_MAC_RXDMAERR       124 /* RX DMA Direction Error Interrupt */
+#define IRQ_MAC_TXDMAERR       125 /* TX DMA Direction Error Interrupt */
+#define IRQ_MAC_STMDONE                126 /* Station Mgt. Transfer Done Interrupt */
+
+#define NR_MACH_IRQS   (IRQ_MAC_STMDONE + 1)
+#define NR_IRQS                (NR_MACH_IRQS + NR_SPARE_IRQS)
 
 #define IVG7            7
 #define IVG8            8
index 3c6777cb35322d3a0bec238f12c656a7396e8d5e..073b5d73d391eefed27aeba2c7bf7e60fa756fb0 100644 (file)
@@ -41,7 +41,7 @@
 #define L1_DATA_A_START                0xFF800000
 #define L1_DATA_B_START                0xFF900000
 
-#define L1_CODE_LENGTH         0xC000
+#define L1_CODE_LENGTH         0x8000
 
 #ifdef CONFIG_BFIN_DCACHE
 
index df224d04e1677bb5b7f4d0d0bf631e7797c3943f..b14c28810a4434f3fb4bc265ef36caae666a9d6d 100644 (file)
@@ -9,6 +9,11 @@ config BFIN527_EZKIT
        help
          BF527-EZKIT-LITE board support.
 
+config BFIN527_EZKIT_V2
+       bool "BF527-EZKIT-V2"
+       help
+         BF527-EZKIT-LITE V2.1+ board support.
+
 config BFIN527_BLUETECHNIX_CM
        bool "Bluetechnix CM-BF527"
        help
index eb6ed3362f9f413adc63bc698eaa82b00ecdf104..51a5817c4a900804137f04805ed5c5179ab5052b 100644 (file)
@@ -3,5 +3,6 @@
 #
 
 obj-$(CONFIG_BFIN527_EZKIT)            += ezkit.o
+obj-$(CONFIG_BFIN527_EZKIT_V2)         += ezkit.o
 obj-$(CONFIG_BFIN527_BLUETECHNIX_CM)   += cm_bf527.o
 obj-$(CONFIG_BFIN526_EZBRD)            += ezbrd.o
index 7ab0800e291427ddbfae33468a703f0b9b838a61..ebe76d1e874aabbb183bf6fe43dd948c1360431b 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/i2c.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
-#include <linux/usb/sl811.h>
 #include <linux/usb/musb.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
@@ -270,50 +269,6 @@ static struct platform_device dm9000_device = {
 };
 #endif
 
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
-static struct resource sl811_hcd_resources[] = {
-       {
-               .start = 0x20340000,
-               .end = 0x20340000,
-               .flags = IORESOURCE_MEM,
-       }, {
-               .start = 0x20340004,
-               .end = 0x20340004,
-               .flags = IORESOURCE_MEM,
-       }, {
-               .start = CONFIG_USB_SL811_BFIN_IRQ,
-               .end = CONFIG_USB_SL811_BFIN_IRQ,
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-       },
-};
-
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
-void sl811_port_power(struct device *dev, int is_on)
-{
-       gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
-       gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
-}
-#endif
-
-static struct sl811_platform_data sl811_priv = {
-       .potpg = 10,
-       .power = 250,       /* == 500mA */
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
-       .port_power = &sl811_port_power,
-#endif
-};
-
-static struct platform_device sl811_hcd_device = {
-       .name = "sl811-hcd",
-       .id = 0,
-       .dev = {
-               .platform_data = &sl811_priv,
-       },
-       .num_resources = ARRAY_SIZE(sl811_hcd_resources),
-       .resource = sl811_hcd_resources,
-};
-#endif
-
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static struct platform_device bfin_mii_bus = {
        .name = "bfin_mii_bus",
@@ -384,8 +339,8 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-       || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+       || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 16,
@@ -462,8 +417,8 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-       || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+       || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
        {
                .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -603,30 +558,105 @@ static struct platform_device cm_flash_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = UART0_THR,
+               .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+       .name = "bfin-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
        {
-               .start = 0xFFC02000,
-               .end = 0xFFC020FF,
+               .start = UART1_THR,
+               .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART1_ERROR,
+               .end = IRQ_UART1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_TX,
+               .end = CH_UART1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+       {       /* CTS pin */
+               .start = GPIO_PF9,
+               .end = GPIO_PF9,
+               .flags = IORESOURCE_IO,
+       },
+       {       /* RTS pin */
+               .start = GPIO_PF10,
+               .end = GPIO_PF10,
+               .flags = IORESOURCE_IO,
+       },
 #endif
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart1_peripherals[] = {
+       P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
        .name = "bfin-uart",
        .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+       .resource = bfin_uart1_resources,
+       .dev = {
+               .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -725,16 +755,75 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 };
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+       {
+               .start = SPORT0_TCR1,
+               .end = SPORT0_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT0_RX,
+               .end = IRQ_SPORT0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT0_ERROR,
+               .end = IRQ_SPORT0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
        .name = "bfin-sport-uart",
        .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+       .resource = bfin_sport0_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+       {
+               .start = SPORT1_TCR1,
+               .end = SPORT1_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT1_RX,
+               .end = IRQ_SPORT1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT1_ERROR,
+               .end = IRQ_SPORT1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
        .name = "bfin-sport-uart",
        .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+       .resource = bfin_sport1_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 #include <linux/input.h>
@@ -795,10 +884,6 @@ static struct platform_device *cmbf527_devices[] __initdata = {
        &rtc_device,
 #endif
 
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
-       &sl811_hcd_device,
-#endif
-
 #if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
        &bfin_isp1760_device,
 #endif
@@ -829,7 +914,12 @@ static struct platform_device *cmbf527_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -846,9 +936,13 @@ static struct platform_device *cmbf527_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
        &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
        &bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
        &bfin_device_gpiokeys,
@@ -871,6 +965,33 @@ static int __init cm_init(void)
 
 arch_initcall(cm_init);
 
+static struct platform_device *cmbf527_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(cmbf527_early_devices,
+               ARRAY_SIZE(cmbf527_early_devices));
+}
+
 void native_machine_restart(char *cmd)
 {
        /* workaround reboot hang when booting from SPI */
index cad23b15d83c5ba233db0ef3c275a894732a2055..55069af4f67dd88b69230c659e67c8b821713de0 100644 (file)
@@ -274,8 +274,8 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = {
        .median                 = 2,    /* do 8 measurements */
        .averaging              = 1,    /* take the average of 4 middle samples */
        .pen_down_acc_interval  = 255,  /* 9.4 ms */
-       .gpio_output            = 1,    /* configure AUX/VBAT/GPIO as GPIO output */
-       .gpio_default           = 1,    /* During initialization set GPIO = HIGH */
+       .gpio_export            = 1,    /* Export GPIO to gpiolib */
+       .gpio_base              = -1,   /* Dynamic allocation */
 };
 #endif
 
@@ -439,30 +439,105 @@ static struct platform_device bfin_spi0_device = {
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = UART0_THR,
+               .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+       .name = "bfin-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
        {
-               .start = 0xFFC02000,
-               .end = 0xFFC020FF,
+               .start = UART1_THR,
+               .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART1_ERROR,
+               .end = IRQ_UART1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_TX,
+               .end = CH_UART1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+       {       /* CTS pin */
+               .start = GPIO_PG0,
+               .end = GPIO_PG0,
+               .flags = IORESOURCE_IO,
+       },
+       {       /* RTS pin */
+               .start = GPIO_PF10,
+               .end = GPIO_PF10,
+               .flags = IORESOURCE_IO,
+       },
 #endif
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart1_peripherals[] = {
+       P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
        .name = "bfin-uart",
        .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+       .resource = bfin_uart1_resources,
+       .dev = {
+               .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -556,16 +631,75 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 };
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+       {
+               .start = SPORT0_TCR1,
+               .end = SPORT0_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT0_RX,
+               .end = IRQ_SPORT0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT0_ERROR,
+               .end = IRQ_SPORT0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
        .name = "bfin-sport-uart",
        .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+       .resource = bfin_sport0_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+       {
+               .start = SPORT1_TCR1,
+               .end = SPORT1_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT1_RX,
+               .end = IRQ_SPORT1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT1_ERROR,
+               .end = IRQ_SPORT1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
        .name = "bfin-sport-uart",
        .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+       .resource = bfin_sport1_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 #include <linux/input.h>
@@ -615,9 +749,10 @@ static struct platform_device bfin_dpmc = {
 #include <asm/bfin-lq035q1.h>
 
 static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = {
-       .mode =         LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
-       .use_bl =       1,
-       .gpio_bl =      GPIO_PG12,
+       .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
+       .ppi_mode = USE_RGB565_16_BIT_PPI,
+       .use_bl = 1,
+       .gpio_bl = GPIO_PG12,
 };
 
 static struct resource bfin_lq035q1_resources[] = {
@@ -665,7 +800,12 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
@@ -686,9 +826,13 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
        &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
        &bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
        &bfin_device_gpiokeys,
@@ -711,6 +855,33 @@ static int __init ezbrd_init(void)
 
 arch_initcall(ezbrd_init);
 
+static struct platform_device *ezbrd_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(ezbrd_early_devices,
+               ARRAY_SIZE(ezbrd_early_devices));
+}
+
 void native_machine_restart(char *cmd)
 {
        /* workaround reboot hang when booting from SPI */
index 5294fdd207326fc716d5df787d849c8af33c7557..923383386aa18cee70cd86efb4db19fe5017e8a1 100644 (file)
@@ -16,8 +16,9 @@
 #include <linux/i2c.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
-#include <linux/usb/sl811.h>
 #include <linux/usb/musb.h>
+#include <linux/leds.h>
+#include <linux/input.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/reboot.h>
 /*
  * Name the Board for the /proc/cpuinfo
  */
+#ifdef CONFIG_BFIN527_EZKIT_V2
+const char bfin_board_name[] = "ADI BF527-EZKIT V2";
+#else
 const char bfin_board_name[] = "ADI BF527-EZKIT";
+#endif
 
 /*
  *  Driver needs to know address, irq and flag pin.
@@ -143,6 +148,33 @@ static struct platform_device bf52x_t350mcqb_device = {
 };
 #endif
 
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+#include <asm/bfin-lq035q1.h>
+
+static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = {
+       .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
+       .ppi_mode = USE_RGB565_8_BIT_PPI,
+};
+
+static struct resource bfin_lq035q1_resources[] = {
+       {
+               .start = IRQ_PPI_ERROR,
+               .end = IRQ_PPI_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_lq035q1_device = {
+       .name           = "bfin-lq035q1",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(bfin_lq035q1_resources),
+       .resource       = bfin_lq035q1_resources,
+       .dev            = {
+               .platform_data = &bfin_lq035q1_data,
+       },
+};
+#endif
+
 #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
 static struct mtd_partition ezkit_partitions[] = {
        {
@@ -326,50 +358,6 @@ static struct platform_device dm9000_device = {
 };
 #endif
 
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
-static struct resource sl811_hcd_resources[] = {
-       {
-               .start = 0x20340000,
-               .end = 0x20340000,
-               .flags = IORESOURCE_MEM,
-       }, {
-               .start = 0x20340004,
-               .end = 0x20340004,
-               .flags = IORESOURCE_MEM,
-       }, {
-               .start = CONFIG_USB_SL811_BFIN_IRQ,
-               .end = CONFIG_USB_SL811_BFIN_IRQ,
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-       },
-};
-
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
-void sl811_port_power(struct device *dev, int is_on)
-{
-       gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
-       gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
-}
-#endif
-
-static struct sl811_platform_data sl811_priv = {
-       .potpg = 10,
-       .power = 250,       /* == 500mA */
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
-       .port_power = &sl811_port_power,
-#endif
-};
-
-static struct platform_device sl811_hcd_device = {
-       .name = "sl811-hcd",
-       .id = 0,
-       .dev = {
-               .platform_data = &sl811_priv,
-       },
-       .num_resources = ARRAY_SIZE(sl811_hcd_resources),
-       .resource = sl811_hcd_resources,
-};
-#endif
-
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static struct platform_device bfin_mii_bus = {
        .name = "bfin_mii_bus",
@@ -440,8 +428,8 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-       || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+       || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 16,
@@ -488,8 +476,7 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = {
        .median                 = 2,    /* do 8 measurements */
        .averaging              = 1,    /* take the average of 4 middle samples */
        .pen_down_acc_interval  = 255,  /* 9.4 ms */
-       .gpio_output            = 1,    /* configure AUX/VBAT/GPIO as GPIO output */
-       .gpio_default           = 1,    /* During initialization set GPIO = HIGH */
+       .gpio_export            = 0,    /* Export GPIO to gpiolib */
 };
 #endif
 
@@ -500,14 +487,6 @@ static struct bfin5xx_spi_chip spi_ad7879_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \
-        && defined(CONFIG_SND_SOC_WM8731_SPI)
-static struct bfin5xx_spi_chip spi_wm8731_chip_info = {
-       .enable_dma = 0,
-       .bits_per_word = 16,
-};
-#endif
-
 #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
 static struct bfin5xx_spi_chip spidev_chip_info = {
        .enable_dma = 0,
@@ -515,6 +494,29 @@ static struct bfin5xx_spi_chip spidev_chip_info = {
 };
 #endif
 
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+       .name = "bfin-i2s",
+       .id = CONFIG_SND_BF5XX_SPORT_NUM,
+       /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+static struct platform_device bfin_tdm = {
+       .name = "bfin-tdm",
+       .id = CONFIG_SND_BF5XX_SPORT_NUM,
+       /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+static struct bfin5xx_spi_chip lq035q1_spi_chip_info = {
+       .enable_dma     = 0,
+       .bits_per_word  = 8,
+};
+#endif
+
 static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_MTD_M25P80) \
        || defined(CONFIG_MTD_M25P80_MODULE)
@@ -542,8 +544,8 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-       || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+       || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
        {
                .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -586,17 +588,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                .mode = SPI_CPHA | SPI_CPOL,
        },
 #endif
-#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \
-        && defined(CONFIG_SND_SOC_WM8731_SPI)
-       {
-               .modalias       = "wm8731",
-               .max_speed_hz   = 3125000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num        = 0,
-               .chip_select    = 5,
-               .controller_data = &spi_wm8731_chip_info,
-               .mode = SPI_MODE_0,
-       },
-#endif
 #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
        {
                .modalias = "spidev",
@@ -606,6 +597,16 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                .controller_data = &spidev_chip_info,
        },
 #endif
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+       {
+               .modalias = "bfin-lq035q1-spi",
+               .max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = 7,
+               .controller_data = &lq035q1_spi_chip_info,
+               .mode = SPI_CPHA | SPI_CPOL,
+       },
+#endif
 };
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
@@ -647,30 +648,105 @@ static struct platform_device bfin_spi0_device = {
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = UART0_THR,
+               .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+       .name = "bfin-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
        {
-               .start = 0xFFC02000,
-               .end = 0xFFC020FF,
+               .start = UART1_THR,
+               .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART1_ERROR,
+               .end = IRQ_UART1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_TX,
+               .end = CH_UART1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+       {       /* CTS pin */
+               .start = GPIO_PF9,
+               .end = GPIO_PF9,
+               .flags = IORESOURCE_IO,
+       },
+       {       /* RTS pin */
+               .start = GPIO_PF10,
+               .end = GPIO_PF10,
+               .flags = IORESOURCE_IO,
+       },
 #endif
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart1_peripherals[] = {
+       P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
        .name = "bfin-uart",
        .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+       .resource = bfin_uart1_resources,
+       .dev = {
+               .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -749,6 +825,71 @@ static struct platform_device i2c_bfin_twi_device = {
 };
 #endif
 
+#if defined(CONFIG_PMIC_ADP5520) || defined(CONFIG_PMIC_ADP5520_MODULE)
+#include <linux/mfd/adp5520.h>
+
+       /*
+        *  ADP5520/5501 LEDs Data
+        */
+
+static struct led_info adp5520_leds[] = {
+       {
+               .name = "adp5520-led1",
+               .default_trigger = "none",
+               .flags = FLAG_ID_ADP5520_LED1_ADP5501_LED0 | ADP5520_LED_OFFT_600ms,
+       },
+};
+
+static struct adp5520_leds_platform_data adp5520_leds_data = {
+       .num_leds = ARRAY_SIZE(adp5520_leds),
+       .leds = adp5520_leds,
+       .fade_in = ADP5520_FADE_T_600ms,
+       .fade_out = ADP5520_FADE_T_600ms,
+       .led_on_time = ADP5520_LED_ONT_600ms,
+};
+
+       /*
+        *  ADP5520 Keypad Data
+        */
+
+static const unsigned short adp5520_keymap[ADP5520_KEYMAPSIZE] = {
+       [ADP5520_KEY(3, 3)]     = KEY_1,
+       [ADP5520_KEY(2, 3)]     = KEY_2,
+       [ADP5520_KEY(1, 3)]     = KEY_3,
+       [ADP5520_KEY(0, 3)]     = KEY_UP,
+       [ADP5520_KEY(3, 2)]     = KEY_4,
+       [ADP5520_KEY(2, 2)]     = KEY_5,
+       [ADP5520_KEY(1, 2)]     = KEY_6,
+       [ADP5520_KEY(0, 2)]     = KEY_DOWN,
+       [ADP5520_KEY(3, 1)]     = KEY_7,
+       [ADP5520_KEY(2, 1)]     = KEY_8,
+       [ADP5520_KEY(1, 1)]     = KEY_9,
+       [ADP5520_KEY(0, 1)]     = KEY_DOT,
+       [ADP5520_KEY(3, 0)]     = KEY_BACKSPACE,
+       [ADP5520_KEY(2, 0)]     = KEY_0,
+       [ADP5520_KEY(1, 0)]     = KEY_HELP,
+       [ADP5520_KEY(0, 0)]     = KEY_ENTER,
+};
+
+static struct adp5520_keys_platform_data adp5520_keys_data = {
+       .rows_en_mask   = ADP5520_ROW_R3 | ADP5520_ROW_R2 | ADP5520_ROW_R1 | ADP5520_ROW_R0,
+       .cols_en_mask   = ADP5520_COL_C3 | ADP5520_COL_C2 | ADP5520_COL_C1 | ADP5520_COL_C0,
+       .keymap         = adp5520_keymap,
+       .keymapsize     = ARRAY_SIZE(adp5520_keymap),
+       .repeat         = 0,
+};
+
+       /*
+        *  ADP5520/5501 Multifuction Device Init Data
+        */
+
+static struct adp5520_platform_data adp5520_pdev_data = {
+       .leds = &adp5520_leds_data,
+       .keys = &adp5520_keys_data,
+};
+
+#endif
+
 static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
        {
@@ -766,22 +907,99 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
                I2C_BOARD_INFO("bfin-adv7393", 0x2B),
        },
 #endif
+#if defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE)
+       {
+               I2C_BOARD_INFO("ad7879", 0x2C),
+               .irq = IRQ_PF8,
+               .platform_data = (void *)&bfin_ad7879_ts_info,
+       },
+#endif
+#if defined(CONFIG_PMIC_ADP5520) || defined(CONFIG_PMIC_ADP5520_MODULE)
+       {
+               I2C_BOARD_INFO("pmic-adp5520", 0x32),
+               .irq = IRQ_PF9,
+               .platform_data = (void *)&adp5520_pdev_data,
+       },
+#endif
+#if defined(CONFIG_SND_SOC_SSM2602) || defined(CONFIG_SND_SOC_SSM2602_MODULE)
+       {
+               I2C_BOARD_INFO("ssm2602", 0x1b),
+       },
+#endif
 };
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+       {
+               .start = SPORT0_TCR1,
+               .end = SPORT0_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT0_RX,
+               .end = IRQ_SPORT0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT0_ERROR,
+               .end = IRQ_SPORT0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
        .name = "bfin-sport-uart",
        .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+       .resource = bfin_sport0_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+       {
+               .start = SPORT1_TCR1,
+               .end = SPORT1_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT1_RX,
+               .end = IRQ_SPORT1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT1_ERROR,
+               .end = IRQ_SPORT1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
        .name = "bfin-sport-uart",
        .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+       .resource = bfin_sport1_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
-#include <linux/input.h>
 #include <linux/gpio_keys.h>
 
 static struct gpio_keys_button bfin_gpio_keys_table[] = {
@@ -803,7 +1021,6 @@ static struct platform_device bfin_device_gpiokeys = {
 #endif
 
 #if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE)
-#include <linux/input.h>
 #include <asm/bfin_rotary.h>
 
 static struct bfin_rotary_platform_data bfin_rotary_data = {
@@ -872,10 +1089,6 @@ static struct platform_device *stamp_devices[] __initdata = {
        &rtc_device,
 #endif
 
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
-       &sl811_hcd_device,
-#endif
-
 #if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
        &bfin_isp1760_device,
 #endif
@@ -909,8 +1122,17 @@ static struct platform_device *stamp_devices[] __initdata = {
        &bf52x_t350mcqb_device,
 #endif
 
+#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
+       &bfin_lq035q1_device,
+#endif
+
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -927,9 +1149,13 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
        &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
        &bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
        &bfin_device_gpiokeys,
@@ -942,6 +1168,14 @@ static struct platform_device *stamp_devices[] __initdata = {
 #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
        &ezkit_flash_device,
 #endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+       &bfin_i2s,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+       &bfin_tdm,
+#endif
 };
 
 static int __init ezkit_init(void)
@@ -956,6 +1190,33 @@ static int __init ezkit_init(void)
 
 arch_initcall(ezkit_init);
 
+static struct platform_device *ezkit_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(ezkit_early_devices,
+               ARRAY_SIZE(ezkit_early_devices));
+}
+
 void native_machine_restart(char *cmd)
 {
        /* workaround reboot hang when booting from SPI */
index aa6579a64a2f0dccae0a81f66a5886680934e773..704d9253e41d35373e48643557d48dbdd05efc7d 100644 (file)
 
 #define GPIO_IRQ_BASE  IRQ_PF0
 
-#define NR_IRQS     (IRQ_PH15+1)
+#define IRQ_MAC_PHYINT         119 /* PHY_INT Interrupt */
+#define IRQ_MAC_MMCINT         120 /* MMC Counter Interrupt */
+#define IRQ_MAC_RXFSINT                121 /* RX Frame-Status Interrupt */
+#define IRQ_MAC_TXFSINT                122 /* TX Frame-Status Interrupt */
+#define IRQ_MAC_WAKEDET                123 /* Wake-Up Interrupt */
+#define IRQ_MAC_RXDMAERR       124 /* RX DMA Direction Error Interrupt */
+#define IRQ_MAC_TXDMAERR       125 /* TX DMA Direction Error Interrupt */
+#define IRQ_MAC_STMDONE                126 /* Station Mgt. Transfer Done Interrupt */
+
+#define NR_MACH_IRQS   (IRQ_MAC_STMDONE + 1)
+#define NR_IRQS                (NR_MACH_IRQS + NR_SPARE_IRQS)
 
 #define IVG7            7
 #define IVG8            8
index 4adceb0bdb6d3c0dc8f762bb9c921d20516ded04..175371af0692a0bbf71106dd2a8228c3b561140e 100644 (file)
@@ -171,7 +171,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 16,
@@ -206,7 +206,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
        {
                .modalias = "ad1836",
                .max_speed_hz = 16,
@@ -257,21 +257,50 @@ static struct platform_device bfin_spi0_device = {
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = BFIN_UART_THR,
+               .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX + 1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
 };
 
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart0_device = {
        .name = "bfin-uart",
-       .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -394,7 +423,9 @@ static struct platform_device *h8606_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
 #endif
 
 #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
@@ -424,3 +455,18 @@ static int __init H8606_init(void)
 }
 
 arch_initcall(H8606_init);
+
+static struct platform_device *H8606_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(H8606_early_devices,
+               ARRAY_SIZE(H8606_early_devices));
+}
index b580884848d4175aabf31afe9f0008afcd858d67..842b4fa76ea992d31c932eced7876fabdb6083aa 100644 (file)
@@ -195,21 +195,50 @@ static struct platform_device bfin_spi0_device = {
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = BFIN_UART_THR,
+               .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX + 1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
 };
 
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart0_device = {
        .name = "bfin-uart",
-       .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -241,16 +270,75 @@ static struct platform_device bfin_sir0_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+       {
+               .start = SPORT0_TCR1,
+               .end = SPORT0_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT0_RX,
+               .end = IRQ_SPORT0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT0_ERROR,
+               .end = IRQ_SPORT0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
        .name = "bfin-sport-uart",
        .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+       .resource = bfin_sport0_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+       {
+               .start = SPORT1_TCR1,
+               .end = SPORT1_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT1_RX,
+               .end = IRQ_SPORT1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT1_ERROR,
+               .end = IRQ_SPORT1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
        .name = "bfin-sport-uart",
        .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+       .resource = bfin_sport1_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 #include <linux/input.h>
@@ -344,7 +432,9 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -354,9 +444,13 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
        &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
        &bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
        &bfin_device_gpiokeys,
@@ -392,3 +486,27 @@ static int __init blackstamp_init(void)
 }
 
 arch_initcall(blackstamp_init);
+
+static struct platform_device *stamp_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(stamp_early_devices,
+               ARRAY_SIZE(stamp_early_devices));
+}
index 7fc3b860d4ae9846bc07a5601a4091026ad16e9e..fdcde61906dc3a51da0f72dd27a20d5d6a4f3efb 100644 (file)
@@ -71,7 +71,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 16,
@@ -110,7 +110,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
        {
                .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -242,21 +242,50 @@ static struct platform_device smsc911x_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = BFIN_UART_THR,
+               .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX + 1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
 };
 
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart0_device = {
        .name = "bfin-uart",
-       .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -288,16 +317,75 @@ static struct platform_device bfin_sir0_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+       {
+               .start = SPORT0_TCR1,
+               .end = SPORT0_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT0_RX,
+               .end = IRQ_SPORT0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT0_ERROR,
+               .end = IRQ_SPORT0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
        .name = "bfin-sport-uart",
        .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+       .resource = bfin_sport0_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+       {
+               .start = SPORT1_TCR1,
+               .end = SPORT1_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT1_RX,
+               .end = IRQ_SPORT1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT1_ERROR,
+               .end = IRQ_SPORT1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
        .name = "bfin-sport-uart",
        .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+       .resource = bfin_sport1_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 static struct resource isp1362_hcd_resources[] = {
@@ -432,7 +520,9 @@ static struct platform_device *cm_bf533_devices[] __initdata = {
        &bfin_dpmc,
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -442,9 +532,13 @@ static struct platform_device *cm_bf533_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
        &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
        &bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
        &rtc_device,
@@ -486,3 +580,27 @@ static int __init cm_bf533_init(void)
 }
 
 arch_initcall(cm_bf533_init);
+
+static struct platform_device *cm_bf533_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(cm_bf533_early_devices,
+               ARRAY_SIZE(cm_bf533_early_devices));
+}
index d4689dcc198e6b5073b3daef3cd0f1f3f1f6c022..739773cb7fc65111af77c1b568cfce769d3569bd 100644 (file)
@@ -222,7 +222,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 16,
@@ -261,7 +261,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
        {
                .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -320,21 +320,50 @@ static struct platform_device bfin_spi0_device = {
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = BFIN_UART_THR,
+               .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX + 1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
 };
 
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart0_device = {
        .name = "bfin-uart",
-       .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -444,6 +473,30 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 #endif
 };
 
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+       .name = "bfin-i2s",
+       .id = CONFIG_SND_BF5XX_SPORT_NUM,
+       /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+static struct platform_device bfin_tdm = {
+       .name = "bfin-tdm",
+       .id = CONFIG_SND_BF5XX_SPORT_NUM,
+       /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+static struct platform_device bfin_ac97 = {
+       .name = "bfin-ac97",
+       .id = CONFIG_SND_BF5XX_SPORT_NUM,
+       /* TODO: add platform data here */
+};
+#endif
+
 static struct platform_device *ezkit_devices[] __initdata = {
 
        &bfin_dpmc,
@@ -471,7 +524,9 @@ static struct platform_device *ezkit_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -487,6 +542,18 @@ static struct platform_device *ezkit_devices[] __initdata = {
 #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
        &i2c_gpio_device,
 #endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+       &bfin_i2s,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+       &bfin_tdm,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+       &bfin_ac97,
+#endif
 };
 
 static int __init ezkit_init(void)
@@ -500,3 +567,18 @@ static int __init ezkit_init(void)
 }
 
 arch_initcall(ezkit_init);
+
+static struct platform_device *ezkit_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(ezkit_early_devices,
+               ARRAY_SIZE(ezkit_early_devices));
+}
index 8ec42ba35b9e4675ca627fcf5747359b8c4d2b7e..7349970db97860f8b0def99b000ed8c36c642cb8 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/usb/isp1362.h>
 #endif
 #include <asm/irq.h>
+#include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
 
@@ -143,21 +144,50 @@ static struct platform_device spi_bfin_master_device = {
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = BFIN_UART_THR,
+               .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX + 1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
 };
 
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart0_device = {
        .name = "bfin-uart",
-       .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -241,7 +271,9 @@ static struct platform_device *ip0x_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -276,3 +308,18 @@ static int __init ip0x_init(void)
 }
 
 arch_initcall(ip0x_init);
+
+static struct platform_device *ip0x_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(ip0x_early_devices,
+               ARRAY_SIZE(ip0x_early_devices));
+}
index 6d68dcfa2da21ade9ddbd50856219cfeb9d7ecdb..c457eaa60239e4e2281553114302c1001eeabdff 100644 (file)
@@ -184,7 +184,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 16,
@@ -251,7 +251,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
        {
                .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -322,21 +322,50 @@ static struct platform_device bfin_spi0_device = {
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = BFIN_UART_THR,
+               .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX + 1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
        .name = "bfin-uart",
-       .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -368,16 +397,75 @@ static struct platform_device bfin_sir0_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+       {
+               .start = SPORT0_TCR1,
+               .end = SPORT0_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT0_RX,
+               .end = IRQ_SPORT0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT0_ERROR,
+               .end = IRQ_SPORT0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
        .name = "bfin-sport-uart",
        .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+       .resource = bfin_sport0_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+       {
+               .start = SPORT1_TCR1,
+               .end = SPORT1_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT1_RX,
+               .end = IRQ_SPORT1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT1_ERROR,
+               .end = IRQ_SPORT1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
        .name = "bfin-sport-uart",
        .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+       .resource = bfin_sport1_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 #include <linux/input.h>
@@ -474,6 +562,30 @@ static struct platform_device bfin_dpmc = {
        },
 };
 
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+       .name = "bfin-i2s",
+       .id = CONFIG_SND_BF5XX_SPORT_NUM,
+       /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+static struct platform_device bfin_tdm = {
+       .name = "bfin-tdm",
+       .id = CONFIG_SND_BF5XX_SPORT_NUM,
+       /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+static struct platform_device bfin_ac97 = {
+       .name = "bfin-ac97",
+       .id = CONFIG_SND_BF5XX_SPORT_NUM,
+       /* TODO: add platform data here */
+};
+#endif
+
 static struct platform_device *stamp_devices[] __initdata = {
 
        &bfin_dpmc,
@@ -495,7 +607,9 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -505,9 +619,13 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
        &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
        &bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
        &bfin_device_gpiokeys,
@@ -520,6 +638,18 @@ static struct platform_device *stamp_devices[] __initdata = {
 #if defined(CONFIG_MTD_BFIN_ASYNC) || defined(CONFIG_MTD_BFIN_ASYNC_MODULE)
        &stamp_flash_device,
 #endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+       &bfin_i2s,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+       &bfin_tdm,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+       &bfin_ac97,
+#endif
 };
 
 static int __init stamp_init(void)
@@ -548,6 +678,30 @@ static int __init stamp_init(void)
 
 arch_initcall(stamp_init);
 
+static struct platform_device *stamp_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(stamp_early_devices,
+               ARRAY_SIZE(stamp_early_devices));
+}
+
 void native_machine_restart(char *cmd)
 {
        /* workaround pull up on cpld / flash pin not being strong enough */
index c31498be0bbb48a9a244e70bd503342daac33a4b..1f7e9765d954b9bbcd20d9d0d376dbd383d64848 100644 (file)
@@ -104,7 +104,8 @@ Core        Emulation               **
 
 #define GPIO_IRQ_BASE          IRQ_PF0
 
-#define        NR_IRQS         (IRQ_PF15+1)
+#define NR_MACH_IRQS           (IRQ_PF15 + 1)
+#define NR_IRQS                        (NR_MACH_IRQS + NR_SPARE_IRQS)
 
 #define IVG7                   7
 #define IVG8                   8
index c85f4d770535e5c838a8e94fea1452a9db3c9d1c..d35fc5fe4c2b8a506a47c6b4319df1ec4a0509aa 100644 (file)
@@ -73,7 +73,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 16,
@@ -112,7 +112,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
        {
                .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -329,8 +329,8 @@ static struct platform_device cm_flash_device = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
 static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = UART0_THR,
+               .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
        {
@@ -373,18 +373,25 @@ static struct resource bfin_uart0_resources[] = {
 #endif
 };
 
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
 static struct platform_device bfin_uart0_device = {
        .name = "bfin-uart",
        .id = 0,
        .num_resources = ARRAY_SIZE(bfin_uart0_resources),
        .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
 };
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
 static struct resource bfin_uart1_resources[] = {
        {
-               .start = 0xFFC02000,
-               .end = 0xFFC020FF,
+               .start = UART1_THR,
+               .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
        {
@@ -427,11 +434,18 @@ static struct resource bfin_uart1_resources[] = {
 #endif
 };
 
+unsigned short bfin_uart1_peripherals[] = {
+       P_UART1_TX, P_UART1_RX, 0
+};
+
 static struct platform_device bfin_uart1_device = {
        .name = "bfin-uart",
        .id = 1,
        .num_resources = ARRAY_SIZE(bfin_uart1_resources),
        .resource = bfin_uart1_resources,
+       .dev = {
+               .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+       },
 };
 #endif
 #endif
@@ -512,16 +526,75 @@ static struct platform_device i2c_bfin_twi_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+       {
+               .start = SPORT0_TCR1,
+               .end = SPORT0_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT0_RX,
+               .end = IRQ_SPORT0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT0_ERROR,
+               .end = IRQ_SPORT0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
        .name = "bfin-sport-uart",
        .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+       .resource = bfin_sport0_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+       {
+               .start = SPORT1_TCR1,
+               .end = SPORT1_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT1_RX,
+               .end = IRQ_SPORT1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT1_ERROR,
+               .end = IRQ_SPORT1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
        .name = "bfin-sport-uart",
        .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+       .resource = bfin_sport1_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static struct platform_device bfin_mii_bus = {
@@ -633,9 +706,13 @@ static struct platform_device *cm_bf537e_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
        &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
        &bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
        &isp1362_hcd_device,
@@ -683,6 +760,33 @@ static int __init cm_bf537e_init(void)
 
 arch_initcall(cm_bf537e_init);
 
+static struct platform_device *cm_bf537e_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(cm_bf537e_early_devices,
+               ARRAY_SIZE(cm_bf537e_early_devices));
+}
+
 void bfin_get_ether_addr(char *addr)
 {
        random_ether_addr(addr);
index ea11aa81340de555b209bff8db92fcc09b041418..d464ad5b72b2971fbe483079fb209dc26dc86444 100644 (file)
@@ -74,7 +74,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 16,
@@ -113,7 +113,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
        {
                .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -327,25 +327,93 @@ static struct platform_device cm_flash_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = UART0_THR,
+               .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
-       }, {
-               .start = 0xFFC02000,
-               .end = 0xFFC020FF,
+       },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+       .name = "bfin-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+       {
+               .start = UART1_THR,
+               .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART1_ERROR,
+               .end = IRQ_UART1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_TX,
+               .end = CH_UART1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+       P_UART1_TX, P_UART1_RX, 0
 };
 
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart1_device = {
        .name = "bfin-uart",
        .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+       .resource = bfin_uart1_resources,
+       .dev = {
+               .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -423,16 +491,75 @@ static struct platform_device i2c_bfin_twi_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+       {
+               .start = SPORT0_TCR1,
+               .end = SPORT0_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT0_RX,
+               .end = IRQ_SPORT0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT0_ERROR,
+               .end = IRQ_SPORT0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
        .name = "bfin-sport-uart",
        .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+       .resource = bfin_sport0_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+       {
+               .start = SPORT1_TCR1,
+               .end = SPORT1_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT1_RX,
+               .end = IRQ_SPORT1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT1_ERROR,
+               .end = IRQ_SPORT1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
        .name = "bfin-sport-uart",
        .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+       .resource = bfin_sport1_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static struct platform_device bfin_mii_bus = {
@@ -522,7 +649,12 @@ static struct platform_device *cm_bf537u_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -539,9 +671,13 @@ static struct platform_device *cm_bf537u_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
        &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
        &bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
        &isp1362_hcd_device,
@@ -589,6 +725,33 @@ static int __init cm_bf537u_init(void)
 
 arch_initcall(cm_bf537u_init);
 
+static struct platform_device *cm_bf537u_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(cm_bf537u_early_devices,
+               ARRAY_SIZE(cm_bf537u_early_devices));
+}
+
 void bfin_get_ether_addr(char *addr)
 {
        random_ether_addr(addr);
index 0da9272527013c3a3faa2d435cb610f3f0f5b784..c489d602c59013036d1bb0b546fd208d6773091a 100644 (file)
@@ -211,25 +211,93 @@ static struct platform_device bfin_spi0_device = {
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = UART0_THR,
+               .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
-       }, {
-               .start = 0xFFC02000,
-               .end = 0xFFC020FF,
+       },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+       .name = "bfin-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+       {
+               .start = UART1_THR,
+               .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART1_ERROR,
+               .end = IRQ_UART1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_TX,
+               .end = CH_UART1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+       P_UART1_TX, P_UART1_RX, 0
 };
 
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart1_device = {
        .name = "bfin-uart",
        .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+       .resource = bfin_uart1_resources,
+       .dev = {
+               .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -309,16 +377,75 @@ static struct platform_device i2c_bfin_twi_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+       {
+               .start = SPORT0_TCR1,
+               .end = SPORT0_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT0_RX,
+               .end = IRQ_SPORT0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT0_ERROR,
+               .end = IRQ_SPORT0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
        .name = "bfin-sport-uart",
        .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+       .resource = bfin_sport0_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+       {
+               .start = SPORT1_TCR1,
+               .end = SPORT1_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT1_RX,
+               .end = IRQ_SPORT1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT1_ERROR,
+               .end = IRQ_SPORT1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
        .name = "bfin-sport-uart",
        .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+       .resource = bfin_sport1_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 static struct platform_device *minotaur_devices[] __initdata = {
 #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
@@ -343,7 +470,12 @@ static struct platform_device *minotaur_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -360,9 +492,13 @@ static struct platform_device *minotaur_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
        &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
        &bfin_sport1_uart_device,
 #endif
+#endif
 
 };
 
@@ -380,6 +516,33 @@ static int __init minotaur_init(void)
 
 arch_initcall(minotaur_init);
 
+static struct platform_device *minotaur_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(minotaur_early_devices,
+               ARRAY_SIZE(minotaur_early_devices));
+}
+
 void native_machine_restart(char *cmd)
 {
        /* workaround reboot hang when booting from SPI */
index 4e0afda472ab2905557fe2d8ad1000860e0524af..812e8f9916019626f6c690435b7e89dff36b32ef 100644 (file)
@@ -17,7 +17,6 @@
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
-#include <linux/usb/sl811.h>
 
 #include <linux/spi/ad7877.h>
 
@@ -99,51 +98,6 @@ static struct platform_device smc91x_device = {
 };
 #endif
 
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
-static struct resource sl811_hcd_resources[] = {
-       {
-               .start = 0x20340000,
-               .end = 0x20340000,
-               .flags = IORESOURCE_MEM,
-       }, {
-               .start = 0x20340004,
-               .end = 0x20340004,
-               .flags = IORESOURCE_MEM,
-       }, {
-               .start = CONFIG_USB_SL811_BFIN_IRQ,
-               .end = CONFIG_USB_SL811_BFIN_IRQ,
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-       },
-};
-
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
-void sl811_port_power(struct device *dev, int is_on)
-{
-       gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
-       gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
-
-}
-#endif
-
-static struct sl811_platform_data sl811_priv = {
-       .potpg = 10,
-       .power = 250,       /* == 500mA */
-#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
-       .port_power = &sl811_port_power,
-#endif
-};
-
-static struct platform_device sl811_hcd_device = {
-       .name = "sl811-hcd",
-       .id = 0,
-       .dev = {
-               .platform_data = &sl811_priv,
-       },
-       .num_resources = ARRAY_SIZE(sl811_hcd_resources),
-       .resource = sl811_hcd_resources,
-};
-#endif
-
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static struct platform_device bfin_mii_bus = {
        .name = "bfin_mii_bus",
@@ -221,8 +175,8 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-       || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+       || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 16,
@@ -284,8 +238,8 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-       || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+       || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
        {
                .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -362,25 +316,93 @@ static struct platform_device bfin_fb_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = UART0_THR,
+               .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
-       }, {
-               .start = 0xFFC02000,
-               .end = 0xFFC020FF,
+       },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+       .name = "bfin-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+       {
+               .start = UART1_THR,
+               .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART1_ERROR,
+               .end = IRQ_UART1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_TX,
+               .end = CH_UART1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+       P_UART1_TX, P_UART1_RX, 0
 };
 
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart1_device = {
        .name = "bfin-uart",
        .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+       .resource = bfin_uart1_resources,
+       .dev = {
+               .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -446,10 +468,6 @@ static struct platform_device *stamp_devices[] __initdata = {
        &rtc_device,
 #endif
 
-#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
-       &sl811_hcd_device,
-#endif
-
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
        &smc91x_device,
 #endif
@@ -472,7 +490,12 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -498,6 +521,24 @@ static int __init pnav_init(void)
 
 arch_initcall(pnav_init);
 
+static struct platform_device *stamp_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(stamp_early_devices,
+               ARRAY_SIZE(stamp_early_devices));
+}
+
 void bfin_get_ether_addr(char *addr)
 {
        random_ether_addr(addr);
index ac9b52e0087ccb831c06130c8d5b225ff82c4024..9eaf5b05c11eac86b46a2680368386b7673a2fc0 100644 (file)
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb/isp1362.h>
 #endif
+#include <linux/i2c.h>
+#include <linux/i2c/adp5588.h>
+#include <linux/etherdevice.h>
 #include <linux/ata_platform.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
-#include <linux/i2c.h>
 #include <linux/usb/sl811.h>
 #include <linux/spi/mmc_spi.h>
 #include <linux/leds.h>
 #include <asm/reboot.h>
 #include <asm/portmux.h>
 #include <asm/dpmc.h>
+#ifdef CONFIG_REGULATOR_ADP_SWITCH
+#include <linux/regulator/adp_switch.h>
+#endif
+#ifdef CONFIG_REGULATOR_AD5398
+#include <linux/regulator/ad5398.h>
+#endif
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/userspace-consumer.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -208,8 +218,8 @@ static struct resource sl811_hcd_resources[] = {
                .end = 0x20340004,
                .flags = IORESOURCE_MEM,
        }, {
-               .start = CONFIG_USB_SL811_BFIN_IRQ,
-               .end = CONFIG_USB_SL811_BFIN_IRQ,
+               .start = IRQ_PF4,
+               .end = IRQ_PF4,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
        },
 };
@@ -454,6 +464,9 @@ static struct physmap_flash_data stamp_flash_data = {
        .width      = 2,
        .parts      = stamp_partitions,
        .nr_parts   = ARRAY_SIZE(stamp_partitions),
+#ifdef CONFIG_ROMKERNEL
+       .probe_type = "map_rom",
+#endif
 };
 
 static struct resource stamp_flash_resource = {
@@ -515,20 +528,19 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
-       || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+       || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 16,
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_AD1938) \
-       || defined(CONFIG_SND_BF5XX_SOC_AD1938_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD193X) \
+       || defined(CONFIG_SND_BF5XX_SOC_AD193X_MODULE)
 static struct bfin5xx_spi_chip ad1938_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 8,
-       .cs_gpio = GPIO_PF5,
 };
 #endif
 
@@ -644,6 +656,42 @@ static struct ad714x_platform_data ad7142_i2c_platform_data = {
 };
 #endif
 
+#if defined(CONFIG_AD2S90) || defined(CONFIG_AD2S90_MODULE)
+static struct bfin5xx_spi_chip ad2s90_spi_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD2S120X) || defined(CONFIG_AD2S120X_MODULE)
+unsigned short ad2s120x_platform_data[] = {
+       /* used as SAMPLE and RDVEL */
+       GPIO_PF5, GPIO_PF6, 0
+};
+
+static struct bfin5xx_spi_chip ad2s120x_spi_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD2S1210) || defined(CONFIG_AD2S1210_MODULE)
+unsigned short ad2s1210_platform_data[] = {
+       /* use as SAMPLE, A0, A1 */
+       GPIO_PF7, GPIO_PF8, GPIO_PF9,
+# if defined(CONFIG_AD2S1210_GPIO_INPUT) || defined(CONFIG_AD2S1210_GPIO_OUTPUT)
+       /* the RES0 and RES1 pins */
+       GPIO_PF4, GPIO_PF5,
+# endif
+       0,
+};
+
+static struct bfin5xx_spi_chip ad2s1210_spi_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 8,
+};
+#endif
+
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 #define MMC_SPI_CARD_DETECT_INT IRQ_PF5
 
@@ -686,11 +734,11 @@ static const struct ad7877_platform_data bfin_ad7877_ts_info = {
        .y_plate_ohms           = 486,
        .pressure_max           = 1000,
        .pressure_min           = 0,
-       .stopacq_polarity       = 1,
-       .first_conversion_delay = 3,
-       .acquisition_time       = 1,
-       .averaging              = 1,
-       .pen_down_acc_interval  = 1,
+       .stopacq_polarity       = 1,
+       .first_conversion_delay = 3,
+       .acquisition_time       = 1,
+       .averaging              = 1,
+       .pen_down_acc_interval  = 1,
 };
 #endif
 
@@ -701,13 +749,13 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = {
        .x_plate_ohms           = 620,  /* 620 Ohm from the touch datasheet */
        .pressure_max           = 10000,
        .pressure_min           = 0,
-       .first_conversion_delay = 3,    /* wait 512us before do a first conversion */
-       .acquisition_time       = 1,    /* 4us acquisition time per sample */
+       .first_conversion_delay = 3,    /* wait 512us before do a first conversion */
+       .acquisition_time       = 1,    /* 4us acquisition time per sample */
        .median                 = 2,    /* do 8 measurements */
-       .averaging              = 1,    /* take the average of 4 middle samples */
-       .pen_down_acc_interval  = 255,  /* 9.4 ms */
-       .gpio_output            = 1,    /* configure AUX/VBAT/GPIO as GPIO output */
-       .gpio_default           = 1,    /* During initialization set GPIO = HIGH */
+       .averaging              = 1,    /* take the average of 4 middle samples */
+       .pen_down_acc_interval  = 255,  /* 9.4 ms */
+       .gpio_export            = 1,    /* Export GPIO to gpiolib */
+       .gpio_base              = -1,   /* Dynamic allocation */
 };
 #endif
 
@@ -742,6 +790,11 @@ static const struct adxl34x_platform_data adxl34x_info = {
 /*     .ev_code_act_inactivity = KEY_A,*/      /* EV_KEY */
        .power_mode = ADXL_AUTO_SLEEP | ADXL_LINK,
        .fifo_mode = ADXL_FIFO_STREAM,
+       .orientation_enable = ADXL_EN_ORIENTATION_3D,
+       .deadzone_angle = ADXL_DEADZONE_ANGLE_10p8,
+       .divisor_length =  ADXL_LP_FILTER_DIVISOR_16,
+       /* EV_KEY {+Z, +Y, +X, -X, -Y, -Z} */
+       .ev_codes_orient_3d = {BTN_Z, BTN_Y, BTN_X, BTN_A, BTN_B, BTN_C},
 };
 #endif
 
@@ -813,6 +866,35 @@ static struct adf702x_platform_data adf7021_platform_data = {
        .adf702x_regs = adf7021_regs,
        .tx_reg = TXREG,
 };
+static inline void adf702x_mac_init(void)
+{
+       random_ether_addr(adf7021_platform_data.mac_addr);
+}
+#else
+static inline void adf702x_mac_init(void) {}
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+#include <linux/spi/ads7846.h>
+static struct bfin5xx_spi_chip ad7873_spi_chip_info = {
+       .bits_per_word  = 8,
+};
+
+static int ads7873_get_pendown_state(void)
+{
+       return gpio_get_value(GPIO_PF6);
+}
+
+static struct ads7846_platform_data __initdata ad7873_pdata = {
+       .model          = 7873,         /* AD7873 */
+       .x_max          = 0xfff,
+       .y_max          = 0xfff,
+       .x_plate_ohms   = 620,
+       .debounce_max   = 1,
+       .debounce_rep   = 0,
+       .debounce_tol   = (~0),
+       .get_pendown_state = ads7873_get_pendown_state,
+};
 #endif
 
 #if defined(CONFIG_MTD_DATAFLASH) \
@@ -893,24 +975,25 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
-       || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \
+       || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE)
        {
-               .modalias = "ad1836",
+               .modalias = "ad183x",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 0,
                .chip_select = 4,/* CONFIG_SND_BLACKFIN_SPI_PFBIT */
+               .platform_data = "ad1836", /* only includes chip name for the moment */
                .controller_data = &ad1836_spi_chip_info,
                .mode = SPI_MODE_3,
        },
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_AD1938) || defined(CONFIG_SND_BF5XX_SOC_AD1938_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD193X) || defined(CONFIG_SND_BF5XX_SOC_AD193X_MODULE)
        {
-               .modalias = "ad1938",
+               .modalias = "ad193x",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
                .bus_num = 0,
-               .chip_select = 0,/* CONFIG_SND_BLACKFIN_SPI_PFBIT */
+               .chip_select = 5,
                .controller_data = &ad1938_spi_chip_info,
                .mode = SPI_MODE_3,
        },
@@ -929,6 +1012,37 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
+#if defined(CONFIG_AD2S90) || defined(CONFIG_AD2S90_MODULE)
+       {
+               .modalias = "ad2s90",
+               .bus_num = 0,
+               .chip_select = 3,            /* change it for your board */
+               .platform_data = NULL,
+               .controller_data = &ad2s90_spi_chip_info,
+       },
+#endif
+
+#if defined(CONFIG_AD2S120X) || defined(CONFIG_AD2S120X_MODULE)
+       {
+               .modalias = "ad2s120x",
+               .bus_num = 0,
+               .chip_select = 4,            /* CS, change it for your board */
+               .platform_data = ad2s120x_platform_data,
+               .controller_data = &ad2s120x_spi_chip_info,
+       },
+#endif
+
+#if defined(CONFIG_AD2S1210) || defined(CONFIG_AD2S1210_MODULE)
+       {
+               .modalias = "ad2s1210",
+               .max_speed_hz = 8192000,
+               .bus_num = 0,
+               .chip_select = 4,            /* CS, change it for your board */
+               .platform_data = ad2s1210_platform_data,
+               .controller_data = &ad2s1210_spi_chip_info,
+       },
+#endif
+
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
        {
                .modalias = "mmc_spi",
@@ -1016,7 +1130,18 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                .mode = SPI_MODE_0,
        },
 #endif
-
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+       {
+               .modalias = "ads7846",
+               .max_speed_hz = 2000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .irq = IRQ_PF6,
+               .chip_select = GPIO_PF10 + MAX_CTRL_CS, /* GPIO controlled SSEL */
+               .controller_data = &ad7873_spi_chip_info,
+               .platform_data = &ad7873_pdata,
+               .mode = SPI_MODE_0,
+       },
+#endif
 };
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
@@ -1132,9 +1257,10 @@ static struct platform_device bfin_fb_device = {
 #include <asm/bfin-lq035q1.h>
 
 static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = {
-       .mode =         LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
-       .use_bl =       0,      /* let something else control the LCD Blacklight */
-       .gpio_bl =      GPIO_PF7,
+       .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
+       .ppi_mode = USE_RGB565_16_BIT_PPI,
+       .use_bl = 0,    /* let something else control the LCD Blacklight */
+       .gpio_bl = GPIO_PF7,
 };
 
 static struct resource bfin_lq035q1_resources[] = {
@@ -1148,8 +1274,8 @@ static struct resource bfin_lq035q1_resources[] = {
 static struct platform_device bfin_lq035q1_device = {
        .name           = "bfin-lq035q1",
        .id             = -1,
-       .num_resources  = ARRAY_SIZE(bfin_lq035q1_resources),
-       .resource       = bfin_lq035q1_resources,
+       .num_resources  = ARRAY_SIZE(bfin_lq035q1_resources),
+       .resource       = bfin_lq035q1_resources,
        .dev            = {
                .platform_data = &bfin_lq035q1_data,
        },
@@ -1157,30 +1283,105 @@ static struct platform_device bfin_lq035q1_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = UART0_THR,
+               .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+       {       /* CTS pin */
+               .start = GPIO_PG7,
+               .end = GPIO_PG7,
+               .flags = IORESOURCE_IO,
+       },
+       {       /* RTS pin */
+               .start = GPIO_PG6,
+               .end = GPIO_PG6,
+               .flags = IORESOURCE_IO,
+       },
+#endif
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+       .name = "bfin-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
        {
-               .start = 0xFFC02000,
-               .end = 0xFFC020FF,
+               .start = UART1_THR,
+               .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
-#endif
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART1_ERROR,
+               .end = IRQ_UART1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_TX,
+               .end = CH_UART1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+       P_UART1_TX, P_UART1_RX, 0
 };
 
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart1_device = {
        .name = "bfin-uart",
        .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+       .resource = bfin_uart1_resources,
+       .dev = {
+               .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -1260,7 +1461,6 @@ static struct platform_device i2c_bfin_twi_device = {
 #endif
 
 #if defined(CONFIG_KEYBOARD_ADP5588) || defined(CONFIG_KEYBOARD_ADP5588_MODULE)
-#include <linux/i2c/adp5588.h>
 static const unsigned short adp5588_keymap[ADP5588_KEYMAPSIZE] = {
        [0]      = KEY_GRAVE,
        [1]      = KEY_1,
@@ -1457,7 +1657,6 @@ static struct adp5520_platform_data adp5520_pdev_data = {
 #endif
 
 #if defined(CONFIG_GPIO_ADP5588) || defined(CONFIG_GPIO_ADP5588_MODULE)
-#include <linux/i2c/adp5588.h>
 static struct adp5588_gpio_platform_data adp5588_gpio_data = {
        .gpio_start = 50,
        .pullup_dis_mask = 0,
@@ -1516,6 +1715,101 @@ static struct adp8870_backlight_platform_data adp8870_pdata = {
 };
 #endif
 
+#if defined(CONFIG_BACKLIGHT_ADP8860) || defined(CONFIG_BACKLIGHT_ADP8860_MODULE)
+#include <linux/i2c/adp8860.h>
+static struct led_info adp8860_leds[] = {
+       {
+               .name = "adp8860-led7",
+               .default_trigger = "none",
+               .flags = ADP8860_LED_D7 | ADP8860_LED_OFFT_600ms,
+       },
+};
+
+static struct adp8860_backlight_platform_data adp8860_pdata = {
+       .bl_led_assign = ADP8860_BL_D1 | ADP8860_BL_D2 | ADP8860_BL_D3 |
+                        ADP8860_BL_D4 | ADP8860_BL_D5 | ADP8860_BL_D6, /* 1 = Backlight 0 = Individual LED */
+
+       .bl_fade_in = ADP8860_FADE_T_1200ms,            /* Backlight Fade-In Timer */
+       .bl_fade_out = ADP8860_FADE_T_1200ms,           /* Backlight Fade-Out Timer */
+       .bl_fade_law = ADP8860_FADE_LAW_CUBIC1,         /* fade-on/fade-off transfer characteristic */
+
+       .en_ambl_sens = 1,                              /* 1 = enable ambient light sensor */
+       .abml_filt = ADP8860_BL_AMBL_FILT_320ms,        /* Light sensor filter time */
+
+       .l1_daylight_max = ADP8860_BL_CUR_mA(20),       /* use BL_CUR_mA(I) 0 <= I <= 30 mA */
+       .l1_daylight_dim = ADP8860_BL_CUR_mA(0),        /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
+       .l2_office_max = ADP8860_BL_CUR_mA(6),          /* use BL_CUR_mA(I) 0 <= I <= 30 mA */
+       .l2_office_dim = ADP8860_BL_CUR_mA(0),          /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
+       .l3_dark_max = ADP8860_BL_CUR_mA(2),            /* use BL_CUR_mA(I) 0 <= I <= 30 mA */
+       .l3_dark_dim = ADP8860_BL_CUR_mA(0),            /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */
+
+       .l2_trip = ADP8860_L2_COMP_CURR_uA(710),        /* use L2_COMP_CURR_uA(I) 0 <= I <= 1106 uA */
+       .l2_hyst = ADP8860_L2_COMP_CURR_uA(73),         /* use L2_COMP_CURR_uA(I) 0 <= I <= 1106 uA */
+       .l3_trip = ADP8860_L3_COMP_CURR_uA(43),         /* use L3_COMP_CURR_uA(I) 0 <= I <= 138 uA */
+       .l3_hyst = ADP8860_L3_COMP_CURR_uA(11),         /* use L3_COMP_CURR_uA(I) 0 <= I <= 138 uA */
+
+       .leds = adp8860_leds,
+       .num_leds = ARRAY_SIZE(adp8860_leds),
+       .led_fade_law = ADP8860_FADE_LAW_SQUARE,        /* fade-on/fade-off transfer characteristic */
+       .led_fade_in = ADP8860_FADE_T_600ms,
+       .led_fade_out = ADP8860_FADE_T_600ms,
+       .led_on_time = ADP8860_LED_ONT_200ms,
+};
+#endif
+
+#if defined(CONFIG_REGULATOR_AD5398) || defined(CONFIG_REGULATOR_AD5398_MODULE)
+static struct regulator_consumer_supply ad5398_consumer = {
+       .supply = "current",
+};
+
+static struct regulator_init_data ad5398_regulator_data = {
+       .constraints = {
+               .name = "current range",
+               .max_uA = 120000,
+               .valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies = 1,
+       .consumer_supplies     = &ad5398_consumer,
+};
+
+static struct ad5398_platform_data ad5398_i2c_platform_data = {
+       .current_bits = 10,
+       .current_offset = 4,
+       .regulator_data = &ad5398_regulator_data,
+};
+
+#if defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER) || \
+       defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER_MODULE)
+static struct platform_device ad5398_virt_consumer_device = {
+       .name = "reg-virt-consumer",
+       .id = 0,
+       .dev = {
+               .platform_data = "current", /* Passed to driver */
+       },
+};
+#endif
+#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \
+       defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE)
+static struct regulator_bulk_data ad5398_bulk_data = {
+       .supply = "current",
+};
+
+static struct regulator_userspace_consumer_data ad5398_userspace_comsumer_data = {
+       .name = "ad5398",
+       .num_supplies = 1,
+       .supplies = &ad5398_bulk_data,
+};
+
+static struct platform_device ad5398_userspace_consumer_device = {
+       .name = "reg-userspace-consumer",
+       .id = 0,
+       .dev = {
+               .platform_data = &ad5398_userspace_comsumer_data,
+       },
+};
+#endif
+#endif
+
 static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 #if defined(CONFIG_INPUT_AD714X_I2C) || defined(CONFIG_INPUT_AD714X_I2C_MODULE)
        {
@@ -1524,6 +1818,52 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
                .platform_data = (void *)&ad7142_i2c_platform_data,
        },
 #endif
+
+#if defined(CONFIG_AD7150) || defined(CONFIG_AD7150_MODULE)
+       {
+               I2C_BOARD_INFO("ad7150", 0x48),
+               .irq = IRQ_PG5, /* fixme: use real interrupt number */
+       },
+#endif
+
+#if defined(CONFIG_AD7152) || defined(CONFIG_AD7152_MODULE)
+       {
+               I2C_BOARD_INFO("ad7152", 0x48),
+       },
+#endif
+
+#if defined(CONFIG_AD774X) || defined(CONFIG_AD774X_MODULE)
+       {
+               I2C_BOARD_INFO("ad774x", 0x48),
+       },
+#endif
+
+#if defined(CONFIG_AD7414) || defined(CONFIG_AD7414_MODULE)
+       {
+               I2C_BOARD_INFO("ad7414", 0x9),
+               .irq = IRQ_PG5,
+               /*
+                * platform_data pointer is borrwoed by the driver to
+                * store custimer defined IRQ ALART level mode.
+                * only IRQF_TRIGGER_HIGH and IRQF_TRIGGER_LOW are valid.
+                */
+               .platform_data = (void *)IRQF_TRIGGER_LOW,
+       },
+#endif
+
+#if defined(CONFIG_AD7416) || defined(CONFIG_AD7416_MODULE)
+       {
+               I2C_BOARD_INFO("ad7417", 0xb),
+               .irq = IRQ_PG5,
+               /*
+                * platform_data pointer is borrwoed by the driver to
+                * store custimer defined IRQ ALART level mode.
+                * only IRQF_TRIGGER_HIGH and IRQF_TRIGGER_LOW are valid.
+                */
+               .platform_data = (void *)IRQF_TRIGGER_LOW,
+       },
+#endif
+
 #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
        {
                I2C_BOARD_INFO("pcf8574_lcd", 0x22),
@@ -1595,24 +1935,105 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
                I2C_BOARD_INFO("adau1761", 0x38),
        },
 #endif
+#if defined(CONFIG_SND_SOC_ADAU1361) || defined(CONFIG_SND_SOC_ADAU1361_MODULE)
+       {
+               I2C_BOARD_INFO("adau1361", 0x38),
+       },
+#endif
 #if defined(CONFIG_AD525X_DPOT) || defined(CONFIG_AD525X_DPOT_MODULE)
        {
                I2C_BOARD_INFO("ad5258", 0x18),
        },
 #endif
+#if defined(CONFIG_SND_SOC_SSM2602) || defined(CONFIG_SND_SOC_SSM2602_MODULE)
+       {
+               I2C_BOARD_INFO("ssm2602", 0x1b),
+       },
+#endif
+#if defined(CONFIG_REGULATOR_AD5398) || defined(CONFIG_REGULATOR_AD5398_MODULE)
+       {
+               I2C_BOARD_INFO("ad5398", 0xC),
+               .platform_data = (void *)&ad5398_i2c_platform_data,
+       },
+#endif
+#if defined(CONFIG_BACKLIGHT_ADP8860) || defined(CONFIG_BACKLIGHT_ADP8860_MODULE)
+       {
+               I2C_BOARD_INFO("adp8860", 0x2A),
+               .platform_data = (void *)&adp8860_pdata,
+       },
+#endif
 };
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+       {
+               .start = SPORT0_TCR1,
+               .end = SPORT0_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT0_RX,
+               .end = IRQ_SPORT0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT0_ERROR,
+               .end = IRQ_SPORT0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
        .name = "bfin-sport-uart",
        .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+       .resource = bfin_sport0_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+       {
+               .start = SPORT1_TCR1,
+               .end = SPORT1_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT1_RX,
+               .end = IRQ_SPORT1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT1_ERROR,
+               .end = IRQ_SPORT1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
        .name = "bfin-sport-uart",
        .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+       .resource = bfin_sport1_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
 #define CF_IDE_NAND_CARD_USE_HDD_INTERFACE
@@ -1701,13 +2122,121 @@ static struct platform_device bfin_dpmc = {
        },
 };
 
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+       .name = "bfin-i2s",
+       .id = CONFIG_SND_BF5XX_SPORT_NUM,
+       /* TODO: add platform data here */
+};
+#endif
+
 #if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
 static struct platform_device bfin_tdm = {
        .name = "bfin-tdm",
+       .id = CONFIG_SND_BF5XX_SPORT_NUM,
        /* TODO: add platform data here */
 };
 #endif
 
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+static struct platform_device bfin_ac97 = {
+       .name = "bfin-ac97",
+       .id = CONFIG_SND_BF5XX_SPORT_NUM,
+       /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_REGULATOR_ADP_SWITCH) || defined(CONFIG_REGULATOR_ADP_SWITCH_MODULE)
+#define REGULATOR_ADP122        "adp122"
+#define REGULATOR_ADP150        "adp150"
+
+static struct regulator_consumer_supply adp122_consumers = {
+               .supply = REGULATOR_ADP122,
+};
+
+static struct regulator_consumer_supply adp150_consumers = {
+               .supply = REGULATOR_ADP150,
+};
+
+static struct regulator_init_data adp_switch_regulator_data[] = {
+       {
+               .constraints = {
+                       .name = REGULATOR_ADP122,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+                       .min_uA = 0,
+                       .max_uA = 300000,
+               },
+               .num_consumer_supplies = 1,     /* only 1 */
+               .consumer_supplies     = &adp122_consumers,
+               .driver_data           = (void *)GPIO_PF2, /* gpio port only */
+       },
+       {
+               .constraints = {
+                       .name = REGULATOR_ADP150,
+                       .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+                       .min_uA = 0,
+                       .max_uA = 150000,
+               },
+               .num_consumer_supplies = 1,     /* only 1 */
+               .consumer_supplies     = &adp150_consumers,
+               .driver_data           = (void *)GPIO_PF3, /* gpio port only */
+       },
+};
+
+static struct adp_switch_platform_data adp_switch_pdata = {
+       .regulator_num = ARRAY_SIZE(adp_switch_regulator_data),
+       .regulator_data = adp_switch_regulator_data,
+};
+
+static struct platform_device adp_switch_device = {
+       .name = "adp_switch",
+       .id = 0,
+       .dev = {
+               .platform_data = &adp_switch_pdata,
+       },
+};
+
+#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \
+       defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE)
+static struct regulator_bulk_data adp122_bulk_data = {
+       .supply = REGULATOR_ADP122,
+};
+
+static struct regulator_userspace_consumer_data adp122_userspace_comsumer_data = {
+       .name = REGULATOR_ADP122,
+       .num_supplies = 1,
+       .supplies = &adp122_bulk_data,
+};
+
+static struct platform_device adp122_userspace_consumer_device = {
+       .name = "reg-userspace-consumer",
+       .id = 0,
+       .dev = {
+               .platform_data = &adp122_userspace_comsumer_data,
+       },
+};
+
+static struct regulator_bulk_data adp150_bulk_data = {
+       .supply = REGULATOR_ADP150,
+};
+
+static struct regulator_userspace_consumer_data adp150_userspace_comsumer_data = {
+       .name = REGULATOR_ADP150,
+       .num_supplies = 1,
+       .supplies = &adp150_bulk_data,
+};
+
+static struct platform_device adp150_userspace_consumer_device = {
+       .name = "reg-userspace-consumer",
+       .id = 1,
+       .dev = {
+               .platform_data = &adp150_userspace_comsumer_data,
+       },
+};
+#endif
+#endif
+
+
 static struct platform_device *stamp_devices[] __initdata = {
 
        &bfin_dpmc,
@@ -1771,7 +2300,12 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -1788,9 +2322,13 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
        &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
        &bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
        &bfin_pata_device,
@@ -1808,18 +2346,46 @@ static struct platform_device *stamp_devices[] __initdata = {
        &stamp_flash_device,
 #endif
 
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+       &bfin_i2s,
+#endif
+
 #if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
        &bfin_tdm,
 #endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+       &bfin_ac97,
+#endif
+#if defined(CONFIG_REGULATOR_AD5398) || defined(CONFIG_REGULATOR_AD5398_MODULE)
+#if defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER) || \
+       defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER_MODULE)
+       &ad5398_virt_consumer_device,
+#endif
+#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \
+       defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE)
+       &ad5398_userspace_consumer_device,
+#endif
+#endif
+
+#if defined(CONFIG_REGULATOR_ADP_SWITCH) || defined(CONFIG_REGULATOR_ADP_SWITCH_MODULE)
+       &adp_switch_device,
+#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \
+       defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE)
+       &adp122_userspace_consumer_device,
+       &adp150_userspace_consumer_device,
+#endif
+#endif
 };
 
 static int __init stamp_init(void)
 {
        printk(KERN_INFO "%s(): registering device resources\n", __func__);
-       i2c_register_board_info(0, bfin_i2c_board_info,
-                               ARRAY_SIZE(bfin_i2c_board_info));
        bfin_plat_nand_init();
+       adf702x_mac_init();
        platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+       i2c_register_board_info(0, bfin_i2c_board_info,
+                               ARRAY_SIZE(bfin_i2c_board_info));
        spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
 
        return 0;
@@ -1827,6 +2393,34 @@ static int __init stamp_init(void)
 
 arch_initcall(stamp_init);
 
+
+static struct platform_device *stamp_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(stamp_early_devices,
+               ARRAY_SIZE(stamp_early_devices));
+}
+
 void native_machine_restart(char *cmd)
 {
        /* workaround reboot hang when booting from SPI */
index 57163b65a4f5d230463d8699e22d4a3253d37d75..4f0a2e72ce4cdc99f08dd964c8325b885a72aa23 100644 (file)
@@ -74,7 +74,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 16,
@@ -113,7 +113,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
        {
                .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -327,25 +327,93 @@ static struct platform_device cm_flash_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = UART0_THR,
+               .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
-       }, {
-               .start = 0xFFC02000,
-               .end = 0xFFC020FF,
+       },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+       .name = "bfin-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+       {
+               .start = UART1_THR,
+               .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART1_ERROR,
+               .end = IRQ_UART1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_TX,
+               .end = CH_UART1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+       P_UART1_TX, P_UART1_RX, 0
 };
 
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart1_device = {
        .name = "bfin-uart",
        .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+       .resource = bfin_uart1_resources,
+       .dev = {
+               .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -425,16 +493,75 @@ static struct platform_device i2c_bfin_twi_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+       {
+               .start = SPORT0_TCR1,
+               .end = SPORT0_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT0_RX,
+               .end = IRQ_SPORT0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT0_ERROR,
+               .end = IRQ_SPORT0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
 static struct platform_device bfin_sport0_uart_device = {
        .name = "bfin-sport-uart",
        .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+       .resource = bfin_sport0_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+       {
+               .start = SPORT1_TCR1,
+               .end = SPORT1_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT1_RX,
+               .end = IRQ_SPORT1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT1_ERROR,
+               .end = IRQ_SPORT1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
 };
 
 static struct platform_device bfin_sport1_uart_device = {
        .name = "bfin-sport-uart",
        .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+       .resource = bfin_sport1_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static struct platform_device bfin_mii_bus = {
@@ -524,7 +651,12 @@ static struct platform_device *cm_bf537_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -541,9 +673,13 @@ static struct platform_device *cm_bf537_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
        &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
        &bfin_sport1_uart_device,
 #endif
+#endif
 
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
        &isp1362_hcd_device,
@@ -591,6 +727,33 @@ static int __init tcm_bf537_init(void)
 
 arch_initcall(tcm_bf537_init);
 
+static struct platform_device *cm_bf537_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(cm_bf537_early_devices,
+               ARRAY_SIZE(cm_bf537_early_devices));
+}
+
 void bfin_get_ether_addr(char *addr)
 {
        random_ether_addr(addr);
index 0defa9457e7f91edd607bba27b153df21581d380..789a4f226f7b2c8b0b75eb763e12b693830978c9 100644 (file)
 
 #define GPIO_IRQ_BASE  IRQ_PF0
 
-#define NR_IRQS     (IRQ_PH15+1)
+#define IRQ_MAC_PHYINT         98 /* PHY_INT Interrupt */
+#define IRQ_MAC_MMCINT         99 /* MMC Counter Interrupt */
+#define IRQ_MAC_RXFSINT                100 /* RX Frame-Status Interrupt */
+#define IRQ_MAC_TXFSINT                101 /* TX Frame-Status Interrupt */
+#define IRQ_MAC_WAKEDET                102 /* Wake-Up Interrupt */
+#define IRQ_MAC_RXDMAERR       103 /* RX DMA Direction Error Interrupt */
+#define IRQ_MAC_TXDMAERR       104 /* TX DMA Direction Error Interrupt */
+#define IRQ_MAC_STMDONE                105 /* Station Mgt. Transfer Done Interrupt */
+
+#define NR_MACH_IRQS   (IRQ_MAC_STMDONE + 1)
+#define NR_IRQS                (NR_MACH_IRQS + NR_SPARE_IRQS)
 
 #define IVG7            7
 #define IVG8            8
index c296bb1ed50370230b756fff443479c980de01ac..1a1f65855b033843530b441979eaae90a1490e85 100644 (file)
@@ -41,37 +41,148 @@ static struct platform_device rtc_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = UART0_THR,
+               .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+       {       /* CTS pin */
+               .start = GPIO_PG7,
+               .end = GPIO_PG7,
+               .flags = IORESOURCE_IO,
+       },
+       {       /* RTS pin */
+               .start = GPIO_PG6,
+               .end = GPIO_PG6,
+               .flags = IORESOURCE_IO,
+       },
+#endif
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+       .name = "bfin-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
        {
-               .start = 0xFFC02000,
-               .end = 0xFFC020FF,
+               .start = UART1_THR,
+               .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART1_ERROR,
+               .end = IRQ_UART1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_TX,
+               .end = CH_UART1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+       P_UART1_TX, P_UART1_RX, 0
+};
+
+static struct platform_device bfin_uart1_device = {
+       .name = "bfin-uart",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+       .resource = bfin_uart1_resources,
+       .dev = {
+               .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+       },
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART2
+static struct resource bfin_uart2_resources[] = {
        {
-               .start = 0xFFC02100,
-               .end = 0xFFC021FF,
+               .start = UART2_THR,
+               .end = UART2_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
-#endif
+       {
+               .start = IRQ_UART2_RX,
+               .end = IRQ_UART2_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART2_ERROR,
+               .end = IRQ_UART2_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART2_TX,
+               .end = CH_UART2_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART2_RX,
+               .end = CH_UART2_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart2_peripherals[] = {
+       P_UART2_TX, P_UART2_RX, 0
 };
 
-static struct platform_device bfin_uart_device = {
+static struct platform_device bfin_uart2_device = {
        .name = "bfin-uart",
-       .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .id = 2,
+       .num_resources = ARRAY_SIZE(bfin_uart2_resources),
+       .resource = bfin_uart2_resources,
+       .dev = {
+               .platform_data = &bfin_uart2_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -151,6 +262,145 @@ static struct platform_device bfin_sir2_device = {
 #endif
 #endif
 
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+       {
+               .start = SPORT0_TCR1,
+               .end = SPORT0_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT0_RX,
+               .end = IRQ_SPORT0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT0_ERROR,
+               .end = IRQ_SPORT0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
+static struct platform_device bfin_sport0_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+       .resource = bfin_sport0_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+       {
+               .start = SPORT1_TCR1,
+               .end = SPORT1_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT1_RX,
+               .end = IRQ_SPORT1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT1_ERROR,
+               .end = IRQ_SPORT1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+       .resource = bfin_sport1_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+static struct resource bfin_sport2_uart_resources[] = {
+       {
+               .start = SPORT2_TCR1,
+               .end = SPORT2_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT2_RX,
+               .end = IRQ_SPORT2_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT2_ERROR,
+               .end = IRQ_SPORT2_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport2_peripherals[] = {
+       P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS,
+       P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0
+};
+
+static struct platform_device bfin_sport2_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 2,
+       .num_resources = ARRAY_SIZE(bfin_sport2_uart_resources),
+       .resource = bfin_sport2_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport2_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+static struct resource bfin_sport3_uart_resources[] = {
+       {
+               .start = SPORT3_TCR1,
+               .end = SPORT3_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT3_RX,
+               .end = IRQ_SPORT3_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT3_ERROR,
+               .end = IRQ_SPORT3_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport3_peripherals[] = {
+       P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS,
+       P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0
+};
+
+static struct platform_device bfin_sport3_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 3,
+       .num_resources = ARRAY_SIZE(bfin_sport3_uart_resources),
+       .resource = bfin_sport3_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport3_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#endif
+
 #if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
 unsigned short bfin_can_peripherals[] = {
        P_CAN0_RX, P_CAN0_TX, 0
@@ -268,8 +518,8 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = {
        .median                 = 2,    /* do 8 measurements */
        .averaging              = 1,    /* take the average of 4 middle samples */
        .pen_down_acc_interval  = 255,  /* 9.4 ms */
-       .gpio_output            = 1,    /* configure AUX/VBAT/GPIO as GPIO output */
-       .gpio_default           = 1,    /* During initialization set GPIO = HIGH */
+       .gpio_export            = 1,    /* Export GPIO to gpiolib */
+       .gpio_base              = -1,   /* Dynamic allocation */
 };
 #endif
 
@@ -284,9 +534,10 @@ static struct bfin5xx_spi_chip spi_ad7879_chip_info = {
 #include <asm/bfin-lq035q1.h>
 
 static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = {
-       .mode =         LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
-       .use_bl =       0,      /* let something else control the LCD Blacklight */
-       .gpio_bl =      GPIO_PF7,
+       .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB,
+       .ppi_mode = USE_RGB565_16_BIT_PPI,
+       .use_bl = 0,    /* let something else control the LCD Blacklight */
+       .gpio_bl = GPIO_PF7,
 };
 
 static struct resource bfin_lq035q1_resources[] = {
@@ -622,7 +873,15 @@ static struct platform_device *cm_bf538_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+       &bfin_uart2_device,
+#endif
 #endif
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
@@ -648,6 +907,21 @@ static struct platform_device *cm_bf538_devices[] __initdata = {
 #endif
 #endif
 
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+       &bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+       &bfin_sport3_uart_device,
+#endif
+#endif
+
 #if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
        &bfin_can_device,
 #endif
@@ -683,3 +957,39 @@ static int __init ezkit_init(void)
 }
 
 arch_initcall(ezkit_init);
+
+static struct platform_device *ezkit_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+       &bfin_uart2_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+       &bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+       &bfin_sport3_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(ezkit_early_devices,
+               ARRAY_SIZE(ezkit_early_devices));
+}
index a4b7fcbc556b5fe817be7f1dbfe7cd604555d128..7a479d224dc79da2c1d371469110e40158d870be 100644 (file)
 
 #define GPIO_IRQ_BASE  IRQ_PF0
 
-#define NR_IRQS     (IRQ_PF15+1)
+#define NR_MACH_IRQS   (IRQ_PF15 + 1)
+#define NR_IRQS                (NR_MACH_IRQS + NR_SPARE_IRQS)
 
 #define IVG7            7
 #define IVG8            8
index ccdcd6da2e9fc09f00b7e1f19bb2b26bbfbdccce..f60c333fec667ea8c88f0023659e8d2ae9dcab8e 100644 (file)
@@ -127,44 +127,211 @@ static struct platform_device rtc_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = UART0_DLL,
+               .end = UART0_RBR+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+       .name = "bfin-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
        {
-               .start = 0xFFC02000,
-               .end = 0xFFC020FF,
+               .start = UART1_DLL,
+               .end = UART1_RBR+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART1_ERROR,
+               .end = IRQ_UART1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_TX,
+               .end = CH_UART1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+       {       /* CTS pin -- 0 means not supported */
+               .start = GPIO_PE10,
+               .end = GPIO_PE10,
+               .flags = IORESOURCE_IO,
+       },
+       {       /* RTS pin -- 0 means not supported */
+               .start = GPIO_PE9,
+               .end = GPIO_PE9,
+               .flags = IORESOURCE_IO,
+       },
+#endif
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+       P_UART1_TX, P_UART1_RX,
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+       P_UART1_RTS, P_UART1_CTS,
+#endif
+       0
+};
+
+static struct platform_device bfin_uart1_device = {
+       .name = "bfin-uart",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+       .resource = bfin_uart1_resources,
+       .dev = {
+               .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+       },
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART2
+static struct resource bfin_uart2_resources[] = {
        {
-               .start = 0xFFC02100,
-               .end = 0xFFC021FF,
+               .start = UART2_DLL,
+               .end = UART2_RBR+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART2_RX,
+               .end = IRQ_UART2_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART2_ERROR,
+               .end = IRQ_UART2_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART2_TX,
+               .end = CH_UART2_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART2_RX,
+               .end = CH_UART2_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart2_peripherals[] = {
+       P_UART2_TX, P_UART2_RX, 0
+};
+
+static struct platform_device bfin_uart2_device = {
+       .name = "bfin-uart",
+       .id = 2,
+       .num_resources = ARRAY_SIZE(bfin_uart2_resources),
+       .resource = bfin_uart2_resources,
+       .dev = {
+               .platform_data = &bfin_uart2_peripherals, /* Passed to driver */
+       },
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART3
+static struct resource bfin_uart3_resources[] = {
        {
-               .start = 0xFFC03100,
-               .end = 0xFFC031FF,
+               .start = UART3_DLL,
+               .end = UART3_RBR+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART3_RX,
+               .end = IRQ_UART3_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART3_ERROR,
+               .end = IRQ_UART3_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART3_TX,
+               .end = CH_UART3_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART3_RX,
+               .end = CH_UART3_RX,
+               .flags = IORESOURCE_DMA,
+       },
+#ifdef CONFIG_BFIN_UART3_CTSRTS
+       {       /* CTS pin -- 0 means not supported */
+               .start = GPIO_PB3,
+               .end = GPIO_PB3,
+               .flags = IORESOURCE_IO,
+       },
+       {       /* RTS pin -- 0 means not supported */
+               .start = GPIO_PB2,
+               .end = GPIO_PB2,
+               .flags = IORESOURCE_IO,
+       },
 #endif
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart3_peripherals[] = {
+       P_UART3_TX, P_UART3_RX,
+#ifdef CONFIG_BFIN_UART3_CTSRTS
+       P_UART3_RTS, P_UART3_CTS,
+#endif
+       0
+};
+
+static struct platform_device bfin_uart3_device = {
        .name = "bfin-uart",
-       .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .id = 3,
+       .num_resources = ARRAY_SIZE(bfin_uart3_resources),
+       .resource = bfin_uart3_resources,
+       .dev = {
+               .platform_data = &bfin_uart3_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -359,6 +526,145 @@ static struct platform_device musb_device = {
 };
 #endif
 
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+       {
+               .start = SPORT0_TCR1,
+               .end = SPORT0_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT0_RX,
+               .end = IRQ_SPORT0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT0_ERROR,
+               .end = IRQ_SPORT0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
+static struct platform_device bfin_sport0_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+       .resource = bfin_sport0_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+       {
+               .start = SPORT1_TCR1,
+               .end = SPORT1_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT1_RX,
+               .end = IRQ_SPORT1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT1_ERROR,
+               .end = IRQ_SPORT1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+       .resource = bfin_sport1_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+static struct resource bfin_sport2_uart_resources[] = {
+       {
+               .start = SPORT2_TCR1,
+               .end = SPORT2_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT2_RX,
+               .end = IRQ_SPORT2_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT2_ERROR,
+               .end = IRQ_SPORT2_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport2_peripherals[] = {
+       P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS,
+       P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0
+};
+
+static struct platform_device bfin_sport2_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 2,
+       .num_resources = ARRAY_SIZE(bfin_sport2_uart_resources),
+       .resource = bfin_sport2_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport2_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+static struct resource bfin_sport3_uart_resources[] = {
+       {
+               .start = SPORT3_TCR1,
+               .end = SPORT3_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT3_RX,
+               .end = IRQ_SPORT3_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT3_ERROR,
+               .end = IRQ_SPORT3_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport3_peripherals[] = {
+       P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS,
+       P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0
+};
+
+static struct platform_device bfin_sport3_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 3,
+       .num_resources = ARRAY_SIZE(bfin_sport3_uart_resources),
+       .resource = bfin_sport3_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport3_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#endif
+
 #if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE)
 static struct resource bfin_atapi_resources[] = {
        {
@@ -752,7 +1058,18 @@ static struct platform_device *cm_bf548_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+       &bfin_uart2_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART3
+       &bfin_uart3_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -782,6 +1099,21 @@ static struct platform_device *cm_bf548_devices[] __initdata = {
        &musb_device,
 #endif
 
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+       &bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+       &bfin_sport3_uart_device,
+#endif
+#endif
+
 #if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE)
        &bfin_atapi_device,
 #endif
@@ -833,3 +1165,42 @@ static int __init cm_bf548_init(void)
 }
 
 arch_initcall(cm_bf548_init);
+
+static struct platform_device *cm_bf548_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+       &bfin_uart2_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART3
+       &bfin_uart3_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+       &bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+       &bfin_sport3_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(cm_bf548_early_devices,
+               ARRAY_SIZE(cm_bf548_early_devices));
+}
index 60193f72777c5d07f7bec6f46f16bfd46ce98a0c..06919db00a7419df563e40a00ac65ca5220caa7c 100644 (file)
@@ -232,44 +232,211 @@ static struct platform_device rtc_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = UART0_DLL,
+               .end = UART0_RBR+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_RX,
+               .end = IRQ_UART0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART0_ERROR,
+               .end = IRQ_UART0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART0_TX,
+               .end = CH_UART0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART0_RX,
+               .end = CH_UART0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+       .name = "bfin-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
        {
-               .start = 0xFFC02000,
-               .end = 0xFFC020FF,
+               .start = UART1_DLL,
+               .end = UART1_RBR+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_RX,
+               .end = IRQ_UART1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART1_ERROR,
+               .end = IRQ_UART1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART1_TX,
+               .end = CH_UART1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART1_RX,
+               .end = CH_UART1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+       {       /* CTS pin -- 0 means not supported */
+               .start = GPIO_PE10,
+               .end = GPIO_PE10,
+               .flags = IORESOURCE_IO,
+       },
+       {       /* RTS pin -- 0 means not supported */
+               .start = GPIO_PE9,
+               .end = GPIO_PE9,
+               .flags = IORESOURCE_IO,
+       },
+#endif
+};
+
+unsigned short bfin_uart1_peripherals[] = {
+       P_UART1_TX, P_UART1_RX,
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+       P_UART1_RTS, P_UART1_CTS,
+#endif
+       0
+};
+
+static struct platform_device bfin_uart1_device = {
+       .name = "bfin-uart",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_uart1_resources),
+       .resource = bfin_uart1_resources,
+       .dev = {
+               .platform_data = &bfin_uart1_peripherals, /* Passed to driver */
+       },
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART2
+static struct resource bfin_uart2_resources[] = {
        {
-               .start = 0xFFC02100,
-               .end = 0xFFC021FF,
+               .start = UART2_DLL,
+               .end = UART2_RBR+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART2_RX,
+               .end = IRQ_UART2_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART2_ERROR,
+               .end = IRQ_UART2_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART2_TX,
+               .end = CH_UART2_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART2_RX,
+               .end = CH_UART2_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart2_peripherals[] = {
+       P_UART2_TX, P_UART2_RX, 0
+};
+
+static struct platform_device bfin_uart2_device = {
+       .name = "bfin-uart",
+       .id = 2,
+       .num_resources = ARRAY_SIZE(bfin_uart2_resources),
+       .resource = bfin_uart2_resources,
+       .dev = {
+               .platform_data = &bfin_uart2_peripherals, /* Passed to driver */
+       },
+};
 #endif
 #ifdef CONFIG_SERIAL_BFIN_UART3
+static struct resource bfin_uart3_resources[] = {
        {
-               .start = 0xFFC03100,
-               .end = 0xFFC031FF,
+               .start = UART3_DLL,
+               .end = UART3_RBR+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART3_RX,
+               .end = IRQ_UART3_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART3_ERROR,
+               .end = IRQ_UART3_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART3_TX,
+               .end = CH_UART3_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART3_RX,
+               .end = CH_UART3_RX,
+               .flags = IORESOURCE_DMA,
+       },
+#ifdef CONFIG_BFIN_UART3_CTSRTS
+       {       /* CTS pin -- 0 means not supported */
+               .start = GPIO_PB3,
+               .end = GPIO_PB3,
+               .flags = IORESOURCE_IO,
+       },
+       {       /* RTS pin -- 0 means not supported */
+               .start = GPIO_PB2,
+               .end = GPIO_PB2,
+               .flags = IORESOURCE_IO,
+       },
 #endif
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart3_peripherals[] = {
+       P_UART3_TX, P_UART3_RX,
+#ifdef CONFIG_BFIN_UART3_CTSRTS
+       P_UART3_RTS, P_UART3_CTS,
+#endif
+       0
+};
+
+static struct platform_device bfin_uart3_device = {
        .name = "bfin-uart",
-       .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .id = 3,
+       .num_resources = ARRAY_SIZE(bfin_uart3_resources),
+       .resource = bfin_uart3_resources,
+       .dev = {
+               .platform_data = &bfin_uart3_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -464,6 +631,145 @@ static struct platform_device musb_device = {
 };
 #endif
 
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+static struct resource bfin_sport0_uart_resources[] = {
+       {
+               .start = SPORT0_TCR1,
+               .end = SPORT0_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT0_RX,
+               .end = IRQ_SPORT0_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT0_ERROR,
+               .end = IRQ_SPORT0_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport0_peripherals[] = {
+       P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+       P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+
+static struct platform_device bfin_sport0_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources),
+       .resource = bfin_sport0_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+static struct resource bfin_sport1_uart_resources[] = {
+       {
+               .start = SPORT1_TCR1,
+               .end = SPORT1_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT1_RX,
+               .end = IRQ_SPORT1_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT1_ERROR,
+               .end = IRQ_SPORT1_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport1_peripherals[] = {
+       P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+       P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources),
+       .resource = bfin_sport1_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport1_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+static struct resource bfin_sport2_uart_resources[] = {
+       {
+               .start = SPORT2_TCR1,
+               .end = SPORT2_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT2_RX,
+               .end = IRQ_SPORT2_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT2_ERROR,
+               .end = IRQ_SPORT2_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport2_peripherals[] = {
+       P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS,
+       P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0
+};
+
+static struct platform_device bfin_sport2_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 2,
+       .num_resources = ARRAY_SIZE(bfin_sport2_uart_resources),
+       .resource = bfin_sport2_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport2_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+static struct resource bfin_sport3_uart_resources[] = {
+       {
+               .start = SPORT3_TCR1,
+               .end = SPORT3_MRCS3+4,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_SPORT3_RX,
+               .end = IRQ_SPORT3_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_SPORT3_ERROR,
+               .end = IRQ_SPORT3_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+unsigned short bfin_sport3_peripherals[] = {
+       P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS,
+       P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0
+};
+
+static struct platform_device bfin_sport3_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 3,
+       .num_resources = ARRAY_SIZE(bfin_sport3_uart_resources),
+       .resource = bfin_sport3_uart_resources,
+       .dev = {
+               .platform_data = &bfin_sport3_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#endif
+
 #if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
 unsigned short bfin_can_peripherals[] = {
        P_CAN0_RX, P_CAN0_TX, 0
@@ -657,8 +963,8 @@ static struct bfin5xx_spi_chip spi_flash_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-       || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+       || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 16,
@@ -714,8 +1020,8 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                .mode = SPI_MODE_3,
        },
 #endif
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-       || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+       || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
        {
                .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -951,6 +1257,30 @@ static struct platform_device bfin_dpmc = {
        },
 };
 
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+static struct platform_device bfin_i2s = {
+       .name = "bfin-i2s",
+       .id = CONFIG_SND_BF5XX_SPORT_NUM,
+       /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+static struct platform_device bfin_tdm = {
+       .name = "bfin-tdm",
+       .id = CONFIG_SND_BF5XX_SPORT_NUM,
+       /* TODO: add platform data here */
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+static struct platform_device bfin_ac97 = {
+       .name = "bfin-ac97",
+       .id = CONFIG_SND_BF5XX_SPORT_NUM,
+       /* TODO: add platform data here */
+};
+#endif
+
 static struct platform_device *ezkit_devices[] __initdata = {
 
        &bfin_dpmc,
@@ -960,7 +1290,18 @@ static struct platform_device *ezkit_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+       &bfin_uart2_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART3
+       &bfin_uart3_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -994,6 +1335,21 @@ static struct platform_device *ezkit_devices[] __initdata = {
        &bfin_isp1760_device,
 #endif
 
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+       &bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+       &bfin_sport3_uart_device,
+#endif
+#endif
+
 #if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE)
        &bfin_can_device,
 #endif
@@ -1037,6 +1393,18 @@ static struct platform_device *ezkit_devices[] __initdata = {
 #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
        &ezkit_flash_device,
 #endif
+
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+       &bfin_i2s,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+       &bfin_tdm,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+       &bfin_ac97,
+#endif
 };
 
 static int __init ezkit_init(void)
@@ -1058,3 +1426,42 @@ static int __init ezkit_init(void)
 }
 
 arch_initcall(ezkit_init);
+
+static struct platform_device *ezkit_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+       &bfin_uart1_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+       &bfin_uart2_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART3
+       &bfin_uart3_device,
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE)
+#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
+       &bfin_sport0_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
+       &bfin_sport1_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
+       &bfin_sport2_uart_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
+       &bfin_sport3_uart_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(ezkit_early_devices,
+               ARRAY_SIZE(ezkit_early_devices));
+}
index 106db05684aeaebcaa67afc497e4ddb75a9066fc..1f99b51a3d56b225c0673ca6d451da2b075e406b 100644 (file)
@@ -317,7 +317,8 @@ Events         (highest priority)  EMU         0
 
 #define GPIO_IRQ_BASE  IRQ_PA0
 
-#define NR_IRQS     (IRQ_PJ15+1)
+#define NR_MACH_IRQS   (IRQ_PJ15 + 1)
+#define NR_IRQS                (NR_MACH_IRQS + NR_SPARE_IRQS)
 
 /* For compatibility reasons with existing code */
 
index 59e18afe28c616b4d448b0e9ac441b79542138c5..b3402971831841af413cbcdd0fd5a9405e4986b2 100644 (file)
@@ -6,3 +6,4 @@ obj-y := ints-priority.o dma.o
 
 obj-$(CONFIG_BF561_COREB) += coreb.o
 obj-$(CONFIG_SMP)  += smp.o secondary.o atomic.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
index 07e8dc8770da10c2d0fbc7319a13f89485ea438b..5163e2c383c5201a2c59e5cab514660640d86bd6 100644 (file)
@@ -176,7 +176,7 @@ static struct resource smsc911x_resources[] = {
 };
 
 static struct smsc911x_platform_config smsc911x_config = {
-       .flags = SMSC911X_USE_32BIT,
+       .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
        .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
        .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
        .phy_interface = PHY_INTERFACE_MODE_MII,
index dfc8d5b7798612b7741cb33fc94fdc08ebbe053e..e127aedc1d7f0be56267dcfd2b934f25742ba408 100644 (file)
@@ -72,7 +72,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 16,
@@ -111,7 +111,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        },
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
        {
                .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -305,21 +305,50 @@ static struct platform_device isp1362_hcd_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = BFIN_UART_THR,
+               .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART_RX,
+               .end = IRQ_UART_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART_ERROR,
+               .end = IRQ_UART_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART_TX,
+               .end = CH_UART_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART_RX,
+               .end = CH_UART_RX,
+               .flags = IORESOURCE_DMA,
+       },
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
        .name = "bfin-uart",
-       .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -463,7 +492,9 @@ static struct platform_device *cm_bf561_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -516,3 +547,18 @@ static int __init cm_bf561_init(void)
 }
 
 arch_initcall(cm_bf561_init);
+
+static struct platform_device *cm_bf561_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(cm_bf561_early_devices,
+               ARRAY_SIZE(cm_bf561_early_devices));
+}
index ffd3e6a80d1a7e370f9ced5ceb777bdf0752e2f0..9b93e2f9579159316a10f9670aefe18c8888409f 100644 (file)
@@ -160,21 +160,50 @@ static struct platform_device smc91x_device = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
        {
-               .start = 0xFFC00400,
-               .end = 0xFFC004FF,
+               .start = BFIN_UART_THR,
+               .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART_RX,
+               .end = IRQ_UART_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART_ERROR,
+               .end = IRQ_UART_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART_TX,
+               .end = CH_UART_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART_RX,
+               .end = CH_UART_RX,
+               .flags = IORESOURCE_DMA,
+       },
 };
 
-static struct platform_device bfin_uart_device = {
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
        .name = "bfin-uart",
-       .id = 1,
-       .num_resources = ARRAY_SIZE(bfin_uart_resources),
-       .resource = bfin_uart_resources,
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
 };
 #endif
+#endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
@@ -245,8 +274,8 @@ static struct platform_device ezkit_flash_device = {
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-       || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+       || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
        .enable_dma = 0,
        .bits_per_word = 16,
@@ -299,8 +328,8 @@ static struct platform_device bfin_spi0_device = {
 #endif
 
 static struct spi_board_info bfin_spi_board_info[] __initdata = {
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-       || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD183X) \
+       || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE)
        {
                .modalias = "ad1836",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -412,7 +441,9 @@ static struct platform_device *ezkit_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-       &bfin_uart_device,
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
 #endif
 
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
@@ -458,3 +489,18 @@ static int __init ezkit_init(void)
 }
 
 arch_initcall(ezkit_init);
+
+static struct platform_device *ezkit_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(ezkit_early_devices,
+               ARRAY_SIZE(ezkit_early_devices));
+}
index 8ba7252455e13d8960a2acaf3b4839e3641256d3..d3017e53686bdbba56c7aac3d7000d5d119fc946 100644 (file)
@@ -42,6 +42,52 @@ static struct platform_device smc91x_device = {
        .resource      = smc91x_resources,
 };
 
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
+       {
+               .start = BFIN_UART_THR,
+               .end = BFIN_UART_GCTL+2,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_UART_RX,
+               .end = IRQ_UART_RX+1,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = IRQ_UART_ERROR,
+               .end = IRQ_UART_ERROR,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = CH_UART_TX,
+               .end = CH_UART_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       {
+               .start = CH_UART_RX,
+               .end = CH_UART_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+unsigned short bfin_uart0_peripherals[] = {
+       P_UART0_TX, P_UART0_RX, 0
+};
+
+static struct platform_device bfin_uart0_device = {
+       .name = "bfin-uart",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_uart0_resources),
+       .resource = bfin_uart0_resources,
+       .dev = {
+               .platform_data = &bfin_uart0_peripherals, /* Passed to driver */
+       },
+};
+#endif
+#endif
+
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
 static struct resource bfin_sir0_resources[] = {
@@ -73,6 +119,13 @@ static struct platform_device bfin_sir0_device = {
 
 static struct platform_device *tepla_devices[] __initdata = {
        &smc91x_device,
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#endif
+
 #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
 #ifdef CONFIG_BFIN_SIR0
        &bfin_sir0_device,
@@ -87,3 +140,18 @@ static int __init tepla_init(void)
 }
 
 arch_initcall(tepla_init);
+
+static struct platform_device *tepla_early_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+       &bfin_uart0_device,
+#endif
+#endif
+};
+
+void __init native_machine_early_platform_add_devices(void)
+{
+       printk(KERN_INFO "register early platform devices\n");
+       early_platform_add_devices(tepla_early_devices,
+               ARRAY_SIZE(tepla_early_devices));
+}
diff --git a/arch/blackfin/mach-bf561/hotplug.c b/arch/blackfin/mach-bf561/hotplug.c
new file mode 100644 (file)
index 0000000..c95169b
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2007-2009 Analog Devices Inc.
+ *               Graff Yang <graf.yang@analog.com>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <asm/blackfin.h>
+#include <asm/smp.h>
+#define SIC_SYSIRQ(irq)        (irq - (IRQ_CORETMR + 1))
+
+int hotplug_coreb;
+
+void platform_cpu_die(void)
+{
+       unsigned long iwr[2] = {0, 0};
+       unsigned long bank = SIC_SYSIRQ(IRQ_SUPPLE_0) / 32;
+       unsigned long bit = 1 << (SIC_SYSIRQ(IRQ_SUPPLE_0) % 32);
+
+       hotplug_coreb = 1;
+
+       iwr[bank] = bit;
+
+       /* disable core timer */
+       bfin_write_TCNTL(0);
+
+       /* clear ipi interrupt IRQ_SUPPLE_0 */
+       bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (10 + 1)));
+       SSYNC();
+
+       coreb_sleep(iwr[0], iwr[1], 0);
+}
index 7b208db267bfcc238cb69fc3fecd583c188e7b1c..c95566ade51b0b0cd6794a861cf71995c000364c 100644 (file)
 
 #define GPIO_IRQ_BASE          IRQ_PF0
 
-#define NR_IRQS                        (IRQ_PF47 + 1)
+#define NR_MACH_IRQS           (IRQ_PF47 + 1)
+#define NR_IRQS                        (NR_MACH_IRQS + NR_SPARE_IRQS)
 
 #define IVG7                   7
 #define IVG8                   8
index 390c7f4ae7b331c3b20689b044fe9b914f1f657a..2c8c514dd38649945d48890570c31699e3cf1b0f 100644 (file)
@@ -25,4 +25,6 @@ void platform_send_ipi_cpu(unsigned int cpu);
 
 void platform_clear_ipi(unsigned int cpu);
 
+void bfin_local_timer_setup(void);
+
 #endif /* !_MACH_BF561_SMP */
index 8e6050369c060b6d83e960492975e98ec0ca2be4..4624eebbf9c4c92b5e95220282b3f676dd6dbf76 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <asm/blackfin.h>
 #include <asm/asm-offsets.h>
+#include <asm/trace.h>
 
 __INIT
 
@@ -62,6 +63,8 @@ ENTRY(_coreb_trampoline_start)
        M2 = r0;
        M3 = r0;
 
+       trace_buffer_init(p0,r0);
+
        /* Turn off the icache */
        p0.l = LO(IMEM_CONTROL);
        p0.h = HI(IMEM_CONTROL);
@@ -159,6 +162,41 @@ ENTRY(_coreb_trampoline_start)
 ENDPROC(_coreb_trampoline_start)
 ENTRY(_coreb_trampoline_end)
 
+.section ".text"
+ENTRY(_set_sicb_iwr)
+       P0.H = hi(SICB_IWR0);
+       P0.L = lo(SICB_IWR0);
+       P1.H = hi(SICB_IWR1);
+       P1.L = lo(SICB_IWR1);
+       [P0] = R0;
+       [P1] = R1;
+       SSYNC;
+       RTS;
+ENDPROC(_set_sicb_iwr)
+
+ENTRY(_coreb_sleep)
+       sp.l = lo(INITIAL_STACK);
+       sp.h = hi(INITIAL_STACK);
+       fp = sp;
+       usp = sp;
+
+       call _set_sicb_iwr;
+
+       CLI R2;
+       SSYNC;
+       IDLE;
+       STI R2;
+
+       R0 = IWR_DISABLE_ALL;
+       R1 = IWR_DISABLE_ALL;
+       call _set_sicb_iwr;
+
+       p0.h = hi(COREB_L1_CODE_START);
+       p0.l = lo(COREB_L1_CODE_START);
+       jump (p0);
+ENDPROC(_coreb_sleep)
+
+__CPUINIT
 ENTRY(_coreb_start)
        [--sp] = reti;
 
@@ -176,12 +214,20 @@ ENTRY(_coreb_start)
        sp = [p0];
        usp = sp;
        fp = sp;
+#ifdef CONFIG_HOTPLUG_CPU
+       p0.l = _hotplug_coreb;
+       p0.h = _hotplug_coreb;
+       r0 = [p0];
+       cc = BITTST(r0, 0);
+       if cc jump 3f;
+#endif
        sp += -12;
        call _init_pda
        sp += 12;
+#ifdef CONFIG_HOTPLUG_CPU
+3:
+#endif
        call _secondary_start_kernel;
 .L_exit:
        jump.s  .L_exit;
 ENDPROC(_coreb_start)
-
-__FINIT
index 0192532e96a242fefe806ad168fc9bc311d35f2b..3b9a4bf7daccf96b1314ae45e53deff5b09ed76a 100644 (file)
 #include <linux/delay.h>
 #include <asm/smp.h>
 #include <asm/dma.h>
+#include <asm/time.h>
 
 static DEFINE_SPINLOCK(boot_lock);
 
-static cpumask_t cpu_callin_map;
-
 /*
  * platform_init_cpus() - Tell the world about how many cores we
  * have. This is called while setting up the architecture support
@@ -66,13 +65,15 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
        bfin_write_SICB_IAR5(bfin_read_SICA_IAR5());
        bfin_write_SICB_IAR6(bfin_read_SICA_IAR6());
        bfin_write_SICB_IAR7(bfin_read_SICA_IAR7());
+       bfin_write_SICB_IWR0(IWR_DISABLE_ALL);
+       bfin_write_SICB_IWR1(IWR_DISABLE_ALL);
        SSYNC();
 
        /* Store CPU-private information to the cpu_data array. */
        bfin_setup_cpudata(cpu);
 
        /* We are done with local CPU inits, unblock the boot CPU. */
-       cpu_set(cpu, cpu_callin_map);
+       set_cpu_online(cpu, true);
        spin_lock(&boot_lock);
        spin_unlock(&boot_lock);
 }
@@ -81,28 +82,28 @@ int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle
 {
        unsigned long timeout;
 
-       /* CoreB already running?! */
-       BUG_ON((bfin_read_SICA_SYSCR() & COREB_SRAM_INIT) == 0);
-
        printk(KERN_INFO "Booting Core B.\n");
 
        spin_lock(&boot_lock);
 
-       /* Kick CoreB, which should start execution from CORE_SRAM_BASE. */
-       SSYNC();
-       bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~COREB_SRAM_INIT);
-       SSYNC();
+       if ((bfin_read_SICA_SYSCR() & COREB_SRAM_INIT) == 0) {
+               /* CoreB already running, sending ipi to wakeup it */
+               platform_send_ipi_cpu(cpu, IRQ_SUPPLE_0);
+       } else {
+               /* Kick CoreB, which should start execution from CORE_SRAM_BASE. */
+               bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~COREB_SRAM_INIT);
+               SSYNC();
+       }
 
        timeout = jiffies + 1 * HZ;
        while (time_before(jiffies, timeout)) {
-               if (cpu_isset(cpu, cpu_callin_map))
+               if (cpu_online(cpu))
                        break;
                udelay(100);
                barrier();
        }
 
-       if (cpu_isset(cpu, cpu_callin_map)) {
-               cpu_set(cpu, cpu_online_map);
+       if (cpu_online(cpu)) {
                /* release the lock and let coreb run */
                spin_unlock(&boot_lock);
                return 0;
@@ -147,3 +148,20 @@ void platform_clear_ipi(unsigned int cpu)
        bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (10 + cpu)));
        SSYNC();
 }
+
+/*
+ * Setup core B's local core timer.
+ * In SMP, core timer is used for clock event device.
+ */
+void __cpuinit bfin_local_timer_setup(void)
+{
+#if defined(CONFIG_TICKSOURCE_CORETMR)
+       bfin_coretmr_init();
+       bfin_coretmr_clockevent_init();
+       get_irq_chip(IRQ_CORETMR)->unmask(IRQ_CORETMR);
+#else
+       /* Power down the core timer, just to play safe. */
+       bfin_write_TCNTL(0);
+#endif
+
+}
index 7775828972530af124b30fee5c3b6972fe4d1c07..4391d03dc8455056c6984f6931d3bee246856220 100644 (file)
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 #include <linux/fs.h>
+#include <linux/delay.h>
 #include <asm/blackfin.h>
 #include <asm/time.h>
 #include <asm/dpmc.h>
 
+#define CPUFREQ_CPU 0
+
 /* this is the table of CCLK frequencies, in Hz */
 /* .index is the entry in the auxillary dpm_state_table[] */
 static struct cpufreq_frequency_table bfin_freq_table[] = {
@@ -41,64 +44,124 @@ static struct bfin_dpm_state {
        unsigned int tscale; /* change the divider on the core timer interrupt */
 } dpm_state_table[3];
 
+#if defined(CONFIG_CYCLES_CLOCKSOURCE)
 /*
  normalized to maximum frequncy offset for CYCLES,
  used in time-ts cycles clock source, but could be used
  somewhere also.
* normalized to maximum frequncy offset for CYCLES,
* used in time-ts cycles clock source, but could be used
* somewhere also.
  */
 unsigned long long __bfin_cycles_off;
 unsigned int __bfin_cycles_mod;
+#endif
 
 /**************************************************************************/
+static void __init bfin_init_tables(unsigned long cclk, unsigned long sclk)
+{
 
-static unsigned int bfin_getfreq_khz(unsigned int cpu)
+       unsigned long csel, min_cclk;
+       int index;
+
+       /* Anomaly 273 seems to still exist on non-BF54x w/dcache turned on */
+#if ANOMALY_05000273 || ANOMALY_05000274 || \
+       (!defined(CONFIG_BF54x) && defined(CONFIG_BFIN_EXTMEM_DCACHEABLE))
+       min_cclk = sclk * 2;
+#else
+       min_cclk = sclk;
+#endif
+       csel = ((bfin_read_PLL_DIV() & CSEL) >> 4);
+
+       for (index = 0;  (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) {
+               bfin_freq_table[index].frequency = cclk >> index;
+               dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */
+               dpm_state_table[index].tscale =  (TIME_SCALE / (1 << csel)) - 1;
+
+               pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n",
+                                                bfin_freq_table[index].frequency,
+                                                dpm_state_table[index].csel,
+                                                dpm_state_table[index].tscale);
+       }
+       return;
+}
+
+static void bfin_adjust_core_timer(void *info)
 {
-       /* The driver only support single cpu */
-       if (cpu != 0)
-               return -1;
+       unsigned int tscale;
+       unsigned int index = *(unsigned int *)info;
 
-       return get_cclk() / 1000;
+       /* we have to adjust the core timer, because it is using cclk */
+       tscale = dpm_state_table[index].tscale;
+       bfin_write_TSCALE(tscale);
+       return;
 }
 
+static unsigned int bfin_getfreq_khz(unsigned int cpu)
+{
+       /* Both CoreA/B have the same core clock */
+       return get_cclk() / 1000;
+}
 
-static int bfin_target(struct cpufreq_policy *policy,
+static int bfin_target(struct cpufreq_policy *poli,
                        unsigned int target_freq, unsigned int relation)
 {
-       unsigned int index, plldiv, tscale;
+       unsigned int index, plldiv, cpu;
        unsigned long flags, cclk_hz;
        struct cpufreq_freqs freqs;
+       static unsigned long lpj_ref;
+       static unsigned int  lpj_ref_freq;
+
+#if defined(CONFIG_CYCLES_CLOCKSOURCE)
        cycles_t cycles;
+#endif
 
-       if (cpufreq_frequency_table_target(policy, bfin_freq_table,
-                target_freq, relation, &index))
-               return -EINVAL;
-
-       cclk_hz = bfin_freq_table[index].frequency;
-
-       freqs.old = bfin_getfreq_khz(0);
-       freqs.new = cclk_hz;
-       freqs.cpu = 0;
-
-       pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n",
-                cclk_hz, target_freq, freqs.old);
-
-       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-       local_irq_save_hw(flags);
-               plldiv = (bfin_read_PLL_DIV() & SSEL) | dpm_state_table[index].csel;
-               tscale = dpm_state_table[index].tscale;
-               bfin_write_PLL_DIV(plldiv);
-               /* we have to adjust the core timer, because it is using cclk */
-               bfin_write_TSCALE(tscale);
-               cycles = get_cycles();
-               SSYNC();
-       cycles += 10; /* ~10 cycles we lose after get_cycles() */
-       __bfin_cycles_off += (cycles << __bfin_cycles_mod) - (cycles << index);
-       __bfin_cycles_mod = index;
-       local_irq_restore_hw(flags);
-       /* TODO: just test case for cycles clock source, remove later */
-       pr_debug("cpufreq: done\n");
-       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+       for_each_online_cpu(cpu) {
+               struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+
+               if (!policy)
+                       continue;
+
+               if (cpufreq_frequency_table_target(policy, bfin_freq_table,
+                                target_freq, relation, &index))
+                       return -EINVAL;
+
+               cclk_hz = bfin_freq_table[index].frequency;
+
+               freqs.old = bfin_getfreq_khz(0);
+               freqs.new = cclk_hz;
+               freqs.cpu = cpu;
+
+               pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n",
+                        cclk_hz, target_freq, freqs.old);
+
+               cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+               if (cpu == CPUFREQ_CPU) {
+                       local_irq_save_hw(flags);
+                       plldiv = (bfin_read_PLL_DIV() & SSEL) |
+                                               dpm_state_table[index].csel;
+                       bfin_write_PLL_DIV(plldiv);
+                       on_each_cpu(bfin_adjust_core_timer, &index, 1);
+#if defined(CONFIG_CYCLES_CLOCKSOURCE)
+                       cycles = get_cycles();
+                       SSYNC();
+                       cycles += 10; /* ~10 cycles we lose after get_cycles() */
+                       __bfin_cycles_off +=
+                           (cycles << __bfin_cycles_mod) - (cycles << index);
+                       __bfin_cycles_mod = index;
+#endif
+                       if (!lpj_ref_freq) {
+                               lpj_ref = loops_per_jiffy;
+                               lpj_ref_freq = freqs.old;
+                       }
+                       if (freqs.new != freqs.old) {
+                               loops_per_jiffy = cpufreq_scale(lpj_ref,
+                                               lpj_ref_freq, freqs.new);
+                       }
+                       local_irq_restore_hw(flags);
+               }
+               /* TODO: just test case for cycles clock source, remove later */
+               cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+       }
 
+       pr_debug("cpufreq: done\n");
        return 0;
 }
 
@@ -110,37 +173,16 @@ static int bfin_verify_speed(struct cpufreq_policy *policy)
 static int __init __bfin_cpu_init(struct cpufreq_policy *policy)
 {
 
-       unsigned long cclk, sclk, csel, min_cclk;
-       int index;
-
-       if (policy->cpu != 0)
-               return -EINVAL;
+       unsigned long cclk, sclk;
 
        cclk = get_cclk() / 1000;
        sclk = get_sclk() / 1000;
 
-#if ANOMALY_05000273 || ANOMALY_05000274 || \
-       (!defined(CONFIG_BF54x) && defined(CONFIG_BFIN_EXTMEM_DCACHEABLE))
-       min_cclk = sclk * 2;
-#else
-       min_cclk = sclk;
-#endif
-       csel = ((bfin_read_PLL_DIV() & CSEL) >> 4);
-
-       for (index = 0;  (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) {
-               bfin_freq_table[index].frequency = cclk >> index;
-               dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */
-               dpm_state_table[index].tscale =  (TIME_SCALE / (1 << csel)) - 1;
-
-               pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n",
-                                                bfin_freq_table[index].frequency,
-                                                dpm_state_table[index].csel,
-                                                dpm_state_table[index].tscale);
-       }
+       if (policy->cpu == CPUFREQ_CPU)
+               bfin_init_tables(cclk, sclk);
 
        policy->cpuinfo.transition_latency = 50000; /* 50us assumed */
 
-       /*Now ,only support one cpu */
        policy->cur = cclk;
        cpufreq_frequency_table_get_attr(bfin_freq_table, policy->cpu);
        return cpufreq_frequency_table_cpuinfo(policy, bfin_freq_table);
index 01b2f58dfb95f9e83d8f5cbf8067fb68358e6c9f..a5847f5d67c7325ae6c53996f02f0b7d348267c3 100644 (file)
@@ -405,7 +405,7 @@ ENTRY(_double_fault)
 
        r0 = sp;        /* stack frame pt_regs pointer argument ==> r0 */
        SP += -12;
-       call _double_fault_c;
+       pseudo_long_call _double_fault_c, p5;
        SP += 12;
 .L_double_fault_panic:
         JUMP .L_double_fault_panic
@@ -447,7 +447,7 @@ ENTRY(_exception_to_level5)
 
        r0 = sp;        /* stack frame pt_regs pointer argument ==> r0 */
        SP += -12;
-       call _trap_c;
+       pseudo_long_call _trap_c, p4;
        SP += 12;
 
        /* If interrupts were off during the exception (IPEND[4] = 1), turn them off
@@ -482,6 +482,8 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
        [--sp] = ASTAT;
        [--sp] = (R7:6,P5:4);
 
+       ANOMALY_283_315_WORKAROUND(p5, r7)
+
 #ifdef CONFIG_EXACT_HWERR
        /* Make sure all pending read/writes complete. This will ensure any
         * accesses which could cause hardware errors completes, and signal
@@ -492,8 +494,6 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
        ssync;
 #endif
 
-       ANOMALY_283_315_WORKAROUND(p5, r7)
-
 #ifdef CONFIG_DEBUG_DOUBLEFAULT
        /*
         * Save these registers, as they are only valid in exception context
@@ -551,7 +551,7 @@ ENTRY(_kernel_execve)
        p0 = sp;
        sp += -16;
        [sp + 12] = p0;
-       call _do_execve;
+       pseudo_long_call _do_execve, p5;
        SP += 16;
        cc = r0 == 0;
        if ! cc jump .Lexecve_failed;
@@ -626,13 +626,6 @@ ENTRY(_system_call)
        p0 = [sp + PT_ORIG_P0];
 #endif /* CONFIG_IPIPE */
 
-       /* Check the System Call */
-       r7 = __NR_syscall;
-       /* System call number is passed in P0 */
-       r6 = p0;
-       cc = r6 < r7;
-       if ! cc jump .Lbadsys;
-
        /* are we tracing syscalls?*/
        r7 = sp;
        r6.l = lo(ALIGN_PAGE_MASK);
@@ -642,6 +635,14 @@ ENTRY(_system_call)
        r7 = [p2+TI_FLAGS];
        CC = BITTST(r7,TIF_SYSCALL_TRACE);
        if CC JUMP _sys_trace;
+       CC = BITTST(r7,TIF_SINGLESTEP);
+       if CC JUMP _sys_trace;
+
+       /* Make sure the system call # is valid */
+       p4 = __NR_syscall;
+       /* System call number is passed in P0 */
+       cc = p4 <= p0;
+       if cc jump .Lbadsys;
 
        /* Execute the appropriate system call */
 
@@ -704,7 +705,7 @@ ENTRY(_system_call)
        sp += 4;
 
        SP += -12;
-       call _schedule;
+       pseudo_long_call _schedule, p4;
        SP += 12;
 
        jump .Lresume_userspace_1;
@@ -723,7 +724,7 @@ ENTRY(_system_call)
 
        r0 = sp;
        SP += -12;
-       call _do_notify_resume;
+       pseudo_long_call _do_notify_resume, p5;
        SP += 12;
 
 .Lsyscall_really_exit:
@@ -736,11 +737,17 @@ ENDPROC(_system_call)
  * this symbol need not be global anyways, so ...
  */
 _sys_trace:
-       call _syscall_trace;
-
-       /* Execute the appropriate system call */
+       r0 = sp;
+       pseudo_long_call _syscall_trace_enter, p5;
 
+       /* Make sure the system call # is valid */
        p4 = [SP + PT_P0];
+       p3 = __NR_syscall;
+       cc = p3 <= p4;
+       r0 = -ENOSYS;
+       if cc jump .Lsys_trace_badsys;
+
+       /* Execute the appropriate system call */
        p5.l = _sys_call_table;
        p5.h = _sys_call_table;
        p5 = p5 + (p4 << 2);
@@ -758,9 +765,11 @@ _sys_trace:
        SP += -12;
        call (p5);
        SP += 24;
+.Lsys_trace_badsys:
        [sp + PT_R0] = r0;
 
-       call _syscall_trace;
+       r0 = sp;
+       pseudo_long_call _syscall_trace_leave, p5;
        jump .Lresume_userspace;
 ENDPROC(_sys_trace)
 
@@ -965,6 +974,13 @@ ENTRY(_evt_evt14)
        sti r0;
 #else
        cli r0;
+#endif
+#ifdef CONFIG_TRACE_IRQFLAGS
+       [--sp] = rets;
+       sp += -12;
+       call _trace_hardirqs_off;
+       sp += 12;
+       rets = [sp++];
 #endif
        [--sp] = RETI;
        SP += 4;
@@ -989,6 +1005,14 @@ ENTRY(_schedule_and_signal_from_int)
        p1 = rets;
        [sp + PT_RESERVED] = p1;
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+       /* trace_hardirqs_on() checks if all irqs are disabled. But here IRQ 15
+        * is turned on, so disable all irqs. */
+       cli r0;
+       sp += -12;
+       call _trace_hardirqs_on;
+       sp += 12;
+#endif
 #ifdef CONFIG_SMP
        GET_PDA(p0, r0);        /* Fetch current PDA (can't migrate to other CPU here) */
        r0 = [p0 + PDA_IRQFLAGS];
@@ -1007,7 +1031,8 @@ ENTRY(_schedule_and_signal_from_int)
 
        r0 = sp;
        sp += -12;
-       call _finish_atomic_sections;
+
+       pseudo_long_call _finish_atomic_sections, p5;
        sp += 12;
        jump.s .Lresume_userspace;
 ENDPROC(_schedule_and_signal_from_int)
@@ -1357,7 +1382,7 @@ ENTRY(_sys_call_table)
        .long _sys_newuname
        .long _sys_ni_syscall   /* old sys_modify_ldt */
        .long _sys_adjtimex
-       .long _sys_ni_syscall   /* 125 */ /* sys_mprotect */
+       .long _sys_mprotect     /* 125 */
        .long _sys_ni_syscall   /* old sys_sigprocmask */
        .long _sys_ni_syscall   /* old "creat_module" */
        .long _sys_init_module
@@ -1376,16 +1401,16 @@ ENTRY(_sys_call_table)
        .long _sys_getdents
        .long _sys_ni_syscall   /* sys_select */
        .long _sys_flock
-       .long _sys_ni_syscall   /* sys_msync */
+       .long _sys_msync
        .long _sys_readv                /* 145 */
        .long _sys_writev
        .long _sys_getsid
        .long _sys_fdatasync
        .long _sys_sysctl
-       .long _sys_ni_syscall   /* 150 */ /* sys_mlock */
-       .long _sys_ni_syscall   /* sys_munlock */
-       .long _sys_ni_syscall   /* sys_mlockall */
-       .long _sys_ni_syscall   /* sys_munlockall */
+       .long _sys_mlock        /* 150 */
+       .long _sys_munlock
+       .long _sys_mlockall
+       .long _sys_munlockall
        .long _sys_sched_setparam
        .long _sys_sched_getparam /* 155 */
        .long _sys_sched_setscheduler
@@ -1450,8 +1475,8 @@ ENTRY(_sys_call_table)
        .long _sys_setfsuid     /* 215 */
        .long _sys_setfsgid
        .long _sys_pivot_root
-       .long _sys_ni_syscall   /* sys_mincore */
-       .long _sys_ni_syscall   /* sys_madvise */
+       .long _sys_mincore
+       .long _sys_madvise
        .long _sys_getdents64   /* 220 */
        .long _sys_fcntl64
        .long _sys_ni_syscall   /* reserved for TUX */
@@ -1507,7 +1532,7 @@ ENTRY(_sys_call_table)
        .long _sys_utimes
        .long _sys_fadvise64_64
        .long _sys_ni_syscall /* vserver */
-       .long _sys_ni_syscall /* 275, mbind */
+       .long _sys_mbind        /* 275 */
        .long _sys_ni_syscall /* get_mempolicy */
        .long _sys_ni_syscall /* set_mempolicy */
        .long _sys_mq_open
index cab0a0031eee9b0ed13fc682c0186d13c578d622..4391621d90488a1fcb7f89f72efca8bf707ecc6a 100644 (file)
@@ -144,8 +144,8 @@ ENTRY(__start)
 #endif
 
        /* Initialize stack pointer */
-       sp.l = _init_thread_union;
-       sp.h = _init_thread_union;
+       sp.l = _init_thread_union + THREAD_SIZE;
+       sp.h = _init_thread_union + THREAD_SIZE;
        fp = sp;
        usp = sp;
 
@@ -186,6 +186,11 @@ ENTRY(__start)
 
        /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
        call _bfin_relocate_l1_mem;
+
+#ifdef CONFIG_ROMKERNEL
+       call _bfin_relocate_xip_data;
+#endif
+
 #ifdef CONFIG_BFIN_KERNEL_CLOCK
        /* Only use on-chip scratch space for stack when absolutely required
         * to avoid Anomaly 05000227 ... we know the init_clocks() func only
@@ -257,12 +262,7 @@ ENTRY(_real_start)
        R0 = R7;
        call _cmdline_init;
 
-       /* Load the current thread pointer and stack */
-       p1 = THREAD_SIZE + 4 (z);       /* +4 is for reti loading */
-       sp = sp + p1;
-       usp = sp;
-       fp = sp;
-       sp += -12;
+       sp += -12 + 4; /* +4 is for reti loading above */
        call _init_pda
        sp += 12;
        jump.l _start_kernel;
index 8085ff1cce004828ff83a5bc2a68aec0afa59636..cee62cf4acd429d07b4d84991c6e088f795a1eb4 100644 (file)
@@ -87,6 +87,13 @@ __common_int_entry:
        sti r1;
 #else
        cli r1;
+#endif
+#ifdef CONFIG_TRACE_IRQFLAGS
+       [--sp] = r0;
+       sp += -12;
+       call _trace_hardirqs_off;
+       sp += 12;
+       r0 = [sp++];
 #endif
        [--sp] = RETI;  /* orig_pc */
        /* Clear all L registers.  */
@@ -109,10 +116,10 @@ __common_int_entry:
        cc = r0 == 0;
        if cc jump .Lcommon_restore_context;
 #else /* CONFIG_IPIPE */
-       call _do_irq;
+       pseudo_long_call _do_irq, p2;
        SP += 12;
 #endif /* CONFIG_IPIPE */
-       call _return_from_int;
+       pseudo_long_call _return_from_int, p2;
 .Lcommon_restore_context:
        RESTORE_CONTEXT
        rti;
@@ -168,7 +175,7 @@ ENTRY(_evt_ivhw)
 
        r0 = sp;        /* stack frame pt_regs pointer argument ==> r0 */
        SP += -12;
-       call _trap_c;
+       pseudo_long_call _trap_c, p5;
        SP += 12;
 
 #ifdef EBIU_ERRMST
@@ -179,7 +186,7 @@ ENTRY(_evt_ivhw)
        w[p0] = r0.l;
 #endif
 
-       call _ret_from_exception;
+       pseudo_long_call _ret_from_exception, p2;
 
 .Lcommon_restore_all_sys:
        RESTORE_ALL_SYS
@@ -187,12 +194,28 @@ ENTRY(_evt_ivhw)
 ENDPROC(_evt_ivhw)
 
 /* Interrupt routine for evt2 (NMI).
- * We don't actually use this, so just return.
  * For inner circle type details, please see:
  * http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:nmi
  */
 ENTRY(_evt_nmi)
+#ifndef CONFIG_NMI_WATCHDOG
 .weak _evt_nmi
+#else
+       /* Not take account of CPLBs, this handler will not return */
+       SAVE_ALL_SYS
+       r0 = sp;
+       r1 = retn;
+       [sp + PT_PC] = r1;
+       trace_buffer_save(p4,r5);
+
+       ANOMALY_283_315_WORKAROUND(p4, r5)
+
+       SP += -12;
+       call _do_nmi;
+       SP += 12;
+1:
+       jump 1b;
+#endif
        rtn;
 ENDPROC(_evt_nmi)
 
@@ -223,7 +246,7 @@ ENTRY(_evt_system_call)
 #ifdef CONFIG_FRAME_POINTER
        fp = 0;
 #endif
-       call _system_call;
+       pseudo_long_call _system_call, p2;
        jump .Lcommon_restore_context;
 ENDPROC(_evt_system_call)
 
index 1873b2c1fede8b2d267d639dbe9c111e05091b10..7ad8878bfa1815110a53220a1d96ab2c53df0476 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/dpmc.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/bfin_sport.h>
+#include <asm/bfin_can.h>
 
 #define SIC_SYSIRQ(irq)        (irq - (IRQ_CORETMR + 1))
 
@@ -172,7 +173,12 @@ static void bfin_internal_mask_irq(unsigned int irq)
        local_irq_restore_hw(flags);
 }
 
+#ifdef CONFIG_SMP
+static void bfin_internal_unmask_irq_affinity(unsigned int irq,
+               const struct cpumask *affinity)
+#else
 static void bfin_internal_unmask_irq(unsigned int irq)
+#endif
 {
        unsigned long flags;
 
@@ -185,16 +191,38 @@ static void bfin_internal_unmask_irq(unsigned int irq)
        local_irq_save_hw(flags);
        mask_bank = SIC_SYSIRQ(irq) / 32;
        mask_bit = SIC_SYSIRQ(irq) % 32;
-       bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) |
-                            (1 << mask_bit));
 #ifdef CONFIG_SMP
-       bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) |
-                            (1 << mask_bit));
+       if (cpumask_test_cpu(0, affinity))
+#endif
+               bfin_write_SIC_IMASK(mask_bank,
+                       bfin_read_SIC_IMASK(mask_bank) |
+                       (1 << mask_bit));
+#ifdef CONFIG_SMP
+       if (cpumask_test_cpu(1, affinity))
+               bfin_write_SICB_IMASK(mask_bank,
+                       bfin_read_SICB_IMASK(mask_bank) |
+                       (1 << mask_bit));
 #endif
 #endif
        local_irq_restore_hw(flags);
 }
 
+#ifdef CONFIG_SMP
+static void bfin_internal_unmask_irq(unsigned int irq)
+{
+       struct irq_desc *desc = irq_to_desc(irq);
+       bfin_internal_unmask_irq_affinity(irq, desc->affinity);
+}
+
+static int bfin_internal_set_affinity(unsigned int irq, const struct cpumask *mask)
+{
+       bfin_internal_mask_irq(irq);
+       bfin_internal_unmask_irq_affinity(irq, mask);
+
+       return 0;
+}
+#endif
+
 #ifdef CONFIG_PM
 int bfin_internal_set_wake(unsigned int irq, unsigned int state)
 {
@@ -224,11 +252,6 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state)
        wakeup |= USBWE;
        break;
 #endif
-#ifdef IRQ_KEY
-       case IRQ_KEY:
-       wakeup |= KPADWE;
-       break;
-#endif
 #ifdef CONFIG_BF54x
        case IRQ_CNT:
        wakeup |= ROTWE;
@@ -270,6 +293,9 @@ static struct irq_chip bfin_internal_irqchip = {
        .mask_ack = bfin_internal_mask_irq,
        .disable = bfin_internal_mask_irq,
        .enable = bfin_internal_unmask_irq,
+#ifdef CONFIG_SMP
+       .set_affinity = bfin_internal_set_affinity,
+#endif
 #ifdef CONFIG_PM
        .set_wake = bfin_internal_set_wake,
 #endif
@@ -294,7 +320,6 @@ static int error_int_mask;
 static void bfin_generic_error_mask_irq(unsigned int irq)
 {
        error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR));
-
        if (!error_int_mask)
                bfin_internal_mask_irq(IRQ_GENERIC_ERROR);
 }
@@ -385,6 +410,127 @@ static void bfin_demux_error_irq(unsigned int int_err_irq,
 }
 #endif                         /* BF537_GENERIC_ERROR_INT_DEMUX */
 
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static int mac_stat_int_mask;
+
+static void bfin_mac_status_ack_irq(unsigned int irq)
+{
+       switch (irq) {
+       case IRQ_MAC_MMCINT:
+               bfin_write_EMAC_MMC_TIRQS(
+                       bfin_read_EMAC_MMC_TIRQE() &
+                       bfin_read_EMAC_MMC_TIRQS());
+               bfin_write_EMAC_MMC_RIRQS(
+                       bfin_read_EMAC_MMC_RIRQE() &
+                       bfin_read_EMAC_MMC_RIRQS());
+               break;
+       case IRQ_MAC_RXFSINT:
+               bfin_write_EMAC_RX_STKY(
+                       bfin_read_EMAC_RX_IRQE() &
+                       bfin_read_EMAC_RX_STKY());
+               break;
+       case IRQ_MAC_TXFSINT:
+               bfin_write_EMAC_TX_STKY(
+                       bfin_read_EMAC_TX_IRQE() &
+                       bfin_read_EMAC_TX_STKY());
+               break;
+       case IRQ_MAC_WAKEDET:
+                bfin_write_EMAC_WKUP_CTL(
+                       bfin_read_EMAC_WKUP_CTL() | MPKS | RWKS);
+               break;
+       default:
+               /* These bits are W1C */
+               bfin_write_EMAC_SYSTAT(1L << (irq - IRQ_MAC_PHYINT));
+               break;
+       }
+}
+
+static void bfin_mac_status_mask_irq(unsigned int irq)
+{
+       mac_stat_int_mask &= ~(1L << (irq - IRQ_MAC_PHYINT));
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+       switch (irq) {
+       case IRQ_MAC_PHYINT:
+               bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() & ~PHYIE);
+               break;
+       default:
+               break;
+       }
+#else
+       if (!mac_stat_int_mask)
+               bfin_internal_mask_irq(IRQ_MAC_ERROR);
+#endif
+       bfin_mac_status_ack_irq(irq);
+}
+
+static void bfin_mac_status_unmask_irq(unsigned int irq)
+{
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+       switch (irq) {
+       case IRQ_MAC_PHYINT:
+               bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() | PHYIE);
+               break;
+       default:
+               break;
+       }
+#else
+       if (!mac_stat_int_mask)
+               bfin_internal_unmask_irq(IRQ_MAC_ERROR);
+#endif
+       mac_stat_int_mask |= 1L << (irq - IRQ_MAC_PHYINT);
+}
+
+#ifdef CONFIG_PM
+int bfin_mac_status_set_wake(unsigned int irq, unsigned int state)
+{
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+       return bfin_internal_set_wake(IRQ_GENERIC_ERROR, state);
+#else
+       return bfin_internal_set_wake(IRQ_MAC_ERROR, state);
+#endif
+}
+#endif
+
+static struct irq_chip bfin_mac_status_irqchip = {
+       .name = "MACST",
+       .ack = bfin_ack_noop,
+       .mask_ack = bfin_mac_status_mask_irq,
+       .mask = bfin_mac_status_mask_irq,
+       .unmask = bfin_mac_status_unmask_irq,
+#ifdef CONFIG_PM
+       .set_wake = bfin_mac_status_set_wake,
+#endif
+};
+
+static void bfin_demux_mac_status_irq(unsigned int int_err_irq,
+                                struct irq_desc *inta_desc)
+{
+       int i, irq = 0;
+       u32 status = bfin_read_EMAC_SYSTAT();
+
+       for (i = 0; i < (IRQ_MAC_STMDONE - IRQ_MAC_PHYINT); i++)
+               if (status & (1L << i)) {
+                       irq = IRQ_MAC_PHYINT + i;
+                       break;
+               }
+
+       if (irq) {
+               if (mac_stat_int_mask & (1L << (irq - IRQ_MAC_PHYINT))) {
+                       bfin_handle_irq(irq);
+               } else {
+                       bfin_mac_status_ack_irq(irq);
+                       pr_debug("IRQ %d:"
+                                " MASKED MAC ERROR INTERRUPT ASSERTED\n",
+                                irq);
+               }
+       } else
+               printk(KERN_ERR
+                      "%s : %s : LINE %d :\nIRQ ?: MAC ERROR"
+                      " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n",
+                      __func__, __FILE__, __LINE__);
+}
+#endif
+
 static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle)
 {
 #ifdef CONFIG_IPIPE
@@ -1031,7 +1177,6 @@ int __init init_arch_irq(void)
 #elif defined(CONFIG_BF538) || defined(CONFIG_BF539)
                case IRQ_PORTF_INTA:
 #endif
-
                        set_irq_chained_handler(irq,
                                                bfin_demux_gpio_irq);
                        break;
@@ -1040,29 +1185,36 @@ int __init init_arch_irq(void)
                        set_irq_chained_handler(irq, bfin_demux_error_irq);
                        break;
 #endif
-
-#ifdef CONFIG_SMP
-#ifdef CONFIG_TICKSOURCE_GPTMR0
-               case IRQ_TIMER0:
-#endif
-#ifdef CONFIG_TICKSOURCE_CORETMR
-               case IRQ_CORETMR:
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+               case IRQ_MAC_ERROR:
+                       set_irq_chained_handler(irq, bfin_demux_mac_status_irq);
+                       break;
 #endif
+#ifdef CONFIG_SMP
                case IRQ_SUPPLE_0:
                case IRQ_SUPPLE_1:
                        set_irq_handler(irq, handle_percpu_irq);
                        break;
 #endif
 
-#ifdef CONFIG_IPIPE
-#ifndef CONFIG_TICKSOURCE_CORETMR
-               case IRQ_TIMER0:
+#ifdef CONFIG_TICKSOURCE_CORETMR
+               case IRQ_CORETMR:
+# ifdef CONFIG_SMP
+                       set_irq_handler(irq, handle_percpu_irq);
+                       break;
+# else
                        set_irq_handler(irq, handle_simple_irq);
                        break;
+# endif
 #endif
-               case IRQ_CORETMR:
+
+#ifdef CONFIG_TICKSOURCE_GPTMR0
+               case IRQ_TIMER0:
                        set_irq_handler(irq, handle_simple_irq);
                        break;
+#endif
+
+#ifdef CONFIG_IPIPE
                default:
                        set_irq_handler(irq, handle_level_irq);
                        break;
@@ -1078,14 +1230,22 @@ int __init init_arch_irq(void)
        for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++)
                set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip,
                                         handle_level_irq);
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+       set_irq_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq);
+#endif
 #endif
 
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+       for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++)
+               set_irq_chip_and_handler(irq, &bfin_mac_status_irqchip,
+                                        handle_level_irq);
+#endif
        /* if configured as edge, then will be changed to do_edge_IRQ */
-       for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; irq++)
+       for (irq = GPIO_IRQ_BASE;
+               irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++)
                set_irq_chip_and_handler(irq, &bfin_gpio_irqchip,
                                         handle_level_irq);
 
-
        bfin_write_IMASK(0);
        CSYNC();
        ilat = bfin_read_ILAT();
index 8837be4edb4a47ebb90501129d2aa69fc725486e..c1f1ccc846f067ade4556eb3c2e98db523a27a50 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/suspend.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 
index 369e687582b7da4a86a3fab7a537a6740839ad1f..7cecbaf0358ab03e0a42e5492475d7a241f31fd3 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/smp.h>
 #include <linux/seq_file.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
 #include <asm/mmu_context.h>
@@ -122,9 +123,17 @@ static void ipi_call_function(unsigned int cpu, struct ipi_message *msg)
        wait = msg->call_struct.wait;
        cpu_clear(cpu, msg->call_struct.pending);
        func(info);
-       if (wait)
+       if (wait) {
+#ifdef __ARCH_SYNC_CORE_DCACHE
+               /*
+                * 'wait' usually means synchronization between CPUs.
+                * Invalidate D cache in case shared data was changed
+                * by func() to ensure cache coherence.
+                */
+               resync_core_dcache();
+#endif
                cpu_clear(cpu, msg->call_struct.waitmask);
-       else
+       else
                kfree(msg);
 }
 
@@ -219,6 +228,13 @@ int smp_call_function(void (*func)(void *info), void *info, int wait)
                        blackfin_dcache_invalidate_range(
                                (unsigned long)(&msg->call_struct.waitmask),
                                (unsigned long)(&msg->call_struct.waitmask));
+#ifdef __ARCH_SYNC_CORE_DCACHE
+               /*
+                * Invalidate D cache in case shared data was changed by
+                * other processors to ensure cache coherence.
+                */
+               resync_core_dcache();
+#endif
                kfree(msg);
        }
        return 0;
@@ -261,6 +277,13 @@ int smp_call_function_single(int cpuid, void (*func) (void *info), void *info,
                        blackfin_dcache_invalidate_range(
                                (unsigned long)(&msg->call_struct.waitmask),
                                (unsigned long)(&msg->call_struct.waitmask));
+#ifdef __ARCH_SYNC_CORE_DCACHE
+               /*
+                * Invalidate D cache in case shared data was changed by
+                * other processors to ensure cache coherence.
+                */
+               resync_core_dcache();
+#endif
                kfree(msg);
        }
        return 0;
@@ -322,8 +345,11 @@ void smp_send_stop(void)
 
 int __cpuinit __cpu_up(unsigned int cpu)
 {
-       struct task_struct *idle;
        int ret;
+       static struct task_struct *idle;
+
+       if (idle)
+               free_task(idle);
 
        idle = fork_idle(cpu);
        if (IS_ERR(idle)) {
@@ -332,7 +358,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
        }
 
        secondary_stack = task_stack_page(idle) + THREAD_SIZE;
-       smp_wmb();
 
        ret = platform_boot_secondary(cpu, idle);
 
@@ -343,9 +368,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
 
 static void __cpuinit setup_secondary(unsigned int cpu)
 {
-#if !defined(CONFIG_TICKSOURCE_GPTMR0)
-       struct irq_desc *timer_desc;
-#endif
        unsigned long ilat;
 
        bfin_write_IMASK(0);
@@ -360,17 +382,6 @@ static void __cpuinit setup_secondary(unsigned int cpu)
        bfin_irq_flags |= IMASK_IVG15 |
            IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
            IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
-
-#if defined(CONFIG_TICKSOURCE_GPTMR0)
-       /* Power down the core timer, just to play safe. */
-       bfin_write_TCNTL(0);
-
-       /* system timer0 has been setup by CoreA. */
-#else
-       timer_desc = irq_desc + IRQ_CORETMR;
-       setup_core_timer();
-       timer_desc->chip->enable(IRQ_CORETMR);
-#endif
 }
 
 void __cpuinit secondary_start_kernel(void)
@@ -405,7 +416,6 @@ void __cpuinit secondary_start_kernel(void)
        atomic_inc(&mm->mm_users);
        atomic_inc(&mm->mm_count);
        current->active_mm = mm;
-       BUG_ON(current->mm);    /* Can't be, but better be safe than sorry. */
 
        preempt_disable();
 
@@ -413,6 +423,9 @@ void __cpuinit secondary_start_kernel(void)
 
        platform_secondary_init(cpu);
 
+       /* setup local core timer */
+       bfin_local_timer_setup();
+
        local_irq_enable();
 
        /*
@@ -462,25 +475,58 @@ void smp_icache_flush_range_others(unsigned long start, unsigned long end)
 EXPORT_SYMBOL_GPL(smp_icache_flush_range_others);
 
 #ifdef __ARCH_SYNC_CORE_ICACHE
+unsigned long icache_invld_count[NR_CPUS];
 void resync_core_icache(void)
 {
        unsigned int cpu = get_cpu();
        blackfin_invalidate_entire_icache();
-       ++per_cpu(cpu_data, cpu).icache_invld_count;
+       icache_invld_count[cpu]++;
        put_cpu();
 }
 EXPORT_SYMBOL(resync_core_icache);
 #endif
 
 #ifdef __ARCH_SYNC_CORE_DCACHE
+unsigned long dcache_invld_count[NR_CPUS];
 unsigned long barrier_mask __attribute__ ((__section__(".l2.bss")));
 
 void resync_core_dcache(void)
 {
        unsigned int cpu = get_cpu();
        blackfin_invalidate_entire_dcache();
-       ++per_cpu(cpu_data, cpu).dcache_invld_count;
+       dcache_invld_count[cpu]++;
        put_cpu();
 }
 EXPORT_SYMBOL(resync_core_dcache);
 #endif
+
+#ifdef CONFIG_HOTPLUG_CPU
+int __cpuexit __cpu_disable(void)
+{
+       unsigned int cpu = smp_processor_id();
+
+       if (cpu == 0)
+               return -EPERM;
+
+       set_cpu_online(cpu, false);
+       return 0;
+}
+
+static DECLARE_COMPLETION(cpu_killed);
+
+int __cpuexit __cpu_die(unsigned int cpu)
+{
+       return wait_for_completion_timeout(&cpu_killed, 5000);
+}
+
+void cpu_die(void)
+{
+       complete(&cpu_killed);
+
+       atomic_dec(&init_mm.mm_users);
+       atomic_dec(&init_mm.mm_count);
+
+       local_irq_disable();
+       platform_cpu_die();
+}
+#endif
index bb9c98f9cb5b5845bf2caf87589902375a01289d..355b87aa6b9322da7c1e5074e0eb5170fe6d5de3 100644 (file)
@@ -4,6 +4,7 @@
  * Licensed under the GPL-2 or later.
  */
 
+#include <linux/gfp.h>
 #include <linux/swap.h>
 #include <linux/bootmem.h>
 #include <linux/uaccess.h>
index 84cdc5a1c139bddc5f81c7e2ac17a8af112ed45d..39b058564f62400db2b00af74127d13cd0d83fd4 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/sched.h>
 
@@ -62,7 +63,7 @@ static void isram_write(const void *addr, uint64_t data)
        uint32_t cmd;
        unsigned long flags;
 
-       if (addr >= (void *)(L1_CODE_START + L1_CODE_LENGTH))
+       if (unlikely(addr >= (void *)(L1_CODE_START + L1_CODE_LENGTH)))
                return;
 
        cmd = IADDR2DTEST(addr) | 2;             /* write */
@@ -93,7 +94,7 @@ static uint64_t isram_read(const void *addr)
        unsigned long flags;
        uint64_t ret;
 
-       if (addr > (void *)(L1_CODE_START + L1_CODE_LENGTH))
+       if (unlikely(addr > (void *)(L1_CODE_START + L1_CODE_LENGTH)))
                return 0;
 
        cmd = IADDR2DTEST(addr) | 0;              /* read */
@@ -120,7 +121,7 @@ static bool isram_check_addr(const void *addr, size_t n)
 {
        if ((addr >= (void *)L1_CODE_START) &&
            (addr < (void *)(L1_CODE_START + L1_CODE_LENGTH))) {
-               if ((addr + n) > (void *)(L1_CODE_START + L1_CODE_LENGTH)) {
+               if (unlikely((addr + n) > (void *)(L1_CODE_START + L1_CODE_LENGTH))) {
                        show_stack(NULL, NULL);
                        pr_err("copy involving %p length (%zu) too long\n", addr, n);
                }
index f068c11ea98f5ca6c53568b4e7cf2dfc3a363a1f..49b2ff2c8b74bee191df47682bcbae227b5beac6 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 #include <asm/blackfin.h>
 #include <asm/mem_map.h>
 #include "blackfin_sram.h"
@@ -402,7 +403,7 @@ void *l1_data_A_sram_alloc(size_t size)
        void *addr;
        unsigned int cpu;
 
-       cpu = get_cpu();
+       cpu = smp_processor_id();
        /* add mutex operation */
        spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
 
@@ -411,7 +412,6 @@ void *l1_data_A_sram_alloc(size_t size)
 
        /* add mutex operation */
        spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
-       put_cpu();
 
        pr_debug("Allocated address in l1_data_A_sram_alloc is 0x%lx+0x%lx\n",
                 (long unsigned int)addr, size);
@@ -430,7 +430,7 @@ int l1_data_A_sram_free(const void *addr)
        int ret;
        unsigned int cpu;
 
-       cpu = get_cpu();
+       cpu = smp_processor_id();
        /* add mutex operation */
        spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
 
@@ -439,7 +439,6 @@ int l1_data_A_sram_free(const void *addr)
 
        /* add mutex operation */
        spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
-       put_cpu();
 
        return ret;
 #else
@@ -455,7 +454,7 @@ void *l1_data_B_sram_alloc(size_t size)
        void *addr;
        unsigned int cpu;
 
-       cpu = get_cpu();
+       cpu = smp_processor_id();
        /* add mutex operation */
        spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
 
@@ -464,7 +463,6 @@ void *l1_data_B_sram_alloc(size_t size)
 
        /* add mutex operation */
        spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
-       put_cpu();
 
        pr_debug("Allocated address in l1_data_B_sram_alloc is 0x%lx+0x%lx\n",
                 (long unsigned int)addr, size);
@@ -483,7 +481,7 @@ int l1_data_B_sram_free(const void *addr)
        int ret;
        unsigned int cpu;
 
-       cpu = get_cpu();
+       cpu = smp_processor_id();
        /* add mutex operation */
        spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
 
@@ -492,7 +490,6 @@ int l1_data_B_sram_free(const void *addr)
 
        /* add mutex operation */
        spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
-       put_cpu();
 
        return ret;
 #else
@@ -540,7 +537,7 @@ void *l1_inst_sram_alloc(size_t size)
        void *addr;
        unsigned int cpu;
 
-       cpu = get_cpu();
+       cpu = smp_processor_id();
        /* add mutex operation */
        spin_lock_irqsave(&per_cpu(l1_inst_sram_lock, cpu), flags);
 
@@ -549,7 +546,6 @@ void *l1_inst_sram_alloc(size_t size)
 
        /* add mutex operation */
        spin_unlock_irqrestore(&per_cpu(l1_inst_sram_lock, cpu), flags);
-       put_cpu();
 
        pr_debug("Allocated address in l1_inst_sram_alloc is 0x%lx+0x%lx\n",
                 (long unsigned int)addr, size);
@@ -568,7 +564,7 @@ int l1_inst_sram_free(const void *addr)
        int ret;
        unsigned int cpu;
 
-       cpu = get_cpu();
+       cpu = smp_processor_id();
        /* add mutex operation */
        spin_lock_irqsave(&per_cpu(l1_inst_sram_lock, cpu), flags);
 
@@ -577,7 +573,6 @@ int l1_inst_sram_free(const void *addr)
 
        /* add mutex operation */
        spin_unlock_irqrestore(&per_cpu(l1_inst_sram_lock, cpu), flags);
-       put_cpu();
 
        return ret;
 #else
@@ -593,7 +588,7 @@ void *l1sram_alloc(size_t size)
        void *addr;
        unsigned int cpu;
 
-       cpu = get_cpu();
+       cpu = smp_processor_id();
        /* add mutex operation */
        spin_lock_irqsave(&per_cpu(l1sram_lock, cpu), flags);
 
@@ -602,7 +597,6 @@ void *l1sram_alloc(size_t size)
 
        /* add mutex operation */
        spin_unlock_irqrestore(&per_cpu(l1sram_lock, cpu), flags);
-       put_cpu();
 
        return addr;
 }
@@ -614,7 +608,7 @@ void *l1sram_alloc_max(size_t *psize)
        void *addr;
        unsigned int cpu;
 
-       cpu = get_cpu();
+       cpu = smp_processor_id();
        /* add mutex operation */
        spin_lock_irqsave(&per_cpu(l1sram_lock, cpu), flags);
 
@@ -623,7 +617,6 @@ void *l1sram_alloc_max(size_t *psize)
 
        /* add mutex operation */
        spin_unlock_irqrestore(&per_cpu(l1sram_lock, cpu), flags);
-       put_cpu();
 
        return addr;
 }
@@ -635,7 +628,7 @@ int l1sram_free(const void *addr)
        int ret;
        unsigned int cpu;
 
-       cpu = get_cpu();
+       cpu = smp_processor_id();
        /* add mutex operation */
        spin_lock_irqsave(&per_cpu(l1sram_lock, cpu), flags);
 
@@ -644,7 +637,6 @@ int l1sram_free(const void *addr)
 
        /* add mutex operation */
        spin_unlock_irqrestore(&per_cpu(l1sram_lock, cpu), flags);
-       put_cpu();
 
        return ret;
 }
index 7f656ae0b21d2e16d940ad22f81748d36f4730d6..a8737a8eb2294143692a2502d4cef7b9c4a631b3 100644 (file)
@@ -14,7 +14,6 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
index 562b9a7feae776c5f9ef024726e82ff3dc66774a..109dcd826d171cac5d3fcf31228ab7230f057f1a 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/errno.h>
 #include <linux/major.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/poll.h>
 #include <linux/init.h>
index c4c69cf721e5155141f8261ed536ede9570c3e35..93f0f64b132649d9446a5580d6b1ab740df255e3 100644 (file)
@@ -11,9 +11,9 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/fs.h>
-#include <linux/slab.h>
 #include <arch/svinto.h>
 #include <linux/init.h>
 
index 179e7b8043313eaab628b2ceabf79d67ba67dab4..506826399ae72edbcca777b79898a1c886475f59 100644 (file)
@@ -27,7 +27,6 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
index d4b9c36ddc0fb62f2f8f284897a9504f411307a6..bc0cfdad1cbceecd2c7347c427c087b6ed8105ee 100644 (file)
@@ -50,7 +50,7 @@ pcibios_align_resource(void *data, const struct resource *res,
        if ((res->flags & IORESOURCE_IO) && (start & 0x300))
                start = (start + 0x3ff) & ~0x3ff;
 
-       return start
+       return start;
 }
 
 int pcibios_enable_resources(struct pci_dev *dev, int mask)
index fbe65954ee6c32ab895cbfae568b1613b918b0ee..ee55578d9834159b8e403c0b8e3f26ce2de4d5f4 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 
 void *dma_alloc_coherent(struct device *dev, size_t size,
index d2a0fbf5341fc1870e8bf9d245acb980d3f95f6c..4889f196ecd6c2478c11b309c4fc06ca89ebf0c0 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/errno.h>
 #include <linux/major.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/poll.h>
index 120e7f796fea9707f009af5bffbc15aad6fbdd0f..2661a9529d701a85d0d41358627912e192a10539 100644 (file)
@@ -9,9 +9,9 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/fs.h>
-#include <linux/slab.h>
 #include <hwregs/reg_rdwr.h>
 #include <hwregs/reg_map.h>
 #include <hwregs/timer_defs.h>
index 372d0ca6efbc66cfb98fafd6720e57044dc7bcd9..0b7e3f143281c435e5ff5d836fbb23b762758c5d 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/errno.h>
index a6aca819e9f334050d6927146fa0a2941901c1e6..88dc9b9c4ba051f84988926c4ab304af8091bc27 100644 (file)
@@ -15,7 +15,7 @@
 
 #define ATOMIC_INIT(i)  { (i) }
 
-#define atomic_read(v) ((v)->counter)
+#define atomic_read(v) (*(volatile int *)&(v)->counter)
 #define atomic_set(v,i) (((v)->counter) = (i))
 
 /* These should be written in asm but we do it in C for now. */
index 6d7b9eda40367c87c4f9e76540e04eab3442f8c8..469f7f9d62e0805122105648e3e9b8aaef5c66c4 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/init.h>
 #include <linux/seq_file.h>
index abc13e368b909540df0c66206f7e95ad42d07745..bcd502f74cda46e6ef8c710fe4d76daea0e124f2 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #if 0
 #define DEBUGP printk
index 9aa571169bcc5ea1f9847ab8bea143ccadfc6f14..b917549a7d94b72735fb461d7a213f8a68da8f1e 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
index ff68b9f516a17f9fd2a5ace9b3abd263efb14ca0..df33ab89d70f0083c99380db30faaa8114d7512e 100644 (file)
@@ -8,6 +8,7 @@
  *
  */
 
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <asm/tlb.h>
index 00a57af79afc6b7d6d45fd1046dd96abdf35184b..fae32c7fdcb6619c487f3786993c70b6b0481788 100644 (file)
@@ -36,7 +36,7 @@
 #define smp_mb__after_atomic_inc()     barrier()
 
 #define ATOMIC_INIT(i)         { (i) }
-#define atomic_read(v)         ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
 #define atomic_set(v, i)       (((v)->counter) = (i))
 
 #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
index e3616a6f941d4ad535aa7183ca7dadc3f6999377..a2320a4a00424a7448fe9a27767a07e37c27defe 100644 (file)
@@ -21,12 +21,12 @@ typedef struct {
 
 #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
 
-#define KERNEL_DS              MAKE_MM_SEG(0xdfffffffUL)
-
 #ifdef CONFIG_MMU
 #define USER_DS                        MAKE_MM_SEG(TASK_SIZE - 1)
+#define KERNEL_DS              MAKE_MM_SEG(0xdfffffffUL)
 #else
-#define USER_DS                        KERNEL_DS
+#define USER_DS                        MAKE_MM_SEG(memory_end)
+#define KERNEL_DS              MAKE_MM_SEG(0xe0000000UL)
 #endif
 
 #define get_ds()               (KERNEL_DS)
index 53650c958f415e60efdf586ba58d45f497d416cf..0b67ec5b44141ff5216184380355554197ba2107 100644 (file)
@@ -27,8 +27,6 @@
 #define VERIFY_READ    0
 #define VERIFY_WRITE   1
 
-#define __addr_ok(addr) ((unsigned long)(addr) < get_addr_limit())
-
 /*
  * check that a range of addresses falls within the current address limit
  */
index 62d1aba615dc707edeb0784deb4466d239e53822..625136625a7fef7a0aea779e8d34d15f9c2e345c 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
index 035516cb7a974e1fe44539b7cba4672f8e50d9b2..71abd1510a59d5e453b5a4567c237a32a1f18a44 100644 (file)
@@ -9,7 +9,6 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
index 2c912e80516206dd890d52f5c9fb80a48bd4ee1d..85d110b71cf735166a31d3d2872e46fc597bbc6d 100644 (file)
@@ -10,7 +10,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include <linux/list.h>
 #include <linux/pci.h>
index 1ed15d7fea20c0e8975b22d492fa1e5da3bfb107..6b4fb28e9f997d1a9bf64f19cd26fba08ac8b9df 100644 (file)
@@ -41,7 +41,7 @@ pcibios_align_resource(void *data, const struct resource *res,
        if ((res->flags & IORESOURCE_IO) && (start & 0x300))
                start = (start + 0x3ff) & ~0x3ff;
 
-       return start
+       return start;
 }
 
 
@@ -94,8 +94,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
                                r = &dev->resource[idx];
                                if (!r->start)
                                        continue;
-                               if (pci_claim_resource(dev, idx) < 0)
-                                       printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev));
+                               pci_claim_resource(dev, idx);
                        }
                }
                pcibios_allocate_bus_resources(&bus->children);
@@ -125,7 +124,6 @@ static void __init pcibios_allocate_resources(int pass)
                                DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
                                    r->start, r->end, r->flags, disabled, pass);
                                if (pci_claim_resource(dev, idx) < 0) {
-                                       printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, pci_name(dev));
                                        /* We'll assign a new address later */
                                        r->end -= r->start;
                                        r->start = 0;
index ba587523c015e7755b5e670ec62c96586ead264c..20f6497b2cd5d57cc25e167d3ef31487f7b8c943 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 
index c0dcec65c6b7df665b9ce9dd0e02324a165f9b57..f8dd37e495353f978ca3c4725e330909384d7a58 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 
 #include <asm/segment.h>
 #include <asm/io.h>
index 44840e73e90756c13a670a59321549d4b14c3efc..7a73aaeae3ac987fe5a0d5c8d659d7fde472a9f7 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/hardirq.h>
+#include <linux/gfp.h>
 
 #include <asm/pgalloc.h>
 #include <asm/io.h>
index 0708284f85fb3d690d4e649366ea056282a171b8..ed64588ac3a76662935dc1fddd1b9e015ebaa475 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/pagemap.h>
+#include <linux/gfp.h>
 #include <linux/swap.h>
 #include <linux/mm.h>
 #include <linux/kernel.h>
index 66f616fb4860a779d5cc1eafa68d48d41b4db0e2..c42c83d507bc42c2208b21ff978d92e84c42d161 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include <linux/sched.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/quicklist.h>
index 33c8c0fa9583e0c2794cf0950006d824da961778..e936804b7508758112b853bfca42f9992ebadb44 100644 (file)
@@ -10,7 +10,7 @@
 
 #define ATOMIC_INIT(i) { (i) }
 
-#define atomic_read(v)         ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
 #define atomic_set(v, i)       (((v)->counter) = i)
 
 #include <asm/system.h>
index bd883faa983d898eac8d70b873df93f37eb4fad7..8c8b0ffa6ad709d9a9d32b95ff380a3a734f84f0 100644 (file)
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/interrupt.h>
 #include <linux/reboot.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
index 9942f24aff9e19067a5b74ae05bb3ae26dfdb119..7cc3380f250cc608ea8815472a5652d2b1b04c3b 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/bootmem.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 
 #include <asm/setup.h>
 #include <asm/segment.h>
index 5c7af09ae8d1c3e830c3ff2ae0dfa2c29ac19e96..944a502c2e561a53905151eb18c0b70d90aab110 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include <asm/setup.h>
index 40d8aa811e4e4506dbc97fc5575ba2091845e159..5552ddfaab5ea69c5417f955eb32aa7ddb043c70 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 
 #include <asm/setup.h>
 #include <asm/segment.h>
index 88405cb0832ae88e48f2770e5d8af797d519a346..4e1948447a00834969be528f7ac2a6a681ba1b44 100644 (file)
@@ -21,8 +21,8 @@
 #define ATOMIC_INIT(i)         ((atomic_t) { (i) })
 #define ATOMIC64_INIT(i)       ((atomic64_t) { (i) })
 
-#define atomic_read(v)         ((v)->counter)
-#define atomic64_read(v)       ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
+#define atomic64_read(v)       (*(volatile long *)&(v)->counter)
 
 #define atomic_set(v,i)                (((v)->counter) = (i))
 #define atomic64_set(v,i)      (((v)->counter) = (i))
index 6ebc229a1c51fe97b4055e32ef89b09b39678f39..9da3df6f1a522b7ac46330918967776343d67652 100644 (file)
@@ -437,17 +437,18 @@ __fls (unsigned long x)
  * hweightN: returns the hamming weight (i.e. the number
  * of bits set) of a N-bit word
  */
-static __inline__ unsigned long
-hweight64 (unsigned long x)
+static __inline__ unsigned long __arch_hweight64(unsigned long x)
 {
        unsigned long result;
        result = ia64_popcnt(x);
        return result;
 }
 
-#define hweight32(x)   (unsigned int) hweight64((x) & 0xfffffffful)
-#define hweight16(x)   (unsigned int) hweight64((x) & 0xfffful)
-#define hweight8(x)    (unsigned int) hweight64((x) & 0xfful)
+#define __arch_hweight32(x) ((unsigned int) __arch_hweight64((x) & 0xfffffffful))
+#define __arch_hweight16(x) ((unsigned int) __arch_hweight64((x) & 0xfffful))
+#define __arch_hweight8(x)  ((unsigned int) __arch_hweight64((x) & 0xfful))
+
+#include <asm-generic/bitops/const_hweight.h>
 
 #endif /* __KERNEL__ */
 
index 00eb1b130b63fb91cc6594cfa4b2046f4a8cd7d7..1ed4c8fedb8370e7b8403e36244b2fce043e0aae 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _ASM_DMI_H
 #define _ASM_DMI_H 1
 
+#include <linux/slab.h>
 #include <asm/io.h>
 
 /* Use normal IO mappings for DMI */
index b7515bc808a8d815708c45124661e94cc4d63286..8b9318d311a0b81897d9acc84d1a630494de457d 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/acpi.h>
 
 #include <asm/acpi-ext.h>
index f1c9f70b4e45b969183543fc0a6430a90d133786..c6c90f39f4d9e35381cedf30cbd700fd4d7c84cb 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/efi.h>
 #include <linux/mmzone.h>
 #include <linux/nodemask.h>
+#include <linux/slab.h>
 #include <acpi/processor.h>
 #include <asm/io.h>
 #include <asm/iosapic.h>
@@ -784,6 +785,14 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
        return 0;
 }
 
+int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
+{
+       if (isa_irq >= 16)
+               return -1;
+       *gsi = isa_irq;
+       return 0;
+}
+
 /*
  *  ACPI based hotplug CPU support
  */
index 7b435451b3dc225d05f453f14f8e77881f472e2b..b0b4e6e710f24a90fbf1b422d0a92bb038339f02 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
index c745d0aeb6e0a5ea306c819d67e0f4ac6ce6bc81..a0f001928502b6c1b8e692e36095df36e6b7f3b5 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/efi.h>
 #include <linux/kexec.h>
index 95ac77aeae9b8fc2194e25e4c7f0fef05f5bc887..7ded76658d2da69075bb0c748d73c8159beda9dd 100644 (file)
@@ -86,6 +86,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/string.h>
 #include <linux/bootmem.h>
index d4093a173a3ec29e7d927f1f9b1dd080c3b89af9..640479304ac0f9a1e17b33d32b2422283e479ff3 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/kernel_stat.h>
-#include <linux/slab.h>
 #include <linux/ptrace.h>
 #include <linux/random.h>      /* for rand_initialize_irq() */
 #include <linux/signal.h>
index 378b4833024f110ac7e11265341774f3a6ee75be..a0220dc5ff421effdc55e130aad53a6af39ba348 100644 (file)
@@ -85,6 +85,7 @@
 #include <linux/cpumask.h>
 #include <linux/kdebug.h>
 #include <linux/cpu.h>
+#include <linux/gfp.h>
 
 #include <asm/delay.h>
 #include <asm/machvec.h>
index f94aaa86933fd81f0b347466907e16bdfcf10781..09b4d6828c4544f6088aab1561b897cab083c1f4 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/smp.h>
 #include <linux/workqueue.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 
 #include <asm/delay.h>
 #include <asm/machvec.h>
index 53292abf846c453b45c2f3e3afcd57ca0e9a6308..3095654f9ab394839b9ae52509b5ec786c9f7837 100644 (file)
@@ -1,6 +1,7 @@
 /* Glue code to lib/swiotlb.c */
 
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include <linux/cache.h>
 #include <linux/module.h>
 #include <linux/dma-mapping.h>
index 703062c44fb9df33c7eefceefcf82b9598c71c59..ab985f785c140830d1a9b781685696f93ac8909a 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/rcupdate.h>
 #include <linux/completion.h>
 #include <linux/tracehook.h>
+#include <linux/slab.h>
 
 #include <asm/errno.h>
 #include <asm/intrinsics.h>
index d92765cae10a802d920eca6eaf634621b233a467..53f1648c8b813cf496abf851830a0ce21f3aa333 100644 (file)
 #include <linux/kallsyms.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/notifier.h>
 #include <linux/personality.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/stddef.h>
 #include <linux/thread_info.h>
 #include <linux/unistd.h>
index b61afbbe076f6152935e79fca3eb7da61f251c71..0dec7f702448a07b6fc520342969411423d6445a 100644 (file)
@@ -11,7 +11,6 @@
  */
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
index b3a5818088d912c46a63160c016ba3e2fdaad930..28f299de290397361565b4407f3ec0736fd7a018 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/node.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/nodemask.h>
index a595823582d9cd6aa653d4ec56e5d045151c9cdb..c4696d217ce0bfe5216393cd4ad572194937175d 100644 (file)
@@ -18,9 +18,9 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/efi.h>
 #include <linux/genalloc.h>
+#include <linux/gfp.h>
 #include <asm/page.h>
 #include <asm/pal.h>
 #include <asm/system.h>
index 26e0e089bfe76b0b89772bfc7f5617abc02d2a9d..7f3c0a2e60cdb32178f757534f670ab74f3b19a6 100644 (file)
@@ -23,8 +23,8 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/percpu.h>
-#include <linux/gfp.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/kvm_host.h>
 #include <linux/kvm.h>
@@ -1802,7 +1802,8 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
 {
        struct kvm_memory_slot *memslot;
        int r, i;
-       long n, base;
+       long base;
+       unsigned long n;
        unsigned long *dirty_bitmap = (unsigned long *)(kvm->arch.vm_base +
                        offsetof(struct kvm_vm_data, kvm_mem_dirty_log));
 
@@ -1815,7 +1816,7 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
        if (!memslot->dirty_bitmap)
                goto out;
 
-       n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+       n = kvm_dirty_bitmap_bytes(memslot);
        base = memslot->base_gfn / BITS_PER_LONG;
 
        for (i = 0; i < n/sizeof(long); ++i) {
@@ -1831,7 +1832,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
                struct kvm_dirty_log *log)
 {
        int r;
-       int n;
+       unsigned long n;
        struct kvm_memory_slot *memslot;
        int is_dirty = 0;
 
@@ -1850,7 +1851,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
        if (is_dirty) {
                kvm_flush_remote_tlbs(kvm);
                memslot = &kvm->memslots->memslots[log->slot];
-               n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+               n = kvm_dirty_bitmap_bytes(memslot);
                memset(memslot->dirty_bitmap, 0, n);
        }
        r = 0;
index 8d586d1e2515936b8b09c48215e084a853623403..61620323bb60adadf942288b53446604d8323b69 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/acpi.h>
 #include <linux/efi.h>
 #include <linux/nodemask.h>
+#include <linux/slab.h>
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
 #include <asm/meminit.h>
index b0f615759e97461052eb154c431487c90d4cbad3..1841ee7e65f9b2a11f800e1fc3c965d1c9172c10 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/hugetlb.h>
 #include <linux/pagemap.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/log2.h>
 #include <asm/mman.h>
index f3de9d7a98b481c632fa4960211213f0a3ee307d..5dfd916e9ea610db1a047e0462d6398082bde63e 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/smp.h>
 #include <linux/mm.h>
 #include <linux/bootmem.h>
+#include <linux/slab.h>
 
 #include <asm/delay.h>
 #include <asm/mmu_context.h>
index c6d6b62db66c99c05c4cc5ee8c84f19c4a768d5b..cad775a1a157b66566ef761aed4418caa0e4e871 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/bootmem.h>
 #include <linux/string.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <asm/sn/bte.h>
 
index 66f633bff059af9b33539a9a52f89e55c2a6e9cf..8cdcb173a13877842cbcc1833b68d70037c54cfc 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/sn/sn_sal.h>
 #include "xtalk/hubdev.h"
 #include <linux/acpi.h>
+#include <linux/slab.h>
 
 
 /*
index 308e6595110e4e4f6aa03047f12333dd83663dad..4433dd019d3c92ef3fa7cf71d7df61ce58864c6b 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/bootmem.h>
+#include <linux/slab.h>
 #include <asm/sn/types.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/sn_feature_sets.h>
index ee774c366a06c82840a89c80dfb46b3086ead611..98079f29d9a9ff19bcdcd13bebfd7104ddd06a98 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright (C) 1992 - 1997, 2000-2006 Silicon Graphics, Inc. All rights reserved.
  */
 
+#include <linux/slab.h>
 #include <asm/sn/types.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/io.h>
index 40d6eeda1c4bbfe2f86031ab12dd1c5386a25311..13c15d968098d90b91beedb38855e331c73e616d 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/spinlock.h>
 #include <linux/init.h>
 #include <linux/rculist.h>
+#include <linux/slab.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/intr.h>
index fbbfb970120128a29df68c549895187ea3e3013e..ebfdd6a9ae1a0ac6401581ab8de42592175a87c5 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/pci.h>
 #include <linux/cpumask.h>
 #include <linux/msi.h>
+#include <linux/slab.h>
 
 #include <asm/sn/addrs.h>
 #include <asm/sn/intr.h>
index 98b684928e12eae87c840344f1e256c1d118702c..a9d310de57da650ac7c3549774729c990ceac583 100644 (file)
@@ -9,6 +9,7 @@
  * a description of how these routines should be used.
  */
 
+#include <linux/gfp.h>
 #include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <asm/dma.h>
index d13e5a22a558cbc4f3233c02b71bdb4ebf124e8e..3cb5cf37764429de80f7c89fdae1752db15e5ca5 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/geo.h>
index efb454534e525c2e9bbb76d4447dc2a97224332c..4d4536e3b6f3d35f9f0e84a0180a14011215603f 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/bitmap.h>
+#include <linux/slab.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/io.h>
index 012f3b82ee55d4b4792041fd8a51c633550bba52..27faba035f3a348fdb847beb1e6ca831e703ddb7 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/sn/addrs.h>
index 777dd9a9108b1213d372ae42be06d93e0c36342a..48cca37625ebdd04d08136037eeca93d92b71b73 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/module.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 
 #include <xen/interface/xen.h>
index 63f0cf0f50dde3949725305e42fa6472971c6f45..d44a51e5271b7b5b10a5d8610ce1076f4e536be5 100644 (file)
@@ -26,7 +26,7 @@
  *
  * Atomically reads the value of @v.
  */
-#define atomic_read(v) ((v)->counter)
+#define atomic_read(v) (*(volatile int *)&(v)->counter)
 
 /**
  * atomic_set - set atomic variable
index 67a01e1e4283f86d07bdc3de5f89c0ab3d6b7a9d..bc8c8c1511b2eb23c07d6ad82c812d62841b5d94 100644 (file)
  */
 
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/hardirq.h>
 
 #include <asm/io.h>
index 9f581df3952b5cb87fbae357f858003750fd9400..73e2205ebf5afba2c17ca848701c0ae026f52fab 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/bitops.h>
 #include <linux/nodemask.h>
 #include <linux/pfn.h>
+#include <linux/gfp.h>
 #include <asm/types.h>
 #include <asm/processor.h>
 #include <asm/page.h>
index 6a0d7650f980fcdcbd5d5ab3b4547f4120bc65b8..11dd30b16b3bc35b19f1d1e1c5e7ad7e9d73531d 100644 (file)
@@ -2,6 +2,6 @@
 # Makefile for Linux arch/m68k/amiga source directory
 #
 
-obj-y          := config.o amiints.o cia.o chipram.o amisound.o
+obj-y          := config.o amiints.o cia.o chipram.o amisound.o platform.o
 
 obj-$(CONFIG_AMIGA_PCMCIA)     += pcmcia.o
diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c
new file mode 100644 (file)
index 0000000..38f18bf
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  Copyright (C) 2007-2009 Geert Uytterhoeven
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/zorro.h>
+
+#include <asm/amigahw.h>
+
+
+#ifdef CONFIG_ZORRO
+
+static const struct resource zorro_resources[] __initconst = {
+       /* Zorro II regions (on Zorro II/III) */
+       {
+               .name   = "Zorro II exp",
+               .start  = 0x00e80000,
+               .end    = 0x00efffff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .name   = "Zorro II mem",
+               .start  = 0x00200000,
+               .end    = 0x009fffff,
+               .flags  = IORESOURCE_MEM,
+       },
+       /* Zorro III regions (on Zorro III only) */
+       {
+               .name   = "Zorro III exp",
+               .start  = 0xff000000,
+               .end    = 0xffffffff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .name   = "Zorro III cfg",
+               .start  = 0x40000000,
+               .end    = 0x7fffffff,
+               .flags  = IORESOURCE_MEM,
+       }
+};
+
+
+static int __init amiga_init_bus(void)
+{
+       if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
+               return -ENODEV;
+
+       platform_device_register_simple("amiga-zorro", -1, zorro_resources,
+                                       AMIGAHW_PRESENT(ZORRO3) ? 4 : 2);
+       return 0;
+}
+
+subsys_initcall(amiga_init_bus);
+
+#endif /* CONFIG_ZORRO */
+
+
+static int __init amiga_init_devices(void)
+{
+       if (!MACH_IS_AMIGA)
+               return -ENODEV;
+
+       /* video hardware */
+       if (AMIGAHW_PRESENT(AMI_VIDEO))
+               platform_device_register_simple("amiga-video", -1, NULL, 0);
+
+
+       /* sound hardware */
+       if (AMIGAHW_PRESENT(AMI_AUDIO))
+               platform_device_register_simple("amiga-audio", -1, NULL, 0);
+
+
+       /* storage interfaces */
+       if (AMIGAHW_PRESENT(AMI_FLOPPY))
+               platform_device_register_simple("amiga-floppy", -1, NULL, 0);
+
+       return 0;
+}
+
+device_initcall(amiga_init_devices);
index c50bec8aabb1983e3517857b5abafa75f91b7ace..cb8617bb194ba638eed418f27aff8fa61a9e1591 100644 (file)
@@ -9,8 +9,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/ioport.h>
 #include <linux/capability.h>
 #include <linux/fcntl.h>
 static unsigned char days_in_mo[] =
 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
-static char rtc_status;
+static atomic_t rtc_status = ATOMIC_INIT(1);
 
-static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-                    unsigned long arg)
+static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
        unsigned char msr;
@@ -133,29 +130,20 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 }
 
 /*
- *     We enforce only one user at a time here with the open/close.
- *     Also clear the previous interrupt data on an open, and clean
- *     up things on a close.
+ * We enforce only one user at a time here with the open/close.
  */
-
 static int rtc_open(struct inode *inode, struct file *file)
 {
-       lock_kernel();
-       if(rtc_status) {
-               unlock_kernel();
+       if (!atomic_dec_and_test(&rtc_status)) {
+               atomic_inc(&rtc_status);
                return -EBUSY;
        }
-
-       rtc_status = 1;
-       unlock_kernel();
        return 0;
 }
 
 static int rtc_release(struct inode *inode, struct file *file)
 {
-       lock_kernel();
-       rtc_status = 0;
-       unlock_kernel();
+       atomic_inc(&rtc_status);
        return 0;
 }
 
@@ -164,9 +152,9 @@ static int rtc_release(struct inode *inode, struct file *file)
  */
 
 static const struct file_operations rtc_fops = {
-       .ioctl =        rtc_ioctl,
-       .open =         rtc_open,
-       .release =      rtc_release,
+       .unlocked_ioctl = rtc_ioctl,
+       .open           = rtc_open,
+       .release        = rtc_release,
 };
 
 static struct miscdevice rtc_dev = {
index f5b3d098b0f5e1295a7f2653941de23c387ec227..7b98242960de76b58da5cd7fb1e72d0985091c0b 100644 (file)
@@ -1,4 +1,2 @@
 extern void hp300_sched_init(irq_handler_t vector);
-extern unsigned long hp300_gettimeoffset (void);
-
-
+extern unsigned long hp300_gettimeoffset(void);
index 88b7af20a9960c59f42258d017fe6b16ef79b5ce..6a223b3f7e74abe9faeed1345901171bca95a114 100644 (file)
@@ -15,7 +15,7 @@
 
 #define ATOMIC_INIT(i) { (i) }
 
-#define atomic_read(v)         ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
 #define atomic_set(v, i)       (((v)->counter) = i)
 
 static inline void atomic_add(int i, atomic_t *v)
@@ -148,14 +148,18 @@ static inline int atomic_xchg(atomic_t *v, int new)
 static inline int atomic_sub_and_test(int i, atomic_t *v)
 {
        char c;
-       __asm__ __volatile__("subl %2,%1; seq %0" : "=d" (c), "+m" (*v): "g" (i));
+       __asm__ __volatile__("subl %2,%1; seq %0"
+                            : "=d" (c), "+m" (*v)
+                            : "id" (i));
        return c != 0;
 }
 
 static inline int atomic_add_negative(int i, atomic_t *v)
 {
        char c;
-       __asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "+m" (*v): "g" (i));
+       __asm__ __volatile__("addl %2,%1; smi %0"
+                            : "=d" (c), "+m" (*v)
+                            : "id" (i));
        return c != 0;
 }
 
index 5674cb9449bd81278fa67e319a0b66abca0efd39..289310c63a8a5c361fe2f659205bd827b9889e7c 100644 (file)
@@ -15,7 +15,7 @@
 
 #define ATOMIC_INIT(i) { (i) }
 
-#define atomic_read(v)         ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
 #define atomic_set(v, i)       (((v)->counter) = i)
 
 static __inline__ void atomic_add(int i, atomic_t *v)
index 9bde784e7bad038a41d471a22af238587a998aad..b4ecdaada5201b11281f57548d36daf3fff16342 100644 (file)
@@ -365,6 +365,10 @@ static inline int minix_test_bit(int nr, const void *vaddr)
 #define ext2_set_bit_atomic(lock, nr, addr)    test_and_set_bit((nr) ^ 24, (unsigned long *)(addr))
 #define ext2_clear_bit(nr, addr)               __test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr))
 #define ext2_clear_bit_atomic(lock, nr, addr)  test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr))
+#define ext2_find_next_zero_bit(addr, size, offset) \
+       generic_find_next_zero_le_bit((unsigned long *)addr, size, offset)
+#define ext2_find_next_bit(addr, size, offset) \
+       generic_find_next_le_bit((unsigned long *)addr, size, offset)
 
 static inline int ext2_test_bit(int nr, const void *vaddr)
 {
@@ -394,10 +398,9 @@ static inline int ext2_find_first_zero_bit(const void *vaddr, unsigned size)
        return (p - addr) * 32 + res;
 }
 
-static inline int ext2_find_next_zero_bit(const void *vaddr, unsigned size,
-                                         unsigned offset)
+static inline unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
+               unsigned long size, unsigned long offset)
 {
-       const unsigned long *addr = vaddr;
        const unsigned long *p = addr + (offset >> 5);
        int bit = offset & 31UL, res;
 
@@ -437,10 +440,9 @@ static inline int ext2_find_first_bit(const void *vaddr, unsigned size)
        return (p - addr) * 32 + res;
 }
 
-static inline int ext2_find_next_bit(const void *vaddr, unsigned size,
-                                    unsigned offset)
+static inline unsigned long generic_find_next_le_bit(const unsigned long *addr,
+               unsigned long size, unsigned long offset)
 {
-       const unsigned long *addr = vaddr;
        const unsigned long *p = addr + (offset >> 5);
        int bit = offset & 31UL, res;
 
index ef2293873612c6985814be4786420573d00869f6..01a8716c5fc558253538b9cbea14a923b8b889be 100644 (file)
@@ -212,5 +212,10 @@ struct mcf_platform_uart {
 #define        MCFUART_URF_RXS         0xc0            /* Receiver status */
 #endif
 
+#if defined(CONFIG_M5272)
+#define MCFUART_TXFIFOSIZE     25
+#else
+#define MCFUART_TXFIFOSIZE     1
+#endif
 /****************************************************************************/
 #endif /* mcfuart_h */
index 85c41b75aa78d5f3dfa57f7f78fde49680a1a819..36265ccf5c7b520577d3729db545cfc8ea1a8b6b 100644 (file)
@@ -1,26 +1,12 @@
 #ifndef _M68K_PARAM_H
 #define _M68K_PARAM_H
 
-#ifdef __KERNEL__
-# define HZ            CONFIG_HZ       /* Internal kernel timer frequency */
-# define USER_HZ       100             /* .. some user interfaces are in "ticks" */
-# define CLOCKS_PER_SEC        (USER_HZ)       /* like times() */
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
-
 #ifdef __uClinux__
 #define EXEC_PAGESIZE  4096
 #else
 #define EXEC_PAGESIZE  8192
 #endif
 
-#ifndef NOGROUP
-#define NOGROUP                (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64      /* max length of hostname */
+#include <asm-generic/param.h>
 
 #endif /* _M68K_PARAM_H */
index 1320eaa4cc2aab4b531a565c57ab62afb30bd0ec..a29dd74a17cb25827a203654c5d7fafb156ff485 100644 (file)
@@ -17,13 +17,11 @@ struct sigcontext {
 #ifndef __uClinux__
 # ifdef __mcoldfire__
        unsigned long  sc_fpregs[2][2]; /* room for two fp registers */
-       unsigned long  sc_fpcntl[3];
-       unsigned char  sc_fpstate[16+6*8];
 # else
        unsigned long  sc_fpregs[2*3];  /* room for two fp registers */
+# endif
        unsigned long  sc_fpcntl[3];
        unsigned char  sc_fpstate[216];
-# endif
 #endif
 };
 
index 2bb4245404d836ca73e770ed24146f7c6c78e9b4..4bbb3c2a888057e93c264c76e029909dc7bd8884 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include <asm/pgalloc.h>
index 17c3f325255de36707bcb2dac5ec0981d57a7f42..1a6be27cf165a0cd60c210e72abcf727c981c462 100644 (file)
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/reboot.h>
 #include <linux/init_task.h>
index aacd6d17b83373b4bab02b0710e69978b5472c08..ada4f4cca811b6ea14e0406619d8d7181ae60b77 100644 (file)
@@ -455,7 +455,7 @@ static inline void access_error040(struct frame *fp)
 
                if (do_page_fault(&fp->ptregs, addr, errorcode)) {
 #ifdef DEBUG
-                       printk("do_page_fault() !=0 \n");
+                       printk("do_page_fault() !=0\n");
 #endif
                        if (user_mode(&fp->ptregs)){
                                /* delay writebacks after signal delivery */
index 0356da9bf763abacdb678c7af196a091fd7300d3..1c16b1baf8dbf9e7b03f22cd663192c83aa07cf7 100644 (file)
@@ -148,7 +148,7 @@ static void mac_cache_card_flush(int writeback)
 void __init config_mac(void)
 {
        if (!MACH_IS_MAC)
-               printk(KERN_ERR "ERROR: no Mac, but config_mac() called!! \n");
+               printk(KERN_ERR "ERROR: no Mac, but config_mac() called!!\n");
 
        mach_sched_init = mac_sched_init;
        mach_init_IRQ = mac_init_IRQ;
@@ -867,7 +867,7 @@ static void __init mac_identify(void)
         */
        iop_preinit();
 
-       printk(KERN_INFO "Detected Macintosh model: %d \n", model);
+       printk(KERN_INFO "Detected Macintosh model: %d\n", model);
 
        /*
         * Report booter data:
@@ -878,12 +878,12 @@ static void __init mac_identify(void)
                mac_bi_data.videoaddr, mac_bi_data.videorow,
                mac_bi_data.videodepth, mac_bi_data.dimensions & 0xFFFF,
                mac_bi_data.dimensions >> 16);
-       printk(KERN_DEBUG " Videological 0x%lx phys. 0x%lx, SCC at 0x%lx \n",
+       printk(KERN_DEBUG " Videological 0x%lx phys. 0x%lx, SCC at 0x%lx\n",
                mac_bi_data.videological, mac_orig_videoaddr,
                mac_bi_data.sccbase);
-       printk(KERN_DEBUG " Boottime: 0x%lx GMTBias: 0x%lx \n",
+       printk(KERN_DEBUG " Boottime: 0x%lx GMTBias: 0x%lx\n",
                mac_bi_data.boottime, mac_bi_data.gmtbias);
-       printk(KERN_DEBUG " Machine ID: %ld CPUid: 0x%lx memory size: 0x%lx \n",
+       printk(KERN_DEBUG " Machine ID: %ld CPUid: 0x%lx memory size: 0x%lx\n",
                mac_bi_data.id, mac_bi_data.cpuid, mac_bi_data.memsize);
 
        iop_init();
index 5d818568b343719a7ab82f9a8fb075a048a9535e..0f118ca156d9a0e8bd366e9d742989d57c5be3a3 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/rtc.h>
 #include <linux/mm.h>
index d0e35cf99fc69a531cb0239277c3351525c13773..a96394a0333d3d3c82cd70fbd4beb4764b02f018 100644 (file)
@@ -154,7 +154,6 @@ good_area:
         * the fault.
         */
 
- survive:
        fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0);
 #ifdef DEBUG
        printk("handle_mm_fault returns %d\n",fault);
@@ -180,15 +179,10 @@ good_area:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_global_init(current)) {
-               yield();
-               down_read(&mm->mmap_sem);
-               goto survive;
-       }
-
-       printk("VM: killing process %s\n", current->comm);
-       if (user_mode(regs))
-               do_group_exit(SIGKILL);
+       if (!user_mode(regs))
+               goto no_context;
+       pagefault_out_of_memory();
+       return 0;
 
 no_context:
        current->thread.signo = SIGBUS;
index 774549accd2df34096528255822e61599af1a80b..8bc842554e5b4618ad3e77208dc5872cd184fef2 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/gfp.h>
 
 #include <asm/setup.h>
 #include <asm/uaccess.h>
index b7473525b43179fa9066d3a1d978120f1caac164..34c77ce24fba5b54a46c63449620259a2a9fdd93 100644 (file)
@@ -9,9 +9,9 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/pagemap.h>
+#include <linux/gfp.h>
 
 #include <asm/setup.h>
 #include <asm/segment.h>
index 4665fc84b7dcc50ab43174bcf7760f43a5859533..02b7a03e422681032b1a62ebf45183e1ed629b21 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/gfp.h>
 
 #include <asm/setup.h>
 #include <asm/uaccess.h>
index cea5e3e4e63646abf411aeb34be8172493214a34..11ac6f63967a24ac134e406d253400f3ff496bb0 100644 (file)
@@ -9,8 +9,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/ioport.h>
 #include <linux/capability.h>
 #include <linux/fcntl.h>
@@ -37,8 +35,7 @@ static const unsigned char days_in_mo[] =
 
 static atomic_t rtc_ready = ATOMIC_INIT(1);
 
-static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-                    unsigned long arg)
+static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        volatile MK48T08ptr_t rtc = (MK48T08ptr_t)MVME_RTC_BASE;
        unsigned long flags;
@@ -121,22 +118,15 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 }
 
 /*
- *     We enforce only one user at a time here with the open/close.
- *     Also clear the previous interrupt data on an open, and clean
- *     up things on a close.
+ * We enforce only one user at a time here with the open/close.
  */
-
 static int rtc_open(struct inode *inode, struct file *file)
 {
-       lock_kernel();
        if( !atomic_dec_and_test(&rtc_ready) )
        {
                atomic_inc( &rtc_ready );
-               unlock_kernel();
                return -EBUSY;
        }
-       unlock_kernel();
-
        return 0;
 }
 
@@ -151,9 +141,9 @@ static int rtc_release(struct inode *inode, struct file *file)
  */
 
 static const struct file_operations rtc_fops = {
-       .ioctl =        rtc_ioctl,
-       .open =         rtc_open,
-       .release =      rtc_release,
+       .unlocked_ioctl = rtc_ioctl,
+       .open           = rtc_open,
+       .release        = rtc_release,
 };
 
 static struct miscdevice rtc_dev=
index 31ab3f08bbda25ad37be9a26abeb3f511c25b554..ad10fecec2fe665d7dcf86936da97eae6bd25d0c 100644 (file)
@@ -126,7 +126,7 @@ static void q40_reset(void)
 {
         halted = 1;
         printk("\n\n*******************************************\n"
-               "Called q40_reset : press the RESET button!! \n"
+               "Called q40_reset : press the RESET button!!\n"
                "*******************************************\n");
        Q40_LED_ON();
        while (1)
index f9277e8b4159b34e81d79c56c2c47f26e1cf7361..ca0966cac72adfe68cf6eef8b680c395ee7eea5d 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 
index 117481e86305798610f894e8f0e7b896315dc573..d5ddcdaa2347356152047deb6d272a5594e0b97a 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/bitops.h>
 #include <linux/mm.h>
 #include <linux/bootmem.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include <asm/sun3x.h>
index ce404bc9ccbdff8acf6c2160719964e4a0cfd6cd..14042574ac217550db926fd24e308b7c5620f756 100644 (file)
@@ -94,7 +94,7 @@ cflags-$(CONFIG_M520x)                := $(call cc-option,-mcpu=5208,-m5200)
 cflags-$(CONFIG_M523x)         := $(call cc-option,-mcpu=523x,-m5307)
 cflags-$(CONFIG_M5249)         := $(call cc-option,-mcpu=5249,-m5200)
 cflags-$(CONFIG_M5271)         := $(call cc-option,-mcpu=5271,-m5307)
-cflags-$(CONFIG_M5272)         := $(call cc-option,-mcpu=5271,-m5200)
+cflags-$(CONFIG_M5272)         := $(call cc-option,-mcpu=5272,-m5307)
 cflags-$(CONFIG_M5275)         := $(call cc-option,-mcpu=5275,-m5307)
 cflags-$(CONFIG_M528x)         := $(call cc-option,-m528x,-m5307)
 cflags-$(CONFIG_M5307)         := $(call cc-option,-m5307,-m5200)
index aaf38bbbb6cdff29e9630bd35f757cf1ec85cf0f..fc61541aeb715f6f872ce55275fdf3eb1965275f 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
index 56043ade394197ebb011fcfcd94a50df9d181179..aff6f57ef8b5da2819f7a074a7365716991d9de7 100644 (file)
@@ -145,6 +145,6 @@ ENTRY(ret_from_user_signal)
        trap #0
 
 ENTRY(ret_from_user_rt_signal)
-       move #__NR_rt_sigreturn,%d0
+       movel #__NR_rt_sigreturn,%d0
        trap #0
 
index 959cb249c759fd4cae926a49259a67c9893fac34..6aa66134b433cf6312703189ad240b004900a5e8 100644 (file)
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/interrupt.h>
 #include <linux/reboot.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
index f3236d0b522ddceaa39a9a468b7cc4f02d27b5d1..8a6653f56bd8b29c286b3f973191d53557721e78 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/bootmem.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 
 #include <asm/setup.h>
 #include <asm/segment.h>
index bc32f38843f0a1cf1ca5c138129a825cfefdb1d2..902c1dfda9e530eefd41aad1ff7367f211ac529b 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include <asm/setup.h>
index d5b9e1357808c40661b440b1d00a968068e05d53..8f7949e786d454bb23839707906161e4d1f885f2 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 
 #include <asm/segment.h>
 #include <asm/page.h>
index 1143f77caca4d32d7739bd11b9e7c2118c0f7170..6f22970d8c2037380e4342e7e88a7dbab9c74dc3 100644 (file)
@@ -107,7 +107,6 @@ void init_IRQ(void)
        _ramvec[vba+CPMVEC_PIO_PC7]     = inthandler;  /* pio - pc7 */
        _ramvec[vba+CPMVEC_PIO_PC6]     = inthandler;  /* pio - pc6 */
        _ramvec[vba+CPMVEC_TIMER3]      = inthandler;  /* timer 3 */
-       _ramvec[vba+CPMVEC_RISCTIMER]   = inthandler;  /* reserved */
        _ramvec[vba+CPMVEC_PIO_PC5]     = inthandler;  /* pio - pc5 */
        _ramvec[vba+CPMVEC_PIO_PC4]     = inthandler;  /* pio - pc4 */
        _ramvec[vba+CPMVEC_RESERVED2]   = inthandler;  /* reserved */
index b008168ae946b6e479c690911c8d2f0e451b1017..76818f926539bf444c8aa577d12dc1af1296d665 100644 (file)
@@ -14,6 +14,8 @@ config MICROBLAZE
        select USB_ARCH_HAS_EHCI
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select HAVE_OPROFILE
+       select HAVE_DMA_ATTRS
+       select HAVE_DMA_API_DEBUG
        select TRACING_SUPPORT
 
 config SWAP
@@ -73,12 +75,6 @@ config LOCKDEP_SUPPORT
 config HAVE_LATENCYTOP_SUPPORT
        def_bool y
 
-config PCI
-       def_bool n
-
-config NO_DMA
-       def_bool y
-
 config DTC
        def_bool y
 
@@ -146,7 +142,6 @@ menu "Advanced setup"
 
 config ADVANCED_OPTIONS
        bool "Prompt for advanced kernel configuration options"
-       depends on MMU
        help
          This option will enable prompting for a variety of advanced kernel
          configuration options.  These options can cause the kernel to not
@@ -158,6 +153,15 @@ config ADVANCED_OPTIONS
 comment "Default settings for advanced configuration options are used"
        depends on !ADVANCED_OPTIONS
 
+config XILINX_UNCACHED_SHADOW
+       bool "Are you using uncached shadow for RAM ?"
+       depends on ADVANCED_OPTIONS && !MMU
+       default n
+       help
+         This is needed to be able to allocate uncachable memory regions.
+         The feature requires the design to define the RAM memory controller
+         window to be twice as large as the actual physical memory.
+
 config HIGHMEM_START_BOOL
        bool "Set high memory pool address"
        depends on ADVANCED_OPTIONS && HIGHMEM
@@ -175,7 +179,7 @@ config HIGHMEM_START
 
 config LOWMEM_SIZE_BOOL
        bool "Set maximum low memory"
-       depends on ADVANCED_OPTIONS
+       depends on ADVANCED_OPTIONS && MMU
        help
          This option allows you to set the maximum amount of memory which
          will be used as "low memory", that is, memory which the kernel can
@@ -187,7 +191,6 @@ config LOWMEM_SIZE_BOOL
 
 config LOWMEM_SIZE
        hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL
-       depends on MMU
        default "0x30000000"
 
 config KERNEL_START_BOOL
@@ -208,7 +211,7 @@ config KERNEL_START
 
 config TASK_SIZE_BOOL
        bool "Set custom user task size"
-       depends on ADVANCED_OPTIONS
+       depends on ADVANCED_OPTIONS && MMU
        help
          This option allows you to set the amount of virtual address space
          allocated to user tasks.  This can be useful in optimizing the
@@ -218,42 +221,34 @@ config TASK_SIZE_BOOL
 
 config TASK_SIZE
        hex "Size of user task space" if TASK_SIZE_BOOL
-       depends on MMU
        default "0x80000000"
 
-config CONSISTENT_START_BOOL
-       bool "Set custom consistent memory pool address"
-       depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
-       help
-         This option allows you to set the base virtual address
-         of the the consistent memory pool.  This pool of virtual
-         memory is used to make consistent memory allocations.
+endmenu
 
-config CONSISTENT_START
-       hex "Base virtual address of consistent memory pool" if CONSISTENT_START_BOOL
-       depends on MMU
-       default "0xff100000" if NOT_COHERENT_CACHE
+source "mm/Kconfig"
 
-config CONSISTENT_SIZE_BOOL
-       bool "Set custom consistent memory pool size"
-       depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
-       help
-         This option allows you to set the size of the the
-         consistent memory pool.  This pool of virtual memory
-         is used to make consistent memory allocations.
+menu "Exectuable file formats"
 
-config CONSISTENT_SIZE
-       hex "Size of consistent memory pool" if CONSISTENT_SIZE_BOOL
-       depends on MMU
-       default "0x00200000" if NOT_COHERENT_CACHE
+source "fs/Kconfig.binfmt"
 
 endmenu
 
-source "mm/Kconfig"
+menu "Bus Options"
 
-menu "Exectuable file formats"
+config PCI
+       bool "PCI support"
 
-source "fs/Kconfig.binfmt"
+config PCI_DOMAINS
+       def_bool PCI
+
+config PCI_SYSCALL
+       def_bool PCI
+
+config PCI_XILINX
+       bool "Xilinx PCI host bridge support"
+       depends on PCI
+
+source "drivers/pci/Kconfig"
 
 endmenu
 
index d2d6cfcb1a3028bde39bad803094746713518d5d..72f6e85837467679354d37ec148db56eb4868363 100644 (file)
@@ -50,6 +50,7 @@ libs-y += $(LIBGCC)
 core-y += arch/microblaze/kernel/
 core-y += arch/microblaze/mm/
 core-y += arch/microblaze/platform/
+core-$(CONFIG_PCI) += arch/microblaze/pci/
 
 drivers-$(CONFIG_OPROFILE) += arch/microblaze/oprofile/
 
@@ -83,7 +84,7 @@ define archhelp
   echo '* linux.bin    - Create raw binary'
   echo '  linux.bin.gz - Create compressed raw binary'
   echo '  simpleImage.<dt> - ELF image with $(arch)/boot/dts/<dt>.dts linked in'
-  echo '                   - stripped elf with fdt blob
+  echo '                   - stripped elf with fdt blob'
   echo '  simpleImage.<dt>.unstrip - full ELF image with fdt blob'
   echo '  *_defconfig      - Select default config from arch/microblaze/configs'
   echo ''
@@ -93,3 +94,5 @@ define archhelp
   echo '  name of a dts file from the arch/microblaze/boot/dts/ directory'
   echo '  (minus the .dts extension).'
 endef
+
+MRPROPER_FILES += $(boot)/simpleImage.*
index 902cf9846c3cb9b89f0940a8a635554cb265fd0b..57f50c2371c6e36372962886180324ffba5b5fd2 100644 (file)
@@ -23,8 +23,6 @@ $(obj)/system.dtb: $(obj)/$(DTB).dtb
 endif
 
 $(obj)/linux.bin: vmlinux FORCE
-       [ -n $(CONFIG_INITRAMFS_SOURCE) ] && [ ! -e $(CONFIG_INITRAMFS_SOURCE) ] && \
-       touch $(CONFIG_INITRAMFS_SOURCE) || echo "No CPIO image"
        $(call if_changed,objcopy)
        $(call if_changed,uimage)
        @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
@@ -62,6 +60,4 @@ quiet_cmd_dtc = DTC     $@
 $(obj)/%.dtb: $(dtstree)/%.dts FORCE
        $(call if_changed,dtc)
 
-clean-kernel += linux.bin linux.bin.gz simpleImage.*
-
-clean-files += *.dtb simpleImage.*.unstrip
+clean-files += *.dtb simpleImage.*.unstrip linux.bin.ub
index 6fced1fe3bf06316fd7e3280d4a8b427128f7059..3c91cf6192c6a1603019d8477eeb14113611995e 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc6
-# Wed Feb  3 10:02:59 2010
+# Linux kernel version: 2.6.34-rc6
+# Thu May  6 11:22:14 2010
 #
 CONFIG_MICROBLAZE=y
 # CONFIG_SWAP is not set
@@ -22,8 +22,6 @@ CONFIG_GENERIC_CSUM=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-# CONFIG_PCI is not set
-CONFIG_NO_DMA=y
 CONFIG_DTC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
@@ -56,7 +54,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -106,6 +103,8 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
@@ -245,13 +244,20 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 # CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
+
+#
+# Bus Options
+#
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_NET=y
 
 #
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -341,7 +347,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
 CONFIG_OF_DEVICE=y
+CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
@@ -370,6 +378,7 @@ CONFIG_MISC_DEVICES=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -383,9 +392,30 @@ CONFIG_NETDEVICES=y
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# CONFIG_ETHOC is not set
 # CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
@@ -394,6 +424,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
 # CONFIG_KS8851_MLL is not set
 CONFIG_XILINX_EMACLITE=y
@@ -444,6 +475,7 @@ CONFIG_SERIAL_UARTLITE=y
 CONFIG_SERIAL_UARTLITE_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -471,6 +503,12 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # 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
@@ -502,6 +540,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
@@ -572,6 +611,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -595,6 +635,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=y
 CONFIG_CIFS_STATS=y
 CONFIG_CIFS_STATS2=y
@@ -696,6 +737,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_OBJECTS is not set
 CONFIG_DEBUG_SLAB=y
 # CONFIG_DEBUG_SLAB_LEAK is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 CONFIG_DEBUG_SPINLOCK=y
 # CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_LOCK_ALLOC is not set
@@ -741,6 +783,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_EARLY_PRINTK=y
 # CONFIG_HEART_BEAT is not set
@@ -862,5 +905,6 @@ CONFIG_ZLIB_INFLATE=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
index ce2da535246a54df020ae48e053c2f8a2df1ff3f..dd3a494257f4330453b860edd1176aefac58c174 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc6
-# Wed Feb  3 10:03:21 2010
+# Linux kernel version: 2.6.34-rc6
+# Thu May  6 11:25:12 2010
 #
 CONFIG_MICROBLAZE=y
 # CONFIG_SWAP is not set
@@ -22,8 +22,6 @@ CONFIG_GENERIC_CSUM=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-# CONFIG_PCI is not set
-CONFIG_NO_DMA=y
 CONFIG_DTC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
@@ -58,7 +56,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -96,6 +93,8 @@ CONFIG_SLAB=y
 # CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
@@ -209,11 +208,14 @@ CONFIG_PROC_DEVICETREE=y
 #
 # Advanced setup
 #
+# CONFIG_ADVANCED_OPTIONS is not set
 
 #
 # Default settings for advanced configuration options are used
 #
+CONFIG_LOWMEM_SIZE=0x30000000
 CONFIG_KERNEL_START=0x90000000
+CONFIG_TASK_SIZE=0x80000000
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -235,13 +237,20 @@ CONFIG_BINFMT_FLAT=y
 # CONFIG_BINFMT_SHARED_FLAT is not set
 # CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
+
+#
+# Bus Options
+#
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_NET=y
 
 #
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -413,6 +422,7 @@ CONFIG_MTD_UCLINUX=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
 CONFIG_OF_DEVICE=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
@@ -442,6 +452,7 @@ CONFIG_MISC_DEVICES=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -458,6 +469,7 @@ CONFIG_NETDEVICES=y
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# CONFIG_ETHOC is not set
 # CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
@@ -466,6 +478,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
 # CONFIG_KS8851_MLL is not set
 # CONFIG_XILINX_EMACLITE is not set
@@ -516,6 +529,7 @@ CONFIG_SERIAL_UARTLITE=y
 CONFIG_SERIAL_UARTLITE_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -544,6 +558,12 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # 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
@@ -593,6 +613,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
@@ -661,6 +682,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -689,6 +711,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -733,6 +756,7 @@ CONFIG_DEBUG_OBJECTS_TIMERS=y
 # CONFIG_DEBUG_OBJECTS_WORK is not set
 CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
 # 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
@@ -758,6 +782,7 @@ CONFIG_DEBUG_SG=y
 # 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
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -782,6 +807,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_EARLY_PRINTK=y
 # CONFIG_HEART_BEAT is not set
@@ -901,5 +927,6 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_ZLIB_INFLATE=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
index e52210891d78ed167a71e24ca35c1cd9abee6bf4..4efe96a036f74a7ce058f563d44c21f46c0cc374 100644 (file)
@@ -15,7 +15,7 @@
 
 #include <asm/registers.h>
 
-#define L1_CACHE_SHIFT 2
+#define L1_CACHE_SHIFT 5
 /* word-granular cache in microblaze */
 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
 
index 78a038452c0faa0106f3a0f7bb48e50e811c91da..402b46e630f6d5acb6490b92a047264ce17ec802 100644 (file)
@@ -14,6 +14,10 @@ struct device_node;
 struct dev_archdata {
        /* Optional pointer to an OF device node */
        struct device_node      *of_node;
+
+       /* DMA operations on that device */
+       struct dma_map_ops      *dma_ops;
+       void                    *dma_data;
 };
 
 struct pdev_archdata {
index d00e40099165b7075ef8efd35df050f06246fce2..18b3731c850987fef9654bdc6b4d00652a1964cd 100644 (file)
@@ -1 +1,153 @@
-#include <asm-generic/dma-mapping-broken.h>
+/*
+ * Implements the generic device dma API for microblaze and the pci
+ *
+ * Copyright (C) 2009-2010 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2009-2010 PetaLogix
+ *
+ * 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.
+ *
+ * This file is base on powerpc and x86 dma-mapping.h versions
+ * Copyright (C) 2004 IBM
+ */
+
+#ifndef _ASM_MICROBLAZE_DMA_MAPPING_H
+#define _ASM_MICROBLAZE_DMA_MAPPING_H
+
+/*
+ * See Documentation/PCI/PCI-DMA-mapping.txt and
+ * Documentation/DMA-API.txt for documentation.
+ */
+
+#include <linux/types.h>
+#include <linux/cache.h>
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-debug.h>
+#include <linux/dma-attrs.h>
+#include <asm/io.h>
+#include <asm-generic/dma-coherent.h>
+
+#define DMA_ERROR_CODE         (~(dma_addr_t)0x0)
+
+#define __dma_alloc_coherent(dev, gfp, size, handle)   NULL
+#define __dma_free_coherent(size, addr)                ((void)0)
+#define __dma_sync(addr, size, rw)             ((void)0)
+
+static inline unsigned long device_to_mask(struct device *dev)
+{
+       if (dev->dma_mask && *dev->dma_mask)
+               return *dev->dma_mask;
+       /* Assume devices without mask can take 32 bit addresses */
+       return 0xfffffffful;
+}
+
+extern struct dma_map_ops *dma_ops;
+
+/*
+ * Available generic sets of operations
+ */
+extern struct dma_map_ops dma_direct_ops;
+
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+       /* We don't handle the NULL dev case for ISA for now. We could
+        * do it via an out of line call but it is not needed for now. The
+        * only ISA DMA device we support is the floppy and we have a hack
+        * in the floppy driver directly to get a device for us.
+        */
+       if (unlikely(!dev) || !dev->archdata.dma_ops)
+               return NULL;
+
+       return dev->archdata.dma_ops;
+}
+
+static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
+{
+       dev->archdata.dma_ops = ops;
+}
+
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       if (unlikely(!ops))
+               return 0;
+       if (!ops->dma_supported)
+               return 1;
+       return ops->dma_supported(dev, mask);
+}
+
+#ifdef CONFIG_PCI
+/* We have our own implementation of pci_set_dma_mask() */
+#define HAVE_ARCH_PCI_SET_DMA_MASK
+
+#endif
+
+static inline int dma_set_mask(struct device *dev, u64 dma_mask)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       if (unlikely(ops == NULL))
+               return -EIO;
+       if (ops->set_dma_mask)
+               return ops->set_dma_mask(dev, dma_mask);
+       if (!dev->dma_mask || !dma_supported(dev, dma_mask))
+               return -EIO;
+       *dev->dma_mask = dma_mask;
+       return 0;
+}
+
+#include <asm-generic/dma-mapping-common.h>
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+       if (ops->mapping_error)
+               return ops->mapping_error(dev, dma_addr);
+
+       return (dma_addr == DMA_ERROR_CODE);
+}
+
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_is_consistent(d, h)        (1)
+
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+                                       dma_addr_t *dma_handle, gfp_t flag)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+       void *memory;
+
+       BUG_ON(!ops);
+
+       memory = ops->alloc_coherent(dev, size, dma_handle, flag);
+
+       debug_dma_alloc_coherent(dev, size, *dma_handle, memory);
+       return memory;
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+                                    void *cpu_addr, dma_addr_t dma_handle)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       BUG_ON(!ops);
+       debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
+       ops->free_coherent(dev, size, cpu_addr, dma_handle);
+}
+
+static inline int dma_get_cache_alignment(void)
+{
+       return L1_CACHE_BYTES;
+}
+
+static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+               enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+       __dma_sync(vaddr, size, (int)direction);
+}
+
+#endif /* _ASM_MICROBLAZE_DMA_MAPPING_H */
index 08c073badf198f3296b384742b98a31a1ab9b408..0d73d0c6de37c275341f4a8c050fc75cf61019fa 100644 (file)
 #define MAX_DMA_ADDRESS (CONFIG_KERNEL_START + memory_size - 1)
 #endif
 
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy     (0)
+#endif
+
 #endif /* _ASM_MICROBLAZE_DMA_H */
index 90731df9e574c30bd8684272be6f11250147997c..4c7b5d037c88ad8fd974cbe03cd660a630ee976d 100644 (file)
@@ -64,12 +64,6 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
 void die(const char *str, struct pt_regs *fp, long err);
 void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr);
 
-#ifdef CONFIG_MMU
-void __bug(const char *file, int line, void *data);
-int bad_trap(int trap_num, struct pt_regs *regs);
-int debug_trap(struct pt_regs *regs);
-#endif /* CONFIG_MMU */
-
 #if defined(CONFIG_KGDB)
 void (*debugger)(struct pt_regs *regs);
 int (*debugger_bpt)(struct pt_regs *regs);
index 8dbb6e7a03a2183c135656ca4fee82e302223885..ad3fd61b2fe7eff6689e72a9e6936093e226740d 100644 (file)
@@ -55,7 +55,7 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
                __futex_atomic_op("or %1,%0,%4;", ret, oldval, uaddr, oparg);
                break;
        case FUTEX_OP_ANDN:
-               __futex_atomic_op("and %1,%0,%4;", ret, oldval, uaddr, oparg);
+               __futex_atomic_op("andn %1,%0,%4;", ret, oldval, uaddr, oparg);
                break;
        case FUTEX_OP_XOR:
                __futex_atomic_op("xor %1,%0,%4;", ret, oldval, uaddr, oparg);
index 267c7c779e537b1be0c475abaca0719170f54b1f..00b5398d08c79336761eaaf9954d1c260597459a 100644 (file)
 #include <asm/page.h>
 #include <linux/types.h>
 #include <linux/mm.h>          /* Get struct page {...} */
+#include <asm-generic/iomap.h>
 
+#ifndef CONFIG_PCI
+#define _IO_BASE       0
+#define _ISA_MEM_BASE  0
+#define PCI_DRAM_OFFSET        0
+#else
+#define _IO_BASE       isa_io_base
+#define _ISA_MEM_BASE  isa_mem_base
+#define PCI_DRAM_OFFSET        pci_dram_offset
+#endif
+
+extern unsigned long isa_io_base;
+extern unsigned long pci_io_base;
+extern unsigned long pci_dram_offset;
+
+extern resource_size_t isa_mem_base;
 
 #define IO_SPACE_LIMIT (0xFFFFFFFF)
 
@@ -92,6 +108,11 @@ static inline void writel(unsigned int v, volatile void __iomem *addr)
 #define iowrite16(v, addr)     __raw_writew((u16)(v), (u16 *)(addr))
 #define iowrite32(v, addr)     __raw_writel((u32)(v), (u32 *)(addr))
 
+#define ioread16be(addr)       __raw_readw((u16 *)(addr))
+#define ioread32be(addr)       __raw_readl((u32 *)(addr))
+#define iowrite16be(v, addr)   __raw_writew((u16)(v), (u16 *)(addr))
+#define iowrite32be(v, addr)   __raw_writel((u32)(v), (u32 *)(addr))
+
 /* These are the definitions for the x86 IO instructions
  * inb/inw/inl/outb/outw/outl, the "string" versions
  * insb/insw/insl/outsb/outsw/outsl, and the "pausing" versions
@@ -118,15 +139,10 @@ static inline void writel(unsigned int v, volatile void __iomem *addr)
 
 #ifdef CONFIG_MMU
 
-#define mm_ptov(addr)          ((void *)__phys_to_virt(addr))
-#define mm_vtop(addr)          ((unsigned long)__virt_to_phys(addr))
 #define phys_to_virt(addr)     ((void *)__phys_to_virt(addr))
 #define virt_to_phys(addr)     ((unsigned long)__virt_to_phys(addr))
 #define virt_to_bus(addr)      ((unsigned long)__virt_to_phys(addr))
 
-#define __page_address(page) \
-               (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
-#define page_to_phys(page)     virt_to_phys((void *)__page_address(page))
 #define page_to_bus(page)      (page_to_phys(page))
 #define bus_to_virt(addr)      (phys_to_virt(addr))
 
@@ -227,15 +243,7 @@ static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size,
 #define out_8(a, v) __raw_writeb((v), (a))
 #define in_8(a) __raw_readb(a)
 
-/* FIXME */
-static inline void __iomem *ioport_map(unsigned long port, unsigned int len)
-{
-       return (void __iomem *) (port);
-}
-
-static inline void ioport_unmap(void __iomem *addr)
-{
-       /* Nothing to do */
-}
+#define ioport_map(port, nr)   ((void __iomem *)(port))
+#define ioport_unmap(addr)
 
 #endif /* _ASM_MICROBLAZE_IO_H */
index 90f050535ebef0f51881fdc451bac5df84816a9d..31a35c33df6302c2be2509b777d262e24c02445d 100644 (file)
 
 #include <linux/interrupt.h>
 
+/* This type is the placeholder for a hardware interrupt number. It has to
+ * be big enough to enclose whatever representation is used by a given
+ * platform.
+ */
+typedef unsigned long irq_hw_number_t;
+
 extern unsigned int nr_irq;
 
 #define NO_IRQ (-1)
@@ -21,7 +27,8 @@ extern unsigned int nr_irq;
 struct pt_regs;
 extern void do_IRQ(struct pt_regs *regs);
 
-/* irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
+/**
+ * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
  * @device: Device node of the device whose interrupt is to be mapped
  * @index: Index of the interrupt to map
  *
@@ -40,4 +47,32 @@ static inline void irq_dispose_mapping(unsigned int virq)
        return;
 }
 
+struct irq_host;
+
+/**
+ * irq_create_mapping - Map a hardware interrupt into linux virq space
+ * @host: host owning this hardware interrupt or NULL for default host
+ * @hwirq: hardware irq number in that host space
+ *
+ * Only one mapping per hardware interrupt is permitted. Returns a linux
+ * virq number.
+ * If the sense/trigger is to be specified, set_irq_type() should be called
+ * on the number returned from that call.
+ */
+extern unsigned int irq_create_mapping(struct irq_host *host,
+                                       irq_hw_number_t hwirq);
+
+/**
+ * irq_create_of_mapping - Map a hardware interrupt into linux virq space
+ * @controller: Device node of the interrupt controller
+ * @inspec: Interrupt specifier from the device-tree
+ * @intsize: Size of the interrupt specifier from the device-tree
+ *
+ * This function is identical to irq_create_mapping except that it takes
+ * as input informations straight from the device-tree (typically the results
+ * of the of_irq_map_*() functions.
+ */
+extern unsigned int irq_create_of_mapping(struct device_node *controller,
+                                       u32 *intspec, unsigned int intsize);
+
 #endif /* _ASM_MICROBLAZE_IRQ_H */
index 9b66c0fa9a32caf5ba14e7f0c9478119808a0759..de493f86d28f7884b2adb7a625c0848a38aa6b74 100644 (file)
@@ -31,6 +31,9 @@
 
 #ifndef __ASSEMBLY__
 
+/* MS be sure that SLAB allocates aligned objects */
+#define ARCH_KMALLOC_MINALIGN  L1_CACHE_BYTES
+
 #define PAGE_UP(addr)  (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1)))
 #define PAGE_DOWN(addr)        ((addr)&(~((PAGE_SIZE)-1)))
 
@@ -61,12 +64,6 @@ extern unsigned int __page_offset;
  */
 #define PAGE_OFFSET    CONFIG_KERNEL_START
 
-/*
- * MAP_NR -- given an address, calculate the index of the page struct which
- * points to the address's page.
- */
-#define MAP_NR(addr) (((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT)
-
 /*
  * The basic type of a PTE - 32 bit physical addressing.
  */
@@ -76,14 +73,7 @@ typedef unsigned long pte_basic_t;
 
 #endif /* CONFIG_MMU */
 
-#  ifndef CONFIG_MMU
-#  define copy_page(to, from)                  memcpy((to), (from), PAGE_SIZE)
-#  define get_user_page(vaddr)                 __get_free_page(GFP_KERNEL)
-#  define free_user_page(page, addr)           free_page(addr)
-#  else /* CONFIG_MMU */
-extern void copy_page(void *to, void *from);
-#  endif /* CONFIG_MMU */
-
+# define copy_page(to, from)                   memcpy((to), (from), PAGE_SIZE)
 # define clear_page(pgaddr)                    memset((pgaddr), 0, PAGE_SIZE)
 
 # define clear_user_page(pgaddr, vaddr, page)  memset((pgaddr), 0, PAGE_SIZE)
@@ -154,7 +144,11 @@ extern int page_is_ram(unsigned long pfn);
 # define pfn_to_virt(pfn)      __va(pfn_to_phys((pfn)))
 
 #  ifdef CONFIG_MMU
-#  define virt_to_page(kaddr)  (mem_map +  MAP_NR(kaddr))
+
+#  define virt_to_page(kaddr)  (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT))
+#  define page_to_virt(page)   __va(page_to_pfn(page) << PAGE_SHIFT)
+#  define page_to_phys(page)     (page_to_pfn(page) << PAGE_SHIFT)
+
 #  else /* CONFIG_MMU */
 #  define virt_to_page(vaddr)  (pfn_to_page(virt_to_pfn(vaddr)))
 #  define page_to_virt(page)   (pfn_to_virt(page_to_pfn(page)))
index 7ad28f6f5f1a841fae1adf43a6b7518e863a0210..0c77cda9f5d80eb6de7b003c09c05ce7a1fea97b 100644 (file)
@@ -1 +1,196 @@
+#ifndef _ASM_MICROBLAZE_PCI_BRIDGE_H
+#define _ASM_MICROBLAZE_PCI_BRIDGE_H
+#ifdef __KERNEL__
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
 #include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/ioport.h>
+
+struct device_node;
+
+enum {
+       /* Force re-assigning all resources (ignore firmware
+        * setup completely)
+        */
+       PCI_REASSIGN_ALL_RSRC   = 0x00000001,
+
+       /* Re-assign all bus numbers */
+       PCI_REASSIGN_ALL_BUS    = 0x00000002,
+
+       /* Do not try to assign, just use existing setup */
+       PCI_PROBE_ONLY          = 0x00000004,
+
+       /* Don't bother with ISA alignment unless the bridge has
+        * ISA forwarding enabled
+        */
+       PCI_CAN_SKIP_ISA_ALIGN  = 0x00000008,
+
+       /* Enable domain numbers in /proc */
+       PCI_ENABLE_PROC_DOMAINS = 0x00000010,
+       /* ... except for domain 0 */
+       PCI_COMPAT_DOMAIN_0             = 0x00000020,
+};
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct pci_controller {
+       struct pci_bus *bus;
+       char is_dynamic;
+       struct device_node *dn;
+       struct list_head list_node;
+       struct device *parent;
+
+       int first_busno;
+       int last_busno;
+
+       int self_busno;
+
+       void __iomem *io_base_virt;
+       resource_size_t io_base_phys;
+
+       resource_size_t pci_io_size;
+
+       /* Some machines (PReP) have a non 1:1 mapping of
+        * the PCI memory space in the CPU bus space
+        */
+       resource_size_t pci_mem_offset;
+
+       /* Some machines have a special region to forward the ISA
+        * "memory" cycles such as VGA memory regions. Left to 0
+        * if unsupported
+        */
+       resource_size_t isa_mem_phys;
+       resource_size_t isa_mem_size;
+
+       struct pci_ops *ops;
+       unsigned int __iomem *cfg_addr;
+       void __iomem *cfg_data;
+
+       /*
+        * Used for variants of PCI indirect handling and possible quirks:
+        *  SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
+        *  EXT_REG - provides access to PCI-e extended registers
+        *  SURPRESS_PRIMARY_BUS - we surpress the setting of PCI_PRIMARY_BUS
+        *   on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS
+        *   to determine which bus number to match on when generating type0
+        *   config cycles
+        *  NO_PCIE_LINK - the Freescale PCI-e controllers have issues with
+        *   hanging if we don't have link and try to do config cycles to
+        *   anything but the PHB.  Only allow talking to the PHB if this is
+        *   set.
+        *  BIG_ENDIAN - cfg_addr is a big endian register
+        *  BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs
+        *   on the PLB4.  Effectively disable MRM commands by setting this.
+        */
+#define INDIRECT_TYPE_SET_CFG_TYPE             0x00000001
+#define INDIRECT_TYPE_EXT_REG          0x00000002
+#define INDIRECT_TYPE_SURPRESS_PRIMARY_BUS     0x00000004
+#define INDIRECT_TYPE_NO_PCIE_LINK             0x00000008
+#define INDIRECT_TYPE_BIG_ENDIAN               0x00000010
+#define INDIRECT_TYPE_BROKEN_MRM               0x00000020
+       u32 indirect_type;
+
+       /* Currently, we limit ourselves to 1 IO range and 3 mem
+        * ranges since the common pci_bus structure can't handle more
+        */
+       struct resource io_resource;
+       struct resource mem_resources[3];
+       int global_number;      /* PCI domain number */
+};
+
+static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
+{
+       return bus->sysdata;
+}
+
+static inline int isa_vaddr_is_ioport(void __iomem *address)
+{
+       /* No specific ISA handling on ppc32 at this stage, it
+        * all goes through PCI
+        */
+       return 0;
+}
+
+/* These are used for config access before all the PCI probing
+   has been done. */
+extern int early_read_config_byte(struct pci_controller *hose, int bus,
+                       int dev_fn, int where, u8 *val);
+extern int early_read_config_word(struct pci_controller *hose, int bus,
+                       int dev_fn, int where, u16 *val);
+extern int early_read_config_dword(struct pci_controller *hose, int bus,
+                       int dev_fn, int where, u32 *val);
+extern int early_write_config_byte(struct pci_controller *hose, int bus,
+                       int dev_fn, int where, u8 val);
+extern int early_write_config_word(struct pci_controller *hose, int bus,
+                       int dev_fn, int where, u16 val);
+extern int early_write_config_dword(struct pci_controller *hose, int bus,
+                       int dev_fn, int where, u32 val);
+
+extern int early_find_capability(struct pci_controller *hose, int bus,
+                                int dev_fn, int cap);
+
+extern void setup_indirect_pci(struct pci_controller *hose,
+                              resource_size_t cfg_addr,
+                              resource_size_t cfg_data, u32 flags);
+
+/* Get the PCI host controller for an OF device */
+extern struct pci_controller *pci_find_hose_for_OF_device(
+                       struct device_node *node);
+
+/* Fill up host controller resources from the OF node */
+extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
+                       struct device_node *dev, int primary);
+
+/* Allocate & free a PCI host bridge structure */
+extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev);
+extern void pcibios_free_controller(struct pci_controller *phb);
+extern void pcibios_setup_phb_resources(struct pci_controller *hose);
+
+#ifdef CONFIG_PCI
+extern unsigned int pci_flags;
+
+static inline void pci_set_flags(int flags)
+{
+       pci_flags = flags;
+}
+
+static inline void pci_add_flags(int flags)
+{
+       pci_flags |= flags;
+}
+
+static inline int pci_has_flag(int flag)
+{
+       return pci_flags & flag;
+}
+
+extern struct list_head hose_list;
+
+extern unsigned long pci_address_to_pio(phys_addr_t address);
+extern int pcibios_vaddr_is_ioport(void __iomem *address);
+#else
+static inline unsigned long pci_address_to_pio(phys_addr_t address)
+{
+       return (unsigned long)-1;
+}
+static inline int pcibios_vaddr_is_ioport(void __iomem *address)
+{
+       return 0;
+}
+
+static inline void pci_set_flags(int flags) { }
+static inline void pci_add_flags(int flags) { }
+static inline int pci_has_flag(int flag)
+{
+       return 0;
+}
+#endif /* CONFIG_PCI */
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_PCI_BRIDGE_H */
index 9f0df5faf2c88d1d89b37ba56c7b535e0e29f4ba..5a388eeeb28fa3735912e741efb6389de28877c2 100644 (file)
@@ -1 +1,169 @@
-#include <asm-generic/pci.h>
+/*
+ * 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.
+ *
+ * Based on powerpc version
+ */
+
+#ifndef __ASM_MICROBLAZE_PCI_H
+#define __ASM_MICROBLAZE_PCI_H
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+
+#include <asm/scatterlist.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+
+#define PCIBIOS_MIN_IO         0x1000
+#define PCIBIOS_MIN_MEM                0x10000000
+
+struct pci_dev;
+
+/* Values for the `which' argument to sys_pciconfig_iobase syscall.  */
+#define IOBASE_BRIDGE_NUMBER   0
+#define IOBASE_MEMORY          1
+#define IOBASE_IO              2
+#define IOBASE_ISA_IO          3
+#define IOBASE_ISA_MEM         4
+
+#define pcibios_scan_all_fns(a, b)     0
+
+/*
+ * Set this to 1 if you want the kernel to re-assign all PCI
+ * bus numbers (don't do that on ppc64 yet !)
+ */
+#define pcibios_assign_all_busses() \
+       (pci_has_flag(PCI_REASSIGN_ALL_BUS))
+
+static inline void pcibios_set_master(struct pci_dev *dev)
+{
+       /* No special bus mastering setup handling */
+}
+
+static inline void pcibios_penalize_isa_irq(int irq, int active)
+{
+       /* We don't do dynamic PCI IRQ allocation */
+}
+
+#ifdef CONFIG_PCI
+extern void set_pci_dma_ops(struct dma_map_ops *dma_ops);
+extern struct dma_map_ops *get_pci_dma_ops(void);
+#else  /* CONFIG_PCI */
+#define set_pci_dma_ops(d)
+#define get_pci_dma_ops()      NULL
+#endif
+
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+                                       enum pci_dma_burst_strategy *strat,
+                                       unsigned long *strategy_parameter)
+{
+       *strat = PCI_DMA_BURST_INFINITY;
+       *strategy_parameter = ~0UL;
+}
+#endif
+
+extern int pci_domain_nr(struct pci_bus *bus);
+
+/* Decide whether to display the domain number in /proc */
+extern int pci_proc_domain(struct pci_bus *bus);
+
+struct vm_area_struct;
+/* Map a range of PCI memory or I/O space for a device into user space */
+int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
+                       enum pci_mmap_state mmap_state, int write_combine);
+
+/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
+#define HAVE_PCI_MMAP  1
+
+extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val,
+                          size_t count);
+extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val,
+                          size_t count);
+extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
+                                     struct vm_area_struct *vma,
+                                     enum pci_mmap_state mmap_state);
+
+#define HAVE_PCI_LEGACY        1
+
+/* The PCI address space does equal the physical memory
+ * address space (no IOMMU).  The IDE and SCSI device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS     (1)
+
+extern void pcibios_resource_to_bus(struct pci_dev *dev,
+                       struct pci_bus_region *region,
+                       struct resource *res);
+
+extern void pcibios_bus_to_resource(struct pci_dev *dev,
+                       struct resource *res,
+                       struct pci_bus_region *region);
+
+static inline struct resource *pcibios_select_root(struct pci_dev *pdev,
+                       struct resource *res)
+{
+       struct resource *root = NULL;
+
+       if (res->flags & IORESOURCE_IO)
+               root = &ioport_resource;
+       if (res->flags & IORESOURCE_MEM)
+               root = &iomem_resource;
+
+       return root;
+}
+
+extern void pcibios_claim_one_bus(struct pci_bus *b);
+
+extern void pcibios_finish_adding_to_bus(struct pci_bus *bus);
+
+extern void pcibios_resource_survey(void);
+
+extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
+extern int remove_phb_dynamic(struct pci_controller *phb);
+
+extern struct pci_dev *of_create_pci_dev(struct device_node *node,
+                                       struct pci_bus *bus, int devfn);
+
+extern void of_scan_pci_bridge(struct device_node *node,
+                               struct pci_dev *dev);
+
+extern void of_scan_bus(struct device_node *node, struct pci_bus *bus);
+extern void of_rescan_bus(struct device_node *node, struct pci_bus *bus);
+
+extern int pci_read_irq_line(struct pci_dev *dev);
+
+extern int pci_bus_find_capability(struct pci_bus *bus,
+                                               unsigned int devfn, int cap);
+
+struct file;
+extern pgprot_t        pci_phys_mem_access_prot(struct file *file,
+                                        unsigned long pfn,
+                                        unsigned long size,
+                                        pgprot_t prot);
+
+#define HAVE_ARCH_PCI_RESOURCE_TO_USER
+extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
+                                const struct resource *rsrc,
+                                resource_size_t *start, resource_size_t *end);
+
+extern void pcibios_setup_bus_devices(struct pci_bus *bus);
+extern void pcibios_setup_bus_self(struct pci_bus *bus);
+
+/* This part of code was originaly in xilinx-pci.h */
+#ifdef CONFIG_PCI_XILINX
+extern void __init xilinx_pci_init(void);
+#else
+static inline void __init xilinx_pci_init(void) { return; }
+#endif
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_MICROBLAZE_PCI_H */
index 7547f50645608c9c34170e9680d3072b9e636a8d..c614a893f8a3d40179be89d162a2879bfff19db9 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/io.h>
 #include <asm/page.h>
 #include <asm/cache.h>
+#include <asm/pgtable.h>
 
 #define PGDIR_ORDER    0
 
@@ -107,22 +108,7 @@ extern inline void free_pgd_slow(pgd_t *pgd)
 #define pmd_alloc_one_fast(mm, address)        ({ BUG(); ((pmd_t *)1); })
 #define pmd_alloc_one(mm, address)     ({ BUG(); ((pmd_t *)2); })
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-               unsigned long address)
-{
-       pte_t *pte;
-       extern int mem_init_done;
-       extern void *early_get_page(void);
-       if (mem_init_done) {
-               pte = (pte_t *)__get_free_page(GFP_KERNEL |
-                                       __GFP_REPEAT | __GFP_ZERO);
-       } else {
-               pte = (pte_t *)early_get_page();
-               if (pte)
-                       clear_page(pte);
-       }
-       return pte;
-}
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
 
 static inline struct page *pte_alloc_one(struct mm_struct *mm,
                unsigned long address)
index cc3a4dfc3eaa94c75dcc37f396a52b8edc373086..ca2d92871545821affe833848788e976b8c2f09a 100644 (file)
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)                \
                remap_pfn_range(vma, vaddr, pfn, size, prot)
 
+#ifndef __ASSEMBLY__
+extern int mem_init_done;
+#endif
+
 #ifndef CONFIG_MMU
 
 #define pgd_present(pgd)       (1) /* pages are always present on non MMU */
@@ -51,6 +55,8 @@ static inline int pte_file(pte_t pte) { return 0; }
 
 #define arch_enter_lazy_cpu_mode()     do {} while (0)
 
+#define pgprot_noncached_wc(prot)      prot
+
 #else /* CONFIG_MMU */
 
 #include <asm-generic/4level-fixup.h>
@@ -68,7 +74,6 @@ static inline int pte_file(pte_t pte) { return 0; }
 
 extern unsigned long va_to_phys(unsigned long address);
 extern pte_t *va_to_pte(unsigned long address);
-extern unsigned long ioremap_bot, ioremap_base;
 
 /*
  * The following only work if pte_present() is true.
@@ -85,10 +90,24 @@ static inline pte_t pte_mkspecial(pte_t pte)        { return pte; }
 #define VMALLOC_START  (CONFIG_KERNEL_START + \
                                max(32 * 1024 * 1024UL, memory_size))
 #define VMALLOC_END    ioremap_bot
-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
 
 #endif /* __ASSEMBLY__ */
 
+/*
+ * Macro to mark a page protection value as "uncacheable".
+ */
+
+#define _PAGE_CACHE_CTL        (_PAGE_GUARDED | _PAGE_NO_CACHE | \
+                                                       _PAGE_WRITETHRU)
+
+#define pgprot_noncached(prot) \
+                       (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
+                                       _PAGE_NO_CACHE | _PAGE_GUARDED))
+
+#define pgprot_noncached_wc(prot) \
+                        (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
+                                                       _PAGE_NO_CACHE))
+
 /*
  * The MicroBlaze MMU is identical to the PPC-40x MMU, and uses a hash
  * table containing PTEs, together with a set of 16 segment registers, to
@@ -397,7 +416,7 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr,
        mts     rmsr, %2\n\
        nop"
        : "=&r" (old), "=&r" (tmp), "=&r" (msr), "=m" (*p)
-       : "r" ((unsigned long)(p+1) - 4), "r" (clr), "r" (set), "m" (*p)
+       : "r" ((unsigned long)(p + 1) - 4), "r" (clr), "r" (set), "m" (*p)
        : "cc");
 
        return old;
@@ -492,15 +511,6 @@ static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
 
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 
-/*
- * When flushing the tlb entry for a page, we also need to flush the hash
- * table entry.  flush_hash_page is assembler (for speed) in hashtable.S.
- */
-extern int flush_hash_page(unsigned context, unsigned long va, pte_t *ptep);
-
-/* Add an HPTE to the hash table */
-extern void add_hash_page(unsigned context, unsigned long va, pte_t *ptep);
-
 /*
  * Encode and decode a swap entry.
  * Note that the bits we use in a PTE for representing a swap entry
@@ -514,15 +524,7 @@ extern void add_hash_page(unsigned context, unsigned long va, pte_t *ptep);
 #define __pte_to_swp_entry(pte)        ((swp_entry_t) { pte_val(pte) >> 2 })
 #define __swp_entry_to_pte(x)  ((pte_t) { (x).val << 2 })
 
-
-/* CONFIG_APUS */
-/* For virtual address to physical address conversion */
-extern void cache_clear(__u32 addr, int length);
-extern void cache_push(__u32 addr, int length);
-extern int mm_end_of_chunk(unsigned long addr, int len);
 extern unsigned long iopa(unsigned long addr);
-/* extern unsigned long mm_ptov(unsigned long addr) \
-       __attribute__ ((const)); TBD */
 
 /* Values for nocacheflag and cmode */
 /* These are not used by the APUS kernel_map, but prevents
@@ -533,18 +535,6 @@ extern unsigned long iopa(unsigned long addr);
 #define        IOMAP_NOCACHE_NONSER    2
 #define        IOMAP_NO_COPYBACK       3
 
-/*
- * Map some physical address range into the kernel address space.
- */
-extern unsigned long kernel_map(unsigned long paddr, unsigned long size,
-                               int nocacheflag, unsigned long *memavailp);
-
-/*
- * Set cache mode of (kernel space) address range.
- */
-extern void kernel_set_cachemode(unsigned long address, unsigned long size,
-                               unsigned int cmode);
-
 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
 #define kern_addr_valid(addr)  (1)
 
@@ -558,26 +548,15 @@ extern void kernel_set_cachemode(unsigned long address, unsigned long size,
 void do_page_fault(struct pt_regs *regs, unsigned long address,
                   unsigned long error_code);
 
-void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
-                            unsigned int size, int flags);
-
-void __init adjust_total_lowmem(void);
 void mapin_ram(void);
 int map_page(unsigned long va, phys_addr_t pa, int flags);
 
 extern int mem_init_done;
-extern unsigned long ioremap_base;
-extern unsigned long ioremap_bot;
 
 asmlinkage void __init mmu_init(void);
 
 void __init *early_get_page(void);
 
-void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle);
-void consistent_free(void *vaddr);
-void consistent_sync(void *vaddr, size_t size, int direction);
-void consistent_sync_page(struct page *page, unsigned long offset,
-       size_t size, int direction);
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
@@ -586,6 +565,14 @@ void consistent_sync_page(struct page *page, unsigned long offset,
 #ifndef __ASSEMBLY__
 #include <asm-generic/pgtable.h>
 
+extern unsigned long ioremap_bot, ioremap_base;
+
+void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle);
+void consistent_free(size_t size, void *vaddr);
+void consistent_sync(void *vaddr, size_t size, int direction);
+void consistent_sync_page(struct page *page, unsigned long offset,
+       size_t size, int direction);
+
 void setup_memory(void);
 #endif /* __ASSEMBLY__ */
 
index 563c6b9453f030a34344cf0e9d63f1a5dd994318..8eeb09211ece1b7f32fc31b6655a2cd8628d0ea6 100644 (file)
@@ -14,7 +14,6 @@
 #include <asm/ptrace.h>
 #include <asm/setup.h>
 #include <asm/registers.h>
-#include <asm/segment.h>
 #include <asm/entry.h>
 #include <asm/current.h>
 
index 03f45a96320412b7a21ac2243f305608b8acae59..e7d67a329bd7d9046004a204864e277bdee92053 100644 (file)
 /* Other Prototypes */
 extern int early_uartlite_console(void);
 
+#ifdef CONFIG_PCI
+/*
+ * PCI <-> OF matching functions
+ * (XXX should these be here?)
+ */
+struct pci_bus;
+struct pci_dev;
+extern int pci_device_from_OF_node(struct device_node *node,
+                                       u8 *bus, u8 *devfn);
+extern struct device_node *pci_busdev_to_OF_node(struct pci_bus *bus,
+                                                       int devfn);
+extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev);
+extern void pci_create_OF_bus_map(void);
+#endif
+
 /*
  * OF address retreival & translation
  */
diff --git a/arch/microblaze/include/asm/segment.h b/arch/microblaze/include/asm/segment.h
deleted file mode 100644 (file)
index 0e7102c..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
- * Copyright (C) 2008-2009 PetaLogix
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * 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.
- */
-
-#ifndef _ASM_MICROBLAZE_SEGMENT_H
-#define _ASM_MICROBLAZE_SEGMENT_H
-
-# ifndef __ASSEMBLY__
-
-typedef struct {
-       unsigned long seg;
-} mm_segment_t;
-
-/*
- * On Microblaze the fs value is actually the top of the corresponding
- * address space.
- *
- * The fs value determines whether argument validity checking should be
- * performed or not. If get_fs() == USER_DS, checking is performed, with
- * get_fs() == KERNEL_DS, checking is bypassed.
- *
- * For historical reasons, these macros are grossly misnamed.
- *
- * For non-MMU arch like Microblaze, KERNEL_DS and USER_DS is equal.
- */
-# define MAKE_MM_SEG(s)       ((mm_segment_t) { (s) })
-
-#  ifndef CONFIG_MMU
-#  define KERNEL_DS    MAKE_MM_SEG(0)
-#  define USER_DS      KERNEL_DS
-#  else
-#  define KERNEL_DS    MAKE_MM_SEG(0xFFFFFFFF)
-#  define USER_DS      MAKE_MM_SEG(TASK_SIZE - 1)
-#  endif
-
-# define get_ds()      (KERNEL_DS)
-# define get_fs()      (current_thread_info()->addr_limit)
-# define set_fs(val)   (current_thread_info()->addr_limit = (val))
-
-# define segment_eq(a, b)      ((a).seg == (b).seg)
-
-# endif /* __ASSEMBLY__ */
-#endif /* _ASM_MICROBLAZE_SEGMENT_H */
index 157970688b2aba72037e94b4e08a96fc831184ac..59efb3fef9577d93d83ad2bf6ce7a15ab8128144 100644 (file)
@@ -87,6 +87,9 @@ void free_initmem(void);
 extern char *klimit;
 extern void ret_from_fork(void);
 
+extern void *alloc_maybe_bootmem(size_t size, gfp_t mask);
+extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
+
 #ifdef CONFIG_DEBUG_FS
 extern struct dentry *of_debugfs_root;
 #endif
index 6e92885d381a80ee3adc680632415c3911ecdb64..b2ca80f646403d683fa9d9a10e3ea79f67bafb0c 100644 (file)
@@ -19,7 +19,6 @@
 #ifndef __ASSEMBLY__
 # include <linux/types.h>
 # include <asm/processor.h>
-# include <asm/segment.h>
 
 /*
  * low level task data that entry.S needs immediate access to
@@ -60,6 +59,10 @@ struct cpu_context {
        __u32   fsr;
 };
 
+typedef struct {
+       unsigned long seg;
+} mm_segment_t;
+
 struct thread_info {
        struct task_struct      *task; /* main task structure */
        struct exec_domain      *exec_domain; /* execution domain */
index 10ec70cd8735446a2c5e0b938487fb6db0f6417a..2e1353c2d18d7d256a0d499ac3f6beae581a6dee 100644 (file)
@@ -23,7 +23,8 @@
 extern void _tlbie(unsigned long address);
 extern void _tlbia(void);
 
-#define __tlbia()      _tlbia()
+#define __tlbia()      { preempt_disable(); _tlbia(); preempt_enable(); }
+#define __tlbie(x)     { _tlbie(x); }
 
 static inline void local_flush_tlb_all(void)
        { __tlbia(); }
@@ -31,7 +32,7 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
        { __tlbia(); }
 static inline void local_flush_tlb_page(struct vm_area_struct *vma,
                                unsigned long vmaddr)
-       { _tlbie(vmaddr); }
+       { __tlbie(vmaddr); }
 static inline void local_flush_tlb_range(struct vm_area_struct *vma,
                unsigned long start, unsigned long end)
        { __tlbia(); }
index 371bd6e56d9a20e60624147a050366f9fd06d2ea..26460d15b338b65847bef4bd1925ca5a8ea40dff 100644 (file)
 #include <asm/mmu.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <asm/segment.h>
 #include <linux/string.h>
 
 #define VERIFY_READ    0
 #define VERIFY_WRITE   1
 
-#define __clear_user(addr, n)  (memset((void *)(addr), 0, (n)), 0)
-
-#ifndef CONFIG_MMU
-
-extern int ___range_ok(unsigned long addr, unsigned long size);
-
-#define __range_ok(addr, size) \
-               ___range_ok((unsigned long)(addr), (unsigned long)(size))
-
-#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0)
-#define __access_ok(add, size) (__range_ok((addr), (size)) == 0)
-
-/* Undefined function to trigger linker error */
-extern int bad_user_access_length(void);
-
-/* FIXME this is function for optimalization -> memcpy */
-#define __get_user(var, ptr)                           \
-({                                                     \
-       int __gu_err = 0;                               \
-       switch (sizeof(*(ptr))) {                       \
-       case 1:                                         \
-       case 2:                                         \
-       case 4:                                         \
-               (var) = *(ptr);                         \
-               break;                                  \
-       case 8:                                         \
-               memcpy((void *) &(var), (ptr), 8);      \
-               break;                                  \
-       default:                                        \
-               (var) = 0;                              \
-               __gu_err = __get_user_bad();            \
-               break;                                  \
-       }                                               \
-       __gu_err;                                       \
-})
+/*
+ * On Microblaze the fs value is actually the top of the corresponding
+ * address space.
+ *
+ * The fs value determines whether argument validity checking should be
+ * performed or not. If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ *
+ * For non-MMU arch like Microblaze, KERNEL_DS and USER_DS is equal.
+ */
+# define MAKE_MM_SEG(s)       ((mm_segment_t) { (s) })
 
-#define __get_user_bad()       (bad_user_access_length(), (-EFAULT))
+#  ifndef CONFIG_MMU
+#  define KERNEL_DS    MAKE_MM_SEG(0)
+#  define USER_DS      KERNEL_DS
+#  else
+#  define KERNEL_DS    MAKE_MM_SEG(0xFFFFFFFF)
+#  define USER_DS      MAKE_MM_SEG(TASK_SIZE - 1)
+#  endif
 
-/* FIXME is not there defined __pu_val */
-#define __put_user(var, ptr)                                   \
-({                                                             \
-       int __pu_err = 0;                                       \
-       switch (sizeof(*(ptr))) {                               \
-       case 1:                                                 \
-       case 2:                                                 \
-       case 4:                                                 \
-               *(ptr) = (var);                                 \
-               break;                                          \
-       case 8: {                                               \
-               typeof(*(ptr)) __pu_val = (var);                \
-               memcpy(ptr, &__pu_val, sizeof(__pu_val));       \
-               }                                               \
-               break;                                          \
-       default:                                                \
-               __pu_err = __put_user_bad();                    \
-               break;                                          \
-       }                                                       \
-       __pu_err;                                               \
-})
+# define get_ds()      (KERNEL_DS)
+# define get_fs()      (current_thread_info()->addr_limit)
+# define set_fs(val)   (current_thread_info()->addr_limit = (val))
 
-#define __put_user_bad()       (bad_user_access_length(), (-EFAULT))
+# define segment_eq(a, b)      ((a).seg == (b).seg)
 
-#define put_user(x, ptr)       __put_user((x), (ptr))
-#define get_user(x, ptr)       __get_user((x), (ptr))
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue. No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path. This means when everything is well,
+ * we don't even have to jump over them. Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+struct exception_table_entry {
+       unsigned long insn, fixup;
+};
 
-#define copy_to_user(to, from, n)      (memcpy((to), (from), (n)), 0)
-#define copy_from_user(to, from, n)    (memcpy((to), (from), (n)), 0)
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
 
-#define __copy_to_user(to, from, n)    (copy_to_user((to), (from), (n)))
-#define __copy_from_user(to, from, n)  (copy_from_user((to), (from), (n)))
-#define __copy_to_user_inatomic(to, from, n) \
-                       (__copy_to_user((to), (from), (n)))
-#define __copy_from_user_inatomic(to, from, n) \
-                       (__copy_from_user((to), (from), (n)))
+#ifndef CONFIG_MMU
 
-static inline unsigned long clear_user(void *addr, unsigned long size)
+/* Check against bounds of physical memory */
+static inline int ___range_ok(unsigned long addr, unsigned long size)
 {
-       if (access_ok(VERIFY_WRITE, addr, size))
-               size = __clear_user(addr, size);
-       return size;
+       return ((addr < memory_start) ||
+               ((addr + size) > memory_end));
 }
 
-/* Returns 0 if exception not found and fixup otherwise.  */
-extern unsigned long search_exception_table(unsigned long);
+#define __range_ok(addr, size) \
+               ___range_ok((unsigned long)(addr), (unsigned long)(size))
 
-extern long strncpy_from_user(char *dst, const char *src, long count);
-extern long strnlen_user(const char *src, long count);
+#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0)
 
-#else /* CONFIG_MMU */
+#else
 
 /*
  * Address is valid if:
@@ -129,22 +101,119 @@ extern long strnlen_user(const char *src, long count);
 /* || printk("access_ok failed for %s at 0x%08lx (size %d), seg 0x%08x\n",
  type?"WRITE":"READ",addr,size,get_fs().seg)) */
 
-/*
- * All the __XXX versions macros/functions below do not perform
- * access checking. It is assumed that the necessary checks have been
- * already performed before the finction (macro) is called.
- */
+#endif
 
-#define get_user(x, ptr)                                               \
-({                                                                     \
-       access_ok(VERIFY_READ, (ptr), sizeof(*(ptr)))                   \
-               ? __get_user((x), (ptr)) : -EFAULT;                     \
+#ifdef CONFIG_MMU
+# define __FIXUP_SECTION       ".section .fixup,\"ax\"\n"
+# define __EX_TABLE_SECTION    ".section __ex_table,\"a\"\n"
+#else
+# define __FIXUP_SECTION       ".section .discard,\"ax\"\n"
+# define __EX_TABLE_SECTION    ".section .discard,\"a\"\n"
+#endif
+
+extern unsigned long __copy_tofrom_user(void __user *to,
+               const void __user *from, unsigned long size);
+
+/* Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail. */
+static inline unsigned long __must_check __clear_user(void __user *to,
+                                                       unsigned long n)
+{
+       /* normal memset with two words to __ex_table */
+       __asm__ __volatile__ (                          \
+                       "1:     sb      r0, %2, r0;"    \
+                       "       addik   %0, %0, -1;"    \
+                       "       bneid   %0, 1b;"        \
+                       "       addik   %2, %2, 1;"     \
+                       "2:                     "       \
+                       __EX_TABLE_SECTION              \
+                       ".word  1b,2b;"                 \
+                       ".previous;"                    \
+               : "=r"(n)                               \
+               : "0"(n), "r"(to)
+       );
+       return n;
+}
+
+static inline unsigned long __must_check clear_user(void __user *to,
+                                                       unsigned long n)
+{
+       might_sleep();
+       if (unlikely(!access_ok(VERIFY_WRITE, to, n)))
+               return n;
+
+       return __clear_user(to, n);
+}
+
+/* put_user and get_user macros */
+extern long __user_bad(void);
+
+#define __get_user_asm(insn, __gu_ptr, __gu_val, __gu_err)     \
+({                                                             \
+       __asm__ __volatile__ (                                  \
+                       "1:"    insn    " %1, %2, r0;"          \
+                       "       addk    %0, r0, r0;"            \
+                       "2:                     "               \
+                       __FIXUP_SECTION                         \
+                       "3:     brid    2b;"                    \
+                       "       addik   %0, r0, %3;"            \
+                       ".previous;"                            \
+                       __EX_TABLE_SECTION                      \
+                       ".word  1b,3b;"                         \
+                       ".previous;"                            \
+               : "=&r"(__gu_err), "=r"(__gu_val)               \
+               : "r"(__gu_ptr), "i"(-EFAULT)                   \
+       );                                                      \
 })
 
-#define put_user(x, ptr)                                               \
+/**
+ * get_user: - Get a simple variable from user space.
+ * @x:   Variable to store result.
+ * @ptr: Source address, in user space.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * This macro copies a single simple variable from user space to kernel
+ * space.  It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and the result of
+ * dereferencing @ptr must be assignable to @x without a cast.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ * On error, the variable @x is set to zero.
+ */
+#define get_user(x, ptr)                                               \
+       __get_user_check((x), (ptr), sizeof(*(ptr)))
+
+#define __get_user_check(x, ptr, size)                                 \
 ({                                                                     \
-       access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr)))                  \
-               ? __put_user((x), (ptr)) : -EFAULT;                     \
+       unsigned long __gu_val = 0;                                     \
+       const typeof(*(ptr)) __user *__gu_addr = (ptr);                 \
+       int __gu_err = 0;                                               \
+                                                                       \
+       if (access_ok(VERIFY_READ, __gu_addr, size)) {                  \
+               switch (size) {                                         \
+               case 1:                                                 \
+                       __get_user_asm("lbu", __gu_addr, __gu_val,      \
+                                      __gu_err);                       \
+                       break;                                          \
+               case 2:                                                 \
+                       __get_user_asm("lhu", __gu_addr, __gu_val,      \
+                                      __gu_err);                       \
+                       break;                                          \
+               case 4:                                                 \
+                       __get_user_asm("lw", __gu_addr, __gu_val,       \
+                                      __gu_err);                       \
+                       break;                                          \
+               default:                                                \
+                       __gu_err = __user_bad();                        \
+                       break;                                          \
+               }                                                       \
+       } else {                                                        \
+               __gu_err = -EFAULT;                                     \
+       }                                                               \
+       x = (typeof(*(ptr)))__gu_val;                                   \
+       __gu_err;                                                       \
 })
 
 #define __get_user(x, ptr)                                             \
@@ -163,28 +232,102 @@ extern long strnlen_user(const char *src, long count);
                __get_user_asm("lw", (ptr), __gu_val, __gu_err);        \
                break;                                                  \
        default:                                                        \
-               __gu_val = 0; __gu_err = -EINVAL;                       \
+               /* __gu_val = 0; __gu_err = -EINVAL;*/ __gu_err = __user_bad();\
        }                                                               \
        x = (__typeof__(*(ptr))) __gu_val;                              \
        __gu_err;                                                       \
 })
 
-#define __get_user_asm(insn, __gu_ptr, __gu_val, __gu_err)             \
+
+#define __put_user_asm(insn, __gu_ptr, __gu_val, __gu_err)     \
+({                                                             \
+       __asm__ __volatile__ (                                  \
+                       "1:"    insn    " %1, %2, r0;"          \
+                       "       addk    %0, r0, r0;"            \
+                       "2:                     "               \
+                       __FIXUP_SECTION                         \
+                       "3:     brid    2b;"                    \
+                       "       addik   %0, r0, %3;"            \
+                       ".previous;"                            \
+                       __EX_TABLE_SECTION                      \
+                       ".word  1b,3b;"                         \
+                       ".previous;"                            \
+               : "=&r"(__gu_err)                               \
+               : "r"(__gu_val), "r"(__gu_ptr), "i"(-EFAULT)    \
+       );                                                      \
+})
+
+#define __put_user_asm_8(__gu_ptr, __gu_val, __gu_err)         \
+({                                                             \
+       __asm__ __volatile__ (" lwi     %0, %1, 0;"             \
+                       "1:     swi     %0, %2, 0;"             \
+                       "       lwi     %0, %1, 4;"             \
+                       "2:     swi     %0, %2, 4;"             \
+                       "       addk    %0, r0, r0;"            \
+                       "3:                     "               \
+                       __FIXUP_SECTION                         \
+                       "4:     brid    3b;"                    \
+                       "       addik   %0, r0, %3;"            \
+                       ".previous;"                            \
+                       __EX_TABLE_SECTION                      \
+                       ".word  1b,4b,2b,4b;"                   \
+                       ".previous;"                            \
+               : "=&r"(__gu_err)                               \
+               : "r"(&__gu_val), "r"(__gu_ptr), "i"(-EFAULT)   \
+               );                                              \
+})
+
+/**
+ * put_user: - Write a simple value into user space.
+ * @x:   Value to copy to user space.
+ * @ptr: Destination address, in user space.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * This macro copies a single simple value from kernel space to user
+ * space.  It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and @x must be assignable
+ * to the result of dereferencing @ptr.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ */
+#define put_user(x, ptr)                                               \
+       __put_user_check((x), (ptr), sizeof(*(ptr)))
+
+#define __put_user_check(x, ptr, size)                                 \
 ({                                                                     \
-       __asm__ __volatile__ (                                          \
-                       "1:"    insn    " %1, %2, r0;                   \
-                               addk    %0, r0, r0;                     \
-                       2:                                              \
-                       .section .fixup,\"ax\";                         \
-                       3:      brid    2b;                             \
-                               addik   %0, r0, %3;                     \
-                       .previous;                                      \
-                       .section __ex_table,\"a\";                      \
-                       .word   1b,3b;                                  \
-                       .previous;"                                     \
-               : "=r"(__gu_err), "=r"(__gu_val)                        \
-               : "r"(__gu_ptr), "i"(-EFAULT)                           \
-       );                                                              \
+       typeof(*(ptr)) __pu_val;                                        \
+       typeof(*(ptr)) __user *__pu_addr = (ptr);                       \
+       int __pu_err = 0;                                               \
+                                                                       \
+       __pu_val = (x);                                                 \
+       if (access_ok(VERIFY_WRITE, __pu_addr, size)) {                 \
+               switch (size) {                                         \
+               case 1:                                                 \
+                       __put_user_asm("sb", __pu_addr, __pu_val,       \
+                                      __pu_err);                       \
+                       break;                                          \
+               case 2:                                                 \
+                       __put_user_asm("sh", __pu_addr, __pu_val,       \
+                                      __pu_err);                       \
+                       break;                                          \
+               case 4:                                                 \
+                       __put_user_asm("sw", __pu_addr, __pu_val,       \
+                                      __pu_err);                       \
+                       break;                                          \
+               case 8:                                                 \
+                       __put_user_asm_8(__pu_addr, __pu_val, __pu_err);\
+                       break;                                          \
+               default:                                                \
+                       __pu_err = __user_bad();                        \
+                       break;                                          \
+               }                                                       \
+       } else {                                                        \
+               __pu_err = -EFAULT;                                     \
+       }                                                               \
+       __pu_err;                                                       \
 })
 
 #define __put_user(x, ptr)                                             \
@@ -195,7 +338,7 @@ extern long strnlen_user(const char *src, long count);
        case 1:                                                         \
                __put_user_asm("sb", (ptr), __gu_val, __gu_err);        \
                break;                                                  \
-       case 2:                                                         \
+       case 2:                                                         \
                __put_user_asm("sh", (ptr), __gu_val, __gu_err);        \
                break;                                                  \
        case 4:                                                         \
@@ -205,121 +348,70 @@ extern long strnlen_user(const char *src, long count);
                __put_user_asm_8((ptr), __gu_val, __gu_err);            \
                break;                                                  \
        default:                                                        \
-               __gu_err = -EINVAL;                                     \
+               /*__gu_err = -EINVAL;*/ __gu_err = __user_bad();        \
        }                                                               \
        __gu_err;                                                       \
 })
 
-#define __put_user_asm_8(__gu_ptr, __gu_val, __gu_err) \
-({                                                     \
-__asm__ __volatile__ ("        lwi     %0, %1, 0;              \
-               1:      swi     %0, %2, 0;              \
-                       lwi     %0, %1, 4;              \
-               2:      swi     %0, %2, 4;              \
-                       addk    %0,r0,r0;               \
-               3:                                      \
-               .section .fixup,\"ax\";                 \
-               4:      brid    3b;                     \
-                       addik   %0, r0, %3;             \
-               .previous;                              \
-               .section __ex_table,\"a\";              \
-               .word   1b,4b,2b,4b;                    \
-               .previous;"                             \
-       : "=&r"(__gu_err)                               \
-       : "r"(&__gu_val),                               \
-       "r"(__gu_ptr), "i"(-EFAULT)                     \
-       );                                              \
-})
-
-#define __put_user_asm(insn, __gu_ptr, __gu_val, __gu_err)     \
-({                                                             \
-       __asm__ __volatile__ (                                  \
-                       "1:"    insn    " %1, %2, r0;           \
-                               addk    %0, r0, r0;             \
-                       2:                                      \
-                       .section .fixup,\"ax\";                 \
-                       3:      brid    2b;                     \
-                               addik   %0, r0, %3;             \
-                       .previous;                              \
-                       .section __ex_table,\"a\";              \
-                       .word   1b,3b;                          \
-                       .previous;"                             \
-               : "=r"(__gu_err)                                \
-               : "r"(__gu_val), "r"(__gu_ptr), "i"(-EFAULT)    \
-       );                                                      \
-})
 
-/*
- * Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail.
- */
-static inline int clear_user(char *to, int size)
-{
-       if (size && access_ok(VERIFY_WRITE, to, size)) {
-               __asm__ __volatile__ ("                         \
-                               1:                              \
-                                       sb      r0, %2, r0;     \
-                                       addik   %0, %0, -1;     \
-                                       bneid   %0, 1b;         \
-                                       addik   %2, %2, 1;      \
-                               2:                              \
-                               .section __ex_table,\"a\";      \
-                               .word   1b,2b;                  \
-                               .section .text;"                \
-                       : "=r"(size)                            \
-                       : "0"(size), "r"(to)
-               );
-       }
-       return size;
-}
-
-#define __copy_from_user(to, from, n)  copy_from_user((to), (from), (n))
+/* copy_to_from_user */
+#define __copy_from_user(to, from, n)  \
+       __copy_tofrom_user((__force void __user *)(to), \
+                               (void __user *)(from), (n))
 #define __copy_from_user_inatomic(to, from, n) \
                copy_from_user((to), (from), (n))
 
-#define copy_to_user(to, from, n)                                      \
-       (access_ok(VERIFY_WRITE, (to), (n)) ?                           \
-               __copy_tofrom_user((void __user *)(to),                 \
-                       (__force const void __user *)(from), (n))       \
-               : -EFAULT)
+static inline long copy_from_user(void *to,
+               const void __user *from, unsigned long n)
+{
+       might_sleep();
+       if (access_ok(VERIFY_READ, from, n))
+               return __copy_from_user(to, from, n);
+       return n;
+}
 
-#define __copy_to_user(to, from, n)    copy_to_user((to), (from), (n))
+#define __copy_to_user(to, from, n)    \
+               __copy_tofrom_user((void __user *)(to), \
+                       (__force const void __user *)(from), (n))
 #define __copy_to_user_inatomic(to, from, n)   copy_to_user((to), (from), (n))
 
-#define copy_from_user(to, from, n)                                    \
-       (access_ok(VERIFY_READ, (from), (n)) ?                          \
-               __copy_tofrom_user((__force void __user *)(to),         \
-                       (void __user *)(from), (n))                     \
-               : -EFAULT)
+static inline long copy_to_user(void __user *to,
+               const void *from, unsigned long n)
+{
+       might_sleep();
+       if (access_ok(VERIFY_WRITE, to, n))
+               return __copy_to_user(to, from, n);
+       return n;
+}
 
+/*
+ * Copy a null terminated string from userspace.
+ */
 extern int __strncpy_user(char *to, const char __user *from, int len);
-extern int __strnlen_user(const char __user *sstr, int len);
-
-#define strncpy_from_user(to, from, len)       \
-               (access_ok(VERIFY_READ, from, 1) ?      \
-                       __strncpy_user(to, from, len) : -EFAULT)
-#define strnlen_user(str, len) \
-               (access_ok(VERIFY_READ, str, 1) ? __strnlen_user(str, len) : 0)
 
-#endif /* CONFIG_MMU */
+#define __strncpy_from_user    __strncpy_user
 
-extern unsigned long __copy_tofrom_user(void __user *to,
-               const void __user *from, unsigned long size);
+static inline long
+strncpy_from_user(char *dst, const char __user *src, long count)
+{
+       if (!access_ok(VERIFY_READ, src, 1))
+               return -EFAULT;
+       return __strncpy_from_user(dst, src, count);
+}
 
 /*
- * The exception table consists of pairs of addresses: the first is the
- * address of an instruction that is allowed to fault, and the second is
- * the address at which the program should continue. No registers are
- * modified, so it is entirely up to the continuation code to figure out
- * what to do.
+ * Return the size of a string (including the ending 0)
  *
- * All the routines below use bits of fixup code that are out of line
- * with the main instruction path. This means when everything is well,
- * we don't even have to jump over them. Further, they do not intrude
- * on our cache or tlb entries.
+ * Return 0 on exception, a value greater than N if too long
  */
-struct exception_table_entry {
-       unsigned long insn, fixup;
-};
+extern int __strnlen_user(const char __user *sstr, int len);
+
+static inline long strnlen_user(const char __user *src, long n)
+{
+       if (!access_ok(VERIFY_READ, src, 1))
+               return 0;
+       return __strnlen_user(src, n);
+}
 
 #endif  /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
index b07594eccf9b0d71c47e996bc33d22f61ffd39e4..e51bc1520825e5e9c7f246d989552e461b7d55df 100644 (file)
@@ -14,7 +14,7 @@ endif
 
 extra-y := head.o vmlinux.lds
 
-obj-y += exceptions.o \
+obj-y += dma.o exceptions.o \
        hw_exception_handler.o init_task.o intc.o irq.o of_device.o \
        of_platform.o process.o prom.o prom_parse.o ptrace.o \
        setup.o signal.o sys_microblaze.o timer.o traps.o reset.o
index 7bc7b68f97db3089952ee59bfe8adcff29c95a0b..c1b459c9757161ae56a8188e48cbedf307d077ad 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/hardirq.h>
 #include <linux/thread_info.h>
 #include <linux/kbuild.h>
+#include <asm/cpuinfo.h>
 
 int main(int argc, char *argv[])
 {
@@ -90,6 +91,7 @@ int main(int argc, char *argv[])
        DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
        DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
        DEFINE(TI_CPU_CONTEXT, offsetof(struct thread_info, cpu_context));
+       DEFINE(TI_PREEMPT_COUNT, offsetof(struct thread_info, preempt_count));
        BLANK();
 
        /* struct cpu_context */
index 2a56bccce4e02a822a5c3193b6ee72175bd03fd8..109876e8d643a3b51eb41a91e7fc8adb9e1a5ec9 100644 (file)
 #include <asm/cpuinfo.h>
 #include <asm/pvr.h>
 
-static inline void __invalidate_flush_icache(unsigned int addr)
-{
-       __asm__ __volatile__ ("wic      %0, r0;"        \
-                                       : : "r" (addr));
-}
-
-static inline void __flush_dcache(unsigned int addr)
-{
-       __asm__ __volatile__ ("wdc.flush        %0, r0;"        \
-                                       : : "r" (addr));
-}
-
-static inline void __invalidate_dcache(unsigned int baseaddr,
-                                               unsigned int offset)
-{
-       __asm__ __volatile__ ("wdc.clear        %0, %1;"        \
-                                       : : "r" (baseaddr), "r" (offset));
-}
-
 static inline void __enable_icache_msr(void)
 {
        __asm__ __volatile__ (" msrset  r0, %0;         \
@@ -115,13 +96,16 @@ static inline void __disable_dcache_nomsr(void)
 }
 
 
-/* Helper macro for computing the limits of cache range loops */
+/* Helper macro for computing the limits of cache range loops
+ *
+ * End address can be unaligned which is OK for C implementation.
+ * ASM implementation align it in ASM macros
+ */
 #define CACHE_LOOP_LIMITS(start, end, cache_line_length, cache_size)   \
 do {                                                                   \
        int align = ~(cache_line_length - 1);                           \
        end = min(start + cache_size, end);                             \
        start &= align;                                                 \
-       end = ((end & align) + cache_line_length);                      \
 } while (0);
 
 /*
@@ -130,9 +114,9 @@ do {                                                                        \
  */
 #define CACHE_ALL_LOOP(cache_size, line_length, op)                    \
 do {                                                                   \
-       unsigned int len = cache_size;                                  \
+       unsigned int len = cache_size - line_length;                    \
        int step = -line_length;                                        \
-       BUG_ON(step >= 0);                                              \
+       WARN_ON(step >= 0);                                             \
                                                                        \
        __asm__ __volatile__ (" 1:      " #op " %0, r0;                 \
                                        bgtid   %0, 1b;                 \
@@ -141,30 +125,26 @@ do {                                                                      \
                                        : "memory");                    \
 } while (0);
 
-
-#define CACHE_ALL_LOOP2(cache_size, line_length, op)                   \
-do {                                                                   \
-       unsigned int len = cache_size;                                  \
-       int step = -line_length;                                        \
-       BUG_ON(step >= 0);                                              \
-                                                                       \
-       __asm__ __volatile__ (" 1:      " #op " r0, %0;                 \
-                                       bgtid   %0, 1b;                 \
-                                       addk    %0, %0, %1;             \
-                                       " : : "r" (len), "r" (step)     \
-                                       : "memory");                    \
-} while (0);
-
-/* for wdc.flush/clear */
+/* Used for wdc.flush/clear which can use rB for offset which is not possible
+ * to use for simple wdc or wic.
+ *
+ * start address is cache aligned
+ * end address is not aligned, if end is aligned then I have to substract
+ * cacheline length because I can't flush/invalidate the next cacheline.
+ * If is not, I align it because I will flush/invalidate whole line.
+ */
 #define CACHE_RANGE_LOOP_2(start, end, line_length, op)                        \
 do {                                                                   \
        int step = -line_length;                                        \
-       int count = end - start;                                        \
-       BUG_ON(count <= 0);                                             \
+       int align = ~(line_length - 1);                                 \
+       int count;                                                      \
+       end = ((end & align) == end) ? end - line_length : end & align; \
+       count = end - start;                                            \
+       WARN_ON(count < 0);                                             \
                                                                        \
-       __asm__ __volatile__ (" 1:      " #op " %0, %1;                 \
-                                       bgtid   %1, 1b;                 \
-                                       addk    %1, %1, %2;             \
+       __asm__ __volatile__ (" 1:      " #op " %0, %1;                 \
+                                       bgtid   %1, 1b;                 \
+                                       addk    %1, %1, %2;             \
                                        " : : "r" (start), "r" (count), \
                                        "r" (step) : "memory");         \
 } while (0);
@@ -173,9 +153,11 @@ do {                                                                       \
 #define CACHE_RANGE_LOOP_1(start, end, line_length, op)                        \
 do {                                                                   \
        int volatile temp;                                              \
-       BUG_ON(end - start <= 0);                                       \
+       int align = ~(line_length - 1);                                 \
+       end = ((end & align) == end) ? end - line_length : end & align; \
+       WARN_ON(end - start < 0);                                       \
                                                                        \
-       __asm__ __volatile__ (" 1:      " #op " %1, r0;                 \
+       __asm__ __volatile__ (" 1:      " #op " %1, r0;                 \
                                        cmpu    %0, %1, %2;             \
                                        bgtid   %0, 1b;                 \
                                        addk    %1, %1, %3;             \
@@ -183,10 +165,14 @@ do {                                                                      \
                                        "r" (line_length) : "memory");  \
 } while (0);
 
+#define ASM_LOOP
+
 static void __flush_icache_range_msr_irq(unsigned long start, unsigned long end)
 {
        unsigned long flags;
-
+#ifndef ASM_LOOP
+       int i;
+#endif
        pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
                                (unsigned int)start, (unsigned int) end);
 
@@ -196,8 +182,13 @@ static void __flush_icache_range_msr_irq(unsigned long start, unsigned long end)
        local_irq_save(flags);
        __disable_icache_msr();
 
+#ifdef ASM_LOOP
        CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
-
+#else
+       for (i = start; i < end; i += cpuinfo.icache_line_length)
+               __asm__ __volatile__ ("wic      %0, r0;"        \
+                               : : "r" (i));
+#endif
        __enable_icache_msr();
        local_irq_restore(flags);
 }
@@ -206,7 +197,9 @@ static void __flush_icache_range_nomsr_irq(unsigned long start,
                                unsigned long end)
 {
        unsigned long flags;
-
+#ifndef ASM_LOOP
+       int i;
+#endif
        pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
                                (unsigned int)start, (unsigned int) end);
 
@@ -216,7 +209,13 @@ static void __flush_icache_range_nomsr_irq(unsigned long start,
        local_irq_save(flags);
        __disable_icache_nomsr();
 
+#ifdef ASM_LOOP
        CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
+#else
+       for (i = start; i < end; i += cpuinfo.icache_line_length)
+               __asm__ __volatile__ ("wic      %0, r0;"        \
+                               : : "r" (i));
+#endif
 
        __enable_icache_nomsr();
        local_irq_restore(flags);
@@ -225,25 +224,41 @@ static void __flush_icache_range_nomsr_irq(unsigned long start,
 static void __flush_icache_range_noirq(unsigned long start,
                                unsigned long end)
 {
+#ifndef ASM_LOOP
+       int i;
+#endif
        pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
                                (unsigned int)start, (unsigned int) end);
 
        CACHE_LOOP_LIMITS(start, end,
                        cpuinfo.icache_line_length, cpuinfo.icache_size);
+#ifdef ASM_LOOP
        CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
+#else
+       for (i = start; i < end; i += cpuinfo.icache_line_length)
+               __asm__ __volatile__ ("wic      %0, r0;"        \
+                               : : "r" (i));
+#endif
 }
 
 static void __flush_icache_all_msr_irq(void)
 {
        unsigned long flags;
-
+#ifndef ASM_LOOP
+       int i;
+#endif
        pr_debug("%s\n", __func__);
 
        local_irq_save(flags);
        __disable_icache_msr();
-
+#ifdef ASM_LOOP
        CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
-
+#else
+       for (i = 0; i < cpuinfo.icache_size;
+                i += cpuinfo.icache_line_length)
+                       __asm__ __volatile__ ("wic      %0, r0;" \
+                                       : : "r" (i));
+#endif
        __enable_icache_msr();
        local_irq_restore(flags);
 }
@@ -251,35 +266,59 @@ static void __flush_icache_all_msr_irq(void)
 static void __flush_icache_all_nomsr_irq(void)
 {
        unsigned long flags;
-
+#ifndef ASM_LOOP
+       int i;
+#endif
        pr_debug("%s\n", __func__);
 
        local_irq_save(flags);
        __disable_icache_nomsr();
-
+#ifdef ASM_LOOP
        CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
-
+#else
+       for (i = 0; i < cpuinfo.icache_size;
+                i += cpuinfo.icache_line_length)
+                       __asm__ __volatile__ ("wic      %0, r0;" \
+                                       : : "r" (i));
+#endif
        __enable_icache_nomsr();
        local_irq_restore(flags);
 }
 
 static void __flush_icache_all_noirq(void)
 {
+#ifndef ASM_LOOP
+       int i;
+#endif
        pr_debug("%s\n", __func__);
+#ifdef ASM_LOOP
        CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
+#else
+       for (i = 0; i < cpuinfo.icache_size;
+                i += cpuinfo.icache_line_length)
+                       __asm__ __volatile__ ("wic      %0, r0;" \
+                                       : : "r" (i));
+#endif
 }
 
 static void __invalidate_dcache_all_msr_irq(void)
 {
        unsigned long flags;
-
+#ifndef ASM_LOOP
+       int i;
+#endif
        pr_debug("%s\n", __func__);
 
        local_irq_save(flags);
        __disable_dcache_msr();
-
+#ifdef ASM_LOOP
        CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
-
+#else
+       for (i = 0; i < cpuinfo.dcache_size;
+                i += cpuinfo.dcache_line_length)
+                       __asm__ __volatile__ ("wdc      %0, r0;" \
+                                       : : "r" (i));
+#endif
        __enable_dcache_msr();
        local_irq_restore(flags);
 }
@@ -287,60 +326,111 @@ static void __invalidate_dcache_all_msr_irq(void)
 static void __invalidate_dcache_all_nomsr_irq(void)
 {
        unsigned long flags;
-
+#ifndef ASM_LOOP
+       int i;
+#endif
        pr_debug("%s\n", __func__);
 
        local_irq_save(flags);
        __disable_dcache_nomsr();
-
+#ifdef ASM_LOOP
        CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
-
+#else
+       for (i = 0; i < cpuinfo.dcache_size;
+                i += cpuinfo.dcache_line_length)
+                       __asm__ __volatile__ ("wdc      %0, r0;" \
+                                       : : "r" (i));
+#endif
        __enable_dcache_nomsr();
        local_irq_restore(flags);
 }
 
 static void __invalidate_dcache_all_noirq_wt(void)
 {
+#ifndef ASM_LOOP
+       int i;
+#endif
        pr_debug("%s\n", __func__);
+#ifdef ASM_LOOP
        CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc)
+#else
+       for (i = 0; i < cpuinfo.dcache_size;
+                i += cpuinfo.dcache_line_length)
+                       __asm__ __volatile__ ("wdc      %0, r0;" \
+                                       : : "r" (i));
+#endif
 }
 
-/* FIXME this is weird - should be only wdc but not work
- * MS: I am getting bus errors and other weird things */
+/* FIXME It is blindly invalidation as is expected
+ * but can't be called on noMMU in microblaze_cache_init below
+ *
+ * MS: noMMU kernel won't boot if simple wdc is used
+ * The reason should be that there are discared data which kernel needs
+ */
 static void __invalidate_dcache_all_wb(void)
 {
+#ifndef ASM_LOOP
+       int i;
+#endif
        pr_debug("%s\n", __func__);
-       CACHE_ALL_LOOP2(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
-                                       wdc.clear)
+#ifdef ASM_LOOP
+       CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
+                                       wdc)
+#else
+       for (i = 0; i < cpuinfo.dcache_size;
+                i += cpuinfo.dcache_line_length)
+                       __asm__ __volatile__ ("wdc      %0, r0;" \
+                                       : : "r" (i));
+#endif
 }
 
 static void __invalidate_dcache_range_wb(unsigned long start,
                                                unsigned long end)
 {
+#ifndef ASM_LOOP
+       int i;
+#endif
        pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
                                (unsigned int)start, (unsigned int) end);
 
        CACHE_LOOP_LIMITS(start, end,
                        cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+#ifdef ASM_LOOP
        CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.clear);
+#else
+       for (i = start; i < end; i += cpuinfo.dcache_line_length)
+               __asm__ __volatile__ ("wdc.clear        %0, r0;"        \
+                               : : "r" (i));
+#endif
 }
 
 static void __invalidate_dcache_range_nomsr_wt(unsigned long start,
                                                        unsigned long end)
 {
+#ifndef ASM_LOOP
+       int i;
+#endif
        pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
                                (unsigned int)start, (unsigned int) end);
        CACHE_LOOP_LIMITS(start, end,
                        cpuinfo.dcache_line_length, cpuinfo.dcache_size);
 
+#ifdef ASM_LOOP
        CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
+#else
+       for (i = start; i < end; i += cpuinfo.dcache_line_length)
+               __asm__ __volatile__ ("wdc      %0, r0;"        \
+                               : : "r" (i));
+#endif
 }
 
 static void __invalidate_dcache_range_msr_irq_wt(unsigned long start,
                                                        unsigned long end)
 {
        unsigned long flags;
-
+#ifndef ASM_LOOP
+       int i;
+#endif
        pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
                                (unsigned int)start, (unsigned int) end);
        CACHE_LOOP_LIMITS(start, end,
@@ -349,7 +439,13 @@ static void __invalidate_dcache_range_msr_irq_wt(unsigned long start,
        local_irq_save(flags);
        __disable_dcache_msr();
 
+#ifdef ASM_LOOP
        CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
+#else
+       for (i = start; i < end; i += cpuinfo.dcache_line_length)
+               __asm__ __volatile__ ("wdc      %0, r0;"        \
+                               : : "r" (i));
+#endif
 
        __enable_dcache_msr();
        local_irq_restore(flags);
@@ -359,7 +455,9 @@ static void __invalidate_dcache_range_nomsr_irq(unsigned long start,
                                                        unsigned long end)
 {
        unsigned long flags;
-
+#ifndef ASM_LOOP
+       int i;
+#endif
        pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
                                (unsigned int)start, (unsigned int) end);
 
@@ -369,7 +467,13 @@ static void __invalidate_dcache_range_nomsr_irq(unsigned long start,
        local_irq_save(flags);
        __disable_dcache_nomsr();
 
+#ifdef ASM_LOOP
        CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
+#else
+       for (i = start; i < end; i += cpuinfo.dcache_line_length)
+               __asm__ __volatile__ ("wdc      %0, r0;"        \
+                               : : "r" (i));
+#endif
 
        __enable_dcache_nomsr();
        local_irq_restore(flags);
@@ -377,19 +481,38 @@ static void __invalidate_dcache_range_nomsr_irq(unsigned long start,
 
 static void __flush_dcache_all_wb(void)
 {
+#ifndef ASM_LOOP
+       int i;
+#endif
        pr_debug("%s\n", __func__);
+#ifdef ASM_LOOP
        CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
                                wdc.flush);
+#else
+       for (i = 0; i < cpuinfo.dcache_size;
+                i += cpuinfo.dcache_line_length)
+                       __asm__ __volatile__ ("wdc.flush        %0, r0;" \
+                                       : : "r" (i));
+#endif
 }
 
 static void __flush_dcache_range_wb(unsigned long start, unsigned long end)
 {
+#ifndef ASM_LOOP
+       int i;
+#endif
        pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
                                (unsigned int)start, (unsigned int) end);
 
        CACHE_LOOP_LIMITS(start, end,
                        cpuinfo.dcache_line_length, cpuinfo.dcache_size);
+#ifdef ASM_LOOP
        CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.flush);
+#else
+       for (i = start; i < end; i += cpuinfo.dcache_line_length)
+               __asm__ __volatile__ ("wdc.flush        %0, r0;"        \
+                               : : "r" (i));
+#endif
 }
 
 /* struct for wb caches and for wt caches */
@@ -493,7 +616,7 @@ const struct scache wt_nomsr_noirq = {
 #define CPUVER_7_20_A  0x0c
 #define CPUVER_7_20_D  0x0f
 
-#define INFO(s)        printk(KERN_INFO "cache: " s " \n");
+#define INFO(s)        printk(KERN_INFO "cache: " s "\n");
 
 void microblaze_cache_init(void)
 {
@@ -532,4 +655,13 @@ void microblaze_cache_init(void)
                        }
                }
        }
+/* FIXME Invalidation is done in U-BOOT
+ * WT cache: Data is already written to main memory
+ * WB cache: Discard data on noMMU which caused that kernel doesn't boot
+ */
+       /* invalidate_dcache(); */
+       enable_dcache();
+
+       invalidate_icache();
+       enable_icache();
 }
index 991d71311b0ebaad156a03e03f9f4f2cce277d30..255ef880351e793b38ef9b3e853c8c30f6ed40be 100644 (file)
@@ -9,7 +9,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <asm/cpuinfo.h>
 #include <asm/pvr.h>
 
index 0c912b2a8e03ae72c1073ff94185595f18a3ab68..4216eb1eaa326a84e4fa2d776ad522d001217d29 100644 (file)
@@ -98,15 +98,17 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 
        if (cpuinfo.use_icache)
                count += seq_printf(m,
-                               "Icache:\t\t%ukB\n",
-                               cpuinfo.icache_size >> 10);
+                               "Icache:\t\t%ukB\tline length:\t%dB\n",
+                               cpuinfo.icache_size >> 10,
+                               cpuinfo.icache_line_length);
        else
                count += seq_printf(m, "Icache:\t\tno\n");
 
        if (cpuinfo.use_dcache) {
                count += seq_printf(m,
-                               "Dcache:\t\t%ukB\n",
-                               cpuinfo.dcache_size >> 10);
+                               "Dcache:\t\t%ukB\tline length:\t%dB\n",
+                               cpuinfo.dcache_size >> 10,
+                               cpuinfo.dcache_line_length);
                if (cpuinfo.dcache_wb)
                        count += seq_printf(m, "\t\twrite-back\n");
                else
diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c
new file mode 100644 (file)
index 0000000..9dcd90b
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2009-2010 PetaLogix
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation
+ *
+ * Provide default implementations of the DMA mapping callbacks for
+ * directly mapped busses.
+ */
+
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
+#include <linux/dma-debug.h>
+#include <asm/bug.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Generic direct DMA implementation
+ *
+ * This implementation supports a per-device offset that can be applied if
+ * the address at which memory is visible to devices is not 0. Platform code
+ * can set archdata.dma_data to an unsigned long holding the offset. By
+ * default the offset is PCI_DRAM_OFFSET.
+ */
+static inline void __dma_sync_page(unsigned long paddr, unsigned long offset,
+                               size_t size, enum dma_data_direction direction)
+{
+       switch (direction) {
+       case DMA_TO_DEVICE:
+               flush_dcache_range(paddr + offset, paddr + offset + size);
+               break;
+       case DMA_FROM_DEVICE:
+               invalidate_dcache_range(paddr + offset, paddr + offset + size);
+               break;
+       default:
+               BUG();
+       }
+}
+
+static unsigned long get_dma_direct_offset(struct device *dev)
+{
+       if (likely(dev))
+               return (unsigned long)dev->archdata.dma_data;
+
+       return PCI_DRAM_OFFSET; /* FIXME Not sure if is correct */
+}
+
+#define NOT_COHERENT_CACHE
+
+static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
+                               dma_addr_t *dma_handle, gfp_t flag)
+{
+#ifdef NOT_COHERENT_CACHE
+       return consistent_alloc(flag, size, dma_handle);
+#else
+       void *ret;
+       struct page *page;
+       int node = dev_to_node(dev);
+
+       /* ignore region specifiers */
+       flag  &= ~(__GFP_HIGHMEM);
+
+       page = alloc_pages_node(node, flag, get_order(size));
+       if (page == NULL)
+               return NULL;
+       ret = page_address(page);
+       memset(ret, 0, size);
+       *dma_handle = virt_to_phys(ret) + get_dma_direct_offset(dev);
+
+       return ret;
+#endif
+}
+
+static void dma_direct_free_coherent(struct device *dev, size_t size,
+                             void *vaddr, dma_addr_t dma_handle)
+{
+#ifdef NOT_COHERENT_CACHE
+       consistent_free(size, vaddr);
+#else
+       free_pages((unsigned long)vaddr, get_order(size));
+#endif
+}
+
+static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
+                            int nents, enum dma_data_direction direction,
+                            struct dma_attrs *attrs)
+{
+       struct scatterlist *sg;
+       int i;
+
+       /* FIXME this part of code is untested */
+       for_each_sg(sgl, sg, nents, i) {
+               sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev);
+               sg->dma_length = sg->length;
+               __dma_sync_page(page_to_phys(sg_page(sg)), sg->offset,
+                                                       sg->length, direction);
+       }
+
+       return nents;
+}
+
+static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg,
+                               int nents, enum dma_data_direction direction,
+                               struct dma_attrs *attrs)
+{
+}
+
+static int dma_direct_dma_supported(struct device *dev, u64 mask)
+{
+       return 1;
+}
+
+static inline dma_addr_t dma_direct_map_page(struct device *dev,
+                                            struct page *page,
+                                            unsigned long offset,
+                                            size_t size,
+                                            enum dma_data_direction direction,
+                                            struct dma_attrs *attrs)
+{
+       __dma_sync_page(page_to_phys(page), offset, size, direction);
+       return page_to_phys(page) + offset + get_dma_direct_offset(dev);
+}
+
+static inline void dma_direct_unmap_page(struct device *dev,
+                                        dma_addr_t dma_address,
+                                        size_t size,
+                                        enum dma_data_direction direction,
+                                        struct dma_attrs *attrs)
+{
+/* There is not necessary to do cache cleanup
+ *
+ * phys_to_virt is here because in __dma_sync_page is __virt_to_phys and
+ * dma_address is physical address
+ */
+       __dma_sync_page(dma_address, 0 , size, direction);
+}
+
+struct dma_map_ops dma_direct_ops = {
+       .alloc_coherent = dma_direct_alloc_coherent,
+       .free_coherent  = dma_direct_free_coherent,
+       .map_sg         = dma_direct_map_sg,
+       .unmap_sg       = dma_direct_unmap_sg,
+       .dma_supported  = dma_direct_dma_supported,
+       .map_page       = dma_direct_map_page,
+       .unmap_page     = dma_direct_unmap_page,
+};
+EXPORT_SYMBOL(dma_direct_ops);
+
+/* Number of entries preallocated for DMA-API debugging */
+#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
+
+static int __init dma_init(void)
+{
+       dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+
+       return 0;
+}
+fs_initcall(dma_init);
index 391d6197fc3bbfb309f7bf1824c16ef80d2ca4cc..8cc18cd2cce6a6f34186597dd7a66013066fa2aa 100644 (file)
@@ -476,6 +476,8 @@ ENTRY(ret_from_fork)
        nop
 
 work_pending:
+       enable_irq
+
        andi    r11, r19, _TIF_NEED_RESCHED
        beqi    r11, 1f
        bralid  r15, schedule
index 3bad4ff494711c205b3536a686e4aa36d9913b94..c0ede25c5b99ec305abd4d97fa774d249b36fda0 100644 (file)
@@ -305,7 +305,7 @@ C_ENTRY(_user_exception):
        swi     r11, r1, PTO+PT_R1;             /* Store user SP.  */
        addi    r11, r0, 1;
        swi     r11, r0, TOPHYS(PER_CPU(KM));   /* Now we're in kernel-mode.  */
-2:     lwi     r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
+2:     lwi     CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
        /* Save away the syscall number.  */
        swi     r12, r1, PTO+PT_R0;
        tovirt(r1,r1)
@@ -322,8 +322,7 @@ C_ENTRY(_user_exception):
        rtid    r11, 0
        nop
 3:
-       add     r11, r0, CURRENT_TASK    /* Get current task ptr into r11 */
-       lwi     r11, r11, TS_THREAD_INFO /* get thread info */
+       lwi     r11, CURRENT_TASK, TS_THREAD_INFO /* get thread info */
        lwi     r11, r11, TI_FLAGS       /* get flags in thread info */
        andi    r11, r11, _TIF_WORK_SYSCALL_MASK
        beqi    r11, 4f
@@ -382,60 +381,50 @@ C_ENTRY(ret_from_trap):
 /* See if returning to kernel mode, if so, skip resched &c.  */
        bnei    r11, 2f;
 
+       swi     r3, r1, PTO + PT_R3
+       swi     r4, r1, PTO + PT_R4
+
        /* We're returning to user mode, so check for various conditions that
         * trigger rescheduling. */
-       # FIXME: Restructure all these flag checks.
-       add     r11, r0, CURRENT_TASK;  /* Get current task ptr into r11 */
-       lwi     r11, r11, TS_THREAD_INFO;       /* get thread info */
+       /* FIXME: Restructure all these flag checks. */
+       lwi     r11, CURRENT_TASK, TS_THREAD_INFO;      /* get thread info */
        lwi     r11, r11, TI_FLAGS;             /* get flags in thread info */
        andi    r11, r11, _TIF_WORK_SYSCALL_MASK
        beqi    r11, 1f
 
-       swi     r3, r1, PTO + PT_R3
-       swi     r4, r1, PTO + PT_R4
        brlid   r15, do_syscall_trace_leave
        addik   r5, r1, PTO + PT_R0
-       lwi     r3, r1, PTO + PT_R3
-       lwi     r4, r1, PTO + PT_R4
 1:
-
        /* We're returning to user mode, so check for various conditions that
         * trigger rescheduling. */
-       /* Get current task ptr into r11 */
-       add     r11, r0, CURRENT_TASK;  /* Get current task ptr into r11 */
-       lwi     r11, r11, TS_THREAD_INFO;       /* get thread info */
+       /* get thread info from current task */
+       lwi     r11, CURRENT_TASK, TS_THREAD_INFO;
        lwi     r11, r11, TI_FLAGS;             /* get flags in thread info */
        andi    r11, r11, _TIF_NEED_RESCHED;
        beqi    r11, 5f;
 
-       swi     r3, r1, PTO + PT_R3; /* store syscall result */
-       swi     r4, r1, PTO + PT_R4;
        bralid  r15, schedule;  /* Call scheduler */
        nop;                            /* delay slot */
-       lwi     r3, r1, PTO + PT_R3; /* restore syscall result */
-       lwi     r4, r1, PTO + PT_R4;
 
        /* Maybe handle a signal */
-5:     add     r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
-       lwi     r11, r11, TS_THREAD_INFO;       /* get thread info */
+5:     /* get thread info from current task*/
+       lwi     r11, CURRENT_TASK, TS_THREAD_INFO;
        lwi     r11, r11, TI_FLAGS;     /* get flags in thread info */
        andi    r11, r11, _TIF_SIGPENDING;
        beqi    r11, 1f;                /* Signals to handle, handle them */
 
-       swi     r3, r1, PTO + PT_R3; /* store syscall result */
-       swi     r4, r1, PTO + PT_R4;
        la      r5, r1, PTO;            /* Arg 1: struct pt_regs *regs */
-       add     r6, r0, r0;             /* Arg 2: sigset_t *oldset */
        addi    r7, r0, 1;              /* Arg 3: int in_syscall */
        bralid  r15, do_signal; /* Handle any signals */
-       nop;
+       add     r6, r0, r0;             /* Arg 2: sigset_t *oldset */
+
+/* Finally, return to user state.  */
+1:
        lwi     r3, r1, PTO + PT_R3; /* restore syscall result */
        lwi     r4, r1, PTO + PT_R4;
 
-/* Finally, return to user state.  */
-1:     swi     r0, r0, PER_CPU(KM);    /* Now officially in user state. */
-       add     r11, r0, CURRENT_TASK;  /* Get current task ptr into r11 */
-       swi     r11, r0, PER_CPU(CURRENT_SAVE); /* save current */
+       swi     r0, r0, PER_CPU(KM);    /* Now officially in user state. */
+       swi     CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
        VM_OFF;
        tophys(r1,r1);
        RESTORE_REGS;
@@ -565,7 +554,7 @@ C_ENTRY(sys_rt_sigreturn_wrapper):
        swi     r11, r1, PTO+PT_R1; /* Store user SP.  */               \
        addi    r11, r0, 1;                                             \
        swi     r11, r0, TOPHYS(PER_CPU(KM)); /* Now we're in kernel-mode.*/\
-2:     lwi     r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */\
+2:     lwi     CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));        \
        /* Save away the syscall number.  */                            \
        swi     r0, r1, PTO+PT_R0;                                      \
        tovirt(r1,r1)
@@ -673,9 +662,7 @@ C_ENTRY(ret_from_exc):
 
        /* We're returning to user mode, so check for various conditions that
           trigger rescheduling. */
-       /* Get current task ptr into r11 */
-       add     r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
-       lwi     r11, r11, TS_THREAD_INFO;       /* get thread info */
+       lwi     r11, CURRENT_TASK, TS_THREAD_INFO;      /* get thread info */
        lwi     r11, r11, TI_FLAGS;     /* get flags in thread info */
        andi    r11, r11, _TIF_NEED_RESCHED;
        beqi    r11, 5f;
@@ -685,8 +672,7 @@ C_ENTRY(ret_from_exc):
        nop;                            /* delay slot */
 
        /* Maybe handle a signal */
-5:     add     r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
-       lwi     r11, r11, TS_THREAD_INFO;       /* get thread info */
+5:     lwi     r11, CURRENT_TASK, TS_THREAD_INFO;      /* get thread info */
        lwi     r11, r11, TI_FLAGS;     /* get flags in thread info */
        andi    r11, r11, _TIF_SIGPENDING;
        beqi    r11, 1f;                /* Signals to handle, handle them */
@@ -705,15 +691,13 @@ C_ENTRY(ret_from_exc):
         * store return registers separately because this macros is use
         * for others exceptions */
        la      r5, r1, PTO;            /* Arg 1: struct pt_regs *regs */
-       add     r6, r0, r0;             /* Arg 2: sigset_t *oldset */
        addi    r7, r0, 0;              /* Arg 3: int in_syscall */
        bralid  r15, do_signal; /* Handle any signals */
-       nop;
+       add     r6, r0, r0;             /* Arg 2: sigset_t *oldset */
 
 /* Finally, return to user state.  */
 1:     swi     r0, r0, PER_CPU(KM);    /* Now officially in user state. */
-       add     r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
-       swi     r11, r0, PER_CPU(CURRENT_SAVE); /* save current */
+       swi     CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
        VM_OFF;
        tophys(r1,r1);
 
@@ -802,7 +786,7 @@ C_ENTRY(_interrupt):
        swi     r11, r0, TOPHYS(PER_CPU(KM));
 
 2:
-       lwi     r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
+       lwi     CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
        swi     r0, r1, PTO + PT_R0;
        tovirt(r1,r1)
        la      r5, r1, PTO;
@@ -817,8 +801,7 @@ ret_from_irq:
        lwi     r11, r1, PTO + PT_MODE;
        bnei    r11, 2f;
 
-       add     r11, r0, CURRENT_TASK;
-       lwi     r11, r11, TS_THREAD_INFO;
+       lwi     r11, CURRENT_TASK, TS_THREAD_INFO;
        lwi     r11, r11, TI_FLAGS; /* MS: get flags from thread info */
        andi    r11, r11, _TIF_NEED_RESCHED;
        beqi    r11, 5f
@@ -826,8 +809,7 @@ ret_from_irq:
        nop; /* delay slot */
 
     /* Maybe handle a signal */
-5:     add     r11, r0, CURRENT_TASK;
-       lwi     r11, r11, TS_THREAD_INFO; /* MS: get thread info */
+5:     lwi     r11, CURRENT_TASK, TS_THREAD_INFO; /* MS: get thread info */
        lwi     r11, r11, TI_FLAGS; /* get flags in thread info */
        andi    r11, r11, _TIF_SIGPENDING;
        beqid   r11, no_intr_resched
@@ -842,8 +824,7 @@ no_intr_resched:
     /* Disable interrupts, we are now committed to the state restore */
        disable_irq
        swi     r0, r0, PER_CPU(KM); /* MS: Now officially in user state. */
-       add     r11, r0, CURRENT_TASK;
-       swi     r11, r0, PER_CPU(CURRENT_SAVE);
+       swi     CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE);
        VM_OFF;
        tophys(r1,r1);
        lwi     r3, r1, PTO + PT_R3; /* MS: restore saved r3, r4 registers */
@@ -853,7 +834,28 @@ no_intr_resched:
        lwi     r1, r1, PT_R1 - PT_SIZE;
        bri     6f;
 /* MS: Return to kernel state. */
-2:     VM_OFF /* MS: turn off MMU */
+2:
+#ifdef CONFIG_PREEMPT
+       lwi     r11, CURRENT_TASK, TS_THREAD_INFO;
+       /* MS: get preempt_count from thread info */
+       lwi     r5, r11, TI_PREEMPT_COUNT;
+       bgti    r5, restore;
+
+       lwi     r5, r11, TI_FLAGS;              /* get flags in thread info */
+       andi    r5, r5, _TIF_NEED_RESCHED;
+       beqi    r5, restore /* if zero jump over */
+
+preempt:
+       /* interrupts are off that's why I am calling preempt_chedule_irq */
+       bralid  r15, preempt_schedule_irq
+       nop
+       lwi     r11, CURRENT_TASK, TS_THREAD_INFO;      /* get thread info */
+       lwi     r5, r11, TI_FLAGS;              /* get flags in thread info */
+       andi    r5, r5, _TIF_NEED_RESCHED;
+       bnei    r5, preempt /* if non zero jump to resched */
+restore:
+#endif
+       VM_OFF /* MS: turn off MMU */
        tophys(r1,r1)
        lwi     r3, r1, PTO + PT_R3; /* MS: restore saved r3, r4 registers */
        lwi     r4, r1, PTO + PT_R4;
@@ -915,7 +917,7 @@ C_ENTRY(_debug_exception):
        swi     r11, r1, PTO+PT_R1; /* Store user SP.  */
        addi    r11, r0, 1;
        swi     r11, r0, TOPHYS(PER_CPU(KM));   /* Now we're in kernel-mode.  */
-2:     lwi     r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
+2:     lwi     CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
        /* Save away the syscall number.  */
        swi     r0, r1, PTO+PT_R0;
        tovirt(r1,r1)
@@ -935,8 +937,7 @@ dbtrap_call:        rtbd    r11, 0;
        bnei    r11, 2f;
 
        /* Get current task ptr into r11 */
-       add     r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
-       lwi     r11, r11, TS_THREAD_INFO;       /* get thread info */
+       lwi     r11, CURRENT_TASK, TS_THREAD_INFO;      /* get thread info */
        lwi     r11, r11, TI_FLAGS;     /* get flags in thread info */
        andi    r11, r11, _TIF_NEED_RESCHED;
        beqi    r11, 5f;
@@ -949,8 +950,7 @@ dbtrap_call:        rtbd    r11, 0;
        /* XXX m68knommu also checks TASK_STATE & TASK_COUNTER here.  */
 
        /* Maybe handle a signal */
-5:     add     r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
-       lwi     r11, r11, TS_THREAD_INFO;       /* get thread info */
+5:     lwi     r11, CURRENT_TASK, TS_THREAD_INFO;      /* get thread info */
        lwi     r11, r11, TI_FLAGS;     /* get flags in thread info */
        andi    r11, r11, _TIF_SIGPENDING;
        beqi    r11, 1f;                /* Signals to handle, handle them */
@@ -966,16 +966,14 @@ dbtrap_call:      rtbd    r11, 0;
           (in a possibly modified form) after do_signal returns.  */
 
        la      r5, r1, PTO;            /* Arg 1: struct pt_regs *regs */
-       add     r6, r0, r0;             /* Arg 2: sigset_t *oldset */
        addi  r7, r0, 0;        /* Arg 3: int in_syscall */
        bralid  r15, do_signal; /* Handle any signals */
-       nop;
+       add     r6, r0, r0;             /* Arg 2: sigset_t *oldset */
 
 
 /* Finally, return to user state.  */
 1:     swi     r0, r0, PER_CPU(KM);    /* Now officially in user state. */
-       add     r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
-       swi     r11, r0, PER_CPU(CURRENT_SAVE); /* save current */
+       swi     CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
        VM_OFF;
        tophys(r1,r1);
 
@@ -1007,7 +1005,7 @@ DBTRAP_return:            /* Make global symbol for debugging */
 
 ENTRY(_switch_to)
        /* prepare return value */
-       addk    r3, r0, r31
+       addk    r3, r0, CURRENT_TASK
 
        /* save registers in cpu_context */
        /* use r11 and r12, volatile registers, as temp register */
@@ -1051,10 +1049,10 @@ ENTRY(_switch_to)
        nop
        swi     r12, r11, CC_FSR
 
-       /* update r31, the current */
-       lwi     r31, r6, TI_TASK/* give me pointer to task which will be next */
+       /* update r31, the current-give me pointer to task which will be next */
+       lwi     CURRENT_TASK, r6, TI_TASK
        /* stored it to current_save too */
-       swi     r31, r0, PER_CPU(CURRENT_SAVE)
+       swi     CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE)
 
        /* get new process' cpu context and restore */
        /* give me start where start context of next task */
index d9f70f83097fc5f3c0f010b6a96f1c33f383ba47..02cbdfe5aa8dd1619ef25e14e65e4f34cf825129 100644 (file)
@@ -121,7 +121,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
                }
                printk(KERN_WARNING "Divide by zero exception " \
                                                        "in kernel mode.\n");
-               die("Divide by exception", regs, SIGBUS);
+               die("Divide by zero exception", regs, SIGBUS);
                break;
        case MICROBLAZE_FPU_EXCEPTION:
                pr_debug(KERN_WARNING "FPU exception\n");
index 388b31ca65a1ed2c9d9314b57cdc23dbee2bf920..515feb404555c6a3b690cea1e80024040691c043 100644 (file)
@@ -151,13 +151,10 @@ int ftrace_make_nop(struct module *mod,
        return ret;
 }
 
-static int ret_addr; /* initialized as 0 by default */
-
 /* I believe that first is called ftrace_make_nop before this function */
 int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 {
        int ret;
-       ret_addr = addr; /* saving where the barrier jump is */
        pr_debug("%s: addr:0x%x, rec->ip: 0x%x, imm:0x%x\n",
                __func__, (unsigned int)addr, (unsigned int)rec->ip, imm);
        ret = ftrace_modify_code(rec->ip, imm);
@@ -194,12 +191,9 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
        ret = ftrace_modify_code(ip, upper);
        ret += ftrace_modify_code(ip + 4, lower);
 
-       /* We just need to remove the rtsd r15, 8 by NOP */
-       BUG_ON(!ret_addr);
-       if (ret_addr)
-               ret += ftrace_modify_code(ret_addr, MICROBLAZE_NOP);
-       else
-               ret = 1; /* fault */
+       /* We just need to replace the rtsd r15, 8 with NOP */
+       ret += ftrace_modify_code((unsigned long)&ftrace_caller,
+                                 MICROBLAZE_NOP);
 
        /* All changes are done - lets do caches consistent */
        flush_icache();
index 30916193fcc75c378d819a0ab48894ce6c4acd98..1bf7398882607ba805b64866f0d6501f4849b033 100644 (file)
@@ -28,6 +28,7 @@
  * for more details.
  */
 
+#include <linux/init.h>
 #include <linux/linkage.h>
 #include <asm/thread_info.h>
 #include <asm/page.h>
@@ -49,8 +50,14 @@ swapper_pg_dir:
 
 #endif /* CONFIG_MMU */
 
-       .text
+       __HEAD
 ENTRY(_start)
+#if CONFIG_KERNEL_BASE_ADDR == 0
+       brai    TOPHYS(real_start)
+       .org    0x100
+real_start:
+#endif
+
        mfs     r1, rmsr
        andi    r1, r1, ~2
        mts     rmsr, r1
@@ -99,8 +106,8 @@ no_fdt_arg:
        tophys(r4,r4)                   /* convert to phys address */
        ori     r3, r0, COMMAND_LINE_SIZE - 1 /* number of loops */
 _copy_command_line:
-       lbu     r7, r5, r6 /* r7=r5+r6 - r5 contain pointer to command line */
-       sb      r7, r4, r6              /* addr[r4+r6]= r7*/
+       lbu     r2, r5, r6 /* r2=r5+r6 - r5 contain pointer to command line */
+       sb      r2, r4, r6              /* addr[r4+r6]= r2*/
        addik   r6, r6, 1               /* increment counting */
        bgtid   r3, _copy_command_line  /* loop for all entries       */
        addik   r3, r3, -1              /* descrement loop */
@@ -128,7 +135,7 @@ _copy_bram:
         * virtual to physical.
         */
        nop
-       addik   r3, r0, 63              /* Invalidate all TLB entries */
+       addik   r3, r0, MICROBLAZE_TLB_SIZE -1  /* Invalidate all TLB entries */
 _invalidate:
        mts     rtlbx, r3
        mts     rtlbhi, r0                      /* flush: ensure V is clear   */
@@ -136,6 +143,11 @@ _invalidate:
        addik   r3, r3, -1
        /* sync */
 
+       /* Setup the kernel PID */
+       mts     rpid,r0                 /* Load the kernel PID */
+       nop
+       bri     4
+
        /*
         * We should still be executing code at physical address area
         * RAM_BASEADDR at this point. However, kernel code is at
@@ -146,10 +158,6 @@ _invalidate:
        addik   r3,r0, CONFIG_KERNEL_START /* Load the kernel virtual address */
        tophys(r4,r3)                   /* Load the kernel physical address */
 
-       mts     rpid,r0                 /* Load the kernel PID */
-       nop
-       bri     4
-
        /*
         * Configure and load two entries into TLB slots 0 and 1.
         * In case we are pinning TLBs, these are reserved in by the
index 2b86c03aa84187cb5857974fba2cb949e349ce93..995a2123635bc2dbb0d9121e500e0dc6ead4494c 100644 (file)
@@ -313,13 +313,13 @@ _hw_exception_handler:
        mfs     r5, rmsr;
        nop
        swi     r5, r1, 0;
-       mfs     r3, resr
+       mfs     r4, resr
        nop
-       mfs     r4, rear;
+       mfs     r3, rear;
        nop
 
 #ifndef CONFIG_MMU
-       andi    r5, r3, 0x1000;         /* Check ESR[DS] */
+       andi    r5, r4, 0x1000;         /* Check ESR[DS] */
        beqi    r5, not_in_delay_slot;  /* Branch if ESR[DS] not set */
        mfs     r17, rbtr;      /* ESR[DS] set - return address in BTR */
        nop
@@ -327,13 +327,14 @@ not_in_delay_slot:
        swi     r17, r1, PT_R17
 #endif
 
-       andi    r5, r3, 0x1F;           /* Extract ESR[EXC] */
+       andi    r5, r4, 0x1F;           /* Extract ESR[EXC] */
 
 #ifdef CONFIG_MMU
        /* Calculate exception vector offset = r5 << 2 */
        addk    r6, r5, r5; /* << 1 */
        addk    r6, r6, r6; /* << 2 */
 
+#ifdef DEBUG
 /* counting which exception happen */
        lwi     r5, r0, 0x200 + TOPHYS(r0_ram)
        addi    r5, r5, 1
@@ -341,6 +342,7 @@ not_in_delay_slot:
        lwi     r5, r6, 0x200 + TOPHYS(r0_ram)
        addi    r5, r5, 1
        swi     r5, r6, 0x200 + TOPHYS(r0_ram)
+#endif
 /* end */
        /* Load the HW Exception vector */
        lwi     r6, r6, TOPHYS(_MB_HW_ExceptionVectorTable)
@@ -376,7 +378,7 @@ handle_other_ex: /* Handle Other exceptions here */
        swi     r18, r1, PT_R18
 
        or      r5, r1, r0
-       andi    r6, r3, 0x1F; /* Load ESR[EC] */
+       andi    r6, r4, 0x1F; /* Load ESR[EC] */
        lwi     r7, r0, PER_CPU(KM) /* MS: saving current kernel mode to regs */
        swi     r7, r1, PT_MODE
        mfs     r7, rfsr
@@ -426,11 +428,11 @@ handle_other_ex: /* Handle Other exceptions here */
  */
 handle_unaligned_ex:
        /* Working registers already saved: R3, R4, R5, R6
-        *  R3 = ESR
-        *  R4 = EAR
+        *  R4 = ESR
+        *  R3 = EAR
         */
 #ifdef CONFIG_MMU
-       andi    r6, r3, 0x1000                  /* Check ESR[DS] */
+       andi    r6, r4, 0x1000                  /* Check ESR[DS] */
        beqi    r6, _no_delayslot               /* Branch if ESR[DS] not set */
        mfs     r17, rbtr;      /* ESR[DS] set - return address in BTR */
        nop
@@ -439,7 +441,7 @@ _no_delayslot:
        RESTORE_STATE;
        bri     unaligned_data_trap
 #endif
-       andi    r6, r3, 0x3E0; /* Mask and extract the register operand */
+       andi    r6, r4, 0x3E0; /* Mask and extract the register operand */
        srl     r6, r6; /* r6 >> 5 */
        srl     r6, r6;
        srl     r6, r6;
@@ -448,33 +450,33 @@ _no_delayslot:
        /* Store the register operand in a temporary location */
        sbi     r6, r0, TOPHYS(ex_reg_op);
 
-       andi    r6, r3, 0x400; /* Extract ESR[S] */
+       andi    r6, r4, 0x400; /* Extract ESR[S] */
        bnei    r6, ex_sw;
 ex_lw:
-       andi    r6, r3, 0x800; /* Extract ESR[W] */
+       andi    r6, r4, 0x800; /* Extract ESR[W] */
        beqi    r6, ex_lhw;
-       lbui    r5, r4, 0; /* Exception address in r4 */
+       lbui    r5, r3, 0; /* Exception address in r3 */
        /* Load a word, byte-by-byte from destination address
                and save it in tmp space */
        sbi     r5, r0, TOPHYS(ex_tmp_data_loc_0);
-       lbui    r5, r4, 1;
+       lbui    r5, r3, 1;
        sbi     r5, r0, TOPHYS(ex_tmp_data_loc_1);
-       lbui    r5, r4, 2;
+       lbui    r5, r3, 2;
        sbi     r5, r0, TOPHYS(ex_tmp_data_loc_2);
-       lbui    r5, r4, 3;
+       lbui    r5, r3, 3;
        sbi     r5, r0, TOPHYS(ex_tmp_data_loc_3);
-       /* Get the destination register value into r3 */
-       lwi     r3, r0, TOPHYS(ex_tmp_data_loc_0);
+       /* Get the destination register value into r4 */
+       lwi     r4, r0, TOPHYS(ex_tmp_data_loc_0);
        bri     ex_lw_tail;
 ex_lhw:
-       lbui    r5, r4, 0; /* Exception address in r4 */
+       lbui    r5, r3, 0; /* Exception address in r3 */
        /* Load a half-word, byte-by-byte from destination
                address and save it in tmp space */
        sbi     r5, r0, TOPHYS(ex_tmp_data_loc_0);
-       lbui    r5, r4, 1;
+       lbui    r5, r3, 1;
        sbi     r5, r0, TOPHYS(ex_tmp_data_loc_1);
-       /* Get the destination register value into r3 */
-       lhui    r3, r0, TOPHYS(ex_tmp_data_loc_0);
+       /* Get the destination register value into r4 */
+       lhui    r4, r0, TOPHYS(ex_tmp_data_loc_0);
 ex_lw_tail:
        /* Get the destination register number into r5 */
        lbui    r5, r0, TOPHYS(ex_reg_op);
@@ -502,25 +504,25 @@ ex_sw_tail:
        andi    r6, r6, 0x800; /* Extract ESR[W] */
        beqi    r6, ex_shw;
        /* Get the word - delay slot */
-       swi     r3, r0, TOPHYS(ex_tmp_data_loc_0);
+       swi     r4, r0, TOPHYS(ex_tmp_data_loc_0);
        /* Store the word, byte-by-byte into destination address */
-       lbui    r3, r0, TOPHYS(ex_tmp_data_loc_0);
-       sbi     r3, r4, 0;
-       lbui    r3, r0, TOPHYS(ex_tmp_data_loc_1);
-       sbi     r3, r4, 1;
-       lbui    r3, r0, TOPHYS(ex_tmp_data_loc_2);
-       sbi     r3, r4, 2;
-       lbui    r3, r0, TOPHYS(ex_tmp_data_loc_3);
-       sbi     r3, r4, 3;
+       lbui    r4, r0, TOPHYS(ex_tmp_data_loc_0);
+       sbi     r4, r3, 0;
+       lbui    r4, r0, TOPHYS(ex_tmp_data_loc_1);
+       sbi     r4, r3, 1;
+       lbui    r4, r0, TOPHYS(ex_tmp_data_loc_2);
+       sbi     r4, r3, 2;
+       lbui    r4, r0, TOPHYS(ex_tmp_data_loc_3);
+       sbi     r4, r3, 3;
        bri     ex_handler_done;
 
 ex_shw:
        /* Store the lower half-word, byte-by-byte into destination address */
-       swi     r3, r0, TOPHYS(ex_tmp_data_loc_0);
-       lbui    r3, r0, TOPHYS(ex_tmp_data_loc_2);
-       sbi     r3, r4, 0;
-       lbui    r3, r0, TOPHYS(ex_tmp_data_loc_3);
-       sbi     r3, r4, 1;
+       swi     r4, r0, TOPHYS(ex_tmp_data_loc_0);
+       lbui    r4, r0, TOPHYS(ex_tmp_data_loc_2);
+       sbi     r4, r3, 0;
+       lbui    r4, r0, TOPHYS(ex_tmp_data_loc_3);
+       sbi     r4, r3, 1;
 ex_sw_end: /* Exception handling of store word, ends. */
 
 ex_handler_done:
@@ -560,21 +562,16 @@ ex_handler_done:
                 */
                mfs     r11, rpid
                nop
-               bri     4
-               mfs     r3, rear                /* Get faulting address */
-               nop
                /* If we are faulting a kernel address, we have to use the
                 * kernel page tables.
                 */
-               ori     r4, r0, CONFIG_KERNEL_START
-               cmpu    r4, r3, r4
-               bgti    r4, ex3
+               ori     r5, r0, CONFIG_KERNEL_START
+               cmpu    r5, r3, r5
+               bgti    r5, ex3
                /* First, check if it was a zone fault (which means a user
                 * tried to access a kernel or read-protected page - always
                 * a SEGV). All other faults here must be stores, so no
                 * need to check ESR_S as well. */
-               mfs     r4, resr
-               nop
                andi    r4, r4, 0x800           /* ESR_Z - zone protection */
                bnei    r4, ex2
 
@@ -589,8 +586,6 @@ ex_handler_done:
                 * tried to access a kernel or read-protected page - always
                 * a SEGV). All other faults here must be stores, so no
                 * need to check ESR_S as well. */
-               mfs     r4, resr
-               nop
                andi    r4, r4, 0x800           /* ESR_Z */
                bnei    r4, ex2
                /* get current task address */
@@ -665,8 +660,6 @@ ex_handler_done:
                 * R3 = ESR
                 */
 
-               mfs     r3, rear                /* Get faulting address */
-               nop
                RESTORE_STATE;
                bri     page_fault_instr_trap
 
@@ -677,18 +670,15 @@ ex_handler_done:
         */
        handle_data_tlb_miss_exception:
                /* Working registers already saved: R3, R4, R5, R6
-                * R3 = ESR
+                * R3 = EAR, R4 = ESR
                 */
                mfs     r11, rpid
                nop
-               bri     4
-               mfs     r3, rear                /* Get faulting address */
-               nop
 
                /* If we are faulting a kernel address, we have to use the
                 * kernel page tables. */
-               ori     r4, r0, CONFIG_KERNEL_START
-               cmpu    r4, r3, r4
+               ori     r6, r0, CONFIG_KERNEL_START
+               cmpu    r4, r3, r6
                bgti    r4, ex5
                ori     r4, r0, swapper_pg_dir
                mts     rpid, r0                /* TLB will have 0 TID */
@@ -731,9 +721,8 @@ ex_handler_done:
                 * Many of these bits are software only. Bits we don't set
                 * here we (properly should) assume have the appropriate value.
                 */
+               brid    finish_tlb_load
                andni   r4, r4, 0x0ce2          /* Make sure 20, 21 are zero */
-
-               bri     finish_tlb_load
        ex7:
                /* The bailout. Restore registers to pre-exception conditions
                 * and call the heavyweights to help us out.
@@ -754,9 +743,6 @@ ex_handler_done:
                 */
                mfs     r11, rpid
                nop
-               bri     4
-               mfs     r3, rear                /* Get faulting address */
-               nop
 
                /* If we are faulting a kernel address, we have to use the
                 * kernel page tables.
@@ -792,7 +778,7 @@ ex_handler_done:
                lwi     r4, r5, 0               /* Get Linux PTE */
 
                andi    r6, r4, _PAGE_PRESENT
-               beqi    r6, ex7
+               beqi    r6, ex10
 
                ori     r4, r4, _PAGE_ACCESSED
                swi     r4, r5, 0
@@ -805,9 +791,8 @@ ex_handler_done:
                 * Many of these bits are software only. Bits we don't set
                 * here we (properly should) assume have the appropriate value.
                 */
+               brid    finish_tlb_load
                andni   r4, r4, 0x0ce2          /* Make sure 20, 21 are zero */
-
-               bri     finish_tlb_load
        ex10:
                /* The bailout. Restore registers to pre-exception conditions
                 * and call the heavyweights to help us out.
@@ -837,9 +822,9 @@ ex_handler_done:
                andi    r5, r5, (MICROBLAZE_TLB_SIZE-1)
                ori     r6, r0, 1
                cmp     r31, r5, r6
-               blti    r31, sem
+               blti    r31, ex12
                addik   r5, r6, 1
-       sem:
+       ex12:
                /* MS: save back current TLB index */
                swi     r5, r0, TOPHYS(tlb_index)
 
@@ -859,7 +844,6 @@ ex_handler_done:
                nop
 
                /* Done...restore registers and get out of here. */
-       ex12:
                mts     rpid, r11
                nop
                bri 4
index 0f06034d1fe09754659c4069a31bd71fe33b02f5..8f120aca123df6e09e939e31d3e15ab7d056183d 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/ftrace.h>
 #include <linux/kernel.h>
 #include <linux/hardirq.h>
 #include <linux/interrupt.h>
@@ -32,7 +33,7 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
 
 static u32 concurrent_irq;
 
-void do_IRQ(struct pt_regs *regs)
+void __irq_entry do_IRQ(struct pt_regs *regs)
 {
        unsigned int irq;
        struct pt_regs *old_regs = set_irq_regs(regs);
@@ -93,3 +94,18 @@ skip:
        }
        return 0;
 }
+
+/* MS: There is no any advance mapping mechanism. We are using simple 32bit
+  intc without any cascades or any connection that's why mapping is 1:1 */
+unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq)
+{
+       return hwirq;
+}
+EXPORT_SYMBOL_GPL(irq_create_mapping);
+
+unsigned int irq_create_of_mapping(struct device_node *controller,
+                                       u32 *intspec, unsigned int intsize)
+{
+       return intspec[0];
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
index bc4dcb7d3861c50aff24b152f37655c80c937d95..ff85f77180355fe6ba8a6c5c1cdeecfa25b5fa75 100644 (file)
@@ -52,3 +52,14 @@ EXPORT_SYMBOL_GPL(_ebss);
 extern void _mcount(void);
 EXPORT_SYMBOL(_mcount);
 #endif
+
+/*
+ * Assembly functions that may be used (directly or indirectly) by modules
+ */
+EXPORT_SYMBOL(__copy_tofrom_user);
+EXPORT_SYMBOL(__strncpy_user);
+
+#ifdef CONFIG_OPT_LIB_ASM
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memmove);
+#endif
index df16c6287a8e54b1ca8e36a10c6f2fe2875d9ff2..0fb5fc6c1fc24343777e8053706e746df8daa49d 100644 (file)
  * We avoid flushing the pinned 0, 1 and possibly 2 entries.
  */
 .globl _tlbia;
+.type  _tlbia, @function
 .align 4;
 _tlbia:
-       addik   r12, r0, 63 /* flush all entries (63 - 3) */
+       addik   r12, r0, MICROBLAZE_TLB_SIZE - 1 /* flush all entries (63 - 3) */
        /* isync */
 _tlbia_1:
        mts     rtlbx, r12
@@ -41,11 +42,13 @@ _tlbia_1:
        /* sync */
        rtsd    r15, 8
        nop
+       .size  _tlbia, . - _tlbia
 
 /*
  * Flush MMU TLB for a particular address (in r5)
  */
 .globl _tlbie;
+.type  _tlbie, @function
 .align 4;
 _tlbie:
        mts     rtlbsx, r5 /* look up the address in TLB */
@@ -59,17 +62,20 @@ _tlbie_1:
        rtsd    r15, 8
        nop
 
+       .size  _tlbie, . - _tlbie
+
 /*
  * Allocate TLB entry for early console
  */
 .globl early_console_reg_tlb_alloc;
+.type  early_console_reg_tlb_alloc, @function
 .align 4;
 early_console_reg_tlb_alloc:
        /*
         * Load a TLB entry for the UART, so that microblaze_progress() can use
         * the UARTs nice and early.  We use a 4k real==virtual mapping.
         */
-       ori     r4, r0, 63
+       ori     r4, r0, MICROBLAZE_TLB_SIZE - 1
        mts     rtlbx, r4 /* TLB slot 2 */
 
        or      r4,r5,r0
@@ -86,35 +92,4 @@ early_console_reg_tlb_alloc:
        rtsd    r15, 8
        nop
 
-/*
- * Copy a whole page (4096 bytes).
- */
-#define COPY_16_BYTES          \
-       lwi     r7, r6, 0;      \
-       lwi     r8, r6, 4;      \
-       lwi     r9, r6, 8;      \
-       lwi     r10, r6, 12;    \
-       swi     r7, r5, 0;      \
-       swi     r8, r5, 4;      \
-       swi     r9, r5, 8;      \
-       swi     r10, r5, 12
-
-
-/* FIXME DCACHE_LINE_BYTES (CONFIG_XILINX_MICROBLAZE0_DCACHE_LINE_LEN * 4)*/
-#define DCACHE_LINE_BYTES (4 * 4)
-
-.globl copy_page;
-.align 4;
-copy_page:
-       ori     r11, r0, (PAGE_SIZE/DCACHE_LINE_BYTES) - 1
-_copy_page_loop:
-       COPY_16_BYTES
-#if DCACHE_LINE_BYTES >= 32
-       COPY_16_BYTES
-#endif
-       addik   r6, r6, DCACHE_LINE_BYTES
-       addik   r5, r5, DCACHE_LINE_BYTES
-       bneid   r11, _copy_page_loop
-       addik   r11, r11, -1
-       rtsd    r15, 8
-       nop
+       .size  early_console_reg_tlb_alloc, . - early_console_reg_tlb_alloc
index 5a45b1adfef1c91f25b191d968238c95854ee674..0e73f6606547ce03f1be8c048971b9de6275c3a0 100644 (file)
 #include <linux/kernel.h>
 #include <linux/elf.h>
 #include <linux/vmalloc.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/string.h>
 
 #include <asm/pgtable.h>
+#include <asm/cacheflush.h>
 
 void *module_alloc(unsigned long size)
 {
@@ -152,6 +152,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
 int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
                struct module *module)
 {
+       flush_dcache();
        return 0;
 }
 
index 1c6d684996d7eae768686ba88945e79148180c74..0dc755286d38e44b8ff209d05d4d7c2a1c9d1b9a 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
-#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
index 812f1bf06c9e5cbfb2a88222974e2931d20f9a24..09bed44dfcd35a5f2300405f9e208982e7208798 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/bitops.h>
 #include <asm/system.h>
 #include <asm/pgalloc.h>
+#include <asm/uaccess.h> /* for USER_DS macros */
 #include <asm/cacheflush.h>
 
 void show_regs(struct pt_regs *regs)
@@ -74,7 +75,10 @@ __setup("hlt", hlt_setup);
 
 void default_idle(void)
 {
-       if (!hlt_counter) {
+       if (likely(hlt_counter)) {
+               while (!need_resched())
+                       cpu_relax();
+       } else {
                clear_thread_flag(TIF_POLLING_NRFLAG);
                smp_mb__after_clear_bit();
                local_irq_disable();
@@ -82,9 +86,7 @@ void default_idle(void)
                        cpu_sleep();
                local_irq_enable();
                set_thread_flag(TIF_POLLING_NRFLAG);
-       } else
-               while (!need_resched())
-                       cpu_relax();
+       }
 }
 
 void cpu_idle(void)
index 6d6349a145f9dd938b83176a5197d3e4a608afa3..a4a7770c61402b17a8b488c35eb0f2c889ac1eee 100644 (file)
@@ -75,7 +75,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
        int rval;
        unsigned long val = 0;
-       unsigned long copied;
 
        switch (request) {
        /* Read/write the word at location ADDR in the registers. */
index bb8c4b9ccb8019bb54cb585a5e8d1f2e77f3acb9..17c98dbcec888f698e2c038eee317ddef7e1f7da 100644 (file)
 #include <linux/io.h>
 #include <linux/bug.h>
 #include <linux/param.h>
+#include <linux/pci.h>
 #include <linux/cache.h>
+#include <linux/of_platform.h>
+#include <linux/dma-mapping.h>
 #include <asm/cacheflush.h>
 #include <asm/entry.h>
 #include <asm/cpuinfo.h>
@@ -54,14 +57,10 @@ void __init setup_arch(char **cmdline_p)
 
        microblaze_cache_init();
 
-       invalidate_dcache();
-       enable_dcache();
-
-       invalidate_icache();
-       enable_icache();
-
        setup_memory();
 
+       xilinx_pci_init();
+
 #if defined(CONFIG_SELFMOD_INTC) || defined(CONFIG_SELFMOD_TIMER)
        printk(KERN_NOTICE "Self modified code enable\n");
 #endif
@@ -93,6 +92,12 @@ inline unsigned get_romfs_len(unsigned *addr)
 }
 #endif /* CONFIG_MTD_UCLINUX_EBSS */
 
+#if defined(CONFIG_EARLY_PRINTK) && defined(CONFIG_SERIAL_UARTLITE_CONSOLE)
+#define eprintk early_printk
+#else
+#define eprintk printk
+#endif
+
 void __init machine_early_init(const char *cmdline, unsigned int ram,
                unsigned int fdt, unsigned int msr)
 {
@@ -140,32 +145,32 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
        setup_early_printk(NULL);
 #endif
 
-       early_printk("Ramdisk addr 0x%08x, ", ram);
+       eprintk("Ramdisk addr 0x%08x, ", ram);
        if (fdt)
-               early_printk("FDT at 0x%08x\n", fdt);
+               eprintk("FDT at 0x%08x\n", fdt);
        else
-               early_printk("Compiled-in FDT at 0x%08x\n",
+               eprintk("Compiled-in FDT at 0x%08x\n",
                                        (unsigned int)_fdt_start);
 
 #ifdef CONFIG_MTD_UCLINUX
-       early_printk("Found romfs @ 0x%08x (0x%08x)\n",
+       eprintk("Found romfs @ 0x%08x (0x%08x)\n",
                        romfs_base, romfs_size);
-       early_printk("#### klimit %p ####\n", old_klimit);
+       eprintk("#### klimit %p ####\n", old_klimit);
        BUG_ON(romfs_size < 0); /* What else can we do? */
 
-       early_printk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n",
+       eprintk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n",
                        romfs_size, romfs_base, (unsigned)&_ebss);
 
-       early_printk("New klimit: 0x%08x\n", (unsigned)klimit);
+       eprintk("New klimit: 0x%08x\n", (unsigned)klimit);
 #endif
 
 #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
        if (msr)
-               early_printk("!!!Your kernel has setup MSR instruction but "
+               eprintk("!!!Your kernel has setup MSR instruction but "
                                "CPU don't have it %d\n", msr);
 #else
        if (!msr)
-               early_printk("!!!Your kernel not setup MSR instruction but "
+               eprintk("!!!Your kernel not setup MSR instruction but "
                                "CPU have it %d\n", msr);
 #endif
 
@@ -188,3 +193,37 @@ static int microblaze_debugfs_init(void)
 }
 arch_initcall(microblaze_debugfs_init);
 #endif
+
+static int dflt_bus_notify(struct notifier_block *nb,
+                               unsigned long action, void *data)
+{
+       struct device *dev = data;
+
+       /* We are only intereted in device addition */
+       if (action != BUS_NOTIFY_ADD_DEVICE)
+               return 0;
+
+       set_dma_ops(dev, &dma_direct_ops);
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block dflt_plat_bus_notifier = {
+       .notifier_call = dflt_bus_notify,
+       .priority = INT_MAX,
+};
+
+static struct notifier_block dflt_of_bus_notifier = {
+       .notifier_call = dflt_bus_notify,
+       .priority = INT_MAX,
+};
+
+static int __init setup_bus_notifier(void)
+{
+       bus_register_notifier(&platform_bus_type, &dflt_plat_bus_notifier);
+       bus_register_notifier(&of_platform_bus_type, &dflt_of_bus_notifier);
+
+       return 0;
+}
+
+arch_initcall(setup_bus_notifier);
index 9f3c205fb75b71c47086f21f9e80863b6dcd14df..f4e00b7f12594877e86c780258e7d93d9bd35490 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/semaphore.h>
 #include <linux/uaccess.h>
 #include <linux/unistd.h>
+#include <linux/slab.h>
 
 #include <asm/syscalls.h>
 
index eaaaf805f31b6d32039376df4f0e9ffdec777b5d..75e49202a5ed6bcb14cf4d629f082349685fae1a 100644 (file)
@@ -22,13 +22,11 @@ void trap_init(void)
        __enable_hw_exceptions();
 }
 
-static int kstack_depth_to_print = 24;
+static unsigned long kstack_depth_to_print = 24;
 
 static int __init kstack_setup(char *s)
 {
-       kstack_depth_to_print = strict_strtoul(s, 0, NULL);
-
-       return 1;
+       return !strict_strtoul(s, 0, &kstack_depth_to_print);
 }
 __setup("kstack=", kstack_setup);
 
@@ -97,37 +95,3 @@ void dump_stack(void)
        show_stack(NULL, NULL);
 }
 EXPORT_SYMBOL(dump_stack);
-
-#ifdef CONFIG_MMU
-void __bug(const char *file, int line, void *data)
-{
-       if (data)
-               printk(KERN_CRIT "kernel BUG at %s:%d (data = %p)!\n",
-                       file, line, data);
-       else
-               printk(KERN_CRIT "kernel BUG at %s:%d!\n", file, line);
-
-       machine_halt();
-}
-
-int bad_trap(int trap_num, struct pt_regs *regs)
-{
-       printk(KERN_CRIT
-               "unimplemented trap %d called at 0x%08lx, pid %d!\n",
-               trap_num, regs->pc, current->pid);
-       return -ENOSYS;
-}
-
-int debug_trap(struct pt_regs *regs)
-{
-       int i;
-       printk(KERN_CRIT "debug trap\n");
-       for (i = 0; i < 32; i++) {
-               /* printk("r%i:%08X\t",i,regs->gpr[i]); */
-               if ((i % 4) == 3)
-                       printk(KERN_CRIT "\n");
-       }
-       printk(KERN_CRIT "pc:%08lX\tmsr:%08lX\n", regs->pc, regs->msr);
-       return -ENOSYS;
-}
-#endif
index 5ef619aad6341b8ecd6ca021c03dd4b74d418653..db72d71246022eec5e40c05aac2624a67ee646e5 100644 (file)
@@ -24,7 +24,8 @@ SECTIONS {
        .text : AT(ADDR(.text) - LOAD_OFFSET) {
                _text = . ;
                _stext = . ;
-               *(.text .text.*)
+               HEAD_TEXT
+               TEXT_TEXT
                *(.fixup)
                EXIT_TEXT
                EXIT_CALL
index b579db068c06fd3346a1458879145ef8f50063b3..4dfe47d3cd916e51ad21e25eb674afea71ff8551 100644 (file)
@@ -10,5 +10,4 @@ else
 lib-y += memcpy.o memmove.o
 endif
 
-lib-$(CONFIG_NO_MMU) += uaccess.o
-lib-$(CONFIG_MMU) += uaccess_old.o
+lib-y += uaccess_old.o
index 02e3ab4eddf3a2a29c742cf6d5b44ca9fe7bc1e0..fdc48bb065d89fe3b2443ef054d1a6ece3744b54 100644 (file)
@@ -30,8 +30,9 @@
  */
 
 #include <linux/linkage.h>
-
+       .text
        .globl  memcpy
+       .type  memcpy, @function
        .ent    memcpy
 
 memcpy:
@@ -345,9 +346,11 @@ a_done:
        rtsd    r15, 8
        nop
 
+.size  memcpy, . - memcpy
 .end memcpy
 /*----------------------------------------------------------------------------*/
        .globl  memmove
+       .type  memmove, @function
        .ent    memmove
 
 memmove:
@@ -659,4 +662,5 @@ d_done:
        rtsd    r15, 8
        nop
 
+.size  memmove, . - memmove
 .end memmove
index cc2108b6b2602180dc11fbb559d4b090359ef35c..014bac92bdff74553595280c0be125a7b17cfcfb 100644 (file)
@@ -53,7 +53,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
        const uint32_t *i_src;
        uint32_t *i_dst;
 
-       if (c >= 4) {
+       if (likely(c >= 4)) {
                unsigned  value, buf_hold;
 
                /* Align the dstination to a word boundry. */
index 4df851d41a2966f992c09ec8f571fe4fd2f0eee2..ecfb663e1fc159dc33a922b894910f4912d6ed09 100644 (file)
 #ifdef __HAVE_ARCH_MEMSET
 void *memset(void *v_src, int c, __kernel_size_t n)
 {
-
        char *src = v_src;
 #ifdef CONFIG_OPT_LIB_FUNCTION
        uint32_t *i_src;
-       uint32_t w32;
+       uint32_t w32 = 0;
 #endif
        /* Truncate c to 8 bits */
        c = (c & 0xFF);
 
 #ifdef CONFIG_OPT_LIB_FUNCTION
-       /* Make a repeating word out of it */
-       w32 = c;
-       w32 |= w32 << 8;
-       w32 |= w32 << 16;
+       if (unlikely(c)) {
+               /* Make a repeating word out of it */
+               w32 = c;
+               w32 |= w32 << 8;
+               w32 |= w32 << 16;
+       }
 
-       if (n >= 4) {
+       if (likely(n >= 4)) {
                /* Align the destination to a word boundary */
                /* This is done in an endian independant manner */
                switch ((unsigned) src & 3) {
diff --git a/arch/microblaze/lib/uaccess.c b/arch/microblaze/lib/uaccess.c
deleted file mode 100644 (file)
index a853fe0..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * 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.
- */
-
-#include <linux/string.h>
-#include <asm/uaccess.h>
-
-#include <asm/bug.h>
-
-long strnlen_user(const char __user *src, long count)
-{
-       return strlen(src) + 1;
-}
-
-#define __do_strncpy_from_user(dst, src, count, res)                   \
-       do {                                                            \
-               char *tmp;                                              \
-               strncpy(dst, src, count);                               \
-               for (tmp = dst; *tmp && count > 0; tmp++, count--)      \
-                       ;                                               \
-               res = (tmp - dst);                                      \
-       } while (0)
-
-long __strncpy_from_user(char *dst, const char __user *src, long count)
-{
-       long res;
-       __do_strncpy_from_user(dst, src, count, res);
-       return res;
-}
-
-long strncpy_from_user(char *dst, const char __user *src, long count)
-{
-       long res = -EFAULT;
-       if (access_ok(VERIFY_READ, src, 1))
-               __do_strncpy_from_user(dst, src, count, res);
-       return res;
-}
-
-unsigned long __copy_tofrom_user(void __user *to,
-               const void __user *from, unsigned long size)
-{
-       memcpy(to, from, size);
-       return 0;
-}
index 67f991c14b8a5f24edcd5aa660555368cc3259e6..5810cec54a7a36e356d5c48b4ad29923ee0829e4 100644 (file)
@@ -22,6 +22,7 @@
 
        .text
 .globl __strncpy_user;
+.type  __strncpy_user, @function
 .align 4;
 __strncpy_user:
 
@@ -50,7 +51,7 @@ __strncpy_user:
 3:
        rtsd    r15,8
        nop
-
+       .size   __strncpy_user, . - __strncpy_user
 
        .section        .fixup, "ax"
        .align  2
@@ -72,6 +73,7 @@ __strncpy_user:
 
        .text
 .globl __strnlen_user;
+.type  __strnlen_user, @function
 .align 4;
 __strnlen_user:
        addik   r3,r6,0
@@ -90,7 +92,7 @@ __strnlen_user:
 3:
        rtsd    r15,8
        nop
-
+       .size   __strnlen_user, . - __strnlen_user
 
        .section        .fixup,"ax"
 4:
@@ -108,6 +110,7 @@ __strnlen_user:
  */
        .text
 .globl __copy_tofrom_user;
+.type  __copy_tofrom_user, @function
 .align 4;
 __copy_tofrom_user:
        /*
@@ -116,20 +119,34 @@ __copy_tofrom_user:
         * r7, r3 - count
         * r4 - tempval
         */
-       addik   r3,r7,0
-       beqi    r3,3f
-1:
-       lbu     r4,r6,r0
-       addik   r6,r6,1
-2:
-       sb      r4,r5,r0
-       addik   r3,r3,-1
-       bneid   r3,1b
-       addik   r5,r5,1         /* delay slot */
+       beqid   r7, 3f /* zero size is not likely */
+       andi    r3, r7, 0x3 /* filter add count */
+       bneid   r3, 4f /* if is odd value then byte copying */
+       or      r3, r5, r6 /* find if is any to/from unaligned */
+       andi    r3, r3, 0x3 /* mask unaligned */
+       bneid   r3, 1f /* it is unaligned -> then jump */
+       or      r3, r0, r0
+
+/* at least one 4 byte copy */
+5:     lw      r4, r6, r3
+6:     sw      r4, r5, r3
+       addik   r7, r7, -4
+       bneid   r7, 5b
+       addik   r3, r3, 4
+       addik   r3, r7, 0
+       rtsd    r15, 8
+       nop
+4:     or      r3, r0, r0
+1:     lbu     r4,r6,r3
+2:     sb      r4,r5,r3
+       addik   r7,r7,-1
+       bneid   r7,1b
+       addik   r3,r3,1         /* delay slot */
 3:
+       addik   r3,r7,0
        rtsd    r15,8
        nop
-
+       .size   __copy_tofrom_user, . - __copy_tofrom_user
 
        .section        __ex_table,"a"
-       .word   1b,3b,2b,3b
+       .word   1b,3b,2b,3b,5b,3b,6b,3b
index 6c8a924d9e266f8313b7107abc844c853968f633..09c49ed872358c1f53f92f8293bde1822829031b 100644 (file)
@@ -2,6 +2,6 @@
 # Makefile
 #
 
-obj-y := init.o
+obj-y := consistent.o init.o
 
 obj-$(CONFIG_MMU) += pgtable.o mmu_context.o fault.o
diff --git a/arch/microblaze/mm/consistent.c b/arch/microblaze/mm/consistent.c
new file mode 100644 (file)
index 0000000..5a59dad
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * Microblaze support for cache consistent memory.
+ * Copyright (C) 2010 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2010 PetaLogix
+ * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * Based on PowerPC version derived from arch/arm/mm/consistent.c
+ * Copyright (C) 2001 Dan Malek (dmalek@jlc.net)
+ * Copyright (C) 2000 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.
+ */
+
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/gfp.h>
+
+#include <asm/pgalloc.h>
+#include <linux/io.h>
+#include <linux/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/mmu.h>
+#include <linux/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/cpuinfo.h>
+#include <asm/tlbflush.h>
+
+#ifndef CONFIG_MMU
+/* I have to use dcache values because I can't relate on ram size */
+# define UNCACHED_SHADOW_MASK (cpuinfo.dcache_high - cpuinfo.dcache_base + 1)
+#endif
+
+/*
+ * Consistent memory allocators. Used for DMA devices that want to
+ * share uncached memory with the processor core.
+ * My crufty no-MMU approach is simple. In the HW platform we can optionally
+ * mirror the DDR up above the processor cacheable region.  So, memory accessed
+ * in this mirror region will not be cached.  It's alloced from the same
+ * pool as normal memory, but the handle we return is shifted up into the
+ * uncached region.  This will no doubt cause big problems if memory allocated
+ * here is not also freed properly. -- JW
+ */
+void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
+{
+       unsigned long order, vaddr;
+       void *ret;
+       unsigned int i, err = 0;
+       struct page *page, *end;
+
+#ifdef CONFIG_MMU
+       phys_addr_t pa;
+       struct vm_struct *area;
+       unsigned long va;
+#endif
+
+       if (in_interrupt())
+               BUG();
+
+       /* Only allocate page size areas. */
+       size = PAGE_ALIGN(size);
+       order = get_order(size);
+
+       vaddr = __get_free_pages(gfp, order);
+       if (!vaddr)
+               return NULL;
+
+       /*
+        * we need to ensure that there are no cachelines in use,
+        * or worse dirty in this area.
+        */
+       flush_dcache_range(virt_to_phys((void *)vaddr),
+                                       virt_to_phys((void *)vaddr) + size);
+
+#ifndef CONFIG_MMU
+       ret = (void *)vaddr;
+       /*
+        * Here's the magic!  Note if the uncached shadow is not implemented,
+        * it's up to the calling code to also test that condition and make
+        * other arranegments, such as manually flushing the cache and so on.
+        */
+# ifdef CONFIG_XILINX_UNCACHED_SHADOW
+       ret = (void *)((unsigned) ret | UNCACHED_SHADOW_MASK);
+# endif
+       if ((unsigned int)ret > cpuinfo.dcache_base &&
+                               (unsigned int)ret < cpuinfo.dcache_high)
+               printk(KERN_WARNING
+                       "ERROR: Your cache coherent area is CACHED!!!\n");
+
+       /* dma_handle is same as physical (shadowed) address */
+       *dma_handle = (dma_addr_t)ret;
+#else
+       /* Allocate some common virtual space to map the new pages. */
+       area = get_vm_area(size, VM_ALLOC);
+       if (!area) {
+               free_pages(vaddr, order);
+               return NULL;
+       }
+       va = (unsigned long) area->addr;
+       ret = (void *)va;
+
+       /* This gives us the real physical address of the first page. */
+       *dma_handle = pa = virt_to_bus((void *)vaddr);
+#endif
+
+       /*
+        * free wasted pages.  We skip the first page since we know
+        * that it will have count = 1 and won't require freeing.
+        * We also mark the pages in use as reserved so that
+        * remap_page_range works.
+        */
+       page = virt_to_page(vaddr);
+       end = page + (1 << order);
+
+       split_page(page, order);
+
+       for (i = 0; i < size && err == 0; i += PAGE_SIZE) {
+#ifdef CONFIG_MMU
+               /* MS: This is the whole magic - use cache inhibit pages */
+               err = map_page(va + i, pa + i, _PAGE_KERNEL | _PAGE_NO_CACHE);
+#endif
+
+               SetPageReserved(page);
+               page++;
+       }
+
+       /* Free the otherwise unused pages. */
+       while (page < end) {
+               __free_page(page);
+               page++;
+       }
+
+       if (err) {
+               free_pages(vaddr, order);
+               return NULL;
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL(consistent_alloc);
+
+/*
+ * free page(s) as defined by the above mapping.
+ */
+void consistent_free(size_t size, void *vaddr)
+{
+       struct page *page;
+
+       if (in_interrupt())
+               BUG();
+
+       size = PAGE_ALIGN(size);
+
+#ifndef CONFIG_MMU
+       /* Clear SHADOW_MASK bit in address, and free as per usual */
+# ifdef CONFIG_XILINX_UNCACHED_SHADOW
+       vaddr = (void *)((unsigned)vaddr & ~UNCACHED_SHADOW_MASK);
+# endif
+       page = virt_to_page(vaddr);
+
+       do {
+               ClearPageReserved(page);
+               __free_page(page);
+               page++;
+       } while (size -= PAGE_SIZE);
+#else
+       do {
+               pte_t *ptep;
+               unsigned long pfn;
+
+               ptep = pte_offset_kernel(pmd_offset(pgd_offset_k(
+                                               (unsigned int)vaddr),
+                                       (unsigned int)vaddr),
+                               (unsigned int)vaddr);
+               if (!pte_none(*ptep) && pte_present(*ptep)) {
+                       pfn = pte_pfn(*ptep);
+                       pte_clear(&init_mm, (unsigned int)vaddr, ptep);
+                       if (pfn_valid(pfn)) {
+                               page = pfn_to_page(pfn);
+
+                               ClearPageReserved(page);
+                               __free_page(page);
+                       }
+               }
+               vaddr += PAGE_SIZE;
+       } while (size -= PAGE_SIZE);
+
+       /* flush tlb */
+       flush_tlb_all();
+#endif
+}
+EXPORT_SYMBOL(consistent_free);
+
+/*
+ * make an area consistent.
+ */
+void consistent_sync(void *vaddr, size_t size, int direction)
+{
+       unsigned long start;
+       unsigned long end;
+
+       start = (unsigned long)vaddr;
+
+       /* Convert start address back down to unshadowed memory region */
+#ifdef CONFIG_XILINX_UNCACHED_SHADOW
+       start &= ~UNCACHED_SHADOW_MASK;
+#endif
+       end = start + size;
+
+       switch (direction) {
+       case PCI_DMA_NONE:
+               BUG();
+       case PCI_DMA_FROMDEVICE:        /* invalidate only */
+               invalidate_dcache_range(start, end);
+               break;
+       case PCI_DMA_TODEVICE:          /* writeback only */
+               flush_dcache_range(start, end);
+               break;
+       case PCI_DMA_BIDIRECTIONAL:     /* writeback and invalidate */
+               flush_dcache_range(start, end);
+               break;
+       }
+}
+EXPORT_SYMBOL(consistent_sync);
+
+/*
+ * consistent_sync_page makes memory consistent. identical
+ * to consistent_sync, but takes a struct page instead of a
+ * virtual address
+ */
+void consistent_sync_page(struct page *page, unsigned long offset,
+       size_t size, int direction)
+{
+       unsigned long start = (unsigned long)page_address(page) + offset;
+       consistent_sync((void *)start, size, direction);
+}
+EXPORT_SYMBOL(consistent_sync_page);
index d9d249a66ff2eda43688483cb1cab0aba3434de9..bab9229931858475d886fd3ac750883c92f5f614 100644 (file)
@@ -106,7 +106,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
        regs->esr = error_code;
 
        /* On a kernel SLB miss we can only check for a valid exception entry */
-       if (kernel_mode(regs) && (address >= TASK_SIZE)) {
+       if (unlikely(kernel_mode(regs) && (address >= TASK_SIZE))) {
                printk(KERN_WARNING "kernel task_size exceed");
                _exception(SIGSEGV, regs, code, address);
        }
@@ -122,7 +122,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
        }
 #endif /* CONFIG_KGDB */
 
-       if (in_atomic() || !mm) {
+       if (unlikely(in_atomic() || !mm)) {
                if (kernel_mode(regs))
                        goto bad_area_nosemaphore;
 
@@ -150,7 +150,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
         * source.  If this is invalid we can skip the address space check,
         * thus avoiding the deadlock.
         */
-       if (!down_read_trylock(&mm->mmap_sem)) {
+       if (unlikely(!down_read_trylock(&mm->mmap_sem))) {
                if (kernel_mode(regs) && !search_exception_tables(regs->pc))
                        goto bad_area_nosemaphore;
 
@@ -158,16 +158,16 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
        }
 
        vma = find_vma(mm, address);
-       if (!vma)
+       if (unlikely(!vma))
                goto bad_area;
 
        if (vma->vm_start <= address)
                goto good_area;
 
-       if (!(vma->vm_flags & VM_GROWSDOWN))
+       if (unlikely(!(vma->vm_flags & VM_GROWSDOWN)))
                goto bad_area;
 
-       if (!is_write)
+       if (unlikely(!is_write))
                goto bad_area;
 
        /*
@@ -179,7 +179,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
         * before setting the user r1.  Thus we allow the stack to
         * expand to 1MB without further checks.
         */
-       if (address + 0x100000 < vma->vm_end) {
+       if (unlikely(address + 0x100000 < vma->vm_end)) {
 
                /* get user regs even if this fault is in kernel mode */
                struct pt_regs *uregs = current->thread.regs;
@@ -209,15 +209,15 @@ good_area:
        code = SEGV_ACCERR;
 
        /* a write */
-       if (is_write) {
-               if (!(vma->vm_flags & VM_WRITE))
+       if (unlikely(is_write)) {
+               if (unlikely(!(vma->vm_flags & VM_WRITE)))
                        goto bad_area;
        /* a read */
        } else {
                /* protection fault */
-               if (error_code & 0x08000000)
+               if (unlikely(error_code & 0x08000000))
                        goto bad_area;
-               if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+               if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC))))
                        goto bad_area;
        }
 
@@ -235,7 +235,7 @@ survive:
                        goto do_sigbus;
                BUG();
        }
-       if (fault & VM_FAULT_MAJOR)
+       if (unlikely(fault & VM_FAULT_MAJOR))
                current->maj_flt++;
        else
                current->min_flt++;
@@ -273,16 +273,11 @@ bad_area_nosemaphore:
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-       if (current->pid == 1) {
-               yield();
-               down_read(&mm->mmap_sem);
-               goto survive;
-       }
        up_read(&mm->mmap_sem);
-       printk(KERN_WARNING "VM: killing process %s\n", current->comm);
-       if (user_mode(regs))
-               do_exit(SIGKILL);
-       bad_page_fault(regs, address, SIGKILL);
+       if (!user_mode(regs))
+               bad_page_fault(regs, address, SIGKILL);
+       else
+               pagefault_out_of_memory();
        return;
 
 do_sigbus:
index a57cedf36715f7511395b3066878731b107edb1e..cca3579d4268d07aab1910a463180f9dd271a4e6 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/initrd.h>
 #include <linux/pagemap.h>
 #include <linux/pfn.h>
+#include <linux/slab.h>
 #include <linux/swap.h>
 
 #include <asm/page.h>
@@ -23,6 +24,9 @@
 #include <asm/sections.h>
 #include <asm/tlb.h>
 
+/* Use for MMU and noMMU because of PCI generic code */
+int mem_init_done;
+
 #ifndef CONFIG_MMU
 unsigned int __page_offset;
 EXPORT_SYMBOL(__page_offset);
@@ -30,7 +34,6 @@ EXPORT_SYMBOL(__page_offset);
 #else
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
-int mem_init_done;
 static int init_bootmem_done;
 #endif /* CONFIG_MMU */
 
@@ -44,6 +47,7 @@ unsigned long memory_start;
 EXPORT_SYMBOL(memory_start);
 unsigned long memory_end; /* due to mm/nommu.c */
 unsigned long memory_size;
+EXPORT_SYMBOL(memory_size);
 
 /*
  * paging_init() sets up the page tables - in fact we've already done this.
@@ -163,7 +167,6 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
        for (addr = begin; addr < end; addr += PAGE_SIZE) {
                ClearPageReserved(virt_to_page(addr));
                init_page_count(virt_to_page(addr));
-               memset((void *)addr, 0xcc, PAGE_SIZE);
                free_page(addr);
                totalram_pages++;
        }
@@ -193,12 +196,6 @@ void free_initmem(void)
                        (unsigned long)(&__init_end));
 }
 
-/* FIXME from arch/powerpc/mm/mem.c*/
-void show_mem(void)
-{
-       printk(KERN_NOTICE "%s\n", __func__);
-}
-
 void __init mem_init(void)
 {
        high_memory = (void *)__va(memory_end);
@@ -208,20 +205,14 @@ void __init mem_init(void)
        printk(KERN_INFO "Memory: %luk/%luk available\n",
               nr_free_pages() << (PAGE_SHIFT-10),
               num_physpages << (PAGE_SHIFT-10));
-#ifdef CONFIG_MMU
        mem_init_done = 1;
-#endif
 }
 
 #ifndef CONFIG_MMU
-/* Check against bounds of physical memory */
-int ___range_ok(unsigned long addr, unsigned long size)
+int page_is_ram(unsigned long pfn)
 {
-       return ((addr < memory_start) ||
-               ((addr + size) > memory_end));
+       return __range_ok(pfn, 0);
 }
-EXPORT_SYMBOL(___range_ok);
-
 #else
 int page_is_ram(unsigned long pfn)
 {
@@ -349,4 +340,27 @@ void __init *early_get_page(void)
        }
        return p;
 }
+
 #endif /* CONFIG_MMU */
+
+void * __init_refok alloc_maybe_bootmem(size_t size, gfp_t mask)
+{
+       if (mem_init_done)
+               return kmalloc(size, mask);
+       else
+               return alloc_bootmem(size);
+}
+
+void * __init_refok zalloc_maybe_bootmem(size_t size, gfp_t mask)
+{
+       void *p;
+
+       if (mem_init_done)
+               p = kzalloc(size, mask);
+       else {
+               p = alloc_bootmem(size);
+               if (p)
+                       memset(p, 0, size);
+       }
+       return p;
+}
index 2820081b21ab8bc4a9b87c5147f3516cfb674c4a..59bf2335a4ce06a9691c02b6f683036579a1381e 100644 (file)
@@ -42,6 +42,7 @@
 
 unsigned long ioremap_base;
 unsigned long ioremap_bot;
+EXPORT_SYMBOL(ioremap_bot);
 
 /* The maximum lowmem defaults to 768Mb, but this can be configured to
  * another value.
@@ -103,7 +104,7 @@ static void __iomem *__ioremap(phys_addr_t addr, unsigned long size,
                area = get_vm_area(size, VM_IOREMAP);
                if (area == NULL)
                        return NULL;
-               v = VMALLOC_VMADDR(area->addr);
+               v = (unsigned long) area->addr;
        } else {
                v = (ioremap_bot -= size);
        }
@@ -154,31 +155,13 @@ int map_page(unsigned long va, phys_addr_t pa, int flags)
                err = 0;
                set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT,
                                __pgprot(flags)));
-               if (mem_init_done)
+               if (unlikely(mem_init_done))
                        flush_HPTE(0, va, pmd_val(*pd));
                        /* flush_HPTE(0, va, pg); */
        }
        return err;
 }
 
-void __init adjust_total_lowmem(void)
-{
-/* TBD */
-#if 0
-       unsigned long max_low_mem = MAX_LOW_MEM;
-
-       if (total_lowmem > max_low_mem) {
-               total_lowmem = max_low_mem;
-#ifndef CONFIG_HIGHMEM
-               printk(KERN_INFO "Warning, memory limited to %ld Mb, use "
-                               "CONFIG_HIGHMEM to reach %ld Mb\n",
-                               max_low_mem >> 20, total_memory >> 20);
-               total_memory = total_lowmem;
-#endif /* CONFIG_HIGHMEM */
-       }
-#endif
-}
-
 /*
  * Map in all of physical memory starting at CONFIG_KERNEL_START.
  */
@@ -206,24 +189,6 @@ void __init mapin_ram(void)
 /* is x a power of 2? */
 #define is_power_of_2(x)       ((x) != 0 && (((x) & ((x) - 1)) == 0))
 
-/*
- * Set up a mapping for a block of I/O.
- * virt, phys, size must all be page-aligned.
- * This should only be called before ioremap is called.
- */
-void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
-                            unsigned int size, int flags)
-{
-       int i;
-
-       if (virt > CONFIG_KERNEL_START && virt < ioremap_bot)
-               ioremap_bot = ioremap_base = virt;
-
-       /* Put it in the page tables. */
-       for (i = 0; i < size; i += PAGE_SIZE)
-               map_page(virt + i, phys + i, flags);
-}
-
 /* Scan the real Linux page tables and return a PTE pointer for
  * a virtual address in a context.
  * Returns true (1) if PTE was found, zero otherwise.  The pointer to
@@ -274,3 +239,18 @@ unsigned long iopa(unsigned long addr)
 
        return pa;
 }
+
+__init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+               unsigned long address)
+{
+       pte_t *pte;
+       if (mem_init_done) {
+               pte = (pte_t *)__get_free_page(GFP_KERNEL |
+                                       __GFP_REPEAT | __GFP_ZERO);
+       } else {
+               pte = (pte_t *)early_get_page();
+               if (pte)
+                       clear_page(pte);
+       }
+       return pte;
+}
diff --git a/arch/microblaze/pci/Makefile b/arch/microblaze/pci/Makefile
new file mode 100644 (file)
index 0000000..9889cc2
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile
+#
+
+obj-$(CONFIG_PCI)              += pci_32.o pci-common.o indirect_pci.o iomap.o
+obj-$(CONFIG_PCI_XILINX)       += xilinx_pci.o
diff --git a/arch/microblaze/pci/indirect_pci.c b/arch/microblaze/pci/indirect_pci.c
new file mode 100644 (file)
index 0000000..25f18f0
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Support for indirect PCI bridges.
+ *
+ * Copyright (C) 1998 Gabriel Paubert.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+
+static int
+indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+                    int len, u32 *val)
+{
+       struct pci_controller *hose = pci_bus_to_host(bus);
+       volatile void __iomem *cfg_data;
+       u8 cfg_type = 0;
+       u32 bus_no, reg;
+
+       if (hose->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK) {
+               if (bus->number != hose->first_busno)
+                       return PCIBIOS_DEVICE_NOT_FOUND;
+               if (devfn != 0)
+                       return PCIBIOS_DEVICE_NOT_FOUND;
+       }
+
+       if (hose->indirect_type & INDIRECT_TYPE_SET_CFG_TYPE)
+               if (bus->number != hose->first_busno)
+                       cfg_type = 1;
+
+       bus_no = (bus->number == hose->first_busno) ?
+                       hose->self_busno : bus->number;
+
+       if (hose->indirect_type & INDIRECT_TYPE_EXT_REG)
+               reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
+       else
+               reg = offset & 0xfc; /* Only 3 bits for function */
+
+       if (hose->indirect_type & INDIRECT_TYPE_BIG_ENDIAN)
+               out_be32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
+                        (devfn << 8) | reg | cfg_type));
+       else
+               out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
+                        (devfn << 8) | reg | cfg_type));
+
+       /*
+        * Note: the caller has already checked that offset is
+        * suitably aligned and that len is 1, 2 or 4.
+        */
+       cfg_data = hose->cfg_data + (offset & 3); /* Only 3 bits for function */
+       switch (len) {
+       case 1:
+               *val = in_8(cfg_data);
+               break;
+       case 2:
+               *val = in_le16(cfg_data);
+               break;
+       default:
+               *val = in_le32(cfg_data);
+               break;
+       }
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+                     int len, u32 val)
+{
+       struct pci_controller *hose = pci_bus_to_host(bus);
+       volatile void __iomem *cfg_data;
+       u8 cfg_type = 0;
+       u32 bus_no, reg;
+
+       if (hose->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK) {
+               if (bus->number != hose->first_busno)
+                       return PCIBIOS_DEVICE_NOT_FOUND;
+               if (devfn != 0)
+                       return PCIBIOS_DEVICE_NOT_FOUND;
+       }
+
+       if (hose->indirect_type & INDIRECT_TYPE_SET_CFG_TYPE)
+               if (bus->number != hose->first_busno)
+                       cfg_type = 1;
+
+       bus_no = (bus->number == hose->first_busno) ?
+                       hose->self_busno : bus->number;
+
+       if (hose->indirect_type & INDIRECT_TYPE_EXT_REG)
+               reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
+       else
+               reg = offset & 0xfc;
+
+       if (hose->indirect_type & INDIRECT_TYPE_BIG_ENDIAN)
+               out_be32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
+                        (devfn << 8) | reg | cfg_type));
+       else
+               out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
+                        (devfn << 8) | reg | cfg_type));
+
+       /* surpress setting of PCI_PRIMARY_BUS */
+       if (hose->indirect_type & INDIRECT_TYPE_SURPRESS_PRIMARY_BUS)
+               if ((offset == PCI_PRIMARY_BUS) &&
+                       (bus->number == hose->first_busno))
+                       val &= 0xffffff00;
+
+       /* Workaround for PCI_28 Errata in 440EPx/GRx */
+       if ((hose->indirect_type & INDIRECT_TYPE_BROKEN_MRM) &&
+                       offset == PCI_CACHE_LINE_SIZE) {
+               val = 0;
+       }
+
+       /*
+        * Note: the caller has already checked that offset is
+        * suitably aligned and that len is 1, 2 or 4.
+        */
+       cfg_data = hose->cfg_data + (offset & 3);
+       switch (len) {
+       case 1:
+               out_8(cfg_data, val);
+               break;
+       case 2:
+               out_le16(cfg_data, val);
+               break;
+       default:
+               out_le32(cfg_data, val);
+               break;
+       }
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops indirect_pci_ops = {
+       .read = indirect_read_config,
+       .write = indirect_write_config,
+};
+
+void __init
+setup_indirect_pci(struct pci_controller *hose,
+                  resource_size_t cfg_addr,
+                  resource_size_t cfg_data, u32 flags)
+{
+       resource_size_t base = cfg_addr & PAGE_MASK;
+       void __iomem *mbase;
+
+       mbase = ioremap(base, PAGE_SIZE);
+       hose->cfg_addr = mbase + (cfg_addr & ~PAGE_MASK);
+       if ((cfg_data & PAGE_MASK) != base)
+               mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE);
+       hose->cfg_data = mbase + (cfg_data & ~PAGE_MASK);
+       hose->ops = &indirect_pci_ops;
+       hose->indirect_type = flags;
+}
diff --git a/arch/microblaze/pci/iomap.c b/arch/microblaze/pci/iomap.c
new file mode 100644 (file)
index 0000000..3fbf16f
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * ppc64 "iomap" interface implementation.
+ *
+ * (C) Copyright 2004 Linus Torvalds
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pci-bridge.h>
+
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
+{
+       resource_size_t start = pci_resource_start(dev, bar);
+       resource_size_t len = pci_resource_len(dev, bar);
+       unsigned long flags = pci_resource_flags(dev, bar);
+
+       if (!len)
+               return NULL;
+       if (max && len > max)
+               len = max;
+       if (flags & IORESOURCE_IO)
+               return ioport_map(start, len);
+       if (flags & IORESOURCE_MEM)
+               return ioremap(start, len);
+       /* What? */
+       return NULL;
+}
+EXPORT_SYMBOL(pci_iomap);
+
+void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
+{
+       if (isa_vaddr_is_ioport(addr))
+               return;
+       if (pcibios_vaddr_is_ioport(addr))
+               return;
+       iounmap(addr);
+}
+EXPORT_SYMBOL(pci_iounmap);
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
new file mode 100644 (file)
index 0000000..9cb782b
--- /dev/null
@@ -0,0 +1,1642 @@
+/*
+ * Contains common pci routines for ALL ppc platform
+ * (based on pci_32.c and pci_64.c)
+ *
+ * Port for PPC64 David Engebretsen, IBM Corp.
+ * Contains common pci routines for ppc64 platform, pSeries and iSeries brands.
+ *
+ * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
+ *   Rework, based on alpha PCI code.
+ *
+ * Common pmac/prep/chrp pci routines. -- Cort
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+#include <linux/syscalls.h>
+#include <linux/irq.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/byteorder.h>
+
+static DEFINE_SPINLOCK(hose_spinlock);
+LIST_HEAD(hose_list);
+
+/* XXX kill that some day ... */
+static int global_phb_number;          /* Global phb counter */
+
+/* ISA Memory physical address */
+resource_size_t isa_mem_base;
+
+/* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */
+unsigned int pci_flags;
+
+static struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
+
+void set_pci_dma_ops(struct dma_map_ops *dma_ops)
+{
+       pci_dma_ops = dma_ops;
+}
+
+struct dma_map_ops *get_pci_dma_ops(void)
+{
+       return pci_dma_ops;
+}
+EXPORT_SYMBOL(get_pci_dma_ops);
+
+int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
+{
+       return dma_set_mask(&dev->dev, mask);
+}
+
+int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
+{
+       int rc;
+
+       rc = dma_set_mask(&dev->dev, mask);
+       dev->dev.coherent_dma_mask = dev->dma_mask;
+
+       return rc;
+}
+
+struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
+{
+       struct pci_controller *phb;
+
+       phb = zalloc_maybe_bootmem(sizeof(struct pci_controller), GFP_KERNEL);
+       if (!phb)
+               return NULL;
+       spin_lock(&hose_spinlock);
+       phb->global_number = global_phb_number++;
+       list_add_tail(&phb->list_node, &hose_list);
+       spin_unlock(&hose_spinlock);
+       phb->dn = dev;
+       phb->is_dynamic = mem_init_done;
+       return phb;
+}
+
+void pcibios_free_controller(struct pci_controller *phb)
+{
+       spin_lock(&hose_spinlock);
+       list_del(&phb->list_node);
+       spin_unlock(&hose_spinlock);
+
+       if (phb->is_dynamic)
+               kfree(phb);
+}
+
+static resource_size_t pcibios_io_size(const struct pci_controller *hose)
+{
+       return hose->io_resource.end - hose->io_resource.start + 1;
+}
+
+int pcibios_vaddr_is_ioport(void __iomem *address)
+{
+       int ret = 0;
+       struct pci_controller *hose;
+       resource_size_t size;
+
+       spin_lock(&hose_spinlock);
+       list_for_each_entry(hose, &hose_list, list_node) {
+               size = pcibios_io_size(hose);
+               if (address >= hose->io_base_virt &&
+                   address < (hose->io_base_virt + size)) {
+                       ret = 1;
+                       break;
+               }
+       }
+       spin_unlock(&hose_spinlock);
+       return ret;
+}
+
+unsigned long pci_address_to_pio(phys_addr_t address)
+{
+       struct pci_controller *hose;
+       resource_size_t size;
+       unsigned long ret = ~0;
+
+       spin_lock(&hose_spinlock);
+       list_for_each_entry(hose, &hose_list, list_node) {
+               size = pcibios_io_size(hose);
+               if (address >= hose->io_base_phys &&
+                   address < (hose->io_base_phys + size)) {
+                       unsigned long base =
+                               (unsigned long)hose->io_base_virt - _IO_BASE;
+                       ret = base + (address - hose->io_base_phys);
+                       break;
+               }
+       }
+       spin_unlock(&hose_spinlock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(pci_address_to_pio);
+
+/*
+ * Return the domain number for this bus.
+ */
+int pci_domain_nr(struct pci_bus *bus)
+{
+       struct pci_controller *hose = pci_bus_to_host(bus);
+
+       return hose->global_number;
+}
+EXPORT_SYMBOL(pci_domain_nr);
+
+/* This routine is meant to be used early during boot, when the
+ * PCI bus numbers have not yet been assigned, and you need to
+ * issue PCI config cycles to an OF device.
+ * It could also be used to "fix" RTAS config cycles if you want
+ * to set pci_assign_all_buses to 1 and still use RTAS for PCI
+ * config cycles.
+ */
+struct pci_controller *pci_find_hose_for_OF_device(struct device_node *node)
+{
+       while (node) {
+               struct pci_controller *hose, *tmp;
+               list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+                       if (hose->dn == node)
+                               return hose;
+               node = node->parent;
+       }
+       return NULL;
+}
+
+static ssize_t pci_show_devspec(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct pci_dev *pdev;
+       struct device_node *np;
+
+       pdev = to_pci_dev(dev);
+       np = pci_device_to_OF_node(pdev);
+       if (np == NULL || np->full_name == NULL)
+               return 0;
+       return sprintf(buf, "%s", np->full_name);
+}
+static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
+
+/* Add sysfs properties */
+int pcibios_add_platform_entries(struct pci_dev *pdev)
+{
+       return device_create_file(&pdev->dev, &dev_attr_devspec);
+}
+
+char __devinit *pcibios_setup(char *str)
+{
+       return str;
+}
+
+/*
+ * Reads the interrupt pin to determine if interrupt is use by card.
+ * If the interrupt is used, then gets the interrupt line from the
+ * openfirmware and sets it in the pci_dev and pci_config line.
+ */
+int pci_read_irq_line(struct pci_dev *pci_dev)
+{
+       struct of_irq oirq;
+       unsigned int virq;
+
+       /* The current device-tree that iSeries generates from the HV
+        * PCI informations doesn't contain proper interrupt routing,
+        * and all the fallback would do is print out crap, so we
+        * don't attempt to resolve the interrupts here at all, some
+        * iSeries specific fixup does it.
+        *
+        * In the long run, we will hopefully fix the generated device-tree
+        * instead.
+        */
+       pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev));
+
+#ifdef DEBUG
+       memset(&oirq, 0xff, sizeof(oirq));
+#endif
+       /* Try to get a mapping from the device-tree */
+       if (of_irq_map_pci(pci_dev, &oirq)) {
+               u8 line, pin;
+
+               /* If that fails, lets fallback to what is in the config
+                * space and map that through the default controller. We
+                * also set the type to level low since that's what PCI
+                * interrupts are. If your platform does differently, then
+                * either provide a proper interrupt tree or don't use this
+                * function.
+                */
+               if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin))
+                       return -1;
+               if (pin == 0)
+                       return -1;
+               if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
+                   line == 0xff || line == 0) {
+                       return -1;
+               }
+               pr_debug(" No map ! Using line %d (pin %d) from PCI config\n",
+                        line, pin);
+
+               virq = irq_create_mapping(NULL, line);
+               if (virq != NO_IRQ)
+                       set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
+       } else {
+               pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
+                        oirq.size, oirq.specifier[0], oirq.specifier[1],
+                        oirq.controller ? oirq.controller->full_name :
+                        "<default>");
+
+               virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+                                            oirq.size);
+       }
+       if (virq == NO_IRQ) {
+               pr_debug(" Failed to map !\n");
+               return -1;
+       }
+
+       pr_debug(" Mapped to linux irq %d\n", virq);
+
+       pci_dev->irq = virq;
+
+       return 0;
+}
+EXPORT_SYMBOL(pci_read_irq_line);
+
+/*
+ * Platform support for /proc/bus/pci/X/Y mmap()s,
+ * modelled on the sparc64 implementation by Dave Miller.
+ *  -- paulus.
+ */
+
+/*
+ * Adjust vm_pgoff of VMA such that it is the physical page offset
+ * corresponding to the 32-bit pci bus offset for DEV requested by the user.
+ *
+ * Basically, the user finds the base address for his device which he wishes
+ * to mmap.  They read the 32-bit value from the config space base register,
+ * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
+ * offset parameter of mmap on /proc/bus/pci/XXX for that device.
+ *
+ * Returns negative error code on failure, zero on success.
+ */
+static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
+                                              resource_size_t *offset,
+                                              enum pci_mmap_state mmap_state)
+{
+       struct pci_controller *hose = pci_bus_to_host(dev->bus);
+       unsigned long io_offset = 0;
+       int i, res_bit;
+
+       if (hose == 0)
+               return NULL;            /* should never happen */
+
+       /* If memory, add on the PCI bridge address offset */
+       if (mmap_state == pci_mmap_mem) {
+#if 0 /* See comment in pci_resource_to_user() for why this is disabled */
+               *offset += hose->pci_mem_offset;
+#endif
+               res_bit = IORESOURCE_MEM;
+       } else {
+               io_offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+               *offset += io_offset;
+               res_bit = IORESOURCE_IO;
+       }
+
+       /*
+        * Check that the offset requested corresponds to one of the
+        * resources of the device.
+        */
+       for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+               struct resource *rp = &dev->resource[i];
+               int flags = rp->flags;
+
+               /* treat ROM as memory (should be already) */
+               if (i == PCI_ROM_RESOURCE)
+                       flags |= IORESOURCE_MEM;
+
+               /* Active and same type? */
+               if ((flags & res_bit) == 0)
+                       continue;
+
+               /* In the range of this resource? */
+               if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)
+                       continue;
+
+               /* found it! construct the final physical address */
+               if (mmap_state == pci_mmap_io)
+                       *offset += hose->io_base_phys - io_offset;
+               return rp;
+       }
+
+       return NULL;
+}
+
+/*
+ * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
+ * device mapping.
+ */
+static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
+                                     pgprot_t protection,
+                                     enum pci_mmap_state mmap_state,
+                                     int write_combine)
+{
+       pgprot_t prot = protection;
+
+       /* Write combine is always 0 on non-memory space mappings. On
+        * memory space, if the user didn't pass 1, we check for a
+        * "prefetchable" resource. This is a bit hackish, but we use
+        * this to workaround the inability of /sysfs to provide a write
+        * combine bit
+        */
+       if (mmap_state != pci_mmap_mem)
+               write_combine = 0;
+       else if (write_combine == 0) {
+               if (rp->flags & IORESOURCE_PREFETCH)
+                       write_combine = 1;
+       }
+
+       return pgprot_noncached(prot);
+}
+
+/*
+ * This one is used by /dev/mem and fbdev who have no clue about the
+ * PCI device, it tries to find the PCI device first and calls the
+ * above routine
+ */
+pgprot_t pci_phys_mem_access_prot(struct file *file,
+                                 unsigned long pfn,
+                                 unsigned long size,
+                                 pgprot_t prot)
+{
+       struct pci_dev *pdev = NULL;
+       struct resource *found = NULL;
+       resource_size_t offset = ((resource_size_t)pfn) << PAGE_SHIFT;
+       int i;
+
+       if (page_is_ram(pfn))
+               return prot;
+
+       prot = pgprot_noncached(prot);
+       for_each_pci_dev(pdev) {
+               for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+                       struct resource *rp = &pdev->resource[i];
+                       int flags = rp->flags;
+
+                       /* Active and same type? */
+                       if ((flags & IORESOURCE_MEM) == 0)
+                               continue;
+                       /* In the range of this resource? */
+                       if (offset < (rp->start & PAGE_MASK) ||
+                           offset > rp->end)
+                               continue;
+                       found = rp;
+                       break;
+               }
+               if (found)
+                       break;
+       }
+       if (found) {
+               if (found->flags & IORESOURCE_PREFETCH)
+                       prot = pgprot_noncached_wc(prot);
+               pci_dev_put(pdev);
+       }
+
+       pr_debug("PCI: Non-PCI map for %llx, prot: %lx\n",
+                (unsigned long long)offset, pgprot_val(prot));
+
+       return prot;
+}
+
+/*
+ * Perform the actual remap of the pages for a PCI device mapping, as
+ * appropriate for this architecture.  The region in the process to map
+ * is described by vm_start and vm_end members of VMA, the base physical
+ * address is found in vm_pgoff.
+ * The pci device structure is provided so that architectures may make mapping
+ * decisions on a per-device or per-bus basis.
+ *
+ * Returns a negative error code on failure, zero on success.
+ */
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+                       enum pci_mmap_state mmap_state, int write_combine)
+{
+       resource_size_t offset =
+               ((resource_size_t)vma->vm_pgoff) << PAGE_SHIFT;
+       struct resource *rp;
+       int ret;
+
+       rp = __pci_mmap_make_offset(dev, &offset, mmap_state);
+       if (rp == NULL)
+               return -EINVAL;
+
+       vma->vm_pgoff = offset >> PAGE_SHIFT;
+       vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,
+                                                 vma->vm_page_prot,
+                                                 mmap_state, write_combine);
+
+       ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+                              vma->vm_end - vma->vm_start, vma->vm_page_prot);
+
+       return ret;
+}
+
+/* This provides legacy IO read access on a bus */
+int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t size)
+{
+       unsigned long offset;
+       struct pci_controller *hose = pci_bus_to_host(bus);
+       struct resource *rp = &hose->io_resource;
+       void __iomem *addr;
+
+       /* Check if port can be supported by that bus. We only check
+        * the ranges of the PHB though, not the bus itself as the rules
+        * for forwarding legacy cycles down bridges are not our problem
+        * here. So if the host bridge supports it, we do it.
+        */
+       offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+       offset += port;
+
+       if (!(rp->flags & IORESOURCE_IO))
+               return -ENXIO;
+       if (offset < rp->start || (offset + size) > rp->end)
+               return -ENXIO;
+       addr = hose->io_base_virt + port;
+
+       switch (size) {
+       case 1:
+               *((u8 *)val) = in_8(addr);
+               return 1;
+       case 2:
+               if (port & 1)
+                       return -EINVAL;
+               *((u16 *)val) = in_le16(addr);
+               return 2;
+       case 4:
+               if (port & 3)
+                       return -EINVAL;
+               *((u32 *)val) = in_le32(addr);
+               return 4;
+       }
+       return -EINVAL;
+}
+
+/* This provides legacy IO write access on a bus */
+int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size)
+{
+       unsigned long offset;
+       struct pci_controller *hose = pci_bus_to_host(bus);
+       struct resource *rp = &hose->io_resource;
+       void __iomem *addr;
+
+       /* Check if port can be supported by that bus. We only check
+        * the ranges of the PHB though, not the bus itself as the rules
+        * for forwarding legacy cycles down bridges are not our problem
+        * here. So if the host bridge supports it, we do it.
+        */
+       offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+       offset += port;
+
+       if (!(rp->flags & IORESOURCE_IO))
+               return -ENXIO;
+       if (offset < rp->start || (offset + size) > rp->end)
+               return -ENXIO;
+       addr = hose->io_base_virt + port;
+
+       /* WARNING: The generic code is idiotic. It gets passed a pointer
+        * to what can be a 1, 2 or 4 byte quantity and always reads that
+        * as a u32, which means that we have to correct the location of
+        * the data read within those 32 bits for size 1 and 2
+        */
+       switch (size) {
+       case 1:
+               out_8(addr, val >> 24);
+               return 1;
+       case 2:
+               if (port & 1)
+                       return -EINVAL;
+               out_le16(addr, val >> 16);
+               return 2;
+       case 4:
+               if (port & 3)
+                       return -EINVAL;
+               out_le32(addr, val);
+               return 4;
+       }
+       return -EINVAL;
+}
+
+/* This provides legacy IO or memory mmap access on a bus */
+int pci_mmap_legacy_page_range(struct pci_bus *bus,
+                              struct vm_area_struct *vma,
+                              enum pci_mmap_state mmap_state)
+{
+       struct pci_controller *hose = pci_bus_to_host(bus);
+       resource_size_t offset =
+               ((resource_size_t)vma->vm_pgoff) << PAGE_SHIFT;
+       resource_size_t size = vma->vm_end - vma->vm_start;
+       struct resource *rp;
+
+       pr_debug("pci_mmap_legacy_page_range(%04x:%02x, %s @%llx..%llx)\n",
+                pci_domain_nr(bus), bus->number,
+                mmap_state == pci_mmap_mem ? "MEM" : "IO",
+                (unsigned long long)offset,
+                (unsigned long long)(offset + size - 1));
+
+       if (mmap_state == pci_mmap_mem) {
+               /* Hack alert !
+                *
+                * Because X is lame and can fail starting if it gets an error
+                * trying to mmap legacy_mem (instead of just moving on without
+                * legacy memory access) we fake it here by giving it anonymous
+                * memory, effectively behaving just like /dev/zero
+                */
+               if ((offset + size) > hose->isa_mem_size) {
+#ifdef CONFIG_MMU
+                       printk(KERN_DEBUG
+                               "Process %s (pid:%d) mapped non-existing PCI"
+                               "legacy memory for 0%04x:%02x\n",
+                               current->comm, current->pid, pci_domain_nr(bus),
+                                                               bus->number);
+#endif
+                       if (vma->vm_flags & VM_SHARED)
+                               return shmem_zero_setup(vma);
+                       return 0;
+               }
+               offset += hose->isa_mem_phys;
+       } else {
+               unsigned long io_offset = (unsigned long)hose->io_base_virt - \
+                                                               _IO_BASE;
+               unsigned long roffset = offset + io_offset;
+               rp = &hose->io_resource;
+               if (!(rp->flags & IORESOURCE_IO))
+                       return -ENXIO;
+               if (roffset < rp->start || (roffset + size) > rp->end)
+                       return -ENXIO;
+               offset += hose->io_base_phys;
+       }
+       pr_debug(" -> mapping phys %llx\n", (unsigned long long)offset);
+
+       vma->vm_pgoff = offset >> PAGE_SHIFT;
+       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+       return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+                              vma->vm_end - vma->vm_start,
+                              vma->vm_page_prot);
+}
+
+void pci_resource_to_user(const struct pci_dev *dev, int bar,
+                         const struct resource *rsrc,
+                         resource_size_t *start, resource_size_t *end)
+{
+       struct pci_controller *hose = pci_bus_to_host(dev->bus);
+       resource_size_t offset = 0;
+
+       if (hose == NULL)
+               return;
+
+       if (rsrc->flags & IORESOURCE_IO)
+               offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+
+       /* We pass a fully fixed up address to userland for MMIO instead of
+        * a BAR value because X is lame and expects to be able to use that
+        * to pass to /dev/mem !
+        *
+        * That means that we'll have potentially 64 bits values where some
+        * userland apps only expect 32 (like X itself since it thinks only
+        * Sparc has 64 bits MMIO) but if we don't do that, we break it on
+        * 32 bits CHRPs :-(
+        *
+        * Hopefully, the sysfs insterface is immune to that gunk. Once X
+        * has been fixed (and the fix spread enough), we can re-enable the
+        * 2 lines below and pass down a BAR value to userland. In that case
+        * we'll also have to re-enable the matching code in
+        * __pci_mmap_make_offset().
+        *
+        * BenH.
+        */
+#if 0
+       else if (rsrc->flags & IORESOURCE_MEM)
+               offset = hose->pci_mem_offset;
+#endif
+
+       *start = rsrc->start - offset;
+       *end = rsrc->end - offset;
+}
+
+/**
+ * pci_process_bridge_OF_ranges - Parse PCI bridge resources from device tree
+ * @hose: newly allocated pci_controller to be setup
+ * @dev: device node of the host bridge
+ * @primary: set if primary bus (32 bits only, soon to be deprecated)
+ *
+ * This function will parse the "ranges" property of a PCI host bridge device
+ * node and setup the resource mapping of a pci controller based on its
+ * content.
+ *
+ * Life would be boring if it wasn't for a few issues that we have to deal
+ * with here:
+ *
+ *   - We can only cope with one IO space range and up to 3 Memory space
+ *     ranges. However, some machines (thanks Apple !) tend to split their
+ *     space into lots of small contiguous ranges. So we have to coalesce.
+ *
+ *   - We can only cope with all memory ranges having the same offset
+ *     between CPU addresses and PCI addresses. Unfortunately, some bridges
+ *     are setup for a large 1:1 mapping along with a small "window" which
+ *     maps PCI address 0 to some arbitrary high address of the CPU space in
+ *     order to give access to the ISA memory hole.
+ *     The way out of here that I've chosen for now is to always set the
+ *     offset based on the first resource found, then override it if we
+ *     have a different offset and the previous was set by an ISA hole.
+ *
+ *   - Some busses have IO space not starting at 0, which causes trouble with
+ *     the way we do our IO resource renumbering. The code somewhat deals with
+ *     it for 64 bits but I would expect problems on 32 bits.
+ *
+ *   - Some 32 bits platforms such as 4xx can have physical space larger than
+ *     32 bits so we need to use 64 bits values for the parsing
+ */
+void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
+                                           struct device_node *dev,
+                                           int primary)
+{
+       const u32 *ranges;
+       int rlen;
+       int pna = of_n_addr_cells(dev);
+       int np = pna + 5;
+       int memno = 0, isa_hole = -1;
+       u32 pci_space;
+       unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size;
+       unsigned long long isa_mb = 0;
+       struct resource *res;
+
+       printk(KERN_INFO "PCI host bridge %s %s ranges:\n",
+              dev->full_name, primary ? "(primary)" : "");
+
+       /* Get ranges property */
+       ranges = of_get_property(dev, "ranges", &rlen);
+       if (ranges == NULL)
+               return;
+
+       /* Parse it */
+       pr_debug("Parsing ranges property...\n");
+       while ((rlen -= np * 4) >= 0) {
+               /* Read next ranges element */
+               pci_space = ranges[0];
+               pci_addr = of_read_number(ranges + 1, 2);
+               cpu_addr = of_translate_address(dev, ranges + 3);
+               size = of_read_number(ranges + pna + 3, 2);
+
+               pr_debug("pci_space: 0x%08x pci_addr:0x%016llx "
+                               "cpu_addr:0x%016llx size:0x%016llx\n",
+                                       pci_space, pci_addr, cpu_addr, size);
+
+               ranges += np;
+
+               /* If we failed translation or got a zero-sized region
+                * (some FW try to feed us with non sensical zero sized regions
+                * such as power3 which look like some kind of attempt
+                * at exposing the VGA memory hole)
+                */
+               if (cpu_addr == OF_BAD_ADDR || size == 0)
+                       continue;
+
+               /* Now consume following elements while they are contiguous */
+               for (; rlen >= np * sizeof(u32);
+                    ranges += np, rlen -= np * 4) {
+                       if (ranges[0] != pci_space)
+                               break;
+                       pci_next = of_read_number(ranges + 1, 2);
+                       cpu_next = of_translate_address(dev, ranges + 3);
+                       if (pci_next != pci_addr + size ||
+                           cpu_next != cpu_addr + size)
+                               break;
+                       size += of_read_number(ranges + pna + 3, 2);
+               }
+
+               /* Act based on address space type */
+               res = NULL;
+               switch ((pci_space >> 24) & 0x3) {
+               case 1:         /* PCI IO space */
+                       printk(KERN_INFO
+                              "  IO 0x%016llx..0x%016llx -> 0x%016llx\n",
+                              cpu_addr, cpu_addr + size - 1, pci_addr);
+
+                       /* We support only one IO range */
+                       if (hose->pci_io_size) {
+                               printk(KERN_INFO
+                                      " \\--> Skipped (too many) !\n");
+                               continue;
+                       }
+                       /* On 32 bits, limit I/O space to 16MB */
+                       if (size > 0x01000000)
+                               size = 0x01000000;
+
+                       /* 32 bits needs to map IOs here */
+                       hose->io_base_virt = ioremap(cpu_addr, size);
+
+                       /* Expect trouble if pci_addr is not 0 */
+                       if (primary)
+                               isa_io_base =
+                                       (unsigned long)hose->io_base_virt;
+                       /* pci_io_size and io_base_phys always represent IO
+                        * space starting at 0 so we factor in pci_addr
+                        */
+                       hose->pci_io_size = pci_addr + size;
+                       hose->io_base_phys = cpu_addr - pci_addr;
+
+                       /* Build resource */
+                       res = &hose->io_resource;
+                       res->flags = IORESOURCE_IO;
+                       res->start = pci_addr;
+                       break;
+               case 2:         /* PCI Memory space */
+               case 3:         /* PCI 64 bits Memory space */
+                       printk(KERN_INFO
+                              " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n",
+                              cpu_addr, cpu_addr + size - 1, pci_addr,
+                              (pci_space & 0x40000000) ? "Prefetch" : "");
+
+                       /* We support only 3 memory ranges */
+                       if (memno >= 3) {
+                               printk(KERN_INFO
+                                      " \\--> Skipped (too many) !\n");
+                               continue;
+                       }
+                       /* Handles ISA memory hole space here */
+                       if (pci_addr == 0) {
+                               isa_mb = cpu_addr;
+                               isa_hole = memno;
+                               if (primary || isa_mem_base == 0)
+                                       isa_mem_base = cpu_addr;
+                               hose->isa_mem_phys = cpu_addr;
+                               hose->isa_mem_size = size;
+                       }
+
+                       /* We get the PCI/Mem offset from the first range or
+                        * the, current one if the offset came from an ISA
+                        * hole. If they don't match, bugger.
+                        */
+                       if (memno == 0 ||
+                           (isa_hole >= 0 && pci_addr != 0 &&
+                            hose->pci_mem_offset == isa_mb))
+                               hose->pci_mem_offset = cpu_addr - pci_addr;
+                       else if (pci_addr != 0 &&
+                                hose->pci_mem_offset != cpu_addr - pci_addr) {
+                               printk(KERN_INFO
+                                      " \\--> Skipped (offset mismatch) !\n");
+                               continue;
+                       }
+
+                       /* Build resource */
+                       res = &hose->mem_resources[memno++];
+                       res->flags = IORESOURCE_MEM;
+                       if (pci_space & 0x40000000)
+                               res->flags |= IORESOURCE_PREFETCH;
+                       res->start = cpu_addr;
+                       break;
+               }
+               if (res != NULL) {
+                       res->name = dev->full_name;
+                       res->end = res->start + size - 1;
+                       res->parent = NULL;
+                       res->sibling = NULL;
+                       res->child = NULL;
+               }
+       }
+
+       /* If there's an ISA hole and the pci_mem_offset is -not- matching
+        * the ISA hole offset, then we need to remove the ISA hole from
+        * the resource list for that brige
+        */
+       if (isa_hole >= 0 && hose->pci_mem_offset != isa_mb) {
+               unsigned int next = isa_hole + 1;
+               printk(KERN_INFO " Removing ISA hole at 0x%016llx\n", isa_mb);
+               if (next < memno)
+                       memmove(&hose->mem_resources[isa_hole],
+                               &hose->mem_resources[next],
+                               sizeof(struct resource) * (memno - next));
+               hose->mem_resources[--memno].flags = 0;
+       }
+}
+
+/* Decide whether to display the domain number in /proc */
+int pci_proc_domain(struct pci_bus *bus)
+{
+       struct pci_controller *hose = pci_bus_to_host(bus);
+
+       if (!(pci_flags & PCI_ENABLE_PROC_DOMAINS))
+               return 0;
+       if (pci_flags & PCI_COMPAT_DOMAIN_0)
+               return hose->global_number != 0;
+       return 1;
+}
+
+void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+                            struct resource *res)
+{
+       resource_size_t offset = 0, mask = (resource_size_t)-1;
+       struct pci_controller *hose = pci_bus_to_host(dev->bus);
+
+       if (!hose)
+               return;
+       if (res->flags & IORESOURCE_IO) {
+               offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+               mask = 0xffffffffu;
+       } else if (res->flags & IORESOURCE_MEM)
+               offset = hose->pci_mem_offset;
+
+       region->start = (res->start - offset) & mask;
+       region->end = (res->end - offset) & mask;
+}
+EXPORT_SYMBOL(pcibios_resource_to_bus);
+
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+                            struct pci_bus_region *region)
+{
+       resource_size_t offset = 0, mask = (resource_size_t)-1;
+       struct pci_controller *hose = pci_bus_to_host(dev->bus);
+
+       if (!hose)
+               return;
+       if (res->flags & IORESOURCE_IO) {
+               offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+               mask = 0xffffffffu;
+       } else if (res->flags & IORESOURCE_MEM)
+               offset = hose->pci_mem_offset;
+       res->start = (region->start + offset) & mask;
+       res->end = (region->end + offset) & mask;
+}
+EXPORT_SYMBOL(pcibios_bus_to_resource);
+
+/* Fixup a bus resource into a linux resource */
+static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
+{
+       struct pci_controller *hose = pci_bus_to_host(dev->bus);
+       resource_size_t offset = 0, mask = (resource_size_t)-1;
+
+       if (res->flags & IORESOURCE_IO) {
+               offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+               mask = 0xffffffffu;
+       } else if (res->flags & IORESOURCE_MEM)
+               offset = hose->pci_mem_offset;
+
+       res->start = (res->start + offset) & mask;
+       res->end = (res->end + offset) & mask;
+}
+
+/* This header fixup will do the resource fixup for all devices as they are
+ * probed, but not for bridge ranges
+ */
+static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
+{
+       struct pci_controller *hose = pci_bus_to_host(dev->bus);
+       int i;
+
+       if (!hose) {
+               printk(KERN_ERR "No host bridge for PCI dev %s !\n",
+                      pci_name(dev));
+               return;
+       }
+       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+               struct resource *res = dev->resource + i;
+               if (!res->flags)
+                       continue;
+               /* On platforms that have PCI_PROBE_ONLY set, we don't
+                * consider 0 as an unassigned BAR value. It's technically
+                * a valid value, but linux doesn't like it... so when we can
+                * re-assign things, we do so, but if we can't, we keep it
+                * around and hope for the best...
+                */
+               if (res->start == 0 && !(pci_flags & PCI_PROBE_ONLY)) {
+                       pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]" \
+                                                       "is unassigned\n",
+                                pci_name(dev), i,
+                                (unsigned long long)res->start,
+                                (unsigned long long)res->end,
+                                (unsigned int)res->flags);
+                       res->end -= res->start;
+                       res->start = 0;
+                       res->flags |= IORESOURCE_UNSET;
+                       continue;
+               }
+
+               pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] fixup...\n",
+                        pci_name(dev), i,
+                        (unsigned long long)res->start,\
+                        (unsigned long long)res->end,
+                        (unsigned int)res->flags);
+
+               fixup_resource(res, dev);
+
+               pr_debug("PCI:%s            %016llx-%016llx\n",
+                        pci_name(dev),
+                        (unsigned long long)res->start,
+                        (unsigned long long)res->end);
+       }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);
+
+/* This function tries to figure out if a bridge resource has been initialized
+ * by the firmware or not. It doesn't have to be absolutely bullet proof, but
+ * things go more smoothly when it gets it right. It should covers cases such
+ * as Apple "closed" bridge resources and bare-metal pSeries unassigned bridges
+ */
+static int __devinit pcibios_uninitialized_bridge_resource(struct pci_bus *bus,
+                                                          struct resource *res)
+{
+       struct pci_controller *hose = pci_bus_to_host(bus);
+       struct pci_dev *dev = bus->self;
+       resource_size_t offset;
+       u16 command;
+       int i;
+
+       /* We don't do anything if PCI_PROBE_ONLY is set */
+       if (pci_flags & PCI_PROBE_ONLY)
+               return 0;
+
+       /* Job is a bit different between memory and IO */
+       if (res->flags & IORESOURCE_MEM) {
+               /* If the BAR is non-0 (res != pci_mem_offset) then it's
+                * probably been initialized by somebody
+                */
+               if (res->start != hose->pci_mem_offset)
+                       return 0;
+
+               /* The BAR is 0, let's check if memory decoding is enabled on
+                * the bridge. If not, we consider it unassigned
+                */
+               pci_read_config_word(dev, PCI_COMMAND, &command);
+               if ((command & PCI_COMMAND_MEMORY) == 0)
+                       return 1;
+
+               /* Memory decoding is enabled and the BAR is 0. If any of
+                * the bridge resources covers that starting address (0 then
+                * it's good enough for us for memory
+                */
+               for (i = 0; i < 3; i++) {
+                       if ((hose->mem_resources[i].flags & IORESOURCE_MEM) &&
+                          hose->mem_resources[i].start == hose->pci_mem_offset)
+                               return 0;
+               }
+
+               /* Well, it starts at 0 and we know it will collide so we may as
+                * well consider it as unassigned. That covers the Apple case.
+                */
+               return 1;
+       } else {
+               /* If the BAR is non-0, then we consider it assigned */
+               offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+               if (((res->start - offset) & 0xfffffffful) != 0)
+                       return 0;
+
+               /* Here, we are a bit different than memory as typically IO
+                * space starting at low addresses -is- valid. What we do
+                * instead if that we consider as unassigned anything that
+                * doesn't have IO enabled in the PCI command register,
+                * and that's it.
+                */
+               pci_read_config_word(dev, PCI_COMMAND, &command);
+               if (command & PCI_COMMAND_IO)
+                       return 0;
+
+               /* It's starting at 0 and IO is disabled in the bridge, consider
+                * it unassigned
+                */
+               return 1;
+       }
+}
+
+/* Fixup resources of a PCI<->PCI bridge */
+static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
+{
+       struct resource *res;
+       int i;
+
+       struct pci_dev *dev = bus->self;
+
+       pci_bus_for_each_resource(bus, res, i) {
+               res = bus->resource[i];
+               if (!res)
+                       continue;
+               if (!res->flags)
+                       continue;
+               if (i >= 3 && bus->self->transparent)
+                       continue;
+
+               pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n",
+                        pci_name(dev), i,
+                        (unsigned long long)res->start,\
+                        (unsigned long long)res->end,
+                        (unsigned int)res->flags);
+
+               /* Perform fixup */
+               fixup_resource(res, dev);
+
+               /* Try to detect uninitialized P2P bridge resources,
+                * and clear them out so they get re-assigned later
+                */
+               if (pcibios_uninitialized_bridge_resource(bus, res)) {
+                       res->flags = 0;
+                       pr_debug("PCI:%s            (unassigned)\n",
+                                                               pci_name(dev));
+               } else {
+                       pr_debug("PCI:%s            %016llx-%016llx\n",
+                                pci_name(dev),
+                                (unsigned long long)res->start,
+                                (unsigned long long)res->end);
+               }
+       }
+}
+
+void __devinit pcibios_setup_bus_self(struct pci_bus *bus)
+{
+       /* Fix up the bus resources for P2P bridges */
+       if (bus->self != NULL)
+               pcibios_fixup_bridge(bus);
+}
+
+void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
+{
+       struct pci_dev *dev;
+
+       pr_debug("PCI: Fixup bus devices %d (%s)\n",
+                bus->number, bus->self ? pci_name(bus->self) : "PHB");
+
+       list_for_each_entry(dev, &bus->devices, bus_list) {
+               struct dev_archdata *sd = &dev->dev.archdata;
+
+               /* Setup OF node pointer in archdata */
+               sd->of_node = pci_device_to_OF_node(dev);
+
+               /* Fixup NUMA node as it may not be setup yet by the generic
+                * code and is needed by the DMA init
+                */
+               set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
+
+               /* Hook up default DMA ops */
+               sd->dma_ops = pci_dma_ops;
+               sd->dma_data = (void *)PCI_DRAM_OFFSET;
+
+               /* Read default IRQs and fixup if necessary */
+               pci_read_irq_line(dev);
+       }
+}
+
+void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+{
+       /* When called from the generic PCI probe, read PCI<->PCI bridge
+        * bases. This is -not- called when generating the PCI tree from
+        * the OF device-tree.
+        */
+       if (bus->self != NULL)
+               pci_read_bridge_bases(bus);
+
+       /* Now fixup the bus bus */
+       pcibios_setup_bus_self(bus);
+
+       /* Now fixup devices on that bus */
+       pcibios_setup_bus_devices(bus);
+}
+EXPORT_SYMBOL(pcibios_fixup_bus);
+
+static int skip_isa_ioresource_align(struct pci_dev *dev)
+{
+       if ((pci_flags & PCI_CAN_SKIP_ISA_ALIGN) &&
+           !(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA))
+               return 1;
+       return 0;
+}
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ *
+ * Why? Because some silly external IO cards only decode
+ * the low 10 bits of the IO address. The 0x00-0xff region
+ * is reserved for motherboard devices that decode all 16
+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+ * but we want to try to avoid allocating at 0x2900-0x2bff
+ * which might have be mirrored at 0x0100-0x03ff..
+ */
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+                               resource_size_t size, resource_size_t align)
+{
+       struct pci_dev *dev = data;
+       resource_size_t start = res->start;
+
+       if (res->flags & IORESOURCE_IO) {
+               if (skip_isa_ioresource_align(dev))
+                       return start;
+               if (start & 0x300)
+                       start = (start + 0x3ff) & ~0x3ff;
+       }
+
+       return start;
+}
+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,
+                                    struct resource *res)
+{
+       struct resource *p, **pp;
+       struct resource **firstpp = NULL;
+
+       for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
+               if (p->end < res->start)
+                       continue;
+               if (res->end < p->start)
+                       break;
+               if (p->start < res->start || p->end > res->end)
+                       return -1;      /* not completely contained */
+               if (firstpp == NULL)
+                       firstpp = pp;
+       }
+       if (firstpp == NULL)
+               return -1;      /* didn't find any conflicting entries? */
+       res->parent = parent;
+       res->child = *firstpp;
+       res->sibling = *pp;
+       *firstpp = res;
+       *pp = NULL;
+       for (p = res->child; p != NULL; p = p->sibling) {
+               p->parent = res;
+               pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n",
+                        p->name,
+                        (unsigned long long)p->start,
+                        (unsigned long long)p->end, res->name);
+       }
+       return 0;
+}
+
+/*
+ *  Handle resources of PCI devices.  If the world were perfect, we could
+ *  just allocate all the resource regions and do nothing more.  It isn't.
+ *  On the other hand, we cannot just re-allocate all devices, as it would
+ *  require us to know lots of host bridge internals.  So we attempt to
+ *  keep as much of the original configuration as possible, but tweak it
+ *  when it's found to be wrong.
+ *
+ *  Known BIOS problems we have to work around:
+ *     - I/O or memory regions not configured
+ *     - regions configured, but not enabled in the command register
+ *     - bogus I/O addresses above 64K used
+ *     - expansion ROMs left enabled (this may sound harmless, but given
+ *       the fact the PCI specs explicitly allow address decoders to be
+ *       shared between expansion ROMs and other resource regions, it's
+ *       at least dangerous)
+ *
+ *  Our solution:
+ *     (1) Allocate resources for all buses behind PCI-to-PCI bridges.
+ *         This gives us fixed barriers on where we can allocate.
+ *     (2) Allocate resources for all enabled devices.  If there is
+ *         a collision, just mark the resource as unallocated. Also
+ *         disable expansion ROMs during this step.
+ *     (3) Try to allocate resources for disabled devices.  If the
+ *         resources were assigned correctly, everything goes well,
+ *         if they weren't, they won't disturb allocation of other
+ *         resources.
+ *     (4) Assign new addresses to resources which were either
+ *         not configured at all or misconfigured.  If explicitly
+ *         requested by the user, configure expansion ROM address
+ *         as well.
+ */
+
+void pcibios_allocate_bus_resources(struct pci_bus *bus)
+{
+       struct pci_bus *b;
+       int i;
+       struct resource *res, *pr;
+
+       pr_debug("PCI: Allocating bus resources for %04x:%02x...\n",
+                pci_domain_nr(bus), bus->number);
+
+       pci_bus_for_each_resource(bus, res, i) {
+               res = bus->resource[i];
+               if (!res || !res->flags
+                   || res->start > res->end || res->parent)
+                       continue;
+               if (bus->parent == NULL)
+                       pr = (res->flags & IORESOURCE_IO) ?
+                               &ioport_resource : &iomem_resource;
+               else {
+                       /* Don't bother with non-root busses when
+                        * re-assigning all resources. We clear the
+                        * resource flags as if they were colliding
+                        * and as such ensure proper re-allocation
+                        * later.
+                        */
+                       if (pci_flags & PCI_REASSIGN_ALL_RSRC)
+                               goto clear_resource;
+                       pr = pci_find_parent_resource(bus->self, res);
+                       if (pr == res) {
+                               /* this happens when the generic PCI
+                                * code (wrongly) decides that this
+                                * bridge is transparent  -- paulus
+                                */
+                               continue;
+                       }
+               }
+
+               pr_debug("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx "
+                        "[0x%x], parent %p (%s)\n",
+                        bus->self ? pci_name(bus->self) : "PHB",
+                        bus->number, i,
+                        (unsigned long long)res->start,
+                        (unsigned long long)res->end,
+                        (unsigned int)res->flags,
+                        pr, (pr && pr->name) ? pr->name : "nil");
+
+               if (pr && !(pr->flags & IORESOURCE_UNSET)) {
+                       if (request_resource(pr, res) == 0)
+                               continue;
+                       /*
+                        * Must be a conflict with an existing entry.
+                        * Move that entry (or entries) under the
+                        * bridge resource and try again.
+                        */
+                       if (reparent_resources(pr, res) == 0)
+                               continue;
+               }
+               printk(KERN_WARNING "PCI: Cannot allocate resource region "
+                      "%d of PCI bridge %d, will remap\n", i, bus->number);
+clear_resource:
+               res->flags = 0;
+       }
+
+       list_for_each_entry(b, &bus->children, node)
+               pcibios_allocate_bus_resources(b);
+}
+
+static inline void __devinit alloc_resource(struct pci_dev *dev, int idx)
+{
+       struct resource *pr, *r = &dev->resource[idx];
+
+       pr_debug("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n",
+                pci_name(dev), idx,
+                (unsigned long long)r->start,
+                (unsigned long long)r->end,
+                (unsigned int)r->flags);
+
+       pr = pci_find_parent_resource(dev, r);
+       if (!pr || (pr->flags & IORESOURCE_UNSET) ||
+           request_resource(pr, r) < 0) {
+               printk(KERN_WARNING "PCI: Cannot allocate resource region %d"
+                      " of device %s, will remap\n", idx, pci_name(dev));
+               if (pr)
+                       pr_debug("PCI:  parent is %p: %016llx-%016llx [%x]\n",
+                                pr,
+                                (unsigned long long)pr->start,
+                                (unsigned long long)pr->end,
+                                (unsigned int)pr->flags);
+               /* We'll assign a new address later */
+               r->flags |= IORESOURCE_UNSET;
+               r->end -= r->start;
+               r->start = 0;
+       }
+}
+
+static void __init pcibios_allocate_resources(int pass)
+{
+       struct pci_dev *dev = NULL;
+       int idx, disabled;
+       u16 command;
+       struct resource *r;
+
+       for_each_pci_dev(dev) {
+               pci_read_config_word(dev, PCI_COMMAND, &command);
+               for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) {
+                       r = &dev->resource[idx];
+                       if (r->parent)          /* Already allocated */
+                               continue;
+                       if (!r->flags || (r->flags & IORESOURCE_UNSET))
+                               continue;       /* Not assigned at all */
+                       /* We only allocate ROMs on pass 1 just in case they
+                        * have been screwed up by firmware
+                        */
+                       if (idx == PCI_ROM_RESOURCE)
+                               disabled = 1;
+                       if (r->flags & IORESOURCE_IO)
+                               disabled = !(command & PCI_COMMAND_IO);
+                       else
+                               disabled = !(command & PCI_COMMAND_MEMORY);
+                       if (pass == disabled)
+                               alloc_resource(dev, idx);
+               }
+               if (pass)
+                       continue;
+               r = &dev->resource[PCI_ROM_RESOURCE];
+               if (r->flags) {
+                       /* Turn the ROM off, leave the resource region,
+                        * but keep it unregistered.
+                        */
+                       u32 reg;
+                       pci_read_config_dword(dev, dev->rom_base_reg, &reg);
+                       if (reg & PCI_ROM_ADDRESS_ENABLE) {
+                               pr_debug("PCI: Switching off ROM of %s\n",
+                                        pci_name(dev));
+                               r->flags &= ~IORESOURCE_ROM_ENABLE;
+                               pci_write_config_dword(dev, dev->rom_base_reg,
+                                               reg & ~PCI_ROM_ADDRESS_ENABLE);
+                       }
+               }
+       }
+}
+
+static void __init pcibios_reserve_legacy_regions(struct pci_bus *bus)
+{
+       struct pci_controller *hose = pci_bus_to_host(bus);
+       resource_size_t offset;
+       struct resource *res, *pres;
+       int i;
+
+       pr_debug("Reserving legacy ranges for domain %04x\n",
+                                                       pci_domain_nr(bus));
+
+       /* Check for IO */
+       if (!(hose->io_resource.flags & IORESOURCE_IO))
+               goto no_io;
+       offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+       res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+       BUG_ON(res == NULL);
+       res->name = "Legacy IO";
+       res->flags = IORESOURCE_IO;
+       res->start = offset;
+       res->end = (offset + 0xfff) & 0xfffffffful;
+       pr_debug("Candidate legacy IO: %pR\n", res);
+       if (request_resource(&hose->io_resource, res)) {
+               printk(KERN_DEBUG
+                      "PCI %04x:%02x Cannot reserve Legacy IO %pR\n",
+                      pci_domain_nr(bus), bus->number, res);
+               kfree(res);
+       }
+
+ no_io:
+       /* Check for memory */
+       offset = hose->pci_mem_offset;
+       pr_debug("hose mem offset: %016llx\n", (unsigned long long)offset);
+       for (i = 0; i < 3; i++) {
+               pres = &hose->mem_resources[i];
+               if (!(pres->flags & IORESOURCE_MEM))
+                       continue;
+               pr_debug("hose mem res: %pR\n", pres);
+               if ((pres->start - offset) <= 0xa0000 &&
+                   (pres->end - offset) >= 0xbffff)
+                       break;
+       }
+       if (i >= 3)
+               return;
+       res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+       BUG_ON(res == NULL);
+       res->name = "Legacy VGA memory";
+       res->flags = IORESOURCE_MEM;
+       res->start = 0xa0000 + offset;
+       res->end = 0xbffff + offset;
+       pr_debug("Candidate VGA memory: %pR\n", res);
+       if (request_resource(pres, res)) {
+               printk(KERN_DEBUG
+                      "PCI %04x:%02x Cannot reserve VGA memory %pR\n",
+                      pci_domain_nr(bus), bus->number, res);
+               kfree(res);
+       }
+}
+
+void __init pcibios_resource_survey(void)
+{
+       struct pci_bus *b;
+
+       /* Allocate and assign resources. If we re-assign everything, then
+        * we skip the allocate phase
+        */
+       list_for_each_entry(b, &pci_root_buses, node)
+               pcibios_allocate_bus_resources(b);
+
+       if (!(pci_flags & PCI_REASSIGN_ALL_RSRC)) {
+               pcibios_allocate_resources(0);
+               pcibios_allocate_resources(1);
+       }
+
+       /* Before we start assigning unassigned resource, we try to reserve
+        * the low IO area and the VGA memory area if they intersect the
+        * bus available resources to avoid allocating things on top of them
+        */
+       if (!(pci_flags & PCI_PROBE_ONLY)) {
+               list_for_each_entry(b, &pci_root_buses, node)
+                       pcibios_reserve_legacy_regions(b);
+       }
+
+       /* Now, if the platform didn't decide to blindly trust the firmware,
+        * we proceed to assigning things that were left unassigned
+        */
+       if (!(pci_flags & PCI_PROBE_ONLY)) {
+               pr_debug("PCI: Assigning unassigned resources...\n");
+               pci_assign_unassigned_resources();
+       }
+}
+
+#ifdef CONFIG_HOTPLUG
+
+/* This is used by the PCI hotplug driver to allocate resource
+ * of newly plugged busses. We can try to consolidate with the
+ * rest of the code later, for now, keep it as-is as our main
+ * resource allocation function doesn't deal with sub-trees yet.
+ */
+void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
+{
+       struct pci_dev *dev;
+       struct pci_bus *child_bus;
+
+       list_for_each_entry(dev, &bus->devices, bus_list) {
+               int i;
+
+               for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+                       struct resource *r = &dev->resource[i];
+
+                       if (r->parent || !r->start || !r->flags)
+                               continue;
+
+                       pr_debug("PCI: Claiming %s: "
+                                "Resource %d: %016llx..%016llx [%x]\n",
+                                pci_name(dev), i,
+                                (unsigned long long)r->start,
+                                (unsigned long long)r->end,
+                                (unsigned int)r->flags);
+
+                       pci_claim_resource(dev, i);
+               }
+       }
+
+       list_for_each_entry(child_bus, &bus->children, node)
+               pcibios_claim_one_bus(child_bus);
+}
+EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
+
+
+/* pcibios_finish_adding_to_bus
+ *
+ * This is to be called by the hotplug code after devices have been
+ * added to a bus, this include calling it for a PHB that is just
+ * being added
+ */
+void pcibios_finish_adding_to_bus(struct pci_bus *bus)
+{
+       pr_debug("PCI: Finishing adding to hotplug bus %04x:%02x\n",
+                pci_domain_nr(bus), bus->number);
+
+       /* Allocate bus and devices resources */
+       pcibios_allocate_bus_resources(bus);
+       pcibios_claim_one_bus(bus);
+
+       /* Add new devices to global lists.  Register in proc, sysfs. */
+       pci_bus_add_devices(bus);
+
+       /* Fixup EEH */
+       /* eeh_add_device_tree_late(bus); */
+}
+EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus);
+
+#endif /* CONFIG_HOTPLUG */
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+       return pci_enable_resources(dev, mask);
+}
+
+void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
+{
+       struct pci_bus *bus = hose->bus;
+       struct resource *res;
+       int i;
+
+       /* Hookup PHB IO resource */
+       bus->resource[0] = res = &hose->io_resource;
+
+       if (!res->flags) {
+               printk(KERN_WARNING "PCI: I/O resource not set for host"
+                      " bridge %s (domain %d)\n",
+                      hose->dn->full_name, hose->global_number);
+               /* Workaround for lack of IO resource only on 32-bit */
+               res->start = (unsigned long)hose->io_base_virt - isa_io_base;
+               res->end = res->start + IO_SPACE_LIMIT;
+               res->flags = IORESOURCE_IO;
+       }
+
+       pr_debug("PCI: PHB IO resource    = %016llx-%016llx [%lx]\n",
+                (unsigned long long)res->start,
+                (unsigned long long)res->end,
+                (unsigned long)res->flags);
+
+       /* Hookup PHB Memory resources */
+       for (i = 0; i < 3; ++i) {
+               res = &hose->mem_resources[i];
+               if (!res->flags) {
+                       if (i > 0)
+                               continue;
+                       printk(KERN_ERR "PCI: Memory resource 0 not set for "
+                              "host bridge %s (domain %d)\n",
+                              hose->dn->full_name, hose->global_number);
+
+                       /* Workaround for lack of MEM resource only on 32-bit */
+                       res->start = hose->pci_mem_offset;
+                       res->end = (resource_size_t)-1LL;
+                       res->flags = IORESOURCE_MEM;
+
+               }
+               bus->resource[i+1] = res;
+
+               pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n",
+                       i, (unsigned long long)res->start,
+                       (unsigned long long)res->end,
+                       (unsigned long)res->flags);
+       }
+
+       pr_debug("PCI: PHB MEM offset     = %016llx\n",
+                (unsigned long long)hose->pci_mem_offset);
+       pr_debug("PCI: PHB IO  offset     = %08lx\n",
+                (unsigned long)hose->io_base_virt - _IO_BASE);
+}
+
+/*
+ * Null PCI config access functions, for the case when we can't
+ * find a hose.
+ */
+#define NULL_PCI_OP(rw, size, type)                                    \
+static int                                                             \
+null_##rw##_config_##size(struct pci_dev *dev, int offset, type val)   \
+{                                                                      \
+       return PCIBIOS_DEVICE_NOT_FOUND;                                \
+}
+
+static int
+null_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+                int len, u32 *val)
+{
+       return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static int
+null_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+                 int len, u32 val)
+{
+       return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static struct pci_ops null_pci_ops = {
+       .read = null_read_config,
+       .write = null_write_config,
+};
+
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+static struct pci_bus *
+fake_pci_bus(struct pci_controller *hose, int busnr)
+{
+       static struct pci_bus bus;
+
+       if (!hose)
+               printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);
+
+       bus.number = busnr;
+       bus.sysdata = hose;
+       bus.ops = hose ? hose->ops : &null_pci_ops;
+       return &bus;
+}
+
+#define EARLY_PCI_OP(rw, size, type)                                   \
+int early_##rw##_config_##size(struct pci_controller *hose, int bus,   \
+                              int devfn, int offset, type value)       \
+{                                                                      \
+       return pci_bus_##rw##_config_##size(fake_pci_bus(hose, bus),    \
+                                           devfn, offset, value);      \
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
+
+int early_find_capability(struct pci_controller *hose, int bus, int devfn,
+                         int cap)
+{
+       return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap);
+}
diff --git a/arch/microblaze/pci/pci_32.c b/arch/microblaze/pci/pci_32.c
new file mode 100644 (file)
index 0000000..3c3d808
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+ * Common pmac/prep/chrp pci routines. -- Cort
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/capability.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+#include <linux/list.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/sections.h>
+#include <asm/pci-bridge.h>
+#include <asm/byteorder.h>
+#include <asm/uaccess.h>
+
+#undef DEBUG
+
+unsigned long isa_io_base;
+unsigned long pci_dram_offset;
+int pcibios_assign_bus_offset = 1;
+
+static u8 *pci_to_OF_bus_map;
+
+/* By default, we don't re-assign bus numbers. We do this only on
+ * some pmacs
+ */
+static int pci_assign_all_buses;
+
+static int pci_bus_count;
+
+/*
+ * Functions below are used on OpenFirmware machines.
+ */
+static void
+make_one_node_map(struct device_node *node, u8 pci_bus)
+{
+       const int *bus_range;
+       int len;
+
+       if (pci_bus >= pci_bus_count)
+               return;
+       bus_range = of_get_property(node, "bus-range", &len);
+       if (bus_range == NULL || len < 2 * sizeof(int)) {
+               printk(KERN_WARNING "Can't get bus-range for %s, "
+                      "assuming it starts at 0\n", node->full_name);
+               pci_to_OF_bus_map[pci_bus] = 0;
+       } else
+               pci_to_OF_bus_map[pci_bus] = bus_range[0];
+
+       for_each_child_of_node(node, node) {
+               struct pci_dev *dev;
+               const unsigned int *class_code, *reg;
+
+               class_code = of_get_property(node, "class-code", NULL);
+               if (!class_code ||
+                       ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
+                       (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
+                       continue;
+               reg = of_get_property(node, "reg", NULL);
+               if (!reg)
+                       continue;
+               dev = pci_get_bus_and_slot(pci_bus, ((reg[0] >> 8) & 0xff));
+               if (!dev || !dev->subordinate) {
+                       pci_dev_put(dev);
+                       continue;
+               }
+               make_one_node_map(node, dev->subordinate->number);
+               pci_dev_put(dev);
+       }
+}
+
+void
+pcibios_make_OF_bus_map(void)
+{
+       int i;
+       struct pci_controller *hose, *tmp;
+       struct property *map_prop;
+       struct device_node *dn;
+
+       pci_to_OF_bus_map = kmalloc(pci_bus_count, GFP_KERNEL);
+       if (!pci_to_OF_bus_map) {
+               printk(KERN_ERR "Can't allocate OF bus map !\n");
+               return;
+       }
+
+       /* We fill the bus map with invalid values, that helps
+        * debugging.
+        */
+       for (i = 0; i < pci_bus_count; i++)
+               pci_to_OF_bus_map[i] = 0xff;
+
+       /* For each hose, we begin searching bridges */
+       list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+               struct device_node *node = hose->dn;
+
+               if (!node)
+                       continue;
+               make_one_node_map(node, hose->first_busno);
+       }
+       dn = of_find_node_by_path("/");
+       map_prop = of_find_property(dn, "pci-OF-bus-map", NULL);
+       if (map_prop) {
+               BUG_ON(pci_bus_count > map_prop->length);
+               memcpy(map_prop->value, pci_to_OF_bus_map, pci_bus_count);
+       }
+       of_node_put(dn);
+#ifdef DEBUG
+       printk(KERN_INFO "PCI->OF bus map:\n");
+       for (i = 0; i < pci_bus_count; i++) {
+               if (pci_to_OF_bus_map[i] == 0xff)
+                       continue;
+               printk(KERN_INFO "%d -> %d\n", i, pci_to_OF_bus_map[i]);
+       }
+#endif
+}
+
+typedef int (*pci_OF_scan_iterator)(struct device_node *node, void *data);
+
+static struct device_node *scan_OF_pci_childs(struct device_node *parent,
+                                       pci_OF_scan_iterator filter, void *data)
+{
+       struct device_node *node;
+       struct device_node *sub_node;
+
+       for_each_child_of_node(parent, node) {
+               const unsigned int *class_code;
+
+               if (filter(node, data)) {
+                       of_node_put(node);
+                       return node;
+               }
+
+               /* For PCI<->PCI bridges or CardBus bridges, we go down
+                * Note: some OFs create a parent node "multifunc-device" as
+                * a fake root for all functions of a multi-function device,
+                * we go down them as well.
+                */
+               class_code = of_get_property(node, "class-code", NULL);
+               if ((!class_code ||
+                       ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
+                       (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&
+                       strcmp(node->name, "multifunc-device"))
+                       continue;
+               sub_node = scan_OF_pci_childs(node, filter, data);
+               if (sub_node) {
+                       of_node_put(node);
+                       return sub_node;
+               }
+       }
+       return NULL;
+}
+
+static struct device_node *scan_OF_for_pci_dev(struct device_node *parent,
+                                              unsigned int devfn)
+{
+       struct device_node *np, *cnp;
+       const u32 *reg;
+       unsigned int psize;
+
+       for_each_child_of_node(parent, np) {
+               reg = of_get_property(np, "reg", &psize);
+               if (reg && psize >= 4 && ((reg[0] >> 8) & 0xff) == devfn)
+                       return np;
+
+               /* Note: some OFs create a parent node "multifunc-device" as
+                * a fake root for all functions of a multi-function device,
+                * we go down them as well. */
+               if (!strcmp(np->name, "multifunc-device")) {
+                       cnp = scan_OF_for_pci_dev(np, devfn);
+                       if (cnp)
+                               return cnp;
+               }
+       }
+       return NULL;
+}
+
+
+static struct device_node *scan_OF_for_pci_bus(struct pci_bus *bus)
+{
+       struct device_node *parent, *np;
+
+       /* Are we a root bus ? */
+       if (bus->self == NULL || bus->parent == NULL) {
+               struct pci_controller *hose = pci_bus_to_host(bus);
+               if (hose == NULL)
+                       return NULL;
+               return of_node_get(hose->dn);
+       }
+
+       /* not a root bus, we need to get our parent */
+       parent = scan_OF_for_pci_bus(bus->parent);
+       if (parent == NULL)
+               return NULL;
+
+       /* now iterate for children for a match */
+       np = scan_OF_for_pci_dev(parent, bus->self->devfn);
+       of_node_put(parent);
+
+       return np;
+}
+
+/*
+ * Scans the OF tree for a device node matching a PCI device
+ */
+struct device_node *
+pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
+{
+       struct device_node *parent, *np;
+
+       pr_debug("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn);
+       parent = scan_OF_for_pci_bus(bus);
+       if (parent == NULL)
+               return NULL;
+       pr_debug(" parent is %s\n", parent ? parent->full_name : "<NULL>");
+       np = scan_OF_for_pci_dev(parent, devfn);
+       of_node_put(parent);
+       pr_debug(" result is %s\n", np ? np->full_name : "<NULL>");
+
+       /* XXX most callers don't release the returned node
+        * mostly because ppc64 doesn't increase the refcount,
+        * we need to fix that.
+        */
+       return np;
+}
+EXPORT_SYMBOL(pci_busdev_to_OF_node);
+
+struct device_node*
+pci_device_to_OF_node(struct pci_dev *dev)
+{
+       return pci_busdev_to_OF_node(dev->bus, dev->devfn);
+}
+EXPORT_SYMBOL(pci_device_to_OF_node);
+
+static int
+find_OF_pci_device_filter(struct device_node *node, void *data)
+{
+       return ((void *)node == data);
+}
+
+/*
+ * Returns the PCI device matching a given OF node
+ */
+int
+pci_device_from_OF_node(struct device_node *node, u8 *bus, u8 *devfn)
+{
+       const unsigned int *reg;
+       struct pci_controller *hose;
+       struct pci_dev *dev = NULL;
+
+       /* Make sure it's really a PCI device */
+       hose = pci_find_hose_for_OF_device(node);
+       if (!hose || !hose->dn)
+               return -ENODEV;
+       if (!scan_OF_pci_childs(hose->dn,
+                       find_OF_pci_device_filter, (void *)node))
+               return -ENODEV;
+       reg = of_get_property(node, "reg", NULL);
+       if (!reg)
+               return -ENODEV;
+       *bus = (reg[0] >> 16) & 0xff;
+       *devfn = ((reg[0] >> 8) & 0xff);
+
+       /* Ok, here we need some tweak. If we have already renumbered
+        * all busses, we can't rely on the OF bus number any more.
+        * the pci_to_OF_bus_map is not enough as several PCI busses
+        * may match the same OF bus number.
+        */
+       if (!pci_to_OF_bus_map)
+               return 0;
+
+       for_each_pci_dev(dev)
+               if (pci_to_OF_bus_map[dev->bus->number] == *bus &&
+                               dev->devfn == *devfn) {
+                       *bus = dev->bus->number;
+                       pci_dev_put(dev);
+                       return 0;
+               }
+
+       return -ENODEV;
+}
+EXPORT_SYMBOL(pci_device_from_OF_node);
+
+/* We create the "pci-OF-bus-map" property now so it appears in the
+ * /proc device tree
+ */
+void __init
+pci_create_OF_bus_map(void)
+{
+       struct property *of_prop;
+       struct device_node *dn;
+
+       of_prop = (struct property *) alloc_bootmem(sizeof(struct property) + \
+                                                                        256);
+       if (!of_prop)
+               return;
+       dn = of_find_node_by_path("/");
+       if (dn) {
+               memset(of_prop, -1, sizeof(struct property) + 256);
+               of_prop->name = "pci-OF-bus-map";
+               of_prop->length = 256;
+               of_prop->value = &of_prop[1];
+               prom_add_property(dn, of_prop);
+               of_node_put(dn);
+       }
+}
+
+static void __devinit pcibios_scan_phb(struct pci_controller *hose)
+{
+       struct pci_bus *bus;
+       struct device_node *node = hose->dn;
+       unsigned long io_offset;
+       struct resource *res = &hose->io_resource;
+
+       pr_debug("PCI: Scanning PHB %s\n",
+                node ? node->full_name : "<NO NAME>");
+
+       /* Create an empty bus for the toplevel */
+       bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose);
+       if (bus == NULL) {
+               printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
+                      hose->global_number);
+               return;
+       }
+       bus->secondary = hose->first_busno;
+       hose->bus = bus;
+
+       /* Fixup IO space offset */
+       io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
+       res->start = (res->start + io_offset) & 0xffffffffu;
+       res->end = (res->end + io_offset) & 0xffffffffu;
+
+       /* Wire up PHB bus resources */
+       pcibios_setup_phb_resources(hose);
+
+       /* Scan children */
+       hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
+}
+
+static int __init pcibios_init(void)
+{
+       struct pci_controller *hose, *tmp;
+       int next_busno = 0;
+
+       printk(KERN_INFO "PCI: Probing PCI hardware\n");
+
+       if (pci_flags & PCI_REASSIGN_ALL_BUS) {
+               printk(KERN_INFO "setting pci_asign_all_busses\n");
+               pci_assign_all_buses = 1;
+       }
+
+       /* Scan all of the recorded PCI controllers.  */
+       list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+               if (pci_assign_all_buses)
+                       hose->first_busno = next_busno;
+               hose->last_busno = 0xff;
+               pcibios_scan_phb(hose);
+               printk(KERN_INFO "calling pci_bus_add_devices()\n");
+               pci_bus_add_devices(hose->bus);
+               if (pci_assign_all_buses || next_busno <= hose->last_busno)
+                       next_busno = hose->last_busno + \
+                                       pcibios_assign_bus_offset;
+       }
+       pci_bus_count = next_busno;
+
+       /* OpenFirmware based machines need a map of OF bus
+        * numbers vs. kernel bus numbers since we may have to
+        * remap them.
+        */
+       if (pci_assign_all_buses)
+               pcibios_make_OF_bus_map();
+
+       /* Call common code to handle resource allocation */
+       pcibios_resource_survey();
+
+       return 0;
+}
+
+subsys_initcall(pcibios_init);
+
+static struct pci_controller*
+pci_bus_to_hose(int bus)
+{
+       struct pci_controller *hose, *tmp;
+
+       list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+               if (bus >= hose->first_busno && bus <= hose->last_busno)
+                       return hose;
+       return NULL;
+}
+
+/* Provide information on locations of various I/O regions in physical
+ * memory.  Do this on a per-card basis so that we choose the right
+ * root bridge.
+ * Note that the returned IO or memory base is a physical address
+ */
+
+long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
+{
+       struct pci_controller *hose;
+       long result = -EOPNOTSUPP;
+
+       hose = pci_bus_to_hose(bus);
+       if (!hose)
+               return -ENODEV;
+
+       switch (which) {
+       case IOBASE_BRIDGE_NUMBER:
+               return (long)hose->first_busno;
+       case IOBASE_MEMORY:
+               return (long)hose->pci_mem_offset;
+       case IOBASE_IO:
+               return (long)hose->io_base_phys;
+       case IOBASE_ISA_IO:
+               return (long)isa_io_base;
+       case IOBASE_ISA_MEM:
+               return (long)isa_mem_base;
+       }
+
+       return result;
+}
diff --git a/arch/microblaze/pci/xilinx_pci.c b/arch/microblaze/pci/xilinx_pci.c
new file mode 100644 (file)
index 0000000..7869a41
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * PCI support for Xilinx plbv46_pci soft-core which can be used on
+ * Xilinx Virtex ML410 / ML510 boards.
+ *
+ * Copyright 2009 Roderick Colenbrander
+ * Copyright 2009 Secret Lab Technologies Ltd.
+ *
+ * The pci bridge fixup code was copied from ppc4xx_pci.c and was written
+ * by Benjamin Herrenschmidt.
+ * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/ioport.h>
+#include <linux/of.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+#define XPLB_PCI_ADDR 0x10c
+#define XPLB_PCI_DATA 0x110
+#define XPLB_PCI_BUS  0x114
+
+#define PCI_HOST_ENABLE_CMD (PCI_COMMAND_SERR | PCI_COMMAND_PARITY | \
+                               PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY)
+
+static struct of_device_id xilinx_pci_match[] = {
+       { .compatible = "xlnx,plbv46-pci-1.03.a", },
+       {}
+};
+
+/**
+ * xilinx_pci_fixup_bridge - Block Xilinx PHB configuration.
+ */
+static void xilinx_pci_fixup_bridge(struct pci_dev *dev)
+{
+       struct pci_controller *hose;
+       int i;
+
+       if (dev->devfn || dev->bus->self)
+               return;
+
+       hose = pci_bus_to_host(dev->bus);
+       if (!hose)
+               return;
+
+       if (!of_match_node(xilinx_pci_match, hose->dn))
+               return;
+
+       /* Hide the PCI host BARs from the kernel as their content doesn't
+        * fit well in the resource management
+        */
+       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+               dev->resource[i].start = 0;
+               dev->resource[i].end = 0;
+               dev->resource[i].flags = 0;
+       }
+
+       dev_info(&dev->dev, "Hiding Xilinx plb-pci host bridge resources %s\n",
+                pci_name(dev));
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, xilinx_pci_fixup_bridge);
+
+#ifdef DEBUG
+/**
+ * xilinx_pci_exclude_device - Don't do config access for non-root bus
+ *
+ * This is a hack.  Config access to any bus other than bus 0 does not
+ * currently work on the ML510 so we prevent it here.
+ */
+static int
+xilinx_pci_exclude_device(struct pci_controller *hose, u_char bus, u8 devfn)
+{
+       return (bus != 0);
+}
+
+/**
+ * xilinx_early_pci_scan - List pci config space for available devices
+ *
+ * List pci devices in very early phase.
+ */
+void __init xilinx_early_pci_scan(struct pci_controller *hose)
+{
+       u32 bus = 0;
+       u32 val, dev, func, offset;
+
+       /* Currently we have only 2 device connected - up-to 32 devices */
+       for (dev = 0; dev < 2; dev++) {
+               /* List only first function number - up-to 8 functions */
+               for (func = 0; func < 1; func++) {
+                       printk(KERN_INFO "%02x:%02x:%02x", bus, dev, func);
+                       /* read the first 64 standardized bytes */
+                       /* Up-to 192 bytes can be list of capabilities */
+                       for (offset = 0; offset < 64; offset += 4) {
+                               early_read_config_dword(hose, bus,
+                                       PCI_DEVFN(dev, func), offset, &val);
+                               if (offset == 0 && val == 0xFFFFFFFF) {
+                                       printk(KERN_CONT "\nABSENT");
+                                       break;
+                               }
+                               if (!(offset % 0x10))
+                                       printk(KERN_CONT "\n%04x:    ", offset);
+
+                               printk(KERN_CONT "%08x  ", val);
+                       }
+                       printk(KERN_INFO "\n");
+               }
+       }
+}
+#else
+void __init xilinx_early_pci_scan(struct pci_controller *hose)
+{
+}
+#endif
+
+/**
+ * xilinx_pci_init - Find and register a Xilinx PCI host bridge
+ */
+void __init xilinx_pci_init(void)
+{
+       struct pci_controller *hose;
+       struct resource r;
+       void __iomem *pci_reg;
+       struct device_node *pci_node;
+
+       pci_node = of_find_matching_node(NULL, xilinx_pci_match);
+       if (!pci_node)
+               return;
+
+       if (of_address_to_resource(pci_node, 0, &r)) {
+               pr_err("xilinx-pci: cannot resolve base address\n");
+               return;
+       }
+
+       hose = pcibios_alloc_controller(pci_node);
+       if (!hose) {
+               pr_err("xilinx-pci: pcibios_alloc_controller() failed\n");
+               return;
+       }
+
+       /* Setup config space */
+       setup_indirect_pci(hose, r.start + XPLB_PCI_ADDR,
+                          r.start + XPLB_PCI_DATA,
+                          INDIRECT_TYPE_SET_CFG_TYPE);
+
+       /* According to the xilinx plbv46_pci documentation the soft-core starts
+        * a self-init when the bus master enable bit is set. Without this bit
+        * set the pci bus can't be scanned.
+        */
+       early_write_config_word(hose, 0, 0, PCI_COMMAND, PCI_HOST_ENABLE_CMD);
+
+       /* Set the max latency timer to 255 */
+       early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0xff);
+
+       /* Set the max bus number to 255, and bus/subbus no's to 0 */
+       pci_reg = of_iomap(pci_node, 0);
+       out_be32(pci_reg + XPLB_PCI_BUS, 0x000000ff);
+       iounmap(pci_reg);
+
+       /* Register the host bridge with the linux kernel! */
+       pci_process_bridge_OF_ranges(hose, pci_node,
+                                       INDIRECT_TYPE_SET_CFG_TYPE);
+
+       pr_info("xilinx-pci: Registered PCI host bridge\n");
+       xilinx_early_pci_scan(hose);
+}
index 29e86923d1bfe60afcc82be1700784ad5847d12c..7e6fd1cbd3f893ca3d50132bc6ffb0fcbc80966c 100644 (file)
@@ -49,7 +49,7 @@ config AR7
          family: TNETD7100, 7200 and 7300.
 
 config BCM47XX
-       bool "BCM47XX based boards"
+       bool "Broadcom BCM47XX based boards"
        select CEVT_R4K
        select CSRC_R4K
        select DMA_NONCOHERENT
@@ -509,6 +509,7 @@ config SIBYTE_SWARM
        bool "Sibyte BCM91250A-SWARM"
        select BOOT_ELF32
        select DMA_COHERENT
+       select HAVE_PATA_PLATFORM
        select NR_CPUS_DEFAULT_2
        select SIBYTE_SB1250
        select SWAP_IO_SPACE
@@ -523,6 +524,7 @@ config SIBYTE_LITTLESUR
        depends on EXPERIMENTAL
        select BOOT_ELF32
        select DMA_COHERENT
+       select HAVE_PATA_PLATFORM
        select NR_CPUS_DEFAULT_2
        select SIBYTE_SB1250
        select SWAP_IO_SPACE
@@ -1305,6 +1307,33 @@ config CPU_CAVIUM_OCTEON
 
 endchoice
 
+if CPU_LOONGSON2F
+config CPU_NOP_WORKAROUNDS
+       bool
+
+config CPU_JUMP_WORKAROUNDS
+       bool
+
+config CPU_LOONGSON2F_WORKAROUNDS
+       bool "Loongson 2F Workarounds"
+       default y
+       select CPU_NOP_WORKAROUNDS
+       select CPU_JUMP_WORKAROUNDS
+       help
+         Loongson 2F01 / 2F02 processors have the NOP & JUMP issues which
+         require workarounds.  Without workarounds the system may hang
+         unexpectedly.  For more information please refer to the gas
+         -mfix-loongson2f-nop and -mfix-loongson2f-jump options.
+
+         Loongson 2F03 and later have fixed these issues and no workarounds
+         are needed.  The workarounds have no significant side effect on them
+         but may decrease the performance of the system so this option should
+         be disabled unless the kernel is intended to be run on 2F01 or 2F02
+         systems.
+
+         If unsure, please say Y.
+endif # CPU_LOONGSON2F
+
 config SYS_SUPPORTS_ZBOOT
        bool
        select HAVE_KERNEL_GZIP
index 2f2eac23332256005659a5c34bafdee0297f0b8e..0b9c01add0a06d91b49ff813f8eb127c70ae112a 100644 (file)
@@ -136,6 +136,19 @@ cflags-$(CONFIG_CPU_LOONGSON2E) += \
        $(call cc-option,-march=loongson2e,-march=r4600)
 cflags-$(CONFIG_CPU_LOONGSON2F) += \
        $(call cc-option,-march=loongson2f,-march=r4600)
+# enable the workarounds for loongson2f
+ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
+  ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-nop,),)
+    $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop)
+  else
+    cflags-$(CONFIG_CPU_NOP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-nop
+  endif
+  ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-jump,),)
+    $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-jump)
+  else
+    cflags-$(CONFIG_CPU_JUMP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-jump
+  endif
+endif
 
 cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
                        -Wa,-mips32 -Wa,--trap
index 379536e3abd1f52d2543386a9d3c5e8cca6c602d..8876195475539e0ea881c2b80b8bf6a21ff2d2d9 100644 (file)
@@ -60,58 +60,22 @@ void __init board_setup(void)
        wmb();
 }
 
-/* use the hexleds to count the number of times the cpu has entered
- * wait, the dots to indicate whether the CPU is currently idle or
- * active (dots off = sleeping, dots on = working) for cases where
- * the number doesn't change for a long(er) period of time.
- */
-static void db1200_wait(void)
-{
-       __asm__("       .set    push                    \n"
-               "       .set    mips3                   \n"
-               "       .set    noreorder               \n"
-               "       cache   0x14, 0(%0)             \n"
-               "       cache   0x14, 32(%0)            \n"
-               "       cache   0x14, 64(%0)            \n"
-               /* dots off: we're about to call wait */
-               "       lui     $26, 0xb980             \n"
-               "       ori     $27, $0, 3              \n"
-               "       sb      $27, 0x18($26)          \n"
-               "       sync                            \n"
-               "       nop                             \n"
-               "       wait                            \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               /* dots on: there's work to do, increment cntr */
-               "       lui     $26, 0xb980             \n"
-               "       sb      $0, 0x18($26)           \n"
-               "       lui     $26, 0xb9c0             \n"
-               "       lb      $27, 0($26)             \n"
-               "       addiu   $27, $27, 1             \n"
-               "       sb      $27, 0($26)             \n"
-               "       sync                            \n"
-               "       .set    pop                     \n"
-               : : "r" (db1200_wait));
-}
-
 static int __init db1200_arch_init(void)
 {
        /* GPIO7 is low-level triggered CPLD cascade */
        set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
        bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
 
-       /* do not autoenable these: CPLD has broken edge int handling,
-        * and the CD handler setup requires manual enabling to work
-        * around that.
+       /* insert/eject pairs: one of both is always screaming.  To avoid
+        * issues they must not be automatically enabled when initially
+        * requested.
         */
        irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN;
        irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN;
-
-       if (cpu_wait)
-               cpu_wait = db1200_wait;
+       irq_to_desc(DB1200_PC0_INSERT_INT)->status |= IRQ_NOAUTOEN;
+       irq_to_desc(DB1200_PC0_EJECT_INT)->status |= IRQ_NOAUTOEN;
+       irq_to_desc(DB1200_PC1_INSERT_INT)->status |= IRQ_NOAUTOEN;
+       irq_to_desc(DB1200_PC1_EJECT_INT)->status |= IRQ_NOAUTOEN;
 
        return 0;
 }
index 246df7aca2e7147b762f6f069381e7d942c17e4a..2fafc78e5ce1d408ef15c09519edef79eb70da3c 100644 (file)
@@ -168,7 +168,7 @@ static struct plat_vlynq_data vlynq_high_data = {
                .on     = vlynq_on,
                .off    = vlynq_off,
        },
-       .reset_bit      = 26,
+       .reset_bit      = 16,
        .gpio_bit       = 19,
 };
 
@@ -600,6 +600,7 @@ static int __init ar7_register_devices(void)
        }
 
        if (ar7_has_high_cpmac()) {
+               res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status);
                if (!res) {
                        cpmac_get_mac(1, cpmac_high_data.dev_addr);
 
index ea17941168ca2d0cd5be6b69a13892ce3b3c6978..8dba8cfb752fa62a8fbc04025785c3ee78d71b30 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/addrspace.h>
 #include <bcm63xx_board.h>
 #include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_uart.h>
 #include <bcm63xx_regs.h>
 #include <bcm63xx_io.h>
 #include <bcm63xx_dev_pci.h>
@@ -40,6 +41,7 @@ static struct board_info __initdata board_96338gw = {
        .name                           = "96338GW",
        .expected_cpu_id                = 0x6338,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .enet0 = {
                .force_speed_100        = 1,
@@ -82,6 +84,7 @@ static struct board_info __initdata board_96338w = {
        .name                           = "96338W",
        .expected_cpu_id                = 0x6338,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .enet0 = {
                .force_speed_100        = 1,
@@ -126,6 +129,8 @@ static struct board_info __initdata board_96338w = {
 static struct board_info __initdata board_96345gw2 = {
        .name                           = "96345GW2",
        .expected_cpu_id                = 0x6345,
+
+       .has_uart0                      = 1,
 };
 #endif
 
@@ -137,6 +142,7 @@ static struct board_info __initdata board_96348r = {
        .name                           = "96348R",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_pci                        = 1,
 
@@ -180,6 +186,7 @@ static struct board_info __initdata board_96348gw_10 = {
        .name                           = "96348GW-10",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -239,6 +246,7 @@ static struct board_info __initdata board_96348gw_11 = {
        .name                           = "96348GW-11",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -292,6 +300,7 @@ static struct board_info __initdata board_96348gw = {
        .name                           = "96348GW",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -349,9 +358,10 @@ static struct board_info __initdata board_FAST2404 = {
        .name                           = "F@ST2404",
        .expected_cpu_id                = 0x6348,
 
-       .has_enet0                      = 1,
-       .has_enet1                      = 1,
-       .has_pci                        = 1,
+       .has_uart0                      = 1,
+        .has_enet0                     = 1,
+        .has_enet1                     = 1,
+        .has_pci                       = 1,
 
        .enet0 = {
                .has_phy                = 1,
@@ -368,10 +378,30 @@ static struct board_info __initdata board_FAST2404 = {
        .has_ehci0                      = 1,
 };
 
+static struct board_info __initdata board_rta1025w_16 = {
+       .name                           = "RTA1025W_16",
+       .expected_cpu_id                = 0x6348,
+
+       .has_enet0                      = 1,
+       .has_enet1                      = 1,
+       .has_pci                        = 1,
+
+       .enet0 = {
+               .has_phy                = 1,
+               .use_internal_phy       = 1,
+       },
+       .enet1 = {
+               .force_speed_100        = 1,
+               .force_duplex_full      = 1,
+       },
+};
+
+
 static struct board_info __initdata board_DV201AMR = {
        .name                           = "DV201AMR",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_pci                        = 1,
        .has_ohci0                      = 1,
 
@@ -391,6 +421,7 @@ static struct board_info __initdata board_96348gw_a = {
        .name                           = "96348GW-A",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -416,6 +447,7 @@ static struct board_info __initdata board_96358vw = {
        .name                           = "96358VW",
        .expected_cpu_id                = 0x6358,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -467,6 +499,7 @@ static struct board_info __initdata board_96358vw2 = {
        .name                           = "96358VW2",
        .expected_cpu_id                = 0x6358,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -514,6 +547,7 @@ static struct board_info __initdata board_AGPFS0 = {
        .name                           = "AGPF-S0",
        .expected_cpu_id                = 0x6358,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -531,6 +565,27 @@ static struct board_info __initdata board_AGPFS0 = {
        .has_ohci0 = 1,
        .has_ehci0 = 1,
 };
+
+static struct board_info __initdata board_DWVS0 = {
+       .name                           = "DWV-S0",
+       .expected_cpu_id                = 0x6358,
+
+       .has_enet0                      = 1,
+       .has_enet1                      = 1,
+       .has_pci                        = 1,
+
+       .enet0 = {
+               .has_phy                = 1,
+               .use_internal_phy       = 1,
+       },
+
+       .enet1 = {
+               .force_speed_100        = 1,
+               .force_duplex_full      = 1,
+       },
+
+       .has_ohci0                      = 1,
+};
 #endif
 
 /*
@@ -552,15 +607,87 @@ static const struct board_info __initdata *bcm963xx_boards[] = {
        &board_FAST2404,
        &board_DV201AMR,
        &board_96348gw_a,
+       &board_rta1025w_16,
 #endif
 
 #ifdef CONFIG_BCM63XX_CPU_6358
        &board_96358vw,
        &board_96358vw2,
        &board_AGPFS0,
+       &board_DWVS0,
 #endif
 };
 
+/*
+ * Register a sane SPROMv2 to make the on-board
+ * bcm4318 WLAN work
+ */
+#ifdef CONFIG_SSB_PCIHOST
+static struct ssb_sprom bcm63xx_sprom = {
+       .revision               = 0x02,
+       .board_rev              = 0x17,
+       .country_code           = 0x0,
+       .ant_available_bg       = 0x3,
+       .pa0b0                  = 0x15ae,
+       .pa0b1                  = 0xfa85,
+       .pa0b2                  = 0xfe8d,
+       .pa1b0                  = 0xffff,
+       .pa1b1                  = 0xffff,
+       .pa1b2                  = 0xffff,
+       .gpio0                  = 0xff,
+       .gpio1                  = 0xff,
+       .gpio2                  = 0xff,
+       .gpio3                  = 0xff,
+       .maxpwr_bg              = 0x004c,
+       .itssi_bg               = 0x00,
+       .boardflags_lo          = 0x2848,
+       .boardflags_hi          = 0x0000,
+};
+#endif
+
+/*
+ * return board name for /proc/cpuinfo
+ */
+const char *board_get_name(void)
+{
+       return board.name;
+}
+
+/*
+ * register & return a new board mac address
+ */
+static int board_get_mac_address(u8 *mac)
+{
+       u8 *p;
+       int count;
+
+       if (mac_addr_used >= nvram.mac_addr_count) {
+               printk(KERN_ERR PFX "not enough mac address\n");
+               return -ENODEV;
+       }
+
+       memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
+       p = mac + ETH_ALEN - 1;
+       count = mac_addr_used;
+
+       while (count--) {
+               do {
+                       (*p)++;
+                       if (*p != 0)
+                               break;
+                       p--;
+               } while (p != mac);
+       }
+
+       if (p == mac) {
+               printk(KERN_ERR PFX "unable to fetch mac address\n");
+               return -ENODEV;
+       }
+
+       mac_addr_used++;
+       return 0;
+}
+
 /*
  * early init callback, read nvram data from flash and checksum it
  */
@@ -659,6 +786,17 @@ void __init board_prom_init(void)
        }
 
        bcm_gpio_writel(val, GPIO_MODE_REG);
+
+       /* Generate MAC address for WLAN and
+        * register our SPROM */
+#ifdef CONFIG_SSB_PCIHOST
+       if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
+               memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+               memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+               if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
+                       printk(KERN_ERR "failed to register fallback SPROM\n");
+       }
+#endif
 }
 
 /*
@@ -676,49 +814,6 @@ void __init board_setup(void)
                panic("unexpected CPU for bcm963xx board");
 }
 
-/*
- * return board name for /proc/cpuinfo
- */
-const char *board_get_name(void)
-{
-       return board.name;
-}
-
-/*
- * register & return a new board mac address
- */
-static int board_get_mac_address(u8 *mac)
-{
-       u8 *p;
-       int count;
-
-       if (mac_addr_used >= nvram.mac_addr_count) {
-               printk(KERN_ERR PFX "not enough mac address\n");
-               return -ENODEV;
-       }
-
-       memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
-       p = mac + ETH_ALEN - 1;
-       count = mac_addr_used;
-
-       while (count--) {
-               do {
-                       (*p)++;
-                       if (*p != 0)
-                               break;
-                       p--;
-               } while (p != mac);
-       }
-
-       if (p == mac) {
-               printk(KERN_ERR PFX "unable to fetch mac address\n");
-               return -ENODEV;
-       }
-
-       mac_addr_used++;
-       return 0;
-}
-
 static struct mtd_partition mtd_partitions[] = {
        {
                .name           = "cfe",
@@ -750,33 +845,6 @@ static struct platform_device mtd_dev = {
        },
 };
 
-/*
- * Register a sane SPROMv2 to make the on-board
- * bcm4318 WLAN work
- */
-#ifdef CONFIG_SSB_PCIHOST
-static struct ssb_sprom bcm63xx_sprom = {
-       .revision               = 0x02,
-       .board_rev              = 0x17,
-       .country_code           = 0x0,
-       .ant_available_bg       = 0x3,
-       .pa0b0                  = 0x15ae,
-       .pa0b1                  = 0xfa85,
-       .pa0b2                  = 0xfe8d,
-       .pa1b0                  = 0xffff,
-       .pa1b1                  = 0xffff,
-       .pa1b2                  = 0xffff,
-       .gpio0                  = 0xff,
-       .gpio1                  = 0xff,
-       .gpio2                  = 0xff,
-       .gpio3                  = 0xff,
-       .maxpwr_bg              = 0x004c,
-       .itssi_bg               = 0x00,
-       .boardflags_lo          = 0x2848,
-       .boardflags_hi          = 0x0000,
-};
-#endif
-
 static struct gpio_led_platform_data bcm63xx_led_data;
 
 static struct platform_device bcm63xx_gpio_leds = {
@@ -792,6 +860,12 @@ int __init board_register_devices(void)
 {
        u32 val;
 
+       if (board.has_uart0)
+               bcm63xx_uart_register(0);
+
+       if (board.has_uart1)
+               bcm63xx_uart_register(1);
+
        if (board.has_pccard)
                bcm63xx_pcmcia_register();
 
@@ -806,17 +880,6 @@ int __init board_register_devices(void)
        if (board.has_dsp)
                bcm63xx_dsp_register(&board.dsp);
 
-       /* Generate MAC address for WLAN and
-        * register our SPROM */
-#ifdef CONFIG_SSB_PCIHOST
-       if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
-               memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
-               memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
-               if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
-                       printk(KERN_ERR "failed to register fallback SPROM\n");
-       }
-#endif
-
        /* read base address of boot chip select (0) */
        if (BCMCPU_IS_6345())
                val = 0x1fc00000;
index 70378bb5e3f93d63b8dd3e631307742fa2491694..cbb7caf86d77bce79656ed1aff48521552853b02 100644 (file)
@@ -36,6 +36,7 @@ static const unsigned long bcm96338_regs_base[] = {
        [RSET_TIMER]            = BCM_6338_TIMER_BASE,
        [RSET_WDT]              = BCM_6338_WDT_BASE,
        [RSET_UART0]            = BCM_6338_UART0_BASE,
+       [RSET_UART1]            = BCM_6338_UART1_BASE,
        [RSET_GPIO]             = BCM_6338_GPIO_BASE,
        [RSET_SPI]              = BCM_6338_SPI_BASE,
        [RSET_OHCI0]            = BCM_6338_OHCI0_BASE,
@@ -72,6 +73,7 @@ static const unsigned long bcm96345_regs_base[] = {
        [RSET_TIMER]            = BCM_6345_TIMER_BASE,
        [RSET_WDT]              = BCM_6345_WDT_BASE,
        [RSET_UART0]            = BCM_6345_UART0_BASE,
+       [RSET_UART1]            = BCM_6345_UART1_BASE,
        [RSET_GPIO]             = BCM_6345_GPIO_BASE,
        [RSET_SPI]              = BCM_6345_SPI_BASE,
        [RSET_UDC0]             = BCM_6345_UDC0_BASE,
@@ -109,6 +111,7 @@ static const unsigned long bcm96348_regs_base[] = {
        [RSET_TIMER]            = BCM_6348_TIMER_BASE,
        [RSET_WDT]              = BCM_6348_WDT_BASE,
        [RSET_UART0]            = BCM_6348_UART0_BASE,
+       [RSET_UART1]            = BCM_6348_UART1_BASE,
        [RSET_GPIO]             = BCM_6348_GPIO_BASE,
        [RSET_SPI]              = BCM_6348_SPI_BASE,
        [RSET_OHCI0]            = BCM_6348_OHCI0_BASE,
@@ -150,6 +153,7 @@ static const unsigned long bcm96358_regs_base[] = {
        [RSET_TIMER]            = BCM_6358_TIMER_BASE,
        [RSET_WDT]              = BCM_6358_WDT_BASE,
        [RSET_UART0]            = BCM_6358_UART0_BASE,
+       [RSET_UART1]            = BCM_6358_UART1_BASE,
        [RSET_GPIO]             = BCM_6358_GPIO_BASE,
        [RSET_SPI]              = BCM_6358_SPI_BASE,
        [RSET_OHCI0]            = BCM_6358_OHCI0_BASE,
@@ -170,6 +174,7 @@ static const unsigned long bcm96358_regs_base[] = {
 static const int bcm96358_irqs[] = {
        [IRQ_TIMER]             = BCM_6358_TIMER_IRQ,
        [IRQ_UART0]             = BCM_6358_UART0_IRQ,
+       [IRQ_UART1]             = BCM_6358_UART1_IRQ,
        [IRQ_DSL]               = BCM_6358_DSL_IRQ,
        [IRQ_ENET0]             = BCM_6358_ENET0_IRQ,
        [IRQ_ENET1]             = BCM_6358_ENET1_IRQ,
index b0519461ad9bf5754f72b67231e6bf01495b7e4f..c2963da0253e65ca9520879d0e6a992e541cd798 100644 (file)
 #include <linux/platform_device.h>
 #include <bcm63xx_cpu.h>
 
-static struct resource uart_resources[] = {
+static struct resource uart0_resources[] = {
        {
-               .start          = -1, /* filled at runtime */
-               .end            = -1, /* filled at runtime */
+               /* start & end filled at runtime */
                .flags          = IORESOURCE_MEM,
        },
        {
-               .start          = -1, /* filled at runtime */
+               /* start filled at runtime */
                .flags          = IORESOURCE_IRQ,
        },
 };
 
-static struct platform_device bcm63xx_uart_device = {
-       .name           = "bcm63xx_uart",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(uart_resources),
-       .resource       = uart_resources,
+static struct resource uart1_resources[] = {
+       {
+               /* start & end filled at runtime */
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               /* start filled at runtime */
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bcm63xx_uart_devices[] = {
+       {
+               .name           = "bcm63xx_uart",
+               .id             = 0,
+               .num_resources  = ARRAY_SIZE(uart0_resources),
+               .resource       = uart0_resources,
+       },
+
+       {
+               .name           = "bcm63xx_uart",
+               .id             = 1,
+               .num_resources  = ARRAY_SIZE(uart1_resources),
+               .resource       = uart1_resources,
+       }
 };
 
-int __init bcm63xx_uart_register(void)
+int __init bcm63xx_uart_register(unsigned int id)
 {
-       uart_resources[0].start = bcm63xx_regset_address(RSET_UART0);
-       uart_resources[0].end = uart_resources[0].start;
-       uart_resources[0].end += RSET_UART_SIZE - 1;
-       uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
-       return platform_device_register(&bcm63xx_uart_device);
+       if (id >= ARRAY_SIZE(bcm63xx_uart_devices))
+               return -ENODEV;
+
+       if (id == 1 && !BCMCPU_IS_6358())
+               return -ENODEV;
+
+       if (id == 0) {
+               uart0_resources[0].start = bcm63xx_regset_address(RSET_UART0);
+               uart0_resources[0].end = uart0_resources[0].start +
+                       RSET_UART_SIZE - 1;
+               uart0_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
+       }
+
+       if (id == 1) {
+               uart1_resources[0].start = bcm63xx_regset_address(RSET_UART1);
+               uart1_resources[0].end = uart1_resources[0].start +
+                       RSET_UART_SIZE - 1;
+               uart1_resources[1].start = bcm63xx_get_irq_number(IRQ_UART1);
+       }
+
+       return platform_device_register(&bcm63xx_uart_devices[id]);
 }
-arch_initcall(bcm63xx_uart_register);
index 87ca39046334444b3ad43885bdfa84f14658b002..315bc7f79ce15bf9ff78f57b6f331200478c27d0 100644 (file)
@@ -125,10 +125,10 @@ static struct gpio_chip bcm63xx_gpio_chip = {
 
 int __init bcm63xx_gpio_init(void)
 {
+       gpio_out_low = bcm_gpio_readl(GPIO_DATA_LO_REG);
+       gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG);
        bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
        pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
 
        return gpiochip_add(&bcm63xx_gpio_chip);
 }
-
-arch_initcall(bcm63xx_gpio_init);
index b321d3b168771592cf744c8be9efc9f91fe31623..9a06fa9f9f0cdc890a8c2f9f8ad05b5384feb510 100644 (file)
@@ -45,9 +45,6 @@ extern struct plat_smp_ops octeon_smp_ops;
 extern void pci_console_init(const char *arg);
 #endif
 
-#ifdef CONFIG_CAVIUM_RESERVE32
-extern uint64_t octeon_reserve32_memory;
-#endif
 static unsigned long long MAX_MEMORY = 512ull << 20;
 
 struct octeon_boot_descriptor *octeon_boot_desc_ptr;
@@ -186,54 +183,6 @@ void octeon_check_cpu_bist(void)
        write_octeon_c0_dcacheerr(0);
 }
 
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-/**
- * Called on every core to setup the wired tlb entry needed
- * if CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB is set.
- *
- */
-static void octeon_hal_setup_per_cpu_reserved32(void *unused)
-{
-       /*
-        * The config has selected to wire the reserve32 memory for all
-        * userspace applications. We need to put a wired TLB entry in for each
-        * 512MB of reserve32 memory. We only handle double 256MB pages here,
-        * so reserve32 must be multiple of 512MB.
-        */
-       uint32_t size = CONFIG_CAVIUM_RESERVE32;
-       uint32_t entrylo0 =
-               0x7 | ((octeon_reserve32_memory & ((1ul << 40) - 1)) >> 6);
-       uint32_t entrylo1 = entrylo0 + (256 << 14);
-       uint32_t entryhi = (0x80000000UL - (CONFIG_CAVIUM_RESERVE32 << 20));
-       while (size >= 512) {
-#if 0
-               pr_info("CPU%d: Adding double wired TLB entry for 0x%lx\n",
-                       smp_processor_id(), entryhi);
-#endif
-               add_wired_entry(entrylo0, entrylo1, entryhi, PM_256M);
-               entrylo0 += 512 << 14;
-               entrylo1 += 512 << 14;
-               entryhi += 512 << 20;
-               size -= 512;
-       }
-}
-#endif /* CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB */
-
-/**
- * Called to release the named block which was used to made sure
- * that nobody used the memory for something else during
- * init. Now we'll free it so userspace apps can use this
- * memory region with bootmem_alloc.
- *
- * This function is called only once from prom_free_prom_memory().
- */
-void octeon_hal_setup_reserved32(void)
-{
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-       on_each_cpu(octeon_hal_setup_per_cpu_reserved32, NULL, 0, 1);
-#endif
-}
-
 /**
  * Reboot Octeon
  *
@@ -294,18 +243,6 @@ static void octeon_halt(void)
        octeon_kill_core(NULL);
 }
 
-#if 0
-/**
- * Platform time init specifics.
- * Returns
- */
-void __init plat_time_init(void)
-{
-       /* Nothing special here, but we are required to have one */
-}
-
-#endif
-
 /**
  * Handle all the error condition interrupts that might occur.
  *
@@ -502,25 +439,13 @@ void __init prom_init(void)
         * memory when it is getting memory from the
         * bootloader. Later, after the memory allocations are
         * complete, the reserve32 will be freed.
-        */
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-       if (CONFIG_CAVIUM_RESERVE32 & 0x1ff)
-               pr_err("CAVIUM_RESERVE32 isn't a multiple of 512MB. "
-                      "This is required if CAVIUM_RESERVE32_USE_WIRED_TLB "
-                      "is set\n");
-       else
-               addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
-                                                       0, 0, 512 << 20,
-                                                       "CAVIUM_RESERVE32", 0);
-#else
-       /*
+        *
         * Allocate memory for RESERVED32 aligned on 2MB boundary. This
         * is in case we later use hugetlb entries with it.
         */
        addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
                                                0, 0, 2 << 20,
                                                "CAVIUM_RESERVE32", 0);
-#endif
        if (addr < 0)
                pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n");
        else
@@ -817,9 +742,4 @@ void prom_free_prom_memory(void)
                panic("Unable to request_irq(OCTEON_IRQ_RML)\n");
        }
 #endif
-
-       /* This call is here so that it is performed after any TLB
-          initializations. It needs to be after these in case the
-          CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */
-       octeon_hal_setup_reserved32();
 }
index 51e980290ce1088f307d639c17b4455f5094b191..6d99b9d8887dd3d77ab4f94d79170fc0eacfbc25 100644 (file)
@@ -279,14 +279,6 @@ static void octeon_cpu_die(unsigned int cpu)
        uint32_t avail_coremask;
        struct cvmx_bootmem_named_block_desc *block_desc;
 
-#ifdef CONFIG_CAVIUM_OCTEON_WATCHDOG
-       /* Disable the watchdog */
-       cvmx_ciu_wdogx_t ciu_wdog;
-       ciu_wdog.u64 = cvmx_read_csr(CVMX_CIU_WDOGX(cpu));
-       ciu_wdog.s.mode = 0;
-       cvmx_write_csr(CVMX_CIU_WDOGX(cpu), ciu_wdog.u64);
-#endif
-
        while (per_cpu(cpu_state, cpu) != CPU_DEAD)
                cpu_relax();
 
index 7fee0273c82935f7a420081ceaed30e71d4774eb..6389ca0fdc6c6f0164a4cad4a2cd363a7b68b7d2 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc6
-# Sun May 31 20:17:18 2009
+# Linux kernel version: 2.6.34-rc2
+# Tue Mar 23 10:36:32 2010
 #
 CONFIG_MIPS=y
 
@@ -9,13 +9,14 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
 CONFIG_BCM63XX=y
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
-# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SIM is not set
 # CONFIG_NEC_MARKEINS is not set
@@ -26,6 +27,7 @@ CONFIG_BCM63XX=y
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP28 is not set
@@ -45,13 +47,17 @@ CONFIG_BCM63XX=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
 
 #
 # CPU support
 #
+CONFIG_BCM63XX_CPU_6338=y
+CONFIG_BCM63XX_CPU_6345=y
 CONFIG_BCM63XX_CPU_6348=y
 CONFIG_BCM63XX_CPU_6358=y
 CONFIG_BOARD_BCM963XX=y
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -69,10 +75,8 @@ CONFIG_CEVT_R4K=y
 CONFIG_CSRC_R4K_LIB=y
 CONFIG_CSRC_R4K=y
 CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
-CONFIG_EARLY_PRINTK=y
+CONFIG_NEED_DMA_MAP_STATE=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
@@ -85,7 +89,8 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 #
 # CPU selection
 #
-# CONFIG_CPU_LOONGSON2 is not set
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -128,7 +133,7 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
@@ -146,9 +151,8 @@ 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 is not set
@@ -170,6 +174,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
@@ -189,15 +194,12 @@ CONFIG_LOCALVERSION=""
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
 # CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_RCU=y
 # 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 is not set
-# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -205,11 +207,11 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_BLK_DEV_INITRD 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
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -223,6 +225,10 @@ CONFIG_BASE_FULL=y
 # CONFIG_EVENTFD is not set
 # CONFIG_SHMEM is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 # CONFIG_VM_EVENT_COUNTERS is not set
 CONFIG_PCI_QUIRKS=y
 # CONFIG_SLUB_DEBUG is not set
@@ -231,14 +237,17 @@ 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
+
+#
+# GCOV-based kernel profiling
+#
 # CONFIG_SLOW_WORK is not set
-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=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
 
@@ -246,14 +255,41 @@ CONFIG_BLOCK=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -263,15 +299,12 @@ CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
 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
 CONFIG_PCCARD=y
-# CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_IOCTL=y
 CONFIG_CARDBUS=y
 
 #
@@ -295,6 +328,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
@@ -333,6 +367,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
@@ -347,6 +382,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
 
@@ -359,7 +395,27 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=y
+CONFIG_NL80211_TESTMODE=y
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+CONFIG_MAC80211=y
+# CONFIG_MAC80211_RC_PID is not set
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
+# CONFIG_MAC80211_MESH is not set
+CONFIG_MAC80211_LEDS=y
+# CONFIG_MAC80211_DEBUG_MENU is not set
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -471,6 +527,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -484,13 +541,16 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# The newer stack is recommended.
 #
 # 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
@@ -529,6 +589,7 @@ CONFIG_MII=y
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
 # CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
@@ -541,17 +602,48 @@ 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_ATL2 is not set
 CONFIG_BCM63XX_ENET=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+CONFIG_WLAN=y
+# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_ATMEL is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8180 is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_ADM8211 is not set
+# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_MWL8K is not set
+# CONFIG_ATH_COMMON is not set
+CONFIG_B43=y
+CONFIG_B43_PCI_AUTOSELECT=y
+CONFIG_B43_PCICORE_AUTOSELECT=y
+# CONFIG_B43_PCMCIA is not set
+CONFIG_B43_PIO=y
+# CONFIG_B43_PHY_LP is not set
+CONFIG_B43_LEDS=y
+# CONFIG_B43_DEBUG is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_IWLWIFI is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_HERMES is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_WL12XX is not set
+# CONFIG_ZD1211RW is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -574,6 +666,7 @@ CONFIG_BCM63XX_ENET=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -607,6 +700,7 @@ CONFIG_BCM63XX_ENET=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_SERIAL_BCM63XX=y
 CONFIG_SERIAL_BCM63XX_CONSOLE=y
 # CONFIG_UNIX98_PTYS is not set
@@ -629,6 +723,11 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_GPIO_SYSFS is not set
@@ -636,6 +735,8 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
@@ -644,16 +745,21 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # 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
 
@@ -662,15 +768,16 @@ CONFIG_SSB_POSSIBLE=y
 #
 CONFIG_SSB=y
 CONFIG_SSB_SPROM=y
+CONFIG_SSB_BLOCKIO=y
 CONFIG_SSB_PCIHOST_POSSIBLE=y
 CONFIG_SSB_PCIHOST=y
-# CONFIG_SSB_B43_PCI_BRIDGE is not set
+CONFIG_SSB_B43_PCI_BRIDGE=y
 CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
 # CONFIG_SSB_PCMCIAHOST is not set
 # CONFIG_SSB_SILENT is not set
 # CONFIG_SSB_DEBUG is not set
 CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
-# CONFIG_SSB_DRIVER_PCICORE is not set
+CONFIG_SSB_DRIVER_PCICORE=y
 # CONFIG_SSB_DRIVER_MIPS is not set
 
 #
@@ -680,27 +787,15 @@ CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH 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
@@ -710,11 +805,7 @@ CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
 #
 # Display device support
 #
-CONFIG_DISPLAY_SUPPORT=y
-
-#
-# Display hardware drivers
-#
+# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -741,13 +832,14 @@ CONFIG_USB=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 is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
-CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=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_SSB is not set
 CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
@@ -796,7 +888,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # 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
@@ -807,8 +898,8 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=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
 
 #
@@ -819,7 +910,29 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_NEW_LEDS is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_TRIGGERS=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGER_TIMER=y
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+CONFIG_LEDS_TRIGGER_GPIO=y
+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
@@ -827,6 +940,10 @@ CONFIG_RTC_LIB=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -838,12 +955,16 @@ CONFIG_RTC_LIB=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-# CONFIG_FILE_LOCKING is not set
 # 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 is not set
+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
@@ -875,8 +996,6 @@ 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_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
 CONFIG_MISC_FILESYSTEMS=y
@@ -888,6 +1007,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -898,7 +1018,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
 
 #
@@ -906,7 +1025,46 @@ CONFIG_MISC_FILESYSTEMS=y
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 # CONFIG_DLM is not set
 
 #
@@ -918,29 +1076,23 @@ 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
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
-# 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_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_EARLY_PRINTK=y
 CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttyS0,115200"
 # CONFIG_CMDLINE_OVERRIDE is not set
@@ -951,8 +1103,108 @@ CONFIG_CMDLINE="console=ttyS0,115200"
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=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 is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# 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
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=y
+# CONFIG_CRYPTO_HW is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index c2f06e38c8546770d2bacd7b93d9248b9803a2ef..0583bb29150f70dc90ea78223280ace61ba91088 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc8
-# Wed Jul  2 17:02:55 2008
+# Linux kernel version: 2.6.34-rc3
+# Sat Apr  3 16:32:11 2010
 #
 CONFIG_MIPS=y
 
@@ -9,20 +9,25 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 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_MARKEINS 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
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP28 is not set
@@ -36,10 +41,13 @@ CONFIG_MIPS=y
 # CONFIG_SIBYTE_SENTOSA is not set
 CONFIG_SIBYTE_BIGSUR=y
 # CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
 # 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_SIBYTE_BCM1x80=y
 CONFIG_SIBYTE_SB1xxx_SOC=y
 # CONFIG_CPU_SB1_PASS_1 is not set
@@ -48,14 +56,13 @@ CONFIG_SIBYTE_SB1xxx_SOC=y
 # CONFIG_CPU_SB1_PASS_4 is not set
 # CONFIG_CPU_SB1_PASS_2_112x is not set
 # CONFIG_CPU_SB1_PASS_3 is not set
-# CONFIG_SIMULATION is not set
 # CONFIG_SB1_CEX_ALWAYS_FATAL is not set
 # CONFIG_SB1_CERR_STALL is not set
-CONFIG_SIBYTE_CFE=y
 # CONFIG_SIBYTE_CFE_CONSOLE is not set
 # CONFIG_SIBYTE_BUS_WATCHER is not set
 # CONFIG_SIBYTE_TBPROF is not set
 CONFIG_SIBYTE_HAS_ZBUS_PROFILING=y
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -66,15 +73,13 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_CEVT_BCM1480=y
 CONFIG_CSRC_BCM1480=y
 CONFIG_CFE=y
 CONFIG_DMA_COHERENT=y
-CONFIG_EARLY_PRINTK=y
 CONFIG_SYS_HAS_EARLY_PRINTK=y
-# CONFIG_HOTPLUG_CPU is not set
 # CONFIG_NO_IOPORT is not set
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
@@ -88,7 +93,8 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 #
 # CPU selection
 #
-# CONFIG_CPU_LOONGSON2 is not set
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 # CONFIG_CPU_MIPS32_R1 is not set
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -101,6 +107,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
@@ -108,6 +115,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 CONFIG_CPU_SB1=y
+# CONFIG_CPU_CAVIUM_OCTEON is not set
 CONFIG_SYS_HAS_CPU_SB1=y
 CONFIG_WEAK_ORDERING=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
@@ -123,11 +131,13 @@ CONFIG_64BIT=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_SIBYTE_DMA_PAGEOPS is not set
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
@@ -142,18 +152,17 @@ 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 is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
+CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_SMP=y
 CONFIG_SYS_SUPPORTS_SMP=y
 CONFIG_NR_CPUS_DEFAULT_4=y
 CONFIG_NR_CPUS=4
-# CONFIG_MIPS_CMP is not set
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -175,6 +184,7 @@ CONFIG_SECCOMP=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -188,6 +198,7 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_TASKSTATS=y
@@ -195,23 +206,39 @@ CONFIG_TASK_DELAY_ACCT=y
 CONFIG_TASK_XACCT=y
 CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_AUDIT=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=64
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_CGROUPS is not set
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 CONFIG_RELAY=y
-# CONFIG_NAMESPACES is not set
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
 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_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
@@ -222,29 +249,36 @@ 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=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 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
@@ -252,26 +286,52 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 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_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+# CONFIG_FREEZER is not set
 
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
@@ -280,8 +340,9 @@ CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 CONFIG_PCI_DEBUG=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 CONFIG_MMU=y
 CONFIG_ZONE_DMA32=y
 # CONFIG_PCCARD is not set
@@ -291,6 +352,8 @@ CONFIG_ZONE_DMA32=y
 # Executable file formats
 #
 CONFIG_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_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
@@ -304,23 +367,20 @@ CONFIG_BINFMT_ELF32=y
 #
 CONFIG_PM=y
 # CONFIG_PM_DEBUG is not set
-
-#
-# Networking
-#
+# CONFIG_PM_RUNTIME is not set
 CONFIG_NET=y
 
 #
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -353,36 +413,6 @@ CONFIG_INET_TCP_DIAG=y
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_TCP_MD5SIG=y
-CONFIG_IP_VS=m
-# CONFIG_IP_VS_DEBUG is not set
-CONFIG_IP_VS_TAB_BITS=12
-
-#
-# IPVS transport protocol load balancing support
-#
-CONFIG_IP_VS_PROTO_TCP=y
-CONFIG_IP_VS_PROTO_UDP=y
-CONFIG_IP_VS_PROTO_ESP=y
-CONFIG_IP_VS_PROTO_AH=y
-
-#
-# IPVS scheduler
-#
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-CONFIG_IP_VS_SED=m
-CONFIG_IP_VS_NQ=m
-
-#
-# IPVS application helper
-#
-CONFIG_IP_VS_FTP=m
 CONFIG_IPV6=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
@@ -399,11 +429,13 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
 CONFIG_IPV6_SIT=m
+CONFIG_IPV6_SIT_6RD=y
 CONFIG_IPV6_NDISC_NODETYPE=y
 CONFIG_IPV6_TUNNEL=m
 CONFIG_IPV6_MULTIPLE_TABLES=y
 CONFIG_IPV6_SUBTREES=y
 # CONFIG_IPV6_MROUTE is not set
+CONFIG_NETLABEL=y
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -421,19 +453,53 @@ CONFIG_NF_CONNTRACK_IRC=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_IPV6=y
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_AH_ESP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_PROTO_SCTP=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
 
 #
 # IP: Netfilter Configuration
 #
+CONFIG_NF_DEFRAG_IPV4=m
 CONFIG_NF_CONNTRACK_IPV4=m
 CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 CONFIG_IP_NF_IPTABLES=m
@@ -459,22 +525,44 @@ CONFIG_IP_NF_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
-# CONFIG_IP_DCCP is not set
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP_CCID2_DEBUG is not set
+CONFIG_IP_DCCP_CCID3=y
+# CONFIG_IP_DCCP_CCID3_DEBUG is not set
+CONFIG_IP_DCCP_CCID3_RTO=100
+CONFIG_IP_DCCP_TFRC_LIB=y
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
 # CONFIG_SCTP_HMAC_NONE is not set
-# CONFIG_SCTP_HMAC_SHA1 is not set
-CONFIG_SCTP_HMAC_MD5=y
+CONFIG_SCTP_HMAC_SHA1=y
+# CONFIG_SCTP_HMAC_MD5 is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
+CONFIG_STP=m
+CONFIG_GARP=m
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
 # CONFIG_DECNET is not set
+CONFIG_LLC=m
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
@@ -482,26 +570,47 @@ CONFIG_SCTP_HMAC_MD5=y
 # 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_HAMRADIO is not set
+CONFIG_HAMRADIO=y
+
+#
+# Packet Radio protocols
+#
+CONFIG_AX25=m
+CONFIG_AX25_DAMA_SLAVE=y
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+
+#
+# AX.25 network device drivers
+#
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+CONFIG_BAYCOM_SER_FDX=m
+CONFIG_BAYCOM_SER_HDX=m
+CONFIG_YAM=m
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 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
 
@@ -513,9 +622,12 @@ 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=m
+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
@@ -530,33 +642,53 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_RAM 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_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 CONFIG_SGI_IOC4=m
 # 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_SENSORS_TSL2550 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+CONFIG_EEPROM_LEGACY=y
+CONFIG_EEPROM_MAX6875=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_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_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 CONFIG_BLK_DEV_IDETAPE=y
-CONFIG_BLK_DEV_IDEFLOPPY=y
-# CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 CONFIG_IDE_PROC_FS=y
 
@@ -581,14 +713,13 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_AMD74XX is not set
 CONFIG_BLK_DEV_CMD64X=y
 # 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=m
 # CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
@@ -600,14 +731,12 @@ CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
 CONFIG_BLK_DEV_TC86C001=m
-# CONFIG_BLK_DEV_IDE_SWARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -625,10 +754,6 @@ CONFIG_BLK_DEV_SR=m
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_CHR_DEV_SCH=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -645,27 +770,36 @@ 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_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS 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_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_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_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
@@ -676,9 +810,15 @@ 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_PM8001 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=y
@@ -700,6 +840,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
@@ -715,6 +856,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -725,14 +867,16 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X 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=y
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -745,13 +889,16 @@ CONFIG_PATA_SIL680=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -774,6 +921,9 @@ CONFIG_PHYLIB=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
@@ -783,23 +933,33 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X 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 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_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
 # CONFIG_E1000E is not set
-# CONFIG_E1000E_ENABLED is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -811,29 +971,42 @@ CONFIG_SB1250_MAC=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # 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_MDIO=m
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
 CONFIG_CHELSIO_T3=m
+# 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=m
 # 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_QLCNIC 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_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP 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
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -856,6 +1029,7 @@ CONFIG_SLIP_MODE_SLIP6=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -873,6 +1047,7 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_PCIPS2 is not set
 # CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -893,8 +1068,6 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
-# CONFIG_SX is not set
-# CONFIG_RIO is not set
 # CONFIG_STALDRV is not set
 # CONFIG_NOZOMI is not set
 
@@ -911,7 +1084,9 @@ CONFIG_SERIAL_SB1250_DUART_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
@@ -923,89 +1098,99 @@ 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
 
 #
 # 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_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-CONFIG_I2C_SIBYTE=y
-# 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_VIA is not set
 # CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
-# CONFIG_I2C_PCA_PLATFORM is not set
 
 #
-# Miscellaneous I2C Chip support
+# I2C system bus drivers (mostly embedded / system-on-chip)
 #
-# CONFIG_DS1682 is not set
-CONFIG_EEPROM_LEGACY=y
-CONFIG_SENSORS_PCF8574=y
-# CONFIG_PCF8575 is not set
-CONFIG_SENSORS_PCF8591=y
-CONFIG_EEPROM_MAX6875=y
-# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+CONFIG_I2C_SIBYTE=y
+# CONFIG_I2C_STUB is not set
 CONFIG_I2C_DEBUG_CORE=y
 CONFIG_I2C_DEBUG_ALGO=y
 CONFIG_I2C_DEBUG_BUS=y
-CONFIG_I2C_DEBUG_CHIP=y
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS 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
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1016,10 +1201,6 @@ CONFIG_SSB_POSSIBLE=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -1030,9 +1211,18 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1040,41 +1230,66 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_INFINIBAND is not set
 CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS 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=m
 CONFIG_EXT2_FS_XATTR=y
-# CONFIG_EXT2_FS_POSIX_ACL is not set
-# CONFIG_EXT2_FS_SECURITY is not set
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
 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_JBD=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=m
+CONFIG_JBD2=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_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=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
 CONFIG_QFMT_V2=m
 CONFIG_QUOTACTL=y
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1103,15 +1318,13 @@ CONFIG_NTFS_RW=y
 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_HUGETLB_PAGE is not set
 CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_ECRYPT_FS is not set
@@ -1120,9 +1333,12 @@ CONFIG_CONFIGFS_FS=m
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS 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
@@ -1133,16 +1349,17 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1205,12 +1422,18 @@ 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_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 is not set
 # CONFIG_TIMER_STATS is not set
@@ -1219,23 +1442,53 @@ CONFIG_SCHED_DEBUG=y
 # 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_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_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
-# CONFIG_DEBUG_LIST is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_LIST=y
 # 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=y
 # 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_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=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_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_EARLY_PRINTK=y
 # CONFIG_CMDLINE_BOOL is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_SB1XXX_CORELIS is not set
@@ -1246,20 +1499,50 @@ CONFIG_DEBUG_MUTEXES=y
 #
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_NETWORK_XFRM=y
+# CONFIG_SECURITY_PATH is not set
+CONFIG_LSM_MMAP_MIN_ADDR=65536
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+# CONFIG_SECURITY_SMACK is not set
+# CONFIG_SECURITY_TOMOYO is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 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
+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=y
+# CONFIG_CRYPTO_PCRYPT is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
 # CONFIG_CRYPTO_TEST is not set
@@ -1276,7 +1559,7 @@ CONFIG_CRYPTO_SEQIV=m
 #
 CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_CTR=m
-# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
@@ -1287,14 +1570,20 @@ CONFIG_CRYPTO_XTS=m
 #
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
 
 #
 # Digest
 #
-# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_GHASH=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1325,25 +1614,36 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
-# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_ZLIB=m
+CONFIG_CRYPTO_LZO=m
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=m
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
+CONFIG_CRC7=m
 CONFIG_LIBCRC32C=m
 CONFIG_AUDIT_GENERIC=y
-CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
-CONFIG_PLIST=y
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
index 1dd74fbdc09b74930200d737087dbc3248dfb847..9252d9b50e592c6df959f24bf90facd247c34a43 100644 (file)
 #include <asm/siginfo.h>
 
 struct mips_abi {
-       int (* const setup_frame)(struct k_sigaction * ka,
+       int (* const setup_frame)(void *sig_return, struct k_sigaction *ka,
                                  struct pt_regs *regs, int signr,
                                  sigset_t *set);
-       int (* const setup_rt_frame)(struct k_sigaction * ka,
+       const unsigned long     signal_return_offset;
+       int (* const setup_rt_frame)(void *sig_return, struct k_sigaction *ka,
                               struct pt_regs *regs, int signr,
                               sigset_t *set, siginfo_t *info);
+       const unsigned long     rt_signal_return_offset;
        const unsigned long     restart;
 };
 
index 519197ede0898f2ce7bd0a3019fd4ac1f541d057..59dc0c7ef7334b2e28e4b508e03f84e8f2ea2aca 100644 (file)
@@ -29,7 +29,7 @@
  *
  * Atomically reads the value of @v.
  */
-#define atomic_read(v)         ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
 
 /*
  * atomic_set - set atomic variable
@@ -410,7 +410,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
  * @v: pointer of type atomic64_t
  *
  */
-#define atomic64_read(v)       ((v)->counter)
+#define atomic64_read(v)       (*(volatile long *)&(v)->counter)
 
 /*
  * atomic64_set - set atomic variable
index ed9aaaaf0749932495c93c11e1ff24838c66cdc6..2d28017e95d0756d1c1117847a5ff4811dffcea1 100644 (file)
@@ -16,7 +16,7 @@
 ({                                                                     \
        __typeof(*(m)) __ret;                                           \
                                                                        \
-       if (kernel_uses_llsc && R10000_LLSC_WAR) {                              \
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {                      \
                __asm__ __volatile__(                                   \
                "       .set    push                            \n"     \
                "       .set    noat                            \n"     \
index e53d7bed5cda3b2abcca04f411b6477d4254afee..ea77a42c5f8cb1bfc6ae03e131b60dde810f87bf 100644 (file)
@@ -310,6 +310,7 @@ do {                                                                        \
 
 #endif /* CONFIG_64BIT */
 
+struct pt_regs;
 struct task_struct;
 
 extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs);
@@ -367,4 +368,8 @@ extern const char *__elf_platform;
 #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
 #endif
 
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+struct linux_binprm;
+extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+                                      int uses_interp);
 #endif /* _ASM_ELF_H */
index aecada6f61178e8837b7f3ed0688e7e0029a1634..3b4092705567b7b4e65dd2680febc6a5a8e540cc 100644 (file)
@@ -41,7 +41,11 @@ struct mips_fpu_emulator_stats {
 DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
 
 #define MIPS_FPU_EMU_INC_STATS(M)                                      \
-       cpu_local_wrap(__local_inc(&__get_cpu_var(fpuemustats).M))
+do {                                                                   \
+       preempt_disable();                                              \
+       __local_inc(&__get_cpu_var(fpuemustats).M);                     \
+       preempt_enable();                                               \
+} while (0)
 
 #else
 #define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
index 032ca73f181bec27c0f7b741862ada66ec104342..48bb82372994c839f9e0f2d9be04b57bac38580c 100644 (file)
@@ -12,7 +12,7 @@
 #define PIT_CH0                        0x40
 #define PIT_CH2                        0x42
 
-extern spinlock_t i8253_lock;
+extern raw_spinlock_t i8253_lock;
 
 extern void setup_pit_timer(void);
 
index b12c4aca2cc93dfad1d44f89b4b84d96ed04773b..96a2391ad85be96a4d4d8e2c9b95ca35c9af6244 100644 (file)
@@ -85,6 +85,7 @@ enum bcm63xx_regs_set {
        RSET_TIMER,
        RSET_WDT,
        RSET_UART0,
+       RSET_UART1,
        RSET_GPIO,
        RSET_SPI,
        RSET_UDC0,
@@ -123,6 +124,7 @@ enum bcm63xx_regs_set {
 #define BCM_6338_TIMER_BASE            (0xfffe0200)
 #define BCM_6338_WDT_BASE              (0xfffe021c)
 #define BCM_6338_UART0_BASE            (0xfffe0300)
+#define BCM_6338_UART1_BASE            (0xdeadbeef)
 #define BCM_6338_GPIO_BASE             (0xfffe0400)
 #define BCM_6338_SPI_BASE              (0xfffe0c00)
 #define BCM_6338_UDC0_BASE             (0xdeadbeef)
@@ -153,6 +155,7 @@ enum bcm63xx_regs_set {
 #define BCM_6345_TIMER_BASE            (0xfffe0200)
 #define BCM_6345_WDT_BASE              (0xfffe021c)
 #define BCM_6345_UART0_BASE            (0xfffe0300)
+#define BCM_6345_UART1_BASE            (0xdeadbeef)
 #define BCM_6345_GPIO_BASE             (0xfffe0400)
 #define BCM_6345_SPI_BASE              (0xdeadbeef)
 #define BCM_6345_UDC0_BASE             (0xdeadbeef)
@@ -182,6 +185,7 @@ enum bcm63xx_regs_set {
 #define BCM_6348_TIMER_BASE            (0xfffe0200)
 #define BCM_6348_WDT_BASE              (0xfffe021c)
 #define BCM_6348_UART0_BASE            (0xfffe0300)
+#define BCM_6348_UART1_BASE            (0xdeadbeef)
 #define BCM_6348_GPIO_BASE             (0xfffe0400)
 #define BCM_6348_SPI_BASE              (0xfffe0c00)
 #define BCM_6348_UDC0_BASE             (0xfffe1000)
@@ -208,6 +212,7 @@ enum bcm63xx_regs_set {
 #define BCM_6358_TIMER_BASE            (0xfffe0040)
 #define BCM_6358_WDT_BASE              (0xfffe005c)
 #define BCM_6358_UART0_BASE            (0xfffe0100)
+#define BCM_6358_UART1_BASE            (0xfffe0120)
 #define BCM_6358_GPIO_BASE             (0xfffe0080)
 #define BCM_6358_SPI_BASE              (0xdeadbeef)
 #define BCM_6358_UDC0_BASE             (0xfffe0800)
@@ -246,6 +251,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
                return BCM_6338_WDT_BASE;
        case RSET_UART0:
                return BCM_6338_UART0_BASE;
+       case RSET_UART1:
+               return BCM_6338_UART1_BASE;
        case RSET_GPIO:
                return BCM_6338_GPIO_BASE;
        case RSET_SPI:
@@ -292,6 +299,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
                return BCM_6345_WDT_BASE;
        case RSET_UART0:
                return BCM_6345_UART0_BASE;
+       case RSET_UART1:
+               return BCM_6345_UART1_BASE;
        case RSET_GPIO:
                return BCM_6345_GPIO_BASE;
        case RSET_SPI:
@@ -338,6 +347,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
                return BCM_6348_WDT_BASE;
        case RSET_UART0:
                return BCM_6348_UART0_BASE;
+       case RSET_UART1:
+               return BCM_6348_UART1_BASE;
        case RSET_GPIO:
                return BCM_6348_GPIO_BASE;
        case RSET_SPI:
@@ -384,6 +395,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
                return BCM_6358_WDT_BASE;
        case RSET_UART0:
                return BCM_6358_UART0_BASE;
+       case RSET_UART1:
+               return BCM_6358_UART1_BASE;
        case RSET_GPIO:
                return BCM_6358_GPIO_BASE;
        case RSET_SPI:
@@ -429,6 +442,7 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
 enum bcm63xx_irq {
        IRQ_TIMER = 0,
        IRQ_UART0,
+       IRQ_UART1,
        IRQ_DSL,
        IRQ_ENET0,
        IRQ_ENET1,
@@ -510,6 +524,7 @@ enum bcm63xx_irq {
  */
 #define BCM_6358_TIMER_IRQ             (IRQ_INTERNAL_BASE + 0)
 #define BCM_6358_UART0_IRQ             (IRQ_INTERNAL_BASE + 2)
+#define BCM_6358_UART1_IRQ             (IRQ_INTERNAL_BASE + 3)
 #define BCM_6358_OHCI0_IRQ             (IRQ_INTERNAL_BASE + 5)
 #define BCM_6358_ENET1_IRQ             (IRQ_INTERNAL_BASE + 6)
 #define BCM_6358_ENET0_IRQ             (IRQ_INTERNAL_BASE + 8)
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h
new file mode 100644 (file)
index 0000000..23c705b
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef BCM63XX_DEV_UART_H_
+#define BCM63XX_DEV_UART_H_
+
+int bcm63xx_uart_register(unsigned int id);
+
+#endif /* BCM63XX_DEV_UART_H_ */
index 76a0b7216af576ea868e3c3f245c7329a5b2a1b6..43d4da0b1e9fe5f7ce0795b41a259a36b861ad60 100644 (file)
@@ -10,6 +10,10 @@ static inline unsigned long bcm63xx_gpio_count(void)
        switch (bcm63xx_get_cpu_id()) {
        case BCM6358_CPU_ID:
                return 40;
+       case BCM6338_CPU_ID:
+               return 8;
+       case BCM6345_CPU_ID:
+               return 16;
        case BCM6348_CPU_ID:
        default:
                return 37;
index 6479090a41066f56d580387764599caede1b9714..474daaa534975b921b2f5321ddae57117832a226 100644 (file)
@@ -45,6 +45,8 @@ struct board_info {
        unsigned int    has_ohci0:1;
        unsigned int    has_ehci0:1;
        unsigned int    has_dsp:1;
+       unsigned int    has_uart0:1;
+       unsigned int    has_uart1:1;
 
        /* ethernet config */
        struct bcm63xx_enet_platform_data enet0;
index 71742bac940d5ad8db0601ac6b60539033d95517..f453c01d06723885b1875457c4a8991628a5549e 100644 (file)
@@ -24,7 +24,7 @@
 #define cpu_has_smartmips              0
 #define cpu_has_vtag_icache            0
 
-#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCMCPU_IS_6348) || defined(CONFIG_CPU_IS_6338) || defined(CONFIG_CPU_IS_BCM6345))
+#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCM63XX_CPU_6348) || defined(CONFIG_BCM63XX_CPU_6345) || defined(CONFIG_BCM63XX_CPU_6338))
 #define cpu_has_dc_aliases             0
 #endif
 
index 1cf7b1401ee43259ed8947e60ccb1b8d91605fe8..fcdbe3a4ce1f4f42de0887506cf1c3cba584e04d 100644 (file)
@@ -307,7 +307,7 @@ extern unsigned long _loongson_addrwincfg_base;
  */
 #define LOONGSON_ADDRWIN_CFG(s, d, w, src, dst, size) do {\
        s##_WIN##w##_BASE = (src); \
-       s##_WIN##w##_MMAP = (src) | ADDRWIN_MAP_DST_##d; \
+       s##_WIN##w##_MMAP = (dst) | ADDRWIN_MAP_DST_##d; \
        s##_WIN##w##_MASK = ~(size-1); \
 } while (0)
 
index 7950ef4f032c218a2382be9560c2138b2c05d8a9..743385d7b5f22b36bcea1f0aa740ad923af41ca4 100644 (file)
 #if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \
     defined(CONFIG_SB1_PASS_2_WORKAROUNDS)
 
-#define BCM1250_M3_WAR 1
+#ifndef __ASSEMBLY__
+extern int sb1250_m3_workaround_needed(void);
+#endif
+
+#define BCM1250_M3_WAR sb1250_m3_workaround_needed()
 #define SIBYTE_1956_WAR        1
 
 #else
index 49382d5e891a35a98b09be21abcdb13366b2cca9..c6e3c93ce7c7a5aad8267d88f8c0089301d1e239 100644 (file)
 #define FPU_CSR_COND6   0x40000000      /* $fcc6 */
 #define FPU_CSR_COND7   0x80000000      /* $fcc7 */
 
+/*
+ * Bits 18 - 20 of the FPU Status Register will be read as 0,
+ * and should be written as zero.
+ */
+#define FPU_CSR_RSVD   0x001c0000
+
 /*
  * X the exception cause indicator
  * E the exception enable
 #define FPU_CSR_UDF_S   0x00000008
 #define FPU_CSR_INE_S   0x00000004
 
-/* rounding mode */
+/* Bits 0 and 1 of FPU Status Register specify the rounding mode */
+#define FPU_CSR_RM     0x00000003
 #define FPU_CSR_RN      0x0     /* nearest */
 #define FPU_CSR_RZ      0x1     /* towards zero */
 #define FPU_CSR_RU      0x2     /* towards +Infinity */
index 4063edd79623c89ba9eb2e5b4c8f0d69e4063191..c436138945a84dca9f1f311e54a801090c396853 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef __ASM_MMU_H
 #define __ASM_MMU_H
 
-typedef unsigned long mm_context_t[NR_CPUS];
+typedef struct {
+       unsigned long asid[NR_CPUS];
+       void *vdso;
+} mm_context_t;
 
 #endif /* __ASM_MMU_H */
index 145bb81ccaa5094efec3806568f7fbb1087031f1..d9592733a7ba4759dbebc01f82efaef4a783e1e5 100644 (file)
@@ -104,7 +104,7 @@ extern unsigned long smtc_asid_mask;
 
 #endif
 
-#define cpu_context(cpu, mm)   ((mm)->context[cpu])
+#define cpu_context(cpu, mm)   ((mm)->context.asid[cpu])
 #define cpu_asid(cpu, mm)      (cpu_context((cpu), (mm)) & ASID_MASK)
 #define asid_cache(cpu)                (cpu_data[cpu].asid_cache)
 
index ac32572430f42c3e359531b6079968196969195b..a16beafcea91dd091f0b491ea572b5902e272a3d 100644 (file)
@@ -188,8 +188,10 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
                                 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
-#define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + UNCAC_BASE)
-#define CAC_ADDR(addr)         ((addr) - UNCAC_BASE + PAGE_OFFSET)
+#define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + UNCAC_BASE +    \
+                                                               PHYS_OFFSET)
+#define CAC_ADDR(addr)         ((addr) - UNCAC_BASE + PAGE_OFFSET -    \
+                                                               PHYS_OFFSET)
 
 #include <asm-generic/memory_model.h>
 #include <asm-generic/getorder.h>
index 26dc69d792a613d71ea693db1b45944fd1089d0c..1be4b0fa30da7dc30d269c8057acb1f659d650c9 100644 (file)
 #endif
 #define FIRST_USER_ADDRESS     0UL
 
-#define VMALLOC_START          MAP_BASE
+/*
+ * TLB refill handlers also map the vmalloc area into xuseg.  Avoid
+ * the first couple of pages so NULL pointer dereferences will still
+ * reliably trap.
+ */
+#define VMALLOC_START          (MAP_BASE + (2 * PAGE_SIZE))
 #define VMALLOC_END    \
-       (VMALLOC_START + \
+       (MAP_BASE + \
         min(PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, \
             (1UL << cpu_vmbits)) - (1UL << 32))
 
index 087a8884ef06e261e46f3480040cd9667066bdd8..ab387910009a3d1fd100f79aa94560552680750a 100644 (file)
@@ -33,13 +33,19 @@ extern void (*cpu_wait)(void);
 
 extern unsigned int vced_count, vcei_count;
 
+/*
+ * A special page (the vdso) is mapped into all processes at the very
+ * top of the virtual memory space.
+ */
+#define SPECIAL_PAGES_SIZE PAGE_SIZE
+
 #ifdef CONFIG_32BIT
 /*
  * User space process size: 2GB. This is hardcoded into a few places,
  * so don't change it unless you know what you are doing.
  */
 #define TASK_SIZE      0x7fff8000UL
-#define STACK_TOP      TASK_SIZE
+#define STACK_TOP      ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
 
 /*
  * This decides where the kernel will search for a free chunk of vm
@@ -59,7 +65,8 @@ extern unsigned int vced_count, vcei_count;
 #define TASK_SIZE32    0x7fff8000UL
 #define TASK_SIZE      0x10000000000UL
 #define STACK_TOP      \
-      (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
+       (((test_thread_flag(TIF_32BIT_ADDR) ?                           \
+          TASK_SIZE32 : TASK_SIZE) & PAGE_MASK) - SPECIAL_PAGES_SIZE)
 
 /*
  * This decides where the kernel will search for a free chunk of vm
index ce47118e52b70e7265dab3caa00c84f2542cfafb..cdc6a46efd988a0b5d09bf134232ac2bf8007764 100644 (file)
@@ -142,9 +142,9 @@ extern int ptrace_set_watch_regs(struct task_struct *child,
 
 extern asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit);
 
-extern NORET_TYPE void die(const char *, const struct pt_regs *) ATTRIB_NORET;
+extern NORET_TYPE void die(const char *, struct pt_regs *) ATTRIB_NORET;
 
-static inline void die_if_kernel(const char *str, const struct pt_regs *regs)
+static inline void die_if_kernel(const char *str, struct pt_regs *regs)
 {
        if (unlikely(!user_mode(regs)))
                die(str, regs);
index 3b6da3330e321772358c9791914e3d472290d2f9..58730c5ce4bfd6ac47b4e62fd0ea4d4c164db60d 100644 (file)
                .endm
 #else
                .macro  get_saved_sp    /* Uniprocessor variation */
+#ifdef CONFIG_CPU_JUMP_WORKAROUNDS
+               /*
+                * Clear BTB (branch target buffer), forbid RAS (return address
+                * stack) to workaround the Out-of-order Issue in Loongson2F
+                * via its diagnostic register.
+                */
+               move    k0, ra
+               jal     1f
+                nop
+1:             jal     1f
+                nop
+1:             jal     1f
+                nop
+1:             jal     1f
+                nop
+1:             move    ra, k0
+               li      k0, 3
+               mtc0    k0, $22
+#endif /* CONFIG_CPU_LOONGSON2F */
 #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
                lui     k1, %hi(kernelsp)
 #else
index b99bd07e199b541fe17ff8489480aa20125b0ac2..697e40c06497bd62d8627b6171f43faf22ccfac8 100644 (file)
@@ -84,6 +84,7 @@ Ip_u2s3u1(_lw);
 Ip_u1u2u3(_mfc0);
 Ip_u1u2u3(_mtc0);
 Ip_u2u1u3(_ori);
+Ip_u3u1u2(_or);
 Ip_u2s3u1(_pref);
 Ip_0(_rfe);
 Ip_u2s3u1(_sc);
@@ -102,6 +103,7 @@ Ip_0(_tlbwr);
 Ip_u3u1u2(_xor);
 Ip_u2u1u3(_xori);
 Ip_u2u1msbu3(_dins);
+Ip_u1(_syscall);
 
 /* Handle labels. */
 struct uasm_label {
@@ -165,6 +167,24 @@ static inline void __cpuinit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
 #define uasm_i_ssnop(buf) uasm_i_sll(buf, 0, 0, 1)
 #define uasm_i_ehb(buf) uasm_i_sll(buf, 0, 0, 3)
 
+static inline void uasm_i_dsrl_safe(u32 **p, unsigned int a1,
+                                   unsigned int a2, unsigned int a3)
+{
+       if (a3 < 32)
+               uasm_i_dsrl(p, a1, a2, a3);
+       else
+               uasm_i_dsrl32(p, a1, a2, a3 - 32);
+}
+
+static inline void uasm_i_dsll_safe(u32 **p, unsigned int a1,
+                                   unsigned int a2, unsigned int a3)
+{
+       if (a3 < 32)
+               uasm_i_dsll(p, a1, a2, a3);
+       else
+               uasm_i_dsll32(p, a1, a2, a3 - 32);
+}
+
 /* Handle relocations. */
 struct uasm_reloc {
        u32 *addr;
diff --git a/arch/mips/include/asm/vdso.h b/arch/mips/include/asm/vdso.h
new file mode 100644 (file)
index 0000000..cca56aa
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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) 2009 Cavium Networks
+ */
+
+#ifndef __ASM_VDSO_H
+#define __ASM_VDSO_H
+
+#include <linux/types.h>
+
+
+#ifdef CONFIG_32BIT
+struct mips_vdso {
+       u32 signal_trampoline[2];
+       u32 rt_signal_trampoline[2];
+};
+#else  /* !CONFIG_32BIT */
+struct mips_vdso {
+       u32 o32_signal_trampoline[2];
+       u32 o32_rt_signal_trampoline[2];
+       u32 rt_signal_trampoline[2];
+       u32 n32_rt_signal_trampoline[2];
+};
+#endif /* CONFIG_32BIT */
+
+#endif /* __ASM_VDSO_H */
index 0d64d0f464185c0c9c383fcad2e1d30416afc854..9ce9f64cb76fa8fce272100f00373694e8f6d4f7 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/mm.h>
 #include <linux/bootmem.h>
 #include <linux/spinlock.h>
+#include <linux/gfp.h>
 #include <asm/mipsregs.h>
 #include <asm/jazz.h>
 #include <asm/io.h>
index 7043f6b9ff3ced77cefbf762b5253ffc1266d8aa..0d0f054a02f4bfc309ad3b7290b83a90dae26cfd 100644 (file)
@@ -76,15 +76,9 @@ void __init plat_mem_setup(void)
 
 #ifdef CONFIG_VT
        screen_info = (struct screen_info) {
-               0, 0,           /* orig-x, orig-y */
-               0,              /* unused */
-               0,              /* orig_video_page */
-               0,              /* orig_video_mode */
-               160,            /* orig_video_cols */
-               0, 0, 0,        /* unused, ega_bx, unused */
-               64,             /* orig_video_lines */
-               0,              /* orig_video_isVGA */
-               16              /* orig_video_points */
+               .orig_video_cols        = 160,
+               .orig_video_lines       = 64,
+               .orig_video_points      = 16,
        };
 #endif
 
index ef20957ca14b7af284f604fe321317e5ecc09157..7a6ac501cbb5abc07cb4f78f43c2e806200ce023 100644 (file)
@@ -6,7 +6,7 @@ extra-y         := head.o init_task.o vmlinux.lds
 
 obj-y          += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
                   ptrace.o reset.o setup.o signal.o syscall.o \
-                  time.o topology.o traps.o unaligned.o watch.o
+                  time.o topology.o traps.o unaligned.o watch.o vdso.o
 
 ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_ftrace.o = -pg
index d7ca256e33ef9615547686c6a1e9ab24ae057311..cefc6e259bafd3acd986588af2c87a6e3ce0f32d 100644 (file)
@@ -164,3 +164,7 @@ void loongson2_cpu_wait(void)
        spin_unlock_irqrestore(&loongson2_wait_lock, flags);
 }
 EXPORT_SYMBOL_GPL(loongson2_cpu_wait);
+
+MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
+MODULE_DESCRIPTION("cpufreq driver for Loongson 2F");
+MODULE_LICENSE("GPL");
index ed5c441615e471cf4b4c1888bcce3eec9c84e6fa..94794062a1777814c03428b27576796fe3f2a7a7 100644 (file)
@@ -15,7 +15,7 @@
 #include <asm/io.h>
 #include <asm/time.h>
 
-DEFINE_SPINLOCK(i8253_lock);
+DEFINE_RAW_SPINLOCK(i8253_lock);
 EXPORT_SYMBOL(i8253_lock);
 
 /*
@@ -26,7 +26,7 @@ EXPORT_SYMBOL(i8253_lock);
 static void init_pit_timer(enum clock_event_mode mode,
                           struct clock_event_device *evt)
 {
-       spin_lock(&i8253_lock);
+       raw_spin_lock(&i8253_lock);
 
        switch(mode) {
        case CLOCK_EVT_MODE_PERIODIC:
@@ -55,7 +55,7 @@ static void init_pit_timer(enum clock_event_mode mode,
                /* Nothing to do here */
                break;
        }
-       spin_unlock(&i8253_lock);
+       raw_spin_unlock(&i8253_lock);
 }
 
 /*
@@ -65,10 +65,10 @@ static void init_pit_timer(enum clock_event_mode mode,
  */
 static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
 {
-       spin_lock(&i8253_lock);
+       raw_spin_lock(&i8253_lock);
        outb_p(delta & 0xff , PIT_CH0); /* LSB */
        outb(delta >> 8 , PIT_CH0);     /* MSB */
-       spin_unlock(&i8253_lock);
+       raw_spin_unlock(&i8253_lock);
 
        return 0;
 }
@@ -137,7 +137,7 @@ static cycle_t pit_read(struct clocksource *cs)
        static int old_count;
        static u32 old_jifs;
 
-       spin_lock_irqsave(&i8253_lock, flags);
+       raw_spin_lock_irqsave(&i8253_lock, flags);
        /*
         * Although our caller may have the read side of xtime_lock,
         * this is now a seqlock, and we are cheating in this routine
@@ -183,7 +183,7 @@ static cycle_t pit_read(struct clocksource *cs)
        old_count = count;
        old_jifs = jifs;
 
-       spin_unlock_irqrestore(&i8253_lock, flags);
+       raw_spin_unlock_irqrestore(&i8253_lock, flags);
 
        count = (LATCH - 1) - count;
 
index 981f86c26168ca9b838fecc8e627663a04e82017..c6345f579a8a4ea13d00251c4d47272b4afffa1d 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/kernel_stat.h>
 #include <linux/module.h>
 #include <linux/proc_fs.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/random.h>
 #include <linux/sched.h>
index a39d0597a37583df6e24d0e09f6ce63f7a96617a..c2dab140dc98fb1588259063699c7ba09b6f8ed7 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/time.h>
 #include <linux/times.h>
 #include <linux/poll.h>
-#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/filter.h>
 #include <linux/shm.h>
@@ -34,6 +33,7 @@
 #include <linux/compat.h>
 #include <linux/vfs.h>
 #include <linux/ipc.h>
+#include <linux/slab.h>
 
 #include <net/sock.h>
 #include <net/scm.h>
index f3d73e1831c1567ccb674429eb83492feb2942e1..99960940d4a410bba1e9842a7049161e74d04d25 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/mman.h>
 #include <linux/personality.h>
 #include <linux/sys.h>
@@ -64,8 +63,13 @@ void __noreturn cpu_idle(void)
 
                        smtc_idle_loop_hook();
 #endif
-                       if (cpu_wait)
+
+                       if (cpu_wait) {
+                               /* Don't trace irqs off for idle */
+                               stop_critical_timings();
                                (*cpu_wait)();
+                               start_critical_timings();
+                       }
                }
 #ifdef CONFIG_HOTPLUG_CPU
                if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) &&
index dcaed1bbbfe5c7e099768a17c9aad126c8c80429..26f9b9ab19cc66b020486be6cef3e21cfe347126 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
-#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/vmalloc.h>
 #include <linux/elf.h>
index 44337ba03717a573119659fcc94fec11c9564b61..a5297e2a353aede2279664446611de8100bf1f98 100644 (file)
@@ -385,7 +385,7 @@ EXPORT(sysn32_call_table)
        PTR     sys_fchmodat
        PTR     sys_faccessat
        PTR     compat_sys_pselect6
-       PTR     sys_ppoll                       /* 6265 */
+       PTR     compat_sys_ppoll                /* 6265 */
        PTR     sys_unshare
        PTR     sys_splice
        PTR     sys_sync_file_range
index 6c8e8c4246f754439602790815f88eaa1bb6280a..10263b405981f0eb4604f1d38bd3887e10f1c129 100644 (file)
  */
 extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
                                 size_t frame_size);
-/*
- * install trampoline code to get back from the sig handler
- */
-extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall);
-
 /* Check and clear pending FPU exceptions in saved CSR */
 extern int fpcsr_pending(unsigned int __user *fpcsr);
 
index d0c68b5d717bce3fde6979d2eeee5e5ac6ea7094..2099d5a4c4b78224f85ee5f9b175907be3d8f15c 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/ucontext.h>
 #include <asm/cpu-features.h>
 #include <asm/war.h>
+#include <asm/vdso.h>
 
 #include "signal-common.h"
 
@@ -44,47 +45,20 @@ extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
 extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
 extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);
 
-/*
- * Horribly complicated - with the bloody RM9000 workarounds enabled
- * the signal trampolines is moving to the end of the structure so we can
- * increase the alignment without breaking software compatibility.
- */
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
 struct sigframe {
        u32 sf_ass[4];          /* argument save space for o32 */
-       u32 sf_code[2];         /* signal trampoline */
+       u32 sf_pad[2];          /* Was: signal trampoline */
        struct sigcontext sf_sc;
        sigset_t sf_mask;
 };
 
 struct rt_sigframe {
        u32 rs_ass[4];          /* argument save space for o32 */
-       u32 rs_code[2];         /* signal trampoline */
+       u32 rs_pad[2];          /* Was: signal trampoline */
        struct siginfo rs_info;
        struct ucontext rs_uc;
 };
 
-#else
-
-struct sigframe {
-       u32 sf_ass[4];                  /* argument save space for o32 */
-       u32 sf_pad[2];
-       struct sigcontext sf_sc;        /* hw context */
-       sigset_t sf_mask;
-       u32 sf_code[8] ____cacheline_aligned;   /* signal trampoline */
-};
-
-struct rt_sigframe {
-       u32 rs_ass[4];                  /* argument save space for o32 */
-       u32 rs_pad[2];
-       struct siginfo rs_info;
-       struct ucontext rs_uc;
-       u32 rs_code[8] ____cacheline_aligned;   /* signal trampoline */
-};
-
-#endif
-
 /*
  * Helper routines
  */
@@ -266,32 +240,6 @@ void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
        return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
 }
 
-int install_sigtramp(unsigned int __user *tramp, unsigned int syscall)
-{
-       int err;
-
-       /*
-        * Set up the return code ...
-        *
-        *         li      v0, __NR__foo_sigreturn
-        *         syscall
-        */
-
-       err = __put_user(0x24020000 + syscall, tramp + 0);
-       err |= __put_user(0x0000000c         , tramp + 1);
-       if (ICACHE_REFILLS_WORKAROUND_WAR) {
-               err |= __put_user(0, tramp + 2);
-               err |= __put_user(0, tramp + 3);
-               err |= __put_user(0, tramp + 4);
-               err |= __put_user(0, tramp + 5);
-               err |= __put_user(0, tramp + 6);
-               err |= __put_user(0, tramp + 7);
-       }
-       flush_cache_sigtramp((unsigned long) tramp);
-
-       return err;
-}
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
@@ -484,8 +432,8 @@ badframe:
 }
 
 #ifdef CONFIG_TRAD_SIGNALS
-static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
-       int signr, sigset_t *set)
+static int setup_frame(void *sig_return, struct k_sigaction *ka,
+                      struct pt_regs *regs, int signr, sigset_t *set)
 {
        struct sigframe __user *frame;
        int err = 0;
@@ -494,8 +442,6 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                goto give_sigsegv;
 
-       err |= install_sigtramp(frame->sf_code, __NR_sigreturn);
-
        err |= setup_sigcontext(regs, &frame->sf_sc);
        err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
        if (err)
@@ -515,7 +461,7 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
        regs->regs[ 5] = 0;
        regs->regs[ 6] = (unsigned long) &frame->sf_sc;
        regs->regs[29] = (unsigned long) frame;
-       regs->regs[31] = (unsigned long) frame->sf_code;
+       regs->regs[31] = (unsigned long) sig_return;
        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -529,8 +475,9 @@ give_sigsegv:
 }
 #endif
 
-static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
-       int signr, sigset_t *set, siginfo_t *info)
+static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
+                         struct pt_regs *regs, int signr, sigset_t *set,
+                         siginfo_t *info)
 {
        struct rt_sigframe __user *frame;
        int err = 0;
@@ -539,8 +486,6 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                goto give_sigsegv;
 
-       err |= install_sigtramp(frame->rs_code, __NR_rt_sigreturn);
-
        /* Create siginfo.  */
        err |= copy_siginfo_to_user(&frame->rs_info, info);
 
@@ -573,7 +518,7 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
        regs->regs[ 5] = (unsigned long) &frame->rs_info;
        regs->regs[ 6] = (unsigned long) &frame->rs_uc;
        regs->regs[29] = (unsigned long) frame;
-       regs->regs[31] = (unsigned long) frame->rs_code;
+       regs->regs[31] = (unsigned long) sig_return;
        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -590,8 +535,11 @@ give_sigsegv:
 struct mips_abi mips_abi = {
 #ifdef CONFIG_TRAD_SIGNALS
        .setup_frame    = setup_frame,
+       .signal_return_offset = offsetof(struct mips_vdso, signal_trampoline),
 #endif
        .setup_rt_frame = setup_rt_frame,
+       .rt_signal_return_offset =
+               offsetof(struct mips_vdso, rt_signal_trampoline),
        .restart        = __NR_restart_syscall
 };
 
@@ -599,6 +547,8 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
        struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
 {
        int ret;
+       struct mips_abi *abi = current->thread.abi;
+       void *vdso = current->mm->context.vdso;
 
        switch(regs->regs[0]) {
        case ERESTART_RESTARTBLOCK:
@@ -619,9 +569,11 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
        regs->regs[0] = 0;              /* Don't deal with this again.  */
 
        if (sig_uses_siginfo(ka))
-               ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
+               ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
+                                         ka, regs, sig, oldset, info);
        else
-               ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
+               ret = abi->setup_frame(vdso + abi->signal_return_offset,
+                                      ka, regs, sig, oldset);
 
        spin_lock_irq(&current->sighand->siglock);
        sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
index 03abaf048f09b3257ad7240378a53e6ddcc5588d..a0ed0e052b2e8f630c34900d5b6e5958f945bbcc 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/system.h>
 #include <asm/fpu.h>
 #include <asm/war.h>
+#include <asm/vdso.h>
 
 #include "signal-common.h"
 
@@ -47,8 +48,6 @@ extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
-#define __NR_O32_sigreturn             4119
-#define __NR_O32_rt_sigreturn          4193
 #define __NR_O32_restart_syscall        4253
 
 /* 32-bit compatibility types */
@@ -77,47 +76,20 @@ struct ucontext32 {
        compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 };
 
-/*
- * Horribly complicated - with the bloody RM9000 workarounds enabled
- * the signal trampolines is moving to the end of the structure so we can
- * increase the alignment without breaking software compatibility.
- */
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
 struct sigframe32 {
        u32 sf_ass[4];          /* argument save space for o32 */
-       u32 sf_code[2];         /* signal trampoline */
+       u32 sf_pad[2];          /* Was: signal trampoline */
        struct sigcontext32 sf_sc;
        compat_sigset_t sf_mask;
 };
 
 struct rt_sigframe32 {
        u32 rs_ass[4];                  /* argument save space for o32 */
-       u32 rs_code[2];                 /* signal trampoline */
+       u32 rs_pad[2];                  /* Was: signal trampoline */
        compat_siginfo_t rs_info;
        struct ucontext32 rs_uc;
 };
 
-#else  /* ICACHE_REFILLS_WORKAROUND_WAR */
-
-struct sigframe32 {
-       u32 sf_ass[4];                  /* argument save space for o32 */
-       u32 sf_pad[2];
-       struct sigcontext32 sf_sc;      /* hw context */
-       compat_sigset_t sf_mask;
-       u32 sf_code[8] ____cacheline_aligned;   /* signal trampoline */
-};
-
-struct rt_sigframe32 {
-       u32 rs_ass[4];                  /* argument save space for o32 */
-       u32 rs_pad[2];
-       compat_siginfo_t rs_info;
-       struct ucontext32 rs_uc;
-       u32 rs_code[8] __attribute__((aligned(32)));    /* signal trampoline */
-};
-
-#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
-
 /*
  * sigcontext handlers
  */
@@ -598,8 +570,8 @@ badframe:
        force_sig(SIGSEGV, current);
 }
 
-static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
-       int signr, sigset_t *set)
+static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
+                         struct pt_regs *regs, int signr, sigset_t *set)
 {
        struct sigframe32 __user *frame;
        int err = 0;
@@ -608,8 +580,6 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                goto give_sigsegv;
 
-       err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
-
        err |= setup_sigcontext32(regs, &frame->sf_sc);
        err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
 
@@ -630,7 +600,7 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        regs->regs[ 5] = 0;
        regs->regs[ 6] = (unsigned long) &frame->sf_sc;
        regs->regs[29] = (unsigned long) frame;
-       regs->regs[31] = (unsigned long) frame->sf_code;
+       regs->regs[31] = (unsigned long) sig_return;
        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -644,8 +614,9 @@ give_sigsegv:
        return -EFAULT;
 }
 
-static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
-       int signr, sigset_t *set, siginfo_t *info)
+static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
+                            struct pt_regs *regs, int signr, sigset_t *set,
+                            siginfo_t *info)
 {
        struct rt_sigframe32 __user *frame;
        int err = 0;
@@ -655,8 +626,6 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                goto give_sigsegv;
 
-       err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);
-
        /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
        err |= copy_siginfo_to_user32(&frame->rs_info, info);
 
@@ -690,7 +659,7 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        regs->regs[ 5] = (unsigned long) &frame->rs_info;
        regs->regs[ 6] = (unsigned long) &frame->rs_uc;
        regs->regs[29] = (unsigned long) frame;
-       regs->regs[31] = (unsigned long) frame->rs_code;
+       regs->regs[31] = (unsigned long) sig_return;
        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -709,7 +678,11 @@ give_sigsegv:
  */
 struct mips_abi mips_abi_32 = {
        .setup_frame    = setup_frame_32,
+       .signal_return_offset =
+               offsetof(struct mips_vdso, o32_signal_trampoline),
        .setup_rt_frame = setup_rt_frame_32,
+       .rt_signal_return_offset =
+               offsetof(struct mips_vdso, o32_rt_signal_trampoline),
        .restart        = __NR_O32_restart_syscall
 };
 
index bb277e82d421196033eeedb53e4c2aa0850ca4e8..2c5df818c65ae0395768264f1192059b792aaf02 100644 (file)
 #include <asm/fpu.h>
 #include <asm/cpu-features.h>
 #include <asm/war.h>
+#include <asm/vdso.h>
 
 #include "signal-common.h"
 
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
-#define __NR_N32_rt_sigreturn          6211
 #define __NR_N32_restart_syscall       6214
 
 extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
@@ -67,27 +67,13 @@ struct ucontextn32 {
        compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 };
 
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
-struct rt_sigframe_n32 {
-       u32 rs_ass[4];                  /* argument save space for o32 */
-       u32 rs_code[2];                 /* signal trampoline */
-       struct compat_siginfo rs_info;
-       struct ucontextn32 rs_uc;
-};
-
-#else  /* ICACHE_REFILLS_WORKAROUND_WAR */
-
 struct rt_sigframe_n32 {
        u32 rs_ass[4];                  /* argument save space for o32 */
-       u32 rs_pad[2];
+       u32 rs_pad[2];                  /* Was: signal trampoline */
        struct compat_siginfo rs_info;
        struct ucontextn32 rs_uc;
-       u32 rs_code[8] ____cacheline_aligned;           /* signal trampoline */
 };
 
-#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
-
 extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
 
 asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
@@ -173,7 +159,7 @@ badframe:
        force_sig(SIGSEGV, current);
 }
 
-static int setup_rt_frame_n32(struct k_sigaction * ka,
+static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
        struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
 {
        struct rt_sigframe_n32 __user *frame;
@@ -184,8 +170,6 @@ static int setup_rt_frame_n32(struct k_sigaction * ka,
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                goto give_sigsegv;
 
-       install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn);
-
        /* Create siginfo.  */
        err |= copy_siginfo_to_user32(&frame->rs_info, info);
 
@@ -219,7 +203,7 @@ static int setup_rt_frame_n32(struct k_sigaction * ka,
        regs->regs[ 5] = (unsigned long) &frame->rs_info;
        regs->regs[ 6] = (unsigned long) &frame->rs_uc;
        regs->regs[29] = (unsigned long) frame;
-       regs->regs[31] = (unsigned long) frame->rs_code;
+       regs->regs[31] = (unsigned long) sig_return;
        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -235,5 +219,7 @@ give_sigsegv:
 
 struct mips_abi mips_abi_n32 = {
        .setup_rt_frame = setup_rt_frame_n32,
+       .rt_signal_return_offset =
+               offsetof(struct mips_vdso, n32_rt_signal_trampoline),
        .restart        = __NR_N32_restart_syscall
 };
index 23499b5bd9c3d42f79352d5dd75243a8b49f96dd..a95dea5459c4d5034514ae68a8134d3bb2eb578d 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/module.h>
 #include <linux/ftrace.h>
+#include <linux/slab.h>
 
 #include <asm/cpu.h>
 #include <asm/processor.h>
@@ -181,7 +182,7 @@ static int vpemask[2][8] = {
        {0, 0, 0, 0, 0, 0, 0, 1}
 };
 int tcnoprog[NR_CPUS];
-static atomic_t idle_hook_initialized = {0};
+static atomic_t idle_hook_initialized = ATOMIC_INIT(0);
 static int clock_hang_reported[NR_CPUS];
 
 #endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
index e96b1c30c7aac6c708d4b55aa5a09f2fb7af31f9..dd81b0f875183d887e97996ee14f961f79055118 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/string.h>
 #include <linux/syscalls.h>
 #include <linux/file.h>
-#include <linux/slab.h>
 #include <linux/utsname.h>
 #include <linux/unistd.h>
 #include <linux/sem.h>
@@ -29,6 +28,7 @@
 #include <linux/module.h>
 #include <linux/ipc.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 
 #include <asm/asm.h>
 #include <asm/branch.h>
@@ -79,7 +79,11 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
        int do_color_align;
        unsigned long task_size;
 
-       task_size = STACK_TOP;
+#ifdef CONFIG_32BIT
+       task_size = TASK_SIZE;
+#else /* Must be CONFIG_64BIT*/
+       task_size = test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE;
+#endif
 
        if (len > task_size)
                return -ENOMEM;
index 4e00f9bc23ee99e333685f176800275941577a3c..d612c6dcb7461c18c93a93f73c584d952eeca631 100644 (file)
@@ -352,9 +352,10 @@ void show_registers(const struct pt_regs *regs)
 
 static DEFINE_SPINLOCK(die_lock);
 
-void __noreturn die(const char * str, const struct pt_regs * regs)
+void __noreturn die(const char * str, struct pt_regs * regs)
 {
        static int die_counter;
+       int sig = SIGSEGV;
 #ifdef CONFIG_MIPS_MT_SMTC
        unsigned long dvpret = dvpe();
 #endif /* CONFIG_MIPS_MT_SMTC */
@@ -365,6 +366,10 @@ void __noreturn die(const char * str, const struct pt_regs * regs)
 #ifdef CONFIG_MIPS_MT_SMTC
        mips_mt_regdump(dvpret);
 #endif /* CONFIG_MIPS_MT_SMTC */
+
+       if (notify_die(DIE_OOPS, str, regs, 0, current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
+               sig = 0;
+
        printk("%s[#%d]:\n", str, ++die_counter);
        show_registers(regs);
        add_taint(TAINT_DIE);
@@ -379,7 +384,7 @@ void __noreturn die(const char * str, const struct pt_regs * regs)
                panic("Fatal exception");
        }
 
-       do_exit(SIGSEGV);
+       do_exit(sig);
 }
 
 extern struct exception_table_entry __start___dbe_table[];
@@ -1557,12 +1562,7 @@ static char panic_null_cerr[] __cpuinitdata =
 void __cpuinit set_uncached_handler(unsigned long offset, void *addr,
        unsigned long size)
 {
-#ifdef CONFIG_32BIT
-       unsigned long uncached_ebase = KSEG1ADDR(ebase);
-#endif
-#ifdef CONFIG_64BIT
-       unsigned long uncached_ebase = TO_UNCAC(ebase);
-#endif
+       unsigned long uncached_ebase = CKSEG1ADDR(ebase);
 
        if (!addr)
                panic(panic_null_cerr);
@@ -1599,7 +1599,7 @@ void __init trap_init(void)
                ebase = (unsigned long)
                        __alloc_bootmem(size, 1 << fls(size), 0);
        } else {
-               ebase = CAC_BASE;
+               ebase = CKSEG0;
                if (cpu_has_mips_r2)
                        ebase += (read_c0_ebase() & 0x3ffff000);
        }
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
new file mode 100644 (file)
index 0000000..b773c11
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * 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) 2009, 2010 Cavium Networks, Inc.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/binfmts.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/unistd.h>
+
+#include <asm/vdso.h>
+#include <asm/uasm.h>
+
+/*
+ * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
+ */
+#define __NR_O32_sigreturn             4119
+#define __NR_O32_rt_sigreturn          4193
+#define __NR_N32_rt_sigreturn          6211
+
+static struct page *vdso_page;
+
+static void __init install_trampoline(u32 *tramp, unsigned int sigreturn)
+{
+       uasm_i_addiu(&tramp, 2, 0, sigreturn);  /* li v0, sigreturn */
+       uasm_i_syscall(&tramp, 0);
+}
+
+static int __init init_vdso(void)
+{
+       struct mips_vdso *vdso;
+
+       vdso_page = alloc_page(GFP_KERNEL);
+       if (!vdso_page)
+               panic("Cannot allocate vdso");
+
+       vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL);
+       if (!vdso)
+               panic("Cannot map vdso");
+       clear_page(vdso);
+
+       install_trampoline(vdso->rt_signal_trampoline, __NR_rt_sigreturn);
+#ifdef CONFIG_32BIT
+       install_trampoline(vdso->signal_trampoline, __NR_sigreturn);
+#else
+       install_trampoline(vdso->n32_rt_signal_trampoline,
+                          __NR_N32_rt_sigreturn);
+       install_trampoline(vdso->o32_signal_trampoline, __NR_O32_sigreturn);
+       install_trampoline(vdso->o32_rt_signal_trampoline,
+                          __NR_O32_rt_sigreturn);
+#endif
+
+       vunmap(vdso);
+
+       pr_notice("init_vdso successfull\n");
+
+       return 0;
+}
+device_initcall(init_vdso);
+
+static unsigned long vdso_addr(unsigned long start)
+{
+       return STACK_TOP;
+}
+
+int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+{
+       int ret;
+       unsigned long addr;
+       struct mm_struct *mm = current->mm;
+
+       down_write(&mm->mmap_sem);
+
+       addr = vdso_addr(mm->start_stack);
+
+       addr = get_unmapped_area(NULL, addr, PAGE_SIZE, 0, 0);
+       if (IS_ERR_VALUE(addr)) {
+               ret = addr;
+               goto up_fail;
+       }
+
+       ret = install_special_mapping(mm, addr, PAGE_SIZE,
+                                     VM_READ|VM_EXEC|
+                                     VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
+                                     VM_ALWAYSDUMP,
+                                     &vdso_page);
+
+       if (ret)
+               goto up_fail;
+
+       mm->context.vdso = (void *)addr;
+
+up_fail:
+       up_write(&mm->mmap_sem);
+       return ret;
+}
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+       if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
+               return "[vdso]";
+       return NULL;
+}
index 6b3b1de9dcae9e024fcaa7d8b5e4ef73439543ce..5995969e8c42b4c4b0d6a1f44005104429c50479 100644 (file)
@@ -41,7 +41,7 @@ EXPORT_SYMBOL(__delay);
 
 void __udelay(unsigned long us)
 {
-       unsigned int lpj = current_cpu_data.udelay_val;
+       unsigned int lpj = raw_current_cpu_data.udelay_val;
 
        __delay((us * 0x000010c7ull * HZ * lpj) >> 32);
 }
@@ -49,7 +49,7 @@ EXPORT_SYMBOL(__udelay);
 
 void __ndelay(unsigned long ns)
 {
-       unsigned int lpj = current_cpu_data.udelay_val;
+       unsigned int lpj = raw_current_cpu_data.udelay_val;
 
        __delay((ns * 0x00000005ull * HZ * lpj) >> 32);
 }
index 3f19d1c5d942207525766dae07f95139bb35dc59..05909d58e2fe1c278e3f30a3d196e1c214724194 100644 (file)
@@ -17,8 +17,7 @@ struct DWstruct {
 #error I feel sick.
 #endif
 
-typedef union
-{
+typedef union {
        struct DWstruct s;
        long long ll;
 } DWunion;
index 853f184b793e0abfc0561d00fab435ef7ac3a930..81fbe6b73f91f71b896292cbf55b7b1c67990f80 100644 (file)
@@ -24,7 +24,7 @@ static const char *system_types[] = {
        [MACH_LEMOTE_FL2F]              "lemote-fuloong-2f-box",
        [MACH_LEMOTE_ML2F7]             "lemote-mengloong-2f-7inches",
        [MACH_LEMOTE_YL2F89]            "lemote-yeeloong-2f-8.9inches",
-       [MACH_DEXXON_GDIUM2F10]         "dexxon-gidum-2f-10inches",
+       [MACH_DEXXON_GDIUM2F10]         "dexxon-gdium-2f",
        [MACH_LEMOTE_NAS]               "lemote-nas-2f",
        [MACH_LEMOTE_LL2F]              "lemote-lynloong-2f",
        [MACH_LOONGSON_END]             NULL,
index ec2f7964a0b0d5c6a6d6f1edfa8e92062c3076aa..30eba60012056f7e547ed0cb1855cab2f51fe016 100644 (file)
@@ -75,7 +75,7 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
        unsigned long end = offset + size;
 
        if (__uncached_access(file, offset)) {
-               if (((uca_start && offset) >= uca_start) &&
+               if (uca_start && (offset >= uca_start) &&
                    (end <= uca_end))
                        return __pgprot((pgprot_val(vma_prot) &
                                         ~_CACHE_MASK) |
@@ -96,7 +96,7 @@ static int __init find_vga_mem_init(void)
                return 0;
 
        for_each_pci_dev(dev) {
-               if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
+               if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
                        for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
                                r = &dev->resource[idx];
                                if (!r->start && r->end)
index 4bd9c18b07a533c087d21f01276b43a65a592950..9e10d6225d9bca134931d2da11d0ba63da784972 100644 (file)
 
 #include <loongson.h>
 
+static inline void loongson_reboot(void)
+{
+#ifndef CONFIG_CPU_JUMP_WORKAROUNDS
+       ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) ();
+#else
+       void (*func)(void);
+
+       func = (void *)ioremap_nocache(LOONGSON_BOOT_BASE, 4);
+
+       __asm__ __volatile__(
+       "       .set    noat                                            \n"
+       "       jr      %[func]                                         \n"
+       "       .set    at                                              \n"
+       : /* No outputs */
+       : [func] "r" (func));
+#endif
+}
+
 static void loongson_restart(char *command)
 {
        /* do preparation for reboot */
        mach_prepare_reboot();
 
        /* reboot via jumping to boot base address */
-       ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) ();
+       loongson_reboot();
 }
 
 static void loongson_poweroff(void)
index 4cd2aa9a342ce2b0dec704c6ae4c1b818da17eb2..27d826bc71033d928c32b4fb8c06af3be0ccfa9b 100644 (file)
@@ -41,15 +41,12 @@ void __init plat_mem_setup(void)
        conswitchp = &vga_con;
 
        screen_info = (struct screen_info) {
-               0, 25,          /* orig-x, orig-y */
-                   0,          /* unused */
-                   0,          /* orig-video-page */
-                   0,          /* orig-video-mode */
-                   80,         /* orig-video-cols */
-                   0, 0, 0,    /* ega_ax, ega_bx, ega_cx */
-                   25,         /* orig-video-lines */
-                   VIDEO_TYPE_VGAC,    /* orig-video-isVGA */
-                   16          /* orig-video-points */
+               .orig_x                 = 0,
+               .orig_y                 = 25,
+               .orig_video_cols        = 80,
+               .orig_video_lines       = 25,
+               .orig_video_isVGA       = VIDEO_TYPE_VGAC,
+               .orig_video_points      = 16,
        };
 #elif defined(CONFIG_DUMMY_CONSOLE)
        conswitchp = &dummy_con;
index 882dfcd42c00cd8769d7e47bac7121b50dba76af..1d8b4d28a0580c3ada3b4eb1834ad64db50c3b59 100644 (file)
@@ -79,7 +79,7 @@ void mach_irq_dispatch(unsigned int pending)
        if (pending & CAUSEF_IP7)
                do_IRQ(LOONGSON_TIMER_IRQ);
        else if (pending & CAUSEF_IP6) {        /* North Bridge, Perf counter */
-#ifdef CONFIG_OPROFILE
+#if defined(CONFIG_OPROFILE) || defined(CONFIG_OPROFILE_MODULE)
                do_IRQ(LOONGSON2_PERFCNT_IRQ);
 #endif
                bonito_irqdispatch();
index 8f2f8e9d8b212ae5897c0aabee5dd35c46837680..f2338d1c0b4889a0bf216f1af9ac9e8adedb3ec1 100644 (file)
@@ -78,6 +78,9 @@ DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
 #define FPCREG_RID     0       /* $0  = revision id */
 #define FPCREG_CSR     31      /* $31 = csr */
 
+/* Determine rounding mode from the RM bits of the FCSR */
+#define modeindex(v) ((v) & FPU_CSR_RM)
+
 /* Convert Mips rounding mode (0..3) to IEEE library modes. */
 static const unsigned char ieee_rm[4] = {
        [FPU_CSR_RN] = IEEE754_RN,
@@ -384,10 +387,14 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
                                        (void *) (xcp->cp0_epc),
                                        MIPSInst_RT(ir), value);
 #endif
-                               value &= (FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
-                               ctx->fcr31 &= ~(FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
-                               /* convert to ieee library modes */
-                               ctx->fcr31 |= (value & ~0x3) | ieee_rm[value & 0x3];
+
+                               /*
+                                * Don't write reserved bits,
+                                * and convert to ieee library modes
+                                */
+                               ctx->fcr31 = (value &
+                                               ~(FPU_CSR_RSVD | FPU_CSR_RM)) |
+                                               ieee_rm[modeindex(value)];
                        }
                        if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
                                return SIGFPE;
index 46067ad542dce8640cbfceb5a46beaf8c210b038..5c779be6f082b8d7ce9965047360e7abef8395d6 100644 (file)
@@ -17,7 +17,6 @@
  */
 #include <linux/init.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <asm/mips-boards/simint.h>
index be8627bc5b02e8782a94e65eee4386508622da56..12af739048fada0927f50e414f30097b8bbb96d6 100644 (file)
@@ -133,7 +133,7 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address,
 }
 
 unsigned long _page_cachable_default;
-EXPORT_SYMBOL_GPL(_page_cachable_default);
+EXPORT_SYMBOL(_page_cachable_default);
 
 static inline void setup_protection_map(void)
 {
index 9367e33fbd1822d92f55302a38fb872982e2fb7d..9547bc0cf188bc2cff41233e67b53ce5bdd0d50c 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/scatterlist.h>
 #include <linux/string.h>
+#include <linux/gfp.h>
 
 #include <asm/cache.h>
 #include <asm/io.h>
index cd0660c51f28357f4ac1b2a9f5501fe85ad16189..a7fee0dfb7a9daaeb67616804f00cac7365d778f 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
 #include <linux/pagemap.h>
-#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/sysctl.h>
 #include <asm/mman.h>
index 12539af38a990bff5e271a2ddfadce886fd867d5..2efcbd24c82fcfa8d2741243101eb5df116e2d85 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/proc_fs.h>
 #include <linux/pfn.h>
 #include <linux/hardirq.h>
+#include <linux/gfp.h>
 
 #include <asm/asm-offsets.h>
 #include <asm/bootinfo.h>
index 0c43248347bd82e8ad0b7fb97414e401fdbe2bba..cacfd31e8ec9d1121c86e81feb35fac4344a9a3b 100644 (file)
@@ -10,6 +10,7 @@
 #include <asm/addrspace.h>
 #include <asm/byteorder.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <asm/cacheflush.h>
 #include <asm/io.h>
index 0de0e4127d6600743d7a8d453b4fd1278939e428..86f004dc83557240a18e02ca15bf2f17fe96005d 100644 (file)
 #include <asm/war.h>
 #include <asm/uasm.h>
 
+/*
+ * TLB load/store/modify handlers.
+ *
+ * Only the fastpath gets synthesized at runtime, the slowpath for
+ * do_page_fault remains normal asm.
+ */
+extern void tlb_do_page_fault_0(void);
+extern void tlb_do_page_fault_1(void);
+
+
 static inline int r45k_bvahwbug(void)
 {
        /* XXX: We should probe for the presence of this bug, but we don't. */
@@ -83,6 +93,7 @@ enum label_id {
        label_nopage_tlbm,
        label_smp_pgtable_change,
        label_r3000_write_probe_fail,
+       label_large_segbits_fault,
 #ifdef CONFIG_HUGETLB_PAGE
        label_tlb_huge_update,
 #endif
@@ -101,6 +112,7 @@ UASM_L_LA(_nopage_tlbs)
 UASM_L_LA(_nopage_tlbm)
 UASM_L_LA(_smp_pgtable_change)
 UASM_L_LA(_r3000_write_probe_fail)
+UASM_L_LA(_large_segbits_fault)
 #ifdef CONFIG_HUGETLB_PAGE
 UASM_L_LA(_tlb_huge_update)
 #endif
@@ -157,6 +169,10 @@ static u32 tlb_handler[128] __cpuinitdata;
 static struct uasm_label labels[128] __cpuinitdata;
 static struct uasm_reloc relocs[128] __cpuinitdata;
 
+#ifdef CONFIG_64BIT
+static int check_for_high_segbits __cpuinitdata;
+#endif
+
 #ifndef CONFIG_MIPS_PGD_C0_CONTEXT
 /*
  * CONFIG_MIPS_PGD_C0_CONTEXT implies 64 bit and lack of pgd_current,
@@ -408,7 +424,7 @@ static __cpuinit __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
                UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
        } else {
 #ifdef CONFIG_64BIT_PHYS_ADDR
-               uasm_i_dsrl(p, reg, reg, ilog2(_PAGE_GLOBAL));
+               uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL));
 #else
                UASM_i_SRL(p, reg, reg, ilog2(_PAGE_GLOBAL));
 #endif
@@ -532,7 +548,24 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
         * The vmalloc handling is not in the hotpath.
         */
        uasm_i_dmfc0(p, tmp, C0_BADVADDR);
-       uasm_il_bltz(p, r, tmp, label_vmalloc);
+
+       if (check_for_high_segbits) {
+               /*
+                * The kernel currently implicitely assumes that the
+                * MIPS SEGBITS parameter for the processor is
+                * (PGDIR_SHIFT+PGDIR_BITS) or less, and will never
+                * allocate virtual addresses outside the maximum
+                * range for SEGBITS = (PGDIR_SHIFT+PGDIR_BITS). But
+                * that doesn't prevent user code from accessing the
+                * higher xuseg addresses.  Here, we make sure that
+                * everything but the lower xuseg addresses goes down
+                * the module_alloc/vmalloc path.
+                */
+               uasm_i_dsrl_safe(p, ptr, tmp, PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
+               uasm_il_bnez(p, r, ptr, label_vmalloc);
+       } else {
+               uasm_il_bltz(p, r, tmp, label_vmalloc);
+       }
        /* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */
 
 #ifdef CONFIG_MIPS_PGD_C0_CONTEXT
@@ -549,14 +582,14 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
         * SMTC uses TCBind value as "CPU" index
         */
        uasm_i_mfc0(p, ptr, C0_TCBIND);
-       uasm_i_dsrl(p, ptr, ptr, 19);
+       uasm_i_dsrl_safe(p, ptr, ptr, 19);
 # else
        /*
         * 64 bit SMP running in XKPHYS has smp_processor_id() << 3
         * stored in CONTEXT.
         */
        uasm_i_dmfc0(p, ptr, C0_CONTEXT);
-       uasm_i_dsrl(p, ptr, ptr, 23);
+       uasm_i_dsrl_safe(p, ptr, ptr, 23);
 # endif
        UASM_i_LA_mostly(p, tmp, pgdc);
        uasm_i_daddu(p, ptr, ptr, tmp);
@@ -569,44 +602,78 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
 
        uasm_l_vmalloc_done(l, *p);
 
-       if (PGDIR_SHIFT - 3 < 32)               /* get pgd offset in bytes */
-               uasm_i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3);
-       else
-               uasm_i_dsrl32(p, tmp, tmp, PGDIR_SHIFT - 3 - 32);
+       /* get pgd offset in bytes */
+       uasm_i_dsrl_safe(p, tmp, tmp, PGDIR_SHIFT - 3);
 
        uasm_i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3);
        uasm_i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */
 #ifndef __PAGETABLE_PMD_FOLDED
        uasm_i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */
        uasm_i_ld(p, ptr, 0, ptr); /* get pmd pointer */
-       uasm_i_dsrl(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */
+       uasm_i_dsrl_safe(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */
        uasm_i_andi(p, tmp, tmp, (PTRS_PER_PMD - 1)<<3);
        uasm_i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */
 #endif
 }
 
+enum vmalloc64_mode {not_refill, refill};
 /*
  * BVADDR is the faulting address, PTR is scratch.
  * PTR will hold the pgd for vmalloc.
  */
 static void __cpuinit
 build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
-                       unsigned int bvaddr, unsigned int ptr)
+                       unsigned int bvaddr, unsigned int ptr,
+                       enum vmalloc64_mode mode)
 {
        long swpd = (long)swapper_pg_dir;
+       int single_insn_swpd;
+       int did_vmalloc_branch = 0;
+
+       single_insn_swpd = uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd);
 
        uasm_l_vmalloc(l, *p);
 
-       if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) {
-               uasm_il_b(p, r, label_vmalloc_done);
-               uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
-       } else {
-               UASM_i_LA_mostly(p, ptr, swpd);
-               uasm_il_b(p, r, label_vmalloc_done);
-               if (uasm_in_compat_space_p(swpd))
-                       uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(swpd));
-               else
-                       uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(swpd));
+       if (mode == refill && check_for_high_segbits) {
+               if (single_insn_swpd) {
+                       uasm_il_bltz(p, r, bvaddr, label_vmalloc_done);
+                       uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
+                       did_vmalloc_branch = 1;
+                       /* fall through */
+               } else {
+                       uasm_il_bgez(p, r, bvaddr, label_large_segbits_fault);
+               }
+       }
+       if (!did_vmalloc_branch) {
+               if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) {
+                       uasm_il_b(p, r, label_vmalloc_done);
+                       uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
+               } else {
+                       UASM_i_LA_mostly(p, ptr, swpd);
+                       uasm_il_b(p, r, label_vmalloc_done);
+                       if (uasm_in_compat_space_p(swpd))
+                               uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(swpd));
+                       else
+                               uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(swpd));
+               }
+       }
+       if (mode == refill && check_for_high_segbits) {
+               uasm_l_large_segbits_fault(l, *p);
+               /*
+                * We get here if we are an xsseg address, or if we are
+                * an xuseg address above (PGDIR_SHIFT+PGDIR_BITS) boundary.
+                *
+                * Ignoring xsseg (assume disabled so would generate
+                * (address errors?), the only remaining possibility
+                * is the upper xuseg addresses.  On processors with
+                * TLB_SEGBITS <= PGDIR_SHIFT+PGDIR_BITS, these
+                * addresses would have taken an address error. We try
+                * to mimic that here by taking a load/istream page
+                * fault.
+                */
+               UASM_i_LA(p, ptr, (unsigned long)tlb_do_page_fault_0);
+               uasm_i_jr(p, ptr);
+               uasm_i_nop(p);
        }
 }
 
@@ -720,9 +787,9 @@ static void __cpuinit build_update_entries(u32 **p, unsigned int tmp,
                        UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
                        UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
                } else {
-                       uasm_i_dsrl(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */
+                       uasm_i_dsrl_safe(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */
                        UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
-                       uasm_i_dsrl(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); /* convert to entrylo1 */
+                       uasm_i_dsrl_safe(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); /* convert to entrylo1 */
                }
                UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */
        } else {
@@ -788,10 +855,15 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
         * create the plain linear handler
         */
        if (bcm1250_m3_war()) {
-               UASM_i_MFC0(&p, K0, C0_BADVADDR);
-               UASM_i_MFC0(&p, K1, C0_ENTRYHI);
+               unsigned int segbits = 44;
+
+               uasm_i_dmfc0(&p, K0, C0_BADVADDR);
+               uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
                uasm_i_xor(&p, K0, K0, K1);
-               UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+               uasm_i_dsrl_safe(&p, K1, K0, 62);
+               uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
+               uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
+               uasm_i_or(&p, K0, K0, K1);
                uasm_il_bnez(&p, &r, K0, label_leave);
                /* No need for uasm_i_nop */
        }
@@ -820,7 +892,7 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
 #endif
 
 #ifdef CONFIG_64BIT
-       build_get_pgd_vmalloc64(&p, &l, &r, K0, K1);
+       build_get_pgd_vmalloc64(&p, &l, &r, K0, K1, refill);
 #endif
 
        /*
@@ -929,15 +1001,6 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
        dump_handler((u32 *)ebase, 64);
 }
 
-/*
- * TLB load/store/modify handlers.
- *
- * Only the fastpath gets synthesized at runtime, the slowpath for
- * do_page_fault remains normal asm.
- */
-extern void tlb_do_page_fault_0(void);
-extern void tlb_do_page_fault_1(void);
-
 /*
  * 128 instructions for the fastpath handler is generous and should
  * never be exceeded.
@@ -1297,7 +1360,7 @@ build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l,
        uasm_i_eret(p); /* return from trap */
 
 #ifdef CONFIG_64BIT
-       build_get_pgd_vmalloc64(p, l, r, tmp, ptr);
+       build_get_pgd_vmalloc64(p, l, r, tmp, ptr, not_refill);
 #endif
 }
 
@@ -1312,10 +1375,15 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
        memset(relocs, 0, sizeof(relocs));
 
        if (bcm1250_m3_war()) {
-               UASM_i_MFC0(&p, K0, C0_BADVADDR);
-               UASM_i_MFC0(&p, K1, C0_ENTRYHI);
+               unsigned int segbits = 44;
+
+               uasm_i_dmfc0(&p, K0, C0_BADVADDR);
+               uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
                uasm_i_xor(&p, K0, K0, K1);
-               UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+               uasm_i_dsrl_safe(&p, K1, K0, 62);
+               uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
+               uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
+               uasm_i_or(&p, K0, K0, K1);
                uasm_il_bnez(&p, &r, K0, label_leave);
                /* No need for uasm_i_nop */
        }
@@ -1516,6 +1584,10 @@ void __cpuinit build_tlb_refill_handler(void)
         */
        static int run_once = 0;
 
+#ifdef CONFIG_64BIT
+       check_for_high_segbits = current_cpu_data.vmbits > (PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
+#endif
+
        switch (current_cpu_type()) {
        case CPU_R2000:
        case CPU_R3000:
index 1581e985246194cc106460ec2c6360f36a886c72..611d564fdcf1e1bb4cbad07244ee2ca34192582c 100644 (file)
@@ -31,7 +31,8 @@ enum fields {
        BIMM = 0x040,
        JIMM = 0x080,
        FUNC = 0x100,
-       SET = 0x200
+       SET = 0x200,
+       SCIMM = 0x400
 };
 
 #define OP_MASK                0x3f
@@ -52,6 +53,8 @@ enum fields {
 #define FUNC_SH                0
 #define SET_MASK       0x7
 #define SET_SH         0
+#define SCIMM_MASK     0xfffff
+#define SCIMM_SH       6
 
 enum opcode {
        insn_invalid,
@@ -61,10 +64,10 @@ enum opcode {
        insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
        insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal,
        insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
-       insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
+       insn_mtc0, insn_or, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
        insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw,
        insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
-       insn_dins
+       insn_dins, insn_syscall
 };
 
 struct insn {
@@ -117,6 +120,7 @@ static struct insn insn_table[] __cpuinitdata = {
        { insn_lw,  M(lw_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
        { insn_mfc0,  M(cop0_op, mfc_op, 0, 0, 0, 0),  RT | RD | SET},
        { insn_mtc0,  M(cop0_op, mtc_op, 0, 0, 0, 0),  RT | RD | SET},
+       { insn_or,  M(spec_op, 0, 0, 0, 0, or_op),  RS | RT | RD },
        { insn_ori,  M(ori_op, 0, 0, 0, 0, 0),  RS | RT | UIMM },
        { insn_pref,  M(pref_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
        { insn_rfe,  M(cop0_op, cop_op, 0, 0, 0, rfe_op),  0 },
@@ -136,6 +140,7 @@ static struct insn insn_table[] __cpuinitdata = {
        { insn_xor,  M(spec_op, 0, 0, 0, 0, xor_op),  RS | RT | RD },
        { insn_xori,  M(xori_op, 0, 0, 0, 0, 0),  RS | RT | UIMM },
        { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
+       { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM},
        { insn_invalid, 0, 0 }
 };
 
@@ -208,6 +213,14 @@ static inline __cpuinit u32 build_jimm(u32 arg)
        return (arg >> 2) & JIMM_MASK;
 }
 
+static inline __cpuinit u32 build_scimm(u32 arg)
+{
+       if (arg & ~SCIMM_MASK)
+               printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+       return (arg & SCIMM_MASK) << SCIMM_SH;
+}
+
 static inline __cpuinit u32 build_func(u32 arg)
 {
        if (arg & ~FUNC_MASK)
@@ -266,6 +279,8 @@ static void __cpuinit build_insn(u32 **buf, enum opcode opc, ...)
                op |= build_func(va_arg(ap, u32));
        if (ip->fields & SET)
                op |= build_set(va_arg(ap, u32));
+       if (ip->fields & SCIMM)
+               op |= build_scimm(va_arg(ap, u32));
        va_end(ap);
 
        **buf = op;
@@ -373,6 +388,7 @@ I_u2s3u1(_lw)
 I_u1u2u3(_mfc0)
 I_u1u2u3(_mtc0)
 I_u2u1u3(_ori)
+I_u3u1u2(_or)
 I_u2s3u1(_pref)
 I_0(_rfe)
 I_u2s3u1(_sc)
@@ -391,6 +407,7 @@ I_0(_tlbwr)
 I_u3u1u2(_xor)
 I_u2u1u3(_xori)
 I_u2u1msbu3(_dins);
+I_u1(_syscall);
 
 /* Handle labels. */
 void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
index 2cb5ae79020326ecffdc4aa455f74d5a54afa506..15949b0be811f9718af9e2896d4bd9e947c84897 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/irq.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/kernel_stat.h>
index a9bc9bacad2b6667ae10e4ec660cc7ec72db1ef1..e0ea96d29fde9fd6d64dca041dda2b8143823306 100644 (file)
@@ -22,7 +22,6 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-#include <linux/slab.h>
 #include <linux/reboot.h>
 #include <pnx833x.h>
 
index 7aca7d5375e5cb4917eb23c705c18868cadb2f2f..cfed5051dc6d6323e86ad8e90144e1006bb52b57 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/random.h>
index af094cd1d85bf030341bb6742079fbac5a630d91..3bba5ec828e886b355b3acc4a43955cf2b837916 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/proc_fs.h>
 #include <linux/irq.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/random.h>
index 7b2cbc5b2c7c1b810f62c32f3eb637de22cc6f3d..fadd8744a6bccfbf25283369608c66b16afeab04 100644 (file)
@@ -20,7 +20,8 @@
  * Reset the PNX8550 board.
  *
  */
-#include <linux/slab.h>
+#include <linux/kernel.h>
+
 #include <asm/reboot.h>
 #include <glb.h>
 
index 29e2326b62577b3d2f6c5ae2a2620ce0e532d731..fa3bf661ae299c1ca8d4012851bd6530c4828888 100644 (file)
@@ -122,7 +122,7 @@ static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id)
         */
 
        /* Check whether the irq belongs to me */
-       enabled = read_c0_perfcnt() & LOONGSON2_PERFCNT_INT_EN;
+       enabled = read_c0_perfctrl() & LOONGSON2_PERFCNT_INT_EN;
        if (!enabled)
                return IRQ_NONE;
        enabled = reg.cnt1_enabled | reg.cnt2_enabled;
index 2bb4057bf6c7f045796cd76eca3d99a3751eea6d..d657ee0bc131c8c3c26c1095b35a312c666ddd94 100644 (file)
@@ -180,15 +180,21 @@ struct pci_ops loongson_pci_ops = {
 };
 
 #ifdef CONFIG_CS5536
+DEFINE_RAW_SPINLOCK(msr_lock);
+
 void _rdmsr(u32 msr, u32 *hi, u32 *lo)
 {
        struct pci_bus bus = {
                .number = PCI_BUS_CS5536
        };
        u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&msr_lock, flags);
        loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
        loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
        loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
+       raw_spin_unlock_irqrestore(&msr_lock, flags);
 }
 EXPORT_SYMBOL(_rdmsr);
 
@@ -198,9 +204,13 @@ void _wrmsr(u32 msr, u32 hi, u32 lo)
                .number = PCI_BUS_CS5536
        };
        u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&msr_lock, flags);
        loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
        loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
        loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
+       raw_spin_unlock_irqrestore(&msr_lock, flags);
 }
 EXPORT_SYMBOL(_wrmsr);
 #endif
index 46c636c27e066be2798fc871ccc39be1ac437b4c..749c1922d4205f0da1ea468fc89edef76c49e462 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <asm/io.h>
 
index ada24e6f951f6b43bff15f9fb862aabb8294ab0c..1711e8e101bc8e0348bb840d2b8973cd7c73f39f 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/mm.h>
 #include <linux/console.h>
 #include <linux/tty.h>
+#include <linux/vt.h>
 
 #include <asm/io.h>
 
@@ -254,7 +255,7 @@ static int __init sb1250_pcibios_init(void)
         * XXX ehs: Should this happen in PCI Device mode?
         */
        io_map_base = ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 1024 * 1024);
-       sb1250_controller.io_map_base = io_map_base;
+       sb1250_controller.io_map_base = (unsigned long)io_map_base;
        set_io_port_base((unsigned long)io_map_base);
 
 #ifdef CONFIG_SIBYTE_HAS_LDT
index db98d87a09225679a076e5b5df405e351db1563e..db00deb59b9c678732983efe955bfe1d2c80a5cc 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/string.h>
 #include <linux/interrupt.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
index fd22597edb64bcf2338e7ae693eed99f855c723f..63be40e470db9baae4269f075feabec031fbaed9 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <asm/pci.h>
 #include <asm/io.h>
 
index 5f673eba142cf6a600e5c4159d84f72f0f6cf6b8..51021cfd04bc1de986912be4346da35cba7df1dd 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/ioport.h>
 #include <linux/irq.h>
 #include <linux/timex.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/bitops.h>
 #include <asm/bootinfo.h>
index 217424231eb6f8ebcb1bcdc25735b848f76a25e6..8ee77887306a24986a54b27af1b3dc009011273a 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/mm.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <asm/page.h>
 #include <linux/swap.h>
 #include <linux/highmem.h>
index 325fab9685d1c57ce73d806e194dbc0e167f4946..529c44a52d6460ab8d6085d36d8314f2568036d3 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/kernel.h>
index f07882029a90d3d155c17b462812c2936229458c..ea6cec3c1e0dbeecde2d7c3ceab11d26b216f18a 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/timex.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/delay.h>
 
index de6a0cc32fea8712988687ea10001ca6d8f106c5..911d3999c0c7e24a34e90d014be87a4fb6b09645 100644 (file)
@@ -89,7 +89,7 @@ static void print_buserr(void)
 void ip22_be_interrupt(int irq)
 {
        const int field = 2 * sizeof(unsigned long);
-       const struct pt_regs *regs = get_irq_regs();
+       struct pt_regs *regs = get_irq_regs();
 
        save_and_clear_buserr();
        print_buserr();
index 30e12e2ec4b5a865bb78e436554ead389160f845..88c684e05a3de3923b437b4f6490545591fcd0b6 100644 (file)
@@ -453,7 +453,7 @@ mips_be_fatal:
 
 void ip22_be_interrupt(int irq)
 {
-       const struct pt_regs *regs = get_irq_regs();
+       struct pt_regs *regs = get_irq_regs();
 
        count_be_interrupt++;
 
index c1c8e40d65d6a5f5353768d0729f067097d0dad3..6a123ea72de54a42bfdc3e2d6b5d705731061e94 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/timex.h>
-#include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/random.h>
 #include <linux/kernel.h>
index d8b65204d28868561d9cff524bc8853fad824f0a..eb40824b172ac1792c541036a5f6c5f8b8790ece 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/irq.h>
 #include <linux/bitops.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/random.h>
 #include <linux/sched.h>
index 06e25d949768bff9f35679951bca010830682484..7a8b0a8b643aec65696d441d30b731cbc04143b1 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/smp.h>
 #include <linux/spinlock.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/kernel_stat.h>
 
 #include <asm/errno.h>
index ed2453eab5cbab8b2f0c8d31da28be35e465570f..d4ed7a9156f59d847985909de7fe64f788664921 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
 #include <linux/errno.h>
index ab44a2f59ee497a973da4c74a2405b6f7f5fcf3c..62371f7725535a7bd8e0a64626244dbb7302d128 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/spinlock.h>
 #include <linux/smp.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/kernel_stat.h>
 
 #include <asm/errno.h>
index 0444da1e23c24e2dc675a40034a2e7adc087ba41..92da3155ce074ac16840c715fde220946a13b4fd 100644 (file)
@@ -87,6 +87,21 @@ static int __init setup_bcm1250(void)
        return ret;
 }
 
+int sb1250_m3_workaround_needed(void)
+{
+       switch (soc_type) {
+       case K_SYS_SOC_TYPE_BCM1250:
+       case K_SYS_SOC_TYPE_BCM1250_ALT:
+       case K_SYS_SOC_TYPE_BCM1250_ALT2:
+       case K_SYS_SOC_TYPE_BCM1125:
+       case K_SYS_SOC_TYPE_BCM1125H:
+               return soc_pass < K_SYS_REVISION_BCM1250_C0;
+
+       default:
+               return 0;
+       }
+}
+
 static int __init setup_bcm112x(void)
 {
        int ret = 0;
index 5277aac96b0f47730df589d1b3e4c5e972f80f84..c308989fc464c3c76a1bc258d38713543c4004c8 100644 (file)
@@ -145,15 +145,14 @@ void __init plat_mem_setup(void)
 
 #ifdef CONFIG_VT
        screen_info = (struct screen_info) {
-               0, 0,           /* orig-x, orig-y */
-               0,              /* unused */
-               52,             /* orig_video_page */
-               3,              /* orig_video_mode */
-               80,             /* orig_video_cols */
-               4626, 3, 9,     /* unused, ega_bx, unused */
-               25,             /* orig_video_lines */
-               0x22,           /* orig_video_isVGA */
-               16              /* orig_video_points */
+               .orig_video_page        = 52,
+               .orig_video_mode        = 3,
+               .orig_video_cols        = 80,
+               .flags                  = 12,
+               .orig_video_ega_bx      = 3,
+               .orig_video_lines       = 25,
+               .orig_video_isVGA       = 0x22,
+               .orig_video_points      = 16,
        };
        /* XXXKW for CFE, get lines/cols from environment */
 #endif
index 707cfa9c547d98ac63fa619a0f831fbc939dba98..9a0be810cafa37ef731ca746f3d5cb6d456c36ab 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/txx9/pci.h>
 #ifdef CONFIG_TOSHIBA_FPCIB0
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <asm/i8259.h>
 #include <asm/txx9/smsc_fdc37m81x.h>
 #endif
index 95184a0a1ae6ced2829ae82edfbaabf60efc147b..adc69291f9e2424759cbfaf715ba7c1118de1b04 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/mtd/physmap.h>
 #include <linux/leds.h>
 #include <linux/sysdev.h>
+#include <linux/slab.h>
 #include <asm/bootinfo.h>
 #include <asm/time.h>
 #include <asm/reboot.h>
index 75c347238f47741792eee5846a3eb2167b1be37a..103abc13d6234764469f33545f6c1710ae74b55e 100644 (file)
@@ -10,6 +10,7 @@
  * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
  */
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/eeprom.h>
index b0c241ecf603c3549a98b385176ad701eb7532c6..7dc0fafbec80b896c615ef5bacf3a41c63c26ac3 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/leds.h>
 #include <linux/interrupt.h>
index 5bf5be9566dece295d8922a8c3c54aa9f5420615..e41222d6c2fd1a5d3a97a20482c09ff10b652eba 100644 (file)
@@ -31,7 +31,7 @@
  * Atomically reads the value of @v.  Note that the guaranteed
  * useful range of an atomic_t is only 24 bits.
  */
-#define atomic_read(v) ((v)->counter)
+#define atomic_read(v) (*(volatile int *)&(v)->counter)
 
 /**
  * atomic_set - set atomic variable
index ec8a21df1142010a2c3bb4e08f5ea6e4615f12dc..82b817c7f7b63b2faca0af0e7c2ad3c671ee2b22 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
@@ -26,6 +25,7 @@
 #include <linux/percpu.h>
 #include <linux/err.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
index 3f24c298a3af1cb583f66a809598cfbbbdde6faa..d464affcba0e31a0d201ac07f51fc7e4bd55cbf6 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/tty.h>
 #include <linux/ioport.h>
index ee82d624b3c63e8f034112b88729c41fd2a4e161..4e34880bea03b889dcbcaea5865d576045bf1707 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 
 static unsigned long pci_sram_allocated = 0xbc000000;
index dd27a9a35152ff9ab853cd381c035890cb77a176..6e6bc0e51521811895e4c3e11e73fdb2fdc49118 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/types.h>
 #include <linux/ptrace.h>
 #include <linux/mman.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
@@ -27,6 +26,7 @@
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/bootmem.h>
+#include <linux/gfp.h>
 
 #include <asm/processor.h>
 #include <asm/system.h>
index baffc581e031d6cb3389f4e15d2268fbd38d945d..9c1624c9e4e9fa05f33d621877c931dbb9ae1abb 100644 (file)
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
 #include <linux/smp.h>
 #include <linux/highmem.h>
-#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/spinlock.h>
 #include <linux/quicklist.h>
index 58cfb44f0acf626355067b4275175cb775708635..91212ea71e697257350e553c81bffb24b5e2f832 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <asm/io.h>
index 54075360a8fdb5cd43c0abee9669ae4ac9bce7fc..6935123178ebec4a9cd9d3dd6628376f4b081b6b 100644 (file)
@@ -26,8 +26,8 @@
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/file.h>
-#include <linux/slab.h>
 #include <linux/ptrace.h>
+#include <linux/slab.h>
 #include <asm/errno.h>
 #include <asm/uaccess.h>
 
index 716634d1f5466645c7e6028bda01ca1abd1aeeac..f81955934aebf4dbf0e97add2e45bb6cdc9042fa 100644 (file)
@@ -189,7 +189,7 @@ static __inline__ void atomic_set(atomic_t *v, int i)
 
 static __inline__ int atomic_read(const atomic_t *v)
 {
-       return v->counter;
+       return (*(volatile int *)&(v)->counter);
 }
 
 /* exported interface */
@@ -286,7 +286,7 @@ atomic64_set(atomic64_t *v, s64 i)
 static __inline__ s64
 atomic64_read(const atomic64_t *v)
 {
-       return v->counter;
+       return (*(volatile long *)&(v)->counter);
 }
 
 #define atomic64_add(i,v)      ((void)(__atomic64_add_return( ((s64)(i)),(v))))
index 212074653df7fc5a109da9222137a13226cc7bff..159a2b81e90c630db82eb9834c2096df7eb66896 100644 (file)
@@ -61,6 +61,7 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/bug.h>
+#include <linux/slab.h>
 
 #include <asm/unwind.h>
 
index c07f618ff7da9264fc9aa242cfaf1515b72d8af5..a029f74a3c5c54ac7a6c0bd8458d66bc3c59fe6b 100644 (file)
 */
 
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/scatterlist.h>
index 38372e7cbb88f1d53372061e5e6e23684bcbc4a9..9efd97405317726369599d9f11e797c5a48d687c 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/types.h>
 
 #include <asm/io.h>
index 1f3aa8db02030a1509253b6d0d51d4910f522761..76332dadc6e93e64e6b0557dc0e5c0bd2e0b0986 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/personality.h>
 #include <linux/ptrace.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/kallsyms.h>
index fb59852006defd58fbf9b035c8b3ec49455c5cfe..e14132430762414166a729ae57e647ec5b9f1316 100644 (file)
@@ -23,7 +23,6 @@
  */
 
 #include <linux/compat.h>
-#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/unistd.h>
 #include <linux/init.h>
index 3f2fce8ce6b628c5af3121cecd93c231c924d781..69d63d354ef05fac8f86a1ff69e98ddefdd93125 100644 (file)
@@ -18,7 +18,6 @@
 */
 #include <linux/types.h>
 #include <linux/spinlock.h>
-#include <linux/slab.h>
 
 #include <linux/kernel.h>
 #include <linux/module.h>
index 13b6e3e59b994762a7efb47483c4b144ca0c5feb..f4f4d700833affc00d9953871b441eae12227831 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/bootmem.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/pci.h>         /* for hppa_dma_ops and pcxl_dma_ops */
index 8a54eb8e37683d8ec1de947ccb51f3abf7672060..2e19500921f9fbdc33f40321ae34f648171faba0 100644 (file)
@@ -313,19 +313,6 @@ config 8XX_MINIMAL_FPEMU
 
          It is recommended that you build a soft-float userspace instead.
 
-config IOMMU_VMERGE
-       bool "Enable IOMMU virtual merging"
-       depends on PPC64
-       default y
-       help
-         Cause IO segments sent to a device for DMA to be merged virtually
-         by the IOMMU when they happen to have been allocated contiguously.
-         This doesn't add pressure to the IOMMU allocator. However, some
-         drivers don't support getting large merged segments coming back
-         from *_map_sg().
-
-         Most drivers don't have this problem; it is safe to say Y here.
-
 config IOMMU_HELPER
        def_bool PPC64
 
index ff9bdb28197db264036e02f4717f41c99efbb4e3..218d49b36a0ce3e0e538539826dbbefba940dd86 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 14:45:07 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:34:22 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -109,6 +104,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -340,7 +336,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -517,6 +512,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -684,6 +681,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=57600
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -714,6 +712,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -754,6 +753,7 @@ CONFIG_WATCHDOG=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
 # CONFIG_MPC5200_WDT is not set
 
 #
@@ -771,18 +771,20 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -813,7 +815,6 @@ CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
@@ -891,7 +892,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -903,7 +903,6 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -1009,6 +1008,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
index 7b3f4d0ed404d2f65d4325b979d0adcc64c827e9..90492ff25232aad737899f3b883ac53d97a22c49 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 14:45:09 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:34:24 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -95,11 +95,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -110,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -317,6 +313,7 @@ CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_HIBERNATION is not set
 # CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
 
@@ -333,7 +330,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -360,7 +356,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -457,6 +452,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -631,6 +628,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 CONFIG_PATA_MPC52xx=y
@@ -668,7 +666,7 @@ CONFIG_PATA_MPC52xx=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -768,6 +766,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -828,6 +827,7 @@ CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -879,6 +879,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -924,18 +925,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -944,6 +948,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1062,6 +1067,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
index eaae2d469aa0a84524208407e10df3e146848fcb..dffc8cac825fb72e4e108dfdf6f10d6a7decd005 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 14:45:08 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:34:23 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -109,6 +104,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -341,7 +337,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -518,6 +513,8 @@ CONFIG_MTD_ROM=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -699,6 +696,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -728,6 +726,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -773,10 +772,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_F71805F is not set
@@ -811,6 +811,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -831,6 +832,7 @@ CONFIG_WATCHDOG=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
 # CONFIG_MPC5200_WDT is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -843,18 +845,20 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1050,6 +1054,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
index 1742c0200b7543c9faef9450215136419b493628..3cb2a522046a9aac204099641b693604da6ab266 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 14:45:10 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:34:25 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,11 +97,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -326,7 +321,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -352,7 +346,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -525,6 +518,8 @@ CONFIG_MTD_PHYSMAP=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -610,6 +605,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 CONFIG_PATA_MPC52xx=m
@@ -647,7 +643,7 @@ CONFIG_PATA_MPC52xx=m
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -775,6 +771,7 @@ CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=9600
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -824,6 +821,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -870,18 +868,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -890,6 +891,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -997,7 +999,6 @@ CONFIG_USB_STORAGE=m
 # 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
@@ -1009,7 +1010,6 @@ CONFIG_USB_STORAGE=m
 # 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
 
 #
@@ -1172,6 +1172,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
index 3972438db719e17b9b505a052fa86d2c068a2a83..96181c62abfafe805cb39c61799dce5176daed15 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 14:45:09 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:34:24 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -109,6 +104,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -346,7 +342,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -524,6 +519,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -704,6 +701,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -733,6 +731,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -780,10 +779,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_F71805F is not set
@@ -818,6 +818,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -838,6 +839,7 @@ CONFIG_WATCHDOG=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
 # CONFIG_MPC5200_WDT is not set
 
 #
@@ -855,18 +857,20 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -897,7 +901,6 @@ CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
@@ -975,7 +978,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -987,7 +989,6 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -1151,6 +1152,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
index baa2bbb6c096a8bb120b6cb91638d777073ddcbe..04f16268e1c3c1c3a624a37be4a90a57ecb0fb34 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:14 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:38 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,14 +97,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -112,6 +106,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -124,7 +119,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -325,6 +320,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -336,7 +332,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -362,7 +357,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -543,6 +537,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -579,6 +575,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -596,6 +593,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -788,6 +786,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -836,6 +835,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -849,15 +849,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -883,10 +877,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -923,6 +918,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -971,18 +967,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -991,6 +990,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1083,7 +1083,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # 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
@@ -1096,7 +1095,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # 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
 
 #
@@ -1259,6 +1257,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1285,6 +1284,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 8b1aa806e548dc7f99dc8acbc3a0cb2adcaadcd5..1843ee11823baf7cdffd6a86a3af8f720101b5ba 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:14 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:39 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -98,7 +98,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
@@ -318,6 +317,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
@@ -346,7 +346,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -387,6 +386,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ATM is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 # CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=y
 # CONFIG_VLAN_8021Q_GVRP is not set
@@ -539,6 +539,8 @@ CONFIG_MTD_UBI_DEBUG=y
 # CONFIG_MTD_UBI_DEBUG_MSG_EBA is not set
 # CONFIG_MTD_UBI_DEBUG_MSG_WL is not set
 # CONFIG_MTD_UBI_DEBUG_MSG_IO is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -563,6 +565,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -690,6 +693,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -720,6 +724,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -732,15 +737,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -765,18 +764,20 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -805,8 +806,6 @@ CONFIG_SSB_POSSIBLE=y
 CONFIG_UIO=y
 # CONFIG_UIO_PDRV is not set
 # CONFIG_UIO_PDRV_GENIRQ is not set
-# CONFIG_UIO_SMX is not set
-# CONFIG_UIO_SERCOS3 is not set
 
 #
 # TI VLYNQ
@@ -887,6 +886,7 @@ CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_UBIFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -911,6 +911,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -976,6 +977,7 @@ CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_HAVE_FUNCTION_TRACER=y
index 2f2d98558e44da0592277114125d6803098bce32..78ae3bf1e9c5f797e234ed0fabf447fc6f616039 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:15 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:40 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -362,7 +357,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -556,6 +550,8 @@ CONFIG_MTD_NAND_FSL_ELBC=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -593,6 +589,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -612,6 +609,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -772,6 +770,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -824,6 +823,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -836,6 +837,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -931,6 +933,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -980,6 +983,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -993,15 +997,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
 # CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
@@ -1044,10 +1042,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1086,6 +1085,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1134,21 +1134,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 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_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1157,6 +1160,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1289,7 +1293,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1302,7 +1305,6 @@ CONFIG_USB_STORAGE=y
 # 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=y
 # CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
@@ -1341,6 +1343,7 @@ CONFIG_USB_ETH_RNDIS=y
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -1511,6 +1514,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1537,6 +1541,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 633e61194603f14717c4a2f84720e48605908d16..cccb71393acaf3073fee8e2f5d193f625dba4ebd 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:16 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:40 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -362,7 +357,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -556,6 +550,8 @@ CONFIG_MTD_NAND_IDS=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -593,6 +589,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -612,6 +609,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -735,6 +733,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -837,6 +836,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -889,6 +889,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -901,6 +903,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -996,6 +999,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1045,6 +1049,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1058,15 +1063,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
 # CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
@@ -1109,10 +1108,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1151,6 +1151,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1199,21 +1200,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 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_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1222,6 +1226,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1354,7 +1359,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1367,7 +1371,6 @@ CONFIG_USB_STORAGE=y
 # 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=y
 # CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
@@ -1406,6 +1409,7 @@ CONFIG_USB_ETH_RNDIS=y
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -1576,6 +1580,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1602,6 +1607,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 0b4262bd49175c5da64a0be5c032efb6ecc6f544..74cb27aa9d17457c2bfb8ed9dfb48735eef35893 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:17 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:41 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -325,6 +320,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -336,7 +332,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -362,7 +357,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -457,6 +451,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -492,6 +488,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -509,6 +506,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -693,6 +691,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -705,6 +705,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -790,6 +791,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -839,6 +841,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -851,15 +854,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -885,10 +882,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -925,6 +923,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -967,18 +966,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -987,6 +989,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1171,6 +1174,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1197,6 +1201,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 155af009f7b5a483b876ef3b29e04e769b24234c..10412a9c7f90667542f851e7a49fba92e19a3d3a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:18 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:42 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -325,6 +320,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -336,7 +332,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -362,7 +357,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -457,6 +451,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -494,6 +490,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -514,6 +511,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -700,6 +698,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -712,6 +712,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -808,6 +809,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -859,6 +861,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -872,15 +875,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
 CONFIG_SPI_MASTER=y
 
@@ -922,10 +919,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -964,6 +962,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1012,21 +1011,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 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_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1035,6 +1037,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1166,7 +1169,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1179,7 +1181,6 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -1204,8 +1205,6 @@ 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
@@ -1298,6 +1297,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1324,6 +1324,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index ff45f490448883499aea992b16d260741fefdafe..7b31fc3f354517f2ffdbf954e79ab6e72c1a2f15 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:19 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:43 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -540,6 +534,8 @@ CONFIG_MTD_PHYSMAP=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -577,6 +573,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -644,6 +641,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -767,6 +765,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -880,6 +879,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -892,6 +893,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -966,6 +968,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1015,6 +1018,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1028,15 +1032,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
 CONFIG_SPI_MASTER=y
 
@@ -1095,21 +1093,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 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_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1118,6 +1119,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1222,7 +1224,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1235,7 +1236,6 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -1399,6 +1399,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1425,6 +1426,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 28d8ff3e8fcaac69d79d7cf3a6bb26ffd9023af9..41401a9b355e1538a648f78bbe4c98e1964fde9b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:20 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:44 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -540,6 +534,8 @@ CONFIG_MTD_PHYSMAP=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -577,6 +573,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -596,6 +593,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -756,6 +754,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -768,6 +768,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -842,6 +843,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -891,6 +893,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -904,15 +907,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
 CONFIG_SPI_MASTER=y
 
@@ -971,21 +968,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 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_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -994,6 +994,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1098,7 +1099,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1111,7 +1111,6 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -1275,6 +1274,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1301,6 +1301,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 6252ab5bf1813b8c9d5d957c4ccd51f95c13cb1e..dc176b676dce0181f7b66c9e4ef9539131b9fa9a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:21 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:45 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -456,6 +450,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -491,6 +487,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -508,6 +505,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -580,6 +578,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -631,6 +630,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -643,6 +644,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -726,6 +728,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -774,6 +777,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -786,15 +790,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -820,10 +818,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -860,6 +859,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -902,18 +902,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -922,6 +925,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1106,6 +1110,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1132,6 +1137,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 78227378e67859e4d6ca363070488725728b704b..f512972c7176bda4466f2a6a8badb5878e33db6b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:21 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:46 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -323,6 +318,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -334,7 +330,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -360,7 +355,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -538,6 +532,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -573,6 +569,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -590,6 +587,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -774,6 +772,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -786,6 +786,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -871,6 +872,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -920,6 +922,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -932,15 +935,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -966,10 +963,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1006,6 +1004,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1048,18 +1047,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1068,6 +1070,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1253,6 +1256,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1279,6 +1283,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 9451d6e5c8024ded16162a929a864c3974ecba9a..77abfe8ff198bae92d96aabee588d6413a961931 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:23 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:47 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,14 +97,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -112,6 +106,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -124,7 +119,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -323,6 +318,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -336,7 +332,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -362,7 +357,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -550,6 +544,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -587,6 +583,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -606,6 +603,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -774,6 +772,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_SERIAL_QE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -825,6 +824,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -837,15 +837,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
 CONFIG_SPI_MASTER=y
 
@@ -876,14 +870,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -932,22 +930,27 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 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_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -956,6 +959,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1145,6 +1149,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1171,6 +1176,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index f67b70d0b29215fa5f705e0e044ece6e64d1a72a..0cdb41418d58d72ff827563ee2b98962738d7723 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:22 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:47 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -124,7 +119,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -456,6 +450,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -491,6 +487,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -508,6 +505,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -631,6 +629,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -755,6 +754,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -767,6 +768,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -851,6 +853,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -901,6 +904,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -913,15 +917,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -947,10 +945,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -987,6 +986,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1029,18 +1029,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1049,6 +1052,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1175,6 +1179,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1201,6 +1206,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index a84fd1194e2b0a372089f16f91443de1833042e0..e69ed1b61425310771d05e59e12691710fe61ee3 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:24 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:48 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -124,7 +119,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -451,6 +445,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -487,6 +483,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -504,6 +501,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -626,6 +624,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -850,6 +849,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -900,6 +900,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -913,15 +914,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -947,10 +942,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -987,6 +983,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1034,18 +1031,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1054,6 +1054,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1079,6 +1080,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1094,14 +1096,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1190,7 +1197,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # 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
@@ -1203,7 +1209,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # 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
 
 #
@@ -1297,6 +1302,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1323,6 +1329,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 72c2067137b974f90b51f0fa1e4ab803aeca6a05..56e3995d898f57af0c4f8a267a1d1e75b33241f7 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:25 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:49 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -322,6 +317,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -333,7 +329,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -359,7 +354,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -537,6 +531,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -573,6 +569,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -590,6 +587,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -812,6 +810,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -862,6 +861,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -875,15 +875,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -909,10 +903,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -949,6 +944,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -996,18 +992,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1016,6 +1015,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1140,7 +1140,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1153,7 +1152,6 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -1245,6 +1243,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1271,6 +1270,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 21dad38b156f175eab1ac55c15a2dfca863c1fac..f67a8d1cd0b06f3fc23835fc30d5f89f2a43666c 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:26 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:50 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,10 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -110,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -315,6 +318,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
 # CONFIG_PCI is not set
@@ -345,7 +349,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -522,6 +525,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_MDIO=y
@@ -575,6 +580,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -701,6 +707,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -732,6 +739,7 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
 
 #
@@ -915,6 +923,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -937,6 +946,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1036,6 +1046,7 @@ CONFIG_DEBUG_MUTEXES=y
 # 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
 CONFIG_SYSCTL_SYSCALL_CHECK=y
index 5db54cd274c69d94833b53bea36491935e670738..61b122a25cdb49eaa3fb858909c42fffb7dd88bb 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:27 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:51 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -316,6 +315,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
 # CONFIG_PCI is not set
@@ -346,7 +346,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -443,6 +442,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -477,6 +478,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -602,6 +604,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -788,6 +791,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -810,6 +814,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 76c7018c5cd21c872d7cbd6879a3ec51afff5c24..a5ceaa4b5e42a92047fdd6a3d2f60964a1b1279b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:28 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:52 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -319,6 +318,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -329,7 +329,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 CONFIG_PCI_DEBUG=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -358,7 +357,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -455,6 +453,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_MDIO=y
@@ -500,6 +500,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -609,6 +610,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -621,6 +624,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -700,6 +704,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -733,7 +738,9 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
@@ -793,6 +800,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -801,6 +810,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -927,6 +937,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -949,6 +960,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index fab8adacbf792c47d594505c0c57947e1514dd95..4adb4eba2d4fa31145cc0b9080b47b73fdd81973 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:29 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:53 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -317,6 +316,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -327,7 +327,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -356,7 +355,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -453,6 +451,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -552,6 +552,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -657,6 +658,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -669,6 +672,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -753,6 +757,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -817,6 +822,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -825,6 +831,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -951,6 +958,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -973,6 +981,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 8290385e9b94bcfe434021a3b658e7597a6a0767..3de8450cd551dd736ddf57513286277e637de014 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:29 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:54 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -314,6 +313,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -324,7 +324,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -352,7 +351,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -447,6 +445,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -491,6 +491,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -596,6 +597,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -608,6 +611,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -692,6 +696,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -756,6 +761,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -764,6 +770,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -856,6 +863,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -878,6 +886,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 2499b5ba71418871398e805861fd232eba72806b..bd467fe13932ea28fe24ae06a86df466ad538c5f 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:30 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:54 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -314,6 +313,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
 # CONFIG_PCI is not set
@@ -344,7 +344,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -441,6 +440,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -475,6 +476,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -600,6 +602,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -815,6 +818,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -837,6 +841,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index e2edb79cfd1a1d8905cc02b21993b861d2d0a79f..9803e031165cd7389525433ee60298ad74b0576e 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:31 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:55 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=16
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -319,6 +318,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -329,7 +329,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -355,7 +354,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -554,6 +552,8 @@ CONFIG_MTD_NAND_SOCRATES=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -591,6 +591,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -610,6 +611,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -867,6 +869,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -916,6 +919,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -929,15 +933,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
 CONFIG_SPI_MASTER=y
 
@@ -979,10 +977,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1021,6 +1020,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1050,21 +1050,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 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_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1073,6 +1076,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1180,6 +1184,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 # CONFIG_HID_A4TECH is not set
 # CONFIG_HID_APPLE is not set
 # CONFIG_HID_BELKIN is not set
@@ -1194,12 +1199,16 @@ CONFIG_USB_HID=y
 # CONFIG_HID_KENSINGTON is not set
 # CONFIG_HID_LOGITECH is not set
 # CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
 # CONFIG_HID_MONTEREY is not set
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_QUANTA is not set
 # CONFIG_HID_SAMSUNG is not set
 # CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
 # CONFIG_HID_SUNPLUS is not set
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1307,7 +1316,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1320,7 +1328,6 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -1491,6 +1498,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1515,6 +1523,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index ce313259df14a26c8d967644747da1dcec6c72a3..880ab7aaf2025090df45f1bafbbaa9799a29a461 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:32 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:56 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -324,6 +323,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -334,7 +334,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -363,7 +362,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -520,6 +518,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=m
@@ -563,6 +563,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -630,6 +631,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=m
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=m
 CONFIG_SCSI_DMA=y
@@ -817,6 +819,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -829,6 +833,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -947,6 +952,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1004,6 +1010,7 @@ CONFIG_I2C_ALGOBIT=m
 # CONFIG_I2C_MPC is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1017,15 +1024,9 @@ CONFIG_I2C_ALGOBIT=m
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -1041,14 +1042,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1081,10 +1086,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1122,6 +1128,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1155,9 +1162,10 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TPS65010 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
-# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1166,6 +1174,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 CONFIG_AGP=m
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 CONFIG_DRM=m
 # CONFIG_DRM_TDFX is not set
 # CONFIG_DRM_R128 is not set
@@ -1308,6 +1317,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=m
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1333,6 +1343,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 0824b46672296510e693aa4b27f8a2fe6bb61e31..230aa2fc06290246e17fe9efbc37993e3e99be45 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:33 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:57 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -315,6 +314,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -325,7 +325,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -351,7 +350,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -525,6 +523,8 @@ CONFIG_MTD_CFI_UTIL=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -560,6 +560,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -632,6 +633,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -704,6 +706,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -755,6 +758,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -767,6 +772,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -851,6 +857,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -902,6 +909,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -913,15 +921,9 @@ CONFIG_I2C_MPC=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -947,10 +949,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -987,6 +990,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1015,18 +1019,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1035,6 +1042,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1172,6 +1180,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1194,6 +1203,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 2137be4100ed4b7fb5c7ccf7eb0008c09b2fdc8f..dbe04b981b87118d88962abd845d033594f7bc15 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:34 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:58 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -318,6 +317,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -328,7 +328,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -354,7 +353,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -528,6 +526,8 @@ CONFIG_MTD_CFI_UTIL=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -564,6 +564,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -636,6 +637,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -708,6 +710,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -760,6 +763,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -772,6 +777,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -858,6 +864,7 @@ CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -912,6 +919,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -923,15 +931,9 @@ CONFIG_I2C_MPC=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -946,14 +948,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -986,10 +992,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1027,6 +1034,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1055,19 +1063,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1076,6 +1089,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1213,6 +1227,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1235,6 +1250,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 5cc89aac3fec9660626531db046813b121bacb9f..845efa79dd200bb7f12d2268b5179f756c7eaaff 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:35 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:59 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -324,6 +323,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -339,7 +339,6 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -368,7 +367,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -559,6 +557,8 @@ CONFIG_MTD_NAND_FSL_UPM=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -594,6 +594,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -611,6 +612,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -716,6 +718,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -728,6 +732,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -812,6 +817,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -860,6 +866,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -872,15 +879,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -906,10 +907,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -946,6 +948,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -974,18 +977,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -994,6 +1000,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1162,6 +1169,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1184,6 +1192,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index e7b9148e58cf648857cb32c729ebeca847e8ed8c..b958136a12f03119ddc0796633d4577a9f3548d7 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:36 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:00 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -318,6 +317,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -328,7 +328,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -354,7 +353,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -528,6 +526,8 @@ CONFIG_MTD_CFI_UTIL=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -564,6 +564,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -636,6 +637,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -708,6 +710,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -760,6 +763,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -772,6 +777,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -858,6 +864,7 @@ CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -912,6 +919,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -923,15 +931,9 @@ CONFIG_I2C_MPC=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -946,14 +948,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -986,10 +992,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1027,6 +1034,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1055,19 +1063,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1076,6 +1089,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1213,6 +1227,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1235,6 +1250,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index a998e401bbfc93b8b28a266f40dbb07754b41ca6..008bc97549274e07454b8bdf0f1f6badb1934bc0 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:36 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:01 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -318,6 +317,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -328,7 +328,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -354,7 +353,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -528,6 +526,8 @@ CONFIG_MTD_CFI_UTIL=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -564,6 +564,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -636,6 +637,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -708,6 +710,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -760,6 +763,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -772,6 +777,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -858,6 +864,7 @@ CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -912,6 +919,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -923,15 +931,9 @@ CONFIG_I2C_MPC=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -946,14 +948,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -986,10 +992,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1027,6 +1034,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1055,19 +1063,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1076,6 +1089,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1213,6 +1227,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1235,6 +1250,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index fc656af04ea1572de6ed96b6914855b1038d3c73..2cf80dba0286fc86fb82bfcc9f9e61f64df14585 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:37 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:01 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -69,6 +69,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -104,10 +108,8 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -115,6 +117,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -328,6 +331,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -343,7 +347,6 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 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
@@ -375,7 +378,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -600,6 +602,8 @@ CONFIG_MTD_NAND_FSL_UPM=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -637,6 +641,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -654,6 +659,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -777,6 +783,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -1004,6 +1011,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1053,6 +1061,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1066,15 +1075,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -1090,14 +1093,19 @@ CONFIG_GPIO_SYSFS=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 CONFIG_GPIO_PCA953X=y
+# CONFIG_GPIO_PCA953X_IRQ is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1130,10 +1138,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 CONFIG_SENSORS_DS1621=y
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1171,6 +1180,7 @@ CONFIG_SENSORS_LM90=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1218,19 +1228,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1239,6 +1254,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1271,6 +1287,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 # CONFIG_HID_A4TECH is not set
 # CONFIG_HID_APPLE is not set
 # CONFIG_HID_BELKIN is not set
@@ -1285,12 +1302,16 @@ CONFIG_USB_HID=y
 # CONFIG_HID_KENSINGTON is not set
 # CONFIG_HID_LOGITECH is not set
 # CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
 # CONFIG_HID_MONTEREY is not set
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_QUANTA is not set
 # CONFIG_HID_SAMSUNG is not set
 # CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
 # CONFIG_HID_SUNPLUS is not set
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1386,7 +1407,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1398,7 +1418,6 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -1423,11 +1442,11 @@ CONFIG_LEDS_GPIO_OF=y
 CONFIG_LEDS_PCA955X=y
 # CONFIG_LEDS_BD2802 is not set
 # CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_TRIGGERS=y
 
 #
 # LED Triggers
 #
-CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
@@ -1506,6 +1525,7 @@ CONFIG_RTC_DRV_CMOS=y
 #
 # CONFIG_RTC_DRV_GENERIC is not set
 CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
 
 #
 # DMA Devices
@@ -1614,6 +1634,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1641,6 +1662,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1851,6 +1873,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
index 622d84f48aba9f218796e134802bdd74592f48ec..183c59c6d8966a0c41469a178adbef50524a173e 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:43 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:07 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -102,11 +102,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -117,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -325,6 +321,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -340,13 +337,11 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
 CONFIG_PCMCIA=y
 # CONFIG_PCMCIA_LOAD_CIS is not set
-# CONFIG_PCMCIA_IOCTL is not set
 # CONFIG_CARDBUS is not set
 
 #
@@ -382,7 +377,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -592,6 +586,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -629,6 +625,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 CONFIG_DS1682=y
 # CONFIG_C2PORT is not set
 
@@ -695,6 +692,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -819,6 +817,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -1059,6 +1058,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1116,6 +1116,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1129,15 +1130,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -1152,14 +1147,18 @@ CONFIG_GPIO_SYSFS=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1192,10 +1191,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1233,6 +1233,7 @@ CONFIG_SENSORS_LM92=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1281,19 +1282,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1302,6 +1308,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1334,6 +1341,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1349,14 +1357,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1463,7 +1476,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1476,7 +1488,6 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -1560,28 +1571,17 @@ CONFIG_RTC_DRV_RX8581=y
 CONFIG_STAGING=y
 # CONFIG_STAGING_EXCLUDE_BUILD is not set
 # CONFIG_ET131X is not set
-# CONFIG_ME4000 is not set
-# CONFIG_MEILHAUS is not set
 # CONFIG_USB_IP_COMMON is not set
+# CONFIG_PRISM2_USB is not set
 # CONFIG_ECHO is not set
 # CONFIG_COMEDI is not set
 # CONFIG_ASUS_OLED is not set
-# CONFIG_ALTERA_PCIE_CHDMA is not set
-# CONFIG_INPUT_MIMIO is not set
+# CONFIG_R8187SE is not set
+# CONFIG_RTL8192SU is not set
+# CONFIG_RTL8192U is not set
+# CONFIG_RTL8192E is not set
 # CONFIG_TRANZPORT is not set
 
-#
-# Android
-#
-# CONFIG_ANDROID is not set
-# CONFIG_DST is not set
-# CONFIG_POHMELFS is not set
-# CONFIG_B3DFG is not set
-# CONFIG_IDE_PHISON is not set
-# CONFIG_PLAN9AUTH is not set
-# CONFIG_HECI is not set
-# CONFIG_USB_CPC is not set
-
 #
 # Qualcomm MSM Camera And Video
 #
@@ -1589,14 +1589,17 @@ CONFIG_STAGING=y
 #
 # Camera Sensor Selection
 #
-# CONFIG_HYPERV_STORAGE is not set
-# CONFIG_HYPERV_BLOCK is not set
-# CONFIG_HYPERV_NET is not set
+# CONFIG_INPUT_GPIO is not set
+# CONFIG_POHMELFS is not set
+# CONFIG_IDE_PHISON is not set
+# CONFIG_VT6655 is not set
+# CONFIG_VT6656 is not set
 CONFIG_VME_BUS=y
 
 #
 # VME Bridge Drivers
 #
+# CONFIG_VME_CA91CX42 is not set
 CONFIG_VME_TSI148=y
 
 #
@@ -1604,6 +1607,24 @@ CONFIG_VME_TSI148=y
 #
 # CONFIG_VME_USER is not set
 
+#
+# VME Board Drivers
+#
+# CONFIG_VMIVME_7805 is not set
+
+#
+# RAR Register Driver
+#
+# CONFIG_RAR_REGISTER is not set
+# CONFIG_IIO is not set
+# CONFIG_RAMZSWAP is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_STRIP is not set
+# CONFIG_PCMCIA_WAVELAN is not set
+# CONFIG_PCMCIA_NETWAVE is not set
+# CONFIG_DT3155 is not set
+# CONFIG_CRYSTALHD is not set
+
 #
 # File systems
 #
@@ -1693,6 +1714,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1719,6 +1741,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1864,6 +1887,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
index eb58dec11a6108695b502b1424dbf4587b964ada..1524d948a2ba2f952ff6d6961553054ec276bc72 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:41 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:05 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -102,11 +102,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -117,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -325,6 +321,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -340,13 +337,11 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
 CONFIG_PCMCIA=y
 # CONFIG_PCMCIA_LOAD_CIS is not set
-# CONFIG_PCMCIA_IOCTL is not set
 # CONFIG_CARDBUS is not set
 
 #
@@ -382,7 +377,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -592,6 +586,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -629,6 +625,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 CONFIG_DS1682=y
 # CONFIG_C2PORT is not set
 
@@ -695,6 +692,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -1001,6 +999,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1058,6 +1057,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1071,15 +1071,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -1094,14 +1088,18 @@ CONFIG_GPIO_SYSFS=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1134,10 +1132,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1175,6 +1174,7 @@ CONFIG_SENSORS_LM92=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1223,19 +1223,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1244,6 +1249,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1276,6 +1282,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1291,14 +1298,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1405,7 +1417,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1418,7 +1429,6 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -1590,6 +1600,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1616,6 +1627,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1761,6 +1773,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
index 62c2b81a4a8fad310c6f6abaf92dad9e75108972..767c204c060311f6c32549b4ee38f38296ced643 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:42 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:06 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -102,11 +102,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -117,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -326,6 +322,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -341,7 +338,6 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 CONFIG_PCI_DEBUG=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -369,7 +365,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -552,6 +547,7 @@ CONFIG_ATM_BR2684=m
 # CONFIG_ATM_BR2684_IPFILTER is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 # CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=m
 # CONFIG_VLAN_8021Q_GVRP is not set
@@ -728,6 +724,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -765,6 +763,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 CONFIG_DS1682=y
 # CONFIG_C2PORT is not set
 
@@ -782,6 +781,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -905,6 +905,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -1155,6 +1156,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1204,6 +1206,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1217,15 +1220,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -1241,14 +1238,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1281,10 +1282,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1322,6 +1324,7 @@ CONFIG_SENSORS_LM92=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1370,19 +1373,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1391,6 +1399,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1423,6 +1432,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1438,14 +1448,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1552,7 +1567,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1565,7 +1579,6 @@ CONFIG_USB_STORAGE=y
 # 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
 # CONFIG_USB_GADGET is not set
 
@@ -1650,29 +1663,29 @@ CONFIG_RTC_DRV_RX8581=y
 CONFIG_STAGING=y
 # CONFIG_STAGING_EXCLUDE_BUILD is not set
 # CONFIG_ET131X is not set
-# CONFIG_ME4000 is not set
-# CONFIG_MEILHAUS is not set
 # CONFIG_USB_IP_COMMON is not set
+# CONFIG_PRISM2_USB is not set
 # CONFIG_ECHO is not set
 # CONFIG_COMEDI is not set
 # CONFIG_ASUS_OLED is not set
-# CONFIG_ALTERA_PCIE_CHDMA is not set
-# CONFIG_INPUT_MIMIO is not set
+# CONFIG_R8187SE is not set
+# CONFIG_RTL8192SU is not set
+# CONFIG_RTL8192U is not set
+# CONFIG_RTL8192E is not set
 # CONFIG_TRANZPORT is not set
 
 #
-# Android
+# Qualcomm MSM Camera And Video
+#
+
+#
+# Camera Sensor Selection
 #
-# CONFIG_ANDROID is not set
-# CONFIG_DST is not set
+# CONFIG_INPUT_GPIO is not set
 # CONFIG_POHMELFS is not set
-# CONFIG_B3DFG is not set
 # CONFIG_IDE_PHISON is not set
-# CONFIG_PLAN9AUTH is not set
-# CONFIG_HECI is not set
 # CONFIG_VT6655 is not set
-# CONFIG_USB_CPC is not set
-# CONFIG_RDC_17F3101X is not set
+# CONFIG_VT6656 is not set
 CONFIG_VME_BUS=y
 
 #
@@ -1686,6 +1699,22 @@ CONFIG_VME_TSI148=y
 #
 # CONFIG_VME_USER is not set
 
+#
+# VME Board Drivers
+#
+# CONFIG_VMIVME_7805 is not set
+
+#
+# RAR Register Driver
+#
+# CONFIG_RAR_REGISTER is not set
+# CONFIG_IIO is not set
+# CONFIG_RAMZSWAP is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_STRIP is not set
+# CONFIG_DT3155 is not set
+# CONFIG_CRYSTALHD is not set
+
 #
 # File systems
 #
@@ -1772,6 +1801,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1798,6 +1828,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1870,7 +1901,7 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=m
+CONFIG_ZLIB_DEFLATE=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
@@ -2006,6 +2037,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
index aab3baebab8cbbb7e025546777c8afb77b5b1e27..55b9e4e867acede870365cee89c1f93a9b624e2d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:39 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:03 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,11 +97,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -112,6 +107,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -320,6 +316,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +332,6 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 CONFIG_PCI_DEBUG=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -362,7 +358,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -571,6 +566,8 @@ CONFIG_MTD_NAND_FSL_ELBC=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
@@ -605,6 +602,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -670,6 +668,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -792,6 +791,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -970,6 +970,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1017,6 +1018,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1029,15 +1031,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -1062,18 +1058,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1082,6 +1081,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1434,6 +1434,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1461,6 +1462,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 727a8c8d15b5309b10b4e74fef986f4e1e6dcfdc..1be38eb057832fbf0019ff7d4bf5d307917bcb4c 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:40 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:04 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,15 +97,11 @@ CONFIG_TREE_RCU=y
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
 # CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -116,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -326,6 +323,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -337,7 +335,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -365,7 +362,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -498,6 +494,8 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -534,6 +532,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -551,6 +550,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -675,6 +675,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -799,6 +800,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -811,6 +814,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -920,6 +924,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -968,6 +973,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -981,15 +987,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -1014,18 +1014,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1034,6 +1037,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1151,6 +1155,7 @@ CONFIG_SND_INTEL8X0=y
 CONFIG_SND_PPC=y
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
@@ -1170,6 +1175,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1185,14 +1191,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1300,7 +1311,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1313,7 +1323,6 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -1475,6 +1484,7 @@ CONFIG_BEFS_FS=m
 # CONFIG_BEFS_DEBUG is not set
 CONFIG_BFS_FS=m
 CONFIG_EFS_FS=m
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 CONFIG_VXFS_FS=m
@@ -1506,6 +1516,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1717,6 +1728,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
index 4fb04dd2cde3c05423d1f725f085c69958d39ffb..a63009457323cb87eff5d5a3b3b74b9a7a5a540b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:38 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:02 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -101,11 +101,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -116,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -327,6 +323,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -342,7 +339,6 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -369,7 +365,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -552,6 +547,7 @@ CONFIG_ATM_BR2684=m
 # CONFIG_ATM_BR2684_IPFILTER is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 # CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=m
 # CONFIG_VLAN_8021Q_GVRP is not set
@@ -733,6 +729,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -768,6 +766,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -785,6 +784,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -1024,6 +1024,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1074,6 +1075,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1086,15 +1088,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -1120,10 +1116,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1160,6 +1157,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1202,18 +1200,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1222,6 +1223,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1376,6 +1378,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1408,6 +1411,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
 CONFIG_SMB_FS=m
 CONFIG_SMB_NLS_DEFAULT=y
 CONFIG_SMB_NLS_REMOTE="cp437"
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1540,6 +1544,7 @@ CONFIG_DEBUG_INFO=y
 # 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
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1618,6 +1623,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
index 5c1dc768bbd80847f434cb0b958d892a35806f0c..9f89d5c9c0be129161fca939a0c232031ae8e232 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:23:58 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:22 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -91,11 +91,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -307,6 +302,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_FSL_SOC=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
@@ -336,7 +332,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -505,6 +500,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -516,6 +513,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -664,6 +662,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -802,6 +801,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -826,6 +826,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -924,6 +925,7 @@ CONFIG_DEBUG_INFO=y
 # 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
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
index 72137cd881da77144b57258d261b8bcee9eafba7..4ab6074db3cfbeebdf7f1e7b6ec07d2334909808 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:23:59 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:23 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -101,11 +101,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -121,6 +116,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -147,7 +143,6 @@ 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
@@ -158,7 +153,6 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
@@ -357,6 +351,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_PCI=y
@@ -365,7 +360,6 @@ 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
@@ -396,7 +390,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -527,6 +520,7 @@ CONFIG_IP_VS_PROTO_UDP=y
 CONFIG_IP_VS_PROTO_AH_ESP=y
 CONFIG_IP_VS_PROTO_ESP=y
 CONFIG_IP_VS_PROTO_AH=y
+# CONFIG_IP_VS_PROTO_SCTP is not set
 
 #
 # IPVS scheduler
@@ -630,6 +624,7 @@ CONFIG_ATM_BR2684=m
 # CONFIG_ATM_BR2684_IPFILTER is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 # CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=m
 # CONFIG_VLAN_8021Q_GVRP is not set
@@ -690,7 +685,6 @@ CONFIG_NET_SCH_FIFO=y
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_NET_TCPPROBE 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
@@ -833,6 +827,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=m
 CONFIG_OF_MDIO=y
@@ -867,6 +863,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=m
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=m
 CONFIG_SCSI_DMA=y
@@ -1179,6 +1176,7 @@ CONFIG_SERIAL_MPSC_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1231,6 +1229,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MV64XXX=m
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1244,15 +1243,9 @@ CONFIG_I2C_MV64XXX=m
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -1278,10 +1271,11 @@ CONFIG_SENSORS_ADM1026=m
 # CONFIG_SENSORS_ADM1029 is not set
 CONFIG_SENSORS_ADM1031=m
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 CONFIG_SENSORS_DS1621=m
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1318,6 +1312,7 @@ CONFIG_SENSORS_SMSC47M1=m
 # CONFIG_SENSORS_SMSC47M192 is not set
 CONFIG_SENSORS_SMSC47B397=m
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1369,9 +1364,9 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
-# CONFIG_AB3100_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1380,6 +1375,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1413,7 +1409,6 @@ CONFIG_USB=m
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
-CONFIG_USB_SUSPEND=y
 # CONFIG_USB_OTG is not set
 CONFIG_USB_MON=m
 # CONFIG_USB_WUSB is not set
@@ -1535,6 +1530,7 @@ CONFIG_USB_SERIAL_MCT_U232=m
 # CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
 # CONFIG_USB_SERIAL_QUALCOMM is not set
 # CONFIG_USB_SERIAL_SPCP8X5 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
@@ -1549,6 +1545,7 @@ CONFIG_USB_SERIAL_XIRCOM=m
 # CONFIG_USB_SERIAL_OPTION is not set
 CONFIG_USB_SERIAL_OMNINET=m
 # CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
 # CONFIG_USB_SERIAL_DEBUG is not set
 
 #
@@ -1561,7 +1558,6 @@ CONFIG_USB_EMI62=m
 CONFIG_USB_RIO500=m
 CONFIG_USB_LEGOTOWER=m
 CONFIG_USB_LCD=m
-# CONFIG_USB_BERRY_CHARGE is not set
 CONFIG_USB_LED=m
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1574,7 +1570,6 @@ CONFIG_USB_LED=m
 # CONFIG_USB_IOWARRIOR is not set
 CONFIG_USB_TEST=m
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 CONFIG_USB_ATM=m
 CONFIG_USB_SPEEDTOUCH=m
 # CONFIG_USB_CXACRU is not set
@@ -1611,6 +1606,7 @@ CONFIG_INFINIBAND_SRP=m
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
 
 #
 # DMA Devices
@@ -1714,6 +1710,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=m
 # CONFIG_SQUASHFS is not set
 CONFIG_VXFS_FS=m
@@ -1742,6 +1739,7 @@ CONFIG_SUNRPC_XPRT_RDMA=m
 CONFIG_RPCSEC_GSS_KRB5=y
 CONFIG_RPCSEC_GSS_SPKM3=m
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1817,7 +1815,7 @@ CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
 CONFIG_NLS_UTF8=m
 # CONFIG_DLM is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1833,9 +1831,11 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
@@ -1880,7 +1880,6 @@ CONFIG_DEBUG_SPINLOCK=y
 # CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_HIGHMEM=y
 CONFIG_DEBUG_BUGVERBOSE=y
@@ -1903,16 +1902,12 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # 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
index 79105413884e8e85a00ade7f92ec68278b8cf24f..81e904e9f392799854c9057677e6381f352549c0 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:23:59 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:24 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -298,6 +298,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
@@ -308,7 +309,6 @@ CONFIG_PCI_8260=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -335,7 +335,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -537,6 +536,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_MDIO=y
@@ -566,6 +567,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -671,6 +673,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -683,6 +687,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -737,6 +742,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -765,7 +771,9 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
@@ -804,6 +812,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -812,6 +822,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -869,6 +880,7 @@ CONFIG_AUTOFS4_FS=y
 #
 # Caches
 #
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
index 58f7ca71a59d93be9502d58e643b4665af4fe4e7..c5af46ef5f40a1dc074e9db224d2bedf8b972dbe 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:00 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:24 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -90,11 +90,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -306,6 +301,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_FSL_SOC=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
@@ -335,7 +331,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -504,6 +499,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -515,6 +512,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -616,6 +614,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -753,6 +752,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -777,6 +777,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 9a0c981277eb179b608ef97f0f0cfb7f56113226..588a2add393fa9e713f959c367c31a215a2fb55f 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:01 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:25 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,11 +96,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -116,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -328,6 +324,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -337,7 +334,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -364,7 +360,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -433,6 +428,7 @@ CONFIG_NF_CONNTRACK_TFTP=m
 CONFIG_NETFILTER_XTABLES=m
 # CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
 # CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_CT is not set
 # CONFIG_NETFILTER_XT_TARGET_DSCP is not set
 CONFIG_NETFILTER_XT_TARGET_HL=m
 # CONFIG_NETFILTER_XT_TARGET_MARK is not set
@@ -665,6 +661,8 @@ CONFIG_MTD_PHYSMAP=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
@@ -700,6 +698,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -717,6 +716,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -840,6 +840,7 @@ CONFIG_ATA_SFF=y
 CONFIG_PATA_IT821X=y
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -954,6 +955,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -966,6 +969,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -1082,6 +1086,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1131,6 +1136,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1144,15 +1150,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -1178,10 +1178,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1218,6 +1219,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1246,18 +1248,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1266,6 +1271,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1417,6 +1423,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=y
 # CONFIG_USB_SERIAL_NAVMAN is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
 # CONFIG_USB_SERIAL_QUALCOMM is not set
 # CONFIG_USB_SERIAL_SPCP8X5 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
@@ -1430,6 +1437,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=y
 # CONFIG_USB_SERIAL_OPTION is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
 # CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
 # CONFIG_USB_SERIAL_DEBUG is not set
 
 #
@@ -1442,7 +1450,6 @@ CONFIG_USB_SERIAL_FTDI_SIO=y
 # 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
@@ -1455,7 +1462,6 @@ CONFIG_USB_SERIAL_FTDI_SIO=y
 # 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
 
 #
@@ -1620,6 +1626,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1651,6 +1658,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1723,9 +1731,11 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_TEXTSEARCH=y
 CONFIG_TEXTSEARCH_KMP=m
 CONFIG_HAS_IOMEM=y
index 4c2c877f93631955870cb12c56a62f752b08f52c..0cbd56fe2e1e132e19f24360b6fbcd8753303e91 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:02 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:26 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -105,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -311,6 +312,7 @@ CONFIG_ISA_DMA_API=y
 #
 # CONFIG_ISA is not set
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
@@ -321,7 +323,6 @@ CONFIG_PCI_8260=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -348,7 +349,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -536,6 +536,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -570,6 +572,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -704,6 +707,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -769,14 +773,9 @@ CONFIG_I2C_CPM=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
 # 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
 
 #
@@ -790,14 +789,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -829,19 +832,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -850,6 +858,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -908,6 +917,7 @@ CONFIG_AUTOFS4_FS=y
 #
 # Caches
 #
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1100,6 +1110,7 @@ CONFIG_DEBUG_INFO=y
 # 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
 CONFIG_SYSCTL_SYSCALL_CHECK=y
index 9e090f2c7e36456316a0e7a60978674c1660ee20..c1be26151021154783b21fae5f4e0bba635b0b56 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:03 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:27 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -89,11 +89,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -104,6 +99,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -309,6 +305,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_FSL_SOC=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
@@ -337,7 +334,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -515,6 +511,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -542,6 +540,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -643,6 +642,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -801,6 +801,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -825,6 +826,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -892,6 +894,7 @@ CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
index 61cf73d0000fdc04cdb7e22cc7fecb93e4ccf8c3..7012ac0134f0d99655f618514138b257f9be28b9 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Wed Dec 30 15:08:52 2009
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 10 14:38:54 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,30 +96,37 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# 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
-# CONFIG_NAMESPACES is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS 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_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
-CONFIG_EMBEDDED=y
-# CONFIG_SYSCTL_SYSCALL is not set
-# CONFIG_KALLSYMS is not set
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -141,6 +148,7 @@ CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
@@ -320,6 +328,7 @@ CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_HIBERNATION is not set
 # CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
 
@@ -336,7 +345,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -363,7 +371,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -454,7 +461,9 @@ 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
+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
@@ -554,6 +563,8 @@ CONFIG_MTD_UBI_BEB_RESERVE=1
 # UBI debugging options
 #
 # CONFIG_MTD_UBI_DEBUG is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -732,6 +743,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 CONFIG_PATA_MPC52xx=y
@@ -770,7 +782,7 @@ CONFIG_PATA_PLATFORM=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -929,6 +941,7 @@ CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -981,6 +994,7 @@ CONFIG_I2C_ALGOBIT=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1010,9 +1024,9 @@ CONFIG_SPI_MASTER=y
 #
 # SPI Master Controller Drivers
 #
-# CONFIG_SPI_BITBANG is not set
-# CONFIG_SPI_GPIO is not set
-# CONFIG_SPI_MPC52xx is not set
+CONFIG_SPI_BITBANG=m
+CONFIG_SPI_GPIO=m
+CONFIG_SPI_MPC52xx=m
 CONFIG_SPI_MPC52xx_PSC=m
 # CONFIG_SPI_XILINX is not set
 # CONFIG_SPI_DESIGNWARE is not set
@@ -1036,14 +1050,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1080,10 +1098,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1123,6 +1142,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1147,6 +1167,7 @@ CONFIG_WATCHDOG=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
 # CONFIG_ALIM7101_WDT is not set
 # CONFIG_MPC5200_WDT is not set
 # CONFIG_WATCHDOG_RTAS is not set
@@ -1172,22 +1193,27 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 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_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1196,6 +1222,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 CONFIG_DRM=y
 # CONFIG_DRM_TDFX is not set
 # CONFIG_DRM_R128 is not set
@@ -1309,32 +1336,46 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
-# CONFIG_HID_APPLE is not set
+CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
 CONFIG_HID_CHERRY=y
-# CONFIG_HID_CHICONY is not set
+CONFIG_HID_CHICONY=y
 CONFIG_HID_CYPRESS=y
-# CONFIG_HID_DRAGONRISE is not set
+CONFIG_HID_DRAGONRISE=y
+# CONFIG_DRAGONRISE_FF 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
-# CONFIG_HID_MONTEREY is not set
+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_LOGIG940_FF is not set
+CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
+CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
-# CONFIG_HID_PANTHERLORD is not set
-# CONFIG_HID_PETALYNX is not set
-# CONFIG_HID_SAMSUNG is not set
-# CONFIG_HID_SONY is not set
-# CONFIG_HID_SUNPLUS is not set
-# CONFIG_HID_GREENASIA is not set
-# CONFIG_HID_SMARTJOYPLUS is not set
-# CONFIG_HID_TOPSEED is not set
-# CONFIG_HID_THRUSTMASTER is not set
-# CONFIG_HID_ZEROPLUS is not set
+CONFIG_HID_ORTEK=y
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
+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
@@ -1349,10 +1390,7 @@ CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
-# CONFIG_USB_OTG_WHITELIST is not set
-# CONFIG_USB_OTG_BLACKLIST_HUB is not set
 CONFIG_USB_MON=y
 # CONFIG_USB_WUSB is not set
 # CONFIG_USB_WUSB_CBAF is not set
@@ -1433,7 +1471,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1445,7 +1482,6 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -1636,6 +1672,7 @@ CONFIG_UBIFS_FS=m
 CONFIG_UBIFS_FS_LZO=y
 CONFIG_UBIFS_FS_ZLIB=y
 # CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1730,8 +1767,11 @@ CONFIG_CRC32=y
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_LZO_COMPRESS=m
-CONFIG_LZO_DECOMPRESS=m
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
@@ -1776,11 +1816,11 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
-# CONFIG_DEBUG_MEMORY_INIT 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
index 1315b775a6d2c2439131da713c5d4742f80ba294..27c63ceeb45a633feb5fefb57c290f22d470fdd2 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:04 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:28 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -109,6 +104,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -311,6 +307,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 # CONFIG_PPC_INDIRECT_PCI is not set
 CONFIG_PCI=y
@@ -319,7 +316,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -345,7 +341,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -440,6 +435,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -484,6 +481,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -605,6 +603,7 @@ CONFIG_SATA_MV=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -696,6 +695,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -750,6 +750,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -762,6 +764,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -846,6 +849,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -910,6 +914,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -918,6 +923,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1044,6 +1050,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1066,6 +1073,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 9073778d35751ce10803860f0e3616c1bb58e2ea..6875fb89377e06d021251015ac20b4be5b8cd63b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:05 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:29 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,8 +96,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -301,6 +300,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
@@ -311,7 +311,6 @@ CONFIG_PCI_8260=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -338,7 +337,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -540,6 +538,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_MDIO=y
@@ -569,6 +569,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -674,6 +675,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -686,6 +689,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -797,6 +801,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -825,7 +830,9 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
@@ -864,6 +871,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -872,6 +881,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -933,6 +943,7 @@ CONFIG_AUTOFS4_FS=y
 #
 # Caches
 #
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
index 05bec4835687100a88885871b68f420d254f8ae5..bbe5ae61d979190c0a828bd41be9e83dff99fdfa 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:06 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:30 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -98,14 +98,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +107,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -126,7 +121,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -331,6 +326,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -344,7 +340,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -370,7 +365,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -560,6 +554,8 @@ CONFIG_MTD_NAND_FSL_ELBC=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -597,6 +593,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -614,6 +611,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -712,7 +710,7 @@ CONFIG_ATA_SFF=y
 # 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_SIL=y
 # CONFIG_SATA_SIS is not set
 # CONFIG_SATA_ULI is not set
 # CONFIG_SATA_VIA is not set
@@ -737,6 +735,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -863,6 +862,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -875,6 +876,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -970,6 +972,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -980,8 +983,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_HW_RANDOM=y
 # CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
-CONFIG_GEN_RTC=y
-# CONFIG_GEN_RTC_X is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -1022,6 +1023,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1035,15 +1037,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -1058,14 +1054,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1098,10 +1098,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1139,6 +1140,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1186,19 +1188,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1207,6 +1214,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1232,6 +1240,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1247,14 +1256,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1344,7 +1358,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # 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
@@ -1357,7 +1370,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # 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
 
 #
@@ -1372,7 +1384,65 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 # CONFIG_EDAC is not set
-# CONFIG_RTC_CLASS 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=y
+# 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_BQ32K 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_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 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
@@ -1453,6 +1523,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1479,6 +1550,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 8f35f8049c9268f3d74c8fb649f83548c369d0e8..cfebef9f9123b6d0bf136e7d1ed894efb51801c9 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:06 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:31 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -103,14 +107,8 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -118,6 +116,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -334,6 +333,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -345,7 +345,6 @@ 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
@@ -376,7 +375,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -509,6 +507,8 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -546,6 +546,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -563,6 +564,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -687,6 +689,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -817,8 +820,11 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
+# CONFIG_IXGBEVF is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_VXGE is not set
@@ -829,6 +835,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -941,6 +948,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_SERIAL_QE=m
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -993,6 +1001,7 @@ CONFIG_I2C_CPM=m
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1006,15 +1015,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -1030,14 +1033,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1069,20 +1076,25 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_UCB1400_CORE is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1091,6 +1103,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1208,6 +1221,7 @@ CONFIG_SND_INTEL8X0=y
 CONFIG_SND_PPC=y
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
@@ -1227,6 +1241,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1242,14 +1257,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1358,7 +1378,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1371,7 +1390,6 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -1452,6 +1470,7 @@ CONFIG_RTC_DRV_CMOS=y
 #
 # CONFIG_RTC_DRV_GENERIC is not set
 CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
 
 #
 # DMA Devices
@@ -1554,6 +1573,7 @@ CONFIG_BEFS_FS=m
 # CONFIG_BEFS_DEBUG is not set
 CONFIG_BFS_FS=m
 CONFIG_EFS_FS=m
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 CONFIG_VXFS_FS=m
@@ -1585,6 +1605,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1730,6 +1751,7 @@ CONFIG_DEBUG_INFO=y
 # 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
 CONFIG_SYSCTL_SYSCALL_CHECK=y
index 8755ea3c7f5fbc82a1b93c1508686eec1062e5e9..f5451d80f19bd7da4e9091b49757368f5cff7e45 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:07 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:31 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -69,6 +69,10 @@ 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_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -100,18 +104,13 @@ CONFIG_TREE_RCU=y
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
 # CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -119,6 +118,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -338,6 +338,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -349,7 +350,6 @@ 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
@@ -380,7 +380,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -513,6 +512,8 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -550,6 +551,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -567,6 +569,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -691,6 +694,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -821,8 +825,11 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
+# CONFIG_IXGBEVF is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_VXGE is not set
@@ -833,6 +840,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -945,6 +953,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_SERIAL_QE=m
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -997,6 +1006,7 @@ CONFIG_I2C_CPM=m
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1010,15 +1020,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -1034,14 +1038,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1073,20 +1081,25 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_UCB1400_CORE is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1095,6 +1108,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1212,6 +1226,7 @@ CONFIG_SND_INTEL8X0=y
 CONFIG_SND_PPC=y
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
@@ -1231,6 +1246,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1246,14 +1262,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1362,7 +1383,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1375,7 +1395,6 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -1456,6 +1475,7 @@ CONFIG_RTC_DRV_CMOS=y
 #
 # CONFIG_RTC_DRV_GENERIC is not set
 CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
 
 #
 # DMA Devices
@@ -1558,6 +1578,7 @@ CONFIG_BEFS_FS=m
 # CONFIG_BEFS_DEBUG is not set
 CONFIG_BFS_FS=m
 CONFIG_EFS_FS=m
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 CONFIG_VXFS_FS=m
@@ -1589,6 +1610,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1734,6 +1756,7 @@ CONFIG_DEBUG_INFO=y
 # 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
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1806,6 +1829,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=y
index 3f6b11b6f4f395d12efb90a961063eac68628d80..d8d3d1d60c8486b2d5f63e9c28378df1983eba42 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:08 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:32 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -89,14 +89,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -305,6 +299,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_FSL_SOC=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
@@ -333,7 +328,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -425,6 +419,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -456,6 +452,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -607,6 +604,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -795,6 +793,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -819,6 +818,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 41884c97a4f36fadd8d0bb69adf1dac67cb1df3a..624eae9a7e20edc5de67fff1c6ebc05fde0ccad4 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:09 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:33 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -98,18 +98,13 @@ CONFIG_TREE_RCU=y
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
 # CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -117,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -328,6 +324,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -339,7 +336,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -367,7 +363,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -500,6 +495,8 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -537,6 +534,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -554,6 +552,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -678,6 +677,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -802,6 +802,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -814,6 +816,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -923,6 +926,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -972,6 +976,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -985,15 +990,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -1009,14 +1008,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1048,20 +1051,25 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_UCB1400_CORE is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1070,6 +1078,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1187,6 +1196,7 @@ CONFIG_SND_INTEL8X0=y
 CONFIG_SND_PPC=y
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
@@ -1206,6 +1216,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1221,14 +1232,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1336,7 +1352,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1349,7 +1364,6 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -1512,6 +1526,7 @@ CONFIG_BEFS_FS=m
 # CONFIG_BEFS_DEBUG is not set
 CONFIG_BFS_FS=m
 CONFIG_EFS_FS=m
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 CONFIG_VXFS_FS=m
@@ -1543,6 +1558,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1754,6 +1770,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
index 6b9e6bd2c98d4a7bcf306aac773ee5fee2a9a22e..45bd499630d03c1aff75063c5b41d10c39b057fc 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:10 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:34 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -90,14 +90,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -313,6 +307,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_FSL_SOC=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
@@ -342,7 +337,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -515,6 +509,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -526,6 +522,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -627,6 +624,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -764,6 +762,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -788,6 +787,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 5d06f2cb8e5e074dbcdaa1c617c1368ce0a916d8..68c175ea427a465dbb53ace458d40cc320fc781f 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:11 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:35 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -105,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -304,6 +305,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
@@ -315,7 +317,6 @@ CONFIG_PCI_8260=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -342,7 +343,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -544,6 +544,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_MDIO=y
@@ -629,6 +631,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -734,6 +737,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -746,6 +751,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -859,6 +865,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -887,7 +894,9 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
@@ -926,6 +935,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -934,6 +945,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -996,6 +1008,7 @@ CONFIG_USB_ETH_RNDIS=y
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -1051,6 +1064,7 @@ CONFIG_AUTOFS4_FS=y
 #
 # Caches
 #
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
index 57ab5748a34d7e0b33611e98c135e07f67654dcf..93f4505b5ac2a1334c1344438b6db9b40fa216f8 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:12 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:36 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,11 +97,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -117,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -319,6 +315,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_PCI=y
@@ -327,7 +324,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -354,7 +350,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -533,6 +528,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -569,6 +566,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -640,6 +638,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -761,6 +760,7 @@ CONFIG_SATA_MV=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -854,6 +854,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -907,6 +908,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -919,6 +922,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -1016,6 +1020,7 @@ CONFIG_SERIAL_MPSC_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1065,6 +1070,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MV64XXX=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1077,15 +1083,9 @@ CONFIG_I2C_MV64XXX=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -1111,10 +1111,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1151,6 +1152,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1179,18 +1181,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1199,6 +1204,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1231,6 +1237,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1247,14 +1254,19 @@ CONFIG_HID_KENSINGTON=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 CONFIG_HID_NTRIG=y
+CONFIG_HID_ORTEK=y
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 CONFIG_HID_GREENASIA=y
 # CONFIG_GREENASIA_FF is not set
@@ -1350,7 +1362,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # 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
@@ -1363,7 +1374,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # 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
 
 #
@@ -1516,6 +1526,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1538,6 +1549,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1620,9 +1632,11 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
index 32f7058bb1738d87f42b4108e6312e247c9143bb..3808bc2be86f7c1ebc8b09031f9ef1221ae3bc05 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc7
-# Mon Aug 24 17:38:50 2009
+# Linux kernel version: 2.6.34-rc4
+# Thu Apr 15 11:32:15 2010
 #
 CONFIG_PPC64=y
 
@@ -9,6 +9,7 @@ CONFIG_PPC64=y
 # Processor support
 #
 CONFIG_PPC_BOOK3S_64=y
+# CONFIG_PPC_BOOK3E_64 is not set
 CONFIG_PPC_BOOK3S=y
 # CONFIG_POWER4_ONLY is not set
 CONFIG_POWER3=y
@@ -35,7 +36,9 @@ 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_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -60,6 +63,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -86,14 +90,15 @@ 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_TINY_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_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
@@ -108,6 +113,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -128,21 +134,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 is not set
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
-CONFIG_MARKERS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
@@ -154,12 +158,14 @@ 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_SLOW_WORK_DEBUG is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -180,14 +186,41 @@ 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_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -226,7 +259,6 @@ CONFIG_PPC_CELL=y
 #
 CONFIG_SPU_FS=m
 CONFIG_SPU_FS_64K_LS=y
-# CONFIG_SPU_TRACE is not set
 CONFIG_SPU_BASE=y
 # CONFIG_PQ2ADS is not set
 # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
@@ -267,7 +299,6 @@ CONFIG_COMPAT_BINFMT_ELF=y
 # CONFIG_HAVE_AOUT is not set
 CONFIG_BINFMT_MISC=y
 CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y
-# CONFIG_IOMMU_VMERGE is not set
 CONFIG_IOMMU_HELPER=y
 # CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
@@ -276,12 +307,15 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
 # CONFIG_IRQ_ALL_CPUS is not set
+CONFIG_SPARSE_IRQ=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_SPARSEMEM_DEFAULT=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -295,13 +329,12 @@ CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTPLUG_SPARSE=y
 # CONFIG_MEMORY_HOTREMOVE is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 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_ARCH_MEMORY_PROBE=y
 CONFIG_PPC_HAS_HASH_64K=y
@@ -312,11 +345,15 @@ CONFIG_PPC_4K_PAGES=y
 CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_SCHED_SMT=y
 CONFIG_PROC_DEVICETREE=y
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE=""
 CONFIG_EXTRA_TARGETS=""
 CONFIG_PM=y
 CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
 # CONFIG_PM_VERBOSE is not set
+# CONFIG_HIBERNATION is not set
+# CONFIG_PM_RUNTIME is not set
 # CONFIG_SECCOMP is not set
 CONFIG_ISA_DMA_API=y
 
@@ -324,6 +361,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_PCI_CHOICE=y
 # CONFIG_PCI is not set
@@ -337,12 +375,12 @@ 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=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -392,6 +430,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -400,6 +439,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
@@ -422,7 +462,6 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # 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
@@ -445,27 +484,30 @@ CONFIG_BT_HCIBTUSB=m
 # CONFIG_BT_HCIBPA10X is not set
 # CONFIG_BT_HCIBFUSB is not set
 # CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+# CONFIG_BT_ATH3K is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
 CONFIG_CFG80211=m
+# 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_DEBUGFS is not set
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
 # CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_LIB80211 is not set
 CONFIG_MAC80211=m
-CONFIG_MAC80211_DEFAULT_PS=y
-CONFIG_MAC80211_DEFAULT_PS_VALUE=1
-
-#
-# Rate control algorithm selection
-#
 CONFIG_MAC80211_RC_PID=y
 # CONFIG_MAC80211_RC_MINSTREL is not set
 CONFIG_MAC80211_RC_DEFAULT_PID=y
 # CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
 CONFIG_MAC80211_RC_DEFAULT="pid"
+# CONFIG_MAC80211_MESH is not set
 # CONFIG_MAC80211_LEDS is not set
 # CONFIG_MAC80211_DEBUGFS is not set
 # CONFIG_MAC80211_DEBUG_MENU is not set
@@ -481,6 +523,7 @@ CONFIG_MAC80211_RC_DEFAULT="pid"
 # 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
@@ -491,6 +534,8 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
@@ -498,6 +543,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
@@ -521,6 +570,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -590,30 +640,27 @@ CONFIG_MII=m
 # 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_NETDEV_1000=y
 CONFIG_GELIC_NET=y
 CONFIG_GELIC_WIRELESS=y
 # CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-CONFIG_WLAN_80211=y
-# CONFIG_LIBERTAS is not set
+CONFIG_WLAN=y
 # CONFIG_LIBERTAS_THINFIRM is not set
 # CONFIG_AT76C50X_USB is not set
 # CONFIG_USB_ZD1201 is not set
 # CONFIG_USB_NET_RNDIS_WLAN is not set
 # CONFIG_RTL8187 is not set
 # CONFIG_MAC80211_HWSIM is not set
-# CONFIG_P54_COMMON is not set
-# CONFIG_AR9170_USB is not set
-# CONFIG_HOSTAP is not set
+# CONFIG_ATH_COMMON is not set
 # CONFIG_B43 is not set
 # CONFIG_B43LEGACY is not set
-# CONFIG_ZD1211RW is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_P54_COMMON is not set
 # CONFIG_RT2X00 is not set
+# CONFIG_WL12XX is not set
+# CONFIG_ZD1211RW is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -631,6 +678,7 @@ CONFIG_USB_NET_AX8817X=m
 # CONFIG_USB_NET_CDCETHER is not set
 # CONFIG_USB_NET_CDC_EEM is not set
 # CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_SMSC75XX is not set
 # CONFIG_USB_NET_SMSC95XX is not set
 # CONFIG_USB_NET_GL620A is not set
 # CONFIG_USB_NET_NET1080 is not set
@@ -665,6 +713,7 @@ CONFIG_SLHC=m
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -712,6 +761,8 @@ CONFIG_DEVKMEM=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -735,7 +786,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
 
@@ -841,13 +891,13 @@ CONFIG_SND_PS3=m
 CONFIG_SND_PS3_DEFAULT_START_DELAY=2000
 CONFIG_SND_USB=y
 CONFIG_SND_USB_AUDIO=m
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
 # CONFIG_SOUND_PRIME is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 CONFIG_HIDRAW=y
 
 #
@@ -866,6 +916,7 @@ CONFIG_USB_HIDDEV=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 # CONFIG_HID_A4TECH is not set
 CONFIG_HID_APPLE=m
 CONFIG_HID_BELKIN=m
@@ -876,17 +927,24 @@ CONFIG_HID_CHERRY=m
 CONFIG_HID_EZKEY=m
 # CONFIG_HID_KYE is not set
 # CONFIG_HID_GYRATION is not set
+CONFIG_HID_TWINHAN=m
 # CONFIG_HID_KENSINGTON is not set
 CONFIG_HID_LOGITECH=m
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_HID_MAGICMOUSE is not set
 CONFIG_HID_MICROSOFT=m
+# CONFIG_HID_MOSART is not set
 # CONFIG_HID_MONTEREY is not set
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_QUANTA is not set
 # CONFIG_HID_SAMSUNG is not set
 CONFIG_HID_SONY=m
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=m
 # CONFIG_HID_GREENASIA is not set
 CONFIG_HID_SMARTJOYPLUS=m
@@ -901,7 +959,7 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=m
 # CONFIG_USB_DEBUG is not set
-# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 
 #
 # Miscellaneous USB options
@@ -909,7 +967,6 @@ CONFIG_USB=m
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
-CONFIG_USB_SUSPEND=y
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
@@ -923,12 +980,13 @@ CONFIG_USB_MON=m
 # CONFIG_USB_C67X00_HCD is not set
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_TT_NEWSCHED=y
 CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=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=m
 # CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
 # CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
@@ -995,7 +1053,6 @@ CONFIG_USB_STORAGE=m
 # 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
@@ -1008,7 +1065,6 @@ CONFIG_USB_STORAGE=m
 # 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
 
 #
@@ -1048,7 +1104,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1077,10 +1135,10 @@ CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
 CONFIG_EXT4_FS=y
-# 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=m
 # CONFIG_JBD_DEBUG is not set
 CONFIG_JBD2=y
@@ -1093,6 +1151,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
@@ -1154,6 +1213,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1164,7 +1224,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
@@ -1181,6 +1240,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1237,7 +1297,7 @@ 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
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1270,6 +1330,7 @@ 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
@@ -1292,6 +1353,7 @@ CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
 CONFIG_DEBUG_LOCK_ALLOC=y
 CONFIG_PROVE_LOCKING=y
+# CONFIG_PROVE_RCU is not set
 CONFIG_LOCKDEP=y
 # CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_LOCKDEP=y
@@ -1308,26 +1370,27 @@ CONFIG_DEBUG_MEMORY_INIT=y
 CONFIG_DEBUG_LIST=y
 # 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_LKDTM 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_TRACING=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=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_KGDB is not set
@@ -1352,13 +1415,16 @@ CONFIG_IRQSTACKS=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 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
@@ -1374,6 +1440,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 CONFIG_CRYPTO_GF128MUL=m
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
@@ -1402,11 +1469,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=m
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
index f2f832161463266198abd8e2ae19debb08280bc6..b1625801526e8fbc901775b53a9a763aed74d3ca 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:13 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:37 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -314,6 +309,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -323,7 +319,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -349,7 +344,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=m
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -524,6 +518,8 @@ CONFIG_MTD_PHYSMAP=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
@@ -555,6 +551,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -626,6 +623,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -846,6 +844,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -895,6 +894,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -908,15 +908,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -941,18 +935,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -961,6 +958,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1071,7 +1069,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1084,7 +1081,6 @@ CONFIG_USB_STORAGE=y
 # 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
 
 #
@@ -1251,6 +1247,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
index c1b475a941eb9d08a272f6b378cfdfa7d14cdf9c..a9b91ed3d4b9e17ae8494e17ba498d19aa43a89c 100644 (file)
@@ -28,6 +28,7 @@
 #define PPC_LLARX(t, a, b, eh) PPC_LDARX(t, a, b, eh)
 #define PPC_STLCX      stringify_in_c(stdcx.)
 #define PPC_CNTLZL     stringify_in_c(cntlzd)
+#define PPC_LR_STKOFF  16
 
 /* Move to CR, single-entry optimized version. Only available
  * on POWER4 and later.
@@ -51,6 +52,7 @@
 #define PPC_STLCX      stringify_in_c(stwcx.)
 #define PPC_CNTLZL     stringify_in_c(cntlzw)
 #define PPC_MTOCRF     stringify_in_c(mtcrf)
+#define PPC_LR_STKOFF  4
 
 #endif
 
index 9f4c9d4f5803d10638b159abf8202e4283e5bca6..bd100fcf40d0c1263e81e5d737e2ec6cfc32b025 100644 (file)
@@ -130,43 +130,5 @@ static inline int irqs_disabled_flags(unsigned long flags)
  */
 struct irq_chip;
 
-#ifdef CONFIG_PERF_EVENTS
-
-#ifdef CONFIG_PPC64
-static inline unsigned long test_perf_event_pending(void)
-{
-       unsigned long x;
-
-       asm volatile("lbz %0,%1(13)"
-               : "=r" (x)
-               : "i" (offsetof(struct paca_struct, perf_event_pending)));
-       return x;
-}
-
-static inline void set_perf_event_pending(void)
-{
-       asm volatile("stb %0,%1(13)" : :
-               "r" (1),
-               "i" (offsetof(struct paca_struct, perf_event_pending)));
-}
-
-static inline void clear_perf_event_pending(void)
-{
-       asm volatile("stb %0,%1(13)" : :
-               "r" (0),
-               "i" (offsetof(struct paca_struct, perf_event_pending)));
-}
-#endif /* CONFIG_PPC64 */
-
-#else  /* CONFIG_PERF_EVENTS */
-
-static inline unsigned long test_perf_event_pending(void)
-{
-       return 0;
-}
-
-static inline void clear_perf_event_pending(void) {}
-#endif /* CONFIG_PERF_EVENTS */
-
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_HW_IRQ_H */
index e96d52a516ba1bac8c0180a3eb75758bf55b919b..53b64be40eb29f2cc4f2aee6eba2ae5f93d4b470 100644 (file)
@@ -108,8 +108,21 @@ extern phys_addr_t kernstart_addr;
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
 #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 
-#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - MEMORY_START))
+/*
+ * On Book-E parts we need __va to parse the device tree and we can't
+ * determine MEMORY_START until then.  However we can determine PHYSICAL_START
+ * from information at hand (program counter, TLB lookup).
+ *
+ * On non-Book-E PPC64 PAGE_OFFSET and MEMORY_START are constants so use
+ * the other definitions for __va & __pa.
+ */
+#ifdef CONFIG_BOOKE
+#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) - PHYSICAL_START + KERNELBASE))
+#define __pa(x) ((unsigned long)(x) + PHYSICAL_START - KERNELBASE)
+#else
+#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) + PAGE_OFFSET - MEMORY_START))
 #define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + MEMORY_START)
+#endif
 
 /*
  * Unfortunately the PLT is in the BSS in the PPC32 ELF ABI,
index aea71479759030651b24361b7eb965fefa65772c..d553bbeb726c1c0f1c6bda61455bfe3006400f25 100644 (file)
@@ -25,7 +25,7 @@
 #define PPC_INST_LDARX                 0x7c0000a8
 #define PPC_INST_LSWI                  0x7c0004aa
 #define PPC_INST_LSWX                  0x7c00042a
-#define PPC_INST_LWARX                 0x7c000029
+#define PPC_INST_LWARX                 0x7c000028
 #define PPC_INST_LWSYNC                        0x7c2004ac
 #define PPC_INST_LXVD2X                        0x7c000698
 #define PPC_INST_MCRXR                 0x7c000400
@@ -62,8 +62,8 @@
 #define __PPC_T_TLB(t) (((t) & 0x3) << 21)
 #define __PPC_WC(w)    (((w) & 0x3) << 21)
 /*
- * Only use the larx hint bit on 64bit CPUs. Once we verify it doesn't have
- * any side effects on all 32bit processors, we can do this all the time.
+ * Only use the larx hint bit on 64bit CPUs. e500v1/v2 based CPUs will treat a
+ * larx with EH set as an illegal instruction.
  */
 #ifdef CONFIG_PPC64
 #define __PPC_EH(eh)   (((eh) & 0x1) << 0)
index efa7f0b879f3156345bda9d6ccfa258b1ecb382f..23913e902fc3c50c4307514c159c53db9e7d004d 100644 (file)
@@ -30,7 +30,7 @@ static inline void syscall_rollback(struct task_struct *task,
 static inline long syscall_get_error(struct task_struct *task,
                                     struct pt_regs *regs)
 {
-       return (regs->ccr & 0x1000) ? -regs->gpr[3] : 0;
+       return (regs->ccr & 0x10000000) ? -regs->gpr[3] : 0;
 }
 
 static inline long syscall_get_return_value(struct task_struct *task,
@@ -44,10 +44,10 @@ static inline void syscall_set_return_value(struct task_struct *task,
                                            int error, long val)
 {
        if (error) {
-               regs->ccr |= 0x1000L;
+               regs->ccr |= 0x10000000L;
                regs->gpr[3] = -error;
        } else {
-               regs->ccr &= ~0x1000L;
+               regs->ccr &= ~0x10000000L;
                regs->gpr[3] = val;
        }
 }
index 957ceb7059c57a8a2bd7c5ffd9330a361baaf160..c09138d150d41eae784608074aa1416ff40265d5 100644 (file)
@@ -133,7 +133,6 @@ int main(void)
        DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr));
        DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
        DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled));
-       DEFINE(PACAPERFPEND, offsetof(struct paca_struct, perf_event_pending));
        DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
 #ifdef CONFIG_PPC_MM_SLICES
        DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct,
index 01fe9ce28379a5bc6bb6738775f5a14c41f43884..a3c684b4c8626a1092875c9bd361245e21411f30 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/notifier.h>
 #include <linux/of.h>
 #include <linux/percpu.h>
+#include <linux/slab.h>
 #include <asm/prom.h>
 
 #include "cacheinfo.h"
index 59c928564a038e490e260fb28862f022659d4d6f..4ff4da2c238bcd8585775cb4f2cb1432b89330c4 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * Contains routines needed to support swiotlb for ppc.
  *
- * Copyright (C) 2009 Becky Bruce, Freescale Semiconductor
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc.
+ * Author: Becky Bruce
  *
  * 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
@@ -70,7 +71,7 @@ static int ppc_swiotlb_bus_notify(struct notifier_block *nb,
        sd->max_direct_dma_addr = 0;
 
        /* May need to bounce if the device can't address all of DRAM */
-       if (dma_get_mask(dev) < lmb_end_of_DRAM())
+       if ((dma_get_mask(dev) + 1) < lmb_end_of_DRAM())
                set_dma_ops(dev, &swiotlb_dma_ops);
 
        return NOTIFY_DONE;
index 6215062caf8cfed39e66cb162339204340c1aad8..6c1df5757cd6e1a260a96557f5d9f7ea1f807f94 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-debug.h>
+#include <linux/gfp.h>
 #include <linux/lmb.h>
 #include <asm/bug.h>
 #include <asm/abs_addr.h>
index 07109d843787118dba501c5b9bb383912348417b..42e9d908914a0e47117cfe7f3dcc5fe50d215d98 100644 (file)
@@ -556,15 +556,6 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
 2:
        TRACE_AND_RESTORE_IRQ(r5);
 
-#ifdef CONFIG_PERF_EVENTS
-       /* check paca->perf_event_pending if we're enabling ints */
-       lbz     r3,PACAPERFPEND(r13)
-       and.    r3,r3,r5
-       beq     27f
-       bl      .perf_event_do_pending
-27:
-#endif /* CONFIG_PERF_EVENTS */
-
        /* extract EE bit and use it to restore paca->hard_enabled */
        ld      r3,_MSR(r1)
        rldicl  r4,r3,49,63             /* r0 = (r3 >> 15) & 1 */
index 25793bb0e7828ad5c60ff550bbb19ec832e8a30d..725526547994d76ce6386d23d8398946357c6291 100644 (file)
@@ -746,9 +746,6 @@ finish_tlb_load:
        rlwimi  r12, r11, 32-19, 27, 31 /* extract WIMGE from pte */
 #else
        rlwimi  r12, r11, 26, 27, 31    /* extract WIMGE from pte */
-#endif
-#ifdef CONFIG_SMP
-       ori     r12, r12, MAS2_M
 #endif
        mtspr   SPRN_MAS2, r12
 
@@ -887,13 +884,17 @@ KernelSPE:
        lwz     r3,_MSR(r1)
        oris    r3,r3,MSR_SPE@h
        stw     r3,_MSR(r1)     /* enable use of SPE after return */
+#ifdef CONFIG_PRINTK
        lis     r3,87f@h
        ori     r3,r3,87f@l
        mr      r4,r2           /* current */
        lwz     r5,_NIP(r1)
        bl      printk
+#endif
        b       ret_from_except
+#ifdef CONFIG_PRINTK
 87:    .string "SPE used in kernel  (task=%p, pc=%x)  \n"
+#endif
        .align  4,0
 
 #endif /* CONFIG_SPE */
index a4c8b38b0ba1f7bed97d9788e80a78f9447a3cc2..71cf280da1847f3255a71d0bb9b9cf439b5852f8 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/of.h>
+#include <linux/slab.h>
 #include <linux/of_platform.h>
 #include <asm/ibmebus.h>
 #include <asm/abs_addr.h>
index 5547ae6e6b0be605e293ae42c49dab911782f568..ec94f906ea43a7dd6729a518d852d8e9879480ed 100644 (file)
 
 #define DBG(...)
 
-#ifdef CONFIG_IOMMU_VMERGE
-static int novmerge = 0;
-#else
-static int novmerge = 1;
-#endif
-
+static int novmerge;
 static int protect4gb = 1;
 
 static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned int);
index 64f6f2031c226901dc54105c7a0f433566e2846d..066bd31551d5414fb0a7a43ed85964c64665f042 100644 (file)
@@ -53,7 +53,6 @@
 #include <linux/bootmem.h>
 #include <linux/pci.h>
 #include <linux/debugfs.h>
-#include <linux/perf_event.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -145,11 +144,6 @@ notrace void raw_local_irq_restore(unsigned long en)
        }
 #endif /* CONFIG_PPC_STD_MMU_64 */
 
-       if (test_perf_event_pending()) {
-               clear_perf_event_pending();
-               perf_event_do_pending();
-       }
-
        /*
         * if (get_paca()->hard_enabled) return;
         * But again we need to take care that gcc gets hard_enabled directly
index 3fd1af90211236dfad7b488206bdf0b7214deaf3..b36f074524adc48e81f72a9853d90d0287f7354e 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/preempt.h>
 #include <linux/module.h>
 #include <linux/kdebug.h>
+#include <linux/slab.h>
 #include <asm/cacheflush.h>
 #include <asm/sstep.h>
 #include <asm/uaccess.h>
index d09d1c615150bcd61b79bae01b0168f5d788d68c..c2c70e1b32cd25eacb691497b6a572c645efe16f 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/iseries/hv_lp_config.h>
 #include <asm/lppaca.h>
index 2d29752cbe169ea9398fbd1381cd9eff64ec28c8..22e507c8a5566d1f4dfcfe9db67482e3c0e83e35 100644 (file)
@@ -127,3 +127,29 @@ _GLOBAL(__setup_cpu_power7)
 _GLOBAL(__restore_cpu_power7)
        /* place holder */
        blr
+
+/*
+ * Get a minimal set of registers for our caller's nth caller.
+ * r3 = regs pointer, r5 = n.
+ *
+ * We only get R1 (stack pointer), NIP (next instruction pointer)
+ * and LR (link register).  These are all we can get in the
+ * general case without doing complicated stack unwinding, but
+ * fortunately they are enough to do a stack backtrace, which
+ * is all we need them for.
+ */
+_GLOBAL(perf_arch_fetch_caller_regs)
+       mr      r6,r1
+       cmpwi   r5,0
+       mflr    r4
+       ble     2f
+       mtctr   r5
+1:     PPC_LL  r6,0(r6)
+       bdnz    1b
+       PPC_LL  r4,PPC_LR_STKOFF(r6)
+2:     PPC_LL  r7,0(r6)
+       PPC_LL  r7,PPC_LR_STKOFF(r7)
+       PPC_STL r6,GPR1-STACK_FRAME_OVERHEAD(r3)
+       PPC_STL r4,_NIP-STACK_FRAME_OVERHEAD(r3)
+       PPC_STL r7,_LINK-STACK_FRAME_OVERHEAD(r3)
+       blr
index 666d08db319e313f87c0d1c975a267461df51ca2..6c1dfc3ff8bc16903d976e73a242c6268eadb3d3 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
-#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
index f3c42ce516e7ed7d2261c6ec22d35c02c099045e..0c0567e58409ae006ae4f077d4a54e2a29fb81d4 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/syscalls.h>
 #include <linux/irq.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
index c13668cf36d940473519e9dc3723e9fc0bd37710..e7db5b48004ab43e30de96e2ac79d93a11b5fd6b 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/irq.h>
 #include <linux/list.h>
 #include <linux/of.h>
+#include <linux/slab.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
index d5e36e5dc7c21368cb088c21013c961d9f232328..d56b35ee7f74f04af5290aa10937f2e323e1cc6d 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/pci.h>
 #include <linux/string.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/prom.h>
index 5120bd44f69a60347f12a0f030829427f20c7323..43b83c35cf54b0dfb07bc5abef8ee558d5f3cd9c 100644 (file)
@@ -35,6 +35,9 @@ struct cpu_hw_events {
        u64 alternatives[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
        unsigned long amasks[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
        unsigned long avalues[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
+
+       unsigned int group_flag;
+       int n_txn_start;
 };
 DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
 
@@ -718,66 +721,6 @@ static int collect_events(struct perf_event *group, int max_count,
        return n;
 }
 
-static void event_sched_in(struct perf_event *event)
-{
-       event->state = PERF_EVENT_STATE_ACTIVE;
-       event->oncpu = smp_processor_id();
-       event->tstamp_running += event->ctx->time - event->tstamp_stopped;
-       if (is_software_event(event))
-               event->pmu->enable(event);
-}
-
-/*
- * Called to enable a whole group of events.
- * Returns 1 if the group was enabled, or -EAGAIN if it could not be.
- * Assumes the caller has disabled interrupts and has
- * frozen the PMU with hw_perf_save_disable.
- */
-int hw_perf_group_sched_in(struct perf_event *group_leader,
-              struct perf_cpu_context *cpuctx,
-              struct perf_event_context *ctx)
-{
-       struct cpu_hw_events *cpuhw;
-       long i, n, n0;
-       struct perf_event *sub;
-
-       if (!ppmu)
-               return 0;
-       cpuhw = &__get_cpu_var(cpu_hw_events);
-       n0 = cpuhw->n_events;
-       n = collect_events(group_leader, ppmu->n_counter - n0,
-                          &cpuhw->event[n0], &cpuhw->events[n0],
-                          &cpuhw->flags[n0]);
-       if (n < 0)
-               return -EAGAIN;
-       if (check_excludes(cpuhw->event, cpuhw->flags, n0, n))
-               return -EAGAIN;
-       i = power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n + n0);
-       if (i < 0)
-               return -EAGAIN;
-       cpuhw->n_events = n0 + n;
-       cpuhw->n_added += n;
-
-       /*
-        * OK, this group can go on; update event states etc.,
-        * and enable any software events
-        */
-       for (i = n0; i < n0 + n; ++i)
-               cpuhw->event[i]->hw.config = cpuhw->events[i];
-       cpuctx->active_oncpu += n;
-       n = 1;
-       event_sched_in(group_leader);
-       list_for_each_entry(sub, &group_leader->sibling_list, group_entry) {
-               if (sub->state != PERF_EVENT_STATE_OFF) {
-                       event_sched_in(sub);
-                       ++n;
-               }
-       }
-       ctx->nr_active += n;
-
-       return 1;
-}
-
 /*
  * Add a event to the PMU.
  * If all events are not already frozen, then we disable and
@@ -805,12 +748,22 @@ static int power_pmu_enable(struct perf_event *event)
        cpuhw->event[n0] = event;
        cpuhw->events[n0] = event->hw.config;
        cpuhw->flags[n0] = event->hw.event_base;
+
+       /*
+        * If group events scheduling transaction was started,
+        * skip the schedulability test here, it will be peformed
+        * at commit time(->commit_txn) as a whole
+        */
+       if (cpuhw->group_flag & PERF_EVENT_TXN_STARTED)
+               goto nocheck;
+
        if (check_excludes(cpuhw->event, cpuhw->flags, n0, 1))
                goto out;
        if (power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n0 + 1))
                goto out;
-
        event->hw.config = cpuhw->events[n0];
+
+nocheck:
        ++cpuhw->n_events;
        ++cpuhw->n_added;
 
@@ -896,11 +849,65 @@ static void power_pmu_unthrottle(struct perf_event *event)
        local_irq_restore(flags);
 }
 
+/*
+ * Start group events scheduling transaction
+ * Set the flag to make pmu::enable() not perform the
+ * schedulability test, it will be performed at commit time
+ */
+void power_pmu_start_txn(const struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+
+       cpuhw->group_flag |= PERF_EVENT_TXN_STARTED;
+       cpuhw->n_txn_start = cpuhw->n_events;
+}
+
+/*
+ * Stop group events scheduling transaction
+ * Clear the flag and pmu::enable() will perform the
+ * schedulability test.
+ */
+void power_pmu_cancel_txn(const struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+
+       cpuhw->group_flag &= ~PERF_EVENT_TXN_STARTED;
+}
+
+/*
+ * Commit group events scheduling transaction
+ * Perform the group schedulability test as a whole
+ * Return 0 if success
+ */
+int power_pmu_commit_txn(const struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuhw;
+       long i, n;
+
+       if (!ppmu)
+               return -EAGAIN;
+       cpuhw = &__get_cpu_var(cpu_hw_events);
+       n = cpuhw->n_events;
+       if (check_excludes(cpuhw->event, cpuhw->flags, 0, n))
+               return -EAGAIN;
+       i = power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n);
+       if (i < 0)
+               return -EAGAIN;
+
+       for (i = cpuhw->n_txn_start; i < n; ++i)
+               cpuhw->event[i]->hw.config = cpuhw->events[i];
+
+       return 0;
+}
+
 struct pmu power_pmu = {
        .enable         = power_pmu_enable,
        .disable        = power_pmu_disable,
        .read           = power_pmu_read,
        .unthrottle     = power_pmu_unthrottle,
+       .start_txn      = power_pmu_start_txn,
+       .cancel_txn     = power_pmu_cancel_txn,
+       .commit_txn     = power_pmu_commit_txn,
 };
 
 /*
@@ -1287,7 +1294,7 @@ static void perf_event_interrupt(struct pt_regs *regs)
                irq_exit();
 }
 
-void hw_perf_event_setup(int cpu)
+static void power_pmu_setup(int cpu)
 {
        struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
 
@@ -1297,6 +1304,23 @@ void hw_perf_event_setup(int cpu)
        cpuhw->mmcr[0] = MMCR0_FC;
 }
 
+static int __cpuinit
+power_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+       unsigned int cpu = (long)hcpu;
+
+       switch (action & ~CPU_TASKS_FROZEN) {
+       case CPU_UP_PREPARE:
+               power_pmu_setup(cpu);
+               break;
+
+       default:
+               break;
+       }
+
+       return NOTIFY_OK;
+}
+
 int register_power_pmu(struct power_pmu *pmu)
 {
        if (ppmu)
@@ -1314,5 +1338,7 @@ int register_power_pmu(struct power_pmu *pmu)
                freeze_events_kernel = MMCR0_FCHV;
 #endif /* CONFIG_PPC64 */
 
+       perf_cpu_notifier(power_pmu_notifier);
+
        return 0;
 }
index 1ed3b8d7981e4c4968c3ce6530b978883e8e030d..c8ae3714e79b2b3466600d982eb98d451f60e0c2 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/proc_fs.h>
-#include <linux/slab.h>
 #include <linux/kernel.h>
 
 #include <asm/machdep.h>
index 5f306c4946e542bedf94001cc3eb0372032dba95..97d4bd9442d380ca8f65d66f28c6fe85892cc9f2 100644 (file)
@@ -653,6 +653,7 @@ static void __init early_cmdline_parse(void)
 #else
 #define OV5_CMO                        0x00
 #endif
+#define OV5_TYPE1_AFFINITY     0x80    /* Type 1 NUMA affinity */
 
 /* Option Vector 6: IBM PAPR hints */
 #define OV6_LINUX              0x02    /* Linux is our OS */
@@ -706,7 +707,7 @@ static unsigned char ibm_architecture_vec[] = {
        OV5_DONATE_DEDICATE_CPU | OV5_MSI,
        0,
        OV5_CMO,
-       0,
+       OV5_TYPE1_AFFINITY,
        0,
        0,
        0,
index fd0d29493fd629a41ea5623dd77beeef1ef86ff1..74367841615a5ae3a31a2c2c9091916d79a0534c 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/completion.h>
 #include <linux/cpumask.h>
 #include <linux/lmb.h>
+#include <linux/slab.h>
 
 #include <asm/prom.h>
 #include <asm/rtas.h>
index a85117d5c9a4c3576ac60d0b774df2c43ca4f9fc..bfc2abafac44ab2f8d510384e4eb9a98a9b8cb17 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <asm/delay.h>
 #include <asm/uaccess.h>
index 2e4832ab210802015ba04fcf31dab5c7dc8cd931..4190eae7850a22006e351957064132629b1c5e15 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/spinlock.h>
 #include <linux/cpu.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
index b152de3e64d45a3646356b438ae9e7fedd088e4f..8f58986c2ad9a7c56117f24bee6fd089333b80b6 100644 (file)
@@ -39,7 +39,6 @@
 #include <asm/serial.h>
 #include <asm/udbg.h>
 #include <asm/mmu_context.h>
-#include <asm/swiotlb.h>
 
 #include "setup.h"
 
@@ -343,11 +342,6 @@ void __init setup_arch(char **cmdline_p)
                ppc_md.setup_arch();
        if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
 
-#ifdef CONFIG_SWIOTLB
-       if (ppc_swiotlb_enable)
-               swiotlb_init(1);
-#endif
-
        paging_init();
 
        /* Initialize the MMU context management stuff */
index 63547394048c39dcbdf151f5b98468c54d91bc5c..914389158a9bf65c407ee4436051d513fdaea002 100644 (file)
@@ -61,7 +61,6 @@
 #include <asm/xmon.h>
 #include <asm/udbg.h>
 #include <asm/kexec.h>
-#include <asm/swiotlb.h>
 #include <asm/mmu_context.h>
 
 #include "setup.h"
@@ -541,11 +540,6 @@ void __init setup_arch(char **cmdline_p)
        if (ppc_md.setup_arch)
                ppc_md.setup_arch();
 
-#ifdef CONFIG_SWIOTLB
-       if (ppc_swiotlb_enable)
-               swiotlb_init(1);
-#endif
-
        paging_init();
 
        /* Initialize the MMU context management stuff */
index a5e54526403df182f074ee3bd90c715d6f54b444..03e45c4a9ef1892c9ca904ec393e1d7d66b78a27 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/smp.h>
 #include <linux/unistd.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/atomic.h>
 #include <asm/smp.h>
 #include <asm/time.h>
index 23c8c5e7dc4d0be08d0e153fb597ebc3b7535bc2..af0e8290b4fc4f90faf3f59136683c10f3c47971 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/interrupt.h>
 
index c5a4732bcc48d934b20b3f725bd642c36c35cc68..19471a1cef1a23766107c0c60e1d0048e2efe0d7 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/ptrace.h>
 #include <linux/elf.h>
 #include <linux/ipc.h>
+#include <linux/slab.h>
 
 #include <asm/ptrace.h>
 #include <asm/types.h>
index 1b16b9a3e49a57dbc0e444e230528763b1faa762..0441bbdadbd12b0b41cf94c89bc401da7a642a1f 100644 (file)
@@ -532,25 +532,60 @@ void __init iSeries_time_init_early(void)
 }
 #endif /* CONFIG_PPC_ISERIES */
 
-#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_PPC32)
-DEFINE_PER_CPU(u8, perf_event_pending);
+#ifdef CONFIG_PERF_EVENTS
 
-void set_perf_event_pending(void)
+/*
+ * 64-bit uses a byte in the PACA, 32-bit uses a per-cpu variable...
+ */
+#ifdef CONFIG_PPC64
+static inline unsigned long test_perf_event_pending(void)
 {
-       get_cpu_var(perf_event_pending) = 1;
-       set_dec(1);
-       put_cpu_var(perf_event_pending);
+       unsigned long x;
+
+       asm volatile("lbz %0,%1(13)"
+               : "=r" (x)
+               : "i" (offsetof(struct paca_struct, perf_event_pending)));
+       return x;
 }
 
+static inline void set_perf_event_pending_flag(void)
+{
+       asm volatile("stb %0,%1(13)" : :
+               "r" (1),
+               "i" (offsetof(struct paca_struct, perf_event_pending)));
+}
+
+static inline void clear_perf_event_pending(void)
+{
+       asm volatile("stb %0,%1(13)" : :
+               "r" (0),
+               "i" (offsetof(struct paca_struct, perf_event_pending)));
+}
+
+#else /* 32-bit */
+
+DEFINE_PER_CPU(u8, perf_event_pending);
+
+#define set_perf_event_pending_flag()  __get_cpu_var(perf_event_pending) = 1
 #define test_perf_event_pending()      __get_cpu_var(perf_event_pending)
 #define clear_perf_event_pending()     __get_cpu_var(perf_event_pending) = 0
 
-#else  /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */
+#endif /* 32 vs 64 bit */
+
+void set_perf_event_pending(void)
+{
+       preempt_disable();
+       set_perf_event_pending_flag();
+       set_dec(1);
+       preempt_enable();
+}
+
+#else  /* CONFIG_PERF_EVENTS */
 
 #define test_perf_event_pending()      0
 #define clear_perf_event_pending()
 
-#endif /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */
+#endif /* CONFIG_PERF_EVENTS */
 
 /*
  * For iSeries shared processors, we have to let the hypervisor
@@ -582,10 +617,6 @@ void timer_interrupt(struct pt_regs * regs)
        set_dec(DECREMENTER_MAX);
 
 #ifdef CONFIG_PPC32
-       if (test_perf_event_pending()) {
-               clear_perf_event_pending();
-               perf_event_do_pending();
-       }
        if (atomic_read(&ppc_n_lost_interrupts) != 0)
                do_IRQ(regs);
 #endif
@@ -604,6 +635,11 @@ void timer_interrupt(struct pt_regs * regs)
 
        calculate_steal_time();
 
+       if (test_perf_event_pending()) {
+               clear_perf_event_pending();
+               perf_event_do_pending();
+       }
+
 #ifdef CONFIG_PPC_ISERIES
        if (firmware_has_feature(FW_FEATURE_ISERIES))
                get_lppaca()->int_dword.fields.decr_int = 0;
index 696626a2e83536f90364dc1c5a0f3136ab8cf8f0..29d128eb6c4353745e05e50534317b08c24ebe68 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
index 77f64218abf3fd116031a3fd9b7fed71e0604e03..82237176a2a3db8c2eadc29db867b5ed0415398f 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/types.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/console.h>
 #include <linux/module.h>
 #include <linux/mm.h>
index f4d1b55aa70bd7b7cf9419285a454b4ce829a852..689a57c2ac8009f3d62a51cb9d94dc90a333d4e3 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <linux/kvm_host.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 
 #include <asm/reg.h>
index 2570fcc7665ddd9376f2db851371efef80fa2045..812312542e50cd9b42d73df0b02168d5a678ac7e 100644 (file)
@@ -440,7 +440,7 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
        unsigned int gtlb_index;
 
        gtlb_index = kvmppc_get_gpr(vcpu, ra);
-       if (gtlb_index > KVM44x_GUEST_TLB_SIZE) {
+       if (gtlb_index >= KVM44x_GUEST_TLB_SIZE) {
                printk("%s: index %d\n", __func__, gtlb_index);
                kvmppc_dump_vcpu(vcpu);
                return EMULATE_FAIL;
index 9a271f0929c727c100fb0cda64dff969f020f49a..604af29b71ed28ac8d641ab977496a2638cdeb19 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/kvm_ppc.h>
 #include <asm/kvm_book3s.h>
 #include <asm/mmu_context.h>
+#include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/vmalloc.h>
 
@@ -1003,7 +1004,8 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
        struct kvm_vcpu *vcpu;
        ulong ga, ga_end;
        int is_dirty = 0;
-       int r, n;
+       int r;
+       unsigned long n;
 
        mutex_lock(&kvm->slots_lock);
 
@@ -1021,7 +1023,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
                kvm_for_each_vcpu(n, vcpu, kvm)
                        kvmppc_mmu_pte_pflush(vcpu, ga, ga_end);
 
-               n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+               n = kvm_dirty_bitmap_bytes(memslot);
                memset(memslot->dirty_bitmap, 0, n);
        }
 
index 4d686cc6b260a797bbc7dffaa1467b574901714f..2a3a1953d4bd76a66ef49feb2882609b2847118e 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/kvm_host.h>
+#include <linux/gfp.h>
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
index efa1198940ab6b550a9f2e9ccf99d88692e43e61..669a5c5fc7d725db4f9d8ae6bddc47bce21eb475 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/kvm_host.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 
 #include <asm/reg.h>
index 0d772e6b6318cf30f081b5ec76c9bfe035ca5250..21011e12caeb9e159e258785b0f8709fe52bed2c 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
index 51aedd7f16bcb14d5d2f073da2fc55a53ec18575..297fcd2ff7d01a0d9dddf473b1cc4e4415fccf4b 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/vmalloc.h>
 #include <linux/hrtimer.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <asm/cputable.h>
 #include <asm/uaccess.h>
 #include <asm/kvm_ppc.h>
index 292115d98ea9663e4038efe9826262e7c97003e1..deac4d30daf4dfcda8bf3bafcaba3751aa393429 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/device.h>      /* devres_*(), devm_ioremap_release() */
+#include <linux/gfp.h>
 #include <linux/io.h>          /* ioremap_flags() */
 #include <linux/module.h>      /* EXPORT_SYMBOL() */
 
index 36692f5c9a7637348bed0bc6f9318498035af14b..757c0bed9a91e5c76e40dbd2a50346f0bc397b10 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
index c5394728bf2e1057b407e68e8f22a6b9fd9a3621..1ed6b52f30319b8ffb717d80d803b143ef6084e7 100644 (file)
@@ -116,7 +116,7 @@ void loadcam_entry(int idx)
        mtspr(SPRN_MAS2, TLBCAM[idx].MAS2);
        mtspr(SPRN_MAS3, TLBCAM[idx].MAS3);
 
-       if (cur_cpu_spec->cpu_features & MMU_FTR_BIG_PHYS)
+       if (mmu_has_feature(MMU_FTR_BIG_PHYS))
                mtspr(SPRN_MAS7, TLBCAM[idx].MAS7);
 
        asm volatile("isync;tlbwe;isync" : : : "memory");
@@ -152,18 +152,13 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
 
        TLBCAM[index].MAS3 = (phys & MAS3_RPN) | MAS3_SX | MAS3_SR;
        TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_SW : 0);
-       if (cur_cpu_spec->cpu_features & MMU_FTR_BIG_PHYS)
+       if (mmu_has_feature(MMU_FTR_BIG_PHYS))
                TLBCAM[index].MAS7 = (u64)phys >> 32;
 
-#ifndef CONFIG_KGDB /* want user access for breakpoints */
        if (flags & _PAGE_USER) {
           TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
           TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
        }
-#else
-       TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
-       TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
-#endif
 
        tlbcam_addrs[index].start = virt;
        tlbcam_addrs[index].limit = virt + size - 1;
index 123f7070238a3624287829f7f485d66c8f28a207..9bb249c3046e3eb6aae16bdfc4a4dd3972f363f8 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/mm.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/hugetlb.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
index b1dbd9ee87ccb477f5d18d846994dcc566317132..767333005eb46e1d1075dbfe6674d5ef7eca3fbe 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/initrd.h>
 #include <linux/pagemap.h>
 #include <linux/lmb.h>
+#include <linux/gfp.h>
 
 #include <asm/pgalloc.h>
 #include <asm/prom.h>
index 776f28d02b6b0a163a6c5f8d6bde6532a350d38c..d7fa50b09b4afe86af00ca4cf661ba0f0908d819 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/poison.h>
 #include <linux/lmb.h>
 #include <linux/hugetlb.h>
+#include <linux/slab.h>
 
 #include <asm/pgalloc.h>
 #include <asm/page.h>
index 311224cdb7ad08c53d0a8b70528b3bf888a4b795..0f594d774bf7c034975ab4f20bcdf7199981aba3 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/gfp.h>
 #include <linux/types.h>
 #include <linux/mm.h>
 #include <linux/stddef.h>
@@ -48,6 +49,7 @@
 #include <asm/sparsemem.h>
 #include <asm/vdso.h>
 #include <asm/fixmap.h>
+#include <asm/swiotlb.h>
 
 #include "mmu_decl.h"
 
@@ -320,6 +322,11 @@ void __init mem_init(void)
        struct page *page;
        unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
 
+#ifdef CONFIG_SWIOTLB
+       if (ppc_swiotlb_enable)
+               swiotlb_init(1);
+#endif
+
        num_physpages = lmb.memory.size >> PAGE_SHIFT;
        high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
 
index 51622daae09d27928591757509c1b23c156decd8..2535828aa84bd0d174b3346c88b826572fe5d50f 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/spinlock.h>
 #include <linux/idr.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 
 #include <asm/mmu_context.h>
 
index dbc692145ecb1aea313fc64992010519c73f1c28..1f2d9ff098952d7b760b8d4e15adf7c709fae41d 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/bootmem.h>
 #include <linux/notifier.h>
 #include <linux/cpu.h>
+#include <linux/slab.h>
 
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
index 64c00227b99786cab5ae38d6513c73db1b13fd8f..eaa7633515b72064443333eb2b7ddeafcd462bf2 100644 (file)
@@ -242,10 +242,11 @@ EXPORT_SYMBOL_GPL(of_node_to_nid);
  */
 static int __init find_min_common_depth(void)
 {
-       int depth;
+       int depth, index;
        const unsigned int *ref_points;
        struct device_node *rtas_root;
        unsigned int len;
+       struct device_node *options;
 
        rtas_root = of_find_node_by_path("/rtas");
 
@@ -258,11 +259,23 @@ static int __init find_min_common_depth(void)
         * configuration (should be all 0's) and the second is for a normal
         * NUMA configuration.
         */
+       index = 1;
        ref_points = of_get_property(rtas_root,
                        "ibm,associativity-reference-points", &len);
 
+       /*
+        * For type 1 affinity information we want the first field
+        */
+       options = of_find_node_by_path("/options");
+       if (options) {
+               const char *str;
+               str = of_get_property(options, "ibm,associativity-form", NULL);
+               if (str && !strcmp(str, "1"))
+                        index = 0;
+       }
+
        if ((len >= 2 * sizeof(unsigned int)) && ref_points) {
-               depth = ref_points[1];
+               depth = ref_points[index];
        } else {
                dbg("NUMA: ibm,associativity-reference-points not found.\n");
                depth = -1;
index 99df697c601acbd9a0fa3267cb313e7a21cd7303..ebc2f38eb381a3760fb8bd8014c5a23a38164980 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/percpu.h>
index 573b3bd1c45b46500c38e65495b9f3a2ee3a47a2..b9243e7557ae970fb06aa9d86b53d760312aebb3 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/highmem.h>
 #include <linux/lmb.h>
+#include <linux/slab.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
index 853d5565eed52b88deb8d37b2379d12fe8d6d6bb..d95679a5fb29f9dfccb3f09816288477b07242ba 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/lmb.h>
+#include <linux/slab.h>
 
 #include <asm/pgalloc.h>
 #include <asm/page.h>
index a040b81e93bdd6b49d16b77e4c8b04b0281c7bc6..e4f8f1fc81a570a38e2ab4e63a35023558633309 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/gfp.h>
-#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
index 6b793aeda72ea041ac2a68f1ca2e2ece7f46badc..642fca137ccb1489c593699b21115ed37c542883 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/notifier.h>
 #include <linux/numa.h>
 #include <linux/oprofile.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include "pr_util.h"
 
index c591339daf58aff5f5b721bc883baeea8928e44e..c579b16845da453b06517662c031d631a9db9b18 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/string.h>
 #include <linux/uaccess.h>
 #include <linux/elf.h>
+#include <linux/slab.h>
 #include "pr_util.h"
 
 
index e5c1b096c3e124186d9a4a4ae5c3f1cac8b06d06..8f771395f424e6d345ad8e6d2a36b093aa9ea946 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/delay.h>
 #include <linux/of_gpio.h>
 #include <linux/of_i2c.h>
+#include <linux/slab.h>
 
 #include <asm/machdep.h>
 #include <asm/prom.h>
index 2b8d8ef32e4eb2175fd822df0b942a35aebb24e4..fda7c2a18282613e8847f577bd425f8aa4367537 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/of.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/of_gpio.h>
 #include <linux/io.h>
 #include <linux/of_platform.h>
index 072b948b2e2dad67abe5c531028e1e603950c03d..a60ee39d3b783d09ab67f2d3d3280af9bfdaf34d 100644 (file)
@@ -62,6 +62,7 @@
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/watchdog.h>
 #include <linux/miscdevice.h>
 #include <linux/uaccess.h>
@@ -711,7 +712,11 @@ static int __devinit mpc52xx_gpt_wdt_init(void)
        return 0;
 }
 
-#define mpc52xx_gpt_wdt_setup(x, y)            (0)
+static inline int mpc52xx_gpt_wdt_setup(struct mpc52xx_gpt_priv *gpt,
+                                       const u32 *period)
+{
+       return 0;
+}
 
 #endif /*  CONFIG_MPC5200_WDT  */
 
index 929d017535a3cb583f13ac122f39cb5503e8478e..d4f8be307cd5b3aef4adc4b360dbfbf08190a442 100644 (file)
@@ -481,6 +481,8 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match)
        if (rc)
                goto err_bcom_rx_irq;
 
+       lpbfifo.dma_irqs_enabled = 1;
+
        /* Request the Bestcomm transmit (memory --> fifo) task and IRQ */
        lpbfifo.bcom_tx_task =
                bcom_gen_bd_tx_init(2, res.start + LPBFIFO_REG_FIFO_DATA,
index f9aee182e6f70c55a1d6c4d3e36990ccc412bf08..f21555d3395ae7ab3b5d4c69d600b84fd1a039bc 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/fsl_devices.h>
 #include <linux/mdio-bitbang.h>
 #include <linux/of_mdio.h>
+#include <linux/slab.h>
 #include <linux/of_platform.h>
 
 #include <asm/io.h>
index d4a09f8705b5c030cef0235e4b1287ccfaf71469..5a55d87d6bd6329beebff4cd742a0db47a7bae7a 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/irq.h>
 #include <linux/types.h>
 #include <linux/bootmem.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/prom.h>
index 82a9bcb858b6adaae55cac776e80d559a2a206fb..d119a7c1c17a970385aa43d975f45f59437053fc 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/gpio.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
+#include <linux/slab.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
 
index d95121894eb7d52dc5e56df8d61e2f5406d8b7cf..3a2ade2e443fea4a46f0598e431dbc3b02cf641d 100644 (file)
@@ -51,7 +51,7 @@ config MPC85xx_DS
        bool "Freescale MPC85xx DS"
        select PPC_I8259
        select DEFAULT_UIMAGE
-       select FSL_ULI1575
+       select FSL_ULI1575 if PCI
        select SWIOTLB
        help
          This option enables support for the MPC85xx DS (MPC8544 DS) board
@@ -60,7 +60,7 @@ config MPC85xx_RDB
        bool "Freescale MPC85xx RDB"
        select PPC_I8259
        select DEFAULT_UIMAGE
-       select FSL_ULI1575
+       select FSL_ULI1575 if PCI
        select SWIOTLB
        help
          This option enables support for the MPC85xx RDB (P2020 RDB) board
index fbe9f3621424eb9bf9d40d3ec99e0b1555db3a0d..a0b5638c5dc8bfef5cbfcc1d57b759c8f57bd387 100644 (file)
@@ -13,7 +13,7 @@ config MPC8641_HPCN
        bool "Freescale MPC8641 HPCN"
        select PPC_I8259
        select DEFAULT_UIMAGE
-       select FSL_ULI1575
+       select FSL_ULI1575 if PCI
        select HAS_RAPIDIO
        select SWIOTLB
        help
@@ -28,7 +28,7 @@ config SBC8641D
 config MPC8610_HPCD
        bool "Freescale MPC8610 HPCD"
        select DEFAULT_UIMAGE
-       select FSL_ULI1575
+       select FSL_ULI1575 if PCI
        help
          This option enables support for the MPC8610 HPCD board.
 
index 11f7b2b6f49ef9a216bc92d4734b3b5c9e8f788a..b8cb08dbd89c62b435b13a2fa69a2819a974d130 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #define GEF_GPIO_DIRECT                0x00
 #define GEF_GPIO_IN            0x04
index 242954c4293f64fcc6222a15de3eb6df6e8c0941..60168c1f98feb5bba3126c1f01ca6987fbe27f58 100644 (file)
@@ -11,7 +11,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/time.h>
index 96fe896f6df34707587d2694f8dcff13e7d369c9..8efe48192f3f50a0748978641fbad80ca050258c 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/msi.h>
 #include <linux/of_platform.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 
 #include <asm/dcr.h>
 #include <asm/machdep.h>
index 00eaaa71630fde9252768167c20b1ce71cfd059d..404d1fc04d59e07d936daafd2f290d7d6d035184 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/pci_regs.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index 7fca09f990ba4fecc0bdc4e7fe5ad64a594d4043..a881bbee8de0564b6a995ad7ed5e1fe7fb5f637e 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/delay.h>
index ca5bfdfe47f2f7a9502e8bacc8b8d6b6ca00bca8..e3ec4976fae7a554c405ce7823d34b09bfbf37c5 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/notifier.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 #include <linux/lmb.h>
 
 #include <asm/prom.h>
index 608fd2b584c910548aff61f8a6c4d421a731b572..1d3c4effea10d1592acf1ea7fdd62370bef7055f 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/reboot.h>
 #include <linux/kexec.h>
index 59305369f6b232bb262521a6abe7cd8c3e2f35d6..50385db586bd951c706f0820d352114abb8adea5 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/mm.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
index 5122ec145271e0e65608718a0233138144a77561..ca7731c0b59518776ada45d17aa7b20f532f8eea 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/kernel.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 
 #include <asm/ppc-pci.h>
index 891f18e337a269a75f07dbcdfb54a1ae11b9c30d..f465d474ad9b13b7813921bfa6cd4e9260b15d26 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/mm.h>
 #include <linux/io.h>
index 1410443731eb8b6aab3f7fae2f64b35ca92c5e2a..121aec353f268b007c558258acd206821efd13e8 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/mm.h>
 #include <linux/io.h>
index eea120229cdbc800a9540f534e49978adb0a446c..6cf3ec62852776ef78f3daa5864ad1615af36c8f 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/file.h>
 #include <linux/fdtable.h>
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/syscalls.h>
index 64a4c2d85f7cbd22671544a7ec3a65aac6fb37e9..5c2808252516500b9d8871dfea5c5e78f67f4268 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/poll.h>
 #include <linux/ptrace.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/time.h>
index 0e9f325c9ff7572318d0e843d707af86593fb78a..a101abf175040eac45df0ab0d972f1765e5d7e6c 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include <asm/spu.h>
index 4678078fede8ecafb3445195ca4b694a44274131..0b04662849320d662ea3cb974b20e5e4bdc711cb 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/vmalloc.h>
 #include <linux/smp.h>
index c23617c6baf39ed1f4854f1f2ed2fde10ebd8e33..187a7d32f86a25ea2ff19e1fab99f7c551d0d59e 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/module.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
index 8efd4244701c2eb1d0a73b07d9e21888ae066e94..ba3588f2d8e0c2df441907788046d2f8128b092c 100644 (file)
@@ -12,7 +12,6 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <asm/uaccess.h>
 #include <asm/prom.h>
index 8f41685d8f42b5669ee2a7e2492b5755e6919986..8553cc49e0d6a9e933eff573b4ea2b2190c87195 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/tty.h>
 #include <linux/major.h>
index 9d53cb481a7cc3ee2714e99ce5bbe67f39d103ac..ce61cea0afb52cc77a4fa806da88cd7489518e88 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/list.h>
 #include <linux/pci.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <asm/iommu.h>
 #include <asm/vio.h>
index 6617915bcb1ae129345936e82fc5573be0a70cca..d2c1d497846e75f46f612d9c85043a56cadcbaa9 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/bcd.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 
 #include <asm/time.h>
 #include <asm/uaccess.h>
index 175aac8ca7e501216578401c8168429acced9af0..b841c9a9db87133ffa16aafef4ea5b1ab6805d98 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/pci.h>
index 2aa8b5631bebe54fc58df8b24d338c5eb2c8c888..00b6730bc48f07392f0604eab8b472badb121242 100644 (file)
@@ -22,7 +22,7 @@
  */
 #include <linux/of.h>
 #include <linux/init.h>
-#include <linux/gfp.h>
+#include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/proc_fs.h>
 #include <linux/module.h>
index 5aea94f30836c5044fe1fab08378a9535ac35f47..b5f05d943a90526b2f60505a439fa92b5fcf9e86 100644 (file)
@@ -29,6 +29,7 @@
  */
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/vmalloc.h>
 #include <linux/string.h>
index 0636a3df6978bed791e6d6160655f3cd56f748ff..39df70529d292d594a0f52fad57b5e19425a78c9 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/tty.h>
 #include <linux/string.h>
index a6152d92224304bc20da05b3e5f44550956e376a..09695ae50f911c521766ad41fc938c1c05642b1b 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/of.h>
 
 #include <asm/pasemi_dma.h>
index 3bf546797cbba702b3b0c41d05682f399aa41039..0f881f64583e97f9436b48c6156d643db7ddead1 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
index 242f8095c2dfc0991f1108c6581d5969cb3e3516..ac6fdd9732912848dd3cc3ee8d606e9ff8c6a894 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/console.h>
 #include <linux/pci.h>
 #include <linux/of_platform.h>
+#include <linux/gfp.h>
 
 #include <asm/prom.h>
 #include <asm/system.h>
index d4f127d18141192bef0d3771e81bc79529d707fc..1e9eba175ff0d0300b62bbb957132b8bae3ef00e 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/sched.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
-#include <linux/slab.h>
 #include <linux/cpufreq.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
index 3ed288e68ec4e613546b12b3ce4f9ec734830488..3ca09d3ccce33f35ab47a5fa53296c213085d243 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/cpufreq.h>
 #include <linux/init.h>
 #include <linux/completion.h>
index 345e2da56767998e3f3af53c23d9cc643d59514b..f45331ab97cbca3176a939194bb046e8181feea7 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/timer.h>
 #include <linux/mutex.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <asm/keylargo.h>
 #include <asm/uninorth.h>
 #include <asm/io.h>
index 80a5258d0364f39162a9ce32562b9b3948dfa6fe..b1cdcf94aa8e95daab73fa9cd757795e19d09301 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/string.h>
 #include <linux/nvram.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/adb.h>
index ede49e78a8da4f631632d7e553513dab2924f8af..cec6359426573d87a8d42a3439fc10393d8918ae 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 
index c20522656367c9ecbb02f91c86fcab197f080617..15c2241f9c72a85cb81c554a9a97d9e9e702aa29 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/tty.h>
 #include <linux/string.h>
index bb028f165fb3d0008533d2e55b3eddbec898f076..b341018326df780af2f85147b6c3cd97863c1453 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/kthread.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/reboot.h>
 
 #include <asm/firmware.h>
index e81b028a2a48d8aca2efd0dcd7357ee9b4e9e62e..7925751e464acd2941ce5dce7caa037fc210a755 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/memory_hotplug.h>
 #include <linux/lmb.h>
+#include <linux/slab.h>
 
 #include <asm/cell-regs.h>
 #include <asm/firmware.h>
index d6487a9c801900d3aa9ee9db65a245f44f26f702..dd521a181f23bdb5237607e65fabbe7df6d2988a 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/ctype.h>
 #include <linux/lmb.h>
 #include <linux/of.h>
+#include <linux/slab.h>
 
 #include <asm/prom.h>
 
index b3c6a993f9f3bc0d16a415391c631d988b887ef2..39a472e9e80fb9e5ccddfbe92cc25acee96f732a 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/mmzone.h>
 #include <linux/io.h>
 #include <linux/mm.h>
index e34b305a7a52a13cdaa7dee57e11a0262940fde3..6d09f5e3e7e49c77bd286dcc22366b4daf53c4b8 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <asm/udbg.h>
 #include <asm/lv1call.h>
index a277f2e28dbc285cb1ff285cf7ac2ec815e98d58..f4803868642c8248872933257c4abd8effaa663e 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/kthread.h>
 #include <linux/module.h>
index 37bce52526da52f156841e364ed6998456d6a18a..e1682bc168a39cdaa89715126c5902625980b1bf 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
 #include <linux/cpu.h>
+#include <linux/slab.h>
 #include "offline_states.h"
 
 #include <asm/prom.h>
index c5f3116b6ca524e8b08aff7193ca796ccd089e00..a00addb559456e6c3ea69658887f630378863ff1 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/debugfs.h>
 #include <asm/smp.h>
 #include <asm/system.h>
index ce37040af870856271deecd0de2c0c42af32457e..30b987b73c20cae978e57c3e8a6fb587b903af3a 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/list.h>
 #include <linux/pci.h>
 #include <linux/rbtree.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <asm/atomic.h>
 #include <asm/pci-bridge.h>
index ec5df8f519c7417327923bcadafdbda76874ec04..2ec500c130b5173ab497f6e51dc2eac7d860a407 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <asm/eeh_event.h>
 #include <asm/ppc-pci.h>
index 9b21ee68ea5070d4e04eb1392505b913ac7f4cf2..01e7b5bb3c1d3853469694bf00235555108321f6 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/of.h>
 #include <linux/lmb.h>
+#include <linux/vmalloc.h>
 #include <asm/firmware.h>
 #include <asm/machdep.h>
 #include <asm/pSeries_reconfig.h>
@@ -54,6 +55,12 @@ static int pseries_remove_lmb(unsigned long base, unsigned int lmb_size)
         */
        start = (unsigned long)__va(base);
        ret = remove_section_mapping(start, start + lmb_size);
+
+       /* Ensure all vmalloc mappings are flushed in case they also
+        * hit that section of memory
+        */
+       vm_unmap_aliases();
+
        return ret;
 }
 
index 42f7e384e6c438c13350feb34ae7183a7abe3fc6..bc3c7f2abd795322ab579da4137688e17f966663 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <asm/uaccess.h>
 #include <asm/nvram.h>
index 225a50ab14be555c9ca6aa92889bb6432e5fcf3d..7ebd9e88d369c242b63dd48b0bd7a02a95f94449 100644 (file)
@@ -11,6 +11,7 @@
  *
  */
 
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/kobject.h>
 #include <linux/mm.h>
index d20b96e22c2ed763aa583cd2e387b29b1927f146..db940d2c39a0a8605fb2b2db5a566ee5861f7016 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/interrupt.h>
 #include <linux/timex.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/random.h>
index a2305d29bbbdb822f89cb64041f66e245aaf9ad9..1a58637bcea5d12112ad96b9fa9e928f96e3f244 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kref.h>
 #include <linux/notifier.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 
 #include <asm/prom.h>
 #include <asm/machdep.h>
index 1b45c458f952fc6da9cb0b9e3ebb63416023ae06..80e9e7652a4d1371b0a17032fa4eb4edc7e0fbf1 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/rtas.h>
 #include <asm/prom.h>
index ca5f2e10972c32db9c737f28e4bbf36b76a1241e..6710761bf60fb725f6b36d9028c52238b9c2715f 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/mm.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/tty.h>
 #include <linux/major.h>
index ecad10d4e9281790928ea0b7d9512b9ebbc6e68b..8d103ca6d6ab8821273519c04a65599785c31351 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/8xx_immap.h>
@@ -485,9 +486,6 @@ int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode)
                return -EINVAL;
        }
 
-       if (reg == &mpc8xx_immr->im_cpm.cp_sicr && mode == CPM_CLK_RX)
-               shift += 3;
-
        for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
                if (clk_map[i][0] == target && clk_map[i][1] == clock) {
                        bits = clk_map[i][2];
@@ -502,6 +500,17 @@ int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode)
 
        bits <<= shift;
        mask <<= shift;
+
+       if (reg == &mpc8xx_immr->im_cpm.cp_sicr) {
+               if (mode == CPM_CLK_RTX) {
+                       bits |= bits << 3;
+                       mask |= mask << 3;
+               } else if (mode == CPM_CLK_RX) {
+                       bits <<= 3;
+                       mask <<= 3;
+               }
+       }
+
        out_be32(reg, (in_be32(reg) & ~mask) | bits);
 
        return 0;
index eb5927212fab39134177bbbcd478fcfac85fabc8..8dc1e24f3c2383bbaf22f2486b9ba076220413ff 100644 (file)
@@ -244,9 +244,6 @@ int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode)
                return -EINVAL;
        }
 
-       if (mode == CPM_CLK_RX)
-               shift += 3;
-
        for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
                if (clk_map[i][0] == target && clk_map[i][1] == clock) {
                        bits = clk_map[i][2];
@@ -259,6 +256,14 @@ int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode)
        bits <<= shift;
        mask <<= shift;
 
+       if (mode == CPM_CLK_RTX) {
+               bits |= bits << 3;
+               mask |= mask << 3;
+       } else if (mode == CPM_CLK_RX) {
+               bits <<= 3;
+               mask <<= 3;
+       }
+
        out_be32(reg, (in_be32(reg) & ~mask) | bits);
 
        cpm2_unmap(im_cpmux);
index 9de72c96e6d1b9718631d9a63a9f8e326b133796..88b9812c854fdc2de978871012eeb3c507717569 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/of_device.h>
 #include <linux/spinlock.h>
 #include <linux/of.h>
+#include <linux/slab.h>
 
 #include <asm/udbg.h>
 #include <asm/io.h>
index bafc3f85360d3c3059f490ea9a312642393196c3..c8b96ed7c0158a81137777b050fbfd745d2dab0a 100644 (file)
@@ -29,7 +29,6 @@
 
 #include <linux/init.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
@@ -38,6 +37,7 @@
 #include <linux/vmalloc.h>
 #include <linux/suspend.h>
 #include <linux/lmb.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/iommu.h>
index 714ec02fed2ea84b8f5825c3197b4af44fa49c0b..eca4545dd52ee0619b0bb0ad2b86597a5737d736 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/spinlock.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include <asm/fsl_gtm.h>
 
 #define GTCFR_STP(x)           ((x) & 1 ? 1 << 5 : 1 << 1)
index e094367d7739e00f8949aab22de0c7c5f0fb1f9d..3482e3fd89c04e99a0205f1fbc82ad7d28313f3e 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/bootmem.h>
 #include <linux/msi.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/of_platform.h>
 #include <sysdev/fsl_soc.h>
 #include <asm/prom.h>
index e1a028c1f18d0a94a415038c343f160309eb034c..a14760fe513a6bc7d5bcbc9780470b1b64e84516 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/bootmem.h>
 #include <linux/lmb.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/prom.h>
index 757a83fe5e59f7ecdb28f82a4ae7b68e77e54363..71fba88f50db86e5946593fe0f8407ffc078974b 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/rio_drv.h>
 #include <linux/of_platform.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
index ee1c0e1cf4a7d814d99788c0c6520fb18bfcd3bf..6478eb10691aafcc85ef4290fe1780802ef0025d 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #define MPC8XXX_GPIO_PINS      32
 
index 339e8a3e26d2071cb37cb01d86d050ea446e1b37..260295b10557697d752dde512aae577401acd4a0 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/bootmem.h>
 #include <linux/spinlock.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include <asm/ptrace.h>
 #include <asm/signal.h>
index 5a32cbef9b6c25b2adb34b7165e12d9398b05587..5287e95cec3a5ad79e6e6f9997335a3f0abd2e45 100644 (file)
@@ -8,6 +8,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/bitmap.h>
 #include <asm/msi_bitmap.h>
index 3d54450640c150dca4403602804a01d81ab5c40b..c9e803f3e267a1fba41f6f5d2285440ed758c0d7 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/of.h>
 #include <linux/init.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 
 static __initdata struct {
        const char *compatible;
index aaa915998eb630cdb0492427a67ac40816e67a68..652652db4ce283f11cee235d689268d0dcfce36d 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
index 110efe2a54fca1d82cc0e00b75fee6637bed7181..3812fc366becfcf92af075f9339338d5e3533008 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/of_gpio.h>
 #include <linux/gpio.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 
 #define GPIO_MASK(gpio)                (0x80000000 >> (gpio))
 #define GPIO_MASK2(gpio)       (0xc0000000 >> ((gpio) * 2))
index 8aa33021e50b39d412d725e3c6dd72afba5e1099..106d767bf65bfd1c7d4e7332d6459de8a338eec4 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/of.h>
 #include <linux/bootmem.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/pci-bridge.h>
index 8e7a7767dd5c4eacb82be33953df8845126e1d71..dc8f8d61807480dc17faea46939dc30caec8ec39 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 #include <asm/qe.h>
 
 struct qe_gpio_chip {
index ebb442ea191770a9dad1d6c69d9a40ac59583a4b..fa589b21dbcdd7ccfa97fefab11ea4f5ab853218 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/stddef.h>
 #include <linux/spinlock.h>
 #include <linux/module.h>
index 43c4569e24b7829a8910f64b7dc6291138b7b792..d5fb173e588cbe602fdd202291f01fc72fd47d76 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 #include <asm/prom.h>
 #include "simple_gpio.h"
 
index 595034cfb85aa34cfad606da9e2a458b16a3f23a..0ab9281e49aec778e054bd32700ce5dfcb76895a 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 
index 4188cbe63a54a954e232a0d5d0dd5f9d4441dc32..e43fe753703114890aaff48dec708aec64f32999 100644 (file)
@@ -11,7 +11,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/kernel_stat.h>
 #include <linux/pagemap.h>
index 4ce7fa95880fdb2aaa09169af226371374e1b55e..9a9586f4103f5d4bbea2a1f5d5a0c27b1453e5f4 100644 (file)
@@ -12,7 +12,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/kernel_stat.h>
 #include <linux/netdevice.h>
index a97d695258297af2b9de00dfd0e42e7dc1767ff4..14e0479d3888eb8d5178fd0f0f4c851dc37ebdf4 100644 (file)
@@ -24,8 +24,8 @@
 /* Symbols defined by linker scripts */
 extern char input_data[];
 extern int input_len;
-extern int _text;
-extern int _end;
+extern char _text, _end;
+extern char _bss, _ebss;
 
 static void error(char *m);
 
@@ -129,12 +129,12 @@ unsigned long decompress_kernel(void)
        unsigned long output_addr;
        unsigned char *output;
 
+       check_ipl_parmblock((void *) 0, (unsigned long) output + SZ__bss_start);
+       memset(&_bss, 0, &_ebss - &_bss);
        free_mem_ptr = (unsigned long)&_end;
        free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
        output = (unsigned char *) ((free_mem_end_ptr + 4095UL) & -4096UL);
 
-       check_ipl_parmblock((void *) 0, (unsigned long) output + SZ__bss_start);
-
 #ifdef CONFIG_BLK_DEV_INITRD
        /*
         * Move the initrd right behind the end of the decompressed
index a3209906739e8dea52ee28bf51968af73172056a..aa819dac2360e946bf4712fc4f56c129a3113355 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <asm/debug.h>
 #include <asm/uaccess.h>
 
index 7ae71cc56973adfdb75b42b1d22ee54fa09a74f5..bcd6884985ad53ec8ebb758c3b050c15c28228c9 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 09:03:07 2010
+# Linux kernel version: 2.6.34-rc3
+# Fri Apr  9 09:57:10 2010
 #
 CONFIG_SCHED_MC=y
 CONFIG_MMU=y
@@ -17,6 +17,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
 CONFIG_NO_IOMEM=y
 CONFIG_NO_DMA=y
 CONFIG_GENERIC_LOCKBREAK=y
@@ -62,15 +63,11 @@ CONFIG_TREE_RCU=y
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=64
 # CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ 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=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 CONFIG_CGROUPS=y
 # CONFIG_CGROUP_DEBUG is not set
 CONFIG_CGROUP_NS=y
@@ -79,6 +76,7 @@ CONFIG_CGROUP_NS=y
 # CONFIG_CPUSETS is not set
 # CONFIG_CGROUP_CPUACCT is not set
 # CONFIG_RESOURCE_COUNTERS is not set
+# CONFIG_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -93,6 +91,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -126,6 +125,7 @@ CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
+CONFIG_TRACEPOINTS=y
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
 CONFIG_HAVE_SYSCALL_WRAPPERS=y
@@ -134,6 +134,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
 CONFIG_HAVE_DEFAULT_NO_SPIN_MUTEXES=y
 
 #
@@ -246,6 +247,7 @@ CONFIG_64BIT=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=32
 CONFIG_HOTPLUG_CPU=y
+# CONFIG_SCHED_BOOK is not set
 CONFIG_COMPAT=y
 CONFIG_SYSVIPC_COMPAT=y
 CONFIG_AUDIT_ARCH=y
@@ -345,13 +347,13 @@ CONFIG_PM_SLEEP=y
 CONFIG_HIBERNATION=y
 CONFIG_PM_STD_PARTITION=""
 # CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
 CONFIG_NET=y
 
 #
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -529,6 +531,7 @@ CONFIG_NET_SCH_FIFO=y
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
 CONFIG_CAN=m
 CONFIG_CAN_RAW=m
 CONFIG_CAN_BCM=m
@@ -605,6 +608,7 @@ CONFIG_MISC_DEVICES=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 # CONFIG_SCSI_DMA is not set
@@ -863,6 +867,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -891,6 +896,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -952,6 +958,7 @@ CONFIG_DEBUG_MUTEXES=y
 # CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # 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
@@ -973,12 +980,17 @@ CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
 # 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_FUNCTION_TRACE_MCOUNT_TEST=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
@@ -995,10 +1007,15 @@ 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_KPROBE_EVENT=y
+# CONFIG_RING_BUFFER_BENCHMARK is not set
 # CONFIG_DYNAMIC_DEBUG is not set
 CONFIG_SAMPLES=y
+# CONFIG_SAMPLE_TRACEPOINTS is not set
+# CONFIG_SAMPLE_TRACE_EVENTS is not set
 # CONFIG_SAMPLE_KOBJECT is not set
 # CONFIG_SAMPLE_KPROBES is not set
+# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
 
 #
 # Security options
@@ -1032,6 +1049,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 CONFIG_CRYPTO_GF128MUL=m
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
@@ -1119,7 +1137,7 @@ CONFIG_CRYPTO_SHA512_S390=m
 # CONFIG_CRYPTO_DES_S390 is not set
 # CONFIG_CRYPTO_AES_S390 is not set
 CONFIG_S390_PRNG=m
-# CONFIG_BINARY_PRINTF is not set
+CONFIG_BINARY_PRINTF=y
 
 #
 # Library routines
@@ -1136,14 +1154,16 @@ CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_LZO_COMPRESS=m
-CONFIG_LZO_DECOMPRESS=m
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_NLATTR=y
 CONFIG_HAVE_KVM=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM=m
+# CONFIG_VHOST_NET is not set
 CONFIG_VIRTIO=y
 CONFIG_VIRTIO_RING=y
 CONFIG_VIRTIO_BALLOON=m
index 87cf523192e98527d85b00c7ee646b79b00b74d5..5b1acdba64957c53622dbf01861b992c78d514dd 100644 (file)
@@ -12,7 +12,6 @@
 
 #include <linux/types.h>
 #include <linux/errno.h>
-#include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
index cd128b07beda7e1c798043c984d4343aa06ae046..c53f8ac825caf3c6aa6ef54d370fa1ecd9f9688d 100644 (file)
@@ -14,8 +14,8 @@
 #include <linux/fs.h>
 #include <linux/namei.h>
 #include <linux/vfs.h>
+#include <linux/slab.h>
 #include <linux/pagemap.h>
-#include <linux/gfp.h>
 #include <linux/time.h>
 #include <linux/parser.h>
 #include <linux/sysfs.h>
index 9b5b9189c15e86cc9f5053145324fe2123805ce9..89a504c3f12ec13f89fdcb34ab2b3602ce0c75a0 100644 (file)
@@ -105,7 +105,7 @@ extern char empty_zero_page[PAGE_SIZE];
 #ifndef __ASSEMBLY__
 /*
  * The vmalloc area will always be on the topmost area of the kernel
- * mapping. We reserve 96MB (31bit) / 1GB (64bit) for vmalloc,
+ * mapping. We reserve 96MB (31bit) / 128GB (64bit) for vmalloc,
  * which should be enough for any sane case.
  * By putting vmalloc at the top, we maximise the gap between physical
  * memory and vmalloc to catch misplaced memory accesses. As a side
@@ -120,8 +120,8 @@ extern unsigned long VMALLOC_START;
 #define VMALLOC_END    0x7e000000UL
 #define VMEM_MAP_END   0x80000000UL
 #else /* __s390x__ */
-#define VMALLOC_SIZE   (1UL << 30)
-#define VMALLOC_END    0x3e040000000UL
+#define VMALLOC_SIZE   (128UL << 30)
+#define VMALLOC_END    0x3e000000000UL
 #define VMEM_MAP_END   0x40000000000UL
 #endif /* __s390x__ */
 
index 67ee6c3c6bb3aa352484c94449c135315b0763ec..1741c1556a4e975ccc9fa7c655f45bb91fd0a530 100644 (file)
@@ -110,6 +110,7 @@ extern void pfault_fini(void);
 #endif /* CONFIG_PFAULT */
 
 extern void cmma_init(void);
+extern int memcpy_real(void *, void *, size_t);
 
 #define finish_arch_switch(prev) do {                                       \
        set_fs(current->thread.mm_segment);                                  \
@@ -218,8 +219,8 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
                        "       l       %0,%2\n"
                        "0:     nr      %0,%5\n"
                        "       lr      %1,%0\n"
-                       "       or      %0,%2\n"
-                       "       or      %1,%3\n"
+                       "       or      %0,%3\n"
+                       "       or      %1,%4\n"
                        "       cs      %0,%1,%2\n"
                        "       jnl     1f\n"
                        "       xr      %1,%0\n"
@@ -239,8 +240,8 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
                        "       l       %0,%2\n"
                        "0:     nr      %0,%5\n"
                        "       lr      %1,%0\n"
-                       "       or      %0,%2\n"
-                       "       or      %1,%3\n"
+                       "       or      %0,%3\n"
+                       "       or      %1,%4\n"
                        "       cs      %0,%1,%2\n"
                        "       jnl     1f\n"
                        "       xr      %1,%0\n"
index 4a76d9480cce533dd5b95d658acb0c6ecd6808e9..533f35751aeb9ad130af57e0f6cf551cfe873862 100644 (file)
@@ -29,6 +29,7 @@ struct vdso_data {
        __u32 tz_minuteswest;           /* Minutes west of Greenwich    0x30 */
        __u32 tz_dsttime;               /* Type of dst correction       0x34 */
        __u32 ectg_available;
+       __u32 ntp_mult;                 /* NTP adjusted multiplier      0x3C */
 };
 
 struct vdso_per_cpu_data {
index 08db736dded00192b435129698a6cf5efee420ac..a09408952ed0691a41c0bfcfefad321a7c79c865 100644 (file)
@@ -61,6 +61,7 @@ int main(void)
        DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
        DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest));
        DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available));
+       DEFINE(__VDSO_NTP_MULT, offsetof(struct vdso_data, ntp_mult));
        DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base));
        DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time));
        /* constants used by the vdso */
index 11c3aba664ea6840604c50399a61121e8742d387..73b624ed9cd8ae612eef9521e8e708b458895bab 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
-#include <linux/slab.h>
 #include <linux/uio.h>
 #include <linux/quota.h>
 #include <linux/module.h>
@@ -52,6 +51,7 @@
 #include <linux/ptrace.h>
 #include <linux/fadvise.h>
 #include <linux/ipc.h>
+#include <linux/slab.h>
 
 #include <asm/types.h>
 #include <asm/uaccess.h>
index 31d618a443af545db6d9c41327507261f55dbf53..2d92c2cf92d71e499fbf6b4a1ac822a4380af3c2 100644 (file)
@@ -82,7 +82,8 @@ asm(
        "       lm      6,15,24(15)\n"
 #endif
        "       br      14\n"
-       "       .size   savesys_ipl_nss, .-savesys_ipl_nss\n");
+       "       .size   savesys_ipl_nss, .-savesys_ipl_nss\n"
+       "       .previous\n");
 
 static __initdata char upper_command_line[COMMAND_LINE_SIZE];
 
index 4348f9bc5393f445221c1444b8e9a2ddfaeb486c..6af7045280a8945009471209766bbd3f0c289b09 100644 (file)
@@ -964,7 +964,7 @@ cleanup_critical:
        clc     4(4,%r12),BASED(cleanup_table_io_work_loop)
        bl      BASED(0f)
        clc     4(4,%r12),BASED(cleanup_table_io_work_loop+4)
-       bl      BASED(cleanup_io_return)
+       bl      BASED(cleanup_io_work_loop)
 0:
        br      %r14
 
@@ -1038,6 +1038,12 @@ cleanup_sysc_leave_insn:
        .long   sysc_done - 8 + 0x80000000
 
 cleanup_io_return:
+       mvc     __LC_RETURN_PSW(4),0(%r12)
+       mvc     __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_return)
+       la      %r12,__LC_RETURN_PSW
+       br      %r14
+
+cleanup_io_work_loop:
        mvc     __LC_RETURN_PSW(4),0(%r12)
        mvc     __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop)
        la      %r12,__LC_RETURN_PSW
index 29fd0f1e6ec41fba888f37d43794871bd2106f6f..52106d53271c3c2b99bede6ffd68f7e0958ab59c 100644 (file)
@@ -946,7 +946,7 @@ cleanup_critical:
        clc     8(8,%r12),BASED(cleanup_table_io_work_loop)
        jl      0f
        clc     8(8,%r12),BASED(cleanup_table_io_work_loop+8)
-       jl      cleanup_io_return
+       jl      cleanup_io_work_loop
 0:
        br      %r14
 
@@ -1020,6 +1020,12 @@ cleanup_sysc_leave_insn:
        .quad   sysc_done - 16
 
 cleanup_io_return:
+       mvc     __LC_RETURN_PSW(8),0(%r12)
+       mvc     __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_return)
+       la      %r12,__LC_RETURN_PSW
+       br      %r14
+
+cleanup_io_work_loop:
        mvc     __LC_RETURN_PSW(8),0(%r12)
        mvc     __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_work_loop)
        la      %r12,__LC_RETURN_PSW
index ca4a62bd862fc8507966c1efdf64e41cae6efe20..9d1f76702d47acd67d3114c49057f363e7133d6d 100644 (file)
@@ -517,7 +517,10 @@ startup:
        lhi     %r1,2                   # mode 2 = esame (dump)
        sigp    %r1,%r0,0x12            # switch to esame mode
        sam64                           # switch to 64 bit mode
+       larl    %r13,4f
+       lmh     %r0,%r15,0(%r13)        # clear high-order half
        jg      startup_continue
+4:     .fill   16,4,0x0
 #else
        mvi     __LC_AR_MODE_ID,0       # set ESA flag (mode 0)
        l       %r13,4f-.LPG0(%r13)
index 1bbcc499d455c87096b84f89bab35a629a5ab388..b8f8dc126102e7a0734eeb037376919e2a34ca62 100644 (file)
@@ -82,7 +82,7 @@ startup_continue:
 _ehead:
 
 #ifdef CONFIG_SHARED_KERNEL
-       .org    0x100000
+       .org    0x100000 - 0x11000      # head.o ends at 0x11000
 #endif
 
 #
index 39580e768658e0b23f76587b6fb59e5c000936f1..cdef68717416cedce7b46d41599bde1f2be9821c 100644 (file)
@@ -21,7 +21,6 @@ startup_continue:
        larl    %r1,sched_clock_base_cc
        mvc     0(8,%r1),__LC_LAST_UPDATE_CLOCK
        larl    %r13,.LPG1              # get base
-       lmh     %r0,%r15,.Lzero64-.LPG1(%r13)   # clear high-order half
        lctlg   %c0,%c15,.Lctl-.LPG1(%r13)      # load control registers
        lg      %r12,.Lparmaddr-.LPG1(%r13)     # pointer to parameter area
                                        # move IPL device to lowcore
@@ -67,7 +66,6 @@ startup_continue:
 .L4malign:.quad 0xffffffffffc00000
 .Lscan2g:.quad 0x80000000 + 0x20000 - 8        # 2GB + 128K - 8
 .Lnop: .long   0x07000700
-.Lzero64:.fill 16,4,0x0
 .Lparmaddr:
        .quad   PARMAREA
        .align  64
@@ -82,7 +80,7 @@ startup_continue:
 _ehead:
 
 #ifdef CONFIG_SHARED_KERNEL
-       .org    0x100000
+       .org    0x100000 - 0x11000      # head.o ends at 0x11000
 #endif
 
 #
index 7eedbbcb54aa5901bf989397cbaa9b405c260529..72c8b0d070c849f5fb2891473f093ad2650f6ea4 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/reboot.h>
 #include <linux/ctype.h>
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <asm/ipl.h>
 #include <asm/smp.h>
 #include <asm/setup.h>
index 86783efa24eebd95af298fc488d08ac8f30bb009..3d34eef5a2c3a03987479a28df28e4a415e3c2f0 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/cacheflush.h>
 #include <asm/sections.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
index 00b6d1d292f2a6efecf23d5abde930f89f68878b..1039fdea15b58bdb805f92838c9342d95253c4fb 100644 (file)
@@ -16,9 +16,9 @@
 #include <linux/fs.h>
 #include <linux/smp.h>
 #include <linux/stddef.h>
+#include <linux/slab.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/user.h>
 #include <linux/interrupt.h>
index 33fdc5a7976472831185126e419a637807e48b1d..9f654da4cecc82377fcd0abf7bd7acfe617eec08 100644 (file)
@@ -640,7 +640,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 
 asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
 {
-       long ret;
+       long ret = 0;
 
        /* Do the secure computing check first. */
        secure_computing(regs->gprs[2]);
@@ -649,7 +649,6 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
         * The sysc_tracesys code in entry.S stored the system
         * call number to gprs[2].
         */
-       ret = regs->gprs[2];
        if (test_thread_flag(TIF_SYSCALL_TRACE) &&
            (tracehook_report_syscall_entry(regs) ||
             regs->gprs[2] >= NR_syscalls)) {
@@ -671,7 +670,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
                                    regs->gprs[2], regs->orig_gpr2,
                                    regs->gprs[3], regs->gprs[4],
                                    regs->gprs[5]);
-       return ret;
+       return ret ?: regs->gprs[2];
 }
 
 asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
index 77a63ae419f00c8196a5e8cc944ac6224795ad2f..91625f759ccdfacd4c6c65deff5d5a974f7433f4 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/tty.h>
 #include <linux/ioport.h>
@@ -401,7 +400,7 @@ setup_lowcore(void)
         * Setup lowcore for boot cpu
         */
        BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096);
-       lc = __alloc_bootmem(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
+       lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
        lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
        lc->restart_psw.addr =
                PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
@@ -433,7 +432,7 @@ setup_lowcore(void)
 #ifndef CONFIG_64BIT
        if (MACHINE_HAS_IEEE) {
                lc->extended_save_area_addr = (__u32)
-                       __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0);
+                       __alloc_bootmem_low(PAGE_SIZE, PAGE_SIZE, 0);
                /* enable extended save area */
                __ctl_set_bit(14, 29);
        }
index 29f65bce55e1bea4cac1e9c00297a0fb7eda371a..e4d98de83dd8393586118ec7ee760d4907385c05 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/cpu.h>
 #include <linux/timex.h>
 #include <linux/bootmem.h>
+#include <linux/slab.h>
 #include <asm/asm-offsets.h>
 #include <asm/ipl.h>
 #include <asm/setup.h>
@@ -292,9 +293,9 @@ static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
        zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL);
        while (raw_sigp(phy_cpu, sigp_stop_and_store_status) == sigp_busy)
                cpu_relax();
-       memcpy(zfcpdump_save_areas[cpu],
-              (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
-              sizeof(struct save_area));
+       memcpy_real(zfcpdump_save_areas[cpu],
+                   (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
+                   sizeof(struct save_area));
 }
 
 struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
index b354427e03b7508a1454385d6a53518f1f7e07e3..c56d3f56d020224583bfcee76790dd761fa39c78 100644 (file)
@@ -256,6 +256,9 @@ restore_registers:
        lghi    %r2,0
        brasl   %r14,arch_set_page_states
 
+       /* Reinitialize the channel subsystem */
+       brasl   %r14,channel_subsystem_reinit
+
        /* Return 0 */
        lmg     %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15)
        lghi    %r2,0
index b5e75e1061c82d35b40b63594f1889ce07d0453b..a0ffc7717ed62994609a66b22202982b1c867dba 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/ebcdic.h>
 #include <asm/sysinfo.h>
 #include <asm/cpcmd.h>
index aa2483e460f32a93e0906fd8a838d3b0dc4cdc4b..a2163c95eb9845ffac908bf09b7af1bb5084cf3c 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/notifier.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
+#include <linux/gfp.h>
 #include <asm/uaccess.h>
 #include <asm/delay.h>
 #include <asm/s390_ext.h>
@@ -220,6 +221,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
        vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
        vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
        vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
+       vdso_data->ntp_mult = mult;
        smp_wmb();
        ++vdso_data->tb_update_count;
 }
@@ -389,7 +391,6 @@ static void __init time_init_wq(void)
        if (time_sync_wq)
                return;
        time_sync_wq = create_singlethread_workqueue("timesync");
-       stop_machine_create();
 }
 
 /*
index 14ef6f05e4324b94f7146f0207e9203aa9a62df5..247b4c2d1e5130ea9d7a3781ae8c786121923bee 100644 (file)
@@ -165,10 +165,11 @@ static void tl_to_cores(struct tl_info *info)
                default:
                        clear_cores();
                        machine_has_topology = 0;
-                       return;
+                       goto out;
                }
                tle = next_tle(tle);
        }
+out:
        spin_unlock_irq(&topology_lock);
 }
 
index 4a98909a83100c40fe5440822302a453403dcf4a..969643954273c2e1a3c75fe045985d3649e661c3 100644 (file)
@@ -38,13 +38,13 @@ __kernel_clock_gettime:
        sl      %r1,__VDSO_XTIME_STAMP+4(%r5)
        brc     3,2f
        ahi     %r0,-1
-2:     mhi     %r0,1000                        /* cyc2ns(clock,cycle_delta) */
+2:     ms      %r0,__VDSO_NTP_MULT(%r5)        /* cyc2ns(clock,cycle_delta) */
        lr      %r2,%r0
-       lhi     %r0,1000
+       l       %r0,__VDSO_NTP_MULT(%r5)
        ltr     %r1,%r1
        mr      %r0,%r0
        jnm     3f
-       ahi     %r0,1000
+       a       %r0,__VDSO_NTP_MULT(%r5)
 3:     alr     %r0,%r2
        srdl    %r0,12
        al      %r0,__VDSO_XTIME_NSEC(%r5)      /*  + xtime */
@@ -86,13 +86,13 @@ __kernel_clock_gettime:
        sl      %r1,__VDSO_XTIME_STAMP+4(%r5)
        brc     3,12f
        ahi     %r0,-1
-12:    mhi     %r0,1000                        /* cyc2ns(clock,cycle_delta) */
+12:    ms      %r0,__VDSO_NTP_MULT(%r5)        /* cyc2ns(clock,cycle_delta) */
        lr      %r2,%r0
-       lhi     %r0,1000
+       l       %r0,__VDSO_NTP_MULT(%r5)
        ltr     %r1,%r1
        mr      %r0,%r0
        jnm     13f
-       ahi     %r0,1000
+       a       %r0,__VDSO_NTP_MULT(%r5)
 13:    alr     %r0,%r2
        srdl    %r0,12
        al      %r0,__VDSO_XTIME_NSEC(%r5)      /*  + xtime */
index ad8acfc949fbdb5d0a7f59375bf567770780686e..2d3633175e3be520850ad6b48b30e94c88058072 100644 (file)
@@ -35,13 +35,13 @@ __kernel_gettimeofday:
        sl      %r1,__VDSO_XTIME_STAMP+4(%r5)
        brc     3,3f
        ahi     %r0,-1
-3:     mhi     %r0,1000                        /* cyc2ns(clock,cycle_delta) */
+3:     ms      %r0,__VDSO_NTP_MULT(%r5)        /* cyc2ns(clock,cycle_delta) */
        st      %r0,24(%r15)
-       lhi     %r0,1000
+       l       %r0,__VDSO_NTP_MULT(%r5)
        ltr     %r1,%r1
        mr      %r0,%r0
        jnm     4f
-       ahi     %r0,1000
+       a       %r0,__VDSO_NTP_MULT(%r5)
 4:     al      %r0,24(%r15)
        srdl    %r0,12
        al      %r0,__VDSO_XTIME_NSEC(%r5)      /*  + xtime */
index 49106c6e6f88336ab9e3d641e97ba25b8179df04..f40467884a03722c668b388591e976f71be8961d 100644 (file)
@@ -36,7 +36,7 @@ __kernel_clock_gettime:
        stck    48(%r15)                        /* Store TOD clock */
        lg      %r1,48(%r15)
        sg      %r1,__VDSO_XTIME_STAMP(%r5)     /* TOD - cycle_last */
-       mghi    %r1,1000
+       msgf    %r1,__VDSO_NTP_MULT(%r5)        /*  * NTP adjustment */
        srlg    %r1,%r1,12                      /* cyc2ns(clock,cycle_delta) */
        alg     %r1,__VDSO_XTIME_NSEC(%r5)      /*  + xtime */
        lg      %r0,__VDSO_XTIME_SEC(%r5)
@@ -64,7 +64,7 @@ __kernel_clock_gettime:
        stck    48(%r15)                        /* Store TOD clock */
        lg      %r1,48(%r15)
        sg      %r1,__VDSO_XTIME_STAMP(%r5)     /* TOD - cycle_last */
-       mghi    %r1,1000
+       msgf    %r1,__VDSO_NTP_MULT(%r5)        /*  * NTP adjustment */
        srlg    %r1,%r1,12                      /* cyc2ns(clock,cycle_delta) */
        alg     %r1,__VDSO_XTIME_NSEC(%r5)      /*  + xtime */
        lg      %r0,__VDSO_XTIME_SEC(%r5)
index f873e75634e1b1041a4df34caa9083c604ce5e45..36ee674722ec3a76b3439fe78752f024ba5ba434 100644 (file)
@@ -31,7 +31,7 @@ __kernel_gettimeofday:
        stck    48(%r15)                        /* Store TOD clock */
        lg      %r1,48(%r15)
        sg      %r1,__VDSO_XTIME_STAMP(%r5)     /* TOD - cycle_last */
-       mghi    %r1,1000
+       msgf    %r1,__VDSO_NTP_MULT(%r5)        /*  * NTP adjustment */
        srlg    %r1,%r1,12                      /* cyc2ns(clock,cycle_delta) */
        alg     %r1,__VDSO_XTIME_NSEC(%r5)      /*  + xtime.tv_nsec */
        lg      %r0,__VDSO_XTIME_SEC(%r5)       /* xtime.tv_sec */
index 834774d8d5f3021c3867c6385a6754abbec04410..35c21bf910c55bff4e1ee45ee968eb69726dd182 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kvm_host.h>
 #include <linux/hrtimer.h>
 #include <linux/signal.h>
+#include <linux/slab.h>
 #include <asm/asm-offsets.h>
 #include <asm/uaccess.h>
 #include "kvm-s390.h"
index 28c55677eb399c33f472a564d596666f01bcedd3..44205507717cc673e1906d557f8d8bbe4e77f863 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/kvm.h>
+#include <linux/gfp.h>
 #include <linux/errno.h>
 #include <asm/current.h>
 #include <asm/debug.h>
index 241a48459b666fab172d376ddfda2da4562145ad..eff3c5989b46b1135336cb806794febeebf6c905 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
+#include <linux/slab.h>
 #include "gaccess.h"
 #include "kvm-s390.h"
 
index f16bd04e39e9566dabe8928e7cd526bdcd26010c..f87b34731e1d9e377de37c30adfcbc50dec18477 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/sysctl.h>
 #include <linux/ctype.h>
index d5865e4024cebb6f6c6e295f95b34096484e07a7..acc91c75bc94a7e4a3b8f87600cbe312c4bdcc90 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/pfn.h>
 #include <linux/poison.h>
 #include <linux/initrd.h>
+#include <linux/gfp.h>
 #include <asm/processor.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
index 81756271dc44a51848f26f93bab6c5b2a066982a..a8c2af8c650fabd9c96a4f9efaf3c0c4f530f294 100644 (file)
@@ -59,3 +59,29 @@ long probe_kernel_write(void *dst, void *src, size_t size)
        }
        return copied < 0 ? -EFAULT : 0;
 }
+
+int memcpy_real(void *dest, void *src, size_t count)
+{
+       register unsigned long _dest asm("2") = (unsigned long) dest;
+       register unsigned long _len1 asm("3") = (unsigned long) count;
+       register unsigned long _src  asm("4") = (unsigned long) src;
+       register unsigned long _len2 asm("5") = (unsigned long) count;
+       unsigned long flags;
+       int rc = -EFAULT;
+
+       if (!count)
+               return 0;
+       flags = __raw_local_irq_stnsm(0xf8UL);
+       asm volatile (
+               "0:     mvcle   %1,%2,0x0\n"
+               "1:     jo      0b\n"
+               "       lhi     %0,0x0\n"
+               "2:\n"
+               EX_TABLE(1b,2b)
+               : "+d" (rc), "+d" (_dest), "+d" (_src), "+d" (_len1),
+                 "+d" (_len2), "=m" (*((long *) dest))
+               : "m" (*((long *) src))
+               : "cc", "memory");
+       __raw_local_irq_ssm(flags);
+       return rc;
+}
index 098923ae458fb04563c72a541e0cd7b287870343..a90d45e9dfb0cbb7b1dce5fb8441a249dc0556c3 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/mm.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 
 #define ESSA_SET_STABLE                1
index ad621e06ada34fd32550bcf66200c24d1e00199c..8d999249d3574fb880da55af3fb5ff40d7f32fe8 100644 (file)
@@ -6,11 +6,11 @@
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
 #include <linux/smp.h>
 #include <linux/highmem.h>
-#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/spinlock.h>
 #include <linux/module.h>
index 300ab012b0fd875efa119d09f2784a60a3769843..90165e7ca04eb2135e57c321de9912208fcea4bc 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/list.h>
 #include <linux/hugetlb.h>
+#include <linux/slab.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/setup.h>
@@ -70,12 +71,8 @@ static pte_t __ref *vmem_pte_alloc(void)
                pte = alloc_bootmem(PTRS_PER_PTE * sizeof(pte_t));
        if (!pte)
                return NULL;
-       if (MACHINE_HAS_HPAGE)
-               clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY | _PAGE_CO,
-                           PTRS_PER_PTE * sizeof(pte_t));
-       else
-               clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY,
-                           PTRS_PER_PTE * sizeof(pte_t));
+       clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY,
+                   PTRS_PER_PTE * sizeof(pte_t));
        return pte;
 }
 
@@ -116,8 +113,7 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro)
                if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) &&
                    (address + HPAGE_SIZE <= start + size) &&
                    (address >= HPAGE_SIZE)) {
-                       pte_val(pte) |= _SEGMENT_ENTRY_LARGE |
-                                       _SEGMENT_ENTRY_CO;
+                       pte_val(pte) |= _SEGMENT_ENTRY_LARGE;
                        pmd_val(*pm_dir) = pte_val(pte);
                        address += HPAGE_SIZE - PAGE_SIZE;
                        continue;
index 856ed68a58e6103efd22d0496cb2884438f8cfa0..651096ff8db49e2c9c4b564c00a0a12510a8b050 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/unistd.h>
 #include <linux/syscalls.h>
 #include <asm/syscalls.h>
index 7f001bbedb00a463d0746c2690421eec1df5bf3a..50fdec54c70a75c6aabd281263139f4dca54a6ef 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/errno.h>
 #include <linux/bootmem.h>
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
index 8d90564c2bcfe7dee87dbb5e814e4ed6db054504..e6d8ab5cfa9d18b8bd5bf97cce9de7ed44bd1285 100644 (file)
@@ -44,6 +44,7 @@ config SUPERH32
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_ARCH_KGDB
        select HAVE_HW_BREAKPOINT
+       select HAVE_MIXED_BREAKPOINTS_REGS
        select PERF_EVENTS if HAVE_HW_BREAKPOINT
        select ARCH_HIBERNATION_POSSIBLE if MMU
 
index 39ed8722d11ad0b12469e6d17d4a98b671328634..6c13b92742e8de0d6410fbf0e3fc9553852d5e75 100644 (file)
@@ -836,6 +836,8 @@ static void __init sh_eth_init(struct sh_eth_plat_data *pd)
                pd->mac_addr[i] = mac_read(a, 0x10 + i);
                msleep(10);
        }
+
+       i2c_put_adapter(a);
 }
 #else
 static void __init sh_eth_init(struct sh_eth_plat_data *pd)
index 66cdbc3c7af9d0ae5e131099da29221fc997b8fd..ccaa290e9aba1cb29222cde90819cecb2f246cc6 100644 (file)
  * and change SW41 to use 720p
  */
 
+/*
+ * about sound
+ *
+ * This setup.c supports FSI slave mode.
+ * Please change J20, J21, J22 pin to 1-2 connection.
+ */
+
 /* Heartbeat */
 static struct resource heartbeat_resource = {
        .start  = PA_LED,
@@ -276,6 +283,7 @@ static struct clk fsimcka_clk = {
        .rate           = 0, /* unknown */
 };
 
+/* change J20, J21, J22 pin to 1-2 connection to use slave mode */
 struct sh_fsi_platform_info fsi_info = {
        .porta_flags = SH_FSI_BRS_INV |
                       SH_FSI_OUT_SLAVE_MODE |
index 18e3356406f3cfa071794aa62901753bc4399d40..6041c66dd10ee1c22bc961262358c4dc9b3bdddb 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:20:36 2010
+# Linux kernel version: 2.6.34-rc2
+# Mon Mar 29 02:21:58 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -47,9 +48,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -71,14 +74,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -107,7 +104,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -116,13 +113,13 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=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
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -234,12 +231,12 @@ CONFIG_CPU_SUBTYPE_SH7724=y
 CONFIG_QUICKLIST=y
 CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
-CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_FORCE_MAX_ZONEORDER=12
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x10000000
 CONFIG_29BIT=y
-# CONFIG_PMB_ENABLE is not set
-# CONFIG_X2TLB is not set
+# CONFIG_PMB is not set
+CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -247,6 +244,8 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -262,7 +261,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -337,7 +336,6 @@ CONFIG_SECCOMP=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -347,7 +345,7 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
 CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_CMDLINE_OVERWRITE=y
 # CONFIG_CMDLINE_EXTEND is not set
-CONFIG_CMDLINE="console=tty0, console=ttySC0,115200 root=/dev/nfs ip=dhcp mem=120M memchunk.vpu=4m"
+CONFIG_CMDLINE="console=tty0, console=ttySC0,115200 root=/dev/nfs ip=dhcp mem=248M memchunk.vpu=8m memchunk.veu0=4m"
 
 #
 # Bus options
@@ -373,6 +371,7 @@ CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_HIBERNATION is not set
 CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 # CONFIG_CPU_IDLE is not set
 CONFIG_NET=y
 
@@ -380,7 +379,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -445,7 +443,45 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
-# CONFIG_IRDA is not set
+CONFIG_IRDA=y
+
+#
+# IrDA protocols
+#
+# CONFIG_IRLAN is not set
+# CONFIG_IRCOMM is not set
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+# CONFIG_IRTTY_SIR is not set
+
+#
+# Dongle support
+#
+CONFIG_SH_SIR=y
+# CONFIG_KINGSUN_DONGLE is not set
+# CONFIG_KSDAZZLE_DONGLE is not set
+# CONFIG_KS959_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_MCS_FIR is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
@@ -556,6 +592,7 @@ CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_NANDSIM is not set
 # CONFIG_MTD_NAND_PLATFORM is not set
 # CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_NAND_SH_FLCTL is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
@@ -597,6 +634,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -616,6 +654,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -768,7 +807,29 @@ CONFIG_KEYBOARD_SH_KEYSC=y
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# 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
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+CONFIG_TOUCHSCREEN_TSC2007=y
+# CONFIG_TOUCHSCREEN_W90X900 is not set
 # CONFIG_INPUT_MISC is not set
 
 #
@@ -802,10 +863,10 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
 # CONFIG_HW_RANDOM_TIMERIOMEM is not set
@@ -830,6 +891,7 @@ CONFIG_I2C_HELPER_AUTO=y
 # CONFIG_I2C_OCORES is not set
 CONFIG_I2C_SH_MOBILE=y
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -843,15 +905,9 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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=y
 CONFIG_SPI_MASTER=y
 
@@ -882,13 +938,16 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -919,23 +978,26 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
-# CONFIG_MFD_CORE is not set
+CONFIG_MFD_CORE=y
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_SH_MOBILE_SDHI is not set
+CONFIG_MFD_SH_MOBILE_SDHI=y
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 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_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 CONFIG_MEDIA_SUPPORT=y
@@ -985,10 +1047,10 @@ CONFIG_SOC_CAMERA=y
 # CONFIG_SOC_CAMERA_MT9M001 is not set
 # CONFIG_SOC_CAMERA_MT9M111 is not set
 # CONFIG_SOC_CAMERA_MT9T031 is not set
-# CONFIG_SOC_CAMERA_MT9T112 is not set
+CONFIG_SOC_CAMERA_MT9T112=y
 # CONFIG_SOC_CAMERA_MT9V022 is not set
 # CONFIG_SOC_CAMERA_RJ54N1 is not set
-# CONFIG_SOC_CAMERA_TW9910 is not set
+CONFIG_SOC_CAMERA_TW9910=y
 # CONFIG_SOC_CAMERA_PLATFORM is not set
 # CONFIG_SOC_CAMERA_OV772X is not set
 # CONFIG_SOC_CAMERA_OV9640 is not set
@@ -1001,6 +1063,7 @@ CONFIG_RADIO_ADAPTERS=y
 # CONFIG_RADIO_SI470X is not set
 # CONFIG_USB_MR800 is not set
 # CONFIG_RADIO_TEA5764 is not set
+# CONFIG_RADIO_SAA7706H is not set
 # CONFIG_RADIO_TEF6862 is not set
 # CONFIG_DAB is not set
 
@@ -1034,6 +1097,7 @@ CONFIG_FB_DEFERRED_IO=y
 #
 # CONFIG_FB_S1D13XXX is not set
 CONFIG_FB_SH_MOBILE_LCDC=y
+# CONFIG_FB_TMIO is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
@@ -1062,7 +1126,46 @@ CONFIG_LOGO=y
 # CONFIG_LOGO_SUPERH_MONO is not set
 # CONFIG_LOGO_SUPERH_VGA16 is not set
 CONFIG_LOGO_SUPERH_CLUT224=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_SEQUENCER=y
+CONFIG_SND_SEQ_DUMMY=y
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_SEQUENCER_OSS 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 is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_SUPERH=y
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+
+#
+# SoC Audio support for SuperH
+#
+CONFIG_SND_SOC_SH4_FSI=y
+# CONFIG_SND_FSI_AK4642 is not set
+CONFIG_SND_FSI_DA7210=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_DA7210=y
+# CONFIG_SOUND_PRIME is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HIDRAW is not set
@@ -1077,6 +1180,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 # CONFIG_HID_A4TECH is not set
 # CONFIG_HID_APPLE is not set
 # CONFIG_HID_BELKIN is not set
@@ -1091,12 +1195,16 @@ CONFIG_USB_HID=y
 # CONFIG_HID_KENSINGTON is not set
 # CONFIG_HID_LOGITECH is not set
 # CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
 # CONFIG_HID_MONTEREY is not set
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_QUANTA is not set
 # CONFIG_HID_SAMSUNG is not set
 # CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
 # CONFIG_HID_SUNPLUS is not set
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1136,6 +1244,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_SL811_HCD is not set
 CONFIG_USB_R8A66597_HCD=y
 # CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
@@ -1188,7 +1297,6 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1200,8 +1308,45 @@ CONFIG_USB_STORAGE=y
 # 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
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# 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=y
+CONFIG_USB_R8A66597=y
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
+# CONFIG_USB_G_MULTI is not set
 
 #
 # OTG and related infrastructure
@@ -1224,10 +1369,8 @@ CONFIG_MMC_BLOCK_BOUNCE=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_SPI=y
-# CONFIG_MMC_TMIO is not set
+CONFIG_MMC_TMIO=y
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
@@ -1253,10 +1396,10 @@ CONFIG_RTC_INTF_DEV=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_RS5C372=y
 # CONFIG_RTC_DRV_ISL1208 is not set
 # CONFIG_RTC_DRV_X1205 is not set
-CONFIG_RTC_DRV_PCF8563=y
+# CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
 # CONFIG_RTC_DRV_BQ32K is not set
@@ -1303,8 +1446,6 @@ CONFIG_RTC_DRV_PCF8563=y
 CONFIG_UIO=y
 # CONFIG_UIO_PDRV is not set
 CONFIG_UIO_PDRV_GENIRQ=y
-# CONFIG_UIO_SMX is not set
-# CONFIG_UIO_SERCOS3 is not set
 
 #
 # TI VLYNQ
@@ -1390,6 +1531,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_UBIFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1418,6 +1560,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1487,6 +1630,7 @@ CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_HAVE_FUNCTION_TRACER=y
@@ -1618,7 +1762,7 @@ CONFIG_CRYPTO_HW=y
 #
 CONFIG_BITREVERSE=y
 CONFIG_GENERIC_FIND_LAST_BIT=y
-# CONFIG_CRC_CCITT is not set
+CONFIG_CRC_CCITT=y
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=y
index fba1f62d56e74ad6cde573b67a437ceb7a54c076..dba024d72a894599ac708051105d6f11d8506298 100644 (file)
@@ -877,7 +877,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 #
 # CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=1
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
index a8d538f06e67771f58a43ca848fc19a0e9a21438..6d511d06cbf6c6bd8d4ea4a39a3a19c1c050412d 100644 (file)
@@ -963,7 +963,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 #
 # CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=1
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
index 727126e907e33c01cdf616529b3c8e0221794398..4a277224a871f9d846210916d48eab26f80ab489 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/dma.h>
 
 DEFINE_SPINLOCK(dma_spin_lock);
index 72622e3076136d425c8e574487332619dc910fab..6ab9c4a1543994f3deafbd8dfccfe1e8392ad948 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <asm/dma.h>
 #include <asm/dmabrg.h>
 #include <asm/io.h>
index 2acbc793032de7da013c16db1c3e1e4eb3ed2c12..7efc9c354fc7e7847f00334d4687075c1416a26d 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/sched.h>
 #include <linux/timer.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <asm/heartbeat.h>
 
 #define DRV_NAME "heartbeat"
index 17811e5d287bd46b159f908a8e880972ab4251b2..f98141b3b7d7283ba82d04e00064231f0715b4a2 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/io.h>
 #include "pci-sh4.h"
 #include <asm/addrspace.h>
+#include <asm/sizes.h>
 
 static int __init __area_sdram_check(struct pci_channel *chan,
                                     unsigned int area)
@@ -47,8 +48,8 @@ static int __init __area_sdram_check(struct pci_channel *chan,
 static struct resource sh7751_pci_resources[] = {
        {
                .name   = "SH7751_IO",
-               .start  = SH7751_PCI_IO_BASE,
-               .end    = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
+               .start  = 0x1000,
+               .end    = SZ_4M - 1,
                .flags  = IORESOURCE_IO
        }, {
                .name   = "SH7751_mem",
index ae91a2dd9183c829ee2177af54c6df627f9c75cb..68cb9b0ac9d28294d00c8cb63a9ece18a5ad7bfd 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include "pcie-sh7786.h"
 #include <asm/sizes.h>
 
index 725be6de589b4e81081ea63a364229ed6bf54911..7b42c247316c56e1e0fc85da723407c041f2097f 100644 (file)
@@ -8,6 +8,7 @@
  * for more details.
  */
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
index 275a448ae8c27bd38bb6cd19fbe7280d8b54198a..c7983124d99dfb6a31bfbf5233f48ba77a168119 100644 (file)
@@ -13,7 +13,7 @@
 
 #define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
 
-#define atomic_read(v)         ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
 #define atomic_set(v,i)                ((v)->counter = (i))
 
 #if defined(CONFIG_GUSA_RB)
index ac04255022b69548e6f71f07f0502e97664c881f..ce830faeebbf50705e1ba1126b240ea274bbd77c 100644 (file)
@@ -211,7 +211,9 @@ extern void __kernel_vsyscall;
 
 #define VSYSCALL_AUX_ENT                                       \
        if (vdso_enabled)                                       \
-               NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE);
+               NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE);        \
+       else                                                    \
+               NEW_AUX_ENT(AT_IGNORE, 0);
 #else
 #define VSYSCALL_AUX_ENT
 #endif /* CONFIG_VSYSCALL */
@@ -219,7 +221,7 @@ extern void __kernel_vsyscall;
 #ifdef CONFIG_SH_FPU
 #define FPU_AUX_ENT    NEW_AUX_ENT(AT_FPUCW, FPSCR_INIT)
 #else
-#define FPU_AUX_ENT
+#define FPU_AUX_ENT    NEW_AUX_ENT(AT_IGNORE, 0)
 #endif
 
 extern int l1i_cache_shape, l1d_cache_shape, l2_cache_shape;
index 965dd780d51b9a1b061d3ad1b8d7bac13d7895ac..e14cad96798ffe10f43b16615792f8dd30225de2 100644 (file)
@@ -46,10 +46,14 @@ struct pmu;
 /* Maximum number of UBC channels */
 #define HBP_NUM                2
 
+static inline int hw_breakpoint_slots(int type)
+{
+       return HBP_NUM;
+}
+
 /* arch/sh/kernel/hw_breakpoint.c */
-extern int arch_check_va_in_userspace(unsigned long va, u16 hbp_len);
-extern int arch_validate_hwbkpt_settings(struct perf_event *bp,
-                                        struct task_struct *tsk);
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
 extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
                                           unsigned long val, void *data);
 
index 19fe84550b4915b7e951b97d52637c86cbd77b31..56e4418c19b984832589a53ccce34b554e56c2ed 100644 (file)
@@ -66,6 +66,13 @@ int pmb_unmap(void __iomem *addr);
 
 #else
 
+static inline int
+pmb_bolt_mapping(unsigned long virt, phys_addr_t phys,
+                unsigned long size, pgprot_t prot)
+{
+       return -EINVAL;
+}
+
 static inline void __iomem *
 pmb_remap_caller(phys_addr_t phys, unsigned long size,
                 pgprot_t prot, void *caller)
index 55f9fec082d4a55d6c047829f897ca40ef985ad3..de23595339940728e89a2f8d7f513445a1ea5fc9 100644 (file)
@@ -76,7 +76,7 @@ enum {
 }
 
 #define TS_INDEX2VAL(i)        ((((i) & 3) << CHCR_TS_LOW_SHIFT) | \
-                        ((((i) >> 2) & 3) << CHCR_TS_HIGH_SHIFT))
+                        (((i) & 0xc) << CHCR_TS_HIGH_SHIFT))
 
 #else /* CONFIG_CPU_SH4A */
 
index 03ea75c5315d4887380d996624e153e603d486df..5963124c1d4ad0f105605e139ea6f1e7d55cc845 100644 (file)
@@ -19,6 +19,8 @@
 
 #define MMUCR          0xFF000010      /* MMU Control Register */
 
+#define MMU_ITLB_ADDRESS_ARRAY  0xF2000000
+#define MMU_ITLB_ADDRESS_ARRAY2        0xF2800000
 #define MMU_UTLB_ADDRESS_ARRAY 0xF6000000
 #define MMU_UTLB_ADDRESS_ARRAY2        0xF6800000
 #define MMU_PAGE_ASSOC_BIT     0x80
@@ -28,6 +30,8 @@
 #define MMUCR_URB              0x00FC0000
 #define MMUCR_URB_SHIFT                18
 #define MMUCR_URB_NENTRIES     64
+#define MMUCR_URC              0x0000FC00
+#define MMUCR_URC_SHIFT                10
 
 #if defined(CONFIG_32BIT) && defined(CONFIG_CPU_SUBTYPE_ST40)
 #define MMUCR_SE               (1 << 4)
index 7672301d0c70917da242ce4e398fa5d4b84712f9..7f62b9380938203ad6d25a221db7c44424b1c46f 100644 (file)
 #define WTCNT          0xffcc0000 /*WDTST*/
 #define WTST           WTCNT
 #define WTBST          0xffcc0008 /*WDTBST*/
+/* Register definitions */
+#elif  defined(CONFIG_CPU_SUBTYPE_SH7722) || \
+       defined(CONFIG_CPU_SUBTYPE_SH7723) || \
+       defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define WTCNT          0xa4520000
+#define WTCSR          0xa4520004
 #else
 /* Register definitions */
 #define WTCNT          0xffc00008
index f059ed62cf57176cbae60d679a16436dff2793c3..7f1b70cace35d74be094e5078df32fe63c7eb680 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/processor.h>
 #include <asm/fpu.h>
 
index c0ad7d46e7848687b5103ad826bb1a92b1a284de..67a1e811cfe852851d353f3e63216dc0d99c619a 100644 (file)
@@ -1,6 +1,5 @@
 #include <linux/clk.h>
 #include <linux/compiler.h>
-#include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/spinlock.h>
 #include <asm/suspend.h>
index dce4f3ff09324f8340327379bac3ea49d6df0878..0fffacea6ed96aebda4c692ace9b1185468d74b5 100644 (file)
@@ -48,7 +48,7 @@ static int sh_cpufreq_target(struct cpufreq_policy *policy,
                return -ENODEV;
 
        cpus_allowed = current->cpus_allowed;
-       set_cpus_allowed(current, cpumask_of_cpu(cpu));
+       set_cpus_allowed_ptr(current, cpumask_of(cpu));
 
        BUG_ON(smp_processor_id() != cpu);
 
@@ -66,7 +66,7 @@ static int sh_cpufreq_target(struct cpufreq_policy *policy,
        freqs.flags     = 0;
 
        cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-       set_cpus_allowed(current, cpus_allowed);
+       set_cpus_allowed_ptr(current, &cpus_allowed);
        clk_set_rate(cpuclk, freq);
        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
index bd1c497280a66b927b1b07e8eaa4817fd278920a..a8234b2010d183c8c0e9374d91f402b799920f0f 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mm.h>
 #include <linux/elf.h>
 #include <linux/ftrace.h>
+#include <linux/slab.h>
 #include <asm/dwarf.h>
 #include <asm/unwinder.h>
 #include <asm/sections.h>
@@ -727,7 +728,7 @@ static int dwarf_parse_cie(void *entry, void *p, unsigned long len,
                           unsigned char *end, struct module *mod)
 {
        struct rb_node **rb_node = &cie_root.rb_node;
-       struct rb_node *parent;
+       struct rb_node *parent = *rb_node;
        struct dwarf_cie *cie;
        unsigned long flags;
        int count;
@@ -856,7 +857,7 @@ static int dwarf_parse_fde(void *entry, u32 entry_type,
                           unsigned char *end, struct module *mod)
 {
        struct rb_node **rb_node = &fde_root.rb_node;
-       struct rb_node *parent;
+       struct rb_node *parent = *rb_node;
        struct dwarf_fde *fde;
        struct dwarf_cie *cie;
        unsigned long flags;
index 675eea7785d9c8a91fa9db53950e37f30e756765..1f2cf6229862e47f9a311652cb6e5cf4c34585c4 100644 (file)
@@ -119,26 +119,17 @@ static int get_hbp_len(u16 hbp_len)
        return len_in_bytes;
 }
 
-/*
- * Check for virtual address in user space.
- */
-int arch_check_va_in_userspace(unsigned long va, u16 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)
+int arch_check_bp_in_kernelspace(struct perf_event *bp)
 {
        unsigned int len;
+       unsigned long va;
+       struct arch_hw_breakpoint *info = counter_arch_bp(bp);
 
-       len = get_hbp_len(hbp_len);
+       va = info->address;
+       len = get_hbp_len(info->len);
 
        return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
 }
@@ -226,8 +217,7 @@ static int arch_build_bp_info(struct perf_event *bp)
 /*
  * Validate the arch-specific HW Breakpoint register settings
  */
-int arch_validate_hwbkpt_settings(struct perf_event *bp,
-                                 struct task_struct *tsk)
+int arch_validate_hwbkpt_settings(struct perf_event *bp)
 {
        struct arch_hw_breakpoint *info = counter_arch_bp(bp);
        unsigned int align;
@@ -270,15 +260,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp,
        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;
 }
 
@@ -363,8 +344,7 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args)
                perf_bp_event(bp, args->regs);
 
                /* Deliver the signal to userspace */
-               if (arch_check_va_in_userspace(bp->attr.bp_addr,
-                                              bp->attr.bp_len)) {
+               if (!arch_check_bp_in_kernelspace(bp)) {
                        siginfo_t info;
 
                        info.si_signo = args->signr;
index 0fd7b41f0a2242c0e6a59e4e00048f7bd7f01c25..273f890b17ae3eb0fd643473e3a62b775cb8f51a 100644 (file)
@@ -112,7 +112,7 @@ void cpu_idle(void)
        }
 }
 
-void __cpuinit select_idle_routine(void)
+void __init select_idle_routine(void)
 {
        /*
         * If a platform has set its own idle routine, leave it alone.
index c96850b061fb8e4830c26afd5c083ab861ab0a06..4049d99f76e13ff5983b4a840a0673ed7ca47d5e 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/ptrace.h>
 #include <linux/preempt.h>
 #include <linux/kdebug.h>
+#include <linux/slab.h>
 #include <asm/cacheflush.h>
 #include <asm/uaccess.h>
 
index 7ff0943e7a0856cb1dcc1339f7f74181baf678dc..81b6de41ae5d1c3bfb87c340acee5291a499a036 100644 (file)
@@ -275,13 +275,30 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
        return &pmu;
 }
 
-void hw_perf_event_setup(int cpu)
+static void sh_pmu_setup(int cpu)
 {
        struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
 
        memset(cpuhw, 0, sizeof(struct cpu_hw_events));
 }
 
+static int __cpuinit
+sh_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+       unsigned int cpu = (long)hcpu;
+
+       switch (action & ~CPU_TASKS_FROZEN) {
+       case CPU_UP_PREPARE:
+               sh_pmu_setup(cpu);
+               break;
+
+       default:
+               break;
+       }
+
+       return NOTIFY_OK;
+}
+
 void hw_perf_enable(void)
 {
        if (!sh_pmu_initialized())
@@ -298,7 +315,7 @@ void hw_perf_disable(void)
        sh_pmu->disable_all();
 }
 
-int register_sh_pmu(struct sh_pmu *pmu)
+int __cpuinit register_sh_pmu(struct sh_pmu *pmu)
 {
        if (sh_pmu)
                return -EBUSY;
@@ -308,5 +325,6 @@ int register_sh_pmu(struct sh_pmu *pmu)
 
        WARN_ON(pmu->num_events > MAX_HWEVENTS);
 
+       perf_cpu_notifier(sh_pmu_notifier);
        return 0;
 }
index 81add9b9ea6eccb8380b685b94fda321b7b63218..17f89aa4e1b3bad5d035e2515eb65c7d19f3d55c 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/mm.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 struct kmem_cache *task_xstate_cachep = NULL;
index 3cb88f114d7affd459d6db2db55ac67be00b5423..052981972ae68ecd299a00bf8ca1196de6605507 100644 (file)
@@ -15,6 +15,7 @@
  */
 #include <linux/module.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/elfcore.h>
 #include <linux/kallsyms.h>
 #include <linux/fs.h>
index c90957a459ac9f59bf85d82f68b2c6caba917071..d4ca6480e355bebce7ccd9a628817cb37f825e84 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/fs.h>
 #include <linux/ptrace.h>
 #include <linux/reboot.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/io.h>
@@ -504,13 +505,6 @@ out:
        return error;
 }
 
-/*
- * These bracket the sleeping functions..
- */
-extern void interruptible_sleep_on(wait_queue_head_t *q);
-
-#define mid_sched      ((unsigned long) interruptible_sleep_on)
-
 #ifdef CONFIG_FRAME_POINTER
 static int in_sh64_switch_to(unsigned long pc)
 {
index c625cdab76dd4143d6001f8b3913699c26e351df..d4104ce9fe53c8a01fc354c41e0d57c5359a1d68 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
-#include <linux/slab.h>
 #include <linux/security.h>
 #include <linux/signal.h>
 #include <linux/io.h>
@@ -86,7 +85,7 @@ static int set_single_step(struct task_struct *tsk, unsigned long addr)
 
        bp = thread->ptrace_bps[0];
        if (!bp) {
-               hw_breakpoint_init(&attr);
+               ptrace_breakpoint_init(&attr);
 
                attr.bp_addr = addr;
                attr.bp_len = HW_BREAKPOINT_LEN_2;
index df3ab5811074f0bfcada56897092f9eeaed937e1..cbf1dd5372b2d223f399ab884fd46bfbd83246d1 100644 (file)
@@ -9,6 +9,7 @@
  * for more details.
  */
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <asm/dwarf.h>
 
 #ifdef CONFIG_DWARF_UNWINDER
@@ -52,3 +53,5 @@ void *return_address(unsigned int depth)
 }
 
 #endif
+
+EXPORT_SYMBOL_GPL(return_address);
index e124cf7008df46ed2e6de79f450901bd4161fbc5..002cc612deef5ce9c93499e8a2ea4043050eb189 100644 (file)
@@ -69,6 +69,7 @@ asmlinkage void __cpuinit start_secondary(void)
        unsigned int cpu;
        struct mm_struct *mm = &init_mm;
 
+       enable_mmu();
        atomic_inc(&mm->mm_count);
        atomic_inc(&mm->mm_users);
        current->active_mm = mm;
index 3f7e415be86ade5ee681e11b174754d91f231d6b..242117cbad67bfa5f936911dbd70024905a68c2b 100644 (file)
@@ -11,7 +11,6 @@
  * for more details.
  */
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/gfp.h>
index 902967e3f84165d683ded5f4a0b9db43a536eb5c..c86a08540258bf72ac09821f13a5c1c94fe9b41d 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/dma-debug.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <asm/cacheflush.h>
 #include <asm/addrspace.h>
 
index 9304117039c4f887d7a94f70e48a73c6d1549ef8..9163db3e8d15c521d75a8ca2a505428cc3409072 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
 #include <linux/pagemap.h>
-#include <linux/slab.h>
 #include <linux/sysctl.h>
 
 #include <asm/mman.h>
index 68028e8f26ce76a42ad5173684f1700406007802..c505de61a5ca468ed017af3f044c7f9bb2635fc4 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/mm.h>
 #include <linux/swap.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/bootmem.h>
 #include <linux/proc_fs.h>
 #include <linux/pagemap.h>
index 1ab2385ecefee5bd195e26949d62eb30ca51ccd1..0c99ec2e7ed8ade5d04614fc7468ecd60464a4c2 100644 (file)
@@ -14,6 +14,7 @@
  */
 #include <linux/vmalloc.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/pci.h>
 #include <linux/io.h>
index 7f682e5dafcf2a1465cd1578dfdd2ce803e46fc2..efbe84af9983e61d127856f6b49a6cfb21c3077f 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/io.h>
 #include <linux/bootmem.h>
 #include <linux/proc_fs.h>
-#include <linux/slab.h>
 #include <asm/fixmap.h>
 #include <asm/page.h>
 #include <asm/pgalloc.h>
index 6f21fb1d8726e257abf6ebd46210fc3383a94cdf..26e03a1f7ca4b6d602e9cc80d2b04ff9bb28600f 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/mm.h>
+#include <linux/slab.h>
 
 #define PGALLOC_GFP GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO
 
index a4662e2782c3fd84c8743dfb56394fdce971fe95..e43ec600afcfbc9b853522ea4df330d1991de589 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/sysdev.h>
 #include <linux/cpu.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/bitops.h>
 #include <linux/debugfs.h>
 #include <linux/fs.h>
@@ -323,6 +322,7 @@ static void __clear_pmb_entry(struct pmb_entry *pmbe)
        writel_uncached(data_val & ~PMB_V, data);
 }
 
+#ifdef CONFIG_PM
 static void set_pmb_entry(struct pmb_entry *pmbe)
 {
        unsigned long flags;
@@ -331,6 +331,7 @@ static void set_pmb_entry(struct pmb_entry *pmbe)
        __set_pmb_entry(pmbe);
        spin_unlock_irqrestore(&pmbe->lock, flags);
 }
+#endif /* CONFIG_PM */
 
 int pmb_bolt_mapping(unsigned long vaddr, phys_addr_t phys,
                     unsigned long size, pgprot_t prot)
@@ -802,7 +803,7 @@ void __init pmb_init(void)
        writel_uncached(0, PMB_IRMCR);
 
        /* Flush out the TLB */
-       __raw_writel(__raw_readl(MMUCR) | MMUCR_TI, MMUCR);
+       local_flush_tlb_all();
        ctrl_barrier();
 }
 
index 32dc674c550c12ec2424adaf46c5856b90a0ea72..b71db6af806088b1d3d84dd4a214b139e44a8700 100644 (file)
@@ -73,5 +73,35 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page)
        jump_to_uncached();
        __raw_writel(page, MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT);
        __raw_writel(asid, MMU_UTLB_ADDRESS_ARRAY2 | MMU_PAGE_ASSOC_BIT);
+       __raw_writel(page, MMU_ITLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT);
+       __raw_writel(asid, MMU_ITLB_ADDRESS_ARRAY2 | MMU_PAGE_ASSOC_BIT);
        back_to_cached();
 }
+
+void local_flush_tlb_all(void)
+{
+       unsigned long flags, status;
+       int i;
+
+       /*
+        * Flush all the TLB.
+        */
+       local_irq_save(flags);
+       jump_to_uncached();
+
+       status = __raw_readl(MMUCR);
+       status = ((status & MMUCR_URB) >> MMUCR_URB_SHIFT);
+
+       if (status == 0)
+               status = MMUCR_URB_NENTRIES;
+
+       for (i = 0; i < status; i++)
+               __raw_writel(0x0, MMU_UTLB_ADDRESS_ARRAY | (i << 8));
+
+       for (i = 0; i < 4; i++)
+               __raw_writel(0x0, MMU_ITLB_ADDRESS_ARRAY | (i << 8));
+
+       back_to_cached();
+       ctrl_barrier();
+       local_irq_restore(flags);
+}
index 4f5f7cbdd508e7e9f1e87f4f5404eab538118281..7a940dbfc2e9d0ecccf71c342b816a9f7bebf577 100644 (file)
@@ -77,3 +77,22 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page)
        for (i = 0; i < ways; i++)
                __raw_writel(data, addr + (i << 8));
 }
+
+void local_flush_tlb_all(void)
+{
+       unsigned long flags, status;
+
+       /*
+        * Flush all the TLB.
+        *
+        * Write to the MMU control register's bit:
+        *      TF-bit for SH-3, TI-bit for SH-4.
+        *      It's same position, bit #2.
+        */
+       local_irq_save(flags);
+       status = __raw_readl(MMUCR);
+       status |= 0x04;
+       __raw_writel(status, MMUCR);
+       ctrl_barrier();
+       local_irq_restore(flags);
+}
index ccac77f504a8532192d063ef2d423b4c4a613948..cfdf7930d2946723262ea5eaf1d1b3f1595eef2e 100644 (file)
@@ -80,3 +80,31 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page)
        __raw_writel(data, addr);
        back_to_cached();
 }
+
+void local_flush_tlb_all(void)
+{
+       unsigned long flags, status;
+       int i;
+
+       /*
+        * Flush all the TLB.
+        */
+       local_irq_save(flags);
+       jump_to_uncached();
+
+       status = __raw_readl(MMUCR);
+       status = ((status & MMUCR_URB) >> MMUCR_URB_SHIFT);
+
+       if (status == 0)
+               status = MMUCR_URB_NENTRIES;
+
+       for (i = 0; i < status; i++)
+               __raw_writel(0x0, MMU_UTLB_ADDRESS_ARRAY | (i << 8));
+
+       for (i = 0; i < 4; i++)
+               __raw_writel(0x0, MMU_ITLB_ADDRESS_ARRAY | (i << 8));
+
+       back_to_cached();
+       ctrl_barrier();
+       local_irq_restore(flags);
+}
index bb5b9098956d9157c2d1bf7c4166b20990bd99a0..c92ce20db39bf478dd6db83a0c3ed6dc430ca027 100644 (file)
@@ -24,13 +24,9 @@ void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
 
        local_irq_save(flags);
 
-       /* Load the entry into the TLB */
-       __update_tlb(vma, addr, pte);
-
-       /* ... and wire it up. */
        status = __raw_readl(MMUCR);
        urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT;
-       status &= ~MMUCR_URB;
+       status &= ~MMUCR_URC;
 
        /*
         * Make sure we're not trying to wire the last TLB entry slot.
@@ -39,7 +35,23 @@ void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
 
        urb = urb % MMUCR_URB_NENTRIES;
 
+       /*
+        * Insert this entry into the highest non-wired TLB slot (via
+        * the URC field).
+        */
+       status |= (urb << MMUCR_URC_SHIFT);
+       __raw_writel(status, MMUCR);
+       ctrl_barrier();
+
+       /* Load the entry into the TLB */
+       __update_tlb(vma, addr, pte);
+
+       /* ... and wire it up. */
+       status = __raw_readl(MMUCR);
+
+       status &= ~MMUCR_URB;
        status |= (urb << MMUCR_URB_SHIFT);
+
        __raw_writel(status, MMUCR);
        ctrl_barrier();
 
index 004bb3f25b5f5f7e080505e967fea140328d480b..3fbe03ce8fe3a665768516dd4e341e783e164e69 100644 (file)
@@ -119,22 +119,3 @@ void local_flush_tlb_mm(struct mm_struct *mm)
                local_irq_restore(flags);
        }
 }
-
-void local_flush_tlb_all(void)
-{
-       unsigned long flags, status;
-
-       /*
-        * Flush all the TLB.
-        *
-        * Write to the MMU control register's bit:
-        *      TF-bit for SH-3, TI-bit for SH-4.
-        *      It's same position, bit #2.
-        */
-       local_irq_save(flags);
-       status = __raw_readl(MMUCR);
-       status |= 0x04;
-       __raw_writel(status, MMUCR);
-       ctrl_barrier();
-       local_irq_restore(flags);
-}
index cf20a5c5136a72ef6b0a89519f203894239343a9..8a4eca551fc0a08542085faddeac7af373ad091b 100644 (file)
@@ -1,6 +1,8 @@
 #include <linux/init.h>
+#include <linux/module.h>
 #include <asm/sizes.h>
 #include <asm/page.h>
+#include <asm/addrspace.h>
 
 /*
  * This is the offset of the uncached section from its cached alias.
 unsigned long cached_to_uncached = SZ_512M;
 unsigned long uncached_size = SZ_512M;
 unsigned long uncached_start, uncached_end;
+EXPORT_SYMBOL(uncached_start);
+EXPORT_SYMBOL(uncached_end);
 
 int virt_addr_uncached(unsigned long kaddr)
 {
        return (kaddr >= uncached_start) && (kaddr < uncached_end);
 }
+EXPORT_SYMBOL(virt_addr_uncached);
 
 void __init uncached_init(void)
 {
+#ifdef CONFIG_29BIT
+       uncached_start = P2SEG;
+#else
        uncached_start = memory_end;
+#endif
        uncached_end = uncached_start + uncached_size;
 }
 
index 6db513674050444dab36ef2818b0fbd03f56310e..9908d477ccd9b0b7e94f267a500d39b6d4cfb73a 100644 (file)
@@ -37,6 +37,9 @@ config SPARC64
        def_bool 64BIT
        select ARCH_SUPPORTS_MSI
        select HAVE_FUNCTION_TRACER
+       select HAVE_FUNCTION_GRAPH_TRACER
+       select HAVE_FUNCTION_GRAPH_FP_TEST
+       select HAVE_FUNCTION_TRACE_MCOUNT_TEST
        select HAVE_KRETPROBES
        select HAVE_KPROBES
        select HAVE_LMB
index 9d3c889718ac60e954d2439d74847a3443ed825c..1b4a831565f9cc9bfe58cc84ac5eb8c906ca0906 100644 (file)
@@ -19,13 +19,10 @@ config DEBUG_DCFLUSH
        bool "D-cache flush debugging"
        depends on SPARC64 && DEBUG_KERNEL
 
-config STACK_DEBUG
-       bool "Stack Overflow Detection Support"
-
 config MCOUNT
        bool
        depends on SPARC64
-       depends on STACK_DEBUG || FUNCTION_TRACER
+       depends on FUNCTION_TRACER
        default y
 
 config FRAME_POINTER
index 56e3163673e304d333cb856538f1e5544b64d4c7..259e3fd50993a95a2970f404a9c7a4a5224a1b5d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33
-# Wed Mar  3 02:54:29 2010
+# Linux kernel version: 2.6.34-rc3
+# Sat Apr  3 15:49:56 2010
 #
 CONFIG_64BIT=y
 CONFIG_SPARC=y
@@ -23,6 +23,7 @@ CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
 CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_MMU=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_OF=y
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -439,6 +440,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -511,6 +513,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -888,6 +891,7 @@ CONFIG_SERIAL_SUNHV=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -935,6 +939,7 @@ CONFIG_I2C_ALGOBIT=y
 #
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -948,15 +953,9 @@ CONFIG_I2C_ALGOBIT=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# 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
 
 #
@@ -982,10 +981,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 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_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1052,18 +1052,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X 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_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1113,6 +1116,7 @@ CONFIG_FB_FFB=y
 # CONFIG_FB_LEO is not set
 CONFIG_FB_XVR500=y
 CONFIG_FB_XVR2500=y
+CONFIG_FB_XVR1000=y
 # CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
@@ -1430,7 +1434,6 @@ CONFIG_USB_STORAGE=m
 # 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
@@ -1443,7 +1446,6 @@ CONFIG_USB_STORAGE=m
 # 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
 
 #
@@ -1610,6 +1612,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1624,6 +1627,7 @@ CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index f0d343c3b956580265210d4fb6a059f2bde2ddd4..7ae128b19d3f6552a847acf4cc0c707f9766f9c7 100644 (file)
@@ -25,7 +25,7 @@ extern int atomic_cmpxchg(atomic_t *, int, int);
 extern int atomic_add_unless(atomic_t *, int, int);
 extern void atomic_set(atomic_t *, int);
 
-#define atomic_read(v)          ((v)->counter)
+#define atomic_read(v)          (*(volatile int *)&(v)->counter)
 
 #define atomic_add(i, v)       ((void)__atomic_add_return( (int)(i), (v)))
 #define atomic_sub(i, v)       ((void)__atomic_add_return(-(int)(i), (v)))
index f2e48009989e1e57f552066d8ae9890264590d5c..2050ca02c4230cff6c447ee3d84c5f3e058cb24b 100644 (file)
@@ -13,8 +13,8 @@
 #define ATOMIC_INIT(i)         { (i) }
 #define ATOMIC64_INIT(i)       { (i) }
 
-#define atomic_read(v)         ((v)->counter)
-#define atomic64_read(v)       ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
+#define atomic64_read(v)       (*(volatile long *)&(v)->counter)
 
 #define atomic_set(v, i)       (((v)->counter) = i)
 #define atomic64_set(v, i)     (((v)->counter) = i)
index e72ac9cdfb982eb307367a7cd1d8f8f9914efaa4..766121a67a24a1de821325352c1b3a5bc738a799 100644 (file)
@@ -44,7 +44,7 @@ extern void change_bit(unsigned long nr, volatile unsigned long *addr);
 
 #ifdef ULTRA_HAS_POPULATION_COUNT
 
-static inline unsigned int hweight64(unsigned long w)
+static inline unsigned int __arch_hweight64(unsigned long w)
 {
        unsigned int res;
 
@@ -52,7 +52,7 @@ static inline unsigned int hweight64(unsigned long w)
        return res;
 }
 
-static inline unsigned int hweight32(unsigned int w)
+static inline unsigned int __arch_hweight32(unsigned int w)
 {
        unsigned int res;
 
@@ -60,7 +60,7 @@ static inline unsigned int hweight32(unsigned int w)
        return res;
 }
 
-static inline unsigned int hweight16(unsigned int w)
+static inline unsigned int __arch_hweight16(unsigned int w)
 {
        unsigned int res;
 
@@ -68,7 +68,7 @@ static inline unsigned int hweight16(unsigned int w)
        return res;
 }
 
-static inline unsigned int hweight8(unsigned int w)
+static inline unsigned int __arch_hweight8(unsigned int w)
 {
        unsigned int res;
 
@@ -78,9 +78,10 @@ static inline unsigned int hweight8(unsigned int w)
 
 #else
 
-#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/arch_hweight.h>
 
 #endif
+#include <asm-generic/bitops/const_hweight.h>
 #include <asm-generic/bitops/lock.h>
 #endif /* __KERNEL__ */
 
index 926397d345ff8c9c661ac69635ec11778c666d7b..050ef35b9dcf5224ead325d70a9274f9209ddc84 100644 (file)
@@ -17,7 +17,7 @@ typedef struct {
        unsigned int    __nmi_count;
        unsigned long   clock_tick;     /* %tick's per second */
        unsigned long   __pad;
-       unsigned int    __pad1;
+       unsigned int    irq0_irqs;
        unsigned int    __pad2;
 
        /* Dcache line 2, rarely used */
index 8b49bf920df3b11a1d7d9b661891c5d0918a11de..bfa1ea45b4cdb893ee9814e077c9fafdda3daff8 100644 (file)
@@ -76,9 +76,26 @@ static inline int raw_irqs_disabled(void)
  */
 static inline unsigned long __raw_local_irq_save(void)
 {
-       unsigned long flags = __raw_local_save_flags();
-
-       raw_local_irq_disable();
+       unsigned long flags, tmp;
+
+       /* Disable interrupts to PIL_NORMAL_MAX unless we already
+        * are using PIL_NMI, in which case PIL_NMI is retained.
+        *
+        * The only values we ever program into the %pil are 0,
+        * PIL_NORMAL_MAX and PIL_NMI.
+        *
+        * Since PIL_NMI is the largest %pil value and all bits are
+        * set in it (0xf), it doesn't matter what PIL_NORMAL_MAX
+        * actually is.
+        */
+       __asm__ __volatile__(
+               "rdpr   %%pil, %0\n\t"
+               "or     %0, %2, %1\n\t"
+               "wrpr   %1, 0x0, %%pil"
+               : "=r" (flags), "=r" (tmp)
+               : "i" (PIL_NORMAL_MAX)
+               : "memory"
+       );
 
        return flags;
 }
index 39327d6a57eb3b60b50d5bd47473c9f14223581c..a232e9e1f4e515d19e8f089872a797c746241777 100644 (file)
@@ -53,8 +53,8 @@ struct stat {
        ino_t           st_ino;
        mode_t          st_mode;
        short           st_nlink;
-       uid16_t         st_uid;
-       gid16_t         st_gid;
+       unsigned short  st_uid;
+       unsigned short  st_gid;
        unsigned short  st_rdev;
        off_t           st_size;
        time_t          st_atime;
index 9e2d9447f2ad094e7e1ef963675ee36fa51ba06f..4827a3aeac7f441f4a241e230f4b5072fa8af53d 100644 (file)
@@ -111,7 +111,7 @@ struct thread_info {
 #define THREAD_SHIFT PAGE_SHIFT
 #endif /* PAGE_SHIFT == 13 */
 
-#define PREEMPT_ACTIVE         0x4000000
+#define PREEMPT_ACTIVE         0x10000000
 
 /*
  * macros/functions for gaining access to the thread information structure
index c6316142db4e52c0a1c4bf2eb03f55a571246bb9..0c2dc1f24a9a74adb05299a89ee07f8ed2bc1eb9 100644 (file)
@@ -13,6 +13,14 @@ extra-y     += init_task.o
 CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS)
 extra-y              += vmlinux.lds
 
+ifdef CONFIG_FUNCTION_TRACER
+# Do not profile debug and lowlevel utilities
+CFLAGS_REMOVE_ftrace.o := -pg
+CFLAGS_REMOVE_time_$(BITS).o := -pg
+CFLAGS_REMOVE_perf_event.o := -pg
+CFLAGS_REMOVE_pcr.o := -pg
+endif
+
 obj-$(CONFIG_SPARC32)   += entry.o wof.o wuf.o
 obj-$(CONFIG_SPARC32)   += etrap_32.o
 obj-$(CONFIG_SPARC32)   += rtrap_32.o
@@ -85,7 +93,7 @@ obj-$(CONFIG_KGDB)        += kgdb_$(BITS).o
 
 
 obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
-CFLAGS_REMOVE_ftrace.o := -pg
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
 
 obj-$(CONFIG_EARLYFB) += btext.o
 obj-$(CONFIG_STACKTRACE)     += stacktrace.o
index 4589ca33220ff6463dbd7191259d01debb5fb13f..415c86d5a8dac990c011309bde3d89afe9a307c7 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/of_device.h>
index 7430ed080b23183b4dc781240846b3f1f718b14e..8de64c8126bcc3f7d19abc7d4c9f49e2eb485471 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/cpumask.h>
index 9103a56b39e839aed5af1f1f7b8fa78b9f7beee3..03ab022e51c5e8378b8ec487b3c896f7e450ee6c 100644 (file)
@@ -13,7 +13,7 @@ static const u32 ftrace_nop = 0x01000000;
 
 static u32 ftrace_call_replace(unsigned long ip, unsigned long addr)
 {
-       static u32 call;
+       u32 call;
        s32 off;
 
        off = ((s32)addr - (s32)ip);
@@ -91,3 +91,61 @@ int __init ftrace_dyn_arch_init(void *data)
        return 0;
 }
 #endif
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+extern void ftrace_graph_call(void);
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+       unsigned long ip = (unsigned long)(&ftrace_graph_call);
+       u32 old, new;
+
+       old = *(u32 *) &ftrace_graph_call;
+       new = ftrace_call_replace(ip, (unsigned long) &ftrace_graph_caller);
+       return ftrace_modify_code(ip, old, new);
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+       unsigned long ip = (unsigned long)(&ftrace_graph_call);
+       u32 old, new;
+
+       old = *(u32 *) &ftrace_graph_call;
+       new = ftrace_call_replace(ip, (unsigned long) &ftrace_stub);
+
+       return ftrace_modify_code(ip, old, new);
+}
+
+#endif /* !CONFIG_DYNAMIC_FTRACE */
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+unsigned long prepare_ftrace_return(unsigned long parent,
+                                   unsigned long self_addr,
+                                   unsigned long frame_pointer)
+{
+       unsigned long return_hooker = (unsigned long) &return_to_handler;
+       struct ftrace_graph_ent trace;
+
+       if (unlikely(atomic_read(&current->tracing_graph_pause)))
+               return parent + 8UL;
+
+       if (ftrace_push_return_trace(parent, self_addr, &trace.depth,
+                                    frame_pointer) == -EBUSY)
+               return parent + 8UL;
+
+       trace.func = self_addr;
+
+       /* Only trace if the calling function expects to */
+       if (!ftrace_graph_entry(&trace)) {
+               current->curr_ret_stack--;
+               return parent + 8UL;
+       }
+
+       return return_hooker;
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
index 314dd0c9fc5b24e5c8064f92520cc37e7cdd3c47..92090cc9e82937a2daf6730dca89668ce9e04869 100644 (file)
@@ -46,6 +46,81 @@ stack_trace_flush:
         nop
        .size           stack_trace_flush,.-stack_trace_flush
 
+#ifdef CONFIG_PERF_EVENTS
+       .globl          perf_arch_fetch_caller_regs
+       .type           perf_arch_fetch_caller_regs,#function
+perf_arch_fetch_caller_regs:
+       /* We always read the %pstate into %o5 since we will use
+        * that to construct a fake %tstate to store into the regs.
+        */
+       rdpr            %pstate, %o5
+       brz,pn          %o2, 50f
+        mov            %o2, %g7
+
+       /* Turn off interrupts while we walk around the register
+        * window by hand.
+        */
+       wrpr            %o5, PSTATE_IE, %pstate
+
+       /* The %canrestore tells us how many register windows are
+        * still live in the chip above us, past that we have to
+        * walk the frame as saved on the stack.   We stash away
+        * the %cwp in %g1 so we can return back to the original
+        * register window.
+        */
+       rdpr            %cwp, %g1
+       rdpr            %canrestore, %g2
+       sub             %g1, 1, %g3
+
+       /* We have the skip count in %g7, if it hits zero then
+        * %fp/%i7 are the registers we need.  Otherwise if our
+        * %canrestore count maintained in %g2 hits zero we have
+        * to start traversing the stack.
+        */
+10:    brz,pn          %g2, 4f
+        sub            %g2, 1, %g2
+       wrpr            %g3, %cwp
+       subcc           %g7, 1, %g7
+       bne,pt          %xcc, 10b
+        sub            %g3, 1, %g3
+
+       /* We found the values we need in the cpu's register
+        * windows.
+        */
+       mov             %fp, %g3
+       ba,pt           %xcc, 3f
+        mov            %i7, %g2
+
+50:    mov             %fp, %g3
+       ba,pt           %xcc, 2f
+        mov            %i7, %g2
+
+       /* We hit the end of the valid register windows in the
+        * cpu, start traversing the stack frame.
+        */
+4:     mov             %fp, %g3
+
+20:    ldx             [%g3 + STACK_BIAS + RW_V9_I7], %g2
+       subcc           %g7, 1, %g7
+       bne,pn          %xcc, 20b
+        ldx            [%g3 + STACK_BIAS + RW_V9_I6], %g3
+
+       /* Restore the current register window position and
+        * re-enable interrupts.
+        */
+3:     wrpr            %g1, %cwp
+       wrpr            %o5, %pstate
+
+2:     stx             %g3, [%o0 + PT_V9_FP]
+       sllx            %o5, 8, %o5
+       stx             %o5, [%o0 + PT_V9_TSTATE]
+       stx             %g2, [%o0 + PT_V9_TPC]
+       add             %g2, 4, %g2
+       retl
+        stx            %g2, [%o0 + PT_V9_TNPC]
+       .size           perf_arch_fetch_caller_regs,.-perf_arch_fetch_caller_regs
+#endif /* CONFIG_PERF_EVENTS */
+
 #ifdef CONFIG_SMP
        .globl          hard_smp_processor_id
        .type           hard_smp_processor_id,#function
index 1d272c3b574084d7c8eb52a45dae241315b10261..7c60afb835b0426571654fb5aa719e84e6cc9bec 100644 (file)
@@ -5,7 +5,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 
 #include <asm/hypervisor.h>
 #include <asm/oplib.h>
index 8414549c1834e728e114ef4bdd9546de686b1a3e..47977a77f6c64ae1bb7dd5a16de27f14b3e59807 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
index e1cbdb94d97bc10030e7ac5add8f1b22a54cc47e..830d70a3e20b4c90997e20f190ca309e1aff7985 100644 (file)
@@ -20,7 +20,9 @@
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/ftrace.h>
 #include <linux/irq.h>
+#include <linux/kmemleak.h>
 
 #include <asm/ptrace.h>
 #include <asm/processor.h>
@@ -45,6 +47,7 @@
 
 #include "entry.h"
 #include "cpumap.h"
+#include "kstack.h"
 
 #define NUM_IVECS      (IMAP_INR + 1)
 
@@ -647,6 +650,14 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
        bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC);
        if (unlikely(!bucket))
                return 0;
+
+       /* The only reference we store to the IRQ bucket is
+        * by physical address which kmemleak can't see, tell
+        * it that this object explicitly is not a leak and
+        * should be scanned.
+        */
+       kmemleak_not_leak(bucket);
+
        __flush_dcache_range((unsigned long) bucket,
                             ((unsigned long) bucket +
                              sizeof(struct ino_bucket)));
@@ -703,25 +714,7 @@ void ack_bad_irq(unsigned int virt_irq)
 void *hardirq_stack[NR_CPUS];
 void *softirq_stack[NR_CPUS];
 
-static __attribute__((always_inline)) void *set_hardirq_stack(void)
-{
-       void *orig_sp, *sp = hardirq_stack[smp_processor_id()];
-
-       __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp));
-       if (orig_sp < sp ||
-           orig_sp > (sp + THREAD_SIZE)) {
-               sp += THREAD_SIZE - 192 - STACK_BIAS;
-               __asm__ __volatile__("mov %0, %%sp" : : "r" (sp));
-       }
-
-       return orig_sp;
-}
-static __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
-{
-       __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
-}
-
-void handler_irq(int irq, struct pt_regs *regs)
+void __irq_entry handler_irq(int irq, struct pt_regs *regs)
 {
        unsigned long pstate, bucket_pa;
        struct pt_regs *old_regs;
index f5a0fd490b59cb27c90381b92edac2ae2809bb71..0a2bd0f99fc1a3ce5d867d130bfc4085daaac503 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/kgdb.h>
 #include <linux/kdebug.h>
+#include <linux/ftrace.h>
 
 #include <asm/kdebug.h>
 #include <asm/ptrace.h>
@@ -108,7 +109,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 }
 
 #ifdef CONFIG_SMP
-void smp_kgdb_capture_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_kgdb_capture_client(int irq, struct pt_regs *regs)
 {
        unsigned long flags;
 
index 6716584e48ab4c052a3d7cf941a1781949f885e6..a39d1ba5a1190cf4c3b23479481734ed0e465e48 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/kprobes.h>
 #include <linux/module.h>
 #include <linux/kdebug.h>
+#include <linux/slab.h>
 #include <asm/signal.h>
 #include <asm/cacheflush.h>
 #include <asm/uaccess.h>
index 5247283d1c03e57c94d40ebfea4074cdf7db3100..53dfb92e09fb5b1a0b37e8f393fa6e3c6b0f3329 100644 (file)
@@ -61,4 +61,23 @@ check_magic:
 
 }
 
+static inline __attribute__((always_inline)) void *set_hardirq_stack(void)
+{
+       void *orig_sp, *sp = hardirq_stack[smp_processor_id()];
+
+       __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp));
+       if (orig_sp < sp ||
+           orig_sp > (sp + THREAD_SIZE)) {
+               sp += THREAD_SIZE - 192 - STACK_BIAS;
+               __asm__ __volatile__("mov %0, %%sp" : : "r" (sp));
+       }
+
+       return orig_sp;
+}
+
+static inline __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
+{
+       __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
+}
+
 #endif /* _KSTACK_H */
index 00d034ea2164d63148d7b0ff04538420b163c513..3ae36f36e7581f107c59af05bb886c57f8032636 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/jiffies.h>
 #include <linux/timer.h>
index 0409d62d8ca2c2b477248c69b66d1308b566b2c7..6a7b4dbc8e09b6c11f8853002ab89130b1547b9e 100644 (file)
@@ -7,7 +7,6 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/mutex.h>
-#include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/interrupt.h>
index 85787577f683e2c818443c1934899cfd3941cd5d..e1656fc41ccbc275dece71ed001a2bead7005ac8 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/profile.h>
 #include <linux/pm.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
index 0ee642f63234a19ce1d32b5d9feab15e9309cc5a..f848aadf54dc1c2c1feb537752fdf3410efbe9d8 100644 (file)
@@ -9,9 +9,9 @@
 #include <linux/elf.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 
 #include <asm/processor.h>
index b287b62c7ea38f2c6ada61069b18790b3baf27b6..a4bd7ba74c89d9f25221f29e616f49f26517aad5 100644 (file)
@@ -23,6 +23,8 @@
 #include <asm/ptrace.h>
 #include <asm/pcr.h>
 
+#include "kstack.h"
+
 /* We don't have a real NMI on sparc64, but we can fake one
  * up using profiling counter overflow interrupts and interrupt
  * levels.
@@ -92,7 +94,7 @@ static void die_nmi(const char *str, struct pt_regs *regs, int do_panic)
 notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
 {
        unsigned int sum, touched = 0;
-       int cpu = smp_processor_id();
+       void *orig_sp;
 
        clear_softint(1 << irq);
 
@@ -100,13 +102,15 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
 
        nmi_enter();
 
+       orig_sp = set_hardirq_stack();
+
        if (notify_die(DIE_NMI, "nmi", regs, 0,
                       pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
                touched = 1;
        else
                pcr_ops->write(PCR_PIC_PRIV);
 
-       sum = kstat_irqs_cpu(0, cpu);
+       sum = local_cpu_data().irq0_irqs;
        if (__get_cpu_var(nmi_touch)) {
                __get_cpu_var(nmi_touch) = 0;
                touched = 1;
@@ -125,6 +129,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
                pcr_ops->write(pcr_enable);
        }
 
+       restore_hardirq_stack(orig_sp);
+
        nmi_exit();
 }
 
index cb8eb799bb6cfb01c4794eb4a7ec065b14d1ad8d..0247e68210b3417eba430ae12ef98facbf0ab76d 100644 (file)
@@ -4,7 +4,6 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/irq.h>
 #include <linux/of_device.h>
index b775658a927d2ffc28507a8560ac89f19cff172f..8a000583b5cf62ef887d419f54528a8080350e6b 100644 (file)
@@ -371,14 +371,19 @@ static void pci_register_iommu_region(struct pci_pbm_info *pbm)
                struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL);
 
                if (!rp) {
-                       prom_printf("Cannot allocate IOMMU resource.\n");
-                       prom_halt();
+                       pr_info("%s: Cannot allocate IOMMU resource.\n",
+                               pbm->name);
+                       return;
                }
                rp->name = "IOMMU";
                rp->start = pbm->mem_space.start + (unsigned long) vdma[0];
                rp->end = rp->start + (unsigned long) vdma[1] - 1UL;
                rp->flags = IORESOURCE_BUSY;
-               request_resource(&pbm->mem_space, rp);
+               if (request_resource(&pbm->mem_space, rp)) {
+                       pr_info("%s: Unable to request IOMMU resource.\n",
+                               pbm->name);
+                       kfree(rp);
+               }
        }
 }
 
index e1b0541feb19d07475a732c152c1f8c35b873a23..e0ef847219c3b0f11b3330d15b57a4858549567d 100644 (file)
@@ -4,6 +4,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/irq.h>
 
 #include "pci_impl.h"
index 2d94e7a03af5280a26d1491b9d49612ca85a81f6..c4a6a50b4849a64c0f98759921267fbe76c3cfe7 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/irq.h>
 
 #include <linux/perf_event.h>
+#include <linux/ftrace.h>
 
 #include <asm/pil.h>
 #include <asm/pcr.h>
@@ -34,7 +35,7 @@ unsigned int picl_shift;
  * Therefore in such situations we defer the work by signalling
  * a lower level cpu IRQ.
  */
-void deferred_pcr_work_irq(int irq, struct pt_regs *regs)
+void __irq_entry deferred_pcr_work_irq(int irq, struct pt_regs *regs)
 {
        struct pt_regs *old_regs;
 
index 68cb9b42088f2e36a6dc28fca5ce64e6619e7d74..e2771939341d538111417aa518d5c2c9cf249b25 100644 (file)
@@ -1337,7 +1337,7 @@ static void perf_callchain_user_32(struct pt_regs *regs,
        callchain_store(entry, PERF_CONTEXT_USER);
        callchain_store(entry, regs->tpc);
 
-       ufp = regs->u_regs[UREG_I6];
+       ufp = regs->u_regs[UREG_I6] & 0xffffffffUL;
        do {
                struct sparc_stackf32 *usf, sf;
                unsigned long pc;
index c49865b30719d2e8113313591834f34d4d5fa063..40e29fc8a4d62bff77080a791ebf0a8a280efaae 100644 (file)
 #include <linux/mm.h>
 #include <linux/stddef.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/smp.h>
 #include <linux/reboot.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #include <asm/auxio.h>
 #include <asm/oplib.h>
index 7e3dfd9bb97ed677715adc641dc530e2c0d63c9b..e608f397e11f68db6b980d0d9f97ca55416c41dd 100644 (file)
@@ -65,6 +65,7 @@ static int genregs32_get(struct task_struct *target,
                        *k++ = regs->u_regs[pos++];
 
                reg_window = (unsigned long __user *) regs->u_regs[UREG_I6];
+               reg_window -= 16;
                for (; count > 0 && pos < 32; count--) {
                        if (get_user(*k++, &reg_window[pos++]))
                                return -EFAULT;
@@ -76,6 +77,7 @@ static int genregs32_get(struct task_struct *target,
                }
 
                reg_window = (unsigned long __user *) regs->u_regs[UREG_I6];
+               reg_window -= 16;
                for (; count > 0 && pos < 32; count--) {
                        if (get_user(reg, &reg_window[pos++]) ||
                            put_user(reg, u++))
@@ -141,6 +143,7 @@ static int genregs32_set(struct task_struct *target,
                        regs->u_regs[pos++] = *k++;
 
                reg_window = (unsigned long __user *) regs->u_regs[UREG_I6];
+               reg_window -= 16;
                for (; count > 0 && pos < 32; count--) {
                        if (put_user(*k++, &reg_window[pos++]))
                                return -EFAULT;
@@ -153,6 +156,7 @@ static int genregs32_set(struct task_struct *target,
                }
 
                reg_window = (unsigned long __user *) regs->u_regs[UREG_I6];
+               reg_window -= 16;
                for (; count > 0 && pos < 32; count--) {
                        if (get_user(reg, u++) ||
                            put_user(reg, &reg_window[pos++]))
index 2f6524d1a817a3906f99109edfb953217bb16c1a..aa90da08bf61c84d54876e6a0e7962ef87b374c7 100644 (file)
@@ -492,6 +492,7 @@ static int genregs32_get(struct task_struct *target,
                        *k++ = regs->u_regs[pos++];
 
                reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
+               reg_window -= 16;
                if (target == current) {
                        for (; count > 0 && pos < 32; count--) {
                                if (get_user(*k++, &reg_window[pos++]))
@@ -516,6 +517,7 @@ static int genregs32_get(struct task_struct *target,
                }
 
                reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
+               reg_window -= 16;
                if (target == current) {
                        for (; count > 0 && pos < 32; count--) {
                                if (get_user(reg, &reg_window[pos++]) ||
@@ -599,6 +601,7 @@ static int genregs32_set(struct task_struct *target,
                        regs->u_regs[pos++] = *k++;
 
                reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
+               reg_window -= 16;
                if (target == current) {
                        for (; count > 0 && pos < 32; count--) {
                                if (put_user(*k++, &reg_window[pos++]))
@@ -625,6 +628,7 @@ static int genregs32_set(struct task_struct *target,
                }
 
                reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
+               reg_window -= 16;
                if (target == current) {
                        for (; count > 0 && pos < 32; count--) {
                                if (get_user(reg, u++) ||
index 83f1873c6c131bfc68b21290fbe0bb3bfb9ffefb..090b9e9ad5e36a416258e003be80556b49330a62 100644 (file)
@@ -130,7 +130,17 @@ rtrap_xcall:
                 nop
                call                    trace_hardirqs_on
                 nop
-               wrpr                    %l4, %pil
+               /* Do not actually set the %pil here.  We will do that
+                * below after we clear PSTATE_IE in the %pstate register.
+                * If we re-enable interrupts here, we can recurse down
+                * the hardirq stack potentially endlessly, causing a
+                * stack overflow.
+                *
+                * It is tempting to put this test and trace_hardirqs_on
+                * call at the 'rt_continue' label, but that will not work
+                * as that path hits unconditionally and we do not want to
+                * execute this in NMI return paths, for example.
+                */
 #endif
 rtrap_no_irq_enable:
                andcc                   %l1, TSTATE_PRIV, %l3
index a2a79e76344f78c606fed829ce18c4c77775b3ac..5f72de67588b876989ec96243b03e633442ad59c 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <asm/smp.h>
 #include <linux/user.h>
 #include <linux/screen_info.h>
index eb14844a0021bbccb76d6981c3f9cabb9ac75c35..b6a2b8f47040b2eb6d5f8fdf82ad2c696d9fe733 100644 (file)
@@ -22,7 +22,9 @@
 #include <linux/profile.h>
 #include <linux/bootmem.h>
 #include <linux/vmalloc.h>
+#include <linux/ftrace.h>
 #include <linux/cpu.h>
+#include <linux/slab.h>
 
 #include <asm/head.h>
 #include <asm/ptrace.h>
@@ -822,13 +824,13 @@ void arch_send_call_function_single_ipi(int cpu)
                      &cpumask_of_cpu(cpu));
 }
 
-void smp_call_function_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
        generic_smp_call_function_interrupt();
 }
 
-void smp_call_function_single_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
        generic_smp_call_function_single_interrupt();
@@ -964,7 +966,7 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
        put_cpu();
 }
 
-void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
 {
        struct mm_struct *mm;
        unsigned long flags;
@@ -1148,7 +1150,7 @@ void smp_release(void)
  */
 extern void prom_world(int);
 
-void smp_penguin_jailcell(int irq, struct pt_regs *regs)
+void __irq_entry smp_penguin_jailcell(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
 
@@ -1364,7 +1366,7 @@ void smp_send_reschedule(int cpu)
                      &cpumask_of_cpu(cpu));
 }
 
-void smp_receive_signal_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
 }
index bc3adbf79c6a8006ca61053f905cde8474cec9fd..892fb884910a52619582d36a0426211db186d4d1 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/sched.h>
 #include <linux/ptrace.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
index 301892e2d7186fd41d32da167ff6218a5e5ce9d2..7f3b97ff62c17394604d8134cafa5b5211e24256 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/ptrace.h>
 #include <linux/smp.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/of.h>
index daded3b9639861b4b0ee0f63c5c54cd9cc447d72..c0ca87553e1c22e34c7aa11669795e0e74c34965 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
-#include <linux/slab.h>
 #include <linux/uio.h>
 #include <linux/nfs_fs.h>
 #include <linux/quota.h>
@@ -44,6 +43,7 @@
 #include <linux/compat.h>
 #include <linux/vfs.h>
 #include <linux/ptrace.h>
+#include <linux/slab.h>
 
 #include <asm/types.h>
 #include <asm/uaccess.h>
index ca39c606fe8e41d90506c574f5ed23c8f89d147d..1eb8b00aed75f293b5df18076e1fc3b81b2cf9c7 100644 (file)
@@ -107,12 +107,12 @@ static unsigned long run_on_cpu(unsigned long cpu,
        unsigned long ret;
 
        /* should return -EINVAL to userspace */
-       if (set_cpus_allowed(current, cpumask_of_cpu(cpu)))
+       if (set_cpus_allowed_ptr(current, cpumask_of(cpu)))
                return 0;
 
        ret = func(arg);
 
-       set_cpus_allowed(current, old_affinity);
+       set_cpus_allowed_ptr(current, &old_affinity);
 
        return ret;
 }
index 67e165102885c6d70729d932eb4845e314d52ffb..c7bbe6cf7b85a3d76c86bbe06ddbccef4e573ad5 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/clocksource.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/ftrace.h>
 
 #include <asm/oplib.h>
 #include <asm/timer.h>
@@ -717,7 +718,7 @@ static struct clock_event_device sparc64_clockevent = {
 };
 static DEFINE_PER_CPU(struct clock_event_device, sparc64_events);
 
-void timer_interrupt(int irq, struct pt_regs *regs)
+void __irq_entry timer_interrupt(int irq, struct pt_regs *regs)
 {
        struct pt_regs *old_regs = set_irq_regs(regs);
        unsigned long tick_mask = tick_ops->softint_mask;
@@ -728,6 +729,7 @@ void timer_interrupt(int irq, struct pt_regs *regs)
 
        irq_enter();
 
+       local_cpu_data().irq0_irqs++;
        kstat_incr_irqs_this_cpu(0, irq_to_desc(0));
 
        if (unlikely(!evt->event_handler)) {
index bdc05a21908b98afab4189b7307a72a6b81a985f..9da57f0329838ef60be9b21b4c471963e3b371fb 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/kdebug.h>
+#include <linux/gfp.h>
 
 #include <asm/smp.h>
 #include <asm/delay.h>
@@ -2202,27 +2203,6 @@ void dump_stack(void)
 
 EXPORT_SYMBOL(dump_stack);
 
-static inline int is_kernel_stack(struct task_struct *task,
-                                 struct reg_window *rw)
-{
-       unsigned long rw_addr = (unsigned long) rw;
-       unsigned long thread_base, thread_end;
-
-       if (rw_addr < PAGE_OFFSET) {
-               if (task != &init_task)
-                       return 0;
-       }
-
-       thread_base = (unsigned long) task_stack_page(task);
-       thread_end = thread_base + sizeof(union thread_union);
-       if (rw_addr >= thread_base &&
-           rw_addr < thread_end &&
-           !(rw_addr & 0x7UL))
-               return 1;
-
-       return 0;
-}
-
 static inline struct reg_window *kernel_stack_up(struct reg_window *rw)
 {
        unsigned long fp = rw->ins[6];
@@ -2251,6 +2231,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
        show_regs(regs);
        add_taint(TAINT_DIE);
        if (regs->tstate & TSTATE_PRIV) {
+               struct thread_info *tp = current_thread_info();
                struct reg_window *rw = (struct reg_window *)
                        (regs->u_regs[UREG_FP] + STACK_BIAS);
 
@@ -2258,8 +2239,8 @@ void die_if_kernel(char *str, struct pt_regs *regs)
                 * find some badly aligned kernel stack.
                 */
                while (rw &&
-                      count++ < 30&&
-                      is_kernel_stack(current, rw)) {
+                      count++ < 30 &&
+                      kstack_valid(tp, (unsigned long) rw)) {
                        printk("Caller[%016lx]: %pS\n", rw->ins[7],
                               (void *) rw->ins[7]);
 
index ebce43018c49c00b5aceacc97fba173df6abef2a..c752c4c479bd8457da289b3da9797980d8dec7da 100644 (file)
@@ -50,7 +50,7 @@ static inline enum direction decode_direction(unsigned int insn)
 }
 
 /* 16 = double-word, 8 = extra-word, 4 = word, 2 = half-word */
-static inline int decode_access_size(unsigned int insn)
+static inline int decode_access_size(struct pt_regs *regs, unsigned int insn)
 {
        unsigned int tmp;
 
@@ -66,7 +66,7 @@ static inline int decode_access_size(unsigned int insn)
                return 2;
        else {
                printk("Impossible unaligned trap. insn=%08x\n", insn);
-               die_if_kernel("Byte sized unaligned access?!?!", current_thread_info()->kregs);
+               die_if_kernel("Byte sized unaligned access?!?!", regs);
 
                /* GCC should never warn that control reaches the end
                 * of this function without returning a value because
@@ -286,7 +286,7 @@ static void log_unaligned(struct pt_regs *regs)
 asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
 {
        enum direction dir = decode_direction(insn);
-       int size = decode_access_size(insn);
+       int size = decode_access_size(regs, insn);
        int orig_asi, asi;
 
        current_thread_info()->kern_una_regs = regs;
index 791c15138f3a4abf3cb368e12041fcd7f304842c..8f982b76c71259e7a28f1f1551629eb397023a31 100644 (file)
@@ -238,12 +238,12 @@ static unsigned int us2e_freq_get(unsigned int cpu)
                return 0;
 
        cpus_allowed = current->cpus_allowed;
-       set_cpus_allowed(current, cpumask_of_cpu(cpu));
+       set_cpus_allowed_ptr(current, cpumask_of(cpu));
 
        clock_tick = sparc64_get_clock_tick(cpu) / 1000;
        estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR);
 
-       set_cpus_allowed(current, cpus_allowed);
+       set_cpus_allowed_ptr(current, &cpus_allowed);
 
        return clock_tick / estar_to_divisor(estar);
 }
@@ -259,7 +259,7 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index)
                return;
 
        cpus_allowed = current->cpus_allowed;
-       set_cpus_allowed(current, cpumask_of_cpu(cpu));
+       set_cpus_allowed_ptr(current, cpumask_of(cpu));
 
        new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000;
        new_bits = index_to_estar_mode(index);
@@ -281,7 +281,7 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index)
 
        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
-       set_cpus_allowed(current, cpus_allowed);
+       set_cpus_allowed_ptr(current, &cpus_allowed);
 }
 
 static int us2e_freq_target(struct cpufreq_policy *policy,
index 365b6464e2ce20037e27af6023aa330ba6380612..f35d1e794548eb8541bee5198f4a353f346d1e3e 100644 (file)
@@ -86,12 +86,12 @@ static unsigned int us3_freq_get(unsigned int cpu)
                return 0;
 
        cpus_allowed = current->cpus_allowed;
-       set_cpus_allowed(current, cpumask_of_cpu(cpu));
+       set_cpus_allowed_ptr(current, cpumask_of(cpu));
 
        reg = read_safari_cfg();
        ret = get_current_freq(cpu, reg);
 
-       set_cpus_allowed(current, cpus_allowed);
+       set_cpus_allowed_ptr(current, &cpus_allowed);
 
        return ret;
 }
@@ -106,7 +106,7 @@ static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index)
                return;
 
        cpus_allowed = current->cpus_allowed;
-       set_cpus_allowed(current, cpumask_of_cpu(cpu));
+       set_cpus_allowed_ptr(current, cpumask_of(cpu));
 
        new_freq = sparc64_get_clock_tick(cpu) / 1000;
        switch (index) {
@@ -140,7 +140,7 @@ static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index)
 
        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
-       set_cpus_allowed(current, cpus_allowed);
+       set_cpus_allowed_ptr(current, &cpus_allowed);
 }
 
 static int us3_freq_target(struct cpufreq_policy *policy,
index c28c71449a6c72652706e49cf1897c639e2f441b..3cb1def9806c307df84a8da15f33dbc484255c51 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/irq.h>
 #include <linux/init.h>
 
index 4e599259396747947c2145e7023cf311636b65d2..0c1e6783657f26172291186637ea5d20a6966677 100644 (file)
@@ -46,11 +46,16 @@ SECTIONS
                SCHED_TEXT
                LOCK_TEXT
                KPROBES_TEXT
+               IRQENTRY_TEXT
                *(.gnu.warning)
        } = 0
        _etext = .;
 
        RO_DATA(PAGE_SIZE)
+
+       /* Start of data section */
+       _sdata = .;
+
        .data1 : {
                *(.data1)
        }
index 24b8b12deed20fa43ce9a28dfdd5c698b2a1d103..3ad6cbdc21636f51c1853c2ab604d2dc692727db 100644 (file)
@@ -7,26 +7,11 @@
 
 #include <linux/linkage.h>
 
-#include <asm/ptrace.h>
-#include <asm/thread_info.h>
-
 /*
  * This is the main variant and is called by C code.  GCC's -pg option
  * automatically instruments every C function with a call to this.
  */
 
-#ifdef CONFIG_STACK_DEBUG
-
-#define OVSTACKSIZE    4096            /* lets hope this is enough */
-
-       .data
-       .align          8
-panicstring:
-       .asciz          "Stack overflow\n"
-       .align          8
-ovstack:
-       .skip           OVSTACKSIZE
-#endif
        .text
        .align          32
        .globl          _mcount
@@ -35,84 +20,48 @@ ovstack:
        .type           mcount,#function
 _mcount:
 mcount:
-#ifdef CONFIG_STACK_DEBUG
-       /*
-        * Check whether %sp is dangerously low.
-        */
-       ldub            [%g6 + TI_FPDEPTH], %g1
-       srl             %g1, 1, %g3
-       add             %g3, 1, %g3
-       sllx            %g3, 8, %g3                     ! each fpregs frame is 256b
-       add             %g3, 192, %g3
-       add             %g6, %g3, %g3                   ! where does task_struct+frame end?
-       sub             %g3, STACK_BIAS, %g3
-       cmp             %sp, %g3
-       bg,pt           %xcc, 1f
-        nop
-       lduh            [%g6 + TI_CPU], %g1
-       sethi           %hi(hardirq_stack), %g3
-       or              %g3, %lo(hardirq_stack), %g3
-       sllx            %g1, 3, %g1
-       ldx             [%g3 + %g1], %g7
-       sub             %g7, STACK_BIAS, %g7
-       cmp             %sp, %g7
-       bleu,pt         %xcc, 2f
-        sethi          %hi(THREAD_SIZE), %g3
-       add             %g7, %g3, %g7
-       cmp             %sp, %g7
-       blu,pn          %xcc, 1f
-2:      sethi          %hi(softirq_stack), %g3
-       or              %g3, %lo(softirq_stack), %g3
-       ldx             [%g3 + %g1], %g7
-       sub             %g7, STACK_BIAS, %g7
-       cmp             %sp, %g7
-       bleu,pt         %xcc, 3f
-        sethi          %hi(THREAD_SIZE), %g3
-       add             %g7, %g3, %g7
-       cmp             %sp, %g7
-       blu,pn          %xcc, 1f
-        nop
-       /* If we are already on ovstack, don't hop onto it
-        * again, we are already trying to output the stack overflow
-        * message.
-        */
-3:     sethi           %hi(ovstack), %g7               ! cant move to panic stack fast enough
-        or             %g7, %lo(ovstack), %g7
-       add             %g7, OVSTACKSIZE, %g3
-       sub             %g3, STACK_BIAS + 192, %g3
-       sub             %g7, STACK_BIAS, %g7
-       cmp             %sp, %g7
-       blu,pn          %xcc, 2f
-        cmp            %sp, %g3
-       bleu,pn         %xcc, 1f
-        nop
-2:     mov             %g3, %sp
-       sethi           %hi(panicstring), %g3
-       call            prom_printf
-        or             %g3, %lo(panicstring), %o0
-       call            prom_halt
-        nop
-1:
-#endif
 #ifdef CONFIG_FUNCTION_TRACER
 #ifdef CONFIG_DYNAMIC_FTRACE
-       mov             %o7, %o0
-       .globl          mcount_call
-mcount_call:
-       call            ftrace_stub
-        mov            %o0, %o7
+       /* Do nothing, the retl/nop below is all we need.  */
 #else
-       sethi           %hi(ftrace_trace_function), %g1
+       sethi           %hi(function_trace_stop), %g1
+       lduw            [%g1 + %lo(function_trace_stop)], %g2
+       brnz,pn         %g2, 2f
+        sethi          %hi(ftrace_trace_function), %g1
        sethi           %hi(ftrace_stub), %g2
        ldx             [%g1 + %lo(ftrace_trace_function)], %g1
        or              %g2, %lo(ftrace_stub), %g2
        cmp             %g1, %g2
        be,pn           %icc, 1f
-        mov            %i7, %o1
-       jmpl            %g1, %g0
-        mov            %o7, %o0
+        mov            %i7, %g3
+       save            %sp, -176, %sp
+       mov             %g3, %o1
+       jmpl            %g1, %o7
+        mov            %i7, %o0
+       ret
+        restore
        /* not reached */
 1:
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       sethi           %hi(ftrace_graph_return), %g1
+       ldx             [%g1 + %lo(ftrace_graph_return)], %g3
+       cmp             %g2, %g3
+       bne,pn          %xcc, 5f
+        sethi          %hi(ftrace_graph_entry_stub), %g2
+       sethi           %hi(ftrace_graph_entry), %g1
+       or              %g2, %lo(ftrace_graph_entry_stub), %g2
+       ldx             [%g1 + %lo(ftrace_graph_entry)], %g1
+       cmp             %g1, %g2
+       be,pt           %xcc, 2f
+        nop
+5:     mov             %i7, %g2
+       mov             %fp, %g3
+       save            %sp, -176, %sp
+       mov             %g2, %l0
+       ba,pt           %xcc, ftrace_graph_caller
+        mov            %g3, %l1
+#endif
+2:
 #endif
 #endif
        retl
@@ -131,14 +80,50 @@ ftrace_stub:
        .globl          ftrace_caller
        .type           ftrace_caller,#function
 ftrace_caller:
-       mov             %i7, %o1
-       mov             %o7, %o0
+       sethi           %hi(function_trace_stop), %g1
+       mov             %i7, %g2
+       lduw            [%g1 + %lo(function_trace_stop)], %g1
+       brnz,pn         %g1, ftrace_stub
+        mov            %fp, %g3
+       save            %sp, -176, %sp
+       mov             %g2, %o1
+       mov             %g2, %l0
+       mov             %g3, %l1
        .globl          ftrace_call
 ftrace_call:
        call            ftrace_stub
-        mov            %o0, %o7
-       retl
+        mov            %i7, %o0
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       .globl          ftrace_graph_call
+ftrace_graph_call:
+       call            ftrace_stub
         nop
+#endif
+       ret
+        restore
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       .size           ftrace_graph_call,.-ftrace_graph_call
+#endif
+       .size           ftrace_call,.-ftrace_call
        .size           ftrace_caller,.-ftrace_caller
 #endif
 #endif
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ENTRY(ftrace_graph_caller)
+       mov             %l0, %o0
+       mov             %i7, %o1
+       call            prepare_ftrace_return
+        mov            %l1, %o2
+       ret
+        restore        %o0, -8, %i7
+END(ftrace_graph_caller)
+
+ENTRY(return_to_handler)
+       save            %sp, -176, %sp
+       call            ftrace_return_to_handler
+        mov            %fp, %o0
+       jmpl            %o0 + 8, %g0
+        restore
+END(return_to_handler)
+#endif
index f27d10369e0cdea561c78c7e3be4e0b326ffd8be..5fdddf134caa6992afb6c4fdf2056a93e7ffdb2d 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
 #include <linux/pagemap.h>
-#include <linux/slab.h>
 #include <linux/sysctl.h>
 
 #include <asm/mman.h>
index dc7c3b17a15f2badfbdc03dc3a1c2cac77ed0818..6d0e02c4fe09cdc318d6da849668495546d21897 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/bootmem.h>
 #include <linux/pagemap.h>
 #include <linux/poison.h>
+#include <linux/gfp.h>
 
 #include <asm/sections.h>
 #include <asm/system.h>
index 9245a822a2f17cf8a20fc9edd12f217156f973ac..b2831dc3c121c135a0ed41fe09aaf975f1aa678f 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/bootmem.h>
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
-#include <linux/slab.h>
 #include <linux/initrd.h>
 #include <linux/swap.h>
 #include <linux/pagemap.h>
@@ -26,6 +25,7 @@
 #include <linux/percpu.h>
 #include <linux/lmb.h>
 #include <linux/mmzone.h>
+#include <linux/gfp.h>
 
 #include <asm/head.h>
 #include <asm/system.h>
@@ -2117,7 +2117,7 @@ int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node)
                               "node=%d entry=%lu/%lu\n", start, block, nr,
                               node,
                               addr >> VMEMMAP_CHUNK_SHIFT,
-                              VMEMMAP_SIZE >> VMEMMAP_CHUNK_SHIFT);
+                              VMEMMAP_SIZE);
                }
        }
        return 0;
index df49b200ca4c12317077c44712d0f89f107ff872..f5f75a58e0b3cc7077f78a610f6cc6107c75bcb8 100644 (file)
@@ -10,7 +10,6 @@
 
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
@@ -20,6 +19,7 @@
 #include <linux/seq_file.h>
 #include <linux/kdebug.h>
 #include <linux/log2.h>
+#include <linux/gfp.h>
 
 #include <asm/bitext.h>
 #include <asm/page.h>
index 18652534b91a592a2dfb3c97cce676323fe471f2..cf38846753dd55c3ece5d7be244b23d9ca3fbda3 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/bootmem.h>
 #include <linux/highmem.h>
 #include <linux/fs.h>
index 36a0813f9517b39ec9b7b86c17a03233d442483e..101d7c82870be8a704a2ab84f07d97a2d890f37a 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/kernel.h>
 #include <linux/preempt.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 #include <asm/page.h>
 #include <asm/tlbflush.h>
index 64cda95f59ca35db49675b90c8b8f1d6447f5c16..7a656bd8bd3c185f9fe324f6bd5a8a9bc2f533d2 100644 (file)
@@ -6,6 +6,7 @@
 #include "linux/irqreturn.h"
 #include "linux/kd.h"
 #include "linux/sched.h"
+#include "linux/slab.h"
 #include "chan_kern.h"
 #include "irq_kern.h"
 #include "irq_user.h"
index a74245ae3a84db98443460ed794ec70ce15eb15a..f05372694233a55734500b8aa3578a0338f00d43 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include "init.h"
 #include "irq_kern.h"
index 4ebc8a34738f7d43a6020c8a05e604d8cad7d8e5..a11573be0961fd7b233a02ff40421aa3a53940c7 100644 (file)
@@ -7,6 +7,7 @@
 #include "linux/interrupt.h"
 #include "linux/list.h"
 #include "linux/mutex.h"
+#include "linux/slab.h"
 #include "linux/workqueue.h"
 #include "asm/atomic.h"
 #include "init.h"
index c1ff6903b622126789945164c0a33101d0a7943a..da992a3ad6b78254ee2cda6346dd10fd0e86ec0b 100644 (file)
@@ -31,6 +31,7 @@
 #include "linux/ctype.h"
 #include "linux/capability.h"
 #include "linux/mm.h"
+#include "linux/slab.h"
 #include "linux/vmalloc.h"
 #include "linux/blkpg.h"
 #include "linux/genhd.h"
index fda30d21fb90628cec430c151f9e3993df74fc5c..97974c1bdd126b8c92ab5023aa3806e3115be4dc 100644 (file)
@@ -8,6 +8,7 @@
 #include "linux/smp_lock.h"
 #include "linux/ptrace.h"
 #include "linux/sched.h"
+#include "linux/slab.h"
 #include "asm/current.h"
 #include "asm/processor.h"
 #include "asm/uaccess.h"
index 89474ba0741e616cdfc2598553198ba99cf86bcb..a3f0b04d7101ccb1fea64254339328fbec12412f 100644 (file)
@@ -12,6 +12,7 @@
 #include "linux/module.h"
 #include "linux/sched.h"
 #include "linux/seq_file.h"
+#include "linux/slab.h"
 #include "as-layout.h"
 #include "kern_util.h"
 #include "os.h"
index a5d5e70cf6f55bb0db78971b1bce19cab31abeec..8137ccc9635b5c98ae902fb8f6c5884faf67b8fe 100644 (file)
@@ -5,10 +5,10 @@
 
 #include <linux/stddef.h>
 #include <linux/bootmem.h>
-#include <linux/gfp.h>
 #include <linux/highmem.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
+#include <linux/slab.h>
 #include <asm/fixmap.h>
 #include <asm/page.h>
 #include "as-layout.h"
index 2f910a1b745452fdcccc1c167cdd3671d2275023..fab4371184f6e49affeba13f3fc0965ec7f29727 100644 (file)
@@ -7,13 +7,13 @@
 #include <linux/stddef.h>
 #include <linux/err.h>
 #include <linux/hardirq.h>
-#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/personality.h>
 #include <linux/proc_fs.h>
 #include <linux/ptrace.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/tick.h>
index 00197d3d21ec96daba38fe57b74db08183fc1310..869bec9f2516d8ae46d6deb4c96d73b1c64e9817 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include "linux/sched.h"
+#include "linux/slab.h"
 #include "kern_util.h"
 #include "os.h"
 #include "skas.h"
index 8bfd1e90581225eb0e19fada92611399d2a1d4c8..3d099f97478595be72b5cd15b5eebb9877ea32c6 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "linux/mm.h"
 #include "linux/sched.h"
+#include "linux/slab.h"
 #include "asm/pgalloc.h"
 #include "asm/pgtable.h"
 #include "as-layout.h"
index a4846a84a7be2ddae740675dfcec28e5a6a88328..3f2bf208d884ec6973d550f84a9f5d0625ae2e5f 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/mm.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/unistd.h>
 #include "os.h"
 #include "proc_mm.h"
index 0eacb1ffb42135b02435fa2f0a1897eca651a7dd..a2d3a5fbeeda02a7456fc21a843a70a15d9b1c14 100644 (file)
@@ -53,11 +53,15 @@ config X86
        select HAVE_KERNEL_LZMA
        select HAVE_KERNEL_LZO
        select HAVE_HW_BREAKPOINT
+       select HAVE_MIXED_BREAKPOINTS_REGS
        select PERF_EVENTS
        select ANON_INODES
        select HAVE_ARCH_KMEMCHECK
        select HAVE_USER_RETURN_NOTIFIER
 
+config INSTRUCTION_DECODER
+       def_bool (KPROBES || PERF_EVENTS)
+
 config OUTPUT_FORMAT
        string
        default "elf32-i386" if X86_32
@@ -197,20 +201,17 @@ config HAVE_INTEL_TXT
 
 # Use the generic interrupt handling code in kernel/irq/:
 config GENERIC_HARDIRQS
-       bool
-       default y
+       def_bool y
 
 config GENERIC_HARDIRQS_NO__DO_IRQ
        def_bool y
 
 config GENERIC_IRQ_PROBE
-       bool
-       default y
+       def_bool y
 
 config GENERIC_PENDING_IRQ
-       bool
+       def_bool y
        depends on GENERIC_HARDIRQS && SMP
-       default y
 
 config USE_GENERIC_SMP_HELPERS
        def_bool y
@@ -225,19 +226,22 @@ config X86_64_SMP
        depends on X86_64 && SMP
 
 config X86_HT
-       bool
+       def_bool y
        depends on SMP
-       default y
 
 config X86_TRAMPOLINE
-       bool
+       def_bool y
        depends on SMP || (64BIT && ACPI_SLEEP)
-       default y
 
 config X86_32_LAZY_GS
        def_bool y
        depends on X86_32 && !CC_STACKPROTECTOR
 
+config ARCH_HWEIGHT_CFLAGS
+       string
+       default "-fcall-saved-ecx -fcall-saved-edx" if X86_32
+       default "-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" if X86_64
+
 config KTIME_SCALAR
        def_bool X86_32
 source "init/Kconfig"
@@ -447,7 +451,7 @@ config X86_NUMAQ
          firmware with - send email to <Martin.Bligh@us.ibm.com>.
 
 config X86_SUPPORTS_MEMORY_FAILURE
-       bool
+       def_bool y
        # MCE code calls memory_failure():
        depends on X86_MCE
        # On 32-bit this adds too big of NODES_SHIFT and we run out of page flags:
@@ -455,7 +459,6 @@ config X86_SUPPORTS_MEMORY_FAILURE
        # On 32-bit SPARSEMEM adds too big of SECTIONS_WIDTH:
        depends on X86_64 || !SPARSEMEM
        select ARCH_SUPPORTS_MEMORY_FAILURE
-       default y
 
 config X86_VISWS
        bool "SGI 320/540 (Visual Workstation)"
@@ -570,7 +573,6 @@ config PARAVIRT_SPINLOCKS
 
 config PARAVIRT_CLOCK
        bool
-       default n
 
 endif
 
@@ -749,7 +751,6 @@ config MAXSMP
        bool "Configure Maximum number of SMP Processors and NUMA Nodes"
        depends on X86_64 && SMP && DEBUG_KERNEL && EXPERIMENTAL
        select CPUMASK_OFFSTACK
-       default n
        ---help---
          Configure maximum number of CPUS and NUMA Nodes for this architecture.
          If unsure, say N.
@@ -829,7 +830,6 @@ config X86_VISWS_APIC
 
 config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
        bool "Reroute for broken boot IRQs"
-       default n
        depends on X86_IO_APIC
        ---help---
          This option enables a workaround that fixes a source of
@@ -876,9 +876,8 @@ config X86_MCE_AMD
           the DRAM Error Threshold.
 
 config X86_ANCIENT_MCE
-       def_bool n
+       bool "Support for old Pentium 5 / WinChip machine checks"
        depends on X86_32 && X86_MCE
-       prompt "Support for old Pentium 5 / WinChip machine checks"
        ---help---
          Include support for machine check handling on old Pentium 5 or WinChip
          systems. These typically need to be enabled explicitely on the command
@@ -886,8 +885,7 @@ config X86_ANCIENT_MCE
 
 config X86_MCE_THRESHOLD
        depends on X86_MCE_AMD || X86_MCE_INTEL
-       bool
-       default y
+       def_bool y
 
 config X86_MCE_INJECT
        depends on X86_MCE
@@ -1026,8 +1024,8 @@ config X86_CPUID
 
 choice
        prompt "High Memory Support"
-       default HIGHMEM4G if !X86_NUMAQ
        default HIGHMEM64G if X86_NUMAQ
+       default HIGHMEM4G
        depends on X86_32
 
 config NOHIGHMEM
@@ -1216,8 +1214,8 @@ config NUMA_EMU
 
 config NODES_SHIFT
        int "Maximum NUMA Nodes (as a power of 2)" if !MAXSMP
-       range 1 9
-       default "9" if MAXSMP
+       range 1 10
+       default "10" if MAXSMP
        default "6" if X86_64
        default "4" if X86_NUMAQ
        default "3"
@@ -1285,7 +1283,7 @@ source "mm/Kconfig"
 
 config HIGHPTE
        bool "Allocate 3rd-level pagetables from highmem"
-       depends on X86_32 && (HIGHMEM4G || HIGHMEM64G)
+       depends on HIGHMEM
        ---help---
          The VM uses one page table entry for each page of physical memory.
          For systems with a lot of RAM, this can be wasteful of precious
@@ -1369,8 +1367,7 @@ config MATH_EMULATION
          kernel, it won't hurt.
 
 config MTRR
-       bool
-       default y
+       def_bool y
        prompt "MTRR (Memory Type Range Register) support" if EMBEDDED
        ---help---
          On Intel P6 family processors (Pentium Pro, Pentium II and later)
@@ -1436,8 +1433,7 @@ config MTRR_SANITIZER_SPARE_REG_NR_DEFAULT
          mtrr_spare_reg_nr=N on the kernel command line.
 
 config X86_PAT
-       bool
-       default y
+       def_bool y
        prompt "x86 PAT support" if EMBEDDED
        depends on MTRR
        ---help---
@@ -1605,8 +1601,7 @@ config X86_NEED_RELOCS
        depends on X86_32 && RELOCATABLE
 
 config PHYSICAL_ALIGN
-       hex
-       prompt "Alignment value to which kernel should be aligned" if X86_32
+       hex "Alignment value to which kernel should be aligned" if X86_32
        default "0x1000000"
        range 0x2000 0x1000000
        ---help---
@@ -1653,7 +1648,6 @@ config COMPAT_VDSO
 
 config CMDLINE_BOOL
        bool "Built-in kernel command line"
-       default n
        ---help---
          Allow for specifying boot arguments to the kernel at
          build time.  On some systems (e.g. embedded ones), it is
@@ -1687,7 +1681,6 @@ config CMDLINE
 
 config CMDLINE_OVERRIDE
        bool "Built-in command line overrides boot loader arguments"
-       default n
        depends on CMDLINE_BOOL
        ---help---
          Set this option to 'Y' to have the kernel ignore the boot loader
@@ -1723,8 +1716,7 @@ source "drivers/acpi/Kconfig"
 source "drivers/sfi/Kconfig"
 
 config X86_APM_BOOT
-       bool
-       default y
+       def_bool y
        depends on APM || APM_MODULE
 
 menuconfig APM
@@ -1953,8 +1945,7 @@ config DMAR_DEFAULT_ON
          experimental.
 
 config DMAR_BROKEN_GFX_WA
-       def_bool n
-       prompt "Workaround broken graphics drivers (going away soon)"
+       bool "Workaround broken graphics drivers (going away soon)"
        depends on DMAR && BROKEN
        ---help---
          Current Graphics drivers tend to use physical address
@@ -2052,7 +2043,6 @@ config SCx200HR_TIMER
 config OLPC
        bool "One Laptop Per Child support"
        select GPIOLIB
-       default n
        ---help---
          Add support for detecting the unique features of the OLPC
          XO hardware.
index a19829374e6a006b80a5db969a19c4f7dbae3449..2ac9069890cdf594610e19424c54626bb1f051aa 100644 (file)
@@ -338,6 +338,10 @@ config X86_F00F_BUG
        def_bool y
        depends on M586MMX || M586TSC || M586 || M486 || M386
 
+config X86_INVD_BUG
+       def_bool y
+       depends on M486 || M386
+
 config X86_WP_WORKS_OK
        def_bool y
        depends on !M386
@@ -502,23 +506,3 @@ config CPU_SUP_UMC_32
          CPU might render the kernel unbootable.
 
          If unsure, say N.
-
-config X86_DS
-       def_bool X86_PTRACE_BTS
-       depends on X86_DEBUGCTLMSR
-       select HAVE_HW_BRANCH_TRACER
-
-config X86_PTRACE_BTS
-       bool "Branch Trace Store"
-       default y
-       depends on X86_DEBUGCTLMSR
-       depends on BROKEN
-       ---help---
-         This adds a ptrace interface to the hardware's branch trace store.
-
-         Debuggers may use it to collect an execution trace of the debugged
-         application in order to answer the question 'how did I get here?'.
-         Debuggers may trace user mode as well as kernel mode.
-
-         Say Y unless there is no application development on this machine
-         and you want to save a small amount of code size.
index bc01e3ebfeb29bfbfe6d60b42276bc6565cf2e66..75085080b63e2f74d32d4fa2b4bd2f8972d2b7de 100644 (file)
@@ -45,7 +45,6 @@ config EARLY_PRINTK
 
 config EARLY_PRINTK_DBGP
        bool "Early printk via EHCI debug port"
-       default n
        depends on EARLY_PRINTK && PCI
        ---help---
          Write kernel log output directly into the EHCI debug port.
@@ -76,7 +75,6 @@ config DEBUG_PER_CPU_MAPS
        bool "Debug access to per_cpu maps"
        depends on DEBUG_KERNEL
        depends on SMP
-       default n
        ---help---
          Say Y to verify that the per_cpu map being accessed has
          been setup.  Adds a fair amount of code to kernel memory
@@ -174,15 +172,6 @@ config IOMMU_LEAK
          Add a simple leak tracer to the IOMMU code. This is useful when you
          are debugging a buggy device driver that leaks IOMMU mappings.
 
-config X86_DS_SELFTEST
-    bool "DS selftest"
-    default y
-    depends on DEBUG_KERNEL
-    depends on X86_DS
-       ---help---
-         Perform Debug Store selftests at boot time.
-         If in doubt, say "N".
-
 config HAVE_MMIOTRACE_SUPPORT
        def_bool y
 
index 0a43dc515e4c10dcd38f2d5adbd7e42b614069f4..8aa1b59b9074586e1fe9930b85d0cf945f14a695 100644 (file)
@@ -95,8 +95,9 @@ sp-$(CONFIG_X86_64) := rsp
 cfi := $(call as-instr,.cfi_startproc\n.cfi_rel_offset $(sp-y)$(comma)0\n.cfi_endproc,-DCONFIG_AS_CFI=1)
 # is .cfi_signal_frame supported too?
 cfi-sigframe := $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1)
-KBUILD_AFLAGS += $(cfi) $(cfi-sigframe)
-KBUILD_CFLAGS += $(cfi) $(cfi-sigframe)
+cfi-sections := $(call as-instr,.cfi_sections .debug_frame,-DCONFIG_AS_CFI_SECTIONS=1)
+KBUILD_AFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections)
+KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections)
 
 LDFLAGS := -m elf_$(UTS_MACHINE)
 
index daef6cd2b45d6bae0c63228002478c01251adaf7..1a8f8649c035b2e6fe5b30b0032382760cc9e495 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/i387.h>
 
 struct crypto_fpu_ctx {
index 280c019cfad8c8475741178daed7406214a8308c..0350311906ae731ca91e9ecedbc3e7acbaa668d0 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
-#include <linux/slab.h>
 #include <linux/binfmts.h>
 #include <linux/personality.h>
 #include <linux/init.h>
index 59b4556a5b92288eb23b8cb09fc28c6ea2bd2e5d..e790bc1fbfa3a3f5b925b2dcabe82caced57a8bb 100644 (file)
@@ -626,7 +626,7 @@ ia32_sys_call_table:
        .quad stub32_sigreturn
        .quad stub32_clone              /* 120 */
        .quad sys_setdomainname
-       .quad sys_uname
+       .quad sys_newuname
        .quad sys_modify_ldt
        .quad compat_sys_adjtimex
        .quad sys32_mprotect            /* 125 */
index 74c35431b7d830ebb4ca7979945cdbf19714f8ff..626be156d88def72a0fa7bf87f5e3f822c9c63bd 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/ptrace.h>
 #include <linux/highuid.h>
 #include <linux/sysctl.h>
+#include <linux/slab.h>
 #include <asm/mman.h>
 #include <asm/types.h>
 #include <asm/uaccess.h>
index b97f786a48d597ce4c718667a19c0d8c2b45c9c7..a63a68be1cce2258daf9cadf0d465b291296c930 100644 (file)
@@ -6,8 +6,8 @@
        .macro LOCK_PREFIX
 1:     lock
        .section .smp_locks,"a"
-       _ASM_ALIGN
-       _ASM_PTR 1b
+       .balign 4
+       .long 1b - .
        .previous
        .endm
 #else
index b09ec55650b3806f91f4909558a61688a39404ee..03b6bb5394a02d7211f79a00d0b87e2f74e5cbc7 100644 (file)
  */
 
 #ifdef CONFIG_SMP
-#define LOCK_PREFIX \
+#define LOCK_PREFIX_HERE \
                ".section .smp_locks,\"a\"\n"   \
-               _ASM_ALIGN "\n"                 \
-               _ASM_PTR "661f\n" /* address */ \
+               ".balign 4\n"                   \
+               ".long 671f - .\n" /* offset */ \
                ".previous\n"                   \
-               "661:\n\tlock; "
+               "671:"
+
+#define LOCK_PREFIX LOCK_PREFIX_HERE "\n\tlock; "
 
 #else /* ! CONFIG_SMP */
+#define LOCK_PREFIX_HERE ""
 #define LOCK_PREFIX ""
 #endif
 
-/* This must be included *after* the definition of LOCK_PREFIX */
-#include <asm/cpufeature.h>
-
 struct alt_instr {
        u8 *instr;              /* original instruction */
        u8 *replacement;
@@ -95,6 +95,12 @@ static inline int alternatives_text_reserved(void *start, void *end)
       "663:\n\t" newinstr "\n664:\n"           /* replacement     */   \
       ".previous"
 
+/*
+ * This must be included *after* the definition of ALTERNATIVE due to
+ * <asm/arch_hweight.h>
+ */
+#include <asm/cpufeature.h>
+
 /*
  * Alternative instructions for different CPU types or capabilities.
  *
index ba19ad4c47d03010f9d371bb80fe94e13676cf5a..7014e88bc7798af33f681724ff90cf09eda52af5 100644 (file)
@@ -21,6 +21,7 @@
 #define _ASM_X86_AMD_IOMMU_TYPES_H
 
 #include <linux/types.h>
+#include <linux/mutex.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
 
 
 /* constants to configure the command buffer */
 #define CMD_BUFFER_SIZE    8192
+#define CMD_BUFFER_UNINITIALIZED 1
 #define CMD_BUFFER_ENTRIES 512
 #define MMIO_CMD_SIZE_SHIFT 56
 #define MMIO_CMD_SIZE_512 (0x9ULL << MMIO_CMD_SIZE_SHIFT)
                                (~((1ULL << (12 + ((lvl) * 9))) - 1)))
 #define PM_ALIGNED(lvl, addr)  ((PM_MAP_MASK(lvl) & (addr)) == (addr))
 
+/*
+ * Returns the page table level to use for a given page size
+ * Pagesize is expected to be a power-of-two
+ */
+#define PAGE_SIZE_LEVEL(pagesize) \
+               ((__ffs(pagesize) - 12) / 9)
+/*
+ * Returns the number of ptes to use for a given page size
+ * Pagesize is expected to be a power-of-two
+ */
+#define PAGE_SIZE_PTE_COUNT(pagesize) \
+               (1ULL << ((__ffs(pagesize) - 12) % 9))
+
+/*
+ * Aligns a given io-virtual address to a given page size
+ * Pagesize is expected to be a power-of-two
+ */
+#define PAGE_SIZE_ALIGN(address, pagesize) \
+               ((address) & ~((pagesize) - 1))
+/*
+ * Creates an IOMMU PTE for an address an a given pagesize
+ * The PTE has no permission bits set
+ * Pagesize is expected to be a power-of-two larger than 4096
+ */
+#define PAGE_SIZE_PTE(address, pagesize)               \
+               (((address) | ((pagesize) - 1)) &       \
+                (~(pagesize >> 1)) & PM_ADDR_MASK)
+
+/*
+ * Takes a PTE value with mode=0x07 and returns the page size it maps
+ */
+#define PTE_PAGE_SIZE(pte) \
+       (1ULL << (1 + ffz(((pte) | 0xfffULL))))
+
 #define IOMMU_PTE_P  (1ULL << 0)
 #define IOMMU_PTE_TV (1ULL << 1)
 #define IOMMU_PTE_U  (1ULL << 59)
@@ -237,6 +273,7 @@ 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*/
+       struct mutex api_lock;  /* protect page tables in the iommu-api path */
        u16 id;                 /* the domain id written to the device table */
        int mode;               /* paging mode (0-6 levels) */
        u64 *pt_root;           /* page table root pointer */
index b4ac2cdcb64fd603643fa8409a753b4c5859d918..1fa03e04ae4475e9bdc342aa117d9048a4e93105 100644 (file)
@@ -373,6 +373,7 @@ extern atomic_t init_deasserted;
 extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip);
 #endif
 
+#ifdef CONFIG_X86_LOCAL_APIC
 static inline u32 apic_read(u32 reg)
 {
        return apic->read(reg);
@@ -403,10 +404,19 @@ static inline u32 safe_apic_wait_icr_idle(void)
        return apic->safe_wait_icr_idle();
 }
 
+#else /* CONFIG_X86_LOCAL_APIC */
+
+static inline u32 apic_read(u32 reg) { return 0; }
+static inline void apic_write(u32 reg, u32 val) { }
+static inline u64 apic_icr_read(void) { return 0; }
+static inline void apic_icr_write(u32 low, u32 high) { }
+static inline void apic_wait_icr_idle(void) { }
+static inline u32 safe_apic_wait_icr_idle(void) { return 0; }
+
+#endif /* CONFIG_X86_LOCAL_APIC */
 
 static inline void ack_APIC_irq(void)
 {
-#ifdef CONFIG_X86_LOCAL_APIC
        /*
         * ack_APIC_irq() actually gets compiled as a single instruction
         * ... yummie.
@@ -414,7 +424,6 @@ static inline void ack_APIC_irq(void)
 
        /* Docs say use 0 for future compatibility */
        apic_write(APIC_EOI, 0);
-#endif
 }
 
 static inline unsigned default_get_apic_id(unsigned long x)
diff --git a/arch/x86/include/asm/arch_hweight.h b/arch/x86/include/asm/arch_hweight.h
new file mode 100644 (file)
index 0000000..9686c3d
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef _ASM_X86_HWEIGHT_H
+#define _ASM_X86_HWEIGHT_H
+
+#ifdef CONFIG_64BIT
+/* popcnt %edi, %eax -- redundant REX prefix for alignment */
+#define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7"
+/* popcnt %rdi, %rax */
+#define POPCNT64 ".byte 0xf3,0x48,0x0f,0xb8,0xc7"
+#define REG_IN "D"
+#define REG_OUT "a"
+#else
+/* popcnt %eax, %eax */
+#define POPCNT32 ".byte 0xf3,0x0f,0xb8,0xc0"
+#define REG_IN "a"
+#define REG_OUT "a"
+#endif
+
+/*
+ * __sw_hweightXX are called from within the alternatives below
+ * and callee-clobbered registers need to be taken care of. See
+ * ARCH_HWEIGHT_CFLAGS in <arch/x86/Kconfig> for the respective
+ * compiler switches.
+ */
+static inline unsigned int __arch_hweight32(unsigned int w)
+{
+       unsigned int res = 0;
+
+       asm (ALTERNATIVE("call __sw_hweight32", POPCNT32, X86_FEATURE_POPCNT)
+                    : "="REG_OUT (res)
+                    : REG_IN (w));
+
+       return res;
+}
+
+static inline unsigned int __arch_hweight16(unsigned int w)
+{
+       return __arch_hweight32(w & 0xffff);
+}
+
+static inline unsigned int __arch_hweight8(unsigned int w)
+{
+       return __arch_hweight32(w & 0xff);
+}
+
+static inline unsigned long __arch_hweight64(__u64 w)
+{
+       unsigned long res = 0;
+
+#ifdef CONFIG_X86_32
+       return  __arch_hweight32((u32)w) +
+               __arch_hweight32((u32)(w >> 32));
+#else
+       asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT)
+                    : "="REG_OUT (res)
+                    : REG_IN (w));
+#endif /* CONFIG_X86_32 */
+
+       return res;
+}
+
+#endif
index 8f8217b9bdac67a7312959cad211232f60fbb8ce..952a826ac4e55bf605a05ddad11ae1fb9c315ae9 100644 (file)
@@ -22,7 +22,7 @@
  */
 static inline int atomic_read(const atomic_t *v)
 {
-       return v->counter;
+       return (*(volatile int *)&(v)->counter);
 }
 
 /**
@@ -246,6 +246,29 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
 
 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
 
+/*
+ * atomic_dec_if_positive - decrement by 1 if old value positive
+ * @v: pointer of type atomic_t
+ *
+ * The function returns the old value of *v minus 1, even if
+ * the atomic variable, v, was not decremented.
+ */
+static inline int atomic_dec_if_positive(atomic_t *v)
+{
+       int c, old, dec;
+       c = atomic_read(v);
+       for (;;) {
+               dec = c - 1;
+               if (unlikely(dec < 0))
+                       break;
+               old = atomic_cmpxchg((v), c, dec);
+               if (likely(old == c))
+                       break;
+               c = old;
+       }
+       return dec;
+}
+
 /**
  * atomic_inc_short - increment of a short integer
  * @v: pointer to type int
index 03027bf28de5790afd8c6eb7c01b8362b19a78f6..2a934aa19a4363dce92289390341b4b243ac5167 100644 (file)
@@ -14,109 +14,193 @@ typedef struct {
 
 #define ATOMIC64_INIT(val)     { (val) }
 
-extern u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val);
+#ifdef CONFIG_X86_CMPXCHG64
+#define ATOMIC64_ALTERNATIVE_(f, g) "call atomic64_" #g "_cx8"
+#else
+#define ATOMIC64_ALTERNATIVE_(f, g) ALTERNATIVE("call atomic64_" #f "_386", "call atomic64_" #g "_cx8", X86_FEATURE_CX8)
+#endif
+
+#define ATOMIC64_ALTERNATIVE(f) ATOMIC64_ALTERNATIVE_(f, f)
+
+/**
+ * atomic64_cmpxchg - cmpxchg atomic64 variable
+ * @p: pointer to type atomic64_t
+ * @o: expected value
+ * @n: new value
+ *
+ * Atomically sets @v to @n if it was equal to @o and returns
+ * the old value.
+ */
+
+static inline long long atomic64_cmpxchg(atomic64_t *v, long long o, long long n)
+{
+       return cmpxchg64(&v->counter, o, n);
+}
 
 /**
  * atomic64_xchg - xchg atomic64 variable
- * @ptr:      pointer to type atomic64_t
- * @new_val:  value to assign
+ * @v: pointer to type atomic64_t
+ * @n: value to assign
  *
- * Atomically xchgs the value of @ptr to @new_val and returns
+ * Atomically xchgs the value of @v to @n and returns
  * the old value.
  */
-extern u64 atomic64_xchg(atomic64_t *ptr, u64 new_val);
+static inline long long atomic64_xchg(atomic64_t *v, long long n)
+{
+       long long o;
+       unsigned high = (unsigned)(n >> 32);
+       unsigned low = (unsigned)n;
+       asm volatile(ATOMIC64_ALTERNATIVE(xchg)
+                    : "=A" (o), "+b" (low), "+c" (high)
+                    : "S" (v)
+                    : "memory"
+                    );
+       return o;
+}
 
 /**
  * atomic64_set - set atomic64 variable
- * @ptr:      pointer to type atomic64_t
- * @new_val:  value to assign
+ * @v: pointer to type atomic64_t
+ * @n: value to assign
  *
- * Atomically sets the value of @ptr to @new_val.
+ * Atomically sets the value of @v to @n.
  */
-extern void atomic64_set(atomic64_t *ptr, u64 new_val);
+static inline void atomic64_set(atomic64_t *v, long long i)
+{
+       unsigned high = (unsigned)(i >> 32);
+       unsigned low = (unsigned)i;
+       asm volatile(ATOMIC64_ALTERNATIVE(set)
+                    : "+b" (low), "+c" (high)
+                    : "S" (v)
+                    : "eax", "edx", "memory"
+                    );
+}
 
 /**
  * atomic64_read - read atomic64 variable
- * @ptr:      pointer to type atomic64_t
+ * @v: pointer to type atomic64_t
  *
- * Atomically reads the value of @ptr and returns it.
+ * Atomically reads the value of @v and returns it.
  */
-static inline u64 atomic64_read(atomic64_t *ptr)
+static inline long long atomic64_read(atomic64_t *v)
 {
-       u64 res;
-
-       /*
-        * Note, we inline this atomic64_t primitive because
-        * it only clobbers EAX/EDX and leaves the others
-        * untouched. We also (somewhat subtly) rely on the
-        * fact that cmpxchg8b returns the current 64-bit value
-        * of the memory location we are touching:
-        */
-       asm volatile(
-               "mov %%ebx, %%eax\n\t"
-               "mov %%ecx, %%edx\n\t"
-               LOCK_PREFIX "cmpxchg8b %1\n"
-                       : "=&A" (res)
-                       : "m" (*ptr)
-               );
-
-       return res;
-}
-
-extern u64 atomic64_read(atomic64_t *ptr);
+       long long r;
+       asm volatile(ATOMIC64_ALTERNATIVE(read)
+                    : "=A" (r), "+c" (v)
+                    : : "memory"
+                    );
+       return r;
+ }
 
 /**
  * atomic64_add_return - add and return
- * @delta: integer value to add
- * @ptr:   pointer to type atomic64_t
+ * @i: integer value to add
+ * @v: pointer to type atomic64_t
  *
- * Atomically adds @delta to @ptr and returns @delta + *@ptr
+ * Atomically adds @i to @v and returns @i + *@v
  */
-extern u64 atomic64_add_return(u64 delta, atomic64_t *ptr);
+static inline long long atomic64_add_return(long long i, atomic64_t *v)
+{
+       asm volatile(ATOMIC64_ALTERNATIVE(add_return)
+                    : "+A" (i), "+c" (v)
+                    : : "memory"
+                    );
+       return i;
+}
 
 /*
  * Other variants with different arithmetic operators:
  */
-extern u64 atomic64_sub_return(u64 delta, atomic64_t *ptr);
-extern u64 atomic64_inc_return(atomic64_t *ptr);
-extern u64 atomic64_dec_return(atomic64_t *ptr);
+static inline long long atomic64_sub_return(long long i, atomic64_t *v)
+{
+       asm volatile(ATOMIC64_ALTERNATIVE(sub_return)
+                    : "+A" (i), "+c" (v)
+                    : : "memory"
+                    );
+       return i;
+}
+
+static inline long long atomic64_inc_return(atomic64_t *v)
+{
+       long long a;
+       asm volatile(ATOMIC64_ALTERNATIVE(inc_return)
+                    : "=A" (a)
+                    : "S" (v)
+                    : "memory", "ecx"
+                    );
+       return a;
+}
+
+static inline long long atomic64_dec_return(atomic64_t *v)
+{
+       long long a;
+       asm volatile(ATOMIC64_ALTERNATIVE(dec_return)
+                    : "=A" (a)
+                    : "S" (v)
+                    : "memory", "ecx"
+                    );
+       return a;
+}
 
 /**
  * atomic64_add - add integer to atomic64 variable
- * @delta: integer value to add
- * @ptr:   pointer to type atomic64_t
+ * @i: integer value to add
+ * @v: pointer to type atomic64_t
  *
- * Atomically adds @delta to @ptr.
+ * Atomically adds @i to @v.
  */
-extern void atomic64_add(u64 delta, atomic64_t *ptr);
+static inline long long atomic64_add(long long i, atomic64_t *v)
+{
+       asm volatile(ATOMIC64_ALTERNATIVE_(add, add_return)
+                    : "+A" (i), "+c" (v)
+                    : : "memory"
+                    );
+       return i;
+}
 
 /**
  * atomic64_sub - subtract the atomic64 variable
- * @delta: integer value to subtract
- * @ptr:   pointer to type atomic64_t
+ * @i: integer value to subtract
+ * @v: pointer to type atomic64_t
  *
- * Atomically subtracts @delta from @ptr.
+ * Atomically subtracts @i from @v.
  */
-extern void atomic64_sub(u64 delta, atomic64_t *ptr);
+static inline long long atomic64_sub(long long i, atomic64_t *v)
+{
+       asm volatile(ATOMIC64_ALTERNATIVE_(sub, sub_return)
+                    : "+A" (i), "+c" (v)
+                    : : "memory"
+                    );
+       return i;
+}
 
 /**
  * atomic64_sub_and_test - subtract value from variable and test result
- * @delta: integer value to subtract
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically subtracts @delta from @ptr and returns
+ * @i: integer value to subtract
+ * @v: pointer to type atomic64_t
 *
+ * Atomically subtracts @i from @v and returns
  * true if the result is zero, or false for all
  * other cases.
  */
-extern int atomic64_sub_and_test(u64 delta, atomic64_t *ptr);
+static inline int atomic64_sub_and_test(long long i, atomic64_t *v)
+{
+       return atomic64_sub_return(i, v) == 0;
+}
 
 /**
  * atomic64_inc - increment atomic64 variable
- * @ptr: pointer to type atomic64_t
+ * @v: pointer to type atomic64_t
  *
- * Atomically increments @ptr by 1.
+ * Atomically increments @v by 1.
  */
-extern void atomic64_inc(atomic64_t *ptr);
+static inline void atomic64_inc(atomic64_t *v)
+{
+       asm volatile(ATOMIC64_ALTERNATIVE_(inc, inc_return)
+                    : : "S" (v)
+                    : "memory", "eax", "ecx", "edx"
+                    );
+}
 
 /**
  * atomic64_dec - decrement atomic64 variable
@@ -124,37 +208,97 @@ extern void atomic64_inc(atomic64_t *ptr);
  *
  * Atomically decrements @ptr by 1.
  */
-extern void atomic64_dec(atomic64_t *ptr);
+static inline void atomic64_dec(atomic64_t *v)
+{
+       asm volatile(ATOMIC64_ALTERNATIVE_(dec, dec_return)
+                    : : "S" (v)
+                    : "memory", "eax", "ecx", "edx"
+                    );
+}
 
 /**
  * atomic64_dec_and_test - decrement and test
- * @ptr: pointer to type atomic64_t
+ * @v: pointer to type atomic64_t
  *
- * Atomically decrements @ptr by 1 and
+ * Atomically decrements @v by 1 and
  * returns true if the result is 0, or false for all other
  * cases.
  */
-extern int atomic64_dec_and_test(atomic64_t *ptr);
+static inline int atomic64_dec_and_test(atomic64_t *v)
+{
+       return atomic64_dec_return(v) == 0;
+}
 
 /**
  * atomic64_inc_and_test - increment and test
- * @ptr: pointer to type atomic64_t
+ * @v: pointer to type atomic64_t
  *
- * Atomically increments @ptr by 1
+ * Atomically increments @v by 1
  * and returns true if the result is zero, or false for all
  * other cases.
  */
-extern int atomic64_inc_and_test(atomic64_t *ptr);
+static inline int atomic64_inc_and_test(atomic64_t *v)
+{
+       return atomic64_inc_return(v) == 0;
+}
 
 /**
  * atomic64_add_negative - add and test if negative
- * @delta: integer value to add
- * @ptr:   pointer to type atomic64_t
+ * @i: integer value to add
+ * @v: pointer to type atomic64_t
  *
- * Atomically adds @delta to @ptr and returns true
+ * Atomically adds @i to @v and returns true
  * if the result is negative, or false when
  * result is greater than or equal to zero.
  */
-extern int atomic64_add_negative(u64 delta, atomic64_t *ptr);
+static inline int atomic64_add_negative(long long i, atomic64_t *v)
+{
+       return atomic64_add_return(i, v) < 0;
+}
+
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
+{
+       unsigned low = (unsigned)u;
+       unsigned high = (unsigned)(u >> 32);
+       asm volatile(ATOMIC64_ALTERNATIVE(add_unless) "\n\t"
+                    : "+A" (a), "+c" (v), "+S" (low), "+D" (high)
+                    : : "memory");
+       return (int)a;
+}
+
+
+static inline int atomic64_inc_not_zero(atomic64_t *v)
+{
+       int r;
+       asm volatile(ATOMIC64_ALTERNATIVE(inc_not_zero)
+                    : "=a" (r)
+                    : "S" (v)
+                    : "ecx", "edx", "memory"
+                    );
+       return r;
+}
+
+static inline long long atomic64_dec_if_positive(atomic64_t *v)
+{
+       long long r;
+       asm volatile(ATOMIC64_ALTERNATIVE(dec_if_positive)
+                    : "=A" (r)
+                    : "S" (v)
+                    : "ecx", "memory"
+                    );
+       return r;
+}
+
+#undef ATOMIC64_ALTERNATIVE
+#undef ATOMIC64_ALTERNATIVE_
 
 #endif /* _ASM_X86_ATOMIC64_32_H */
index 51c5b405692952bf9ed7e342ee724bfc202f4017..49fd1ea229511632ac849b17f55543e6782da9ae 100644 (file)
@@ -18,7 +18,7 @@
  */
 static inline long atomic64_read(const atomic64_t *v)
 {
-       return v->counter;
+       return (*(volatile long *)&(v)->counter);
 }
 
 /**
@@ -221,4 +221,27 @@ static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
 
 #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
 
+/*
+ * atomic64_dec_if_positive - decrement by 1 if old value positive
+ * @v: pointer of type atomic_t
+ *
+ * The function returns the old value of *v minus 1, even if
+ * the atomic variable, v, was not decremented.
+ */
+static inline long atomic64_dec_if_positive(atomic64_t *v)
+{
+       long c, old, dec;
+       c = atomic64_read(v);
+       for (;;) {
+               dec = c - 1;
+               if (unlikely(dec < 0))
+                       break;
+               old = atomic64_cmpxchg((v), c, dec);
+               if (likely(old == c))
+                       break;
+               c = old;
+       }
+       return dec;
+}
+
 #endif /* _ASM_X86_ATOMIC64_64_H */
index 02b47a603fc88ee76f316989bc0475cb89be5e24..545776efeb164c72d523f2c78f2c501e1535344c 100644 (file)
@@ -444,7 +444,9 @@ static inline int fls(int x)
 
 #define ARCH_HAS_FAST_MULTIPLIER 1
 
-#include <asm-generic/bitops/hweight.h>
+#include <asm/arch_hweight.h>
+
+#include <asm-generic/bitops/const_hweight.h>
 
 #endif /* __KERNEL__ */
 
index 7a1065958ba9d3f1c5a26b9862864e4707418916..3b62ab56c7a04a92ad795dbe627401981bf1485a 100644 (file)
@@ -24,7 +24,7 @@
 #define MIN_KERNEL_ALIGN       (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2)
 
 #if (CONFIG_PHYSICAL_ALIGN & (CONFIG_PHYSICAL_ALIGN-1)) || \
-       (CONFIG_PHYSICAL_ALIGN < (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2))
+       (CONFIG_PHYSICAL_ALIGN < MIN_KERNEL_ALIGN)
 #error "Invalid value for CONFIG_PHYSICAL_ALIGN"
 #endif
 
index 634c40a739a65ccd2cadef1ea4dd16af1f7b6b9c..c70068d05f70856db76044a3abee750467d4fd1d 100644 (file)
@@ -44,9 +44,6 @@ static inline void copy_from_user_page(struct vm_area_struct *vma,
        memcpy(dst, src, len);
 }
 
-#define PG_WC                          PG_arch_1
-PAGEFLAG(WC, WC)
-
 #ifdef CONFIG_X86_PAT
 /*
  * X86 PAT uses page flags WC and Uncached together to keep track of
@@ -55,16 +52,24 @@ PAGEFLAG(WC, WC)
  * _PAGE_CACHE_UC_MINUS and fourth state where page's memory type has not
  * been changed from its default (value of -1 used to denote this).
  * Note we do not support _PAGE_CACHE_UC here.
- *
- * Caller must hold memtype_lock for atomicity.
  */
+
+#define _PGMT_DEFAULT          0
+#define _PGMT_WC               (1UL << PG_arch_1)
+#define _PGMT_UC_MINUS         (1UL << PG_uncached)
+#define _PGMT_WB               (1UL << PG_uncached | 1UL << PG_arch_1)
+#define _PGMT_MASK             (1UL << PG_uncached | 1UL << PG_arch_1)
+#define _PGMT_CLEAR_MASK       (~_PGMT_MASK)
+
 static inline unsigned long get_page_memtype(struct page *pg)
 {
-       if (!PageUncached(pg) && !PageWC(pg))
+       unsigned long pg_flags = pg->flags & _PGMT_MASK;
+
+       if (pg_flags == _PGMT_DEFAULT)
                return -1;
-       else if (!PageUncached(pg) && PageWC(pg))
+       else if (pg_flags == _PGMT_WC)
                return _PAGE_CACHE_WC;
-       else if (PageUncached(pg) && !PageWC(pg))
+       else if (pg_flags == _PGMT_UC_MINUS)
                return _PAGE_CACHE_UC_MINUS;
        else
                return _PAGE_CACHE_WB;
@@ -72,25 +77,26 @@ static inline unsigned long get_page_memtype(struct page *pg)
 
 static inline void set_page_memtype(struct page *pg, unsigned long memtype)
 {
+       unsigned long memtype_flags = _PGMT_DEFAULT;
+       unsigned long old_flags;
+       unsigned long new_flags;
+
        switch (memtype) {
        case _PAGE_CACHE_WC:
-               ClearPageUncached(pg);
-               SetPageWC(pg);
+               memtype_flags = _PGMT_WC;
                break;
        case _PAGE_CACHE_UC_MINUS:
-               SetPageUncached(pg);
-               ClearPageWC(pg);
+               memtype_flags = _PGMT_UC_MINUS;
                break;
        case _PAGE_CACHE_WB:
-               SetPageUncached(pg);
-               SetPageWC(pg);
-               break;
-       default:
-       case -1:
-               ClearPageUncached(pg);
-               ClearPageWC(pg);
+               memtype_flags = _PGMT_WB;
                break;
        }
+
+       do {
+               old_flags = pg->flags;
+               new_flags = (old_flags & _PGMT_CLEAR_MASK) | memtype_flags;
+       } while (cmpxchg(&pg->flags, old_flags, new_flags) != old_flags);
 }
 #else
 static inline unsigned long get_page_memtype(struct page *pg) { return -1; }
index ffb9bb6b6c372be80ce68445e60750a53458ea6e..8859e12dd3cf85a6f6c9aa1d8ccda53cb799c018 100644 (file)
@@ -271,7 +271,8 @@ extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64);
        __typeof__(*(ptr)) __ret;                               \
        __typeof__(*(ptr)) __old = (o);                         \
        __typeof__(*(ptr)) __new = (n);                         \
-       alternative_io("call cmpxchg8b_emu",                    \
+       alternative_io(LOCK_PREFIX_HERE                         \
+                       "call cmpxchg8b_emu",                   \
                        "lock; cmpxchg8b (%%esi)" ,             \
                       X86_FEATURE_CX8,                         \
                       "=A" (__ret),                            \
index 0cd82d06861333b1c42f8ac2dba79462c11e24ce..dca9c545f44e6be7105f85c3a5f17ac16020d9fa 100644 (file)
  */
 #define X86_FEATURE_IDA                (7*32+ 0) /* Intel Dynamic Acceleration */
 #define X86_FEATURE_ARAT       (7*32+ 1) /* Always Running APIC Timer */
+#define X86_FEATURE_CPB                (7*32+ 2) /* AMD Core Performance Boost */
 
 /* Virtualization flags: Linux defined */
 #define X86_FEATURE_TPR_SHADOW  (8*32+ 0) /* Intel TPR Shadow */
 
 #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
 
+#include <asm/asm.h>
 #include <linux/bitops.h>
 
 extern const char * const x86_cap_flags[NCAPINTS*32];
@@ -283,6 +285,62 @@ extern const char * const x86_power_flags[32];
 
 #endif /* CONFIG_X86_64 */
 
+/*
+ * Static testing of CPU features.  Used the same as boot_cpu_has().
+ * These are only valid after alternatives have run, but will statically
+ * patch the target code for additional performance.
+ *
+ */
+static __always_inline __pure bool __static_cpu_has(u8 bit)
+{
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+               asm goto("1: jmp %l[t_no]\n"
+                        "2:\n"
+                        ".section .altinstructions,\"a\"\n"
+                        _ASM_ALIGN "\n"
+                        _ASM_PTR "1b\n"
+                        _ASM_PTR "0\n"         /* no replacement */
+                        " .byte %P0\n"         /* feature bit */
+                        " .byte 2b - 1b\n"     /* source len */
+                        " .byte 0\n"           /* replacement len */
+                        " .byte 0xff + 0 - (2b-1b)\n"  /* padding */
+                        ".previous\n"
+                        : : "i" (bit) : : t_no);
+               return true;
+       t_no:
+               return false;
+#else
+               u8 flag;
+               /* Open-coded due to __stringify() in ALTERNATIVE() */
+               asm volatile("1: movb $0,%0\n"
+                            "2:\n"
+                            ".section .altinstructions,\"a\"\n"
+                            _ASM_ALIGN "\n"
+                            _ASM_PTR "1b\n"
+                            _ASM_PTR "3f\n"
+                            " .byte %P1\n"             /* feature bit */
+                            " .byte 2b - 1b\n"         /* source len */
+                            " .byte 4f - 3f\n"         /* replacement len */
+                            " .byte 0xff + (4f-3f) - (2b-1b)\n" /* padding */
+                            ".previous\n"
+                            ".section .altinstr_replacement,\"ax\"\n"
+                            "3: movb $1,%0\n"
+                            "4:\n"
+                            ".previous\n"
+                            : "=qm" (flag) : "i" (bit));
+               return flag;
+#endif
+}
+
+#define static_cpu_has(bit)                                    \
+(                                                              \
+       __builtin_constant_p(boot_cpu_has(bit)) ?               \
+               boot_cpu_has(bit) :                             \
+       (__builtin_constant_p(bit) && !((bit) & ~0xff)) ?       \
+               __static_cpu_has(bit) :                         \
+               boot_cpu_has(bit)                               \
+)
+
 #endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */
 
 #endif /* _ASM_X86_CPUFEATURE_H */
diff --git a/arch/x86/include/asm/ds.h b/arch/x86/include/asm/ds.h
deleted file mode 100644 (file)
index 70dac19..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Debug Store (DS) support
- *
- * This provides a low-level interface to the hardware's Debug Store
- * feature that is used for branch trace store (BTS) and
- * precise-event based sampling (PEBS).
- *
- * It manages:
- * - DS and BTS hardware configuration
- * - buffer overflow handling (to be done)
- * - buffer access
- *
- * It does not do:
- * - security checking (is the caller allowed to trace the task)
- * - buffer allocation (memory accounting)
- *
- *
- * Copyright (C) 2007-2009 Intel Corporation.
- * Markus Metzger <markus.t.metzger@intel.com>, 2007-2009
- */
-
-#ifndef _ASM_X86_DS_H
-#define _ASM_X86_DS_H
-
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/err.h>
-
-
-#ifdef CONFIG_X86_DS
-
-struct task_struct;
-struct ds_context;
-struct ds_tracer;
-struct bts_tracer;
-struct pebs_tracer;
-
-typedef void (*bts_ovfl_callback_t)(struct bts_tracer *);
-typedef void (*pebs_ovfl_callback_t)(struct pebs_tracer *);
-
-
-/*
- * A list of features plus corresponding macros to talk about them in
- * the ds_request function's flags parameter.
- *
- * We use the enum to index an array of corresponding control bits;
- * we use the macro to index a flags bit-vector.
- */
-enum ds_feature {
-       dsf_bts = 0,
-       dsf_bts_kernel,
-#define BTS_KERNEL (1 << dsf_bts_kernel)
-       /* trace kernel-mode branches */
-
-       dsf_bts_user,
-#define BTS_USER (1 << dsf_bts_user)
-       /* trace user-mode branches */
-
-       dsf_bts_overflow,
-       dsf_bts_max,
-       dsf_pebs = dsf_bts_max,
-
-       dsf_pebs_max,
-       dsf_ctl_max = dsf_pebs_max,
-       dsf_bts_timestamps = dsf_ctl_max,
-#define BTS_TIMESTAMPS (1 << dsf_bts_timestamps)
-       /* add timestamps into BTS trace */
-
-#define BTS_USER_FLAGS (BTS_KERNEL | BTS_USER | BTS_TIMESTAMPS)
-};
-
-
-/*
- * Request BTS or PEBS
- *
- * Due to alignement constraints, the actual buffer may be slightly
- * smaller than the requested or provided buffer.
- *
- * Returns a pointer to a tracer structure on success, or
- * ERR_PTR(errcode) on failure.
- *
- * The interrupt threshold is independent from the overflow callback
- * to allow users to use their own overflow interrupt handling mechanism.
- *
- * The function might sleep.
- *
- * task: the task to request recording for
- * cpu:  the cpu to request recording for
- * base: the base pointer for the (non-pageable) buffer;
- * size: the size of the provided buffer in bytes
- * ovfl: pointer to a function to be called on buffer overflow;
- *       NULL if cyclic buffer requested
- * th: the interrupt threshold in records from the end of the buffer;
- *     -1 if no interrupt threshold is requested.
- * flags: a bit-mask of the above flags
- */
-extern struct bts_tracer *ds_request_bts_task(struct task_struct *task,
-                                             void *base, size_t size,
-                                             bts_ovfl_callback_t ovfl,
-                                             size_t th, unsigned int flags);
-extern struct bts_tracer *ds_request_bts_cpu(int cpu, void *base, size_t size,
-                                            bts_ovfl_callback_t ovfl,
-                                            size_t th, unsigned int flags);
-extern struct pebs_tracer *ds_request_pebs_task(struct task_struct *task,
-                                               void *base, size_t size,
-                                               pebs_ovfl_callback_t ovfl,
-                                               size_t th, unsigned int flags);
-extern struct pebs_tracer *ds_request_pebs_cpu(int cpu,
-                                              void *base, size_t size,
-                                              pebs_ovfl_callback_t ovfl,
-                                              size_t th, unsigned int flags);
-
-/*
- * Release BTS or PEBS resources
- * Suspend and resume BTS or PEBS tracing
- *
- * Must be called with irq's enabled.
- *
- * tracer: the tracer handle returned from ds_request_~()
- */
-extern void ds_release_bts(struct bts_tracer *tracer);
-extern void ds_suspend_bts(struct bts_tracer *tracer);
-extern void ds_resume_bts(struct bts_tracer *tracer);
-extern void ds_release_pebs(struct pebs_tracer *tracer);
-extern void ds_suspend_pebs(struct pebs_tracer *tracer);
-extern void ds_resume_pebs(struct pebs_tracer *tracer);
-
-/*
- * Release BTS or PEBS resources
- * Suspend and resume BTS or PEBS tracing
- *
- * Cpu tracers must call this on the traced cpu.
- * Task tracers must call ds_release_~_noirq() for themselves.
- *
- * May be called with irq's disabled.
- *
- * Returns 0 if successful;
- * -EPERM if the cpu tracer does not trace the current cpu.
- * -EPERM if the task tracer does not trace itself.
- *
- * tracer: the tracer handle returned from ds_request_~()
- */
-extern int ds_release_bts_noirq(struct bts_tracer *tracer);
-extern int ds_suspend_bts_noirq(struct bts_tracer *tracer);
-extern int ds_resume_bts_noirq(struct bts_tracer *tracer);
-extern int ds_release_pebs_noirq(struct pebs_tracer *tracer);
-extern int ds_suspend_pebs_noirq(struct pebs_tracer *tracer);
-extern int ds_resume_pebs_noirq(struct pebs_tracer *tracer);
-
-
-/*
- * The raw DS buffer state as it is used for BTS and PEBS recording.
- *
- * This is the low-level, arch-dependent interface for working
- * directly on the raw trace data.
- */
-struct ds_trace {
-       /* the number of bts/pebs records */
-       size_t n;
-       /* the size of a bts/pebs record in bytes */
-       size_t size;
-       /* pointers into the raw buffer:
-          - to the first entry */
-       void *begin;
-       /* - one beyond the last entry */
-       void *end;
-       /* - one beyond the newest entry */
-       void *top;
-       /* - the interrupt threshold */
-       void *ith;
-       /* flags given on ds_request() */
-       unsigned int flags;
-};
-
-/*
- * An arch-independent view on branch trace data.
- */
-enum bts_qualifier {
-       bts_invalid,
-#define BTS_INVALID bts_invalid
-
-       bts_branch,
-#define BTS_BRANCH bts_branch
-
-       bts_task_arrives,
-#define BTS_TASK_ARRIVES bts_task_arrives
-
-       bts_task_departs,
-#define BTS_TASK_DEPARTS bts_task_departs
-
-       bts_qual_bit_size = 4,
-       bts_qual_max = (1 << bts_qual_bit_size),
-};
-
-struct bts_struct {
-       __u64 qualifier;
-       union {
-               /* BTS_BRANCH */
-               struct {
-                       __u64 from;
-                       __u64 to;
-               } lbr;
-               /* BTS_TASK_ARRIVES or BTS_TASK_DEPARTS */
-               struct {
-                       __u64 clock;
-                       pid_t pid;
-               } event;
-       } variant;
-};
-
-
-/*
- * The BTS state.
- *
- * This gives access to the raw DS state and adds functions to provide
- * an arch-independent view of the BTS data.
- */
-struct bts_trace {
-       struct ds_trace ds;
-
-       int (*read)(struct bts_tracer *tracer, const void *at,
-                   struct bts_struct *out);
-       int (*write)(struct bts_tracer *tracer, const struct bts_struct *in);
-};
-
-
-/*
- * The PEBS state.
- *
- * This gives access to the raw DS state and the PEBS-specific counter
- * reset value.
- */
-struct pebs_trace {
-       struct ds_trace ds;
-
-       /* the number of valid counters in the below array */
-       unsigned int counters;
-
-#define MAX_PEBS_COUNTERS 4
-       /* the counter reset value */
-       unsigned long long counter_reset[MAX_PEBS_COUNTERS];
-};
-
-
-/*
- * Read the BTS or PEBS trace.
- *
- * Returns a view on the trace collected for the parameter tracer.
- *
- * The view remains valid as long as the traced task is not running or
- * the tracer is suspended.
- * Writes into the trace buffer are not reflected.
- *
- * tracer: the tracer handle returned from ds_request_~()
- */
-extern const struct bts_trace *ds_read_bts(struct bts_tracer *tracer);
-extern const struct pebs_trace *ds_read_pebs(struct pebs_tracer *tracer);
-
-
-/*
- * Reset the write pointer of the BTS/PEBS buffer.
- *
- * Returns 0 on success; -Eerrno on error
- *
- * tracer: the tracer handle returned from ds_request_~()
- */
-extern int ds_reset_bts(struct bts_tracer *tracer);
-extern int ds_reset_pebs(struct pebs_tracer *tracer);
-
-/*
- * Set the PEBS counter reset value.
- *
- * Returns 0 on success; -Eerrno on error
- *
- * tracer: the tracer handle returned from ds_request_pebs()
- * counter: the index of the counter
- * value: the new counter reset value
- */
-extern int ds_set_pebs_reset(struct pebs_tracer *tracer,
-                            unsigned int counter, u64 value);
-
-/*
- * Initialization
- */
-struct cpuinfo_x86;
-extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *);
-
-/*
- * Context switch work
- */
-extern void ds_switch_to(struct task_struct *prev, struct task_struct *next);
-
-#else /* CONFIG_X86_DS */
-
-struct cpuinfo_x86;
-static inline void __cpuinit ds_init_intel(struct cpuinfo_x86 *ignored) {}
-static inline void ds_switch_to(struct task_struct *prev,
-                               struct task_struct *next) {}
-
-#endif /* CONFIG_X86_DS */
-#endif /* _ASM_X86_DS_H */
index ae6253ab90294c89d4d009f370a6a0046431971b..733f7e91e7a99f45435a6b46c831ff3e6e9c05da 100644 (file)
 #define CFI_SIGNAL_FRAME
 #endif
 
+#if defined(CONFIG_AS_CFI_SECTIONS) && defined(__ASSEMBLY__)
+       /*
+        * Emit CFI data in .debug_frame sections, not .eh_frame sections.
+        * The latter we currently just discard since we don't do DWARF
+        * unwinding at runtime.  So only the offline DWARF information is
+        * useful to anyone.  Note we should not use this directive if this
+        * file is used in the vDSO assembly, or if vmlinux.lds.S gets
+        * changed so it doesn't discard .eh_frame.
+        */
+       .cfi_sections .debug_frame
+#endif
+
 #else
 
 /*
index 635f03bb499528ff7905b3b96f112a910d4c57e3..d07b44f7d1dc014b3d1cb77e49138ef5f97f5d24 100644 (file)
@@ -82,6 +82,9 @@ enum fixed_addresses {
 #endif
        FIX_DBGP_BASE,
        FIX_EARLYCON_MEM_BASE,
+#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
+       FIX_OHCI1394_BASE,
+#endif
 #ifdef CONFIG_X86_LOCAL_APIC
        FIX_APIC_BASE,  /* local (CPU) APIC) -- required for SMP or not */
 #endif
@@ -132,9 +135,6 @@ enum fixed_addresses {
           (__end_of_permanent_fixed_addresses & (TOTAL_FIX_BTMAPS - 1))
         : __end_of_permanent_fixed_addresses,
        FIX_BTMAP_BEGIN = FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1,
-#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
-       FIX_OHCI1394_BASE,
-#endif
 #ifdef CONFIG_X86_32
        FIX_WP_TEST,
 #endif
index 0f8576427cfefff4ada5dfdaac118e01428d8997..aeab29aee617240fbf479d2945572879be4525ec 100644 (file)
@@ -35,7 +35,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
 
 #define __ARCH_IRQ_STAT
 
-#define inc_irq_stat(member)   percpu_add(irq_stat.member, 1)
+#define inc_irq_stat(member)   percpu_inc(irq_stat.member)
 
 #define local_softirq_pending()        percpu_read(irq_stat.__softirq_pending)
 
index 2a1bd8f4f23ad34bafa49c829e18172d17569d50..942255310e6a16391b3e0a5bcbcd59ccafece3d6 100644 (file)
@@ -41,12 +41,16 @@ struct arch_hw_breakpoint {
 /* Total number of available HW breakpoint registers */
 #define HBP_NUM 4
 
+static inline int hw_breakpoint_slots(int type)
+{
+       return HBP_NUM;
+}
+
 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 arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
 extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
                                           unsigned long val, void *data);
 
index a929c9ede33d55db556e5fc603facb61b39d5d68..46c0fe05f230112b5aa5e176d4292e56526f8279 100644 (file)
@@ -133,6 +133,7 @@ extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void);
 
 typedef int vector_irq_t[NR_VECTORS];
 DECLARE_PER_CPU(vector_irq_t, vector_irq);
+extern void setup_vector_irq(int cpu);
 
 #ifdef CONFIG_X86_IO_APIC
 extern void lock_vector_lock(void);
index e153a2b3889adff99966ce1bc1f0c8995f33eac1..5df477ac3af7cd9b962241e883a17bd201aec81e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_KVM_HYPERV_H
-#define _ASM_X86_KVM_HYPERV_H
+#ifndef _ASM_X86_HYPERV_H
+#define _ASM_X86_HYPERV_H
 
 #include <linux/types.h>
 
 #define HYPERV_CPUID_ENLIGHTMENT_INFO          0x40000004
 #define HYPERV_CPUID_IMPLEMENT_LIMITS          0x40000005
 
+#define HYPERV_HYPERVISOR_PRESENT_BIT          0x80000000
+#define HYPERV_CPUID_MIN                       0x40000005
+#define HYPERV_CPUID_MAX                       0x4000ffff
+
 /*
  * Feature identification. EAX indicates which features are available
  * to the partition based upon the current partition privileges.
 /* MSR used to provide vcpu index */
 #define HV_X64_MSR_VP_INDEX                    0x40000002
 
+/* MSR used to read the per-partition time reference counter */
+#define HV_X64_MSR_TIME_REF_COUNT              0x40000020
+
 /* Define the virtual APIC registers */
 #define HV_X64_MSR_EOI                         0x40000070
 #define HV_X64_MSR_ICR                         0x40000071
index b78c0941e4228872afa00684eafff0dddc9d02ff..70abda7058c81c791946e0e1e78afa963a260a7a 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  */
-#ifndef ASM_X86__HYPERVISOR_H
-#define ASM_X86__HYPERVISOR_H
+#ifndef _ASM_X86_HYPERVISOR_H
+#define _ASM_X86_HYPERVISOR_H
 
 extern void init_hypervisor(struct cpuinfo_x86 *c);
 extern void init_hypervisor_platform(void);
 
+/*
+ * x86 hypervisor information
+ */
+struct hypervisor_x86 {
+       /* Hypervisor name */
+       const char      *name;
+
+       /* Detection routine */
+       bool            (*detect)(void);
+
+       /* Adjust CPU feature bits (run once per CPU) */
+       void            (*set_cpu_features)(struct cpuinfo_x86 *);
+
+       /* Platform setup (run once per boot) */
+       void            (*init_platform)(void);
+};
+
+extern const struct hypervisor_x86 *x86_hyper;
+
+/* Recognized hypervisors */
+extern const struct hypervisor_x86 x86_hyper_vmware;
+extern const struct hypervisor_x86 x86_hyper_ms_hyperv;
+
 #endif
index da2930924501547c0349570d12323b37522115e2..c991b3a7b904bbfea99c5b74e423808eb55b1c56 100644 (file)
@@ -16,7 +16,9 @@
 #include <linux/kernel_stat.h>
 #include <linux/regset.h>
 #include <linux/hardirq.h>
+#include <linux/slab.h>
 #include <asm/asm.h>
+#include <asm/cpufeature.h>
 #include <asm/processor.h>
 #include <asm/sigcontext.h>
 #include <asm/user.h>
@@ -56,6 +58,11 @@ extern int restore_i387_xstate_ia32(void __user *buf);
 
 #define X87_FSW_ES (1 << 7)    /* Exception Summary */
 
+static __always_inline __pure bool use_xsave(void)
+{
+       return static_cpu_has(X86_FEATURE_XSAVE);
+}
+
 #ifdef CONFIG_X86_64
 
 /* Ignore delayed exceptions from user space */
@@ -91,15 +98,15 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
    values. The kernel data segment can be sometimes 0 and sometimes
    new user value. Both should be ok.
    Use the PDA as safe address because it should be already in L1. */
-static inline void clear_fpu_state(struct task_struct *tsk)
+static inline void fpu_clear(struct fpu *fpu)
 {
-       struct xsave_struct *xstate = &tsk->thread.xstate->xsave;
-       struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave;
+       struct xsave_struct *xstate = &fpu->state->xsave;
+       struct i387_fxsave_struct *fx = &fpu->state->fxsave;
 
        /*
         * xsave header may indicate the init state of the FP.
         */
-       if ((task_thread_info(tsk)->status & TS_XSAVE) &&
+       if (use_xsave() &&
            !(xstate->xsave_hdr.xstate_bv & XSTATE_FP))
                return;
 
@@ -111,6 +118,11 @@ static inline void clear_fpu_state(struct task_struct *tsk)
                          X86_FEATURE_FXSAVE_LEAK);
 }
 
+static inline void clear_fpu_state(struct task_struct *tsk)
+{
+       fpu_clear(&tsk->thread.fpu);
+}
+
 static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
 {
        int err;
@@ -135,7 +147,7 @@ static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
        return err;
 }
 
-static inline void fxsave(struct task_struct *tsk)
+static inline void fpu_fxsave(struct fpu *fpu)
 {
        /* Using "rex64; fxsave %0" is broken because, if the memory operand
           uses any extended registers for addressing, a second REX prefix
@@ -145,42 +157,45 @@ static inline void fxsave(struct task_struct *tsk)
        /* Using "fxsaveq %0" would be the ideal choice, but is only supported
           starting with gas 2.16. */
        __asm__ __volatile__("fxsaveq %0"
-                            : "=m" (tsk->thread.xstate->fxsave));
+                            : "=m" (fpu->state->fxsave));
 #elif 0
        /* Using, as a workaround, the properly prefixed form below isn't
           accepted by any binutils version so far released, complaining that
           the same type of prefix is used twice if an extended register is
           needed for addressing (fix submitted to mainline 2005-11-21). */
        __asm__ __volatile__("rex64/fxsave %0"
-                            : "=m" (tsk->thread.xstate->fxsave));
+                            : "=m" (fpu->state->fxsave));
 #else
        /* This, however, we can work around by forcing the compiler to select
           an addressing mode that doesn't require extended registers. */
        __asm__ __volatile__("rex64/fxsave (%1)"
-                            : "=m" (tsk->thread.xstate->fxsave)
-                            : "cdaSDb" (&tsk->thread.xstate->fxsave));
+                            : "=m" (fpu->state->fxsave)
+                            : "cdaSDb" (&fpu->state->fxsave));
 #endif
 }
 
-static inline void __save_init_fpu(struct task_struct *tsk)
+static inline void fpu_save_init(struct fpu *fpu)
 {
-       if (task_thread_info(tsk)->status & TS_XSAVE)
-               xsave(tsk);
+       if (use_xsave())
+               fpu_xsave(fpu);
        else
-               fxsave(tsk);
+               fpu_fxsave(fpu);
+
+       fpu_clear(fpu);
+}
 
-       clear_fpu_state(tsk);
+static inline void __save_init_fpu(struct task_struct *tsk)
+{
+       fpu_save_init(&tsk->thread.fpu);
        task_thread_info(tsk)->status &= ~TS_USEDFPU;
 }
 
 #else  /* CONFIG_X86_32 */
 
 #ifdef CONFIG_MATH_EMULATION
-extern void finit_task(struct task_struct *tsk);
+extern void finit_soft_fpu(struct i387_soft_struct *soft);
 #else
-static inline void finit_task(struct task_struct *tsk)
-{
-}
+static inline void finit_soft_fpu(struct i387_soft_struct *soft) {}
 #endif
 
 static inline void tolerant_fwait(void)
@@ -216,13 +231,13 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
 /*
  * These must be called with preempt disabled
  */
-static inline void __save_init_fpu(struct task_struct *tsk)
+static inline void fpu_save_init(struct fpu *fpu)
 {
-       if (task_thread_info(tsk)->status & TS_XSAVE) {
-               struct xsave_struct *xstate = &tsk->thread.xstate->xsave;
-               struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave;
+       if (use_xsave()) {
+               struct xsave_struct *xstate = &fpu->state->xsave;
+               struct i387_fxsave_struct *fx = &fpu->state->fxsave;
 
-               xsave(tsk);
+               fpu_xsave(fpu);
 
                /*
                 * xsave header may indicate the init state of the FP.
@@ -246,8 +261,8 @@ static inline void __save_init_fpu(struct task_struct *tsk)
                "fxsave %[fx]\n"
                "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:",
                X86_FEATURE_FXSR,
-               [fx] "m" (tsk->thread.xstate->fxsave),
-               [fsw] "m" (tsk->thread.xstate->fxsave.swd) : "memory");
+               [fx] "m" (fpu->state->fxsave),
+               [fsw] "m" (fpu->state->fxsave.swd) : "memory");
 clear_state:
        /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
           is pending.  Clear the x87 state here by setting it to fixed
@@ -259,17 +274,34 @@ clear_state:
                X86_FEATURE_FXSAVE_LEAK,
                [addr] "m" (safe_address));
 end:
+       ;
+}
+
+static inline void __save_init_fpu(struct task_struct *tsk)
+{
+       fpu_save_init(&tsk->thread.fpu);
        task_thread_info(tsk)->status &= ~TS_USEDFPU;
 }
 
+
 #endif /* CONFIG_X86_64 */
 
-static inline int restore_fpu_checking(struct task_struct *tsk)
+static inline int fpu_fxrstor_checking(struct fpu *fpu)
 {
-       if (task_thread_info(tsk)->status & TS_XSAVE)
-               return xrstor_checking(&tsk->thread.xstate->xsave);
+       return fxrstor_checking(&fpu->state->fxsave);
+}
+
+static inline int fpu_restore_checking(struct fpu *fpu)
+{
+       if (use_xsave())
+               return fpu_xrstor_checking(fpu);
        else
-               return fxrstor_checking(&tsk->thread.xstate->fxsave);
+               return fpu_fxrstor_checking(fpu);
+}
+
+static inline int restore_fpu_checking(struct task_struct *tsk)
+{
+       return fpu_restore_checking(&tsk->thread.fpu);
 }
 
 /*
@@ -397,30 +429,59 @@ static inline void clear_fpu(struct task_struct *tsk)
 static inline unsigned short get_fpu_cwd(struct task_struct *tsk)
 {
        if (cpu_has_fxsr) {
-               return tsk->thread.xstate->fxsave.cwd;
+               return tsk->thread.fpu.state->fxsave.cwd;
        } else {
-               return (unsigned short)tsk->thread.xstate->fsave.cwd;
+               return (unsigned short)tsk->thread.fpu.state->fsave.cwd;
        }
 }
 
 static inline unsigned short get_fpu_swd(struct task_struct *tsk)
 {
        if (cpu_has_fxsr) {
-               return tsk->thread.xstate->fxsave.swd;
+               return tsk->thread.fpu.state->fxsave.swd;
        } else {
-               return (unsigned short)tsk->thread.xstate->fsave.swd;
+               return (unsigned short)tsk->thread.fpu.state->fsave.swd;
        }
 }
 
 static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk)
 {
        if (cpu_has_xmm) {
-               return tsk->thread.xstate->fxsave.mxcsr;
+               return tsk->thread.fpu.state->fxsave.mxcsr;
        } else {
                return MXCSR_DEFAULT;
        }
 }
 
+static bool fpu_allocated(struct fpu *fpu)
+{
+       return fpu->state != NULL;
+}
+
+static inline int fpu_alloc(struct fpu *fpu)
+{
+       if (fpu_allocated(fpu))
+               return 0;
+       fpu->state = kmem_cache_alloc(task_xstate_cachep, GFP_KERNEL);
+       if (!fpu->state)
+               return -ENOMEM;
+       WARN_ON((unsigned long)fpu->state & 15);
+       return 0;
+}
+
+static inline void fpu_free(struct fpu *fpu)
+{
+       if (fpu->state) {
+               kmem_cache_free(task_xstate_cachep, fpu->state);
+               fpu->state = NULL;
+       }
+}
+
+static inline void fpu_copy(struct fpu *dst, struct fpu *src)
+{
+       memcpy(dst->state, src->state, xstate_size);
+}
+
 #endif /* __ASSEMBLY__ */
 
 #define PSHUFB_XMM5_XMM0 .byte 0x66, 0x0f, 0x38, 0x00, 0xc5
index 1edbf89680fd57e577e6ccae74e5ef110d285414..fc1f579fb965157cec8ce23376a59ff5a23280e9 100644 (file)
@@ -6,7 +6,7 @@
 #define PIT_CH0                        0x40
 #define PIT_CH2                        0x42
 
-extern spinlock_t i8253_lock;
+extern raw_spinlock_t i8253_lock;
 
 extern struct clock_event_device *global_clock_event;
 
index 96c2e0ad04ca04f94d2a7974007dd647a4142549..88c765e16410beecf7be2bfdad19b0cf4918ec46 100644 (file)
@@ -68,6 +68,8 @@ struct insn {
        const insn_byte_t *next_byte;
 };
 
+#define MAX_INSN_SIZE  16
+
 #define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6)
 #define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3)
 #define X86_MODRM_RM(modrm) ((modrm) & 0x07)
index a1dcfa3ab17dd505c7400869463ed81adfcca91b..30a3e977612306033c9647487dde3298b31a4f73 100644 (file)
@@ -347,6 +347,7 @@ extern void __iomem *early_ioremap(resource_size_t phys_addr,
 extern void __iomem *early_memremap(resource_size_t phys_addr,
                                    unsigned long size);
 extern void early_iounmap(void __iomem *addr, unsigned long size);
+extern void fixup_early_ioremap(void);
 
 #define IO_SPACE_LIMIT 0xffff
 
index 35832a03a5158ab7e00451619599406eda612319..63cb4096c3dc998efba7e160f6804c0b6d80c309 100644 (file)
@@ -159,7 +159,6 @@ struct io_apic_irq_attr;
 extern int io_apic_set_pci_routing(struct device *dev, int irq,
                 struct io_apic_irq_attr *irq_attr);
 void setup_IO_APIC_irq_extra(u32 gsi);
-extern int (*ioapic_renumber_irq)(int ioapic, int irq);
 extern void ioapic_init_mappings(void);
 extern void ioapic_insert_resources(void);
 
@@ -180,12 +179,13 @@ extern void ioapic_write_entry(int apic, int pin,
 extern void setup_ioapic_ids_from_mpc(void);
 
 struct mp_ioapic_gsi{
-       int gsi_base;
-       int gsi_end;
+       u32 gsi_base;
+       u32 gsi_end;
 };
 extern struct mp_ioapic_gsi  mp_gsi_routing[];
-int mp_find_ioapic(int gsi);
-int mp_find_ioapic_pin(int ioapic, int gsi);
+extern u32 gsi_end;
+int mp_find_ioapic(u32 gsi);
+int mp_find_ioapic_pin(int ioapic, u32 gsi);
 void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
 extern void __init pre_init_apic_IRQ0(void);
 
@@ -197,7 +197,8 @@ static const int timer_through_8259 = 0;
 static inline void ioapic_init_mappings(void)  { }
 static inline void ioapic_insert_resources(void) { }
 static inline void probe_nr_irqs_gsi(void)     { }
-static inline int mp_find_ioapic(int gsi) { return 0; }
+#define gsi_end (NR_IRQS_LEGACY - 1)
+static inline int mp_find_ioapic(u32 gsi) { return 0; }
 
 struct io_apic_irq_attr;
 static inline int io_apic_set_pci_routing(struct device *dev, int irq,
index f70e60071fe80039e4d439cca6667f65729bcbd5..af00bd1d208934941f00ba7e911c20dd868a3f2b 100644 (file)
@@ -16,11 +16,16 @@ extern int k8_numa_init(unsigned long start_pfn, unsigned long end_pfn);
 extern int k8_scan_nodes(void);
 
 #ifdef CONFIG_K8_NB
+extern int num_k8_northbridges;
+
 static inline struct pci_dev *node_to_k8_nb_misc(int node)
 {
        return (node < num_k8_northbridges) ? k8_northbridges[node] : NULL;
 }
+
 #else
+#define num_k8_northbridges 0
+
 static inline struct pci_dev *node_to_k8_nb_misc(int node)
 {
        return NULL;
index 4ffa345a8ccbd7d2b7db8debd7caa090aceaf8a5..54788253915739a2a07faa87f8186ab261e0a065 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/types.h>
 #include <linux/ptrace.h>
 #include <linux/percpu.h>
+#include <asm/insn.h>
 
 #define  __ARCH_WANT_KPROBES_INSN_SLOT
 
@@ -36,7 +37,6 @@ typedef u8 kprobe_opcode_t;
 #define RELATIVEJUMP_SIZE 5
 #define RELATIVECALL_OPCODE 0xe8
 #define RELATIVE_ADDR_SIZE 4
-#define MAX_INSN_SIZE 16
 #define MAX_STACK_SIZE 64
 #define MIN_STACK_SIZE(ADDR)                                          \
        (((MAX_STACK_SIZE) < (((unsigned long)current_thread_info()) + \
index ba0eed8aa1a6d133a065963ab0cd331bf9eeacb9..b60f2924c41314468d5c9b2df3fcea77fdc0c063 100644 (file)
 
 #ifndef __ASSEMBLY__
 #include <asm/hw_irq.h>
-#include <asm/kvm_para.h>
 
 /*G:030
  * But first, how does our Guest contact the Host to ask for privileged
  * operations?  There are two ways: the direct way is to make a "hypercall",
  * to make requests of the Host Itself.
  *
- * We use the KVM hypercall mechanism, though completely different hypercall
- * numbers. Seventeen hypercalls are available: the hypercall number is put in
- * the %eax register, and the arguments (when required) are placed in %ebx,
- * %ecx, %edx and %esi.  If a return value makes sense, it's returned in %eax.
+ * Our hypercall mechanism uses the highest unused trap code (traps 32 and
+ * above are used by real hardware interrupts).  Seventeen hypercalls are
+ * available: the hypercall number is put in the %eax register, and the
+ * arguments (when required) are placed in %ebx, %ecx, %edx and %esi.
+ * If a return value makes sense, it's returned in %eax.
  *
  * Grossly invalid calls result in Sudden Death at the hands of the vengeful
  * Host, rather than returning failure.  This reflects Winston Churchill's
  * definition of a gentleman: "someone who is only rude intentionally".
-:*/
+ */
+static inline unsigned long
+hcall(unsigned long call,
+      unsigned long arg1, unsigned long arg2, unsigned long arg3,
+      unsigned long arg4)
+{
+       /* "int" is the Intel instruction to trigger a trap. */
+       asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY)
+                    /* The call in %eax (aka "a") might be overwritten */
+                    : "=a"(call)
+                      /* The arguments are in %eax, %ebx, %ecx, %edx & %esi */
+                    : "a"(call), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4)
+                      /* "memory" means this might write somewhere in memory.
+                       * This isn't true for all calls, but it's safe to tell
+                       * gcc that it might happen so it doesn't get clever. */
+                    : "memory");
+       return call;
+}
 
 /* Can't use our min() macro here: needs to be a constant */
 #define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32)
index d8bf23a88d05922c5ccecbf3820f9d816f5b7db7..c82868e9f905f04779778542298ce5560ae2e865 100644 (file)
@@ -105,16 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
 struct device;
 extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
                                 int active_high_low);
-extern int acpi_probe_gsi(void);
-#ifdef CONFIG_X86_IO_APIC
-extern int mp_find_ioapic(int gsi);
-extern int mp_find_ioapic_pin(int ioapic, int gsi);
-#endif
-#else /* !CONFIG_ACPI: */
-static inline int acpi_probe_gsi(void)
-{
-       return 0;
-}
 #endif /* CONFIG_ACPI */
 
 #define PHYSID_ARRAY_SIZE      BITS_TO_LONGS(MAX_APICS)
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
new file mode 100644 (file)
index 0000000..79ce568
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _ASM_X86_MSHYPER_H
+#define _ASM_X86_MSHYPER_H
+
+#include <linux/types.h>
+#include <asm/hyperv.h>
+
+struct ms_hyperv_info {
+       u32 features;
+       u32 hints;
+};
+
+extern struct ms_hyperv_info ms_hyperv;
+
+#endif
index 1cd58cdbc03f2e97dee6983b5a8ea2ebef7d0061..bc473acfa7f97ea52e9800a4afc038d543e84ce2 100644 (file)
 #define MSR_IA32_LASTINTTOIP           0x000001de
 
 /* DEBUGCTLMSR bits (others vary by model): */
-#define _DEBUGCTLMSR_LBR       0 /* last branch recording */
-#define _DEBUGCTLMSR_BTF       1 /* single-step on branches */
-
-#define DEBUGCTLMSR_LBR                (1UL << _DEBUGCTLMSR_LBR)
-#define DEBUGCTLMSR_BTF                (1UL << _DEBUGCTLMSR_BTF)
+#define DEBUGCTLMSR_LBR                        (1UL <<  0) /* last branch recording */
+#define DEBUGCTLMSR_BTF                        (1UL <<  1) /* single-step on branches */
+#define DEBUGCTLMSR_TR                 (1UL <<  6)
+#define DEBUGCTLMSR_BTS                        (1UL <<  7)
+#define DEBUGCTLMSR_BTINT              (1UL <<  8)
+#define DEBUGCTLMSR_BTS_OFF_OS         (1UL <<  9)
+#define DEBUGCTLMSR_BTS_OFF_USR                (1UL << 10)
+#define DEBUGCTLMSR_FREEZE_LBRS_ON_PMI (1UL << 11)
 
 #define MSR_IA32_MC0_CTL               0x00000400
 #define MSR_IA32_MC0_STATUS            0x00000401
 #define MSR_AMD64_PATCH_LEVEL          0x0000008b
 #define MSR_AMD64_NB_CFG               0xc001001f
 #define MSR_AMD64_PATCH_LOADER         0xc0010020
+#define MSR_AMD64_OSVW_ID_LENGTH       0xc0010140
+#define MSR_AMD64_OSVW_STATUS          0xc0010141
 #define MSR_AMD64_IBSFETCHCTL          0xc0011030
 #define MSR_AMD64_IBSFETCHLINAD                0xc0011031
 #define MSR_AMD64_IBSFETCHPHYSAD       0xc0011032
 #define MSR_P4_U2L_ESCR0               0x000003b0
 #define MSR_P4_U2L_ESCR1               0x000003b1
 
+#define MSR_P4_PEBS_MATRIX_VERT                0x000003f2
+
 /* Intel Core-based CPU performance counters */
 #define MSR_CORE_PERF_FIXED_CTR0       0x00000309
 #define MSR_CORE_PERF_FIXED_CTR1       0x0000030a
index 66a272dfd8b8aa0d5fcb788ace9bec17da31e236..0ec6d12d84e68b377909da90f18ec0e3488f4526 100644 (file)
@@ -190,6 +190,29 @@ do {                                                                       \
        pfo_ret__;                                      \
 })
 
+#define percpu_unary_op(op, var)                       \
+({                                                     \
+       switch (sizeof(var)) {                          \
+       case 1:                                         \
+               asm(op "b "__percpu_arg(0)              \
+                   : "+m" (var));                      \
+               break;                                  \
+       case 2:                                         \
+               asm(op "w "__percpu_arg(0)              \
+                   : "+m" (var));                      \
+               break;                                  \
+       case 4:                                         \
+               asm(op "l "__percpu_arg(0)              \
+                   : "+m" (var));                      \
+               break;                                  \
+       case 8:                                         \
+               asm(op "q "__percpu_arg(0)              \
+                   : "+m" (var));                      \
+               break;                                  \
+       default: __bad_percpu_size();                   \
+       }                                               \
+})
+
 /*
  * percpu_read() makes gcc load the percpu variable every time it is
  * accessed while percpu_read_stable() allows the value to be cached.
@@ -207,6 +230,7 @@ do {                                                                        \
 #define percpu_and(var, val)           percpu_to_op("and", var, val)
 #define percpu_or(var, val)            percpu_to_op("or", var, val)
 #define percpu_xor(var, val)           percpu_to_op("xor", var, val)
+#define percpu_inc(var)                percpu_unary_op("inc", var)
 
 #define __this_cpu_read_1(pcp)         percpu_from_op("mov", (pcp), "m"(pcp))
 #define __this_cpu_read_2(pcp)         percpu_from_op("mov", (pcp), "m"(pcp))
index db6109a885a76a6ecd116c59baae0088007ffc45..254883d0c7e088424ed983154613b4ad889435e1 100644 (file)
@@ -5,7 +5,7 @@
  * Performance event hw details:
  */
 
-#define X86_PMC_MAX_GENERIC                                    8
+#define X86_PMC_MAX_GENERIC                                   32
 #define X86_PMC_MAX_FIXED                                      3
 
 #define X86_PMC_IDX_GENERIC                                    0
 #define MSR_ARCH_PERFMON_EVENTSEL0                          0x186
 #define MSR_ARCH_PERFMON_EVENTSEL1                          0x187
 
-#define ARCH_PERFMON_EVENTSEL_ENABLE                     (1 << 22)
-#define ARCH_PERFMON_EVENTSEL_ANY                        (1 << 21)
-#define ARCH_PERFMON_EVENTSEL_INT                        (1 << 20)
-#define ARCH_PERFMON_EVENTSEL_OS                         (1 << 17)
-#define ARCH_PERFMON_EVENTSEL_USR                        (1 << 16)
-
-/*
- * Includes eventsel and unit mask as well:
- */
-
-
-#define INTEL_ARCH_EVTSEL_MASK         0x000000FFULL
-#define INTEL_ARCH_UNIT_MASK           0x0000FF00ULL
-#define INTEL_ARCH_EDGE_MASK           0x00040000ULL
-#define INTEL_ARCH_INV_MASK            0x00800000ULL
-#define INTEL_ARCH_CNT_MASK            0xFF000000ULL
-#define INTEL_ARCH_EVENT_MASK  (INTEL_ARCH_UNIT_MASK|INTEL_ARCH_EVTSEL_MASK)
-
-/*
- * 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 INTEL_ARCH_FIXED_MASK \
-       (INTEL_ARCH_CNT_MASK| \
-        INTEL_ARCH_INV_MASK| \
-        INTEL_ARCH_EDGE_MASK|\
-        INTEL_ARCH_UNIT_MASK|\
-        INTEL_ARCH_EVENT_MASK)
+#define ARCH_PERFMON_EVENTSEL_EVENT                    0x000000FFULL
+#define ARCH_PERFMON_EVENTSEL_UMASK                    0x0000FF00ULL
+#define ARCH_PERFMON_EVENTSEL_USR                      (1ULL << 16)
+#define ARCH_PERFMON_EVENTSEL_OS                       (1ULL << 17)
+#define ARCH_PERFMON_EVENTSEL_EDGE                     (1ULL << 18)
+#define ARCH_PERFMON_EVENTSEL_INT                      (1ULL << 20)
+#define ARCH_PERFMON_EVENTSEL_ANY                      (1ULL << 21)
+#define ARCH_PERFMON_EVENTSEL_ENABLE                   (1ULL << 22)
+#define ARCH_PERFMON_EVENTSEL_INV                      (1ULL << 23)
+#define ARCH_PERFMON_EVENTSEL_CMASK                    0xFF000000ULL
+
+#define AMD64_EVENTSEL_EVENT   \
+       (ARCH_PERFMON_EVENTSEL_EVENT | (0x0FULL << 32))
+#define INTEL_ARCH_EVENT_MASK  \
+       (ARCH_PERFMON_EVENTSEL_UMASK | ARCH_PERFMON_EVENTSEL_EVENT)
+
+#define X86_RAW_EVENT_MASK             \
+       (ARCH_PERFMON_EVENTSEL_EVENT |  \
+        ARCH_PERFMON_EVENTSEL_UMASK |  \
+        ARCH_PERFMON_EVENTSEL_EDGE  |  \
+        ARCH_PERFMON_EVENTSEL_INV   |  \
+        ARCH_PERFMON_EVENTSEL_CMASK)
+#define AMD64_RAW_EVENT_MASK           \
+       (X86_RAW_EVENT_MASK          |  \
+        AMD64_EVENTSEL_EVENT)
 
 #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL                0x3c
 #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK                (0x00 << 8)
@@ -67,7 +59,7 @@
 union cpuid10_eax {
        struct {
                unsigned int version_id:8;
-               unsigned int num_events:8;
+               unsigned int num_counters:8;
                unsigned int bit_width:8;
                unsigned int mask_length:8;
        } split;
@@ -76,7 +68,7 @@ union cpuid10_eax {
 
 union cpuid10_edx {
        struct {
-               unsigned int num_events_fixed:4;
+               unsigned int num_counters_fixed:4;
                unsigned int reserved:28;
        } split;
        unsigned int full;
@@ -136,6 +128,18 @@ extern void perf_events_lapic_init(void);
 
 #define PERF_EVENT_INDEX_OFFSET                        0
 
+/*
+ * Abuse bit 3 of the cpu eflags register to indicate proper PEBS IP fixups.
+ * This flag is otherwise unused and ABI specified to be 0, so nobody should
+ * care what we do with it.
+ */
+#define PERF_EFLAGS_EXACT      (1UL << 3)
+
+struct pt_regs;
+extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
+extern unsigned long perf_misc_flags(struct pt_regs *regs);
+#define perf_misc_flags(regs)  perf_misc_flags(regs)
+
 #else
 static inline void init_hw_perf_events(void)           { }
 static inline void perf_events_lapic_init(void)        { }
diff --git a/arch/x86/include/asm/perf_event_p4.h b/arch/x86/include/asm/perf_event_p4.h
new file mode 100644 (file)
index 0000000..b05400a
--- /dev/null
@@ -0,0 +1,794 @@
+/*
+ * Netburst Perfomance Events (P4, old Xeon)
+ */
+
+#ifndef PERF_EVENT_P4_H
+#define PERF_EVENT_P4_H
+
+#include <linux/cpu.h>
+#include <linux/bitops.h>
+
+/*
+ * NetBurst has perfomance MSRs shared between
+ * threads if HT is turned on, ie for both logical
+ * processors (mem: in turn in Atom with HT support
+ * perf-MSRs are not shared and every thread has its
+ * own perf-MSRs set)
+ */
+#define ARCH_P4_TOTAL_ESCR     (46)
+#define ARCH_P4_RESERVED_ESCR  (2) /* IQ_ESCR(0,1) not always present */
+#define ARCH_P4_MAX_ESCR       (ARCH_P4_TOTAL_ESCR - ARCH_P4_RESERVED_ESCR)
+#define ARCH_P4_MAX_CCCR       (18)
+#define ARCH_P4_MAX_COUNTER    (ARCH_P4_MAX_CCCR / 2)
+
+#define P4_ESCR_EVENT_MASK     0x7e000000U
+#define P4_ESCR_EVENT_SHIFT    25
+#define P4_ESCR_EVENTMASK_MASK 0x01fffe00U
+#define P4_ESCR_EVENTMASK_SHIFT        9
+#define P4_ESCR_TAG_MASK       0x000001e0U
+#define P4_ESCR_TAG_SHIFT      5
+#define P4_ESCR_TAG_ENABLE     0x00000010U
+#define P4_ESCR_T0_OS          0x00000008U
+#define P4_ESCR_T0_USR         0x00000004U
+#define P4_ESCR_T1_OS          0x00000002U
+#define P4_ESCR_T1_USR         0x00000001U
+
+#define P4_ESCR_EVENT(v)       ((v) << P4_ESCR_EVENT_SHIFT)
+#define P4_ESCR_EMASK(v)       ((v) << P4_ESCR_EVENTMASK_SHIFT)
+#define P4_ESCR_TAG(v)         ((v) << P4_ESCR_TAG_SHIFT)
+
+/* Non HT mask */
+#define P4_ESCR_MASK                   \
+       (P4_ESCR_EVENT_MASK     |       \
+       P4_ESCR_EVENTMASK_MASK  |       \
+       P4_ESCR_TAG_MASK        |       \
+       P4_ESCR_TAG_ENABLE      |       \
+       P4_ESCR_T0_OS           |       \
+       P4_ESCR_T0_USR)
+
+/* HT mask */
+#define P4_ESCR_MASK_HT                        \
+       (P4_ESCR_MASK | P4_ESCR_T1_OS | P4_ESCR_T1_USR)
+
+#define P4_CCCR_OVF                    0x80000000U
+#define P4_CCCR_CASCADE                        0x40000000U
+#define P4_CCCR_OVF_PMI_T0             0x04000000U
+#define P4_CCCR_OVF_PMI_T1             0x08000000U
+#define P4_CCCR_FORCE_OVF              0x02000000U
+#define P4_CCCR_EDGE                   0x01000000U
+#define P4_CCCR_THRESHOLD_MASK         0x00f00000U
+#define P4_CCCR_THRESHOLD_SHIFT                20
+#define P4_CCCR_COMPLEMENT             0x00080000U
+#define P4_CCCR_COMPARE                        0x00040000U
+#define P4_CCCR_ESCR_SELECT_MASK       0x0000e000U
+#define P4_CCCR_ESCR_SELECT_SHIFT      13
+#define P4_CCCR_ENABLE                 0x00001000U
+#define P4_CCCR_THREAD_SINGLE          0x00010000U
+#define P4_CCCR_THREAD_BOTH            0x00020000U
+#define P4_CCCR_THREAD_ANY             0x00030000U
+#define P4_CCCR_RESERVED               0x00000fffU
+
+#define P4_CCCR_THRESHOLD(v)           ((v) << P4_CCCR_THRESHOLD_SHIFT)
+#define P4_CCCR_ESEL(v)                        ((v) << P4_CCCR_ESCR_SELECT_SHIFT)
+
+/* Custom bits in reerved CCCR area */
+#define P4_CCCR_CACHE_OPS_MASK         0x0000003fU
+
+
+/* Non HT mask */
+#define P4_CCCR_MASK                           \
+       (P4_CCCR_OVF                    |       \
+       P4_CCCR_CASCADE                 |       \
+       P4_CCCR_OVF_PMI_T0              |       \
+       P4_CCCR_FORCE_OVF               |       \
+       P4_CCCR_EDGE                    |       \
+       P4_CCCR_THRESHOLD_MASK          |       \
+       P4_CCCR_COMPLEMENT              |       \
+       P4_CCCR_COMPARE                 |       \
+       P4_CCCR_ESCR_SELECT_MASK        |       \
+       P4_CCCR_ENABLE)
+
+/* HT mask */
+#define P4_CCCR_MASK_HT        (P4_CCCR_MASK | P4_CCCR_THREAD_ANY)
+
+#define P4_GEN_ESCR_EMASK(class, name, bit)    \
+       class##__##name = ((1 << bit) << P4_ESCR_EVENTMASK_SHIFT)
+#define P4_ESCR_EMASK_BIT(class, name)         class##__##name
+
+/*
+ * config field is 64bit width and consists of
+ * HT << 63 | ESCR << 32 | CCCR
+ * where HT is HyperThreading bit (since ESCR
+ * has it reserved we may use it for own purpose)
+ *
+ * note that this is NOT the addresses of respective
+ * ESCR and CCCR but rather an only packed value should
+ * be unpacked and written to a proper addresses
+ *
+ * the base idea is to pack as much info as
+ * possible
+ */
+#define p4_config_pack_escr(v)         (((u64)(v)) << 32)
+#define p4_config_pack_cccr(v)         (((u64)(v)) & 0xffffffffULL)
+#define p4_config_unpack_escr(v)       (((u64)(v)) >> 32)
+#define p4_config_unpack_cccr(v)       (((u64)(v)) & 0xffffffffULL)
+
+#define p4_config_unpack_emask(v)                      \
+       ({                                              \
+               u32 t = p4_config_unpack_escr((v));     \
+               t = t &  P4_ESCR_EVENTMASK_MASK;        \
+               t = t >> P4_ESCR_EVENTMASK_SHIFT;       \
+               t;                                      \
+       })
+
+#define p4_config_unpack_event(v)                      \
+       ({                                              \
+               u32 t = p4_config_unpack_escr((v));     \
+               t = t &  P4_ESCR_EVENT_MASK;            \
+               t = t >> P4_ESCR_EVENT_SHIFT;           \
+               t;                                      \
+       })
+
+#define p4_config_unpack_cache_event(v)        (((u64)(v)) & P4_CCCR_CACHE_OPS_MASK)
+
+#define P4_CONFIG_HT_SHIFT             63
+#define P4_CONFIG_HT                   (1ULL << P4_CONFIG_HT_SHIFT)
+
+static inline bool p4_is_event_cascaded(u64 config)
+{
+       u32 cccr = p4_config_unpack_cccr(config);
+       return !!(cccr & P4_CCCR_CASCADE);
+}
+
+static inline int p4_ht_config_thread(u64 config)
+{
+       return !!(config & P4_CONFIG_HT);
+}
+
+static inline u64 p4_set_ht_bit(u64 config)
+{
+       return config | P4_CONFIG_HT;
+}
+
+static inline u64 p4_clear_ht_bit(u64 config)
+{
+       return config & ~P4_CONFIG_HT;
+}
+
+static inline int p4_ht_active(void)
+{
+#ifdef CONFIG_SMP
+       return smp_num_siblings > 1;
+#endif
+       return 0;
+}
+
+static inline int p4_ht_thread(int cpu)
+{
+#ifdef CONFIG_SMP
+       if (smp_num_siblings == 2)
+               return cpu != cpumask_first(__get_cpu_var(cpu_sibling_map));
+#endif
+       return 0;
+}
+
+static inline int p4_should_swap_ts(u64 config, int cpu)
+{
+       return p4_ht_config_thread(config) ^ p4_ht_thread(cpu);
+}
+
+static inline u32 p4_default_cccr_conf(int cpu)
+{
+       /*
+        * Note that P4_CCCR_THREAD_ANY is "required" on
+        * non-HT machines (on HT machines we count TS events
+        * regardless the state of second logical processor
+        */
+       u32 cccr = P4_CCCR_THREAD_ANY;
+
+       if (!p4_ht_thread(cpu))
+               cccr |= P4_CCCR_OVF_PMI_T0;
+       else
+               cccr |= P4_CCCR_OVF_PMI_T1;
+
+       return cccr;
+}
+
+static inline u32 p4_default_escr_conf(int cpu, int exclude_os, int exclude_usr)
+{
+       u32 escr = 0;
+
+       if (!p4_ht_thread(cpu)) {
+               if (!exclude_os)
+                       escr |= P4_ESCR_T0_OS;
+               if (!exclude_usr)
+                       escr |= P4_ESCR_T0_USR;
+       } else {
+               if (!exclude_os)
+                       escr |= P4_ESCR_T1_OS;
+               if (!exclude_usr)
+                       escr |= P4_ESCR_T1_USR;
+       }
+
+       return escr;
+}
+
+enum P4_EVENTS {
+       P4_EVENT_TC_DELIVER_MODE,
+       P4_EVENT_BPU_FETCH_REQUEST,
+       P4_EVENT_ITLB_REFERENCE,
+       P4_EVENT_MEMORY_CANCEL,
+       P4_EVENT_MEMORY_COMPLETE,
+       P4_EVENT_LOAD_PORT_REPLAY,
+       P4_EVENT_STORE_PORT_REPLAY,
+       P4_EVENT_MOB_LOAD_REPLAY,
+       P4_EVENT_PAGE_WALK_TYPE,
+       P4_EVENT_BSQ_CACHE_REFERENCE,
+       P4_EVENT_IOQ_ALLOCATION,
+       P4_EVENT_IOQ_ACTIVE_ENTRIES,
+       P4_EVENT_FSB_DATA_ACTIVITY,
+       P4_EVENT_BSQ_ALLOCATION,
+       P4_EVENT_BSQ_ACTIVE_ENTRIES,
+       P4_EVENT_SSE_INPUT_ASSIST,
+       P4_EVENT_PACKED_SP_UOP,
+       P4_EVENT_PACKED_DP_UOP,
+       P4_EVENT_SCALAR_SP_UOP,
+       P4_EVENT_SCALAR_DP_UOP,
+       P4_EVENT_64BIT_MMX_UOP,
+       P4_EVENT_128BIT_MMX_UOP,
+       P4_EVENT_X87_FP_UOP,
+       P4_EVENT_TC_MISC,
+       P4_EVENT_GLOBAL_POWER_EVENTS,
+       P4_EVENT_TC_MS_XFER,
+       P4_EVENT_UOP_QUEUE_WRITES,
+       P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE,
+       P4_EVENT_RETIRED_BRANCH_TYPE,
+       P4_EVENT_RESOURCE_STALL,
+       P4_EVENT_WC_BUFFER,
+       P4_EVENT_B2B_CYCLES,
+       P4_EVENT_BNR,
+       P4_EVENT_SNOOP,
+       P4_EVENT_RESPONSE,
+       P4_EVENT_FRONT_END_EVENT,
+       P4_EVENT_EXECUTION_EVENT,
+       P4_EVENT_REPLAY_EVENT,
+       P4_EVENT_INSTR_RETIRED,
+       P4_EVENT_UOPS_RETIRED,
+       P4_EVENT_UOP_TYPE,
+       P4_EVENT_BRANCH_RETIRED,
+       P4_EVENT_MISPRED_BRANCH_RETIRED,
+       P4_EVENT_X87_ASSIST,
+       P4_EVENT_MACHINE_CLEAR,
+       P4_EVENT_INSTR_COMPLETED,
+};
+
+#define P4_OPCODE(event)               event##_OPCODE
+#define P4_OPCODE_ESEL(opcode)         ((opcode & 0x00ff) >> 0)
+#define P4_OPCODE_EVNT(opcode)         ((opcode & 0xff00) >> 8)
+#define P4_OPCODE_PACK(event, sel)     (((event) << 8) | sel)
+
+/*
+ * Comments below the event represent ESCR restriction
+ * for this event and counter index per ESCR
+ *
+ * MSR_P4_IQ_ESCR0 and MSR_P4_IQ_ESCR1 are available only on early
+ * processor builds (family 0FH, models 01H-02H). These MSRs
+ * are not available on later versions, so that we don't use
+ * them completely
+ *
+ * Also note that CCCR1 do not have P4_CCCR_ENABLE bit properly
+ * working so that we should not use this CCCR and respective
+ * counter as result
+ */
+enum P4_EVENT_OPCODES {
+       P4_OPCODE(P4_EVENT_TC_DELIVER_MODE)             = P4_OPCODE_PACK(0x01, 0x01),
+       /*
+        * MSR_P4_TC_ESCR0:     4, 5
+        * MSR_P4_TC_ESCR1:     6, 7
+        */
+
+       P4_OPCODE(P4_EVENT_BPU_FETCH_REQUEST)           = P4_OPCODE_PACK(0x03, 0x00),
+       /*
+        * MSR_P4_BPU_ESCR0:    0, 1
+        * MSR_P4_BPU_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_ITLB_REFERENCE)              = P4_OPCODE_PACK(0x18, 0x03),
+       /*
+        * MSR_P4_ITLB_ESCR0:   0, 1
+        * MSR_P4_ITLB_ESCR1:   2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_MEMORY_CANCEL)               = P4_OPCODE_PACK(0x02, 0x05),
+       /*
+        * MSR_P4_DAC_ESCR0:    8, 9
+        * MSR_P4_DAC_ESCR1:    10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_MEMORY_COMPLETE)             = P4_OPCODE_PACK(0x08, 0x02),
+       /*
+        * MSR_P4_SAAT_ESCR0:   8, 9
+        * MSR_P4_SAAT_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_LOAD_PORT_REPLAY)            = P4_OPCODE_PACK(0x04, 0x02),
+       /*
+        * MSR_P4_SAAT_ESCR0:   8, 9
+        * MSR_P4_SAAT_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_STORE_PORT_REPLAY)           = P4_OPCODE_PACK(0x05, 0x02),
+       /*
+        * MSR_P4_SAAT_ESCR0:   8, 9
+        * MSR_P4_SAAT_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_MOB_LOAD_REPLAY)             = P4_OPCODE_PACK(0x03, 0x02),
+       /*
+        * MSR_P4_MOB_ESCR0:    0, 1
+        * MSR_P4_MOB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_PAGE_WALK_TYPE)              = P4_OPCODE_PACK(0x01, 0x04),
+       /*
+        * MSR_P4_PMH_ESCR0:    0, 1
+        * MSR_P4_PMH_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_BSQ_CACHE_REFERENCE)         = P4_OPCODE_PACK(0x0c, 0x07),
+       /*
+        * MSR_P4_BSU_ESCR0:    0, 1
+        * MSR_P4_BSU_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_IOQ_ALLOCATION)              = P4_OPCODE_PACK(0x03, 0x06),
+       /*
+        * MSR_P4_FSB_ESCR0:    0, 1
+        * MSR_P4_FSB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_IOQ_ACTIVE_ENTRIES)          = P4_OPCODE_PACK(0x1a, 0x06),
+       /*
+        * MSR_P4_FSB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_FSB_DATA_ACTIVITY)           = P4_OPCODE_PACK(0x17, 0x06),
+       /*
+        * MSR_P4_FSB_ESCR0:    0, 1
+        * MSR_P4_FSB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_BSQ_ALLOCATION)              = P4_OPCODE_PACK(0x05, 0x07),
+       /*
+        * MSR_P4_BSU_ESCR0:    0, 1
+        */
+
+       P4_OPCODE(P4_EVENT_BSQ_ACTIVE_ENTRIES)          = P4_OPCODE_PACK(0x06, 0x07),
+       /*
+        * NOTE: no ESCR name in docs, it's guessed
+        * MSR_P4_BSU_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_SSE_INPUT_ASSIST)            = P4_OPCODE_PACK(0x34, 0x01),
+       /*
+        * MSR_P4_FIRM_ESCR0:   8, 9
+        * MSR_P4_FIRM_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_PACKED_SP_UOP)               = P4_OPCODE_PACK(0x08, 0x01),
+       /*
+        * MSR_P4_FIRM_ESCR0:   8, 9
+        * MSR_P4_FIRM_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_PACKED_DP_UOP)               = P4_OPCODE_PACK(0x0c, 0x01),
+       /*
+        * MSR_P4_FIRM_ESCR0:   8, 9
+        * MSR_P4_FIRM_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_SCALAR_SP_UOP)               = P4_OPCODE_PACK(0x0a, 0x01),
+       /*
+        * MSR_P4_FIRM_ESCR0:   8, 9
+        * MSR_P4_FIRM_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_SCALAR_DP_UOP)               = P4_OPCODE_PACK(0x0e, 0x01),
+       /*
+        * MSR_P4_FIRM_ESCR0:   8, 9
+        * MSR_P4_FIRM_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_64BIT_MMX_UOP)               = P4_OPCODE_PACK(0x02, 0x01),
+       /*
+        * MSR_P4_FIRM_ESCR0:   8, 9
+        * MSR_P4_FIRM_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_128BIT_MMX_UOP)              = P4_OPCODE_PACK(0x1a, 0x01),
+       /*
+        * MSR_P4_FIRM_ESCR0:   8, 9
+        * MSR_P4_FIRM_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_X87_FP_UOP)                  = P4_OPCODE_PACK(0x04, 0x01),
+       /*
+        * MSR_P4_FIRM_ESCR0:   8, 9
+        * MSR_P4_FIRM_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_TC_MISC)                     = P4_OPCODE_PACK(0x06, 0x01),
+       /*
+        * MSR_P4_TC_ESCR0:     4, 5
+        * MSR_P4_TC_ESCR1:     6, 7
+        */
+
+       P4_OPCODE(P4_EVENT_GLOBAL_POWER_EVENTS)         = P4_OPCODE_PACK(0x13, 0x06),
+       /*
+        * MSR_P4_FSB_ESCR0:    0, 1
+        * MSR_P4_FSB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_TC_MS_XFER)                  = P4_OPCODE_PACK(0x05, 0x00),
+       /*
+        * MSR_P4_MS_ESCR0:     4, 5
+        * MSR_P4_MS_ESCR1:     6, 7
+        */
+
+       P4_OPCODE(P4_EVENT_UOP_QUEUE_WRITES)            = P4_OPCODE_PACK(0x09, 0x00),
+       /*
+        * MSR_P4_MS_ESCR0:     4, 5
+        * MSR_P4_MS_ESCR1:     6, 7
+        */
+
+       P4_OPCODE(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE) = P4_OPCODE_PACK(0x05, 0x02),
+       /*
+        * MSR_P4_TBPU_ESCR0:   4, 5
+        * MSR_P4_TBPU_ESCR1:   6, 7
+        */
+
+       P4_OPCODE(P4_EVENT_RETIRED_BRANCH_TYPE)         = P4_OPCODE_PACK(0x04, 0x02),
+       /*
+        * MSR_P4_TBPU_ESCR0:   4, 5
+        * MSR_P4_TBPU_ESCR1:   6, 7
+        */
+
+       P4_OPCODE(P4_EVENT_RESOURCE_STALL)              = P4_OPCODE_PACK(0x01, 0x01),
+       /*
+        * MSR_P4_ALF_ESCR0:    12, 13, 16
+        * MSR_P4_ALF_ESCR1:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_WC_BUFFER)                   = P4_OPCODE_PACK(0x05, 0x05),
+       /*
+        * MSR_P4_DAC_ESCR0:    8, 9
+        * MSR_P4_DAC_ESCR1:    10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_B2B_CYCLES)                  = P4_OPCODE_PACK(0x16, 0x03),
+       /*
+        * MSR_P4_FSB_ESCR0:    0, 1
+        * MSR_P4_FSB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_BNR)                         = P4_OPCODE_PACK(0x08, 0x03),
+       /*
+        * MSR_P4_FSB_ESCR0:    0, 1
+        * MSR_P4_FSB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_SNOOP)                       = P4_OPCODE_PACK(0x06, 0x03),
+       /*
+        * MSR_P4_FSB_ESCR0:    0, 1
+        * MSR_P4_FSB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_RESPONSE)                    = P4_OPCODE_PACK(0x04, 0x03),
+       /*
+        * MSR_P4_FSB_ESCR0:    0, 1
+        * MSR_P4_FSB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_FRONT_END_EVENT)             = P4_OPCODE_PACK(0x08, 0x05),
+       /*
+        * MSR_P4_CRU_ESCR2:    12, 13, 16
+        * MSR_P4_CRU_ESCR3:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_EXECUTION_EVENT)             = P4_OPCODE_PACK(0x0c, 0x05),
+       /*
+        * MSR_P4_CRU_ESCR2:    12, 13, 16
+        * MSR_P4_CRU_ESCR3:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_REPLAY_EVENT)                = P4_OPCODE_PACK(0x09, 0x05),
+       /*
+        * MSR_P4_CRU_ESCR2:    12, 13, 16
+        * MSR_P4_CRU_ESCR3:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_INSTR_RETIRED)               = P4_OPCODE_PACK(0x02, 0x04),
+       /*
+        * MSR_P4_CRU_ESCR0:    12, 13, 16
+        * MSR_P4_CRU_ESCR1:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_UOPS_RETIRED)                = P4_OPCODE_PACK(0x01, 0x04),
+       /*
+        * MSR_P4_CRU_ESCR0:    12, 13, 16
+        * MSR_P4_CRU_ESCR1:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_UOP_TYPE)                    = P4_OPCODE_PACK(0x02, 0x02),
+       /*
+        * MSR_P4_RAT_ESCR0:    12, 13, 16
+        * MSR_P4_RAT_ESCR1:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_BRANCH_RETIRED)              = P4_OPCODE_PACK(0x06, 0x05),
+       /*
+        * MSR_P4_CRU_ESCR2:    12, 13, 16
+        * MSR_P4_CRU_ESCR3:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_MISPRED_BRANCH_RETIRED)      = P4_OPCODE_PACK(0x03, 0x04),
+       /*
+        * MSR_P4_CRU_ESCR0:    12, 13, 16
+        * MSR_P4_CRU_ESCR1:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_X87_ASSIST)                  = P4_OPCODE_PACK(0x03, 0x05),
+       /*
+        * MSR_P4_CRU_ESCR2:    12, 13, 16
+        * MSR_P4_CRU_ESCR3:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_MACHINE_CLEAR)               = P4_OPCODE_PACK(0x02, 0x05),
+       /*
+        * MSR_P4_CRU_ESCR2:    12, 13, 16
+        * MSR_P4_CRU_ESCR3:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_INSTR_COMPLETED)             = P4_OPCODE_PACK(0x07, 0x04),
+       /*
+        * MSR_P4_CRU_ESCR0:    12, 13, 16
+        * MSR_P4_CRU_ESCR1:    14, 15, 17
+        */
+};
+
+/*
+ * a caller should use P4_ESCR_EMASK_NAME helper to
+ * pick the EventMask needed, for example
+ *
+ *     P4_ESCR_EMASK_NAME(P4_EVENT_TC_DELIVER_MODE, DD)
+ */
+enum P4_ESCR_EMASKS {
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, DD, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, DB, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, DI, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, BD, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, BB, 4),
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, BI, 5),
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, ID, 6),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_BPU_FETCH_REQUEST, TCMISS, 0),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_ITLB_REFERENCE, HIT, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_ITLB_REFERENCE, MISS, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_ITLB_REFERENCE, HIT_UK, 2),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_MEMORY_CANCEL, ST_RB_FULL, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_MEMORY_CANCEL, 64K_CONF, 3),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_MEMORY_COMPLETE, LSC, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_MEMORY_COMPLETE, SSC, 1),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_LOAD_PORT_REPLAY, SPLIT_LD, 1),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_STORE_PORT_REPLAY, SPLIT_ST, 1),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_MOB_LOAD_REPLAY, NO_STA, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_MOB_LOAD_REPLAY, NO_STD, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_MOB_LOAD_REPLAY, PARTIAL_DATA, 4),
+       P4_GEN_ESCR_EMASK(P4_EVENT_MOB_LOAD_REPLAY, UNALGN_ADDR, 5),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_PAGE_WALK_TYPE, DTMISS, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_PAGE_WALK_TYPE, ITMISS, 1),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE, 4),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM, 5),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS, 8),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS, 9),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS, 10),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, DEFAULT, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, ALL_READ, 5),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, ALL_WRITE, 6),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_UC, 7),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_WC, 8),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_WT, 9),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_WP, 10),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_WB, 11),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, OWN, 13),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, OTHER, 14),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, PREFETCH, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, DEFAULT, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_READ, 5),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_WRITE, 6),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_UC, 7),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WC, 8),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WT, 9),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WP, 10),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WB, 11),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, OWN, 13),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, OTHER, 14),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, PREFETCH, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OTHER, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_DRV, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OWN, 4),
+       P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OTHER, 5),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE0, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE1, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_LEN0, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_LEN1, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_IO_TYPE, 5),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_LOCK_TYPE, 6),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_CACHE_TYPE, 7),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_SPLIT_TYPE, 8),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_DEM_TYPE, 9),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_ORD_TYPE, 10),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE0, 11),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE1, 12),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE2, 13),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE0, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE1, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN0, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN1, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_IO_TYPE, 5),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LOCK_TYPE, 6),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_CACHE_TYPE, 7),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_SPLIT_TYPE, 8),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_DEM_TYPE, 9),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_ORD_TYPE, 10),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE0, 11),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE1, 12),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE2, 13),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_SSE_INPUT_ASSIST, ALL, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_PACKED_SP_UOP, ALL, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_PACKED_DP_UOP, ALL, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_SCALAR_SP_UOP, ALL, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_SCALAR_DP_UOP, ALL, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_64BIT_MMX_UOP, ALL, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_128BIT_MMX_UOP, ALL, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_X87_FP_UOP, ALL, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_MISC, FLUSH, 4),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING, 0),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_MS_XFER, CISC, 0),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_BUILD, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_DELIVER, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_UOP_QUEUE_WRITES, FROM_ROM, 2),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CONDITIONAL, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CALL, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, RETURN, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, INDIRECT, 4),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_BRANCH_TYPE, CALL, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT, 4),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_RESOURCE_STALL, SBFULL, 5),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_WC_BUFFER, WCB_EVICTS, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_WC_BUFFER, WCB_FULL_EVICTS, 1),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_FRONT_END_EVENT, NBOGUS, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_FRONT_END_EVENT, BOGUS, 1),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, NBOGUS0, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, NBOGUS1, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, NBOGUS2, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, NBOGUS3, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, BOGUS0, 4),
+       P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, BOGUS1, 5),
+       P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, BOGUS2, 6),
+       P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, BOGUS3, 7),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_REPLAY_EVENT, NBOGUS, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_REPLAY_EVENT, BOGUS, 1),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_RETIRED, NBOGUSTAG, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_RETIRED, BOGUSNTAG, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_RETIRED, BOGUSTAG, 3),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_UOPS_RETIRED, NBOGUS, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_UOPS_RETIRED, BOGUS, 1),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_UOP_TYPE, TAGLOADS, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_UOP_TYPE, TAGSTORES, 2),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_BRANCH_RETIRED, MMNP, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BRANCH_RETIRED, MMNM, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BRANCH_RETIRED, MMTP, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BRANCH_RETIRED, MMTM, 3),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS, 0),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, FPSU, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, FPSO, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, POAO, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, POAU, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, PREA, 4),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_MACHINE_CLEAR, CLEAR, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_MACHINE_CLEAR, MOCLEAR, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_MACHINE_CLEAR, SMCLEAR, 2),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_COMPLETED, NBOGUS, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_COMPLETED, BOGUS, 1),
+};
+
+/* P4 PEBS: stale for a while */
+#define P4_PEBS_METRIC_MASK    0x00001fffU
+#define P4_PEBS_UOB_TAG                0x01000000U
+#define P4_PEBS_ENABLE         0x02000000U
+
+/* Replay metrics for MSR_IA32_PEBS_ENABLE and MSR_P4_PEBS_MATRIX_VERT */
+#define P4_PEBS__1stl_cache_load_miss_retired  0x3000001
+#define P4_PEBS__2ndl_cache_load_miss_retired  0x3000002
+#define P4_PEBS__dtlb_load_miss_retired                0x3000004
+#define P4_PEBS__dtlb_store_miss_retired       0x3000004
+#define P4_PEBS__dtlb_all_miss_retired         0x3000004
+#define P4_PEBS__tagged_mispred_branch         0x3018000
+#define P4_PEBS__mob_load_replay_retired       0x3000200
+#define P4_PEBS__split_load_retired            0x3000400
+#define P4_PEBS__split_store_retired           0x3000400
+
+#define P4_VERT__1stl_cache_load_miss_retired  0x0000001
+#define P4_VERT__2ndl_cache_load_miss_retired  0x0000001
+#define P4_VERT__dtlb_load_miss_retired                0x0000001
+#define P4_VERT__dtlb_store_miss_retired       0x0000002
+#define P4_VERT__dtlb_all_miss_retired         0x0000003
+#define P4_VERT__tagged_mispred_branch         0x0000010
+#define P4_VERT__mob_load_replay_retired       0x0000001
+#define P4_VERT__split_load_retired            0x0000001
+#define P4_VERT__split_store_retired           0x0000002
+
+enum P4_CACHE_EVENTS {
+       P4_CACHE__NONE,
+
+       P4_CACHE__1stl_cache_load_miss_retired,
+       P4_CACHE__2ndl_cache_load_miss_retired,
+       P4_CACHE__dtlb_load_miss_retired,
+       P4_CACHE__dtlb_store_miss_retired,
+       P4_CACHE__itlb_reference_hit,
+       P4_CACHE__itlb_reference_miss,
+
+       P4_CACHE__MAX
+};
+
+#endif /* PERF_EVENT_P4_H */
index 47339a1ac7b6607306a1157ad984ba4b86f14108..2984a25ff383d5db7a3dffac2d38dca3f9628d69 100644 (file)
@@ -19,7 +19,6 @@
 #include <asm/paravirt.h>
 
 #include <linux/bitops.h>
-#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
 
index b753ea59703a114f056b32d9b1455622d7b131a9..5a51379dcbe4a7c3dab91a157f752d4c58889117 100644 (file)
@@ -21,7 +21,6 @@ struct mm_struct;
 #include <asm/msr.h>
 #include <asm/desc_defs.h>
 #include <asm/nops.h>
-#include <asm/ds.h>
 
 #include <linux/personality.h>
 #include <linux/cpumask.h>
@@ -29,6 +28,7 @@ struct mm_struct;
 #include <linux/threads.h>
 #include <linux/math64.h>
 #include <linux/init.h>
+#include <linux/err.h>
 
 #define HBP_NUM 4
 /*
@@ -113,7 +113,6 @@ struct cpuinfo_x86 {
        /* Index into per_cpu list: */
        u16                     cpu_index;
 #endif
-       unsigned int            x86_hyper_vendor;
 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
 
 #define X86_VENDOR_INTEL       0
@@ -127,9 +126,6 @@ struct cpuinfo_x86 {
 
 #define X86_VENDOR_UNKNOWN     0xff
 
-#define X86_HYPER_VENDOR_NONE  0
-#define X86_HYPER_VENDOR_VMWARE 1
-
 /*
  * capabilities of CPUs
  */
@@ -380,6 +376,10 @@ union thread_xstate {
        struct xsave_struct             xsave;
 };
 
+struct fpu {
+       union thread_xstate *state;
+};
+
 #ifdef CONFIG_X86_64
 DECLARE_PER_CPU(struct orig_ist, orig_ist);
 
@@ -457,7 +457,7 @@ struct thread_struct {
        unsigned long           trap_no;
        unsigned long           error_code;
        /* floating point and extended processor state */
-       union thread_xstate     *xstate;
+       struct fpu              fpu;
 #ifdef CONFIG_X86_32
        /* Virtual 86 mode info */
        struct vm86_struct __user *vm86_info;
@@ -473,10 +473,6 @@ struct thread_struct {
        unsigned long           iopl;
        /* Max allowed port in the bitmap, in bytes: */
        unsigned                io_bitmap_max;
-/* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set.  */
-       unsigned long   debugctlmsr;
-       /* Debug Store context; see asm/ds.h */
-       struct ds_context       *ds_ctx;
 };
 
 static inline unsigned long native_get_debugreg(int regno)
@@ -803,7 +799,7 @@ extern void cpu_init(void);
 
 static inline unsigned long get_debugctlmsr(void)
 {
-    unsigned long debugctlmsr = 0;
+       unsigned long debugctlmsr = 0;
 
 #ifndef CONFIG_X86_DEBUGCTLMSR
        if (boot_cpu_data.x86 < 6)
@@ -811,21 +807,6 @@ static inline unsigned long get_debugctlmsr(void)
 #endif
        rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
 
-    return debugctlmsr;
-}
-
-static inline unsigned long get_debugctlmsr_on_cpu(int cpu)
-{
-       u64 debugctlmsr = 0;
-       u32 val1, val2;
-
-#ifndef CONFIG_X86_DEBUGCTLMSR
-       if (boot_cpu_data.x86 < 6)
-               return 0;
-#endif
-       rdmsr_on_cpu(cpu, MSR_IA32_DEBUGCTLMSR, &val1, &val2);
-       debugctlmsr = val1 | ((u64)val2 << 32);
-
        return debugctlmsr;
 }
 
@@ -838,18 +819,6 @@ static inline void update_debugctlmsr(unsigned long debugctlmsr)
        wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
 }
 
-static inline void update_debugctlmsr_on_cpu(int cpu,
-                                            unsigned long debugctlmsr)
-{
-#ifndef CONFIG_X86_DEBUGCTLMSR
-       if (boot_cpu_data.x86 < 6)
-               return;
-#endif
-       wrmsr_on_cpu(cpu, MSR_IA32_DEBUGCTLMSR,
-                    (u32)((u64)debugctlmsr),
-                    (u32)((u64)debugctlmsr >> 32));
-}
-
 /*
  * from system description table in BIOS. Mostly for MCA use, but
  * others may find it useful:
index 86723035a5150ea3016a7d3fd18b0192bdbd0a3a..52b098a6eebbfa8b72d4e4b90fdecff89af3af40 100644 (file)
 
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
-
-/* configuration/status structure used in PTRACE_BTS_CONFIG and
-   PTRACE_BTS_STATUS commands.
-*/
-struct ptrace_bts_config {
-       /* requested or actual size of BTS buffer in bytes */
-       __u32 size;
-       /* bitmask of below flags */
-       __u32 flags;
-       /* buffer overflow signal */
-       __u32 signal;
-       /* actual size of bts_struct in bytes */
-       __u32 bts_size;
-};
-#endif /* __ASSEMBLY__ */
-
-#define PTRACE_BTS_O_TRACE     0x1 /* branch trace */
-#define PTRACE_BTS_O_SCHED     0x2 /* scheduling events w/ jiffies */
-#define PTRACE_BTS_O_SIGNAL     0x4 /* send SIG<signal> on buffer overflow
-                                      instead of wrapping around */
-#define PTRACE_BTS_O_ALLOC     0x8 /* (re)allocate buffer */
-
-#define PTRACE_BTS_CONFIG      40
-/* Configure branch trace recording.
-   ADDR points to a struct ptrace_bts_config.
-   DATA gives the size of that buffer.
-   A new buffer is allocated, if requested in the flags.
-   An overflow signal may only be requested for new buffers.
-   Returns the number of bytes read.
-*/
-#define PTRACE_BTS_STATUS      41
-/* Return the current configuration in a struct ptrace_bts_config
-   pointed to by ADDR; DATA gives the size of that buffer.
-   Returns the number of bytes written.
-*/
-#define PTRACE_BTS_SIZE                42
-/* Return the number of available BTS records for draining.
-   DATA and ADDR are ignored.
-*/
-#define PTRACE_BTS_GET         43
-/* Get a single BTS record.
-   DATA defines the index into the BTS array, where 0 is the newest
-   entry, and higher indices refer to older entries.
-   ADDR is pointing to struct bts_struct (see asm/ds.h).
-*/
-#define PTRACE_BTS_CLEAR       44
-/* Clear the BTS buffer.
-   DATA and ADDR are ignored.
-*/
-#define PTRACE_BTS_DRAIN       45
-/* Read all available BTS records and clear the buffer.
-   ADDR points to an array of struct bts_struct.
-   DATA gives the size of that buffer.
-   BTS records are read from oldest to newest.
-   Returns number of BTS records drained.
-*/
+#endif
 
 #endif /* _ASM_X86_PTRACE_ABI_H */
index 69a686a7dff0bd991e6cde83e057e3884ea805ba..78cd1ea945008da5c1405e0db89201b78dd90d7a 100644 (file)
@@ -289,12 +289,6 @@ extern int do_get_thread_area(struct task_struct *p, int idx,
 extern int do_set_thread_area(struct task_struct *p, int idx,
                              struct user_desc __user *info, int can_allocate);
 
-#ifdef CONFIG_X86_PTRACE_BTS
-extern void ptrace_bts_untrace(struct task_struct *tsk);
-
-#define arch_ptrace_untrace(tsk)       ptrace_bts_untrace(tsk)
-#endif /* CONFIG_X86_PTRACE_BTS */
-
 #endif /* __KERNEL__ */
 
 #endif /* !__ASSEMBLY__ */
index e0d28901e9691ee53fcd57edf0fa08a6cd5ce8c2..d4092fac226b75249493e3fcc2ed0a4287abac10 100644 (file)
@@ -92,8 +92,7 @@ struct thread_info {
 #define TIF_IO_BITMAP          22      /* uses I/O bitmap */
 #define TIF_FREEZE             23      /* is freezing for suspend */
 #define TIF_FORCED_TF          24      /* true if TF in eflags artificially */
-#define TIF_DEBUGCTLMSR                25      /* uses thread_struct.debugctlmsr */
-#define TIF_DS_AREA_MSR                26      /* uses thread_struct.ds_area_msr */
+#define TIF_BLOCKSTEP          25      /* set when we want DEBUGCTLMSR_BTF */
 #define TIF_LAZY_MMU_UPDATES   27      /* task is updating the mmu lazily */
 #define TIF_SYSCALL_TRACEPOINT 28      /* syscall tracepoint instrumentation */
 
@@ -115,8 +114,7 @@ struct thread_info {
 #define _TIF_IO_BITMAP         (1 << TIF_IO_BITMAP)
 #define _TIF_FREEZE            (1 << TIF_FREEZE)
 #define _TIF_FORCED_TF         (1 << TIF_FORCED_TF)
-#define _TIF_DEBUGCTLMSR       (1 << TIF_DEBUGCTLMSR)
-#define _TIF_DS_AREA_MSR       (1 << TIF_DS_AREA_MSR)
+#define _TIF_BLOCKSTEP         (1 << TIF_BLOCKSTEP)
 #define _TIF_LAZY_MMU_UPDATES  (1 << TIF_LAZY_MMU_UPDATES)
 #define _TIF_SYSCALL_TRACEPOINT        (1 << TIF_SYSCALL_TRACEPOINT)
 
@@ -147,7 +145,7 @@ struct thread_info {
 
 /* flags to check in __switch_to() */
 #define _TIF_WORK_CTXSW                                                        \
-       (_TIF_IO_BITMAP|_TIF_DEBUGCTLMSR|_TIF_DS_AREA_MSR|_TIF_NOTSC)
+       (_TIF_IO_BITMAP|_TIF_NOTSC|_TIF_BLOCKSTEP)
 
 #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY)
 #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW|_TIF_DEBUG)
@@ -244,7 +242,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TS_POLLING             0x0004  /* true if in idle loop
                                           and not sleeping */
 #define TS_RESTORE_SIGMASK     0x0008  /* restore signal mask in do_signal() */
-#define TS_XSAVE               0x0010  /* Use xsave/xrstor */
 
 #define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
 
index 4da91ad69e0d6abbd717a1fafcd0bfe3221ede54..f66cda56781dddd9dc29dffd56944c596976a0ad 100644 (file)
@@ -79,7 +79,7 @@ static inline int get_si_code(unsigned long condition)
 
 extern int panic_on_unrecovered_nmi;
 
-void math_error(void __user *);
+void math_error(struct pt_regs *, int, int);
 void math_emulate(struct math_emu_info *);
 #ifndef CONFIG_X86_32
 asmlinkage void smp_thermal_interrupt(void);
diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
deleted file mode 100644 (file)
index e49ed6d..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2008, VMware, 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, 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.
- *
- */
-#ifndef ASM_X86__VMWARE_H
-#define ASM_X86__VMWARE_H
-
-extern void vmware_platform_setup(void);
-extern int vmware_platform(void);
-extern void vmware_set_feature_bits(struct cpuinfo_x86 *c);
-
-#endif
index ddc04ccad03b467de69b4b5d189f0a7a06156f82..2c4390cae22883014816647319fb6569d6867c2c 100644 (file)
@@ -37,8 +37,9 @@ extern int check_for_xstate(struct i387_fxsave_struct __user *buf,
                            void __user *fpstate,
                            struct _fpx_sw_bytes *sw);
 
-static inline int xrstor_checking(struct xsave_struct *fx)
+static inline int fpu_xrstor_checking(struct fpu *fpu)
 {
+       struct xsave_struct *fx = &fpu->state->xsave;
        int err;
 
        asm volatile("1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n\t"
@@ -110,12 +111,12 @@ static inline void xrstor_state(struct xsave_struct *fx, u64 mask)
                     :   "memory");
 }
 
-static inline void xsave(struct task_struct *tsk)
+static inline void fpu_xsave(struct fpu *fpu)
 {
        /* This, however, we can work around by forcing the compiler to select
           an addressing mode that doesn't require extended registers. */
        __asm__ __volatile__(".byte " REX_PREFIX "0x0f,0xae,0x27"
-                            : : "D" (&(tsk->thread.xstate->xsave)),
+                            : : "D" (&(fpu->state->xsave)),
                                 "a" (-1), "d"(-1) : "memory");
 }
 #endif
index 4c58352209e0e89114778a80f66e3025d315e670..e77b220837214cef81deff278e2f79ef1ed202a7 100644 (file)
@@ -47,8 +47,6 @@ obj-$(CONFIG_X86_TRAMPOLINE)  += trampoline.o
 obj-y                          += process.o
 obj-y                          += i387.o xsave.o
 obj-y                          += ptrace.o
-obj-$(CONFIG_X86_DS)           += ds.o
-obj-$(CONFIG_X86_DS_SELFTEST)          += ds_selftest.o
 obj-$(CONFIG_X86_32)           += tls.o
 obj-$(CONFIG_IA32_EMULATION)   += tls.o
 obj-y                          += step.o
index 0061ea2630615efe9e1f3af3fd8d851821c9f3b0..9a5ed58f09dcdcc0a80e5e14ab9b09bb062d44a3 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/dmi.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <linux/bootmem.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
@@ -92,6 +93,53 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
 enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
 
 
+/*
+ * ISA irqs by default are the first 16 gsis but can be
+ * any gsi as specified by an interrupt source override.
+ */
+static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = {
+       0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+static unsigned int gsi_to_irq(unsigned int gsi)
+{
+       unsigned int irq = gsi + NR_IRQS_LEGACY;
+       unsigned int i;
+
+       for (i = 0; i < NR_IRQS_LEGACY; i++) {
+               if (isa_irq_to_gsi[i] == gsi) {
+                       return i;
+               }
+       }
+
+       /* Provide an identity mapping of gsi == irq
+        * except on truly weird platforms that have
+        * non isa irqs in the first 16 gsis.
+        */
+       if (gsi >= NR_IRQS_LEGACY)
+               irq = gsi;
+       else
+               irq = gsi_end + 1 + gsi;
+
+       return irq;
+}
+
+static u32 irq_to_gsi(int irq)
+{
+       unsigned int gsi;
+
+       if (irq < NR_IRQS_LEGACY)
+               gsi = isa_irq_to_gsi[irq];
+       else if (irq <= gsi_end)
+               gsi = irq;
+       else if (irq <= (gsi_end + NR_IRQS_LEGACY))
+               gsi = irq - gsi_end;
+       else
+               gsi = 0xffffffff;
+
+       return gsi;
+}
+
 /*
  * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
  * to map the target physical address. The problem is that set_fixmap()
@@ -312,7 +360,7 @@ acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
 /*
  * Parse Interrupt Source Override for the ACPI SCI
  */
-static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
+static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger, u32 gsi)
 {
        if (trigger == 0)       /* compatible SCI trigger is level */
                trigger = 3;
@@ -332,7 +380,7 @@ static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
         * If GSI is < 16, this will update its flags,
         * else it will create a new mp_irqs[] entry.
         */
-       mp_override_legacy_irq(gsi, polarity, trigger, gsi);
+       mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
 
        /*
         * stash over-ride to indicate we've been here
@@ -356,9 +404,10 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header,
        acpi_table_print_madt_entry(header);
 
        if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) {
-               acpi_sci_ioapic_setup(intsrc->global_irq,
+               acpi_sci_ioapic_setup(intsrc->source_irq,
                                      intsrc->inti_flags & ACPI_MADT_POLARITY_MASK,
-                                     (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
+                                     (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2,
+                                     intsrc->global_irq);
                return 0;
        }
 
@@ -447,7 +496,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
 
 int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 {
-       *irq = gsi;
+       *irq = gsi_to_irq(gsi);
 
 #ifdef CONFIG_X86_IO_APIC
        if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
@@ -457,6 +506,14 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
        return 0;
 }
 
+int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
+{
+       if (isa_irq >= 16)
+               return -1;
+       *gsi = irq_to_gsi(isa_irq);
+       return 0;
+}
+
 /*
  * success: return IRQ number (>=0)
  * failure: return < 0
@@ -481,7 +538,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
                plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
        }
 #endif
-       irq = plat_gsi;
+       irq = gsi_to_irq(plat_gsi);
 
        return irq;
 }
@@ -866,29 +923,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
 extern int es7000_plat;
 #endif
 
-int __init acpi_probe_gsi(void)
-{
-       int idx;
-       int gsi;
-       int max_gsi = 0;
-
-       if (acpi_disabled)
-               return 0;
-
-       if (!acpi_ioapic)
-               return 0;
-
-       max_gsi = 0;
-       for (idx = 0; idx < nr_ioapics; idx++) {
-               gsi = mp_gsi_routing[idx].gsi_end;
-
-               if (gsi > max_gsi)
-                       max_gsi = gsi;
-       }
-
-       return max_gsi + 1;
-}
-
 static void assign_to_mp_irq(struct mpc_intsrc *m,
                                    struct mpc_intsrc *mp_irq)
 {
@@ -946,13 +980,13 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
        mp_irq.dstirq = pin;    /* INTIN# */
 
        save_mp_irq(&mp_irq);
+
+       isa_irq_to_gsi[bus_irq] = gsi;
 }
 
 void __init mp_config_acpi_legacy_irqs(void)
 {
        int i;
-       int ioapic;
-       unsigned int dstapic;
        struct mpc_intsrc mp_irq;
 
 #if defined (CONFIG_MCA) || defined (CONFIG_EISA)
@@ -972,20 +1006,28 @@ void __init mp_config_acpi_legacy_irqs(void)
                return;
 #endif
 
-       /*
-        * Locate the IOAPIC that manages the ISA IRQs (0-15).
-        */
-       ioapic = mp_find_ioapic(0);
-       if (ioapic < 0)
-               return;
-       dstapic = mp_ioapics[ioapic].apicid;
-
        /*
         * Use the default configuration for the IRQs 0-15.  Unless
         * overridden by (MADT) interrupt source override entries.
         */
        for (i = 0; i < 16; i++) {
+               int ioapic, pin;
+               unsigned int dstapic;
                int idx;
+               u32 gsi;
+
+               /* Locate the gsi that irq i maps to. */
+               if (acpi_isa_irq_to_gsi(i, &gsi))
+                       continue;
+
+               /*
+                * Locate the IOAPIC that manages the ISA IRQ.
+                */
+               ioapic = mp_find_ioapic(gsi);
+               if (ioapic < 0)
+                       continue;
+               pin = mp_find_ioapic_pin(ioapic, gsi);
+               dstapic = mp_ioapics[ioapic].apicid;
 
                for (idx = 0; idx < mp_irq_entries; idx++) {
                        struct mpc_intsrc *irq = mp_irqs + idx;
@@ -995,7 +1037,7 @@ void __init mp_config_acpi_legacy_irqs(void)
                                break;
 
                        /* Do we already have a mapping for this IOAPIC pin */
-                       if (irq->dstapic == dstapic && irq->dstirq == i)
+                       if (irq->dstapic == dstapic && irq->dstirq == pin)
                                break;
                }
 
@@ -1010,7 +1052,7 @@ void __init mp_config_acpi_legacy_irqs(void)
                mp_irq.dstapic = dstapic;
                mp_irq.irqtype = mp_INT;
                mp_irq.srcbusirq = i; /* Identity mapped */
-               mp_irq.dstirq = i;
+               mp_irq.dstirq = pin;
 
                save_mp_irq(&mp_irq);
        }
@@ -1075,11 +1117,6 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 
        ioapic_pin = mp_find_ioapic_pin(ioapic, gsi);
 
-#ifdef CONFIG_X86_32
-       if (ioapic_renumber_irq)
-               gsi = ioapic_renumber_irq(ioapic, gsi);
-#endif
-
        if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
                printk(KERN_ERR "Invalid reference to IOAPIC pin "
                       "%d-%d\n", mp_ioapics[ioapic].apicid,
@@ -1093,7 +1130,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
        set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
                             trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
                             polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
-       io_apic_set_pci_routing(dev, gsi, &irq_attr);
+       io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr);
 
        return gsi;
 }
@@ -1153,7 +1190,8 @@ static int __init acpi_parse_madt_ioapic_entries(void)
         * pretend we got one so we can set the SCI flags.
         */
        if (!acpi_sci_override_gsi)
-               acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0);
+               acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0,
+                                     acpi_gbl_FADT.sci_interrupt);
 
        /* Fill in identity legacy mappings where no override */
        mp_config_acpi_legacy_irqs();
index 3a4bf35c179b7e54b8d1902d22d734cdc4cc4b89..70237732a6c7c5f62f941d5df0594f7386ca6a10 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/vmalloc.h>
 #include <linux/memory.h>
 #include <linux/stop_machine.h>
+#include <linux/slab.h>
 #include <asm/alternative.h>
 #include <asm/sections.h>
 #include <asm/pgtable.h>
@@ -193,7 +194,7 @@ static void __init_or_module add_nops(void *insns, unsigned int len)
 }
 
 extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
-extern u8 *__smp_locks[], *__smp_locks_end[];
+extern s32 __smp_locks[], __smp_locks_end[];
 static void *text_poke_early(void *addr, const void *opcode, size_t len);
 
 /* Replace instructions with better alternatives for this CPU type.
@@ -234,37 +235,41 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
 
 #ifdef CONFIG_SMP
 
-static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
+static void alternatives_smp_lock(const s32 *start, const s32 *end,
+                                 u8 *text, u8 *text_end)
 {
-       u8 **ptr;
+       const s32 *poff;
 
        mutex_lock(&text_mutex);
-       for (ptr = start; ptr < end; ptr++) {
-               if (*ptr < text)
-                       continue;
-               if (*ptr > text_end)
+       for (poff = start; poff < end; poff++) {
+               u8 *ptr = (u8 *)poff + *poff;
+
+               if (!*poff || ptr < text || ptr >= text_end)
                        continue;
                /* turn DS segment override prefix into lock prefix */
-               text_poke(*ptr, ((unsigned char []){0xf0}), 1);
+               if (*ptr == 0x3e)
+                       text_poke(ptr, ((unsigned char []){0xf0}), 1);
        };
        mutex_unlock(&text_mutex);
 }
 
-static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
+static void alternatives_smp_unlock(const s32 *start, const s32 *end,
+                                   u8 *text, u8 *text_end)
 {
-       u8 **ptr;
+       const s32 *poff;
 
        if (noreplace_smp)
                return;
 
        mutex_lock(&text_mutex);
-       for (ptr = start; ptr < end; ptr++) {
-               if (*ptr < text)
-                       continue;
-               if (*ptr > text_end)
+       for (poff = start; poff < end; poff++) {
+               u8 *ptr = (u8 *)poff + *poff;
+
+               if (!*poff || ptr < text || ptr >= text_end)
                        continue;
                /* turn lock prefix into DS segment override prefix */
-               text_poke(*ptr, ((unsigned char []){0x3E}), 1);
+               if (*ptr == 0xf0)
+                       text_poke(ptr, ((unsigned char []){0x3E}), 1);
        };
        mutex_unlock(&text_mutex);
 }
@@ -275,8 +280,8 @@ struct smp_alt_module {
        char            *name;
 
        /* ptrs to lock prefixes */
-       u8              **locks;
-       u8              **locks_end;
+       const s32       *locks;
+       const s32       *locks_end;
 
        /* .text segment, needed to avoid patching init code ;) */
        u8              *text;
@@ -397,16 +402,19 @@ void alternatives_smp_switch(int smp)
 int alternatives_text_reserved(void *start, void *end)
 {
        struct smp_alt_module *mod;
-       u8 **ptr;
+       const s32 *poff;
        u8 *text_start = start;
        u8 *text_end = end;
 
        list_for_each_entry(mod, &smp_alt_modules, next) {
                if (mod->text > text_end || mod->text_end < text_start)
                        continue;
-               for (ptr = mod->locks; ptr < mod->locks_end; ptr++)
-                       if (text_start <= *ptr && text_end >= *ptr)
+               for (poff = mod->locks; poff < mod->locks_end; poff++) {
+                       const u8 *ptr = (const u8 *)poff + *poff;
+
+                       if (text_start <= ptr && text_end > ptr)
                                return 1;
+               }
        }
 
        return 0;
index adb0ba025702938b37586c9a8c2999cf68b135dd..fa5a1474cd182db250e189cfc8b262683f2585ba 100644 (file)
@@ -18,8 +18,8 @@
  */
 
 #include <linux/pci.h>
-#include <linux/gfp.h>
 #include <linux/bitmap.h>
+#include <linux/slab.h>
 #include <linux/debugfs.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
@@ -118,7 +118,7 @@ static bool check_device(struct device *dev)
                return false;
 
        /* No device or no PCI device */
-       if (!dev || dev->bus != &pci_bus_type)
+       if (dev->bus != &pci_bus_type)
                return false;
 
        devid = get_device_id(dev);
@@ -392,6 +392,7 @@ static int __iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
        u32 tail, head;
        u8 *target;
 
+       WARN_ON(iommu->cmd_buf_size & CMD_BUFFER_UNINITIALIZED);
        tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
        target = iommu->cmd_buf + tail;
        memcpy_toio(target, cmd, sizeof(*cmd));
@@ -730,18 +731,22 @@ static bool increase_address_space(struct protection_domain *domain,
 
 static u64 *alloc_pte(struct protection_domain *domain,
                      unsigned long address,
-                     int end_lvl,
+                     unsigned long page_size,
                      u64 **pte_page,
                      gfp_t gfp)
 {
+       int level, end_lvl;
        u64 *pte, *page;
-       int level;
+
+       BUG_ON(!is_power_of_2(page_size));
 
        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)];
+       level   = domain->mode - 1;
+       pte     = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
+       address = PAGE_SIZE_ALIGN(address, page_size);
+       end_lvl = PAGE_SIZE_LEVEL(page_size);
 
        while (level > end_lvl) {
                if (!IOMMU_PTE_PRESENT(*pte)) {
@@ -751,6 +756,10 @@ static u64 *alloc_pte(struct protection_domain *domain,
                        *pte = PM_LEVEL_PDE(level, virt_to_phys(page));
                }
 
+               /* No level skipping support yet */
+               if (PM_PTE_LEVEL(*pte) != level)
+                       return NULL;
+
                level -= 1;
 
                pte = IOMMU_PTE_PAGE(*pte);
@@ -768,28 +777,47 @@ static u64 *alloc_pte(struct protection_domain *domain,
  * 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)
+static u64 *fetch_pte(struct protection_domain *domain, unsigned long address)
 {
        int level;
        u64 *pte;
 
-       level =  domain->mode - 1;
-       pte   = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
+       if (address > PM_LEVEL_SIZE(domain->mode))
+               return NULL;
+
+       level   =  domain->mode - 1;
+       pte     = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
 
-       while (level > map_size) {
+       while (level > 0) {
+
+               /* Not Present */
                if (!IOMMU_PTE_PRESENT(*pte))
                        return NULL;
 
+               /* Large PTE */
+               if (PM_PTE_LEVEL(*pte) == 0x07) {
+                       unsigned long pte_mask, __pte;
+
+                       /*
+                        * If we have a series of large PTEs, make
+                        * sure to return a pointer to the first one.
+                        */
+                       pte_mask = PTE_PAGE_SIZE(*pte);
+                       pte_mask = ~((PAGE_SIZE_PTE_COUNT(pte_mask) << 3) - 1);
+                       __pte    = ((unsigned long)pte) & pte_mask;
+
+                       return (u64 *)__pte;
+               }
+
+               /* No level skipping support yet */
+               if (PM_PTE_LEVEL(*pte) != level)
+                       return NULL;
+
                level -= 1;
 
+               /* Walk to the next level */
                pte = IOMMU_PTE_PAGE(*pte);
                pte = &pte[PM_LEVEL_INDEX(level, address)];
-
-               if ((PM_PTE_LEVEL(*pte) == 0) && level != map_size) {
-                       pte = NULL;
-                       break;
-               }
        }
 
        return pte;
@@ -806,44 +834,84 @@ static int iommu_map_page(struct protection_domain *dom,
                          unsigned long bus_addr,
                          unsigned long phys_addr,
                          int prot,
-                         int map_size)
+                         unsigned long page_size)
 {
        u64 __pte, *pte;
-
-       bus_addr  = PAGE_ALIGN(bus_addr);
-       phys_addr = PAGE_ALIGN(phys_addr);
-
-       BUG_ON(!PM_ALIGNED(map_size, bus_addr));
-       BUG_ON(!PM_ALIGNED(map_size, phys_addr));
+       int i, count;
 
        if (!(prot & IOMMU_PROT_MASK))
                return -EINVAL;
 
-       pte = alloc_pte(dom, bus_addr, map_size, NULL, GFP_KERNEL);
+       bus_addr  = PAGE_ALIGN(bus_addr);
+       phys_addr = PAGE_ALIGN(phys_addr);
+       count     = PAGE_SIZE_PTE_COUNT(page_size);
+       pte       = alloc_pte(dom, bus_addr, page_size, NULL, GFP_KERNEL);
+
+       for (i = 0; i < count; ++i)
+               if (IOMMU_PTE_PRESENT(pte[i]))
+                       return -EBUSY;
 
-       if (IOMMU_PTE_PRESENT(*pte))
-               return -EBUSY;
+       if (page_size > PAGE_SIZE) {
+               __pte = PAGE_SIZE_PTE(phys_addr, page_size);
+               __pte |= PM_LEVEL_ENC(7) | IOMMU_PTE_P | IOMMU_PTE_FC;
+       } else
+               __pte = phys_addr | IOMMU_PTE_P | IOMMU_PTE_FC;
 
-       __pte = phys_addr | IOMMU_PTE_P;
        if (prot & IOMMU_PROT_IR)
                __pte |= IOMMU_PTE_IR;
        if (prot & IOMMU_PROT_IW)
                __pte |= IOMMU_PTE_IW;
 
-       *pte = __pte;
+       for (i = 0; i < count; ++i)
+               pte[i] = __pte;
 
        update_domain(dom);
 
        return 0;
 }
 
-static void iommu_unmap_page(struct protection_domain *dom,
-                            unsigned long bus_addr, int map_size)
+static unsigned long iommu_unmap_page(struct protection_domain *dom,
+                                     unsigned long bus_addr,
+                                     unsigned long page_size)
 {
-       u64 *pte = fetch_pte(dom, bus_addr, map_size);
+       unsigned long long unmap_size, unmapped;
+       u64 *pte;
+
+       BUG_ON(!is_power_of_2(page_size));
+
+       unmapped = 0;
 
-       if (pte)
-               *pte = 0;
+       while (unmapped < page_size) {
+
+               pte = fetch_pte(dom, bus_addr);
+
+               if (!pte) {
+                       /*
+                        * No PTE for this address
+                        * move forward in 4kb steps
+                        */
+                       unmap_size = PAGE_SIZE;
+               } else if (PM_PTE_LEVEL(*pte) == 0) {
+                       /* 4kb PTE found for this address */
+                       unmap_size = PAGE_SIZE;
+                       *pte       = 0ULL;
+               } else {
+                       int count, i;
+
+                       /* Large PTE found which maps this address */
+                       unmap_size = PTE_PAGE_SIZE(*pte);
+                       count      = PAGE_SIZE_PTE_COUNT(unmap_size);
+                       for (i = 0; i < count; i++)
+                               pte[i] = 0ULL;
+               }
+
+               bus_addr  = (bus_addr & ~(unmap_size - 1)) + unmap_size;
+               unmapped += unmap_size;
+       }
+
+       BUG_ON(!is_power_of_2(unmapped));
+
+       return unmapped;
 }
 
 /*
@@ -877,7 +945,7 @@ static int dma_ops_unity_map(struct dma_ops_domain *dma_dom,
        for (addr = e->address_start; addr < e->address_end;
             addr += PAGE_SIZE) {
                ret = iommu_map_page(&dma_dom->domain, addr, addr, e->prot,
-                                    PM_MAP_4k);
+                                    PAGE_SIZE);
                if (ret)
                        return ret;
                /*
@@ -1005,7 +1073,7 @@ static int alloc_new_range(struct dma_ops_domain *dma_dom,
                u64 *pte, *pte_page;
 
                for (i = 0; i < num_ptes; ++i) {
-                       pte = alloc_pte(&dma_dom->domain, address, PM_MAP_4k,
+                       pte = alloc_pte(&dma_dom->domain, address, PAGE_SIZE,
                                        &pte_page, gfp);
                        if (!pte)
                                goto out_free;
@@ -1041,7 +1109,7 @@ static int alloc_new_range(struct dma_ops_domain *dma_dom,
        for (i = dma_dom->aperture[index]->offset;
             i < dma_dom->aperture_size;
             i += PAGE_SIZE) {
-               u64 *pte = fetch_pte(&dma_dom->domain, i, PM_MAP_4k);
+               u64 *pte = fetch_pte(&dma_dom->domain, i);
                if (!pte || !IOMMU_PTE_PRESENT(*pte))
                        continue;
 
@@ -1711,7 +1779,7 @@ static u64* dma_ops_get_pte(struct dma_ops_domain *dom,
 
        pte = aperture->pte_pages[APERTURE_PAGE_INDEX(address)];
        if (!pte) {
-               pte = alloc_pte(&dom->domain, address, PM_MAP_4k, &pte_page,
+               pte = alloc_pte(&dom->domain, address, PAGE_SIZE, &pte_page,
                                GFP_ATOMIC);
                aperture->pte_pages[APERTURE_PAGE_INDEX(address)] = pte_page;
        } else
@@ -2186,7 +2254,7 @@ static void prealloc_protection_domains(void)
        struct dma_ops_domain *dma_dom;
        u16 devid;
 
-       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+       for_each_pci_dev(dev) {
 
                /* Do we handle this device? */
                if (!check_device(&dev->dev))
@@ -2298,7 +2366,7 @@ static void cleanup_domain(struct protection_domain *domain)
        list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) {
                struct device *dev = dev_data->dev;
 
-               do_detach(dev);
+               __detach_device(dev);
                atomic_set(&dev_data->bind, 0);
        }
 
@@ -2327,6 +2395,7 @@ static struct protection_domain *protection_domain_alloc(void)
                return NULL;
 
        spin_lock_init(&domain->lock);
+       mutex_init(&domain->api_lock);
        domain->id = domain_id_alloc();
        if (!domain->id)
                goto out_err;
@@ -2379,9 +2448,7 @@ static void amd_iommu_domain_destroy(struct iommu_domain *dom)
 
        free_pagetable(domain);
 
-       domain_id_free(domain->id);
-
-       kfree(domain);
+       protection_domain_free(domain);
 
        dom->priv = NULL;
 }
@@ -2439,12 +2506,11 @@ static int amd_iommu_attach_device(struct iommu_domain *dom,
        return ret;
 }
 
-static int amd_iommu_map_range(struct iommu_domain *dom,
-                              unsigned long iova, phys_addr_t paddr,
-                              size_t size, int iommu_prot)
+static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova,
+                        phys_addr_t paddr, int gfp_order, int iommu_prot)
 {
+       unsigned long page_size = 0x1000UL << gfp_order;
        struct protection_domain *domain = dom->priv;
-       unsigned long i,  npages = iommu_num_pages(paddr, size, PAGE_SIZE);
        int prot = 0;
        int ret;
 
@@ -2453,53 +2519,50 @@ static int amd_iommu_map_range(struct iommu_domain *dom,
        if (iommu_prot & IOMMU_WRITE)
                prot |= IOMMU_PROT_IW;
 
-       iova  &= PAGE_MASK;
-       paddr &= PAGE_MASK;
+       mutex_lock(&domain->api_lock);
+       ret = iommu_map_page(domain, iova, paddr, prot, page_size);
+       mutex_unlock(&domain->api_lock);
 
-       for (i = 0; i < npages; ++i) {
-               ret = iommu_map_page(domain, iova, paddr, prot, PM_MAP_4k);
-               if (ret)
-                       return ret;
-
-               iova  += PAGE_SIZE;
-               paddr += PAGE_SIZE;
-       }
-
-       return 0;
+       return ret;
 }
 
-static void amd_iommu_unmap_range(struct iommu_domain *dom,
-                                 unsigned long iova, size_t size)
+static int amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova,
+                          int gfp_order)
 {
-
        struct protection_domain *domain = dom->priv;
-       unsigned long i,  npages = iommu_num_pages(iova, size, PAGE_SIZE);
+       unsigned long page_size, unmap_size;
 
-       iova  &= PAGE_MASK;
+       page_size  = 0x1000UL << gfp_order;
 
-       for (i = 0; i < npages; ++i) {
-               iommu_unmap_page(domain, iova, PM_MAP_4k);
-               iova  += PAGE_SIZE;
-       }
+       mutex_lock(&domain->api_lock);
+       unmap_size = iommu_unmap_page(domain, iova, page_size);
+       mutex_unlock(&domain->api_lock);
 
        iommu_flush_tlb_pde(domain);
+
+       return get_order(unmap_size);
 }
 
 static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
                                          unsigned long iova)
 {
        struct protection_domain *domain = dom->priv;
-       unsigned long offset = iova & ~PAGE_MASK;
+       unsigned long offset_mask;
        phys_addr_t paddr;
-       u64 *pte;
+       u64 *pte, __pte;
 
-       pte = fetch_pte(domain, iova, PM_MAP_4k);
+       pte = fetch_pte(domain, iova);
 
        if (!pte || !IOMMU_PTE_PRESENT(*pte))
                return 0;
 
-       paddr  = *pte & IOMMU_PAGE_MASK;
-       paddr |= offset;
+       if (PM_PTE_LEVEL(*pte) == 0)
+               offset_mask = PAGE_SIZE - 1;
+       else
+               offset_mask = PTE_PAGE_SIZE(*pte) - 1;
+
+       __pte = *pte & PM_ADDR_MASK;
+       paddr = (__pte & ~offset_mask) | (iova & offset_mask);
 
        return paddr;
 }
@@ -2515,8 +2578,8 @@ static struct iommu_ops amd_iommu_ops = {
        .domain_destroy = amd_iommu_domain_destroy,
        .attach_dev = amd_iommu_attach_device,
        .detach_dev = amd_iommu_detach_device,
-       .map = amd_iommu_map_range,
-       .unmap = amd_iommu_unmap_range,
+       .map = amd_iommu_map,
+       .unmap = amd_iommu_unmap,
        .iova_to_phys = amd_iommu_iova_to_phys,
        .domain_has_cap = amd_iommu_domain_has_cap,
 };
index 9dc91b4314703ff6157222bfbecac53329c34372..3bacb4d0844c1e6b7794b6a23013dcbf77f3694e 100644 (file)
@@ -19,8 +19,8 @@
 
 #include <linux/pci.h>
 #include <linux/acpi.h>
-#include <linux/gfp.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/sysdev.h>
 #include <linux/interrupt.h>
 #include <linux/msi.h>
@@ -120,6 +120,7 @@ struct ivmd_header {
 bool amd_iommu_dump;
 
 static int __initdata amd_iommu_detected;
+static bool __initdata amd_iommu_disabled;
 
 u16 amd_iommu_last_bdf;                        /* largest PCI device id we have
                                           to handle */
@@ -138,9 +139,9 @@ int amd_iommus_present;
 bool amd_iommu_np_cache __read_mostly;
 
 /*
- * Set to true if ACPI table parsing and hardware intialization went properly
+ * The ACPI table parsing functions set this variable on an error
  */
-static bool amd_iommu_initialized;
+static int __initdata amd_iommu_init_err;
 
 /*
  * List of protection domains - used during resume
@@ -391,9 +392,11 @@ static int __init find_last_devid_acpi(struct acpi_table_header *table)
         */
        for (i = 0; i < table->length; ++i)
                checksum += p[i];
-       if (checksum != 0)
+       if (checksum != 0) {
                /* ACPI table corrupt */
-               return -ENODEV;
+               amd_iommu_init_err = -ENODEV;
+               return 0;
+       }
 
        p += IVRS_HEADER_LENGTH;
 
@@ -436,7 +439,7 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu)
        if (cmd_buf == NULL)
                return NULL;
 
-       iommu->cmd_buf_size = CMD_BUFFER_SIZE;
+       iommu->cmd_buf_size = CMD_BUFFER_SIZE | CMD_BUFFER_UNINITIALIZED;
 
        return cmd_buf;
 }
@@ -472,12 +475,13 @@ static void iommu_enable_command_buffer(struct amd_iommu *iommu)
                    &entry, sizeof(entry));
 
        amd_iommu_reset_cmd_buffer(iommu);
+       iommu->cmd_buf_size &= ~(CMD_BUFFER_UNINITIALIZED);
 }
 
 static void __init free_command_buffer(struct amd_iommu *iommu)
 {
        free_pages((unsigned long)iommu->cmd_buf,
-                  get_order(iommu->cmd_buf_size));
+                  get_order(iommu->cmd_buf_size & ~(CMD_BUFFER_UNINITIALIZED)));
 }
 
 /* allocates the memory where the IOMMU will log its events to */
@@ -920,11 +924,16 @@ static int __init init_iommu_all(struct acpi_table_header *table)
                                    h->mmio_phys);
 
                        iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL);
-                       if (iommu == NULL)
-                               return -ENOMEM;
+                       if (iommu == NULL) {
+                               amd_iommu_init_err = -ENOMEM;
+                               return 0;
+                       }
+
                        ret = init_iommu_one(iommu, h);
-                       if (ret)
-                               return ret;
+                       if (ret) {
+                               amd_iommu_init_err = ret;
+                               return 0;
+                       }
                        break;
                default:
                        break;
@@ -934,8 +943,6 @@ static int __init init_iommu_all(struct acpi_table_header *table)
        }
        WARN_ON(p != end);
 
-       amd_iommu_initialized = true;
-
        return 0;
 }
 
@@ -1211,6 +1218,10 @@ static int __init amd_iommu_init(void)
        if (acpi_table_parse("IVRS", find_last_devid_acpi) != 0)
                return -ENODEV;
 
+       ret = amd_iommu_init_err;
+       if (ret)
+               goto out;
+
        dev_table_size     = tbl_size(DEV_TABLE_ENTRY_SIZE);
        alias_table_size   = tbl_size(ALIAS_TABLE_ENTRY_SIZE);
        rlookup_table_size = tbl_size(RLOOKUP_TABLE_ENTRY_SIZE);
@@ -1270,12 +1281,19 @@ static int __init amd_iommu_init(void)
        if (acpi_table_parse("IVRS", init_iommu_all) != 0)
                goto free;
 
-       if (!amd_iommu_initialized)
+       if (amd_iommu_init_err) {
+               ret = amd_iommu_init_err;
                goto free;
+       }
 
        if (acpi_table_parse("IVRS", init_memory_definitions) != 0)
                goto free;
 
+       if (amd_iommu_init_err) {
+               ret = amd_iommu_init_err;
+               goto free;
+       }
+
        ret = sysdev_class_register(&amd_iommu_sysdev_class);
        if (ret)
                goto free;
@@ -1288,6 +1306,8 @@ static int __init amd_iommu_init(void)
        if (ret)
                goto free;
 
+       enable_iommus();
+
        if (iommu_pass_through)
                ret = amd_iommu_init_passthrough();
        else
@@ -1300,8 +1320,6 @@ static int __init amd_iommu_init(void)
 
        amd_iommu_init_notifier();
 
-       enable_iommus();
-
        if (iommu_pass_through)
                goto out;
 
@@ -1315,6 +1333,7 @@ out:
        return ret;
 
 free:
+       disable_iommus();
 
        amd_iommu_uninit_devices();
 
@@ -1354,6 +1373,9 @@ void __init amd_iommu_detect(void)
        if (no_iommu || (iommu_detected && !gart_iommu_aperture))
                return;
 
+       if (amd_iommu_disabled)
+               return;
+
        if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) {
                iommu_detected = 1;
                amd_iommu_detected = 1;
@@ -1383,6 +1405,8 @@ static int __init parse_amd_iommu_options(char *str)
        for (; *str; ++str) {
                if (strncmp(str, "fullflush", 9) == 0)
                        amd_iommu_unmap_flush = true;
+               if (strncmp(str, "off", 3) == 0)
+                       amd_iommu_disabled = true;
        }
 
        return 1;
index 4b7099526d2c1c8c6c496f4ce0f8e028fbac9eab..a35347501d36883b802c6471ed466b4e271ce8c8 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
+#include <linux/slab.h>
 #include <linux/pm.h>
 #include <linux/pci.h>
 #include <linux/sfi.h>
@@ -428,7 +429,7 @@ static int apbt_cpuhp_notify(struct notifier_block *n,
 
 static __init int apbt_late_init(void)
 {
-       if (disable_apbt_percpu)
+       if (disable_apbt_percpu || !apb_timer_block_enabled)
                return 0;
        /* This notifier should be called after workqueue is ready */
        hotcpu_notifier(apbt_cpuhp_notify, -20);
index 3704997e8b2573bda630720f4c47bd4a7ec3b8c5..b5d8b0bcf23588a413d5766d160e24ac6c811441 100644 (file)
@@ -393,6 +393,7 @@ void __init gart_iommu_hole_init(void)
        for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
                int bus;
                int dev_base, dev_limit;
+               u32 ctl;
 
                bus = bus_dev_ranges[i].bus;
                dev_base = bus_dev_ranges[i].dev_base;
@@ -406,7 +407,19 @@ void __init gart_iommu_hole_init(void)
                        gart_iommu_aperture = 1;
                        x86_init.iommu.iommu_init = gart_iommu_init;
 
-                       aper_order = (read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL) >> 1) & 7;
+                       ctl = read_pci_config(bus, slot, 3,
+                                             AMD64_GARTAPERTURECTL);
+
+                       /*
+                        * Before we do anything else disable the GART. It may
+                        * still be enabled if we boot into a crash-kernel here.
+                        * Reconfiguring the GART while it is enabled could have
+                        * unknown side-effects.
+                        */
+                       ctl &= ~GARTEN;
+                       write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl);
+
+                       aper_order = (ctl >> 1) & 7;
                        aper_size = (32 * 1024 * 1024) << aper_order;
                        aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff;
                        aper_base <<= 25;
index 00187f1fcfb7f75602f845f4f01bf6dc6d3bfdf2..e5a4a1e016180c0a5aea127d550ae2389600de73 100644 (file)
@@ -1640,8 +1640,10 @@ int __init APIC_init_uniprocessor(void)
        }
 #endif
 
+#ifndef CONFIG_SMP
        enable_IR_x2apic();
        default_setup_apic_routing();
+#endif
 
        verify_local_APIC();
        connect_bsp_APIC();
index dd2b5f26464364611bf603f10689289630bdd00e..425e53a87febe983ab07533d17d4d10e4f24a726 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/errno.h>
 #include <linux/acpi.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/nmi.h>
 #include <linux/smp.h>
 #include <linux/io.h>
@@ -130,24 +131,6 @@ int                                        es7000_plat;
 
 static unsigned int                    base;
 
-static int
-es7000_rename_gsi(int ioapic, int gsi)
-{
-       if (es7000_plat == ES7000_ZORRO)
-               return gsi;
-
-       if (!base) {
-               int i;
-               for (i = 0; i < nr_ioapics; i++)
-                       base += nr_ioapic_registers[i];
-       }
-
-       if (!ioapic && (gsi < 16))
-               gsi += base;
-
-       return gsi;
-}
-
 static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
 {
        unsigned long vect = 0, psaival = 0;
@@ -189,7 +172,6 @@ static void setup_unisys(void)
                es7000_plat = ES7000_ZORRO;
        else
                es7000_plat = ES7000_CLASSIC;
-       ioapic_renumber_irq = es7000_rename_gsi;
 }
 
 /*
index e4e0ddcb1546bde04f0d01675756622b9d2434bd..33f3563a2a52a8b40cc2a07d8a60a03a583457a7 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/freezer.h>
 #include <linux/kthread.h>
 #include <linux/jiffies.h>     /* time_after() */
+#include <linux/slab.h>
 #ifdef CONFIG_ACPI
 #include <acpi/acpi_bus.h>
 #endif
@@ -88,6 +89,9 @@ int nr_ioapics;
 /* IO APIC gsi routing info */
 struct mp_ioapic_gsi  mp_gsi_routing[MAX_IO_APICS];
 
+/* The last gsi number used */
+u32 gsi_end;
+
 /* MP IRQ source entries */
 struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
 
@@ -1012,10 +1016,9 @@ static inline int irq_trigger(int idx)
        return MPBIOS_trigger(idx);
 }
 
-int (*ioapic_renumber_irq)(int ioapic, int irq);
 static int pin_2_irq(int idx, int apic, int pin)
 {
-       int irq, i;
+       int irq;
        int bus = mp_irqs[idx].srcbus;
 
        /*
@@ -1027,18 +1030,12 @@ static int pin_2_irq(int idx, int apic, int pin)
        if (test_bit(bus, mp_bus_not_pci)) {
                irq = mp_irqs[idx].srcbusirq;
        } else {
-               /*
-                * PCI IRQs are mapped in order
-                */
-               i = irq = 0;
-               while (i < apic)
-                       irq += nr_ioapic_registers[i++];
-               irq += pin;
-               /*
-                 * For MPS mode, so far only needed by ES7000 platform
-                 */
-               if (ioapic_renumber_irq)
-                       irq = ioapic_renumber_irq(apic, irq);
+               u32 gsi = mp_gsi_routing[apic].gsi_base + pin;
+
+               if (gsi >= NR_IRQS_LEGACY)
+                       irq = gsi;
+               else
+                       irq = gsi_end + 1 + gsi;
        }
 
 #ifdef CONFIG_X86_32
@@ -1268,6 +1265,14 @@ void __setup_vector_irq(int cpu)
        /* Mark the inuse vectors */
        for_each_irq_desc(irq, desc) {
                cfg = desc->chip_data;
+
+               /*
+                * If it is a legacy IRQ handled by the legacy PIC, this cpu
+                * will be part of the irq_cfg's domain.
+                */
+               if (irq < legacy_pic->nr_legacy_irqs && !IO_APIC_IRQ(irq))
+                       cpumask_set_cpu(cpu, cfg->domain);
+
                if (!cpumask_test_cpu(cpu, cfg->domain))
                        continue;
                vector = cfg->vector;
@@ -1941,20 +1946,8 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
 
 void __init enable_IO_APIC(void)
 {
-       union IO_APIC_reg_01 reg_01;
        int i8259_apic, i8259_pin;
        int apic;
-       unsigned long flags;
-
-       /*
-        * The number of IO-APIC IRQ registers (== #pins):
-        */
-       for (apic = 0; apic < nr_ioapics; apic++) {
-               raw_spin_lock_irqsave(&ioapic_lock, flags);
-               reg_01.raw = io_apic_read(apic, 1);
-               raw_spin_unlock_irqrestore(&ioapic_lock, flags);
-               nr_ioapic_registers[apic] = reg_01.bits.entries+1;
-       }
 
        if (!legacy_pic->nr_legacy_irqs)
                return;
@@ -2536,6 +2529,9 @@ void irq_force_complete_move(int irq)
        struct irq_desc *desc = irq_to_desc(irq);
        struct irq_cfg *cfg = desc->chip_data;
 
+       if (!cfg)
+               return;
+
        __irq_complete_move(&desc, cfg->vector);
 }
 #else
@@ -3846,27 +3842,20 @@ int __init io_apic_get_redir_entries (int ioapic)
        reg_01.raw = io_apic_read(ioapic, 1);
        raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
-       return reg_01.bits.entries;
+       /* The register returns the maximum index redir index
+        * supported, which is one less than the total number of redir
+        * entries.
+        */
+       return reg_01.bits.entries + 1;
 }
 
 void __init probe_nr_irqs_gsi(void)
 {
-       int nr = 0;
+       int nr;
 
-       nr = acpi_probe_gsi();
-       if (nr > nr_irqs_gsi) {
+       nr = gsi_end + 1 + NR_IRQS_LEGACY;
+       if (nr > nr_irqs_gsi)
                nr_irqs_gsi = nr;
-       } else {
-               /* for acpi=off or acpi is not compiled in */
-               int idx;
-
-               nr = 0;
-               for (idx = 0; idx < nr_ioapics; idx++)
-                       nr += io_apic_get_redir_entries(idx) + 1;
-
-               if (nr > nr_irqs_gsi)
-                       nr_irqs_gsi = nr;
-       }
 
        printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
 }
@@ -4073,22 +4062,27 @@ int __init io_apic_get_version(int ioapic)
        return reg_01.bits.version;
 }
 
-int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
+int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity)
 {
-       int i;
+       int ioapic, pin, idx;
 
        if (skip_ioapic_setup)
                return -1;
 
-       for (i = 0; i < mp_irq_entries; i++)
-               if (mp_irqs[i].irqtype == mp_INT &&
-                   mp_irqs[i].srcbusirq == bus_irq)
-                       break;
-       if (i >= mp_irq_entries)
+       ioapic = mp_find_ioapic(gsi);
+       if (ioapic < 0)
+               return -1;
+
+       pin = mp_find_ioapic_pin(ioapic, gsi);
+       if (pin < 0)
+               return -1;
+
+       idx = find_irq_entry(ioapic, pin, mp_INT);
+       if (idx < 0)
                return -1;
 
-       *trigger = irq_trigger(i);
-       *polarity = irq_polarity(i);
+       *trigger = irq_trigger(idx);
+       *polarity = irq_polarity(idx);
        return 0;
 }
 
@@ -4229,7 +4223,7 @@ void __init ioapic_insert_resources(void)
        }
 }
 
-int mp_find_ioapic(int gsi)
+int mp_find_ioapic(u32 gsi)
 {
        int i = 0;
 
@@ -4244,7 +4238,7 @@ int mp_find_ioapic(int gsi)
        return -1;
 }
 
-int mp_find_ioapic_pin(int ioapic, int gsi)
+int mp_find_ioapic_pin(int ioapic, u32 gsi)
 {
        if (WARN_ON(ioapic == -1))
                return -1;
@@ -4272,6 +4266,7 @@ static int bad_ioapic(unsigned long address)
 void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 {
        int idx = 0;
+       int entries;
 
        if (bad_ioapic(address))
                return;
@@ -4290,9 +4285,17 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
         * Build basic GSI lookup table to facilitate gsi->io_apic lookups
         * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
         */
+       entries = io_apic_get_redir_entries(idx);
        mp_gsi_routing[idx].gsi_base = gsi_base;
-       mp_gsi_routing[idx].gsi_end = gsi_base +
-           io_apic_get_redir_entries(idx);
+       mp_gsi_routing[idx].gsi_end = gsi_base + entries - 1;
+
+       /*
+        * The number of IO-APIC IRQ registers (== #pins):
+        */
+       nr_ioapic_registers[idx] = entries;
+
+       if (mp_gsi_routing[idx].gsi_end > gsi_end)
+               gsi_end = mp_gsi_routing[idx].gsi_end;
 
        printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
               "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
index 8aa65adbd25d75340fe2d73434528207921f4a83..1edaf15c0b8eef05b36653a0ed9087a9b3717f9e 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/sysdev.h>
 #include <linux/sysctl.h>
 #include <linux/percpu.h>
index 49dbeaef2a27b03f092b2eb267d26b6028b9c382..c085d52dbaf2f1305ea35c16e0877fb11abcb7e7 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/ctype.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
 #include <linux/cpu.h>
 #include <linux/init.h>
 #include <linux/io.h>
index 031aa887b0ebae42d98ecfeacb66eeede0a8910a..c4f9182ca3ac0a9538659243f2bc03547f0ae198 100644 (file)
@@ -1224,7 +1224,7 @@ static void reinit_timer(void)
 #ifdef INIT_TIMER_AFTER_SUSPEND
        unsigned long flags;
 
-       spin_lock_irqsave(&i8253_lock, flags);
+       raw_spin_lock_irqsave(&i8253_lock, flags);
        /* set the clock to HZ */
        outb_pit(0x34, PIT_MODE);               /* binary, mode 2, LSB/MSB, ch 0 */
        udelay(10);
@@ -1232,7 +1232,7 @@ static void reinit_timer(void)
        udelay(10);
        outb_pit(LATCH >> 8, PIT_CH0);  /* MSB */
        udelay(10);
-       spin_unlock_irqrestore(&i8253_lock, flags);
+       raw_spin_unlock_irqrestore(&i8253_lock, flags);
 #endif
 }
 
index 30f25a75fe2876ef93605181f81c386c02953bfb..5de7f4c5697136e180e4a24e153bde77c7112b8c 100644 (file)
@@ -5,7 +5,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/acpi.h>
 #include <asm/io.h>
index c202b62f36719b1c00ca635e75f91e996d55c4e3..3a785da34b6f981dd678f217c5f75f728a30d8ae 100644 (file)
@@ -14,7 +14,7 @@ CFLAGS_common.o               := $(nostackp)
 
 obj-y                  := intel_cacheinfo.o addon_cpuid_features.o
 obj-y                  += proc.o capflags.o powerflags.o common.o
-obj-y                  += vmware.o hypervisor.o sched.o
+obj-y                  += vmware.o hypervisor.o sched.o mshyperv.o
 
 obj-$(CONFIG_X86_32)   += bugs.o cmpxchg.o
 obj-$(CONFIG_X86_64)   += bugs_64.o
index 97ad79cdf688d785e1c34f1aaa053da9804d60c1..10fa5684a6628e5e095a698d8bc8065748bc4534 100644 (file)
@@ -30,12 +30,14 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
        const struct cpuid_bit *cb;
 
        static const struct cpuid_bit __cpuinitconst cpuid_bits[] = {
-               { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
-               { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006 },
-               { X86_FEATURE_NPT,   CR_EDX, 0, 0x8000000a },
-               { X86_FEATURE_LBRV,  CR_EDX, 1, 0x8000000a },
-               { X86_FEATURE_SVML,  CR_EDX, 2, 0x8000000a },
-               { X86_FEATURE_NRIPS, CR_EDX, 3, 0x8000000a },
+               { X86_FEATURE_IDA,              CR_EAX, 1, 0x00000006 },
+               { X86_FEATURE_ARAT,             CR_EAX, 2, 0x00000006 },
+               { X86_FEATURE_APERFMPERF,       CR_ECX, 0, 0x00000006 },
+               { X86_FEATURE_CPB,              CR_EDX, 9, 0x80000007 },
+               { X86_FEATURE_NPT,              CR_EDX, 0, 0x8000000a },
+               { X86_FEATURE_LBRV,             CR_EDX, 1, 0x8000000a },
+               { X86_FEATURE_SVML,             CR_EDX, 2, 0x8000000a },
+               { X86_FEATURE_NRIPS,            CR_EDX, 3, 0x8000000a },
                { 0, 0, 0, 0 }
        };
 
index 01a2652123951a07c3b4e5e3e01f5e061f291696..c39576cb3018507f2d359521741c1764778b68f7 100644 (file)
@@ -86,7 +86,7 @@ static void __init check_fpu(void)
 
 static void __init check_hlt(void)
 {
-       if (paravirt_enabled())
+       if (boot_cpu_data.x86 >= 5 || paravirt_enabled())
                return;
 
        printk(KERN_INFO "Checking 'hlt' instruction... ");
index 4868e4a951eeec310c10d06428d60c49e2fe79b5..c1c00d0b1692d47bf45981439122b962a9b1dac0 100644 (file)
@@ -1243,10 +1243,7 @@ void __cpuinit cpu_init(void)
        /*
         * Force FPU initialization:
         */
-       if (cpu_has_xsave)
-               current_thread_info()->status = TS_XSAVE;
-       else
-               current_thread_info()->status = 0;
+       current_thread_info()->status = 0;
        clear_used_math();
        mxcsr_feature_mask_init();
 
index 1840c0a5170bfda11e0f80d50f5ba301774e9d1b..bd54bf67e6fb6fe1a96679a48987e0900dacbb45 100644 (file)
@@ -2,8 +2,8 @@
 # K8 systems. ACPI is preferred to all other hardware-specific drivers.
 # speedstep-* is preferred over p4-clockmod.
 
-obj-$(CONFIG_X86_POWERNOW_K8)          += powernow-k8.o
-obj-$(CONFIG_X86_ACPI_CPUFREQ)         += acpi-cpufreq.o
+obj-$(CONFIG_X86_POWERNOW_K8)          += powernow-k8.o mperf.o
+obj-$(CONFIG_X86_ACPI_CPUFREQ)         += acpi-cpufreq.o mperf.o
 obj-$(CONFIG_X86_PCC_CPUFREQ)          += pcc-cpufreq.o
 obj-$(CONFIG_X86_POWERNOW_K6)          += powernow-k6.o
 obj-$(CONFIG_X86_POWERNOW_K7)          += powernow-k7.o
index 1b1920fa7c8085934cbd846e9329cc538c25be4b..1d3cddaa40ee66d5730c11e6758a449f680b8cf6 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/cpufreq.h>
 #include <linux/compiler.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 #include <trace/events/power.h>
 
 #include <linux/acpi.h>
@@ -45,6 +46,7 @@
 #include <asm/msr.h>
 #include <asm/processor.h>
 #include <asm/cpufeature.h>
+#include "mperf.h"
 
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
                "acpi-cpufreq", msg)
@@ -70,8 +72,6 @@ struct acpi_cpufreq_data {
 
 static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data);
 
-static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf);
-
 /* acpi_perf_data is a pointer to percpu data. */
 static struct acpi_processor_performance *acpi_perf_data;
 
@@ -239,45 +239,6 @@ static u32 get_cur_val(const struct cpumask *mask)
        return cmd.val;
 }
 
-/* Called via smp_call_function_single(), on the target CPU */
-static void read_measured_perf_ctrs(void *_cur)
-{
-       struct aperfmperf *am = _cur;
-
-       get_aperfmperf(am);
-}
-
-/*
- * Return the measured active (C0) frequency on this CPU since last call
- * to this function.
- * Input: cpu number
- * Return: Average CPU frequency in terms of max frequency (zero on error)
- *
- * We use IA32_MPERF and IA32_APERF MSRs to get the measured performance
- * over a period of time, while CPU is in C0 state.
- * IA32_MPERF counts at the rate of max advertised frequency
- * IA32_APERF counts at the rate of actual CPU frequency
- * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and
- * no meaning should be associated with absolute values of these MSRs.
- */
-static unsigned int get_measured_perf(struct cpufreq_policy *policy,
-                                     unsigned int cpu)
-{
-       struct aperfmperf perf;
-       unsigned long ratio;
-       unsigned int retval;
-
-       if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1))
-               return 0;
-
-       ratio = calc_aperfmperf_ratio(&per_cpu(acfreq_old_perf, cpu), &perf);
-       per_cpu(acfreq_old_perf, cpu) = perf;
-
-       retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT;
-
-       return retval;
-}
-
 static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
 {
        struct acpi_cpufreq_data *data = per_cpu(acfreq_data, cpu);
@@ -701,7 +662,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
 
        /* Check for APERF/MPERF support in hardware */
        if (cpu_has(c, X86_FEATURE_APERFMPERF))
-               acpi_cpufreq_driver.getavg = get_measured_perf;
+               acpi_cpufreq_driver.getavg = cpufreq_get_measured_perf;
 
        dprintk("CPU%u - ACPI performance management activated.\n", cpu);
        for (i = 0; i < perf->state_count; i++)
index 006b278b0d5d973f794e3c0f17a0e9f925369f52..c587db472a75a21eeabb0c52a1df3b7f48b549f4 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/cpufreq.h>
 
index ac27ec2264d50afd3601ae7a5a10caf93bb94858..16e3483be9e3c13db575daddf9d1a18bc84ab1ec 100644 (file)
@@ -80,6 +80,7 @@
 #include <linux/cpufreq.h>
 #include <linux/pci.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 
 #include <asm/processor-cyrix.h>
 
index da5f70fcb766d1f4a257466e5710c7da62af6d5e..e7b559d74c5242c0ea0c490e21c6e298ff9dd557 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/cpufreq.h>
 #include <linux/timex.h>
 
diff --git a/arch/x86/kernel/cpu/cpufreq/mperf.c b/arch/x86/kernel/cpu/cpufreq/mperf.c
new file mode 100644 (file)
index 0000000..911e193
--- /dev/null
@@ -0,0 +1,51 @@
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/slab.h>
+
+#include "mperf.h"
+
+static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf);
+
+/* Called via smp_call_function_single(), on the target CPU */
+static void read_measured_perf_ctrs(void *_cur)
+{
+       struct aperfmperf *am = _cur;
+
+       get_aperfmperf(am);
+}
+
+/*
+ * Return the measured active (C0) frequency on this CPU since last call
+ * to this function.
+ * Input: cpu number
+ * Return: Average CPU frequency in terms of max frequency (zero on error)
+ *
+ * We use IA32_MPERF and IA32_APERF MSRs to get the measured performance
+ * over a period of time, while CPU is in C0 state.
+ * IA32_MPERF counts at the rate of max advertised frequency
+ * IA32_APERF counts at the rate of actual CPU frequency
+ * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and
+ * no meaning should be associated with absolute values of these MSRs.
+ */
+unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy,
+                                       unsigned int cpu)
+{
+       struct aperfmperf perf;
+       unsigned long ratio;
+       unsigned int retval;
+
+       if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1))
+               return 0;
+
+       ratio = calc_aperfmperf_ratio(&per_cpu(acfreq_old_perf, cpu), &perf);
+       per_cpu(acfreq_old_perf, cpu) = perf;
+
+       retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT;
+
+       return retval;
+}
+EXPORT_SYMBOL_GPL(cpufreq_get_measured_perf);
+MODULE_LICENSE("GPL");
diff --git a/arch/x86/kernel/cpu/cpufreq/mperf.h b/arch/x86/kernel/cpu/cpufreq/mperf.h
new file mode 100644 (file)
index 0000000..5dbf295
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ *  (c) 2010 Advanced Micro Devices, Inc.
+ *  Your use of this code is subject to the terms and conditions of the
+ *  GNU general public license version 2. See "COPYING" or
+ *  http://www.gnu.org/licenses/gpl.html
+ */
+
+unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy,
+                                       unsigned int cpu);
index 869615193720c1b126dc5069d37cc9620f1049b3..7b8a8ba67b0779911991ba8fbb1cbab28b6fa749 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/init.h>
 #include <linux/smp.h>
 #include <linux/cpufreq.h>
-#include <linux/slab.h>
 #include <linux/cpumask.h>
 #include <linux/timex.h>
 
index ff36d2979a909ddee0748e79f30608206e2e5c9b..ce7cde713e7174e8293b552b332f968946a46904 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/sched.h>
 #include <linux/cpufreq.h>
 #include <linux/compiler.h>
+#include <linux/slab.h>
 
 #include <linux/acpi.h>
 #include <linux/io.h>
index cb01dac267d3de14486db1bf3ed081be5999a45e..b3379d6a5c57214cadb73f8f6dffc37b83ccb6e9 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/timex.h>
 #include <linux/io.h>
 
index d360b56e9825e43e16b185b00746a016e806c1f5..6f3dc8fbbfdc77fe49a070bffcc685b3af102ce8 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- *   (c) 2003-2006 Advanced Micro Devices, Inc.
+ *   (c) 2003-2010 Advanced Micro Devices, Inc.
  *  Your use of this code is subject to the terms and conditions of the
  *  GNU general public license version 2. See "COPYING" or
  *  http://www.gnu.org/licenses/gpl.html
@@ -46,6 +45,7 @@
 #define PFX "powernow-k8: "
 #define VERSION "version 2.20.00"
 #include "powernow-k8.h"
+#include "mperf.h"
 
 /* serialize freq changes  */
 static DEFINE_MUTEX(fidvid_mutex);
@@ -54,6 +54,12 @@ static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data);
 
 static int cpu_family = CPU_OPTERON;
 
+/* core performance boost */
+static bool cpb_capable, cpb_enabled;
+static struct msr __percpu *msrs;
+
+static struct cpufreq_driver cpufreq_amd64_driver;
+
 #ifndef CONFIG_SMP
 static inline const struct cpumask *cpu_core_mask(int cpu)
 {
@@ -929,7 +935,8 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data,
                powernow_table[i].index = index;
 
                /* Frequency may be rounded for these */
-               if (boot_cpu_data.x86 == 0x10 || boot_cpu_data.x86 == 0x11) {
+               if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10)
+                                || boot_cpu_data.x86 == 0x11) {
                        powernow_table[i].frequency =
                                freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7);
                } else
@@ -1248,6 +1255,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
        struct powernow_k8_data *data;
        struct init_on_cpu init_on_cpu;
        int rc;
+       struct cpuinfo_x86 *c = &cpu_data(pol->cpu);
 
        if (!cpu_online(pol->cpu))
                return -ENODEV;
@@ -1322,6 +1330,10 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
                return -EINVAL;
        }
 
+       /* Check for APERF/MPERF support in hardware */
+       if (cpu_has(c, X86_FEATURE_APERFMPERF))
+               cpufreq_amd64_driver.getavg = cpufreq_get_measured_perf;
+
        cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu);
 
        if (cpu_family == CPU_HW_PSTATE)
@@ -1393,8 +1405,77 @@ out:
        return khz;
 }
 
+static void _cpb_toggle_msrs(bool t)
+{
+       int cpu;
+
+       get_online_cpus();
+
+       rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
+
+       for_each_cpu(cpu, cpu_online_mask) {
+               struct msr *reg = per_cpu_ptr(msrs, cpu);
+               if (t)
+                       reg->l &= ~BIT(25);
+               else
+                       reg->l |= BIT(25);
+       }
+       wrmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
+
+       put_online_cpus();
+}
+
+/*
+ * Switch on/off core performance boosting.
+ *
+ * 0=disable
+ * 1=enable.
+ */
+static void cpb_toggle(bool t)
+{
+       if (!cpb_capable)
+               return;
+
+       if (t && !cpb_enabled) {
+               cpb_enabled = true;
+               _cpb_toggle_msrs(t);
+               printk(KERN_INFO PFX "Core Boosting enabled.\n");
+       } else if (!t && cpb_enabled) {
+               cpb_enabled = false;
+               _cpb_toggle_msrs(t);
+               printk(KERN_INFO PFX "Core Boosting disabled.\n");
+       }
+}
+
+static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf,
+                                size_t count)
+{
+       int ret = -EINVAL;
+       unsigned long val = 0;
+
+       ret = strict_strtoul(buf, 10, &val);
+       if (!ret && (val == 0 || val == 1) && cpb_capable)
+               cpb_toggle(val);
+       else
+               return -EINVAL;
+
+       return count;
+}
+
+static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf)
+{
+       return sprintf(buf, "%u\n", cpb_enabled);
+}
+
+#define define_one_rw(_name) \
+static struct freq_attr _name = \
+__ATTR(_name, 0644, show_##_name, store_##_name)
+
+define_one_rw(cpb);
+
 static struct freq_attr *powernow_k8_attr[] = {
        &cpufreq_freq_attr_scaling_available_freqs,
+       &cpb,
        NULL,
 };
 
@@ -1410,10 +1491,51 @@ static struct cpufreq_driver cpufreq_amd64_driver = {
        .attr           = powernow_k8_attr,
 };
 
+/*
+ * Clear the boost-disable flag on the CPU_DOWN path so that this cpu
+ * cannot block the remaining ones from boosting. On the CPU_UP path we
+ * simply keep the boost-disable flag in sync with the current global
+ * state.
+ */
+static int __cpuinit cpb_notify(struct notifier_block *nb, unsigned long action,
+                               void *hcpu)
+{
+       unsigned cpu = (long)hcpu;
+       u32 lo, hi;
+
+       switch (action) {
+       case CPU_UP_PREPARE:
+       case CPU_UP_PREPARE_FROZEN:
+
+               if (!cpb_enabled) {
+                       rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
+                       lo |= BIT(25);
+                       wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi);
+               }
+               break;
+
+       case CPU_DOWN_PREPARE:
+       case CPU_DOWN_PREPARE_FROZEN:
+               rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
+               lo &= ~BIT(25);
+               wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi);
+               break;
+
+       default:
+               break;
+       }
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata cpb_nb = {
+       .notifier_call          = cpb_notify,
+};
+
 /* driver entry point for init */
 static int __cpuinit powernowk8_init(void)
 {
-       unsigned int i, supported_cpus = 0;
+       unsigned int i, supported_cpus = 0, cpu;
 
        for_each_online_cpu(i) {
                int rc;
@@ -1422,15 +1544,36 @@ static int __cpuinit powernowk8_init(void)
                        supported_cpus++;
        }
 
-       if (supported_cpus == num_online_cpus()) {
-               printk(KERN_INFO PFX "Found %d %s "
-                       "processors (%d cpu cores) (" VERSION ")\n",
-                       num_online_nodes(),
-                       boot_cpu_data.x86_model_id, supported_cpus);
-               return cpufreq_register_driver(&cpufreq_amd64_driver);
+       if (supported_cpus != num_online_cpus())
+               return -ENODEV;
+
+       printk(KERN_INFO PFX "Found %d %s (%d cpu cores) (" VERSION ")\n",
+               num_online_nodes(), boot_cpu_data.x86_model_id, supported_cpus);
+
+       if (boot_cpu_has(X86_FEATURE_CPB)) {
+
+               cpb_capable = true;
+
+               register_cpu_notifier(&cpb_nb);
+
+               msrs = msrs_alloc();
+               if (!msrs) {
+                       printk(KERN_ERR "%s: Error allocating msrs!\n", __func__);
+                       return -ENOMEM;
+               }
+
+               rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
+
+               for_each_cpu(cpu, cpu_online_mask) {
+                       struct msr *reg = per_cpu_ptr(msrs, cpu);
+                       cpb_enabled |= !(!!(reg->l & BIT(25)));
+               }
+
+               printk(KERN_INFO PFX "Core Performance Boosting: %s.\n",
+                       (cpb_enabled ? "on" : "off"));
        }
 
-       return -ENODEV;
+       return cpufreq_register_driver(&cpufreq_amd64_driver);
 }
 
 /* driver entry point for term */
@@ -1438,6 +1581,13 @@ static void __exit powernowk8_exit(void)
 {
        dprintk("exit\n");
 
+       if (boot_cpu_has(X86_FEATURE_CPB)) {
+               msrs_free(msrs);
+               msrs = NULL;
+
+               unregister_cpu_notifier(&cpb_nb);
+       }
+
        cpufreq_unregister_driver(&cpufreq_amd64_driver);
 }
 
index 02ce824073cb9463e33e0fb5a32d7f7e60814b2f..df3529b1c02d7bfe468d8d073f51099400805ce6 100644 (file)
@@ -5,7 +5,6 @@
  *  http://www.gnu.org/licenses/gpl.html
  */
 
-
 enum pstate {
        HW_PSTATE_INVALID = 0xff,
        HW_PSTATE_0 = 0,
@@ -55,7 +54,6 @@ struct powernow_k8_data {
        struct cpumask *available_cores;
 };
 
-
 /* processor's cpuid instruction support */
 #define CPUID_PROCESSOR_SIGNATURE      1       /* function 1 */
 #define CPUID_XFAM                     0x0ff00000      /* extended family */
index 8d672ef162cef76306d7e978556f5910e7da4184..9b1ff37de46ae6a729f48d2d94ad30548806884d 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/sched.h>       /* current */
 #include <linux/delay.h>
 #include <linux/compiler.h>
+#include <linux/gfp.h>
 
 #include <asm/msr.h>
 #include <asm/processor.h>
index 2ce8e0b5cc541b38052f4c2075fbd021f745ba06..561758e951802356aa88bb78d4b10c5da2c4e6c7 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/sched.h>
 
 #include "speedstep-lib.h"
index ad0083abfa23f7fcdc30c4a5e8d0ada72214db92..a94ec6be69fa5c798381d41c1c4cb10a0029d385 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
-#include <linux/slab.h>
 
 #include <asm/msr.h>
 #include <asm/tsc.h>
index 04d73c114e4944d4bcceaa577c82b8f9545a9a53..8abd869baabfb7eccbb9c5888a20ccd8b29e91bd 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <asm/ist.h>
index 08be922de33ad7b2d14cde498f53ac013817edde..dd531cc56a8f2c2f6da4acd545f413d869ee5869 100644 (file)
  *
  */
 
+#include <linux/module.h>
 #include <asm/processor.h>
-#include <asm/vmware.h>
 #include <asm/hypervisor.h>
 
-static inline void __cpuinit
-detect_hypervisor_vendor(struct cpuinfo_x86 *c)
+/*
+ * Hypervisor detect order.  This is specified explicitly here because
+ * some hypervisors might implement compatibility modes for other
+ * hypervisors and therefore need to be detected in specific sequence.
+ */
+static const __initconst struct hypervisor_x86 * const hypervisors[] =
 {
-       if (vmware_platform())
-               c->x86_hyper_vendor = X86_HYPER_VENDOR_VMWARE;
-       else
-               c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE;
-}
+       &x86_hyper_vmware,
+       &x86_hyper_ms_hyperv,
+};
 
-static inline void __cpuinit
-hypervisor_set_feature_bits(struct cpuinfo_x86 *c)
+const struct hypervisor_x86 *x86_hyper;
+EXPORT_SYMBOL(x86_hyper);
+
+static inline void __init
+detect_hypervisor_vendor(void)
 {
-       if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE) {
-               vmware_set_feature_bits(c);
-               return;
+       const struct hypervisor_x86 *h, * const *p;
+
+       for (p = hypervisors; p < hypervisors + ARRAY_SIZE(hypervisors); p++) {
+               h = *p;
+               if (h->detect()) {
+                       x86_hyper = h;
+                       printk(KERN_INFO "Hypervisor detected: %s\n", h->name);
+                       break;
+               }
        }
 }
 
 void __cpuinit init_hypervisor(struct cpuinfo_x86 *c)
 {
-       detect_hypervisor_vendor(c);
-       hypervisor_set_feature_bits(c);
+       if (x86_hyper && x86_hyper->set_cpu_features)
+               x86_hyper->set_cpu_features(c);
 }
 
 void __init init_hypervisor_platform(void)
 {
+
+       detect_hypervisor_vendor();
+
+       if (!x86_hyper)
+               return;
+
        init_hypervisor(&boot_cpu_data);
-       if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
-               vmware_platform_setup();
+
+       if (x86_hyper->init_platform)
+               x86_hyper->init_platform();
 }
index 7e1cca13af3589a562d26c0ead4a2a3c1474c129..85f69cdeae1020a18e1c9097c8da276a8e50b992 100644 (file)
@@ -12,7 +12,6 @@
 #include <asm/processor.h>
 #include <asm/pgtable.h>
 #include <asm/msr.h>
-#include <asm/ds.h>
 #include <asm/bugs.h>
 #include <asm/cpu.h>
 
@@ -47,6 +46,27 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
                (c->x86 == 0x6 && c->x86_model >= 0x0e))
                set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
 
+       /*
+        * Atom erratum AAE44/AAF40/AAG38/AAH41:
+        *
+        * A race condition between speculative fetches and invalidating
+        * a large page.  This is worked around in microcode, but we
+        * need the microcode to have already been loaded... so if it is
+        * not, recommend a BIOS update and disable large pages.
+        */
+       if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_mask <= 2) {
+               u32 ucode, junk;
+
+               wrmsr(MSR_IA32_UCODE_REV, 0, 0);
+               sync_core();
+               rdmsr(MSR_IA32_UCODE_REV, junk, ucode);
+
+               if (ucode < 0x20e) {
+                       printk(KERN_WARNING "Atom PSE erratum detected, BIOS microcode update recommended\n");
+                       clear_cpu_cap(c, X86_FEATURE_PSE);
+               }
+       }
+
 #ifdef CONFIG_X86_64
        set_cpu_cap(c, X86_FEATURE_SYSENTER32);
 #else
@@ -352,12 +372,6 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
                        set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON);
        }
 
-       if (c->cpuid_level > 6) {
-               unsigned ecx = cpuid_ecx(6);
-               if (ecx & 0x01)
-                       set_cpu_cap(c, X86_FEATURE_APERFMPERF);
-       }
-
        if (cpu_has_xmm2)
                set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
        if (cpu_has_ds) {
@@ -367,7 +381,6 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
                        set_cpu_cap(c, X86_FEATURE_BTS);
                if (!(l1 & (1<<12)))
                        set_cpu_cap(c, X86_FEATURE_PEBS);
-               ds_init_intel(c);
        }
 
        if (c->x86 == 6 && c->x86_model == 29 && cpu_has_clflush)
index b3eeb66c0a51af93e3d7015aa737ce3af66ed1e3..33eae2062cf55b06c864ad8511062440f37f10fe 100644 (file)
@@ -148,13 +148,19 @@ union _cpuid4_leaf_ecx {
        u32 full;
 };
 
+struct amd_l3_cache {
+       struct   pci_dev *dev;
+       bool     can_disable;
+       unsigned indices;
+       u8       subcaches[4];
+};
+
 struct _cpuid4_info {
        union _cpuid4_leaf_eax eax;
        union _cpuid4_leaf_ebx ebx;
        union _cpuid4_leaf_ecx ecx;
        unsigned long size;
-       bool can_disable;
-       unsigned int l3_indices;
+       struct amd_l3_cache *l3;
        DECLARE_BITMAP(shared_cpu_map, NR_CPUS);
 };
 
@@ -164,8 +170,7 @@ struct _cpuid4_info_regs {
        union _cpuid4_leaf_ebx ebx;
        union _cpuid4_leaf_ecx ecx;
        unsigned long size;
-       bool can_disable;
-       unsigned int l3_indices;
+       struct amd_l3_cache *l3;
 };
 
 unsigned short                 num_cache_leaves;
@@ -302,87 +307,163 @@ struct _cache_attr {
 };
 
 #ifdef CONFIG_CPU_SUP_AMD
-static unsigned int __cpuinit amd_calc_l3_indices(void)
+
+/*
+ * L3 cache descriptors
+ */
+static struct amd_l3_cache **__cpuinitdata l3_caches;
+
+static void __cpuinit amd_calc_l3_indices(struct amd_l3_cache *l3)
 {
-       /*
-        * We're called over smp_call_function_single() and therefore
-        * are on the correct cpu.
-        */
-       int cpu = smp_processor_id();
-       int node = cpu_to_node(cpu);
-       struct pci_dev *dev = node_to_k8_nb_misc(node);
        unsigned int sc0, sc1, sc2, sc3;
        u32 val = 0;
 
-       pci_read_config_dword(dev, 0x1C4, &val);
+       pci_read_config_dword(l3->dev, 0x1C4, &val);
 
        /* calculate subcache sizes */
-       sc0 = !(val & BIT(0));
-       sc1 = !(val & BIT(4));
-       sc2 = !(val & BIT(8))  + !(val & BIT(9));
-       sc3 = !(val & BIT(12)) + !(val & BIT(13));
+       l3->subcaches[0] = sc0 = !(val & BIT(0));
+       l3->subcaches[1] = sc1 = !(val & BIT(4));
+       l3->subcaches[2] = sc2 = !(val & BIT(8))  + !(val & BIT(9));
+       l3->subcaches[3] = sc3 = !(val & BIT(12)) + !(val & BIT(13));
 
-       return (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1;
+       l3->indices = (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1;
+}
+
+static struct amd_l3_cache * __cpuinit amd_init_l3_cache(int node)
+{
+       struct amd_l3_cache *l3;
+       struct pci_dev *dev = node_to_k8_nb_misc(node);
+
+       l3 = kzalloc(sizeof(struct amd_l3_cache), GFP_ATOMIC);
+       if (!l3) {
+               printk(KERN_WARNING "Error allocating L3 struct\n");
+               return NULL;
+       }
+
+       l3->dev = dev;
+
+       amd_calc_l3_indices(l3);
+
+       return l3;
 }
 
 static void __cpuinit
 amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
 {
-       if (index < 3)
+       int node;
+
+       if (boot_cpu_data.x86 != 0x10)
                return;
 
-       if (boot_cpu_data.x86 == 0x11)
+       if (index < 3)
                return;
 
        /* see errata #382 and #388 */
-       if ((boot_cpu_data.x86 == 0x10) &&
-           ((boot_cpu_data.x86_model < 0x8) ||
-            (boot_cpu_data.x86_mask  < 0x1)))
+       if (boot_cpu_data.x86_model < 0x8)
+               return;
+
+       if ((boot_cpu_data.x86_model == 0x8 ||
+            boot_cpu_data.x86_model == 0x9)
+               &&
+            boot_cpu_data.x86_mask < 0x1)
+                       return;
+
+       /* not in virtualized environments */
+       if (num_k8_northbridges == 0)
                return;
 
-       this_leaf->can_disable = true;
-       this_leaf->l3_indices  = amd_calc_l3_indices();
+       /*
+        * Strictly speaking, the amount in @size below is leaked since it is
+        * never freed but this is done only on shutdown so it doesn't matter.
+        */
+       if (!l3_caches) {
+               int size = num_k8_northbridges * sizeof(struct amd_l3_cache *);
+
+               l3_caches = kzalloc(size, GFP_ATOMIC);
+               if (!l3_caches)
+                       return;
+       }
+
+       node = amd_get_nb_id(smp_processor_id());
+
+       if (!l3_caches[node]) {
+               l3_caches[node] = amd_init_l3_cache(node);
+               l3_caches[node]->can_disable = true;
+       }
+
+       WARN_ON(!l3_caches[node]);
+
+       this_leaf->l3 = l3_caches[node];
 }
 
 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
-                                 unsigned int index)
+                                 unsigned int slot)
 {
-       int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
-       int node = amd_get_nb_id(cpu);
-       struct pci_dev *dev = node_to_k8_nb_misc(node);
+       struct pci_dev *dev = this_leaf->l3->dev;
        unsigned int reg = 0;
 
-       if (!this_leaf->can_disable)
+       if (!this_leaf->l3 || !this_leaf->l3->can_disable)
                return -EINVAL;
 
        if (!dev)
                return -EINVAL;
 
-       pci_read_config_dword(dev, 0x1BC + index * 4, &reg);
+       pci_read_config_dword(dev, 0x1BC + slot * 4, &reg);
        return sprintf(buf, "0x%08x\n", reg);
 }
 
-#define SHOW_CACHE_DISABLE(index)                                      \
+#define SHOW_CACHE_DISABLE(slot)                                       \
 static ssize_t                                                         \
-show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf)  \
+show_cache_disable_##slot(struct _cpuid4_info *this_leaf, char *buf)   \
 {                                                                      \
-       return show_cache_disable(this_leaf, buf, index);               \
+       return show_cache_disable(this_leaf, buf, slot);                \
 }
 SHOW_CACHE_DISABLE(0)
 SHOW_CACHE_DISABLE(1)
 
+static void amd_l3_disable_index(struct amd_l3_cache *l3, int cpu,
+                                unsigned slot, unsigned long idx)
+{
+       int i;
+
+       idx |= BIT(30);
+
+       /*
+        *  disable index in all 4 subcaches
+        */
+       for (i = 0; i < 4; i++) {
+               u32 reg = idx | (i << 20);
+
+               if (!l3->subcaches[i])
+                       continue;
+
+               pci_write_config_dword(l3->dev, 0x1BC + slot * 4, reg);
+
+               /*
+                * We need to WBINVD on a core on the node containing the L3
+                * cache which indices we disable therefore a simple wbinvd()
+                * is not sufficient.
+                */
+               wbinvd_on_cpu(cpu);
+
+               reg |= BIT(31);
+               pci_write_config_dword(l3->dev, 0x1BC + slot * 4, reg);
+       }
+}
+
+
 static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
-       const char *buf, size_t count, unsigned int index)
+                                  const char *buf, size_t count,
+                                  unsigned int slot)
 {
+       struct pci_dev *dev = this_leaf->l3->dev;
        int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
-       int node = amd_get_nb_id(cpu);
-       struct pci_dev *dev = node_to_k8_nb_misc(node);
        unsigned long val = 0;
 
 #define SUBCACHE_MASK  (3UL << 20)
 #define SUBCACHE_INDEX 0xfff
 
-       if (!this_leaf->can_disable)
+       if (!this_leaf->l3 || !this_leaf->l3->can_disable)
                return -EINVAL;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -396,26 +477,20 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
 
        /* do not allow writes outside of allowed bits */
        if ((val & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) ||
-           ((val & SUBCACHE_INDEX) > this_leaf->l3_indices))
+           ((val & SUBCACHE_INDEX) > this_leaf->l3->indices))
                return -EINVAL;
 
-       val |= BIT(30);
-       pci_write_config_dword(dev, 0x1BC + index * 4, val);
-       /*
-        * We need to WBINVD on a core on the node containing the L3 cache which
-        * indices we disable therefore a simple wbinvd() is not sufficient.
-        */
-       wbinvd_on_cpu(cpu);
-       pci_write_config_dword(dev, 0x1BC + index * 4, val | BIT(31));
+       amd_l3_disable_index(this_leaf->l3, cpu, slot, val);
+
        return count;
 }
 
-#define STORE_CACHE_DISABLE(index)                                     \
+#define STORE_CACHE_DISABLE(slot)                                      \
 static ssize_t                                                         \
-store_cache_disable_##index(struct _cpuid4_info *this_leaf,            \
+store_cache_disable_##slot(struct _cpuid4_info *this_leaf,             \
                            const char *buf, size_t count)              \
 {                                                                      \
-       return store_cache_disable(this_leaf, buf, count, index);       \
+       return store_cache_disable(this_leaf, buf, count, slot);        \
 }
 STORE_CACHE_DISABLE(0)
 STORE_CACHE_DISABLE(1)
@@ -443,8 +518,7 @@ __cpuinit cpuid4_cache_lookup_regs(int index,
 
        if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
                amd_cpuid4(index, &eax, &ebx, &ecx);
-               if (boot_cpu_data.x86 >= 0x10)
-                       amd_check_l3_disable(index, this_leaf);
+               amd_check_l3_disable(index, this_leaf);
        } else {
                cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
        }
@@ -701,6 +775,7 @@ static void __cpuinit free_cache_attributes(unsigned int cpu)
        for (i = 0; i < num_cache_leaves; i++)
                cache_remove_shared_cpu_map(cpu, i);
 
+       kfree(per_cpu(ici_cpuid4_info, cpu)->l3);
        kfree(per_cpu(ici_cpuid4_info, cpu));
        per_cpu(ici_cpuid4_info, cpu) = NULL;
 }
@@ -985,7 +1060,7 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
 
                this_leaf = CPUID4_INFO_IDX(cpu, i);
 
-               if (this_leaf->can_disable)
+               if (this_leaf->l3 && this_leaf->l3->can_disable)
                        ktype_cache.default_attrs = default_l3_attrs;
                else
                        ktype_cache.default_attrs = default_attrs;
index 73734baa50f2200e6925104fbc9f9c2f057ea9a1..e7dbde7bfedb6a114536ff4448188ab76ebbd6bd 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kdebug.h>
 #include <linux/cpu.h>
 #include <linux/sched.h>
+#include <linux/gfp.h>
 #include <asm/mce.h>
 #include <asm/apic.h>
 
index 3ab9c886b61338e80f9a4f4fbc66814fc177f58b..7a355ddcc64b98707fef017c084937b82219aa89 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/sched.h>
 #include <linux/sysfs.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/poll.h>
@@ -538,7 +539,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
        struct mce m;
        int i;
 
-       __get_cpu_var(mce_poll_count)++;
+       percpu_inc(mce_poll_count);
 
        mce_setup(&m);
 
@@ -933,7 +934,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 
        atomic_inc(&mce_entry);
 
-       __get_cpu_var(mce_exception_count)++;
+       percpu_inc(mce_exception_count);
 
        if (notify_die(DIE_NMI, "machine check", regs, error_code,
                           18, SIGKILL) == NOTIFY_STOP)
index cda932ca3ade1c9eaff1e4847349110057943814..224392d8fe8c095390439a10ea45af2e21bc0930 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/cpu.h>
 #include <linux/smp.h>
index d15df6e49bf02936be5f51854040efbf7a7e89cf..62b48e40920a2fe2445bc68ba562fcc2e4d8c987 100644 (file)
@@ -5,6 +5,7 @@
  * Author: Andi Kleen
  */
 
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/percpu.h>
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
new file mode 100644 (file)
index 0000000..16f41bb
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * HyperV  Detection code.
+ *
+ * Copyright (C) 2010, Novell, Inc.
+ * Author : K. Y. Srinivasan <ksrinivasan@novell.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; version 2 of the License.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <asm/processor.h>
+#include <asm/hypervisor.h>
+#include <asm/hyperv.h>
+#include <asm/mshyperv.h>
+
+struct ms_hyperv_info ms_hyperv;
+
+static bool __init ms_hyperv_platform(void)
+{
+       u32 eax;
+       u32 hyp_signature[3];
+
+       if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
+               return false;
+
+       cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS,
+             &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]);
+
+       return eax >= HYPERV_CPUID_MIN &&
+               eax <= HYPERV_CPUID_MAX &&
+               !memcmp("Microsoft Hv", hyp_signature, 12);
+}
+
+static void __init ms_hyperv_init_platform(void)
+{
+       /*
+        * Extract the features and hints
+        */
+       ms_hyperv.features = cpuid_eax(HYPERV_CPUID_FEATURES);
+       ms_hyperv.hints    = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
+
+       printk(KERN_INFO "HyperV: features 0x%x, hints 0x%x\n",
+              ms_hyperv.features, ms_hyperv.hints);
+}
+
+const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
+       .name                   = "Microsoft HyperV",
+       .detect                 = ms_hyperv_platform,
+       .init_platform          = ms_hyperv_init_platform,
+};
+EXPORT_SYMBOL(x86_hyper_ms_hyperv);
index 9aa5dc76ff4a156304a3c864776c3665628004e4..fd31a441c61cbecf51e554d2292a2600b7a70295 100644 (file)
@@ -6,7 +6,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/mm.h>
 
index e006e56f699c24d1fe193a307bf799fda3801c6d..79289632cb270cb4aa02c1e5cc58d4c3de5b53b1 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/module.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #define LINE_SIZE 80
index 42aafd11e1705621dbb06de06e184432c87d9931..fd4db0db3708917ce471190eb7647a64074dc910 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/kdebug.h>
 #include <linux/sched.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <linux/highmem.h>
 #include <linux/cpu.h>
 #include <linux/bitops.h>
 #include <asm/apic.h>
 #include <asm/stacktrace.h>
 #include <asm/nmi.h>
+#include <asm/compat.h>
+
+#if 0
+#undef wrmsrl
+#define wrmsrl(msr, val)                                       \
+do {                                                           \
+       trace_printk("wrmsrl(%lx, %lx)\n", (unsigned long)(msr),\
+                       (unsigned long)(val));                  \
+       native_write_msr((msr), (u32)((u64)(val)),              \
+                       (u32)((u64)(val) >> 32));               \
+} while (0)
+#endif
 
-static u64 perf_event_mask __read_mostly;
-
-/* The maximal number of PEBS events: */
-#define MAX_PEBS_EVENTS        4
+/*
+ * best effort, GUP based copy_from_user() that assumes IRQ or NMI context
+ */
+static unsigned long
+copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
+{
+       unsigned long offset, addr = (unsigned long)from;
+       int type = in_nmi() ? KM_NMI : KM_IRQ0;
+       unsigned long size, len = 0;
+       struct page *page;
+       void *map;
+       int ret;
 
-/* The size of a BTS record in bytes: */
-#define BTS_RECORD_SIZE                24
+       do {
+               ret = __get_user_pages_fast(addr, 1, 0, &page);
+               if (!ret)
+                       break;
 
-/* The size of a per-cpu BTS buffer in bytes: */
-#define BTS_BUFFER_SIZE                (BTS_RECORD_SIZE * 2048)
+               offset = addr & (PAGE_SIZE - 1);
+               size = min(PAGE_SIZE - offset, n - len);
 
-/* The BTS overflow threshold in bytes from the end of the buffer: */
-#define BTS_OVFL_TH            (BTS_RECORD_SIZE * 128)
+               map = kmap_atomic(page, type);
+               memcpy(to, map+offset, size);
+               kunmap_atomic(map, type);
+               put_page(page);
 
+               len  += size;
+               to   += size;
+               addr += size;
 
-/*
- * Bits in the debugctlmsr controlling branch tracing.
- */
-#define X86_DEBUGCTL_TR                        (1 << 6)
-#define X86_DEBUGCTL_BTS               (1 << 7)
-#define X86_DEBUGCTL_BTINT             (1 << 8)
-#define X86_DEBUGCTL_BTS_OFF_OS                (1 << 9)
-#define X86_DEBUGCTL_BTS_OFF_USR       (1 << 10)
+       } while (len < n);
 
-/*
- * A debug store configuration.
- *
- * We only support architectures that use 64bit fields.
- */
-struct debug_store {
-       u64     bts_buffer_base;
-       u64     bts_index;
-       u64     bts_absolute_maximum;
-       u64     bts_interrupt_threshold;
-       u64     pebs_buffer_base;
-       u64     pebs_index;
-       u64     pebs_absolute_maximum;
-       u64     pebs_interrupt_threshold;
-       u64     pebs_event_reset[MAX_PEBS_EVENTS];
-};
+       return len;
+}
 
 struct event_constraint {
        union {
@@ -87,18 +94,41 @@ struct amd_nb {
        struct event_constraint event_constraints[X86_PMC_IDX_MAX];
 };
 
+#define MAX_LBR_ENTRIES                16
+
 struct cpu_hw_events {
+       /*
+        * Generic x86 PMC bits
+        */
        struct perf_event       *events[X86_PMC_IDX_MAX]; /* in counter order */
        unsigned long           active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
-       unsigned long           interrupts;
        int                     enabled;
-       struct debug_store      *ds;
 
        int                     n_events;
        int                     n_added;
        int                     assign[X86_PMC_IDX_MAX]; /* event to counter assignment */
        u64                     tags[X86_PMC_IDX_MAX];
        struct perf_event       *event_list[X86_PMC_IDX_MAX]; /* in enabled order */
+
+       unsigned int            group_flag;
+
+       /*
+        * Intel DebugStore bits
+        */
+       struct debug_store      *ds;
+       u64                     pebs_enabled;
+
+       /*
+        * Intel LBR bits
+        */
+       int                             lbr_users;
+       void                            *lbr_context;
+       struct perf_branch_stack        lbr_stack;
+       struct perf_branch_entry        lbr_entries[MAX_LBR_ENTRIES];
+
+       /*
+        * AMD specific bits
+        */
        struct amd_nb           *amd_nb;
 };
 
@@ -112,44 +142,75 @@ struct cpu_hw_events {
 #define EVENT_CONSTRAINT(c, n, m)      \
        __EVENT_CONSTRAINT(c, n, m, HWEIGHT(n))
 
+/*
+ * Constraint on the Event code.
+ */
 #define INTEL_EVENT_CONSTRAINT(c, n)   \
-       EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVTSEL_MASK)
+       EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)
 
+/*
+ * Constraint on the Event code + UMask + fixed-mask
+ *
+ * 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 FIXED_EVENT_CONSTRAINT(c, n)   \
-       EVENT_CONSTRAINT(c, (1ULL << (32+n)), INTEL_ARCH_FIXED_MASK)
+       EVENT_CONSTRAINT(c, (1ULL << (32+n)), X86_RAW_EVENT_MASK)
+
+/*
+ * Constraint on the Event code + UMask
+ */
+#define PEBS_EVENT_CONSTRAINT(c, n)    \
+       EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)
 
 #define EVENT_CONSTRAINT_END           \
        EVENT_CONSTRAINT(0, 0, 0)
 
 #define for_each_event_constraint(e, c)        \
-       for ((e) = (c); (e)->cmask; (e)++)
+       for ((e) = (c); (e)->weight; (e)++)
+
+union perf_capabilities {
+       struct {
+               u64     lbr_format    : 6;
+               u64     pebs_trap     : 1;
+               u64     pebs_arch_reg : 1;
+               u64     pebs_format   : 4;
+               u64     smm_freeze    : 1;
+       };
+       u64     capabilities;
+};
 
 /*
  * struct x86_pmu - generic x86 pmu
  */
 struct x86_pmu {
+       /*
+        * Generic x86 PMC bits
+        */
        const char      *name;
        int             version;
        int             (*handle_irq)(struct pt_regs *);
        void            (*disable_all)(void);
-       void            (*enable_all)(void);
-       void            (*enable)(struct hw_perf_event *, int);
-       void            (*disable)(struct hw_perf_event *, int);
+       void            (*enable_all)(int added);
+       void            (*enable)(struct perf_event *);
+       void            (*disable)(struct perf_event *);
+       int             (*hw_config)(struct perf_event *event);
+       int             (*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign);
        unsigned        eventsel;
        unsigned        perfctr;
        u64             (*event_map)(int);
-       u64             (*raw_event)(u64);
        int             max_events;
-       int             num_events;
-       int             num_events_fixed;
-       int             event_bits;
-       u64             event_mask;
+       int             num_counters;
+       int             num_counters_fixed;
+       int             cntval_bits;
+       u64             cntval_mask;
        int             apic;
        u64             max_period;
-       u64             intel_ctrl;
-       void            (*enable_bts)(u64 config);
-       void            (*disable_bts)(void);
-
        struct event_constraint *
                        (*get_event_constraints)(struct cpu_hw_events *cpuc,
                                                 struct perf_event *event);
@@ -157,6 +218,32 @@ struct x86_pmu {
        void            (*put_event_constraints)(struct cpu_hw_events *cpuc,
                                                 struct perf_event *event);
        struct event_constraint *event_constraints;
+       void            (*quirks)(void);
+
+       int             (*cpu_prepare)(int cpu);
+       void            (*cpu_starting)(int cpu);
+       void            (*cpu_dying)(int cpu);
+       void            (*cpu_dead)(int cpu);
+
+       /*
+        * Intel Arch Perfmon v2+
+        */
+       u64                     intel_ctrl;
+       union perf_capabilities intel_cap;
+
+       /*
+        * Intel DebugStore bits
+        */
+       int             bts, pebs;
+       int             pebs_record_size;
+       void            (*drain_pebs)(struct pt_regs *regs);
+       struct event_constraint *pebs_constraints;
+
+       /*
+        * Intel LBR
+        */
+       unsigned long   lbr_tos, lbr_from, lbr_to; /* MSR base regs       */
+       int             lbr_nr;                    /* hardware stack size */
 };
 
 static struct x86_pmu x86_pmu __read_mostly;
@@ -165,8 +252,7 @@ static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
        .enabled = 1,
 };
 
-static int x86_perf_event_set_period(struct perf_event *event,
-                            struct hw_perf_event *hwc, int idx);
+static int x86_perf_event_set_period(struct perf_event *event);
 
 /*
  * Generalized hw caching related hw_event table, filled
@@ -189,11 +275,12 @@ static u64 __read_mostly hw_cache_event_ids
  * Returns the delta events processed.
  */
 static u64
-x86_perf_event_update(struct perf_event *event,
-                       struct hw_perf_event *hwc, int idx)
+x86_perf_event_update(struct perf_event *event)
 {
-       int shift = 64 - x86_pmu.event_bits;
+       struct hw_perf_event *hwc = &event->hw;
+       int shift = 64 - x86_pmu.cntval_bits;
        u64 prev_raw_count, new_raw_count;
+       int idx = hwc->idx;
        s64 delta;
 
        if (idx == X86_PMC_IDX_FIXED_BTS)
@@ -234,33 +321,32 @@ again:
 static atomic_t active_events;
 static DEFINE_MUTEX(pmc_reserve_mutex);
 
+#ifdef CONFIG_X86_LOCAL_APIC
+
 static bool reserve_pmc_hardware(void)
 {
-#ifdef CONFIG_X86_LOCAL_APIC
        int i;
 
        if (nmi_watchdog == NMI_LOCAL_APIC)
                disable_lapic_nmi_watchdog();
 
-       for (i = 0; i < x86_pmu.num_events; i++) {
+       for (i = 0; i < x86_pmu.num_counters; i++) {
                if (!reserve_perfctr_nmi(x86_pmu.perfctr + i))
                        goto perfctr_fail;
        }
 
-       for (i = 0; i < x86_pmu.num_events; i++) {
+       for (i = 0; i < x86_pmu.num_counters; i++) {
                if (!reserve_evntsel_nmi(x86_pmu.eventsel + i))
                        goto eventsel_fail;
        }
-#endif
 
        return true;
 
-#ifdef CONFIG_X86_LOCAL_APIC
 eventsel_fail:
        for (i--; i >= 0; i--)
                release_evntsel_nmi(x86_pmu.eventsel + i);
 
-       i = x86_pmu.num_events;
+       i = x86_pmu.num_counters;
 
 perfctr_fail:
        for (i--; i >= 0; i--)
@@ -270,128 +356,36 @@ perfctr_fail:
                enable_lapic_nmi_watchdog();
 
        return false;
-#endif
 }
 
 static void release_pmc_hardware(void)
 {
-#ifdef CONFIG_X86_LOCAL_APIC
        int i;
 
-       for (i = 0; i < x86_pmu.num_events; i++) {
+       for (i = 0; i < x86_pmu.num_counters; i++) {
                release_perfctr_nmi(x86_pmu.perfctr + i);
                release_evntsel_nmi(x86_pmu.eventsel + i);
        }
 
        if (nmi_watchdog == NMI_LOCAL_APIC)
                enable_lapic_nmi_watchdog();
-#endif
-}
-
-static inline bool bts_available(void)
-{
-       return x86_pmu.enable_bts != NULL;
-}
-
-static inline void init_debug_store_on_cpu(int cpu)
-{
-       struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-
-       if (!ds)
-               return;
-
-       wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA,
-                    (u32)((u64)(unsigned long)ds),
-                    (u32)((u64)(unsigned long)ds >> 32));
 }
 
-static inline void fini_debug_store_on_cpu(int cpu)
-{
-       if (!per_cpu(cpu_hw_events, cpu).ds)
-               return;
-
-       wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
-}
-
-static void release_bts_hardware(void)
-{
-       int cpu;
-
-       if (!bts_available())
-               return;
-
-       get_online_cpus();
-
-       for_each_online_cpu(cpu)
-               fini_debug_store_on_cpu(cpu);
-
-       for_each_possible_cpu(cpu) {
-               struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-
-               if (!ds)
-                       continue;
+#else
 
-               per_cpu(cpu_hw_events, cpu).ds = NULL;
+static bool reserve_pmc_hardware(void) { return true; }
+static void release_pmc_hardware(void) {}
 
-               kfree((void *)(unsigned long)ds->bts_buffer_base);
-               kfree(ds);
-       }
-
-       put_online_cpus();
-}
-
-static int reserve_bts_hardware(void)
-{
-       int cpu, err = 0;
-
-       if (!bts_available())
-               return 0;
-
-       get_online_cpus();
-
-       for_each_possible_cpu(cpu) {
-               struct debug_store *ds;
-               void *buffer;
-
-               err = -ENOMEM;
-               buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL);
-               if (unlikely(!buffer))
-                       break;
-
-               ds = kzalloc(sizeof(*ds), GFP_KERNEL);
-               if (unlikely(!ds)) {
-                       kfree(buffer);
-                       break;
-               }
-
-               ds->bts_buffer_base = (u64)(unsigned long)buffer;
-               ds->bts_index = ds->bts_buffer_base;
-               ds->bts_absolute_maximum =
-                       ds->bts_buffer_base + BTS_BUFFER_SIZE;
-               ds->bts_interrupt_threshold =
-                       ds->bts_absolute_maximum - BTS_OVFL_TH;
-
-               per_cpu(cpu_hw_events, cpu).ds = ds;
-               err = 0;
-       }
-
-       if (err)
-               release_bts_hardware();
-       else {
-               for_each_online_cpu(cpu)
-                       init_debug_store_on_cpu(cpu);
-       }
-
-       put_online_cpus();
+#endif
 
-       return err;
-}
+static int reserve_ds_buffers(void);
+static void release_ds_buffers(void);
 
 static void hw_perf_event_destroy(struct perf_event *event)
 {
        if (atomic_dec_and_mutex_lock(&active_events, &pmc_reserve_mutex)) {
                release_pmc_hardware();
-               release_bts_hardware();
+               release_ds_buffers();
                mutex_unlock(&pmc_reserve_mutex);
        }
 }
@@ -434,54 +428,11 @@ set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event_attr *attr)
        return 0;
 }
 
-/*
- * Setup the hardware configuration for a given attr_type
- */
-static int __hw_perf_event_init(struct perf_event *event)
+static int x86_setup_perfctr(struct perf_event *event)
 {
        struct perf_event_attr *attr = &event->attr;
        struct hw_perf_event *hwc = &event->hw;
        u64 config;
-       int err;
-
-       if (!x86_pmu_initialized())
-               return -ENODEV;
-
-       err = 0;
-       if (!atomic_inc_not_zero(&active_events)) {
-               mutex_lock(&pmc_reserve_mutex);
-               if (atomic_read(&active_events) == 0) {
-                       if (!reserve_pmc_hardware())
-                               err = -EBUSY;
-                       else
-                               err = reserve_bts_hardware();
-               }
-               if (!err)
-                       atomic_inc(&active_events);
-               mutex_unlock(&pmc_reserve_mutex);
-       }
-       if (err)
-               return err;
-
-       event->destroy = hw_perf_event_destroy;
-
-       /*
-        * Generate PMC IRQs:
-        * (keep 'enabled' bit clear for now)
-        */
-       hwc->config = ARCH_PERFMON_EVENTSEL_INT;
-
-       hwc->idx = -1;
-       hwc->last_cpu = -1;
-       hwc->last_tag = ~0ULL;
-
-       /*
-        * Count user and OS events unless requested not to.
-        */
-       if (!attr->exclude_user)
-               hwc->config |= ARCH_PERFMON_EVENTSEL_USR;
-       if (!attr->exclude_kernel)
-               hwc->config |= ARCH_PERFMON_EVENTSEL_OS;
 
        if (!hwc->sample_period) {
                hwc->sample_period = x86_pmu.max_period;
@@ -498,16 +449,8 @@ static int __hw_perf_event_init(struct perf_event *event)
                        return -EOPNOTSUPP;
        }
 
-       /*
-        * Raw hw_event type provide the config in the hw_event structure
-        */
-       if (attr->type == PERF_TYPE_RAW) {
-               hwc->config |= x86_pmu.raw_event(attr->config);
-               if ((hwc->config & ARCH_PERFMON_EVENTSEL_ANY) &&
-                   perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
-                       return -EACCES;
+       if (attr->type == PERF_TYPE_RAW)
                return 0;
-       }
 
        if (attr->type == PERF_TYPE_HW_CACHE)
                return set_ext_hw_attr(hwc, attr);
@@ -532,11 +475,11 @@ static int __hw_perf_event_init(struct perf_event *event)
        if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) &&
            (hwc->sample_period == 1)) {
                /* BTS is not supported by this architecture. */
-               if (!bts_available())
+               if (!x86_pmu.bts)
                        return -EOPNOTSUPP;
 
                /* BTS is currently only allowed for user-mode. */
-               if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
+               if (!attr->exclude_kernel)
                        return -EOPNOTSUPP;
        }
 
@@ -545,12 +488,87 @@ static int __hw_perf_event_init(struct perf_event *event)
        return 0;
 }
 
+static int x86_pmu_hw_config(struct perf_event *event)
+{
+       if (event->attr.precise_ip) {
+               int precise = 0;
+
+               /* Support for constant skid */
+               if (x86_pmu.pebs)
+                       precise++;
+
+               /* Support for IP fixup */
+               if (x86_pmu.lbr_nr)
+                       precise++;
+
+               if (event->attr.precise_ip > precise)
+                       return -EOPNOTSUPP;
+       }
+
+       /*
+        * Generate PMC IRQs:
+        * (keep 'enabled' bit clear for now)
+        */
+       event->hw.config = ARCH_PERFMON_EVENTSEL_INT;
+
+       /*
+        * Count user and OS events unless requested not to
+        */
+       if (!event->attr.exclude_user)
+               event->hw.config |= ARCH_PERFMON_EVENTSEL_USR;
+       if (!event->attr.exclude_kernel)
+               event->hw.config |= ARCH_PERFMON_EVENTSEL_OS;
+
+       if (event->attr.type == PERF_TYPE_RAW)
+               event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK;
+
+       return x86_setup_perfctr(event);
+}
+
+/*
+ * Setup the hardware configuration for a given attr_type
+ */
+static int __hw_perf_event_init(struct perf_event *event)
+{
+       int err;
+
+       if (!x86_pmu_initialized())
+               return -ENODEV;
+
+       err = 0;
+       if (!atomic_inc_not_zero(&active_events)) {
+               mutex_lock(&pmc_reserve_mutex);
+               if (atomic_read(&active_events) == 0) {
+                       if (!reserve_pmc_hardware())
+                               err = -EBUSY;
+                       else {
+                               err = reserve_ds_buffers();
+                               if (err)
+                                       release_pmc_hardware();
+                       }
+               }
+               if (!err)
+                       atomic_inc(&active_events);
+               mutex_unlock(&pmc_reserve_mutex);
+       }
+       if (err)
+               return err;
+
+       event->destroy = hw_perf_event_destroy;
+
+       event->hw.idx = -1;
+       event->hw.last_cpu = -1;
+       event->hw.last_tag = ~0ULL;
+
+       return x86_pmu.hw_config(event);
+}
+
 static void x86_pmu_disable_all(void)
 {
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
        int idx;
 
-       for (idx = 0; idx < x86_pmu.num_events; idx++) {
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
                u64 val;
 
                if (!test_bit(idx, cpuc->active_mask))
@@ -580,12 +598,12 @@ void hw_perf_disable(void)
        x86_pmu.disable_all();
 }
 
-static void x86_pmu_enable_all(void)
+static void x86_pmu_enable_all(int added)
 {
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
        int idx;
 
-       for (idx = 0; idx < x86_pmu.num_events; idx++) {
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
                struct perf_event *event = cpuc->events[idx];
                u64 val;
 
@@ -638,7 +656,7 @@ static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
                if (test_bit(hwc->idx, used_mask))
                        break;
 
-               set_bit(hwc->idx, used_mask);
+               __set_bit(hwc->idx, used_mask);
                if (assign)
                        assign[i] = hwc->idx;
        }
@@ -660,14 +678,14 @@ static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
         * assign events to counters starting with most
         * constrained events.
         */
-       wmax = x86_pmu.num_events;
+       wmax = x86_pmu.num_counters;
 
        /*
         * when fixed event counters are present,
         * wmax is incremented by 1 to account
         * for one more choice
         */
-       if (x86_pmu.num_events_fixed)
+       if (x86_pmu.num_counters_fixed)
                wmax++;
 
        for (w = 1, num = n; num && w <= wmax; w++) {
@@ -687,7 +705,7 @@ static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
                        if (j == X86_PMC_IDX_MAX)
                                break;
 
-                       set_bit(j, used_mask);
+                       __set_bit(j, used_mask);
 
                        if (assign)
                                assign[i] = j;
@@ -717,7 +735,7 @@ static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader,
        struct perf_event *event;
        int n, max_count;
 
-       max_count = x86_pmu.num_events + x86_pmu.num_events_fixed;
+       max_count = x86_pmu.num_counters + x86_pmu.num_counters_fixed;
 
        /* current number of events already accepted */
        n = cpuc->n_events;
@@ -780,6 +798,7 @@ static inline int match_prev_assignment(struct hw_perf_event *hwc,
                hwc->last_tag == cpuc->tags[i];
 }
 
+static int x86_pmu_start(struct perf_event *event);
 static void x86_pmu_stop(struct perf_event *event);
 
 void hw_perf_enable(void)
@@ -787,7 +806,7 @@ void hw_perf_enable(void)
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
        struct perf_event *event;
        struct hw_perf_event *hwc;
-       int i;
+       int i, added = cpuc->n_added;
 
        if (!x86_pmu_initialized())
                return;
@@ -796,6 +815,7 @@ void hw_perf_enable(void)
                return;
 
        if (cpuc->n_added) {
+               int n_running = cpuc->n_events - cpuc->n_added;
                /*
                 * apply assignment obtained either from
                 * hw_perf_group_sched_in() or x86_pmu_enable()
@@ -803,8 +823,7 @@ void hw_perf_enable(void)
                 * step1: save events moving to new counters
                 * step2: reprogram moved events into new counters
                 */
-               for (i = 0; i < cpuc->n_events; i++) {
-
+               for (i = 0; i < n_running; i++) {
                        event = cpuc->event_list[i];
                        hwc = &event->hw;
 
@@ -819,29 +838,18 @@ void hw_perf_enable(void)
                                continue;
 
                        x86_pmu_stop(event);
-
-                       hwc->idx = -1;
                }
 
                for (i = 0; i < cpuc->n_events; i++) {
-
                        event = cpuc->event_list[i];
                        hwc = &event->hw;
 
-                       if (hwc->idx == -1) {
+                       if (!match_prev_assignment(hwc, cpuc, i))
                                x86_assign_hw_event(event, cpuc, i);
-                               x86_perf_event_set_period(event, hwc, hwc->idx);
-                       }
-                       /*
-                        * need to mark as active because x86_pmu_disable()
-                        * clear active_mask and events[] yet it preserves
-                        * idx
-                        */
-                       set_bit(hwc->idx, cpuc->active_mask);
-                       cpuc->events[hwc->idx] = event;
+                       else if (i < n_running)
+                               continue;
 
-                       x86_pmu.enable(hwc, hwc->idx);
-                       perf_event_update_userpage(event);
+                       x86_pmu_start(event);
                }
                cpuc->n_added = 0;
                perf_events_lapic_init();
@@ -850,18 +858,20 @@ void hw_perf_enable(void)
        cpuc->enabled = 1;
        barrier();
 
-       x86_pmu.enable_all();
+       x86_pmu.enable_all(added);
 }
 
-static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, int idx)
+static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc,
+                                         u64 enable_mask)
 {
-       (void)checking_wrmsrl(hwc->config_base + idx,
-                             hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE);
+       wrmsrl(hwc->config_base + hwc->idx, hwc->config | enable_mask);
 }
 
-static inline void x86_pmu_disable_event(struct hw_perf_event *hwc, int idx)
+static inline void x86_pmu_disable_event(struct perf_event *event)
 {
-       (void)checking_wrmsrl(hwc->config_base + idx, hwc->config);
+       struct hw_perf_event *hwc = &event->hw;
+
+       wrmsrl(hwc->config_base + hwc->idx, hwc->config);
 }
 
 static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left);
@@ -871,12 +881,12 @@ static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left);
  * To be called with the event disabled in hw:
  */
 static int
-x86_perf_event_set_period(struct perf_event *event,
-                            struct hw_perf_event *hwc, int idx)
+x86_perf_event_set_period(struct perf_event *event)
 {
+       struct hw_perf_event *hwc = &event->hw;
        s64 left = atomic64_read(&hwc->period_left);
        s64 period = hwc->sample_period;
-       int err, ret = 0;
+       int ret = 0, idx = hwc->idx;
 
        if (idx == X86_PMC_IDX_FIXED_BTS)
                return 0;
@@ -914,19 +924,20 @@ x86_perf_event_set_period(struct perf_event *event,
         */
        atomic64_set(&hwc->prev_count, (u64)-left);
 
-       err = checking_wrmsrl(hwc->event_base + idx,
-                            (u64)(-left) & x86_pmu.event_mask);
+       wrmsrl(hwc->event_base + idx,
+                       (u64)(-left) & x86_pmu.cntval_mask);
 
        perf_event_update_userpage(event);
 
        return ret;
 }
 
-static void x86_pmu_enable_event(struct hw_perf_event *hwc, int idx)
+static void x86_pmu_enable_event(struct perf_event *event)
 {
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
        if (cpuc->enabled)
-               __x86_pmu_enable_event(hwc, idx);
+               __x86_pmu_enable_event(&event->hw,
+                                      ARCH_PERFMON_EVENTSEL_ENABLE);
 }
 
 /*
@@ -952,7 +963,15 @@ static int x86_pmu_enable(struct perf_event *event)
        if (n < 0)
                return n;
 
-       ret = x86_schedule_events(cpuc, n, assign);
+       /*
+        * If group events scheduling transaction was started,
+        * skip the schedulability test here, it will be peformed
+        * at commit time(->commit_txn) as a whole
+        */
+       if (cpuc->group_flag & PERF_EVENT_TXN_STARTED)
+               goto out;
+
+       ret = x86_pmu.schedule_events(cpuc, n, assign);
        if (ret)
                return ret;
        /*
@@ -961,45 +980,45 @@ static int x86_pmu_enable(struct perf_event *event)
         */
        memcpy(cpuc->assign, assign, n*sizeof(int));
 
+out:
        cpuc->n_events = n;
-       cpuc->n_added  = n - n0;
+       cpuc->n_added += n - n0;
 
        return 0;
 }
 
 static int x86_pmu_start(struct perf_event *event)
 {
-       struct hw_perf_event *hwc = &event->hw;
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       int idx = event->hw.idx;
 
-       if (hwc->idx == -1)
+       if (idx == -1)
                return -EAGAIN;
 
-       x86_perf_event_set_period(event, hwc, hwc->idx);
-       x86_pmu.enable(hwc, hwc->idx);
+       x86_perf_event_set_period(event);
+       cpuc->events[idx] = event;
+       __set_bit(idx, cpuc->active_mask);
+       x86_pmu.enable(event);
+       perf_event_update_userpage(event);
 
        return 0;
 }
 
 static void x86_pmu_unthrottle(struct perf_event *event)
 {
-       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-       struct hw_perf_event *hwc = &event->hw;
-
-       if (WARN_ON_ONCE(hwc->idx >= X86_PMC_IDX_MAX ||
-                               cpuc->events[hwc->idx] != event))
-               return;
-
-       x86_pmu.enable(hwc, hwc->idx);
+       int ret = x86_pmu_start(event);
+       WARN_ON_ONCE(ret);
 }
 
 void perf_event_print_debug(void)
 {
        u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left, fixed;
+       u64 pebs;
        struct cpu_hw_events *cpuc;
        unsigned long flags;
        int cpu, idx;
 
-       if (!x86_pmu.num_events)
+       if (!x86_pmu.num_counters)
                return;
 
        local_irq_save(flags);
@@ -1012,16 +1031,18 @@ void perf_event_print_debug(void)
                rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
                rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow);
                rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, fixed);
+               rdmsrl(MSR_IA32_PEBS_ENABLE, pebs);
 
                pr_info("\n");
                pr_info("CPU#%d: ctrl:       %016llx\n", cpu, ctrl);
                pr_info("CPU#%d: status:     %016llx\n", cpu, status);
                pr_info("CPU#%d: overflow:   %016llx\n", cpu, overflow);
                pr_info("CPU#%d: fixed:      %016llx\n", cpu, fixed);
+               pr_info("CPU#%d: pebs:       %016llx\n", cpu, pebs);
        }
-       pr_info("CPU#%d: active:       %016llx\n", cpu, *(u64 *)cpuc->active_mask);
+       pr_info("CPU#%d: active:     %016llx\n", cpu, *(u64 *)cpuc->active_mask);
 
-       for (idx = 0; idx < x86_pmu.num_events; idx++) {
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
                rdmsrl(x86_pmu.eventsel + idx, pmc_ctrl);
                rdmsrl(x86_pmu.perfctr  + idx, pmc_count);
 
@@ -1034,7 +1055,7 @@ void perf_event_print_debug(void)
                pr_info("CPU#%d:   gen-PMC%d left:  %016llx\n",
                        cpu, idx, prev_left);
        }
-       for (idx = 0; idx < x86_pmu.num_events_fixed; idx++) {
+       for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) {
                rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, pmc_count);
 
                pr_info("CPU#%d: fixed-PMC%d count: %016llx\n",
@@ -1049,18 +1070,16 @@ static void x86_pmu_stop(struct perf_event *event)
        struct hw_perf_event *hwc = &event->hw;
        int idx = hwc->idx;
 
-       /*
-        * Must be done before we disable, otherwise the nmi handler
-        * could reenable again:
-        */
-       clear_bit(idx, cpuc->active_mask);
-       x86_pmu.disable(hwc, idx);
+       if (!__test_and_clear_bit(idx, cpuc->active_mask))
+               return;
+
+       x86_pmu.disable(event);
 
        /*
         * Drain the remaining delta count out of a event
         * that we are disabling:
         */
-       x86_perf_event_update(event, hwc, idx);
+       x86_perf_event_update(event);
 
        cpuc->events[idx] = NULL;
 }
@@ -1101,15 +1120,15 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
 
        cpuc = &__get_cpu_var(cpu_hw_events);
 
-       for (idx = 0; idx < x86_pmu.num_events; idx++) {
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
                if (!test_bit(idx, cpuc->active_mask))
                        continue;
 
                event = cpuc->events[idx];
                hwc = &event->hw;
 
-               val = x86_perf_event_update(event, hwc, idx);
-               if (val & (1ULL << (x86_pmu.event_bits - 1)))
+               val = x86_perf_event_update(event);
+               if (val & (1ULL << (x86_pmu.cntval_bits - 1)))
                        continue;
 
                /*
@@ -1118,11 +1137,11 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
                handled         = 1;
                data.period     = event->hw.last_period;
 
-               if (!x86_perf_event_set_period(event, hwc, idx))
+               if (!x86_perf_event_set_period(event))
                        continue;
 
                if (perf_event_overflow(event, 1, &data, regs))
-                       x86_pmu.disable(hwc, idx);
+                       x86_pmu_stop(event);
        }
 
        if (handled)
@@ -1152,7 +1171,6 @@ void set_perf_event_pending(void)
 
 void perf_events_lapic_init(void)
 {
-#ifdef CONFIG_X86_LOCAL_APIC
        if (!x86_pmu.apic || !x86_pmu_initialized())
                return;
 
@@ -1160,7 +1178,6 @@ void perf_events_lapic_init(void)
         * Always use NMI for PMU
         */
        apic_write(APIC_LVTPC, APIC_DM_NMI);
-#endif
 }
 
 static int __kprobes
@@ -1184,9 +1201,7 @@ perf_event_nmi_handler(struct notifier_block *self,
 
        regs = args->regs;
 
-#ifdef CONFIG_X86_LOCAL_APIC
        apic_write(APIC_LVTPC, APIC_DM_NMI);
-#endif
        /*
         * Can't rely on the handled return value to say it was our NMI, two
         * events could trigger 'simultaneously' raising two back-to-back NMIs.
@@ -1223,120 +1238,48 @@ x86_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
        return &unconstrained;
 }
 
-static int x86_event_sched_in(struct perf_event *event,
-                         struct perf_cpu_context *cpuctx)
-{
-       int ret = 0;
-
-       event->state = PERF_EVENT_STATE_ACTIVE;
-       event->oncpu = smp_processor_id();
-       event->tstamp_running += event->ctx->time - event->tstamp_stopped;
-
-       if (!is_x86_event(event))
-               ret = event->pmu->enable(event);
-
-       if (!ret && !is_software_event(event))
-               cpuctx->active_oncpu++;
-
-       if (!ret && event->attr.exclusive)
-               cpuctx->exclusive = 1;
-
-       return ret;
-}
+#include "perf_event_amd.c"
+#include "perf_event_p6.c"
+#include "perf_event_p4.c"
+#include "perf_event_intel_lbr.c"
+#include "perf_event_intel_ds.c"
+#include "perf_event_intel.c"
 
-static void x86_event_sched_out(struct perf_event *event,
-                           struct perf_cpu_context *cpuctx)
+static int __cpuinit
+x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
 {
-       event->state = PERF_EVENT_STATE_INACTIVE;
-       event->oncpu = -1;
-
-       if (!is_x86_event(event))
-               event->pmu->disable(event);
-
-       event->tstamp_running -= event->ctx->time - event->tstamp_stopped;
-
-       if (!is_software_event(event))
-               cpuctx->active_oncpu--;
-
-       if (event->attr.exclusive || !cpuctx->active_oncpu)
-               cpuctx->exclusive = 0;
-}
+       unsigned int cpu = (long)hcpu;
+       int ret = NOTIFY_OK;
 
-/*
- * Called to enable a whole group of events.
- * Returns 1 if the group was enabled, or -EAGAIN if it could not be.
- * Assumes the caller has disabled interrupts and has
- * frozen the PMU with hw_perf_save_disable.
- *
- * called with PMU disabled. If successful and return value 1,
- * then guaranteed to call perf_enable() and hw_perf_enable()
- */
-int hw_perf_group_sched_in(struct perf_event *leader,
-              struct perf_cpu_context *cpuctx,
-              struct perf_event_context *ctx)
-{
-       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-       struct perf_event *sub;
-       int assign[X86_PMC_IDX_MAX];
-       int n0, n1, ret;
+       switch (action & ~CPU_TASKS_FROZEN) {
+       case CPU_UP_PREPARE:
+               if (x86_pmu.cpu_prepare)
+                       ret = x86_pmu.cpu_prepare(cpu);
+               break;
 
-       /* n0 = total number of events */
-       n0 = collect_events(cpuc, leader, true);
-       if (n0 < 0)
-               return n0;
+       case CPU_STARTING:
+               if (x86_pmu.cpu_starting)
+                       x86_pmu.cpu_starting(cpu);
+               break;
 
-       ret = x86_schedule_events(cpuc, n0, assign);
-       if (ret)
-               return ret;
+       case CPU_DYING:
+               if (x86_pmu.cpu_dying)
+                       x86_pmu.cpu_dying(cpu);
+               break;
 
-       ret = x86_event_sched_in(leader, cpuctx);
-       if (ret)
-               return ret;
+       case CPU_UP_CANCELED:
+       case CPU_DEAD:
+               if (x86_pmu.cpu_dead)
+                       x86_pmu.cpu_dead(cpu);
+               break;
 
-       n1 = 1;
-       list_for_each_entry(sub, &leader->sibling_list, group_entry) {
-               if (sub->state > PERF_EVENT_STATE_OFF) {
-                       ret = x86_event_sched_in(sub, cpuctx);
-                       if (ret)
-                               goto undo;
-                       ++n1;
-               }
+       default:
+               break;
        }
-       /*
-        * copy new assignment, now we know it is possible
-        * will be used by hw_perf_enable()
-        */
-       memcpy(cpuc->assign, assign, n0*sizeof(int));
-
-       cpuc->n_events  = n0;
-       cpuc->n_added   = n1;
-       ctx->nr_active += n1;
 
-       /*
-        * 1 means successful and events are active
-        * This is not quite true because we defer
-        * actual activation until hw_perf_enable() but
-        * this way we* ensure caller won't try to enable
-        * individual events
-        */
-       return 1;
-undo:
-       x86_event_sched_out(leader, cpuctx);
-       n0  = 1;
-       list_for_each_entry(sub, &leader->sibling_list, group_entry) {
-               if (sub->state == PERF_EVENT_STATE_ACTIVE) {
-                       x86_event_sched_out(sub, cpuctx);
-                       if (++n0 == n1)
-                               break;
-               }
-       }
        return ret;
 }
 
-#include "perf_event_amd.c"
-#include "perf_event_p6.c"
-#include "perf_event_intel.c"
-
 static void __init pmu_check_apic(void)
 {
        if (cpu_has_apic)
@@ -1373,53 +1316,110 @@ void __init init_hw_perf_events(void)
 
        pr_cont("%s PMU driver.\n", x86_pmu.name);
 
-       if (x86_pmu.num_events > X86_PMC_MAX_GENERIC) {
+       if (x86_pmu.quirks)
+               x86_pmu.quirks();
+
+       if (x86_pmu.num_counters > X86_PMC_MAX_GENERIC) {
                WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
-                    x86_pmu.num_events, X86_PMC_MAX_GENERIC);
-               x86_pmu.num_events = X86_PMC_MAX_GENERIC;
+                    x86_pmu.num_counters, X86_PMC_MAX_GENERIC);
+               x86_pmu.num_counters = X86_PMC_MAX_GENERIC;
        }
-       perf_event_mask = (1 << x86_pmu.num_events) - 1;
-       perf_max_events = x86_pmu.num_events;
+       x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
+       perf_max_events = x86_pmu.num_counters;
 
-       if (x86_pmu.num_events_fixed > X86_PMC_MAX_FIXED) {
+       if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) {
                WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
-                    x86_pmu.num_events_fixed, X86_PMC_MAX_FIXED);
-               x86_pmu.num_events_fixed = X86_PMC_MAX_FIXED;
+                    x86_pmu.num_counters_fixed, X86_PMC_MAX_FIXED);
+               x86_pmu.num_counters_fixed = X86_PMC_MAX_FIXED;
        }
 
-       perf_event_mask |=
-               ((1LL << x86_pmu.num_events_fixed)-1) << X86_PMC_IDX_FIXED;
-       x86_pmu.intel_ctrl = perf_event_mask;
+       x86_pmu.intel_ctrl |=
+               ((1LL << x86_pmu.num_counters_fixed)-1) << X86_PMC_IDX_FIXED;
 
        perf_events_lapic_init();
        register_die_notifier(&perf_event_nmi_notifier);
 
        unconstrained = (struct event_constraint)
-               __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_events) - 1,
-                                  0, x86_pmu.num_events);
+               __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1,
+                                  0, x86_pmu.num_counters);
 
        if (x86_pmu.event_constraints) {
                for_each_event_constraint(c, x86_pmu.event_constraints) {
-                       if (c->cmask != INTEL_ARCH_FIXED_MASK)
+                       if (c->cmask != X86_RAW_EVENT_MASK)
                                continue;
 
-                       c->idxmsk64 |= (1ULL << x86_pmu.num_events) - 1;
-                       c->weight += x86_pmu.num_events;
+                       c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
+                       c->weight += x86_pmu.num_counters;
                }
        }
 
        pr_info("... version:                %d\n",     x86_pmu.version);
-       pr_info("... bit width:              %d\n",     x86_pmu.event_bits);
-       pr_info("... generic registers:      %d\n",     x86_pmu.num_events);
-       pr_info("... value mask:             %016Lx\n", x86_pmu.event_mask);
+       pr_info("... bit width:              %d\n",     x86_pmu.cntval_bits);
+       pr_info("... generic registers:      %d\n",     x86_pmu.num_counters);
+       pr_info("... value mask:             %016Lx\n", x86_pmu.cntval_mask);
        pr_info("... max period:             %016Lx\n", x86_pmu.max_period);
-       pr_info("... fixed-purpose events:   %d\n",     x86_pmu.num_events_fixed);
-       pr_info("... event mask:             %016Lx\n", perf_event_mask);
+       pr_info("... fixed-purpose events:   %d\n",     x86_pmu.num_counters_fixed);
+       pr_info("... event mask:             %016Lx\n", x86_pmu.intel_ctrl);
+
+       perf_cpu_notifier(x86_pmu_notifier);
 }
 
 static inline void x86_pmu_read(struct perf_event *event)
 {
-       x86_perf_event_update(event, &event->hw, event->hw.idx);
+       x86_perf_event_update(event);
+}
+
+/*
+ * Start group events scheduling transaction
+ * Set the flag to make pmu::enable() not perform the
+ * schedulability test, it will be performed at commit time
+ */
+static void x86_pmu_start_txn(const struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       cpuc->group_flag |= PERF_EVENT_TXN_STARTED;
+}
+
+/*
+ * Stop group events scheduling transaction
+ * Clear the flag and pmu::enable() will perform the
+ * schedulability test.
+ */
+static void x86_pmu_cancel_txn(const struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       cpuc->group_flag &= ~PERF_EVENT_TXN_STARTED;
+}
+
+/*
+ * Commit group events scheduling transaction
+ * Perform the group schedulability test as a whole
+ * Return 0 if success
+ */
+static int x86_pmu_commit_txn(const struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       int assign[X86_PMC_IDX_MAX];
+       int n, ret;
+
+       n = cpuc->n_events;
+
+       if (!x86_pmu_initialized())
+               return -EAGAIN;
+
+       ret = x86_pmu.schedule_events(cpuc, n, assign);
+       if (ret)
+               return ret;
+
+       /*
+        * copy new assignment, now we know it is possible
+        * will be used by hw_perf_enable()
+        */
+       memcpy(cpuc->assign, assign, n*sizeof(int));
+
+       return 0;
 }
 
 static const struct pmu pmu = {
@@ -1429,8 +1429,37 @@ static const struct pmu pmu = {
        .stop           = x86_pmu_stop,
        .read           = x86_pmu_read,
        .unthrottle     = x86_pmu_unthrottle,
+       .start_txn      = x86_pmu_start_txn,
+       .cancel_txn     = x86_pmu_cancel_txn,
+       .commit_txn     = x86_pmu_commit_txn,
 };
 
+/*
+ * validate that we can schedule this event
+ */
+static int validate_event(struct perf_event *event)
+{
+       struct cpu_hw_events *fake_cpuc;
+       struct event_constraint *c;
+       int ret = 0;
+
+       fake_cpuc = kmalloc(sizeof(*fake_cpuc), GFP_KERNEL | __GFP_ZERO);
+       if (!fake_cpuc)
+               return -ENOMEM;
+
+       c = x86_pmu.get_event_constraints(fake_cpuc, event);
+
+       if (!c || !c->weight)
+               ret = -ENOSPC;
+
+       if (x86_pmu.put_event_constraints)
+               x86_pmu.put_event_constraints(fake_cpuc, event);
+
+       kfree(fake_cpuc);
+
+       return ret;
+}
+
 /*
  * validate a single event group
  *
@@ -1471,7 +1500,7 @@ static int validate_group(struct perf_event *event)
 
        fake_cpuc->n_events = n;
 
-       ret = x86_schedule_events(fake_cpuc, n, NULL);
+       ret = x86_pmu.schedule_events(fake_cpuc, n, NULL);
 
 out_free:
        kfree(fake_cpuc);
@@ -1496,6 +1525,8 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
 
                if (event->group_leader != event)
                        err = validate_group(event);
+               else
+                       err = validate_event(event);
 
                event->pmu = tmp;
        }
@@ -1543,8 +1574,7 @@ static void backtrace_address(void *data, unsigned long addr, int reliable)
 {
        struct perf_callchain_entry *entry = data;
 
-       if (reliable)
-               callchain_store(entry, addr);
+       callchain_store(entry, addr);
 }
 
 static const struct stacktrace_ops backtrace_ops = {
@@ -1566,49 +1596,42 @@ perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry)
        dump_trace(NULL, regs, NULL, regs->bp, &backtrace_ops, entry);
 }
 
-/*
- * best effort, GUP based copy_from_user() that assumes IRQ or NMI context
- */
-static unsigned long
-copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
+#ifdef CONFIG_COMPAT
+static inline int
+perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
 {
-       unsigned long offset, addr = (unsigned long)from;
-       int type = in_nmi() ? KM_NMI : KM_IRQ0;
-       unsigned long size, len = 0;
-       struct page *page;
-       void *map;
-       int ret;
-
-       do {
-               ret = __get_user_pages_fast(addr, 1, 0, &page);
-               if (!ret)
-                       break;
+       /* 32-bit process in 64-bit kernel. */
+       struct stack_frame_ia32 frame;
+       const void __user *fp;
 
-               offset = addr & (PAGE_SIZE - 1);
-               size = min(PAGE_SIZE - offset, n - len);
+       if (!test_thread_flag(TIF_IA32))
+               return 0;
 
-               map = kmap_atomic(page, type);
-               memcpy(to, map+offset, size);
-               kunmap_atomic(map, type);
-               put_page(page);
+       fp = compat_ptr(regs->bp);
+       while (entry->nr < PERF_MAX_STACK_DEPTH) {
+               unsigned long bytes;
+               frame.next_frame     = 0;
+               frame.return_address = 0;
 
-               len  += size;
-               to   += size;
-               addr += size;
+               bytes = copy_from_user_nmi(&frame, fp, sizeof(frame));
+               if (bytes != sizeof(frame))
+                       break;
 
-       } while (len < n);
+               if (fp < compat_ptr(regs->sp))
+                       break;
 
-       return len;
+               callchain_store(entry, frame.return_address);
+               fp = compat_ptr(frame.next_frame);
+       }
+       return 1;
 }
-
-static int copy_stack_frame(const void __user *fp, struct stack_frame *frame)
+#else
+static inline int
+perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
 {
-       unsigned long bytes;
-
-       bytes = copy_from_user_nmi(frame, fp, sizeof(*frame));
-
-       return bytes == sizeof(*frame);
+    return 0;
 }
+#endif
 
 static void
 perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry)
@@ -1624,11 +1647,16 @@ perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry)
        callchain_store(entry, PERF_CONTEXT_USER);
        callchain_store(entry, regs->ip);
 
+       if (perf_callchain_user32(regs, entry))
+               return;
+
        while (entry->nr < PERF_MAX_STACK_DEPTH) {
+               unsigned long bytes;
                frame.next_frame             = NULL;
                frame.return_address = 0;
 
-               if (!copy_stack_frame(fp, &frame))
+               bytes = copy_from_user_nmi(&frame, fp, sizeof(frame));
+               if (bytes != sizeof(frame))
                        break;
 
                if ((unsigned long)fp < regs->sp)
@@ -1663,6 +1691,11 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
 {
        struct perf_callchain_entry *entry;
 
+       if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+               /* TODO: We don't support guest os callchain now */
+               return NULL;
+       }
+
        if (in_nmi())
                entry = &__get_cpu_var(pmc_nmi_entry);
        else
@@ -1675,28 +1708,48 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
        return entry;
 }
 
-void hw_perf_event_setup_online(int cpu)
+void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip)
 {
-       init_debug_store_on_cpu(cpu);
+       regs->ip = ip;
+       /*
+        * perf_arch_fetch_caller_regs adds another call, we need to increment
+        * the skip level
+        */
+       regs->bp = rewind_frame_pointer(skip + 1);
+       regs->cs = __KERNEL_CS;
+       local_save_flags(regs->flags);
+}
 
-       switch (boot_cpu_data.x86_vendor) {
-       case X86_VENDOR_AMD:
-               amd_pmu_cpu_online(cpu);
-               break;
-       default:
-               return;
-       }
+unsigned long perf_instruction_pointer(struct pt_regs *regs)
+{
+       unsigned long ip;
+
+       if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
+               ip = perf_guest_cbs->get_guest_ip();
+       else
+               ip = instruction_pointer(regs);
+
+       return ip;
 }
 
-void hw_perf_event_setup_offline(int cpu)
+unsigned long perf_misc_flags(struct pt_regs *regs)
 {
-       init_debug_store_on_cpu(cpu);
+       int misc = 0;
 
-       switch (boot_cpu_data.x86_vendor) {
-       case X86_VENDOR_AMD:
-               amd_pmu_cpu_offline(cpu);
-               break;
-       default:
-               return;
+       if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+               if (perf_guest_cbs->is_user_mode())
+                       misc |= PERF_RECORD_MISC_GUEST_USER;
+               else
+                       misc |= PERF_RECORD_MISC_GUEST_KERNEL;
+       } else {
+               if (user_mode(regs))
+                       misc |= PERF_RECORD_MISC_USER;
+               else
+                       misc |= PERF_RECORD_MISC_KERNEL;
        }
+
+       if (regs->flags & PERF_EFLAGS_EXACT)
+               misc |= PERF_RECORD_MISC_EXACT_IP;
+
+       return misc;
 }
index 8f3dbfda3c4f0553f7687856337637ab153baa88..611df11ba15e7f9145e49f2fa2c7e61b1371d77c 100644 (file)
@@ -2,7 +2,7 @@
 
 static DEFINE_RAW_SPINLOCK(amd_nb_lock);
 
-static __initconst u64 amd_hw_cache_event_ids
+static __initconst const u64 amd_hw_cache_event_ids
                                [PERF_COUNT_HW_CACHE_MAX]
                                [PERF_COUNT_HW_CACHE_OP_MAX]
                                [PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -111,22 +111,19 @@ static u64 amd_pmu_event_map(int hw_event)
        return amd_perfmon_event_map[hw_event];
 }
 
-static u64 amd_pmu_raw_event(u64 hw_event)
+static int amd_pmu_hw_config(struct perf_event *event)
 {
-#define K7_EVNTSEL_EVENT_MASK  0xF000000FFULL
-#define K7_EVNTSEL_UNIT_MASK   0x00000FF00ULL
-#define K7_EVNTSEL_EDGE_MASK   0x000040000ULL
-#define K7_EVNTSEL_INV_MASK    0x000800000ULL
-#define K7_EVNTSEL_REG_MASK    0x0FF000000ULL
-
-#define K7_EVNTSEL_MASK                        \
-       (K7_EVNTSEL_EVENT_MASK |        \
-        K7_EVNTSEL_UNIT_MASK  |        \
-        K7_EVNTSEL_EDGE_MASK  |        \
-        K7_EVNTSEL_INV_MASK   |        \
-        K7_EVNTSEL_REG_MASK)
-
-       return hw_event & K7_EVNTSEL_MASK;
+       int ret = x86_pmu_hw_config(event);
+
+       if (ret)
+               return ret;
+
+       if (event->attr.type != PERF_TYPE_RAW)
+               return 0;
+
+       event->hw.config |= event->attr.config & AMD64_RAW_EVENT_MASK;
+
+       return 0;
 }
 
 /*
@@ -137,6 +134,13 @@ static inline int amd_is_nb_event(struct hw_perf_event *hwc)
        return (hwc->config & 0xe0) == 0xe0;
 }
 
+static inline int amd_has_nb(struct cpu_hw_events *cpuc)
+{
+       struct amd_nb *nb = cpuc->amd_nb;
+
+       return nb && nb->nb_id != -1;
+}
+
 static void amd_put_event_constraints(struct cpu_hw_events *cpuc,
                                      struct perf_event *event)
 {
@@ -147,7 +151,7 @@ static void amd_put_event_constraints(struct cpu_hw_events *cpuc,
        /*
         * only care about NB events
         */
-       if (!(nb && amd_is_nb_event(hwc)))
+       if (!(amd_has_nb(cpuc) && amd_is_nb_event(hwc)))
                return;
 
        /*
@@ -158,7 +162,7 @@ static void amd_put_event_constraints(struct cpu_hw_events *cpuc,
         * be removed on one CPU at a time AND PMU is disabled
         * when we come here
         */
-       for (i = 0; i < x86_pmu.num_events; i++) {
+       for (i = 0; i < x86_pmu.num_counters; i++) {
                if (nb->owners[i] == event) {
                        cmpxchg(nb->owners+i, event, NULL);
                        break;
@@ -208,13 +212,13 @@ amd_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
        struct hw_perf_event *hwc = &event->hw;
        struct amd_nb *nb = cpuc->amd_nb;
        struct perf_event *old = NULL;
-       int max = x86_pmu.num_events;
+       int max = x86_pmu.num_counters;
        int i, j, k = -1;
 
        /*
         * if not NB event or no NB, then no constraints
         */
-       if (!(nb && amd_is_nb_event(hwc)))
+       if (!(amd_has_nb(cpuc) && amd_is_nb_event(hwc)))
                return &unconstrained;
 
        /*
@@ -271,28 +275,6 @@ done:
        return &emptyconstraint;
 }
 
-static __initconst struct x86_pmu amd_pmu = {
-       .name                   = "AMD",
-       .handle_irq             = x86_pmu_handle_irq,
-       .disable_all            = x86_pmu_disable_all,
-       .enable_all             = x86_pmu_enable_all,
-       .enable                 = x86_pmu_enable_event,
-       .disable                = x86_pmu_disable_event,
-       .eventsel               = MSR_K7_EVNTSEL0,
-       .perfctr                = MSR_K7_PERFCTR0,
-       .event_map              = amd_pmu_event_map,
-       .raw_event              = amd_pmu_raw_event,
-       .max_events             = ARRAY_SIZE(amd_perfmon_event_map),
-       .num_events             = 4,
-       .event_bits             = 48,
-       .event_mask             = (1ULL << 48) - 1,
-       .apic                   = 1,
-       /* use highest bit to detect overflow */
-       .max_period             = (1ULL << 47) - 1,
-       .get_event_constraints  = amd_get_event_constraints,
-       .put_event_constraints  = amd_put_event_constraints
-};
-
 static struct amd_nb *amd_alloc_nb(int cpu, int nb_id)
 {
        struct amd_nb *nb;
@@ -308,58 +290,62 @@ static struct amd_nb *amd_alloc_nb(int cpu, int nb_id)
        /*
         * initialize all possible NB constraints
         */
-       for (i = 0; i < x86_pmu.num_events; i++) {
-               set_bit(i, nb->event_constraints[i].idxmsk);
+       for (i = 0; i < x86_pmu.num_counters; i++) {
+               __set_bit(i, nb->event_constraints[i].idxmsk);
                nb->event_constraints[i].weight = 1;
        }
        return nb;
 }
 
-static void amd_pmu_cpu_online(int cpu)
+static int amd_pmu_cpu_prepare(int cpu)
+{
+       struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+
+       WARN_ON_ONCE(cpuc->amd_nb);
+
+       if (boot_cpu_data.x86_max_cores < 2)
+               return NOTIFY_OK;
+
+       cpuc->amd_nb = amd_alloc_nb(cpu, -1);
+       if (!cpuc->amd_nb)
+               return NOTIFY_BAD;
+
+       return NOTIFY_OK;
+}
+
+static void amd_pmu_cpu_starting(int cpu)
 {
-       struct cpu_hw_events *cpu1, *cpu2;
-       struct amd_nb *nb = NULL;
+       struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+       struct amd_nb *nb;
        int i, nb_id;
 
        if (boot_cpu_data.x86_max_cores < 2)
                return;
 
-       /*
-        * function may be called too early in the
-        * boot process, in which case nb_id is bogus
-        */
        nb_id = amd_get_nb_id(cpu);
-       if (nb_id == BAD_APICID)
-               return;
-
-       cpu1 = &per_cpu(cpu_hw_events, cpu);
-       cpu1->amd_nb = NULL;
+       WARN_ON_ONCE(nb_id == BAD_APICID);
 
        raw_spin_lock(&amd_nb_lock);
 
        for_each_online_cpu(i) {
-               cpu2 = &per_cpu(cpu_hw_events, i);
-               nb = cpu2->amd_nb;
-               if (!nb)
+               nb = per_cpu(cpu_hw_events, i).amd_nb;
+               if (WARN_ON_ONCE(!nb))
                        continue;
-               if (nb->nb_id == nb_id)
-                       goto found;
-       }
 
-       nb = amd_alloc_nb(cpu, nb_id);
-       if (!nb) {
-               pr_err("perf_events: failed NB allocation for CPU%d\n", cpu);
-               raw_spin_unlock(&amd_nb_lock);
-               return;
+               if (nb->nb_id == nb_id) {
+                       kfree(cpuc->amd_nb);
+                       cpuc->amd_nb = nb;
+                       break;
+               }
        }
-found:
-       nb->refcnt++;
-       cpu1->amd_nb = nb;
+
+       cpuc->amd_nb->nb_id = nb_id;
+       cpuc->amd_nb->refcnt++;
 
        raw_spin_unlock(&amd_nb_lock);
 }
 
-static void amd_pmu_cpu_offline(int cpu)
+static void amd_pmu_cpu_dead(int cpu)
 {
        struct cpu_hw_events *cpuhw;
 
@@ -370,14 +356,45 @@ static void amd_pmu_cpu_offline(int cpu)
 
        raw_spin_lock(&amd_nb_lock);
 
-       if (--cpuhw->amd_nb->refcnt == 0)
-               kfree(cpuhw->amd_nb);
+       if (cpuhw->amd_nb) {
+               struct amd_nb *nb = cpuhw->amd_nb;
+
+               if (nb->nb_id == -1 || --nb->refcnt == 0)
+                       kfree(nb);
 
-       cpuhw->amd_nb = NULL;
+               cpuhw->amd_nb = NULL;
+       }
 
        raw_spin_unlock(&amd_nb_lock);
 }
 
+static __initconst const struct x86_pmu amd_pmu = {
+       .name                   = "AMD",
+       .handle_irq             = x86_pmu_handle_irq,
+       .disable_all            = x86_pmu_disable_all,
+       .enable_all             = x86_pmu_enable_all,
+       .enable                 = x86_pmu_enable_event,
+       .disable                = x86_pmu_disable_event,
+       .hw_config              = amd_pmu_hw_config,
+       .schedule_events        = x86_schedule_events,
+       .eventsel               = MSR_K7_EVNTSEL0,
+       .perfctr                = MSR_K7_PERFCTR0,
+       .event_map              = amd_pmu_event_map,
+       .max_events             = ARRAY_SIZE(amd_perfmon_event_map),
+       .num_counters           = 4,
+       .cntval_bits            = 48,
+       .cntval_mask            = (1ULL << 48) - 1,
+       .apic                   = 1,
+       /* use highest bit to detect overflow */
+       .max_period             = (1ULL << 47) - 1,
+       .get_event_constraints  = amd_get_event_constraints,
+       .put_event_constraints  = amd_put_event_constraints,
+
+       .cpu_prepare            = amd_pmu_cpu_prepare,
+       .cpu_starting           = amd_pmu_cpu_starting,
+       .cpu_dead               = amd_pmu_cpu_dead,
+};
+
 static __init int amd_pmu_init(void)
 {
        /* Performance-monitoring supported from K7 and later: */
@@ -390,11 +407,6 @@ static __init int amd_pmu_init(void)
        memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
               sizeof(hw_cache_event_ids));
 
-       /*
-        * explicitly initialize the boot cpu, other cpus will get
-        * the cpu hotplug callbacks from smp_init()
-        */
-       amd_pmu_cpu_online(smp_processor_id());
        return 0;
 }
 
@@ -405,12 +417,4 @@ static int amd_pmu_init(void)
        return 0;
 }
 
-static void amd_pmu_cpu_online(int cpu)
-{
-}
-
-static void amd_pmu_cpu_offline(int cpu)
-{
-}
-
 #endif
index 44b60c8521070fa40852be25a44a0fa989578fde..fdbc652d3febaa5b7da8a3b844d5a031a677d4a0 100644 (file)
@@ -88,7 +88,7 @@ static u64 intel_pmu_event_map(int hw_event)
        return intel_perfmon_event_map[hw_event];
 }
 
-static __initconst u64 westmere_hw_cache_event_ids
+static __initconst const u64 westmere_hw_cache_event_ids
                                [PERF_COUNT_HW_CACHE_MAX]
                                [PERF_COUNT_HW_CACHE_OP_MAX]
                                [PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -179,7 +179,7 @@ static __initconst u64 westmere_hw_cache_event_ids
  },
 };
 
-static __initconst u64 nehalem_hw_cache_event_ids
+static __initconst const u64 nehalem_hw_cache_event_ids
                                [PERF_COUNT_HW_CACHE_MAX]
                                [PERF_COUNT_HW_CACHE_OP_MAX]
                                [PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -270,7 +270,7 @@ static __initconst u64 nehalem_hw_cache_event_ids
  },
 };
 
-static __initconst u64 core2_hw_cache_event_ids
+static __initconst const u64 core2_hw_cache_event_ids
                                [PERF_COUNT_HW_CACHE_MAX]
                                [PERF_COUNT_HW_CACHE_OP_MAX]
                                [PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -361,7 +361,7 @@ static __initconst u64 core2_hw_cache_event_ids
  },
 };
 
-static __initconst u64 atom_hw_cache_event_ids
+static __initconst const u64 atom_hw_cache_event_ids
                                [PERF_COUNT_HW_CACHE_MAX]
                                [PERF_COUNT_HW_CACHE_OP_MAX]
                                [PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -452,60 +452,6 @@ static __initconst u64 atom_hw_cache_event_ids
  },
 };
 
-static u64 intel_pmu_raw_event(u64 hw_event)
-{
-#define CORE_EVNTSEL_EVENT_MASK                0x000000FFULL
-#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_MASK              \
-       (INTEL_ARCH_EVTSEL_MASK |       \
-        INTEL_ARCH_UNIT_MASK   |       \
-        INTEL_ARCH_EDGE_MASK   |       \
-        INTEL_ARCH_INV_MASK    |       \
-        INTEL_ARCH_CNT_MASK)
-
-       return hw_event & CORE_EVNTSEL_MASK;
-}
-
-static void intel_pmu_enable_bts(u64 config)
-{
-       unsigned long debugctlmsr;
-
-       debugctlmsr = get_debugctlmsr();
-
-       debugctlmsr |= X86_DEBUGCTL_TR;
-       debugctlmsr |= X86_DEBUGCTL_BTS;
-       debugctlmsr |= X86_DEBUGCTL_BTINT;
-
-       if (!(config & ARCH_PERFMON_EVENTSEL_OS))
-               debugctlmsr |= X86_DEBUGCTL_BTS_OFF_OS;
-
-       if (!(config & ARCH_PERFMON_EVENTSEL_USR))
-               debugctlmsr |= X86_DEBUGCTL_BTS_OFF_USR;
-
-       update_debugctlmsr(debugctlmsr);
-}
-
-static void intel_pmu_disable_bts(void)
-{
-       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-       unsigned long debugctlmsr;
-
-       if (!cpuc->ds)
-               return;
-
-       debugctlmsr = get_debugctlmsr();
-
-       debugctlmsr &=
-               ~(X86_DEBUGCTL_TR | X86_DEBUGCTL_BTS | X86_DEBUGCTL_BTINT |
-                 X86_DEBUGCTL_BTS_OFF_OS | X86_DEBUGCTL_BTS_OFF_USR);
-
-       update_debugctlmsr(debugctlmsr);
-}
-
 static void intel_pmu_disable_all(void)
 {
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
@@ -514,12 +460,17 @@ static void intel_pmu_disable_all(void)
 
        if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask))
                intel_pmu_disable_bts();
+
+       intel_pmu_pebs_disable_all();
+       intel_pmu_lbr_disable_all();
 }
 
-static void intel_pmu_enable_all(void)
+static void intel_pmu_enable_all(int added)
 {
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 
+       intel_pmu_pebs_enable_all();
+       intel_pmu_lbr_enable_all();
        wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl);
 
        if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
@@ -533,6 +484,42 @@ static void intel_pmu_enable_all(void)
        }
 }
 
+/*
+ * Workaround for:
+ *   Intel Errata AAK100 (model 26)
+ *   Intel Errata AAP53  (model 30)
+ *   Intel Errata BD53   (model 44)
+ *
+ * These chips need to be 'reset' when adding counters by programming
+ * the magic three (non counting) events 0x4300D2, 0x4300B1 and 0x4300B5
+ * either in sequence on the same PMC or on different PMCs.
+ */
+static void intel_pmu_nhm_enable_all(int added)
+{
+       if (added) {
+               struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+               int i;
+
+               wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 0, 0x4300D2);
+               wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 1, 0x4300B1);
+               wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 2, 0x4300B5);
+
+               wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x3);
+               wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x0);
+
+               for (i = 0; i < 3; i++) {
+                       struct perf_event *event = cpuc->events[i];
+
+                       if (!event)
+                               continue;
+
+                       __x86_pmu_enable_event(&event->hw,
+                                              ARCH_PERFMON_EVENTSEL_ENABLE);
+               }
+       }
+       intel_pmu_enable_all(added);
+}
+
 static inline u64 intel_pmu_get_status(void)
 {
        u64 status;
@@ -547,102 +534,43 @@ static inline void intel_pmu_ack_status(u64 ack)
        wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
 }
 
-static inline void
-intel_pmu_disable_fixed(struct hw_perf_event *hwc, int __idx)
+static void intel_pmu_disable_fixed(struct hw_perf_event *hwc)
 {
-       int idx = __idx - X86_PMC_IDX_FIXED;
+       int idx = hwc->idx - X86_PMC_IDX_FIXED;
        u64 ctrl_val, mask;
 
        mask = 0xfULL << (idx * 4);
 
        rdmsrl(hwc->config_base, ctrl_val);
        ctrl_val &= ~mask;
-       (void)checking_wrmsrl(hwc->config_base, ctrl_val);
+       wrmsrl(hwc->config_base, ctrl_val);
 }
 
-static void intel_pmu_drain_bts_buffer(void)
+static void intel_pmu_disable_event(struct perf_event *event)
 {
-       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-       struct debug_store *ds = cpuc->ds;
-       struct bts_record {
-               u64     from;
-               u64     to;
-               u64     flags;
-       };
-       struct perf_event *event = cpuc->events[X86_PMC_IDX_FIXED_BTS];
-       struct bts_record *at, *top;
-       struct perf_output_handle handle;
-       struct perf_event_header header;
-       struct perf_sample_data data;
-       struct pt_regs regs;
-
-       if (!event)
-               return;
-
-       if (!ds)
-               return;
-
-       at  = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
-       top = (struct bts_record *)(unsigned long)ds->bts_index;
-
-       if (top <= at)
-               return;
-
-       ds->bts_index = ds->bts_buffer_base;
-
-       perf_sample_data_init(&data, 0);
-
-       data.period     = event->hw.last_period;
-       regs.ip         = 0;
-
-       /*
-        * Prepare a generic sample, i.e. fill in the invariant fields.
-        * We will overwrite the from and to address before we output
-        * the sample.
-        */
-       perf_prepare_sample(&header, &data, event, &regs);
-
-       if (perf_output_begin(&handle, event,
-                             header.size * (top - at), 1, 1))
-               return;
-
-       for (; at < top; at++) {
-               data.ip         = at->from;
-               data.addr       = at->to;
-
-               perf_output_sample(&handle, &header, &data, event);
-       }
-
-       perf_output_end(&handle);
-
-       /* There's new data available. */
-       event->hw.interrupts++;
-       event->pending_kill = POLL_IN;
-}
+       struct hw_perf_event *hwc = &event->hw;
 
-static inline void
-intel_pmu_disable_event(struct hw_perf_event *hwc, int idx)
-{
-       if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
+       if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) {
                intel_pmu_disable_bts();
                intel_pmu_drain_bts_buffer();
                return;
        }
 
        if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
-               intel_pmu_disable_fixed(hwc, idx);
+               intel_pmu_disable_fixed(hwc);
                return;
        }
 
-       x86_pmu_disable_event(hwc, idx);
+       x86_pmu_disable_event(event);
+
+       if (unlikely(event->attr.precise_ip))
+               intel_pmu_pebs_disable(event);
 }
 
-static inline void
-intel_pmu_enable_fixed(struct hw_perf_event *hwc, int __idx)
+static void intel_pmu_enable_fixed(struct hw_perf_event *hwc)
 {
-       int idx = __idx - X86_PMC_IDX_FIXED;
+       int idx = hwc->idx - X86_PMC_IDX_FIXED;
        u64 ctrl_val, bits, mask;
-       int err;
 
        /*
         * Enable IRQ generation (0x8),
@@ -667,12 +595,14 @@ intel_pmu_enable_fixed(struct hw_perf_event *hwc, int __idx)
        rdmsrl(hwc->config_base, ctrl_val);
        ctrl_val &= ~mask;
        ctrl_val |= bits;
-       err = checking_wrmsrl(hwc->config_base, ctrl_val);
+       wrmsrl(hwc->config_base, ctrl_val);
 }
 
-static void intel_pmu_enable_event(struct hw_perf_event *hwc, int idx)
+static void intel_pmu_enable_event(struct perf_event *event)
 {
-       if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
+       struct hw_perf_event *hwc = &event->hw;
+
+       if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) {
                if (!__get_cpu_var(cpu_hw_events).enabled)
                        return;
 
@@ -681,11 +611,14 @@ static void intel_pmu_enable_event(struct hw_perf_event *hwc, int idx)
        }
 
        if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
-               intel_pmu_enable_fixed(hwc, idx);
+               intel_pmu_enable_fixed(hwc);
                return;
        }
 
-       __x86_pmu_enable_event(hwc, idx);
+       if (unlikely(event->attr.precise_ip))
+               intel_pmu_pebs_enable(event);
+
+       __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
 }
 
 /*
@@ -694,14 +627,8 @@ static void intel_pmu_enable_event(struct hw_perf_event *hwc, int idx)
  */
 static int intel_pmu_save_and_restart(struct perf_event *event)
 {
-       struct hw_perf_event *hwc = &event->hw;
-       int idx = hwc->idx;
-       int ret;
-
-       x86_perf_event_update(event, hwc, idx);
-       ret = x86_perf_event_set_period(event, hwc, idx);
-
-       return ret;
+       x86_perf_event_update(event);
+       return x86_perf_event_set_period(event);
 }
 
 static void intel_pmu_reset(void)
@@ -710,20 +637,20 @@ static void intel_pmu_reset(void)
        unsigned long flags;
        int idx;
 
-       if (!x86_pmu.num_events)
+       if (!x86_pmu.num_counters)
                return;
 
        local_irq_save(flags);
 
        printk("clearing PMU state on CPU#%d\n", smp_processor_id());
 
-       for (idx = 0; idx < x86_pmu.num_events; idx++) {
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
                checking_wrmsrl(x86_pmu.eventsel + idx, 0ull);
                checking_wrmsrl(x86_pmu.perfctr  + idx, 0ull);
        }
-       for (idx = 0; idx < x86_pmu.num_events_fixed; idx++) {
+       for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++)
                checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
-       }
+
        if (ds)
                ds->bts_index = ds->bts_buffer_base;
 
@@ -745,11 +672,11 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
 
        cpuc = &__get_cpu_var(cpu_hw_events);
 
-       perf_disable();
+       intel_pmu_disable_all();
        intel_pmu_drain_bts_buffer();
        status = intel_pmu_get_status();
        if (!status) {
-               perf_enable();
+               intel_pmu_enable_all(0);
                return 0;
        }
 
@@ -759,16 +686,23 @@ again:
                WARN_ONCE(1, "perfevents: irq loop stuck!\n");
                perf_event_print_debug();
                intel_pmu_reset();
-               perf_enable();
-               return 1;
+               goto done;
        }
 
        inc_irq_stat(apic_perf_irqs);
        ack = status;
+
+       intel_pmu_lbr_read();
+
+       /*
+        * PEBS overflow sets bit 62 in the global status register
+        */
+       if (__test_and_clear_bit(62, (unsigned long *)&status))
+               x86_pmu.drain_pebs(regs);
+
        for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
                struct perf_event *event = cpuc->events[bit];
 
-               clear_bit(bit, (unsigned long *) &status);
                if (!test_bit(bit, cpuc->active_mask))
                        continue;
 
@@ -778,7 +712,7 @@ again:
                data.period = event->hw.last_period;
 
                if (perf_event_overflow(event, 1, &data, regs))
-                       intel_pmu_disable_event(&event->hw, bit);
+                       x86_pmu_stop(event);
        }
 
        intel_pmu_ack_status(ack);
@@ -790,27 +724,23 @@ again:
        if (status)
                goto again;
 
-       perf_enable();
-
+done:
+       intel_pmu_enable_all(0);
        return 1;
 }
 
-static struct event_constraint bts_constraint =
-       EVENT_CONSTRAINT(0, 1ULL << X86_PMC_IDX_FIXED_BTS, 0);
-
 static struct event_constraint *
-intel_special_constraints(struct perf_event *event)
+intel_bts_constraints(struct perf_event *event)
 {
-       unsigned int hw_event;
-
-       hw_event = event->hw.config & INTEL_ARCH_EVENT_MASK;
+       struct hw_perf_event *hwc = &event->hw;
+       unsigned int hw_event, bts_event;
 
-       if (unlikely((hw_event ==
-                     x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS)) &&
-                    (event->hw.sample_period == 1))) {
+       hw_event = hwc->config & INTEL_ARCH_EVENT_MASK;
+       bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
 
+       if (unlikely(hw_event == bts_event && hwc->sample_period == 1))
                return &bts_constraint;
-       }
+
        return NULL;
 }
 
@@ -819,24 +749,53 @@ intel_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event
 {
        struct event_constraint *c;
 
-       c = intel_special_constraints(event);
+       c = intel_bts_constraints(event);
+       if (c)
+               return c;
+
+       c = intel_pebs_constraints(event);
        if (c)
                return c;
 
        return x86_get_event_constraints(cpuc, event);
 }
 
-static __initconst struct x86_pmu core_pmu = {
+static int intel_pmu_hw_config(struct perf_event *event)
+{
+       int ret = x86_pmu_hw_config(event);
+
+       if (ret)
+               return ret;
+
+       if (event->attr.type != PERF_TYPE_RAW)
+               return 0;
+
+       if (!(event->attr.config & ARCH_PERFMON_EVENTSEL_ANY))
+               return 0;
+
+       if (x86_pmu.version < 3)
+               return -EINVAL;
+
+       if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
+               return -EACCES;
+
+       event->hw.config |= ARCH_PERFMON_EVENTSEL_ANY;
+
+       return 0;
+}
+
+static __initconst const struct x86_pmu core_pmu = {
        .name                   = "core",
        .handle_irq             = x86_pmu_handle_irq,
        .disable_all            = x86_pmu_disable_all,
        .enable_all             = x86_pmu_enable_all,
        .enable                 = x86_pmu_enable_event,
        .disable                = x86_pmu_disable_event,
+       .hw_config              = x86_pmu_hw_config,
+       .schedule_events        = x86_schedule_events,
        .eventsel               = MSR_ARCH_PERFMON_EVENTSEL0,
        .perfctr                = MSR_ARCH_PERFMON_PERFCTR0,
        .event_map              = intel_pmu_event_map,
-       .raw_event              = intel_pmu_raw_event,
        .max_events             = ARRAY_SIZE(intel_perfmon_event_map),
        .apic                   = 1,
        /*
@@ -849,17 +808,32 @@ static __initconst struct x86_pmu core_pmu = {
        .event_constraints      = intel_core_event_constraints,
 };
 
-static __initconst struct x86_pmu intel_pmu = {
+static void intel_pmu_cpu_starting(int cpu)
+{
+       init_debug_store_on_cpu(cpu);
+       /*
+        * Deal with CPUs that don't clear their LBRs on power-up.
+        */
+       intel_pmu_lbr_reset();
+}
+
+static void intel_pmu_cpu_dying(int cpu)
+{
+       fini_debug_store_on_cpu(cpu);
+}
+
+static __initconst const struct x86_pmu intel_pmu = {
        .name                   = "Intel",
        .handle_irq             = intel_pmu_handle_irq,
        .disable_all            = intel_pmu_disable_all,
        .enable_all             = intel_pmu_enable_all,
        .enable                 = intel_pmu_enable_event,
        .disable                = intel_pmu_disable_event,
+       .hw_config              = intel_pmu_hw_config,
+       .schedule_events        = x86_schedule_events,
        .eventsel               = MSR_ARCH_PERFMON_EVENTSEL0,
        .perfctr                = MSR_ARCH_PERFMON_PERFCTR0,
        .event_map              = intel_pmu_event_map,
-       .raw_event              = intel_pmu_raw_event,
        .max_events             = ARRAY_SIZE(intel_perfmon_event_map),
        .apic                   = 1,
        /*
@@ -868,11 +842,38 @@ static __initconst struct x86_pmu intel_pmu = {
         * the generic event period:
         */
        .max_period             = (1ULL << 31) - 1,
-       .enable_bts             = intel_pmu_enable_bts,
-       .disable_bts            = intel_pmu_disable_bts,
-       .get_event_constraints  = intel_get_event_constraints
+       .get_event_constraints  = intel_get_event_constraints,
+
+       .cpu_starting           = intel_pmu_cpu_starting,
+       .cpu_dying              = intel_pmu_cpu_dying,
 };
 
+static void intel_clovertown_quirks(void)
+{
+       /*
+        * PEBS is unreliable due to:
+        *
+        *   AJ67  - PEBS may experience CPL leaks
+        *   AJ68  - PEBS PMI may be delayed by one event
+        *   AJ69  - GLOBAL_STATUS[62] will only be set when DEBUGCTL[12]
+        *   AJ106 - FREEZE_LBRS_ON_PMI doesn't work in combination with PEBS
+        *
+        * AJ67 could be worked around by restricting the OS/USR flags.
+        * AJ69 could be worked around by setting PMU_FREEZE_ON_PMI.
+        *
+        * AJ106 could possibly be worked around by not allowing LBR
+        *       usage from PEBS, including the fixup.
+        * AJ68  could possibly be worked around by always programming
+        *       a pebs_event_reset[0] value and coping with the lost events.
+        *
+        * But taken together it might just make sense to not enable PEBS on
+        * these chips.
+        */
+       printk(KERN_WARNING "PEBS disabled due to CPU errata.\n");
+       x86_pmu.pebs = 0;
+       x86_pmu.pebs_constraints = NULL;
+}
+
 static __init int intel_pmu_init(void)
 {
        union cpuid10_edx edx;
@@ -882,12 +883,13 @@ static __init int intel_pmu_init(void)
        int version;
 
        if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
-               /* check for P6 processor family */
-          if (boot_cpu_data.x86 == 6) {
-               return p6_pmu_init();
-          } else {
+               switch (boot_cpu_data.x86) {
+               case 0x6:
+                       return p6_pmu_init();
+               case 0xf:
+                       return p4_pmu_init();
+               }
                return -ENODEV;
-          }
        }
 
        /*
@@ -905,16 +907,28 @@ static __init int intel_pmu_init(void)
                x86_pmu = intel_pmu;
 
        x86_pmu.version                 = version;
-       x86_pmu.num_events              = eax.split.num_events;
-       x86_pmu.event_bits              = eax.split.bit_width;
-       x86_pmu.event_mask              = (1ULL << eax.split.bit_width) - 1;
+       x86_pmu.num_counters            = eax.split.num_counters;
+       x86_pmu.cntval_bits             = eax.split.bit_width;
+       x86_pmu.cntval_mask             = (1ULL << eax.split.bit_width) - 1;
 
        /*
         * Quirk: v2 perfmon does not report fixed-purpose events, so
         * assume at least 3 events:
         */
        if (version > 1)
-               x86_pmu.num_events_fixed = max((int)edx.split.num_events_fixed, 3);
+               x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3);
+
+       /*
+        * v2 and above have a perf capabilities MSR
+        */
+       if (version > 1) {
+               u64 capabilities;
+
+               rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities);
+               x86_pmu.intel_cap.capabilities = capabilities;
+       }
+
+       intel_ds_init();
 
        /*
         * Install the hw-cache-events table:
@@ -925,28 +939,38 @@ static __init int intel_pmu_init(void)
                break;
 
        case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
+               x86_pmu.quirks = intel_clovertown_quirks;
        case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
        case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */
        case 29: /* six-core 45 nm xeon "Dunnington" */
                memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
                       sizeof(hw_cache_event_ids));
 
+               intel_pmu_lbr_init_core();
+
                x86_pmu.event_constraints = intel_core2_event_constraints;
                pr_cont("Core2 events, ");
                break;
 
        case 26: /* 45 nm nehalem, "Bloomfield" */
        case 30: /* 45 nm nehalem, "Lynnfield" */
+       case 46: /* 45 nm nehalem-ex, "Beckton" */
                memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
                       sizeof(hw_cache_event_ids));
 
+               intel_pmu_lbr_init_nhm();
+
                x86_pmu.event_constraints = intel_nehalem_event_constraints;
-               pr_cont("Nehalem/Corei7 events, ");
+               x86_pmu.enable_all = intel_pmu_nhm_enable_all;
+               pr_cont("Nehalem events, ");
                break;
+
        case 28: /* Atom */
                memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
                       sizeof(hw_cache_event_ids));
 
+               intel_pmu_lbr_init_atom();
+
                x86_pmu.event_constraints = intel_gen_event_constraints;
                pr_cont("Atom events, ");
                break;
@@ -956,7 +980,10 @@ static __init int intel_pmu_init(void)
                memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids,
                       sizeof(hw_cache_event_ids));
 
+               intel_pmu_lbr_init_nhm();
+
                x86_pmu.event_constraints = intel_westmere_event_constraints;
+               x86_pmu.enable_all = intel_pmu_nhm_enable_all;
                pr_cont("Westmere events, ");
                break;
 
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
new file mode 100644 (file)
index 0000000..18018d1
--- /dev/null
@@ -0,0 +1,641 @@
+#ifdef CONFIG_CPU_SUP_INTEL
+
+/* The maximal number of PEBS events: */
+#define MAX_PEBS_EVENTS                4
+
+/* The size of a BTS record in bytes: */
+#define BTS_RECORD_SIZE                24
+
+#define BTS_BUFFER_SIZE                (PAGE_SIZE << 4)
+#define PEBS_BUFFER_SIZE       PAGE_SIZE
+
+/*
+ * pebs_record_32 for p4 and core not supported
+
+struct pebs_record_32 {
+       u32 flags, ip;
+       u32 ax, bc, cx, dx;
+       u32 si, di, bp, sp;
+};
+
+ */
+
+struct pebs_record_core {
+       u64 flags, ip;
+       u64 ax, bx, cx, dx;
+       u64 si, di, bp, sp;
+       u64 r8,  r9,  r10, r11;
+       u64 r12, r13, r14, r15;
+};
+
+struct pebs_record_nhm {
+       u64 flags, ip;
+       u64 ax, bx, cx, dx;
+       u64 si, di, bp, sp;
+       u64 r8,  r9,  r10, r11;
+       u64 r12, r13, r14, r15;
+       u64 status, dla, dse, lat;
+};
+
+/*
+ * A debug store configuration.
+ *
+ * We only support architectures that use 64bit fields.
+ */
+struct debug_store {
+       u64     bts_buffer_base;
+       u64     bts_index;
+       u64     bts_absolute_maximum;
+       u64     bts_interrupt_threshold;
+       u64     pebs_buffer_base;
+       u64     pebs_index;
+       u64     pebs_absolute_maximum;
+       u64     pebs_interrupt_threshold;
+       u64     pebs_event_reset[MAX_PEBS_EVENTS];
+};
+
+static void init_debug_store_on_cpu(int cpu)
+{
+       struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+       if (!ds)
+               return;
+
+       wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA,
+                    (u32)((u64)(unsigned long)ds),
+                    (u32)((u64)(unsigned long)ds >> 32));
+}
+
+static void fini_debug_store_on_cpu(int cpu)
+{
+       if (!per_cpu(cpu_hw_events, cpu).ds)
+               return;
+
+       wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
+}
+
+static void release_ds_buffers(void)
+{
+       int cpu;
+
+       if (!x86_pmu.bts && !x86_pmu.pebs)
+               return;
+
+       get_online_cpus();
+
+       for_each_online_cpu(cpu)
+               fini_debug_store_on_cpu(cpu);
+
+       for_each_possible_cpu(cpu) {
+               struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+               if (!ds)
+                       continue;
+
+               per_cpu(cpu_hw_events, cpu).ds = NULL;
+
+               kfree((void *)(unsigned long)ds->pebs_buffer_base);
+               kfree((void *)(unsigned long)ds->bts_buffer_base);
+               kfree(ds);
+       }
+
+       put_online_cpus();
+}
+
+static int reserve_ds_buffers(void)
+{
+       int cpu, err = 0;
+
+       if (!x86_pmu.bts && !x86_pmu.pebs)
+               return 0;
+
+       get_online_cpus();
+
+       for_each_possible_cpu(cpu) {
+               struct debug_store *ds;
+               void *buffer;
+               int max, thresh;
+
+               err = -ENOMEM;
+               ds = kzalloc(sizeof(*ds), GFP_KERNEL);
+               if (unlikely(!ds))
+                       break;
+               per_cpu(cpu_hw_events, cpu).ds = ds;
+
+               if (x86_pmu.bts) {
+                       buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL);
+                       if (unlikely(!buffer))
+                               break;
+
+                       max = BTS_BUFFER_SIZE / BTS_RECORD_SIZE;
+                       thresh = max / 16;
+
+                       ds->bts_buffer_base = (u64)(unsigned long)buffer;
+                       ds->bts_index = ds->bts_buffer_base;
+                       ds->bts_absolute_maximum = ds->bts_buffer_base +
+                               max * BTS_RECORD_SIZE;
+                       ds->bts_interrupt_threshold = ds->bts_absolute_maximum -
+                               thresh * BTS_RECORD_SIZE;
+               }
+
+               if (x86_pmu.pebs) {
+                       buffer = kzalloc(PEBS_BUFFER_SIZE, GFP_KERNEL);
+                       if (unlikely(!buffer))
+                               break;
+
+                       max = PEBS_BUFFER_SIZE / x86_pmu.pebs_record_size;
+
+                       ds->pebs_buffer_base = (u64)(unsigned long)buffer;
+                       ds->pebs_index = ds->pebs_buffer_base;
+                       ds->pebs_absolute_maximum = ds->pebs_buffer_base +
+                               max * x86_pmu.pebs_record_size;
+                       /*
+                        * Always use single record PEBS
+                        */
+                       ds->pebs_interrupt_threshold = ds->pebs_buffer_base +
+                               x86_pmu.pebs_record_size;
+               }
+
+               err = 0;
+       }
+
+       if (err)
+               release_ds_buffers();
+       else {
+               for_each_online_cpu(cpu)
+                       init_debug_store_on_cpu(cpu);
+       }
+
+       put_online_cpus();
+
+       return err;
+}
+
+/*
+ * BTS
+ */
+
+static struct event_constraint bts_constraint =
+       EVENT_CONSTRAINT(0, 1ULL << X86_PMC_IDX_FIXED_BTS, 0);
+
+static void intel_pmu_enable_bts(u64 config)
+{
+       unsigned long debugctlmsr;
+
+       debugctlmsr = get_debugctlmsr();
+
+       debugctlmsr |= DEBUGCTLMSR_TR;
+       debugctlmsr |= DEBUGCTLMSR_BTS;
+       debugctlmsr |= DEBUGCTLMSR_BTINT;
+
+       if (!(config & ARCH_PERFMON_EVENTSEL_OS))
+               debugctlmsr |= DEBUGCTLMSR_BTS_OFF_OS;
+
+       if (!(config & ARCH_PERFMON_EVENTSEL_USR))
+               debugctlmsr |= DEBUGCTLMSR_BTS_OFF_USR;
+
+       update_debugctlmsr(debugctlmsr);
+}
+
+static void intel_pmu_disable_bts(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       unsigned long debugctlmsr;
+
+       if (!cpuc->ds)
+               return;
+
+       debugctlmsr = get_debugctlmsr();
+
+       debugctlmsr &=
+               ~(DEBUGCTLMSR_TR | DEBUGCTLMSR_BTS | DEBUGCTLMSR_BTINT |
+                 DEBUGCTLMSR_BTS_OFF_OS | DEBUGCTLMSR_BTS_OFF_USR);
+
+       update_debugctlmsr(debugctlmsr);
+}
+
+static void intel_pmu_drain_bts_buffer(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct debug_store *ds = cpuc->ds;
+       struct bts_record {
+               u64     from;
+               u64     to;
+               u64     flags;
+       };
+       struct perf_event *event = cpuc->events[X86_PMC_IDX_FIXED_BTS];
+       struct bts_record *at, *top;
+       struct perf_output_handle handle;
+       struct perf_event_header header;
+       struct perf_sample_data data;
+       struct pt_regs regs;
+
+       if (!event)
+               return;
+
+       if (!ds)
+               return;
+
+       at  = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
+       top = (struct bts_record *)(unsigned long)ds->bts_index;
+
+       if (top <= at)
+               return;
+
+       ds->bts_index = ds->bts_buffer_base;
+
+       perf_sample_data_init(&data, 0);
+       data.period = event->hw.last_period;
+       regs.ip     = 0;
+
+       /*
+        * Prepare a generic sample, i.e. fill in the invariant fields.
+        * We will overwrite the from and to address before we output
+        * the sample.
+        */
+       perf_prepare_sample(&header, &data, event, &regs);
+
+       if (perf_output_begin(&handle, event, header.size * (top - at), 1, 1))
+               return;
+
+       for (; at < top; at++) {
+               data.ip         = at->from;
+               data.addr       = at->to;
+
+               perf_output_sample(&handle, &header, &data, event);
+       }
+
+       perf_output_end(&handle);
+
+       /* There's new data available. */
+       event->hw.interrupts++;
+       event->pending_kill = POLL_IN;
+}
+
+/*
+ * PEBS
+ */
+
+static struct event_constraint intel_core_pebs_events[] = {
+       PEBS_EVENT_CONSTRAINT(0x00c0, 0x1), /* INSTR_RETIRED.ANY */
+       PEBS_EVENT_CONSTRAINT(0xfec1, 0x1), /* X87_OPS_RETIRED.ANY */
+       PEBS_EVENT_CONSTRAINT(0x00c5, 0x1), /* BR_INST_RETIRED.MISPRED */
+       PEBS_EVENT_CONSTRAINT(0x1fc7, 0x1), /* SIMD_INST_RETURED.ANY */
+       PEBS_EVENT_CONSTRAINT(0x01cb, 0x1), /* MEM_LOAD_RETIRED.L1D_MISS */
+       PEBS_EVENT_CONSTRAINT(0x02cb, 0x1), /* MEM_LOAD_RETIRED.L1D_LINE_MISS */
+       PEBS_EVENT_CONSTRAINT(0x04cb, 0x1), /* MEM_LOAD_RETIRED.L2_MISS */
+       PEBS_EVENT_CONSTRAINT(0x08cb, 0x1), /* MEM_LOAD_RETIRED.L2_LINE_MISS */
+       PEBS_EVENT_CONSTRAINT(0x10cb, 0x1), /* MEM_LOAD_RETIRED.DTLB_MISS */
+       EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_nehalem_pebs_events[] = {
+       PEBS_EVENT_CONSTRAINT(0x00c0, 0xf), /* INSTR_RETIRED.ANY */
+       PEBS_EVENT_CONSTRAINT(0xfec1, 0xf), /* X87_OPS_RETIRED.ANY */
+       PEBS_EVENT_CONSTRAINT(0x00c5, 0xf), /* BR_INST_RETIRED.MISPRED */
+       PEBS_EVENT_CONSTRAINT(0x1fc7, 0xf), /* SIMD_INST_RETURED.ANY */
+       PEBS_EVENT_CONSTRAINT(0x01cb, 0xf), /* MEM_LOAD_RETIRED.L1D_MISS */
+       PEBS_EVENT_CONSTRAINT(0x02cb, 0xf), /* MEM_LOAD_RETIRED.L1D_LINE_MISS */
+       PEBS_EVENT_CONSTRAINT(0x04cb, 0xf), /* MEM_LOAD_RETIRED.L2_MISS */
+       PEBS_EVENT_CONSTRAINT(0x08cb, 0xf), /* MEM_LOAD_RETIRED.L2_LINE_MISS */
+       PEBS_EVENT_CONSTRAINT(0x10cb, 0xf), /* MEM_LOAD_RETIRED.DTLB_MISS */
+       EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint *
+intel_pebs_constraints(struct perf_event *event)
+{
+       struct event_constraint *c;
+
+       if (!event->attr.precise_ip)
+               return NULL;
+
+       if (x86_pmu.pebs_constraints) {
+               for_each_event_constraint(c, x86_pmu.pebs_constraints) {
+                       if ((event->hw.config & c->cmask) == c->code)
+                               return c;
+               }
+       }
+
+       return &emptyconstraint;
+}
+
+static void intel_pmu_pebs_enable(struct perf_event *event)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct hw_perf_event *hwc = &event->hw;
+
+       hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
+
+       cpuc->pebs_enabled |= 1ULL << hwc->idx;
+       WARN_ON_ONCE(cpuc->enabled);
+
+       if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1)
+               intel_pmu_lbr_enable(event);
+}
+
+static void intel_pmu_pebs_disable(struct perf_event *event)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct hw_perf_event *hwc = &event->hw;
+
+       cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
+       if (cpuc->enabled)
+               wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
+
+       hwc->config |= ARCH_PERFMON_EVENTSEL_INT;
+
+       if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1)
+               intel_pmu_lbr_disable(event);
+}
+
+static void intel_pmu_pebs_enable_all(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       if (cpuc->pebs_enabled)
+               wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
+}
+
+static void intel_pmu_pebs_disable_all(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       if (cpuc->pebs_enabled)
+               wrmsrl(MSR_IA32_PEBS_ENABLE, 0);
+}
+
+#include <asm/insn.h>
+
+static inline bool kernel_ip(unsigned long ip)
+{
+#ifdef CONFIG_X86_32
+       return ip > PAGE_OFFSET;
+#else
+       return (long)ip < 0;
+#endif
+}
+
+static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       unsigned long from = cpuc->lbr_entries[0].from;
+       unsigned long old_to, to = cpuc->lbr_entries[0].to;
+       unsigned long ip = regs->ip;
+
+       /*
+        * We don't need to fixup if the PEBS assist is fault like
+        */
+       if (!x86_pmu.intel_cap.pebs_trap)
+               return 1;
+
+       /*
+        * No LBR entry, no basic block, no rewinding
+        */
+       if (!cpuc->lbr_stack.nr || !from || !to)
+               return 0;
+
+       /*
+        * Basic blocks should never cross user/kernel boundaries
+        */
+       if (kernel_ip(ip) != kernel_ip(to))
+               return 0;
+
+       /*
+        * unsigned math, either ip is before the start (impossible) or
+        * the basic block is larger than 1 page (sanity)
+        */
+       if ((ip - to) > PAGE_SIZE)
+               return 0;
+
+       /*
+        * We sampled a branch insn, rewind using the LBR stack
+        */
+       if (ip == to) {
+               regs->ip = from;
+               return 1;
+       }
+
+       do {
+               struct insn insn;
+               u8 buf[MAX_INSN_SIZE];
+               void *kaddr;
+
+               old_to = to;
+               if (!kernel_ip(ip)) {
+                       int bytes, size = MAX_INSN_SIZE;
+
+                       bytes = copy_from_user_nmi(buf, (void __user *)to, size);
+                       if (bytes != size)
+                               return 0;
+
+                       kaddr = buf;
+               } else
+                       kaddr = (void *)to;
+
+               kernel_insn_init(&insn, kaddr);
+               insn_get_length(&insn);
+               to += insn.length;
+       } while (to < ip);
+
+       if (to == ip) {
+               regs->ip = old_to;
+               return 1;
+       }
+
+       /*
+        * Even though we decoded the basic block, the instruction stream
+        * never matched the given IP, either the TO or the IP got corrupted.
+        */
+       return 0;
+}
+
+static int intel_pmu_save_and_restart(struct perf_event *event);
+
+static void __intel_pmu_pebs_event(struct perf_event *event,
+                                  struct pt_regs *iregs, void *__pebs)
+{
+       /*
+        * We cast to pebs_record_core since that is a subset of
+        * both formats and we don't use the other fields in this
+        * routine.
+        */
+       struct pebs_record_core *pebs = __pebs;
+       struct perf_sample_data data;
+       struct pt_regs regs;
+
+       if (!intel_pmu_save_and_restart(event))
+               return;
+
+       perf_sample_data_init(&data, 0);
+       data.period = event->hw.last_period;
+
+       /*
+        * We use the interrupt regs as a base because the PEBS record
+        * does not contain a full regs set, specifically it seems to
+        * lack segment descriptors, which get used by things like
+        * user_mode().
+        *
+        * In the simple case fix up only the IP and BP,SP regs, for
+        * PERF_SAMPLE_IP and PERF_SAMPLE_CALLCHAIN to function properly.
+        * A possible PERF_SAMPLE_REGS will have to transfer all regs.
+        */
+       regs = *iregs;
+       regs.ip = pebs->ip;
+       regs.bp = pebs->bp;
+       regs.sp = pebs->sp;
+
+       if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(&regs))
+               regs.flags |= PERF_EFLAGS_EXACT;
+       else
+               regs.flags &= ~PERF_EFLAGS_EXACT;
+
+       if (perf_event_overflow(event, 1, &data, &regs))
+               x86_pmu_stop(event);
+}
+
+static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct debug_store *ds = cpuc->ds;
+       struct perf_event *event = cpuc->events[0]; /* PMC0 only */
+       struct pebs_record_core *at, *top;
+       int n;
+
+       if (!ds || !x86_pmu.pebs)
+               return;
+
+       at  = (struct pebs_record_core *)(unsigned long)ds->pebs_buffer_base;
+       top = (struct pebs_record_core *)(unsigned long)ds->pebs_index;
+
+       /*
+        * Whatever else happens, drain the thing
+        */
+       ds->pebs_index = ds->pebs_buffer_base;
+
+       if (!test_bit(0, cpuc->active_mask))
+               return;
+
+       WARN_ON_ONCE(!event);
+
+       if (!event->attr.precise_ip)
+               return;
+
+       n = top - at;
+       if (n <= 0)
+               return;
+
+       /*
+        * Should not happen, we program the threshold at 1 and do not
+        * set a reset value.
+        */
+       WARN_ON_ONCE(n > 1);
+       at += n - 1;
+
+       __intel_pmu_pebs_event(event, iregs, at);
+}
+
+static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct debug_store *ds = cpuc->ds;
+       struct pebs_record_nhm *at, *top;
+       struct perf_event *event = NULL;
+       u64 status = 0;
+       int bit, n;
+
+       if (!ds || !x86_pmu.pebs)
+               return;
+
+       at  = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
+       top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
+
+       ds->pebs_index = ds->pebs_buffer_base;
+
+       n = top - at;
+       if (n <= 0)
+               return;
+
+       /*
+        * Should not happen, we program the threshold at 1 and do not
+        * set a reset value.
+        */
+       WARN_ON_ONCE(n > MAX_PEBS_EVENTS);
+
+       for ( ; at < top; at++) {
+               for_each_set_bit(bit, (unsigned long *)&at->status, MAX_PEBS_EVENTS) {
+                       event = cpuc->events[bit];
+                       if (!test_bit(bit, cpuc->active_mask))
+                               continue;
+
+                       WARN_ON_ONCE(!event);
+
+                       if (!event->attr.precise_ip)
+                               continue;
+
+                       if (__test_and_set_bit(bit, (unsigned long *)&status))
+                               continue;
+
+                       break;
+               }
+
+               if (!event || bit >= MAX_PEBS_EVENTS)
+                       continue;
+
+               __intel_pmu_pebs_event(event, iregs, at);
+       }
+}
+
+/*
+ * BTS, PEBS probe and setup
+ */
+
+static void intel_ds_init(void)
+{
+       /*
+        * No support for 32bit formats
+        */
+       if (!boot_cpu_has(X86_FEATURE_DTES64))
+               return;
+
+       x86_pmu.bts  = boot_cpu_has(X86_FEATURE_BTS);
+       x86_pmu.pebs = boot_cpu_has(X86_FEATURE_PEBS);
+       if (x86_pmu.pebs) {
+               char pebs_type = x86_pmu.intel_cap.pebs_trap ?  '+' : '-';
+               int format = x86_pmu.intel_cap.pebs_format;
+
+               switch (format) {
+               case 0:
+                       printk(KERN_CONT "PEBS fmt0%c, ", pebs_type);
+                       x86_pmu.pebs_record_size = sizeof(struct pebs_record_core);
+                       x86_pmu.drain_pebs = intel_pmu_drain_pebs_core;
+                       x86_pmu.pebs_constraints = intel_core_pebs_events;
+                       break;
+
+               case 1:
+                       printk(KERN_CONT "PEBS fmt1%c, ", pebs_type);
+                       x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm);
+                       x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
+                       x86_pmu.pebs_constraints = intel_nehalem_pebs_events;
+                       break;
+
+               default:
+                       printk(KERN_CONT "no PEBS fmt%d%c, ", format, pebs_type);
+                       x86_pmu.pebs = 0;
+                       break;
+               }
+       }
+}
+
+#else /* CONFIG_CPU_SUP_INTEL */
+
+static int reserve_ds_buffers(void)
+{
+       return 0;
+}
+
+static void release_ds_buffers(void)
+{
+}
+
+#endif /* CONFIG_CPU_SUP_INTEL */
diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
new file mode 100644 (file)
index 0000000..d202c1b
--- /dev/null
@@ -0,0 +1,218 @@
+#ifdef CONFIG_CPU_SUP_INTEL
+
+enum {
+       LBR_FORMAT_32           = 0x00,
+       LBR_FORMAT_LIP          = 0x01,
+       LBR_FORMAT_EIP          = 0x02,
+       LBR_FORMAT_EIP_FLAGS    = 0x03,
+};
+
+/*
+ * We only support LBR implementations that have FREEZE_LBRS_ON_PMI
+ * otherwise it becomes near impossible to get a reliable stack.
+ */
+
+static void __intel_pmu_lbr_enable(void)
+{
+       u64 debugctl;
+
+       rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+       debugctl |= (DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI);
+       wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+}
+
+static void __intel_pmu_lbr_disable(void)
+{
+       u64 debugctl;
+
+       rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+       debugctl &= ~(DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI);
+       wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+}
+
+static void intel_pmu_lbr_reset_32(void)
+{
+       int i;
+
+       for (i = 0; i < x86_pmu.lbr_nr; i++)
+               wrmsrl(x86_pmu.lbr_from + i, 0);
+}
+
+static void intel_pmu_lbr_reset_64(void)
+{
+       int i;
+
+       for (i = 0; i < x86_pmu.lbr_nr; i++) {
+               wrmsrl(x86_pmu.lbr_from + i, 0);
+               wrmsrl(x86_pmu.lbr_to   + i, 0);
+       }
+}
+
+static void intel_pmu_lbr_reset(void)
+{
+       if (!x86_pmu.lbr_nr)
+               return;
+
+       if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
+               intel_pmu_lbr_reset_32();
+       else
+               intel_pmu_lbr_reset_64();
+}
+
+static void intel_pmu_lbr_enable(struct perf_event *event)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       if (!x86_pmu.lbr_nr)
+               return;
+
+       WARN_ON_ONCE(cpuc->enabled);
+
+       /*
+        * Reset the LBR stack if we changed task context to
+        * avoid data leaks.
+        */
+
+       if (event->ctx->task && cpuc->lbr_context != event->ctx) {
+               intel_pmu_lbr_reset();
+               cpuc->lbr_context = event->ctx;
+       }
+
+       cpuc->lbr_users++;
+}
+
+static void intel_pmu_lbr_disable(struct perf_event *event)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       if (!x86_pmu.lbr_nr)
+               return;
+
+       cpuc->lbr_users--;
+       WARN_ON_ONCE(cpuc->lbr_users < 0);
+
+       if (cpuc->enabled && !cpuc->lbr_users)
+               __intel_pmu_lbr_disable();
+}
+
+static void intel_pmu_lbr_enable_all(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       if (cpuc->lbr_users)
+               __intel_pmu_lbr_enable();
+}
+
+static void intel_pmu_lbr_disable_all(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       if (cpuc->lbr_users)
+               __intel_pmu_lbr_disable();
+}
+
+static inline u64 intel_pmu_lbr_tos(void)
+{
+       u64 tos;
+
+       rdmsrl(x86_pmu.lbr_tos, tos);
+
+       return tos;
+}
+
+static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
+{
+       unsigned long mask = x86_pmu.lbr_nr - 1;
+       u64 tos = intel_pmu_lbr_tos();
+       int i;
+
+       for (i = 0; i < x86_pmu.lbr_nr; i++) {
+               unsigned long lbr_idx = (tos - i) & mask;
+               union {
+                       struct {
+                               u32 from;
+                               u32 to;
+                       };
+                       u64     lbr;
+               } msr_lastbranch;
+
+               rdmsrl(x86_pmu.lbr_from + lbr_idx, msr_lastbranch.lbr);
+
+               cpuc->lbr_entries[i].from  = msr_lastbranch.from;
+               cpuc->lbr_entries[i].to    = msr_lastbranch.to;
+               cpuc->lbr_entries[i].flags = 0;
+       }
+       cpuc->lbr_stack.nr = i;
+}
+
+#define LBR_FROM_FLAG_MISPRED  (1ULL << 63)
+
+/*
+ * Due to lack of segmentation in Linux the effective address (offset)
+ * is the same as the linear address, allowing us to merge the LIP and EIP
+ * LBR formats.
+ */
+static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
+{
+       unsigned long mask = x86_pmu.lbr_nr - 1;
+       int lbr_format = x86_pmu.intel_cap.lbr_format;
+       u64 tos = intel_pmu_lbr_tos();
+       int i;
+
+       for (i = 0; i < x86_pmu.lbr_nr; i++) {
+               unsigned long lbr_idx = (tos - i) & mask;
+               u64 from, to, flags = 0;
+
+               rdmsrl(x86_pmu.lbr_from + lbr_idx, from);
+               rdmsrl(x86_pmu.lbr_to   + lbr_idx, to);
+
+               if (lbr_format == LBR_FORMAT_EIP_FLAGS) {
+                       flags = !!(from & LBR_FROM_FLAG_MISPRED);
+                       from = (u64)((((s64)from) << 1) >> 1);
+               }
+
+               cpuc->lbr_entries[i].from  = from;
+               cpuc->lbr_entries[i].to    = to;
+               cpuc->lbr_entries[i].flags = flags;
+       }
+       cpuc->lbr_stack.nr = i;
+}
+
+static void intel_pmu_lbr_read(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       if (!cpuc->lbr_users)
+               return;
+
+       if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
+               intel_pmu_lbr_read_32(cpuc);
+       else
+               intel_pmu_lbr_read_64(cpuc);
+}
+
+static void intel_pmu_lbr_init_core(void)
+{
+       x86_pmu.lbr_nr     = 4;
+       x86_pmu.lbr_tos    = 0x01c9;
+       x86_pmu.lbr_from   = 0x40;
+       x86_pmu.lbr_to     = 0x60;
+}
+
+static void intel_pmu_lbr_init_nhm(void)
+{
+       x86_pmu.lbr_nr     = 16;
+       x86_pmu.lbr_tos    = 0x01c9;
+       x86_pmu.lbr_from   = 0x680;
+       x86_pmu.lbr_to     = 0x6c0;
+}
+
+static void intel_pmu_lbr_init_atom(void)
+{
+       x86_pmu.lbr_nr     = 8;
+       x86_pmu.lbr_tos    = 0x01c9;
+       x86_pmu.lbr_from   = 0x40;
+       x86_pmu.lbr_to     = 0x60;
+}
+
+#endif /* CONFIG_CPU_SUP_INTEL */
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c
new file mode 100644 (file)
index 0000000..424fc8d
--- /dev/null
@@ -0,0 +1,857 @@
+/*
+ * Netburst Perfomance Events (P4, old Xeon)
+ *
+ *  Copyright (C) 2010 Parallels, Inc., Cyrill Gorcunov <gorcunov@openvz.org>
+ *  Copyright (C) 2010 Intel Corporation, Lin Ming <ming.m.lin@intel.com>
+ *
+ *  For licencing details see kernel-base/COPYING
+ */
+
+#ifdef CONFIG_CPU_SUP_INTEL
+
+#include <asm/perf_event_p4.h>
+
+#define P4_CNTR_LIMIT 3
+/*
+ * array indices: 0,1 - HT threads, used with HT enabled cpu
+ */
+struct p4_event_bind {
+       unsigned int opcode;                    /* Event code and ESCR selector */
+       unsigned int escr_msr[2];               /* ESCR MSR for this event */
+       char cntr[2][P4_CNTR_LIMIT];            /* counter index (offset), -1 on abscence */
+};
+
+struct p4_cache_event_bind {
+       unsigned int metric_pebs;
+       unsigned int metric_vert;
+};
+
+#define P4_GEN_CACHE_EVENT_BIND(name)          \
+       [P4_CACHE__##name] = {                  \
+               .metric_pebs = P4_PEBS__##name, \
+               .metric_vert = P4_VERT__##name, \
+       }
+
+static struct p4_cache_event_bind p4_cache_event_bind_map[] = {
+       P4_GEN_CACHE_EVENT_BIND(1stl_cache_load_miss_retired),
+       P4_GEN_CACHE_EVENT_BIND(2ndl_cache_load_miss_retired),
+       P4_GEN_CACHE_EVENT_BIND(dtlb_load_miss_retired),
+       P4_GEN_CACHE_EVENT_BIND(dtlb_store_miss_retired),
+};
+
+/*
+ * Note that we don't use CCCR1 here, there is an
+ * exception for P4_BSQ_ALLOCATION but we just have
+ * no workaround
+ *
+ * consider this binding as resources which particular
+ * event may borrow, it doesn't contain EventMask,
+ * Tags and friends -- they are left to a caller
+ */
+static struct p4_event_bind p4_event_bind_map[] = {
+       [P4_EVENT_TC_DELIVER_MODE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_TC_DELIVER_MODE),
+               .escr_msr       = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 },
+               .cntr           = { {4, 5, -1}, {6, 7, -1} },
+       },
+       [P4_EVENT_BPU_FETCH_REQUEST] = {
+               .opcode         = P4_OPCODE(P4_EVENT_BPU_FETCH_REQUEST),
+               .escr_msr       = { MSR_P4_BPU_ESCR0, MSR_P4_BPU_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_ITLB_REFERENCE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_ITLB_REFERENCE),
+               .escr_msr       = { MSR_P4_ITLB_ESCR0, MSR_P4_ITLB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_MEMORY_CANCEL] = {
+               .opcode         = P4_OPCODE(P4_EVENT_MEMORY_CANCEL),
+               .escr_msr       = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_MEMORY_COMPLETE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_MEMORY_COMPLETE),
+               .escr_msr       = { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_LOAD_PORT_REPLAY] = {
+               .opcode         = P4_OPCODE(P4_EVENT_LOAD_PORT_REPLAY),
+               .escr_msr       = { MSR_P4_SAAT_ESCR0, MSR_P4_SAAT_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_STORE_PORT_REPLAY] = {
+               .opcode         = P4_OPCODE(P4_EVENT_STORE_PORT_REPLAY),
+               .escr_msr       = { MSR_P4_SAAT_ESCR0 ,  MSR_P4_SAAT_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_MOB_LOAD_REPLAY] = {
+               .opcode         = P4_OPCODE(P4_EVENT_MOB_LOAD_REPLAY),
+               .escr_msr       = { MSR_P4_MOB_ESCR0, MSR_P4_MOB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_PAGE_WALK_TYPE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_PAGE_WALK_TYPE),
+               .escr_msr       = { MSR_P4_PMH_ESCR0, MSR_P4_PMH_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_BSQ_CACHE_REFERENCE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_BSQ_CACHE_REFERENCE),
+               .escr_msr       = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_IOQ_ALLOCATION] = {
+               .opcode         = P4_OPCODE(P4_EVENT_IOQ_ALLOCATION),
+               .escr_msr       = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_IOQ_ACTIVE_ENTRIES] = {       /* shared ESCR */
+               .opcode         = P4_OPCODE(P4_EVENT_IOQ_ACTIVE_ENTRIES),
+               .escr_msr       = { MSR_P4_FSB_ESCR1,  MSR_P4_FSB_ESCR1 },
+               .cntr           = { {2, -1, -1}, {3, -1, -1} },
+       },
+       [P4_EVENT_FSB_DATA_ACTIVITY] = {
+               .opcode         = P4_OPCODE(P4_EVENT_FSB_DATA_ACTIVITY),
+               .escr_msr       = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_BSQ_ALLOCATION] = {           /* shared ESCR, broken CCCR1 */
+               .opcode         = P4_OPCODE(P4_EVENT_BSQ_ALLOCATION),
+               .escr_msr       = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR0 },
+               .cntr           = { {0, -1, -1}, {1, -1, -1} },
+       },
+       [P4_EVENT_BSQ_ACTIVE_ENTRIES] = {       /* shared ESCR */
+               .opcode         = P4_OPCODE(P4_EVENT_BSQ_ACTIVE_ENTRIES),
+               .escr_msr       = { MSR_P4_BSU_ESCR1 , MSR_P4_BSU_ESCR1 },
+               .cntr           = { {2, -1, -1}, {3, -1, -1} },
+       },
+       [P4_EVENT_SSE_INPUT_ASSIST] = {
+               .opcode         = P4_OPCODE(P4_EVENT_SSE_INPUT_ASSIST),
+               .escr_msr       = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_PACKED_SP_UOP] = {
+               .opcode         = P4_OPCODE(P4_EVENT_PACKED_SP_UOP),
+               .escr_msr       = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_PACKED_DP_UOP] = {
+               .opcode         = P4_OPCODE(P4_EVENT_PACKED_DP_UOP),
+               .escr_msr       = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_SCALAR_SP_UOP] = {
+               .opcode         = P4_OPCODE(P4_EVENT_SCALAR_SP_UOP),
+               .escr_msr       = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_SCALAR_DP_UOP] = {
+               .opcode         = P4_OPCODE(P4_EVENT_SCALAR_DP_UOP),
+               .escr_msr       = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_64BIT_MMX_UOP] = {
+               .opcode         = P4_OPCODE(P4_EVENT_64BIT_MMX_UOP),
+               .escr_msr       = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_128BIT_MMX_UOP] = {
+               .opcode         = P4_OPCODE(P4_EVENT_128BIT_MMX_UOP),
+               .escr_msr       = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_X87_FP_UOP] = {
+               .opcode         = P4_OPCODE(P4_EVENT_X87_FP_UOP),
+               .escr_msr       = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_TC_MISC] = {
+               .opcode         = P4_OPCODE(P4_EVENT_TC_MISC),
+               .escr_msr       = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 },
+               .cntr           = { {4, 5, -1}, {6, 7, -1} },
+       },
+       [P4_EVENT_GLOBAL_POWER_EVENTS] = {
+               .opcode         = P4_OPCODE(P4_EVENT_GLOBAL_POWER_EVENTS),
+               .escr_msr       = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_TC_MS_XFER] = {
+               .opcode         = P4_OPCODE(P4_EVENT_TC_MS_XFER),
+               .escr_msr       = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 },
+               .cntr           = { {4, 5, -1}, {6, 7, -1} },
+       },
+       [P4_EVENT_UOP_QUEUE_WRITES] = {
+               .opcode         = P4_OPCODE(P4_EVENT_UOP_QUEUE_WRITES),
+               .escr_msr       = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 },
+               .cntr           = { {4, 5, -1}, {6, 7, -1} },
+       },
+       [P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE),
+               .escr_msr       = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR0 },
+               .cntr           = { {4, 5, -1}, {6, 7, -1} },
+       },
+       [P4_EVENT_RETIRED_BRANCH_TYPE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_RETIRED_BRANCH_TYPE),
+               .escr_msr       = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR1 },
+               .cntr           = { {4, 5, -1}, {6, 7, -1} },
+       },
+       [P4_EVENT_RESOURCE_STALL] = {
+               .opcode         = P4_OPCODE(P4_EVENT_RESOURCE_STALL),
+               .escr_msr       = { MSR_P4_ALF_ESCR0, MSR_P4_ALF_ESCR1 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_WC_BUFFER] = {
+               .opcode         = P4_OPCODE(P4_EVENT_WC_BUFFER),
+               .escr_msr       = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_B2B_CYCLES] = {
+               .opcode         = P4_OPCODE(P4_EVENT_B2B_CYCLES),
+               .escr_msr       = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_BNR] = {
+               .opcode         = P4_OPCODE(P4_EVENT_BNR),
+               .escr_msr       = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_SNOOP] = {
+               .opcode         = P4_OPCODE(P4_EVENT_SNOOP),
+               .escr_msr       = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_RESPONSE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_RESPONSE),
+               .escr_msr       = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_FRONT_END_EVENT] = {
+               .opcode         = P4_OPCODE(P4_EVENT_FRONT_END_EVENT),
+               .escr_msr       = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_EXECUTION_EVENT] = {
+               .opcode         = P4_OPCODE(P4_EVENT_EXECUTION_EVENT),
+               .escr_msr       = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_REPLAY_EVENT] = {
+               .opcode         = P4_OPCODE(P4_EVENT_REPLAY_EVENT),
+               .escr_msr       = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_INSTR_RETIRED] = {
+               .opcode         = P4_OPCODE(P4_EVENT_INSTR_RETIRED),
+               .escr_msr       = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_UOPS_RETIRED] = {
+               .opcode         = P4_OPCODE(P4_EVENT_UOPS_RETIRED),
+               .escr_msr       = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_UOP_TYPE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_UOP_TYPE),
+               .escr_msr       = { MSR_P4_RAT_ESCR0, MSR_P4_RAT_ESCR1 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_BRANCH_RETIRED] = {
+               .opcode         = P4_OPCODE(P4_EVENT_BRANCH_RETIRED),
+               .escr_msr       = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_MISPRED_BRANCH_RETIRED] = {
+               .opcode         = P4_OPCODE(P4_EVENT_MISPRED_BRANCH_RETIRED),
+               .escr_msr       = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_X87_ASSIST] = {
+               .opcode         = P4_OPCODE(P4_EVENT_X87_ASSIST),
+               .escr_msr       = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_MACHINE_CLEAR] = {
+               .opcode         = P4_OPCODE(P4_EVENT_MACHINE_CLEAR),
+               .escr_msr       = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_INSTR_COMPLETED] = {
+               .opcode         = P4_OPCODE(P4_EVENT_INSTR_COMPLETED),
+               .escr_msr       = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+};
+
+#define P4_GEN_CACHE_EVENT(event, bit, cache_event)                      \
+       p4_config_pack_escr(P4_ESCR_EVENT(event)                        | \
+                           P4_ESCR_EMASK_BIT(event, bit))              | \
+       p4_config_pack_cccr(cache_event                                 | \
+                           P4_CCCR_ESEL(P4_OPCODE_ESEL(P4_OPCODE(event))))
+
+static __initconst const u64 p4_hw_cache_event_ids
+                               [PERF_COUNT_HW_CACHE_MAX]
+                               [PERF_COUNT_HW_CACHE_OP_MAX]
+                               [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D ) ] = {
+       [ C(OP_READ) ] = {
+               [ C(RESULT_ACCESS) ] = 0x0,
+               [ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
+                                               P4_CACHE__1stl_cache_load_miss_retired),
+       },
+ },
+ [ C(LL  ) ] = {
+       [ C(OP_READ) ] = {
+               [ C(RESULT_ACCESS) ] = 0x0,
+               [ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
+                                               P4_CACHE__2ndl_cache_load_miss_retired),
+       },
+},
+ [ C(DTLB) ] = {
+       [ C(OP_READ) ] = {
+               [ C(RESULT_ACCESS) ] = 0x0,
+               [ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
+                                               P4_CACHE__dtlb_load_miss_retired),
+       },
+       [ C(OP_WRITE) ] = {
+               [ C(RESULT_ACCESS) ] = 0x0,
+               [ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
+                                               P4_CACHE__dtlb_store_miss_retired),
+       },
+ },
+ [ C(ITLB) ] = {
+       [ C(OP_READ) ] = {
+               [ C(RESULT_ACCESS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, HIT,
+                                               P4_CACHE__itlb_reference_hit),
+               [ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, MISS,
+                                               P4_CACHE__itlb_reference_miss),
+       },
+       [ C(OP_WRITE) ] = {
+               [ C(RESULT_ACCESS) ] = -1,
+               [ C(RESULT_MISS)   ] = -1,
+       },
+       [ C(OP_PREFETCH) ] = {
+               [ C(RESULT_ACCESS) ] = -1,
+               [ C(RESULT_MISS)   ] = -1,
+       },
+ },
+};
+
+static u64 p4_general_events[PERF_COUNT_HW_MAX] = {
+  /* non-halted CPU clocks */
+  [PERF_COUNT_HW_CPU_CYCLES] =
+       p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_GLOBAL_POWER_EVENTS)         |
+               P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING)),
+
+  /*
+   * retired instructions
+   * in a sake of simplicity we don't use the FSB tagging
+   */
+  [PERF_COUNT_HW_INSTRUCTIONS] =
+       p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_INSTR_RETIRED)               |
+               P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG)           |
+               P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSNTAG)),
+
+  /* cache hits */
+  [PERF_COUNT_HW_CACHE_REFERENCES] =
+       p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_BSQ_CACHE_REFERENCE)         |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS)   |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE)   |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM)   |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS)   |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE)   |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM)),
+
+  /* cache misses */
+  [PERF_COUNT_HW_CACHE_MISSES] =
+       p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_BSQ_CACHE_REFERENCE)         |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS)   |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS)   |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS)),
+
+  /* branch instructions retired */
+  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] =
+       p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_RETIRED_BRANCH_TYPE)         |
+               P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL)    |
+               P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CALL)           |
+               P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN)         |
+               P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT)),
+
+  /* mispredicted branches retired */
+  [PERF_COUNT_HW_BRANCH_MISSES]        =
+       p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_MISPRED_BRANCH_RETIRED)      |
+               P4_ESCR_EMASK_BIT(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS)),
+
+  /* bus ready clocks (cpu is driving #DRDY_DRV\#DRDY_OWN):  */
+  [PERF_COUNT_HW_BUS_CYCLES] =
+       p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_FSB_DATA_ACTIVITY)           |
+               P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV)         |
+               P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN))        |
+       p4_config_pack_cccr(P4_CCCR_EDGE | P4_CCCR_COMPARE),
+};
+
+static struct p4_event_bind *p4_config_get_bind(u64 config)
+{
+       unsigned int evnt = p4_config_unpack_event(config);
+       struct p4_event_bind *bind = NULL;
+
+       if (evnt < ARRAY_SIZE(p4_event_bind_map))
+               bind = &p4_event_bind_map[evnt];
+
+       return bind;
+}
+
+static u64 p4_pmu_event_map(int hw_event)
+{
+       struct p4_event_bind *bind;
+       unsigned int esel;
+       u64 config;
+
+       config = p4_general_events[hw_event];
+       bind = p4_config_get_bind(config);
+       esel = P4_OPCODE_ESEL(bind->opcode);
+       config |= p4_config_pack_cccr(P4_CCCR_ESEL(esel));
+
+       return config;
+}
+
+static int p4_hw_config(struct perf_event *event)
+{
+       int cpu = get_cpu();
+       int rc = 0;
+       unsigned int evnt;
+       u32 escr, cccr;
+
+       /*
+        * the reason we use cpu that early is that: if we get scheduled
+        * first time on the same cpu -- we will not need swap thread
+        * specific flags in config (and will save some cpu cycles)
+        */
+
+       cccr = p4_default_cccr_conf(cpu);
+       escr = p4_default_escr_conf(cpu, event->attr.exclude_kernel,
+                                        event->attr.exclude_user);
+       event->hw.config = p4_config_pack_escr(escr) |
+                          p4_config_pack_cccr(cccr);
+
+       if (p4_ht_active() && p4_ht_thread(cpu))
+               event->hw.config = p4_set_ht_bit(event->hw.config);
+
+       if (event->attr.type == PERF_TYPE_RAW) {
+
+               /* user data may have out-of-bound event index */
+               evnt = p4_config_unpack_event(event->attr.config);
+               if (evnt >= ARRAY_SIZE(p4_event_bind_map)) {
+                       rc = -EINVAL;
+                       goto out;
+               }
+
+               /*
+                * We don't control raw events so it's up to the caller
+                * to pass sane values (and we don't count the thread number
+                * on HT machine but allow HT-compatible specifics to be
+                * passed on)
+                *
+                * XXX: HT wide things should check perf_paranoid_cpu() &&
+                *      CAP_SYS_ADMIN
+                */
+               event->hw.config |= event->attr.config &
+                       (p4_config_pack_escr(P4_ESCR_MASK_HT) |
+                        p4_config_pack_cccr(P4_CCCR_MASK_HT));
+       }
+
+       rc = x86_setup_perfctr(event);
+out:
+       put_cpu();
+       return rc;
+}
+
+static inline void p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc)
+{
+       unsigned long dummy;
+
+       rdmsrl(hwc->config_base + hwc->idx, dummy);
+       if (dummy & P4_CCCR_OVF) {
+               (void)checking_wrmsrl(hwc->config_base + hwc->idx,
+                       ((u64)dummy) & ~P4_CCCR_OVF);
+       }
+}
+
+static inline void p4_pmu_disable_event(struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+
+       /*
+        * If event gets disabled while counter is in overflowed
+        * state we need to clear P4_CCCR_OVF, otherwise interrupt get
+        * asserted again and again
+        */
+       (void)checking_wrmsrl(hwc->config_base + hwc->idx,
+               (u64)(p4_config_unpack_cccr(hwc->config)) &
+                       ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED);
+}
+
+static void p4_pmu_disable_all(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       int idx;
+
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+               struct perf_event *event = cpuc->events[idx];
+               if (!test_bit(idx, cpuc->active_mask))
+                       continue;
+               p4_pmu_disable_event(event);
+       }
+}
+
+static void p4_pmu_enable_event(struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+       int thread = p4_ht_config_thread(hwc->config);
+       u64 escr_conf = p4_config_unpack_escr(p4_clear_ht_bit(hwc->config));
+       unsigned int idx = p4_config_unpack_event(hwc->config);
+       unsigned int idx_cache = p4_config_unpack_cache_event(hwc->config);
+       struct p4_event_bind *bind;
+       struct p4_cache_event_bind *bind_cache;
+       u64 escr_addr, cccr;
+
+       bind = &p4_event_bind_map[idx];
+       escr_addr = (u64)bind->escr_msr[thread];
+
+       /*
+        * - we dont support cascaded counters yet
+        * - and counter 1 is broken (erratum)
+        */
+       WARN_ON_ONCE(p4_is_event_cascaded(hwc->config));
+       WARN_ON_ONCE(hwc->idx == 1);
+
+       /* we need a real Event value */
+       escr_conf &= ~P4_ESCR_EVENT_MASK;
+       escr_conf |= P4_ESCR_EVENT(P4_OPCODE_EVNT(bind->opcode));
+
+       cccr = p4_config_unpack_cccr(hwc->config);
+
+       /*
+        * it could be Cache event so that we need to
+        * set metrics into additional MSRs
+        */
+       BUILD_BUG_ON(P4_CACHE__MAX > P4_CCCR_CACHE_OPS_MASK);
+       if (idx_cache > P4_CACHE__NONE &&
+               idx_cache < ARRAY_SIZE(p4_cache_event_bind_map)) {
+               bind_cache = &p4_cache_event_bind_map[idx_cache];
+               (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)bind_cache->metric_pebs);
+               (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)bind_cache->metric_vert);
+       }
+
+       (void)checking_wrmsrl(escr_addr, escr_conf);
+       (void)checking_wrmsrl(hwc->config_base + hwc->idx,
+                               (cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE);
+}
+
+static void p4_pmu_enable_all(int added)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       int idx;
+
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+               struct perf_event *event = cpuc->events[idx];
+               if (!test_bit(idx, cpuc->active_mask))
+                       continue;
+               p4_pmu_enable_event(event);
+       }
+}
+
+static int p4_pmu_handle_irq(struct pt_regs *regs)
+{
+       struct perf_sample_data data;
+       struct cpu_hw_events *cpuc;
+       struct perf_event *event;
+       struct hw_perf_event *hwc;
+       int idx, handled = 0;
+       u64 val;
+
+       data.addr = 0;
+       data.raw = NULL;
+
+       cpuc = &__get_cpu_var(cpu_hw_events);
+
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+
+               if (!test_bit(idx, cpuc->active_mask))
+                       continue;
+
+               event = cpuc->events[idx];
+               hwc = &event->hw;
+
+               WARN_ON_ONCE(hwc->idx != idx);
+
+               /*
+                * FIXME: Redundant call, actually not needed
+                * but just to check if we're screwed
+                */
+               p4_pmu_clear_cccr_ovf(hwc);
+
+               val = x86_perf_event_update(event);
+               if (val & (1ULL << (x86_pmu.cntval_bits - 1)))
+                       continue;
+
+               /*
+                * event overflow
+                */
+               handled         = 1;
+               data.period     = event->hw.last_period;
+
+               if (!x86_perf_event_set_period(event))
+                       continue;
+               if (perf_event_overflow(event, 1, &data, regs))
+                       p4_pmu_disable_event(event);
+       }
+
+       if (handled) {
+               /* p4 quirk: unmask it again */
+               apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED);
+               inc_irq_stat(apic_perf_irqs);
+       }
+
+       return handled;
+}
+
+/*
+ * swap thread specific fields according to a thread
+ * we are going to run on
+ */
+static void p4_pmu_swap_config_ts(struct hw_perf_event *hwc, int cpu)
+{
+       u32 escr, cccr;
+
+       /*
+        * we either lucky and continue on same cpu or no HT support
+        */
+       if (!p4_should_swap_ts(hwc->config, cpu))
+               return;
+
+       /*
+        * the event is migrated from an another logical
+        * cpu, so we need to swap thread specific flags
+        */
+
+       escr = p4_config_unpack_escr(hwc->config);
+       cccr = p4_config_unpack_cccr(hwc->config);
+
+       if (p4_ht_thread(cpu)) {
+               cccr &= ~P4_CCCR_OVF_PMI_T0;
+               cccr |= P4_CCCR_OVF_PMI_T1;
+               if (escr & P4_ESCR_T0_OS) {
+                       escr &= ~P4_ESCR_T0_OS;
+                       escr |= P4_ESCR_T1_OS;
+               }
+               if (escr & P4_ESCR_T0_USR) {
+                       escr &= ~P4_ESCR_T0_USR;
+                       escr |= P4_ESCR_T1_USR;
+               }
+               hwc->config  = p4_config_pack_escr(escr);
+               hwc->config |= p4_config_pack_cccr(cccr);
+               hwc->config |= P4_CONFIG_HT;
+       } else {
+               cccr &= ~P4_CCCR_OVF_PMI_T1;
+               cccr |= P4_CCCR_OVF_PMI_T0;
+               if (escr & P4_ESCR_T1_OS) {
+                       escr &= ~P4_ESCR_T1_OS;
+                       escr |= P4_ESCR_T0_OS;
+               }
+               if (escr & P4_ESCR_T1_USR) {
+                       escr &= ~P4_ESCR_T1_USR;
+                       escr |= P4_ESCR_T0_USR;
+               }
+               hwc->config  = p4_config_pack_escr(escr);
+               hwc->config |= p4_config_pack_cccr(cccr);
+               hwc->config &= ~P4_CONFIG_HT;
+       }
+}
+
+/*
+ * ESCR address hashing is tricky, ESCRs are not sequential
+ * in memory but all starts from MSR_P4_BSU_ESCR0 (0x03e0) and
+ * the metric between any ESCRs is laid in range [0xa0,0xe1]
+ *
+ * so we make ~70% filled hashtable
+ */
+
+#define P4_ESCR_MSR_BASE               0x000003a0
+#define P4_ESCR_MSR_MAX                        0x000003e1
+#define P4_ESCR_MSR_TABLE_SIZE         (P4_ESCR_MSR_MAX - P4_ESCR_MSR_BASE + 1)
+#define P4_ESCR_MSR_IDX(msr)           (msr - P4_ESCR_MSR_BASE)
+#define P4_ESCR_MSR_TABLE_ENTRY(msr)   [P4_ESCR_MSR_IDX(msr)] = msr
+
+static const unsigned int p4_escr_table[P4_ESCR_MSR_TABLE_SIZE] = {
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ALF_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ALF_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BPU_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BPU_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BSU_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BSU_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR2),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR3),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR4),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR5),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_DAC_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_DAC_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FIRM_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FIRM_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FLAME_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FLAME_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FSB_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FSB_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IQ_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IQ_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IS_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IS_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ITLB_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ITLB_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IX_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IX_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MOB_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MOB_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MS_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MS_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_PMH_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_PMH_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_RAT_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_RAT_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SAAT_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SAAT_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SSU_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SSU_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TBPU_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TBPU_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TC_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TC_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_U2L_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_U2L_ESCR1),
+};
+
+static int p4_get_escr_idx(unsigned int addr)
+{
+       unsigned int idx = P4_ESCR_MSR_IDX(addr);
+
+       if (unlikely(idx >= P4_ESCR_MSR_TABLE_SIZE ||
+                       !p4_escr_table[idx])) {
+               WARN_ONCE(1, "P4 PMU: Wrong address passed: %x\n", addr);
+               return -1;
+       }
+
+       return idx;
+}
+
+static int p4_next_cntr(int thread, unsigned long *used_mask,
+                       struct p4_event_bind *bind)
+{
+       int i, j;
+
+       for (i = 0; i < P4_CNTR_LIMIT; i++) {
+               j = bind->cntr[thread][i];
+               if (j != -1 && !test_bit(j, used_mask))
+                       return j;
+       }
+
+       return -1;
+}
+
+static int p4_pmu_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
+{
+       unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+       unsigned long escr_mask[BITS_TO_LONGS(P4_ESCR_MSR_TABLE_SIZE)];
+       int cpu = raw_smp_processor_id();
+       struct hw_perf_event *hwc;
+       struct p4_event_bind *bind;
+       unsigned int i, thread, num;
+       int cntr_idx, escr_idx;
+
+       bitmap_zero(used_mask, X86_PMC_IDX_MAX);
+       bitmap_zero(escr_mask, P4_ESCR_MSR_TABLE_SIZE);
+
+       for (i = 0, num = n; i < n; i++, num--) {
+
+               hwc = &cpuc->event_list[i]->hw;
+               thread = p4_ht_thread(cpu);
+               bind = p4_config_get_bind(hwc->config);
+               escr_idx = p4_get_escr_idx(bind->escr_msr[thread]);
+               if (unlikely(escr_idx == -1))
+                       goto done;
+
+               if (hwc->idx != -1 && !p4_should_swap_ts(hwc->config, cpu)) {
+                       cntr_idx = hwc->idx;
+                       if (assign)
+                               assign[i] = hwc->idx;
+                       goto reserve;
+               }
+
+               cntr_idx = p4_next_cntr(thread, used_mask, bind);
+               if (cntr_idx == -1 || test_bit(escr_idx, escr_mask))
+                       goto done;
+
+               p4_pmu_swap_config_ts(hwc, cpu);
+               if (assign)
+                       assign[i] = cntr_idx;
+reserve:
+               set_bit(cntr_idx, used_mask);
+               set_bit(escr_idx, escr_mask);
+       }
+
+done:
+       return num ? -ENOSPC : 0;
+}
+
+static __initconst const struct x86_pmu p4_pmu = {
+       .name                   = "Netburst P4/Xeon",
+       .handle_irq             = p4_pmu_handle_irq,
+       .disable_all            = p4_pmu_disable_all,
+       .enable_all             = p4_pmu_enable_all,
+       .enable                 = p4_pmu_enable_event,
+       .disable                = p4_pmu_disable_event,
+       .eventsel               = MSR_P4_BPU_CCCR0,
+       .perfctr                = MSR_P4_BPU_PERFCTR0,
+       .event_map              = p4_pmu_event_map,
+       .max_events             = ARRAY_SIZE(p4_general_events),
+       .get_event_constraints  = x86_get_event_constraints,
+       /*
+        * IF HT disabled we may need to use all
+        * ARCH_P4_MAX_CCCR counters simulaneously
+        * though leave it restricted at moment assuming
+        * HT is on
+        */
+       .num_counters           = ARCH_P4_MAX_CCCR,
+       .apic                   = 1,
+       .cntval_bits            = 40,
+       .cntval_mask            = (1ULL << 40) - 1,
+       .max_period             = (1ULL << 39) - 1,
+       .hw_config              = p4_hw_config,
+       .schedule_events        = p4_pmu_schedule_events,
+};
+
+static __init int p4_pmu_init(void)
+{
+       unsigned int low, high;
+
+       /* If we get stripped -- indexig fails */
+       BUILD_BUG_ON(ARCH_P4_MAX_CCCR > X86_PMC_MAX_GENERIC);
+
+       rdmsr(MSR_IA32_MISC_ENABLE, low, high);
+       if (!(low & (1 << 7))) {
+               pr_cont("unsupported Netburst CPU model %d ",
+                       boot_cpu_data.x86_model);
+               return -ENODEV;
+       }
+
+       memcpy(hw_cache_event_ids, p4_hw_cache_event_ids,
+               sizeof(hw_cache_event_ids));
+
+       pr_cont("Netburst events, ");
+
+       x86_pmu = p4_pmu;
+
+       return 0;
+}
+
+#endif /* CONFIG_CPU_SUP_INTEL */
index a4e67b99d91c088f7d645aa57d5ed7bef124e0e3..34ba07be2cdab5ffa45b3dfe783fc24a939bceb1 100644 (file)
@@ -27,24 +27,6 @@ static u64 p6_pmu_event_map(int hw_event)
  */
 #define P6_NOP_EVENT                   0x0000002EULL
 
-static u64 p6_pmu_raw_event(u64 hw_event)
-{
-#define P6_EVNTSEL_EVENT_MASK          0x000000FFULL
-#define P6_EVNTSEL_UNIT_MASK           0x0000FF00ULL
-#define P6_EVNTSEL_EDGE_MASK           0x00040000ULL
-#define P6_EVNTSEL_INV_MASK            0x00800000ULL
-#define P6_EVNTSEL_REG_MASK            0xFF000000ULL
-
-#define P6_EVNTSEL_MASK                        \
-       (P6_EVNTSEL_EVENT_MASK |        \
-        P6_EVNTSEL_UNIT_MASK  |        \
-        P6_EVNTSEL_EDGE_MASK  |        \
-        P6_EVNTSEL_INV_MASK   |        \
-        P6_EVNTSEL_REG_MASK)
-
-       return hw_event & P6_EVNTSEL_MASK;
-}
-
 static struct event_constraint p6_event_constraints[] =
 {
        INTEL_EVENT_CONSTRAINT(0xc1, 0x1),      /* FLOPS */
@@ -66,7 +48,7 @@ static void p6_pmu_disable_all(void)
        wrmsrl(MSR_P6_EVNTSEL0, val);
 }
 
-static void p6_pmu_enable_all(void)
+static void p6_pmu_enable_all(int added)
 {
        unsigned long val;
 
@@ -77,45 +59,48 @@ static void p6_pmu_enable_all(void)
 }
 
 static inline void
-p6_pmu_disable_event(struct hw_perf_event *hwc, int idx)
+p6_pmu_disable_event(struct perf_event *event)
 {
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct hw_perf_event *hwc = &event->hw;
        u64 val = P6_NOP_EVENT;
 
        if (cpuc->enabled)
                val |= ARCH_PERFMON_EVENTSEL_ENABLE;
 
-       (void)checking_wrmsrl(hwc->config_base + idx, val);
+       (void)checking_wrmsrl(hwc->config_base + hwc->idx, val);
 }
 
-static void p6_pmu_enable_event(struct hw_perf_event *hwc, int idx)
+static void p6_pmu_enable_event(struct perf_event *event)
 {
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct hw_perf_event *hwc = &event->hw;
        u64 val;
 
        val = hwc->config;
        if (cpuc->enabled)
                val |= ARCH_PERFMON_EVENTSEL_ENABLE;
 
-       (void)checking_wrmsrl(hwc->config_base + idx, val);
+       (void)checking_wrmsrl(hwc->config_base + hwc->idx, val);
 }
 
-static __initconst struct x86_pmu p6_pmu = {
+static __initconst const struct x86_pmu p6_pmu = {
        .name                   = "p6",
        .handle_irq             = x86_pmu_handle_irq,
        .disable_all            = p6_pmu_disable_all,
        .enable_all             = p6_pmu_enable_all,
        .enable                 = p6_pmu_enable_event,
        .disable                = p6_pmu_disable_event,
+       .hw_config              = x86_pmu_hw_config,
+       .schedule_events        = x86_schedule_events,
        .eventsel               = MSR_P6_EVNTSEL0,
        .perfctr                = MSR_P6_PERFCTR0,
        .event_map              = p6_pmu_event_map,
-       .raw_event              = p6_pmu_raw_event,
        .max_events             = ARRAY_SIZE(p6_perfmon_event_map),
        .apic                   = 1,
        .max_period             = (1ULL << 31) - 1,
        .version                = 0,
-       .num_events             = 2,
+       .num_counters           = 2,
        /*
         * Events have 40 bits implemented. However they are designed such
         * that bits [32-39] are sign extensions of bit 31. As such the
@@ -123,8 +108,8 @@ static __initconst struct x86_pmu p6_pmu = {
         *
         * See IA-32 Intel Architecture Software developer manual Vol 3B
         */
-       .event_bits             = 32,
-       .event_mask             = (1ULL << 32) - 1,
+       .cntval_bits            = 32,
+       .cntval_mask            = (1ULL << 32) - 1,
        .get_event_constraints  = x86_get_event_constraints,
        .event_constraints      = p6_event_constraints,
 };
index 1cbed97b59cf841d8c41b4466ac040cf1c794b03..b9d1ff588445db7659ffd3d4d0e4414e846081d6 100644 (file)
  */
 
 #include <linux/dmi.h>
+#include <linux/module.h>
 #include <asm/div64.h>
-#include <asm/vmware.h>
 #include <asm/x86_init.h>
+#include <asm/hypervisor.h>
 
 #define CPUID_VMWARE_INFO_LEAF 0x40000000
 #define VMWARE_HYPERVISOR_MAGIC        0x564D5868
@@ -64,7 +65,7 @@ static unsigned long vmware_get_tsc_khz(void)
        return tsc_hz;
 }
 
-void __init vmware_platform_setup(void)
+static void __init vmware_platform_setup(void)
 {
        uint32_t eax, ebx, ecx, edx;
 
@@ -82,24 +83,21 @@ void __init vmware_platform_setup(void)
  * serial key should be enough, as this will always have a VMware
  * specific string when running under VMware hypervisor.
  */
-int vmware_platform(void)
+static bool __init vmware_platform(void)
 {
        if (cpu_has_hypervisor) {
-               unsigned int eax, ebx, ecx, edx;
-               char hyper_vendor_id[13];
-
-               cpuid(CPUID_VMWARE_INFO_LEAF, &eax, &ebx, &ecx, &edx);
-               memcpy(hyper_vendor_id + 0, &ebx, 4);
-               memcpy(hyper_vendor_id + 4, &ecx, 4);
-               memcpy(hyper_vendor_id + 8, &edx, 4);
-               hyper_vendor_id[12] = '\0';
-               if (!strcmp(hyper_vendor_id, "VMwareVMware"))
-                       return 1;
+               unsigned int eax;
+               unsigned int hyper_vendor_id[3];
+
+               cpuid(CPUID_VMWARE_INFO_LEAF, &eax, &hyper_vendor_id[0],
+                     &hyper_vendor_id[1], &hyper_vendor_id[2]);
+               if (!memcmp(hyper_vendor_id, "VMwareVMware", 12))
+                       return true;
        } else if (dmi_available && dmi_name_in_serial("VMware") &&
                   __vmware_platform())
-               return 1;
+               return true;
 
-       return 0;
+       return false;
 }
 
 /*
@@ -114,8 +112,16 @@ int vmware_platform(void)
  * so that the kernel could just trust the hypervisor with providing a
  * reliable virtual TSC that is suitable for timekeeping.
  */
-void __cpuinit vmware_set_feature_bits(struct cpuinfo_x86 *c)
+static void __cpuinit vmware_set_cpu_features(struct cpuinfo_x86 *c)
 {
        set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
        set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE);
 }
+
+const __refconst struct hypervisor_x86 x86_hyper_vmware = {
+       .name                   = "VMware",
+       .detect                 = vmware_platform,
+       .set_cpu_features       = vmware_set_cpu_features,
+       .init_platform          = vmware_platform_setup,
+};
+EXPORT_SYMBOL(x86_hyper_vmware);
index 83e5e628de73a7234f90c2f7130e98fa4df4fe4e..8b862d5900fe4a29b6bc100770e371db41ee0d91 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/cpu.h>
 #include <linux/notifier.h>
 #include <linux/uaccess.h>
+#include <linux/gfp.h>
 
 #include <asm/processor.h>
 #include <asm/msr.h>
index a4849c10a77e0b7016574e26b332910dcf2955a6..ebd4c51d096a525cbc6978561e11b3a4afbeb385 100644 (file)
@@ -27,7 +27,6 @@
 #include <asm/cpu.h>
 #include <asm/reboot.h>
 #include <asm/virtext.h>
-#include <asm/x86_init.h>
 
 #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
 
@@ -103,10 +102,5 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
 #ifdef CONFIG_HPET_TIMER
        hpet_disable();
 #endif
-
-#ifdef CONFIG_X86_64
-       x86_platform.iommu_shutdown();
-#endif
-
        crash_save_cpu(regs, safe_smp_processor_id());
 }
index cd97ce18c29d10e27e6c9f0421f1492137a313e6..67414550c3ccf25b3d5a3094ba42b5d0f158610d 100644 (file)
@@ -5,6 +5,7 @@
  *     Copyright (C) IBM Corporation, 2004. All rights reserved
  */
 
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/highmem.h>
 #include <linux/crash_dump.h>
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c
deleted file mode 100644 (file)
index 1c47390..0000000
+++ /dev/null
@@ -1,1437 +0,0 @@
-/*
- * Debug Store support
- *
- * This provides a low-level interface to the hardware's Debug Store
- * feature that is used for branch trace store (BTS) and
- * precise-event based sampling (PEBS).
- *
- * It manages:
- * - DS and BTS hardware configuration
- * - buffer overflow handling (to be done)
- * - buffer access
- *
- * It does not do:
- * - security checking (is the caller allowed to trace the task)
- * - buffer allocation (memory accounting)
- *
- *
- * Copyright (C) 2007-2009 Intel Corporation.
- * Markus Metzger <markus.t.metzger@intel.com>, 2007-2009
- */
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/trace_clock.h>
-
-#include <asm/ds.h>
-
-#include "ds_selftest.h"
-
-/*
- * The configuration for a particular DS hardware implementation:
- */
-struct ds_configuration {
-       /* The name of the configuration: */
-       const char              *name;
-
-       /* The size of pointer-typed fields in DS, BTS, and PEBS: */
-       unsigned char           sizeof_ptr_field;
-
-       /* The size of a BTS/PEBS record in bytes: */
-       unsigned char           sizeof_rec[2];
-
-       /* The number of pebs counter reset values in the DS structure. */
-       unsigned char           nr_counter_reset;
-
-       /* Control bit-masks indexed by enum ds_feature: */
-       unsigned long           ctl[dsf_ctl_max];
-};
-static struct ds_configuration ds_cfg __read_mostly;
-
-
-/* Maximal size of a DS configuration: */
-#define MAX_SIZEOF_DS          0x80
-
-/* Maximal size of a BTS record: */
-#define MAX_SIZEOF_BTS         (3 * 8)
-
-/* BTS and PEBS buffer alignment: */
-#define DS_ALIGNMENT           (1 << 3)
-
-/* Number of buffer pointers in DS: */
-#define NUM_DS_PTR_FIELDS      8
-
-/* Size of a pebs reset value in DS: */
-#define PEBS_RESET_FIELD_SIZE  8
-
-/* Mask of control bits in the DS MSR register: */
-#define BTS_CONTROL                              \
-       ( ds_cfg.ctl[dsf_bts]                   | \
-         ds_cfg.ctl[dsf_bts_kernel]            | \
-         ds_cfg.ctl[dsf_bts_user]              | \
-         ds_cfg.ctl[dsf_bts_overflow] )
-
-/*
- * A BTS or PEBS tracer.
- *
- * This holds the configuration of the tracer and serves as a handle
- * to identify tracers.
- */
-struct ds_tracer {
-       /* The DS context (partially) owned by this tracer. */
-       struct ds_context       *context;
-       /* The buffer provided on ds_request() and its size in bytes. */
-       void                    *buffer;
-       size_t                  size;
-};
-
-struct bts_tracer {
-       /* The common DS part: */
-       struct ds_tracer        ds;
-
-       /* The trace including the DS configuration: */
-       struct bts_trace        trace;
-
-       /* Buffer overflow notification function: */
-       bts_ovfl_callback_t     ovfl;
-
-       /* Active flags affecting trace collection. */
-       unsigned int            flags;
-};
-
-struct pebs_tracer {
-       /* The common DS part: */
-       struct ds_tracer        ds;
-
-       /* The trace including the DS configuration: */
-       struct pebs_trace       trace;
-
-       /* Buffer overflow notification function: */
-       pebs_ovfl_callback_t    ovfl;
-};
-
-/*
- * Debug Store (DS) save area configuration (see Intel64 and IA32
- * Architectures Software Developer's Manual, section 18.5)
- *
- * The DS configuration consists of the following fields; different
- * architetures vary in the size of those fields.
- *
- * - double-word aligned base linear address of the BTS buffer
- * - write pointer into the BTS buffer
- * - end linear address of the BTS buffer (one byte beyond the end of
- *   the buffer)
- * - interrupt pointer into BTS buffer
- *   (interrupt occurs when write pointer passes interrupt pointer)
- * - double-word aligned base linear address of the PEBS buffer
- * - write pointer into the PEBS buffer
- * - end linear address of the PEBS buffer (one byte beyond the end of
- *   the buffer)
- * - interrupt pointer into PEBS buffer
- *   (interrupt occurs when write pointer passes interrupt pointer)
- * - value to which counter is reset following counter overflow
- *
- * Later architectures use 64bit pointers throughout, whereas earlier
- * architectures use 32bit pointers in 32bit mode.
- *
- *
- * We compute the base address for the first 8 fields based on:
- * - the field size stored in the DS configuration
- * - the relative field position
- * - an offset giving the start of the respective region
- *
- * This offset is further used to index various arrays holding
- * information for BTS and PEBS at the respective index.
- *
- * On later 32bit processors, we only access the lower 32bit of the
- * 64bit pointer fields. The upper halves will be zeroed out.
- */
-
-enum ds_field {
-       ds_buffer_base = 0,
-       ds_index,
-       ds_absolute_maximum,
-       ds_interrupt_threshold,
-};
-
-enum ds_qualifier {
-       ds_bts = 0,
-       ds_pebs
-};
-
-static inline unsigned long
-ds_get(const unsigned char *base, enum ds_qualifier qual, enum ds_field field)
-{
-       base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual)));
-       return *(unsigned long *)base;
-}
-
-static inline void
-ds_set(unsigned char *base, enum ds_qualifier qual, enum ds_field field,
-       unsigned long value)
-{
-       base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual)));
-       (*(unsigned long *)base) = value;
-}
-
-
-/*
- * Locking is done only for allocating BTS or PEBS resources.
- */
-static DEFINE_SPINLOCK(ds_lock);
-
-/*
- * We either support (system-wide) per-cpu or per-thread allocation.
- * We distinguish the two based on the task_struct pointer, where a
- * NULL pointer indicates per-cpu allocation for the current cpu.
- *
- * Allocations are use-counted. As soon as resources are allocated,
- * further allocations must be of the same type (per-cpu or
- * per-thread). We model this by counting allocations (i.e. the number
- * of tracers of a certain type) for one type negatively:
- *   =0  no tracers
- *   >0  number of per-thread tracers
- *   <0  number of per-cpu tracers
- *
- * Tracers essentially gives the number of ds contexts for a certain
- * type of allocation.
- */
-static atomic_t tracers = ATOMIC_INIT(0);
-
-static inline int get_tracer(struct task_struct *task)
-{
-       int error;
-
-       spin_lock_irq(&ds_lock);
-
-       if (task) {
-               error = -EPERM;
-               if (atomic_read(&tracers) < 0)
-                       goto out;
-               atomic_inc(&tracers);
-       } else {
-               error = -EPERM;
-               if (atomic_read(&tracers) > 0)
-                       goto out;
-               atomic_dec(&tracers);
-       }
-
-       error = 0;
-out:
-       spin_unlock_irq(&ds_lock);
-       return error;
-}
-
-static inline void put_tracer(struct task_struct *task)
-{
-       if (task)
-               atomic_dec(&tracers);
-       else
-               atomic_inc(&tracers);
-}
-
-/*
- * The DS context is either attached to a thread or to a cpu:
- * - in the former case, the thread_struct contains a pointer to the
- *   attached context.
- * - in the latter case, we use a static array of per-cpu context
- *   pointers.
- *
- * Contexts are use-counted. They are allocated on first access and
- * deallocated when the last user puts the context.
- */
-struct ds_context {
-       /* The DS configuration; goes into MSR_IA32_DS_AREA: */
-       unsigned char           ds[MAX_SIZEOF_DS];
-
-       /* The owner of the BTS and PEBS configuration, respectively: */
-       struct bts_tracer       *bts_master;
-       struct pebs_tracer      *pebs_master;
-
-       /* Use count: */
-       unsigned long           count;
-
-       /* Pointer to the context pointer field: */
-       struct ds_context       **this;
-
-       /* The traced task; NULL for cpu tracing: */
-       struct task_struct      *task;
-
-       /* The traced cpu; only valid if task is NULL: */
-       int                     cpu;
-};
-
-static DEFINE_PER_CPU(struct ds_context *, cpu_ds_context);
-
-
-static struct ds_context *ds_get_context(struct task_struct *task, int cpu)
-{
-       struct ds_context **p_context =
-               (task ? &task->thread.ds_ctx : &per_cpu(cpu_ds_context, cpu));
-       struct ds_context *context = NULL;
-       struct ds_context *new_context = NULL;
-
-       /* Chances are small that we already have a context. */
-       new_context = kzalloc(sizeof(*new_context), GFP_KERNEL);
-       if (!new_context)
-               return NULL;
-
-       spin_lock_irq(&ds_lock);
-
-       context = *p_context;
-       if (likely(!context)) {
-               context = new_context;
-
-               context->this = p_context;
-               context->task = task;
-               context->cpu = cpu;
-               context->count = 0;
-
-               *p_context = context;
-       }
-
-       context->count++;
-
-       spin_unlock_irq(&ds_lock);
-
-       if (context != new_context)
-               kfree(new_context);
-
-       return context;
-}
-
-static void ds_put_context(struct ds_context *context)
-{
-       struct task_struct *task;
-       unsigned long irq;
-
-       if (!context)
-               return;
-
-       spin_lock_irqsave(&ds_lock, irq);
-
-       if (--context->count) {
-               spin_unlock_irqrestore(&ds_lock, irq);
-               return;
-       }
-
-       *(context->this) = NULL;
-
-       task = context->task;
-
-       if (task)
-               clear_tsk_thread_flag(task, TIF_DS_AREA_MSR);
-
-       /*
-        * We leave the (now dangling) pointer to the DS configuration in
-        * the DS_AREA msr. This is as good or as bad as replacing it with
-        * NULL - the hardware would crash if we enabled tracing.
-        *
-        * This saves us some problems with having to write an msr on a
-        * different cpu while preventing others from doing the same for the
-        * next context for that same cpu.
-        */
-
-       spin_unlock_irqrestore(&ds_lock, irq);
-
-       /* The context might still be in use for context switching. */
-       if (task && (task != current))
-               wait_task_context_switch(task);
-
-       kfree(context);
-}
-
-static void ds_install_ds_area(struct ds_context *context)
-{
-       unsigned long ds;
-
-       ds = (unsigned long)context->ds;
-
-       /*
-        * There is a race between the bts master and the pebs master.
-        *
-        * The thread/cpu access is synchronized via get/put_cpu() for
-        * task tracing and via wrmsr_on_cpu for cpu tracing.
-        *
-        * If bts and pebs are collected for the same task or same cpu,
-        * the same confiuration is written twice.
-        */
-       if (context->task) {
-               get_cpu();
-               if (context->task == current)
-                       wrmsrl(MSR_IA32_DS_AREA, ds);
-               set_tsk_thread_flag(context->task, TIF_DS_AREA_MSR);
-               put_cpu();
-       } else
-               wrmsr_on_cpu(context->cpu, MSR_IA32_DS_AREA,
-                            (u32)((u64)ds), (u32)((u64)ds >> 32));
-}
-
-/*
- * Call the tracer's callback on a buffer overflow.
- *
- * context: the ds context
- * qual: the buffer type
- */
-static void ds_overflow(struct ds_context *context, enum ds_qualifier qual)
-{
-       switch (qual) {
-       case ds_bts:
-               if (context->bts_master &&
-                   context->bts_master->ovfl)
-                       context->bts_master->ovfl(context->bts_master);
-               break;
-       case ds_pebs:
-               if (context->pebs_master &&
-                   context->pebs_master->ovfl)
-                       context->pebs_master->ovfl(context->pebs_master);
-               break;
-       }
-}
-
-
-/*
- * Write raw data into the BTS or PEBS buffer.
- *
- * The remainder of any partially written record is zeroed out.
- *
- * context: the DS context
- * qual:    the buffer type
- * record:  the data to write
- * size:    the size of the data
- */
-static int ds_write(struct ds_context *context, enum ds_qualifier qual,
-                   const void *record, size_t size)
-{
-       int bytes_written = 0;
-
-       if (!record)
-               return -EINVAL;
-
-       while (size) {
-               unsigned long base, index, end, write_end, int_th;
-               unsigned long write_size, adj_write_size;
-
-               /*
-                * Write as much as possible without producing an
-                * overflow interrupt.
-                *
-                * Interrupt_threshold must either be
-                * - bigger than absolute_maximum or
-                * - point to a record between buffer_base and absolute_maximum
-                *
-                * Index points to a valid record.
-                */
-               base   = ds_get(context->ds, qual, ds_buffer_base);
-               index  = ds_get(context->ds, qual, ds_index);
-               end    = ds_get(context->ds, qual, ds_absolute_maximum);
-               int_th = ds_get(context->ds, qual, ds_interrupt_threshold);
-
-               write_end = min(end, int_th);
-
-               /*
-                * If we are already beyond the interrupt threshold,
-                * we fill the entire buffer.
-                */
-               if (write_end <= index)
-                       write_end = end;
-
-               if (write_end <= index)
-                       break;
-
-               write_size = min((unsigned long) size, write_end - index);
-               memcpy((void *)index, record, write_size);
-
-               record = (const char *)record + write_size;
-               size -= write_size;
-               bytes_written += write_size;
-
-               adj_write_size = write_size / ds_cfg.sizeof_rec[qual];
-               adj_write_size *= ds_cfg.sizeof_rec[qual];
-
-               /* Zero out trailing bytes. */
-               memset((char *)index + write_size, 0,
-                      adj_write_size - write_size);
-               index += adj_write_size;
-
-               if (index >= end)
-                       index = base;
-               ds_set(context->ds, qual, ds_index, index);
-
-               if (index >= int_th)
-                       ds_overflow(context, qual);
-       }
-
-       return bytes_written;
-}
-
-
-/*
- * Branch Trace Store (BTS) uses the following format. Different
- * architectures vary in the size of those fields.
- * - source linear address
- * - destination linear address
- * - flags
- *
- * Later architectures use 64bit pointers throughout, whereas earlier
- * architectures use 32bit pointers in 32bit mode.
- *
- * We compute the base address for the fields based on:
- * - the field size stored in the DS configuration
- * - the relative field position
- *
- * In order to store additional information in the BTS buffer, we use
- * a special source address to indicate that the record requires
- * special interpretation.
- *
- * Netburst indicated via a bit in the flags field whether the branch
- * was predicted; this is ignored.
- *
- * We use two levels of abstraction:
- * - the raw data level defined here
- * - an arch-independent level defined in ds.h
- */
-
-enum bts_field {
-       bts_from,
-       bts_to,
-       bts_flags,
-
-       bts_qual                = bts_from,
-       bts_clock               = bts_to,
-       bts_pid                 = bts_flags,
-
-       bts_qual_mask           = (bts_qual_max - 1),
-       bts_escape              = ((unsigned long)-1 & ~bts_qual_mask)
-};
-
-static inline unsigned long bts_get(const char *base, unsigned long field)
-{
-       base += (ds_cfg.sizeof_ptr_field * field);
-       return *(unsigned long *)base;
-}
-
-static inline void bts_set(char *base, unsigned long field, unsigned long val)
-{
-       base += (ds_cfg.sizeof_ptr_field * field);
-       (*(unsigned long *)base) = val;
-}
-
-
-/*
- * The raw BTS data is architecture dependent.
- *
- * For higher-level users, we give an arch-independent view.
- * - ds.h defines struct bts_struct
- * - bts_read translates one raw bts record into a bts_struct
- * - bts_write translates one bts_struct into the raw format and
- *   writes it into the top of the parameter tracer's buffer.
- *
- * return: bytes read/written on success; -Eerrno, otherwise
- */
-static int
-bts_read(struct bts_tracer *tracer, const void *at, struct bts_struct *out)
-{
-       if (!tracer)
-               return -EINVAL;
-
-       if (at < tracer->trace.ds.begin)
-               return -EINVAL;
-
-       if (tracer->trace.ds.end < (at + tracer->trace.ds.size))
-               return -EINVAL;
-
-       memset(out, 0, sizeof(*out));
-       if ((bts_get(at, bts_qual) & ~bts_qual_mask) == bts_escape) {
-               out->qualifier = (bts_get(at, bts_qual) & bts_qual_mask);
-               out->variant.event.clock = bts_get(at, bts_clock);
-               out->variant.event.pid = bts_get(at, bts_pid);
-       } else {
-               out->qualifier = bts_branch;
-               out->variant.lbr.from = bts_get(at, bts_from);
-               out->variant.lbr.to   = bts_get(at, bts_to);
-
-               if (!out->variant.lbr.from && !out->variant.lbr.to)
-                       out->qualifier = bts_invalid;
-       }
-
-       return ds_cfg.sizeof_rec[ds_bts];
-}
-
-static int bts_write(struct bts_tracer *tracer, const struct bts_struct *in)
-{
-       unsigned char raw[MAX_SIZEOF_BTS];
-
-       if (!tracer)
-               return -EINVAL;
-
-       if (MAX_SIZEOF_BTS < ds_cfg.sizeof_rec[ds_bts])
-               return -EOVERFLOW;
-
-       switch (in->qualifier) {
-       case bts_invalid:
-               bts_set(raw, bts_from, 0);
-               bts_set(raw, bts_to, 0);
-               bts_set(raw, bts_flags, 0);
-               break;
-       case bts_branch:
-               bts_set(raw, bts_from, in->variant.lbr.from);
-               bts_set(raw, bts_to,   in->variant.lbr.to);
-               bts_set(raw, bts_flags, 0);
-               break;
-       case bts_task_arrives:
-       case bts_task_departs:
-               bts_set(raw, bts_qual, (bts_escape | in->qualifier));
-               bts_set(raw, bts_clock, in->variant.event.clock);
-               bts_set(raw, bts_pid, in->variant.event.pid);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return ds_write(tracer->ds.context, ds_bts, raw,
-                       ds_cfg.sizeof_rec[ds_bts]);
-}
-
-
-static void ds_write_config(struct ds_context *context,
-                           struct ds_trace *cfg, enum ds_qualifier qual)
-{
-       unsigned char *ds = context->ds;
-
-       ds_set(ds, qual, ds_buffer_base, (unsigned long)cfg->begin);
-       ds_set(ds, qual, ds_index, (unsigned long)cfg->top);
-       ds_set(ds, qual, ds_absolute_maximum, (unsigned long)cfg->end);
-       ds_set(ds, qual, ds_interrupt_threshold, (unsigned long)cfg->ith);
-}
-
-static void ds_read_config(struct ds_context *context,
-                          struct ds_trace *cfg, enum ds_qualifier qual)
-{
-       unsigned char *ds = context->ds;
-
-       cfg->begin = (void *)ds_get(ds, qual, ds_buffer_base);
-       cfg->top = (void *)ds_get(ds, qual, ds_index);
-       cfg->end = (void *)ds_get(ds, qual, ds_absolute_maximum);
-       cfg->ith = (void *)ds_get(ds, qual, ds_interrupt_threshold);
-}
-
-static void ds_init_ds_trace(struct ds_trace *trace, enum ds_qualifier qual,
-                            void *base, size_t size, size_t ith,
-                            unsigned int flags) {
-       unsigned long buffer, adj;
-
-       /*
-        * Adjust the buffer address and size to meet alignment
-        * constraints:
-        * - buffer is double-word aligned
-        * - size is multiple of record size
-        *
-        * We checked the size at the very beginning; we have enough
-        * space to do the adjustment.
-        */
-       buffer = (unsigned long)base;
-
-       adj = ALIGN(buffer, DS_ALIGNMENT) - buffer;
-       buffer += adj;
-       size   -= adj;
-
-       trace->n = size / ds_cfg.sizeof_rec[qual];
-       trace->size = ds_cfg.sizeof_rec[qual];
-
-       size = (trace->n * trace->size);
-
-       trace->begin = (void *)buffer;
-       trace->top = trace->begin;
-       trace->end = (void *)(buffer + size);
-       /*
-        * The value for 'no threshold' is -1, which will set the
-        * threshold outside of the buffer, just like we want it.
-        */
-       ith *= ds_cfg.sizeof_rec[qual];
-       trace->ith = (void *)(buffer + size - ith);
-
-       trace->flags = flags;
-}
-
-
-static int ds_request(struct ds_tracer *tracer, struct ds_trace *trace,
-                     enum ds_qualifier qual, struct task_struct *task,
-                     int cpu, void *base, size_t size, size_t th)
-{
-       struct ds_context *context;
-       int error;
-       size_t req_size;
-
-       error = -EOPNOTSUPP;
-       if (!ds_cfg.sizeof_rec[qual])
-               goto out;
-
-       error = -EINVAL;
-       if (!base)
-               goto out;
-
-       req_size = ds_cfg.sizeof_rec[qual];
-       /* We might need space for alignment adjustments. */
-       if (!IS_ALIGNED((unsigned long)base, DS_ALIGNMENT))
-               req_size += DS_ALIGNMENT;
-
-       error = -EINVAL;
-       if (size < req_size)
-               goto out;
-
-       if (th != (size_t)-1) {
-               th *= ds_cfg.sizeof_rec[qual];
-
-               error = -EINVAL;
-               if (size <= th)
-                       goto out;
-       }
-
-       tracer->buffer = base;
-       tracer->size = size;
-
-       error = -ENOMEM;
-       context = ds_get_context(task, cpu);
-       if (!context)
-               goto out;
-       tracer->context = context;
-
-       /*
-        * Defer any tracer-specific initialization work for the context until
-        * context ownership has been clarified.
-        */
-
-       error = 0;
- out:
-       return error;
-}
-
-static struct bts_tracer *ds_request_bts(struct task_struct *task, int cpu,
-                                        void *base, size_t size,
-                                        bts_ovfl_callback_t ovfl, size_t th,
-                                        unsigned int flags)
-{
-       struct bts_tracer *tracer;
-       int error;
-
-       /* Buffer overflow notification is not yet implemented. */
-       error = -EOPNOTSUPP;
-       if (ovfl)
-               goto out;
-
-       error = get_tracer(task);
-       if (error < 0)
-               goto out;
-
-       error = -ENOMEM;
-       tracer = kzalloc(sizeof(*tracer), GFP_KERNEL);
-       if (!tracer)
-               goto out_put_tracer;
-       tracer->ovfl = ovfl;
-
-       /* Do some more error checking and acquire a tracing context. */
-       error = ds_request(&tracer->ds, &tracer->trace.ds,
-                          ds_bts, task, cpu, base, size, th);
-       if (error < 0)
-               goto out_tracer;
-
-       /* Claim the bts part of the tracing context we acquired above. */
-       spin_lock_irq(&ds_lock);
-
-       error = -EPERM;
-       if (tracer->ds.context->bts_master)
-               goto out_unlock;
-       tracer->ds.context->bts_master = tracer;
-
-       spin_unlock_irq(&ds_lock);
-
-       /*
-        * Now that we own the bts part of the context, let's complete the
-        * initialization for that part.
-        */
-       ds_init_ds_trace(&tracer->trace.ds, ds_bts, base, size, th, flags);
-       ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_bts);
-       ds_install_ds_area(tracer->ds.context);
-
-       tracer->trace.read  = bts_read;
-       tracer->trace.write = bts_write;
-
-       /* Start tracing. */
-       ds_resume_bts(tracer);
-
-       return tracer;
-
- out_unlock:
-       spin_unlock_irq(&ds_lock);
-       ds_put_context(tracer->ds.context);
- out_tracer:
-       kfree(tracer);
- out_put_tracer:
-       put_tracer(task);
- out:
-       return ERR_PTR(error);
-}
-
-struct bts_tracer *ds_request_bts_task(struct task_struct *task,
-                                      void *base, size_t size,
-                                      bts_ovfl_callback_t ovfl,
-                                      size_t th, unsigned int flags)
-{
-       return ds_request_bts(task, 0, base, size, ovfl, th, flags);
-}
-
-struct bts_tracer *ds_request_bts_cpu(int cpu, void *base, size_t size,
-                                     bts_ovfl_callback_t ovfl,
-                                     size_t th, unsigned int flags)
-{
-       return ds_request_bts(NULL, cpu, base, size, ovfl, th, flags);
-}
-
-static struct pebs_tracer *ds_request_pebs(struct task_struct *task, int cpu,
-                                          void *base, size_t size,
-                                          pebs_ovfl_callback_t ovfl, size_t th,
-                                          unsigned int flags)
-{
-       struct pebs_tracer *tracer;
-       int error;
-
-       /* Buffer overflow notification is not yet implemented. */
-       error = -EOPNOTSUPP;
-       if (ovfl)
-               goto out;
-
-       error = get_tracer(task);
-       if (error < 0)
-               goto out;
-
-       error = -ENOMEM;
-       tracer = kzalloc(sizeof(*tracer), GFP_KERNEL);
-       if (!tracer)
-               goto out_put_tracer;
-       tracer->ovfl = ovfl;
-
-       /* Do some more error checking and acquire a tracing context. */
-       error = ds_request(&tracer->ds, &tracer->trace.ds,
-                          ds_pebs, task, cpu, base, size, th);
-       if (error < 0)
-               goto out_tracer;
-
-       /* Claim the pebs part of the tracing context we acquired above. */
-       spin_lock_irq(&ds_lock);
-
-       error = -EPERM;
-       if (tracer->ds.context->pebs_master)
-               goto out_unlock;
-       tracer->ds.context->pebs_master = tracer;
-
-       spin_unlock_irq(&ds_lock);
-
-       /*
-        * Now that we own the pebs part of the context, let's complete the
-        * initialization for that part.
-        */
-       ds_init_ds_trace(&tracer->trace.ds, ds_pebs, base, size, th, flags);
-       ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_pebs);
-       ds_install_ds_area(tracer->ds.context);
-
-       /* Start tracing. */
-       ds_resume_pebs(tracer);
-
-       return tracer;
-
- out_unlock:
-       spin_unlock_irq(&ds_lock);
-       ds_put_context(tracer->ds.context);
- out_tracer:
-       kfree(tracer);
- out_put_tracer:
-       put_tracer(task);
- out:
-       return ERR_PTR(error);
-}
-
-struct pebs_tracer *ds_request_pebs_task(struct task_struct *task,
-                                        void *base, size_t size,
-                                        pebs_ovfl_callback_t ovfl,
-                                        size_t th, unsigned int flags)
-{
-       return ds_request_pebs(task, 0, base, size, ovfl, th, flags);
-}
-
-struct pebs_tracer *ds_request_pebs_cpu(int cpu, void *base, size_t size,
-                                       pebs_ovfl_callback_t ovfl,
-                                       size_t th, unsigned int flags)
-{
-       return ds_request_pebs(NULL, cpu, base, size, ovfl, th, flags);
-}
-
-static void ds_free_bts(struct bts_tracer *tracer)
-{
-       struct task_struct *task;
-
-       task = tracer->ds.context->task;
-
-       WARN_ON_ONCE(tracer->ds.context->bts_master != tracer);
-       tracer->ds.context->bts_master = NULL;
-
-       /* Make sure tracing stopped and the tracer is not in use. */
-       if (task && (task != current))
-               wait_task_context_switch(task);
-
-       ds_put_context(tracer->ds.context);
-       put_tracer(task);
-
-       kfree(tracer);
-}
-
-void ds_release_bts(struct bts_tracer *tracer)
-{
-       might_sleep();
-
-       if (!tracer)
-               return;
-
-       ds_suspend_bts(tracer);
-       ds_free_bts(tracer);
-}
-
-int ds_release_bts_noirq(struct bts_tracer *tracer)
-{
-       struct task_struct *task;
-       unsigned long irq;
-       int error;
-
-       if (!tracer)
-               return 0;
-
-       task = tracer->ds.context->task;
-
-       local_irq_save(irq);
-
-       error = -EPERM;
-       if (!task &&
-           (tracer->ds.context->cpu != smp_processor_id()))
-               goto out;
-
-       error = -EPERM;
-       if (task && (task != current))
-               goto out;
-
-       ds_suspend_bts_noirq(tracer);
-       ds_free_bts(tracer);
-
-       error = 0;
- out:
-       local_irq_restore(irq);
-       return error;
-}
-
-static void update_task_debugctlmsr(struct task_struct *task,
-                                   unsigned long debugctlmsr)
-{
-       task->thread.debugctlmsr = debugctlmsr;
-
-       get_cpu();
-       if (task == current)
-               update_debugctlmsr(debugctlmsr);
-       put_cpu();
-}
-
-void ds_suspend_bts(struct bts_tracer *tracer)
-{
-       struct task_struct *task;
-       unsigned long debugctlmsr;
-       int cpu;
-
-       if (!tracer)
-               return;
-
-       tracer->flags = 0;
-
-       task = tracer->ds.context->task;
-       cpu  = tracer->ds.context->cpu;
-
-       WARN_ON(!task && irqs_disabled());
-
-       debugctlmsr = (task ?
-                      task->thread.debugctlmsr :
-                      get_debugctlmsr_on_cpu(cpu));
-       debugctlmsr &= ~BTS_CONTROL;
-
-       if (task)
-               update_task_debugctlmsr(task, debugctlmsr);
-       else
-               update_debugctlmsr_on_cpu(cpu, debugctlmsr);
-}
-
-int ds_suspend_bts_noirq(struct bts_tracer *tracer)
-{
-       struct task_struct *task;
-       unsigned long debugctlmsr, irq;
-       int cpu, error = 0;
-
-       if (!tracer)
-               return 0;
-
-       tracer->flags = 0;
-
-       task = tracer->ds.context->task;
-       cpu  = tracer->ds.context->cpu;
-
-       local_irq_save(irq);
-
-       error = -EPERM;
-       if (!task && (cpu != smp_processor_id()))
-               goto out;
-
-       debugctlmsr = (task ?
-                      task->thread.debugctlmsr :
-                      get_debugctlmsr());
-       debugctlmsr &= ~BTS_CONTROL;
-
-       if (task)
-               update_task_debugctlmsr(task, debugctlmsr);
-       else
-               update_debugctlmsr(debugctlmsr);
-
-       error = 0;
- out:
-       local_irq_restore(irq);
-       return error;
-}
-
-static unsigned long ds_bts_control(struct bts_tracer *tracer)
-{
-       unsigned long control;
-
-       control = ds_cfg.ctl[dsf_bts];
-       if (!(tracer->trace.ds.flags & BTS_KERNEL))
-               control |= ds_cfg.ctl[dsf_bts_kernel];
-       if (!(tracer->trace.ds.flags & BTS_USER))
-               control |= ds_cfg.ctl[dsf_bts_user];
-
-       return control;
-}
-
-void ds_resume_bts(struct bts_tracer *tracer)
-{
-       struct task_struct *task;
-       unsigned long debugctlmsr;
-       int cpu;
-
-       if (!tracer)
-               return;
-
-       tracer->flags = tracer->trace.ds.flags;
-
-       task = tracer->ds.context->task;
-       cpu  = tracer->ds.context->cpu;
-
-       WARN_ON(!task && irqs_disabled());
-
-       debugctlmsr = (task ?
-                      task->thread.debugctlmsr :
-                      get_debugctlmsr_on_cpu(cpu));
-       debugctlmsr |= ds_bts_control(tracer);
-
-       if (task)
-               update_task_debugctlmsr(task, debugctlmsr);
-       else
-               update_debugctlmsr_on_cpu(cpu, debugctlmsr);
-}
-
-int ds_resume_bts_noirq(struct bts_tracer *tracer)
-{
-       struct task_struct *task;
-       unsigned long debugctlmsr, irq;
-       int cpu, error = 0;
-
-       if (!tracer)
-               return 0;
-
-       tracer->flags = tracer->trace.ds.flags;
-
-       task = tracer->ds.context->task;
-       cpu  = tracer->ds.context->cpu;
-
-       local_irq_save(irq);
-
-       error = -EPERM;
-       if (!task && (cpu != smp_processor_id()))
-               goto out;
-
-       debugctlmsr = (task ?
-                      task->thread.debugctlmsr :
-                      get_debugctlmsr());
-       debugctlmsr |= ds_bts_control(tracer);
-
-       if (task)
-               update_task_debugctlmsr(task, debugctlmsr);
-       else
-               update_debugctlmsr(debugctlmsr);
-
-       error = 0;
- out:
-       local_irq_restore(irq);
-       return error;
-}
-
-static void ds_free_pebs(struct pebs_tracer *tracer)
-{
-       struct task_struct *task;
-
-       task = tracer->ds.context->task;
-
-       WARN_ON_ONCE(tracer->ds.context->pebs_master != tracer);
-       tracer->ds.context->pebs_master = NULL;
-
-       ds_put_context(tracer->ds.context);
-       put_tracer(task);
-
-       kfree(tracer);
-}
-
-void ds_release_pebs(struct pebs_tracer *tracer)
-{
-       might_sleep();
-
-       if (!tracer)
-               return;
-
-       ds_suspend_pebs(tracer);
-       ds_free_pebs(tracer);
-}
-
-int ds_release_pebs_noirq(struct pebs_tracer *tracer)
-{
-       struct task_struct *task;
-       unsigned long irq;
-       int error;
-
-       if (!tracer)
-               return 0;
-
-       task = tracer->ds.context->task;
-
-       local_irq_save(irq);
-
-       error = -EPERM;
-       if (!task &&
-           (tracer->ds.context->cpu != smp_processor_id()))
-               goto out;
-
-       error = -EPERM;
-       if (task && (task != current))
-               goto out;
-
-       ds_suspend_pebs_noirq(tracer);
-       ds_free_pebs(tracer);
-
-       error = 0;
- out:
-       local_irq_restore(irq);
-       return error;
-}
-
-void ds_suspend_pebs(struct pebs_tracer *tracer)
-{
-
-}
-
-int ds_suspend_pebs_noirq(struct pebs_tracer *tracer)
-{
-       return 0;
-}
-
-void ds_resume_pebs(struct pebs_tracer *tracer)
-{
-
-}
-
-int ds_resume_pebs_noirq(struct pebs_tracer *tracer)
-{
-       return 0;
-}
-
-const struct bts_trace *ds_read_bts(struct bts_tracer *tracer)
-{
-       if (!tracer)
-               return NULL;
-
-       ds_read_config(tracer->ds.context, &tracer->trace.ds, ds_bts);
-       return &tracer->trace;
-}
-
-const struct pebs_trace *ds_read_pebs(struct pebs_tracer *tracer)
-{
-       if (!tracer)
-               return NULL;
-
-       ds_read_config(tracer->ds.context, &tracer->trace.ds, ds_pebs);
-
-       tracer->trace.counters = ds_cfg.nr_counter_reset;
-       memcpy(tracer->trace.counter_reset,
-              tracer->ds.context->ds +
-              (NUM_DS_PTR_FIELDS * ds_cfg.sizeof_ptr_field),
-              ds_cfg.nr_counter_reset * PEBS_RESET_FIELD_SIZE);
-
-       return &tracer->trace;
-}
-
-int ds_reset_bts(struct bts_tracer *tracer)
-{
-       if (!tracer)
-               return -EINVAL;
-
-       tracer->trace.ds.top = tracer->trace.ds.begin;
-
-       ds_set(tracer->ds.context->ds, ds_bts, ds_index,
-              (unsigned long)tracer->trace.ds.top);
-
-       return 0;
-}
-
-int ds_reset_pebs(struct pebs_tracer *tracer)
-{
-       if (!tracer)
-               return -EINVAL;
-
-       tracer->trace.ds.top = tracer->trace.ds.begin;
-
-       ds_set(tracer->ds.context->ds, ds_pebs, ds_index,
-              (unsigned long)tracer->trace.ds.top);
-
-       return 0;
-}
-
-int ds_set_pebs_reset(struct pebs_tracer *tracer,
-                     unsigned int counter, u64 value)
-{
-       if (!tracer)
-               return -EINVAL;
-
-       if (ds_cfg.nr_counter_reset < counter)
-               return -EINVAL;
-
-       *(u64 *)(tracer->ds.context->ds +
-                (NUM_DS_PTR_FIELDS * ds_cfg.sizeof_ptr_field) +
-                (counter * PEBS_RESET_FIELD_SIZE)) = value;
-
-       return 0;
-}
-
-static const struct ds_configuration ds_cfg_netburst = {
-       .name = "Netburst",
-       .ctl[dsf_bts]           = (1 << 2) | (1 << 3),
-       .ctl[dsf_bts_kernel]    = (1 << 5),
-       .ctl[dsf_bts_user]      = (1 << 6),
-       .nr_counter_reset       = 1,
-};
-static const struct ds_configuration ds_cfg_pentium_m = {
-       .name = "Pentium M",
-       .ctl[dsf_bts]           = (1 << 6) | (1 << 7),
-       .nr_counter_reset       = 1,
-};
-static const struct ds_configuration ds_cfg_core2_atom = {
-       .name = "Core 2/Atom",
-       .ctl[dsf_bts]           = (1 << 6) | (1 << 7),
-       .ctl[dsf_bts_kernel]    = (1 << 9),
-       .ctl[dsf_bts_user]      = (1 << 10),
-       .nr_counter_reset       = 1,
-};
-static const struct ds_configuration ds_cfg_core_i7 = {
-       .name = "Core i7",
-       .ctl[dsf_bts]           = (1 << 6) | (1 << 7),
-       .ctl[dsf_bts_kernel]    = (1 << 9),
-       .ctl[dsf_bts_user]      = (1 << 10),
-       .nr_counter_reset       = 4,
-};
-
-static void
-ds_configure(const struct ds_configuration *cfg,
-            struct cpuinfo_x86 *cpu)
-{
-       unsigned long nr_pebs_fields = 0;
-
-       printk(KERN_INFO "[ds] using %s configuration\n", cfg->name);
-
-#ifdef __i386__
-       nr_pebs_fields = 10;
-#else
-       nr_pebs_fields = 18;
-#endif
-
-       /*
-        * Starting with version 2, architectural performance
-        * monitoring supports a format specifier.
-        */
-       if ((cpuid_eax(0xa) & 0xff) > 1) {
-               unsigned long perf_capabilities, format;
-
-               rdmsrl(MSR_IA32_PERF_CAPABILITIES, perf_capabilities);
-
-               format = (perf_capabilities >> 8) & 0xf;
-
-               switch (format) {
-               case 0:
-                       nr_pebs_fields = 18;
-                       break;
-               case 1:
-                       nr_pebs_fields = 22;
-                       break;
-               default:
-                       printk(KERN_INFO
-                              "[ds] unknown PEBS format: %lu\n", format);
-                       nr_pebs_fields = 0;
-                       break;
-               }
-       }
-
-       memset(&ds_cfg, 0, sizeof(ds_cfg));
-       ds_cfg = *cfg;
-
-       ds_cfg.sizeof_ptr_field =
-               (cpu_has(cpu, X86_FEATURE_DTES64) ? 8 : 4);
-
-       ds_cfg.sizeof_rec[ds_bts]  = ds_cfg.sizeof_ptr_field * 3;
-       ds_cfg.sizeof_rec[ds_pebs] = ds_cfg.sizeof_ptr_field * nr_pebs_fields;
-
-       if (!cpu_has(cpu, X86_FEATURE_BTS)) {
-               ds_cfg.sizeof_rec[ds_bts] = 0;
-               printk(KERN_INFO "[ds] bts not available\n");
-       }
-       if (!cpu_has(cpu, X86_FEATURE_PEBS)) {
-               ds_cfg.sizeof_rec[ds_pebs] = 0;
-               printk(KERN_INFO "[ds] pebs not available\n");
-       }
-
-       printk(KERN_INFO "[ds] sizes: address: %u bit, ",
-              8 * ds_cfg.sizeof_ptr_field);
-       printk("bts/pebs record: %u/%u bytes\n",
-              ds_cfg.sizeof_rec[ds_bts], ds_cfg.sizeof_rec[ds_pebs]);
-
-       WARN_ON_ONCE(MAX_PEBS_COUNTERS < ds_cfg.nr_counter_reset);
-}
-
-void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
-{
-       /* Only configure the first cpu. Others are identical. */
-       if (ds_cfg.name)
-               return;
-
-       switch (c->x86) {
-       case 0x6:
-               switch (c->x86_model) {
-               case 0x9:
-               case 0xd: /* Pentium M */
-                       ds_configure(&ds_cfg_pentium_m, c);
-                       break;
-               case 0xf:
-               case 0x17: /* Core2 */
-               case 0x1c: /* Atom */
-                       ds_configure(&ds_cfg_core2_atom, c);
-                       break;
-               case 0x1a: /* Core i7 */
-                       ds_configure(&ds_cfg_core_i7, c);
-                       break;
-               default:
-                       /* Sorry, don't know about them. */
-                       break;
-               }
-               break;
-       case 0xf:
-               switch (c->x86_model) {
-               case 0x0:
-               case 0x1:
-               case 0x2: /* Netburst */
-                       ds_configure(&ds_cfg_netburst, c);
-                       break;
-               default:
-                       /* Sorry, don't know about them. */
-                       break;
-               }
-               break;
-       default:
-               /* Sorry, don't know about them. */
-               break;
-       }
-}
-
-static inline void ds_take_timestamp(struct ds_context *context,
-                                    enum bts_qualifier qualifier,
-                                    struct task_struct *task)
-{
-       struct bts_tracer *tracer = context->bts_master;
-       struct bts_struct ts;
-
-       /* Prevent compilers from reading the tracer pointer twice. */
-       barrier();
-
-       if (!tracer || !(tracer->flags & BTS_TIMESTAMPS))
-               return;
-
-       memset(&ts, 0, sizeof(ts));
-       ts.qualifier            = qualifier;
-       ts.variant.event.clock  = trace_clock_global();
-       ts.variant.event.pid    = task->pid;
-
-       bts_write(tracer, &ts);
-}
-
-/*
- * Change the DS configuration from tracing prev to tracing next.
- */
-void ds_switch_to(struct task_struct *prev, struct task_struct *next)
-{
-       struct ds_context *prev_ctx     = prev->thread.ds_ctx;
-       struct ds_context *next_ctx     = next->thread.ds_ctx;
-       unsigned long debugctlmsr       = next->thread.debugctlmsr;
-
-       /* Make sure all data is read before we start. */
-       barrier();
-
-       if (prev_ctx) {
-               update_debugctlmsr(0);
-
-               ds_take_timestamp(prev_ctx, bts_task_departs, prev);
-       }
-
-       if (next_ctx) {
-               ds_take_timestamp(next_ctx, bts_task_arrives, next);
-
-               wrmsrl(MSR_IA32_DS_AREA, (unsigned long)next_ctx->ds);
-       }
-
-       update_debugctlmsr(debugctlmsr);
-}
-
-static __init int ds_selftest(void)
-{
-       if (ds_cfg.sizeof_rec[ds_bts]) {
-               int error;
-
-               error = ds_selftest_bts();
-               if (error) {
-                       WARN(1, "[ds] selftest failed. disabling bts.\n");
-                       ds_cfg.sizeof_rec[ds_bts] = 0;
-               }
-       }
-
-       if (ds_cfg.sizeof_rec[ds_pebs]) {
-               int error;
-
-               error = ds_selftest_pebs();
-               if (error) {
-                       WARN(1, "[ds] selftest failed. disabling pebs.\n");
-                       ds_cfg.sizeof_rec[ds_pebs] = 0;
-               }
-       }
-
-       return 0;
-}
-device_initcall(ds_selftest);
diff --git a/arch/x86/kernel/ds_selftest.c b/arch/x86/kernel/ds_selftest.c
deleted file mode 100644 (file)
index 6bc7c19..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Debug Store support - selftest
- *
- *
- * Copyright (C) 2009 Intel Corporation.
- * Markus Metzger <markus.t.metzger@intel.com>, 2009
- */
-
-#include "ds_selftest.h"
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/smp.h>
-#include <linux/cpu.h>
-
-#include <asm/ds.h>
-
-
-#define BUFFER_SIZE            521     /* Intentionally chose an odd size. */
-#define SMALL_BUFFER_SIZE      24      /* A single bts entry. */
-
-struct ds_selftest_bts_conf {
-       struct bts_tracer *tracer;
-       int error;
-       int (*suspend)(struct bts_tracer *);
-       int (*resume)(struct bts_tracer *);
-};
-
-static int ds_selftest_bts_consistency(const struct bts_trace *trace)
-{
-       int error = 0;
-
-       if (!trace) {
-               printk(KERN_CONT "failed to access trace...");
-               /* Bail out. Other tests are pointless. */
-               return -1;
-       }
-
-       if (!trace->read) {
-               printk(KERN_CONT "bts read not available...");
-               error = -1;
-       }
-
-       /* Do some sanity checks on the trace configuration. */
-       if (!trace->ds.n) {
-               printk(KERN_CONT "empty bts buffer...");
-               error = -1;
-       }
-       if (!trace->ds.size) {
-               printk(KERN_CONT "bad bts trace setup...");
-               error = -1;
-       }
-       if (trace->ds.end !=
-           (char *)trace->ds.begin + (trace->ds.n * trace->ds.size)) {
-               printk(KERN_CONT "bad bts buffer setup...");
-               error = -1;
-       }
-       /*
-        * We allow top in [begin; end], since its not clear when the
-        * overflow adjustment happens: after the increment or before the
-        * write.
-        */
-       if ((trace->ds.top < trace->ds.begin) ||
-           (trace->ds.end < trace->ds.top)) {
-               printk(KERN_CONT "bts top out of bounds...");
-               error = -1;
-       }
-
-       return error;
-}
-
-static int ds_selftest_bts_read(struct bts_tracer *tracer,
-                               const struct bts_trace *trace,
-                               const void *from, const void *to)
-{
-       const unsigned char *at;
-
-       /*
-        * Check a few things which do not belong to this test.
-        * They should be covered by other tests.
-        */
-       if (!trace)
-               return -1;
-
-       if (!trace->read)
-               return -1;
-
-       if (to < from)
-               return -1;
-
-       if (from < trace->ds.begin)
-               return -1;
-
-       if (trace->ds.end < to)
-               return -1;
-
-       if (!trace->ds.size)
-               return -1;
-
-       /* Now to the test itself. */
-       for (at = from; (void *)at < to; at += trace->ds.size) {
-               struct bts_struct bts;
-               unsigned long index;
-               int error;
-
-               if (((void *)at - trace->ds.begin) % trace->ds.size) {
-                       printk(KERN_CONT
-                              "read from non-integer index...");
-                       return -1;
-               }
-               index = ((void *)at - trace->ds.begin) / trace->ds.size;
-
-               memset(&bts, 0, sizeof(bts));
-               error = trace->read(tracer, at, &bts);
-               if (error < 0) {
-                       printk(KERN_CONT
-                              "error reading bts trace at [%lu] (0x%p)...",
-                              index, at);
-                       return error;
-               }
-
-               switch (bts.qualifier) {
-               case BTS_BRANCH:
-                       break;
-               default:
-                       printk(KERN_CONT
-                              "unexpected bts entry %llu at [%lu] (0x%p)...",
-                              bts.qualifier, index, at);
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-static void ds_selftest_bts_cpu(void *arg)
-{
-       struct ds_selftest_bts_conf *conf = arg;
-       const struct bts_trace *trace;
-       void *top;
-
-       if (IS_ERR(conf->tracer)) {
-               conf->error = PTR_ERR(conf->tracer);
-               conf->tracer = NULL;
-
-               printk(KERN_CONT
-                      "initialization failed (err: %d)...", conf->error);
-               return;
-       }
-
-       /* We should meanwhile have enough trace. */
-       conf->error = conf->suspend(conf->tracer);
-       if (conf->error < 0)
-               return;
-
-       /* Let's see if we can access the trace. */
-       trace = ds_read_bts(conf->tracer);
-
-       conf->error = ds_selftest_bts_consistency(trace);
-       if (conf->error < 0)
-               return;
-
-       /* If everything went well, we should have a few trace entries. */
-       if (trace->ds.top == trace->ds.begin) {
-               /*
-                * It is possible but highly unlikely that we got a
-                * buffer overflow and end up at exactly the same
-                * position we started from.
-                * Let's issue a warning, but continue.
-                */
-               printk(KERN_CONT "no trace/overflow...");
-       }
-
-       /* Let's try to read the trace we collected. */
-       conf->error =
-               ds_selftest_bts_read(conf->tracer, trace,
-                                    trace->ds.begin, trace->ds.top);
-       if (conf->error < 0)
-               return;
-
-       /*
-        * Let's read the trace again.
-        * Since we suspended tracing, we should get the same result.
-        */
-       top = trace->ds.top;
-
-       trace = ds_read_bts(conf->tracer);
-       conf->error = ds_selftest_bts_consistency(trace);
-       if (conf->error < 0)
-               return;
-
-       if (top != trace->ds.top) {
-               printk(KERN_CONT "suspend not working...");
-               conf->error = -1;
-               return;
-       }
-
-       /* Let's collect some more trace - see if resume is working. */
-       conf->error = conf->resume(conf->tracer);
-       if (conf->error < 0)
-               return;
-
-       conf->error = conf->suspend(conf->tracer);
-       if (conf->error < 0)
-               return;
-
-       trace = ds_read_bts(conf->tracer);
-
-       conf->error = ds_selftest_bts_consistency(trace);
-       if (conf->error < 0)
-               return;
-
-       if (trace->ds.top == top) {
-               /*
-                * It is possible but highly unlikely that we got a
-                * buffer overflow and end up at exactly the same
-                * position we started from.
-                * Let's issue a warning and check the full trace.
-                */
-               printk(KERN_CONT
-                      "no resume progress/overflow...");
-
-               conf->error =
-                       ds_selftest_bts_read(conf->tracer, trace,
-                                            trace->ds.begin, trace->ds.end);
-       } else if (trace->ds.top < top) {
-               /*
-                * We had a buffer overflow - the entire buffer should
-                * contain trace records.
-                */
-               conf->error =
-                       ds_selftest_bts_read(conf->tracer, trace,
-                                            trace->ds.begin, trace->ds.end);
-       } else {
-               /*
-                * It is quite likely that the buffer did not overflow.
-                * Let's just check the delta trace.
-                */
-               conf->error =
-                       ds_selftest_bts_read(conf->tracer, trace, top,
-                                            trace->ds.top);
-       }
-       if (conf->error < 0)
-               return;
-
-       conf->error = 0;
-}
-
-static int ds_suspend_bts_wrap(struct bts_tracer *tracer)
-{
-       ds_suspend_bts(tracer);
-       return 0;
-}
-
-static int ds_resume_bts_wrap(struct bts_tracer *tracer)
-{
-       ds_resume_bts(tracer);
-       return 0;
-}
-
-static void ds_release_bts_noirq_wrap(void *tracer)
-{
-       (void)ds_release_bts_noirq(tracer);
-}
-
-static int ds_selftest_bts_bad_release_noirq(int cpu,
-                                            struct bts_tracer *tracer)
-{
-       int error = -EPERM;
-
-       /* Try to release the tracer on the wrong cpu. */
-       get_cpu();
-       if (cpu != smp_processor_id()) {
-               error = ds_release_bts_noirq(tracer);
-               if (error != -EPERM)
-                       printk(KERN_CONT "release on wrong cpu...");
-       }
-       put_cpu();
-
-       return error ? 0 : -1;
-}
-
-static int ds_selftest_bts_bad_request_cpu(int cpu, void *buffer)
-{
-       struct bts_tracer *tracer;
-       int error;
-
-       /* Try to request cpu tracing while task tracing is active. */
-       tracer = ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE, NULL,
-                                   (size_t)-1, BTS_KERNEL);
-       error = PTR_ERR(tracer);
-       if (!IS_ERR(tracer)) {
-               ds_release_bts(tracer);
-               error = 0;
-       }
-
-       if (error != -EPERM)
-               printk(KERN_CONT "cpu/task tracing overlap...");
-
-       return error ? 0 : -1;
-}
-
-static int ds_selftest_bts_bad_request_task(void *buffer)
-{
-       struct bts_tracer *tracer;
-       int error;
-
-       /* Try to request cpu tracing while task tracing is active. */
-       tracer = ds_request_bts_task(current, buffer, BUFFER_SIZE, NULL,
-                                   (size_t)-1, BTS_KERNEL);
-       error = PTR_ERR(tracer);
-       if (!IS_ERR(tracer)) {
-               error = 0;
-               ds_release_bts(tracer);
-       }
-
-       if (error != -EPERM)
-               printk(KERN_CONT "task/cpu tracing overlap...");
-
-       return error ? 0 : -1;
-}
-
-int ds_selftest_bts(void)
-{
-       struct ds_selftest_bts_conf conf;
-       unsigned char buffer[BUFFER_SIZE], *small_buffer;
-       unsigned long irq;
-       int cpu;
-
-       printk(KERN_INFO "[ds] bts selftest...");
-       conf.error = 0;
-
-       small_buffer = (unsigned char *)ALIGN((unsigned long)buffer, 8) + 8;
-
-       get_online_cpus();
-       for_each_online_cpu(cpu) {
-               conf.suspend = ds_suspend_bts_wrap;
-               conf.resume = ds_resume_bts_wrap;
-               conf.tracer =
-                       ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE,
-                                          NULL, (size_t)-1, BTS_KERNEL);
-               ds_selftest_bts_cpu(&conf);
-               if (conf.error >= 0)
-                       conf.error = ds_selftest_bts_bad_request_task(buffer);
-               ds_release_bts(conf.tracer);
-               if (conf.error < 0)
-                       goto out;
-
-               conf.suspend = ds_suspend_bts_noirq;
-               conf.resume = ds_resume_bts_noirq;
-               conf.tracer =
-                       ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE,
-                                          NULL, (size_t)-1, BTS_KERNEL);
-               smp_call_function_single(cpu, ds_selftest_bts_cpu, &conf, 1);
-               if (conf.error >= 0) {
-                       conf.error =
-                               ds_selftest_bts_bad_release_noirq(cpu,
-                                                                 conf.tracer);
-                       /* We must not release the tracer twice. */
-                       if (conf.error < 0)
-                               conf.tracer = NULL;
-               }
-               if (conf.error >= 0)
-                       conf.error = ds_selftest_bts_bad_request_task(buffer);
-               smp_call_function_single(cpu, ds_release_bts_noirq_wrap,
-                                        conf.tracer, 1);
-               if (conf.error < 0)
-                       goto out;
-       }
-
-       conf.suspend = ds_suspend_bts_wrap;
-       conf.resume = ds_resume_bts_wrap;
-       conf.tracer =
-               ds_request_bts_task(current, buffer, BUFFER_SIZE,
-                                   NULL, (size_t)-1, BTS_KERNEL);
-       ds_selftest_bts_cpu(&conf);
-       if (conf.error >= 0)
-               conf.error = ds_selftest_bts_bad_request_cpu(0, buffer);
-       ds_release_bts(conf.tracer);
-       if (conf.error < 0)
-               goto out;
-
-       conf.suspend = ds_suspend_bts_noirq;
-       conf.resume = ds_resume_bts_noirq;
-       conf.tracer =
-               ds_request_bts_task(current, small_buffer, SMALL_BUFFER_SIZE,
-                                  NULL, (size_t)-1, BTS_KERNEL);
-       local_irq_save(irq);
-       ds_selftest_bts_cpu(&conf);
-       if (conf.error >= 0)
-               conf.error = ds_selftest_bts_bad_request_cpu(0, buffer);
-       ds_release_bts_noirq(conf.tracer);
-       local_irq_restore(irq);
-       if (conf.error < 0)
-               goto out;
-
-       conf.error = 0;
- out:
-       put_online_cpus();
-       printk(KERN_CONT "%s.\n", (conf.error ? "failed" : "passed"));
-
-       return conf.error;
-}
-
-int ds_selftest_pebs(void)
-{
-       return 0;
-}
diff --git a/arch/x86/kernel/ds_selftest.h b/arch/x86/kernel/ds_selftest.h
deleted file mode 100644 (file)
index 2ba8745..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Debug Store support - selftest
- *
- *
- * Copyright (C) 2009 Intel Corporation.
- * Markus Metzger <markus.t.metzger@intel.com>, 2009
- */
-
-#ifdef CONFIG_X86_DS_SELFTEST
-extern int ds_selftest_bts(void);
-extern int ds_selftest_pebs(void);
-#else
-static inline int ds_selftest_bts(void) { return 0; }
-static inline int ds_selftest_pebs(void) { return 0; }
-#endif
index 6d817554780adea96603f6f852ee398d62b9e41a..c89a386930b7f4d9bc9c74dc0fa0151056860493 100644 (file)
@@ -224,11 +224,6 @@ unsigned __kprobes long oops_begin(void)
        int cpu;
        unsigned long flags;
 
-       /* notify the hw-branch tracer so it may disable tracing and
-          add the last trace to the trace buffer -
-          the earlier this happens, the more useful the trace. */
-       trace_hw_branch_oops();
-
        oops_enter();
 
        /* racy, but better than risking deadlock. */
index 4fd1420faffa4fd747d8de2844c8d7278b79587c..e1a93be4fd444410402f7a7b625f41e4c15a77df 100644 (file)
@@ -14,6 +14,8 @@
 #define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :)
 #endif
 
+#include <linux/uaccess.h>
+
 extern void
 show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
                unsigned long *stack, unsigned long bp, char *log_lvl);
@@ -29,4 +31,26 @@ struct stack_frame {
        struct stack_frame *next_frame;
        unsigned long return_address;
 };
+
+struct stack_frame_ia32 {
+    u32 next_frame;
+    u32 return_address;
+};
+
+static inline unsigned long rewind_frame_pointer(int n)
+{
+       struct stack_frame *frame;
+
+       get_bp(frame);
+
+#ifdef CONFIG_FRAME_POINTER
+       while (n--) {
+               if (probe_kernel_address(&frame->next_frame, frame))
+                       break;
+       }
 #endif
+
+       return (unsigned long)frame;
+}
+
+#endif /* DUMPSTACK_H */
index d5e2a2ebb6272d73c55af7b696cab37f5fa3bef5..272c9f1f05f31bf20492dfb6be35bed716be26b1 100644 (file)
@@ -208,7 +208,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
                        if (in_irq_stack(stack, irq_stack, irq_stack_end)) {
                                if (ops->stack(data, "IRQ") < 0)
                                        break;
-                               bp = print_context_stack(tinfo, stack, bp,
+                               bp = ops->walk_stack(tinfo, stack, bp,
                                        ops, data, irq_stack_end, &graph);
                                /*
                                 * We link to the next stack (which would be
@@ -229,7 +229,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
        /*
         * This handles the process stack:
         */
-       bp = print_context_stack(tinfo, stack, bp, ops, data, NULL, &graph);
+       bp = ops->walk_stack(tinfo, stack, bp, ops, data, NULL, &graph);
        put_cpu();
 }
 EXPORT_SYMBOL(dump_trace);
index 740b440fbd730d056c5b197a9c3da84362cb3b2a..7bca3c6a02fb186ebd039ff495f05fd051f32b6e 100644 (file)
@@ -519,29 +519,45 @@ u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type,
        printk(KERN_DEBUG "e820 remove range: %016Lx - %016Lx ",
                       (unsigned long long) start,
                       (unsigned long long) end);
-       e820_print_type(old_type);
+       if (checktype)
+               e820_print_type(old_type);
        printk(KERN_CONT "\n");
 
        for (i = 0; i < e820.nr_map; i++) {
                struct e820entry *ei = &e820.map[i];
                u64 final_start, final_end;
+               u64 ei_end;
 
                if (checktype && ei->type != old_type)
                        continue;
+
+               ei_end = ei->addr + ei->size;
                /* totally covered? */
-               if (ei->addr >= start &&
-                   (ei->addr + ei->size) <= (start + size)) {
+               if (ei->addr >= start && ei_end <= end) {
                        real_removed_size += ei->size;
                        memset(ei, 0, sizeof(struct e820entry));
                        continue;
                }
+
+               /* new range is totally covered? */
+               if (ei->addr < start && ei_end > end) {
+                       e820_add_region(end, ei_end - end, ei->type);
+                       ei->size = start - ei->addr;
+                       real_removed_size += size;
+                       continue;
+               }
+
                /* partially covered */
                final_start = max(start, ei->addr);
-               final_end = min(start + size, ei->addr + ei->size);
+               final_end = min(end, ei_end);
                if (final_start >= final_end)
                        continue;
                real_removed_size += final_end - final_start;
 
+               /*
+                * left range could be head or tail, so need to update
+                * size at first.
+                */
                ei->size -= final_end - final_start;
                if (ei->addr < final_start)
                        continue;
index 44a8e0dc6737d9f28ba0fe258655e0d43b02226d..cd49141cf153fb124dc46a6497dbc863a3c81ad9 100644 (file)
@@ -53,6 +53,7 @@
 #include <asm/processor-flags.h>
 #include <asm/ftrace.h>
 #include <asm/irq_vectors.h>
+#include <asm/cpufeature.h>
 
 /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this.  */
 #include <linux/elf-em.h>
@@ -905,7 +906,25 @@ ENTRY(simd_coprocessor_error)
        RING0_INT_FRAME
        pushl $0
        CFI_ADJUST_CFA_OFFSET 4
+#ifdef CONFIG_X86_INVD_BUG
+       /* AMD 486 bug: invd from userspace calls exception 19 instead of #GP */
+661:   pushl $do_general_protection
+662:
+.section .altinstructions,"a"
+       .balign 4
+       .long 661b
+       .long 663f
+       .byte X86_FEATURE_XMM
+       .byte 662b-661b
+       .byte 664f-663f
+.previous
+.section .altinstr_replacement,"ax"
+663:   pushl $do_simd_coprocessor_error
+664:
+.previous
+#else
        pushl $do_simd_coprocessor_error
+#endif
        CFI_ADJUST_CFA_OFFSET 4
        jmp error_code
        CFI_ENDPROC
index adedeef1dedcad654c9955c88c677709fec22f6c..b2e2460373920128697e5bf7e93e3ca708de64ca 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/init.h>
 #include <linux/start_kernel.h>
+#include <linux/mm.h>
 
 #include <asm/setup.h>
 #include <asm/sections.h>
@@ -44,9 +45,10 @@ void __init i386_start_kernel(void)
 #ifdef CONFIG_BLK_DEV_INITRD
        /* Reserve INITRD */
        if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
+               /* Assume only end is not page aligned */
                u64 ramdisk_image = boot_params.hdr.ramdisk_image;
                u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
-               u64 ramdisk_end   = ramdisk_image + ramdisk_size;
+               u64 ramdisk_end   = PAGE_ALIGN(ramdisk_image + ramdisk_size);
                reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
        }
 #endif
index b5a9896ca1e74be8805c4f5384ffc8d50f6589b6..7147143fd614e429392741ae13ce5577c7be5364 100644 (file)
@@ -103,9 +103,10 @@ void __init x86_64_start_reservations(char *real_mode_data)
 #ifdef CONFIG_BLK_DEV_INITRD
        /* Reserve INITRD */
        if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
+               /* Assume only end is not page aligned */
                unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
                unsigned long ramdisk_size  = boot_params.hdr.ramdisk_size;
-               unsigned long ramdisk_end   = ramdisk_image + ramdisk_size;
+               unsigned long ramdisk_end   = PAGE_ALIGN(ramdisk_image + ramdisk_size);
                reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
        }
 #endif
index ee4fa1bfcb33354b96069b4728dd5cf367e74e12..23b4ecdffa9bcc76dc0659ab6e6ed1c7882ad677 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/sysdev.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/hpet.h>
 #include <linux/init.h>
 #include <linux/cpu.h>
@@ -399,9 +400,15 @@ static int hpet_next_event(unsigned long delta,
         * then we might have a real hardware problem. We can not do
         * much about it here, but at least alert the user/admin with
         * a prominent warning.
+        * An erratum on some chipsets (ICH9,..), results in comparator read
+        * immediately following a write returning old value. Workaround
+        * for this is to read this value second time, when first
+        * read returns old value.
         */
-       WARN_ONCE(hpet_readl(HPET_Tn_CMP(timer)) != cnt,
+       if (unlikely((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt)) {
+               WARN_ONCE(hpet_readl(HPET_Tn_CMP(timer)) != cnt,
                  KERN_WARNING "hpet: compare register read back failed.\n");
+       }
 
        return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
 }
@@ -1143,6 +1150,7 @@ int hpet_set_periodic_freq(unsigned long freq)
                do_div(clc, freq);
                clc >>= hpet_clockevent.shift;
                hpet_pie_delta = clc;
+               hpet_pie_limit = 0;
        }
        return 1;
 }
index d6cc065f519f8afe7d3db61668cd86109c5431ff..a8f1b803d2fd916c7aacf4952ff33b620f790852 100644 (file)
@@ -188,26 +188,17 @@ static int get_hbp_len(u8 hbp_len)
        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)
+int arch_check_bp_in_kernelspace(struct perf_event *bp)
 {
        unsigned int len;
+       unsigned long va;
+       struct arch_hw_breakpoint *info = counter_arch_bp(bp);
 
-       len = get_hbp_len(hbp_len);
+       va = info->address;
+       len = get_hbp_len(info->len);
 
        return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
 }
@@ -300,8 +291,7 @@ static int arch_build_bp_info(struct perf_event *bp)
 /*
  * Validate the arch-specific HW Breakpoint register settings
  */
-int arch_validate_hwbkpt_settings(struct perf_event *bp,
-                                 struct task_struct *tsk)
+int arch_validate_hwbkpt_settings(struct perf_event *bp)
 {
        struct arch_hw_breakpoint *info = counter_arch_bp(bp);
        unsigned int align;
@@ -314,16 +304,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp,
 
        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;
@@ -350,15 +330,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp,
        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;
 }
 
index c01a2b846d478a94d86ec94416394094f80ccd5e..86cef6b322530ffecaa657ecda41b6cf2619fb47 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/module.h>
 #include <linux/regset.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <asm/sigcontext.h>
 #include <asm/processor.h>
@@ -101,65 +102,62 @@ void __cpuinit fpu_init(void)
 
        mxcsr_feature_mask_init();
        /* clean state in init */
-       if (cpu_has_xsave)
-               current_thread_info()->status = TS_XSAVE;
-       else
-               current_thread_info()->status = 0;
+       current_thread_info()->status = 0;
        clear_used_math();
 }
 #endif /* CONFIG_X86_64 */
 
-/*
- * The _current_ task is using the FPU for the first time
- * so initialize it and set the mxcsr to its default
- * value at reset if we support XMM instructions and then
- * remeber the current task has used the FPU.
- */
-int init_fpu(struct task_struct *tsk)
+static void fpu_finit(struct fpu *fpu)
 {
-       if (tsk_used_math(tsk)) {
-               if (HAVE_HWFP && tsk == current)
-                       unlazy_fpu(tsk);
-               return 0;
-       }
-
-       /*
-        * Memory allocation at the first usage of the FPU and other state.
-        */
-       if (!tsk->thread.xstate) {
-               tsk->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
-                                                     GFP_KERNEL);
-               if (!tsk->thread.xstate)
-                       return -ENOMEM;
-       }
-
 #ifdef CONFIG_X86_32
        if (!HAVE_HWFP) {
-               memset(tsk->thread.xstate, 0, xstate_size);
-               finit_task(tsk);
-               set_stopped_child_used_math(tsk);
-               return 0;
+               finit_soft_fpu(&fpu->state->soft);
+               return;
        }
 #endif
 
        if (cpu_has_fxsr) {
-               struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave;
+               struct i387_fxsave_struct *fx = &fpu->state->fxsave;
 
                memset(fx, 0, xstate_size);
                fx->cwd = 0x37f;
                if (cpu_has_xmm)
                        fx->mxcsr = MXCSR_DEFAULT;
        } else {
-               struct i387_fsave_struct *fp = &tsk->thread.xstate->fsave;
+               struct i387_fsave_struct *fp = &fpu->state->fsave;
                memset(fp, 0, xstate_size);
                fp->cwd = 0xffff037fu;
                fp->swd = 0xffff0000u;
                fp->twd = 0xffffffffu;
                fp->fos = 0xffff0000u;
        }
+}
+
+/*
+ * The _current_ task is using the FPU for the first time
+ * so initialize it and set the mxcsr to its default
+ * value at reset if we support XMM instructions and then
+ * remeber the current task has used the FPU.
+ */
+int init_fpu(struct task_struct *tsk)
+{
+       int ret;
+
+       if (tsk_used_math(tsk)) {
+               if (HAVE_HWFP && tsk == current)
+                       unlazy_fpu(tsk);
+               return 0;
+       }
+
        /*
-        * Only the device not available exception or ptrace can call init_fpu.
+        * Memory allocation at the first usage of the FPU and other state.
         */
+       ret = fpu_alloc(&tsk->thread.fpu);
+       if (ret)
+               return ret;
+
+       fpu_finit(&tsk->thread.fpu);
+
        set_stopped_child_used_math(tsk);
        return 0;
 }
@@ -193,7 +191,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset,
                return ret;
 
        return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                  &target->thread.xstate->fxsave, 0, -1);
+                                  &target->thread.fpu.state->fxsave, 0, -1);
 }
 
 int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
@@ -210,19 +208,19 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
                return ret;
 
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-                                &target->thread.xstate->fxsave, 0, -1);
+                                &target->thread.fpu.state->fxsave, 0, -1);
 
        /*
         * mxcsr reserved bits must be masked to zero for security reasons.
         */
-       target->thread.xstate->fxsave.mxcsr &= mxcsr_feature_mask;
+       target->thread.fpu.state->fxsave.mxcsr &= mxcsr_feature_mask;
 
        /*
         * update the header bits in the xsave header, indicating the
         * presence of FP and SSE state.
         */
        if (cpu_has_xsave)
-               target->thread.xstate->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE;
+               target->thread.fpu.state->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE;
 
        return ret;
 }
@@ -245,14 +243,14 @@ int xstateregs_get(struct task_struct *target, const struct user_regset *regset,
         * memory layout in the thread struct, so that we can copy the entire
         * xstateregs to the user using one user_regset_copyout().
         */
-       memcpy(&target->thread.xstate->fxsave.sw_reserved,
+       memcpy(&target->thread.fpu.state->fxsave.sw_reserved,
               xstate_fx_sw_bytes, sizeof(xstate_fx_sw_bytes));
 
        /*
         * Copy the xstate memory layout.
         */
        ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                 &target->thread.xstate->xsave, 0, -1);
+                                 &target->thread.fpu.state->xsave, 0, -1);
        return ret;
 }
 
@@ -271,14 +269,14 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset,
                return ret;
 
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-                                &target->thread.xstate->xsave, 0, -1);
+                                &target->thread.fpu.state->xsave, 0, -1);
 
        /*
         * mxcsr reserved bits must be masked to zero for security reasons.
         */
-       target->thread.xstate->fxsave.mxcsr &= mxcsr_feature_mask;
+       target->thread.fpu.state->fxsave.mxcsr &= mxcsr_feature_mask;
 
-       xsave_hdr = &target->thread.xstate->xsave.xsave_hdr;
+       xsave_hdr = &target->thread.fpu.state->xsave.xsave_hdr;
 
        xsave_hdr->xstate_bv &= pcntxt_mask;
        /*
@@ -364,7 +362,7 @@ static inline u32 twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
 static void
 convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk)
 {
-       struct i387_fxsave_struct *fxsave = &tsk->thread.xstate->fxsave;
+       struct i387_fxsave_struct *fxsave = &tsk->thread.fpu.state->fxsave;
        struct _fpreg *to = (struct _fpreg *) &env->st_space[0];
        struct _fpxreg *from = (struct _fpxreg *) &fxsave->st_space[0];
        int i;
@@ -404,7 +402,7 @@ static void convert_to_fxsr(struct task_struct *tsk,
                            const struct user_i387_ia32_struct *env)
 
 {
-       struct i387_fxsave_struct *fxsave = &tsk->thread.xstate->fxsave;
+       struct i387_fxsave_struct *fxsave = &tsk->thread.fpu.state->fxsave;
        struct _fpreg *from = (struct _fpreg *) &env->st_space[0];
        struct _fpxreg *to = (struct _fpxreg *) &fxsave->st_space[0];
        int i;
@@ -444,7 +442,7 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset,
 
        if (!cpu_has_fxsr) {
                return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                          &target->thread.xstate->fsave, 0,
+                                          &target->thread.fpu.state->fsave, 0,
                                           -1);
        }
 
@@ -474,7 +472,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
 
        if (!cpu_has_fxsr) {
                return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-                                         &target->thread.xstate->fsave, 0, -1);
+                                         &target->thread.fpu.state->fsave, 0, -1);
        }
 
        if (pos > 0 || count < sizeof(env))
@@ -489,7 +487,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
         * presence of FP.
         */
        if (cpu_has_xsave)
-               target->thread.xstate->xsave.xsave_hdr.xstate_bv |= XSTATE_FP;
+               target->thread.fpu.state->xsave.xsave_hdr.xstate_bv |= XSTATE_FP;
        return ret;
 }
 
@@ -500,7 +498,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
 static inline int save_i387_fsave(struct _fpstate_ia32 __user *buf)
 {
        struct task_struct *tsk = current;
-       struct i387_fsave_struct *fp = &tsk->thread.xstate->fsave;
+       struct i387_fsave_struct *fp = &tsk->thread.fpu.state->fsave;
 
        fp->status = fp->swd;
        if (__copy_to_user(buf, fp, sizeof(struct i387_fsave_struct)))
@@ -511,7 +509,7 @@ static inline int save_i387_fsave(struct _fpstate_ia32 __user *buf)
 static int save_i387_fxsave(struct _fpstate_ia32 __user *buf)
 {
        struct task_struct *tsk = current;
-       struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave;
+       struct i387_fxsave_struct *fx = &tsk->thread.fpu.state->fxsave;
        struct user_i387_ia32_struct env;
        int err = 0;
 
@@ -546,7 +544,7 @@ static int save_i387_xsave(void __user *buf)
         * header as well as change any contents in the memory layout.
         * xrestore as part of sigreturn will capture all the changes.
         */
-       tsk->thread.xstate->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE;
+       tsk->thread.fpu.state->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE;
 
        if (save_i387_fxsave(fx) < 0)
                return -1;
@@ -598,7 +596,7 @@ static inline int restore_i387_fsave(struct _fpstate_ia32 __user *buf)
 {
        struct task_struct *tsk = current;
 
-       return __copy_from_user(&tsk->thread.xstate->fsave, buf,
+       return __copy_from_user(&tsk->thread.fpu.state->fsave, buf,
                                sizeof(struct i387_fsave_struct));
 }
 
@@ -609,10 +607,10 @@ static int restore_i387_fxsave(struct _fpstate_ia32 __user *buf,
        struct user_i387_ia32_struct env;
        int err;
 
-       err = __copy_from_user(&tsk->thread.xstate->fxsave, &buf->_fxsr_env[0],
+       err = __copy_from_user(&tsk->thread.fpu.state->fxsave, &buf->_fxsr_env[0],
                               size);
        /* mxcsr reserved bits must be masked to zero for security reasons */
-       tsk->thread.xstate->fxsave.mxcsr &= mxcsr_feature_mask;
+       tsk->thread.fpu.state->fxsave.mxcsr &= mxcsr_feature_mask;
        if (err || __copy_from_user(&env, buf, sizeof(env)))
                return 1;
        convert_to_fxsr(tsk, &env);
@@ -628,7 +626,7 @@ static int restore_i387_xsave(void __user *buf)
        struct i387_fxsave_struct __user *fx =
                (struct i387_fxsave_struct __user *) &fx_user->_fxsr_env[0];
        struct xsave_hdr_struct *xsave_hdr =
-                               &current->thread.xstate->xsave.xsave_hdr;
+                               &current->thread.fpu.state->xsave.xsave_hdr;
        u64 mask;
        int err;
 
index 23c167925a5c078bcd387b6bce8e34f7a6dca694..2dfd315974436bf8f4f63e32c7efd3390018cfe5 100644 (file)
@@ -16,7 +16,7 @@
 #include <asm/hpet.h>
 #include <asm/smp.h>
 
-DEFINE_SPINLOCK(i8253_lock);
+DEFINE_RAW_SPINLOCK(i8253_lock);
 EXPORT_SYMBOL(i8253_lock);
 
 /*
@@ -33,7 +33,7 @@ struct clock_event_device *global_clock_event;
 static void init_pit_timer(enum clock_event_mode mode,
                           struct clock_event_device *evt)
 {
-       spin_lock(&i8253_lock);
+       raw_spin_lock(&i8253_lock);
 
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
@@ -62,7 +62,7 @@ static void init_pit_timer(enum clock_event_mode mode,
                /* Nothing to do here */
                break;
        }
-       spin_unlock(&i8253_lock);
+       raw_spin_unlock(&i8253_lock);
 }
 
 /*
@@ -72,10 +72,10 @@ static void init_pit_timer(enum clock_event_mode mode,
  */
 static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
 {
-       spin_lock(&i8253_lock);
+       raw_spin_lock(&i8253_lock);
        outb_pit(delta & 0xff , PIT_CH0);       /* LSB */
        outb_pit(delta >> 8 , PIT_CH0);         /* MSB */
-       spin_unlock(&i8253_lock);
+       raw_spin_unlock(&i8253_lock);
 
        return 0;
 }
@@ -130,7 +130,7 @@ static cycle_t pit_read(struct clocksource *cs)
        int count;
        u32 jifs;
 
-       spin_lock_irqsave(&i8253_lock, flags);
+       raw_spin_lock_irqsave(&i8253_lock, flags);
        /*
         * Although our caller may have the read side of xtime_lock,
         * this is now a seqlock, and we are cheating in this routine
@@ -176,7 +176,7 @@ static cycle_t pit_read(struct clocksource *cs)
        old_count = count;
        old_jifs = jifs;
 
-       spin_unlock_irqrestore(&i8253_lock, flags);
+       raw_spin_unlock_irqrestore(&i8253_lock, flags);
 
        count = (LATCH - 1) - count;
 
index fb725ee15f5515c9fb6333145f586a7079acae20..7c9f02c130f3ca9167e81205f39c968174a8e9ef 100644 (file)
@@ -5,7 +5,6 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
index ef257fc2921b1a0ed133493d53186e3b064e2529..990ae7cfc5783f131df476506bc9341574a466c2 100644 (file)
@@ -5,7 +5,6 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/kprobes.h>
 #include <linux/init.h>
@@ -61,7 +60,7 @@ static irqreturn_t math_error_irq(int cpl, void *dev_id)
        outb(0, 0xF0);
        if (ignore_fpu_irq || !boot_cpu_data.hard_math)
                return IRQ_NONE;
-       math_error((void __user *)get_irq_regs()->ip);
+       math_error(get_irq_regs(), 0, 16);
        return IRQ_HANDLED;
 }
 
@@ -141,6 +140,28 @@ void __init init_IRQ(void)
        x86_init.irqs.intr_init();
 }
 
+/*
+ * Setup the vector to irq mappings.
+ */
+void setup_vector_irq(int cpu)
+{
+#ifndef CONFIG_X86_IO_APIC
+       int irq;
+
+       /*
+        * On most of the platforms, legacy PIC delivers the interrupts on the
+        * boot cpu. But there are certain platforms where PIC interrupts are
+        * delivered to multiple cpu's. If the legacy IRQ is handled by the
+        * legacy PIC, for the new cpu that is coming online, setup the static
+        * legacy vector to irq mapping:
+        */
+       for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++)
+               per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq;
+#endif
+
+       __setup_vector_irq(cpu);
+}
+
 static void __init smp_intr_init(void)
 {
 #ifdef CONFIG_SMP
index 9b895464dd0311f9c0c4619b5cf7e3f5e94dd2de..0f7bc20cfcdedd58f66b6b036bfb7d824e599e37 100644 (file)
@@ -2,8 +2,8 @@
  * Shared support code for AMD K8 northbridges and derivates.
  * Copyright 2006 Andi Kleen, SUSE Labs. Subject to GPLv2.
  */
-#include <linux/gfp.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/module.h>
index e444357375ce1421e137d6731adc3edba30def28..8afd9f321f100de0a8ddc236f1f411d4d98680ad 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/stat.h>
 #include <linux/io.h>
index bfba6019d762aa6652e58b3b09681a83b2e74525..b2258ca9100349c2618d00e4aadf8c7cdd62bb26 100644 (file)
@@ -618,8 +618,8 @@ int kgdb_arch_init(void)
         * portion of kgdb because this operation requires mutexs to
         * complete.
         */
+       hw_breakpoint_init(&attr);
        attr.bp_addr = (unsigned long)kgdb_arch_init;
-       attr.type = PERF_TYPE_BREAKPOINT;
        attr.bp_len = HW_BREAKPOINT_LEN_1;
        attr.bp_type = HW_BREAKPOINT_W;
        attr.disabled = 1;
index b43bbaebe2c0884d009c4d07a30f2db64f6538b5..345a4b1fe1446812d65e25fd424886d05aeb1fe4 100644 (file)
@@ -422,14 +422,22 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
 
 static void __kprobes clear_btf(void)
 {
-       if (test_thread_flag(TIF_DEBUGCTLMSR))
-               update_debugctlmsr(0);
+       if (test_thread_flag(TIF_BLOCKSTEP)) {
+               unsigned long debugctl = get_debugctlmsr();
+
+               debugctl &= ~DEBUGCTLMSR_BTF;
+               update_debugctlmsr(debugctl);
+       }
 }
 
 static void __kprobes restore_btf(void)
 {
-       if (test_thread_flag(TIF_DEBUGCTLMSR))
-               update_debugctlmsr(current->thread.debugctlmsr);
+       if (test_thread_flag(TIF_BLOCKSTEP)) {
+               unsigned long debugctl = get_debugctlmsr();
+
+               debugctl |= DEBUGCTLMSR_BTF;
+               update_debugctlmsr(debugctl);
+       }
 }
 
 void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
@@ -534,20 +542,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
        struct kprobe_ctlblk *kcb;
 
        addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
-       if (*addr != BREAKPOINT_INSTRUCTION) {
-               /*
-                * The breakpoint instruction was removed right
-                * after we hit it.  Another cpu has removed
-                * either a probepoint or a debugger breakpoint
-                * at this address.  In either case, no further
-                * handling of this interrupt is appropriate.
-                * Back up over the (now missing) int3 and run
-                * the original instruction.
-                */
-               regs->ip = (unsigned long)addr;
-               return 1;
-       }
-
        /*
         * We don't want to be preempted for the entire
         * duration of kprobe processing. We conditionally
@@ -579,6 +573,19 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
                                setup_singlestep(p, regs, kcb, 0);
                        return 1;
                }
+       } else if (*addr != BREAKPOINT_INSTRUCTION) {
+               /*
+                * The breakpoint instruction was removed right
+                * after we hit it.  Another cpu has removed
+                * either a probepoint or a debugger breakpoint
+                * at this address.  In either case, no further
+                * handling of this interrupt is appropriate.
+                * Back up over the (now missing) int3 and run
+                * the original instruction.
+                */
+               regs->ip = (unsigned long)addr;
+               preempt_enable_no_resched();
+               return 1;
        } else if (kprobe_running()) {
                p = __get_cpu_var(current_kprobe);
                if (p->break_handler && p->break_handler(p, regs)) {
index ec6ef60cbd170b0809d20287a60c226fb8fc25ed..ea697263b3738d2b20ef1131cb28ff8be44aa021 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/mm.h>
index 4a8bb82248ae8a9a945854105c19447fec8a6530..035c8c529181fa351c042f8d6a5b8ec3240dec8f 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/mm.h>
 #include <linux/kexec.h>
 #include <linux/string.h>
+#include <linux/gfp.h>
 #include <linux/reboot.h>
 #include <linux/numa.h>
 #include <linux/ftrace.h>
index 845d80ce1ef1143b591852b7ac16177080d3c07a..63eaf6596233b8cbe19425460ba8fe4a0ef888c1 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/kernel.h>
 #include <linux/mca.h>
 #include <linux/kprobes.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <linux/proc_fs.h>
index cceb5bc3c3c258c2a6f1957ee152f00c7310d462..2cd8c544e41a22a224c8f29f3f517e609c60536e 100644 (file)
@@ -201,9 +201,9 @@ static int do_microcode_update(const void __user *buf, size_t size)
        return error;
 }
 
-static int microcode_open(struct inode *unused1, struct file *unused2)
+static int microcode_open(struct inode *inode, struct file *file)
 {
-       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
+       return capable(CAP_SYS_RAWIO) ? nonseekable_open(inode, file) : -EPERM;
 }
 
 static ssize_t microcode_write(struct file *file, const char __user *buf,
index 85a343e28937770e383aec0d1320140bc7e0baf8..356170262a930c3cf94dff52f4f5a18ee74f0a9b 100644 (file)
@@ -343,10 +343,11 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
                                int (*get_ucode_data)(void *, const void *, size_t))
 {
        struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
-       u8 *ucode_ptr = data, *new_mc = NULL, *mc;
+       u8 *ucode_ptr = data, *new_mc = NULL, *mc = NULL;
        int new_rev = uci->cpu_sig.rev;
        unsigned int leftover = size;
        enum ucode_state state = UCODE_OK;
+       unsigned int curr_mc_size = 0;
 
        while (leftover) {
                struct microcode_header_intel mc_header;
@@ -361,9 +362,15 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
                        break;
                }
 
-               mc = vmalloc(mc_size);
-               if (!mc)
-                       break;
+               /* For performance reasons, reuse mc area when possible */
+               if (!mc || mc_size > curr_mc_size) {
+                       if (mc)
+                               vfree(mc);
+                       mc = vmalloc(mc_size);
+                       if (!mc)
+                               break;
+                       curr_mc_size = mc_size;
+               }
 
                if (get_ucode_data(mc, ucode_ptr, mc_size) ||
                    microcode_sanity_check(mc) < 0) {
@@ -376,13 +383,16 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
                                vfree(new_mc);
                        new_rev = mc_header.rev;
                        new_mc  = mc;
-               } else
-                       vfree(mc);
+                       mc = NULL;      /* trigger new vmalloc */
+               }
 
                ucode_ptr += mc_size;
                leftover  -= mc_size;
        }
 
+       if (mc)
+               vfree(mc);
+
        if (leftover) {
                if (new_mc)
                        vfree(new_mc);
index 89f386f044e43fa4ed4d29503bfc838900e3841c..e0bc186d7501f123265ae288ae071e772016e89b 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/bug.h>
 #include <linux/mm.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/page.h>
index a2c1edd2d3acdaf3dc4dfd9cb9b8abc41c56e2ad..5ae5d2426edfd0f74e3d9a4235bd143b5c9f5768 100644 (file)
@@ -115,21 +115,6 @@ static void __init MP_bus_info(struct mpc_bus *m)
                printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
 }
 
-static int bad_ioapic(unsigned long address)
-{
-       if (nr_ioapics >= MAX_IO_APICS) {
-               printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
-                      "(found %d)\n", MAX_IO_APICS, nr_ioapics);
-               panic("Recompile kernel with bigger MAX_IO_APICS!\n");
-       }
-       if (!address) {
-               printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
-                      " found in table, skipping!\n");
-               return 1;
-       }
-       return 0;
-}
-
 static void __init MP_ioapic_info(struct mpc_ioapic *m)
 {
        if (!(m->flags & MPC_APIC_USABLE))
@@ -138,15 +123,7 @@ static void __init MP_ioapic_info(struct mpc_ioapic *m)
        printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n",
               m->apicid, m->apicver, m->apicaddr);
 
-       if (bad_ioapic(m->apicaddr))
-               return;
-
-       mp_ioapics[nr_ioapics].apicaddr = m->apicaddr;
-       mp_ioapics[nr_ioapics].apicid = m->apicid;
-       mp_ioapics[nr_ioapics].type = m->type;
-       mp_ioapics[nr_ioapics].apicver = m->apicver;
-       mp_ioapics[nr_ioapics].flags = m->flags;
-       nr_ioapics++;
+       mp_register_ioapic(m->apicid, m->apicaddr, gsi_end + 1);
 }
 
 static void print_MP_intsrc_info(struct mpc_intsrc *m)
@@ -664,7 +641,7 @@ static void __init smp_reserve_memory(struct mpf_intel *mpf)
 {
        unsigned long size = get_mpc_size(mpf->physptr);
 
-       reserve_early(mpf->physptr, mpf->physptr+size, "MP-table mpc");
+       reserve_early_overlap_ok(mpf->physptr, mpf->physptr+size, "MP-table mpc");
 }
 
 static int __init smp_scan_config(unsigned long base, unsigned long length)
@@ -693,7 +670,7 @@ static int __init smp_scan_config(unsigned long base, unsigned long length)
                               mpf, (u64)virt_to_phys(mpf));
 
                        mem = virt_to_phys(mpf);
-                       reserve_early(mem, mem + sizeof(*mpf), "MP-table mpf");
+                       reserve_early_overlap_ok(mem, mem + sizeof(*mpf), "MP-table mpf");
                        if (mpf->physptr)
                                smp_reserve_memory(mpf);
 
index 0aad8670858eacd917cd8330c6e952cb2f41d1b4..e796448f0eb5e7a156600d690a32807e3b7b39fa 100644 (file)
@@ -237,4 +237,9 @@ void __init x86_mrst_early_setup(void)
        x86_init.pci.fixup_irqs = x86_init_noop;
 
        legacy_pic = &null_legacy_pic;
+
+       /* Avoid searching for BIOS MP tables */
+       x86_init.mpparse.find_smp_config = x86_init_noop;
+       x86_init.mpparse.get_smp_config = x86_init_uint_noop;
+
 }
index 206735ac8cbdbaf053e039fb5f6e4fb5c50a5f8a..4d4468e9f47cbc7ba182ea92c78ec989c0a8b555 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/cpu.h>
 #include <linux/notifier.h>
 #include <linux/uaccess.h>
+#include <linux/gfp.h>
 
 #include <asm/processor.h>
 #include <asm/msr.h>
index a4ac764a6880fdaa7b06fc984b5d1976b2b2ee0f..4b7e3d8b01ddfdeb5b1e49bbdfc4519e2b102ac1 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/dma-debug.h>
 #include <linux/dmar.h>
 #include <linux/bootmem.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/kmemleak.h>
 
index f3af115a573a5adbb053eae3a6c6921acf8b41fd..0f7f130caa6778d6077868e6e768b88f1439fc24 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/iommu-helper.h>
 #include <linux/sysdev.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 #include <asm/atomic.h>
 #include <asm/mtrr.h>
 #include <asm/pgtable.h>
@@ -564,6 +565,9 @@ static void enable_gart_translations(void)
 
                enable_gart_translation(dev, __pa(agp_gatt_table));
        }
+
+       /* Flush the GART-TLB to remove stale entries */
+       k8_flush_garts();
 }
 
 /*
index 22be12b60a8ff2b12678e5198379d19260de9ce4..3af4af810c07947d9a697444f3010bf2d5427e45 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/scatterlist.h>
 #include <linux/string.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/mm.h>
 
index ad9540676fccb7138917dc6520cdf88dd95b10f8..e7e35219b32f23e115c23846d06c07b0128e26ae 100644 (file)
@@ -20,7 +20,6 @@
 #include <asm/idle.h>
 #include <asm/uaccess.h>
 #include <asm/i387.h>
-#include <asm/ds.h>
 #include <asm/debugreg.h>
 
 unsigned long idle_halt;
@@ -32,26 +31,22 @@ struct kmem_cache *task_xstate_cachep;
 
 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 {
+       int ret;
+
        *dst = *src;
-       if (src->thread.xstate) {
-               dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
-                                                     GFP_KERNEL);
-               if (!dst->thread.xstate)
-                       return -ENOMEM;
-               WARN_ON((unsigned long)dst->thread.xstate & 15);
-               memcpy(dst->thread.xstate, src->thread.xstate, xstate_size);
+       if (fpu_allocated(&src->thread.fpu)) {
+               memset(&dst->thread.fpu, 0, sizeof(dst->thread.fpu));
+               ret = fpu_alloc(&dst->thread.fpu);
+               if (ret)
+                       return ret;
+               fpu_copy(&dst->thread.fpu, &src->thread.fpu);
        }
        return 0;
 }
 
 void free_thread_xstate(struct task_struct *tsk)
 {
-       if (tsk->thread.xstate) {
-               kmem_cache_free(task_xstate_cachep, tsk->thread.xstate);
-               tsk->thread.xstate = NULL;
-       }
-
-       WARN(tsk->thread.ds_ctx, "leaking DS context\n");
+       fpu_free(&tsk->thread.fpu);
 }
 
 void free_thread_info(struct thread_info *ti)
@@ -198,11 +193,16 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
        prev = &prev_p->thread;
        next = &next_p->thread;
 
-       if (test_tsk_thread_flag(next_p, TIF_DS_AREA_MSR) ||
-           test_tsk_thread_flag(prev_p, TIF_DS_AREA_MSR))
-               ds_switch_to(prev_p, next_p);
-       else if (next->debugctlmsr != prev->debugctlmsr)
-               update_debugctlmsr(next->debugctlmsr);
+       if (test_tsk_thread_flag(prev_p, TIF_BLOCKSTEP) ^
+           test_tsk_thread_flag(next_p, TIF_BLOCKSTEP)) {
+               unsigned long debugctl = get_debugctlmsr();
+
+               debugctl &= ~DEBUGCTLMSR_BTF;
+               if (test_tsk_thread_flag(next_p, TIF_BLOCKSTEP))
+                       debugctl |= DEBUGCTLMSR_BTF;
+
+               update_debugctlmsr(debugctl);
+       }
 
        if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^
            test_tsk_thread_flag(next_p, TIF_NOTSC)) {
@@ -526,21 +526,39 @@ static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c)
 }
 
 /*
- * Check for AMD CPUs, which have potentially C1E support
+ * Check for AMD CPUs, where APIC timer interrupt does not wake up CPU from C1e.
+ * For more information see
+ * - Erratum #400 for NPT family 0xf and family 0x10 CPUs
+ * - Erratum #365 for family 0x11 (not affected because C1e not in use)
  */
 static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c)
 {
+       u64 val;
        if (c->x86_vendor != X86_VENDOR_AMD)
-               return 0;
-
-       if (c->x86 < 0x0F)
-               return 0;
+               goto no_c1e_idle;
 
        /* Family 0x0f models < rev F do not have C1E */
-       if (c->x86 == 0x0f && c->x86_model < 0x40)
-               return 0;
+       if (c->x86 == 0x0F && c->x86_model >= 0x40)
+               return 1;
 
-       return 1;
+       if (c->x86 == 0x10) {
+               /*
+                * check OSVW bit for CPUs that are not affected
+                * by erratum #400
+                */
+               if (cpu_has(c, X86_FEATURE_OSVW)) {
+                       rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val);
+                       if (val >= 2) {
+                               rdmsrl(MSR_AMD64_OSVW_STATUS, val);
+                               if (!(val & BIT(1)))
+                                       goto no_c1e_idle;
+                       }
+               }
+               return 1;
+       }
+
+no_c1e_idle:
+       return 0;
 }
 
 static cpumask_var_t c1e_mask;
index f6c62667e30c89db95a8f2bc7054a6c12108f0dd..8d128783af47374e56412d01d0488aa12af1647b 100644 (file)
@@ -55,7 +55,6 @@
 #include <asm/cpu.h>
 #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");
@@ -238,13 +237,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
                kfree(p->thread.io_bitmap_ptr);
                p->thread.io_bitmap_max = 0;
        }
-
-       clear_tsk_thread_flag(p, TIF_DS_AREA_MSR);
-       p->thread.ds_ctx = NULL;
-
-       clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR);
-       p->thread.debugctlmsr = 0;
-
        return err;
 }
 
@@ -317,7 +309,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 
        /* we're going to use this soon, after a few expensive things */
        if (preload_fpu)
-               prefetch(next->xstate);
+               prefetch(next->fpu.state);
 
        /*
         * Reload esp0.
index dc9690b4c4cccf5450a8f49c0aec3bbdb1a86f78..3c2422a99f1f8293480ad436551cfac8c600d326 100644 (file)
@@ -49,7 +49,6 @@
 #include <asm/ia32.h>
 #include <asm/idle.h>
 #include <asm/syscalls.h>
-#include <asm/ds.h>
 #include <asm/debugreg.h>
 
 asmlinkage extern void ret_from_fork(void);
@@ -276,12 +275,12 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
 
        set_tsk_thread_flag(p, TIF_FORK);
 
-       p->thread.fs = me->thread.fs;
-       p->thread.gs = me->thread.gs;
        p->thread.io_bitmap_ptr = NULL;
 
        savesegment(gs, p->thread.gsindex);
+       p->thread.gs = p->thread.gsindex ? 0 : me->thread.gs;
        savesegment(fs, p->thread.fsindex);
+       p->thread.fs = p->thread.fsindex ? 0 : me->thread.fs;
        savesegment(es, p->thread.es);
        savesegment(ds, p->thread.ds);
 
@@ -313,13 +312,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
                if (err)
                        goto out;
        }
-
-       clear_tsk_thread_flag(p, TIF_DS_AREA_MSR);
-       p->thread.ds_ctx = NULL;
-
-       clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR);
-       p->thread.debugctlmsr = 0;
-
        err = 0;
 out:
        if (err && p->thread.io_bitmap_ptr) {
@@ -396,7 +388,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 
        /* we're going to use this soon, after a few expensive things */
        if (preload_fpu)
-               prefetch(next->xstate);
+               prefetch(next->fpu.state);
 
        /*
         * Reload esp0, LDT and the page table pointer:
index a503b1fd04e51048c25fca9b675add81cac37304..70c4872cd8aa0cc5a21cd3d7b1d9b8cc9a2575fb 100644 (file)
@@ -2,9 +2,6 @@
 /*
  * Pentium III FXSR, SSE support
  *     Gareth Hughes <gareth@valinux.com>, May 2000
- *
- * BTS tracing
- *     Markus Metzger <markus.t.metzger@intel.com>, Dec 2007
  */
 
 #include <linux/kernel.h>
@@ -12,6 +9,7 @@
 #include <linux/mm.h>
 #include <linux/smp.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/ptrace.h>
 #include <linux/regset.h>
 #include <linux/tracehook.h>
@@ -21,7 +19,6 @@
 #include <linux/audit.h>
 #include <linux/seccomp.h>
 #include <linux/signal.h>
-#include <linux/workqueue.h>
 #include <linux/perf_event.h>
 #include <linux/hw_breakpoint.h>
 
@@ -35,7 +32,6 @@
 #include <asm/desc.h>
 #include <asm/prctl.h>
 #include <asm/proto.h>
-#include <asm/ds.h>
 #include <asm/hw_breakpoint.h>
 
 #include "tls.h"
@@ -692,7 +688,7 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr,
        struct perf_event_attr attr;
 
        if (!t->ptrace_bps[nr]) {
-               hw_breakpoint_init(&attr);
+               ptrace_breakpoint_init(&attr);
                /*
                 * Put stub len and type to register (reserve) an inactive but
                 * correct bp
@@ -788,342 +784,6 @@ static int ioperm_get(struct task_struct *target,
                                   0, IO_BITMAP_BYTES);
 }
 
-#ifdef CONFIG_X86_PTRACE_BTS
-/*
- * A branch trace store context.
- *
- * Contexts may only be installed by ptrace_bts_config() and only for
- * ptraced tasks.
- *
- * Contexts are destroyed when the tracee is detached from the tracer.
- * The actual destruction work requires interrupts enabled, so the
- * work is deferred and will be scheduled during __ptrace_unlink().
- *
- * Contexts hold an additional task_struct reference on the traced
- * task, as well as a reference on the tracer's mm.
- *
- * Ptrace already holds a task_struct for the duration of ptrace operations,
- * but since destruction is deferred, it may be executed after both
- * tracer and tracee exited.
- */
-struct bts_context {
-       /* The branch trace handle. */
-       struct bts_tracer       *tracer;
-
-       /* The buffer used to store the branch trace and its size. */
-       void                    *buffer;
-       unsigned int            size;
-
-       /* The mm that paid for the above buffer. */
-       struct mm_struct        *mm;
-
-       /* The task this context belongs to. */
-       struct task_struct      *task;
-
-       /* The signal to send on a bts buffer overflow. */
-       unsigned int            bts_ovfl_signal;
-
-       /* The work struct to destroy a context. */
-       struct work_struct      work;
-};
-
-static int alloc_bts_buffer(struct bts_context *context, unsigned int size)
-{
-       void *buffer = NULL;
-       int err = -ENOMEM;
-
-       err = account_locked_memory(current->mm, current->signal->rlim, size);
-       if (err < 0)
-               return err;
-
-       buffer = kzalloc(size, GFP_KERNEL);
-       if (!buffer)
-               goto out_refund;
-
-       context->buffer = buffer;
-       context->size = size;
-       context->mm = get_task_mm(current);
-
-       return 0;
-
- out_refund:
-       refund_locked_memory(current->mm, size);
-       return err;
-}
-
-static inline void free_bts_buffer(struct bts_context *context)
-{
-       if (!context->buffer)
-               return;
-
-       kfree(context->buffer);
-       context->buffer = NULL;
-
-       refund_locked_memory(context->mm, context->size);
-       context->size = 0;
-
-       mmput(context->mm);
-       context->mm = NULL;
-}
-
-static void free_bts_context_work(struct work_struct *w)
-{
-       struct bts_context *context;
-
-       context = container_of(w, struct bts_context, work);
-
-       ds_release_bts(context->tracer);
-       put_task_struct(context->task);
-       free_bts_buffer(context);
-       kfree(context);
-}
-
-static inline void free_bts_context(struct bts_context *context)
-{
-       INIT_WORK(&context->work, free_bts_context_work);
-       schedule_work(&context->work);
-}
-
-static inline struct bts_context *alloc_bts_context(struct task_struct *task)
-{
-       struct bts_context *context = kzalloc(sizeof(*context), GFP_KERNEL);
-       if (context) {
-               context->task = task;
-               task->bts = context;
-
-               get_task_struct(task);
-       }
-
-       return context;
-}
-
-static int ptrace_bts_read_record(struct task_struct *child, size_t index,
-                                 struct bts_struct __user *out)
-{
-       struct bts_context *context;
-       const struct bts_trace *trace;
-       struct bts_struct bts;
-       const unsigned char *at;
-       int error;
-
-       context = child->bts;
-       if (!context)
-               return -ESRCH;
-
-       trace = ds_read_bts(context->tracer);
-       if (!trace)
-               return -ESRCH;
-
-       at = trace->ds.top - ((index + 1) * trace->ds.size);
-       if ((void *)at < trace->ds.begin)
-               at += (trace->ds.n * trace->ds.size);
-
-       if (!trace->read)
-               return -EOPNOTSUPP;
-
-       error = trace->read(context->tracer, at, &bts);
-       if (error < 0)
-               return error;
-
-       if (copy_to_user(out, &bts, sizeof(bts)))
-               return -EFAULT;
-
-       return sizeof(bts);
-}
-
-static int ptrace_bts_drain(struct task_struct *child,
-                           long size,
-                           struct bts_struct __user *out)
-{
-       struct bts_context *context;
-       const struct bts_trace *trace;
-       const unsigned char *at;
-       int error, drained = 0;
-
-       context = child->bts;
-       if (!context)
-               return -ESRCH;
-
-       trace = ds_read_bts(context->tracer);
-       if (!trace)
-               return -ESRCH;
-
-       if (!trace->read)
-               return -EOPNOTSUPP;
-
-       if (size < (trace->ds.top - trace->ds.begin))
-               return -EIO;
-
-       for (at = trace->ds.begin; (void *)at < trace->ds.top;
-            out++, drained++, at += trace->ds.size) {
-               struct bts_struct bts;
-
-               error = trace->read(context->tracer, at, &bts);
-               if (error < 0)
-                       return error;
-
-               if (copy_to_user(out, &bts, sizeof(bts)))
-                       return -EFAULT;
-       }
-
-       memset(trace->ds.begin, 0, trace->ds.n * trace->ds.size);
-
-       error = ds_reset_bts(context->tracer);
-       if (error < 0)
-               return error;
-
-       return drained;
-}
-
-static int ptrace_bts_config(struct task_struct *child,
-                            long cfg_size,
-                            const struct ptrace_bts_config __user *ucfg)
-{
-       struct bts_context *context;
-       struct ptrace_bts_config cfg;
-       unsigned int flags = 0;
-
-       if (cfg_size < sizeof(cfg))
-               return -EIO;
-
-       if (copy_from_user(&cfg, ucfg, sizeof(cfg)))
-               return -EFAULT;
-
-       context = child->bts;
-       if (!context)
-               context = alloc_bts_context(child);
-       if (!context)
-               return -ENOMEM;
-
-       if (cfg.flags & PTRACE_BTS_O_SIGNAL) {
-               if (!cfg.signal)
-                       return -EINVAL;
-
-               return -EOPNOTSUPP;
-               context->bts_ovfl_signal = cfg.signal;
-       }
-
-       ds_release_bts(context->tracer);
-       context->tracer = NULL;
-
-       if ((cfg.flags & PTRACE_BTS_O_ALLOC) && (cfg.size != context->size)) {
-               int err;
-
-               free_bts_buffer(context);
-               if (!cfg.size)
-                       return 0;
-
-               err = alloc_bts_buffer(context, cfg.size);
-               if (err < 0)
-                       return err;
-       }
-
-       if (cfg.flags & PTRACE_BTS_O_TRACE)
-               flags |= BTS_USER;
-
-       if (cfg.flags & PTRACE_BTS_O_SCHED)
-               flags |= BTS_TIMESTAMPS;
-
-       context->tracer =
-               ds_request_bts_task(child, context->buffer, context->size,
-                                   NULL, (size_t)-1, flags);
-       if (unlikely(IS_ERR(context->tracer))) {
-               int error = PTR_ERR(context->tracer);
-
-               free_bts_buffer(context);
-               context->tracer = NULL;
-               return error;
-       }
-
-       return sizeof(cfg);
-}
-
-static int ptrace_bts_status(struct task_struct *child,
-                            long cfg_size,
-                            struct ptrace_bts_config __user *ucfg)
-{
-       struct bts_context *context;
-       const struct bts_trace *trace;
-       struct ptrace_bts_config cfg;
-
-       context = child->bts;
-       if (!context)
-               return -ESRCH;
-
-       if (cfg_size < sizeof(cfg))
-               return -EIO;
-
-       trace = ds_read_bts(context->tracer);
-       if (!trace)
-               return -ESRCH;
-
-       memset(&cfg, 0, sizeof(cfg));
-       cfg.size        = trace->ds.end - trace->ds.begin;
-       cfg.signal      = context->bts_ovfl_signal;
-       cfg.bts_size    = sizeof(struct bts_struct);
-
-       if (cfg.signal)
-               cfg.flags |= PTRACE_BTS_O_SIGNAL;
-
-       if (trace->ds.flags & BTS_USER)
-               cfg.flags |= PTRACE_BTS_O_TRACE;
-
-       if (trace->ds.flags & BTS_TIMESTAMPS)
-               cfg.flags |= PTRACE_BTS_O_SCHED;
-
-       if (copy_to_user(ucfg, &cfg, sizeof(cfg)))
-               return -EFAULT;
-
-       return sizeof(cfg);
-}
-
-static int ptrace_bts_clear(struct task_struct *child)
-{
-       struct bts_context *context;
-       const struct bts_trace *trace;
-
-       context = child->bts;
-       if (!context)
-               return -ESRCH;
-
-       trace = ds_read_bts(context->tracer);
-       if (!trace)
-               return -ESRCH;
-
-       memset(trace->ds.begin, 0, trace->ds.n * trace->ds.size);
-
-       return ds_reset_bts(context->tracer);
-}
-
-static int ptrace_bts_size(struct task_struct *child)
-{
-       struct bts_context *context;
-       const struct bts_trace *trace;
-
-       context = child->bts;
-       if (!context)
-               return -ESRCH;
-
-       trace = ds_read_bts(context->tracer);
-       if (!trace)
-               return -ESRCH;
-
-       return (trace->ds.top - trace->ds.begin) / trace->ds.size;
-}
-
-/*
- * Called from __ptrace_unlink() after the child has been moved back
- * to its original parent.
- */
-void ptrace_bts_untrace(struct task_struct *child)
-{
-       if (unlikely(child->bts)) {
-               free_bts_context(child->bts);
-               child->bts = NULL;
-       }
-}
-#endif /* CONFIG_X86_PTRACE_BTS */
-
 /*
  * Called by kernel/ptrace.c when detaching..
  *
@@ -1251,39 +911,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                break;
 #endif
 
-       /*
-        * These bits need more cooking - not enabled yet:
-        */
-#ifdef CONFIG_X86_PTRACE_BTS
-       case PTRACE_BTS_CONFIG:
-               ret = ptrace_bts_config
-                       (child, data, (struct ptrace_bts_config __user *)addr);
-               break;
-
-       case PTRACE_BTS_STATUS:
-               ret = ptrace_bts_status
-                       (child, data, (struct ptrace_bts_config __user *)addr);
-               break;
-
-       case PTRACE_BTS_SIZE:
-               ret = ptrace_bts_size(child);
-               break;
-
-       case PTRACE_BTS_GET:
-               ret = ptrace_bts_read_record
-                       (child, data, (struct bts_struct __user *) addr);
-               break;
-
-       case PTRACE_BTS_CLEAR:
-               ret = ptrace_bts_clear(child);
-               break;
-
-       case PTRACE_BTS_DRAIN:
-               ret = ptrace_bts_drain
-                       (child, data, (struct bts_struct __user *) addr);
-               break;
-#endif /* CONFIG_X86_PTRACE_BTS */
-
        default:
                ret = ptrace_request(child, request, addr, data);
                break;
@@ -1543,14 +1170,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 
        case PTRACE_GET_THREAD_AREA:
        case PTRACE_SET_THREAD_AREA:
-#ifdef CONFIG_X86_PTRACE_BTS
-       case PTRACE_BTS_CONFIG:
-       case PTRACE_BTS_STATUS:
-       case PTRACE_BTS_SIZE:
-       case PTRACE_BTS_GET:
-       case PTRACE_BTS_CLEAR:
-       case PTRACE_BTS_DRAIN:
-#endif /* CONFIG_X86_PTRACE_BTS */
                return arch_ptrace(child, request, addr, data);
 
        default:
index 5d7ba1a449bde18735d58777f3f510c04eaa5280..c4851eff57b32ce96e5bc2e72f536d01a6a78fb8 100644 (file)
@@ -55,7 +55,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/delay.h>
 
@@ -314,16 +313,17 @@ static void __init reserve_brk(void)
 #define MAX_MAP_CHUNK  (NR_FIX_BTMAPS << PAGE_SHIFT)
 static void __init relocate_initrd(void)
 {
-
+       /* Assume only end is not page aligned */
        u64 ramdisk_image = boot_params.hdr.ramdisk_image;
        u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
+       u64 area_size     = PAGE_ALIGN(ramdisk_size);
        u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;
        u64 ramdisk_here;
        unsigned long slop, clen, mapaddr;
        char *p, *q;
 
        /* We need to move the initrd down into lowmem */
-       ramdisk_here = find_e820_area(0, end_of_lowmem, ramdisk_size,
+       ramdisk_here = find_e820_area(0, end_of_lowmem, area_size,
                                         PAGE_SIZE);
 
        if (ramdisk_here == -1ULL)
@@ -332,7 +332,7 @@ static void __init relocate_initrd(void)
 
        /* Note: this includes all the lowmem currently occupied by
           the initrd, we rely on that fact to keep the data intact. */
-       reserve_early(ramdisk_here, ramdisk_here + ramdisk_size,
+       reserve_early(ramdisk_here, ramdisk_here + area_size,
                         "NEW RAMDISK");
        initrd_start = ramdisk_here + PAGE_OFFSET;
        initrd_end   = initrd_start + ramdisk_size;
@@ -376,9 +376,10 @@ static void __init relocate_initrd(void)
 
 static void __init reserve_initrd(void)
 {
+       /* Assume only end is not page aligned */
        u64 ramdisk_image = boot_params.hdr.ramdisk_image;
        u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
-       u64 ramdisk_end   = ramdisk_image + ramdisk_size;
+       u64 ramdisk_end   = PAGE_ALIGN(ramdisk_image + ramdisk_size);
        u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;
 
        if (!boot_params.hdr.type_of_loader ||
@@ -606,6 +607,16 @@ static int __init setup_elfcorehdr(char *arg)
 early_param("elfcorehdr", setup_elfcorehdr);
 #endif
 
+static __init void reserve_ibft_region(void)
+{
+       unsigned long addr, size = 0;
+
+       addr = find_ibft_region(&size);
+
+       if (size)
+               reserve_early_overlap_ok(addr, addr + size, "ibft");
+}
+
 #ifdef CONFIG_X86_RESERVE_LOW_64K
 static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
 {
@@ -908,6 +919,8 @@ void __init setup_arch(char **cmdline_p)
         */
        find_smp_config();
 
+       reserve_ibft_region();
+
        reserve_trampoline_memory();
 
 #ifdef CONFIG_ACPI_SLEEP
@@ -975,8 +988,6 @@ void __init setup_arch(char **cmdline_p)
 
        dma32_reserve_bootmem();
 
-       reserve_ibft_region();
-
 #ifdef CONFIG_KVM_CLOCK
        kvmclock_init();
 #endif
index 34e0993826513200126a201fd9bfc7a0c59f7890..7ded57896c0a1271f653ea14aaaf309e0dcb96c0 100644 (file)
@@ -81,7 +81,6 @@ static int __init sfi_parse_cpus(struct sfi_table_header *table)
 #endif /* CONFIG_X86_LOCAL_APIC */
 
 #ifdef CONFIG_X86_IO_APIC
-static u32 gsi_base;
 
 static int __init sfi_parse_ioapic(struct sfi_table_header *table)
 {
@@ -94,8 +93,7 @@ static int __init sfi_parse_ioapic(struct sfi_table_header *table)
        pentry = (struct sfi_apic_table_entry *)sb->pentry;
 
        for (i = 0; i < num; i++) {
-               mp_register_ioapic(i, pentry->phys_addr, gsi_base);
-               gsi_base += io_apic_get_redir_entries(i);
+               mp_register_ioapic(i, pentry->phys_addr, gsi_end + 1);
                pentry++;
        }
 
index ec1de97600e70638bcfdcb53da52a83bc1288829..d801210945d6f5d93e3a8c672243a67792bca3cd 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/cache.h>
 #include <linux/interrupt.h>
 #include <linux/cpu.h>
+#include <linux/gfp.h>
 
 #include <asm/mtrr.h>
 #include <asm/tlbflush.h>
index a02e80c3c54bedbfdcb05d8741461d0abdc6fe9d..763d815e27a005159ca5b52c68df4f43010b9832 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/nmi.h>
 #include <linux/tboot.h>
 #include <linux/stackprotector.h>
+#include <linux/gfp.h>
 
 #include <asm/acpi.h>
 #include <asm/desc.h>
@@ -242,12 +243,10 @@ static void __cpuinit smp_callin(void)
        end_local_APIC_setup();
        map_cpu_to_logical_apicid();
 
-       notify_cpu_starting(cpuid);
-
        /*
         * Need to setup vector mappings before we enable interrupts.
         */
-       __setup_vector_irq(smp_processor_id());
+       setup_vector_irq(smp_processor_id());
        /*
         * Get our bogomips.
         *
@@ -264,6 +263,8 @@ static void __cpuinit smp_callin(void)
         */
        smp_store_cpu_info(cpuid);
 
+       notify_cpu_starting(cpuid);
+
        /*
         * Allow the master to continue.
         */
index 3149032ff107598e49c1451df9f5964ac81d4f2c..58de45ee08b6f76638cd70011972f645cf9ea25e 100644 (file)
@@ -157,22 +157,6 @@ static int enable_single_step(struct task_struct *child)
        return 1;
 }
 
-/*
- * Install this value in MSR_IA32_DEBUGCTLMSR whenever child is running.
- */
-static void write_debugctlmsr(struct task_struct *child, unsigned long val)
-{
-       if (child->thread.debugctlmsr == val)
-               return;
-
-       child->thread.debugctlmsr = val;
-
-       if (child != current)
-               return;
-
-       update_debugctlmsr(val);
-}
-
 /*
  * Enable single or block step.
  */
@@ -186,15 +170,17 @@ static void enable_step(struct task_struct *child, bool block)
         * that uses user-mode single stepping itself.
         */
        if (enable_single_step(child) && block) {
-               set_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
-               write_debugctlmsr(child,
-                                 child->thread.debugctlmsr | DEBUGCTLMSR_BTF);
-       } else {
-               write_debugctlmsr(child,
-                                 child->thread.debugctlmsr & ~DEBUGCTLMSR_BTF);
-
-               if (!child->thread.debugctlmsr)
-                       clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
+               unsigned long debugctl = get_debugctlmsr();
+
+               debugctl |= DEBUGCTLMSR_BTF;
+               update_debugctlmsr(debugctl);
+               set_tsk_thread_flag(child, TIF_BLOCKSTEP);
+       } else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) {
+               unsigned long debugctl = get_debugctlmsr();
+
+               debugctl &= ~DEBUGCTLMSR_BTF;
+               update_debugctlmsr(debugctl);
+               clear_tsk_thread_flag(child, TIF_BLOCKSTEP);
        }
 }
 
@@ -213,11 +199,13 @@ void user_disable_single_step(struct task_struct *child)
        /*
         * Make sure block stepping (BTF) is disabled.
         */
-       write_debugctlmsr(child,
-                         child->thread.debugctlmsr & ~DEBUGCTLMSR_BTF);
+       if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) {
+               unsigned long debugctl = get_debugctlmsr();
 
-       if (!child->thread.debugctlmsr)
-               clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
+               debugctl &= ~DEBUGCTLMSR_BTF;
+               update_debugctlmsr(debugctl);
+               clear_tsk_thread_flag(child, TIF_BLOCKSTEP);
+       }
 
        /* Always clear TIF_SINGLESTEP... */
        clear_tsk_thread_flag(child, TIF_SINGLESTEP);
index 364d015efebcc88dd6966cbfb741dfc41ccc410a..17b03dd3a6b50f45cb87e7f4cfb1312414a35274 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/seq_file.h>
 #include <linux/proc_fs.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include <asm/mmu_context.h>
 #include <asm/uv/uv.h>
index 1168e44541887e441e0cb8422cdaf67e86bfe4e5..02cfb9b8f5b10f8d282715cc7a79fd49e04b7468 100644 (file)
@@ -108,15 +108,6 @@ static inline void preempt_conditional_cli(struct pt_regs *regs)
        dec_preempt_count();
 }
 
-#ifdef CONFIG_X86_32
-static inline void
-die_if_kernel(const char *str, struct pt_regs *regs, long err)
-{
-       if (!user_mode_vm(regs))
-               die(str, regs, err);
-}
-#endif
-
 static void __kprobes
 do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
        long error_code, siginfo_t *info)
@@ -543,11 +534,11 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
 
        /* 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;
+       clear_tsk_thread_flag(tsk, TIF_BLOCKSTEP);
 
        /* Store the virtualized DR6 value */
        tsk->thread.debugreg6 = dr6;
@@ -585,55 +576,67 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
        return;
 }
 
-#ifdef CONFIG_X86_64
-static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr)
-{
-       if (fixup_exception(regs))
-               return 1;
-
-       notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE);
-       /* Illegal floating point operation in the kernel */
-       current->thread.trap_no = trapnr;
-       die(str, regs, 0);
-       return 0;
-}
-#endif
-
 /*
  * Note that we play around with the 'TS' bit in an attempt to get
  * the correct behaviour even in the presence of the asynchronous
  * IRQ13 behaviour
  */
-void math_error(void __user *ip)
+void math_error(struct pt_regs *regs, int error_code, int trapnr)
 {
-       struct task_struct *task;
+       struct task_struct *task = current;
        siginfo_t info;
-       unsigned short cwd, swd, err;
+       unsigned short err;
+       char *str = (trapnr == 16) ? "fpu exception" : "simd exception";
+
+       if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP)
+               return;
+       conditional_sti(regs);
+
+       if (!user_mode_vm(regs))
+       {
+               if (!fixup_exception(regs)) {
+                       task->thread.error_code = error_code;
+                       task->thread.trap_no = trapnr;
+                       die(str, regs, error_code);
+               }
+               return;
+       }
 
        /*
         * Save the info for the exception handler and clear the error.
         */
-       task = current;
        save_init_fpu(task);
-       task->thread.trap_no = 16;
-       task->thread.error_code = 0;
+       task->thread.trap_no = trapnr;
+       task->thread.error_code = error_code;
        info.si_signo = SIGFPE;
        info.si_errno = 0;
-       info.si_addr = ip;
-       /*
-        * (~cwd & swd) will mask out exceptions that are not set to unmasked
-        * status.  0x3f is the exception bits in these regs, 0x200 is the
-        * C1 reg you need in case of a stack fault, 0x040 is the stack
-        * fault bit.  We should only be taking one exception at a time,
-        * so if this combination doesn't produce any single exception,
-        * then we have a bad program that isn't synchronizing its FPU usage
-        * and it will suffer the consequences since we won't be able to
-        * fully reproduce the context of the exception
-        */
-       cwd = get_fpu_cwd(task);
-       swd = get_fpu_swd(task);
+       info.si_addr = (void __user *)regs->ip;
+       if (trapnr == 16) {
+               unsigned short cwd, swd;
+               /*
+                * (~cwd & swd) will mask out exceptions that are not set to unmasked
+                * status.  0x3f is the exception bits in these regs, 0x200 is the
+                * C1 reg you need in case of a stack fault, 0x040 is the stack
+                * fault bit.  We should only be taking one exception at a time,
+                * so if this combination doesn't produce any single exception,
+                * then we have a bad program that isn't synchronizing its FPU usage
+                * and it will suffer the consequences since we won't be able to
+                * fully reproduce the context of the exception
+                */
+               cwd = get_fpu_cwd(task);
+               swd = get_fpu_swd(task);
 
-       err = swd & ~cwd;
+               err = swd & ~cwd;
+       } else {
+               /*
+                * The SIMD FPU exceptions are handled a little differently, as there
+                * is only a single status/control register.  Thus, to determine which
+                * unmasked exception was caught we must mask the exception mask bits
+                * at 0x1f80, and then use these to mask the exception bits at 0x3f.
+                */
+               unsigned short mxcsr = get_fpu_mxcsr(task);
+               err = ~(mxcsr >> 7) & mxcsr;
+       }
 
        if (err & 0x001) {      /* Invalid op */
                /*
@@ -662,97 +665,17 @@ void math_error(void __user *ip)
 
 dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
 {
-       conditional_sti(regs);
-
 #ifdef CONFIG_X86_32
        ignore_fpu_irq = 1;
-#else
-       if (!user_mode(regs) &&
-           kernel_math_error(regs, "kernel x87 math error", 16))
-               return;
 #endif
 
-       math_error((void __user *)regs->ip);
-}
-
-static void simd_math_error(void __user *ip)
-{
-       struct task_struct *task;
-       siginfo_t info;
-       unsigned short mxcsr;
-
-       /*
-        * Save the info for the exception handler and clear the error.
-        */
-       task = current;
-       save_init_fpu(task);
-       task->thread.trap_no = 19;
-       task->thread.error_code = 0;
-       info.si_signo = SIGFPE;
-       info.si_errno = 0;
-       info.si_code = __SI_FAULT;
-       info.si_addr = ip;
-       /*
-        * The SIMD FPU exceptions are handled a little differently, as there
-        * is only a single status/control register.  Thus, to determine which
-        * unmasked exception was caught we must mask the exception mask bits
-        * at 0x1f80, and then use these to mask the exception bits at 0x3f.
-        */
-       mxcsr = get_fpu_mxcsr(task);
-       switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) {
-       case 0x000:
-       default:
-               break;
-       case 0x001: /* Invalid Op */
-               info.si_code = FPE_FLTINV;
-               break;
-       case 0x002: /* Denormalize */
-       case 0x010: /* Underflow */
-               info.si_code = FPE_FLTUND;
-               break;
-       case 0x004: /* Zero Divide */
-               info.si_code = FPE_FLTDIV;
-               break;
-       case 0x008: /* Overflow */
-               info.si_code = FPE_FLTOVF;
-               break;
-       case 0x020: /* Precision */
-               info.si_code = FPE_FLTRES;
-               break;
-       }
-       force_sig_info(SIGFPE, &info, task);
+       math_error(regs, error_code, 16);
 }
 
 dotraplinkage void
 do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
 {
-       conditional_sti(regs);
-
-#ifdef CONFIG_X86_32
-       if (cpu_has_xmm) {
-               /* Handle SIMD FPU exceptions on PIII+ processors. */
-               ignore_fpu_irq = 1;
-               simd_math_error((void __user *)regs->ip);
-               return;
-       }
-       /*
-        * Handle strange cache flush from user space exception
-        * in all other cases.  This is undocumented behaviour.
-        */
-       if (regs->flags & X86_VM_MASK) {
-               handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
-               return;
-       }
-       current->thread.trap_no = 19;
-       current->thread.error_code = error_code;
-       die_if_kernel("cache flush denied", regs, error_code);
-       force_sig(SIGSEGV, current);
-#else
-       if (!user_mode(regs) &&
-                       kernel_math_error(regs, "kernel simd math error", 19))
-               return;
-       simd_math_error((void __user *)regs->ip);
-#endif
+       math_error(regs, error_code, 19);
 }
 
 dotraplinkage void
index ece73d8e32409feffaba8fde7d8b8e042c6771e7..1d40336b030adc9206a48cc0a5e39ba0c22dcf7e 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/module.h>
 #include <linux/rbtree.h>
+#include <linux/slab.h>
 #include <linux/irq.h>
 
 #include <asm/apic.h>
index 2b75ef638dbc6f0716d02c58dd23cc8a97acc45a..56e421bc379b19931d4db718b35e3b92e71c3d5e 100644 (file)
@@ -19,6 +19,7 @@
  *  Copyright (c) Dimitri Sivanich
  */
 #include <linux/clockchips.h>
+#include <linux/slab.h>
 
 #include <asm/uv/uv_mmrs.h>
 #include <asm/uv/uv_hub.h>
index 7dd599deca4a7f34139fc338eb4a959e7bcbd80e..ce9fbacb7526284f35c8290d994a8f804c4e61c0 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/sched.h>
+#include <linux/gfp.h>
 #include <asm/vmi.h>
 #include <asm/io.h>
 #include <asm/fixmap.h>
index 44879df55696407556d711b69b0f83fdc311f7f0..2cc249718c46e47ca28dd9e48ff1691a3c39d185 100644 (file)
@@ -291,8 +291,8 @@ SECTIONS
        .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
                __smp_locks = .;
                *(.smp_locks)
-               __smp_locks_end = .;
                . = ALIGN(PAGE_SIZE);
+               __smp_locks_end = .;
        }
 
 #ifdef CONFIG_X86_64
index 693920b22496f13f5e67384168ae6f4a79cc9235..1b950d151e58a3154568f78ae21b8260fe77335c 100644 (file)
@@ -54,7 +54,6 @@ EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(__memcpy);
 
 EXPORT_SYMBOL(empty_zero_page);
-EXPORT_SYMBOL(init_level4_pgt);
 #ifndef CONFIG_PARAVIRT
 EXPORT_SYMBOL(native_load_gs_index);
 #endif
index 782c3a362ec611af114dd73144fe706c9d70fd16..37e68fc5e24a4daa33bcb6c730162a0969c91430 100644 (file)
@@ -99,7 +99,7 @@ int save_i387_xstate(void __user *buf)
                if (err)
                        return err;
 
-               if (task_thread_info(tsk)->status & TS_XSAVE)
+               if (use_xsave())
                        err = xsave_user(buf);
                else
                        err = fxsave_user(buf);
@@ -109,14 +109,14 @@ int save_i387_xstate(void __user *buf)
                task_thread_info(tsk)->status &= ~TS_USEDFPU;
                stts();
        } else {
-               if (__copy_to_user(buf, &tsk->thread.xstate->fxsave,
+               if (__copy_to_user(buf, &tsk->thread.fpu.state->fxsave,
                                   xstate_size))
                        return -1;
        }
 
        clear_used_math(); /* trigger finit */
 
-       if (task_thread_info(tsk)->status & TS_XSAVE) {
+       if (use_xsave()) {
                struct _fpstate __user *fx = buf;
                struct _xstate __user *x = buf;
                u64 xstate_bv;
@@ -225,7 +225,7 @@ int restore_i387_xstate(void __user *buf)
                clts();
                task_thread_info(current)->status |= TS_USEDFPU;
        }
-       if (task_thread_info(tsk)->status & TS_XSAVE)
+       if (use_xsave())
                err = restore_user_xstate(buf);
        else
                err = fxrstor_checking((__force struct i387_fxsave_struct *)
index 294698b6daff60c288dcd1304470ab7c6254000f..0150affad25d082c4dd8eea9546b30ee12491731 100644 (file)
@@ -32,6 +32,7 @@
 #define pr_fmt(fmt) "pit: " fmt
 
 #include <linux/kvm_host.h>
+#include <linux/slab.h>
 
 #include "irq.h"
 #include "i8254.h"
index 07771da85de55a75db97f4c7522ad465ce386b26..a790fa128a9fada66d5e816bc342b2b27186a92a 100644 (file)
@@ -26,6 +26,7 @@
  *   Port from Qemu.
  */
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/bitops.h>
 #include "irq.h"
 
index 4b224f90087bd602ce3c74a09392cb7dc5d23f07..1eb7a4ae0c9c0382ac64b44040f02e3accc4d005 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/math64.h>
+#include <linux/slab.h>
 #include <asm/processor.h>
 #include <asm/msr.h>
 #include <asm/page.h>
index 741373e8ca777a318ed7e487ef8982a181ea24f4..19a8906bcaa2c5301dddf55821078248a85e23a7 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/hugetlb.h>
 #include <linux/compiler.h>
 #include <linux/srcu.h>
+#include <linux/slab.h>
 
 #include <asm/page.h>
 #include <asm/cmpxchg.h>
@@ -1489,8 +1490,8 @@ static int mmu_zap_unsync_children(struct kvm *kvm,
                for_each_sp(pages, sp, parents, i) {
                        kvm_mmu_zap_page(kvm, sp);
                        mmu_pages_clear_parents(&parents);
+                       zapped++;
                }
-               zapped += pages.nr;
                kvm_mmu_pages_init(parent, &parents, &pages);
        }
 
@@ -1541,14 +1542,16 @@ void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages)
         */
 
        if (used_pages > kvm_nr_mmu_pages) {
-               while (used_pages > kvm_nr_mmu_pages) {
+               while (used_pages > kvm_nr_mmu_pages &&
+                       !list_empty(&kvm->arch.active_mmu_pages)) {
                        struct kvm_mmu_page *page;
 
                        page = container_of(kvm->arch.active_mmu_pages.prev,
                                            struct kvm_mmu_page, link);
-                       kvm_mmu_zap_page(kvm, page);
+                       used_pages -= kvm_mmu_zap_page(kvm, page);
                        used_pages--;
                }
+               kvm_nr_mmu_pages = used_pages;
                kvm->arch.n_free_mmu_pages = 0;
        }
        else
@@ -1595,7 +1598,8 @@ static void mmu_unshadow(struct kvm *kvm, gfn_t gfn)
                    && !sp->role.invalid) {
                        pgprintk("%s: zap %lx %x\n",
                                 __func__, gfn, sp->role.word);
-                       kvm_mmu_zap_page(kvm, sp);
+                       if (kvm_mmu_zap_page(kvm, sp))
+                               nn = bucket->first;
                }
        }
 }
index 52f78dd03010569eba75d6db749d83e4c19265e9..737361fcd503e10091d0cb0e485ede146ec9a6f1 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/highmem.h>
 #include <linux/sched.h>
 #include <linux/ftrace_event.h>
+#include <linux/slab.h>
 
 #include <asm/desc.h>
 
@@ -705,29 +706,28 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
        if (err)
                goto free_svm;
 
+       err = -ENOMEM;
        page = alloc_page(GFP_KERNEL);
-       if (!page) {
-               err = -ENOMEM;
+       if (!page)
                goto uninit;
-       }
 
-       err = -ENOMEM;
        msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER);
        if (!msrpm_pages)
-               goto uninit;
+               goto free_page1;
 
        nested_msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER);
        if (!nested_msrpm_pages)
-               goto uninit;
-
-       svm->msrpm = page_address(msrpm_pages);
-       svm_vcpu_init_msrpm(svm->msrpm);
+               goto free_page2;
 
        hsave_page = alloc_page(GFP_KERNEL);
        if (!hsave_page)
-               goto uninit;
+               goto free_page3;
+
        svm->nested.hsave = page_address(hsave_page);
 
+       svm->msrpm = page_address(msrpm_pages);
+       svm_vcpu_init_msrpm(svm->msrpm);
+
        svm->nested.msrpm = page_address(nested_msrpm_pages);
 
        svm->vmcb = page_address(page);
@@ -743,6 +743,12 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
 
        return &svm->vcpu;
 
+free_page3:
+       __free_pages(nested_msrpm_pages, MSRPM_ALLOC_ORDER);
+free_page2:
+       __free_pages(msrpm_pages, MSRPM_ALLOC_ORDER);
+free_page1:
+       __free_page(page);
 uninit:
        kvm_vcpu_uninit(&svm->vcpu);
 free_svm:
@@ -2061,7 +2067,7 @@ static int cpuid_interception(struct vcpu_svm *svm)
 static int iret_interception(struct vcpu_svm *svm)
 {
        ++svm->vcpu.stat.nmi_window_exits;
-       svm->vmcb->control.intercept &= ~(1UL << INTERCEPT_IRET);
+       svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_IRET);
        svm->vcpu.arch.hflags |= HF_IRET_MASK;
        return 1;
 }
@@ -2473,7 +2479,7 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu)
 
        svm->vmcb->control.event_inj = SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_NMI;
        vcpu->arch.hflags |= HF_NMI_MASK;
-       svm->vmcb->control.intercept |= (1UL << INTERCEPT_IRET);
+       svm->vmcb->control.intercept |= (1ULL << INTERCEPT_IRET);
        ++vcpu->stat.nmi_injections;
 }
 
@@ -2533,10 +2539,10 @@ static void svm_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
 
        if (masked) {
                svm->vcpu.arch.hflags |= HF_NMI_MASK;
-               svm->vmcb->control.intercept |= (1UL << INTERCEPT_IRET);
+               svm->vmcb->control.intercept |= (1ULL << INTERCEPT_IRET);
        } else {
                svm->vcpu.arch.hflags &= ~HF_NMI_MASK;
-               svm->vmcb->control.intercept &= ~(1UL << INTERCEPT_IRET);
+               svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_IRET);
        }
 }
 
index 14873b9f84308ad125ae12969e0eeed269705de4..edca080407a541a4ec331fe3a2516b6b8334eb64 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/sched.h>
 #include <linux/moduleparam.h>
 #include <linux/ftrace_event.h>
+#include <linux/slab.h>
 #include "kvm_cache_regs.h"
 #include "x86.h"
 
@@ -76,6 +77,8 @@ module_param(emulate_invalid_guest_state, bool, S_IRUGO);
 #define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE)
 #define KVM_RMODE_VM_CR4_ALWAYS_ON (X86_CR4_VME | X86_CR4_PAE | X86_CR4_VMXE)
 
+#define RMODE_GUEST_OWNED_EFLAGS_BITS (~(X86_EFLAGS_IOPL | X86_EFLAGS_VM))
+
 /*
  * These 2 parameters are used to config the controls for Pause-Loop Exiting:
  * ple_gap:    upper bound on the amount of time between two successive
@@ -130,7 +133,7 @@ struct vcpu_vmx {
        } host_state;
        struct {
                int vm86_active;
-               u8 save_iopl;
+               ulong save_rflags;
                struct kvm_save_segment {
                        u16 selector;
                        unsigned long base;
@@ -817,18 +820,23 @@ static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu)
 
 static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
 {
-       unsigned long rflags;
+       unsigned long rflags, save_rflags;
 
        rflags = vmcs_readl(GUEST_RFLAGS);
-       if (to_vmx(vcpu)->rmode.vm86_active)
-               rflags &= ~(unsigned long)(X86_EFLAGS_IOPL | X86_EFLAGS_VM);
+       if (to_vmx(vcpu)->rmode.vm86_active) {
+               rflags &= RMODE_GUEST_OWNED_EFLAGS_BITS;
+               save_rflags = to_vmx(vcpu)->rmode.save_rflags;
+               rflags |= save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS;
+       }
        return rflags;
 }
 
 static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
 {
-       if (to_vmx(vcpu)->rmode.vm86_active)
+       if (to_vmx(vcpu)->rmode.vm86_active) {
+               to_vmx(vcpu)->rmode.save_rflags = rflags;
                rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
+       }
        vmcs_writel(GUEST_RFLAGS, rflags);
 }
 
@@ -1482,8 +1490,8 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
        vmcs_write32(GUEST_TR_AR_BYTES, vmx->rmode.tr.ar);
 
        flags = vmcs_readl(GUEST_RFLAGS);
-       flags &= ~(X86_EFLAGS_IOPL | X86_EFLAGS_VM);
-       flags |= (vmx->rmode.save_iopl << IOPL_SHIFT);
+       flags &= RMODE_GUEST_OWNED_EFLAGS_BITS;
+       flags |= vmx->rmode.save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS;
        vmcs_writel(GUEST_RFLAGS, flags);
 
        vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) |
@@ -1556,8 +1564,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
        vmcs_write32(GUEST_TR_AR_BYTES, 0x008b);
 
        flags = vmcs_readl(GUEST_RFLAGS);
-       vmx->rmode.save_iopl
-               = (flags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
+       vmx->rmode.save_rflags = flags;
 
        flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
 
@@ -2696,8 +2703,7 @@ static int vmx_nmi_allowed(struct kvm_vcpu *vcpu)
                return 0;
 
        return  !(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
-                       (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS |
-                               GUEST_INTR_STATE_NMI));
+                       (GUEST_INTR_STATE_MOV_SS | GUEST_INTR_STATE_NMI));
 }
 
 static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu)
@@ -3653,8 +3659,11 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
 
        /* We need to handle NMIs before interrupts are enabled */
        if ((exit_intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR &&
-           (exit_intr_info & INTR_INFO_VALID_MASK))
+           (exit_intr_info & INTR_INFO_VALID_MASK)) {
+               kvm_before_handle_nmi(&vmx->vcpu);
                asm("int $2");
+               kvm_after_handle_nmi(&vmx->vcpu);
+       }
 
        idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK;
 
index e46282a565658bdcc3ed2bae40677948cfcb3bf9..dd9bc8fb81abddc4dc633dbc20392d1b5fcf14eb 100644 (file)
@@ -39,6 +39,8 @@
 #include <linux/cpufreq.h>
 #include <linux/user-return-notifier.h>
 #include <linux/srcu.h>
+#include <linux/slab.h>
+#include <linux/perf_event.h>
 #include <trace/events/kvm.h>
 #undef TRACE_INCLUDE_FILE
 #define CREATE_TRACE_POINTS
@@ -432,8 +434,6 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 
 #ifdef CONFIG_X86_64
        if (cr0 & 0xffffffff00000000UL) {
-               printk(KERN_DEBUG "set_cr0: 0x%lx #GP, reserved bits 0x%lx\n",
-                      cr0, kvm_read_cr0(vcpu));
                kvm_inject_gp(vcpu, 0);
                return;
        }
@@ -442,14 +442,11 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
        cr0 &= ~CR0_RESERVED_BITS;
 
        if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) {
-               printk(KERN_DEBUG "set_cr0: #GP, CD == 0 && NW == 1\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
 
        if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE)) {
-               printk(KERN_DEBUG "set_cr0: #GP, set PG flag "
-                      "and a clear PE flag\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
@@ -460,15 +457,11 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
                        int cs_db, cs_l;
 
                        if (!is_pae(vcpu)) {
-                               printk(KERN_DEBUG "set_cr0: #GP, start paging "
-                                      "in long mode while PAE is disabled\n");
                                kvm_inject_gp(vcpu, 0);
                                return;
                        }
                        kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
                        if (cs_l) {
-                               printk(KERN_DEBUG "set_cr0: #GP, start paging "
-                                      "in long mode while CS.L == 1\n");
                                kvm_inject_gp(vcpu, 0);
                                return;
 
@@ -476,8 +469,6 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
                } else
 #endif
                if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->arch.cr3)) {
-                       printk(KERN_DEBUG "set_cr0: #GP, pdptrs "
-                              "reserved bits\n");
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
@@ -504,28 +495,23 @@ void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
        unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE;
 
        if (cr4 & CR4_RESERVED_BITS) {
-               printk(KERN_DEBUG "set_cr4: #GP, reserved bits\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
 
        if (is_long_mode(vcpu)) {
                if (!(cr4 & X86_CR4_PAE)) {
-                       printk(KERN_DEBUG "set_cr4: #GP, clearing PAE while "
-                              "in long mode\n");
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
        } else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE)
                   && ((cr4 ^ old_cr4) & pdptr_bits)
                   && !load_pdptrs(vcpu, vcpu->arch.cr3)) {
-               printk(KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
 
        if (cr4 & X86_CR4_VMXE) {
-               printk(KERN_DEBUG "set_cr4: #GP, setting VMXE\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
@@ -546,21 +532,16 @@ void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
 
        if (is_long_mode(vcpu)) {
                if (cr3 & CR3_L_MODE_RESERVED_BITS) {
-                       printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n");
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
        } else {
                if (is_pae(vcpu)) {
                        if (cr3 & CR3_PAE_RESERVED_BITS) {
-                               printk(KERN_DEBUG
-                                      "set_cr3: #GP, reserved bits\n");
                                kvm_inject_gp(vcpu, 0);
                                return;
                        }
                        if (is_paging(vcpu) && !load_pdptrs(vcpu, cr3)) {
-                               printk(KERN_DEBUG "set_cr3: #GP, pdptrs "
-                                      "reserved bits\n");
                                kvm_inject_gp(vcpu, 0);
                                return;
                        }
@@ -592,7 +573,6 @@ EXPORT_SYMBOL_GPL(kvm_set_cr3);
 void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
 {
        if (cr8 & CR8_RESERVED_BITS) {
-               printk(KERN_DEBUG "set_cr8: #GP, reserved bits 0x%lx\n", cr8);
                kvm_inject_gp(vcpu, 0);
                return;
        }
@@ -648,15 +628,12 @@ static u32 emulated_msrs[] = {
 static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
 {
        if (efer & efer_reserved_bits) {
-               printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n",
-                      efer);
                kvm_inject_gp(vcpu, 0);
                return;
        }
 
        if (is_paging(vcpu)
            && (vcpu->arch.efer & EFER_LME) != (efer & EFER_LME)) {
-               printk(KERN_DEBUG "set_efer: #GP, change LME while paging\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
@@ -666,7 +643,6 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
 
                feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
                if (!feat || !(feat->edx & bit(X86_FEATURE_FXSR_OPT))) {
-                       printk(KERN_DEBUG "set_efer: #GP, enable FFXSR w/o CPUID capability\n");
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
@@ -677,7 +653,6 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
 
                feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
                if (!feat || !(feat->ecx & bit(X86_FEATURE_SVM))) {
-                       printk(KERN_DEBUG "set_efer: #GP, enable SVM w/o SVM\n");
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
@@ -966,9 +941,13 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data)
                if (msr >= MSR_IA32_MC0_CTL &&
                    msr < MSR_IA32_MC0_CTL + 4 * bank_num) {
                        u32 offset = msr - MSR_IA32_MC0_CTL;
-                       /* only 0 or all 1s can be written to IA32_MCi_CTL */
+                       /* only 0 or all 1s can be written to IA32_MCi_CTL
+                        * some Linux kernels though clear bit 10 in bank 4 to
+                        * workaround a BIOS/GART TBL issue on AMD K8s, ignore
+                        * this to avoid an uncatched #GP in the guest
+                        */
                        if ((offset & 0x3) == 0 &&
-                           data != 0 && data != ~(u64)0)
+                           data != 0 && (data | (1 << 10)) != ~(u64)0)
                                return -1;
                        vcpu->arch.mce_banks[offset] = data;
                        break;
@@ -1734,6 +1713,7 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
        if (copy_from_user(cpuid_entries, entries,
                           cpuid->nent * sizeof(struct kvm_cpuid_entry)))
                goto out_free;
+       vcpu_load(vcpu);
        for (i = 0; i < cpuid->nent; i++) {
                vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function;
                vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax;
@@ -1751,6 +1731,7 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
        r = 0;
        kvm_apic_set_version(vcpu);
        kvm_x86_ops->cpuid_update(vcpu);
+       vcpu_put(vcpu);
 
 out_free:
        vfree(cpuid_entries);
@@ -1771,9 +1752,11 @@ static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
        if (copy_from_user(&vcpu->arch.cpuid_entries, entries,
                           cpuid->nent * sizeof(struct kvm_cpuid_entry2)))
                goto out;
+       vcpu_load(vcpu);
        vcpu->arch.cpuid_nent = cpuid->nent;
        kvm_apic_set_version(vcpu);
        kvm_x86_ops->cpuid_update(vcpu);
+       vcpu_put(vcpu);
        return 0;
 
 out:
@@ -2634,8 +2617,9 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
                                      struct kvm_dirty_log *log)
 {
-       int r, n, i;
+       int r, i;
        struct kvm_memory_slot *memslot;
+       unsigned long n;
        unsigned long is_dirty = 0;
        unsigned long *dirty_bitmap = NULL;
 
@@ -2650,7 +2634,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
        if (!memslot->dirty_bitmap)
                goto out;
 
-       n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+       n = kvm_dirty_bitmap_bytes(memslot);
 
        r = -ENOMEM;
        dirty_bitmap = vmalloc(n);
@@ -3764,6 +3748,51 @@ static void kvm_timer_init(void)
        }
 }
 
+static DEFINE_PER_CPU(struct kvm_vcpu *, current_vcpu);
+
+static int kvm_is_in_guest(void)
+{
+       return percpu_read(current_vcpu) != NULL;
+}
+
+static int kvm_is_user_mode(void)
+{
+       int user_mode = 3;
+
+       if (percpu_read(current_vcpu))
+               user_mode = kvm_x86_ops->get_cpl(percpu_read(current_vcpu));
+
+       return user_mode != 0;
+}
+
+static unsigned long kvm_get_guest_ip(void)
+{
+       unsigned long ip = 0;
+
+       if (percpu_read(current_vcpu))
+               ip = kvm_rip_read(percpu_read(current_vcpu));
+
+       return ip;
+}
+
+static struct perf_guest_info_callbacks kvm_guest_cbs = {
+       .is_in_guest            = kvm_is_in_guest,
+       .is_user_mode           = kvm_is_user_mode,
+       .get_guest_ip           = kvm_get_guest_ip,
+};
+
+void kvm_before_handle_nmi(struct kvm_vcpu *vcpu)
+{
+       percpu_write(current_vcpu, vcpu);
+}
+EXPORT_SYMBOL_GPL(kvm_before_handle_nmi);
+
+void kvm_after_handle_nmi(struct kvm_vcpu *vcpu)
+{
+       percpu_write(current_vcpu, NULL);
+}
+EXPORT_SYMBOL_GPL(kvm_after_handle_nmi);
+
 int kvm_arch_init(void *opaque)
 {
        int r;
@@ -3800,6 +3829,8 @@ int kvm_arch_init(void *opaque)
 
        kvm_timer_init();
 
+       perf_register_guest_info_callbacks(&kvm_guest_cbs);
+
        return 0;
 
 out:
@@ -3808,6 +3839,8 @@ out:
 
 void kvm_arch_exit(void)
 {
+       perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
+
        if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
                cpufreq_unregister_notifier(&kvmclock_cpufreq_notifier_block,
                                            CPUFREQ_TRANSITION_NOTIFIER);
@@ -4482,7 +4515,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
                kvm_set_cr8(vcpu, kvm_run->cr8);
 
        if (vcpu->arch.pio.cur_count) {
+               vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
                r = complete_pio(vcpu);
+               srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
                if (r)
                        goto out;
        }
@@ -5145,6 +5180,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
        int ret = 0;
        u32 old_tss_base = get_segment_base(vcpu, VCPU_SREG_TR);
        u16 old_tss_sel = get_segment_selector(vcpu, VCPU_SREG_TR);
+       u32 desc_limit;
 
        old_tss_base = kvm_mmu_gva_to_gpa_write(vcpu, old_tss_base, NULL);
 
@@ -5167,7 +5203,10 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
                }
        }
 
-       if (!nseg_desc.p || get_desc_limit(&nseg_desc) < 0x67) {
+       desc_limit = get_desc_limit(&nseg_desc);
+       if (!nseg_desc.p ||
+           ((desc_limit < 0x67 && (nseg_desc.type & 8)) ||
+            desc_limit < 0x2b)) {
                kvm_queue_exception_e(vcpu, TS_VECTOR, tss_selector & 0xfffc);
                return 1;
        }
index 2d101639bd8d776bf6f97252a3120a0cfa7730d7..b7a404722d2b791efa2a9ae12d636ec2e5fd0a83 100644 (file)
@@ -65,4 +65,7 @@ static inline int is_paging(struct kvm_vcpu *vcpu)
        return kvm_read_cr0_bits(vcpu, X86_CR0_PG);
 }
 
+void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
+void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
+
 #endif
index 7e59dc1d3fc2f6fcba984f1d729c65fb59f44b35..2bdf628066bd85288bf8143d50175d4f7ea6b398 100644 (file)
@@ -115,7 +115,7 @@ static void async_hcall(unsigned long call, unsigned long arg1,
        local_irq_save(flags);
        if (lguest_data.hcall_status[next_call] != 0xFF) {
                /* Table full, so do normal hcall which will flush table. */
-               kvm_hypercall4(call, arg1, arg2, arg3, arg4);
+               hcall(call, arg1, arg2, arg3, arg4);
        } else {
                lguest_data.hcalls[next_call].arg0 = call;
                lguest_data.hcalls[next_call].arg1 = arg1;
@@ -145,46 +145,45 @@ static void async_hcall(unsigned long call, unsigned long arg1,
  * So, when we're in lazy mode, we call async_hcall() to store the call for
  * future processing:
  */
-static void lazy_hcall1(unsigned long call,
-                      unsigned long arg1)
+static void lazy_hcall1(unsigned long call, unsigned long arg1)
 {
        if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-               kvm_hypercall1(call, arg1);
+               hcall(call, arg1, 0, 0, 0);
        else
                async_hcall(call, arg1, 0, 0, 0);
 }
 
 /* You can imagine what lazy_hcall2, 3 and 4 look like. :*/
 static void lazy_hcall2(unsigned long call,
-                      unsigned long arg1,
-                      unsigned long arg2)
+                       unsigned long arg1,
+                       unsigned long arg2)
 {
        if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-               kvm_hypercall2(call, arg1, arg2);
+               hcall(call, arg1, arg2, 0, 0);
        else
                async_hcall(call, arg1, arg2, 0, 0);
 }
 
 static void lazy_hcall3(unsigned long call,
-                      unsigned long arg1,
-                      unsigned long arg2,
-                      unsigned long arg3)
+                       unsigned long arg1,
+                       unsigned long arg2,
+                       unsigned long arg3)
 {
        if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-               kvm_hypercall3(call, arg1, arg2, arg3);
+               hcall(call, arg1, arg2, arg3, 0);
        else
                async_hcall(call, arg1, arg2, arg3, 0);
 }
 
 #ifdef CONFIG_X86_PAE
 static void lazy_hcall4(unsigned long call,
-                      unsigned long arg1,
-                      unsigned long arg2,
-                      unsigned long arg3,
-                      unsigned long arg4)
+                       unsigned long arg1,
+                       unsigned long arg2,
+                       unsigned long arg3,
+                       unsigned long arg4)
 {
        if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-               kvm_hypercall4(call, arg1, arg2, arg3, arg4);
+               hcall(call, arg1, arg2, arg3, arg4);
        else
                async_hcall(call, arg1, arg2, arg3, arg4);
 }
@@ -196,13 +195,13 @@ static void lazy_hcall4(unsigned long call,
 :*/
 static void lguest_leave_lazy_mmu_mode(void)
 {
-       kvm_hypercall0(LHCALL_FLUSH_ASYNC);
+       hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0);
        paravirt_leave_lazy_mmu();
 }
 
 static void lguest_end_context_switch(struct task_struct *next)
 {
-       kvm_hypercall0(LHCALL_FLUSH_ASYNC);
+       hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0);
        paravirt_end_context_switch(next);
 }
 
@@ -286,7 +285,7 @@ static void lguest_write_idt_entry(gate_desc *dt,
        /* Keep the local copy up to date. */
        native_write_idt_entry(dt, entrynum, g);
        /* Tell Host about this new entry. */
-       kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]);
+       hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1], 0);
 }
 
 /*
@@ -300,7 +299,7 @@ static void lguest_load_idt(const struct desc_ptr *desc)
        struct desc_struct *idt = (void *)desc->address;
 
        for (i = 0; i < (desc->size+1)/8; i++)
-               kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b);
+               hcall(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b, 0);
 }
 
 /*
@@ -321,7 +320,7 @@ static void lguest_load_gdt(const struct desc_ptr *desc)
        struct desc_struct *gdt = (void *)desc->address;
 
        for (i = 0; i < (desc->size+1)/8; i++)
-               kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b);
+               hcall(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b, 0);
 }
 
 /*
@@ -334,8 +333,8 @@ static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum,
 {
        native_write_gdt_entry(dt, entrynum, desc, type);
        /* Tell Host about this new entry. */
-       kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, entrynum,
-                      dt[entrynum].a, dt[entrynum].b);
+       hcall(LHCALL_LOAD_GDT_ENTRY, entrynum,
+             dt[entrynum].a, dt[entrynum].b, 0);
 }
 
 /*
@@ -931,7 +930,7 @@ static int lguest_clockevent_set_next_event(unsigned long delta,
        }
 
        /* Please wake us this far in the future. */
-       kvm_hypercall1(LHCALL_SET_CLOCKEVENT, delta);
+       hcall(LHCALL_SET_CLOCKEVENT, delta, 0, 0, 0);
        return 0;
 }
 
@@ -942,7 +941,7 @@ static void lguest_clockevent_set_mode(enum clock_event_mode mode,
        case CLOCK_EVT_MODE_UNUSED:
        case CLOCK_EVT_MODE_SHUTDOWN:
                /* A 0 argument shuts the clock down. */
-               kvm_hypercall0(LHCALL_SET_CLOCKEVENT);
+               hcall(LHCALL_SET_CLOCKEVENT, 0, 0, 0, 0);
                break;
        case CLOCK_EVT_MODE_ONESHOT:
                /* This is what we expect. */
@@ -1100,7 +1099,7 @@ static void set_lguest_basic_apic_ops(void)
 /* STOP!  Until an interrupt comes in. */
 static void lguest_safe_halt(void)
 {
-       kvm_hypercall0(LHCALL_HALT);
+       hcall(LHCALL_HALT, 0, 0, 0, 0);
 }
 
 /*
@@ -1112,8 +1111,8 @@ static void lguest_safe_halt(void)
  */
 static void lguest_power_off(void)
 {
-       kvm_hypercall2(LHCALL_SHUTDOWN, __pa("Power down"),
-                                       LGUEST_SHUTDOWN_POWEROFF);
+       hcall(LHCALL_SHUTDOWN, __pa("Power down"),
+             LGUEST_SHUTDOWN_POWEROFF, 0, 0);
 }
 
 /*
@@ -1123,7 +1122,7 @@ static void lguest_power_off(void)
  */
 static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p)
 {
-       kvm_hypercall2(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF);
+       hcall(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF, 0, 0);
        /* The hcall won't return, but to keep gcc happy, we're "done". */
        return NOTIFY_DONE;
 }
@@ -1162,7 +1161,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count)
                len = sizeof(scratch) - 1;
        scratch[len] = '\0';
        memcpy(scratch, buf, len);
-       kvm_hypercall1(LHCALL_NOTIFY, __pa(scratch));
+       hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0, 0);
 
        /* This routine returns the number of bytes actually written. */
        return len;
@@ -1174,7 +1173,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count)
  */
 static void lguest_restart(char *reason)
 {
-       kvm_hypercall2(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART);
+       hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0, 0);
 }
 
 /*G:050
index 27eac0faee48eca0838970b2b1e7c64fb1a2c121..4f420c2f2d5534ea4ac5af20292e25c4346c3cda 100644 (file)
@@ -32,7 +32,7 @@ ENTRY(lguest_entry)
         */
        movl $LHCALL_LGUEST_INIT, %eax
        movl $lguest_data - __PAGE_OFFSET, %ebx
-       .byte 0x0f,0x01,0xc1 /* KVM_HYPERCALL */
+       int $LGUEST_TRAP_ENTRY
 
        /* Set up the initial stack so we can run C code. */
        movl $(init_thread_union+THREAD_SIZE),%esp
index 419386c24b8205c3a22c993b3da48f448bf96283..f871e04b6965b828045b08d183dadd0c2aaa487f 100644 (file)
@@ -20,17 +20,18 @@ lib-y := delay.o
 lib-y += thunk_$(BITS).o
 lib-y += usercopy_$(BITS).o getuser.o putuser.o
 lib-y += memcpy_$(BITS).o
-lib-$(CONFIG_KPROBES) += insn.o inat.o
+lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o
 
 obj-y += msr.o msr-reg.o msr-reg-export.o
 
 ifeq ($(CONFIG_X86_32),y)
         obj-y += atomic64_32.o
+        lib-y += atomic64_cx8_32.o
         lib-y += checksum_32.o
         lib-y += strstr_32.o
         lib-y += semaphore_32.o string_32.o
 ifneq ($(CONFIG_X86_CMPXCHG64),y)
-        lib-y += cmpxchg8b_emu.o
+        lib-y += cmpxchg8b_emu.o atomic64_386_32.o
 endif
         lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o
 else
index 824fa0be55a39f295d200dd5e130647c11c4a9f3..540179e8e9fa9c8d58aeb724a354a5f9dec74f12 100644 (file)
 #include <asm/cmpxchg.h>
 #include <asm/atomic.h>
 
-static noinline u64 cmpxchg8b(u64 *ptr, u64 old, u64 new)
-{
-       u32 low = new;
-       u32 high = new >> 32;
-
-       asm volatile(
-               LOCK_PREFIX "cmpxchg8b %1\n"
-                    : "+A" (old), "+m" (*ptr)
-                    :  "b" (low),  "c" (high)
-                    );
-       return old;
-}
-
-u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val)
-{
-       return cmpxchg8b(&ptr->counter, old_val, new_val);
-}
-EXPORT_SYMBOL(atomic64_cmpxchg);
-
-/**
- * atomic64_xchg - xchg atomic64 variable
- * @ptr:      pointer to type atomic64_t
- * @new_val:  value to assign
- *
- * Atomically xchgs the value of @ptr to @new_val and returns
- * the old value.
- */
-u64 atomic64_xchg(atomic64_t *ptr, u64 new_val)
-{
-       /*
-        * Try first with a (possibly incorrect) assumption about
-        * what we have there. We'll do two loops most likely,
-        * but we'll get an ownership MESI transaction straight away
-        * instead of a read transaction followed by a
-        * flush-for-ownership transaction:
-        */
-       u64 old_val, real_val = 0;
-
-       do {
-               old_val = real_val;
-
-               real_val = atomic64_cmpxchg(ptr, old_val, new_val);
-
-       } while (real_val != old_val);
-
-       return old_val;
-}
-EXPORT_SYMBOL(atomic64_xchg);
-
-/**
- * atomic64_set - set atomic64 variable
- * @ptr:      pointer to type atomic64_t
- * @new_val:  value to assign
- *
- * Atomically sets the value of @ptr to @new_val.
- */
-void atomic64_set(atomic64_t *ptr, u64 new_val)
-{
-       atomic64_xchg(ptr, new_val);
-}
-EXPORT_SYMBOL(atomic64_set);
-
-/**
-EXPORT_SYMBOL(atomic64_read);
- * atomic64_add_return - add and return
- * @delta: integer value to add
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically adds @delta to @ptr and returns @delta + *@ptr
- */
-noinline u64 atomic64_add_return(u64 delta, atomic64_t *ptr)
-{
-       /*
-        * Try first with a (possibly incorrect) assumption about
-        * what we have there. We'll do two loops most likely,
-        * but we'll get an ownership MESI transaction straight away
-        * instead of a read transaction followed by a
-        * flush-for-ownership transaction:
-        */
-       u64 old_val, new_val, real_val = 0;
-
-       do {
-               old_val = real_val;
-               new_val = old_val + delta;
-
-               real_val = atomic64_cmpxchg(ptr, old_val, new_val);
-
-       } while (real_val != old_val);
-
-       return new_val;
-}
-EXPORT_SYMBOL(atomic64_add_return);
-
-u64 atomic64_sub_return(u64 delta, atomic64_t *ptr)
-{
-       return atomic64_add_return(-delta, ptr);
-}
-EXPORT_SYMBOL(atomic64_sub_return);
-
-u64 atomic64_inc_return(atomic64_t *ptr)
-{
-       return atomic64_add_return(1, ptr);
-}
-EXPORT_SYMBOL(atomic64_inc_return);
-
-u64 atomic64_dec_return(atomic64_t *ptr)
-{
-       return atomic64_sub_return(1, ptr);
-}
-EXPORT_SYMBOL(atomic64_dec_return);
-
-/**
- * atomic64_add - add integer to atomic64 variable
- * @delta: integer value to add
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically adds @delta to @ptr.
- */
-void atomic64_add(u64 delta, atomic64_t *ptr)
-{
-       atomic64_add_return(delta, ptr);
-}
-EXPORT_SYMBOL(atomic64_add);
-
-/**
- * atomic64_sub - subtract the atomic64 variable
- * @delta: integer value to subtract
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically subtracts @delta from @ptr.
- */
-void atomic64_sub(u64 delta, atomic64_t *ptr)
-{
-       atomic64_add(-delta, ptr);
-}
-EXPORT_SYMBOL(atomic64_sub);
-
-/**
- * atomic64_sub_and_test - subtract value from variable and test result
- * @delta: integer value to subtract
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically subtracts @delta from @ptr and returns
- * true if the result is zero, or false for all
- * other cases.
- */
-int atomic64_sub_and_test(u64 delta, atomic64_t *ptr)
-{
-       u64 new_val = atomic64_sub_return(delta, ptr);
-
-       return new_val == 0;
-}
-EXPORT_SYMBOL(atomic64_sub_and_test);
-
-/**
- * atomic64_inc - increment atomic64 variable
- * @ptr: pointer to type atomic64_t
- *
- * Atomically increments @ptr by 1.
- */
-void atomic64_inc(atomic64_t *ptr)
-{
-       atomic64_add(1, ptr);
-}
-EXPORT_SYMBOL(atomic64_inc);
-
-/**
- * atomic64_dec - decrement atomic64 variable
- * @ptr: pointer to type atomic64_t
- *
- * Atomically decrements @ptr by 1.
- */
-void atomic64_dec(atomic64_t *ptr)
-{
-       atomic64_sub(1, ptr);
-}
-EXPORT_SYMBOL(atomic64_dec);
-
-/**
- * atomic64_dec_and_test - decrement and test
- * @ptr: pointer to type atomic64_t
- *
- * Atomically decrements @ptr by 1 and
- * returns true if the result is 0, or false for all other
- * cases.
- */
-int atomic64_dec_and_test(atomic64_t *ptr)
-{
-       return atomic64_sub_and_test(1, ptr);
-}
-EXPORT_SYMBOL(atomic64_dec_and_test);
-
-/**
- * atomic64_inc_and_test - increment and test
- * @ptr: pointer to type atomic64_t
- *
- * Atomically increments @ptr by 1
- * and returns true if the result is zero, or false for all
- * other cases.
- */
-int atomic64_inc_and_test(atomic64_t *ptr)
-{
-       return atomic64_sub_and_test(-1, ptr);
-}
-EXPORT_SYMBOL(atomic64_inc_and_test);
-
-/**
- * atomic64_add_negative - add and test if negative
- * @delta: integer value to add
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically adds @delta to @ptr and returns true
- * if the result is negative, or false when
- * result is greater than or equal to zero.
- */
-int atomic64_add_negative(u64 delta, atomic64_t *ptr)
-{
-       s64 new_val = atomic64_add_return(delta, ptr);
-
-       return new_val < 0;
-}
-EXPORT_SYMBOL(atomic64_add_negative);
+long long atomic64_read_cx8(long long, const atomic64_t *v);
+EXPORT_SYMBOL(atomic64_read_cx8);
+long long atomic64_set_cx8(long long, const atomic64_t *v);
+EXPORT_SYMBOL(atomic64_set_cx8);
+long long atomic64_xchg_cx8(long long, unsigned high);
+EXPORT_SYMBOL(atomic64_xchg_cx8);
+long long atomic64_add_return_cx8(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_add_return_cx8);
+long long atomic64_sub_return_cx8(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_sub_return_cx8);
+long long atomic64_inc_return_cx8(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_inc_return_cx8);
+long long atomic64_dec_return_cx8(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_dec_return_cx8);
+long long atomic64_dec_if_positive_cx8(atomic64_t *v);
+EXPORT_SYMBOL(atomic64_dec_if_positive_cx8);
+int atomic64_inc_not_zero_cx8(atomic64_t *v);
+EXPORT_SYMBOL(atomic64_inc_not_zero_cx8);
+int atomic64_add_unless_cx8(atomic64_t *v, long long a, long long u);
+EXPORT_SYMBOL(atomic64_add_unless_cx8);
+
+#ifndef CONFIG_X86_CMPXCHG64
+long long atomic64_read_386(long long, const atomic64_t *v);
+EXPORT_SYMBOL(atomic64_read_386);
+long long atomic64_set_386(long long, const atomic64_t *v);
+EXPORT_SYMBOL(atomic64_set_386);
+long long atomic64_xchg_386(long long, unsigned high);
+EXPORT_SYMBOL(atomic64_xchg_386);
+long long atomic64_add_return_386(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_add_return_386);
+long long atomic64_sub_return_386(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_sub_return_386);
+long long atomic64_inc_return_386(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_inc_return_386);
+long long atomic64_dec_return_386(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_dec_return_386);
+long long atomic64_add_386(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_add_386);
+long long atomic64_sub_386(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_sub_386);
+long long atomic64_inc_386(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_inc_386);
+long long atomic64_dec_386(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_dec_386);
+long long atomic64_dec_if_positive_386(atomic64_t *v);
+EXPORT_SYMBOL(atomic64_dec_if_positive_386);
+int atomic64_inc_not_zero_386(atomic64_t *v);
+EXPORT_SYMBOL(atomic64_inc_not_zero_386);
+int atomic64_add_unless_386(atomic64_t *v, long long a, long long u);
+EXPORT_SYMBOL(atomic64_add_unless_386);
+#endif
diff --git a/arch/x86/lib/atomic64_386_32.S b/arch/x86/lib/atomic64_386_32.S
new file mode 100644 (file)
index 0000000..4a5979a
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * atomic64_t for 386/486
+ *
+ * Copyright Â© 2010  Luca Barbieri
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/linkage.h>
+#include <asm/alternative-asm.h>
+#include <asm/dwarf2.h>
+
+/* if you want SMP support, implement these with real spinlocks */
+.macro LOCK reg
+       pushfl
+       CFI_ADJUST_CFA_OFFSET 4
+       cli
+.endm
+
+.macro UNLOCK reg
+       popfl
+       CFI_ADJUST_CFA_OFFSET -4
+.endm
+
+.macro BEGIN func reg
+$v = \reg
+
+ENTRY(atomic64_\func\()_386)
+       CFI_STARTPROC
+       LOCK $v
+
+.macro RETURN
+       UNLOCK $v
+       ret
+.endm
+
+.macro END_
+       CFI_ENDPROC
+ENDPROC(atomic64_\func\()_386)
+.purgem RETURN
+.purgem END_
+.purgem END
+.endm
+
+.macro END
+RETURN
+END_
+.endm
+.endm
+
+BEGIN read %ecx
+       movl  ($v), %eax
+       movl 4($v), %edx
+END
+
+BEGIN set %esi
+       movl %ebx,  ($v)
+       movl %ecx, 4($v)
+END
+
+BEGIN xchg %esi
+       movl  ($v), %eax
+       movl 4($v), %edx
+       movl %ebx,  ($v)
+       movl %ecx, 4($v)
+END
+
+BEGIN add %ecx
+       addl %eax,  ($v)
+       adcl %edx, 4($v)
+END
+
+BEGIN add_return %ecx
+       addl  ($v), %eax
+       adcl 4($v), %edx
+       movl %eax,  ($v)
+       movl %edx, 4($v)
+END
+
+BEGIN sub %ecx
+       subl %eax,  ($v)
+       sbbl %edx, 4($v)
+END
+
+BEGIN sub_return %ecx
+       negl %edx
+       negl %eax
+       sbbl $0, %edx
+       addl  ($v), %eax
+       adcl 4($v), %edx
+       movl %eax,  ($v)
+       movl %edx, 4($v)
+END
+
+BEGIN inc %esi
+       addl $1,  ($v)
+       adcl $0, 4($v)
+END
+
+BEGIN inc_return %esi
+       movl  ($v), %eax
+       movl 4($v), %edx
+       addl $1, %eax
+       adcl $0, %edx
+       movl %eax,  ($v)
+       movl %edx, 4($v)
+END
+
+BEGIN dec %esi
+       subl $1,  ($v)
+       sbbl $0, 4($v)
+END
+
+BEGIN dec_return %esi
+       movl  ($v), %eax
+       movl 4($v), %edx
+       subl $1, %eax
+       sbbl $0, %edx
+       movl %eax,  ($v)
+       movl %edx, 4($v)
+END
+
+BEGIN add_unless %ecx
+       addl %eax, %esi
+       adcl %edx, %edi
+       addl  ($v), %eax
+       adcl 4($v), %edx
+       cmpl %eax, %esi
+       je 3f
+1:
+       movl %eax,  ($v)
+       movl %edx, 4($v)
+       movl $1, %eax
+2:
+RETURN
+3:
+       cmpl %edx, %edi
+       jne 1b
+       xorl %eax, %eax
+       jmp 2b
+END_
+
+BEGIN inc_not_zero %esi
+       movl  ($v), %eax
+       movl 4($v), %edx
+       testl %eax, %eax
+       je 3f
+1:
+       addl $1, %eax
+       adcl $0, %edx
+       movl %eax,  ($v)
+       movl %edx, 4($v)
+       movl $1, %eax
+2:
+RETURN
+3:
+       testl %edx, %edx
+       jne 1b
+       jmp 2b
+END_
+
+BEGIN dec_if_positive %esi
+       movl  ($v), %eax
+       movl 4($v), %edx
+       subl $1, %eax
+       sbbl $0, %edx
+       js 1f
+       movl %eax,  ($v)
+       movl %edx, 4($v)
+1:
+END
diff --git a/arch/x86/lib/atomic64_cx8_32.S b/arch/x86/lib/atomic64_cx8_32.S
new file mode 100644 (file)
index 0000000..71e080d
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * atomic64_t for 586+
+ *
+ * Copyright Â© 2010  Luca Barbieri
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/linkage.h>
+#include <asm/alternative-asm.h>
+#include <asm/dwarf2.h>
+
+.macro SAVE reg
+       pushl %\reg
+       CFI_ADJUST_CFA_OFFSET 4
+       CFI_REL_OFFSET \reg, 0
+.endm
+
+.macro RESTORE reg
+       popl %\reg
+       CFI_ADJUST_CFA_OFFSET -4
+       CFI_RESTORE \reg
+.endm
+
+.macro read64 reg
+       movl %ebx, %eax
+       movl %ecx, %edx
+/* we need LOCK_PREFIX since otherwise cmpxchg8b always does the write */
+       LOCK_PREFIX
+       cmpxchg8b (\reg)
+.endm
+
+ENTRY(atomic64_read_cx8)
+       CFI_STARTPROC
+
+       read64 %ecx
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_read_cx8)
+
+ENTRY(atomic64_set_cx8)
+       CFI_STARTPROC
+
+1:
+/* we don't need LOCK_PREFIX since aligned 64-bit writes
+ * are atomic on 586 and newer */
+       cmpxchg8b (%esi)
+       jne 1b
+
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_set_cx8)
+
+ENTRY(atomic64_xchg_cx8)
+       CFI_STARTPROC
+
+       movl %ebx, %eax
+       movl %ecx, %edx
+1:
+       LOCK_PREFIX
+       cmpxchg8b (%esi)
+       jne 1b
+
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_xchg_cx8)
+
+.macro addsub_return func ins insc
+ENTRY(atomic64_\func\()_return_cx8)
+       CFI_STARTPROC
+       SAVE ebp
+       SAVE ebx
+       SAVE esi
+       SAVE edi
+
+       movl %eax, %esi
+       movl %edx, %edi
+       movl %ecx, %ebp
+
+       read64 %ebp
+1:
+       movl %eax, %ebx
+       movl %edx, %ecx
+       \ins\()l %esi, %ebx
+       \insc\()l %edi, %ecx
+       LOCK_PREFIX
+       cmpxchg8b (%ebp)
+       jne 1b
+
+10:
+       movl %ebx, %eax
+       movl %ecx, %edx
+       RESTORE edi
+       RESTORE esi
+       RESTORE ebx
+       RESTORE ebp
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_\func\()_return_cx8)
+.endm
+
+addsub_return add add adc
+addsub_return sub sub sbb
+
+.macro incdec_return func ins insc
+ENTRY(atomic64_\func\()_return_cx8)
+       CFI_STARTPROC
+       SAVE ebx
+
+       read64 %esi
+1:
+       movl %eax, %ebx
+       movl %edx, %ecx
+       \ins\()l $1, %ebx
+       \insc\()l $0, %ecx
+       LOCK_PREFIX
+       cmpxchg8b (%esi)
+       jne 1b
+
+10:
+       movl %ebx, %eax
+       movl %ecx, %edx
+       RESTORE ebx
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_\func\()_return_cx8)
+.endm
+
+incdec_return inc add adc
+incdec_return dec sub sbb
+
+ENTRY(atomic64_dec_if_positive_cx8)
+       CFI_STARTPROC
+       SAVE ebx
+
+       read64 %esi
+1:
+       movl %eax, %ebx
+       movl %edx, %ecx
+       subl $1, %ebx
+       sbb $0, %ecx
+       js 2f
+       LOCK_PREFIX
+       cmpxchg8b (%esi)
+       jne 1b
+
+2:
+       movl %ebx, %eax
+       movl %ecx, %edx
+       RESTORE ebx
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_dec_if_positive_cx8)
+
+ENTRY(atomic64_add_unless_cx8)
+       CFI_STARTPROC
+       SAVE ebp
+       SAVE ebx
+/* these just push these two parameters on the stack */
+       SAVE edi
+       SAVE esi
+
+       movl %ecx, %ebp
+       movl %eax, %esi
+       movl %edx, %edi
+
+       read64 %ebp
+1:
+       cmpl %eax, 0(%esp)
+       je 4f
+2:
+       movl %eax, %ebx
+       movl %edx, %ecx
+       addl %esi, %ebx
+       adcl %edi, %ecx
+       LOCK_PREFIX
+       cmpxchg8b (%ebp)
+       jne 1b
+
+       movl $1, %eax
+3:
+       addl $8, %esp
+       CFI_ADJUST_CFA_OFFSET -8
+       RESTORE ebx
+       RESTORE ebp
+       ret
+4:
+       cmpl %edx, 4(%esp)
+       jne 2b
+       xorl %eax, %eax
+       jmp 3b
+       CFI_ENDPROC
+ENDPROC(atomic64_add_unless_cx8)
+
+ENTRY(atomic64_inc_not_zero_cx8)
+       CFI_STARTPROC
+       SAVE ebx
+
+       read64 %esi
+1:
+       testl %eax, %eax
+       je 4f
+2:
+       movl %eax, %ebx
+       movl %edx, %ecx
+       addl $1, %ebx
+       adcl $0, %ecx
+       LOCK_PREFIX
+       cmpxchg8b (%esi)
+       jne 1b
+
+       movl $1, %eax
+3:
+       RESTORE ebx
+       ret
+4:
+       testl %edx, %edx
+       jne 2b
+       jmp 3b
+       CFI_ENDPROC
+ENDPROC(atomic64_inc_not_zero_cx8)
index 15acecf0d7aa0c4768493d79dedfdf518a647707..41fcf00e49dfc7ca9549ce5e4dd26f360ee81353 100644 (file)
@@ -60,7 +60,7 @@ ENTRY(call_rwsem_down_write_failed)
        ENDPROC(call_rwsem_down_write_failed)
 
 ENTRY(call_rwsem_wake)
-       decw %dx    /* do nothing if still outstanding active readers */
+       decl %edx       /* do nothing if still outstanding active readers */
        jnz 1f
        save_common_regs
        movq %rax,%rdi
index aa0987088774613ccc36ece2c33ee35e9f382866..dc8adad10a2f3881cdbca82b9a624dc17b88c4f8 100644 (file)
@@ -30,10 +30,10 @@ static void fclex(void)
 }
 
 /* Needs to be externally visible */
-void finit_task(struct task_struct *tsk)
+void finit_soft_fpu(struct i387_soft_struct *soft)
 {
-       struct i387_soft_struct *soft = &tsk->thread.xstate->soft;
        struct address *oaddr, *iaddr;
+       memset(soft, 0, sizeof(*soft));
        soft->cwd = 0x037f;
        soft->swd = 0;
        soft->ftop = 0; /* We don't keep top in the status word internally. */
@@ -52,7 +52,7 @@ void finit_task(struct task_struct *tsk)
 
 void finit(void)
 {
-       finit_task(current);
+       finit_soft_fpu(&current->thread.fpu.state->soft);
 }
 
 /*
index 5d87f586f8d7242cc48c41265a90ab67069a7800..7718541541d4ba1143c05f0d2d099686a3d784ff 100644 (file)
@@ -681,7 +681,7 @@ int fpregs_soft_set(struct task_struct *target,
                    unsigned int pos, unsigned int count,
                    const void *kbuf, const void __user *ubuf)
 {
-       struct i387_soft_struct *s387 = &target->thread.xstate->soft;
+       struct i387_soft_struct *s387 = &target->thread.fpu.state->soft;
        void *space = s387->st_space;
        int ret;
        int offset, other, i, tags, regnr, tag, newtop;
@@ -733,7 +733,7 @@ int fpregs_soft_get(struct task_struct *target,
                    unsigned int pos, unsigned int count,
                    void *kbuf, void __user *ubuf)
 {
-       struct i387_soft_struct *s387 = &target->thread.xstate->soft;
+       struct i387_soft_struct *s387 = &target->thread.fpu.state->soft;
        const void *space = s387->st_space;
        int ret;
        int offset = (S387->ftop & 7) * 10, other = 80 - offset;
index 50fa0ec2c8a5f87a463a14164cf365291627a532..2c614410a5f3978d646f87d2814edaf2ec383396 100644 (file)
@@ -31,7 +31,7 @@
 #define SEG_EXPAND_DOWN(s)     (((s).b & ((1 << 11) | (1 << 10))) \
                                 == (1 << 10))
 
-#define I387                   (current->thread.xstate)
+#define I387                   (current->thread.fpu.state)
 #define FPU_info               (I387->soft.info)
 
 #define FPU_CS                 (*(unsigned short *) &(FPU_info->regs->cs))
index 06630d26e56d1e01823901f525385eb002531bf6..a4c768397baae6054f5938fc4170fb0876ccdb80 100644 (file)
@@ -6,6 +6,7 @@ nostackp := $(call cc-option, -fno-stack-protector)
 CFLAGS_physaddr.o              := $(nostackp)
 CFLAGS_setup_nx.o              := $(nostackp)
 
+obj-$(CONFIG_X86_PAT)          += pat_rbtree.o
 obj-$(CONFIG_SMP)              += tlb.o
 
 obj-$(CONFIG_X86_32)           += pgtable_32.o iomap_32.o
index f46c340727b8be21fb8270618ff9d03962667409..069ce7c37c016f0b34fc017fd005babc08d0ef53 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
 #include <linux/pagemap.h>
-#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/sysctl.h>
 #include <asm/mman.h>
index e71c5cbc8f3561f6ce701582377749155af587b8..b278535b14aa00ce5b46de5e5bdd01cc75dc0c8a 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/gfp.h>
 #include <linux/initrd.h>
 #include <linux/ioport.h>
 #include <linux/swap.h>
@@ -331,11 +332,23 @@ int devmem_is_allowed(unsigned long pagenr)
 
 void free_init_pages(char *what, unsigned long begin, unsigned long end)
 {
-       unsigned long addr = begin;
+       unsigned long addr;
+       unsigned long begin_aligned, end_aligned;
 
-       if (addr >= end)
+       /* Make sure boundaries are page aligned */
+       begin_aligned = PAGE_ALIGN(begin);
+       end_aligned   = end & PAGE_MASK;
+
+       if (WARN_ON(begin_aligned != begin || end_aligned != end)) {
+               begin = begin_aligned;
+               end   = end_aligned;
+       }
+
+       if (begin >= end)
                return;
 
+       addr = begin;
+
        /*
         * If debugging page accesses then do not free this memory but
         * mark them not present - any buggy init-section access will
@@ -343,7 +356,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
         */
 #ifdef CONFIG_DEBUG_PAGEALLOC
        printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
-               begin, PAGE_ALIGN(end));
+               begin, end);
        set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
 #else
        /*
@@ -358,8 +371,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
        for (; addr < end; addr += PAGE_SIZE) {
                ClearPageReserved(virt_to_page(addr));
                init_page_count(virt_to_page(addr));
-               memset((void *)(addr & ~(PAGE_SIZE-1)),
-                       POISON_FREE_INITMEM, PAGE_SIZE);
+               memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
                free_page(addr);
                totalram_pages++;
        }
@@ -376,6 +388,15 @@ void free_initmem(void)
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-       free_init_pages("initrd memory", start, end);
+       /*
+        * end could be not aligned, and We can not align that,
+        * decompresser could be confused by aligned initrd_end
+        * We already reserve the end partial page before in
+        *   - i386_start_kernel()
+        *   - x86_64_start_kernel()
+        *   - relocate_initrd()
+        * So here We can do PAGE_ALIGN() safely to get partial page to be freed
+        */
+       free_init_pages("initrd memory", start, PAGE_ALIGN(end));
 }
 #endif
index 5cb3f0f54f47070c3f9268af39c9f5dcb0e08f57..bca79091b9d6158bcab97bdba2d8b767babeea46 100644 (file)
 #include <linux/pfn.h>
 #include <linux/poison.h>
 #include <linux/bootmem.h>
-#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/memory_hotplug.h>
 #include <linux/initrd.h>
 #include <linux/cpumask.h>
+#include <linux/gfp.h>
 
 #include <asm/asm.h>
 #include <asm/bios_ebda.h>
index e9b040e1cde5cb2ee1ad926845e2cc0e4b1f1907..ee41bba315d1897a5d30602a830d944f94f42fc7 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/memory_hotplug.h>
 #include <linux/nmi.h>
+#include <linux/gfp.h>
 
 #include <asm/processor.h>
 #include <asm/bios_ebda.h>
index 5eb1ba74a3a933e9c82f18773395a57c0954a3ed..12e4d2d3c1105e24990808cd898897bdefebb403 100644 (file)
@@ -448,6 +448,20 @@ static inline void __init early_clear_fixmap(enum fixed_addresses idx)
 static void __iomem *prev_map[FIX_BTMAPS_SLOTS] __initdata;
 static unsigned long prev_size[FIX_BTMAPS_SLOTS] __initdata;
 
+void __init fixup_early_ioremap(void)
+{
+       int i;
+
+       for (i = 0; i < FIX_BTMAPS_SLOTS; i++) {
+               if (prev_map[i]) {
+                       WARN_ON(1);
+                       break;
+               }
+       }
+
+       early_ioremap_init();
+}
+
 static int __init check_early_ioremap_leak(void)
 {
        int count = 0;
index 536fb682336601bce1cd428faac9cc0b1ed1a20b..5d0e67fff1a655454145c945ffe65a87ec7331a9 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/kdebug.h>
 #include <linux/mutex.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 #include <linux/errno.h>
index 34a3291ca1038969be2657ce8cc7e49fd64a4381..3adff7dcc148585339565e9d358fe315e0de818a 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/module.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/version.h>
index cf07c26d9a4a59b9637a7b5389ffe33efbf5a701..28195c350b97e9470c499bea879c0839ff56d339 100644 (file)
@@ -6,13 +6,13 @@
 #include <linux/bootmem.h>
 #include <linux/module.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
 #include <linux/pfn.h>
 #include <linux/percpu.h>
+#include <linux/gfp.h>
 
 #include <asm/e820.h>
 #include <asm/processor.h>
index ae9648eb1c7f44b919cf93ef7d8f008714409f4e..bbe5502ee1cbdaa7eaf5d9de15454b143b67b626 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/debugfs.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/gfp.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/fs.h>
 #include <linux/rbtree.h>
@@ -30,6 +30,8 @@
 #include <asm/pat.h>
 #include <asm/io.h>
 
+#include "pat_internal.h"
+
 #ifdef CONFIG_X86_PAT
 int __read_mostly pat_enabled = 1;
 
@@ -53,19 +55,15 @@ static inline void pat_disable(const char *reason)
 #endif
 
 
-static int debug_enable;
+int pat_debug_enable;
 
 static int __init pat_debug_setup(char *str)
 {
-       debug_enable = 1;
+       pat_debug_enable = 1;
        return 0;
 }
 __setup("debugpat", pat_debug_setup);
 
-#define dprintk(fmt, arg...) \
-       do { if (debug_enable) printk(KERN_INFO fmt, ##arg); } while (0)
-
-
 static u64 __read_mostly boot_pat_state;
 
 enum {
@@ -132,84 +130,7 @@ void pat_init(void)
 
 #undef PAT
 
-static char *cattr_name(unsigned long flags)
-{
-       switch (flags & _PAGE_CACHE_MASK) {
-       case _PAGE_CACHE_UC:            return "uncached";
-       case _PAGE_CACHE_UC_MINUS:      return "uncached-minus";
-       case _PAGE_CACHE_WB:            return "write-back";
-       case _PAGE_CACHE_WC:            return "write-combining";
-       default:                        return "broken";
-       }
-}
-
-/*
- * The global memtype list keeps track of memory type for specific
- * physical memory areas. Conflicting memory types in different
- * mappings can cause CPU cache corruption. To avoid this we keep track.
- *
- * The list is sorted based on starting address and can contain multiple
- * entries for each address (this allows reference counting for overlapping
- * areas). All the aliases have the same cache attributes of course.
- * Zero attributes are represented as holes.
- *
- * The data structure is a list that is also organized as an rbtree
- * sorted on the start address of memtype range.
- *
- * memtype_lock protects both the linear list and rbtree.
- */
-
-struct memtype {
-       u64                     start;
-       u64                     end;
-       unsigned long           type;
-       struct list_head        nd;
-       struct rb_node          rb;
-};
-
-static struct rb_root memtype_rbroot = RB_ROOT;
-static LIST_HEAD(memtype_list);
-static DEFINE_SPINLOCK(memtype_lock);  /* protects memtype list */
-
-static struct memtype *memtype_rb_search(struct rb_root *root, u64 start)
-{
-       struct rb_node *node = root->rb_node;
-       struct memtype *last_lower = NULL;
-
-       while (node) {
-               struct memtype *data = container_of(node, struct memtype, rb);
-
-               if (data->start < start) {
-                       last_lower = data;
-                       node = node->rb_right;
-               } else if (data->start > start) {
-                       node = node->rb_left;
-               } else
-                       return data;
-       }
-
-       /* Will return NULL if there is no entry with its start <= start */
-       return last_lower;
-}
-
-static void memtype_rb_insert(struct rb_root *root, struct memtype *data)
-{
-       struct rb_node **new = &(root->rb_node);
-       struct rb_node *parent = NULL;
-
-       while (*new) {
-               struct memtype *this = container_of(*new, struct memtype, rb);
-
-               parent = *new;
-               if (data->start <= this->start)
-                       new = &((*new)->rb_left);
-               else if (data->start > this->start)
-                       new = &((*new)->rb_right);
-       }
-
-       rb_link_node(&data->rb, parent, new);
-       rb_insert_color(&data->rb, root);
-}
+static DEFINE_SPINLOCK(memtype_lock);  /* protects memtype accesses */
 
 /*
  * Does intersection of PAT memory type and MTRR memory type and returns
@@ -237,33 +158,6 @@ static unsigned long pat_x_mtrr_type(u64 start, u64 end, unsigned long req_type)
        return req_type;
 }
 
-static int
-chk_conflict(struct memtype *new, struct memtype *entry, unsigned long *type)
-{
-       if (new->type != entry->type) {
-               if (type) {
-                       new->type = entry->type;
-                       *type = entry->type;
-               } else
-                       goto conflict;
-       }
-
-        /* check overlaps with more than one entry in the list */
-       list_for_each_entry_continue(entry, &memtype_list, nd) {
-               if (new->end <= entry->start)
-                       break;
-               else if (new->type != entry->type)
-                       goto conflict;
-       }
-       return 0;
-
- conflict:
-       printk(KERN_INFO "%s:%d conflicting memory types "
-              "%Lx-%Lx %s<->%s\n", current->comm, current->pid, new->start,
-              new->end, cattr_name(new->type), cattr_name(entry->type));
-       return -EBUSY;
-}
-
 static int pat_pagerange_is_ram(unsigned long start, unsigned long end)
 {
        int ram_page = 0, not_rampage = 0;
@@ -296,8 +190,6 @@ static int pat_pagerange_is_ram(unsigned long start, unsigned long end)
  * Here we do two pass:
  * - Find the memtype of all the pages in the range, look for any conflicts
  * - In case of no conflicts, set the new memtype for pages in the range
- *
- * Caller must hold memtype_lock for atomicity.
  */
 static int reserve_ram_pages_type(u64 start, u64 end, unsigned long req_type,
                                  unsigned long *new_type)
@@ -364,9 +256,8 @@ static int free_ram_pages_type(u64 start, u64 end)
 int reserve_memtype(u64 start, u64 end, unsigned long req_type,
                    unsigned long *new_type)
 {
-       struct memtype *new, *entry;
+       struct memtype *new;
        unsigned long actual_type;
-       struct list_head *where;
        int is_range_ram;
        int err = 0;
 
@@ -404,9 +295,7 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
        is_range_ram = pat_pagerange_is_ram(start, end);
        if (is_range_ram == 1) {
 
-               spin_lock(&memtype_lock);
                err = reserve_ram_pages_type(start, end, req_type, new_type);
-               spin_unlock(&memtype_lock);
 
                return err;
        } else if (is_range_ram < 0) {
@@ -423,42 +312,7 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
 
        spin_lock(&memtype_lock);
 
-       /* Search for existing mapping that overlaps the current range */
-       where = NULL;
-       list_for_each_entry(entry, &memtype_list, nd) {
-               if (end <= entry->start) {
-                       where = entry->nd.prev;
-                       break;
-               } else if (start <= entry->start) { /* end > entry->start */
-                       err = chk_conflict(new, entry, new_type);
-                       if (!err) {
-                               dprintk("Overlap at 0x%Lx-0x%Lx\n",
-                                       entry->start, entry->end);
-                               where = entry->nd.prev;
-                       }
-                       break;
-               } else if (start < entry->end) { /* start > entry->start */
-                       err = chk_conflict(new, entry, new_type);
-                       if (!err) {
-                               dprintk("Overlap at 0x%Lx-0x%Lx\n",
-                                       entry->start, entry->end);
-
-                               /*
-                                * Move to right position in the linked
-                                * list to add this new entry
-                                */
-                               list_for_each_entry_continue(entry,
-                                                       &memtype_list, nd) {
-                                       if (start <= entry->start) {
-                                               where = entry->nd.prev;
-                                               break;
-                                       }
-                               }
-                       }
-                       break;
-               }
-       }
-
+       err = rbt_memtype_check_insert(new, new_type);
        if (err) {
                printk(KERN_INFO "reserve_memtype failed 0x%Lx-0x%Lx, "
                       "track %s, req %s\n",
@@ -469,13 +323,6 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
                return err;
        }
 
-       if (where)
-               list_add(&new->nd, where);
-       else
-               list_add_tail(&new->nd, &memtype_list);
-
-       memtype_rb_insert(&memtype_rbroot, new);
-
        spin_unlock(&memtype_lock);
 
        dprintk("reserve_memtype added 0x%Lx-0x%Lx, track %s, req %s, ret %s\n",
@@ -487,7 +334,6 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
 
 int free_memtype(u64 start, u64 end)
 {
-       struct memtype *entry, *saved_entry;
        int err = -EINVAL;
        int is_range_ram;
 
@@ -501,9 +347,7 @@ int free_memtype(u64 start, u64 end)
        is_range_ram = pat_pagerange_is_ram(start, end);
        if (is_range_ram == 1) {
 
-               spin_lock(&memtype_lock);
                err = free_ram_pages_type(start, end);
-               spin_unlock(&memtype_lock);
 
                return err;
        } else if (is_range_ram < 0) {
@@ -511,46 +355,7 @@ int free_memtype(u64 start, u64 end)
        }
 
        spin_lock(&memtype_lock);
-
-       entry = memtype_rb_search(&memtype_rbroot, start);
-       if (unlikely(entry == NULL))
-               goto unlock_ret;
-
-       /*
-        * Saved entry points to an entry with start same or less than what
-        * we searched for. Now go through the list in both directions to look
-        * for the entry that matches with both start and end, with list stored
-        * in sorted start address
-        */
-       saved_entry = entry;
-       list_for_each_entry_from(entry, &memtype_list, nd) {
-               if (entry->start == start && entry->end == end) {
-                       rb_erase(&entry->rb, &memtype_rbroot);
-                       list_del(&entry->nd);
-                       kfree(entry);
-                       err = 0;
-                       break;
-               } else if (entry->start > start) {
-                       break;
-               }
-       }
-
-       if (!err)
-               goto unlock_ret;
-
-       entry = saved_entry;
-       list_for_each_entry_reverse(entry, &memtype_list, nd) {
-               if (entry->start == start && entry->end == end) {
-                       rb_erase(&entry->rb, &memtype_rbroot);
-                       list_del(&entry->nd);
-                       kfree(entry);
-                       err = 0;
-                       break;
-               } else if (entry->start < start) {
-                       break;
-               }
-       }
-unlock_ret:
+       err = rbt_memtype_erase(start, end);
        spin_unlock(&memtype_lock);
 
        if (err) {
@@ -583,10 +388,8 @@ static unsigned long lookup_memtype(u64 paddr)
 
        if (pat_pagerange_is_ram(paddr, paddr + PAGE_SIZE)) {
                struct page *page;
-               spin_lock(&memtype_lock);
                page = pfn_to_page(paddr >> PAGE_SHIFT);
                rettype = get_page_memtype(page);
-               spin_unlock(&memtype_lock);
                /*
                 * -1 from get_page_memtype() implies RAM page is in its
                 * default state and not reserved, and hence of type WB
@@ -599,7 +402,7 @@ static unsigned long lookup_memtype(u64 paddr)
 
        spin_lock(&memtype_lock);
 
-       entry = memtype_rb_search(&memtype_rbroot, paddr);
+       entry = rbt_memtype_lookup(paddr);
        if (entry != NULL)
                rettype = entry->type;
        else
@@ -936,29 +739,25 @@ EXPORT_SYMBOL_GPL(pgprot_writecombine);
 
 #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_X86_PAT)
 
-/* get Nth element of the linked list */
 static struct memtype *memtype_get_idx(loff_t pos)
 {
-       struct memtype *list_node, *print_entry;
-       int i = 1;
+       struct memtype *print_entry;
+       int ret;
 
-       print_entry  = kmalloc(sizeof(struct memtype), GFP_KERNEL);
+       print_entry  = kzalloc(sizeof(struct memtype), GFP_KERNEL);
        if (!print_entry)
                return NULL;
 
        spin_lock(&memtype_lock);
-       list_for_each_entry(list_node, &memtype_list, nd) {
-               if (pos == i) {
-                       *print_entry = *list_node;
-                       spin_unlock(&memtype_lock);
-                       return print_entry;
-               }
-               ++i;
-       }
+       ret = rbt_memtype_copy_nth_element(print_entry, pos);
        spin_unlock(&memtype_lock);
-       kfree(print_entry);
 
-       return NULL;
+       if (!ret) {
+               return print_entry;
+       } else {
+               kfree(print_entry);
+               return NULL;
+       }
 }
 
 static void *memtype_seq_start(struct seq_file *seq, loff_t *pos)
diff --git a/arch/x86/mm/pat_internal.h b/arch/x86/mm/pat_internal.h
new file mode 100644 (file)
index 0000000..4f39eef
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef __PAT_INTERNAL_H_
+#define __PAT_INTERNAL_H_
+
+extern int pat_debug_enable;
+
+#define dprintk(fmt, arg...) \
+       do { if (pat_debug_enable) printk(KERN_INFO fmt, ##arg); } while (0)
+
+struct memtype {
+       u64                     start;
+       u64                     end;
+       u64                     subtree_max_end;
+       unsigned long           type;
+       struct rb_node          rb;
+};
+
+static inline char *cattr_name(unsigned long flags)
+{
+       switch (flags & _PAGE_CACHE_MASK) {
+       case _PAGE_CACHE_UC:            return "uncached";
+       case _PAGE_CACHE_UC_MINUS:      return "uncached-minus";
+       case _PAGE_CACHE_WB:            return "write-back";
+       case _PAGE_CACHE_WC:            return "write-combining";
+       default:                        return "broken";
+       }
+}
+
+#ifdef CONFIG_X86_PAT
+extern int rbt_memtype_check_insert(struct memtype *new,
+                                       unsigned long *new_type);
+extern int rbt_memtype_erase(u64 start, u64 end);
+extern struct memtype *rbt_memtype_lookup(u64 addr);
+extern int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos);
+#else
+static inline int rbt_memtype_check_insert(struct memtype *new,
+                                       unsigned long *new_type)
+{ return 0; }
+static inline int rbt_memtype_erase(u64 start, u64 end)
+{ return 0; }
+static inline struct memtype *rbt_memtype_lookup(u64 addr)
+{ return NULL; }
+static inline int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos)
+{ return 0; }
+#endif
+
+#endif /* __PAT_INTERNAL_H_ */
diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c
new file mode 100644 (file)
index 0000000..07de4cb
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * Handle caching attributes in page tables (PAT)
+ *
+ * Authors: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *          Suresh B Siddha <suresh.b.siddha@intel.com>
+ *
+ * Interval tree (augmented rbtree) used to store the PAT memory type
+ * reservations.
+ */
+
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rbtree.h>
+#include <linux/sched.h>
+#include <linux/gfp.h>
+
+#include <asm/pgtable.h>
+#include <asm/pat.h>
+
+#include "pat_internal.h"
+
+/*
+ * The memtype tree keeps track of memory type for specific
+ * physical memory areas. Without proper tracking, conflicting memory
+ * types in different mappings can cause CPU cache corruption.
+ *
+ * The tree is an interval tree (augmented rbtree) with tree ordered
+ * on starting address. Tree can contain multiple entries for
+ * different regions which overlap. All the aliases have the same
+ * cache attributes of course.
+ *
+ * memtype_lock protects the rbtree.
+ */
+
+static void memtype_rb_augment_cb(struct rb_node *node);
+static struct rb_root memtype_rbroot = RB_AUGMENT_ROOT(&memtype_rb_augment_cb);
+
+static int is_node_overlap(struct memtype *node, u64 start, u64 end)
+{
+       if (node->start >= end || node->end <= start)
+               return 0;
+
+       return 1;
+}
+
+static u64 get_subtree_max_end(struct rb_node *node)
+{
+       u64 ret = 0;
+       if (node) {
+               struct memtype *data = container_of(node, struct memtype, rb);
+               ret = data->subtree_max_end;
+       }
+       return ret;
+}
+
+/* Update 'subtree_max_end' for a node, based on node and its children */
+static void update_node_max_end(struct rb_node *node)
+{
+       struct memtype *data;
+       u64 max_end, child_max_end;
+
+       if (!node)
+               return;
+
+       data = container_of(node, struct memtype, rb);
+       max_end = data->end;
+
+       child_max_end = get_subtree_max_end(node->rb_right);
+       if (child_max_end > max_end)
+               max_end = child_max_end;
+
+       child_max_end = get_subtree_max_end(node->rb_left);
+       if (child_max_end > max_end)
+               max_end = child_max_end;
+
+       data->subtree_max_end = max_end;
+}
+
+/* Update 'subtree_max_end' for a node and all its ancestors */
+static void update_path_max_end(struct rb_node *node)
+{
+       u64 old_max_end, new_max_end;
+
+       while (node) {
+               struct memtype *data = container_of(node, struct memtype, rb);
+
+               old_max_end = data->subtree_max_end;
+               update_node_max_end(node);
+               new_max_end = data->subtree_max_end;
+
+               if (new_max_end == old_max_end)
+                       break;
+
+               node = rb_parent(node);
+       }
+}
+
+/* Find the first (lowest start addr) overlapping range from rb tree */
+static struct memtype *memtype_rb_lowest_match(struct rb_root *root,
+                               u64 start, u64 end)
+{
+       struct rb_node *node = root->rb_node;
+       struct memtype *last_lower = NULL;
+
+       while (node) {
+               struct memtype *data = container_of(node, struct memtype, rb);
+
+               if (get_subtree_max_end(node->rb_left) > start) {
+                       /* Lowest overlap if any must be on left side */
+                       node = node->rb_left;
+               } else if (is_node_overlap(data, start, end)) {
+                       last_lower = data;
+                       break;
+               } else if (start >= data->start) {
+                       /* Lowest overlap if any must be on right side */
+                       node = node->rb_right;
+               } else {
+                       break;
+               }
+       }
+       return last_lower; /* Returns NULL if there is no overlap */
+}
+
+static struct memtype *memtype_rb_exact_match(struct rb_root *root,
+                               u64 start, u64 end)
+{
+       struct memtype *match;
+
+       match = memtype_rb_lowest_match(root, start, end);
+       while (match != NULL && match->start < end) {
+               struct rb_node *node;
+
+               if (match->start == start && match->end == end)
+                       return match;
+
+               node = rb_next(&match->rb);
+               if (node)
+                       match = container_of(node, struct memtype, rb);
+               else
+                       match = NULL;
+       }
+
+       return NULL; /* Returns NULL if there is no exact match */
+}
+
+static int memtype_rb_check_conflict(struct rb_root *root,
+                               u64 start, u64 end,
+                               unsigned long reqtype, unsigned long *newtype)
+{
+       struct rb_node *node;
+       struct memtype *match;
+       int found_type = reqtype;
+
+       match = memtype_rb_lowest_match(&memtype_rbroot, start, end);
+       if (match == NULL)
+               goto success;
+
+       if (match->type != found_type && newtype == NULL)
+               goto failure;
+
+       dprintk("Overlap at 0x%Lx-0x%Lx\n", match->start, match->end);
+       found_type = match->type;
+
+       node = rb_next(&match->rb);
+       while (node) {
+               match = container_of(node, struct memtype, rb);
+
+               if (match->start >= end) /* Checked all possible matches */
+                       goto success;
+
+               if (is_node_overlap(match, start, end) &&
+                   match->type != found_type) {
+                       goto failure;
+               }
+
+               node = rb_next(&match->rb);
+       }
+success:
+       if (newtype)
+               *newtype = found_type;
+
+       return 0;
+
+failure:
+       printk(KERN_INFO "%s:%d conflicting memory types "
+               "%Lx-%Lx %s<->%s\n", current->comm, current->pid, start,
+               end, cattr_name(found_type), cattr_name(match->type));
+       return -EBUSY;
+}
+
+static void memtype_rb_augment_cb(struct rb_node *node)
+{
+       if (node)
+               update_path_max_end(node);
+}
+
+static void memtype_rb_insert(struct rb_root *root, struct memtype *newdata)
+{
+       struct rb_node **node = &(root->rb_node);
+       struct rb_node *parent = NULL;
+
+       while (*node) {
+               struct memtype *data = container_of(*node, struct memtype, rb);
+
+               parent = *node;
+               if (newdata->start <= data->start)
+                       node = &((*node)->rb_left);
+               else if (newdata->start > data->start)
+                       node = &((*node)->rb_right);
+       }
+
+       rb_link_node(&newdata->rb, parent, node);
+       rb_insert_color(&newdata->rb, root);
+}
+
+int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type)
+{
+       int err = 0;
+
+       err = memtype_rb_check_conflict(&memtype_rbroot, new->start, new->end,
+                                               new->type, ret_type);
+
+       if (!err) {
+               if (ret_type)
+                       new->type = *ret_type;
+
+               memtype_rb_insert(&memtype_rbroot, new);
+       }
+       return err;
+}
+
+int rbt_memtype_erase(u64 start, u64 end)
+{
+       struct memtype *data;
+
+       data = memtype_rb_exact_match(&memtype_rbroot, start, end);
+       if (!data)
+               return -EINVAL;
+
+       rb_erase(&data->rb, &memtype_rbroot);
+       return 0;
+}
+
+struct memtype *rbt_memtype_lookup(u64 addr)
+{
+       struct memtype *data;
+       data = memtype_rb_lowest_match(&memtype_rbroot, addr, addr + PAGE_SIZE);
+       return data;
+}
+
+#if defined(CONFIG_DEBUG_FS)
+int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos)
+{
+       struct rb_node *node;
+       int i = 1;
+
+       node = rb_first(&memtype_rbroot);
+       while (node && pos != i) {
+               node = rb_next(node);
+               i++;
+       }
+
+       if (node) { /* pos == i */
+               struct memtype *this = container_of(node, struct memtype, rb);
+               *out = *this;
+               return 0;
+       } else {
+               return 1;
+       }
+}
+#endif
index c9ba9deafe83f30daaae9b0e998c3de715671d43..5c4ee422590e5dc23aec0071e642bf246b627565 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/mm.h>
+#include <linux/gfp.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/tlb.h>
index 46c8834aedc0fe3c16e5c88d70012f62f436a3c3..792854003ed339c742dbbeabaeff2f90e0f44a31 100644 (file)
@@ -6,7 +6,6 @@
 #include <linux/swap.h>
 #include <linux/smp.h>
 #include <linux/highmem.h>
-#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/spinlock.h>
 #include <linux/module.h>
@@ -19,6 +18,7 @@
 #include <asm/e820.h>
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
+#include <asm/io.h>
 
 unsigned int __VMALLOC_RESERVE = 128 << 20;
 
@@ -129,6 +129,7 @@ static int __init parse_reservetop(char *arg)
 
        address = memparse(arg, &arg);
        reserve_top_address(address);
+       fixup_early_ioremap();
        return 0;
 }
 early_param("reservetop", parse_reservetop);
index 28c68762648f9e28e02a9bd598c613e9e953fc37..f9897f7a9ef1e25cfa81e9190a3449bec9e35f70 100644 (file)
@@ -363,6 +363,54 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
        for (i = 0; i < MAX_NUMNODES; i++)
                cutoff_node(i, start, end);
 
+       /*
+        * Join together blocks on the same node, holes between
+        * which don't overlap with memory on other nodes.
+        */
+       for (i = 0; i < num_node_memblks; ++i) {
+               int j, k;
+
+               for (j = i + 1; j < num_node_memblks; ++j) {
+                       unsigned long start, end;
+
+                       if (memblk_nodeid[i] != memblk_nodeid[j])
+                               continue;
+                       start = min(node_memblk_range[i].end,
+                                   node_memblk_range[j].end);
+                       end = max(node_memblk_range[i].start,
+                                 node_memblk_range[j].start);
+                       for (k = 0; k < num_node_memblks; ++k) {
+                               if (memblk_nodeid[i] == memblk_nodeid[k])
+                                       continue;
+                               if (start < node_memblk_range[k].end &&
+                                   end > node_memblk_range[k].start)
+                                       break;
+                       }
+                       if (k < num_node_memblks)
+                               continue;
+                       start = min(node_memblk_range[i].start,
+                                   node_memblk_range[j].start);
+                       end = max(node_memblk_range[i].end,
+                                 node_memblk_range[j].end);
+                       printk(KERN_INFO "SRAT: Node %d "
+                              "[%Lx,%Lx) + [%Lx,%Lx) -> [%lx,%lx)\n",
+                              memblk_nodeid[i],
+                              node_memblk_range[i].start,
+                              node_memblk_range[i].end,
+                              node_memblk_range[j].start,
+                              node_memblk_range[j].end,
+                              start, end);
+                       node_memblk_range[i].start = start;
+                       node_memblk_range[i].end = end;
+                       k = --num_node_memblks - j;
+                       memmove(memblk_nodeid + j, memblk_nodeid + j+1,
+                               k * sizeof(*memblk_nodeid));
+                       memmove(node_memblk_range + j, node_memblk_range + j+1,
+                               k * sizeof(*node_memblk_range));
+                       --j;
+               }
+       }
+
        memnode_shift = compute_hash_shift(node_memblk_range, num_node_memblks,
                                           memblk_nodeid);
        if (memnode_shift < 0) {
@@ -461,7 +509,8 @@ void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes)
                 * node, it must now point to the fake node ID.
                 */
                for (j = 0; j < MAX_LOCAL_APIC; j++)
-                       if (apicid_to_node[j] == nid)
+                       if (apicid_to_node[j] == nid &&
+                           fake_apicid_to_node[j] == NUMA_NO_NODE)
                                fake_apicid_to_node[j] = i;
        }
        for (i = 0; i < num_nodes; i++)
index 2c505ee7101488b7032aad6f89d15ddb134457aa..b28d2f1253bbc927731afa08022fdef21a598a24 100644 (file)
@@ -31,8 +31,9 @@ static struct op_x86_model_spec *model;
 static DEFINE_PER_CPU(struct op_msrs, cpu_msrs);
 static DEFINE_PER_CPU(unsigned long, saved_lvtpc);
 
-/* 0 == registered but off, 1 == registered and on */
-static int nmi_enabled = 0;
+/* must be protected with get_online_cpus()/put_online_cpus(): */
+static int nmi_enabled;
+static int ctr_running;
 
 struct op_counter_config counter_config[OP_MAX_COUNTER];
 
@@ -61,12 +62,16 @@ static int profile_exceptions_notify(struct notifier_block *self,
 {
        struct die_args *args = (struct die_args *)data;
        int ret = NOTIFY_DONE;
-       int cpu = smp_processor_id();
 
        switch (val) {
        case DIE_NMI:
        case DIE_NMI_IPI:
-               model->check_ctrs(args->regs, &per_cpu(cpu_msrs, cpu));
+               if (ctr_running)
+                       model->check_ctrs(args->regs, &__get_cpu_var(cpu_msrs));
+               else if (!nmi_enabled)
+                       break;
+               else
+                       model->stop(&__get_cpu_var(cpu_msrs));
                ret = NOTIFY_STOP;
                break;
        default:
@@ -95,24 +100,36 @@ static void nmi_cpu_save_registers(struct op_msrs *msrs)
 static void nmi_cpu_start(void *dummy)
 {
        struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs);
-       model->start(msrs);
+       if (!msrs->controls)
+               WARN_ON_ONCE(1);
+       else
+               model->start(msrs);
 }
 
 static int nmi_start(void)
 {
+       get_online_cpus();
        on_each_cpu(nmi_cpu_start, NULL, 1);
+       ctr_running = 1;
+       put_online_cpus();
        return 0;
 }
 
 static void nmi_cpu_stop(void *dummy)
 {
        struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs);
-       model->stop(msrs);
+       if (!msrs->controls)
+               WARN_ON_ONCE(1);
+       else
+               model->stop(msrs);
 }
 
 static void nmi_stop(void)
 {
+       get_online_cpus();
        on_each_cpu(nmi_cpu_stop, NULL, 1);
+       ctr_running = 0;
+       put_online_cpus();
 }
 
 #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
@@ -252,7 +269,10 @@ static int nmi_switch_event(void)
        if (nmi_multiplex_on() < 0)
                return -EINVAL;         /* not necessary */
 
-       on_each_cpu(nmi_cpu_switch, NULL, 1);
+       get_online_cpus();
+       if (ctr_running)
+               on_each_cpu(nmi_cpu_switch, NULL, 1);
+       put_online_cpus();
 
        return 0;
 }
@@ -295,6 +315,7 @@ static void free_msrs(void)
                kfree(per_cpu(cpu_msrs, i).controls);
                per_cpu(cpu_msrs, i).controls = NULL;
        }
+       nmi_shutdown_mux();
 }
 
 static int allocate_msrs(void)
@@ -307,14 +328,21 @@ static int allocate_msrs(void)
                per_cpu(cpu_msrs, i).counters = kzalloc(counters_size,
                                                        GFP_KERNEL);
                if (!per_cpu(cpu_msrs, i).counters)
-                       return 0;
+                       goto fail;
                per_cpu(cpu_msrs, i).controls = kzalloc(controls_size,
                                                        GFP_KERNEL);
                if (!per_cpu(cpu_msrs, i).controls)
-                       return 0;
+                       goto fail;
        }
 
+       if (!nmi_setup_mux())
+               goto fail;
+
        return 1;
+
+fail:
+       free_msrs();
+       return 0;
 }
 
 static void nmi_cpu_setup(void *dummy)
@@ -336,49 +364,6 @@ static struct notifier_block profile_exceptions_nb = {
        .priority = 2
 };
 
-static int nmi_setup(void)
-{
-       int err = 0;
-       int cpu;
-
-       if (!allocate_msrs())
-               err = -ENOMEM;
-       else if (!nmi_setup_mux())
-               err = -ENOMEM;
-       else
-               err = register_die_notifier(&profile_exceptions_nb);
-
-       if (err) {
-               free_msrs();
-               nmi_shutdown_mux();
-               return err;
-       }
-
-       /* We need to serialize save and setup for HT because the subset
-        * of msrs are distinct for save and setup operations
-        */
-
-       /* Assume saved/restored counters are the same on all CPUs */
-       model->fill_in_addresses(&per_cpu(cpu_msrs, 0));
-       for_each_possible_cpu(cpu) {
-               if (!cpu)
-                       continue;
-
-               memcpy(per_cpu(cpu_msrs, cpu).counters,
-                      per_cpu(cpu_msrs, 0).counters,
-                      sizeof(struct op_msr) * model->num_counters);
-
-               memcpy(per_cpu(cpu_msrs, cpu).controls,
-                      per_cpu(cpu_msrs, 0).controls,
-                      sizeof(struct op_msr) * model->num_controls);
-
-               mux_clone(cpu);
-       }
-       on_each_cpu(nmi_cpu_setup, NULL, 1);
-       nmi_enabled = 1;
-       return 0;
-}
-
 static void nmi_cpu_restore_registers(struct op_msrs *msrs)
 {
        struct op_msr *counters = msrs->counters;
@@ -412,20 +397,24 @@ static void nmi_cpu_shutdown(void *dummy)
        apic_write(APIC_LVTPC, per_cpu(saved_lvtpc, cpu));
        apic_write(APIC_LVTERR, v);
        nmi_cpu_restore_registers(msrs);
+       if (model->cpu_down)
+               model->cpu_down();
 }
 
-static void nmi_shutdown(void)
+static void nmi_cpu_up(void *dummy)
 {
-       struct op_msrs *msrs;
+       if (nmi_enabled)
+               nmi_cpu_setup(dummy);
+       if (ctr_running)
+               nmi_cpu_start(dummy);
+}
 
-       nmi_enabled = 0;
-       on_each_cpu(nmi_cpu_shutdown, NULL, 1);
-       unregister_die_notifier(&profile_exceptions_nb);
-       nmi_shutdown_mux();
-       msrs = &get_cpu_var(cpu_msrs);
-       model->shutdown(msrs);
-       free_msrs();
-       put_cpu_var(cpu_msrs);
+static void nmi_cpu_down(void *dummy)
+{
+       if (ctr_running)
+               nmi_cpu_stop(dummy);
+       if (nmi_enabled)
+               nmi_cpu_shutdown(dummy);
 }
 
 static int nmi_create_files(struct super_block *sb, struct dentry *root)
@@ -457,7 +446,6 @@ static int nmi_create_files(struct super_block *sb, struct dentry *root)
        return 0;
 }
 
-#ifdef CONFIG_SMP
 static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
                                 void *data)
 {
@@ -465,10 +453,10 @@ static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
        switch (action) {
        case CPU_DOWN_FAILED:
        case CPU_ONLINE:
-               smp_call_function_single(cpu, nmi_cpu_start, NULL, 0);
+               smp_call_function_single(cpu, nmi_cpu_up, NULL, 0);
                break;
        case CPU_DOWN_PREPARE:
-               smp_call_function_single(cpu, nmi_cpu_stop, NULL, 1);
+               smp_call_function_single(cpu, nmi_cpu_down, NULL, 1);
                break;
        }
        return NOTIFY_DONE;
@@ -477,7 +465,75 @@ static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
 static struct notifier_block oprofile_cpu_nb = {
        .notifier_call = oprofile_cpu_notifier
 };
-#endif
+
+static int nmi_setup(void)
+{
+       int err = 0;
+       int cpu;
+
+       if (!allocate_msrs())
+               return -ENOMEM;
+
+       /* We need to serialize save and setup for HT because the subset
+        * of msrs are distinct for save and setup operations
+        */
+
+       /* Assume saved/restored counters are the same on all CPUs */
+       err = model->fill_in_addresses(&per_cpu(cpu_msrs, 0));
+       if (err)
+               goto fail;
+
+       for_each_possible_cpu(cpu) {
+               if (!cpu)
+                       continue;
+
+               memcpy(per_cpu(cpu_msrs, cpu).counters,
+                      per_cpu(cpu_msrs, 0).counters,
+                      sizeof(struct op_msr) * model->num_counters);
+
+               memcpy(per_cpu(cpu_msrs, cpu).controls,
+                      per_cpu(cpu_msrs, 0).controls,
+                      sizeof(struct op_msr) * model->num_controls);
+
+               mux_clone(cpu);
+       }
+
+       nmi_enabled = 0;
+       ctr_running = 0;
+       barrier();
+       err = register_die_notifier(&profile_exceptions_nb);
+       if (err)
+               goto fail;
+
+       get_online_cpus();
+       register_cpu_notifier(&oprofile_cpu_nb);
+       on_each_cpu(nmi_cpu_setup, NULL, 1);
+       nmi_enabled = 1;
+       put_online_cpus();
+
+       return 0;
+fail:
+       free_msrs();
+       return err;
+}
+
+static void nmi_shutdown(void)
+{
+       struct op_msrs *msrs;
+
+       get_online_cpus();
+       unregister_cpu_notifier(&oprofile_cpu_nb);
+       on_each_cpu(nmi_cpu_shutdown, NULL, 1);
+       nmi_enabled = 0;
+       ctr_running = 0;
+       put_online_cpus();
+       barrier();
+       unregister_die_notifier(&profile_exceptions_nb);
+       msrs = &get_cpu_var(cpu_msrs);
+       model->shutdown(msrs);
+       free_msrs();
+       put_cpu_var(cpu_msrs);
+}
 
 #ifdef CONFIG_PM
 
@@ -687,9 +743,6 @@ int __init op_nmi_init(struct oprofile_operations *ops)
                return -ENODEV;
        }
 
-#ifdef CONFIG_SMP
-       register_cpu_notifier(&oprofile_cpu_nb);
-#endif
        /* default values, can be overwritten by model */
        ops->create_files       = nmi_create_files;
        ops->setup              = nmi_setup;
@@ -716,12 +769,6 @@ int __init op_nmi_init(struct oprofile_operations *ops)
 
 void op_nmi_exit(void)
 {
-       if (using_nmi) {
+       if (using_nmi)
                exit_sysfs();
-#ifdef CONFIG_SMP
-               unregister_cpu_notifier(&oprofile_cpu_nb);
-#endif
-       }
-       if (model->exit)
-               model->exit();
 }
index 090cbbec7dbdf4103b6af9670be20c41a33f2e21..b67a6b5aa8d449ee06e0c22b586b6c51af4d2170 100644 (file)
 #include "op_counter.h"
 
 #define NUM_COUNTERS 4
-#define NUM_CONTROLS 4
 #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
 #define NUM_VIRT_COUNTERS 32
-#define NUM_VIRT_CONTROLS 32
 #else
 #define NUM_VIRT_COUNTERS NUM_COUNTERS
-#define NUM_VIRT_CONTROLS NUM_CONTROLS
 #endif
 
 #define OP_EVENT_MASK                  0x0FFF
@@ -105,102 +102,6 @@ static u32 get_ibs_caps(void)
        return ibs_caps;
 }
 
-#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
-
-static void op_mux_switch_ctrl(struct op_x86_model_spec const *model,
-                              struct op_msrs const * const msrs)
-{
-       u64 val;
-       int i;
-
-       /* enable active counters */
-       for (i = 0; i < NUM_COUNTERS; ++i) {
-               int virt = op_x86_phys_to_virt(i);
-               if (!reset_value[virt])
-                       continue;
-               rdmsrl(msrs->controls[i].addr, val);
-               val &= model->reserved;
-               val |= op_x86_get_ctrl(model, &counter_config[virt]);
-               wrmsrl(msrs->controls[i].addr, val);
-       }
-}
-
-#endif
-
-/* functions for op_amd_spec */
-
-static void op_amd_fill_in_addresses(struct op_msrs * const msrs)
-{
-       int i;
-
-       for (i = 0; i < NUM_COUNTERS; i++) {
-               if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i))
-                       msrs->counters[i].addr = MSR_K7_PERFCTR0 + i;
-       }
-
-       for (i = 0; i < NUM_CONTROLS; i++) {
-               if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i))
-                       msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i;
-       }
-}
-
-static void op_amd_setup_ctrs(struct op_x86_model_spec const *model,
-                             struct op_msrs const * const msrs)
-{
-       u64 val;
-       int i;
-
-       /* setup reset_value */
-       for (i = 0; i < NUM_VIRT_COUNTERS; ++i) {
-               if (counter_config[i].enabled
-                   && msrs->counters[op_x86_virt_to_phys(i)].addr)
-                       reset_value[i] = counter_config[i].count;
-               else
-                       reset_value[i] = 0;
-       }
-
-       /* clear all counters */
-       for (i = 0; i < NUM_CONTROLS; ++i) {
-               if (unlikely(!msrs->controls[i].addr)) {
-                       if (counter_config[i].enabled && !smp_processor_id())
-                               /*
-                                * counter is reserved, this is on all
-                                * cpus, so report only for cpu #0
-                                */
-                               op_x86_warn_reserved(i);
-                       continue;
-               }
-               rdmsrl(msrs->controls[i].addr, val);
-               if (val & ARCH_PERFMON_EVENTSEL_ENABLE)
-                       op_x86_warn_in_use(i);
-               val &= model->reserved;
-               wrmsrl(msrs->controls[i].addr, val);
-       }
-
-       /* avoid a false detection of ctr overflows in NMI handler */
-       for (i = 0; i < NUM_COUNTERS; ++i) {
-               if (unlikely(!msrs->counters[i].addr))
-                       continue;
-               wrmsrl(msrs->counters[i].addr, -1LL);
-       }
-
-       /* enable active counters */
-       for (i = 0; i < NUM_COUNTERS; ++i) {
-               int virt = op_x86_phys_to_virt(i);
-               if (!reset_value[virt])
-                       continue;
-
-               /* setup counter registers */
-               wrmsrl(msrs->counters[i].addr, -(u64)reset_value[virt]);
-
-               /* setup control registers */
-               rdmsrl(msrs->controls[i].addr, val);
-               val &= model->reserved;
-               val |= op_x86_get_ctrl(model, &counter_config[virt]);
-               wrmsrl(msrs->controls[i].addr, val);
-       }
-}
-
 /*
  * 16-bit Linear Feedback Shift Register (LFSR)
  *
@@ -365,6 +266,125 @@ static void op_amd_stop_ibs(void)
                wrmsrl(MSR_AMD64_IBSOPCTL, 0);
 }
 
+#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
+
+static void op_mux_switch_ctrl(struct op_x86_model_spec const *model,
+                              struct op_msrs const * const msrs)
+{
+       u64 val;
+       int i;
+
+       /* enable active counters */
+       for (i = 0; i < NUM_COUNTERS; ++i) {
+               int virt = op_x86_phys_to_virt(i);
+               if (!reset_value[virt])
+                       continue;
+               rdmsrl(msrs->controls[i].addr, val);
+               val &= model->reserved;
+               val |= op_x86_get_ctrl(model, &counter_config[virt]);
+               wrmsrl(msrs->controls[i].addr, val);
+       }
+}
+
+#endif
+
+/* functions for op_amd_spec */
+
+static void op_amd_shutdown(struct op_msrs const * const msrs)
+{
+       int i;
+
+       for (i = 0; i < NUM_COUNTERS; ++i) {
+               if (!msrs->counters[i].addr)
+                       continue;
+               release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
+               release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
+       }
+}
+
+static int op_amd_fill_in_addresses(struct op_msrs * const msrs)
+{
+       int i;
+
+       for (i = 0; i < NUM_COUNTERS; i++) {
+               if (!reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i))
+                       goto fail;
+               if (!reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) {
+                       release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
+                       goto fail;
+               }
+               /* both registers must be reserved */
+               msrs->counters[i].addr = MSR_K7_PERFCTR0 + i;
+               msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i;
+               continue;
+       fail:
+               if (!counter_config[i].enabled)
+                       continue;
+               op_x86_warn_reserved(i);
+               op_amd_shutdown(msrs);
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+static void op_amd_setup_ctrs(struct op_x86_model_spec const *model,
+                             struct op_msrs const * const msrs)
+{
+       u64 val;
+       int i;
+
+       /* setup reset_value */
+       for (i = 0; i < NUM_VIRT_COUNTERS; ++i) {
+               if (counter_config[i].enabled
+                   && msrs->counters[op_x86_virt_to_phys(i)].addr)
+                       reset_value[i] = counter_config[i].count;
+               else
+                       reset_value[i] = 0;
+       }
+
+       /* clear all counters */
+       for (i = 0; i < NUM_COUNTERS; ++i) {
+               if (!msrs->controls[i].addr)
+                       continue;
+               rdmsrl(msrs->controls[i].addr, val);
+               if (val & ARCH_PERFMON_EVENTSEL_ENABLE)
+                       op_x86_warn_in_use(i);
+               val &= model->reserved;
+               wrmsrl(msrs->controls[i].addr, val);
+               /*
+                * avoid a false detection of ctr overflows in NMI
+                * handler
+                */
+               wrmsrl(msrs->counters[i].addr, -1LL);
+       }
+
+       /* enable active counters */
+       for (i = 0; i < NUM_COUNTERS; ++i) {
+               int virt = op_x86_phys_to_virt(i);
+               if (!reset_value[virt])
+                       continue;
+
+               /* setup counter registers */
+               wrmsrl(msrs->counters[i].addr, -(u64)reset_value[virt]);
+
+               /* setup control registers */
+               rdmsrl(msrs->controls[i].addr, val);
+               val &= model->reserved;
+               val |= op_x86_get_ctrl(model, &counter_config[virt]);
+               wrmsrl(msrs->controls[i].addr, val);
+       }
+
+       if (ibs_caps)
+               setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_NMI, 0);
+}
+
+static void op_amd_cpu_shutdown(void)
+{
+       if (ibs_caps)
+               setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_FIX, 1);
+}
+
 static int op_amd_check_ctrs(struct pt_regs * const regs,
                             struct op_msrs const * const msrs)
 {
@@ -425,42 +445,16 @@ static void op_amd_stop(struct op_msrs const * const msrs)
        op_amd_stop_ibs();
 }
 
-static void op_amd_shutdown(struct op_msrs const * const msrs)
-{
-       int i;
-
-       for (i = 0; i < NUM_COUNTERS; ++i) {
-               if (msrs->counters[i].addr)
-                       release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
-       }
-       for (i = 0; i < NUM_CONTROLS; ++i) {
-               if (msrs->controls[i].addr)
-                       release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
-       }
-}
-
-static u8 ibs_eilvt_off;
-
-static inline void apic_init_ibs_nmi_per_cpu(void *arg)
-{
-       ibs_eilvt_off = setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_NMI, 0);
-}
-
-static inline void apic_clear_ibs_nmi_per_cpu(void *arg)
-{
-       setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_FIX, 1);
-}
-
-static int init_ibs_nmi(void)
+static int __init_ibs_nmi(void)
 {
 #define IBSCTL_LVTOFFSETVAL            (1 << 8)
 #define IBSCTL                         0x1cc
        struct pci_dev *cpu_cfg;
        int nodes;
        u32 value = 0;
+       u8 ibs_eilvt_off;
 
-       /* per CPU setup */
-       on_each_cpu(apic_init_ibs_nmi_per_cpu, NULL, 1);
+       ibs_eilvt_off = setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_FIX, 1);
 
        nodes = 0;
        cpu_cfg = NULL;
@@ -490,22 +484,15 @@ static int init_ibs_nmi(void)
        return 0;
 }
 
-/* uninitialize the APIC for the IBS interrupts if needed */
-static void clear_ibs_nmi(void)
-{
-       if (ibs_caps)
-               on_each_cpu(apic_clear_ibs_nmi_per_cpu, NULL, 1);
-}
-
 /* initialize the APIC for the IBS interrupts if available */
-static void ibs_init(void)
+static void init_ibs(void)
 {
        ibs_caps = get_ibs_caps();
 
        if (!ibs_caps)
                return;
 
-       if (init_ibs_nmi()) {
+       if (__init_ibs_nmi()) {
                ibs_caps = 0;
                return;
        }
@@ -514,14 +501,6 @@ static void ibs_init(void)
               (unsigned)ibs_caps);
 }
 
-static void ibs_exit(void)
-{
-       if (!ibs_caps)
-               return;
-
-       clear_ibs_nmi();
-}
-
 static int (*create_arch_files)(struct super_block *sb, struct dentry *root);
 
 static int setup_ibs_files(struct super_block *sb, struct dentry *root)
@@ -570,27 +549,22 @@ static int setup_ibs_files(struct super_block *sb, struct dentry *root)
 
 static int op_amd_init(struct oprofile_operations *ops)
 {
-       ibs_init();
+       init_ibs();
        create_arch_files = ops->create_files;
        ops->create_files = setup_ibs_files;
        return 0;
 }
 
-static void op_amd_exit(void)
-{
-       ibs_exit();
-}
-
 struct op_x86_model_spec op_amd_spec = {
        .num_counters           = NUM_COUNTERS,
-       .num_controls           = NUM_CONTROLS,
+       .num_controls           = NUM_COUNTERS,
        .num_virt_counters      = NUM_VIRT_COUNTERS,
        .reserved               = MSR_AMD_EVENTSEL_RESERVED,
        .event_mask             = OP_EVENT_MASK,
        .init                   = op_amd_init,
-       .exit                   = op_amd_exit,
        .fill_in_addresses      = &op_amd_fill_in_addresses,
        .setup_ctrs             = &op_amd_setup_ctrs,
+       .cpu_down               = &op_amd_cpu_shutdown,
        .check_ctrs             = &op_amd_check_ctrs,
        .start                  = &op_amd_start,
        .stop                   = &op_amd_stop,
index e6a160a4684a4a9d96914acc161122d6c7f8c208..182558dd5515add420a27dfa58304d04b6a6f71a 100644 (file)
@@ -385,8 +385,26 @@ static unsigned int get_stagger(void)
 
 static unsigned long reset_value[NUM_COUNTERS_NON_HT];
 
+static void p4_shutdown(struct op_msrs const * const msrs)
+{
+       int i;
 
-static void p4_fill_in_addresses(struct op_msrs * const msrs)
+       for (i = 0; i < num_counters; ++i) {
+               if (msrs->counters[i].addr)
+                       release_perfctr_nmi(msrs->counters[i].addr);
+       }
+       /*
+        * some of the control registers are specially reserved in
+        * conjunction with the counter registers (hence the starting offset).
+        * This saves a few bits.
+        */
+       for (i = num_counters; i < num_controls; ++i) {
+               if (msrs->controls[i].addr)
+                       release_evntsel_nmi(msrs->controls[i].addr);
+       }
+}
+
+static int p4_fill_in_addresses(struct op_msrs * const msrs)
 {
        unsigned int i;
        unsigned int addr, cccraddr, stag;
@@ -468,6 +486,18 @@ static void p4_fill_in_addresses(struct op_msrs * const msrs)
                        msrs->controls[i++].addr = MSR_P4_CRU_ESCR5;
                }
        }
+
+       for (i = 0; i < num_counters; ++i) {
+               if (!counter_config[i].enabled)
+                       continue;
+               if (msrs->controls[i].addr)
+                       continue;
+               op_x86_warn_reserved(i);
+               p4_shutdown(msrs);
+               return -EBUSY;
+       }
+
+       return 0;
 }
 
 
@@ -668,26 +698,6 @@ static void p4_stop(struct op_msrs const * const msrs)
        }
 }
 
-static void p4_shutdown(struct op_msrs const * const msrs)
-{
-       int i;
-
-       for (i = 0; i < num_counters; ++i) {
-               if (msrs->counters[i].addr)
-                       release_perfctr_nmi(msrs->counters[i].addr);
-       }
-       /*
-        * some of the control registers are specially reserved in
-        * conjunction with the counter registers (hence the starting offset).
-        * This saves a few bits.
-        */
-       for (i = num_counters; i < num_controls; ++i) {
-               if (msrs->controls[i].addr)
-                       release_evntsel_nmi(msrs->controls[i].addr);
-       }
-}
-
-
 #ifdef CONFIG_SMP
 struct op_x86_model_spec op_p4_ht2_spec = {
        .num_counters           = NUM_COUNTERS_HT2,
index 2bf90fafa7b56a89e6e6e7627c623c57bad62b67..d769cda540823e12a0dbfbdba923ec481f07abfd 100644 (file)
@@ -30,19 +30,46 @@ static int counter_width = 32;
 
 static u64 *reset_value;
 
-static void ppro_fill_in_addresses(struct op_msrs * const msrs)
+static void ppro_shutdown(struct op_msrs const * const msrs)
 {
        int i;
 
-       for (i = 0; i < num_counters; i++) {
-               if (reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i))
-                       msrs->counters[i].addr = MSR_P6_PERFCTR0 + i;
+       for (i = 0; i < num_counters; ++i) {
+               if (!msrs->counters[i].addr)
+                       continue;
+               release_perfctr_nmi(MSR_P6_PERFCTR0 + i);
+               release_evntsel_nmi(MSR_P6_EVNTSEL0 + i);
+       }
+       if (reset_value) {
+               kfree(reset_value);
+               reset_value = NULL;
        }
+}
+
+static int ppro_fill_in_addresses(struct op_msrs * const msrs)
+{
+       int i;
 
        for (i = 0; i < num_counters; i++) {
-               if (reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i))
-                       msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i;
+               if (!reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i))
+                       goto fail;
+               if (!reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i)) {
+                       release_perfctr_nmi(MSR_P6_PERFCTR0 + i);
+                       goto fail;
+               }
+               /* both registers must be reserved */
+               msrs->counters[i].addr = MSR_P6_PERFCTR0 + i;
+               msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i;
+               continue;
+       fail:
+               if (!counter_config[i].enabled)
+                       continue;
+               op_x86_warn_reserved(i);
+               ppro_shutdown(msrs);
+               return -EBUSY;
        }
+
+       return 0;
 }
 
 
@@ -78,26 +105,17 @@ static void ppro_setup_ctrs(struct op_x86_model_spec const *model,
 
        /* clear all counters */
        for (i = 0; i < num_counters; ++i) {
-               if (unlikely(!msrs->controls[i].addr)) {
-                       if (counter_config[i].enabled && !smp_processor_id())
-                               /*
-                                * counter is reserved, this is on all
-                                * cpus, so report only for cpu #0
-                                */
-                               op_x86_warn_reserved(i);
+               if (!msrs->controls[i].addr)
                        continue;
-               }
                rdmsrl(msrs->controls[i].addr, val);
                if (val & ARCH_PERFMON_EVENTSEL_ENABLE)
                        op_x86_warn_in_use(i);
                val &= model->reserved;
                wrmsrl(msrs->controls[i].addr, val);
-       }
-
-       /* avoid a false detection of ctr overflows in NMI handler */
-       for (i = 0; i < num_counters; ++i) {
-               if (unlikely(!msrs->counters[i].addr))
-                       continue;
+               /*
+                * avoid a false detection of ctr overflows in NMI *
+                * handler
+                */
                wrmsrl(msrs->counters[i].addr, -1LL);
        }
 
@@ -189,25 +207,6 @@ static void ppro_stop(struct op_msrs const * const msrs)
        }
 }
 
-static void ppro_shutdown(struct op_msrs const * const msrs)
-{
-       int i;
-
-       for (i = 0; i < num_counters; ++i) {
-               if (msrs->counters[i].addr)
-                       release_perfctr_nmi(MSR_P6_PERFCTR0 + i);
-       }
-       for (i = 0; i < num_counters; ++i) {
-               if (msrs->controls[i].addr)
-                       release_evntsel_nmi(MSR_P6_EVNTSEL0 + i);
-       }
-       if (reset_value) {
-               kfree(reset_value);
-               reset_value = NULL;
-       }
-}
-
-
 struct op_x86_model_spec op_ppro_spec = {
        .num_counters           = 2,
        .num_controls           = 2,
@@ -239,11 +238,11 @@ static void arch_perfmon_setup_counters(void)
        if (eax.split.version_id == 0 && current_cpu_data.x86 == 6 &&
                current_cpu_data.x86_model == 15) {
                eax.split.version_id = 2;
-               eax.split.num_events = 2;
+               eax.split.num_counters = 2;
                eax.split.bit_width = 40;
        }
 
-       num_counters = eax.split.num_events;
+       num_counters = eax.split.num_counters;
 
        op_arch_perfmon_spec.num_counters = num_counters;
        op_arch_perfmon_spec.num_controls = num_counters;
index ff82a755edd4ad206b3153374371d84a1d77f43a..89017fa1fd63bbfa9450f73767690dad26525b7c 100644 (file)
@@ -40,10 +40,10 @@ struct op_x86_model_spec {
        u64             reserved;
        u16             event_mask;
        int             (*init)(struct oprofile_operations *ops);
-       void            (*exit)(void);
-       void            (*fill_in_addresses)(struct op_msrs * const msrs);
+       int             (*fill_in_addresses)(struct op_msrs * const msrs);
        void            (*setup_ctrs)(struct op_x86_model_spec const *model,
                                      struct op_msrs const * const msrs);
+       void            (*cpu_down)(void);
        int             (*check_ctrs)(struct pt_regs * const regs,
                                      struct op_msrs const * const msrs);
        void            (*start)(struct op_msrs const * const msrs);
index 6e22454bfaa6d51e4f22ce9eb5c379e1770319d6..31930fd30ea95a36232c2ed7df0a6a1f97147b1f 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 #include <asm/numa.h>
 #include <asm/pci_x86.h>
 
@@ -65,14 +66,44 @@ resource_to_addr(struct acpi_resource *resource,
                        struct acpi_resource_address64 *addr)
 {
        acpi_status status;
-
-       status = acpi_resource_to_address64(resource, addr);
-       if (ACPI_SUCCESS(status) &&
-           (addr->resource_type == ACPI_MEMORY_RANGE ||
-           addr->resource_type == ACPI_IO_RANGE) &&
-           addr->address_length > 0 &&
-           addr->producer_consumer == ACPI_PRODUCER) {
+       struct acpi_resource_memory24 *memory24;
+       struct acpi_resource_memory32 *memory32;
+       struct acpi_resource_fixed_memory32 *fixed_memory32;
+
+       memset(addr, 0, sizeof(*addr));
+       switch (resource->type) {
+       case ACPI_RESOURCE_TYPE_MEMORY24:
+               memory24 = &resource->data.memory24;
+               addr->resource_type = ACPI_MEMORY_RANGE;
+               addr->minimum = memory24->minimum;
+               addr->address_length = memory24->address_length;
+               addr->maximum = addr->minimum + addr->address_length - 1;
+               return AE_OK;
+       case ACPI_RESOURCE_TYPE_MEMORY32:
+               memory32 = &resource->data.memory32;
+               addr->resource_type = ACPI_MEMORY_RANGE;
+               addr->minimum = memory32->minimum;
+               addr->address_length = memory32->address_length;
+               addr->maximum = addr->minimum + addr->address_length - 1;
                return AE_OK;
+       case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+               fixed_memory32 = &resource->data.fixed_memory32;
+               addr->resource_type = ACPI_MEMORY_RANGE;
+               addr->minimum = fixed_memory32->address;
+               addr->address_length = fixed_memory32->address_length;
+               addr->maximum = addr->minimum + addr->address_length - 1;
+               return AE_OK;
+       case ACPI_RESOURCE_TYPE_ADDRESS16:
+       case ACPI_RESOURCE_TYPE_ADDRESS32:
+       case ACPI_RESOURCE_TYPE_ADDRESS64:
+               status = acpi_resource_to_address64(resource, addr);
+               if (ACPI_SUCCESS(status) &&
+                   (addr->resource_type == ACPI_MEMORY_RANGE ||
+                   addr->resource_type == ACPI_IO_RANGE) &&
+                   addr->address_length > 0) {
+                       return AE_OK;
+               }
+               break;
        }
        return AE_ERROR;
 }
@@ -90,30 +121,6 @@ count_resource(struct acpi_resource *acpi_res, void *data)
        return AE_OK;
 }
 
-static void
-align_resource(struct acpi_device *bridge, struct resource *res)
-{
-       int align = (res->flags & IORESOURCE_MEM) ? 16 : 4;
-
-       /*
-        * Host bridge windows are not BARs, but the decoders on the PCI side
-        * that claim this address space have starting alignment and length
-        * constraints, so fix any obvious BIOS goofs.
-        */
-       if (!IS_ALIGNED(res->start, align)) {
-               dev_printk(KERN_DEBUG, &bridge->dev,
-                          "host bridge window %pR invalid; "
-                          "aligning start to %d-byte boundary\n", res, align);
-               res->start &= ~(align - 1);
-       }
-       if (!IS_ALIGNED(res->end + 1, align)) {
-               dev_printk(KERN_DEBUG, &bridge->dev,
-                          "host bridge window %pR invalid; "
-                          "aligning end to %d-byte boundary\n", res, align);
-               res->end = ALIGN(res->end, align) - 1;
-       }
-}
-
 static acpi_status
 setup_resource(struct acpi_resource *acpi_res, void *data)
 {
@@ -122,7 +129,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
        struct acpi_resource_address64 addr;
        acpi_status status;
        unsigned long flags;
-       struct resource *root;
+       struct resource *root, *conflict;
        u64 start, end;
 
        status = resource_to_addr(acpi_res, &addr);
@@ -141,7 +148,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
                return AE_OK;
 
        start = addr.minimum + addr.translation_offset;
-       end = start + addr.address_length - 1;
+       end = addr.maximum + addr.translation_offset;
 
        res = &info->res[info->res_num];
        res->name = info->name;
@@ -149,7 +156,6 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
        res->start = start;
        res->end = end;
        res->child = NULL;
-       align_resource(info->bridge, res);
 
        if (!pci_use_crs) {
                dev_printk(KERN_DEBUG, &info->bridge->dev,
@@ -157,9 +163,12 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
                return AE_OK;
        }
 
-       if (insert_resource(root, res)) {
+       conflict = insert_resource_conflict(root, res);
+       if (conflict) {
                dev_err(&info->bridge->dev,
-                       "can't allocate host bridge window %pR\n", res);
+                       "address space collision: host bridge window %pR "
+                       "conflicts with %s %pR\n",
+                       res, conflict->name, conflict);
        } else {
                pci_bus_add_resource(info->bus, res, 0);
                info->res_num++;
index 294e10cb11e108a82ce6140b44a67049d12dc3e6..cf2e93869c489ee14b8e074817a62a55dacf3845 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 
 #include <asm/acpi.h>
 #include <asm/segment.h>
index dece3eb9c90639731811f8bc4bd7139d51a7fd69..97da2ba9344b4ca7fa1f08d7cd015fe77a332ea6 100644 (file)
@@ -72,6 +72,9 @@ pcibios_align_resource(void *data, const struct resource *res,
                        return start;
                if (start & 0x300)
                        start = (start + 0x3ff) & ~0x3ff;
+       } else if (res->flags & IORESOURCE_MEM) {
+               if (start < BIOS_END)
+                       start = BIOS_END;
        }
        return start;
 }
@@ -127,9 +130,6 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
                                        continue;
                                if (!r->start ||
                                    pci_claim_resource(dev, idx) < 0) {
-                                       dev_info(&dev->dev,
-                                                "can't reserve window %pR\n",
-                                                r);
                                        /*
                                         * Something is wrong with the region.
                                         * Invalidate the resource to prevent
@@ -181,8 +181,6 @@ static void __init pcibios_allocate_resources(int pass)
                                        "BAR %d: reserving %pr (d=%d, p=%d)\n",
                                        idx, r, disabled, pass);
                                if (pci_claim_resource(dev, idx) < 0) {
-                                       dev_info(&dev->dev,
-                                                "can't reserve %pR\n", r);
                                        /* We'll assign a new address later */
                                        r->end -= r->start;
                                        r->start = 0;
index 8b107521d24e63f235cdd86ddf4ee86826e36ded..5d362b5ba06f35146d40cd161b6b19ade0ff84e6 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/dmi.h>
 #include <linux/io.h>
index 8f3f9a50b1e0b4891be7fbba0d62ee16bff6a273..39b9ebe8f8863d598345991c90942b5aed70ae21 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/sfi_acpi.h>
 #include <linux/bitmap.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
 #include <asm/acpi.h>
index 8bf2fcb88d0427ff5c63e37fab736355ecbc8332..7ef3a2735df39f2fdfbd4624a440e22d3e169879 100644 (file)
@@ -109,7 +109,7 @@ static int pci_device_update_fixed(struct pci_bus *bus, unsigned int devfn,
                        decode++;
                        decode = ~(decode - 1);
                } else {
-                       decode = ~0;
+                       decode = 0;
                }
 
                /*
@@ -247,6 +247,10 @@ static void __devinit pci_fixed_bar_fixup(struct pci_dev *dev)
        u32 size;
        int i;
 
+       /* Must have extended configuration space */
+       if (dev->cfg_size < PCIE_CAP_OFFSET + 4)
+               return;
+
        /* Fixup the BAR sizes for fixed BAR devices and make them unmoveable */
        offset = fixed_bar_cap(dev->bus, dev->devfn);
        if (!offset || PCI_DEVFN(2, 0) == dev->devfn ||
index 1c975cc9839e0617e3b08d245e91277ec10450e3..59a225c17b84264f07bb07ca4db54b8962fce9c4 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/uaccess.h>
 #include <asm/pci_x86.h>
index 81197c62d5b3f8240b7f261cf2efee90ea110fb2..3769079874d8f57702bbea42bcc7446908b5af23 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright (c) 2006 Rafael J. Wysocki <rjw@sisk.pl>
  */
 
+#include <linux/gfp.h>
 #include <linux/suspend.h>
 #include <linux/bootmem.h>
 
index 65fdc86e923fd92175b95bfef56ad1c82d64bc2d..d24f983ba1e5f670cc4cb9dbaf0bf056416e8278 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
  */
 
+#include <linux/gfp.h>
 #include <linux/smp.h>
 #include <linux/suspend.h>
 #include <asm/proto.h>
index b641388d8286acfcf73bc6f7ca850609270739b3..ad47daeafa4eace0e505c51aae54d43317d62233 100644 (file)
@@ -27,10 +27,17 @@ ENTRY(swsusp_arch_suspend)
        ret
 
 ENTRY(restore_image)
+       movl    mmu_cr4_features, %ecx
        movl    resume_pg_dir, %eax
        subl    $__PAGE_OFFSET, %eax
        movl    %eax, %cr3
 
+       jecxz   1f      # cr4 Pentium and higher, skip if zero
+       andl    $~(X86_CR4_PGE), %ecx
+       movl    %ecx, %cr4;  # turn off PGE
+       movl    %cr3, %eax;  # flush TLB
+       movl    %eax, %cr3
+1:
        movl    restore_pblist, %edx
        .p2align 4,,7
 
@@ -54,16 +61,8 @@ done:
        movl    $swapper_pg_dir, %eax
        subl    $__PAGE_OFFSET, %eax
        movl    %eax, %cr3
-       /* Flush TLB, including "global" things (vmalloc) */
        movl    mmu_cr4_features, %ecx
        jecxz   1f      # cr4 Pentium and higher, skip if zero
-       movl    %ecx, %edx
-       andl    $~(X86_CR4_PGE), %edx
-       movl    %edx, %cr4;  # turn off PGE
-1:
-       movl    %cr3, %eax;  # flush TLB
-       movl    %eax, %cr3
-       jecxz   1f      # cr4 Pentium and higher, skip if zero
        movl    %ecx, %cr4;  # turn PGE back on
 1:
 
index 21e1aeb9f3ea1b1f839445dbae69ad461ddf188f..ac74869b8140754b45277126fb6f5dcc5a9e6834 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/mm.h>
 #include <linux/err.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/random.h>
 #include <linux/elf.h>
index e133ce25e29022d20bdd5e954c9a6697bfc7ab91..1304bcec8ee57d1b15c8cb72aed55cea283d2d5b 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/init.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 
 #include "debugfs.h"
index b607239c1ba8304f2732f0e7035a81f2ee1bff8c..65d8d79b46a8467cbc11c4495a160d7b416a0b32 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/highmem.h>
 #include <linux/console.h>
 #include <linux/pci.h>
+#include <linux/gfp.h>
 
 #include <xen/xen.h>
 #include <xen/interface/xen.h>
index f9eb7de74f42998745872dea255ec821e2abe1ce..914f04695ce5e1a917e786ab2ac231369083ec1e 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/debugfs.h>
 #include <linux/bug.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
index deafb65ef44edb7a18ef96e6846843948c7b90b1..a29693fd3138e06bbd46ad875249da6c5a35cdce 100644 (file)
@@ -14,6 +14,7 @@
  */
 #include <linux/sched.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/smp.h>
 
 #include <asm/paravirt.h>
index 24ded31b5aeceeabfadc05fc5c5ff7aa95fa2b97..e0500646585d4a5d7bc64338798ba955494ab387 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/spinlock.h>
 #include <linux/debugfs.h>
 #include <linux/log2.h>
+#include <linux/gfp.h>
 
 #include <asm/paravirt.h>
 
index 0d3f07cd1b5fe9aee977674b11b0beb311e25eb0..32764b8880b5f85b6d88032bbb1fbee0d7f7359c 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/clockchips.h>
 #include <linux/kernel_stat.h>
 #include <linux/math64.h>
+#include <linux/gfp.h>
 
 #include <asm/pvclock.h>
 #include <asm/xen/hypervisor.h>
index 22d6dde426192266c3915403f8a73785fef6f916..a96a0619d0b7ec630dc3cecf124a7389d6ce3cf3 100644 (file)
@@ -46,7 +46,7 @@
  *
  * Atomically reads the value of @v.
  */
-#define atomic_read(v)         ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
 
 /**
  * atomic_set - set atomic variable
index f5319d78c876135326374c530f7f85f13f961d72..2783fda76ddc18f052494c7b9010db3e0e208cfa 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 #include <asm/cacheflush.h>
 
index e1a04a346e75811cde445b4ad4bce4cd0c679cd9..f167e0f5e05e524b6deffbbda3127da8ae3905c8 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/elf.h>
 #include <linux/init.h>
 #include <linux/prctl.h>
@@ -31,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/mqueue.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
index cdbc27ca9665dea72be443a347120a3c547a8386..ba150e5de2ebe6583c2b708525a26e33b8acbfb2 100644 (file)
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/bootmem.h>
+#include <linux/gfp.h>
 #include <linux/swap.h>
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 
 #include <asm/bootparam.h>
 #include <asm/page.h>
index e60a1f57022f358a6ca1e61119ed8e71f547bcbf..2c723e8b30da4f7b08b9bb7418735356d69639fb 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/sched.h>
 #include <linux/console.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/major.h>
 #include <linux/param.h>
index 62a5921321cd4e379223bc9fba4242a5dba488b6..f9e89f4d94bba17392f0416598d0ff7f27f92002 100644 (file)
@@ -78,8 +78,9 @@ config BLK_DEV_INTEGRITY
        Protection.  If in doubt, say N.
 
 config BLK_CGROUP
-       tristate
+       tristate "Block cgroup support"
        depends on CGROUPS
+       depends on CFQ_GROUP_IOSCHED
        default n
        ---help---
        Generic block IO controller cgroup interface. This is the common
index 8618d8996fea9c9b278b7529d44ac958c24fa465..6d88544b677fe8865922795ccac817d1d301954f 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/module.h>
 #include <linux/bio.h>
 #include <linux/blkdev.h>
+#include <linux/gfp.h>
 
 #include "blk.h"
 
index 4b686ad08eaaad5384f7d0c6535b5b4154679c5f..2cc682b860ead9d15350620c595bfbb30f4a533d 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kdev_t.h>
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include "blk-cgroup.h"
 
 static DEFINE_SPINLOCK(blkio_list_lock);
@@ -285,16 +286,16 @@ done:
 static struct cgroup_subsys_state *
 blkiocg_create(struct cgroup_subsys *subsys, struct cgroup *cgroup)
 {
-       struct blkio_cgroup *blkcg, *parent_blkcg;
+       struct blkio_cgroup *blkcg;
+       struct cgroup *parent = cgroup->parent;
 
-       if (!cgroup->parent) {
+       if (!parent) {
                blkcg = &blkio_root_cgroup;
                goto done;
        }
 
        /* Currently we do not support hierarchy deeper than two level (0,1) */
-       parent_blkcg = cgroup_to_blkio_cgroup(cgroup->parent);
-       if (css_depth(&parent_blkcg->css) > 0)
+       if (parent != cgroup->top_cgroup)
                return ERR_PTR(-EINVAL);
 
        blkcg = kzalloc(sizeof(*blkcg), GFP_KERNEL);
index 96e83c2bdb94f0a06e4cd4f2f04e86b3b115fdb4..edce1ef7933d69d553b890fcd4d42edaed1a01be 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/mempool.h>
 #include <linux/bio.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 #include "blk.h"
 
index 3f65c8aadb2fb9ba6116f82653e314efce950a51..d22c4c55c40689c23b7d275fbb76af17c0b23efa 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/bio.h>
 #include <linux/blkdev.h>
 #include <linux/bootmem.h>     /* for max_pfn/max_low_pfn */
+#include <linux/slab.h>
 
 #include "blk.h"
 
index 31e7a9375c1333cc35ab40d565c5c1ed4e8703e7..f5ed5a1187ba8564527b70f682328b31eea4549a 100644 (file)
@@ -8,7 +8,9 @@
 #include <linux/blkdev.h>
 #include <linux/bootmem.h>     /* for max_pfn/max_low_pfn */
 #include <linux/gcd.h>
+#include <linux/lcm.h>
 #include <linux/jiffies.h>
+#include <linux/gfp.h>
 
 #include "blk.h"
 
@@ -461,16 +463,6 @@ void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
 }
 EXPORT_SYMBOL(blk_queue_stack_limits);
 
-static unsigned int lcm(unsigned int a, unsigned int b)
-{
-       if (a && b)
-               return (a * b) / gcd(a, b);
-       else if (b)
-               return b;
-
-       return a;
-}
-
 /**
  * blk_stack_limits - adjust queue_limits for stacked devices
  * @t: the stacking driver limits (top device)
index 2ae2cb3f362fb4984907d54a625c6e5af3b5f779..306759bbdf1be719ef1f8e0a1f1912475c521a09 100644 (file)
@@ -2,6 +2,7 @@
  * Functions related to sysfs handling
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/bio.h>
 #include <linux/blkdev.h>
@@ -106,6 +107,19 @@ static ssize_t queue_max_sectors_show(struct request_queue *q, char *page)
        return queue_var_show(max_sectors_kb, (page));
 }
 
+static ssize_t queue_max_segments_show(struct request_queue *q, char *page)
+{
+       return queue_var_show(queue_max_segments(q), (page));
+}
+
+static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page)
+{
+       if (test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
+               return queue_var_show(queue_max_segment_size(q), (page));
+
+       return queue_var_show(PAGE_CACHE_SIZE, (page));
+}
+
 static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page)
 {
        return queue_var_show(queue_logical_block_size(q), page);
@@ -280,6 +294,16 @@ static struct queue_sysfs_entry queue_max_hw_sectors_entry = {
        .show = queue_max_hw_sectors_show,
 };
 
+static struct queue_sysfs_entry queue_max_segments_entry = {
+       .attr = {.name = "max_segments", .mode = S_IRUGO },
+       .show = queue_max_segments_show,
+};
+
+static struct queue_sysfs_entry queue_max_segment_size_entry = {
+       .attr = {.name = "max_segment_size", .mode = S_IRUGO },
+       .show = queue_max_segment_size_show,
+};
+
 static struct queue_sysfs_entry queue_iosched_entry = {
        .attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR },
        .show = elv_iosched_show,
@@ -355,6 +379,8 @@ static struct attribute *default_attrs[] = {
        &queue_ra_entry.attr,
        &queue_max_hw_sectors_entry.attr,
        &queue_max_sectors_entry.attr,
+       &queue_max_segments_entry.attr,
+       &queue_max_segment_size_entry.attr,
        &queue_iosched_entry.attr,
        &queue_hw_sector_size_entry.attr,
        &queue_logical_block_size_entry.attr,
index 6b0f52c20964e484c95a2e6c120dc77e2b821b88..ece65fc4c79b511c37fb3eb89c4a746dc105ba8d 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/module.h>
 #include <linux/bio.h>
 #include <linux/blkdev.h>
+#include <linux/slab.h>
 
 #include "blk.h"
 
index 1ba7e0aca8781b55ce14fa54491da8f81505b747..4f0c06c7a3388062f5aa58a8ffbe56de5d7c1f1e 100644 (file)
@@ -109,6 +109,7 @@ void blk_rq_timed_out_timer(unsigned long data)
        struct request_queue *q = (struct request_queue *) data;
        unsigned long flags, next = 0;
        struct request *rq, *tmp;
+       int next_set = 0;
 
        spin_lock_irqsave(q->queue_lock, flags);
 
@@ -122,16 +123,13 @@ void blk_rq_timed_out_timer(unsigned long data)
                        if (blk_mark_rq_complete(rq))
                                continue;
                        blk_rq_timed_out(rq);
-               } else if (!next || time_after(next, rq->deadline))
+               } else if (!next_set || time_after(next, rq->deadline)) {
                        next = rq->deadline;
+                       next_set = 1;
+               }
        }
 
-       /*
-        * next can never be 0 here with the list non-empty, since we always
-        * bump ->deadline to 1 so we can detect if the timer was ever added
-        * or not. See comment in blk_add_timer()
-        */
-       if (next)
+       if (next_set)
                mod_timer(&q->timeout, round_jiffies_up(next));
 
        spin_unlock_irqrestore(q->queue_lock, flags);
index 46597a6bd112d9c209904dab7cc6da723cbc9fb8..82d58829ba591eeef13a3ed4eca96b8a019c4d85 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/idr.h>
 #include <linux/bsg.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_ioctl.h>
index dee9d9378fee18658875fba10122ed0cbe308d04..5f127cfb2e924baf06f77ae95d1832e13048cee4 100644 (file)
@@ -7,6 +7,7 @@
  *  Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  */
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/elevator.h>
 #include <linux/jiffies.h>
@@ -47,6 +48,7 @@ static const int cfq_hist_divisor = 4;
 #define CFQ_SERVICE_SHIFT       12
 
 #define CFQQ_SEEK_THR          (sector_t)(8 * 100)
+#define CFQQ_CLOSE_THR         (sector_t)(8 * 1024)
 #define CFQQ_SECT_THR_NONROT   (sector_t)(2 * 32)
 #define CFQQ_SEEKY(cfqq)       (hweight32(cfqq->seek_history) > 32/8)
 
@@ -947,6 +949,11 @@ cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create)
        unsigned int major, minor;
 
        cfqg = cfqg_of_blkg(blkiocg_lookup_group(blkcg, key));
+       if (cfqg && !cfqg->blkg.dev && bdi->dev && dev_name(bdi->dev)) {
+               sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor);
+               cfqg->blkg.dev = MKDEV(major, minor);
+               goto done;
+       }
        if (cfqg || !create)
                goto done;
 
@@ -1517,7 +1524,8 @@ static void __cfq_set_active_queue(struct cfq_data *cfqd,
                                   struct cfq_queue *cfqq)
 {
        if (cfqq) {
-               cfq_log_cfqq(cfqd, cfqq, "set_active");
+               cfq_log_cfqq(cfqd, cfqq, "set_active wl_prio:%d wl_type:%d",
+                               cfqd->serving_prio, cfqd->serving_type);
                cfqq->slice_start = 0;
                cfqq->dispatch_start = jiffies;
                cfqq->allocated_slice = 0;
@@ -1660,9 +1668,9 @@ static inline sector_t cfq_dist_from_last(struct cfq_data *cfqd,
 }
 
 static inline int cfq_rq_close(struct cfq_data *cfqd, struct cfq_queue *cfqq,
-                              struct request *rq, bool for_preempt)
+                              struct request *rq)
 {
-       return cfq_dist_from_last(cfqd, rq) <= CFQQ_SEEK_THR;
+       return cfq_dist_from_last(cfqd, rq) <= CFQQ_CLOSE_THR;
 }
 
 static struct cfq_queue *cfqq_close(struct cfq_data *cfqd,
@@ -1689,7 +1697,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd,
         * will contain the closest sector.
         */
        __cfqq = rb_entry(parent, struct cfq_queue, p_node);
-       if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false))
+       if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq))
                return __cfqq;
 
        if (blk_rq_pos(__cfqq->next_rq) < sector)
@@ -1700,7 +1708,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd,
                return NULL;
 
        __cfqq = rb_entry(node, struct cfq_queue, p_node);
-       if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false))
+       if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq))
                return __cfqq;
 
        return NULL;
@@ -1721,6 +1729,8 @@ static struct cfq_queue *cfq_close_cooperator(struct cfq_data *cfqd,
 {
        struct cfq_queue *cfqq;
 
+       if (cfq_class_idle(cur_cfqq))
+               return NULL;
        if (!cfq_cfqq_sync(cur_cfqq))
                return NULL;
        if (CFQQ_SEEKY(cur_cfqq))
@@ -1787,7 +1797,11 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq)
         * Otherwise, we do only if they are the last ones
         * in their service tree.
         */
-       return service_tree->count == 1 && cfq_cfqq_sync(cfqq);
+       if (service_tree->count == 1 && cfq_cfqq_sync(cfqq))
+               return 1;
+       cfq_log_cfqq(cfqd, cfqq, "Not idling. st->count:%d",
+                       service_tree->count);
+       return 0;
 }
 
 static void cfq_arm_slice_timer(struct cfq_data *cfqd)
@@ -1832,8 +1846,11 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
         * time slice.
         */
        if (sample_valid(cic->ttime_samples) &&
-           (cfqq->slice_end - jiffies < cic->ttime_mean))
+           (cfqq->slice_end - jiffies < cic->ttime_mean)) {
+               cfq_log_cfqq(cfqd, cfqq, "Not idling. think_time:%d",
+                               cic->ttime_mean);
                return;
+       }
 
        cfq_mark_cfqq_wait_request(cfqq);
 
@@ -2041,6 +2058,7 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg)
                slice = max(slice, 2 * cfqd->cfq_slice_idle);
 
        slice = max_t(unsigned, slice, CFQ_MIN_TT);
+       cfq_log(cfqd, "workload slice:%d", slice);
        cfqd->workload_expires = jiffies + slice;
        cfqd->noidle_tree_requires_idle = false;
 }
@@ -2188,10 +2206,13 @@ static int cfq_forced_dispatch(struct cfq_data *cfqd)
        struct cfq_queue *cfqq;
        int dispatched = 0;
 
-       while ((cfqq = cfq_get_next_queue_forced(cfqd)) != NULL)
+       /* Expire the timeslice of the current active queue first */
+       cfq_slice_expired(cfqd, 0);
+       while ((cfqq = cfq_get_next_queue_forced(cfqd)) != NULL) {
+               __cfq_set_active_queue(cfqd, cfqq);
                dispatched += __cfq_forced_dispatch_cfqq(cfqq);
+       }
 
-       cfq_slice_expired(cfqd, 0);
        BUG_ON(cfqd->busy_queues);
 
        cfq_log(cfqd, "forced_dispatch=%d", dispatched);
@@ -3103,7 +3124,7 @@ 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, cfqq, rq, true))
+       if (cfq_rq_close(cfqd, cfqq, rq))
                return true;
 
        return false;
@@ -3307,6 +3328,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
                if (cfq_should_wait_busy(cfqd, cfqq)) {
                        cfqq->slice_end = jiffies + cfqd->cfq_slice_idle;
                        cfq_mark_cfqq_wait_busy(cfqq);
+                       cfq_log_cfqq(cfqd, cfqq, "will busy wait");
                }
 
                /*
@@ -3672,8 +3694,10 @@ static void *cfq_init_queue(struct request_queue *q)
         * to make sure that cfq_put_cfqg() does not try to kfree root group
         */
        atomic_set(&cfqg->ref, 1);
+       rcu_read_lock();
        blkiocg_add_blkio_group(&blkio_root_cgroup, &cfqg->blkg, (void *)cfqd,
                                        0);
+       rcu_read_unlock();
 #endif
        /*
         * Not strictly needed (since RB_ROOT just clears the node and we
index 4eb8e9ea4af561cd9d141a44709cb94138a25594..f26051f446814d24cf2bb1bb4077de455ffe54af 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/elevator.h>
 #include <linux/fd.h>
 #include <linux/hdreg.h>
+#include <linux/slab.h>
 #include <linux/syscalls.h>
 #include <linux/smp_lock.h>
 #include <linux/types.h>
index df75676f6671ea97e33b78567dae2fbfb0f75058..76e3702d53817e4aee08d092a59f07ca840145cc 100644 (file)
@@ -154,7 +154,7 @@ static struct elevator_type *elevator_get(const char *name)
 
                spin_unlock(&elv_list_lock);
 
-               sprintf(elv, "%s-iosched", name);
+               snprintf(elv, sizeof(elv), "%s-iosched", name);
 
                request_module("%s", elv);
                spin_lock(&elv_list_lock);
index be48ea51faee2e3a73fd5d5fcc1c7071772db061..8905d2a2a717c1adde73d0fb63014bb71271e4ae 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/capability.h>
 #include <linux/blkdev.h>
+#include <linux/gfp.h>
 #include <linux/blkpg.h>
 #include <linux/hdreg.h>
 #include <linux/backing-dev.h>
index 3a0d369d08c7488f8f475091ef3ee6b5dfe46211..232c4b38cd3769d31e0c79700a49f42915c683a6 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/elevator.h>
 #include <linux/bio.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 struct noop_data {
index 3e4524e6139bcf3b58e8f44a8de33a96e9333aee..76fae27ed01cb9834049e2b641d9e561ef0844e5 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/rtnetlink.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
 #include "internal.h"
index 412241ce4cfae25822a6beccf9360c9f52ccc89f..c3c196b5823a2e12c790cce27b9ae8439c20d445 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/notifier.h>
 #include <linux/rtnetlink.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
 #include "internal.h"
index ec87f53d50595f0c545df398932799d5d2054c0d..fdd8257d35d9d8133098f3592f5e3d1c2fd09261 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/raid/pq.h>
 #include <linux/async_tx.h>
+#include <linux/gfp.h>
 
 /**
  * pq_scribble_page - space to hold throwaway P or Q buffer for
index 943f2abac9b44fa6cab26fc763c1939702e7a6e8..ce038d861eb9d2706e4474e725b5c6f4eadc4a00 100644 (file)
@@ -324,6 +324,7 @@ 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)
 {
+       void *scribble = submit->scribble;
        int non_zero_srcs, i;
 
        BUG_ON(faila == failb);
@@ -332,11 +333,13 @@ async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
 
        pr_debug("%s: disks: %d len: %zu\n", __func__, disks, bytes);
 
-       /* we need to preserve the contents of 'blocks' for the async
-        * case, so punt to synchronous if a scribble buffer is not available
+       /* if a dma resource is not available or a scribble buffer is not
+        * available punt to the synchronous path.  In the 'dma not
+        * available' case be sure to use the scribble buffer to
+        * preserve the content of 'blocks' as the caller intended.
         */
-       if (!submit->scribble) {
-               void **ptrs = (void **) blocks;
+       if (!async_dma_find_channel(DMA_PQ) || !scribble) {
+               void **ptrs = scribble ? scribble : (void **) blocks;
 
                async_tx_quiesce(&submit->depend_tx);
                for (i = 0; i < disks; i++)
@@ -406,11 +409,13 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila,
 
        pr_debug("%s: disks: %d len: %zu\n", __func__, disks, bytes);
 
-       /* we need to preserve the contents of 'blocks' for the async
-        * case, so punt to synchronous if a scribble buffer is not available
+       /* if a dma resource is not available or a scribble buffer is not
+        * available punt to the synchronous path.  In the 'dma not
+        * available' case be sure to use the scribble buffer to
+        * preserve the content of 'blocks' as the caller intended.
         */
-       if (!scribble) {
-               void **ptrs = (void **) blocks;
+       if (!async_dma_find_channel(DMA_PQ) || !scribble) {
+               void **ptrs = scribble ? scribble : (void **) blocks;
 
                async_tx_quiesce(&submit->depend_tx);
                for (i = 0; i < disks; i++)
index f84f6b4301d98df03dd02c05db9d4351885bc39e..c1321935ebcc587f31e991c6a0c917986164102e 100644 (file)
@@ -20,6 +20,7 @@
  *
  */
 #include <linux/async_tx.h>
+#include <linux/gfp.h>
 #include <linux/random.h>
 
 #undef pr
index 2bb7348d8d5543364b1c75440e9d1c13ad1a0e2c..05eb32e0d9495015f1a7970a079f882d0762a5c7 100644 (file)
@@ -46,6 +46,12 @@ struct authenc_request_ctx {
        char tail[];
 };
 
+static void authenc_request_complete(struct aead_request *req, int err)
+{
+       if (err != -EINPROGRESS)
+               aead_request_complete(req, err);
+}
+
 static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
                                 unsigned int keylen)
 {
@@ -142,7 +148,7 @@ static void authenc_geniv_ahash_update_done(struct crypto_async_request *areq,
                                 crypto_aead_authsize(authenc), 1);
 
 out:
-       aead_request_complete(req, err);
+       authenc_request_complete(req, err);
 }
 
 static void authenc_geniv_ahash_done(struct crypto_async_request *areq, int err)
@@ -208,7 +214,7 @@ static void authenc_verify_ahash_update_done(struct crypto_async_request *areq,
        err = crypto_ablkcipher_decrypt(abreq);
 
 out:
-       aead_request_complete(req, err);
+       authenc_request_complete(req, err);
 }
 
 static void authenc_verify_ahash_done(struct crypto_async_request *areq,
@@ -245,7 +251,7 @@ static void authenc_verify_ahash_done(struct crypto_async_request *areq,
        err = crypto_ablkcipher_decrypt(abreq);
 
 out:
-       aead_request_complete(req, err);
+       authenc_request_complete(req, err);
 }
 
 static u8 *crypto_authenc_ahash_fb(struct aead_request *req, unsigned int flags)
@@ -379,7 +385,7 @@ static void crypto_authenc_encrypt_done(struct crypto_async_request *req,
                err = crypto_authenc_genicv(areq, iv, 0);
        }
 
-       aead_request_complete(areq, err);
+       authenc_request_complete(areq, err);
 }
 
 static int crypto_authenc_encrypt(struct aead_request *req)
@@ -420,7 +426,7 @@ static void crypto_authenc_givencrypt_done(struct crypto_async_request *req,
                err = crypto_authenc_genicv(areq, greq->giv, 0);
        }
 
-       aead_request_complete(areq, err);
+       authenc_request_complete(areq, err);
 }
 
 static int crypto_authenc_givencrypt(struct aead_givcrypt_request *req)
index 15c2eb53454194971aa3122a2d5f7f0c84773409..8d9544cf8169fd30d12fdea1d6303cfd3f4e7158 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/scatterlist.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 
 struct hmac_ctx {
index ba05e7380e76c6d340d6273c2d4602a0c597f9b1..f93cb5311182bbc6faf48c46599e4b92578410bf 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mutex.h>
 #include <linux/random.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
 static DEFINE_MUTEX(crypto_default_rng_lock);
index 5a013a8bf87a3ceb1a61036a459d71f3520ba09e..4c44912294178816688177e56faada3c85d6267d 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 
index aa3f84ccc78632ca241f0cc87d14c6a98444f946..a35159947a262f779041fe7bff86671cac00ed98 100644 (file)
@@ -18,8 +18,8 @@
 #include <crypto/hash.h>
 #include <linux/err.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/scatterlist.h>
 #include <linux/string.h>
 #include <linux/moduleparam.h>
index fc5b836f343084f74b76f516133adbe455e04ab7..b75182d8ab1460b141619cc63af15d03fe6b2475 100644 (file)
@@ -18,6 +18,7 @@
 
 #define BH_TRACE 0
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/raid/xor.h>
 #include <linux/jiffies.h>
 #include <asm/xor.h>
index 34f1e1064dbc3bdfd3b3aff8f2667b228fe2de3d..f42a03029b7c01d58193ee4b4b63d2660852a46c 100644 (file)
@@ -17,6 +17,7 @@ obj-$(CONFIG_SFI)             += sfi/
 obj-$(CONFIG_PNP)              += pnp/
 obj-$(CONFIG_ARM_AMBA)         += amba/
 
+obj-$(CONFIG_VIRTIO)           += virtio/
 obj-$(CONFIG_XEN)              += xen/
 
 # regulators early, since some subsystems rely on them to initialize
@@ -108,7 +109,6 @@ obj-$(CONFIG_PPC_PS3)               += ps3/
 obj-$(CONFIG_OF)               += of/
 obj-$(CONFIG_SSB)              += ssb/
 obj-$(CONFIG_VHOST_NET)                += vhost/
-obj-$(CONFIG_VIRTIO)           += virtio/
 obj-$(CONFIG_VLYNQ)            += vlynq/
 obj-$(CONFIG_STAGING)          += staging/
 obj-y                          += platform/
index b6ed60b57b0dd095686479862064ae42d4fc8a2c..56205a0b85dfc60eb3dc85def0a7432639ea0142 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #ifdef CONFIG_ACPI_PROCFS_POWER
index 3597d73f28f6029dcf7e6b037c216cae1018b998..d98571385656154b8ef39664852e808397846a11 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/memory_hotplug.h>
+#include <linux/slab.h>
 #include <acpi/acpi_drivers.h>
 
 #define ACPI_MEMORY_DEVICE_CLASS               "memory"
index 7e52295f1ecc020d65582eb9d1c867126673a1d6..62122134693b808f866e9b0cea0b7349bb1ac5a0 100644 (file)
 #include <linux/freezer.h>
 #include <linux/cpu.h>
 #include <linux/clockchips.h>
+#include <linux/slab.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
-#define ACPI_PROCESSOR_AGGREGATOR_CLASS        "processor_aggregator"
+#define ACPI_PROCESSOR_AGGREGATOR_CLASS        "acpi_pad"
 #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator"
 #define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80
 static DEFINE_MUTEX(isolated_cpus_lock);
index 837de669743a6824c10886ff331718e600ea0d8f..78c55508aff5adee685ca664a6f33531e469663a 100644 (file)
@@ -117,19 +117,14 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
        if (ACPI_FAILURE(status))
                return_ACPI_STATUS(status);
 
-       /* Mark wake-enabled or HW enable, or both */
-
-       if (gpe_event_info->runtime_count) {
-               /* Clear the GPE (of stale events), then enable it */
-               status = acpi_hw_clear_gpe(gpe_event_info);
-               if (ACPI_FAILURE(status))
-                       return_ACPI_STATUS(status);
-
-               /* Enable the requested runtime GPE */
-               status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
-       }
+       /* Clear the GPE (of stale events), then enable it */
+       status = acpi_hw_clear_gpe(gpe_event_info);
+       if (ACPI_FAILURE(status))
+               return_ACPI_STATUS(status);
 
-       return_ACPI_STATUS(AE_OK);
+       /* Enable the requested GPE */
+       status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
+       return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
index edf62bf5b266a1c83f7175eb6f9ba503ebd74d52..2fbfe51fb141a6858f912681d0b15e6b976b85f1 100644 (file)
@@ -468,6 +468,23 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
 
                acpi_ut_add_reference(obj_desc->field.region_obj);
 
+               /* allow full data read from EC address space */
+               if (obj_desc->field.region_obj->region.space_id ==
+                       ACPI_ADR_SPACE_EC) {
+                       if (obj_desc->common_field.bit_length > 8) {
+                               unsigned width =
+                                       ACPI_ROUND_BITS_UP_TO_BYTES(
+                                       obj_desc->common_field.bit_length);
+                               // access_bit_width is u8, don't overflow it
+                               if (width > 8)
+                                       width = 8;
+                               obj_desc->common_field.access_byte_width =
+                                                       width;
+                               obj_desc->common_field.access_bit_width =
+                                                       8 * width;
+                       }
+               }
+
                ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
                                  "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
                                  obj_desc->field.start_field_bit_offset,
index 75f39f2c166d88b3b186a0bb2633fac77165753b..3026e3fa83efc82923daf64e1f00fd2b59f23848 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/jiffies.h>
 #include <linux/async.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_ACPI_PROCFS_POWER
 #include <linux/proc_fs.h>
@@ -567,13 +568,13 @@ static int acpi_battery_update(struct acpi_battery *battery)
        result = acpi_battery_get_status(battery);
        if (result)
                return result;
-#ifdef CONFIG_ACPI_SYSFS_POWER
        if (!acpi_battery_present(battery)) {
+#ifdef CONFIG_ACPI_SYSFS_POWER
                sysfs_remove_battery(battery);
+#endif
                battery->update_time = 0;
                return 0;
        }
-#endif
        if (!battery->update_time ||
            old_present != acpi_battery_present(battery)) {
                result = acpi_battery_get_info(battery);
@@ -879,7 +880,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
 #ifdef CONFIG_ACPI_SYSFS_POWER
        /* acpi_battery_update could remove power_supply object */
        if (battery->bat.dev)
-               kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
+               power_supply_changed(&battery->bat);
 #endif
 }
 
index b70cd37561423bc360c0f9bf15cdfdfe731a34a8..743576bf1bd79e5e7b8c6fc10bafb674d88c8803 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/device.h>
 #include <linux/proc_fs.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #ifdef CONFIG_X86
 #include <asm/mpspec.h>
 #endif
@@ -526,7 +527,7 @@ int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id,
        if (!event_is_open)
                return 0;
 
-       event = kmalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
+       event = kzalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
        if (!event)
                return -ENOMEM;
 
index f53fbe307c9dba027d9e4dc53867f0579da2f783..fd51c4ab4829dee0f37446f32a15a4679065675c 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
index 5faf6c21257d3fa7f483d671dfd47b975c5d7c1a..45cd03b4630e00579d1b0840c5c1afb3657b9b94 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/acpi.h>
 #include <acpi/acpi_bus.h>
index cc421b7ae166c4ffe6a005c73b3f2714a36db2b9..146135e7a6a125731ec902e898bfe4b9364c0d6e 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/moduleparam.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <acpi/acpi_drivers.h>
 
index d9a85f1ddde6ca62ac1d529f4023df10b140714d..3fe29e992be8aa2cd324f02696388862319327e2 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/notifier.h>
@@ -1025,13 +1026,10 @@ static int dock_remove(struct dock_station *ds)
 static acpi_status
 find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
-       acpi_status status = AE_OK;
-
        if (is_dock(handle))
-               if (dock_add(handle) >= 0)
-                       status = AE_CTRL_TERMINATE;
+               dock_add(handle);
 
-       return status;
+       return AE_OK;
 }
 
 static acpi_status
index 1ac28c6a672ea3667331772f5535515d8b129e9d..f2234db85da041ae72b450ef7b73c102000933e1 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
@@ -628,12 +629,12 @@ static u32 acpi_ec_gpe_handler(void *data)
 
 static acpi_status
 acpi_ec_space_handler(u32 function, acpi_physical_address address,
-                     u32 bits, u64 *value,
+                     u32 bits, u64 *value64,
                      void *handler_context, void *region_context)
 {
        struct acpi_ec *ec = handler_context;
-       int result = 0, i;
-       u8 temp = 0;
+       int result = 0, i, bytes = bits / 8;
+       u8 *value = (u8 *)value64;
 
        if ((address > 0xFF) || !value || !handler_context)
                return AE_BAD_PARAMETER;
@@ -641,32 +642,15 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
        if (function != ACPI_READ && function != ACPI_WRITE)
                return AE_BAD_PARAMETER;
 
-       if (bits != 8 && acpi_strict)
-               return AE_BAD_PARAMETER;
-
-       if (EC_FLAGS_MSI)
+       if (EC_FLAGS_MSI || bits > 8)
                acpi_ec_burst_enable(ec);
 
-       if (function == ACPI_READ) {
-               result = acpi_ec_read(ec, address, &temp);
-               *value = temp;
-       } else {
-               temp = 0xff & (*value);
-               result = acpi_ec_write(ec, address, temp);
-       }
-
-       for (i = 8; unlikely(bits - i > 0); i += 8) {
-               ++address;
-               if (function == ACPI_READ) {
-                       result = acpi_ec_read(ec, address, &temp);
-                       (*value) |= ((u64)temp) << i;
-               } else {
-                       temp = 0xff & ((*value) >> i);
-                       result = acpi_ec_write(ec, address, temp);
-               }
-       }
+       for (i = 0; i < bytes; ++i, ++address, ++value)
+               result = (function == ACPI_READ) ?
+                       acpi_ec_read(ec, address, value) :
+                       acpi_ec_write(ec, address, *value);
 
-       if (EC_FLAGS_MSI)
+       if (EC_FLAGS_MSI || bits > 8)
                acpi_ec_burst_disable(ec);
 
        switch (result) {
index c511071bfd79bfac075012eb52f90d9a45646acc..d439314a75d8b183f4eecda98a3a6ef4dbcfa7ee 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/poll.h>
+#include <linux/gfp.h>
 #include <acpi/acpi_drivers.h>
 #include <net/netlink.h>
 #include <net/genetlink.h>
index 6d5b64b7d526e8c00f3e695d999708f55aae3540..4af6301601e701e1ad0938e47eb65df8400faa4d 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/rwsem.h>
 #include <linux/acpi.h>
 
index 4bb18c980ac6ec938408b46ee220108eff496985..1c527a19287276d5effcfda7f6ab62a020a5a44d 100644 (file)
@@ -123,6 +123,10 @@ int acpi_hest_firmware_first_pci(struct pci_dev *pci)
 {
        acpi_status status = AE_NOT_FOUND;
        struct acpi_table_header *hest = NULL;
+
+       if (acpi_disabled)
+               return 0;
+
        status = acpi_get_table(ACPI_SIG_HEST, 1, &hest);
 
        if (ACPI_SUCCESS(status)) {
index b8725461d8874aec865d8617f1c5c1ef70ae1bae..b0337d3146047d150c8a62eb8e5756282e5ea5f0 100644 (file)
@@ -61,8 +61,10 @@ int node_to_pxm(int node)
 
 void __acpi_map_pxm_to_node(int pxm, int node)
 {
-       pxm_to_node_map[pxm] = node;
-       node_to_pxm_map[node] = pxm;
+       if (pxm_to_node_map[pxm] == NUMA_NO_NODE || node < pxm_to_node_map[pxm])
+               pxm_to_node_map[pxm] = node;
+       if (node_to_pxm_map[node] == PXM_INVAL || pxm < node_to_pxm_map[node])
+               node_to_pxm_map[node] = pxm;
 }
 
 int acpi_map_pxm_to_node(int pxm)
index 8e6d8665f0aecd54a6895046c13071b831a250c6..7594f65800cf29aba1f1fbedb3563c51ed732d4a 100644 (file)
@@ -758,7 +758,14 @@ static acpi_status __acpi_os_execute(acpi_execute_type type,
        queue = hp ? kacpi_hotplug_wq :
                (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq);
        dpc->wait = hp ? 1 : 0;
-       INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+
+       if (queue == kacpi_hotplug_wq)
+               INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+       else if (queue == kacpi_notify_wq)
+               INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+       else
+               INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+
        ret = queue_work(queue, &dpc->work);
 
        if (!ret) {
@@ -1151,16 +1158,10 @@ int acpi_check_resource_conflict(const struct resource *res)
 
        if (clash) {
                if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
-                       printk("%sACPI: %s resource %s [0x%llx-0x%llx]"
-                              " conflicts with ACPI region %s"
-                              " [0x%llx-0x%llx]\n",
-                              acpi_enforce_resources == ENFORCE_RESOURCES_LAX
-                              ? KERN_WARNING : KERN_ERR,
-                              ioport ? "I/O" : "Memory", res->name,
-                              (long long) res->start, (long long) res->end,
-                              res_list_elem->name,
-                              (long long) res_list_elem->start,
-                              (long long) res_list_elem->end);
+                       printk(KERN_WARNING "ACPI: resource %s %pR"
+                              " conflicts with ACPI region %s %pR\n",
+                              res->name, res, res_list_elem->name,
+                              res_list_elem);
                        if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX)
                                printk(KERN_NOTICE "ACPI: This conflict may"
                                       " cause random problems and system"
index 843699ed93f25b9ce5613c6ca250f9509bfecf07..e4804fb05e233d8dae18aacce47835a06dca16ec 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/pm.h>
 #include <linux/pci.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
@@ -400,11 +401,13 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
         * driver reported one, then use it. Exit in any case.
         */
        if (gsi < 0) {
+               u32 dev_gsi;
                dev_warn(&dev->dev, "PCI INT %c: no GSI", pin_name(pin));
                /* Interrupt Line values above 0xF are forbidden */
-               if (dev->irq > 0 && (dev->irq <= 0xF)) {
-                       printk(" - using IRQ %d\n", dev->irq);
-                       acpi_register_gsi(&dev->dev, dev->irq,
+               if (dev->irq > 0 && (dev->irq <= 0xF) &&
+                   (acpi_isa_irq_to_gsi(dev->irq, &dev_gsi) == 0)) {
+                       printk(" - using ISA IRQ %d\n", dev->irq);
+                       acpi_register_gsi(&dev->dev, dev_gsi,
                                          ACPI_LEVEL_SENSITIVE,
                                          ACPI_ACTIVE_LOW);
                        return 0;
index 04b0f007c9b79e5d5708aeed1529069e85afb45e..8d47a5846aebc192479d943b0a4826030b5a4344 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/pm.h>
 #include <linux/pci.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
index d724736d56c8e0f25345d28c50f8b76295f4bfaa..aefce33f2a09c88d8fb3fec7b2bd7fa57a899de2 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/pci.h>
 #include <linux/pci-acpi.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
index 11f219743204fa9b8ffa6c7682d9f852d7838273..07f7fea8a4e26471ce6fabd4b90ade3c69ec9e43 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/acpi.h>
index 0f30c3c1eea475b7e2c0bb247981903ba6e006b3..ddc76787b8424f1a11d50ef0f7810b920ad05ef9 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <acpi/acpi_bus.h>
index 834c5af0de4bead0ec1b77f67d6d0357a8ccb1e6..66f67293341ec5f82a01319b2a33c16c379eb84f 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/jiffies.h>
 #include <linux/mutex.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 #include <linux/kdev_t.h>
 #include <linux/sched.h>
 #include <linux/time.h>
@@ -34,7 +35,7 @@
 #define ACPI_POWER_METER_NAME          "power_meter"
 ACPI_MODULE_NAME(ACPI_POWER_METER_NAME);
 #define ACPI_POWER_METER_DEVICE_NAME   "Power Meter"
-#define ACPI_POWER_METER_CLASS         "power_meter_resource"
+#define ACPI_POWER_METER_CLASS         "pwr_meter_resource"
 
 #define NUM_SENSORS                    17
 
index 791ac7b0f8dffbf9c7f5823a17d00871d3a6bf20..51284351418f4a5cb0f176e1475d94db1e5e4b83 100644 (file)
@@ -8,6 +8,7 @@
  *     - Added _PDC for platforms with Intel CPUs
  */
 #include <linux/dmi.h>
+#include <linux/slab.h>
 
 #include <acpi/acpi_drivers.h>
 #include <acpi/processor.h>
index b5658cdce27fec45f4d718e924af3229308249e0..5675d9747e871f1007070081fbc59557576c6d65 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/dmi.h>
 #include <linux/moduleparam.h>
 #include <linux/cpuidle.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
index 37dfce749398b35abc6ef3b00fac13ce678146b3..5939e7f7d8e9004ea794408c61b6665d52f92851 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
+#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/acpi.h>
index d648a9860b88d2557e13ae958c2a7e3b0480464b..ba1bd263d903094692c3683c9557e8b919d1d985 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_X86
 #include <asm/cpufeature.h>
index 29c6f5766dcfa1ecee58af693c1dcebde9135bd3..9ade1a5b32edbef3b07142cac70cfa116ce31b89 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/cpufreq.h>
index 89ad11138e48fa36f3e5d154cbfff73fff228509..4ff76e8174ebf716db53b1d5f2d3bbecd82ad332 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
index fd09229282eaccd8dda3ccde049b417814c3ad29..f8be23b6c12919f5d31a4cce63908b920f8f3c4b 100644 (file)
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 #include <linux/wait.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include "sbshc.h"
 
 #define PREFIX "ACPI: "
 
-#define ACPI_SMB_HC_CLASS      "smbus_host_controller"
+#define ACPI_SMB_HC_CLASS      "smbus_host_ctl"
 #define ACPI_SMB_HC_DEVICE_NAME        "ACPI SMBus HC"
 
 struct acpi_smb_hc {
index fb7fc24fe72725817ee38e970dc9b90f07998522..0338f513a010064b14b1bc8adb6a30fd0d44e4db 100644 (file)
@@ -4,10 +4,12 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/acpi.h>
 #include <linux/signal.h>
 #include <linux/kthread.h>
+#include <linux/dmi.h>
 
 #include <acpi/acpi_drivers.h>
 
@@ -1032,6 +1034,41 @@ static void acpi_add_id(struct acpi_device *device, const char *dev_id)
        list_add_tail(&id->list, &device->pnp.ids);
 }
 
+/*
+ * Old IBM workstations have a DSDT bug wherein the SMBus object
+ * lacks the SMBUS01 HID and the methods do not have the necessary "_"
+ * prefix.  Work around this.
+ */
+static int acpi_ibm_smbus_match(struct acpi_device *device)
+{
+       acpi_handle h_dummy;
+       struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
+       int result;
+
+       if (!dmi_name_in_vendors("IBM"))
+               return -ENODEV;
+
+       /* Look for SMBS object */
+       result = acpi_get_name(device->handle, ACPI_SINGLE_NAME, &path);
+       if (result)
+               return result;
+
+       if (strcmp("SMBS", path.pointer)) {
+               result = -ENODEV;
+               goto out;
+       }
+
+       /* Does it have the necessary (but misnamed) methods? */
+       result = -ENODEV;
+       if (ACPI_SUCCESS(acpi_get_handle(device->handle, "SBI", &h_dummy)) &&
+           ACPI_SUCCESS(acpi_get_handle(device->handle, "SBR", &h_dummy)) &&
+           ACPI_SUCCESS(acpi_get_handle(device->handle, "SBW", &h_dummy)))
+               result = 0;
+out:
+       kfree(path.pointer);
+       return result;
+}
+
 static void acpi_device_set_id(struct acpi_device *device)
 {
        acpi_status status;
@@ -1044,12 +1081,6 @@ static void acpi_device_set_id(struct acpi_device *device)
                if (ACPI_IS_ROOT_DEVICE(device)) {
                        acpi_add_id(device, ACPI_SYSTEM_HID);
                        break;
-               } else if (ACPI_IS_ROOT_DEVICE(device->parent)) {
-                       /* \_SB_, the only root-level namespace device */
-                       acpi_add_id(device, ACPI_BUS_HID);
-                       strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
-                       strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
-                       break;
                }
 
                status = acpi_get_object_info(device->handle, &info);
@@ -1082,6 +1113,14 @@ static void acpi_device_set_id(struct acpi_device *device)
                        acpi_add_id(device, ACPI_BAY_HID);
                else if (ACPI_SUCCESS(acpi_dock_match(device)))
                        acpi_add_id(device, ACPI_DOCK_HID);
+               else if (!acpi_ibm_smbus_match(device))
+                       acpi_add_id(device, ACPI_SMBUS_IBM_HID);
+               else if (!acpi_device_hid(device) &&
+                        ACPI_IS_ROOT_DEVICE(device->parent)) {
+                       acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */
+                       strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
+                       strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
+               }
 
                break;
        case ACPI_BUS_TYPE_POWER:
index f74834a544fd6b85eae3941ea9c5401f08a91450..baa76bbf244a3ab338e9244a58591c3431ebdc75 100644 (file)
@@ -450,6 +450,38 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
                },
        },
        {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Lenovo ThinkPad T410",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T410"),
+               },
+       },
+       {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Lenovo ThinkPad T510",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T510"),
+               },
+       },
+       {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Lenovo ThinkPad W510",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W510"),
+               },
+       },
+       {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Lenovo ThinkPad X201[s]",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201"),
+               },
+       },
+       {
        .callback = init_old_suspend_ordering,
        .ident = "Panasonic CF51-2L",
        .matches = {
@@ -458,6 +490,30 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
                DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),
                },
        },
+       {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Dell Studio 1558",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1558"),
+               },
+       },
+       {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Dell Studio 1557",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1557"),
+               },
+       },
+       {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Dell Studio 1555",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1555"),
+               },
+       },
        {},
 };
 #endif /* CONFIG_SUSPEND */
index 743f2445e2a13f48ce549c8a87e18063d17f84e5..4aaf2497613804d1fcc6673f93da998537ea8696 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/string.h>
 #include <asm/uaccess.h>
index 5d3893558cf73566e128f36e6e11482c13ccbef2..efad1f33aeb588b1c4910697ac97dfcfc2ad2b92 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/module.h>
 #include <linux/dmi.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/jiffies.h>
index c9a49f4747e675707e67aeeaa708fec550f2a5bf..b002a471c5d49d7afdb9c5db81e78ae65743c4ff 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <acpi/acpi_bus.h>
index 2ff2b6ab5b6c3c656090a4947638bdb9bb618622..a0c93b3214827a69bd4ada20fb5742b4dbbfc381 100644 (file)
 #include <linux/sort.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/dmi.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
+#include <linux/suspend.h>
 
 #define PREFIX "ACPI: "
 
@@ -88,7 +90,6 @@ module_param(allow_duplicates, bool, 0644);
 static int register_count = 0;
 static int acpi_video_bus_add(struct acpi_device *device);
 static int acpi_video_bus_remove(struct acpi_device *device, int type);
-static int acpi_video_resume(struct acpi_device *device);
 static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
 
 static const struct acpi_device_id video_device_ids[] = {
@@ -104,7 +105,6 @@ static struct acpi_driver acpi_video_bus = {
        .ops = {
                .add = acpi_video_bus_add,
                .remove = acpi_video_bus_remove,
-               .resume = acpi_video_resume,
                .notify = acpi_video_bus_notify,
                },
 };
@@ -159,6 +159,7 @@ struct acpi_video_bus {
        struct proc_dir_entry *dir;
        struct input_dev *input;
        char phys[32];  /* for input device */
+       struct notifier_block pm_nb;
 };
 
 struct acpi_video_device_flags {
@@ -998,6 +999,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
        }
 
        if (acpi_video_backlight_support()) {
+               struct backlight_properties props;
                int result;
                static int count = 0;
                char *name;
@@ -1010,12 +1012,21 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
                        return;
 
                sprintf(name, "acpi_video%d", count++);
-               device->backlight = backlight_device_register(name,
-                       NULL, device, &acpi_backlight_ops);
+               memset(&props, 0, sizeof(struct backlight_properties));
+               props.max_brightness = device->brightness->count - 3;
+               device->backlight = backlight_device_register(name, NULL, device,
+                                                             &acpi_backlight_ops,
+                                                             &props);
                kfree(name);
                if (IS_ERR(device->backlight))
                        return;
-               device->backlight->props.max_brightness = device->brightness->count-3;
+
+               /*
+                * Save current brightness level in case we have to restore it
+                * before acpi_video_device_lcd_set_level() is called next time.
+                */
+               device->backlight->props.brightness =
+                               acpi_video_get_brightness(device->backlight);
 
                result = sysfs_create_link(&device->backlight->dev.kobj,
                                           &device->dev->dev.kobj, "device");
@@ -2119,7 +2130,7 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
 {
        struct acpi_video_bus *video = acpi_driver_data(device);
        struct input_dev *input;
-       int keycode;
+       int keycode = 0;
 
        if (!video)
                return;
@@ -2155,17 +2166,19 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
                break;
 
        default:
-               keycode = KEY_UNKNOWN;
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                  "Unsupported event [0x%x]\n", event));
                break;
        }
 
        acpi_notifier_call_chain(device, event, 0);
-       input_report_key(input, keycode, 1);
-       input_sync(input);
-       input_report_key(input, keycode, 0);
-       input_sync(input);
+
+       if (keycode) {
+               input_report_key(input, keycode, 1);
+               input_sync(input);
+               input_report_key(input, keycode, 0);
+               input_sync(input);
+       }
 
        return;
 }
@@ -2176,7 +2189,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
        struct acpi_device *device = NULL;
        struct acpi_video_bus *bus;
        struct input_dev *input;
-       int keycode;
+       int keycode = 0;
 
        if (!video_device)
                return;
@@ -2217,39 +2230,48 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
                keycode = KEY_DISPLAY_OFF;
                break;
        default:
-               keycode = KEY_UNKNOWN;
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                  "Unsupported event [0x%x]\n", event));
                break;
        }
 
        acpi_notifier_call_chain(device, event, 0);
-       input_report_key(input, keycode, 1);
-       input_sync(input);
-       input_report_key(input, keycode, 0);
-       input_sync(input);
+
+       if (keycode) {
+               input_report_key(input, keycode, 1);
+               input_sync(input);
+               input_report_key(input, keycode, 0);
+               input_sync(input);
+       }
 
        return;
 }
 
-static int instance;
-static int acpi_video_resume(struct acpi_device *device)
+static int acpi_video_resume(struct notifier_block *nb,
+                               unsigned long val, void *ign)
 {
        struct acpi_video_bus *video;
        struct acpi_video_device *video_device;
        int i;
 
-       if (!device || !acpi_driver_data(device))
-               return -EINVAL;
+       switch (val) {
+       case PM_HIBERNATION_PREPARE:
+       case PM_SUSPEND_PREPARE:
+       case PM_RESTORE_PREPARE:
+               return NOTIFY_DONE;
+       }
 
-       video = acpi_driver_data(device);
+       video = container_of(nb, struct acpi_video_bus, pm_nb);
+
+       dev_info(&video->device->dev, "Restoring backlight state\n");
 
        for (i = 0; i < video->attached_count; i++) {
                video_device = video->attached_array[i].bind_info;
                if (video_device && video_device->backlight)
                        acpi_video_set_brightness(video_device->backlight);
        }
-       return AE_OK;
+
+       return NOTIFY_OK;
 }
 
 static acpi_status
@@ -2273,6 +2295,8 @@ acpi_video_bus_match(acpi_handle handle, u32 level, void *context,
        return AE_OK;
 }
 
+static int instance;
+
 static int acpi_video_bus_add(struct acpi_device *device)
 {
        struct acpi_video_bus *video;
@@ -2354,7 +2378,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
        set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
        set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
        set_bit(KEY_DISPLAY_OFF, input->keybit);
-       set_bit(KEY_UNKNOWN, input->keybit);
 
        error = input_register_device(input);
        if (error)
@@ -2366,6 +2389,10 @@ static int acpi_video_bus_add(struct acpi_device *device)
               video->flags.rom ? "yes" : "no",
               video->flags.post ? "yes" : "no");
 
+       video->pm_nb.notifier_call = acpi_video_resume;
+       video->pm_nb.priority = 0;
+       register_pm_notifier(&video->pm_nb);
+
        return 0;
 
  err_free_input_dev:
@@ -2392,6 +2419,8 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
 
        video = acpi_driver_data(device);
 
+       unregister_pm_notifier(&video->pm_nb);
+
        acpi_video_bus_stop_devices(video);
        acpi_video_bus_put_devices(video);
        acpi_video_bus_remove_fs(device);
index 6bd930b93bccf8f19eb80967429d6a980908dd29..5326af28a4100fbb4c611c8aa76bcb490938bb97 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/device.h>
 #include <linux/dmi.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
 #include <linux/libata.h>
@@ -641,6 +642,21 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { 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, 0x0581), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0582), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0583), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0584), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0585), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0586), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0587), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0588), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0589), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x058a), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x058b), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x058c), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x058d), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x058e), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x058f), 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 */
@@ -2263,7 +2279,7 @@ static void ahci_port_intr(struct ata_port *ap)
        struct ahci_port_priv *pp = ap->private_data;
        struct ahci_host_priv *hpriv = ap->host->private_data;
        int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING);
-       u32 status, qc_active;
+       u32 status, qc_active = 0;
        int rc;
 
        status = readl(port_mmio + PORT_IRQ_STAT);
@@ -2321,11 +2337,22 @@ static void ahci_port_intr(struct ata_port *ap)
                }
        }
 
-       /* pp->active_link is valid iff any command is in flight */
-       if (ap->qc_active && pp->active_link->sactive)
-               qc_active = readl(port_mmio + PORT_SCR_ACT);
-       else
-               qc_active = readl(port_mmio + PORT_CMD_ISSUE);
+       /* pp->active_link is not reliable once FBS is enabled, both
+        * PORT_SCR_ACT and PORT_CMD_ISSUE should be checked because
+        * NCQ and non-NCQ commands may be in flight at the same time.
+        */
+       if (pp->fbs_enabled) {
+               if (ap->qc_active) {
+                       qc_active = readl(port_mmio + PORT_SCR_ACT);
+                       qc_active |= readl(port_mmio + PORT_CMD_ISSUE);
+               }
+       } else {
+               /* pp->active_link is valid iff any command is in flight */
+               if (ap->qc_active && pp->active_link->sactive)
+                       qc_active = readl(port_mmio + PORT_SCR_ACT);
+               else
+                       qc_active = readl(port_mmio + PORT_CMD_ISSUE);
+       }
 
        rc = ata_qc_complete_multiple(ap, qc_active);
 
@@ -3022,6 +3049,14 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
                 * On HP dv[4-6] and HDX18 with earlier BIOSen, link
                 * to the harddisk doesn't become online after
                 * resuming from STR.  Warn and fail suspend.
+                *
+                * http://bugzilla.kernel.org/show_bug.cgi?id=12276
+                *
+                * Use dates instead of versions to match as HP is
+                * apparently recycling both product and version
+                * strings.
+                *
+                * http://bugzilla.kernel.org/show_bug.cgi?id=15462
                 */
                {
                        .ident = "dv4",
@@ -3030,7 +3065,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
                                DMI_MATCH(DMI_PRODUCT_NAME,
                                          "HP Pavilion dv4 Notebook PC"),
                        },
-                       .driver_data = "F.30", /* cutoff BIOS version */
+                       .driver_data = "20090105",      /* F.30 */
                },
                {
                        .ident = "dv5",
@@ -3039,7 +3074,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
                                DMI_MATCH(DMI_PRODUCT_NAME,
                                          "HP Pavilion dv5 Notebook PC"),
                        },
-                       .driver_data = "F.16", /* cutoff BIOS version */
+                       .driver_data = "20090506",      /* F.16 */
                },
                {
                        .ident = "dv6",
@@ -3048,7 +3083,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
                                DMI_MATCH(DMI_PRODUCT_NAME,
                                          "HP Pavilion dv6 Notebook PC"),
                        },
-                       .driver_data = "F.21",  /* cutoff BIOS version */
+                       .driver_data = "20090423",      /* F.21 */
                },
                {
                        .ident = "HDX18",
@@ -3057,7 +3092,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
                                DMI_MATCH(DMI_PRODUCT_NAME,
                                          "HP HDX18 Notebook PC"),
                        },
-                       .driver_data = "F.23",  /* cutoff BIOS version */
+                       .driver_data = "20090430",      /* F.23 */
                },
                /*
                 * Acer eMachines G725 has the same problem.  BIOS
@@ -3065,6 +3100,8 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
                 * work.  Inbetween, there are V1.06, V2.06 and V3.03
                 * that we don't have much idea about.  For now,
                 * blacklist anything older than V3.04.
+                *
+                * http://bugzilla.kernel.org/show_bug.cgi?id=15104
                 */
                {
                        .ident = "G725",
@@ -3072,19 +3109,21 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
                                DMI_MATCH(DMI_SYS_VENDOR, "eMachines"),
                                DMI_MATCH(DMI_PRODUCT_NAME, "eMachines G725"),
                        },
-                       .driver_data = "V3.04", /* cutoff BIOS version */
+                       .driver_data = "20091216",      /* V3.04 */
                },
                { }     /* terminate list */
        };
        const struct dmi_system_id *dmi = dmi_first_match(sysids);
-       const char *ver;
+       int year, month, date;
+       char buf[9];
 
        if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2))
                return false;
 
-       ver = dmi_get_system_info(DMI_BIOS_VERSION);
+       dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
+       snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
 
-       return !ver || strcmp(ver, dmi->driver_data) < 0;
+       return strcmp(buf, dmi->driver_data) < 0;
 }
 
 static bool ahci_broken_online(struct pci_dev *pdev)
index c33806654e46d5bfb984866c7bdad185c4f90ffe..83bc49fac9bb543d3857a3b81c9e5286cfb466db 100644 (file)
@@ -90,6 +90,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 #include <linux/dmi.h>
index 292fdbc0431a20e872509809ccd733683f61bb9c..7b5eea7e01dc83e5a42f0c075472ca67ef7e38ee 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/acpi.h>
 #include <linux/libata.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <scsi/scsi_device.h>
 #include "libata.h"
 
index 4a28420efff22a2059c50bbe6a15804d79c73dc1..49cffb6094a3183958fe536542c1b9208becaaf2 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/io.h>
 #include <linux/async.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
@@ -1493,6 +1494,7 @@ static int ata_hpa_resize(struct ata_device *dev)
 {
        struct ata_eh_context *ehc = &dev->link->eh_context;
        int print_info = ehc->i.flags & ATA_EHI_PRINTINFO;
+       bool unlock_hpa = ata_ignore_hpa || dev->flags & ATA_DFLAG_UNLOCK_HPA;
        u64 sectors = ata_id_n_sectors(dev->id);
        u64 native_sectors;
        int rc;
@@ -1509,7 +1511,7 @@ static int ata_hpa_resize(struct ata_device *dev)
                /* If device aborted the command or HPA isn't going to
                 * be unlocked, skip HPA resizing.
                 */
-               if (rc == -EACCES || !ata_ignore_hpa) {
+               if (rc == -EACCES || !unlock_hpa) {
                        ata_dev_printk(dev, KERN_WARNING, "HPA support seems "
                                       "broken, skipping HPA handling\n");
                        dev->horkage |= ATA_HORKAGE_BROKEN_HPA;
@@ -1524,7 +1526,7 @@ static int ata_hpa_resize(struct ata_device *dev)
        dev->n_native_sectors = native_sectors;
 
        /* nothing to do? */
-       if (native_sectors <= sectors || !ata_ignore_hpa) {
+       if (native_sectors <= sectors || !unlock_hpa) {
                if (!print_info || native_sectors == sectors)
                        return 0;
 
@@ -4185,36 +4187,51 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
                goto fail;
 
        /* verify n_sectors hasn't changed */
-       if (dev->class == ATA_DEV_ATA && n_sectors &&
-           dev->n_sectors != n_sectors) {
-               ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch "
-                              "%llu != %llu\n",
-                              (unsigned long long)n_sectors,
-                              (unsigned long long)dev->n_sectors);
-               /*
-                * Something could have caused HPA to be unlocked
-                * involuntarily.  If n_native_sectors hasn't changed
-                * and the new size matches it, keep the device.
-                */
-               if (dev->n_native_sectors == n_native_sectors &&
-                   dev->n_sectors > n_sectors &&
-                   dev->n_sectors == n_native_sectors) {
-                       ata_dev_printk(dev, KERN_WARNING,
-                                      "new n_sectors matches native, probably "
-                                      "late HPA unlock, continuing\n");
-                       /* keep using the old n_sectors */
-                       dev->n_sectors = n_sectors;
-               } else {
-                       /* restore original n_[native]_sectors and fail */
-                       dev->n_native_sectors = n_native_sectors;
-                       dev->n_sectors = n_sectors;
-                       rc = -ENODEV;
-                       goto fail;
-               }
+       if (dev->class != ATA_DEV_ATA || !n_sectors ||
+           dev->n_sectors == n_sectors)
+               return 0;
+
+       /* n_sectors has changed */
+       ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch %llu != %llu\n",
+                      (unsigned long long)n_sectors,
+                      (unsigned long long)dev->n_sectors);
+
+       /*
+        * Something could have caused HPA to be unlocked
+        * involuntarily.  If n_native_sectors hasn't changed and the
+        * new size matches it, keep the device.
+        */
+       if (dev->n_native_sectors == n_native_sectors &&
+           dev->n_sectors > n_sectors && dev->n_sectors == n_native_sectors) {
+               ata_dev_printk(dev, KERN_WARNING,
+                              "new n_sectors matches native, probably "
+                              "late HPA unlock, continuing\n");
+               /* keep using the old n_sectors */
+               dev->n_sectors = n_sectors;
+               return 0;
        }
 
-       return 0;
+       /*
+        * Some BIOSes boot w/o HPA but resume w/ HPA locked.  Try
+        * unlocking HPA in those cases.
+        *
+        * https://bugzilla.kernel.org/show_bug.cgi?id=15396
+        */
+       if (dev->n_native_sectors == n_native_sectors &&
+           dev->n_sectors < n_sectors && n_sectors == n_native_sectors &&
+           !(dev->horkage & ATA_HORKAGE_BROKEN_HPA)) {
+               ata_dev_printk(dev, KERN_WARNING,
+                              "old n_sectors matches native, probably "
+                              "late HPA lock, will try to unlock HPA\n");
+               /* try unlocking HPA */
+               dev->flags |= ATA_DFLAG_UNLOCK_HPA;
+               rc = -EIO;
+       } else
+               rc = -ENODEV;
 
+       /* restore original n_[native_]sectors and fail */
+       dev->n_native_sectors = n_native_sectors;
+       dev->n_sectors = n_sectors;
  fail:
        ata_dev_printk(dev, KERN_ERR, "revalidation failed (errno=%d)\n", rc);
        return rc;
@@ -4353,6 +4370,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "HTS541080G9SA00",    "MB4OC60D",     ATA_HORKAGE_NONCQ, },
        { "HTS541010G9SA00",    "MBZOC60D",     ATA_HORKAGE_NONCQ, },
 
+       /* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */
+       { "C300-CTFDDAC128MAG", "0001",         ATA_HORKAGE_NONCQ, },
+
        /* devices which puke on READ_NATIVE_MAX */
        { "HDS724040KLSA80",    "KFAOA20N",     ATA_HORKAGE_BROKEN_HPA, },
        { "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_HORKAGE_BROKEN_HPA },
index 9f6cfac0f2cce6ac50bf8ca2262326cad5c21201..228740f356c961ef3768411a349d146a950c3c4f 100644 (file)
@@ -879,6 +879,8 @@ static void ata_eh_set_pending(struct ata_port *ap, int fastdrain)
 void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
+       struct request_queue *q = qc->scsicmd->device->request_queue;
+       unsigned long flags;
 
        WARN_ON(!ap->ops->error_handler);
 
@@ -890,7 +892,9 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
         * Note that ATA_QCFLAG_FAILED is unconditionally set after
         * this function completes.
         */
+       spin_lock_irqsave(q->queue_lock, flags);
        blk_abort_request(qc->scsicmd->request);
+       spin_unlock_irqrestore(q->queue_lock, flags);
 }
 
 /**
@@ -1624,6 +1628,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)
        }
 
        /* okay, this error is ours */
+       memset(&tf, 0, sizeof(tf));
        rc = ata_eh_read_log_10h(dev, &tag, &tf);
        if (rc) {
                ata_link_printk(link, KERN_ERR, "failed to read log page 10h "
index 51f0ffb78cbd62af877453cd2bea3a07e999cc46..00305f41ed86397a0af8746cccd03160020a2881 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/kernel.h>
 #include <linux/libata.h>
+#include <linux/slab.h>
 #include "libata.h"
 
 const struct ata_port_operations sata_pmp_port_ops = {
index bea003a24d277268fb7cd9337e9851269e0c809c..0088cdeb0b1ee14e127a759650e087b59de6bb22 100644 (file)
@@ -33,6 +33,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/blkdev.h>
 #include <linux/spinlock.h>
index 561dec2481cb2da91bed31b037edc31e2301b57b..e3877b6843c9ad4d16b469770b9c4595cdd0a086 100644 (file)
@@ -33,6 +33,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/libata.h>
 #include <linux/highmem.h>
@@ -1667,6 +1668,7 @@ unsigned int ata_sff_host_intr(struct ata_port *ap,
 {
        struct ata_eh_info *ehi = &ap->link.eh_info;
        u8 status, host_stat = 0;
+       bool bmdma_stopped = false;
 
        VPRINTK("ata%u: protocol %d task_state %d\n",
                ap->print_id, qc->tf.protocol, ap->hsm_task_state);
@@ -1699,6 +1701,7 @@ unsigned int ata_sff_host_intr(struct ata_port *ap,
 
                        /* before we do anything else, clear DMA-Start bit */
                        ap->ops->bmdma_stop(qc);
+                       bmdma_stopped = true;
 
                        if (unlikely(host_stat & ATA_DMA_ERR)) {
                                /* error when transfering data to/from memory */
@@ -1716,8 +1719,14 @@ unsigned int ata_sff_host_intr(struct ata_port *ap,
 
        /* check main status, clearing INTRQ if needed */
        status = ata_sff_irq_status(ap);
-       if (status & ATA_BUSY)
-               goto idle_irq;
+       if (status & ATA_BUSY) {
+               if (bmdma_stopped) {
+                       /* BMDMA engine is already stopped, we're screwed */
+                       qc->err_mask |= AC_ERR_HSM;
+                       ap->hsm_task_state = HSM_ST_ERR;
+               } else
+                       goto idle_irq;
+       }
 
        /* ack bmdma irq events */
        ap->ops->sff_irq_clear(ap);
@@ -1762,13 +1771,16 @@ EXPORT_SYMBOL_GPL(ata_sff_host_intr);
 irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
+       bool retried = false;
        unsigned int i;
-       unsigned int handled = 0, polling = 0;
+       unsigned int handled, idle, polling;
        unsigned long flags;
 
        /* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
        spin_lock_irqsave(&host->lock, flags);
 
+retry:
+       handled = idle = polling = 0;
        for (i = 0; i < host->n_ports; i++) {
                struct ata_port *ap = host->ports[i];
                struct ata_queued_cmd *qc;
@@ -1782,7 +1794,8 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
                                handled |= ata_sff_host_intr(ap, qc);
                        else
                                polling |= 1 << i;
-               }
+               } else
+                       idle |= 1 << i;
        }
 
        /*
@@ -1790,7 +1803,9 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
         * asserting IRQ line, nobody cared will ensue.  Check IRQ
         * pending status if available and clear spurious IRQ.
         */
-       if (!handled) {
+       if (!handled && !retried) {
+               bool retry = false;
+
                for (i = 0; i < host->n_ports; i++) {
                        struct ata_port *ap = host->ports[i];
 
@@ -1801,12 +1816,23 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
                            !ap->ops->sff_irq_check(ap))
                                continue;
 
-                       if (printk_ratelimit())
-                               ata_port_printk(ap, KERN_INFO,
-                                               "clearing spurious IRQ\n");
+                       if (idle & (1 << i)) {
+                               ap->ops->sff_check_status(ap);
+                               ap->ops->sff_irq_clear(ap);
+                       } else {
+                               /* clear INTRQ and check if BUSY cleared */
+                               if (!(ap->ops->sff_check_status(ap) & ATA_BUSY))
+                                       retry |= true;
+                               /*
+                                * With command in flight, we can't do
+                                * sff_irq_clear() w/o racing with completion.
+                                */
+                       }
+               }
 
-                       ap->ops->sff_check_status(ap);
-                       ap->ops->sff_irq_clear(ap);
+               if (retry) {
+                       retried = true;
+                       goto retry;
                }
        }
 
index 8e5e13210426d9effb029058453f2c2cb9ae7504..1ea2be0f4b94fea1ff90137a15b891191b47bab9 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <acpi/acpi_bus.h>
 
index 5c129f99a7e36256c18772b074ac87eb95bfdcb5..66ce6a526f2732d186630cef161678aeb0052853 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <scsi/scsi_host.h>
 #include <linux/ata.h>
 #include <linux/libata.h>
index 376dd380b43c7243e214a4b74c42addfb398960f..c6a946aa252c1f05d40e847921435a40439eb201 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <linux/ata.h>
 #include <linux/clk.h>
index 6fe7ded40c6a346027bf091019ea6dc65edbdf5e..bb6e0746e07d110a5a31f561fc72c52923238031 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 
index 6cd5d5dd9e3b04a42799c9e4f2712a82505dc769..45896b3c65389ad8e43d6a091fbb0563c8c08072 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 
index b663b7ffae4bf4f9a0298910443e10a65e95f7e4..fa812e206eeb2e4670b59d23a96015d0167a44ff 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <linux/ata.h>
 #include <linux/libata.h>
index 9bde1cb5f981891536dac2656bec4fcc14d61409..5cb286fd839e62d6e4ecc51843f43a9ce4a80ea6 100644 (file)
@@ -75,6 +75,7 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 
index 4cc7bbd10ec20d441311b655ee1323801bfcb7c3..211b6438b3a015db5a9ccaa1db5da525b54a53e8 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/pmu.h>
 #include <linux/scatterlist.h>
 #include <linux/of.h>
+#include <linux/gfp.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
index 2bc2dbe30e8fe6d4635cf90f986ad866926c0feb..9f5b053611ddef3c29aa7c460643638055579377 100644 (file)
@@ -16,7 +16,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/libata.h>
 #include <linux/of_platform.h>
index 37ef416c12428e811c777b14a38248de7ab6a429..005a44483a7b5e1b76eb3b2c69cbf376f13721e0 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/libata.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/workqueue.h>
 #include <scsi/scsi_host.h>
index 147de2fd66d2f67358058a26baa024a08db28d4b..d94b8f0bd743b7613f125d34bfcee3ce582e1c4e 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <scsi/scsi_host.h>
 #include <linux/ata.h>
 #include <linux/libata.h>
@@ -423,6 +424,8 @@ static struct pcmcia_device_id pcmcia_devices[] = {
        PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
        PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
        PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
+       PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 1GB", 0x2e6d1829, 0x55d5bffb),
+       PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 4GB", 0x2e6d1829, 0x531e7d10),
        PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
        PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2      ", 0x547e66dc, 0x8671043b),
        PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
@@ -443,6 +446,8 @@ static struct pcmcia_device_id pcmcia_devices[] = {
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
+       PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF133", 0x709b1bf1, 0x7558f133),
+       PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS8GCF133", 0x709b1bf1, 0xb2f89b47),
        PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
        PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
        PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
index 45f1e10f917b473f41f19cf1859658d2f3bb95c7..0ffd631000b76daf758668321bf2f7a4b7568945 100644 (file)
@@ -19,6 +19,7 @@
  *
  */
 
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
index 237a24d41a2d2d8d17ef007d1aa41806d5f790f8..37092cfd7bc67a168a548570aaaef0947a0b72ea 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 #include <linux/dmi.h>
index 3059ec017de3fde4c4f2100d99da286ccdf93836..741e7cb69d8c269adc9d2f1f4815726cd8dee260 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 #include <linux/dmi.h>
@@ -576,6 +577,10 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                        u8 rev = isa->revision;
                        pci_dev_put(isa);
 
+                       if ((id->device == 0x0415 || id->device == 0x3164) &&
+                           (config->id != id->device))
+                               continue;
+
                        if (rev >= config->rev_min && rev <= config->rev_max)
                                break;
                }
@@ -677,6 +682,7 @@ static const struct pci_device_id via[] = {
        { PCI_VDEVICE(VIA, 0x3164), },
        { PCI_VDEVICE(VIA, 0x5324), },
        { PCI_VDEVICE(VIA, 0xC409), VIA_IDFLAG_SINGLE },
+       { PCI_VDEVICE(VIA, 0x9001), VIA_IDFLAG_SINGLE },
 
        { },
 };
index 6c65b0776a2cc900c6b97dd437a458cc7fd125ed..5904cfdb8dbed34d68cfc9aaf07df51571d04826 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
index ce4136eea08fa5f309855a621dd981a412fd6d9b..a69192b38b438411cf4b8e839cbe32dfcd357f6c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
index 4406902b4293f4ee838fd0388b89fb64b6cfc085..27dc6c86a4cd27305037cf1e41d8393c6cf9b93a 100644 (file)
@@ -39,6 +39,7 @@
  * happy to assist.
  */
 
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
index df8ee325d3ca3869c1fb6609a3432d590178d8c7..71cc0d42f9e1c015ba90d27d4a457d5e247fddc5 100644 (file)
@@ -64,6 +64,7 @@
 #include <linux/ata_platform.h>
 #include <linux/mbus.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
index 684fe04dbbb7f8200f710c578206d83bd6239030..2a98b09ab7357cca4ee654ff2b7e7e79b2ba6eb7 100644 (file)
@@ -38,6 +38,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
index 63306285c8437a8e14271013d55f53e647a762f4..5356ec00d2b44d6ea587bc09e94a8fbb8c165121 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
index 326c0cfc29b34c366c146ea0c2a6c128d5f7f2f4..92ba45e6689b2e403f66158b4380d488ff2f05a1 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
index 1370df6c420ceed4317ff3cec8800a7f00a7507d..433b6b89c795e9ba2562b407d45d0805f2340622 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
index bbcf970068ad0916a42db2fb7ea663d91d0b7011..232468f2ea90eed5ae195e32270270c62e4c7b4a 100644 (file)
@@ -81,6 +81,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
index e5bff47e8aa132415d00200ff566757d6a15177e..011e098590d16f80f714e12e8808e036a7e3c0f7 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
index 5effec6f545870a071f003923666b8b4cb310d53..6d44f07b69f8fc656b75397c26552f4170b7366d 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/mm.h>
 #include <linux/timer.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
 #include <asm/uaccess.h>
index 8af23411743c2924eead86ac7fda5f0f5fa50d19..9d18644c897e9f43ef6d8f7cd93d90c237d98322 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/mutex.h>
 #include <linux/firmware.h>
 #include <linux/ihex.h>
+#include <linux/slab.h>
 
 #include <asm/atomic.h>
 #include <asm/io.h>
index 02ad83d6b562b6e0d14142a126622b26c7e9f180..b86712167eb8fddc08d4be0cfe1843550ab9df2d 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/atm_tcp.h>
 #include <linux/bitops.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
 
index 0c302614544382992bf67fb656a001cffa9c5edd..719ec5a0dca547091df22ef8464a5bf2dcbfe241 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/atm_eni.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/atomic.h>
index cd5049af47a9a11144d58e8cceed873c2bfb2483..6e600afd06ae6d0fbbaeb96d7aa02093954771b5 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/init.h>
 #include <linux/capability.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 #include <asm/system.h>
 #include <asm/string.h>
index e8c6529dc366a6401730d4b16d12a98597d6ab0b..c213e0da0343d4d9cda4d7283664537939a3ab8a 100644 (file)
@@ -67,6 +67,7 @@
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
 #include <asm/uaccess.h>
index 4e49021e67ee465b5ecc8ffb312e1c7a88399431..54720baa7363996203a9489a0bfae45e0fa4a7da 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/wait.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
index 84672dc57f7afdebd84dbb760cfb3979d590dd97..dab5cf5274fb4d6c7a37915f9d2d7e2f86d546e8 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/capability.h>
 #include <linux/atm_idt77105.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 #include <asm/param.h>
 #include <asm/uaccess.h>
index 01f36c08cb52cb7ac5a91d3c844c4feb3cc6114d..98657a6a330d00a5ad8f1489e34784cfa3085a37 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/wait.h>
 #include <linux/jiffies.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
index 25a4c86f839b29a5436f1de6cf2829c543296435..ee9ddeb53417c7da782d252f7d9e4f8113ee44b4 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/uio.h>  
 #include <linux/init.h>  
 #include <linux/wait.h>
+#include <linux/slab.h>
 #include <asm/system.h>  
 #include <asm/io.h>  
 #include <asm/atomic.h>  
index 7fe7c324e7ef5213fa5cd616024ed8d58a84f508..cbe15a86c6698b2044b45469fa57f8d199aca15e 100644 (file)
@@ -55,6 +55,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/atmdev.h>
 #include <asm/io.h>
@@ -306,11 +307,10 @@ static void vci_bitfield_iterate(struct lanai_dev *lanai,
        const unsigned long *lp,
        void (*func)(struct lanai_dev *,vci_t vci))
 {
-       vci_t vci = find_first_bit(lp, NUM_VCI);
-       while (vci < NUM_VCI) {
+       vci_t vci;
+
+       for_each_set_bit(vci, lp, NUM_VCI)
                func(lanai, vci);
-               vci = find_next_bit(lp, NUM_VCI, vci + 1);
-       }
 }
 
 /* -------------------- BUFFER  UTILITIES: */
index 50838407b11792e61bbff23373e33ace90ab0a8d..b7473a6110a7600b8bbfdbab35a3289618cd12c7 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
index 51eed679a0596dd959b713743777cc430da0e4db..ded76c4c9f4f1599d6b8087eff93d9247e4f8526 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/firmware.h>
 #include <linux/ctype.h>
 #include <linux/swab.h>
+#include <linux/slab.h>
 
 #define VERSION "0.07"
 #define PTAG "solos-pci"
index 6dd3f591996820be5580044d7f14d21043ea30ca..da4b91ffa53e7aade73d36ed12819853ae2ffff6 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/capability.h>
 #include <linux/atm_suni.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 #include <asm/param.h>
 #include <asm/uaccess.h>
index fc8cb07c24779033dd95bfa1e7d3c343bd50836c..c45ae0573bbd2cb69c43f7057f3954ee638b46dc 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/atmdev.h>
 #include <linux/sonet.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
 
index 2e9635be048c2fdb4e8b4773a49464558ba4f351..702accec89e9d3f42aec6ef905d278be4dd65650 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/capability.h>
 #include <linux/bitops.h>
 #include <linux/wait.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 #include <asm/system.h>
 #include <asm/string.h>
index eacb175f6bd37a4e5c4314c65a039a1fb04b91d8..49758593a5ba6d79c283df0317ef961b70c62729 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/cdev.h>
 #include <linux/delay.h>
 #include <linux/device.h>
index b0ca5a47f47d99dbf5b7572e266091548fb2f407..3fecfb446d90b0e09c257da5950aa4cde7581061 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/fb.h>
 #include <linux/mm.h>
 #include <linux/platform_device.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/uaccess.h>
 #include <linux/cfag12864b.h>
index b9cda053d3c0c20182a264c6da5424fe872c6e5e..8fc200b2e2c0a3ceed42364b467a2ea26b574fcf 100644 (file)
@@ -328,6 +328,7 @@ attribute_container_add_attrs(struct device *classdev)
                return sysfs_create_group(&classdev->kobj, cont->grp);
 
        for (i = 0; attrs[i]; i++) {
+               sysfs_attr_init(&attrs[i]->attr);
                error = device_create_file(classdev, attrs[i]);
                if (error)
                        return error;
index 71f6af5c8b0bdfda4fce6fd9bf83cb82ebdadcf7..12eec3f633b13f0b6e6544a6ce895ff298d4cd84 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/string.h>
 #include "base.h"
index 0147f476b8a9d81be9792aa5572617d910ebaaaa..9c6a0d6408e7b7a609bdd2170c75def1277326ca 100644 (file)
@@ -219,6 +219,8 @@ static void class_create_release(struct class *cls)
  * This is used to create a struct class pointer that can then be used
  * in calls to device_create().
  *
+ * Returns &struct class pointer on success, or ERR_PTR() on error.
+ *
  * Note, the pointer created here is to be destroyed when finished by
  * making a call to class_destroy().
  */
index ef55df34ddd0274e66d7328bad4f230f83884e9a..b56a0ba31d4a0f7f2c677bb20a216bf1698cfe88 100644 (file)
@@ -1345,6 +1345,8 @@ static void root_device_release(struct device *dev)
  * 'module' symlink which points to the @owner directory
  * in sysfs.
  *
+ * Returns &struct device pointer on success, or ERR_PTR() on error.
+ *
  * Note: You probably want to use root_device_register().
  */
 struct device *__root_device_register(const char *name, struct module *owner)
@@ -1432,6 +1434,8 @@ static void device_create_release(struct device *dev)
  * Any further sysfs files that might be required can be created using this
  * pointer.
  *
+ * Returns &struct device pointer on success, or ERR_PTR() on error.
+ *
  * Note: the struct class passed to this function must have previously
  * been created with a call to class_create().
  */
@@ -1492,6 +1496,8 @@ EXPORT_SYMBOL_GPL(device_create_vargs);
  * Any further sysfs files that might be required can be created using this
  * pointer.
  *
+ * Returns &struct device pointer on success, or ERR_PTR() on error.
+ *
  * Note: the struct class passed to this function must have previously
  * been created with a call to class_create().
  */
index 7036e8e96ab89080231f3287f52cac1e801e6d0b..f35719aab3c1f38f046a118e8326d6022a51e2cf 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/topology.h>
 #include <linux/device.h>
 #include <linux/node.h>
+#include <linux/gfp.h>
 
 #include "base.h"
 
@@ -79,24 +80,24 @@ void unregister_cpu(struct cpu *cpu)
 }
 
 #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
-static ssize_t cpu_probe_store(struct sys_device *dev,
-                               struct sysdev_attribute *attr,
-                               const char *buf,
+static ssize_t cpu_probe_store(struct sysdev_class *class,
+                              struct sysdev_class_attribute *attr,
+                              const char *buf,
                               size_t count)
 {
        return arch_cpu_probe(buf, count);
 }
 
-static ssize_t cpu_release_store(struct sys_device *dev,
-                               struct sysdev_attribute *attr,
-                               const char *buf,
+static ssize_t cpu_release_store(struct sysdev_class *class,
+                                struct sysdev_class_attribute *attr,
+                                const char *buf,
                                 size_t count)
 {
        return arch_cpu_release(buf, count);
 }
 
-static SYSDEV_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
-static SYSDEV_ATTR(release, S_IWUSR, NULL, cpu_release_store);
+static SYSDEV_CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
+static SYSDEV_CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store);
 #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
 
 #else /* ... !CONFIG_HOTPLUG_CPU */
index 05dd307e8f024038bfe6e9d762e3dff1dd6281ee..cf7a0c78805278e64f195921b3991c577691da66 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/device.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "base.h"
 
index dac478c6e46089c5bf8070dfa4127659b44fb6ec..057cf11326bff9c84e3e18b24cee28250a49562a 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/cred.h>
 #include <linux/sched.h>
 #include <linux/init_task.h>
+#include <linux/slab.h>
 
 static struct vfsmount *dev_mnt;
 
index 962a3b574f21eb4d5d4fed4b84ab91e64b5e453e..d4d8ce53886aa8276165ef151aab2dca46b2ecac 100644 (file)
@@ -2,6 +2,7 @@
  * Coherent per-device memory handling.
  * Borrowed from i386
  */
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/dma-mapping.h>
 
index ca9186f70a695378c9bc9f5e7622d1d601cc6787..763d59c1eb65d0e329a727b1f58953e6ab2bca9b 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 /*
  * Managed DMA API
index 90c9fff09eadff6fbbd2e554e39db3653867ea9c..b631f7c59453c2a51f1ce4d65c6fec458cde51e3 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include "base.h"
 
index d0dc26ad53871df760302961376ed779c58a113c..985da11174e7a139a9269fce26d29ea2f1a0e32b 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kthread.h>
 #include <linux/highmem.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #define to_dev(obj) container_of(obj, struct device, kobj)
 
@@ -78,6 +79,7 @@ firmware_timeout_show(struct class *class,
 /**
  * firmware_timeout_store - set number of seconds to wait for firmware
  * @class: device class pointer
+ * @attr: device attribute pointer
  * @buf: buffer to scan for timeout value
  * @count: number of bytes in @buf
  *
@@ -442,6 +444,7 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p,
        fw_priv = dev_get_drvdata(f_dev);
 
        fw_priv->fw = fw;
+       sysfs_bin_attr_init(&fw_priv->attr_data);
        retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data);
        if (retval) {
                dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__);
index 8ad4ffea6920429e0185dd2b7675bd468ed5c354..6e6b6a11b3ced64d1c90e3c9d35d25823f6b5ccf 100644 (file)
@@ -80,20 +80,6 @@ void iommu_detach_device(struct iommu_domain *domain, struct device *dev)
 }
 EXPORT_SYMBOL_GPL(iommu_detach_device);
 
-int iommu_map_range(struct iommu_domain *domain, unsigned long iova,
-                   phys_addr_t paddr, size_t size, int prot)
-{
-       return iommu_ops->map(domain, iova, paddr, size, prot);
-}
-EXPORT_SYMBOL_GPL(iommu_map_range);
-
-void iommu_unmap_range(struct iommu_domain *domain, unsigned long iova,
-                     size_t size)
-{
-       iommu_ops->unmap(domain, iova, size);
-}
-EXPORT_SYMBOL_GPL(iommu_unmap_range);
-
 phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
                               unsigned long iova)
 {
@@ -107,3 +93,32 @@ int iommu_domain_has_cap(struct iommu_domain *domain,
        return iommu_ops->domain_has_cap(domain, cap);
 }
 EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
+
+int iommu_map(struct iommu_domain *domain, unsigned long iova,
+             phys_addr_t paddr, int gfp_order, int prot)
+{
+       unsigned long invalid_mask;
+       size_t size;
+
+       size         = 0x1000UL << gfp_order;
+       invalid_mask = size - 1;
+
+       BUG_ON((iova | paddr) & invalid_mask);
+
+       return iommu_ops->map(domain, iova, paddr, gfp_order, prot);
+}
+EXPORT_SYMBOL_GPL(iommu_map);
+
+int iommu_unmap(struct iommu_domain *domain, unsigned long iova, int gfp_order)
+{
+       unsigned long invalid_mask;
+       size_t size;
+
+       size         = 0x1000UL << gfp_order;
+       invalid_mask = size - 1;
+
+       BUG_ON(iova & invalid_mask);
+
+       return iommu_ops->unmap(domain, iova, gfp_order);
+}
+EXPORT_SYMBOL_GPL(iommu_unmap);
index 2f8691511190f921e1e6a75beab9581d123d68d7..933442f40321b1889b183cf4396486a4c35ad96f 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mm.h>
 #include <linux/mutex.h>
 #include <linux/stat.h>
+#include <linux/slab.h>
 
 #include <asm/atomic.h>
 #include <asm/uaccess.h>
@@ -312,7 +313,7 @@ static ssize_t
 print_block_size(struct sysdev_class *class, struct sysdev_class_attribute *attr,
                 char *buf)
 {
-       return sprintf(buf, "%#lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
+       return sprintf(buf, "%lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
 }
 
 static SYSDEV_CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
@@ -429,12 +430,16 @@ static inline int memory_fail_init(void)
  * differentiation between which *physical* devices each
  * section belongs to...
  */
+int __weak arch_get_memory_phys_device(unsigned long start_pfn)
+{
+       return 0;
+}
 
 static int add_memory_block(int nid, struct mem_section *section,
-                       unsigned long state, int phys_device,
-                       enum mem_add_context context)
+                       unsigned long state, enum mem_add_context context)
 {
        struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+       unsigned long start_pfn;
        int ret = 0;
 
        if (!mem)
@@ -443,7 +448,8 @@ static int add_memory_block(int nid, struct mem_section *section,
        mem->phys_index = __section_nr(section);
        mem->state = state;
        mutex_init(&mem->state_mutex);
-       mem->phys_device = phys_device;
+       start_pfn = section_nr_to_pfn(mem->phys_index);
+       mem->phys_device = arch_get_memory_phys_device(start_pfn);
 
        ret = register_memory(mem, section);
        if (!ret)
@@ -515,7 +521,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section,
  */
 int register_new_memory(int nid, struct mem_section *section)
 {
-       return add_memory_block(nid, section, MEM_OFFLINE, 0, HOTPLUG);
+       return add_memory_block(nid, section, MEM_OFFLINE, HOTPLUG);
 }
 
 int unregister_memory_section(struct mem_section *section)
@@ -548,7 +554,7 @@ int __init memory_dev_init(void)
                if (!present_section_nr(i))
                        continue;
                err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE,
-                                       0, BOOT);
+                                      BOOT);
                if (!ret)
                        ret = err;
        }
index 103be9cacb050bc23364cb3718b2ea51734bfc21..f32f2f9b7be5fadb9a6f16300dc91cfcd7065ea3 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include "base.h"
 
index ad43185ec15adebc4d48d80ffb58275b18827da3..057979a19eea10283e5db959580a6f0208c8ab80 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/cpu.h>
 #include <linux/device.h>
 #include <linux/swap.h>
+#include <linux/slab.h>
 
 static struct sysdev_class_attribute *node_state_attrs[];
 
@@ -165,8 +166,11 @@ static ssize_t node_read_distance(struct sys_device * dev,
        int len = 0;
        int i;
 
-       /* buf currently PAGE_SIZE, need ~4 chars per node */
-       BUILD_BUG_ON(MAX_NUMNODES*4 > PAGE_SIZE/2);
+       /*
+        * buf is currently PAGE_SIZE in length and each node needs 4 chars
+        * at the most (distance + space or newline).
+        */
+       BUILD_BUG_ON(MAX_NUMNODES * 4 > PAGE_SIZE);
 
        for_each_online_node(i)
                len += sprintf(buf + len, "%s%d", i ? " " : "", node_distance(nid, i));
index 1ba9d617d241ba170842eba208b5dca64783960a..c5fbe198fbdb54eb269a0b8c0b3e94b6ba71e2fe 100644 (file)
@@ -187,7 +187,7 @@ EXPORT_SYMBOL_GPL(platform_device_alloc);
  * released.
  */
 int platform_device_add_resources(struct platform_device *pdev,
-                                 struct resource *res, unsigned int num)
+                                 const struct resource *res, unsigned int num)
 {
        struct resource *r;
 
@@ -362,10 +362,12 @@ EXPORT_SYMBOL_GPL(platform_device_unregister);
  * enumeration tasks, they don't fully conform to the Linux driver model.
  * In particular, when such drivers are built as modules, they can't be
  * "hotplugged".
+ *
+ * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
  */
 struct platform_device *platform_device_register_simple(const char *name,
                                                        int id,
-                                                       struct resource *res,
+                                                       const struct resource *res,
                                                        unsigned int num)
 {
        struct platform_device *pdev;
@@ -408,6 +410,8 @@ EXPORT_SYMBOL_GPL(platform_device_register_simple);
  * allocated for the device allows drivers using such devices to be
  * unloaded without waiting for the last reference to the device to be
  * dropped.
+ *
+ * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
  */
 struct platform_device *platform_device_register_data(
                struct device *parent,
@@ -559,6 +563,8 @@ EXPORT_SYMBOL_GPL(platform_driver_probe);
  *
  * Use this in legacy-style modules that probe hardware directly and
  * register a single platform device and corresponding platform driver.
+ *
+ * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
  */
 struct platform_device * __init_or_module platform_create_bundle(
                        struct platform_driver *driver,
@@ -1052,9 +1058,11 @@ static __initdata LIST_HEAD(early_platform_driver_list);
 static __initdata LIST_HEAD(early_platform_device_list);
 
 /**
- * early_platform_driver_register
+ * early_platform_driver_register - register early platform driver
  * @epdrv: early_platform driver structure
  * @buf: string passed from early_param()
+ *
+ * Helper function for early_platform_init() / early_platform_init_buffer()
  */
 int __init early_platform_driver_register(struct early_platform_driver *epdrv,
                                          char *buf)
@@ -1106,9 +1114,12 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv,
 }
 
 /**
- * early_platform_add_devices - add a numbers of early platform devices
+ * early_platform_add_devices - adds a number of early platform devices
  * @devs: array of early platform devices to add
  * @num: number of early platform devices in array
+ *
+ * Used by early architecture code to register early platform devices and
+ * their platform data.
  */
 void __init early_platform_add_devices(struct platform_device **devs, int num)
 {
@@ -1128,8 +1139,12 @@ void __init early_platform_add_devices(struct platform_device **devs, int num)
 }
 
 /**
- * early_platform_driver_register_all
+ * early_platform_driver_register_all - register early platform drivers
  * @class_str: string to identify early platform driver class
+ *
+ * Used by architecture code to register all early platform drivers
+ * for a certain class. If omitted then only early platform drivers
+ * with matching kernel command line class parameters will be registered.
  */
 void __init early_platform_driver_register_all(char *class_str)
 {
@@ -1151,7 +1166,7 @@ void __init early_platform_driver_register_all(char *class_str)
 }
 
 /**
- * early_platform_match
+ * early_platform_match - find early platform device matching driver
  * @epdrv: early platform driver structure
  * @id: id to match against
  */
@@ -1169,7 +1184,7 @@ early_platform_match(struct early_platform_driver *epdrv, int id)
 }
 
 /**
- * early_platform_left
+ * early_platform_left - check if early platform driver has matching devices
  * @epdrv: early platform driver structure
  * @id: return true if id or above exists
  */
@@ -1187,7 +1202,7 @@ static  __init int early_platform_left(struct early_platform_driver *epdrv,
 }
 
 /**
- * early_platform_driver_probe_id
+ * early_platform_driver_probe_id - probe drivers matching class_str and id
  * @class_str: string to identify early platform driver class
  * @id: id to match against
  * @nr_probe: number of platform devices to successfully probe before exiting
@@ -1257,10 +1272,14 @@ static int __init early_platform_driver_probe_id(char *class_str,
 }
 
 /**
- * early_platform_driver_probe
+ * early_platform_driver_probe - probe a class of registered drivers
  * @class_str: string to identify early platform driver class
  * @nr_probe: number of platform devices to successfully probe before exiting
  * @user_only: only probe user specified early platform devices
+ *
+ * Used by architecture code to probe registered early platform drivers
+ * within a certain class. For probe to happen a registered early platform
+ * device matching a registered early platform driver is needed.
  */
 int __init early_platform_driver_probe(char *class_str,
                                       int nr_probe,
index d477f4dc5e514b202aaaa1efe0a6b20b3eeb62e3..941fcb87e52a12765df2aaa2e2ab21267693af9f 100644 (file)
@@ -439,8 +439,23 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
        if (dev->bus && dev->bus->pm) {
                pm_dev_dbg(dev, state, "EARLY ");
                error = pm_noirq_op(dev, dev->bus->pm, state);
+               if (error)
+                       goto End;
        }
 
+       if (dev->type && dev->type->pm) {
+               pm_dev_dbg(dev, state, "EARLY type ");
+               error = pm_noirq_op(dev, dev->type->pm, state);
+               if (error)
+                       goto End;
+       }
+
+       if (dev->class && dev->class->pm) {
+               pm_dev_dbg(dev, state, "EARLY class ");
+               error = pm_noirq_op(dev, dev->class->pm, state);
+       }
+
+End:
        TRACE_RESUME(error);
        return error;
 }
@@ -735,10 +750,26 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
 {
        int error = 0;
 
+       if (dev->class && dev->class->pm) {
+               pm_dev_dbg(dev, state, "LATE class ");
+               error = pm_noirq_op(dev, dev->class->pm, state);
+               if (error)
+                       goto End;
+       }
+
+       if (dev->type && dev->type->pm) {
+               pm_dev_dbg(dev, state, "LATE type ");
+               error = pm_noirq_op(dev, dev->type->pm, state);
+               if (error)
+                       goto End;
+       }
+
        if (dev->bus && dev->bus->pm) {
                pm_dev_dbg(dev, state, "LATE ");
                error = pm_noirq_op(dev, dev->bus->pm, state);
        }
+
+End:
        return error;
 }
 
index 8980feec5d14e37bbbb947bcd91900d147582ff4..9354dc10a3635b25e87ca10fe92babffb9faba9d 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/pm.h>
 #include <linux/device.h>
index 459f1bc25a7b813e1094f54903d57852825983af..c5f22bb0a48efb78422f770bb298fdcc94203d96 100644 (file)
@@ -2533,7 +2533,6 @@ static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
        Controller->RequestQueue[n] = RequestQueue;
        blk_queue_bounce_limit(RequestQueue, Controller->BounceBufferLimit);
        RequestQueue->queuedata = Controller;
-       blk_queue_max_hw_segments(RequestQueue, Controller->DriverScatterGatherLimit);
        blk_queue_max_segments(RequestQueue, Controller->DriverScatterGatherLimit);
        blk_queue_max_hw_sectors(RequestQueue, Controller->MaxBlocksPerCommand);
        disk->queue = RequestQueue;
index 0552258390240ae8f71ebf89d09c4542eff749e9..832798aa14f6318f34c053577c809a126038cf16 100644 (file)
@@ -54,6 +54,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <linux/fd.h>
 #include <linux/hdreg.h>
@@ -65,6 +66,7 @@
 #include <linux/blkdev.h>
 #include <linux/elevator.h>
 #include <linux/interrupt.h>
+#include <linux/platform_device.h>
 
 #include <asm/setup.h>
 #include <asm/uaccess.h>
@@ -1695,34 +1697,18 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
        return get_disk(unit[drive].gendisk);
 }
 
-static int __init amiga_floppy_init(void)
+static int __init amiga_floppy_probe(struct platform_device *pdev)
 {
        int i, ret;
 
-       if (!MACH_IS_AMIGA)
-               return -ENODEV;
-
-       if (!AMIGAHW_PRESENT(AMI_FLOPPY))
-               return -ENODEV;
-
        if (register_blkdev(FLOPPY_MAJOR,"fd"))
                return -EBUSY;
 
-       /*
-        *  We request DSKPTR, DSKLEN and DSKDATA only, because the other
-        *  floppy registers are too spreaded over the custom register space
-        */
-       ret = -EBUSY;
-       if (!request_mem_region(CUSTOM_PHYSADDR+0x20, 8, "amiflop [Paula]")) {
-               printk("fd: cannot get floppy registers\n");
-               goto out_blkdev;
-       }
-
        ret = -ENOMEM;
        if ((raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE, "Floppy")) ==
            NULL) {
                printk("fd: cannot get chip mem buffer\n");
-               goto out_memregion;
+               goto out_blkdev;
        }
 
        ret = -EBUSY;
@@ -1791,18 +1777,13 @@ out_irq2:
        free_irq(IRQ_AMIGA_DSKBLK, NULL);
 out_irq:
        amiga_chip_free(raw_buf);
-out_memregion:
-       release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
 out_blkdev:
        unregister_blkdev(FLOPPY_MAJOR,"fd");
        return ret;
 }
 
-module_init(amiga_floppy_init);
-#ifdef MODULE
-
 #if 0 /* not safe to unload */
-void cleanup_module(void)
+static int __exit amiga_floppy_remove(struct platform_device *pdev)
 {
        int i;
 
@@ -1819,12 +1800,25 @@ void cleanup_module(void)
        custom.dmacon = DMAF_DISK; /* disable DMA */
        amiga_chip_free(raw_buf);
        blk_cleanup_queue(floppy_queue);
-       release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
        unregister_blkdev(FLOPPY_MAJOR, "fd");
 }
 #endif
 
-#else
+static struct platform_driver amiga_floppy_driver = {
+       .driver   = {
+               .name   = "amiga-floppy",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init amiga_floppy_init(void)
+{
+       return platform_driver_probe(&amiga_floppy_driver, amiga_floppy_probe);
+}
+
+module_init(amiga_floppy_init);
+
+#ifndef MODULE
 static int __init amiga_floppy_setup (char *str)
 {
        int n;
@@ -1839,3 +1833,5 @@ static int __init amiga_floppy_setup (char *str)
 
 __setup("floppy=", amiga_floppy_setup);
 #endif
+
+MODULE_ALIAS("platform:amiga-floppy");
index 3af97d4da2db7ac30dc808da80b036acbd848256..035cefe4045ae76f076f3d56a85b058c3bb68fc7 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/backing-dev.h>
 #include <linux/fs.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 #include <linux/genhd.h>
 #include <linux/netdevice.h>
 #include "aoe.h"
index 62141ec09a227f2637464173f1f52af5bcac9f33..4a1b9e7464aa51e0d529ba920bbc597d5f9a381d 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/blkdev.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/skbuff.h>
 #include "aoe.h"
index 64a223b0cc2229fb14250dd60fd572b8f8bd9c59..5674bd01d96dffc86a8818f6a62a72207092c71e 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <linux/ata.h>
+#include <linux/slab.h>
 #include <linux/hdreg.h>
 #include <linux/blkdev.h>
 #include <linux/skbuff.h>
index fa67027789aab80ca8c11deccad4e2d3ec225697..0849280bfc1c11adb175e4034126b269f52b3492 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/blkdev.h>
 #include <linux/netdevice.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include "aoe.h"
 
 static void dummy_timer(ulong);
index ce0d62cd71b265de46e12447b3a665b10c479131..4d3bc0d49df59394ea550a74c05c4ad0c84c436b 100644 (file)
@@ -4,6 +4,7 @@
  * Ethernet portion of AoE driver
  */
 
+#include <linux/gfp.h>
 #include <linux/hdreg.h>
 #include <linux/blkdev.h>
 #include <linux/netdevice.h>
index c6ddeacb77fdaa2541f55c294ec25dfa0dd7004b..6081e81d5738b3fecb90da4350d7325b6b78d28a 100644 (file)
@@ -15,9 +15,9 @@
 #include <linux/blkdev.h>
 #include <linux/bio.h>
 #include <linux/highmem.h>
-#include <linux/gfp.h>
 #include <linux/radix-tree.h>
 #include <linux/buffer_head.h> /* invalidate_bh_lrus() */
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
index 9e3af307aae1c3e50c506aadb776b4cda4549224..eb5ff0531cfb33cf41df0a089bf8eb7a0119099f 100644 (file)
@@ -3341,6 +3341,7 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id)
                                        printk(KERN_WARNING
                                               "cciss: controller cciss%d failed, stopping.\n",
                                               h->ctlr);
+                                       spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
                                        fail_all_cmds(h->ctlr);
                                        return IRQ_HANDLED;
                                }
index 17956ff6a08dea7b4de01e707553de42ca60bd22..df018990c42252f59f4e57c40abddabb3118368f 100644 (file)
@@ -536,7 +536,9 @@ static void atodb_endio(struct bio *bio, int error)
        put_ldev(mdev);
 }
 
+/* sector to word */
 #define S2W(s) ((s)<<(BM_EXT_SHIFT-BM_BLOCK_SHIFT-LN2_BPL))
+
 /* activity log to on disk bitmap -- prepare bio unless that sector
  * is already covered by previously prepared bios */
 static int atodb_prepare_unless_covered(struct drbd_conf *mdev,
@@ -546,13 +548,20 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev,
 {
        struct bio *bio;
        struct page *page;
-       sector_t on_disk_sector = enr + mdev->ldev->md.md_offset
-                                     + mdev->ldev->md.bm_offset;
+       sector_t on_disk_sector;
        unsigned int page_offset = PAGE_SIZE;
        int offset;
        int i = 0;
        int err = -ENOMEM;
 
+       /* We always write aligned, full 4k blocks,
+        * so we can ignore the logical_block_size (for now) */
+       enr &= ~7U;
+       on_disk_sector = enr + mdev->ldev->md.md_offset
+                            + mdev->ldev->md.bm_offset;
+
+       D_ASSERT(!(on_disk_sector & 7U));
+
        /* Check if that enr is already covered by an already created bio.
         * Caution, bios[] is not NULL terminated,
         * but only initialized to all NULL.
@@ -588,7 +597,7 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev,
 
        offset = S2W(enr);
        drbd_bm_get_lel(mdev, offset,
-                       min_t(size_t, S2W(1), drbd_bm_words(mdev) - offset),
+                       min_t(size_t, S2W(8), drbd_bm_words(mdev) - offset),
                        kmap(page) + page_offset);
        kunmap(page);
 
@@ -597,7 +606,7 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev,
        bio->bi_bdev = mdev->ldev->md_bdev;
        bio->bi_sector = on_disk_sector;
 
-       if (bio_add_page(bio, page, MD_SECTOR_SIZE, page_offset) != MD_SECTOR_SIZE)
+       if (bio_add_page(bio, page, 4096, page_offset) != 4096)
                goto out_put_page;
 
        atomic_inc(&wc->count);
@@ -1327,7 +1336,7 @@ int drbd_rs_del_all(struct drbd_conf *mdev)
                /* ok, ->resync is there. */
                for (i = 0; i < mdev->resync->nr_elements; i++) {
                        e = lc_element_by_index(mdev->resync, i);
-                       bm_ext = e ? lc_entry(e, struct bm_extent, lce) : NULL;
+                       bm_ext = lc_entry(e, struct bm_extent, lce);
                        if (bm_ext->lce.lc_number == LC_FREE)
                                continue;
                        if (bm_ext->lce.lc_number == mdev->resync_wenr) {
index b61057e7788219f6a574aa35df82d6e9d532c526..3390716898d5aaf429b8c08db34cd28ff68ed569 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/vmalloc.h>
 #include <linux/string.h>
 #include <linux/drbd.h>
+#include <linux/slab.h>
 #include <asm/kmap_types.h>
 #include "drbd_int.h"
 
@@ -66,7 +67,7 @@ struct drbd_bitmap {
        size_t   bm_words;
        size_t   bm_number_of_pages;
        sector_t bm_dev_capacity;
-       struct semaphore bm_change; /* serializes resize operations */
+       struct mutex bm_change; /* serializes resize operations */
 
        atomic_t bm_async_io;
        wait_queue_head_t bm_io_wait;
@@ -114,7 +115,7 @@ void drbd_bm_lock(struct drbd_conf *mdev, char *why)
                return;
        }
 
-       trylock_failed = down_trylock(&b->bm_change);
+       trylock_failed = !mutex_trylock(&b->bm_change);
 
        if (trylock_failed) {
                dev_warn(DEV, "%s going to '%s' but bitmap already locked for '%s' by %s\n",
@@ -125,7 +126,7 @@ void drbd_bm_lock(struct drbd_conf *mdev, char *why)
                    b->bm_task == mdev->receiver.task ? "receiver" :
                    b->bm_task == mdev->asender.task  ? "asender"  :
                    b->bm_task == mdev->worker.task   ? "worker"   : "?");
-               down(&b->bm_change);
+               mutex_lock(&b->bm_change);
        }
        if (__test_and_set_bit(BM_LOCKED, &b->bm_flags))
                dev_err(DEV, "FIXME bitmap already locked in bm_lock\n");
@@ -147,7 +148,7 @@ void drbd_bm_unlock(struct drbd_conf *mdev)
 
        b->bm_why  = NULL;
        b->bm_task = NULL;
-       up(&b->bm_change);
+       mutex_unlock(&b->bm_change);
 }
 
 /* word offset to long pointer */
@@ -295,7 +296,7 @@ int drbd_bm_init(struct drbd_conf *mdev)
        if (!b)
                return -ENOMEM;
        spin_lock_init(&b->bm_lock);
-       init_MUTEX(&b->bm_change);
+       mutex_init(&b->bm_change);
        init_waitqueue_head(&b->bm_io_wait);
 
        mdev->bitmap = b;
index d9301e861d9f355f611128f625cd470ad05b3383..e5e86a78182001fc0894f0aa156470a75abf9154 100644 (file)
@@ -261,6 +261,9 @@ static inline const char *cmdname(enum drbd_packets cmd)
                [P_OV_REQUEST]          = "OVRequest",
                [P_OV_REPLY]            = "OVReply",
                [P_OV_RESULT]           = "OVResult",
+               [P_CSUM_RS_REQUEST]     = "CsumRSRequest",
+               [P_RS_IS_IN_SYNC]       = "CsumRSIsInSync",
+               [P_COMPRESSED_BITMAP]   = "CBitmap",
                [P_MAX_CMD]             = NULL,
        };
 
@@ -443,13 +446,18 @@ struct p_rs_param_89 {
        char csums_alg[SHARED_SECRET_MAX];
 } __packed;
 
+enum drbd_conn_flags {
+       CF_WANT_LOSE = 1,
+       CF_DRY_RUN = 2,
+};
+
 struct p_protocol {
        struct p_header head;
        u32 protocol;
        u32 after_sb_0p;
        u32 after_sb_1p;
        u32 after_sb_2p;
-       u32 want_lose;
+       u32 conn_flags;
        u32 two_primaries;
 
               /* Since protocol version 87 and higher. */
@@ -791,6 +799,8 @@ enum {
                                 * while this is set. */
        RESIZE_PENDING,         /* Size change detected locally, waiting for the response from
                                 * the peer, if it changed there as well. */
+       CONN_DRY_RUN,           /* Expect disconnect after resync handshake. */
+       GOT_PING_ACK,           /* set when we receive a ping_ack packet, misc wait gets woken */
 };
 
 struct drbd_bitmap; /* opaque for drbd_conf */
index ab871e00ffc5b91702f3adfa6dbf2eeaa4047e24..93d1f9b469d4cce769a5923686bd96753969a491 100644 (file)
@@ -1668,7 +1668,7 @@ int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc)
 int drbd_send_protocol(struct drbd_conf *mdev)
 {
        struct p_protocol *p;
-       int size, rv;
+       int size, cf, rv;
 
        size = sizeof(struct p_protocol);
 
@@ -1685,9 +1685,22 @@ int drbd_send_protocol(struct drbd_conf *mdev)
        p->after_sb_0p   = cpu_to_be32(mdev->net_conf->after_sb_0p);
        p->after_sb_1p   = cpu_to_be32(mdev->net_conf->after_sb_1p);
        p->after_sb_2p   = cpu_to_be32(mdev->net_conf->after_sb_2p);
-       p->want_lose     = cpu_to_be32(mdev->net_conf->want_lose);
        p->two_primaries = cpu_to_be32(mdev->net_conf->two_primaries);
 
+       cf = 0;
+       if (mdev->net_conf->want_lose)
+               cf |= CF_WANT_LOSE;
+       if (mdev->net_conf->dry_run) {
+               if (mdev->agreed_pro_version >= 92)
+                       cf |= CF_DRY_RUN;
+               else {
+                       dev_err(DEV, "--dry-run is not supported by peer");
+                       kfree(p);
+                       return 0;
+               }
+       }
+       p->conn_flags    = cpu_to_be32(cf);
+
        if (mdev->agreed_pro_version >= 87)
                strcpy(p->integrity_alg, mdev->net_conf->integrity_alg);
 
@@ -3161,14 +3174,18 @@ void drbd_free_bc(struct drbd_backing_dev *ldev)
 void drbd_free_sock(struct drbd_conf *mdev)
 {
        if (mdev->data.socket) {
+               mutex_lock(&mdev->data.mutex);
                kernel_sock_shutdown(mdev->data.socket, SHUT_RDWR);
                sock_release(mdev->data.socket);
                mdev->data.socket = NULL;
+               mutex_unlock(&mdev->data.mutex);
        }
        if (mdev->meta.socket) {
+               mutex_lock(&mdev->meta.mutex);
                kernel_sock_shutdown(mdev->meta.socket, SHUT_RDWR);
                sock_release(mdev->meta.socket);
                mdev->meta.socket = NULL;
+               mutex_unlock(&mdev->meta.mutex);
        }
 }
 
index 4df3b40b1057d225fe310601c77021a6f37f0d7c..6429d2b19e064a0e5aa56c77a91aca2d96e588dd 100644 (file)
@@ -285,8 +285,8 @@ int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force)
                }
 
                if (r == SS_NO_UP_TO_DATE_DISK && force &&
-                   (mdev->state.disk == D_INCONSISTENT ||
-                    mdev->state.disk == D_OUTDATED)) {
+                   (mdev->state.disk < D_UP_TO_DATE &&
+                    mdev->state.disk >= D_INCONSISTENT)) {
                        mask.disk = D_MASK;
                        val.disk  = D_UP_TO_DATE;
                        forced = 1;
@@ -407,7 +407,7 @@ static int drbd_nl_primary(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
        }
 
        reply->ret_code =
-               drbd_set_role(mdev, R_PRIMARY, primary_args.overwrite_peer);
+               drbd_set_role(mdev, R_PRIMARY, primary_args.primary_force);
 
        return 0;
 }
@@ -941,6 +941,25 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
 
        drbd_md_set_sector_offsets(mdev, nbc);
 
+       /* allocate a second IO page if logical_block_size != 512 */
+       logical_block_size = bdev_logical_block_size(nbc->md_bdev);
+       if (logical_block_size == 0)
+               logical_block_size = MD_SECTOR_SIZE;
+
+       if (logical_block_size != MD_SECTOR_SIZE) {
+               if (!mdev->md_io_tmpp) {
+                       struct page *page = alloc_page(GFP_NOIO);
+                       if (!page)
+                               goto force_diskless_dec;
+
+                       dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n",
+                            logical_block_size, MD_SECTOR_SIZE);
+                       dev_warn(DEV, "Workaround engaged (has performance impact).\n");
+
+                       mdev->md_io_tmpp = page;
+               }
+       }
+
        if (!mdev->bitmap) {
                if (drbd_bm_init(mdev)) {
                        retcode = ERR_NOMEM;
@@ -980,25 +999,6 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
                goto force_diskless_dec;
        }
 
-       /* allocate a second IO page if logical_block_size != 512 */
-       logical_block_size = bdev_logical_block_size(nbc->md_bdev);
-       if (logical_block_size == 0)
-               logical_block_size = MD_SECTOR_SIZE;
-
-       if (logical_block_size != MD_SECTOR_SIZE) {
-               if (!mdev->md_io_tmpp) {
-                       struct page *page = alloc_page(GFP_NOIO);
-                       if (!page)
-                               goto force_diskless_dec;
-
-                       dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n",
-                            logical_block_size, MD_SECTOR_SIZE);
-                       dev_warn(DEV, "Workaround engaged (has performance impact).\n");
-
-                       mdev->md_io_tmpp = page;
-               }
-       }
-
        /* Reset the "barriers don't work" bits here, then force meta data to
         * be written, to ensure we determine if barriers are supported. */
        if (nbc->dc.no_md_flush)
index df8ad9660d8f969adff252371ce86be9f2ab4aab..be3374b6846057734b6e6bd75e4f2d64065a84d2 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/uaccess.h>
 #include <linux/fs.h>
 #include <linux/file.h>
-#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/drbd.h>
index d065c646b35a06fe9fba171864951efbe12e405d..3f096e7959b44ad44f990edeac2a118808a73c06 100644 (file)
@@ -899,7 +899,8 @@ retry:
 
        drbd_thread_start(&mdev->asender);
 
-       drbd_send_protocol(mdev);
+       if (!drbd_send_protocol(mdev))
+               return -1;
        drbd_send_sync_param(mdev, &mdev->sync_conf);
        drbd_send_sizes(mdev, 0);
        drbd_send_uuids(mdev);
@@ -2513,6 +2514,10 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol
        }
 
        if (hg == -100) {
+               /* FIXME this log message is not correct if we end up here
+                * after an attempted attach on a diskless node.
+                * We just refuse to attach -- well, we drop the "connection"
+                * to that disk, in a way... */
                dev_alert(DEV, "Split-Brain detected, dropping connection!\n");
                drbd_khelper(mdev, "split-brain");
                return C_MASK;
@@ -2538,6 +2543,16 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol
                }
        }
 
+       if (mdev->net_conf->dry_run || test_bit(CONN_DRY_RUN, &mdev->flags)) {
+               if (hg == 0)
+                       dev_info(DEV, "dry-run connect: No resync, would become Connected immediately.\n");
+               else
+                       dev_info(DEV, "dry-run connect: Would become %s, doing a %s resync.",
+                                drbd_conn_str(hg > 0 ? C_SYNC_SOURCE : C_SYNC_TARGET),
+                                abs(hg) >= 2 ? "full" : "bit-map based");
+               return C_MASK;
+       }
+
        if (abs(hg) >= 2) {
                dev_info(DEV, "Writing the whole bitmap, full sync required after drbd_sync_handshake.\n");
                if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from sync_handshake"))
@@ -2585,7 +2600,7 @@ static int receive_protocol(struct drbd_conf *mdev, struct p_header *h)
        struct p_protocol *p = (struct p_protocol *)h;
        int header_size, data_size;
        int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p;
-       int p_want_lose, p_two_primaries;
+       int p_want_lose, p_two_primaries, cf;
        char p_integrity_alg[SHARED_SECRET_MAX] = "";
 
        header_size = sizeof(*p) - sizeof(*h);
@@ -2598,8 +2613,14 @@ static int receive_protocol(struct drbd_conf *mdev, struct p_header *h)
        p_after_sb_0p   = be32_to_cpu(p->after_sb_0p);
        p_after_sb_1p   = be32_to_cpu(p->after_sb_1p);
        p_after_sb_2p   = be32_to_cpu(p->after_sb_2p);
-       p_want_lose     = be32_to_cpu(p->want_lose);
        p_two_primaries = be32_to_cpu(p->two_primaries);
+       cf              = be32_to_cpu(p->conn_flags);
+       p_want_lose = cf & CF_WANT_LOSE;
+
+       clear_bit(CONN_DRY_RUN, &mdev->flags);
+
+       if (cf & CF_DRY_RUN)
+               set_bit(CONN_DRY_RUN, &mdev->flags);
 
        if (p_proto != mdev->net_conf->wire_protocol) {
                dev_err(DEV, "incompatible communication protocols\n");
@@ -3118,13 +3139,16 @@ static int receive_state(struct drbd_conf *mdev, struct p_header *h)
 
                put_ldev(mdev);
                if (nconn == C_MASK) {
+                       nconn = C_CONNECTED;
                        if (mdev->state.disk == D_NEGOTIATING) {
                                drbd_force_state(mdev, NS(disk, D_DISKLESS));
-                               nconn = C_CONNECTED;
                        } else if (peer_state.disk == D_NEGOTIATING) {
                                dev_err(DEV, "Disk attach process on the peer node was aborted.\n");
                                peer_state.disk = D_DISKLESS;
+                               real_peer_disk = D_DISKLESS;
                        } else {
+                               if (test_and_clear_bit(CONN_DRY_RUN, &mdev->flags))
+                                       return FALSE;
                                D_ASSERT(oconn == C_WF_REPORT_PARAMS);
                                drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
                                return FALSE;
@@ -3594,10 +3618,7 @@ static void drbd_disconnect(struct drbd_conf *mdev)
 
        /* asender does not clean up anything. it must not interfere, either */
        drbd_thread_stop(&mdev->asender);
-
-       mutex_lock(&mdev->data.mutex);
        drbd_free_sock(mdev);
-       mutex_unlock(&mdev->data.mutex);
 
        spin_lock_irq(&mdev->req_lock);
        _drbd_wait_ee_list_empty(mdev, &mdev->active_ee);
@@ -4054,6 +4075,8 @@ static int got_PingAck(struct drbd_conf *mdev, struct p_header *h)
 {
        /* restore idle timeout */
        mdev->meta.socket->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ;
+       if (!test_and_set_bit(GOT_PING_ACK, &mdev->flags))
+               wake_up(&mdev->misc_wait);
 
        return TRUE;
 }
index b453c2bca3be5d3740c81be7e41d2ff953bb937d..d48a1dfd7b2455cdb2b7b7f0df0af282c6c5a695 100644 (file)
@@ -235,7 +235,7 @@ void drbd_endio_pri(struct bio *bio, int error)
        if (unlikely(error)) {
                what = (bio_data_dir(bio) == WRITE)
                        ? write_completed_with_error
-                       : (bio_rw(bio) == READA)
+                       : (bio_rw(bio) == READ)
                          ? read_completed_with_error
                          : read_ahead_completed_with_error;
        } else
@@ -938,7 +938,8 @@ int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 
                if (eq) {
                        drbd_set_in_sync(mdev, e->sector, e->size);
-                       mdev->rs_same_csum++;
+                       /* rs_same_csums unit is BM_BLOCK_SIZE */
+                       mdev->rs_same_csum += e->size >> BM_BLOCK_SHIFT;
                        ok = drbd_send_ack(mdev, P_RS_IS_IN_SYNC, e);
                } else {
                        inc_rs_pending(mdev);
@@ -1288,6 +1289,14 @@ int drbd_alter_sa(struct drbd_conf *mdev, int na)
        return retcode;
 }
 
+static void ping_peer(struct drbd_conf *mdev)
+{
+       clear_bit(GOT_PING_ACK, &mdev->flags);
+       request_ping(mdev);
+       wait_event(mdev->misc_wait,
+                  test_bit(GOT_PING_ACK, &mdev->flags) || mdev->state.conn < C_CONNECTED);
+}
+
 /**
  * drbd_start_resync() - Start the resync process
  * @mdev:      DRBD device.
@@ -1371,7 +1380,6 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
                _drbd_pause_after(mdev);
        }
        write_unlock_irq(&global_state_lock);
-       drbd_state_unlock(mdev);
        put_ldev(mdev);
 
        if (r == SS_SUCCESS) {
@@ -1382,11 +1390,8 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
 
                if (mdev->rs_total == 0) {
                        /* Peer still reachable? Beware of failing before-resync-target handlers! */
-                       request_ping(mdev);
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(mdev->net_conf->ping_timeo*HZ/9); /* 9 instead 10 */
+                       ping_peer(mdev);
                        drbd_resync_finished(mdev);
-                       return;
                }
 
                /* ns.conn may already be != mdev->state.conn,
@@ -1398,6 +1403,7 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
 
                drbd_md_sync(mdev);
        }
+       drbd_state_unlock(mdev);
 }
 
 int drbd_worker(struct drbd_thread *thi)
index 5116c65c07cb71e9384372faaf7a7d9fa8c29d89..81c78b3ce2df1201edb6a9a6a077fbfc7826105a 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/genhd.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
@@ -165,12 +164,12 @@ unsigned long read_timer(void)
        unsigned long t, flags;
        int i;
 
-       spin_lock_irqsave(&i8253_lock, flags);
+       raw_spin_lock_irqsave(&i8253_lock, flags);
        t = jiffies * 11932;
        outb_p(0, 0x43);
        i = inb_p(0x40);
        i |= inb(0x40) << 8;
-       spin_unlock_irqrestore(&i8253_lock, flags);
+       raw_spin_unlock_irqrestore(&i8253_lock, flags);
        return(t - i);
 }
 #endif
index bd112c8c7bcde9b3efdbceadc6fc89d65f6c9ea0..8546d123b9a745492cbbe0aace5b5ce6a2324298 100644 (file)
@@ -71,7 +71,6 @@
 #include <linux/buffer_head.h>         /* for invalidate_bdev() */
 #include <linux/completion.h>
 #include <linux/highmem.h>
-#include <linux/gfp.h>
 #include <linux/kthread.h>
 #include <linux/splice.h>
 
@@ -238,6 +237,8 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec,
                if (ret)
                        goto fail;
 
+               file_update_time(file);
+
                transfer_result = lo_do_transfer(lo, WRITE, page, offset,
                                bvec->bv_page, bv_offs, size, IV);
                copied = size;
index 5416c9a606e43694b59dc0dec09075b8257bf964..28db925dbdad9f659cf1fc981df6755729aa5b17 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/mg_disk.h>
+#include <linux/slab.h>
 
 #define MG_RES_SEC (CONFIG_MG_DISK_RES << 1)
 
index cc923a5b430c51d11f0cc4fd1b2c32405c72ca6a..218d091f3c52180106633075f8750db044a11434 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/compiler.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <linux/net.h>
 #include <linux/kthread.h>
index eb2091aa1c19e2abf7ccfdafce320c44f7d14abb..6cd8b705b11be399bca98b3ca44f503c68fbbf98 100644 (file)
@@ -63,6 +63,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <scsi/osd_initiator.h>
 #include <scsi/osd_attributes.h>
 #include <scsi/osd_sec.h>
index 8866ca369d5e5e1814c27eab1b3c53fb5ff0777b..71acf4e53356f6ba6e4810848324e2ea268ae482 100644 (file)
@@ -341,11 +341,11 @@ static int pcd_wait(struct pcd_unit *cd, int go, int stop, char *fun, char *msg)
               && (j++ < PCD_SPIN))
                udelay(PCD_DELAY);
 
-       if ((r & (IDE_ERR & stop)) || (j >= PCD_SPIN)) {
+       if ((r & (IDE_ERR & stop)) || (j > PCD_SPIN)) {
                s = read_reg(cd, 7);
                e = read_reg(cd, 1);
                p = read_reg(cd, 2);
-               if (j >= PCD_SPIN)
+               if (j > PCD_SPIN)
                        e |= 0x100;
                if (fun)
                        printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
index e712cd51af1543c75ca13092c1662e551df256f4..c1e5cd029b23bf42562d3e07392f4713e7ab3b47 100644 (file)
@@ -145,6 +145,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV};
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/fs.h>
 #include <linux/delay.h>
 #include <linux/hdreg.h>
index ddb4f9abd480b8f0cb6ce013d6c514e5a211d120..c059aab3006b9a5c794e0b91814dd41d064c0052 100644 (file)
@@ -391,11 +391,11 @@ static int pf_wait(struct pf_unit *pf, int go, int stop, char *fun, char *msg)
               && (j++ < PF_SPIN))
                udelay(PF_SPIN_DEL);
 
-       if ((r & (STAT_ERR & stop)) || (j >= PF_SPIN)) {
+       if ((r & (STAT_ERR & stop)) || (j > PF_SPIN)) {
                s = read_reg(pf, 7);
                e = read_reg(pf, 1);
                p = read_reg(pf, 2);
-               if (j >= PF_SPIN)
+               if (j > PF_SPIN)
                        e |= 0x100;
                if (fun)
                        printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
index 1e4006e18f03060138709ed6930e770211e5706e..bc5825fdeaabcfa297e9d00ffe1be1e8ade921fe 100644 (file)
@@ -274,11 +274,11 @@ static int pt_wait(struct pt_unit *tape, int go, int stop, char *fun, char *msg)
               && (j++ < PT_SPIN))
                udelay(PT_SPIN_DEL);
 
-       if ((r & (STAT_ERR & stop)) || (j >= PT_SPIN)) {
+       if ((r & (STAT_ERR & stop)) || (j > PT_SPIN)) {
                s = read_reg(pi, 7);
                e = read_reg(pi, 1);
                p = read_reg(pi, 2);
-               if (j >= PT_SPIN)
+               if (j > PT_SPIN)
                        e |= 0x100;
                if (fun)
                        printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
index 39c8514442eb7364e42fa868e1c5499f9d3d10c7..8a549db2aa7859b588e106c981301dbd5118aec6 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/compat.h>
 #include <linux/kthread.h>
 #include <linux/errno.h>
 #include <linux/spinlock.h>
@@ -57,6 +58,7 @@
 #include <linux/miscdevice.h>
 #include <linux/freezer.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_ioctl.h>
 #include <scsi/scsi.h>
@@ -2983,7 +2985,7 @@ static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd)
        mutex_unlock(&ctl_mutex);
 }
 
-static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long pkt_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        void __user *argp = (void __user *)arg;
        struct pkt_ctrl_command ctrl_cmd;
@@ -3020,10 +3022,20 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm
        return ret;
 }
 
+#ifdef CONFIG_COMPAT
+static long pkt_ctl_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       return pkt_ctl_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
+}
+#endif
 
 static const struct file_operations pkt_ctl_fops = {
-       .ioctl   = pkt_ctl_ioctl,
-       .owner   = THIS_MODULE,
+       .open           = nonseekable_open,
+       .unlocked_ioctl = pkt_ctl_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl   = pkt_ctl_compat_ioctl,
+#endif
+       .owner          = THIS_MODULE,
 };
 
 static struct miscdevice pkt_misc = {
index bc95469d33c122018e96ccbc9576370e64c89afd..3b419e3fffa1d4a366b2e1d3b10654e47c06d63f 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/ata.h>
 #include <linux/blkdev.h>
+#include <linux/slab.h>
 
 #include <asm/lv1call.h>
 #include <asm/ps3stor.h>
index e4460822997293c324e3a5d617ec49acd0801ccd..b3bdb8af89cfad5e80e8ea9d01f5134c1872fbbe 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <asm/cell-regs.h>
 #include <asm/firmware.h>
index 821c2833f9cf343407df6b90367567ac6fd99e3a..e463657569ff06e3039822a62ca888624160eca2 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/module.h>
 #include <linux/fd.h>
+#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/hdreg.h>
 #include <linux/kernel.h>
index 2e889838e819016c8c693cba1d0498595a027565..0536b5b29adcb02ff76c4fcf8b4501668220a6d3 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/blkdev.h>
 #include <linux/timer.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 
 #define DRV_NAME "ub"
index ad1ba393801ae4fe222d0117a1bd7d6a6fedc187..2f9470ff8f7cec7c7d3de70ea0c347a0e92bf4e1 100644 (file)
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
+#include <linux/gfp.h>
 #include <linux/ioctl.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/timer.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/dma-mapping.h>
 
 #include <linux/fcntl.h>        /* O_ACCMODE */
index 3c64af05fa82a0fa79dbf26c9cf84c509b54c604..2138a7ae050c10c44bdba1608f441a7811ca1a22 100644 (file)
@@ -1,5 +1,6 @@
 //#define DEBUG
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/hdreg.h>
 #include <linux/virtio.h>
@@ -347,14 +348,13 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
        set_capacity(vblk->disk, cap);
 
        /* We can handle whatever the host told us to handle. */
-       blk_queue_max_phys_segments(q, vblk->sg_elems-2);
-       blk_queue_max_hw_segments(q, vblk->sg_elems-2);
+       blk_queue_max_segments(q, vblk->sg_elems-2);
 
        /* No need to bounce any requests */
        blk_queue_bounce_limit(q, BLK_BOUNCE_ANY);
 
        /* No real sector limit. */
-       blk_queue_max_sectors(q, -1U);
+       blk_queue_max_hw_sectors(q, -1U);
 
        /* Host can optionally specify maximum segment size and number of
         * segments. */
index 1a325fb05c9282745013d53e541e13b7b748d1a8..18a80ff57ce89f821fd3f5910a09207b7f5db605 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/blkpg.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
index 9c09694b2520cc5a2422416431576a46d0871eaf..82ed403147c06c66143b0d5fdbcf5ddfccdc8232 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/hdreg.h>
 #include <linux/cdrom.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/scatterlist.h>
 
 #include <xen/xen.h>
index 64f941e0f14b07180ebe1089786f1842a22b7b94..9114654b54d9a933b1728830b120a9059bcf24c3 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/module.h>
 #include <linux/blkdev.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 
 #include <asm/setup.h>
 #include <asm/amigahw.h>
index 3126a3d0c45c0e7a43350ad41e45018a39968dab..b50b41d97a7f2d781ebf5e0c58a79e1298171f1b 100644 (file)
@@ -19,6 +19,7 @@
  **/
 
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
index 523d197b9824571a0a9b810f096f2516d794fe62..204727586ee913896b1511e87ceffe3fcf8d6d88 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/kthread.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include <net/bluetooth/bluetooth.h>
 
 #define BTM_HEADER_LEN                 4
index 94f1f55f81f0472583d929d6f9f211bd78ecd51c..0dba76aa2232d9231e466ef2e610fffb29513df9 100644 (file)
@@ -19,6 +19,7 @@
  **/
 
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/sdio_ids.h>
 #include <linux/mmc/sdio_func.h>
index 73dbf40c874d956900819ffb6502e620bfcaa917..a7637d72cef6ba42ae2c92715d3ba1b5157449a2 100644 (file)
@@ -6,9 +6,9 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/agp_backend.h>
-#include <linux/gfp.h>
 #include <linux/page-flags.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include "agp.h"
 
 #define AMD_MMBASE     0x14
index c3ab46da51a35da4bfb5a6965a02e4c5d8c96401..ee4f855611b676b589046fad44f1e934bd615896 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/miscdevice.h>
 #include <linux/pm.h>
index 58c57cb2518cc7dcd4322c4bfbd97eeab69afdcb..9d2c97a69cdd2f280aec61be7eb57b32b52b3f66 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/pci.h>
 #include <linux/fs.h>
 #include <linux/agpgart.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include "agp.h"
 #include "compat_ioctl.h"
index c50543966eb22deaf622ff991f888a61e587910a..fb86708e47edb69693969d1be821ba71f2f31715 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/cacheflush.h>
 #include <asm/pgtable.h>
index 58752b70efead7a76ca65c1441574dfa50931a07..056b289a1e89e2452613bbf875e49b28f6db9d16 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/agp_backend.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 
 #include <asm/acpi-ext.h>
 
index a3e10dc7cc25ff375674a79c510effbcdfc452f9..aa4248efc5d81341e02bdbafbb1d47f3f3228a79 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/pagemap.h>
@@ -97,6 +98,9 @@ EXPORT_SYMBOL(intel_agp_enabled);
 #define IS_PINEVIEW (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB)
 
+#define IS_SNB (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \
+               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB)
+
 #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \
@@ -107,8 +111,7 @@ EXPORT_SYMBOL(intel_agp_enabled);
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || \
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB || \
-               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \
-               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB)
+               IS_SNB)
 
 extern int agp_memory_reserved;
 
@@ -175,6 +178,10 @@ extern int agp_memory_reserved;
 #define SNB_GMCH_GMS_STOLEN_448M       (0xe << 3)
 #define SNB_GMCH_GMS_STOLEN_480M       (0xf << 3)
 #define SNB_GMCH_GMS_STOLEN_512M       (0x10 << 3)
+#define SNB_GTT_SIZE_0M                        (0 << 8)
+#define SNB_GTT_SIZE_1M                        (1 << 8)
+#define SNB_GTT_SIZE_2M                        (2 << 8)
+#define SNB_GTT_SIZE_MASK              (3 << 8)
 
 static const struct aper_size_info_fixed intel_i810_sizes[] =
 {
@@ -1200,6 +1207,9 @@ static void intel_i9xx_setup_flush(void)
        if (intel_private.ifp_resource.start)
                return;
 
+       if (IS_SNB)
+               return;
+
        /* setup a resource for this object */
        intel_private.ifp_resource.name = "Intel Flush Page";
        intel_private.ifp_resource.flags = IORESOURCE_MEM;
@@ -1438,6 +1448,8 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
 
 static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
 {
+       u16 snb_gmch_ctl;
+
        switch (agp_bridge->dev->device) {
        case PCI_DEVICE_ID_INTEL_GM45_HB:
        case PCI_DEVICE_ID_INTEL_EAGLELAKE_HB:
@@ -1449,9 +1461,26 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
        case PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB:
        case PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB:
        case PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB:
+               *gtt_offset = *gtt_size = MB(2);
+               break;
        case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB:
        case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB:
-               *gtt_offset = *gtt_size = MB(2);
+               *gtt_offset = MB(2);
+
+               pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl);
+               switch (snb_gmch_ctl & SNB_GTT_SIZE_MASK) {
+               default:
+               case SNB_GTT_SIZE_0M:
+                       printk(KERN_ERR "Bad GTT size mask: 0x%04x.\n", snb_gmch_ctl);
+                       *gtt_size = MB(0);
+                       break;
+               case SNB_GTT_SIZE_1M:
+                       *gtt_size = MB(1);
+                       break;
+               case SNB_GTT_SIZE_2M:
+                       *gtt_size = MB(2);
+                       break;
+               }
                break;
        default:
                *gtt_offset = *gtt_size = KB(512);
@@ -1788,8 +1817,6 @@ static int intel_845_configure(void)
        pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));
        /* clear any possible error conditions */
        pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c);
-
-       intel_i830_setup_flush();
        return 0;
 }
 
@@ -2159,7 +2186,6 @@ static const struct agp_bridge_driver intel_845_driver = {
        .agp_destroy_page       = agp_generic_destroy_page,
        .agp_destroy_pages      = agp_generic_destroy_pages,
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
-       .chipset_flush          = intel_i830_chipset_flush,
 };
 
 static const struct agp_bridge_driver intel_850_driver = {
index 7e36d2b4f9d4fc863bc5392d588b152a69d8614c..10f24e349a26cf0059c9ba7566a6c3659803ac40 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/agp_backend.h>
-#include <linux/gfp.h>
 #include <linux/page-flags.h>
 #include <linux/mm.h>
 #include <linux/jiffies.h>
index 0d426ae39c850adaa86e379a764ee315767f992f..ffa888cd1c882818aebbe2eea0bedbc1929f439d 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/acpi.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/agp_backend.h>
 #include <asm/sn/addrs.h>
index d89da4ac061f2d0c3aea71b51666039b203537ec..6f48931ac1cec7d9a82aa4ab1d80509876678eb2 100644 (file)
@@ -3,6 +3,7 @@
  */
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/pagemap.h>
 #include <linux/agp_backend.h>
index 6c32fbf071648931374bfc6fa699d6ba37a523f1..56b27671adc46b23c80ca24425241048d0cae7ea 100644 (file)
@@ -2021,8 +2021,6 @@ static int __init rs_init(void)
        state->baud_base = amiga_colorclock;
        state->xmit_fifo_size = 1;
 
-       local_irq_save(flags);
-
        /* set ISRs, and then disable the rx interrupts */
        error = request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state);
        if (error)
@@ -2033,6 +2031,8 @@ static int __init rs_init(void)
        if (error)
                goto fail_free_irq;
 
+       local_irq_save(flags);
+
        /* turn off Rx and Tx interrupts */
        custom.intena = IF_RBF | IF_TBE;
        mb();
index 2628c7415ea863b07b0caa5064bbf0c0c42f3dfb..e397df3ad98e2f451a51e9bcb91cd3c47deaa610 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
index d8cff909001c1e4cbd68c8aa22f08eb70d08bbdb..555cd93c2ee5124c102ab892b49bc0cd3da3d2c8 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/kernel.h>
 #include <linux/wait.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/miscdevice.h>
index c02db01f736ea46bc536190910a2f4a9e336bfbb..7fef305774dee184ecc0ac34fe0d39b77005ffc7 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/cdev.h>
 #include <linux/list.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
 
index b861c08263a443c653ae948ed774d4c3011a03c3..9824b41629041e6fd610805cd08441e05d532287 100644 (file)
@@ -79,6 +79,7 @@
 #include <linux/bitops.h>
 #include <linux/firmware.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 
 #include <linux/io.h>
 #include <linux/uaccess.h>
index 85832ab924e662ffa3f1d4cf588c1b5fb7becab2..8a1b28a10ef0af184e4ff4e03e9eaaf4783f97ca 100644 (file)
@@ -24,7 +24,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/slab.h>        /* for kmalloc() and kfree() */
 #include <linux/major.h>
 #include <linux/types.h>
 #include <linux/errno.h>
index 17b044a71e026fc8c943de8ea5bf64c852abc75c..6f5ffe1320f700f330beabd0481e62b5b9a56f48 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/ctype.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
-#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
index d400cbd280f2fbb858102f0defb111a583979f3a..5954ee1dc9538c4eb4849f07c1d28e06558782a3 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/interrupt.h>
 #include <linux/tty_flip.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <asm/uaccess.h>
 
 #define DEBUG 
index e481c5938badeb19c2ea9d518e9340c4dc93edd3..9ded667625ac06c91d1940bf79ba261b65943b59 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/seq_file.h>
 #include <linux/bitops.h>
 #include <linux/clocksource.h>
+#include <linux/slab.h>
 
 #include <asm/current.h>
 #include <asm/uaccess.h>
@@ -215,9 +216,7 @@ static void hpet_timer_set_irq(struct hpet_dev *devp)
        else
                v &= ~0xffff;
 
-       for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ;
-               irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) {
-
+       for_each_set_bit(irq, &v, HPET_MAX_IRQ) {
                if (irq >= nr_irqs) {
                        irq = HPET_MAX_IRQ;
                        break;
index 465185fc0f524bb2eb15cc4d3cf251af264a48ae..35cca4c7fb186684aa41ef27228d85a932d97774 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/spinlock.h>
 #include <linux/delay.h>
 #include <linux/freezer.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
@@ -312,6 +313,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
        spin_lock_irqsave(&hp->lock, flags);
        /* Check and then increment for fast path open. */
        if (hp->count++ > 0) {
+               tty_kref_get(tty);
                spin_unlock_irqrestore(&hp->lock, flags);
                hvc_kick();
                return 0;
@@ -319,7 +321,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
 
        tty->driver_data = hp;
 
-       hp->tty = tty;
+       hp->tty = tty_kref_get(tty);
 
        spin_unlock_irqrestore(&hp->lock, flags);
 
@@ -336,6 +338,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
                spin_lock_irqsave(&hp->lock, flags);
                hp->tty = NULL;
                spin_unlock_irqrestore(&hp->lock, flags);
+               tty_kref_put(tty);
                tty->driver_data = NULL;
                kref_put(&hp->kref, destroy_hvc_struct);
                printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
@@ -363,6 +366,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
                return;
 
        hp = tty->driver_data;
+
        spin_lock_irqsave(&hp->lock, flags);
 
        if (--hp->count == 0) {
@@ -389,6 +393,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
                spin_unlock_irqrestore(&hp->lock, flags);
        }
 
+       tty_kref_put(tty);
        kref_put(&hp->kref, destroy_hvc_struct);
 }
 
@@ -424,10 +429,11 @@ static void hvc_hangup(struct tty_struct *tty)
        spin_unlock_irqrestore(&hp->lock, flags);
 
        if (hp->ops->notifier_hangup)
-                       hp->ops->notifier_hangup(hp, hp->data);
+               hp->ops->notifier_hangup(hp, hp->data);
 
        while(temp_open_count) {
                --temp_open_count;
+               tty_kref_put(tty);
                kref_put(&hp->kref, destroy_hvc_struct);
        }
 }
@@ -592,7 +598,7 @@ int hvc_poll(struct hvc_struct *hp)
        }
 
        /* No tty attached, just skip */
-       tty = hp->tty;
+       tty = tty_kref_get(hp->tty);
        if (tty == NULL)
                goto bail;
 
@@ -672,6 +678,8 @@ int hvc_poll(struct hvc_struct *hp)
 
                tty_flip_buffer_push(tty);
        }
+       if (tty)
+               tty_kref_put(tty);
 
        return poll_mask;
 }
@@ -807,7 +815,7 @@ int hvc_remove(struct hvc_struct *hp)
        struct tty_struct *tty;
 
        spin_lock_irqsave(&hp->lock, flags);
-       tty = hp->tty;
+       tty = tty_kref_get(hp->tty);
 
        if (hp->index < MAX_NR_HVC_CONSOLES)
                vtermnos[hp->index] = -1;
@@ -819,18 +827,18 @@ int hvc_remove(struct hvc_struct *hp)
        /*
         * We 'put' the instance that was grabbed when the kref instance
         * was initialized using kref_init().  Let the last holder of this
-        * kref cause it to be removed, which will probably be the tty_hangup
+        * kref cause it to be removed, which will probably be the tty_vhangup
         * below.
         */
        kref_put(&hp->kref, destroy_hvc_struct);
 
        /*
-        * This function call will auto chain call hvc_hangup.  The tty should
-        * always be valid at this time unless a simultaneous tty close already
-        * cleaned up the hvc_struct.
+        * This function call will auto chain call hvc_hangup.
         */
-       if (tty)
-               tty_hangup(tty);
+       if (tty) {
+               tty_vhangup(tty);
+               tty_kref_put(tty);
+       }
        return 0;
 }
 EXPORT_SYMBOL_GPL(hvc_remove);
index 37b0542a4eeb055e52fbe7e137a7cc2f65081ce1..5a80ad68ef22c259a734c2ae987cf5375aafda55 100644 (file)
@@ -12,6 +12,7 @@
 #define pr_fmt(fmt)            KMSG_COMPONENT ": " fmt
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <asm/ebcdic.h>
 #include <linux/ctype.h>
 #include <linux/delay.h>
index 266b858b8f857e9573a8ed568bc8c054974dd7b9..bedc6c1b6fa5ef290db126aa9bef863f9b68fe22 100644 (file)
@@ -74,6 +74,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/stat.h>
 #include <linux/tty.h>
index 91b53eb1c053bff15349b80d6b949abb71ad4fb8..86fe45c19968a14fef860dae956c3827eb2a067c 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/pci.h>
 #include <linux/stop_machine.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 
index 54b0d9ba65cf4e74b7dfde417176cad5e7219f60..9cd0feca318c3e5f7f9bde8bce6932dbc0be4eba 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/device.h>
 #include <linux/hw_random.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 
 #include <asm/octeon/octeon.h>
 #include <asm/octeon/cvmx-rnm-defs.h>
index 544d9085a8e8088da17604a677471c5f3d6423ae..0bc0cb70210b4bb04b7869c9ffd7ac198950bba7 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/hw_random.h>
+#include <linux/gfp.h>
 
 #define TX4939_RNG_RCSR                0x00000000
 #define TX4939_RNG_ROR(n)      (0x00000018 + (n) * 8)
index ec5e3f8df648ba1e719836a9b8349246005ba685..c6ad4234378d7e5cd0818d839e81c3b641e1d426 100644 (file)
@@ -2272,42 +2272,52 @@ static int create_files(struct bmc_device *bmc)
        bmc->device_id_attr.attr.name = "device_id";
        bmc->device_id_attr.attr.mode = S_IRUGO;
        bmc->device_id_attr.show = device_id_show;
+       sysfs_attr_init(&bmc->device_id_attr.attr);
 
        bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs";
        bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
        bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
+       sysfs_attr_init(&bmc->provides_dev_sdrs_attr.attr);
 
        bmc->revision_attr.attr.name = "revision";
        bmc->revision_attr.attr.mode = S_IRUGO;
        bmc->revision_attr.show = revision_show;
+       sysfs_attr_init(&bmc->revision_attr.attr);
 
        bmc->firmware_rev_attr.attr.name = "firmware_revision";
        bmc->firmware_rev_attr.attr.mode = S_IRUGO;
        bmc->firmware_rev_attr.show = firmware_rev_show;
+       sysfs_attr_init(&bmc->firmware_rev_attr.attr);
 
        bmc->version_attr.attr.name = "ipmi_version";
        bmc->version_attr.attr.mode = S_IRUGO;
        bmc->version_attr.show = ipmi_version_show;
+       sysfs_attr_init(&bmc->version_attr.attr);
 
        bmc->add_dev_support_attr.attr.name = "additional_device_support";
        bmc->add_dev_support_attr.attr.mode = S_IRUGO;
        bmc->add_dev_support_attr.show = add_dev_support_show;
+       sysfs_attr_init(&bmc->add_dev_support_attr.attr);
 
        bmc->manufacturer_id_attr.attr.name = "manufacturer_id";
        bmc->manufacturer_id_attr.attr.mode = S_IRUGO;
        bmc->manufacturer_id_attr.show = manufacturer_id_show;
+       sysfs_attr_init(&bmc->manufacturer_id_attr.attr);
 
        bmc->product_id_attr.attr.name = "product_id";
        bmc->product_id_attr.attr.mode = S_IRUGO;
        bmc->product_id_attr.show = product_id_show;
+       sysfs_attr_init(&bmc->product_id_attr.attr);
 
        bmc->guid_attr.attr.name = "guid";
        bmc->guid_attr.attr.mode = S_IRUGO;
        bmc->guid_attr.show = guid_show;
+       sysfs_attr_init(&bmc->guid_attr.attr);
 
        bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision";
        bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
        bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
+       sysfs_attr_init(&bmc->aux_firmware_rev_attr.attr);
 
        err = device_create_file(&bmc->dev->dev,
                           &bmc->device_id_attr);
index be2e8f9a27c336e52bed89e1827e290c243de342..c1ab303455cf5b673d5684b6db72e453fd3e774f 100644 (file)
 #include <linux/timer.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
+#include <linux/slab.h>
 
 #include <linux/uaccess.h>
 #include <linux/io.h>
@@ -878,8 +879,8 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)
        if (tport == NULL)
                return -ENODEV;
        port = container_of(tport, struct isi_port, port);
-       card = &isi_card[BOARD(tty->index)];
 
+       tty->driver_data = port;
        return tty_port_open(tport, tty, filp);
 }
 
@@ -935,7 +936,12 @@ static void isicom_shutdown(struct tty_port *port)
 static void isicom_close(struct tty_struct *tty, struct file *filp)
 {
        struct isi_port *ip = tty->driver_data;
-       struct tty_port *port = &ip->port;
+       struct tty_port *port;
+
+       if (ip == NULL)
+               return;
+
+       port = &ip->port;
        if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
                return;
        tty_port_close(port, tty, filp);
index 4cd6c527ee4141929c2257e9798a7c51cab45a6b..4e395c956a09f1c4c1a8f472b1caad9401fb4585 100644 (file)
@@ -827,6 +827,8 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
                return -ENODEV;
        if (portp->devnr < 1)
                return -ENODEV;
+
+       tty->driver_data = portp;
        return tty_port_open(&portp->port, tty, filp);
 }
 
index 87c67b42bc08b03a17aaf410705f8c3e6e2d3638..83bef4efe37636869f418756462516d00a4f3ccd 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/uio.h>
 #include <linux/mutex.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
index 1f3215ac085bca594dc014cf91e23a745a8e1058..f54dab8acdcd6561c742b0541afdae3828dedfd9 100644 (file)
@@ -225,6 +225,7 @@ int __weak phys_mem_access_prot_allowed(struct file *file,
  * outside of main memory.
  *
  */
+#ifdef pgprot_noncached
 static int uncached_access(struct file *file, unsigned long addr)
 {
 #if defined(CONFIG_IA64)
@@ -251,6 +252,7 @@ static int uncached_access(struct file *file, unsigned long addr)
        return addr >= __pa(high_memory);
 #endif
 }
+#endif
 
 static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
                                     unsigned long size, pgprot_t vma_prot)
@@ -710,11 +712,6 @@ static loff_t memory_lseek(struct file *file, loff_t offset, int orig)
        switch (orig) {
        case SEEK_CUR:
                offset += file->f_pos;
-               if ((unsigned long long)offset <
-                   (unsigned long long)file->f_pos) {
-                       ret = -EOVERFLOW;
-                       break;
-               }
        case SEEK_SET:
                /* to avoid userland mistaking f_pos=-9 as -EBADF=-9 */
                if ((unsigned long long)offset >= ~0xFFFULL) {
@@ -908,6 +905,9 @@ static int __init chr_dev_init(void)
                printk("unable to get major %d for memory devs\n", MEM_MAJOR);
 
        mem_class = class_create(THIS_MODULE, "mem");
+       if (IS_ERR(mem_class))
+               return PTR_ERR(mem_class);
+
        mem_class->devnode = mem_devnode;
        for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) {
                if (!devlist[minor].name)
index 94a136e96c06c69b51aea6c31162606382ff6330..92ab03d282945bfe804ee3b48d3d6f428e4d55b8 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/miscdevice.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
-#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
@@ -49,6 +48,7 @@
 #include <linux/device.h>
 #include <linux/tty.h>
 #include <linux/kmod.h>
+#include <linux/gfp.h>
 
 /*
  * Head entry for the doubly linked miscdevice list
index 04fd0d843b3b2871625015e8f88f04d8eeb628ae..ea7c99fa978f9e8d2877ba8a783daeef5214cc5c 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/time.h>
 #include <linux/math64.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/sn/addrs.h>
index 166495d6a1d7dc8acea02b934b3c8c87c0de875b..107b0bd58d1911e028257893490d11542181a210 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
index e0c5d2a690464d37138daf88f5842aab027defe0..d2692d443f7bf9b721ba52e9b376883c2bf1e16e 100644 (file)
 #include <linux/string.h>
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
-#include <linux/gfp.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -1011,6 +1011,7 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
        if (!info->ioaddr)
                return -ENODEV;
 
+       tty->driver_data = info;
        return tty_port_open(&info->port, tty, filp);
 }
 
@@ -1074,7 +1075,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
        struct mxser_port *info = tty->driver_data;
        struct tty_port *port = &info->port;
 
-       if (tty->index == MXSER_PORTS)
+       if (tty->index == MXSER_PORTS || info == NULL)
                return;
        if (tty_port_close_start(port, tty, filp) == 0)
                return;
@@ -1768,7 +1769,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
                int len, lsr;
 
                len = mxser_chars_in_buffer(tty);
-               spin_lock(&info->slock);
+               spin_lock_irq(&info->slock);
                lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_THRE;
                spin_unlock_irq(&info->slock);
                len += (lsr ? 0 : 1);
@@ -1778,12 +1779,12 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
        case MOXA_ASPP_MON: {
                int mcr, status;
 
-               spin_lock(&info->slock);
+               spin_lock_irq(&info->slock);
                status = mxser_get_msr(info->ioaddr, 1, tty->index);
                mxser_check_modem_status(tty, info, status);
 
                mcr = inb(info->ioaddr + UART_MCR);
-               spin_unlock(&info->slock);
+               spin_unlock_irq(&info->slock);
 
                if (mcr & MOXA_MUST_MCR_XON_FLAG)
                        info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD;
index a3f32a15fde4196ce889b02be3cb2ada16b16d12..a6638003f530ff55688231f2acf09b3e12262b05 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/init.h>
 #include <linux/kfifo.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 
 #include <linux/delay.h>
index 5eb83c3ca20de35be340031015a93495ae19e12b..47e8f7b0e4c18d1893e3caba579581e7ee755762 100644 (file)
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/fcntl.h>
 #include <linux/mc146818rtc.h>
index c9bc896d68afe62a416bf547f5dfc09ba63c0891..90b199f97bec5aff836ee6b64dca439176d5107e 100644 (file)
@@ -1026,14 +1026,16 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
 
        xoutb(0, REG_FLAGS1(iobase));   /* clear detectCMM */
        /* last check before exit */
-       if (!io_detect_cm4000(iobase, dev))
-               count = -ENODEV;
+       if (!io_detect_cm4000(iobase, dev)) {
+               rc = -ENODEV;
+               goto release_io;
+       }
 
        if (test_bit(IS_INVREV, &dev->flags) && count > 0)
                str_invert_revert(dev->rbuf, count);
 
        if (copy_to_user(buf, dev->rbuf, count))
-               return -EFAULT;
+               rc = -EFAULT;
 
 release_io:
        clear_bit(LOCK_IO, &dev->flags);
index 590762a7f21790d64ea2b65725ff2a88902b1946..65920163f53d5206bb0e8f0f1eca8a2bde278a6c 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/netdevice.h>
 #include <linux/ppp_channel.h>
 #include <linux/ppp_defs.h>
+#include <linux/slab.h>
 #include <linux/if_ppp.h>
 #include <linux/skbuff.h>
 
index 432655bcb04c138f7446d3d1bb08e76cba0f3b51..fdd37543aa79e6d0b159767f791024d4c31e83fb 100644 (file)
@@ -64,6 +64,7 @@
 #include <linux/parport.h>
 #include <linux/ctype.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/major.h>
 #include <linux/ppdev.h>
 #include <linux/smp_lock.h>
index f424d394a286415e82c8aafdc634073f916f6521..606048b72bcf2e0adbebf8590a92e4f1b55fd5b5 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 
 #include <asm/lv1call.h>
index 5ee4248172630066c6233631ca71a56a9323f116..d83a43130df433962d7b0764ef6fc9c59f781f81 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/uaccess.h>
 #include <linux/bitops.h>
 #include <linux/devpts_fs.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 
index 64acd05f71c8743330e47a1d9883fc59acc22081..8756ab0daa8b3123bb4937dc128920fa0471e130 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/device.h>
 #include <linux/mutex.h>
 #include <linux/smp_lock.h>
+#include <linux/gfp.h>
 
 #include <asm/uaccess.h>
 
@@ -247,6 +248,7 @@ static const struct file_operations raw_fops = {
        .aio_read =     generic_file_aio_read,
        .write  =       do_sync_write,
        .aio_write =    blkdev_aio_write,
+       .fsync  =       blkdev_fsync,
        .open   =       raw_open,
        .release=       raw_release,
        .ioctl  =       raw_ioctl,
index be0ba401966e237bee1daf46dbd2d8ab81baa795..24a282bb89d4bd06fa2d0c82dd52333aad112c19 100644 (file)
@@ -31,7 +31,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <asm/io.h>
index 71f87600907ce04f1da12bb7d3279650a19c2857..2e71aecae206a434fb72501df914f34e90a6b6fb 100644 (file)
@@ -31,7 +31,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
index d687c17be15247343b9f0fd0c4f2882a8ae6f089..6415f3f32a724b4549ccf492487a762be18af999 100644 (file)
@@ -31,7 +31,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
 #include <asm/io.h>
index 706c2a25f7aa137de5f732df4fd62f1c605da178..f9b936ac3394de7e6a4c07b109049ef639b2d546 100644 (file)
@@ -31,7 +31,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <asm/io.h>
 #include <asm/system.h>
index 47fab7c3307302d3d0b553b61e8276a7e5be0824..8a90393faf3c652e1f8fcce37f4c6c99cf474cd2 100644 (file)
@@ -34,7 +34,6 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
 #include <linux/string.h>
index 0a8d1e56c99362e0da9b1df06c2452d30341d006..b02332a5412f781c2631046cb32e12866be64c47 100644 (file)
@@ -909,6 +909,7 @@ static int rc_open(struct tty_struct *tty, struct file *filp)
        if (error)
                return error;
 
+       tty->driver_data = port;
        return tty_port_open(&port->port, tty, filp);
 }
 
index 1ec3d5cd748f5e602fbf7813ca7a23266102daeb..78a62ebe75c72e02c2a9f2ba1ff6a469f63a07ea 100644 (file)
@@ -64,6 +64,7 @@
 #include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/tty_flip.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -626,7 +627,6 @@ static irqreturn_t cd2401_rx_interrupt(int irq, void *dev_id)
        char data;
        int char_count;
        int save_cnt;
-       int len;
 
        /* determine the channel and change to that context */
        channel = (u_short) (base_addr[CyLICR] >> 2);
@@ -1527,7 +1527,6 @@ static int
 cy_ioctl(struct tty_struct *tty, struct file *file,
         unsigned int cmd, unsigned long arg)
 {
-       unsigned long val;
        struct cyclades_port *info = tty->driver_data;
        int ret_val = 0;
        void __user *argp = (void __user *)arg;
index 55a95892ccf91d1005bad85fab371a7104fabe42..ee156948b9f810d3cd66fbb3ff303e218f884a53 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/unaligned.h>
index bba727c3807e355391df8df0c54385be0af07e5a..73f66d03624dfd2b1e51a0aab8c236fc6ec4c7d6 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/err.h>
 #include <linux/kfifo.h>
 #include <linux/platform_device.h>
+#include <linux/gfp.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
index 07ac14d949ce2f12dc94ab6e3b3c0a7ae3a32931..2c24fcdc722a920fe00861be3b77fe76f168d2e6 100644 (file)
@@ -94,6 +94,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/uaccess.h>
+#include <linux/gfp.h>
 
 #include "specialix_io8.h"
 #include "cd1865.h"
index 0e511d61f544eac34417456e509d86bedfd13624..6049fd731924022321f6f2ecf2f7ccf715f23366 100644 (file)
@@ -724,7 +724,6 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
 {
        struct stlport  *portp;
        struct stlbrd   *brdp;
-       struct tty_port *port;
        unsigned int    minordev, brdnr, panelnr;
        int             portnr;
 
@@ -754,7 +753,8 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
        portp = brdp->panels[panelnr]->ports[portnr];
        if (portp == NULL)
                return -ENODEV;
-       port = &portp->port;
+
+       tty->driver_data = portp;
        return tty_port_open(&portp->port, tty, filp);
 
 }
@@ -841,7 +841,8 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
        pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp);
 
        portp = tty->driver_data;
-       BUG_ON(portp == NULL);
+       if(portp == NULL)
+               return;
        tty_port_close(&portp->port, tty, filp);
 }
 
index 1ae2de7d8b4f333bed6a3bc5e2e63460cb4e1336..d4e8b213a46254f34622be1a3026e601e170b463 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/workqueue.h>
 #include <linux/hrtimer.h>
 #include <linux/oom.h>
+#include <linux/slab.h>
 
 #include <asm/ptrace.h>
 #include <asm/irq_regs.h>
@@ -288,7 +289,7 @@ static struct sysrq_key_op sysrq_showstate_blocked_op = {
 
 static void sysrq_ftrace_dump(int key, struct tty_struct *tty)
 {
-       ftrace_dump();
+       ftrace_dump(DUMP_ALL);
 }
 static struct sysrq_key_op sysrq_ftrace_dump_op = {
        .handler        = sysrq_ftrace_dump,
index f06bb37defb12d300eec4c7f5de67efa3d59b9f8..068c816e69423bb0065100f4599310907eb08bc9 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
 
index bf2170fb1cdd7d1d01581aeb9b5abe129a42d32b..0636520fa9bfc4521e02d5b968dd4329bbbf58fa 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/fs.h>
 #include <linux/security.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <acpi/acpi.h>
 #include "tpm.h"
 
index 70efba2ee05321a8960d6391b9cc742eb953dae7..a605cb7dd89887676d3af3102fde78b2ccbd3c51 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include "tpm.h"
 
 /* National definitions */
index 2405f17b29ddd87994f354e5530f264c726d5761..94345994f8a635c3f610327010eb391add6f6234 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/pnp.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/wait.h>
 #include "tpm.h"
index 283a15bc84e36e562704228958265a56e01071fa..1b8ee590b4caeebf0c2e1a5587d73eef996fe824 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/audit.h>
+#include <linux/slab.h>
 #include <linux/tty.h>
 
 struct tty_audit_buf {
index af8d97715728b4829ec152dcd22b5fa4516e9bbc..7ee52164d474b198d481bd4869da64dab33dbade 100644 (file)
@@ -248,7 +248,7 @@ int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
 {
        int copied = 0;
        do {
-               int goal = min(size - copied, TTY_BUFFER_PAGE);
+               int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
                int space = tty_buffer_request_room(tty, goal);
                struct tty_buffer *tb = tty->buf.tail;
                /* If there is no space then tb may be NULL */
@@ -285,7 +285,7 @@ int tty_insert_flip_string_flags(struct tty_struct *tty,
 {
        int copied = 0;
        do {
-               int goal = min(size - copied, TTY_BUFFER_PAGE);
+               int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
                int space = tty_buffer_request_room(tty, goal);
                struct tty_buffer *tb = tty->buf.tail;
                /* If there is no space then tb may be NULL */
index a42c466f7092e2f519f8428be2669ab964a56575..d71f0fc34b467c6e7a7c25c0762321f90b7e3fa0 100644 (file)
@@ -1423,6 +1423,8 @@ static void release_one_tty(struct work_struct *work)
        list_del_init(&tty->tty_files);
        file_list_unlock();
 
+       put_pid(tty->pgrp);
+       put_pid(tty->session);
        free_tty_struct(tty);
 }
 
@@ -1873,6 +1875,7 @@ got_driver:
                 */
                if (filp->f_op == &hung_up_tty_fops)
                        filp->f_op = &tty_fops;
+               unlock_kernel();
                goto retry_open;
        }
        unlock_kernel();
index be492dd664370a787b6da7a2b294b3bf53451de6..a3bd1d0b66cfe3fbba3bf9592c0bfbab26bb88a3 100644 (file)
@@ -119,7 +119,7 @@ EXPORT_SYMBOL(tty_port_tty_set);
 static void tty_port_shutdown(struct tty_port *port)
 {
        mutex_lock(&port->mutex);
-       if (port->ops->shutdown &&
+       if (port->ops->shutdown && !port->console &&
                test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
                        port->ops->shutdown(port);
        mutex_unlock(&port->mutex);
index 042c8149a6d12248cdbbf2e212628cf497f8f1ea..1144a04cda6e99e91f18b057be2f92f2630edda0 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
index f404ccfc9c20992f342eb366dd21231642d078ea..196428c2287a453b6259beff3cefd591199e6071 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/list.h>
 #include <linux/poll.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/virtio.h>
 #include <linux/virtio_console.h>
 #include <linux/workqueue.h>
 #include "hvc_console.h"
 
+/* Moved here from .h file in order to disable MULTIPORT. */
+#define VIRTIO_CONSOLE_F_MULTIPORT 1   /* Does host provide multiple ports? */
+
+struct virtio_console_multiport_conf {
+       struct virtio_console_config config;
+       /* max. number of ports this device can hold */
+       __u32 max_nr_ports;
+       /* number of ports added so far */
+       __u32 nr_ports;
+} __attribute__((packed));
+
+/*
+ * A message that's passed between the Host and the Guest for a
+ * particular port.
+ */
+struct virtio_console_control {
+       __u32 id;               /* Port number */
+       __u16 event;            /* The kind of control event (see below) */
+       __u16 value;            /* Extra information for the key */
+};
+
+/* Some events for control messages */
+#define VIRTIO_CONSOLE_PORT_READY      0
+#define VIRTIO_CONSOLE_CONSOLE_PORT    1
+#define VIRTIO_CONSOLE_RESIZE          2
+#define VIRTIO_CONSOLE_PORT_OPEN       3
+#define VIRTIO_CONSOLE_PORT_NAME       4
+#define VIRTIO_CONSOLE_PORT_REMOVE     5
+
 /*
  * This is a global struct for storing common data for all the devices
  * this driver handles.
@@ -120,7 +150,7 @@ struct ports_device {
        spinlock_t cvq_lock;
 
        /* The current config space is stored here */
-       struct virtio_console_config config;
+       struct virtio_console_multiport_conf config;
 
        /* The virtio device we're associated with */
        struct virtio_device *vdev;
@@ -415,20 +445,16 @@ static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count)
        out_vq->vq_ops->kick(out_vq);
 
        if (ret < 0) {
-               len = 0;
+               in_count = 0;
                goto fail;
        }
 
-       /*
-        * Wait till the host acknowledges it pushed out the data we
-        * sent. Also ensure we return to userspace the number of
-        * bytes that were successfully consumed by the host.
-        */
+       /* Wait till the host acknowledges it pushed out the data we sent. */
        while (!out_vq->vq_ops->get_buf(out_vq, &len))
                cpu_relax();
 fail:
        /* We're expected to return the amount of data we wrote */
-       return len;
+       return in_count;
 }
 
 /*
@@ -645,13 +671,13 @@ static int put_chars(u32 vtermno, const char *buf, int count)
 {
        struct port *port;
 
+       if (unlikely(early_put_chars))
+               return early_put_chars(vtermno, buf, count);
+
        port = find_port_by_vtermno(vtermno);
        if (!port)
                return 0;
 
-       if (unlikely(early_put_chars))
-               return early_put_chars(vtermno, buf, count);
-
        return send_buf(port, (void *)buf, count);
 }
 
@@ -681,6 +707,10 @@ static void resize_console(struct port *port)
        struct virtio_device *vdev;
        struct winsize ws;
 
+       /* The port could have been hot-unplugged */
+       if (!port)
+               return;
+
        vdev = port->portdev->vdev;
        if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)) {
                vdev->config->get(vdev,
@@ -947,11 +977,18 @@ static void handle_control_message(struct ports_device *portdev,
                 */
                err = sysfs_create_group(&port->dev->kobj,
                                         &port_attribute_group);
-               if (err)
+               if (err) {
                        dev_err(port->dev,
                                "Error %d creating sysfs device attributes\n",
                                err);
-
+               } else {
+                       /*
+                        * Generate a udev event so that appropriate
+                        * symlinks can be created based on udev
+                        * rules.
+                        */
+                       kobject_uevent(&port->dev->kobj, KOBJ_CHANGE);
+               }
                break;
        case VIRTIO_CONSOLE_PORT_REMOVE:
                /*
@@ -1206,7 +1243,7 @@ fail:
  */
 static void config_work_handler(struct work_struct *work)
 {
-       struct virtio_console_config virtconconf;
+       struct virtio_console_multiport_conf virtconconf;
        struct ports_device *portdev;
        struct virtio_device *vdev;
        int err;
@@ -1215,7 +1252,8 @@ static void config_work_handler(struct work_struct *work)
 
        vdev = portdev->vdev;
        vdev->config->get(vdev,
-                         offsetof(struct virtio_console_config, nr_ports),
+                         offsetof(struct virtio_console_multiport_conf,
+                                  nr_ports),
                          &virtconconf.nr_ports,
                          sizeof(virtconconf.nr_ports));
 
@@ -1407,16 +1445,19 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
        multiport = false;
        portdev->config.nr_ports = 1;
        portdev->config.max_nr_ports = 1;
+#if 0 /* Multiport is not quite ready yet --RR */
        if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) {
                multiport = true;
                vdev->features[0] |= 1 << VIRTIO_CONSOLE_F_MULTIPORT;
 
-               vdev->config->get(vdev, offsetof(struct virtio_console_config,
-                                                nr_ports),
+               vdev->config->get(vdev,
+                                 offsetof(struct virtio_console_multiport_conf,
+                                          nr_ports),
                                  &portdev->config.nr_ports,
                                  sizeof(portdev->config.nr_ports));
-               vdev->config->get(vdev, offsetof(struct virtio_console_config,
-                                                max_nr_ports),
+               vdev->config->get(vdev,
+                                 offsetof(struct virtio_console_multiport_conf,
+                                          max_nr_ports),
                                  &portdev->config.max_nr_ports,
                                  sizeof(portdev->config.max_nr_ports));
                if (portdev->config.nr_ports > portdev->config.max_nr_ports) {
@@ -1432,6 +1473,7 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
 
        /* Let the Host know we support multiple ports.*/
        vdev->config->finalize_features(vdev);
+#endif
 
        err = init_vqs(portdev);
        if (err < 0) {
@@ -1514,7 +1556,6 @@ static struct virtio_device_id id_table[] = {
 
 static unsigned int features[] = {
        VIRTIO_CONSOLE_F_SIZE,
-       VIRTIO_CONSOLE_F_MULTIPORT,
 };
 
 static struct virtio_driver virtio_console = {
index 8b24729fec89d2ebbee70dc3011d7fd2de670001..12de1202d22cc5b02dabd7362864d5120741cefc 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/fcntl.h>
 #include <linux/major.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/miscdevice.h>
 #include <linux/console.h>
 #include <linux/init.h>
index 87778dcf87277b71c74c6f287558fc1effc40893..6aa10284104aeb6e4bc3a22833ea347e67c5d976 100644 (file)
@@ -888,7 +888,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                        ret = -EFAULT;
                        goto out;
                }
-               if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS && tmp.mode != VT_PROCESS_AUTO) {
+               if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) {
                        ret = -EINVAL;
                        goto out;
                }
@@ -1622,7 +1622,7 @@ static void complete_change_console(struct vc_data *vc)
         * telling it that it has acquired. Also check if it has died and
         * clean up (similar to logic employed in change_console())
         */
-       if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) {
+       if (vc->vt_mode.mode == VT_PROCESS) {
                /*
                 * Send the signal as privileged - kill_pid() will
                 * tell us if the process has gone or something else
@@ -1682,7 +1682,7 @@ void change_console(struct vc_data *new_vc)
         * vt to auto control.
         */
        vc = vc_cons[fg_console].d;
-       if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) {
+       if (vc->vt_mode.mode == VT_PROCESS) {
                /*
                 * Send the signal as privileged - kill_pid() will
                 * tell us if the process has gone or something else
@@ -1693,28 +1693,27 @@ void change_console(struct vc_data *new_vc)
                 */
                vc->vt_newvt = new_vc->vc_num;
                if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
-                       if(vc->vt_mode.mode == VT_PROCESS)
-                               /*
-                                * It worked. Mark the vt to switch to and
-                                * return. The process needs to send us a
-                                * VT_RELDISP ioctl to complete the switch.
-                                */
-                               return;
-               } else {
                        /*
-                        * The controlling process has died, so we revert back to
-                        * normal operation. In this case, we'll also change back
-                        * to KD_TEXT mode. I'm not sure if this is strictly correct
-                        * but it saves the agony when the X server dies and the screen
-                        * remains blanked due to KD_GRAPHICS! It would be nice to do
-                        * this outside of VT_PROCESS but there is no single process
-                        * to account for and tracking tty count may be undesirable.
+                        * It worked. Mark the vt to switch to and
+                        * return. The process needs to send us a
+                        * VT_RELDISP ioctl to complete the switch.
                         */
-                       reset_vc(vc);
+                       return;
                }
 
                /*
-                * Fall through to normal (VT_AUTO and VT_PROCESS_AUTO) handling of the switch...
+                * The controlling process has died, so we revert back to
+                * normal operation. In this case, we'll also change back
+                * to KD_TEXT mode. I'm not sure if this is strictly correct
+                * but it saves the agony when the X server dies and the screen
+                * remains blanked due to KD_GRAPHICS! It would be nice to do
+                * this outside of VT_PROCESS but there is no single process
+                * to account for and tracking tty count may be undesirable.
+                */
+               reset_vc(vc);
+
+               /*
+                * Fall through to normal (VT_AUTO) handling of the switch...
                 */
        }
 
index 4846d50199f3d1c917d23d2a13aa1108d28cace9..7261b8d9087c01bfea7c8eea55d6f4c61b198b5b 100644 (file)
@@ -86,6 +86,7 @@
 #include <linux/fs.h>
 #include <linux/cdev.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
index 578595c4425d2836cdf283eb44e0e1039e060fa5..744f748cc84b7ee0b16146024af02951531fe69e 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/sh_timer.h>
+#include <linux/slab.h>
 
 struct sh_cmt_priv {
        void __iomem *mapbase;
index 4c8a759e60cdb56c14cf57002a9672f81100822e..5fb78bfd73bb7a3fcc84e5fee62fac0ab6f08ba2 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/err.h>
 #include <linux/clockchips.h>
 #include <linux/sh_timer.h>
+#include <linux/slab.h>
 
 struct sh_mtu2_priv {
        void __iomem *mapbase;
index 961f5b5ef6a3584c558c45dbe20a05074fe325b1..fc9ff1e5b7706e64cfb37e536aca2678afab1228 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/sh_timer.h>
+#include <linux/slab.h>
 
 struct sh_tmu_priv {
        void __iomem *mapbase;
index 60697909ebdb00c9e0a4546764fe7e283e4fe800..a7f046b0096ca26121a1016922fef359ee4d805c 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/ktime.h>
 #include <linux/init.h>
 #include <linux/connector.h>
+#include <linux/gfp.h>
 #include <asm/atomic.h>
 #include <asm/unaligned.h>
 
index 537c29ac4487bea4e4d27313f442ddbbc0f35ddc..1d48f40342cbfadd6834b5edaf06d39dddabe315 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/netlink.h>
 #include <linux/moduleparam.h>
 #include <linux/connector.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
index 2d5d575e889d519866a90c5e9abcafda16164770..063b2184caf5506fc1e1a83e1cd6c8dc6f22b6c3 100644 (file)
@@ -662,32 +662,20 @@ static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
        return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
 }
 
-#define define_one_ro(_name) \
-static struct freq_attr _name = \
-__ATTR(_name, 0444, show_##_name, NULL)
-
-#define define_one_ro0400(_name) \
-static struct freq_attr _name = \
-__ATTR(_name, 0400, show_##_name, NULL)
-
-#define define_one_rw(_name) \
-static struct freq_attr _name = \
-__ATTR(_name, 0644, show_##_name, store_##_name)
-
-define_one_ro0400(cpuinfo_cur_freq);
-define_one_ro(cpuinfo_min_freq);
-define_one_ro(cpuinfo_max_freq);
-define_one_ro(cpuinfo_transition_latency);
-define_one_ro(scaling_available_governors);
-define_one_ro(scaling_driver);
-define_one_ro(scaling_cur_freq);
-define_one_ro(bios_limit);
-define_one_ro(related_cpus);
-define_one_ro(affected_cpus);
-define_one_rw(scaling_min_freq);
-define_one_rw(scaling_max_freq);
-define_one_rw(scaling_governor);
-define_one_rw(scaling_setspeed);
+cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
+cpufreq_freq_attr_ro(cpuinfo_min_freq);
+cpufreq_freq_attr_ro(cpuinfo_max_freq);
+cpufreq_freq_attr_ro(cpuinfo_transition_latency);
+cpufreq_freq_attr_ro(scaling_available_governors);
+cpufreq_freq_attr_ro(scaling_driver);
+cpufreq_freq_attr_ro(scaling_cur_freq);
+cpufreq_freq_attr_ro(bios_limit);
+cpufreq_freq_attr_ro(related_cpus);
+cpufreq_freq_attr_ro(affected_cpus);
+cpufreq_freq_attr_rw(scaling_min_freq);
+cpufreq_freq_attr_rw(scaling_max_freq);
+cpufreq_freq_attr_rw(scaling_governor);
+cpufreq_freq_attr_rw(scaling_setspeed);
 
 static struct attribute *default_attrs[] = {
        &cpuinfo_min_freq.attr,
@@ -1113,6 +1101,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
        unsigned int cpu = sys_dev->id;
        unsigned long flags;
        struct cpufreq_policy *data;
+       struct kobject *kobj;
+       struct completion *cmp;
 #ifdef CONFIG_SMP
        struct sys_device *cpu_sys_dev;
        unsigned int j;
@@ -1141,10 +1131,11 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
                dprintk("removing link\n");
                cpumask_clear_cpu(cpu, data->cpus);
                spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-               sysfs_remove_link(&sys_dev->kobj, "cpufreq");
+               kobj = &sys_dev->kobj;
                cpufreq_cpu_put(data);
                cpufreq_debug_enable_ratelimit();
                unlock_policy_rwsem_write(cpu);
+               sysfs_remove_link(kobj, "cpufreq");
                return 0;
        }
 #endif
@@ -1181,7 +1172,10 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
                                data->governor->name, CPUFREQ_NAME_LEN);
 #endif
                        cpu_sys_dev = get_cpu_sysdev(j);
-                       sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq");
+                       kobj = &cpu_sys_dev->kobj;
+                       unlock_policy_rwsem_write(cpu);
+                       sysfs_remove_link(kobj, "cpufreq");
+                       lock_policy_rwsem_write(cpu);
                        cpufreq_cpu_put(data);
                }
        }
@@ -1192,19 +1186,22 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
        if (cpufreq_driver->target)
                __cpufreq_governor(data, CPUFREQ_GOV_STOP);
 
-       kobject_put(&data->kobj);
+       kobj = &data->kobj;
+       cmp = &data->kobj_unregister;
+       unlock_policy_rwsem_write(cpu);
+       kobject_put(kobj);
 
        /* we need to make sure that the underlying kobj is actually
         * not referenced anymore by anybody before we proceed with
         * unloading.
         */
        dprintk("waiting for dropping of refcount\n");
-       wait_for_completion(&data->kobj_unregister);
+       wait_for_completion(cmp);
        dprintk("wait complete\n");
 
+       lock_policy_rwsem_write(cpu);
        if (cpufreq_driver->exit)
                cpufreq_driver->exit(data);
-
        unlock_policy_rwsem_write(cpu);
 
        free_cpumask_var(data->related_cpus);
index 599a40b25cb06e26e14734e4af00efde52b57822..526bfbf696112a89784910718ddf3275ce025fef 100644 (file)
@@ -178,12 +178,8 @@ static ssize_t show_sampling_rate_min(struct kobject *kobj,
        return sprintf(buf, "%u\n", min_sampling_rate);
 }
 
-#define define_one_ro(_name)           \
-static struct global_attr _name =      \
-__ATTR(_name, 0444, show_##_name, NULL)
-
-define_one_ro(sampling_rate_max);
-define_one_ro(sampling_rate_min);
+define_one_global_ro(sampling_rate_max);
+define_one_global_ro(sampling_rate_min);
 
 /* cpufreq_conservative Governor Tunables */
 #define show_one(file_name, object)                                    \
@@ -221,12 +217,8 @@ show_one_old(freq_step);
 show_one_old(sampling_rate_min);
 show_one_old(sampling_rate_max);
 
-#define define_one_ro_old(object, _name)       \
-static struct freq_attr object =               \
-__ATTR(_name, 0444, show_##_name##_old, NULL)
-
-define_one_ro_old(sampling_rate_min_old, sampling_rate_min);
-define_one_ro_old(sampling_rate_max_old, sampling_rate_max);
+cpufreq_freq_attr_ro_old(sampling_rate_min);
+cpufreq_freq_attr_ro_old(sampling_rate_max);
 
 /*** delete after deprecation time ***/
 
@@ -364,16 +356,12 @@ static ssize_t store_freq_step(struct kobject *a, struct attribute *b,
        return count;
 }
 
-#define define_one_rw(_name) \
-static struct global_attr _name = \
-__ATTR(_name, 0644, show_##_name, store_##_name)
-
-define_one_rw(sampling_rate);
-define_one_rw(sampling_down_factor);
-define_one_rw(up_threshold);
-define_one_rw(down_threshold);
-define_one_rw(ignore_nice_load);
-define_one_rw(freq_step);
+define_one_global_rw(sampling_rate);
+define_one_global_rw(sampling_down_factor);
+define_one_global_rw(up_threshold);
+define_one_global_rw(down_threshold);
+define_one_global_rw(ignore_nice_load);
+define_one_global_rw(freq_step);
 
 static struct attribute *dbs_attributes[] = {
        &sampling_rate_max.attr,
@@ -409,16 +397,12 @@ write_one_old(down_threshold);
 write_one_old(ignore_nice_load);
 write_one_old(freq_step);
 
-#define define_one_rw_old(object, _name)       \
-static struct freq_attr object =               \
-__ATTR(_name, 0644, show_##_name##_old, store_##_name##_old)
-
-define_one_rw_old(sampling_rate_old, sampling_rate);
-define_one_rw_old(sampling_down_factor_old, sampling_down_factor);
-define_one_rw_old(up_threshold_old, up_threshold);
-define_one_rw_old(down_threshold_old, down_threshold);
-define_one_rw_old(ignore_nice_load_old, ignore_nice_load);
-define_one_rw_old(freq_step_old, freq_step);
+cpufreq_freq_attr_rw_old(sampling_rate);
+cpufreq_freq_attr_rw_old(sampling_down_factor);
+cpufreq_freq_attr_rw_old(up_threshold);
+cpufreq_freq_attr_rw_old(down_threshold);
+cpufreq_freq_attr_rw_old(ignore_nice_load);
+cpufreq_freq_attr_rw_old(freq_step);
 
 static struct attribute *dbs_attributes_old[] = {
        &sampling_rate_max_old.attr,
@@ -444,6 +428,7 @@ static struct attribute_group dbs_attr_group_old = {
 static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
 {
        unsigned int load = 0;
+       unsigned int max_load = 0;
        unsigned int freq_target;
 
        struct cpufreq_policy *policy;
@@ -501,6 +486,9 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
                        continue;
 
                load = 100 * (wall_time - idle_time) / wall_time;
+
+               if (load > max_load)
+                       max_load = load;
        }
 
        /*
@@ -511,7 +499,7 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
                return;
 
        /* Check for frequency increase */
-       if (load > dbs_tuners_ins.up_threshold) {
+       if (max_load > dbs_tuners_ins.up_threshold) {
                this_dbs_info->down_skip = 0;
 
                /* if we are already at full speed then break out early */
@@ -538,7 +526,7 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
         * can support the current CPU usage without triggering the up
         * policy. To be safe, we focus 10 points under the threshold.
         */
-       if (load < (dbs_tuners_ins.down_threshold - 10)) {
+       if (max_load < (dbs_tuners_ins.down_threshold - 10)) {
                freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100;
 
                this_dbs_info->requested_freq -= freq_target;
index bd444dc93cf2ebf55c3e8545be249c6f025b7308..e1314212d8d4e2d3789c2ae4658e504963bc6a90 100644 (file)
@@ -73,6 +73,7 @@ enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE};
 
 struct cpu_dbs_info_s {
        cputime64_t prev_cpu_idle;
+       cputime64_t prev_cpu_iowait;
        cputime64_t prev_cpu_wall;
        cputime64_t prev_cpu_nice;
        struct cpufreq_policy *cur_policy;
@@ -108,6 +109,7 @@ static struct dbs_tuners {
        unsigned int down_differential;
        unsigned int ignore_nice;
        unsigned int powersave_bias;
+       unsigned int io_is_busy;
 } dbs_tuners_ins = {
        .up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
        .down_differential = DEF_FREQUENCY_DOWN_DIFFERENTIAL,
@@ -148,6 +150,16 @@ static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
        return idle_time;
 }
 
+static inline cputime64_t get_cpu_iowait_time(unsigned int cpu, cputime64_t *wall)
+{
+       u64 iowait_time = get_cpu_iowait_time_us(cpu, wall);
+
+       if (iowait_time == -1ULL)
+               return 0;
+
+       return iowait_time;
+}
+
 /*
  * Find right freq to be set now with powersave_bias on.
  * Returns the freq_hi to be used right now and will set freq_hi_jiffies,
@@ -234,12 +246,8 @@ static ssize_t show_sampling_rate_min(struct kobject *kobj,
        return sprintf(buf, "%u\n", min_sampling_rate);
 }
 
-#define define_one_ro(_name)           \
-static struct global_attr _name =      \
-__ATTR(_name, 0444, show_##_name, NULL)
-
-define_one_ro(sampling_rate_max);
-define_one_ro(sampling_rate_min);
+define_one_global_ro(sampling_rate_max);
+define_one_global_ro(sampling_rate_min);
 
 /* cpufreq_ondemand Governor Tunables */
 #define show_one(file_name, object)                                    \
@@ -249,6 +257,7 @@ static ssize_t show_##file_name                                             \
        return sprintf(buf, "%u\n", dbs_tuners_ins.object);             \
 }
 show_one(sampling_rate, sampling_rate);
+show_one(io_is_busy, io_is_busy);
 show_one(up_threshold, up_threshold);
 show_one(ignore_nice_load, ignore_nice);
 show_one(powersave_bias, powersave_bias);
@@ -274,12 +283,8 @@ show_one_old(powersave_bias);
 show_one_old(sampling_rate_min);
 show_one_old(sampling_rate_max);
 
-#define define_one_ro_old(object, _name)       \
-static struct freq_attr object =               \
-__ATTR(_name, 0444, show_##_name##_old, NULL)
-
-define_one_ro_old(sampling_rate_min_old, sampling_rate_min);
-define_one_ro_old(sampling_rate_max_old, sampling_rate_max);
+cpufreq_freq_attr_ro_old(sampling_rate_min);
+cpufreq_freq_attr_ro_old(sampling_rate_max);
 
 /*** delete after deprecation time ***/
 
@@ -299,6 +304,23 @@ static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
        return count;
 }
 
+static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b,
+                                  const char *buf, size_t count)
+{
+       unsigned int input;
+       int ret;
+
+       ret = sscanf(buf, "%u", &input);
+       if (ret != 1)
+               return -EINVAL;
+
+       mutex_lock(&dbs_mutex);
+       dbs_tuners_ins.io_is_busy = !!input;
+       mutex_unlock(&dbs_mutex);
+
+       return count;
+}
+
 static ssize_t store_up_threshold(struct kobject *a, struct attribute *b,
                                  const char *buf, size_t count)
 {
@@ -376,14 +398,11 @@ static ssize_t store_powersave_bias(struct kobject *a, struct attribute *b,
        return count;
 }
 
-#define define_one_rw(_name) \
-static struct global_attr _name = \
-__ATTR(_name, 0644, show_##_name, store_##_name)
-
-define_one_rw(sampling_rate);
-define_one_rw(up_threshold);
-define_one_rw(ignore_nice_load);
-define_one_rw(powersave_bias);
+define_one_global_rw(sampling_rate);
+define_one_global_rw(io_is_busy);
+define_one_global_rw(up_threshold);
+define_one_global_rw(ignore_nice_load);
+define_one_global_rw(powersave_bias);
 
 static struct attribute *dbs_attributes[] = {
        &sampling_rate_max.attr,
@@ -392,6 +411,7 @@ static struct attribute *dbs_attributes[] = {
        &up_threshold.attr,
        &ignore_nice_load.attr,
        &powersave_bias.attr,
+       &io_is_busy.attr,
        NULL
 };
 
@@ -415,14 +435,10 @@ write_one_old(up_threshold);
 write_one_old(ignore_nice_load);
 write_one_old(powersave_bias);
 
-#define define_one_rw_old(object, _name)       \
-static struct freq_attr object =               \
-__ATTR(_name, 0644, show_##_name##_old, store_##_name##_old)
-
-define_one_rw_old(sampling_rate_old, sampling_rate);
-define_one_rw_old(up_threshold_old, up_threshold);
-define_one_rw_old(ignore_nice_load_old, ignore_nice_load);
-define_one_rw_old(powersave_bias_old, powersave_bias);
+cpufreq_freq_attr_rw_old(sampling_rate);
+cpufreq_freq_attr_rw_old(up_threshold);
+cpufreq_freq_attr_rw_old(ignore_nice_load);
+cpufreq_freq_attr_rw_old(powersave_bias);
 
 static struct attribute *dbs_attributes_old[] = {
        &sampling_rate_max_old.attr,
@@ -470,14 +486,15 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
 
        for_each_cpu(j, policy->cpus) {
                struct cpu_dbs_info_s *j_dbs_info;
-               cputime64_t cur_wall_time, cur_idle_time;
-               unsigned int idle_time, wall_time;
+               cputime64_t cur_wall_time, cur_idle_time, cur_iowait_time;
+               unsigned int idle_time, wall_time, iowait_time;
                unsigned int load, load_freq;
                int freq_avg;
 
                j_dbs_info = &per_cpu(od_cpu_dbs_info, j);
 
                cur_idle_time = get_cpu_idle_time(j, &cur_wall_time);
+               cur_iowait_time = get_cpu_iowait_time(j, &cur_wall_time);
 
                wall_time = (unsigned int) cputime64_sub(cur_wall_time,
                                j_dbs_info->prev_cpu_wall);
@@ -487,6 +504,10 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
                                j_dbs_info->prev_cpu_idle);
                j_dbs_info->prev_cpu_idle = cur_idle_time;
 
+               iowait_time = (unsigned int) cputime64_sub(cur_iowait_time,
+                               j_dbs_info->prev_cpu_iowait);
+               j_dbs_info->prev_cpu_iowait = cur_iowait_time;
+
                if (dbs_tuners_ins.ignore_nice) {
                        cputime64_t cur_nice;
                        unsigned long cur_nice_jiffies;
@@ -504,6 +525,16 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
                        idle_time += jiffies_to_usecs(cur_nice_jiffies);
                }
 
+               /*
+                * For the purpose of ondemand, waiting for disk IO is an
+                * indication that you're performance critical, and not that
+                * the system is actually idle. So subtract the iowait time
+                * from the cpu idle time.
+                */
+
+               if (dbs_tuners_ins.io_is_busy && idle_time >= iowait_time)
+                       idle_time -= iowait_time;
+
                if (unlikely(!wall_time || wall_time < idle_time))
                        continue;
 
@@ -617,6 +648,29 @@ static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
        cancel_delayed_work_sync(&dbs_info->work);
 }
 
+/*
+ * Not all CPUs want IO time to be accounted as busy; this dependson how
+ * efficient idling at a higher frequency/voltage is.
+ * Pavel Machek says this is not so for various generations of AMD and old
+ * Intel systems.
+ * Mike Chan (androidlcom) calis this is also not true for ARM.
+ * Because of this, whitelist specific known (series) of CPUs by default, and
+ * leave all others up to the user.
+ */
+static int should_io_be_busy(void)
+{
+#if defined(CONFIG_X86)
+       /*
+        * For Intel, Core 2 (model 15) andl later have an efficient idle.
+        */
+       if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
+           boot_cpu_data.x86 == 6 &&
+           boot_cpu_data.x86_model >= 15)
+               return 1;
+#endif
+       return 0;
+}
+
 static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                                   unsigned int event)
 {
@@ -679,6 +733,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                        dbs_tuners_ins.sampling_rate =
                                max(min_sampling_rate,
                                    latency * LATENCY_MULTIPLIER);
+                       dbs_tuners_ins.io_is_busy = should_io_be_busy();
                }
                mutex_unlock(&dbs_mutex);
 
index 5a62d678dd1932f777f17fec0bdbda8d6c9398f9..00d73fc8e4e2853d26d217761a2d2e40a2b22ead 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/sysdev.h>
 #include <linux/cpu.h>
 #include <linux/sysfs.h>
index 1aea7157d8fffa603ca79d4cca7552db0bb313bd..f8e57c6303f2c17860d7f7700975ed5502743cb7 100644 (file)
@@ -100,7 +100,6 @@ struct menu_device {
        int             needs_update;
 
        unsigned int    expected_us;
-       unsigned int    measured_us;
        u64             predicted_us;
        unsigned int    exit_us;
        unsigned int    bucket;
@@ -187,14 +186,14 @@ static int menu_select(struct cpuidle_device *dev)
        int i;
        int multiplier;
 
-       data->last_state_idx = 0;
-       data->exit_us = 0;
-
        if (data->needs_update) {
                menu_update(dev);
                data->needs_update = 0;
        }
 
+       data->last_state_idx = 0;
+       data->exit_us = 0;
+
        /* Special case when user has set very strict latency requirement */
        if (unlikely(latency_req == 0))
                return 0;
@@ -294,7 +293,7 @@ static void menu_update(struct cpuidle_device *dev)
        new_factor = data->correction_factor[data->bucket]
                        * (DECAY - 1) / DECAY;
 
-       if (data->expected_us > 0 && data->measured_us < MAX_INTERESTING)
+       if (data->expected_us > 0 && measured_us < MAX_INTERESTING)
                new_factor += RESOLUTION * measured_us / data->expected_us;
        else
                /*
index 8719b36e1a4d9adc858d2327fcac40d66e7df121..0ba9c8b8ee743e960eed3db8e5d9108d7c5eeadc 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/cpuidle.h>
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 #include <linux/cpu.h>
 
 #include "cpuidle.h"
index 1c3849f6b7a2e6c65d68245c2af3809befe40325..6c4c8b7ce3aa195e5dac4e05f7db38c6051a783b 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 #include <asm/dcr.h>
 #include <asm/dcr-regs.h>
 #include <asm/cacheflush.h>
index 6c6656d3b1e2f25c718f85c654a133e21c3090d5..f17ddf37a1edd3852def9fbe0f4f84b1a5348bca 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
+#include <linux/gfp.h>
 
 #include <crypto/ctr.h>
 #include <crypto/des.h>
index b21ef635f3521cbf41f61ff5ce7d01fd45902142..6f29012bcc434dbcc1101782072678991d53a509 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kthread.h>
 #include <linux/platform_device.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 #include "mv_cesa.h"
 /*
index 8c2f3703ec855f27a6863cb964c5d58a9d01dfa2..2e992bc8015b7bd63bf0c5b4b878b8da1bfa69c4 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/percpu.h>
 #include <linux/smp.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 #include <asm/processor.h>
 #include <asm/i387.h>
index fd529d68c5ba5e2494fc44d0ec33eca8741d951e..dc558a09731105bd5b88a93b46acd6b7211d6e6c 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/io.h>
 #include <linux/spinlock.h>
 #include <linux/rtnetlink.h>
+#include <linux/slab.h>
 
 #include <crypto/algapi.h>
 #include <crypto/aes.h>
index 52e6bb70a490d8bebf26745191bcf80ce5338ca2..8661c84a105d86751e1990636f6dbcdeb4962cf3 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/notifier.h>
 #include <linux/device.h>
 #include <linux/dca.h>
+#include <linux/slab.h>
 
 #define DCA_VERSION "1.12.1"
 
index ee916c9857eed0896460e6efb65451082ddbe593..5e8f335e6f6ef36145da8ec7461ba15c04f6344c 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/kdev_t.h>
 #include <linux/err.h>
 #include <linux/dca.h>
+#include <linux/gfp.h>
 
 static struct class *dca_class;
 static struct idr dca_idr;
index efc1a61ca2310bec0b517d20d7675c3f800f0717..278cf5bceef209ad95b796e184239b71978765ab 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include "at_hdmac_regs.h"
 
index 71d58c1a1e862409287ccecb5d874c51fd567e34..9f7e0e6a7eea12e8487cef8fd1395c38cfbdc7a0 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/spinlock.h>
 #include <linux/dmapool.h>
 #include <linux/memory.h>
+#include <linux/gfp.h>
 #include <mach/coh901318.h>
 
 #include "coh901318_lli.h"
index 87399cafce37f3036e228a916126a266d0b501b2..d18b5d069d7eb768789a7f99b783b7c632bb2660 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/jiffies.h>
 #include <linux/rculist.h>
 #include <linux/idr.h>
+#include <linux/slab.h>
 
 static DEFINE_MUTEX(dma_list_mutex);
 static LIST_HEAD(dma_device_list);
index 6fa55fe3dd248034ef5dc3259755c2ce731be47e..68d58c414cf0d67ad5fa975f6ae144a9b0c40012 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <linux/wait.h>
 
 static unsigned int test_buf_size = 16384;
index bbb4be5a3ff493be3bf35ac07474e43002efd71d..88f470f0d820ae5d599f09bf0452351bab203217 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/dmaengine.h>
 #include <linux/delay.h>
index 0099340b96165e326b3682eae05219d7fafcf4b6..3e5a8005c62b9561465609358424acad3c153322 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/dmaengine.h>
index 1ed5d66d7dca0f87f5765bb3ee2242fa684cb7a0..b5ae56c211e6edfd6b1f821f00a872381b309e58 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/dmaengine.h>
index 26febc56dab111470f0eed860a34faea40554e98..6740e319c9cf5422ff4b918c648d4b57e46c97a7 100644 (file)
@@ -57,6 +57,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
 #include "registers.h"
index d545fae30f370f933154a35ba095780fae81e13e..99ec26725bae89699ed758fbee0dd6af9be68582 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/dca.h>
+#include <linux/slab.h>
 #include "dma.h"
 #include "dma_v2.h"
 #include "registers.h"
index ca6e6a0cb7931e32a85b0f9d8da9bb2f5855b63a..1ebc801678b0159e2d7a7017036234160a9493be 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/memory.h>
 #include <linux/ioport.h>
 #include <linux/raid/pq.h>
+#include <linux/slab.h>
 
 #include <mach/adma.h>
 
index c0a272c7368267ad25bd5185e14d5fa965cb2751..bb48a57c2fc1ee291941639754354bf8b7284dc4 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/dmaengine.h>
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 #include <net/tcp.h> /* for memcpy_toiovec */
 #include <asm/io.h>
 #include <asm/uaccess.h>
index 3fdf1f46bd635763772418515ddb1431ff8de574..bbbd58566625cc4b92cb5edf5669528140b03167 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
 
index 466ab10c1ff10de1d001178fde9fdce203c410e3..e2fd34da64f2b2d2930c6fedb00d0aee5a02396a 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
index e69d87f24a257210c14381722617246a1fd184d7..d44626fa35ad08c14c3cb3c6f7a8eb91b655b5b6 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/proc_fs.h>
 #include <linux/of.h>
index 5d17e09cb625412beaf0e8275f39142b7006a4c1..6f25a20de99fbc39e30c6bbbdef0f5e5e3f81fb4 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/dmaengine.h>
 #include <linux/delay.h>
@@ -289,6 +290,7 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
        struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
        struct sh_desc *desc;
        struct sh_dmae_slave *param = chan->private;
+       int ret;
 
        pm_runtime_get_sync(sh_chan->dev);
 
@@ -300,11 +302,15 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
                struct sh_dmae_slave_config *cfg;
 
                cfg = sh_dmae_find_slave(sh_chan, param->slave_id);
-               if (!cfg)
-                       return -EINVAL;
+               if (!cfg) {
+                       ret = -EINVAL;
+                       goto efindslave;
+               }
 
-               if (test_and_set_bit(param->slave_id, sh_dmae_slave_used))
-                       return -EBUSY;
+               if (test_and_set_bit(param->slave_id, sh_dmae_slave_used)) {
+                       ret = -EBUSY;
+                       goto etestused;
+               }
 
                param->config = cfg;
 
@@ -333,10 +339,20 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
        }
        spin_unlock_bh(&sh_chan->desc_lock);
 
-       if (!sh_chan->descs_allocated)
-               pm_runtime_put(sh_chan->dev);
+       if (!sh_chan->descs_allocated) {
+               ret = -ENOMEM;
+               goto edescalloc;
+       }
 
        return sh_chan->descs_allocated;
+
+edescalloc:
+       if (param)
+               clear_bit(param->slave_id, sh_dmae_slave_used);
+etestused:
+efindslave:
+       pm_runtime_put(sh_chan->dev);
+       return ret;
 }
 
 /*
index 3ebc61067e548d407af798687db075ae15003385..75fcf1ac8bb784d79af54a5e50ace219c8ada444 100644 (file)
@@ -1359,3 +1359,5 @@ module_exit(txx9dmac_exit);
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("TXx9 DMA Controller driver");
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
+MODULE_ALIAS("platform:txx9dmac");
+MODULE_ALIAS("platform:txx9dmac-chan");
index 2b95f1a3edfc318fe93ebf58b9bbd89cc8035599..f2330f81cb5ea9b05f5a6c229737f627d5dba601 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
index 3d50274f1348d97b6e3cc4bc9d9f071e73ebb2ec..1609a19df49532b735a6170fe7f56c01114099b6 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/edac.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/gfp.h>
 
 #include "edac_core.h"
 #include "edac_module.h"
index 243e9aacad69dd28cbcbf58893670f2ac9856bce..ae3f80c54198a29918f3809b1299918a330277ac 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
index c7d11cc4e21a5d608c96695f64cb29d78fb54f15..1731d7245816fdedf681d14a5b9290acdeb11a1f 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
index 5fdedbc0f54529de3ef0e8b79a5a49ef6f0f5259..070968178a24a80703708dd50ba363301ad71aac 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/ctype.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "edac_core.h"
 #include "edac_module.h"
index 88840e9fa3e09c200d01b5fb733df7746d32091a..418b65f1a1da858c5b127c863ced032f773424e1 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <linux/bug.h>
 
 #include "edac_core.h"
index 8fc91a019620d57fab83e04ed34fac8d826f0e32..97e64bcdbc061c3b593ee757bd66a6999afb4761 100644 (file)
@@ -294,7 +294,6 @@ wrong_ls_mce:
 void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
 {
        u32 ec  = ERROR_CODE(regs->nbsl);
-       u32 xec = EXT_ERROR_CODE(regs->nbsl);
 
        if (!handle_errors)
                return;
@@ -316,10 +315,15 @@ void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
                if (regs->nbsh & K8_NBSH_ERR_CPU_VAL)
                        pr_cont(", core: %u\n", (u8)(regs->nbsh & 0xf));
        } else {
-               pr_cont(", core: %d\n", fls((regs->nbsh & 0xf) - 1));
+               u8 assoc_cpus = regs->nbsh & 0xf;
+
+               if (assoc_cpus > 0)
+                       pr_cont(", core: %d", fls(assoc_cpus) - 1);
+
+               pr_cont("\n");
        }
 
-       pr_emerg("%s.\n", EXT_ERR_MSG(xec));
+       pr_emerg("%s.\n", EXT_ERR_MSG(regs->nbsl));
 
        if (BUS_ERROR(ec) && nb_bus_decoder)
                nb_bus_decoder(node_id, regs);
@@ -369,7 +373,7 @@ static int amd_decode_mce(struct notifier_block *nb, unsigned long val,
                 ((m->status & MCI_STATUS_PCC) ? "yes" : "no"));
 
        /* do the two bits[14:13] together */
-       ecc = m->status & (3ULL << 45);
+       ecc = (m->status >> 45) & 0x3;
        if (ecc)
                pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U"));
 
index bef94e3d99444eddaa6f6a149a9ba6fe005b073e..c39697df9cb41e87c8177c76bab788b85567003e 100644 (file)
@@ -8,6 +8,7 @@
  */
 #include <linux/module.h>
 #include <linux/sysdev.h>
+#include <linux/slab.h>
 #include <linux/ctype.h>
 
 #include "edac_core.h"
index 6c9a0f2a593cd89fbc998182798bf1e21894d5ea..c0510b3d7035314ecaf89f0bf97ba8092b051f29 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
index fde4db91c4d2c193d117676c15170d6d06df28aa..d41f9002da45d403eb8bc36ca5cc1dccaf477490 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include <linux/io.h>
 #include "edac_core.h"
index 7785d8ffa40486841e3d3f09d66f50416fb91b6e..ee9753cf362ce04901b9924fa82d43a58c3a8224 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include <linux/delay.h>
 #include <linux/mmzone.h>
index 577760a82a0f7d5519cd2631ccf1d7fd99f3ec05..7f3884fcbd467426ad4beec3c53fe91ec99ad46b 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
 
-#include <linux/slab.h>
 
 #include <linux/edac.h>
 #include "edac_core.h"
index c0088ba9672b754429d0bcd8bea19329f36c4064..b8a95cf50718b8e6ef15f74a9c12d49b2b486568 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
index b2d83b95033d382c3d2818c56533287ff4d77d67..b2fd1e899142a15d0020f618e79f218e366a0676 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
index 2eed3ea2cf621303320aec118f0ed3bcfcd9764f..3218819b7286008c908f53869506a73063fa9a57 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
index 94cac0aacea301babafb4abb3ef3cfad3170bae0..4471647b4807eadb31b6e4e278a5298bcfed97e8 100644 (file)
  */
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/ctype.h>
 #include <linux/io.h>
 #include <linux/mod_devicetable.h>
 #include <linux/edac.h>
 #include <linux/smp.h>
+#include <linux/gfp.h>
 
 #include <linux/of_platform.h>
 #include <linux/of_device.h>
index a6b9fec13a74cd4a8afb8a10a89c55e240a7fa86..7e5ff367705c66c25f8ad914772729a04cf585f4 100644 (file)
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/edac.h>
+#include <linux/gfp.h>
 
 #include "edac_core.h"
 #include "edac_module.h"
index 8e6b91bd2e99994525cba93fbdaac6750ec6da23..7f71ee43674486fe3051013729b7b287225f4619 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
index 9900675e9598c25006dd696f6f4d20af3694a223..d55f8e9de78878fc4379645fb26631b487f4cb7c 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
index d4ec6059317604e40aae2e705b50f636dc26c4b9..b6f47de152f31f4130938e04c468b1bbe7933a00 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
-#include <linux/slab.h>
 #include <linux/edac.h>
 #include "edac_core.h"
 
index 8be720b278b7a435d2c106794c2cd663438c92a7..14a34d99eea25554bb123af7c44f44e8d01582a8 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/mutex.h>
 #include <linux/poll.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/time.h>
@@ -959,6 +960,8 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
                u.packet.header_length = GET_HEADER_LENGTH(control);
 
                if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) {
+                       if (u.packet.header_length % 4 != 0)
+                               return -EINVAL;
                        header_length = u.packet.header_length;
                } else {
                        /*
@@ -968,7 +971,8 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
                        if (ctx->header_size == 0) {
                                if (u.packet.header_length > 0)
                                        return -EINVAL;
-                       } else if (u.packet.header_length % ctx->header_size != 0) {
+                       } else if (u.packet.header_length == 0 ||
+                                  u.packet.header_length % ctx->header_size != 0) {
                                return -EINVAL;
                        }
                        header_length = 0;
@@ -1353,24 +1357,24 @@ static int dispatch_ioctl(struct client *client,
                return -ENODEV;
 
        if (_IOC_TYPE(cmd) != '#' ||
-           _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers))
+           _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) ||
+           _IOC_SIZE(cmd) > sizeof(buffer))
                return -EINVAL;
 
-       if (_IOC_DIR(cmd) & _IOC_WRITE) {
-               if (_IOC_SIZE(cmd) > sizeof(buffer) ||
-                   copy_from_user(&buffer, arg, _IOC_SIZE(cmd)))
+       if (_IOC_DIR(cmd) == _IOC_READ)
+               memset(&buffer, 0, _IOC_SIZE(cmd));
+
+       if (_IOC_DIR(cmd) & _IOC_WRITE)
+               if (copy_from_user(&buffer, arg, _IOC_SIZE(cmd)))
                        return -EFAULT;
-       }
 
        ret = ioctl_handlers[_IOC_NR(cmd)](client, &buffer);
        if (ret < 0)
                return ret;
 
-       if (_IOC_DIR(cmd) & _IOC_READ) {
-               if (_IOC_SIZE(cmd) > sizeof(buffer) ||
-                   copy_to_user(arg, &buffer, _IOC_SIZE(cmd)))
+       if (_IOC_DIR(cmd) & _IOC_READ)
+               if (copy_to_user(arg, &buffer, _IOC_SIZE(cmd)))
                        return -EFAULT;
-       }
 
        return ret;
 }
index 5db0518c66da687068c5ede57bce232fb4463283..4b8523f00dce3c1e006bcf05a0c17a608d58d939 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/rwsem.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/workqueue.h>
@@ -126,97 +127,74 @@ int fw_csr_string(const u32 *directory, int key, char *buf, size_t size)
 }
 EXPORT_SYMBOL(fw_csr_string);
 
-static bool is_fw_unit(struct device *dev);
-
-static int match_unit_directory(const u32 *directory, u32 match_flags,
-                               const struct ieee1394_device_id *id)
+static void get_ids(const u32 *directory, int *id)
 {
        struct fw_csr_iterator ci;
-       int key, value, match;
+       int key, value;
 
-       match = 0;
        fw_csr_iterator_init(&ci, directory);
        while (fw_csr_iterator_next(&ci, &key, &value)) {
-               if (key == CSR_VENDOR && value == id->vendor_id)
-                       match |= IEEE1394_MATCH_VENDOR_ID;
-               if (key == CSR_MODEL && value == id->model_id)
-                       match |= IEEE1394_MATCH_MODEL_ID;
-               if (key == CSR_SPECIFIER_ID && value == id->specifier_id)
-                       match |= IEEE1394_MATCH_SPECIFIER_ID;
-               if (key == CSR_VERSION && value == id->version)
-                       match |= IEEE1394_MATCH_VERSION;
+               switch (key) {
+               case CSR_VENDOR:        id[0] = value; break;
+               case CSR_MODEL:         id[1] = value; break;
+               case CSR_SPECIFIER_ID:  id[2] = value; break;
+               case CSR_VERSION:       id[3] = value; break;
+               }
        }
+}
+
+static void get_modalias_ids(struct fw_unit *unit, int *id)
+{
+       get_ids(&fw_parent_device(unit)->config_rom[5], id);
+       get_ids(unit->directory, id);
+}
+
+static bool match_ids(const struct ieee1394_device_id *id_table, int *id)
+{
+       int match = 0;
+
+       if (id[0] == id_table->vendor_id)
+               match |= IEEE1394_MATCH_VENDOR_ID;
+       if (id[1] == id_table->model_id)
+               match |= IEEE1394_MATCH_MODEL_ID;
+       if (id[2] == id_table->specifier_id)
+               match |= IEEE1394_MATCH_SPECIFIER_ID;
+       if (id[3] == id_table->version)
+               match |= IEEE1394_MATCH_VERSION;
 
-       return (match & match_flags) == match_flags;
+       return (match & id_table->match_flags) == id_table->match_flags;
 }
 
+static bool is_fw_unit(struct device *dev);
+
 static int fw_unit_match(struct device *dev, struct device_driver *drv)
 {
-       struct fw_unit *unit = fw_unit(dev);
-       struct fw_device *device;
-       const struct ieee1394_device_id *id;
+       const struct ieee1394_device_id *id_table =
+                       container_of(drv, struct fw_driver, driver)->id_table;
+       int id[] = {0, 0, 0, 0};
 
        /* We only allow binding to fw_units. */
        if (!is_fw_unit(dev))
                return 0;
 
-       device = fw_parent_device(unit);
-       id = container_of(drv, struct fw_driver, driver)->id_table;
+       get_modalias_ids(fw_unit(dev), id);
 
-       for (; id->match_flags != 0; id++) {
-               if (match_unit_directory(unit->directory, id->match_flags, id))
+       for (; id_table->match_flags != 0; id_table++)
+               if (match_ids(id_table, id))
                        return 1;
 
-               /* Also check vendor ID in the root directory. */
-               if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
-                   match_unit_directory(&device->config_rom[5],
-                               IEEE1394_MATCH_VENDOR_ID, id) &&
-                   match_unit_directory(unit->directory, id->match_flags
-                               & ~IEEE1394_MATCH_VENDOR_ID, id))
-                       return 1;
-       }
-
        return 0;
 }
 
 static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
 {
-       struct fw_device *device = fw_parent_device(unit);
-       struct fw_csr_iterator ci;
+       int id[] = {0, 0, 0, 0};
 
-       int key, value;
-       int vendor = 0;
-       int model = 0;
-       int specifier_id = 0;
-       int version = 0;
-
-       fw_csr_iterator_init(&ci, &device->config_rom[5]);
-       while (fw_csr_iterator_next(&ci, &key, &value)) {
-               switch (key) {
-               case CSR_VENDOR:
-                       vendor = value;
-                       break;
-               case CSR_MODEL:
-                       model = value;
-                       break;
-               }
-       }
-
-       fw_csr_iterator_init(&ci, unit->directory);
-       while (fw_csr_iterator_next(&ci, &key, &value)) {
-               switch (key) {
-               case CSR_SPECIFIER_ID:
-                       specifier_id = value;
-                       break;
-               case CSR_VERSION:
-                       version = value;
-                       break;
-               }
-       }
+       get_modalias_ids(unit, id);
 
        return snprintf(buffer, buffer_size,
                        "ieee1394:ven%08Xmo%08Xsp%08Xver%08X",
-                       vendor, model, specifier_id, version);
+                       id[0], id[1], id[2], id[3]);
 }
 
 static int fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
index 1c0b504a42f3068e852fa1b7423ee5c37bfb0abd..8f5aebfb29dfbd5988fd7c5fcb5adfadd8b71b76 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/firewire-constants.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/vmalloc.h>
 
@@ -189,7 +190,7 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
        for (try = 0; try < 5; try++) {
                new = allocate ? old - bandwidth : old + bandwidth;
                if (new < 0 || new > BANDWIDTH_AVAILABLE_INITIAL)
-                       break;
+                       return -EBUSY;
 
                data[0] = cpu_to_be32(old);
                data[1] = cpu_to_be32(new);
@@ -217,7 +218,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
                u32 channels_mask, u64 offset, bool allocate, __be32 data[2])
 {
        __be32 c, all, old;
-       int i, retry = 5;
+       int i, ret = -EIO, retry = 5;
 
        old = all = allocate ? cpu_to_be32(~0) : 0;
 
@@ -225,6 +226,8 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
                if (!(channels_mask & 1 << i))
                        continue;
 
+               ret = -EBUSY;
+
                c = cpu_to_be32(1 << (31 - i));
                if ((old & c) != (all & c))
                        continue;
@@ -250,12 +253,16 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
 
                        /* 1394-1995 IRM, fall through to retry. */
                default:
-                       if (retry--)
+                       if (retry) {
+                               retry--;
                                i--;
+                       } else {
+                               ret = -EIO;
+                       }
                }
        }
 
-       return -EIO;
+       return ret;
 }
 
 static void deallocate_channel(struct fw_card *card, int irm_id,
@@ -331,8 +338,9 @@ void fw_iso_resource_manage(struct fw_card *card, int generation,
        if (ret < 0)
                *bandwidth = 0;
 
-       if (allocate && ret < 0 && c >= 0) {
-               deallocate_channel(card, irm_id, generation, c, buffer);
+       if (allocate && ret < 0) {
+               if (c >= 0)
+                       deallocate_channel(card, irm_id, generation, c, buffer);
                *channel = ret;
        }
 }
index 2d3dc7ded0a94d88fd80e8506685e755ce09113e..7142eeec8074374d87109ec98d65f78d28bd0e74 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/mutex.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 
 #include <asm/unaligned.h>
index 75dc6988cffd5d174ae8eb5445b5ce8744e0f4b0..94b16e0340aeecd22b78fd106f86d7e37b489227 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/firewire.h>
 #include <linux/firewire-constants.h>
-#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -35,6 +34,7 @@
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 
@@ -231,6 +231,8 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
 
 static char ohci_driver_name[] = KBUILD_MODNAME;
 
+#define PCI_DEVICE_ID_TI_TSB12LV22     0x8009
+
 #define QUIRK_CYCLE_TIMER              1
 #define QUIRK_RESET_PACKET             2
 #define QUIRK_BE_HEADERS               4
@@ -239,6 +241,8 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
 static const struct {
        unsigned short vendor, device, flags;
 } ohci_quirks[] = {
+       {PCI_VENDOR_ID_TI,      PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER |
+                                                           QUIRK_RESET_PACKET},
        {PCI_VENDOR_ID_TI,      PCI_ANY_ID,     QUIRK_RESET_PACKET},
        {PCI_VENDOR_ID_AL,      PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
        {PCI_VENDOR_ID_NEC,     PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
@@ -1154,7 +1158,7 @@ static void handle_local_lock(struct fw_ohci *ohci,
                              struct fw_packet *packet, u32 csr)
 {
        struct fw_packet response;
-       int tcode, length, ext_tcode, sel;
+       int tcode, length, ext_tcode, sel, try;
        __be32 *payload, lock_old;
        u32 lock_arg, lock_data;
 
@@ -1181,21 +1185,26 @@ static void handle_local_lock(struct fw_ohci *ohci,
        reg_write(ohci, OHCI1394_CSRCompareData, lock_arg);
        reg_write(ohci, OHCI1394_CSRControl, sel);
 
-       if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000)
-               lock_old = cpu_to_be32(reg_read(ohci, OHCI1394_CSRData));
-       else
-               fw_notify("swap not done yet\n");
+       for (try = 0; try < 20; try++)
+               if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000) {
+                       lock_old = cpu_to_be32(reg_read(ohci,
+                                                       OHCI1394_CSRData));
+                       fw_fill_response(&response, packet->header,
+                                        RCODE_COMPLETE,
+                                        &lock_old, sizeof(lock_old));
+                       goto out;
+               }
+
+       fw_error("swap not done (CSR lock timeout)\n");
+       fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0);
 
-       fw_fill_response(&response, packet->header,
-                        RCODE_COMPLETE, &lock_old, sizeof(lock_old));
  out:
        fw_core_handle_response(&ohci->card, &response);
 }
 
 static void handle_local_request(struct context *ctx, struct fw_packet *packet)
 {
-       u64 offset;
-       u32 csr;
+       u64 offset, csr;
 
        if (ctx == &ctx->ohci->at_request_ctx) {
                packet->ack = ACK_PENDING;
index 18d65fb42ee71850d0914f5fd44cd6a91eaf3111..fb09bb3c0ad6bb9d418b2078e139d9215c0fa816 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mc146818rtc.h>
index b3a0cf57442e440c55d6da83f6213969715448a5..3a4460265b10e094cc5b8df72fc450a9dee44b3e 100644 (file)
@@ -36,6 +36,7 @@
  */
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/blkdev.h>
index dbdf6fadfc795f5378b71fa2dec7fa09521971fe..a777a35381d2ca80ac0dd8846d860d650ef7bf00 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/dmi.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 
 struct dmi_device_attribute{
        struct device_attribute dev_attr;
index 31b983d9462c7c9f5a01b87fa0a449076bd12aa1..d46467271349d79adbabd04a76bb55a7b7cff19f 100644 (file)
@@ -5,7 +5,6 @@
 #include <linux/dmi.h>
 #include <linux/efi.h>
 #include <linux/bootmem.h>
-#include <linux/slab.h>
 #include <asm/dmi.h>
 
 /*
index 082f06ecd327e0db54087f49ab104b50b23c78f9..81b70bd075861c97b0d529c27237c2036f492eed 100644 (file)
@@ -77,6 +77,7 @@
 #include <linux/sysfs.h>
 #include <linux/kobject.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
index dfb15c06c88ff8482de2b03164679633748848b7..d6470ef36e4a937b7c840b6fff4b7788ce40076b 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/limits.h>
 #include <linux/module.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/types.h>
@@ -52,7 +51,7 @@ EXPORT_SYMBOL_GPL(ibft_addr);
  * Routine used to find the iSCSI Boot Format Table. The logical
  * kernel address is set in the ibft_addr global variable.
  */
-void __init reserve_ibft_region(void)
+unsigned long __init find_ibft_region(unsigned long *sizep)
 {
        unsigned long pos;
        unsigned int len = 0;
@@ -78,6 +77,11 @@ void __init reserve_ibft_region(void)
                        }
                }
        }
-       if (ibft_addr)
-               reserve_bootmem(pos, PAGE_ALIGN(len), BOOTMEM_DEFAULT);
+       if (ibft_addr) {
+               *sizep = PAGE_ALIGN(len);
+               return pos;
+       }
+
+       *sizep = 0;
+       return 0;
 }
index d59f7cad2269d817d21e8eebb3044a97c0b8435b..adc07102a20d0caef9fc98290f25be6c5b2b6a3d 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/bootmem.h>
+#include <linux/slab.h>
 
 /*
  * Data types ------------------------------------------------------------------
index 0f93105873cd263b61bb9c2af47007622e6c2f33..9f278153700121850982f626afd925d3fdf6780f 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
index afc097a16b3330393f08b544d4baf87b19d81029..2e8e9e24f887ff790e7866d2ac1e1f27b906ac89 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/gpio.h>
index 2559f2289409f13c431bd60d9ff95a503813b8b1..aa4f09ad3cede46381641831d0b00a305f9c9099 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 /* Steal the hardware definitions from the bttv driver. */
 #include "../media/video/bt8xx/bt848.h"
index 6d1b86661e633410b5698ca075047fa2f62a12a2..eb0c3fe44b29b32e6ee72dc0bb52ccd351aa9323 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/seq_file.h>
 #include <linux/gpio.h>
 #include <linux/idr.h>
+#include <linux/slab.h>
 
 
 /* Optional implementation infrastructure for GPIO interfaces.
@@ -415,7 +416,8 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,
        return 0;
 
 free_sd:
-       sysfs_put(pdesc->value_sd);
+       if (pdesc)
+               sysfs_put(pdesc->value_sd);
 free_id:
        idr_remove(&pdesc_idr, id);
        desc->flags &= GPIO_FLAGS_MASK;
index 753219cf993ac4469d27085e9d54ded68f47ab0d..41a9388f2fde03917455e77a9d18149ba3f292dc 100644 (file)
@@ -80,8 +80,8 @@ static int it8761e_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
        u16 reg;
        u8 bit;
 
-       bit = gpio_num % 7;
-       reg = (gpio_num >= 7) ? gpio_ba + 1 : gpio_ba;
+       bit = gpio_num % 8;
+       reg = (gpio_num >= 8) ? gpio_ba + 1 : gpio_ba;
 
        return !!(inb(reg) & (1 << bit));
 }
@@ -91,8 +91,8 @@ static int it8761e_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
        u8 curr_dirs;
        u8 io_reg, bit;
 
-       bit = gpio_num % 7;
-       io_reg = (gpio_num >= 7) ? GPIO2X_IO : GPIO1X_IO;
+       bit = gpio_num % 8;
+       io_reg = (gpio_num >= 8) ? GPIO2X_IO : GPIO1X_IO;
 
        spin_lock(&sio_lock);
 
@@ -116,8 +116,8 @@ static void it8761e_gpio_set(struct gpio_chip *gc,
        u8 curr_vals, bit;
        u16 reg;
 
-       bit = gpio_num % 7;
-       reg = (gpio_num >= 7) ? gpio_ba + 1 : gpio_ba;
+       bit = gpio_num % 8;
+       reg = (gpio_num >= 8) ? gpio_ba + 1 : gpio_ba;
 
        spin_lock(&sio_lock);
 
@@ -135,8 +135,8 @@ static int it8761e_gpio_direction_out(struct gpio_chip *gc,
 {
        u8 curr_dirs, io_reg, bit;
 
-       bit = gpio_num % 7;
-       io_reg = (gpio_num >= 7) ? GPIO2X_IO : GPIO1X_IO;
+       bit = gpio_num % 8;
+       io_reg = (gpio_num >= 8) ? GPIO2X_IO : GPIO1X_IO;
 
        it8761e_gpio_set(gc, gpio_num, val);
 
@@ -200,7 +200,7 @@ static int __init it8761e_gpio_init(void)
                return -EBUSY;
 
        it8761e_gpio_chip.base = -1;
-       it8761e_gpio_chip.ngpio = 14;
+       it8761e_gpio_chip.ngpio = 16;
 
        err = gpiochip_add(&it8761e_gpio_chip);
        if (err < 0)
index 6c0ebbdc659ee3bdba7fa17256b74462c4858ff2..00c3a14127af0059b08206fd49eabf07f8ed4cd9 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 struct lnw_gpio_register {
        u32     GPLR[2];
index 9d74eef1157ad4b9c5adb2bcddad5436bc8b565a..962f661c18c72d65a4f68a01e639e4b24159e0dd 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mutex.h>
 #include <linux/i2c.h>
 #include <linux/spi/max7301.h>
+#include <linux/slab.h>
 
 static int max7300_i2c_write(struct device *dev, unsigned int reg,
                                unsigned int val)
index 965d9b1ea13edf88f53ba780aa3fa2c57be48d36..92a100ddef6bb506d599fd9bd36343c541979b1e 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/max7301.h>
 
index c9bced55f82bc501288d90f8d5536b27e6e9a848..7696a5625d58c1944d8e15a72cf0f4768ff3f550 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/mutex.h>
 #include <linux/spi/max7301.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 /*
  * Pin configurations, see MAX7301 datasheet page 6
@@ -242,3 +243,7 @@ int __devexit __max730x_remove(struct device *dev)
        return ret;
 }
 EXPORT_SYMBOL_GPL(__max730x_remove);
+
+MODULE_AUTHOR("Juergen Beisert, Wolfram Sang");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MAX730x GPIO-Expanders, generic parts");
index e7d01bd8fdb3cd1bc6e60834e1b12e28aa6bffb1..935479da6705b3161213521b8791f2ebf7633193 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/mc33880.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME "mc33880"
 
index cd651ec8d0349e1621e0ef941dea3db489d86c0c..69f6f1955a31a650f31a9d9113c031a18b44a901 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/mcp23s08.h>
+#include <linux/slab.h>
 
 
 /* Registers are all 8 bits wide.
index ab5daab14bc2589e884316018ddaf0a2fc9a0d62..b827c976dc6214cec1d04256182c05861b345294 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/irq.h>
 #include <linux/i2c.h>
 #include <linux/i2c/pca953x.h>
+#include <linux/slab.h>
 #ifdef CONFIG_OF_GPIO
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
@@ -251,6 +252,18 @@ static void pca953x_irq_bus_lock(unsigned int irq)
 static void pca953x_irq_bus_sync_unlock(unsigned int irq)
 {
        struct pca953x_chip *chip = get_irq_chip_data(irq);
+       uint16_t new_irqs;
+       uint16_t level;
+
+       /* Look for any newly setup interrupt */
+       new_irqs = chip->irq_trig_fall | chip->irq_trig_raise;
+       new_irqs &= ~chip->reg_direction;
+
+       while (new_irqs) {
+               level = __ffs(new_irqs);
+               pca953x_gpio_direction_input(&chip->gpio_chip, level);
+               new_irqs &= ~(1 << level);
+       }
 
        mutex_unlock(&chip->irq_lock);
 }
@@ -277,7 +290,7 @@ static int pca953x_irq_set_type(unsigned int irq, unsigned int type)
        else
                chip->irq_trig_raise &= ~mask;
 
-       return pca953x_gpio_direction_input(&chip->gpio_chip, level);
+       return 0;
 }
 
 static struct irq_chip pca953x_irq_chip = {
index 3ad1eeb496099cceb8118d5666460377aec8d5d0..105701a1f05be48e87c9862a80a907437e03863d 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/device.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/pl061.h>
+#include <linux/slab.h>
 
 #define GPIODIR 0x400
 #define GPIOIS  0x404
@@ -90,6 +91,12 @@ static int pl061_direction_output(struct gpio_chip *gc, unsigned offset,
        gpiodir = readb(chip->base + GPIODIR);
        gpiodir |= 1 << offset;
        writeb(gpiodir, chip->base + GPIODIR);
+
+       /*
+        * gpio value is set again, because pl061 doesn't allow to set value of
+        * a gpio pin before configuring it in OUT mode.
+        */
+       writeb(!!value << offset, chip->base + (1 << (offset + 2)));
        spin_unlock_irqrestore(&chip->lock, flags);
 
        return 0;
@@ -182,7 +189,7 @@ static int pl061_irq_type(unsigned irq, unsigned trigger)
                gpioibe &= ~(1 << offset);
                if (trigger & IRQ_TYPE_EDGE_RISING)
                        gpioiev |= 1 << offset;
-               else
+               else if (trigger & IRQ_TYPE_EDGE_FALLING)
                        gpioiev &= ~(1 << offset);
        }
        writeb(gpioibe, chip->base + GPIOIBE);
@@ -203,7 +210,7 @@ static struct irq_chip pl061_irqchip = {
 
 static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
 {
-       struct list_head *chip_list = get_irq_chip_data(irq);
+       struct list_head *chip_list = get_irq_data(irq);
        struct list_head *ptr;
        struct pl061_gpio *chip;
 
@@ -296,9 +303,9 @@ static int __init pl061_probe(struct amba_device *dev, struct amba_id *id)
                        goto iounmap;
                }
                INIT_LIST_HEAD(chip_list);
-               set_irq_chip_data(irq, chip_list);
+               set_irq_data(irq, chip_list);
        } else
-               chip_list = get_irq_chip_data(irq);
+               chip_list = get_irq_data(irq);
        list_add(&chip->list, chip_list);
 
        for (i = 0; i < PL061_GPIO_NR; i++) {
index d4295fa5369e4bc129e498b69be67ba52ac645ee..ddd053108a136ce2a41dd346a438622609c7f480 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/io.h>
 #include <linux/timb_gpio.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME "timb-gpio"
 
@@ -130,6 +131,7 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger)
        unsigned long flags;
        u32 lvr, flr, bflr = 0;
        u32 ver;
+       int ret = 0;
 
        if (offset < 0 || offset > tgpio->gpio.ngpio)
                return -EINVAL;
@@ -153,8 +155,10 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger)
        }
 
        if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
-               if (ver < 3)
-                       return -EINVAL;
+               if (ver < 3) {
+                       ret = -EINVAL;
+                       goto out;
+               }
                else {
                        flr |= 1 << offset;
                        bflr |= 1 << offset;
@@ -174,9 +178,10 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger)
                iowrite32(bflr, tgpio->membase + TGPIO_BFLR);
 
        iowrite32(1 << offset, tgpio->membase + TGPIO_ICR);
-       spin_unlock_irqrestore(&tgpio->lock, flags);
 
-       return 0;
+out:
+       spin_unlock_irqrestore(&tgpio->lock, flags);
+       return ret;
 }
 
 static void timbgpio_irq(unsigned int irq, struct irq_desc *desc)
index 7fe881e2bdfb7c4cb5044b12bb9b5160ba8d47a4..57635ac35a73d6408785861e3aa8f2bb46508098 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/irq.h>
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
-#include <linux/slab.h>
 
 #include <linux/i2c/twl.h>
 
index d09021f4a7d38042dceed014643fb3a84b52423e..1fa449a1a4cb9f5df485ee505bb3263aeaac120c 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/gpio.h>
 #include <linux/mfd/core.h>
index 511840d1c7ba601616585a3ddacd7969c3400a05..359999290f5585783a3d0a6ffdb68e9693778875 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/gpio.h>
 #include <linux/mfd/core.h>
index de28b4a470eaf8b188ea27941455276af4767051..7607cc61e1ddfd70c9520b61707710fcf4e9143d 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/gpio.h>
 #include <linux/mfd/core.h>
index 3c1177abebd30c5b620114925faa32b5741d592d..b8fa65b5bfca56ca8320e23916d45dbc56a68b1c 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/of_gpio.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 /* Register Offset Definitions */
 #define XGPIO_DATA_OFFSET   (0x0)      /* Data register  */
index d68888fe3df997e21a489d13e94ab4da433a46f5..ba38e0147220e7b199b73b9d0d13804ff80254f3 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "drmP.h"
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #if __OS_HAS_AGP
 
index 8417cc4c43f1104a5ae6bfe35e28936db9f5235a..f7ba82ebf65ae03ead6f466d9f2579cc753a0c95 100644 (file)
@@ -34,6 +34,7 @@
  */
 
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <linux/log2.h>
 #include <asm/shmparam.h>
 #include "drmP.h"
index d91fb8c0b7b31673f43b885e8b0c38b0c1b6ec50..61b9bcfdf040d134403de46acbfd592b23819cdd 100644 (file)
@@ -30,6 +30,7 @@
  *      Jesse Barnes <jesse.barnes@intel.com>
  */
 #include <linux/list.h>
+#include <linux/slab.h>
 #include "drm.h"
 #include "drmP.h"
 #include "drm_crtc.h"
index f2aaf39be3981944fefc63a23fd8edcc9e3a614f..51103aa469f8c1bf773859e6176a004076a70e9a 100644 (file)
@@ -104,6 +104,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
        if (connector->status == connector_status_disconnected) {
                DRM_DEBUG_KMS("%s is disconnected\n",
                          drm_get_connector_name(connector));
+               drm_mode_connector_update_edid_property(connector, NULL);
                goto prune;
        }
 
index 9903f270e4409c8239add50adc2a3db80ca56623..677b275fa721affe2fec2508e780c1b1970f4f73 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "drmP.h"
 
 #if defined(CONFIG_DEBUG_FS)
index 548887c8506fa018139c2d83b29a50fd90c2b436..f7eba0a0973a78ce12669b878711a9983f14cbdb 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
index f3c58e2bd75cde20720712d3416229bcece0bb27..4a66201edaec0ea89ccc9d791a67f29d2ea58245 100644 (file)
@@ -47,6 +47,7 @@
  */
 
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm_core.h"
 
index f97e7c42ac8e1f7bdf53573e491feb0a80f2989f..18f41d7061f0d04f7ff9e1b465ea6565aa520cbe 100644 (file)
@@ -27,6 +27,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
 #include "drmP.h"
@@ -84,6 +85,8 @@ static struct edid_quirk {
 
        /* Envision Peripherals, Inc. EN-7100e */
        { "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH },
+       /* Envision EN2028 */
+       { "EPI", 8232, EDID_QUIRK_PREFER_LARGE_60 },
 
        /* Funai Electronics PM36B */
        { "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 |
@@ -707,15 +710,6 @@ 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;
index 50549703584f5b7d91c54d24f037dfa5d26f5ebc..288ea2f327720b17992d7332f333f717f34f1adc 100644 (file)
@@ -29,6 +29,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/sysrq.h>
+#include <linux/slab.h>
 #include <linux/fb.h>
 #include "drmP.h"
 #include "drm_crtc.h"
@@ -283,6 +284,8 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
        .help_msg = "force-fb(V)",
        .action_msg = "Restore framebuffer console",
 };
+#else
+static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { };
 #endif
 
 static void drm_fb_helper_on(struct fb_info *info)
index 08d14df3bb422d41bd561eea171d4cd91a662a3e..9d532d7fdf59a8e551233c1c44ef730eb22778ca 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "drmP.h"
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 
 static int drm_open_helper(struct inode *inode, struct file *filp,
@@ -140,14 +141,16 @@ int drm_open(struct inode *inode, struct file *filp)
                spin_unlock(&dev->count_lock);
        }
 out:
-       mutex_lock(&dev->struct_mutex);
-       if (minor->type == DRM_MINOR_LEGACY) {
-               BUG_ON((dev->dev_mapping != NULL) &&
-                       (dev->dev_mapping != inode->i_mapping));
-               if (dev->dev_mapping == NULL)
-                       dev->dev_mapping = inode->i_mapping;
+       if (!retcode) {
+               mutex_lock(&dev->struct_mutex);
+               if (minor->type == DRM_MINOR_LEGACY) {
+                       if (dev->dev_mapping == NULL)
+                               dev->dev_mapping = inode->i_mapping;
+                       else if (dev->dev_mapping != inode->i_mapping)
+                               retcode = -ENODEV;
+               }
+               mutex_unlock(&dev->struct_mutex);
        }
-       mutex_unlock(&dev->struct_mutex);
 
        return retcode;
 }
index f36b21c5b2e1501ac3950b7d4521e00570f93558..a93d7b4ddaa6a75c795e88113d6faf07fe3f9024 100644 (file)
@@ -35,6 +35,7 @@
 #include "drmP.h"
 #include "drm_hashtab.h"
 #include <linux/hash.h>
+#include <linux/slab.h>
 
 int drm_ht_create(struct drm_open_hash *ht, unsigned int order)
 {
index b98384dbd9a7ace015a358c6085b01dc5de0a620..a263b7070fc6f81b227d77a3befbd11b6efc8be0 100644 (file)
@@ -36,6 +36,7 @@
 #include "drmP.h"
 
 #include <linux/interrupt.h>   /* For task queue support */
+#include <linux/slab.h>
 
 #include <linux/vgaarb.h>
 /**
@@ -475,6 +476,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
        unsigned long irqflags;
 
        spin_lock_irqsave(&dev->vbl_lock, irqflags);
+       dev->driver->disable_vblank(dev, crtc);
        DRM_WAKEUP(&dev->vbl_queue[crtc]);
        dev->vblank_enabled[crtc] = 0;
        dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc);
index e4865f99989c717faf84c6d5488d788c87cee4ed..7732268eced2564d37f229eefdd7c38ead97dcfd 100644 (file)
@@ -77,7 +77,7 @@ static void *agp_remap(unsigned long offset, unsigned long size,
                    && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >=
                    (offset + size))
                        break;
-       if (!agpmem)
+       if (&agpmem->head == &dev->agp->memory)
                return NULL;
 
        /*
index e68ebf92fa2a5187c0e6b56a5e089a26d0516da2..2ea9ad4a8d699847bb4e8a7d0f1e7dc58ace90e4 100644 (file)
@@ -37,6 +37,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include "drmP.h"
 
index d379c4f2892f1bad75b1d1e9eedd7c1afd127d5c..a9ba6b69ad3526dacce63039457f0c48f961e3db 100644 (file)
@@ -38,6 +38,7 @@
  */
 
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "drmP.h"
 
 /***************************************************
index c7823c863d4f35fb85b0fc5056b19cd08da4b336..9034c4c6100dd2352c78b8b6d207001b0ce53bb5 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include "drmP.h"
 
 #define DEBUG_SCATTER 0
index ad73e141afdbd8096e2908d75e5849962ae1f069..a0c365f2e521a393ead336e55950ba8aa966c11e 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm_core.h"
 
@@ -515,8 +516,6 @@ void drm_put_dev(struct drm_device *dev)
        }
        driver = dev->driver;
 
-       drm_vblank_cleanup(dev);
-
        drm_lastclose(dev);
 
        if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
@@ -536,6 +535,8 @@ void drm_put_dev(struct drm_device *dev)
                dev->agp = NULL;
        }
 
+       drm_vblank_cleanup(dev);
+
        list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
                drm_rmmap(dev, r_list->map);
        drm_ht_remove(&dev->map_hash);
index 014ce24761b98f60b0ed9f8dead7327d2a26f1cf..25bbd30ed7af780924f739d46bf1fcb50b250a25 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/device.h>
 #include <linux/kdev_t.h>
+#include <linux/gfp.h>
 #include <linux/err.h>
 
 #include "drm_sysfs.h"
@@ -353,7 +354,10 @@ static struct bin_attribute edid_attr = {
 int drm_sysfs_connector_add(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
-       int ret = 0, i, j;
+       int attr_cnt = 0;
+       int opt_cnt = 0;
+       int i;
+       int ret = 0;
 
        /* We shouldn't get called more than once for the same connector */
        BUG_ON(device_is_registered(&connector->kdev));
@@ -376,8 +380,8 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
 
        /* Standard attributes */
 
-       for (i = 0; i < ARRAY_SIZE(connector_attrs); i++) {
-               ret = device_create_file(&connector->kdev, &connector_attrs[i]);
+       for (attr_cnt = 0; attr_cnt < ARRAY_SIZE(connector_attrs); attr_cnt++) {
+               ret = device_create_file(&connector->kdev, &connector_attrs[attr_cnt]);
                if (ret)
                        goto err_out_files;
        }
@@ -393,8 +397,8 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
                case DRM_MODE_CONNECTOR_SVIDEO:
                case DRM_MODE_CONNECTOR_Component:
                case DRM_MODE_CONNECTOR_TV:
-                       for (i = 0; i < ARRAY_SIZE(connector_attrs_opt1); i++) {
-                               ret = device_create_file(&connector->kdev, &connector_attrs_opt1[i]);
+                       for (opt_cnt = 0; opt_cnt < ARRAY_SIZE(connector_attrs_opt1); opt_cnt++) {
+                               ret = device_create_file(&connector->kdev, &connector_attrs_opt1[opt_cnt]);
                                if (ret)
                                        goto err_out_files;
                        }
@@ -413,10 +417,10 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
        return 0;
 
 err_out_files:
-       if (i > 0)
-               for (j = 0; j < i; j++)
-                       device_remove_file(&connector->kdev,
-                                          &connector_attrs[i]);
+       for (i = 0; i < opt_cnt; i++)
+               device_remove_file(&connector->kdev, &connector_attrs_opt1[i]);
+       for (i = 0; i < attr_cnt; i++)
+               device_remove_file(&connector->kdev, &connector_attrs[i]);
        device_unregister(&connector->kdev);
 
 out:
index 4ac900f4647f521be90a1279a18a452c21ee48bd..c3b13fb41d0cd557dcf1bf2897d9a5b331356828 100644 (file)
@@ -36,6 +36,7 @@
 #include "drmP.h"
 #if defined(__ia64__)
 #include <linux/efi.h>
+#include <linux/slab.h>
 #endif
 
 static void drm_vm_open(struct vm_area_struct *vma);
index de32d22a8c3974fecb41f64c32af246aa1764eb9..997d91707ad217f545c9720c0b0b9a604617f7e2 100644 (file)
@@ -36,6 +36,7 @@
 #include "i810_drv.h"
 #include <linux/interrupt.h>   /* For task queue support */
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/pagemap.h>
 
 #define I810_BUF_FREE          2
index 06bd732e6463b23e6ed9968e5500299bd37bcd9e..65759a9a85c8e425714c3281f080880eaaf8d0fc 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/interrupt.h>   /* For task queue support */
 #include <linux/pagemap.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 #define I830_BUF_FREE          2
index 1376dfe44c952a2ec9ae9bed4ad1befa10c1bcb3..a0b8447b06e7b6ecaea64a7e564e4ba6d64e9e54 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
@@ -225,7 +226,7 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data)
                } else {
                        struct drm_i915_gem_object *obj_priv;
 
-                       obj_priv = obj->driver_private;
+                       obj_priv = to_intel_bo(obj);
                        seq_printf(m, "Fenced object[%2d] = %p: %s "
                                   "%08x %08zx %08x %s %08x %08x %d",
                                   i, obj, get_pin_flag(obj_priv),
index 8bfc0bbf13e658fd050457c87cfa57f3c8857e8f..c3cfafcbfe7d5ada4b3ee7f9683e4bf809a5ad0f 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/acpi.h>
 #include <linux/pnp.h>
 #include <linux/vga_switcheroo.h>
+#include <linux/slab.h>
 
 /* Really want an OS-independent resettable timer.  Would like to have
  * this loop run for (eg) 3 sec, but have the timer reset every time
@@ -1356,6 +1357,8 @@ static void i915_setup_compression(struct drm_device *dev, int size)
 
        dev_priv->cfb_size = size;
 
+       dev_priv->compressed_fb = compressed_fb;
+
        if (IS_GM45(dev)) {
                g4x_disable_fbc(dev);
                I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
@@ -1363,12 +1366,22 @@ static void i915_setup_compression(struct drm_device *dev, int size)
                i8xx_disable_fbc(dev);
                I915_WRITE(FBC_CFB_BASE, cfb_base);
                I915_WRITE(FBC_LL_BASE, ll_base);
+               dev_priv->compressed_llb = compressed_llb;
        }
 
        DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base,
                  ll_base, size >> 20);
 }
 
+static void i915_cleanup_compression(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       drm_mm_put_block(dev_priv->compressed_fb);
+       if (!IS_GM45(dev))
+               drm_mm_put_block(dev_priv->compressed_llb);
+}
+
 /* true = enable decode, false = disable decoder */
 static unsigned int i915_vga_set_decode(void *cookie, bool state)
 {
@@ -1786,6 +1799,8 @@ int i915_driver_unload(struct drm_device *dev)
                mutex_lock(&dev->struct_mutex);
                i915_gem_cleanup_ringbuffer(dev);
                mutex_unlock(&dev->struct_mutex);
+               if (I915_HAS_FBC(dev) && i915_powersave)
+                       i915_cleanup_compression(dev);
                drm_mm_takedown(&dev_priv->vram);
                i915_gem_lastclose(dev);
 
@@ -1881,29 +1896,29 @@ struct drm_ioctl_desc i915_ioctls[] = {
        DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE,  i915_vblank_pipe_get, DRM_AUTH ),
        DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
        DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-       DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-       DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
-       DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
-       DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH),
-       DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-       DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-       DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0),
-       DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0),
-       DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0),
-       DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0),
-       DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, 0),
-       DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0),
-       DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0),
-       DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0),
-       DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0),
-       DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0),
-       DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0),
-       DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, 0),
-       DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW),
-       DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW),
+       DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+       DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 };
 
 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
index 1b2e95455c05d0cce04d17483c7bd4ff9f218fe0..cc03537bb883e06fd37a5e8bab8ce348e58062ad 100644 (file)
@@ -69,7 +69,8 @@ const static struct intel_device_info intel_845g_info = {
 };
 
 const static struct intel_device_info intel_i85x_info = {
-       .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1,
+       .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1,
+       .cursor_needs_physical = 1,
 };
 
 const static struct intel_device_info intel_i865g_info = {
@@ -80,14 +81,14 @@ const static struct intel_device_info intel_i915g_info = {
        .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1,
 };
 const static struct intel_device_info intel_i915gm_info = {
-       .is_i9xx = 1,  .is_mobile = 1, .has_fbc = 1,
+       .is_i9xx = 1,  .is_mobile = 1,
        .cursor_needs_physical = 1,
 };
 const static struct intel_device_info intel_i945g_info = {
        .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1,
 };
 const static struct intel_device_info intel_i945gm_info = {
-       .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1,
+       .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1,
        .has_hotplug = 1, .cursor_needs_physical = 1,
 };
 
@@ -139,19 +140,19 @@ const static struct intel_device_info intel_ironlake_m_info = {
 
 const static struct intel_device_info intel_sandybridge_d_info = {
        .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1,
-       .has_hotplug = 1,
+       .has_hotplug = 1, .is_gen6 = 1,
 };
 
 const static struct intel_device_info intel_sandybridge_m_info = {
        .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1,
-       .has_hotplug = 1,
+       .has_hotplug = 1, .is_gen6 = 1,
 };
 
 const static struct pci_device_id pciidlist[] = {
        INTEL_VGA_DEVICE(0x3577, &intel_i830_info),
        INTEL_VGA_DEVICE(0x2562, &intel_845g_info),
        INTEL_VGA_DEVICE(0x3582, &intel_i85x_info),
-       INTEL_VGA_DEVICE(0x35e8, &intel_i85x_info),
+       INTEL_VGA_DEVICE(0x358e, &intel_i85x_info),
        INTEL_VGA_DEVICE(0x2572, &intel_i865g_info),
        INTEL_VGA_DEVICE(0x2582, &intel_i915g_info),
        INTEL_VGA_DEVICE(0x258a, &intel_i915g_info),
@@ -361,7 +362,7 @@ int i965_reset(struct drm_device *dev, u8 flags)
            !dev_priv->mm.suspended) {
                drm_i915_ring_buffer_t *ring = &dev_priv->ring;
                struct drm_gem_object *obj = ring->ring_obj;
-               struct drm_i915_gem_object *obj_priv = obj->driver_private;
+               struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
                dev_priv->mm.suspended = 0;
 
                /* Stop the ring if it's running. */
index 979439cfb827998f9301a1bcee3626957828c268..6e4790065d9e0ba506d4a3c74aec326808650294 100644 (file)
@@ -195,6 +195,7 @@ struct intel_overlay;
 struct intel_device_info {
        u8 is_mobile : 1;
        u8 is_i8xx : 1;
+       u8 is_i85x : 1;
        u8 is_i915g : 1;
        u8 is_i9xx : 1;
        u8 is_i945gm : 1;
@@ -205,6 +206,7 @@ struct intel_device_info {
        u8 is_g4x : 1;
        u8 is_pineview : 1;
        u8 is_ironlake : 1;
+       u8 is_gen6 : 1;
        u8 has_fbc : 1;
        u8 has_rc6 : 1;
        u8 has_pipe_cxsr : 1;
@@ -234,11 +236,14 @@ typedef struct drm_i915_private {
 
        drm_dma_handle_t *status_page_dmah;
        void *hw_status_page;
+       void *seqno_page;
        dma_addr_t dma_status_page;
        uint32_t counter;
        unsigned int status_gfx_addr;
+       unsigned int seqno_gfx_addr;
        drm_local_map_t hws_map;
        struct drm_gem_object *hws_obj;
+       struct drm_gem_object *seqno_obj;
        struct drm_gem_object *pwrctx;
 
        struct resource mch_res;
@@ -610,6 +615,8 @@ typedef struct drm_i915_private {
        /* Reclocking support */
        bool render_reclock_avail;
        bool lvds_downclock_avail;
+       /* indicate whether the LVDS EDID is OK */
+       bool lvds_edid_good;
        /* indicates the reduced downclock for LVDS*/
        int lvds_downclock;
        struct work_struct idle_work;
@@ -627,6 +634,9 @@ typedef struct drm_i915_private {
        u8 max_delay;
 
        enum no_fbc_reason no_fbc_reason;
+
+       struct drm_mm_node *compressed_fb;
+       struct drm_mm_node *compressed_llb;
 } drm_i915_private_t;
 
 /** driver private structure attached to each drm_gem_object */
@@ -730,6 +740,8 @@ struct drm_i915_gem_object {
        atomic_t pending_flip;
 };
 
+#define to_intel_bo(x) ((struct drm_i915_gem_object *) (x)->driver_private)
+
 /**
  * Request queue structure.
  *
@@ -1065,7 +1077,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 
 #define IS_I830(dev)           ((dev)->pci_device == 0x3577)
 #define IS_845G(dev)           ((dev)->pci_device == 0x2562)
-#define IS_I85X(dev)           ((dev)->pci_device == 0x3582)
+#define IS_I85X(dev)           (INTEL_INFO(dev)->is_i85x)
 #define IS_I865G(dev)          ((dev)->pci_device == 0x2572)
 #define IS_GEN2(dev)           (INTEL_INFO(dev)->is_i8xx)
 #define IS_I915G(dev)          (INTEL_INFO(dev)->is_i915g)
@@ -1084,6 +1096,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 #define IS_IRONLAKE_M(dev)     ((dev)->pci_device == 0x0046)
 #define IS_IRONLAKE(dev)       (INTEL_INFO(dev)->is_ironlake)
 #define IS_I9XX(dev)           (INTEL_INFO(dev)->is_i9xx)
+#define IS_GEN6(dev)           (INTEL_INFO(dev)->is_gen6)
 #define IS_MOBILE(dev)         (INTEL_INFO(dev)->is_mobile)
 
 #define IS_GEN3(dev)   (IS_I915G(dev) ||                       \
@@ -1107,8 +1120,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 
 #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws)
 
-#define IS_GEN6(dev)   ((dev)->pci_device == 0x0102)
-
 /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
  * rows, which changed the alignment requirements and fence programming.
  */
@@ -1131,6 +1142,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 
 #define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) ||        \
                            IS_GEN6(dev))
+#define HAS_PIPE_CONTROL(dev) (IS_IRONLAKE(dev) || IS_GEN6(dev))
 
 #define PRIMARY_RINGBUFFER_SIZE         (128*1024)
 
index fba37e9f775d6fefdacaacfd0bd0868f6075328f..ef3d91dda71a9a8a0ce0e1ab61a9731afed1f5f8 100644 (file)
@@ -31,6 +31,7 @@
 #include "i915_drv.h"
 #include "i915_trace.h"
 #include "intel_drv.h"
+#include <linux/slab.h>
 #include <linux/swap.h>
 #include <linux/pci.h>
 
@@ -162,7 +163,7 @@ fast_shmem_read(struct page **pages,
 static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj)
 {
        drm_i915_private_t *dev_priv = obj->dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 &&
                obj_priv->tiling_mode != I915_TILING_NONE;
@@ -263,7 +264,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj,
                          struct drm_i915_gem_pread *args,
                          struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        ssize_t remain;
        loff_t offset, page_base;
        char __user *user_data;
@@ -284,7 +285,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret != 0)
                goto fail_put_pages;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = args->offset;
 
        while (remain > 0) {
@@ -353,7 +354,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
                          struct drm_i915_gem_pread *args,
                          struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct mm_struct *mm = current->mm;
        struct page **user_pages;
        ssize_t remain;
@@ -402,7 +403,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret != 0)
                goto fail_put_pages;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = args->offset;
 
        while (remain > 0) {
@@ -478,7 +479,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EBADF;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        /* Bounds check source.
         *
@@ -580,7 +581,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
                         struct drm_i915_gem_pwrite *args,
                         struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        drm_i915_private_t *dev_priv = dev->dev_private;
        ssize_t remain;
        loff_t offset, page_base;
@@ -604,7 +605,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret)
                goto fail;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = obj_priv->gtt_offset + args->offset;
 
        while (remain > 0) {
@@ -654,7 +655,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
                         struct drm_i915_gem_pwrite *args,
                         struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        drm_i915_private_t *dev_priv = dev->dev_private;
        ssize_t remain;
        loff_t gtt_page_base, offset;
@@ -698,7 +699,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret)
                goto out_unpin_object;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = obj_priv->gtt_offset + args->offset;
 
        while (remain > 0) {
@@ -760,7 +761,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
                           struct drm_i915_gem_pwrite *args,
                           struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        ssize_t remain;
        loff_t offset, page_base;
        char __user *user_data;
@@ -780,7 +781,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret != 0)
                goto fail_put_pages;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = args->offset;
        obj_priv->dirty = 1;
 
@@ -828,7 +829,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
                           struct drm_i915_gem_pwrite *args,
                           struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct mm_struct *mm = current->mm;
        struct page **user_pages;
        ssize_t remain;
@@ -876,7 +877,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret != 0)
                goto fail_put_pages;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = args->offset;
        obj_priv->dirty = 1;
 
@@ -951,7 +952,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EBADF;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        /* Bounds check destination.
         *
@@ -1033,7 +1034,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EBADF;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        mutex_lock(&dev->struct_mutex);
 
@@ -1095,7 +1096,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
        DRM_INFO("%s: sw_finish %d (%p %zd)\n",
                 __func__, args->handle, obj, obj->size);
 #endif
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        /* Pinned buffers may be scanout, so flush the cache */
        if (obj_priv->pin_count)
@@ -1166,7 +1167,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        struct drm_gem_object *obj = vma->vm_private_data;
        struct drm_device *dev = obj->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        pgoff_t page_offset;
        unsigned long pfn;
        int ret = 0;
@@ -1233,7 +1234,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        struct drm_gem_mm *mm = dev->mm_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct drm_map_list *list;
        struct drm_local_map *map;
        int ret = 0;
@@ -1304,7 +1305,7 @@ void
 i915_gem_release_mmap(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if (dev->dev_mapping)
                unmap_mapping_range(dev->dev_mapping,
@@ -1315,7 +1316,7 @@ static void
 i915_gem_free_mmap_offset(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct drm_gem_mm *mm = dev->mm_private;
        struct drm_map_list *list;
 
@@ -1346,7 +1347,7 @@ static uint32_t
 i915_gem_get_gtt_alignment(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int start, i;
 
        /*
@@ -1405,7 +1406,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
 
        mutex_lock(&dev->struct_mutex);
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        if (obj_priv->madv != I915_MADV_WILLNEED) {
                DRM_ERROR("Attempting to mmap a purgeable buffer\n");
@@ -1449,7 +1450,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
 void
 i915_gem_object_put_pages(struct drm_gem_object *obj)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page_count = obj->size / PAGE_SIZE;
        int i;
 
@@ -1466,9 +1467,6 @@ i915_gem_object_put_pages(struct drm_gem_object *obj)
                obj_priv->dirty = 0;
 
        for (i = 0; i < page_count; i++) {
-               if (obj_priv->pages[i] == NULL)
-                       break;
-
                if (obj_priv->dirty)
                        set_page_dirty(obj_priv->pages[i]);
 
@@ -1488,7 +1486,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        /* Add a reference if we're newly entering the active list. */
        if (!obj_priv->active) {
@@ -1508,7 +1506,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        BUG_ON(!obj_priv->active);
        list_move_tail(&obj_priv->list, &dev_priv->mm.flushing_list);
@@ -1519,7 +1517,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj)
 static void
 i915_gem_object_truncate(struct drm_gem_object *obj)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct inode *inode;
 
        inode = obj->filp->f_path.dentry->d_inode;
@@ -1540,7 +1538,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        i915_verify_inactive(dev, __FILE__, __LINE__);
        if (obj_priv->pin_count != 0)
@@ -1590,6 +1588,13 @@ i915_gem_process_flushing_list(struct drm_device *dev,
        }
 }
 
+#define PIPE_CONTROL_FLUSH(addr)                                       \
+       OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |          \
+                PIPE_CONTROL_DEPTH_STALL);                             \
+       OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT);                       \
+       OUT_RING(0);                                                    \
+       OUT_RING(0);                                                    \
+
 /**
  * Creates a new sequence number, emitting a write of it to the status page
  * plus an interrupt, which will trigger i915_user_interrupt_handler.
@@ -1624,13 +1629,47 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
        if (dev_priv->mm.next_gem_seqno == 0)
                dev_priv->mm.next_gem_seqno++;
 
-       BEGIN_LP_RING(4);
-       OUT_RING(MI_STORE_DWORD_INDEX);
-       OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
-       OUT_RING(seqno);
+       if (HAS_PIPE_CONTROL(dev)) {
+               u32 scratch_addr = dev_priv->seqno_gfx_addr + 128;
 
-       OUT_RING(MI_USER_INTERRUPT);
-       ADVANCE_LP_RING();
+               /*
+                * Workaround qword write incoherence by flushing the
+                * PIPE_NOTIFY buffers out to memory before requesting
+                * an interrupt.
+                */
+               BEGIN_LP_RING(32);
+               OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+                        PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
+               OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
+               OUT_RING(seqno);
+               OUT_RING(0);
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               scratch_addr += 128; /* write to separate cachelines */
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               scratch_addr += 128;
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               scratch_addr += 128;
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               scratch_addr += 128;
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               scratch_addr += 128;
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+                        PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
+                        PIPE_CONTROL_NOTIFY);
+               OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
+               OUT_RING(seqno);
+               OUT_RING(0);
+               ADVANCE_LP_RING();
+       } else {
+               BEGIN_LP_RING(4);
+               OUT_RING(MI_STORE_DWORD_INDEX);
+               OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+               OUT_RING(seqno);
+
+               OUT_RING(MI_USER_INTERRUPT);
+               ADVANCE_LP_RING();
+       }
 
        DRM_DEBUG_DRIVER("%d\n", seqno);
 
@@ -1754,7 +1793,10 @@ i915_get_gem_seqno(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
 
-       return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
+       if (HAS_PIPE_CONTROL(dev))
+               return ((volatile u32 *)(dev_priv->seqno_page))[0];
+       else
+               return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
 }
 
 /**
@@ -1967,7 +2009,7 @@ static int
 i915_gem_object_wait_rendering(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int ret;
 
        /* This function only exists to support waiting for existing rendering,
@@ -1999,7 +2041,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int ret = 0;
 
 #if WATCH_BUF
@@ -2175,7 +2217,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
 #if WATCH_LRU
                        DRM_INFO("%s: evicting %p\n", __func__, obj);
 #endif
-                       obj_priv = obj->driver_private;
+                       obj_priv = to_intel_bo(obj);
                        BUG_ON(obj_priv->pin_count != 0);
                        BUG_ON(obj_priv->active);
 
@@ -2227,11 +2269,6 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
                                seqno = i915_add_request(dev, NULL, obj->write_domain);
                                if (seqno == 0)
                                        return -ENOMEM;
-
-                               ret = i915_wait_request(dev, seqno);
-                               if (ret)
-                                       return ret;
-
                                continue;
                        }
                }
@@ -2251,12 +2288,11 @@ int
 i915_gem_object_get_pages(struct drm_gem_object *obj,
                          gfp_t gfpmask)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page_count, i;
        struct address_space *mapping;
        struct inode *inode;
        struct page *page;
-       int ret;
 
        if (obj_priv->pages_refcount++ != 0)
                return 0;
@@ -2279,11 +2315,9 @@ i915_gem_object_get_pages(struct drm_gem_object *obj,
                                           mapping_gfp_mask (mapping) |
                                           __GFP_COLD |
                                           gfpmask);
-               if (IS_ERR(page)) {
-                       ret = PTR_ERR(page);
-                       i915_gem_object_put_pages(obj);
-                       return ret;
-               }
+               if (IS_ERR(page))
+                       goto err_pages;
+
                obj_priv->pages[i] = page;
        }
 
@@ -2291,6 +2325,15 @@ i915_gem_object_get_pages(struct drm_gem_object *obj,
                i915_gem_object_do_bit_17_swizzle(obj);
 
        return 0;
+
+err_pages:
+       while (i--)
+               page_cache_release(obj_priv->pages[i]);
+
+       drm_free_large(obj_priv->pages);
+       obj_priv->pages = NULL;
+       obj_priv->pages_refcount--;
+       return PTR_ERR(page);
 }
 
 static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg)
@@ -2298,7 +2341,7 @@ static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg)
        struct drm_gem_object *obj = reg->obj;
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int regnum = obj_priv->fence_reg;
        uint64_t val;
 
@@ -2320,7 +2363,7 @@ static void i965_write_fence_reg(struct drm_i915_fence_reg *reg)
        struct drm_gem_object *obj = reg->obj;
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int regnum = obj_priv->fence_reg;
        uint64_t val;
 
@@ -2340,7 +2383,7 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
        struct drm_gem_object *obj = reg->obj;
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int regnum = obj_priv->fence_reg;
        int tile_width;
        uint32_t fence_reg, val;
@@ -2363,6 +2406,12 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
        pitch_val = obj_priv->stride / tile_width;
        pitch_val = ffs(pitch_val) - 1;
 
+       if (obj_priv->tiling_mode == I915_TILING_Y &&
+           HAS_128_BYTE_Y_TILING(dev))
+               WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL);
+       else
+               WARN_ON(pitch_val > I915_FENCE_MAX_PITCH_VAL);
+
        val = obj_priv->gtt_offset;
        if (obj_priv->tiling_mode == I915_TILING_Y)
                val |= 1 << I830_FENCE_TILING_Y_SHIFT;
@@ -2382,7 +2431,7 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
        struct drm_gem_object *obj = reg->obj;
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int regnum = obj_priv->fence_reg;
        uint32_t val;
        uint32_t pitch_val;
@@ -2426,7 +2475,7 @@ static int i915_find_fence_reg(struct drm_device *dev)
                if (!reg->obj)
                        return i;
 
-               obj_priv = reg->obj->driver_private;
+               obj_priv = to_intel_bo(reg->obj);
                if (!obj_priv->pin_count)
                    avail++;
        }
@@ -2481,7 +2530,7 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct drm_i915_fence_reg *reg = NULL;
        int ret;
 
@@ -2548,7 +2597,7 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if (IS_GEN6(dev)) {
                I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 +
@@ -2584,7 +2633,7 @@ int
 i915_gem_object_put_fence_reg(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if (obj_priv->fence_reg == I915_FENCE_REG_NONE)
                return 0;
@@ -2622,7 +2671,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct drm_mm_node *free_space;
        gfp_t gfpmask =  __GFP_NORETRY | __GFP_NOWARN;
        int ret;
@@ -2729,7 +2778,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
 void
 i915_gem_clflush_object(struct drm_gem_object *obj)
 {
-       struct drm_i915_gem_object      *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object      *obj_priv = to_intel_bo(obj);
 
        /* If we don't have a page list set up, then we're not pinned
         * to GPU, and we can ignore the cache flush because it'll happen
@@ -2830,7 +2879,7 @@ i915_gem_object_flush_write_domain(struct drm_gem_object *obj)
 int
 i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        uint32_t old_write_domain, old_read_domains;
        int ret;
 
@@ -2880,7 +2929,7 @@ int
 i915_gem_object_set_to_display_plane(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        uint32_t old_write_domain, old_read_domains;
        int ret;
 
@@ -3093,7 +3142,7 @@ static void
 i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
 {
        struct drm_device               *dev = obj->dev;
-       struct drm_i915_gem_object      *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object      *obj_priv = to_intel_bo(obj);
        uint32_t                        invalidate_domains = 0;
        uint32_t                        flush_domains = 0;
        uint32_t                        old_read_domains;
@@ -3178,7 +3227,7 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
 static void
 i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if (!obj_priv->page_cpu_valid)
                return;
@@ -3218,7 +3267,7 @@ static int
 i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
                                          uint64_t offset, uint64_t size)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        uint32_t old_read_domains;
        int i, ret;
 
@@ -3287,7 +3336,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int i, ret;
        void __iomem *reloc_page;
        bool need_fence;
@@ -3338,7 +3387,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
                        i915_gem_object_unpin(obj);
                        return -EBADF;
                }
-               target_obj_priv = target_obj->driver_private;
+               target_obj_priv = to_intel_bo(target_obj);
 
 #if WATCH_RELOC
                DRM_INFO("%s: obj %p offset %08x target %d "
@@ -3690,7 +3739,7 @@ i915_gem_wait_for_pending_flip(struct drm_device *dev,
                prepare_to_wait(&dev_priv->pending_flip_queue,
                                &wait, TASK_INTERRUPTIBLE);
                for (i = 0; i < count; i++) {
-                       obj_priv = object_list[i]->driver_private;
+                       obj_priv = to_intel_bo(object_list[i]);
                        if (atomic_read(&obj_priv->pending_flip) > 0)
                                break;
                }
@@ -3799,7 +3848,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
                        goto err;
                }
 
-               obj_priv = object_list[i]->driver_private;
+               obj_priv = to_intel_bo(object_list[i]);
                if (obj_priv->in_execbuffer) {
                        DRM_ERROR("Object %p appears more than once in object list\n",
                                   object_list[i]);
@@ -3925,7 +3974,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 
        for (i = 0; i < args->buffer_count; i++) {
                struct drm_gem_object *obj = object_list[i];
-               struct drm_i915_gem_object *obj_priv = obj->driver_private;
+               struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
                uint32_t old_write_domain = obj->write_domain;
 
                obj->write_domain = obj->pending_write_domain;
@@ -4000,7 +4049,7 @@ err:
 
        for (i = 0; i < args->buffer_count; i++) {
                if (object_list[i]) {
-                       obj_priv = object_list[i]->driver_private;
+                       obj_priv = to_intel_bo(object_list[i]);
                        obj_priv->in_execbuffer = false;
                }
                drm_gem_object_unreference(object_list[i]);
@@ -4178,7 +4227,7 @@ int
 i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int ret;
 
        i915_verify_inactive(dev, __FILE__, __LINE__);
@@ -4211,7 +4260,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        i915_verify_inactive(dev, __FILE__, __LINE__);
        obj_priv->pin_count--;
@@ -4251,7 +4300,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
                mutex_unlock(&dev->struct_mutex);
                return -EBADF;
        }
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        if (obj_priv->madv != I915_MADV_WILLNEED) {
                DRM_ERROR("Attempting to pin a purgeable buffer\n");
@@ -4308,7 +4357,7 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
                return -EBADF;
        }
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        if (obj_priv->pin_filp != file_priv) {
                DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n",
                          args->handle);
@@ -4350,7 +4399,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
         */
        i915_gem_retire_requests(dev);
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        /* Don't count being on the flushing list against the object being
         * done.  Otherwise, a buffer left on the flushing list but not getting
         * flushed (because nobody's flushing that domain) won't ever return
@@ -4396,7 +4445,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
        }
 
        mutex_lock(&dev->struct_mutex);
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        if (obj_priv->pin_count) {
                drm_gem_object_unreference(obj);
@@ -4457,7 +4506,7 @@ int i915_gem_init_object(struct drm_gem_object *obj)
 void i915_gem_free_object(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        trace_i915_gem_object_destroy(obj);
 
@@ -4547,6 +4596,49 @@ i915_gem_idle(struct drm_device *dev)
        return 0;
 }
 
+/*
+ * 965+ support PIPE_CONTROL commands, which provide finer grained control
+ * over cache flushing.
+ */
+static int
+i915_gem_init_pipe_control(struct drm_device *dev)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_gem_object *obj;
+       struct drm_i915_gem_object *obj_priv;
+       int ret;
+
+       obj = drm_gem_object_alloc(dev, 4096);
+       if (obj == NULL) {
+               DRM_ERROR("Failed to allocate seqno page\n");
+               ret = -ENOMEM;
+               goto err;
+       }
+       obj_priv = to_intel_bo(obj);
+       obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
+
+       ret = i915_gem_object_pin(obj, 4096);
+       if (ret)
+               goto err_unref;
+
+       dev_priv->seqno_gfx_addr = obj_priv->gtt_offset;
+       dev_priv->seqno_page =  kmap(obj_priv->pages[0]);
+       if (dev_priv->seqno_page == NULL)
+               goto err_unpin;
+
+       dev_priv->seqno_obj = obj;
+       memset(dev_priv->seqno_page, 0, PAGE_SIZE);
+
+       return 0;
+
+err_unpin:
+       i915_gem_object_unpin(obj);
+err_unref:
+       drm_gem_object_unreference(obj);
+err:
+       return ret;
+}
+
 static int
 i915_gem_init_hws(struct drm_device *dev)
 {
@@ -4564,15 +4656,16 @@ i915_gem_init_hws(struct drm_device *dev)
        obj = drm_gem_object_alloc(dev, 4096);
        if (obj == NULL) {
                DRM_ERROR("Failed to allocate status page\n");
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto err;
        }
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
 
        ret = i915_gem_object_pin(obj, 4096);
        if (ret != 0) {
                drm_gem_object_unreference(obj);
-               return ret;
+               goto err_unref;
        }
 
        dev_priv->status_gfx_addr = obj_priv->gtt_offset;
@@ -4581,10 +4674,16 @@ i915_gem_init_hws(struct drm_device *dev)
        if (dev_priv->hw_status_page == NULL) {
                DRM_ERROR("Failed to map status page.\n");
                memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
-               i915_gem_object_unpin(obj);
-               drm_gem_object_unreference(obj);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_unpin;
+       }
+
+       if (HAS_PIPE_CONTROL(dev)) {
+               ret = i915_gem_init_pipe_control(dev);
+               if (ret)
+                       goto err_unpin;
        }
+
        dev_priv->hws_obj = obj;
        memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
        if (IS_GEN6(dev)) {
@@ -4597,6 +4696,30 @@ i915_gem_init_hws(struct drm_device *dev)
        DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
 
        return 0;
+
+err_unpin:
+       i915_gem_object_unpin(obj);
+err_unref:
+       drm_gem_object_unreference(obj);
+err:
+       return 0;
+}
+
+static void
+i915_gem_cleanup_pipe_control(struct drm_device *dev)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_gem_object *obj;
+       struct drm_i915_gem_object *obj_priv;
+
+       obj = dev_priv->seqno_obj;
+       obj_priv = to_intel_bo(obj);
+       kunmap(obj_priv->pages[0]);
+       i915_gem_object_unpin(obj);
+       drm_gem_object_unreference(obj);
+       dev_priv->seqno_obj = NULL;
+
+       dev_priv->seqno_page = NULL;
 }
 
 static void
@@ -4610,7 +4733,7 @@ i915_gem_cleanup_hws(struct drm_device *dev)
                return;
 
        obj = dev_priv->hws_obj;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        kunmap(obj_priv->pages[0]);
        i915_gem_object_unpin(obj);
@@ -4620,6 +4743,9 @@ i915_gem_cleanup_hws(struct drm_device *dev)
        memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
        dev_priv->hw_status_page = NULL;
 
+       if (HAS_PIPE_CONTROL(dev))
+               i915_gem_cleanup_pipe_control(dev);
+
        /* Write high address into HWS_PGA when disabling. */
        I915_WRITE(HWS_PGA, 0x1ffff000);
 }
@@ -4644,7 +4770,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
                i915_gem_cleanup_hws(dev);
                return -ENOMEM;
        }
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        ret = i915_gem_object_pin(obj, 4096);
        if (ret != 0) {
@@ -4730,6 +4856,11 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
                        ring->space += ring->Size;
        }
 
+       if (IS_I9XX(dev) && !IS_GEN3(dev)) {
+               I915_WRITE(MI_MODE,
+                          (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH);
+       }
+
        return 0;
 }
 
@@ -4932,7 +5063,7 @@ void i915_gem_detach_phys_object(struct drm_device *dev,
        int ret;
        int page_count;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        if (!obj_priv->phys_obj)
                return;
 
@@ -4971,7 +5102,7 @@ i915_gem_attach_phys_object(struct drm_device *dev,
        if (id > I915_MAX_PHYS_OBJECT)
                return -EINVAL;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        if (obj_priv->phys_obj) {
                if (obj_priv->phys_obj->id == id)
@@ -5022,7 +5153,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
                     struct drm_i915_gem_pwrite *args,
                     struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        void *obj_addr;
        int ret;
        char __user *user_data;
index e602614bd3f89a9cbbb7f53c6503e93814272a18..35507cf53fa3c2e3e24c6a145a2882b021bcf1e0 100644 (file)
@@ -72,7 +72,7 @@ void
 i915_gem_dump_object(struct drm_gem_object *obj, int len,
                     const char *where, uint32_t mark)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page;
 
        DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset);
@@ -137,7 +137,7 @@ void
 i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page;
        uint32_t *gtt_mapping;
        uint32_t *backing_map = NULL;
index b5c55d88ff76f260f87a0dc64b140739dcc7ec4f..4bdccefcf2cf7b5f9733b00971f75dfa26b10505 100644 (file)
@@ -202,21 +202,17 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
                 * reg, so dont bother to check the size */
                if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
                        return false;
-       } else if (IS_I9XX(dev)) {
-               uint32_t pitch_val = ffs(stride / tile_width) - 1;
-
-               /* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB)
-                * instead of 4 (2KB) on 945s.
-                */
-               if (pitch_val > I915_FENCE_MAX_PITCH_VAL ||
-                   size > (I830_FENCE_MAX_SIZE_VAL << 20))
+       } else if (IS_GEN3(dev) || IS_GEN2(dev)) {
+               if (stride > 8192)
                        return false;
-       } else {
-               uint32_t pitch_val = ffs(stride / tile_width) - 1;
 
-               if (pitch_val > I830_FENCE_MAX_PITCH_VAL ||
-                   size > (I830_FENCE_MAX_SIZE_VAL << 19))
-                       return false;
+               if (IS_GEN3(dev)) {
+                       if (size > I830_FENCE_MAX_SIZE_VAL << 20)
+                               return false;
+               } else {
+                       if (size > I830_FENCE_MAX_SIZE_VAL << 19)
+                               return false;
+               }
        }
 
        /* 965+ just needs multiples of tile width */
@@ -240,7 +236,7 @@ bool
 i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if (obj_priv->gtt_space == NULL)
                return true;
@@ -280,7 +276,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EINVAL;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) {
                drm_gem_object_unreference_unlocked(obj);
@@ -325,9 +321,12 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
                 * need to ensure that any fence register is cleared.
                 */
                if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode))
-                   ret = i915_gem_object_unbind(obj);
+                       ret = i915_gem_object_unbind(obj);
+               else if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
+                       ret = i915_gem_object_put_fence_reg(obj);
                else
-                   ret = i915_gem_object_put_fence_reg(obj);
+                       i915_gem_release_mmap(obj);
+
                if (ret != 0) {
                        WARN(ret != -ERESTARTSYS,
                             "failed to reset object for tiling switch");
@@ -361,7 +360,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EINVAL;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        mutex_lock(&dev->struct_mutex);
 
@@ -424,7 +423,7 @@ i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page_count = obj->size >> PAGE_SHIFT;
        int i;
 
@@ -453,7 +452,7 @@ i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page_count = obj->size >> PAGE_SHIFT;
        int i;
 
index 5388354da0d176df4ff2a3b7c33de069abff12da..df6a9cd82c4d9a12d455cb2131d66d3fd8e7b1ec 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include <linux/sysrq.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
@@ -259,10 +260,10 @@ static void i915_hotplug_work_func(struct work_struct *work)
 
        if (mode_config->num_connector) {
                list_for_each_entry(connector, &mode_config->connector_list, head) {
-                       struct intel_output *intel_output = to_intel_output(connector);
+                       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
        
-                       if (intel_output->hot_plug)
-                               (*intel_output->hot_plug) (intel_output);
+                       if (intel_encoder->hot_plug)
+                               (*intel_encoder->hot_plug) (intel_encoder);
                }
        }
        /* Just fire off a uevent and let userspace tell us what to do */
@@ -348,7 +349,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)
                                READ_BREADCRUMB(dev_priv);
        }
 
-       if (gt_iir & GT_USER_INTERRUPT) {
+       if (gt_iir & GT_PIPE_NOTIFY) {
                u32 seqno = i915_get_gem_seqno(dev);
                dev_priv->mm.irq_gem_seqno = seqno;
                trace_i915_gem_request_complete(dev, seqno);
@@ -443,7 +444,7 @@ i915_error_object_create(struct drm_device *dev,
        if (src == NULL)
                return NULL;
 
-       src_priv = src->driver_private;
+       src_priv = to_intel_bo(src);
        if (src_priv->pages == NULL)
                return NULL;
 
@@ -455,11 +456,15 @@ i915_error_object_create(struct drm_device *dev,
 
        for (page = 0; page < page_count; page++) {
                void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC);
+               unsigned long flags;
+
                if (d == NULL)
                        goto unwind;
-               s = kmap_atomic(src_priv->pages[page], KM_USER0);
+               local_irq_save(flags);
+               s = kmap_atomic(src_priv->pages[page], KM_IRQ0);
                memcpy(d, s, PAGE_SIZE);
-               kunmap_atomic(s, KM_USER0);
+               kunmap_atomic(s, KM_IRQ0);
+               local_irq_restore(flags);
                dst->pages[page] = d;
        }
        dst->page_count = page_count;
@@ -1004,7 +1009,7 @@ void i915_user_irq_get(struct drm_device *dev)
        spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
        if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) {
                if (HAS_PCH_SPLIT(dev))
-                       ironlake_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
+                       ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
                else
                        i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
        }
@@ -1020,7 +1025,7 @@ void i915_user_irq_put(struct drm_device *dev)
        BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
        if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
                if (HAS_PCH_SPLIT(dev))
-                       ironlake_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
+                       ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
                else
                        i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
        }
@@ -1304,7 +1309,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
        /* enable kind of interrupts always enabled */
        u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
                           DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE;
-       u32 render_mask = GT_USER_INTERRUPT;
+       u32 render_mask = GT_PIPE_NOTIFY;
        u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |
                           SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG;
 
index 7cc8410239cb7855ac732fdf6946cdd059c8ab48..8fcc75c1aa2831be0bac489f9dd2043907d2cf69 100644 (file)
@@ -382,8 +382,57 @@ static void intel_didl_outputs(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_opregion *opregion = &dev_priv->opregion;
        struct drm_connector *connector;
+       acpi_handle handle;
+       struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL;
+       unsigned long long device_id;
+       acpi_status status;
        int i = 0;
 
+       handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev);
+       if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev)))
+               return;
+
+       if (acpi_is_video_device(acpi_dev))
+               acpi_video_bus = acpi_dev;
+       else {
+               list_for_each_entry(acpi_cdev, &acpi_dev->children, node) {
+                       if (acpi_is_video_device(acpi_cdev)) {
+                               acpi_video_bus = acpi_cdev;
+                               break;
+                       }
+               }
+       }
+
+       if (!acpi_video_bus) {
+               printk(KERN_WARNING "No ACPI video bus found\n");
+               return;
+       }
+
+       list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) {
+               if (i >= 8) {
+                       dev_printk (KERN_ERR, &dev->pdev->dev,
+                                   "More than 8 outputs detected\n");
+                       return;
+               }
+               status =
+                       acpi_evaluate_integer(acpi_cdev->handle, "_ADR",
+                                               NULL, &device_id);
+               if (ACPI_SUCCESS(status)) {
+                       if (!device_id)
+                               goto blind_set;
+                       opregion->acpi->didl[i] = (u32)(device_id & 0x0f0f);
+                       i++;
+               }
+       }
+
+end:
+       /* If fewer than 8 outputs, the list must be null terminated */
+       if (i < 8)
+               opregion->acpi->didl[i] = 0;
+       return;
+
+blind_set:
+       i = 0;
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
                int output_type = ACPI_OTHER_OUTPUT;
                if (i >= 8) {
@@ -416,10 +465,7 @@ static void intel_didl_outputs(struct drm_device *dev)
                opregion->acpi->didl[i] |= (1<<31) | output_type | i;
                i++;
        }
-
-       /* If fewer than 8 outputs, the list must be null terminated */
-       if (i < 8)
-               opregion->acpi->didl[i] = 0;
+       goto end;
 }
 
 int intel_opregion_init(struct drm_device *dev, int resume)
index 3d59862c7ccd01d9c14904c97ef1b4853c9a22b8..4cbc5210fd3006f2838ccc00a2f6c61bbbe39318 100644 (file)
 #define   ASYNC_FLIP                (1<<22)
 #define   DISPLAY_PLANE_A           (0<<20)
 #define   DISPLAY_PLANE_B           (1<<20)
+#define GFX_OP_PIPE_CONTROL    ((0x3<<29)|(0x3<<27)|(0x2<<24)|2)
+#define   PIPE_CONTROL_QW_WRITE        (1<<14)
+#define   PIPE_CONTROL_DEPTH_STALL (1<<13)
+#define   PIPE_CONTROL_WC_FLUSH        (1<<12)
+#define   PIPE_CONTROL_IS_FLUSH        (1<<11) /* MBZ on Ironlake */
+#define   PIPE_CONTROL_TC_FLUSH (1<<10) /* GM45+ only */
+#define   PIPE_CONTROL_ISP_DIS (1<<9)
+#define   PIPE_CONTROL_NOTIFY  (1<<8)
+#define   PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */
+#define   PIPE_CONTROL_STALL_EN        (1<<1) /* in addr word, Ironlake+ only */
 
 /*
  * Fence registers
 #define   I830_FENCE_SIZE_BITS(size)   ((ffs((size) >> 19) - 1) << 8)
 #define   I830_FENCE_PITCH_SHIFT       4
 #define   I830_FENCE_REG_VALID         (1<<0)
-#define   I915_FENCE_MAX_PITCH_VAL     0x10
+#define   I915_FENCE_MAX_PITCH_VAL     4
 #define   I830_FENCE_MAX_PITCH_VAL     6
 #define   I830_FENCE_MAX_SIZE_VAL      (1<<8)
 
 #define INSTDONE       0x02090
 #define NOPID          0x02094
 #define HWSTAM         0x02098
+
+#define MI_MODE                0x0209c
+# define VS_TIMER_DISPATCH                             (1 << 6)
+
 #define SCPD0          0x0209c /* 915+ only */
 #define IER            0x020a0
 #define IIR            0x020a4
 #define   FBC_CTL_PERIODIC     (1<<30)
 #define   FBC_CTL_INTERVAL_SHIFT (16)
 #define   FBC_CTL_UNCOMPRESSIBLE (1<<14)
-#define   FBC_C3_IDLE          (1<<13)
+#define   FBC_CTL_C3_IDLE      (1<<13)
 #define   FBC_CTL_STRIDE_SHIFT (5)
 #define   FBC_CTL_FENCENO      (1<<0)
 #define FBC_COMMAND            0x0320c
 #define DISPLAY_PORT_PLL_BIOS_1         0x46010
 #define DISPLAY_PORT_PLL_BIOS_2         0x46014
 
+#define PCH_DSPCLK_GATE_D      0x42020
+# define DPFDUNIT_CLOCK_GATE_DISABLE           (1 << 7)
+# define DPARBUNIT_CLOCK_GATE_DISABLE          (1 << 5)
+
+#define PCH_3DCGDIS0           0x46020
+# define MARIUNIT_CLOCK_GATE_DISABLE           (1 << 18)
+# define SVSMUNIT_CLOCK_GATE_DISABLE           (1 << 1)
+
 #define FDI_PLL_FREQ_CTL        0x46030
 #define  FDI_PLL_FREQ_CHANGE_REQUEST    (1<<24)
 #define  FDI_PLL_FREQ_LOCK_LIMIT_MASK   0xfff00
 #define DEIER   0x4400c
 
 /* GT interrupt */
+#define GT_PIPE_NOTIFY         (1 << 4)
 #define GT_SYNC_STATUS          (1 << 2)
 #define GT_USER_INTERRUPT       (1 << 0)
 
index 70c9d4ba7042b57dc677a9e2fcbcf03a6abe5e4e..f9ba452f0cbf2479649e7dbe947accdeed070f30 100644 (file)
@@ -417,8 +417,9 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
        edp = find_section(bdb, BDB_EDP);
        if (!edp) {
                if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp_support) {
-                       DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported,\
-                                      assume 18bpp panel color depth.\n");
+                       DRM_DEBUG_KMS("No eDP BDB found but eDP panel "
+                                     "supported, assume 18bpp panel color "
+                                     "depth.\n");
                        dev_priv->edp_bpp = 18;
                }
                return;
index fccf07470c8f6f512a8950555095ca122ed95c08..759c2ef72eff6f4fafebf3fc578dad48ae5878fb 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "drm_crtc.h"
@@ -246,19 +247,19 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
 
 static bool intel_crt_detect_ddc(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
        /* CRT should always be at 0, but check anyway */
-       if (intel_output->type != INTEL_OUTPUT_ANALOG)
+       if (intel_encoder->type != INTEL_OUTPUT_ANALOG)
                return false;
 
-       return intel_ddc_probe(intel_output);
+       return intel_ddc_probe(intel_encoder);
 }
 
 static enum drm_connector_status
-intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output)
+intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
 {
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -386,8 +387,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output)
 static enum drm_connector_status intel_crt_detect(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_crtc *crtc;
        int dpms_mode;
        enum drm_connector_status status;
@@ -404,13 +405,13 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
 
        /* for pre-945g platforms use load detect */
        if (encoder->crtc && encoder->crtc->enabled) {
-               status = intel_crt_load_detect(encoder->crtc, intel_output);
+               status = intel_crt_load_detect(encoder->crtc, intel_encoder);
        } else {
-               crtc = intel_get_load_detect_pipe(intel_output,
+               crtc = intel_get_load_detect_pipe(intel_encoder,
                                                  NULL, &dpms_mode);
                if (crtc) {
-                       status = intel_crt_load_detect(crtc, intel_output);
-                       intel_release_load_detect_pipe(intel_output, dpms_mode);
+                       status = intel_crt_load_detect(crtc, intel_encoder);
+                       intel_release_load_detect_pipe(intel_encoder, dpms_mode);
                } else
                        status = connector_status_unknown;
        }
@@ -420,9 +421,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
 
 static void intel_crt_destroy(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-       intel_i2c_destroy(intel_output->ddc_bus);
+       intel_i2c_destroy(intel_encoder->ddc_bus);
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
        kfree(connector);
@@ -431,28 +432,28 @@ static void intel_crt_destroy(struct drm_connector *connector)
 static int intel_crt_get_modes(struct drm_connector *connector)
 {
        int ret;
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
        struct i2c_adapter *ddcbus;
        struct drm_device *dev = connector->dev;
 
 
-       ret = intel_ddc_get_modes(intel_output);
+       ret = intel_ddc_get_modes(intel_encoder);
        if (ret || !IS_G4X(dev))
                goto end;
 
-       ddcbus = intel_output->ddc_bus;
+       ddcbus = intel_encoder->ddc_bus;
        /* Try to probe digital port for output in DVI-I -> VGA mode. */
-       intel_output->ddc_bus =
+       intel_encoder->ddc_bus =
                intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D");
 
-       if (!intel_output->ddc_bus) {
-               intel_output->ddc_bus = ddcbus;
+       if (!intel_encoder->ddc_bus) {
+               intel_encoder->ddc_bus = ddcbus;
                dev_printk(KERN_ERR, &connector->dev->pdev->dev,
                           "DDC bus registration failed for CRTDDC_D.\n");
                goto end;
        }
        /* Try to get modes by GPIOD port */
-       ret = intel_ddc_get_modes(intel_output);
+       ret = intel_ddc_get_modes(intel_encoder);
        intel_i2c_destroy(ddcbus);
 
 end:
@@ -505,23 +506,23 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
 void intel_crt_init(struct drm_device *dev)
 {
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 i2c_reg;
 
-       intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
-       if (!intel_output)
+       intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL);
+       if (!intel_encoder)
                return;
 
-       connector = &intel_output->base;
-       drm_connector_init(dev, &intel_output->base,
+       connector = &intel_encoder->base;
+       drm_connector_init(dev, &intel_encoder->base,
                           &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
 
-       drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs,
+       drm_encoder_init(dev, &intel_encoder->enc, &intel_crt_enc_funcs,
                         DRM_MODE_ENCODER_DAC);
 
-       drm_mode_connector_attach_encoder(&intel_output->base,
-                                         &intel_output->enc);
+       drm_mode_connector_attach_encoder(&intel_encoder->base,
+                                         &intel_encoder->enc);
 
        /* Set up the DDC bus. */
        if (HAS_PCH_SPLIT(dev))
@@ -532,22 +533,22 @@ void intel_crt_init(struct drm_device *dev)
                if (dev_priv->crt_ddc_bus != 0)
                        i2c_reg = dev_priv->crt_ddc_bus;
        }
-       intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
-       if (!intel_output->ddc_bus) {
+       intel_encoder->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
+       if (!intel_encoder->ddc_bus) {
                dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
                           "failed.\n");
                return;
        }
 
-       intel_output->type = INTEL_OUTPUT_ANALOG;
-       intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+       intel_encoder->type = INTEL_OUTPUT_ANALOG;
+       intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
                                   (1 << INTEL_ANALOG_CLONE_BIT) |
                                   (1 << INTEL_SDVO_LVDS_CLONE_BIT);
-       intel_output->crtc_mask = (1 << 0) | (1 << 1);
+       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
        connector->interlace_allowed = 0;
        connector->doublescan_allowed = 0;
 
-       drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs);
+       drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs);
        drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
 
        drm_sysfs_connector_add(connector);
index 9cd6de5f99061a2916af6d453dd46e2de2ea11fe..c7502b6b16009205b9ba0eb27e7158c75035e578 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/input.h>
 #include <linux/i2c.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "intel_drv.h"
 #include "i915_drm.h"
@@ -746,16 +747,16 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
     list_for_each_entry(l_entry, &mode_config->connector_list, head) {
            if (l_entry->encoder &&
                l_entry->encoder->crtc == crtc) {
-                   struct intel_output *intel_output = to_intel_output(l_entry);
-                   if (intel_output->type == type)
+                   struct intel_encoder *intel_encoder = to_intel_encoder(l_entry);
+                   if (intel_encoder->type == type)
                            return true;
            }
     }
     return false;
 }
 
-struct drm_connector *
-intel_pipe_get_output (struct drm_crtc *crtc)
+static struct drm_connector *
+intel_pipe_get_connector (struct drm_crtc *crtc)
 {
     struct drm_device *dev = crtc->dev;
     struct drm_mode_config *mode_config = &dev->mode_config;
@@ -1002,7 +1003,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_framebuffer *fb = crtc->fb;
        struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
-       struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int plane, i;
        u32 fbc_ctl, fbc_ctl2;
@@ -1032,7 +1033,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
        /* enable it... */
        fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC;
        if (IS_I945GM(dev))
-               fbc_ctl |= FBC_C3_IDLE; /* 945 needs special SR handling */
+               fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */
        fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT;
        fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
        if (obj_priv->tiling_mode != I915_TILING_NONE)
@@ -1079,7 +1080,7 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_framebuffer *fb = crtc->fb;
        struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
-       struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA :
                     DPFC_CTL_PLANEB);
@@ -1175,7 +1176,7 @@ static void intel_update_fbc(struct drm_crtc *crtc,
                return;
 
        intel_fb = to_intel_framebuffer(fb);
-       obj_priv = intel_fb->obj->driver_private;
+       obj_priv = to_intel_bo(intel_fb->obj);
 
        /*
         * If FBC is already on, we just have to verify that we can
@@ -1242,7 +1243,7 @@ out_disable:
 static int
 intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        u32 alignment;
        int ret;
 
@@ -1322,7 +1323,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 
        intel_fb = to_intel_framebuffer(crtc->fb);
        obj = intel_fb->obj;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        mutex_lock(&dev->struct_mutex);
        ret = intel_pin_and_fence_fb_obj(dev, obj);
@@ -1400,7 +1401,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 
        if (old_fb) {
                intel_fb = to_intel_framebuffer(old_fb);
-               obj_priv = intel_fb->obj->driver_private;
+               obj_priv = to_intel_bo(intel_fb->obj);
                i915_gem_object_unpin(intel_fb->obj);
        }
        intel_increase_pllclock(crtc, true);
@@ -2916,7 +2917,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
        int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE;
        int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS;
        int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
-       int refclk, num_outputs = 0;
+       int refclk, num_connectors = 0;
        intel_clock_t clock, reduced_clock;
        u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf;
        bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false;
@@ -2942,19 +2943,19 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
        drm_vblank_pre_modeset(dev, pipe);
 
        list_for_each_entry(connector, &mode_config->connector_list, head) {
-               struct intel_output *intel_output = to_intel_output(connector);
+               struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
                if (!connector->encoder || connector->encoder->crtc != crtc)
                        continue;
 
-               switch (intel_output->type) {
+               switch (intel_encoder->type) {
                case INTEL_OUTPUT_LVDS:
                        is_lvds = true;
                        break;
                case INTEL_OUTPUT_SDVO:
                case INTEL_OUTPUT_HDMI:
                        is_sdvo = true;
-                       if (intel_output->needs_tv_clock)
+                       if (intel_encoder->needs_tv_clock)
                                is_tv = true;
                        break;
                case INTEL_OUTPUT_DVO:
@@ -2974,10 +2975,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                        break;
                }
 
-               num_outputs++;
+               num_connectors++;
        }
 
-       if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) {
+       if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) {
                refclk = dev_priv->lvds_ssc_freq * 1000;
                DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
                                        refclk / 1000);
@@ -3048,8 +3049,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                if (is_edp) {
                        struct drm_connector *edp;
                        target_clock = mode->clock;
-                       edp = intel_pipe_get_output(crtc);
-                       intel_edp_link_config(to_intel_output(edp),
+                       edp = intel_pipe_get_connector(crtc);
+                       intel_edp_link_config(to_intel_encoder(edp),
                                        &lane, &link_bw);
                } else {
                        /* DP over FDI requires target mode clock
@@ -3230,7 +3231,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                /* XXX: just matching BIOS for now */
                /*      dpll |= PLL_REF_INPUT_TVCLKINBC; */
                dpll |= 3;
-       else if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2)
+       else if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2)
                dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
        else
                dpll |= PLL_REF_INPUT_DREFCLK;
@@ -3510,7 +3511,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
        if (!bo)
                return -ENOENT;
 
-       obj_priv = bo->driver_private;
+       obj_priv = to_intel_bo(bo);
 
        if (bo->size < width * height * 4) {
                DRM_ERROR("buffer is to small\n");
@@ -3654,9 +3655,9 @@ static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
  * detection.
  *
  * It will be up to the load-detect code to adjust the pipe as appropriate for
- * its requirements.  The pipe will be connected to no other outputs.
+ * its requirements.  The pipe will be connected to no other encoders.
  *
- * Currently this code will only succeed if there is a pipe with no outputs
+ * Currently this code will only succeed if there is a pipe with no encoders
  * configured for it.  In the future, it could choose to temporarily disable
  * some outputs to free up a pipe for its use.
  *
@@ -3669,14 +3670,14 @@ static struct drm_display_mode load_detect_mode = {
                 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 };
 
-struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
+struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
                                            struct drm_display_mode *mode,
                                            int *dpms_mode)
 {
        struct intel_crtc *intel_crtc;
        struct drm_crtc *possible_crtc;
        struct drm_crtc *supported_crtc =NULL;
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_crtc *crtc = NULL;
        struct drm_device *dev = encoder->dev;
        struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
@@ -3728,8 +3729,8 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
        }
 
        encoder->crtc = crtc;
-       intel_output->base.encoder = encoder;
-       intel_output->load_detect_temp = true;
+       intel_encoder->base.encoder = encoder;
+       intel_encoder->load_detect_temp = true;
 
        intel_crtc = to_intel_crtc(crtc);
        *dpms_mode = intel_crtc->dpms_mode;
@@ -3754,23 +3755,23 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
        return crtc;
 }
 
-void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode)
+void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, int dpms_mode)
 {
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_device *dev = encoder->dev;
        struct drm_crtc *crtc = encoder->crtc;
        struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
        struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 
-       if (intel_output->load_detect_temp) {
+       if (intel_encoder->load_detect_temp) {
                encoder->crtc = NULL;
-               intel_output->base.encoder = NULL;
-               intel_output->load_detect_temp = false;
+               intel_encoder->base.encoder = NULL;
+               intel_encoder->load_detect_temp = false;
                crtc->enabled = drm_helper_crtc_in_use(crtc);
                drm_helper_disable_unused_functions(dev);
        }
 
-       /* Switch crtc and output back off if necessary */
+       /* Switch crtc and encoder back off if necessary */
        if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) {
                if (encoder->crtc == crtc)
                        encoder_funcs->dpms(encoder, dpms_mode);
@@ -4155,7 +4156,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
        work = intel_crtc->unpin_work;
        if (work == NULL || !work->pending) {
                if (work && !work->pending) {
-                       obj_priv = work->pending_flip_obj->driver_private;
+                       obj_priv = to_intel_bo(work->pending_flip_obj);
                        DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n",
                                         obj_priv,
                                         atomic_read(&obj_priv->pending_flip));
@@ -4180,7 +4181,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
 
        spin_unlock_irqrestore(&dev->event_lock, flags);
 
-       obj_priv = work->pending_flip_obj->driver_private;
+       obj_priv = to_intel_bo(work->pending_flip_obj);
 
        /* Initial scanout buffer will have a 0 pending flip count */
        if ((atomic_read(&obj_priv->pending_flip) == 0) ||
@@ -4251,7 +4252,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        ret = intel_pin_and_fence_fb_obj(dev, obj);
        if (ret != 0) {
                DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
-                         obj->driver_private);
+                         to_intel_bo(obj));
                kfree(work);
                intel_crtc->unpin_work = NULL;
                mutex_unlock(&dev->struct_mutex);
@@ -4265,7 +4266,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        crtc->fb = fb;
        i915_gem_object_flush_write_domain(obj);
        drm_vblank_get(dev, intel_crtc->pipe);
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        atomic_inc(&obj_priv->pending_flip);
        work->pending_flip_obj = obj;
 
@@ -4398,8 +4399,8 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask)
        int entry = 0;
 
         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               struct intel_output *intel_output = to_intel_output(connector);
-               if (type_mask & intel_output->clone_mask)
+               struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+               if (type_mask & intel_encoder->clone_mask)
                        index_mask |= (1 << entry);
                entry++;
        }
@@ -4494,12 +4495,12 @@ static void intel_setup_outputs(struct drm_device *dev)
                intel_tv_init(dev);
 
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               struct intel_output *intel_output = to_intel_output(connector);
-               struct drm_encoder *encoder = &intel_output->enc;
+               struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+               struct drm_encoder *encoder = &intel_encoder->enc;
 
-               encoder->possible_crtcs = intel_output->crtc_mask;
+               encoder->possible_crtcs = intel_encoder->crtc_mask;
                encoder->possible_clones = intel_connector_clones(dev,
-                                               intel_output->clone_mask);
+                                               intel_encoder->clone_mask);
        }
 }
 
@@ -4717,6 +4718,20 @@ void intel_init_clock_gating(struct drm_device *dev)
         * specs, but enable as much else as we can.
         */
        if (HAS_PCH_SPLIT(dev)) {
+               uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE;
+
+               if (IS_IRONLAKE(dev)) {
+                       /* Required for FBC */
+                       dspclk_gate |= DPFDUNIT_CLOCK_GATE_DISABLE;
+                       /* Required for CxSR */
+                       dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE;
+
+                       I915_WRITE(PCH_3DCGDIS0,
+                                  MARIUNIT_CLOCK_GATE_DISABLE |
+                                  SVSMUNIT_CLOCK_GATE_DISABLE);
+               }
+
+               I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
                return;
        } else if (IS_G4X(dev)) {
                uint32_t dspclk_gate;
@@ -4764,14 +4779,14 @@ void intel_init_clock_gating(struct drm_device *dev)
                struct drm_i915_gem_object *obj_priv = NULL;
 
                if (dev_priv->pwrctx) {
-                       obj_priv = dev_priv->pwrctx->driver_private;
+                       obj_priv = to_intel_bo(dev_priv->pwrctx);
                } else {
                        struct drm_gem_object *pwrctx;
 
                        pwrctx = intel_alloc_power_context(dev);
                        if (pwrctx) {
                                dev_priv->pwrctx = pwrctx;
-                               obj_priv = pwrctx->driver_private;
+                               obj_priv = to_intel_bo(pwrctx);
                        }
                }
 
@@ -4800,7 +4815,7 @@ static void intel_init_display(struct drm_device *dev)
                        dev_priv->display.fbc_enabled = g4x_fbc_enabled;
                        dev_priv->display.enable_fbc = g4x_enable_fbc;
                        dev_priv->display.disable_fbc = g4x_disable_fbc;
-               } else if (IS_I965GM(dev) || IS_I945GM(dev) || IS_I915GM(dev)) {
+               } else if (IS_I965GM(dev)) {
                        dev_priv->display.fbc_enabled = i8xx_fbc_enabled;
                        dev_priv->display.enable_fbc = i8xx_enable_fbc;
                        dev_priv->display.disable_fbc = i8xx_disable_fbc;
@@ -4838,17 +4853,18 @@ static void intel_init_display(struct drm_device *dev)
                dev_priv->display.update_wm = g4x_update_wm;
        else if (IS_I965G(dev))
                dev_priv->display.update_wm = i965_update_wm;
-       else if (IS_I9XX(dev) || IS_MOBILE(dev)) {
+       else if (IS_I9XX(dev)) {
                dev_priv->display.update_wm = i9xx_update_wm;
                dev_priv->display.get_fifo_size = i9xx_get_fifo_size;
+       } else if (IS_I85X(dev)) {
+               dev_priv->display.update_wm = i9xx_update_wm;
+               dev_priv->display.get_fifo_size = i85x_get_fifo_size;
        } else {
-               if (IS_I85X(dev))
-                       dev_priv->display.get_fifo_size = i85x_get_fifo_size;
-               else if (IS_845G(dev))
+               dev_priv->display.update_wm = i830_update_wm;
+               if (IS_845G(dev))
                        dev_priv->display.get_fifo_size = i845_get_fifo_size;
                else
                        dev_priv->display.get_fifo_size = i830_get_fifo_size;
-               dev_priv->display.update_wm = i830_update_wm;
        }
 }
 
@@ -4942,7 +4958,7 @@ void intel_modeset_cleanup(struct drm_device *dev)
        if (dev_priv->pwrctx) {
                struct drm_i915_gem_object *obj_priv;
 
-               obj_priv = dev_priv->pwrctx->driver_private;
+               obj_priv = to_intel_bo(dev_priv->pwrctx);
                I915_WRITE(PWRCTXA, obj_priv->gtt_offset &~ PWRCTX_EN);
                I915_READ(PWRCTXA);
                i915_gem_object_unpin(dev_priv->pwrctx);
@@ -4963,9 +4979,9 @@ void intel_modeset_cleanup(struct drm_device *dev)
 */
 struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-       return &intel_output->enc;
+       return &intel_encoder->enc;
 }
 
 /*
index 3ef3a0d0edd0a45a8ac50f9c420dca4695248bd5..77e40cfcf21622e8a829ea715fcd7772493a395e 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "drm_crtc.h"
@@ -54,23 +55,23 @@ struct intel_dp_priv {
        uint8_t link_bw;
        uint8_t lane_count;
        uint8_t dpcd[4];
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct i2c_adapter adapter;
        struct i2c_algo_dp_aux_data algo;
 };
 
 static void
-intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
+intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
                    uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]);
 
 static void
-intel_dp_link_down(struct intel_output *intel_output, uint32_t DP);
+intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP);
 
 void
-intel_edp_link_config (struct intel_output *intel_output,
+intel_edp_link_config (struct intel_encoder *intel_encoder,
                int *lane_num, int *link_bw)
 {
-       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
 
        *lane_num = dp_priv->lane_count;
        if (dp_priv->link_bw == DP_LINK_BW_1_62)
@@ -80,9 +81,9 @@ intel_edp_link_config (struct intel_output *intel_output,
 }
 
 static int
-intel_dp_max_lane_count(struct intel_output *intel_output)
+intel_dp_max_lane_count(struct intel_encoder *intel_encoder)
 {
-       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
        int max_lane_count = 4;
 
        if (dp_priv->dpcd[0] >= 0x11) {
@@ -98,9 +99,9 @@ intel_dp_max_lane_count(struct intel_output *intel_output)
 }
 
 static int
-intel_dp_max_link_bw(struct intel_output *intel_output)
+intel_dp_max_link_bw(struct intel_encoder *intel_encoder)
 {
-       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
        int max_link_bw = dp_priv->dpcd[1];
 
        switch (max_link_bw) {
@@ -126,11 +127,11 @@ intel_dp_link_clock(uint8_t link_bw)
 /* I think this is a fiction */
 static int
 intel_dp_link_required(struct drm_device *dev,
-                      struct intel_output *intel_output, int pixel_clock)
+                      struct intel_encoder *intel_encoder, int pixel_clock)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       if (IS_eDP(intel_output))
+       if (IS_eDP(intel_encoder))
                return (pixel_clock * dev_priv->edp_bpp) / 8;
        else
                return pixel_clock * 3;
@@ -140,11 +141,11 @@ static int
 intel_dp_mode_valid(struct drm_connector *connector,
                    struct drm_display_mode *mode)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output));
-       int max_lanes = intel_dp_max_lane_count(intel_output);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder));
+       int max_lanes = intel_dp_max_lane_count(intel_encoder);
 
-       if (intel_dp_link_required(connector->dev, intel_output, mode->clock)
+       if (intel_dp_link_required(connector->dev, intel_encoder, mode->clock)
                        > max_link_clock * max_lanes)
                return MODE_CLOCK_HIGH;
 
@@ -208,13 +209,13 @@ intel_hrawclk(struct drm_device *dev)
 }
 
 static int
-intel_dp_aux_ch(struct intel_output *intel_output,
+intel_dp_aux_ch(struct intel_encoder *intel_encoder,
                uint8_t *send, int send_bytes,
                uint8_t *recv, int recv_size)
 {
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        uint32_t output_reg = dp_priv->output_reg;
-       struct drm_device *dev = intel_output->base.dev;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t ch_ctl = output_reg + 0x10;
        uint32_t ch_data = ch_ctl + 4;
@@ -229,7 +230,7 @@ intel_dp_aux_ch(struct intel_output *intel_output,
         * and would like to run at 2MHz. So, take the
         * hrawclk value and divide by 2 and use that
         */
-       if (IS_eDP(intel_output))
+       if (IS_eDP(intel_encoder))
                aux_clock_divider = 225; /* eDP input clock at 450Mhz */
        else if (HAS_PCH_SPLIT(dev))
                aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */
@@ -312,7 +313,7 @@ intel_dp_aux_ch(struct intel_output *intel_output,
 
 /* Write data to the aux channel in native mode */
 static int
-intel_dp_aux_native_write(struct intel_output *intel_output,
+intel_dp_aux_native_write(struct intel_encoder *intel_encoder,
                          uint16_t address, uint8_t *send, int send_bytes)
 {
        int ret;
@@ -329,7 +330,7 @@ intel_dp_aux_native_write(struct intel_output *intel_output,
        memcpy(&msg[4], send, send_bytes);
        msg_bytes = send_bytes + 4;
        for (;;) {
-               ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, &ack, 1);
+               ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, &ack, 1);
                if (ret < 0)
                        return ret;
                if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
@@ -344,15 +345,15 @@ intel_dp_aux_native_write(struct intel_output *intel_output,
 
 /* Write a single byte to the aux channel in native mode */
 static int
-intel_dp_aux_native_write_1(struct intel_output *intel_output,
+intel_dp_aux_native_write_1(struct intel_encoder *intel_encoder,
                            uint16_t address, uint8_t byte)
 {
-       return intel_dp_aux_native_write(intel_output, address, &byte, 1);
+       return intel_dp_aux_native_write(intel_encoder, address, &byte, 1);
 }
 
 /* read bytes from a native aux channel */
 static int
-intel_dp_aux_native_read(struct intel_output *intel_output,
+intel_dp_aux_native_read(struct intel_encoder *intel_encoder,
                         uint16_t address, uint8_t *recv, int recv_bytes)
 {
        uint8_t msg[4];
@@ -371,7 +372,7 @@ intel_dp_aux_native_read(struct intel_output *intel_output,
        reply_bytes = recv_bytes + 1;
 
        for (;;) {
-               ret = intel_dp_aux_ch(intel_output, msg, msg_bytes,
+               ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes,
                                      reply, reply_bytes);
                if (ret == 0)
                        return -EPROTO;
@@ -397,7 +398,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
        struct intel_dp_priv *dp_priv = container_of(adapter,
                                                     struct intel_dp_priv,
                                                     adapter);
-       struct intel_output *intel_output = dp_priv->intel_output;
+       struct intel_encoder *intel_encoder = dp_priv->intel_encoder;
        uint16_t address = algo_data->address;
        uint8_t msg[5];
        uint8_t reply[2];
@@ -436,7 +437,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
        }
 
        for (;;) {
-         ret = intel_dp_aux_ch(intel_output,
+         ret = intel_dp_aux_ch(intel_encoder,
                                msg, msg_bytes,
                                reply, reply_bytes);
                if (ret < 0) {
@@ -464,9 +465,9 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
 }
 
 static int
-intel_dp_i2c_init(struct intel_output *intel_output, const char *name)
+intel_dp_i2c_init(struct intel_encoder *intel_encoder, const char *name)
 {
-       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
 
        DRM_DEBUG_KMS("i2c_init %s\n", name);
        dp_priv->algo.running = false;
@@ -479,7 +480,7 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name)
        strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1);
        dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0';
        dp_priv->adapter.algo_data = &dp_priv->algo;
-       dp_priv->adapter.dev.parent = &intel_output->base.kdev;
+       dp_priv->adapter.dev.parent = &intel_encoder->base.kdev;
        
        return i2c_dp_aux_add_bus(&dp_priv->adapter);
 }
@@ -488,18 +489,18 @@ static bool
 intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
                    struct drm_display_mode *adjusted_mode)
 {
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
        int lane_count, clock;
-       int max_lane_count = intel_dp_max_lane_count(intel_output);
-       int max_clock = intel_dp_max_link_bw(intel_output) == DP_LINK_BW_2_7 ? 1 : 0;
+       int max_lane_count = intel_dp_max_lane_count(intel_encoder);
+       int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0;
        static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
 
        for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
                for (clock = 0; clock <= max_clock; clock++) {
                        int link_avail = intel_dp_link_clock(bws[clock]) * lane_count;
 
-                       if (intel_dp_link_required(encoder->dev, intel_output, mode->clock)
+                       if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock)
                                        <= link_avail) {
                                dp_priv->link_bw = bws[clock];
                                dp_priv->lane_count = lane_count;
@@ -561,16 +562,16 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
        struct intel_dp_m_n m_n;
 
        /*
-        * Find the lane count in the intel_output private
+        * Find the lane count in the intel_encoder private
         */
        list_for_each_entry(connector, &mode_config->connector_list, head) {
-               struct intel_output *intel_output = to_intel_output(connector);
-               struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+               struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+               struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
                if (!connector->encoder || connector->encoder->crtc != crtc)
                        continue;
 
-               if (intel_output->type == INTEL_OUTPUT_DISPLAYPORT) {
+               if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
                        lane_count = dp_priv->lane_count;
                        break;
                }
@@ -625,9 +626,9 @@ static void
 intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
                  struct drm_display_mode *adjusted_mode)
 {
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
-       struct drm_crtc *crtc = intel_output->enc.crtc;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+       struct drm_crtc *crtc = intel_encoder->enc.crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
        dp_priv->DP = (DP_LINK_TRAIN_OFF |
@@ -666,7 +667,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
        if (intel_crtc->pipe == 1)
                dp_priv->DP |= DP_PIPEB_SELECT;
 
-       if (IS_eDP(intel_output)) {
+       if (IS_eDP(intel_encoder)) {
                /* don't miss out required setting for eDP */
                dp_priv->DP |= DP_PLL_ENABLE;
                if (adjusted_mode->clock < 200000)
@@ -701,22 +702,22 @@ static void ironlake_edp_backlight_off (struct drm_device *dev)
 static void
 intel_dp_dpms(struct drm_encoder *encoder, int mode)
 {
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
-       struct drm_device *dev = intel_output->base.dev;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t dp_reg = I915_READ(dp_priv->output_reg);
 
        if (mode != DRM_MODE_DPMS_ON) {
                if (dp_reg & DP_PORT_EN) {
-                       intel_dp_link_down(intel_output, dp_priv->DP);
-                       if (IS_eDP(intel_output))
+                       intel_dp_link_down(intel_encoder, dp_priv->DP);
+                       if (IS_eDP(intel_encoder))
                                ironlake_edp_backlight_off(dev);
                }
        } else {
                if (!(dp_reg & DP_PORT_EN)) {
-                       intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
-                       if (IS_eDP(intel_output))
+                       intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
+                       if (IS_eDP(intel_encoder))
                                ironlake_edp_backlight_on(dev);
                }
        }
@@ -728,12 +729,12 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
  * link status information
  */
 static bool
-intel_dp_get_link_status(struct intel_output *intel_output,
+intel_dp_get_link_status(struct intel_encoder *intel_encoder,
                         uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
        int ret;
 
-       ret = intel_dp_aux_native_read(intel_output,
+       ret = intel_dp_aux_native_read(intel_encoder,
                                       DP_LANE0_1_STATUS,
                                       link_status, DP_LINK_STATUS_SIZE);
        if (ret != DP_LINK_STATUS_SIZE)
@@ -751,13 +752,13 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
 static void
 intel_dp_save(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct drm_device *dev = intel_output->base.dev;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
        dp_priv->save_DP = I915_READ(dp_priv->output_reg);
-       intel_dp_aux_native_read(intel_output, DP_LINK_BW_SET,
+       intel_dp_aux_native_read(intel_encoder, DP_LINK_BW_SET,
                                 dp_priv->save_link_configuration,
                                 sizeof (dp_priv->save_link_configuration));
 }
@@ -824,7 +825,7 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing)
 }
 
 static void
-intel_get_adjust_train(struct intel_output *intel_output,
+intel_get_adjust_train(struct intel_encoder *intel_encoder,
                       uint8_t link_status[DP_LINK_STATUS_SIZE],
                       int lane_count,
                       uint8_t train_set[4])
@@ -941,15 +942,15 @@ intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count)
 }
 
 static bool
-intel_dp_set_link_train(struct intel_output *intel_output,
+intel_dp_set_link_train(struct intel_encoder *intel_encoder,
                        uint32_t dp_reg_value,
                        uint8_t dp_train_pat,
                        uint8_t train_set[4],
                        bool first)
 {
-       struct drm_device *dev = intel_output->base.dev;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        int ret;
 
        I915_WRITE(dp_priv->output_reg, dp_reg_value);
@@ -957,11 +958,11 @@ intel_dp_set_link_train(struct intel_output *intel_output,
        if (first)
                intel_wait_for_vblank(dev);
 
-       intel_dp_aux_native_write_1(intel_output,
+       intel_dp_aux_native_write_1(intel_encoder,
                                    DP_TRAINING_PATTERN_SET,
                                    dp_train_pat);
 
-       ret = intel_dp_aux_native_write(intel_output,
+       ret = intel_dp_aux_native_write(intel_encoder,
                                        DP_TRAINING_LANE0_SET, train_set, 4);
        if (ret != 4)
                return false;
@@ -970,12 +971,12 @@ intel_dp_set_link_train(struct intel_output *intel_output,
 }
 
 static void
-intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
+intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
                    uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE])
 {
-       struct drm_device *dev = intel_output->base.dev;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        uint8_t train_set[4];
        uint8_t link_status[DP_LINK_STATUS_SIZE];
        int i;
@@ -986,7 +987,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
        int tries;
 
        /* Write the link configuration data */
-       intel_dp_aux_native_write(intel_output, 0x100,
+       intel_dp_aux_native_write(intel_encoder, 0x100,
                                  link_configuration, DP_LINK_CONFIGURATION_SIZE);
 
        DP |= DP_PORT_EN;
@@ -1000,14 +1001,14 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
                uint32_t    signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count);
                DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
 
-               if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_1,
+               if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_1,
                                             DP_TRAINING_PATTERN_1, train_set, first))
                        break;
                first = false;
                /* Set training pattern 1 */
 
                udelay(100);
-               if (!intel_dp_get_link_status(intel_output, link_status))
+               if (!intel_dp_get_link_status(intel_encoder, link_status))
                        break;
 
                if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) {
@@ -1032,7 +1033,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
                voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
                /* Compute new train_set as requested by target */
-               intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set);
+               intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);
        }
 
        /* channel equalization */
@@ -1044,13 +1045,13 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
                DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
 
                /* channel eq pattern */
-               if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_2,
+               if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_2,
                                             DP_TRAINING_PATTERN_2, train_set,
                                             false))
                        break;
 
                udelay(400);
-               if (!intel_dp_get_link_status(intel_output, link_status))
+               if (!intel_dp_get_link_status(intel_encoder, link_status))
                        break;
 
                if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) {
@@ -1063,26 +1064,26 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
                        break;
 
                /* Compute new train_set as requested by target */
-               intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set);
+               intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);
                ++tries;
        }
 
        I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF);
        POSTING_READ(dp_priv->output_reg);
-       intel_dp_aux_native_write_1(intel_output,
+       intel_dp_aux_native_write_1(intel_encoder,
                                    DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE);
 }
 
 static void
-intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
+intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP)
 {
-       struct drm_device *dev = intel_output->base.dev;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
        DRM_DEBUG_KMS("\n");
 
-       if (IS_eDP(intel_output)) {
+       if (IS_eDP(intel_encoder)) {
                DP &= ~DP_PLL_ENABLE;
                I915_WRITE(dp_priv->output_reg, DP);
                POSTING_READ(dp_priv->output_reg);
@@ -1095,7 +1096,7 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
 
        udelay(17000);
 
-       if (IS_eDP(intel_output))
+       if (IS_eDP(intel_encoder))
                DP |= DP_LINK_TRAIN_OFF;
        I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN);
        POSTING_READ(dp_priv->output_reg);
@@ -1104,13 +1105,13 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
 static void
 intel_dp_restore(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
        if (dp_priv->save_DP & DP_PORT_EN)
-               intel_dp_link_train(intel_output, dp_priv->save_DP, dp_priv->save_link_configuration);
+               intel_dp_link_train(intel_encoder, dp_priv->save_DP, dp_priv->save_link_configuration);
        else
-               intel_dp_link_down(intel_output,  dp_priv->save_DP);
+               intel_dp_link_down(intel_encoder,  dp_priv->save_DP);
 }
 
 /*
@@ -1123,32 +1124,32 @@ intel_dp_restore(struct drm_connector *connector)
  */
 
 static void
-intel_dp_check_link_status(struct intel_output *intel_output)
+intel_dp_check_link_status(struct intel_encoder *intel_encoder)
 {
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        uint8_t link_status[DP_LINK_STATUS_SIZE];
 
-       if (!intel_output->enc.crtc)
+       if (!intel_encoder->enc.crtc)
                return;
 
-       if (!intel_dp_get_link_status(intel_output, link_status)) {
-               intel_dp_link_down(intel_output, dp_priv->DP);
+       if (!intel_dp_get_link_status(intel_encoder, link_status)) {
+               intel_dp_link_down(intel_encoder, dp_priv->DP);
                return;
        }
 
        if (!intel_channel_eq_ok(link_status, dp_priv->lane_count))
-               intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
+               intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
 }
 
 static enum drm_connector_status
 ironlake_dp_detect(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        enum drm_connector_status status;
 
        status = connector_status_disconnected;
-       if (intel_dp_aux_native_read(intel_output,
+       if (intel_dp_aux_native_read(intel_encoder,
                                     0x000, dp_priv->dpcd,
                                     sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
        {
@@ -1167,10 +1168,10 @@ ironlake_dp_detect(struct drm_connector *connector)
 static enum drm_connector_status
 intel_dp_detect(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct drm_device *dev = intel_output->base.dev;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        uint32_t temp, bit;
        enum drm_connector_status status;
 
@@ -1209,7 +1210,7 @@ intel_dp_detect(struct drm_connector *connector)
                return connector_status_disconnected;
 
        status = connector_status_disconnected;
-       if (intel_dp_aux_native_read(intel_output,
+       if (intel_dp_aux_native_read(intel_encoder,
                                     0x000, dp_priv->dpcd,
                                     sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
        {
@@ -1221,20 +1222,20 @@ intel_dp_detect(struct drm_connector *connector)
 
 static int intel_dp_get_modes(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct drm_device *dev = intel_output->base.dev;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        int ret;
 
        /* We should parse the EDID data and find out if it has an audio sink
         */
 
-       ret = intel_ddc_get_modes(intel_output);
+       ret = intel_ddc_get_modes(intel_encoder);
        if (ret)
                return ret;
 
        /* if eDP has no EDID, try to use fixed panel mode from VBT */
-       if (IS_eDP(intel_output)) {
+       if (IS_eDP(intel_encoder)) {
                if (dev_priv->panel_fixed_mode != NULL) {
                        struct drm_display_mode *mode;
                        mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
@@ -1248,13 +1249,13 @@ static int intel_dp_get_modes(struct drm_connector *connector)
 static void
 intel_dp_destroy (struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-       if (intel_output->i2c_bus)
-               intel_i2c_destroy(intel_output->i2c_bus);
+       if (intel_encoder->i2c_bus)
+               intel_i2c_destroy(intel_encoder->i2c_bus);
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
 
 static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
@@ -1290,12 +1291,12 @@ static const struct drm_encoder_funcs intel_dp_enc_funcs = {
 };
 
 void
-intel_dp_hot_plug(struct intel_output *intel_output)
+intel_dp_hot_plug(struct intel_encoder *intel_encoder)
 {
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
        if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON)
-               intel_dp_check_link_status(intel_output);
+               intel_dp_check_link_status(intel_encoder);
 }
 
 void
@@ -1303,53 +1304,53 @@ intel_dp_init(struct drm_device *dev, int output_reg)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_dp_priv *dp_priv;
        const char *name = NULL;
 
-       intel_output = kcalloc(sizeof(struct intel_output) + 
+       intel_encoder = kcalloc(sizeof(struct intel_encoder) +
                               sizeof(struct intel_dp_priv), 1, GFP_KERNEL);
-       if (!intel_output)
+       if (!intel_encoder)
                return;
 
-       dp_priv = (struct intel_dp_priv *)(intel_output + 1);
+       dp_priv = (struct intel_dp_priv *)(intel_encoder + 1);
 
-       connector = &intel_output->base;
+       connector = &intel_encoder->base;
        drm_connector_init(dev, connector, &intel_dp_connector_funcs,
                           DRM_MODE_CONNECTOR_DisplayPort);
        drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
 
        if (output_reg == DP_A)
-               intel_output->type = INTEL_OUTPUT_EDP;
+               intel_encoder->type = INTEL_OUTPUT_EDP;
        else
-               intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
+               intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
 
        if (output_reg == DP_B || output_reg == PCH_DP_B)
-               intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
+               intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
        else if (output_reg == DP_C || output_reg == PCH_DP_C)
-               intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
+               intel_encoder->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
        else if (output_reg == DP_D || output_reg == PCH_DP_D)
-               intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
+               intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
 
-       if (IS_eDP(intel_output))
-               intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
+       if (IS_eDP(intel_encoder))
+               intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
 
-       intel_output->crtc_mask = (1 << 0) | (1 << 1);
+       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
        connector->interlace_allowed = true;
        connector->doublescan_allowed = 0;
 
-       dp_priv->intel_output = intel_output;
+       dp_priv->intel_encoder = intel_encoder;
        dp_priv->output_reg = output_reg;
        dp_priv->has_audio = false;
        dp_priv->dpms_mode = DRM_MODE_DPMS_ON;
-       intel_output->dev_priv = dp_priv;
+       intel_encoder->dev_priv = dp_priv;
 
-       drm_encoder_init(dev, &intel_output->enc, &intel_dp_enc_funcs,
+       drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs,
                         DRM_MODE_ENCODER_TMDS);
-       drm_encoder_helper_add(&intel_output->enc, &intel_dp_helper_funcs);
+       drm_encoder_helper_add(&intel_encoder->enc, &intel_dp_helper_funcs);
 
-       drm_mode_connector_attach_encoder(&intel_output->base,
-                                         &intel_output->enc);
+       drm_mode_connector_attach_encoder(&intel_encoder->base,
+                                         &intel_encoder->enc);
        drm_sysfs_connector_add(connector);
 
        /* Set up the DDC bus. */
@@ -1377,10 +1378,10 @@ intel_dp_init(struct drm_device *dev, int output_reg)
                        break;
        }
 
-       intel_dp_i2c_init(intel_output, name);
+       intel_dp_i2c_init(intel_encoder, name);
 
-       intel_output->ddc_bus = &dp_priv->adapter;
-       intel_output->hot_plug = intel_dp_hot_plug;
+       intel_encoder->ddc_bus = &dp_priv->adapter;
+       intel_encoder->hot_plug = intel_dp_hot_plug;
 
        if (output_reg == DP_A) {
                /* initialize panel mode from VBT if available for eDP */
index 3a467ca578579a09f6af9731608611bcacd904e0..e30253755f12f419ff56efd9b7b3b893069f566d 100644 (file)
@@ -95,7 +95,7 @@ struct intel_framebuffer {
 };
 
 
-struct intel_output {
+struct intel_encoder {
        struct drm_connector base;
 
        struct drm_encoder enc;
@@ -105,7 +105,7 @@ struct intel_output {
        bool load_detect_temp;
        bool needs_tv_clock;
        void *dev_priv;
-       void (*hot_plug)(struct intel_output *);
+       void (*hot_plug)(struct intel_encoder *);
        int crtc_mask;
        int clone_mask;
 };
@@ -152,15 +152,15 @@ struct intel_crtc {
 };
 
 #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
-#define to_intel_output(x) container_of(x, struct intel_output, base)
-#define enc_to_intel_output(x) container_of(x, struct intel_output, enc)
+#define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
+#define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc)
 #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
 
 struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
                                     const char *name);
 void intel_i2c_destroy(struct i2c_adapter *adapter);
-int intel_ddc_get_modes(struct intel_output *intel_output);
-extern bool intel_ddc_probe(struct intel_output *intel_output);
+int intel_ddc_get_modes(struct intel_encoder *intel_encoder);
+extern bool intel_ddc_probe(struct intel_encoder *intel_encoder);
 void intel_i2c_quirk_set(struct drm_device *dev, bool enable);
 void intel_i2c_reset_gmbus(struct drm_device *dev);
 
@@ -175,7 +175,7 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg);
 void
 intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
                 struct drm_display_mode *adjusted_mode);
-extern void intel_edp_link_config (struct intel_output *, int *, int *);
+extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
 
 
 extern int intel_panel_fitter_pipe (struct drm_device *dev);
@@ -191,10 +191,10 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
 extern void intel_wait_for_vblank(struct drm_device *dev);
 extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
-extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
+extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
                                                   struct drm_display_mode *mode,
                                                   int *dpms_mode);
-extern void intel_release_load_detect_pipe(struct intel_output *intel_output,
+extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
                                           int dpms_mode);
 
 extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB);
index a4d2606de778c3d419713c3d8552290d828826c0..ebf213c96b9c376a05d520b885de0bf24117f6b8 100644 (file)
@@ -25,6 +25,7 @@
  *     Eric Anholt <eric@anholt.net>
  */
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "drm_crtc.h"
@@ -79,8 +80,8 @@ static struct intel_dvo_device intel_dvo_devices[] = {
 static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
 {
        struct drm_i915_private *dev_priv = encoder->dev->dev_private;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
        u32 dvo_reg = dvo->dvo_reg;
        u32 temp = I915_READ(dvo_reg);
 
@@ -98,8 +99,8 @@ static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
 static void intel_dvo_save(struct drm_connector *connector)
 {
        struct drm_i915_private *dev_priv = connector->dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        /* Each output should probably just save the registers it touches,
         * but for now, use more overkill.
@@ -114,8 +115,8 @@ static void intel_dvo_save(struct drm_connector *connector)
 static void intel_dvo_restore(struct drm_connector *connector)
 {
        struct drm_i915_private *dev_priv = connector->dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        dvo->dev_ops->restore(dvo);
 
@@ -127,8 +128,8 @@ static void intel_dvo_restore(struct drm_connector *connector)
 static int intel_dvo_mode_valid(struct drm_connector *connector,
                                struct drm_display_mode *mode)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
                return MODE_NO_DBLESCAN;
@@ -149,8 +150,8 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder,
                                 struct drm_display_mode *mode,
                                 struct drm_display_mode *adjusted_mode)
 {
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        /* If we have timings from the BIOS for the panel, put them in
         * to the adjusted mode.  The CRTC will be set up for this mode,
@@ -185,8 +186,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
        int pipe = intel_crtc->pipe;
        u32 dvo_val;
        u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg;
@@ -240,23 +241,23 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
  */
 static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        return dvo->dev_ops->detect(dvo);
 }
 
 static int intel_dvo_get_modes(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        /* We should probably have an i2c driver get_modes function for those
         * devices which will have a fixed set of modes determined by the chip
         * (TV-out, for example), but for now with just TMDS and LVDS,
         * that's not the case.
         */
-       intel_ddc_get_modes(intel_output);
+       intel_ddc_get_modes(intel_encoder);
        if (!list_empty(&connector->probed_modes))
                return 1;
 
@@ -274,8 +275,8 @@ static int intel_dvo_get_modes(struct drm_connector *connector)
 
 static void intel_dvo_destroy (struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        if (dvo) {
                if (dvo->dev_ops->destroy)
@@ -285,13 +286,13 @@ static void intel_dvo_destroy (struct drm_connector *connector)
                /* no need, in i830_dvoices[] now */
                //kfree(dvo);
        }
-       if (intel_output->i2c_bus)
-               intel_i2c_destroy(intel_output->i2c_bus);
-       if (intel_output->ddc_bus)
-               intel_i2c_destroy(intel_output->ddc_bus);
+       if (intel_encoder->i2c_bus)
+               intel_i2c_destroy(intel_encoder->i2c_bus);
+       if (intel_encoder->ddc_bus)
+               intel_i2c_destroy(intel_encoder->ddc_bus);
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
 
 #ifdef RANDR_GET_CRTC_INTERFACE
@@ -299,8 +300,8 @@ static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
        int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT);
 
        return intel_pipe_to_crtc(pScrn, pipe);
@@ -351,8 +352,8 @@ intel_dvo_get_current_mode (struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
        uint32_t dvo_reg = dvo->dvo_reg;
        uint32_t dvo_val = I915_READ(dvo_reg);
        struct drm_display_mode *mode = NULL;
@@ -382,24 +383,24 @@ intel_dvo_get_current_mode (struct drm_connector *connector)
 
 void intel_dvo_init(struct drm_device *dev)
 {
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_dvo_device *dvo;
        struct i2c_adapter *i2cbus = NULL;
        int ret = 0;
        int i;
        int encoder_type = DRM_MODE_ENCODER_NONE;
-       intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL);
-       if (!intel_output)
+       intel_encoder = kzalloc (sizeof(struct intel_encoder), GFP_KERNEL);
+       if (!intel_encoder)
                return;
 
        /* Set up the DDC bus */
-       intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
-       if (!intel_output->ddc_bus)
+       intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
+       if (!intel_encoder->ddc_bus)
                goto free_intel;
 
        /* Now, try to find a controller */
        for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
-               struct drm_connector *connector = &intel_output->base;
+               struct drm_connector *connector = &intel_encoder->base;
                int gpio;
 
                dvo = &intel_dvo_devices[i];
@@ -434,11 +435,11 @@ void intel_dvo_init(struct drm_device *dev)
                if (!ret)
                        continue;
 
-               intel_output->type = INTEL_OUTPUT_DVO;
-               intel_output->crtc_mask = (1 << 0) | (1 << 1);
+               intel_encoder->type = INTEL_OUTPUT_DVO;
+               intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
                switch (dvo->type) {
                case INTEL_DVO_CHIP_TMDS:
-                       intel_output->clone_mask =
+                       intel_encoder->clone_mask =
                                (1 << INTEL_DVO_TMDS_CLONE_BIT) |
                                (1 << INTEL_ANALOG_CLONE_BIT);
                        drm_connector_init(dev, connector,
@@ -447,7 +448,7 @@ void intel_dvo_init(struct drm_device *dev)
                        encoder_type = DRM_MODE_ENCODER_TMDS;
                        break;
                case INTEL_DVO_CHIP_LVDS:
-                       intel_output->clone_mask =
+                       intel_encoder->clone_mask =
                                (1 << INTEL_DVO_LVDS_CLONE_BIT);
                        drm_connector_init(dev, connector,
                                           &intel_dvo_connector_funcs,
@@ -462,16 +463,16 @@ void intel_dvo_init(struct drm_device *dev)
                connector->interlace_allowed = false;
                connector->doublescan_allowed = false;
 
-               intel_output->dev_priv = dvo;
-               intel_output->i2c_bus = i2cbus;
+               intel_encoder->dev_priv = dvo;
+               intel_encoder->i2c_bus = i2cbus;
 
-               drm_encoder_init(dev, &intel_output->enc,
+               drm_encoder_init(dev, &intel_encoder->enc,
                                 &intel_dvo_enc_funcs, encoder_type);
-               drm_encoder_helper_add(&intel_output->enc,
+               drm_encoder_helper_add(&intel_encoder->enc,
                                       &intel_dvo_helper_funcs);
 
-               drm_mode_connector_attach_encoder(&intel_output->base,
-                                                 &intel_output->enc);
+               drm_mode_connector_attach_encoder(&intel_encoder->base,
+                                                 &intel_encoder->enc);
                if (dvo->type == INTEL_DVO_CHIP_LVDS) {
                        /* For our LVDS chipsets, we should hopefully be able
                         * to dig the fixed panel mode out of the BIOS data.
@@ -489,10 +490,10 @@ void intel_dvo_init(struct drm_device *dev)
                return;
        }
 
-       intel_i2c_destroy(intel_output->ddc_bus);
+       intel_i2c_destroy(intel_encoder->ddc_bus);
        /* Didn't find a chip, so tear down. */
        if (i2cbus != NULL)
                intel_i2c_destroy(i2cbus);
 free_intel:
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
index 8cd791dc5b298d1d11217429798f8f66f0ff0089..8a0b3bcdc7b123c9a445edd14b48af97547708db 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/tty.h>
-#include <linux/slab.h>
 #include <linux/sysrq.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
@@ -145,7 +144,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
                ret = -ENOMEM;
                goto out;
        }
-       obj_priv = fbo->driver_private;
+       obj_priv = to_intel_bo(fbo);
 
        mutex_lock(&dev->struct_mutex);
 
index a30f8bfc198563d3f8beb8634b82e8dc6bb6a915..48cade0cf7b1b5504e3d4cb3e43ed7a00a6ca265 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include "drmP.h"
 #include "drm.h"
@@ -50,8 +51,8 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc = encoder->crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
        u32 sdvox;
 
        sdvox = SDVO_ENCODING_HDMI |
@@ -73,8 +74,8 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
 {
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
        u32 temp;
 
        temp = I915_READ(hdmi_priv->sdvox_reg);
@@ -109,8 +110,8 @@ static void intel_hdmi_save(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
 
        hdmi_priv->save_SDVOX = I915_READ(hdmi_priv->sdvox_reg);
 }
@@ -119,8 +120,8 @@ static void intel_hdmi_restore(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
 
        I915_WRITE(hdmi_priv->sdvox_reg, hdmi_priv->save_SDVOX);
        POSTING_READ(hdmi_priv->sdvox_reg);
@@ -150,21 +151,21 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
 static enum drm_connector_status
 intel_hdmi_detect(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
        struct edid *edid = NULL;
        enum drm_connector_status status = connector_status_disconnected;
 
        hdmi_priv->has_hdmi_sink = false;
-       edid = drm_get_edid(&intel_output->base,
-                           intel_output->ddc_bus);
+       edid = drm_get_edid(&intel_encoder->base,
+                           intel_encoder->ddc_bus);
 
        if (edid) {
                if (edid->input & DRM_EDID_INPUT_DIGITAL) {
                        status = connector_status_connected;
                        hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
                }
-               intel_output->base.display_info.raw_edid = NULL;
+               intel_encoder->base.display_info.raw_edid = NULL;
                kfree(edid);
        }
 
@@ -173,24 +174,24 @@ intel_hdmi_detect(struct drm_connector *connector)
 
 static int intel_hdmi_get_modes(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
        /* We should parse the EDID data and find out if it's an HDMI sink so
         * we can send audio to it.
         */
 
-       return intel_ddc_get_modes(intel_output);
+       return intel_ddc_get_modes(intel_encoder);
 }
 
 static void intel_hdmi_destroy(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-       if (intel_output->i2c_bus)
-               intel_i2c_destroy(intel_output->i2c_bus);
+       if (intel_encoder->i2c_bus)
+               intel_i2c_destroy(intel_encoder->i2c_bus);
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
 
 static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
@@ -229,63 +230,63 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_hdmi_priv *hdmi_priv;
 
-       intel_output = kcalloc(sizeof(struct intel_output) +
+       intel_encoder = kcalloc(sizeof(struct intel_encoder) +
                               sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL);
-       if (!intel_output)
+       if (!intel_encoder)
                return;
-       hdmi_priv = (struct intel_hdmi_priv *)(intel_output + 1);
+       hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1);
 
-       connector = &intel_output->base;
+       connector = &intel_encoder->base;
        drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
                           DRM_MODE_CONNECTOR_HDMIA);
        drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
 
-       intel_output->type = INTEL_OUTPUT_HDMI;
+       intel_encoder->type = INTEL_OUTPUT_HDMI;
 
        connector->interlace_allowed = 0;
        connector->doublescan_allowed = 0;
-       intel_output->crtc_mask = (1 << 0) | (1 << 1);
+       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
 
        /* Set up the DDC bus. */
        if (sdvox_reg == SDVOB) {
-               intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
-               intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
+               intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
+               intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
                dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
        } else if (sdvox_reg == SDVOC) {
-               intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
-               intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
+               intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
+               intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
                dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
        } else if (sdvox_reg == HDMIB) {
-               intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
-               intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
+               intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
+               intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
                                                                "HDMIB");
                dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
        } else if (sdvox_reg == HDMIC) {
-               intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
-               intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
+               intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
+               intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
                                                                "HDMIC");
                dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
        } else if (sdvox_reg == HDMID) {
-               intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
-               intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
+               intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
+               intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
                                                                "HDMID");
                dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;
        }
-       if (!intel_output->ddc_bus)
+       if (!intel_encoder->ddc_bus)
                goto err_connector;
 
        hdmi_priv->sdvox_reg = sdvox_reg;
-       intel_output->dev_priv = hdmi_priv;
+       intel_encoder->dev_priv = hdmi_priv;
 
-       drm_encoder_init(dev, &intel_output->enc, &intel_hdmi_enc_funcs,
+       drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs,
                         DRM_MODE_ENCODER_TMDS);
-       drm_encoder_helper_add(&intel_output->enc, &intel_hdmi_helper_funcs);
+       drm_encoder_helper_add(&intel_encoder->enc, &intel_hdmi_helper_funcs);
 
-       drm_mode_connector_attach_encoder(&intel_output->base,
-                                         &intel_output->enc);
+       drm_mode_connector_attach_encoder(&intel_encoder->base,
+                                         &intel_encoder->enc);
        drm_sysfs_connector_add(connector);
 
        /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
@@ -301,7 +302,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
 
 err_connector:
        drm_connector_cleanup(connector);
-       kfree(intel_output);
+       kfree(intel_encoder);
 
        return;
 }
index fcc753ca5d9446434e026197ba8318cbcfbda9b8..c2649c7df14c7e654aba8eb495c3874c698707b5 100644 (file)
@@ -26,6 +26,7 @@
  *     Eric Anholt <eric@anholt.net>
  */
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/i2c-id.h>
 #include <linux/i2c-algo-bit.h>
 #include "drmP.h"
index 14e516fdc2dd5c71b69f403bf184450171f3f185..b66806a37d37f53ac0a18ae1b536a5db0322c9e3 100644 (file)
@@ -30,6 +30,7 @@
 #include <acpi/button.h>
 #include <linux/dmi.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "drm_crtc.h"
@@ -238,8 +239,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
        struct drm_encoder *tmp_encoder;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
        u32 pfit_control = 0, pfit_pgm_ratios = 0;
        int left_border = 0, right_border = 0, top_border = 0;
        int bottom_border = 0;
@@ -586,8 +587,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
 {
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
 
        /*
         * The LVDS pin pair will already have been turned on in the
@@ -607,53 +608,6 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
        I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control);
 }
 
-/* Some lid devices report incorrect lid status, assume they're connected */
-static const struct dmi_system_id bad_lid_status[] = {
-       {
-               .ident = "Compaq nx9020",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-                       DMI_MATCH(DMI_BOARD_NAME, "3084"),
-               },
-       },
-       {
-               .ident = "Samsung SX20S",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"),
-                       DMI_MATCH(DMI_BOARD_NAME, "SX20S"),
-               },
-       },
-       {
-               .ident = "Aspire One",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire one"),
-               },
-       },
-       {
-               .ident = "Aspire 1810T",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1810T"),
-               },
-       },
-       {
-               .ident = "PC-81005",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "MALATA"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"),
-               },
-       },
-       {
-               .ident = "Clevo M5x0N",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."),
-                       DMI_MATCH(DMI_BOARD_NAME, "M5x0N"),
-               },
-       },
-       { }
-};
-
 /**
  * Detect the LVDS connection.
  *
@@ -669,12 +623,9 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect
        /* ACPI lid methods were generally unreliable in this generation, so
         * don't even bother.
         */
-       if (IS_GEN2(dev))
+       if (IS_GEN2(dev) || IS_GEN3(dev))
                return connector_status_connected;
 
-       if (!dmi_check_system(bad_lid_status) && !acpi_lid_open())
-               status = connector_status_disconnected;
-
        return status;
 }
 
@@ -684,14 +635,16 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect
 static int intel_lvds_get_modes(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
        struct drm_i915_private *dev_priv = dev->dev_private;
        int ret = 0;
 
-       ret = intel_ddc_get_modes(intel_output);
+       if (dev_priv->lvds_edid_good) {
+               ret = intel_ddc_get_modes(intel_encoder);
 
-       if (ret)
-               return ret;
+               if (ret)
+                       return ret;
+       }
 
        /* Didn't get an EDID, so
         * Set wide sync ranges so we get all modes
@@ -764,11 +717,11 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
 static void intel_lvds_destroy(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       if (intel_output->ddc_bus)
-               intel_i2c_destroy(intel_output->ddc_bus);
+       if (intel_encoder->ddc_bus)
+               intel_i2c_destroy(intel_encoder->ddc_bus);
        if (dev_priv->lid_notifier.notifier_call)
                acpi_lid_notifier_unregister(&dev_priv->lid_notifier);
        drm_sysfs_connector_remove(connector);
@@ -781,13 +734,13 @@ static int intel_lvds_set_property(struct drm_connector *connector,
                                   uint64_t value)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output =
-                       to_intel_output(connector);
+       struct intel_encoder *intel_encoder =
+                       to_intel_encoder(connector);
 
        if (property == dev->mode_config.scaling_mode_property &&
                                connector->encoder) {
                struct drm_crtc *crtc = connector->encoder->crtc;
-               struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
+               struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
                if (value == DRM_MODE_SCALE_NONE) {
                        DRM_DEBUG_KMS("no scaling not supported\n");
                        return 0;
@@ -907,6 +860,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
                        DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"),
                },
        },
+       {
+               .callback = intel_no_lvds_dmi_callback,
+               .ident = "Clientron U800",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "U800"),
+               },
+       },
 
        { }     /* terminating entry */
 };
@@ -1017,7 +978,7 @@ static int lvds_is_present_in_vbt(struct drm_device *dev)
 void intel_lvds_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct drm_connector *connector;
        struct drm_encoder *encoder;
        struct drm_display_mode *scan; /* *modes, *bios_mode; */
@@ -1045,40 +1006,40 @@ void intel_lvds_init(struct drm_device *dev)
                gpio = PCH_GPIOC;
        }
 
-       intel_output = kzalloc(sizeof(struct intel_output) +
+       intel_encoder = kzalloc(sizeof(struct intel_encoder) +
                                sizeof(struct intel_lvds_priv), GFP_KERNEL);
-       if (!intel_output) {
+       if (!intel_encoder) {
                return;
        }
 
-       connector = &intel_output->base;
-       encoder = &intel_output->enc;
-       drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs,
+       connector = &intel_encoder->base;
+       encoder = &intel_encoder->enc;
+       drm_connector_init(dev, &intel_encoder->base, &intel_lvds_connector_funcs,
                           DRM_MODE_CONNECTOR_LVDS);
 
-       drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs,
+       drm_encoder_init(dev, &intel_encoder->enc, &intel_lvds_enc_funcs,
                         DRM_MODE_ENCODER_LVDS);
 
-       drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
-       intel_output->type = INTEL_OUTPUT_LVDS;
+       drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc);
+       intel_encoder->type = INTEL_OUTPUT_LVDS;
 
-       intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
-       intel_output->crtc_mask = (1 << 1);
+       intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
+       intel_encoder->crtc_mask = (1 << 1);
        drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
        drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
        connector->display_info.subpixel_order = SubPixelHorizontalRGB;
        connector->interlace_allowed = false;
        connector->doublescan_allowed = false;
 
-       lvds_priv = (struct intel_lvds_priv *)(intel_output + 1);
-       intel_output->dev_priv = lvds_priv;
+       lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1);
+       intel_encoder->dev_priv = lvds_priv;
        /* create the scaling mode property */
        drm_mode_create_scaling_mode_property(dev);
        /*
         * the initial panel fitting mode will be FULL_SCREEN.
         */
 
-       drm_connector_attach_property(&intel_output->base,
+       drm_connector_attach_property(&intel_encoder->base,
                                      dev->mode_config.scaling_mode_property,
                                      DRM_MODE_SCALE_FULLSCREEN);
        lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN;
@@ -1093,8 +1054,8 @@ void intel_lvds_init(struct drm_device *dev)
         */
 
        /* Set up the DDC bus. */
-       intel_output->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C");
-       if (!intel_output->ddc_bus) {
+       intel_encoder->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C");
+       if (!intel_encoder->ddc_bus) {
                dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
                           "failed.\n");
                goto failed;
@@ -1104,7 +1065,10 @@ void intel_lvds_init(struct drm_device *dev)
         * Attempt to get the fixed panel mode from DDC.  Assume that the
         * preferred mode is the right one.
         */
-       intel_ddc_get_modes(intel_output);
+       dev_priv->lvds_edid_good = true;
+
+       if (!intel_ddc_get_modes(intel_encoder))
+               dev_priv->lvds_edid_good = false;
 
        list_for_each_entry(scan, &connector->probed_modes, head) {
                mutex_lock(&dev->mode_config.mutex);
@@ -1182,9 +1146,9 @@ out:
 
 failed:
        DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
-       if (intel_output->ddc_bus)
-               intel_i2c_destroy(intel_output->ddc_bus);
+       if (intel_encoder->ddc_bus)
+               intel_i2c_destroy(intel_encoder->ddc_bus);
        drm_connector_cleanup(connector);
        drm_encoder_cleanup(encoder);
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
index 67e2f4632a2451fd77200e0f9810a18c83afca1d..8e5c83b2d120a7e5f8267244e87d8c66c3360f1b 100644 (file)
@@ -23,6 +23,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/fb.h>
 #include "drmP.h"
@@ -33,7 +34,7 @@
  * intel_ddc_probe
  *
  */
-bool intel_ddc_probe(struct intel_output *intel_output)
+bool intel_ddc_probe(struct intel_encoder *intel_encoder)
 {
        u8 out_buf[] = { 0x0, 0x0};
        u8 buf[2];
@@ -53,9 +54,9 @@ bool intel_ddc_probe(struct intel_output *intel_output)
                }
        };
 
-       intel_i2c_quirk_set(intel_output->base.dev, true);
-       ret = i2c_transfer(intel_output->ddc_bus, msgs, 2);
-       intel_i2c_quirk_set(intel_output->base.dev, false);
+       intel_i2c_quirk_set(intel_encoder->base.dev, true);
+       ret = i2c_transfer(intel_encoder->ddc_bus, msgs, 2);
+       intel_i2c_quirk_set(intel_encoder->base.dev, false);
        if (ret == 2)
                return true;
 
@@ -68,19 +69,19 @@ bool intel_ddc_probe(struct intel_output *intel_output)
  *
  * Fetch the EDID information from @connector using the DDC bus.
  */
-int intel_ddc_get_modes(struct intel_output *intel_output)
+int intel_ddc_get_modes(struct intel_encoder *intel_encoder)
 {
        struct edid *edid;
        int ret = 0;
 
-       intel_i2c_quirk_set(intel_output->base.dev, true);
-       edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus);
-       intel_i2c_quirk_set(intel_output->base.dev, false);
+       intel_i2c_quirk_set(intel_encoder->base.dev, true);
+       edid = drm_get_edid(&intel_encoder->base, intel_encoder->ddc_bus);
+       intel_i2c_quirk_set(intel_encoder->base.dev, false);
        if (edid) {
-               drm_mode_connector_update_edid_property(&intel_output->base,
+               drm_mode_connector_update_edid_property(&intel_encoder->base,
                                                        edid);
-               ret = drm_add_edid_modes(&intel_output->base, edid);
-               intel_output->base.display_info.raw_edid = NULL;
+               ret = drm_add_edid_modes(&intel_encoder->base, edid);
+               intel_encoder->base.display_info.raw_edid = NULL;
                kfree(edid);
        }
 
index d355d1d527e766438a3a177218eed2dbb9210a7d..6d524a1fc271331939c0e3625e75e08e45376d61 100644 (file)
@@ -724,7 +724,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,
        int ret, tmp_width;
        struct overlay_registers *regs;
        bool scale_changed = false;
-       struct drm_i915_gem_object *bo_priv = new_bo->driver_private;
+       struct drm_i915_gem_object *bo_priv = to_intel_bo(new_bo);
        struct drm_device *dev = overlay->dev;
 
        BUG_ON(!mutex_is_locked(&dev->struct_mutex));
@@ -809,7 +809,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,
        intel_overlay_continue(overlay, scale_changed);
 
        overlay->old_vid_bo = overlay->vid_bo;
-       overlay->vid_bo = new_bo->driver_private;
+       overlay->vid_bo = to_intel_bo(new_bo);
 
        return 0;
 
@@ -1068,14 +1068,18 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
 
        drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
                         DRM_MODE_OBJECT_CRTC);
-       if (!drmmode_obj)
-               return -ENOENT;
+       if (!drmmode_obj) {
+               ret = -ENOENT;
+               goto out_free;
+       }
        crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
 
        new_bo = drm_gem_object_lookup(dev, file_priv,
                        put_image_rec->bo_handle);
-       if (!new_bo)
-               return -ENOENT;
+       if (!new_bo) {
+               ret = -ENOENT;
+               goto out_free;
+       }
 
        mutex_lock(&dev->mode_config.mutex);
        mutex_lock(&dev->struct_mutex);
@@ -1165,6 +1169,7 @@ out_unlock:
        mutex_unlock(&dev->struct_mutex);
        mutex_unlock(&dev->mode_config.mutex);
        drm_gem_object_unreference_unlocked(new_bo);
+out_free:
        kfree(params);
 
        return ret;
@@ -1339,7 +1344,7 @@ void intel_setup_overlay(struct drm_device *dev)
        reg_bo = drm_gem_object_alloc(dev, PAGE_SIZE);
        if (!reg_bo)
                goto out_free;
-       overlay->reg_bo = reg_bo->driver_private;
+       overlay->reg_bo = to_intel_bo(reg_bo);
 
        if (OVERLAY_NONPHYSICAL(dev)) {
                ret = i915_gem_object_pin(reg_bo, PAGE_SIZE);
index 48daee5c9c63bad7a813655ff6635784f3b6ef75..87d953664cb0a5d758d9a236d1f7471db43b39c6 100644 (file)
@@ -26,6 +26,7 @@
  *     Eric Anholt <eric@anholt.net>
  */
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include "drmP.h"
 #include "drm.h"
@@ -53,7 +54,7 @@ struct intel_sdvo_priv {
        u8 slave_addr;
 
        /* Register for the SDVO device: SDVOB or SDVOC */
-       int output_device;
+       int sdvo_reg;
 
        /* Active outputs controlled by this SDVO output */
        uint16_t controlled_output;
@@ -123,7 +124,7 @@ struct intel_sdvo_priv {
         */
        struct intel_sdvo_encode encode;
 
-       /* DDC bus used by this SDVO output */
+       /* DDC bus used by this SDVO encoder */
        uint8_t ddc_bus;
 
        /* Mac mini hack -- use the same DDC as the analog connector */
@@ -161,22 +162,22 @@ struct intel_sdvo_priv {
 };
 
 static bool
-intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags);
+intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags);
 
 /**
  * Writes the SDVOB or SDVOC with the given value, but always writes both
  * SDVOB and SDVOC to work around apparent hardware issues (according to
  * comments in the BIOS).
  */
-static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)
+static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val)
 {
-       struct drm_device *dev = intel_output->base.dev;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_sdvo_priv   *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv   *sdvo_priv = intel_encoder->dev_priv;
        u32 bval = val, cval = val;
        int i;
 
-       if (sdvo_priv->output_device == SDVOB) {
+       if (sdvo_priv->sdvo_reg == SDVOB) {
                cval = I915_READ(SDVOC);
        } else {
                bval = I915_READ(SDVOB);
@@ -195,10 +196,10 @@ static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)
        }
 }
 
-static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
+static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr,
                                 u8 *ch)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        u8 out_buf[2];
        u8 buf[2];
        int ret;
@@ -221,7 +222,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
        out_buf[0] = addr;
        out_buf[1] = 0;
 
-       if ((ret = i2c_transfer(intel_output->i2c_bus, msgs, 2)) == 2)
+       if ((ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 2)) == 2)
        {
                *ch = buf[0];
                return true;
@@ -231,10 +232,10 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
        return false;
 }
 
-static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
+static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr,
                                  u8 ch)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        u8 out_buf[2];
        struct i2c_msg msgs[] = {
                {
@@ -248,7 +249,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
        out_buf[0] = addr;
        out_buf[1] = ch;
 
-       if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1)
+       if (i2c_transfer(intel_encoder->i2c_bus, msgs, 1) == 1)
        {
                return true;
        }
@@ -352,13 +353,13 @@ static const struct _sdvo_cmd_name {
     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA),
 };
 
-#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
-#define SDVO_PRIV(output)   ((struct intel_sdvo_priv *) (output)->dev_priv)
+#define SDVO_NAME(dev_priv) ((dev_priv)->sdvo_reg == SDVOB ? "SDVOB" : "SDVOC")
+#define SDVO_PRIV(encoder)   ((struct intel_sdvo_priv *) (encoder)->dev_priv)
 
-static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
+static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd,
                                   void *args, int args_len)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int i;
 
        DRM_DEBUG_KMS("%s: W: %02X ",
@@ -378,19 +379,19 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
        DRM_LOG_KMS("\n");
 }
 
-static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd,
+static void intel_sdvo_write_cmd(struct intel_encoder *intel_encoder, u8 cmd,
                                 void *args, int args_len)
 {
        int i;
 
-       intel_sdvo_debug_write(intel_output, cmd, args, args_len);
+       intel_sdvo_debug_write(intel_encoder, cmd, args, args_len);
 
        for (i = 0; i < args_len; i++) {
-               intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0 - i,
+               intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0 - i,
                                      ((u8*)args)[i]);
        }
 
-       intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd);
+       intel_sdvo_write_byte(intel_encoder, SDVO_I2C_OPCODE, cmd);
 }
 
 static const char *cmd_status_names[] = {
@@ -403,11 +404,11 @@ static const char *cmd_status_names[] = {
        "Scaling not supported"
 };
 
-static void intel_sdvo_debug_response(struct intel_output *intel_output,
+static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder,
                                      void *response, int response_len,
                                      u8 status)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int i;
 
        DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv));
@@ -422,7 +423,7 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output,
        DRM_LOG_KMS("\n");
 }
 
-static u8 intel_sdvo_read_response(struct intel_output *intel_output,
+static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder,
                                   void *response, int response_len)
 {
        int i;
@@ -432,16 +433,16 @@ static u8 intel_sdvo_read_response(struct intel_output *intel_output,
        while (retry--) {
                /* Read the command response */
                for (i = 0; i < response_len; i++) {
-                       intel_sdvo_read_byte(intel_output,
+                       intel_sdvo_read_byte(intel_encoder,
                                             SDVO_I2C_RETURN_0 + i,
                                             &((u8 *)response)[i]);
                }
 
                /* read the return status */
-               intel_sdvo_read_byte(intel_output, SDVO_I2C_CMD_STATUS,
+               intel_sdvo_read_byte(intel_encoder, SDVO_I2C_CMD_STATUS,
                                     &status);
 
-               intel_sdvo_debug_response(intel_output, response, response_len,
+               intel_sdvo_debug_response(intel_encoder, response, response_len,
                                          status);
                if (status != SDVO_CMD_STATUS_PENDING)
                        return status;
@@ -469,10 +470,10 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
  * another I2C transaction after issuing the DDC bus switch, it will be
  * switched to the internal SDVO register.
  */
-static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
+static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encoder,
                                              u8 target)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        u8 out_buf[2], cmd_buf[2], ret_value[2], ret;
        struct i2c_msg msgs[] = {
                {
@@ -496,10 +497,10 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
                },
        };
 
-       intel_sdvo_debug_write(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
+       intel_sdvo_debug_write(intel_encoder, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
                                        &target, 1);
        /* write the DDC switch command argument */
-       intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0, target);
+       intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0, target);
 
        out_buf[0] = SDVO_I2C_OPCODE;
        out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH;
@@ -508,7 +509,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
        ret_value[0] = 0;
        ret_value[1] = 0;
 
-       ret = i2c_transfer(intel_output->i2c_bus, msgs, 3);
+       ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 3);
        if (ret != 3) {
                /* failure in I2C transfer */
                DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
@@ -522,7 +523,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
        return;
 }
 
-static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1)
+static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, bool target_0, bool target_1)
 {
        struct intel_sdvo_set_target_input_args targets = {0};
        u8 status;
@@ -533,10 +534,10 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool
        if (target_1)
                targets.target_1 = 1;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_INPUT, &targets,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_INPUT, &targets,
                             sizeof(targets));
 
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
@@ -547,13 +548,13 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool
  * This function is making an assumption about the layout of the response,
  * which should be checked against the docs.
  */
-static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, bool *input_1, bool *input_2)
+static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, bool *input_1, bool *input_2)
 {
        struct intel_sdvo_get_trained_inputs_response response;
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &response, sizeof(response));
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, &response, sizeof(response));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
@@ -562,29 +563,29 @@ static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, boo
        return true;
 }
 
-static bool intel_sdvo_get_active_outputs(struct intel_output *intel_output,
+static bool intel_sdvo_get_active_outputs(struct intel_encoder *intel_encoder,
                                          u16 *outputs)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, outputs, sizeof(*outputs));
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, outputs, sizeof(*outputs));
 
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_set_active_outputs(struct intel_output *intel_output,
+static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder,
                                          u16 outputs)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
                             sizeof(outputs));
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output,
+static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encoder,
                                               int mode)
 {
        u8 status, state = SDVO_ENCODER_STATE_ON;
@@ -604,24 +605,24 @@ static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output
                break;
        }
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
                             sizeof(state));
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_output,
+static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_encoder,
                                                   int *clock_min,
                                                   int *clock_max)
 {
        struct intel_sdvo_pixel_clock_range clocks;
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
                             NULL, 0);
 
-       status = intel_sdvo_read_response(intel_output, &clocks, sizeof(clocks));
+       status = intel_sdvo_read_response(intel_encoder, &clocks, sizeof(clocks));
 
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
@@ -633,31 +634,31 @@ static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_ou
        return true;
 }
 
-static bool intel_sdvo_set_target_output(struct intel_output *intel_output,
+static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder,
                                         u16 outputs)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
                             sizeof(outputs));
 
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,
+static bool intel_sdvo_get_timing(struct intel_encoder *intel_encoder, u8 cmd,
                                  struct intel_sdvo_dtd *dtd)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, cmd, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &dtd->part1,
+       intel_sdvo_write_cmd(intel_encoder, cmd, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, &dtd->part1,
                                          sizeof(dtd->part1));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
-       intel_sdvo_write_cmd(intel_output, cmd + 1, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &dtd->part2,
+       intel_sdvo_write_cmd(intel_encoder, cmd + 1, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, &dtd->part2,
                                          sizeof(dtd->part2));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
@@ -665,60 +666,60 @@ static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,
        return true;
 }
 
-static bool intel_sdvo_get_input_timing(struct intel_output *intel_output,
+static bool intel_sdvo_get_input_timing(struct intel_encoder *intel_encoder,
                                         struct intel_sdvo_dtd *dtd)
 {
-       return intel_sdvo_get_timing(intel_output,
+       return intel_sdvo_get_timing(intel_encoder,
                                     SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
 }
 
-static bool intel_sdvo_get_output_timing(struct intel_output *intel_output,
+static bool intel_sdvo_get_output_timing(struct intel_encoder *intel_encoder,
                                         struct intel_sdvo_dtd *dtd)
 {
-       return intel_sdvo_get_timing(intel_output,
+       return intel_sdvo_get_timing(intel_encoder,
                                     SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd);
 }
 
-static bool intel_sdvo_set_timing(struct intel_output *intel_output, u8 cmd,
+static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd,
                                  struct intel_sdvo_dtd *dtd)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, cmd, &dtd->part1, sizeof(dtd->part1));
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       intel_sdvo_write_cmd(intel_encoder, cmd, &dtd->part1, sizeof(dtd->part1));
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
-       intel_sdvo_write_cmd(intel_output, cmd + 1, &dtd->part2, sizeof(dtd->part2));
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       intel_sdvo_write_cmd(intel_encoder, cmd + 1, &dtd->part2, sizeof(dtd->part2));
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
        return true;
 }
 
-static bool intel_sdvo_set_input_timing(struct intel_output *intel_output,
+static bool intel_sdvo_set_input_timing(struct intel_encoder *intel_encoder,
                                         struct intel_sdvo_dtd *dtd)
 {
-       return intel_sdvo_set_timing(intel_output,
+       return intel_sdvo_set_timing(intel_encoder,
                                     SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
 }
 
-static bool intel_sdvo_set_output_timing(struct intel_output *intel_output,
+static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder,
                                         struct intel_sdvo_dtd *dtd)
 {
-       return intel_sdvo_set_timing(intel_output,
+       return intel_sdvo_set_timing(intel_encoder,
                                     SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
 }
 
 static bool
-intel_sdvo_create_preferred_input_timing(struct intel_output *output,
+intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder,
                                         uint16_t clock,
                                         uint16_t width,
                                         uint16_t height)
 {
        struct intel_sdvo_preferred_input_timing_args args;
-       struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        uint8_t status;
 
        memset(&args, 0, sizeof(args));
@@ -732,32 +733,33 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output,
            sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height))
                args.scaled = 1;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
+       intel_sdvo_write_cmd(intel_encoder,
+                            SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
                             &args, sizeof(args));
-       status = intel_sdvo_read_response(output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
        return true;
 }
 
-static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output,
+static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_encoder,
                                                  struct intel_sdvo_dtd *dtd)
 {
        bool status;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
                             NULL, 0);
 
-       status = intel_sdvo_read_response(output, &dtd->part1,
+       status = intel_sdvo_read_response(intel_encoder, &dtd->part1,
                                          sizeof(dtd->part1));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
                             NULL, 0);
 
-       status = intel_sdvo_read_response(output, &dtd->part2,
+       status = intel_sdvo_read_response(intel_encoder, &dtd->part2,
                                          sizeof(dtd->part2));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
@@ -765,12 +767,12 @@ static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output,
        return false;
 }
 
-static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
+static int intel_sdvo_get_clock_rate_mult(struct intel_encoder *intel_encoder)
 {
        u8 response, status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &response, 1);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, &response, 1);
 
        if (status != SDVO_CMD_STATUS_SUCCESS) {
                DRM_DEBUG_KMS("Couldn't get SDVO clock rate multiplier\n");
@@ -782,12 +784,12 @@ static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
        return response;
 }
 
-static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 val)
+static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
@@ -876,13 +878,13 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
                mode->flags |= DRM_MODE_FLAG_PVSYNC;
 }
 
-static bool intel_sdvo_get_supp_encode(struct intel_output *output,
+static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder,
                                       struct intel_sdvo_encode *encode)
 {
        uint8_t status;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
-       status = intel_sdvo_read_response(output, encode, sizeof(*encode));
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, encode, sizeof(*encode));
        if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */
                memset(encode, 0, sizeof(*encode));
                return false;
@@ -891,29 +893,30 @@ static bool intel_sdvo_get_supp_encode(struct intel_output *output,
        return true;
 }
 
-static bool intel_sdvo_set_encode(struct intel_output *output, uint8_t mode)
+static bool intel_sdvo_set_encode(struct intel_encoder *intel_encoder,
+                                 uint8_t mode)
 {
        uint8_t status;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1);
-       status = intel_sdvo_read_response(output, NULL, 0);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODE, &mode, 1);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_set_colorimetry(struct intel_output *output,
+static bool intel_sdvo_set_colorimetry(struct intel_encoder *intel_encoder,
                                       uint8_t mode)
 {
        uint8_t status;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
-       status = intel_sdvo_read_response(output, NULL, 0);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
 #if 0
-static void intel_sdvo_dump_hdmi_buf(struct intel_output *output)
+static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder)
 {
        int i, j;
        uint8_t set_buf_index[2];
@@ -922,43 +925,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_output *output)
        uint8_t buf[48];
        uint8_t *pos;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0);
-       intel_sdvo_read_response(output, &av_split, 1);
+       intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0);
+       intel_sdvo_read_response(encoder, &av_split, 1);
 
        for (i = 0; i <= av_split; i++) {
                set_buf_index[0] = i; set_buf_index[1] = 0;
-               intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX,
+               intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_INDEX,
                                     set_buf_index, 2);
-               intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
-               intel_sdvo_read_response(output, &buf_size, 1);
+               intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
+               intel_sdvo_read_response(encoder, &buf_size, 1);
 
                pos = buf;
                for (j = 0; j <= buf_size; j += 8) {
-                       intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA,
+                       intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_DATA,
                                             NULL, 0);
-                       intel_sdvo_read_response(output, pos, 8);
+                       intel_sdvo_read_response(encoder, pos, 8);
                        pos += 8;
                }
        }
 }
 #endif
 
-static void intel_sdvo_set_hdmi_buf(struct intel_output *output, int index,
-                               uint8_t *data, int8_t size, uint8_t tx_rate)
+static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder,
+                                   int index,
+                                   uint8_t *data, int8_t size, uint8_t tx_rate)
 {
     uint8_t set_buf_index[2];
 
     set_buf_index[0] = index;
     set_buf_index[1] = 0;
 
-    intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2);
+    intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_INDEX,
+                        set_buf_index, 2);
 
     for (; size > 0; size -= 8) {
-       intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_DATA, data, 8);
        data += 8;
     }
 
-    intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
+    intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
 }
 
 static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size)
@@ -1033,7 +1038,7 @@ struct dip_infoframe {
        } __attribute__ ((packed)) u;
 } __attribute__((packed));
 
-static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
+static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder,
                                         struct drm_display_mode * mode)
 {
        struct dip_infoframe avi_if = {
@@ -1044,15 +1049,16 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
 
        avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if,
                                                    4 + avi_if.len);
-       intel_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len,
+       intel_sdvo_set_hdmi_buf(intel_encoder, 1, (uint8_t *)&avi_if,
+                               4 + avi_if.len,
                                SDVO_HBUF_TX_VSYNC);
 }
 
-static void intel_sdvo_set_tv_format(struct intel_output *output)
+static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder)
 {
 
        struct intel_sdvo_tv_format format;
-       struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        uint32_t format_map, i;
        uint8_t status;
 
@@ -1065,10 +1071,10 @@ static void intel_sdvo_set_tv_format(struct intel_output *output)
        memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ?
                        sizeof(format) : sizeof(format_map));
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format_map,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format_map,
                             sizeof(format));
 
-       status = intel_sdvo_read_response(output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        if (status != SDVO_CMD_STATUS_SUCCESS)
                DRM_DEBUG_KMS("%s: Failed to set TV format\n",
                          SDVO_NAME(sdvo_priv));
@@ -1078,8 +1084,8 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
                                  struct drm_display_mode *mode,
                                  struct drm_display_mode *adjusted_mode)
 {
-       struct intel_output *output = enc_to_intel_output(encoder);
-       struct intel_sdvo_priv *dev_priv = output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_sdvo_priv *dev_priv = intel_encoder->dev_priv;
 
        if (dev_priv->is_tv) {
                struct intel_sdvo_dtd output_dtd;
@@ -1094,22 +1100,22 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
 
                /* Set output timings */
                intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
-               intel_sdvo_set_target_output(output,
+               intel_sdvo_set_target_output(intel_encoder,
                                             dev_priv->controlled_output);
-               intel_sdvo_set_output_timing(output, &output_dtd);
+               intel_sdvo_set_output_timing(intel_encoder, &output_dtd);
 
                /* Set the input timing to the screen. Assume always input 0. */
-               intel_sdvo_set_target_input(output, true, false);
+               intel_sdvo_set_target_input(intel_encoder, true, false);
 
 
-               success = intel_sdvo_create_preferred_input_timing(output,
+               success = intel_sdvo_create_preferred_input_timing(intel_encoder,
                                                                   mode->clock / 10,
                                                                   mode->hdisplay,
                                                                   mode->vdisplay);
                if (success) {
                        struct intel_sdvo_dtd input_dtd;
 
-                       intel_sdvo_get_preferred_input_timing(output,
+                       intel_sdvo_get_preferred_input_timing(intel_encoder,
                                                             &input_dtd);
                        intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
                        dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
@@ -1132,16 +1138,16 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
                intel_sdvo_get_dtd_from_mode(&output_dtd,
                                dev_priv->sdvo_lvds_fixed_mode);
 
-               intel_sdvo_set_target_output(output,
+               intel_sdvo_set_target_output(intel_encoder,
                                             dev_priv->controlled_output);
-               intel_sdvo_set_output_timing(output, &output_dtd);
+               intel_sdvo_set_output_timing(intel_encoder, &output_dtd);
 
                /* Set the input timing to the screen. Assume always input 0. */
-               intel_sdvo_set_target_input(output, true, false);
+               intel_sdvo_set_target_input(intel_encoder, true, false);
 
 
                success = intel_sdvo_create_preferred_input_timing(
-                               output,
+                               intel_encoder,
                                mode->clock / 10,
                                mode->hdisplay,
                                mode->vdisplay);
@@ -1149,7 +1155,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
                if (success) {
                        struct intel_sdvo_dtd input_dtd;
 
-                       intel_sdvo_get_preferred_input_timing(output,
+                       intel_sdvo_get_preferred_input_timing(intel_encoder,
                                                             &input_dtd);
                        intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
                        dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
@@ -1181,8 +1187,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc = encoder->crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_output *output = enc_to_intel_output(encoder);
-       struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        u32 sdvox = 0;
        int sdvo_pixel_multiply;
        struct intel_sdvo_in_out_map in_out;
@@ -1201,12 +1207,12 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
        in_out.in0 = sdvo_priv->controlled_output;
        in_out.in1 = 0;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP,
                             &in_out, sizeof(in_out));
-       status = intel_sdvo_read_response(output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
        if (sdvo_priv->is_hdmi) {
-               intel_sdvo_set_avi_infoframe(output, mode);
+               intel_sdvo_set_avi_infoframe(intel_encoder, mode);
                sdvox |= SDVO_AUDIO_ENABLE;
        }
 
@@ -1223,16 +1229,16 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
         */
        if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) {
                /* Set the output timing to the screen */
-               intel_sdvo_set_target_output(output,
+               intel_sdvo_set_target_output(intel_encoder,
                                             sdvo_priv->controlled_output);
-               intel_sdvo_set_output_timing(output, &input_dtd);
+               intel_sdvo_set_output_timing(intel_encoder, &input_dtd);
        }
 
        /* Set the input timing to the screen. Assume always input 0. */
-       intel_sdvo_set_target_input(output, true, false);
+       intel_sdvo_set_target_input(intel_encoder, true, false);
 
        if (sdvo_priv->is_tv)
-               intel_sdvo_set_tv_format(output);
+               intel_sdvo_set_tv_format(intel_encoder);
 
        /* We would like to use intel_sdvo_create_preferred_input_timing() to
         * provide the device with a timing it can support, if it supports that
@@ -1240,29 +1246,29 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
         * output the preferred timing, and we don't support that currently.
         */
 #if 0
-       success = intel_sdvo_create_preferred_input_timing(output, clock,
+       success = intel_sdvo_create_preferred_input_timing(encoder, clock,
                                                           width, height);
        if (success) {
                struct intel_sdvo_dtd *input_dtd;
 
-               intel_sdvo_get_preferred_input_timing(output, &input_dtd);
-               intel_sdvo_set_input_timing(output, &input_dtd);
+               intel_sdvo_get_preferred_input_timing(encoder, &input_dtd);
+               intel_sdvo_set_input_timing(encoder, &input_dtd);
        }
 #else
-       intel_sdvo_set_input_timing(output, &input_dtd);
+       intel_sdvo_set_input_timing(intel_encoder, &input_dtd);
 #endif
 
        switch (intel_sdvo_get_pixel_multiplier(mode)) {
        case 1:
-               intel_sdvo_set_clock_rate_mult(output,
+               intel_sdvo_set_clock_rate_mult(intel_encoder,
                                               SDVO_CLOCK_RATE_MULT_1X);
                break;
        case 2:
-               intel_sdvo_set_clock_rate_mult(output,
+               intel_sdvo_set_clock_rate_mult(intel_encoder,
                                               SDVO_CLOCK_RATE_MULT_2X);
                break;
        case 4:
-               intel_sdvo_set_clock_rate_mult(output,
+               intel_sdvo_set_clock_rate_mult(intel_encoder,
                                               SDVO_CLOCK_RATE_MULT_4X);
                break;
        }
@@ -1273,8 +1279,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
                        SDVO_VSYNC_ACTIVE_HIGH |
                        SDVO_HSYNC_ACTIVE_HIGH;
        } else {
-               sdvox |= I915_READ(sdvo_priv->output_device);
-               switch (sdvo_priv->output_device) {
+               sdvox |= I915_READ(sdvo_priv->sdvo_reg);
+               switch (sdvo_priv->sdvo_reg) {
                case SDVOB:
                        sdvox &= SDVOB_PRESERVE_MASK;
                        break;
@@ -1298,26 +1304,26 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
 
        if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL)
                sdvox |= SDVO_STALL_SELECT;
-       intel_sdvo_write_sdvox(output, sdvox);
+       intel_sdvo_write_sdvox(intel_encoder, sdvox);
 }
 
 static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
 {
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        u32 temp;
 
        if (mode != DRM_MODE_DPMS_ON) {
-               intel_sdvo_set_active_outputs(intel_output, 0);
+               intel_sdvo_set_active_outputs(intel_encoder, 0);
                if (0)
-                       intel_sdvo_set_encoder_power_state(intel_output, mode);
+                       intel_sdvo_set_encoder_power_state(intel_encoder, mode);
 
                if (mode == DRM_MODE_DPMS_OFF) {
-                       temp = I915_READ(sdvo_priv->output_device);
+                       temp = I915_READ(sdvo_priv->sdvo_reg);
                        if ((temp & SDVO_ENABLE) != 0) {
-                               intel_sdvo_write_sdvox(intel_output, temp & ~SDVO_ENABLE);
+                               intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE);
                        }
                }
        } else {
@@ -1325,13 +1331,13 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
                int i;
                u8 status;
 
-               temp = I915_READ(sdvo_priv->output_device);
+               temp = I915_READ(sdvo_priv->sdvo_reg);
                if ((temp & SDVO_ENABLE) == 0)
-                       intel_sdvo_write_sdvox(intel_output, temp | SDVO_ENABLE);
+                       intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE);
                for (i = 0; i < 2; i++)
                  intel_wait_for_vblank(dev);
 
-               status = intel_sdvo_get_trained_inputs(intel_output, &input1,
+               status = intel_sdvo_get_trained_inputs(intel_encoder, &input1,
                                                       &input2);
 
 
@@ -1345,8 +1351,8 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
                }
 
                if (0)
-                       intel_sdvo_set_encoder_power_state(intel_output, mode);
-               intel_sdvo_set_active_outputs(intel_output, sdvo_priv->controlled_output);
+                       intel_sdvo_set_encoder_power_state(intel_encoder, mode);
+               intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->controlled_output);
        }
        return;
 }
@@ -1355,22 +1361,22 @@ static void intel_sdvo_save(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int o;
 
-       sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_output);
-       intel_sdvo_get_active_outputs(intel_output, &sdvo_priv->save_active_outputs);
+       sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_encoder);
+       intel_sdvo_get_active_outputs(intel_encoder, &sdvo_priv->save_active_outputs);
 
        if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
-               intel_sdvo_set_target_input(intel_output, true, false);
-               intel_sdvo_get_input_timing(intel_output,
+               intel_sdvo_set_target_input(intel_encoder, true, false);
+               intel_sdvo_get_input_timing(intel_encoder,
                                            &sdvo_priv->save_input_dtd_1);
        }
 
        if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
-               intel_sdvo_set_target_input(intel_output, false, true);
-               intel_sdvo_get_input_timing(intel_output,
+               intel_sdvo_set_target_input(intel_encoder, false, true);
+               intel_sdvo_get_input_timing(intel_encoder,
                                            &sdvo_priv->save_input_dtd_2);
        }
 
@@ -1379,8 +1385,8 @@ static void intel_sdvo_save(struct drm_connector *connector)
                u16  this_output = (1 << o);
                if (sdvo_priv->caps.output_flags & this_output)
                {
-                       intel_sdvo_set_target_output(intel_output, this_output);
-                       intel_sdvo_get_output_timing(intel_output,
+                       intel_sdvo_set_target_output(intel_encoder, this_output);
+                       intel_sdvo_get_output_timing(intel_encoder,
                                                     &sdvo_priv->save_output_dtd[o]);
                }
        }
@@ -1388,66 +1394,66 @@ static void intel_sdvo_save(struct drm_connector *connector)
                /* XXX: Save TV format/enhancements. */
        }
 
-       sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device);
+       sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->sdvo_reg);
 }
 
 static void intel_sdvo_restore(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int o;
        int i;
        bool input1, input2;
        u8 status;
 
-       intel_sdvo_set_active_outputs(intel_output, 0);
+       intel_sdvo_set_active_outputs(intel_encoder, 0);
 
        for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
        {
                u16  this_output = (1 << o);
                if (sdvo_priv->caps.output_flags & this_output) {
-                       intel_sdvo_set_target_output(intel_output, this_output);
-                       intel_sdvo_set_output_timing(intel_output, &sdvo_priv->save_output_dtd[o]);
+                       intel_sdvo_set_target_output(intel_encoder, this_output);
+                       intel_sdvo_set_output_timing(intel_encoder, &sdvo_priv->save_output_dtd[o]);
                }
        }
 
        if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
-               intel_sdvo_set_target_input(intel_output, true, false);
-               intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_1);
+               intel_sdvo_set_target_input(intel_encoder, true, false);
+               intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_1);
        }
 
        if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
-               intel_sdvo_set_target_input(intel_output, false, true);
-               intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_2);
+               intel_sdvo_set_target_input(intel_encoder, false, true);
+               intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_2);
        }
 
-       intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult);
+       intel_sdvo_set_clock_rate_mult(intel_encoder, sdvo_priv->save_sdvo_mult);
 
        if (sdvo_priv->is_tv) {
                /* XXX: Restore TV format/enhancements. */
        }
 
-       intel_sdvo_write_sdvox(intel_output, sdvo_priv->save_SDVOX);
+       intel_sdvo_write_sdvox(intel_encoder, sdvo_priv->save_SDVOX);
 
        if (sdvo_priv->save_SDVOX & SDVO_ENABLE)
        {
                for (i = 0; i < 2; i++)
                        intel_wait_for_vblank(dev);
-               status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2);
+               status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, &input2);
                if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
                        DRM_DEBUG_KMS("First %s output reported failure to "
                                        "sync\n", SDVO_NAME(sdvo_priv));
        }
 
-       intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs);
+       intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->save_active_outputs);
 }
 
 static int intel_sdvo_mode_valid(struct drm_connector *connector,
                                 struct drm_display_mode *mode)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
                return MODE_NO_DBLESCAN;
@@ -1472,12 +1478,12 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector,
        return MODE_OK;
 }
 
-static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struct intel_sdvo_caps *caps)
+static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, struct intel_sdvo_caps *caps)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, caps, sizeof(*caps));
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, caps, sizeof(*caps));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
@@ -1487,22 +1493,22 @@ static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struc
 struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB)
 {
        struct drm_connector *connector = NULL;
-       struct intel_output *iout = NULL;
+       struct intel_encoder *iout = NULL;
        struct intel_sdvo_priv *sdvo;
 
        /* find the sdvo connector */
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               iout = to_intel_output(connector);
+               iout = to_intel_encoder(connector);
 
                if (iout->type != INTEL_OUTPUT_SDVO)
                        continue;
 
                sdvo = iout->dev_priv;
 
-               if (sdvo->output_device == SDVOB && sdvoB)
+               if (sdvo->sdvo_reg == SDVOB && sdvoB)
                        return connector;
 
-               if (sdvo->output_device == SDVOC && !sdvoB)
+               if (sdvo->sdvo_reg == SDVOC && !sdvoB)
                        return connector;
 
        }
@@ -1514,16 +1520,16 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector)
 {
        u8 response[2];
        u8 status;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        DRM_DEBUG_KMS("\n");
 
        if (!connector)
                return 0;
 
-       intel_output = to_intel_output(connector);
+       intel_encoder = to_intel_encoder(connector);
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &response, 2);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, &response, 2);
 
        if (response[0] !=0)
                return 1;
@@ -1535,30 +1541,30 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
 {
        u8 response[2];
        u8 status;
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
-       intel_sdvo_read_response(intel_output, &response, 2);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
+       intel_sdvo_read_response(intel_encoder, &response, 2);
 
        if (on) {
-               intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
-               status = intel_sdvo_read_response(intel_output, &response, 2);
+               intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
+               status = intel_sdvo_read_response(intel_encoder, &response, 2);
 
-               intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
+               intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
        } else {
                response[0] = 0;
                response[1] = 0;
-               intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
+               intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
        }
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
-       intel_sdvo_read_response(intel_output, &response, 2);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
+       intel_sdvo_read_response(intel_encoder, &response, 2);
 }
 
 static bool
-intel_sdvo_multifunc_encoder(struct intel_output *intel_output)
+intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int caps = 0;
 
        if (sdvo_priv->caps.output_flags &
@@ -1592,11 +1598,11 @@ static struct drm_connector *
 intel_find_analog_connector(struct drm_device *dev)
 {
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
 
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               intel_output = to_intel_output(connector);
-               if (intel_output->type == INTEL_OUTPUT_ANALOG)
+               intel_encoder = to_intel_encoder(connector);
+               if (intel_encoder->type == INTEL_OUTPUT_ANALOG)
                        return connector;
        }
        return NULL;
@@ -1621,16 +1627,16 @@ intel_analog_is_connected(struct drm_device *dev)
 enum drm_connector_status
 intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        enum drm_connector_status status = connector_status_connected;
        struct edid *edid = NULL;
 
-       edid = drm_get_edid(&intel_output->base,
-                           intel_output->ddc_bus);
+       edid = drm_get_edid(&intel_encoder->base,
+                           intel_encoder->ddc_bus);
 
        /* This is only applied to SDVO cards with multiple outputs */
-       if (edid == NULL && intel_sdvo_multifunc_encoder(intel_output)) {
+       if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) {
                uint8_t saved_ddc, temp_ddc;
                saved_ddc = sdvo_priv->ddc_bus;
                temp_ddc = sdvo_priv->ddc_bus >> 1;
@@ -1640,8 +1646,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
                 */
                while(temp_ddc > 1) {
                        sdvo_priv->ddc_bus = temp_ddc;
-                       edid = drm_get_edid(&intel_output->base,
-                               intel_output->ddc_bus);
+                       edid = drm_get_edid(&intel_encoder->base,
+                               intel_encoder->ddc_bus);
                        if (edid) {
                                /*
                                 * When we can get the EDID, maybe it is the
@@ -1660,8 +1666,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
         */
        if (edid == NULL &&
            sdvo_priv->analog_ddc_bus &&
-           !intel_analog_is_connected(intel_output->base.dev))
-               edid = drm_get_edid(&intel_output->base,
+           !intel_analog_is_connected(intel_encoder->base.dev))
+               edid = drm_get_edid(&intel_encoder->base,
                                    sdvo_priv->analog_ddc_bus);
        if (edid != NULL) {
                /* Don't report the output as connected if it's a DVI-I
@@ -1676,7 +1682,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
                }
 
                kfree(edid);
-               intel_output->base.display_info.raw_edid = NULL;
+               intel_encoder->base.display_info.raw_edid = NULL;
 
        } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
                status = connector_status_disconnected;
@@ -1688,16 +1694,16 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
 {
        uint16_t response;
        u8 status;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 
-       intel_sdvo_write_cmd(intel_output,
+       intel_sdvo_write_cmd(intel_encoder,
                             SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
        if (sdvo_priv->is_tv) {
                /* add 30ms delay when the output type is SDVO-TV */
                mdelay(30);
        }
-       status = intel_sdvo_read_response(intel_output, &response, 2);
+       status = intel_sdvo_read_response(intel_encoder, &response, 2);
 
        DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8);
 
@@ -1707,10 +1713,10 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
        if (response == 0)
                return connector_status_disconnected;
 
-       if (intel_sdvo_multifunc_encoder(intel_output) &&
+       if (intel_sdvo_multifunc_encoder(intel_encoder) &&
                sdvo_priv->attached_output != response) {
                if (sdvo_priv->controlled_output != response &&
-                       intel_sdvo_output_setup(intel_output, response) != true)
+                       intel_sdvo_output_setup(intel_encoder, response) != true)
                        return connector_status_unknown;
                sdvo_priv->attached_output = response;
        }
@@ -1719,12 +1725,12 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
 
 static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int num_modes;
 
        /* set the bus switch and get the modes */
-       num_modes = intel_ddc_get_modes(intel_output);
+       num_modes = intel_ddc_get_modes(intel_encoder);
 
        /*
         * Mac mini hack.  On this device, the DVI-I connector shares one DDC
@@ -1734,17 +1740,17 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
         */
        if (num_modes == 0 &&
            sdvo_priv->analog_ddc_bus &&
-           !intel_analog_is_connected(intel_output->base.dev)) {
+           !intel_analog_is_connected(intel_encoder->base.dev)) {
                struct i2c_adapter *digital_ddc_bus;
 
                /* Switch to the analog ddc bus and try that
                 */
-               digital_ddc_bus = intel_output->ddc_bus;
-               intel_output->ddc_bus = sdvo_priv->analog_ddc_bus;
+               digital_ddc_bus = intel_encoder->ddc_bus;
+               intel_encoder->ddc_bus = sdvo_priv->analog_ddc_bus;
 
-               (void) intel_ddc_get_modes(intel_output);
+               (void) intel_ddc_get_modes(intel_encoder);
 
-               intel_output->ddc_bus = digital_ddc_bus;
+               intel_encoder->ddc_bus = digital_ddc_bus;
        }
 }
 
@@ -1815,7 +1821,7 @@ struct drm_display_mode sdvo_tv_modes[] = {
 
 static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
 {
-       struct intel_output *output = to_intel_output(connector);
+       struct intel_encoder *output = to_intel_encoder(connector);
        struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
        struct intel_sdvo_sdtv_resolution_request tv_res;
        uint32_t reply = 0, format_map = 0;
@@ -1857,9 +1863,9 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
 
 static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
        struct drm_i915_private *dev_priv = connector->dev->dev_private;
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        struct drm_display_mode *newmode;
 
        /*
@@ -1867,7 +1873,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
         * Assume that the preferred modes are
         * arranged in priority order.
         */
-       intel_ddc_get_modes(intel_output);
+       intel_ddc_get_modes(intel_encoder);
        if (list_empty(&connector->probed_modes) == false)
                goto end;
 
@@ -1896,7 +1902,7 @@ end:
 
 static int intel_sdvo_get_modes(struct drm_connector *connector)
 {
-       struct intel_output *output = to_intel_output(connector);
+       struct intel_encoder *output = to_intel_encoder(connector);
        struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
 
        if (sdvo_priv->is_tv)
@@ -1914,8 +1920,8 @@ static int intel_sdvo_get_modes(struct drm_connector *connector)
 static
 void intel_sdvo_destroy_enhance_property(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        struct drm_device *dev = connector->dev;
 
        if (sdvo_priv->is_tv) {
@@ -1952,13 +1958,13 @@ void intel_sdvo_destroy_enhance_property(struct drm_connector *connector)
 
 static void intel_sdvo_destroy(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 
-       if (intel_output->i2c_bus)
-               intel_i2c_destroy(intel_output->i2c_bus);
-       if (intel_output->ddc_bus)
-               intel_i2c_destroy(intel_output->ddc_bus);
+       if (intel_encoder->i2c_bus)
+               intel_i2c_destroy(intel_encoder->i2c_bus);
+       if (intel_encoder->ddc_bus)
+               intel_i2c_destroy(intel_encoder->ddc_bus);
        if (sdvo_priv->analog_ddc_bus)
                intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
 
@@ -1976,7 +1982,7 @@ static void intel_sdvo_destroy(struct drm_connector *connector)
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
 
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
 
 static int
@@ -1984,9 +1990,9 @@ intel_sdvo_set_property(struct drm_connector *connector,
                        struct drm_property *property,
                        uint64_t val)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_crtc *crtc = encoder->crtc;
        int ret = 0;
        bool changed = false;
@@ -2094,8 +2100,8 @@ intel_sdvo_set_property(struct drm_connector *connector,
                        sdvo_priv->cur_brightness = temp_value;
                }
                if (cmd) {
-                       intel_sdvo_write_cmd(intel_output, cmd, &temp_value, 2);
-                       status = intel_sdvo_read_response(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2);
+                       status = intel_sdvo_read_response(intel_encoder,
                                                                NULL, 0);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO command \n");
@@ -2190,7 +2196,7 @@ intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv)
 }
 
 static bool
-intel_sdvo_get_digital_encoding_mode(struct intel_output *output)
+intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output)
 {
        struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
        uint8_t status;
@@ -2204,42 +2210,42 @@ intel_sdvo_get_digital_encoding_mode(struct intel_output *output)
        return true;
 }
 
-static struct intel_output *
-intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan)
+static struct intel_encoder *
+intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan)
 {
        struct drm_device *dev = chan->drm_dev;
        struct drm_connector *connector;
-       struct intel_output *intel_output = NULL;
+       struct intel_encoder *intel_encoder = NULL;
 
        list_for_each_entry(connector,
                        &dev->mode_config.connector_list, head) {
-               if (to_intel_output(connector)->ddc_bus == &chan->adapter) {
-                       intel_output = to_intel_output(connector);
+               if (to_intel_encoder(connector)->ddc_bus == &chan->adapter) {
+                       intel_encoder = to_intel_encoder(connector);
                        break;
                }
        }
-       return intel_output;
+       return intel_encoder;
 }
 
 static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap,
                                  struct i2c_msg msgs[], int num)
 {
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_sdvo_priv *sdvo_priv;
        struct i2c_algo_bit_data *algo_data;
        const struct i2c_algorithm *algo;
 
        algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data;
-       intel_output =
-               intel_sdvo_chan_to_intel_output(
+       intel_encoder =
+               intel_sdvo_chan_to_intel_encoder(
                                (struct intel_i2c_chan *)(algo_data->data));
-       if (intel_output == NULL)
+       if (intel_encoder == NULL)
                return -EINVAL;
 
-       sdvo_priv = intel_output->dev_priv;
-       algo = intel_output->i2c_bus->algo;
+       sdvo_priv = intel_encoder->dev_priv;
+       algo = intel_encoder->i2c_bus->algo;
 
-       intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
+       intel_sdvo_set_control_bus_switch(intel_encoder, sdvo_priv->ddc_bus);
        return algo->master_xfer(i2c_adap, msgs, num);
 }
 
@@ -2248,12 +2254,12 @@ static struct i2c_algorithm intel_sdvo_i2c_bit_algo = {
 };
 
 static u8
-intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device)
+intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct sdvo_device_mapping *my_mapping, *other_mapping;
 
-       if (output_device == SDVOB) {
+       if (sdvo_reg == SDVOB) {
                my_mapping = &dev_priv->sdvo_mappings[0];
                other_mapping = &dev_priv->sdvo_mappings[1];
        } else {
@@ -2278,7 +2284,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device)
        /* No SDVO device info is found for another DVO port,
         * so use mapping assumption we had before BIOS parsing.
         */
-       if (output_device == SDVOB)
+       if (sdvo_reg == SDVOB)
                return 0x70;
        else
                return 0x72;
@@ -2304,15 +2310,15 @@ static struct dmi_system_id intel_sdvo_bad_tv[] = {
 };
 
 static bool
-intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
+intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags)
 {
-       struct drm_connector *connector = &intel_output->base;
-       struct drm_encoder *encoder = &intel_output->enc;
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct drm_connector *connector = &intel_encoder->base;
+       struct drm_encoder *encoder = &intel_encoder->enc;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        bool ret = true, registered = false;
 
        sdvo_priv->is_tv = false;
-       intel_output->needs_tv_clock = false;
+       intel_encoder->needs_tv_clock = false;
        sdvo_priv->is_lvds = false;
 
        if (device_is_registered(&connector->kdev)) {
@@ -2330,16 +2336,16 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
                connector->connector_type = DRM_MODE_CONNECTOR_DVID;
 
-               if (intel_sdvo_get_supp_encode(intel_output,
+               if (intel_sdvo_get_supp_encode(intel_encoder,
                                               &sdvo_priv->encode) &&
-                   intel_sdvo_get_digital_encoding_mode(intel_output) &&
+                   intel_sdvo_get_digital_encoding_mode(intel_encoder) &&
                    sdvo_priv->is_hdmi) {
                        /* enable hdmi encoding mode if supported */
-                       intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI);
-                       intel_sdvo_set_colorimetry(intel_output,
+                       intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI);
+                       intel_sdvo_set_colorimetry(intel_encoder,
                                                   SDVO_COLORIMETRY_RGB256);
                        connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
-                       intel_output->clone_mask =
+                       intel_encoder->clone_mask =
                                        (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
                                        (1 << INTEL_ANALOG_CLONE_BIT);
                }
@@ -2350,21 +2356,21 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
                connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
                sdvo_priv->is_tv = true;
-               intel_output->needs_tv_clock = true;
-               intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
+               intel_encoder->needs_tv_clock = true;
+               intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
        } else if (flags & SDVO_OUTPUT_RGB0) {
 
                sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
                encoder->encoder_type = DRM_MODE_ENCODER_DAC;
                connector->connector_type = DRM_MODE_CONNECTOR_VGA;
-               intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+               intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
                                        (1 << INTEL_ANALOG_CLONE_BIT);
        } else if (flags & SDVO_OUTPUT_RGB1) {
 
                sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
                encoder->encoder_type = DRM_MODE_ENCODER_DAC;
                connector->connector_type = DRM_MODE_CONNECTOR_VGA;
-               intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+               intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
                                        (1 << INTEL_ANALOG_CLONE_BIT);
        } else if (flags & SDVO_OUTPUT_CVBS0) {
 
@@ -2372,15 +2378,15 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
                connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
                sdvo_priv->is_tv = true;
-               intel_output->needs_tv_clock = true;
-               intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
+               intel_encoder->needs_tv_clock = true;
+               intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
        } else if (flags & SDVO_OUTPUT_LVDS0) {
 
                sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;
                encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
                connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
                sdvo_priv->is_lvds = true;
-               intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
+               intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
                                        (1 << INTEL_SDVO_LVDS_CLONE_BIT);
        } else if (flags & SDVO_OUTPUT_LVDS1) {
 
@@ -2388,7 +2394,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
                connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
                sdvo_priv->is_lvds = true;
-               intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
+               intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
                                        (1 << INTEL_SDVO_LVDS_CLONE_BIT);
        } else {
 
@@ -2401,7 +2407,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                              bytes[0], bytes[1]);
                ret = false;
        }
-       intel_output->crtc_mask = (1 << 0) | (1 << 1);
+       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
 
        if (ret && registered)
                ret = drm_sysfs_connector_add(connector) == 0 ? true : false;
@@ -2413,18 +2419,18 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
 
 static void intel_sdvo_tv_create_property(struct drm_connector *connector)
 {
-      struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+      struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        struct intel_sdvo_tv_format format;
        uint32_t format_map, i;
        uint8_t status;
 
-       intel_sdvo_set_target_output(intel_output,
+       intel_sdvo_set_target_output(intel_encoder,
                                     sdvo_priv->controlled_output);
 
-       intel_sdvo_write_cmd(intel_output,
+       intel_sdvo_write_cmd(intel_encoder,
                             SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0);
-       status = intel_sdvo_read_response(intel_output,
+       status = intel_sdvo_read_response(intel_encoder,
                                          &format, sizeof(format));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return;
@@ -2462,16 +2468,16 @@ static void intel_sdvo_tv_create_property(struct drm_connector *connector)
 
 static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        struct intel_sdvo_enhancements_reply sdvo_data;
        struct drm_device *dev = connector->dev;
        uint8_t status;
        uint16_t response, data_value[2];
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
                                                NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &sdvo_data,
+       status = intel_sdvo_read_response(intel_encoder, &sdvo_data,
                                        sizeof(sdvo_data));
        if (status != SDVO_CMD_STATUS_SUCCESS) {
                DRM_DEBUG_KMS(" incorrect response is returned\n");
@@ -2487,18 +2493,18 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                 * property
                 */
                if (sdvo_data.overscan_h) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO max "
                                                "h_overscan\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_OVERSCAN_H, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n");
@@ -2528,18 +2534,18 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                                        data_value[0], data_value[1], response);
                }
                if (sdvo_data.overscan_v) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO max "
                                                "v_overscan\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_OVERSCAN_V, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n");
@@ -2569,17 +2575,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                                        data_value[0], data_value[1], response);
                }
                if (sdvo_data.position_h) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_POSITION_H, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_POSITION_H, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n");
@@ -2600,17 +2606,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                                        data_value[0], data_value[1], response);
                }
                if (sdvo_data.position_v) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_POSITION_V, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_POSITION_V, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n");
@@ -2633,17 +2639,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
        }
        if (sdvo_priv->is_tv) {
                if (sdvo_data.saturation) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_SATURATION, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max sat\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_SATURATION, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get sat\n");
@@ -2665,17 +2671,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                                        data_value[0], data_value[1], response);
                }
                if (sdvo_data.contrast) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_CONTRAST, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_CONTRAST, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get contrast\n");
@@ -2696,17 +2702,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                                        data_value[0], data_value[1], response);
                }
                if (sdvo_data.hue) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_HUE, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max hue\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_HUE, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get hue\n");
@@ -2729,17 +2735,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
        }
        if (sdvo_priv->is_tv || sdvo_priv->is_lvds) {
                if (sdvo_data.brightness) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max bright\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_BRIGHTNESS, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get brigh\n");
@@ -2764,81 +2770,81 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
        return;
 }
 
-bool intel_sdvo_init(struct drm_device *dev, int output_device)
+bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_sdvo_priv *sdvo_priv;
 
        u8 ch[0x40];
        int i;
 
-       intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
-       if (!intel_output) {
+       intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
+       if (!intel_encoder) {
                return false;
        }
 
-       sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
-       sdvo_priv->output_device = output_device;
+       sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1);
+       sdvo_priv->sdvo_reg = sdvo_reg;
 
-       intel_output->dev_priv = sdvo_priv;
-       intel_output->type = INTEL_OUTPUT_SDVO;
+       intel_encoder->dev_priv = sdvo_priv;
+       intel_encoder->type = INTEL_OUTPUT_SDVO;
 
        /* setup the DDC bus. */
-       if (output_device == SDVOB)
-               intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
+       if (sdvo_reg == SDVOB)
+               intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
        else
-               intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
+               intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
 
-       if (!intel_output->i2c_bus)
+       if (!intel_encoder->i2c_bus)
                goto err_inteloutput;
 
-       sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device);
+       sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg);
 
        /* Save the bit-banging i2c functionality for use by the DDC wrapper */
-       intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality;
+       intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality;
 
        /* Read the regs to test if we can talk to the device */
        for (i = 0; i < 0x40; i++) {
-               if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) {
+               if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) {
                        DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n",
-                                       output_device == SDVOB ? 'B' : 'C');
+                                       sdvo_reg == SDVOB ? 'B' : 'C');
                        goto err_i2c;
                }
        }
 
        /* setup the DDC bus. */
-       if (output_device == SDVOB) {
-               intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
+       if (sdvo_reg == SDVOB) {
+               intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
                sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
                                                "SDVOB/VGA DDC BUS");
                dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS;
        } else {
-               intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
+               intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
                sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
                                                "SDVOC/VGA DDC BUS");
                dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS;
        }
 
-       if (intel_output->ddc_bus == NULL)
+       if (intel_encoder->ddc_bus == NULL)
                goto err_i2c;
 
        /* Wrap with our custom algo which switches to DDC mode */
-       intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
+       intel_encoder->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
 
        /* In default case sdvo lvds is false */
-       intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
+       intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps);
 
-       if (intel_sdvo_output_setup(intel_output,
+       if (intel_sdvo_output_setup(intel_encoder,
                                    sdvo_priv->caps.output_flags) != true) {
                DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
-                         output_device == SDVOB ? 'B' : 'C');
+                         sdvo_reg == SDVOB ? 'B' : 'C');
                goto err_i2c;
        }
 
 
-       connector = &intel_output->base;
+       connector = &intel_encoder->base;
        drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
                           connector->connector_type);
 
@@ -2847,12 +2853,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
        connector->doublescan_allowed = 0;
        connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 
-       drm_encoder_init(dev, &intel_output->enc,
-                       &intel_sdvo_enc_funcs, intel_output->enc.encoder_type);
+       drm_encoder_init(dev, &intel_encoder->enc,
+                       &intel_sdvo_enc_funcs, intel_encoder->enc.encoder_type);
 
-       drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
+       drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs);
 
-       drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
+       drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc);
        if (sdvo_priv->is_tv)
                intel_sdvo_tv_create_property(connector);
 
@@ -2864,9 +2870,9 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
        intel_sdvo_select_ddc_bus(sdvo_priv);
 
        /* Set the input timing to the screen. Assume always input 0. */
-       intel_sdvo_set_target_input(intel_output, true, false);
+       intel_sdvo_set_target_input(intel_encoder, true, false);
 
-       intel_sdvo_get_input_pixel_clock_range(intel_output,
+       intel_sdvo_get_input_pixel_clock_range(intel_encoder,
                                               &sdvo_priv->pixel_clock_min,
                                               &sdvo_priv->pixel_clock_max);
 
@@ -2893,12 +2899,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 err_i2c:
        if (sdvo_priv->analog_ddc_bus != NULL)
                intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
-       if (intel_output->ddc_bus != NULL)
-               intel_i2c_destroy(intel_output->ddc_bus);
-       if (intel_output->i2c_bus != NULL)
-               intel_i2c_destroy(intel_output->i2c_bus);
+       if (intel_encoder->ddc_bus != NULL)
+               intel_i2c_destroy(intel_encoder->ddc_bus);
+       if (intel_encoder->i2c_bus != NULL)
+               intel_i2c_destroy(intel_encoder->i2c_bus);
 err_inteloutput:
-       kfree(intel_output);
+       kfree(intel_encoder);
 
        return false;
 }
index 552ec110b74197c2394058ef4c89b144bc3e3137..d7d39b2327df37bcb6cb89d5ea9d0740814c1050 100644 (file)
@@ -921,8 +921,8 @@ intel_tv_save(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
        int i;
 
        tv_priv->save_TV_H_CTL_1 = I915_READ(TV_H_CTL_1);
@@ -971,8 +971,8 @@ intel_tv_restore(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
        struct drm_crtc *crtc = connector->encoder->crtc;
        struct intel_crtc *intel_crtc;
        int i;
@@ -1068,9 +1068,9 @@ intel_tv_mode_lookup (char *tv_format)
 }
 
 static const struct tv_mode *
-intel_tv_mode_find (struct intel_output *intel_output)
+intel_tv_mode_find (struct intel_encoder *intel_encoder)
 {
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
 
        return intel_tv_mode_lookup(tv_priv->tv_format);
 }
@@ -1078,8 +1078,8 @@ intel_tv_mode_find (struct intel_output *intel_output)
 static enum drm_mode_status
 intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
 
        /* Ensure TV refresh is close to desired refresh */
        if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
@@ -1095,8 +1095,8 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
 {
        struct drm_device *dev = encoder->dev;
        struct drm_mode_config *drm_config = &dev->mode_config;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       const struct tv_mode *tv_mode = intel_tv_mode_find (intel_output);
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder);
        struct drm_encoder *other_encoder;
 
        if (!tv_mode)
@@ -1121,9 +1121,9 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc = encoder->crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
-       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
        u32 tv_ctl;
        u32 hctl1, hctl2, hctl3;
        u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
@@ -1360,9 +1360,9 @@ static const struct drm_display_mode reported_modes[] = {
  * \return false if TV is disconnected.
  */
 static int
-intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
+intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
 {
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long irqflags;
@@ -1441,9 +1441,9 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
  */
 static void intel_tv_find_better_format(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
-       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
        int i;
 
        if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
@@ -1475,9 +1475,9 @@ intel_tv_detect(struct drm_connector *connector)
 {
        struct drm_crtc *crtc;
        struct drm_display_mode mode;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        int dpms_mode;
        int type = tv_priv->type;
 
@@ -1485,12 +1485,12 @@ intel_tv_detect(struct drm_connector *connector)
        drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
 
        if (encoder->crtc && encoder->crtc->enabled) {
-               type = intel_tv_detect_type(encoder->crtc, intel_output);
+               type = intel_tv_detect_type(encoder->crtc, intel_encoder);
        } else {
-               crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode);
+               crtc = intel_get_load_detect_pipe(intel_encoder, &mode, &dpms_mode);
                if (crtc) {
-                       type = intel_tv_detect_type(crtc, intel_output);
-                       intel_release_load_detect_pipe(intel_output, dpms_mode);
+                       type = intel_tv_detect_type(crtc, intel_encoder);
+                       intel_release_load_detect_pipe(intel_encoder, dpms_mode);
                } else
                        type = -1;
        }
@@ -1525,8 +1525,8 @@ static void
 intel_tv_chose_preferred_modes(struct drm_connector *connector,
                               struct drm_display_mode *mode_ptr)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
 
        if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
                mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
@@ -1550,8 +1550,8 @@ static int
 intel_tv_get_modes(struct drm_connector *connector)
 {
        struct drm_display_mode *mode_ptr;
-       struct intel_output *intel_output = to_intel_output(connector);
-       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
        int j, count = 0;
        u64 tmp;
 
@@ -1604,11 +1604,11 @@ intel_tv_get_modes(struct drm_connector *connector)
 static void
 intel_tv_destroy (struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
 
 
@@ -1617,9 +1617,9 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
                      uint64_t val)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_crtc *crtc = encoder->crtc;
        int ret = 0;
        bool changed = false;
@@ -1740,7 +1740,7 @@ intel_tv_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_tv_priv *tv_priv;
        u32 tv_dac_on, tv_dac_off, save_tv_dac;
        char **tv_format_names;
@@ -1780,28 +1780,28 @@ intel_tv_init(struct drm_device *dev)
            (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
                return;
 
-       intel_output = kzalloc(sizeof(struct intel_output) +
+       intel_encoder = kzalloc(sizeof(struct intel_encoder) +
                               sizeof(struct intel_tv_priv), GFP_KERNEL);
-       if (!intel_output) {
+       if (!intel_encoder) {
                return;
        }
 
-       connector = &intel_output->base;
+       connector = &intel_encoder->base;
 
        drm_connector_init(dev, connector, &intel_tv_connector_funcs,
                           DRM_MODE_CONNECTOR_SVIDEO);
 
-       drm_encoder_init(dev, &intel_output->enc, &intel_tv_enc_funcs,
+       drm_encoder_init(dev, &intel_encoder->enc, &intel_tv_enc_funcs,
                         DRM_MODE_ENCODER_TVDAC);
 
-       drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
-       tv_priv = (struct intel_tv_priv *)(intel_output + 1);
-       intel_output->type = INTEL_OUTPUT_TVOUT;
-       intel_output->crtc_mask = (1 << 0) | (1 << 1);
-       intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT);
-       intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1));
-       intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
-       intel_output->dev_priv = tv_priv;
+       drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc);
+       tv_priv = (struct intel_tv_priv *)(intel_encoder + 1);
+       intel_encoder->type = INTEL_OUTPUT_TVOUT;
+       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
+       intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT);
+       intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1));
+       intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
+       intel_encoder->dev_priv = tv_priv;
        tv_priv->type = DRM_MODE_CONNECTOR_Unknown;
 
        /* BIOS margin values */
@@ -1812,7 +1812,7 @@ intel_tv_init(struct drm_device *dev)
 
        tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
 
-       drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs);
+       drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs);
        drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
        connector->interlace_allowed = false;
        connector->doublescan_allowed = false;
index 32db806f3b5aa53e82a25797c271b8f4ca8fa2c0..453df3f6053fbb0ffbe865b1e6f25cc1718d6492 100644 (file)
@@ -12,7 +12,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
              nouveau_dp.o nouveau_grctx.o \
              nv04_timer.o \
              nv04_mc.o nv40_mc.o nv50_mc.o \
-             nv04_fb.o nv10_fb.o nv40_fb.o \
+             nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \
              nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \
              nv04_graph.o nv10_graph.o nv20_graph.o \
              nv40_graph.o nv50_graph.o \
@@ -22,7 +22,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
              nv50_cursor.o nv50_display.o nv50_fbcon.o \
              nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \
              nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \
-             nv17_gpio.o
+             nv17_gpio.o nv50_gpio.o
 
 nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o
 nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
index 0e0730a531371e9e59ec01d1db10b72143c0c67b..e13f6af0037ac4dc805a821d785bf5ef541d9c07 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/pci.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
 
index 20564f8cb0ec45f2fa13f82aa69c6bea375600e5..406228f4a2a05e549090f8a4e4fca09253546833 100644 (file)
@@ -89,19 +89,21 @@ static struct backlight_ops nv50_bl_ops = {
 
 static int nouveau_nv40_backlight_init(struct drm_device *dev)
 {
+       struct backlight_properties props;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct backlight_device *bd;
 
        if (!(nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK))
                return 0;
 
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 31;
        bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev,
-                                      &nv40_bl_ops);
+                                      &nv40_bl_ops, &props);
        if (IS_ERR(bd))
                return PTR_ERR(bd);
 
        dev_priv->backlight = bd;
-       bd->props.max_brightness = 31;
        bd->props.brightness = nv40_get_intensity(bd);
        backlight_update_status(bd);
 
@@ -110,19 +112,21 @@ static int nouveau_nv40_backlight_init(struct drm_device *dev)
 
 static int nouveau_nv50_backlight_init(struct drm_device *dev)
 {
+       struct backlight_properties props;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct backlight_device *bd;
 
        if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT))
                return 0;
 
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 1025;
        bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev,
-                                      &nv50_bl_ops);
+                                      &nv50_bl_ops, &props);
        if (IS_ERR(bd))
                return PTR_ERR(bd);
 
        dev_priv->backlight = bd;
-       bd->props.max_brightness = 1025;
        bd->props.brightness = nv50_get_intensity(bd);
        backlight_update_status(bd);
        return 0;
index 75bceee76044e8ab25b6035e690e09fa3e29f850..abc382a9918bfe9be71c33cb2cba83ee07a25d08 100644 (file)
@@ -2573,48 +2573,34 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
         * each GPIO according to various values listed in each entry
         */
 
-       const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
+       struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
        const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c };
-       const uint8_t *gpio_table = &bios->data[bios->dcb.gpio_table_ptr];
-       const uint8_t *gpio_entry;
        int i;
 
-       if (!iexec->execute)
-               return 1;
-
-       if (bios->dcb.version != 0x40) {
-               NV_ERROR(bios->dev, "DCB table not version 4.0\n");
-               return 0;
+       if (dev_priv->card_type != NV_50) {
+               NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n");
+               return -ENODEV;
        }
 
-       if (!bios->dcb.gpio_table_ptr) {
-               NV_WARN(bios->dev, "Invalid pointer to INIT_8E table\n");
-               return 0;
-       }
+       if (!iexec->execute)
+               return 1;
 
-       gpio_entry = gpio_table + gpio_table[1];
-       for (i = 0; i < gpio_table[2]; i++, gpio_entry += gpio_table[3]) {
-               uint32_t entry = ROM32(gpio_entry[0]), r, s, v;
-               int line = (entry & 0x0000001f);
+       for (i = 0; i < bios->dcb.gpio.entries; i++) {
+               struct dcb_gpio_entry *gpio = &bios->dcb.gpio.entry[i];
+               uint32_t r, s, v;
 
-               BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, entry);
+               BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry);
 
-               if ((entry & 0x0000ff00) == 0x0000ff00)
-                       continue;
+               nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default);
 
-               r = nv50_gpio_reg[line >> 3];
-               s = (line & 0x07) << 2;
-               v = bios_rd32(bios, r) & ~(0x00000003 << s);
-               if (entry & 0x01000000)
-                       v |= (((entry & 0x60000000) >> 29) ^ 2) << s;
-               else
-                       v |= (((entry & 0x18000000) >> 27) ^ 2) << s;
-               bios_wr32(bios, r, v);
-
-               r = nv50_gpio_ctl[line >> 4];
-               s = (line & 0x0f);
+               /* The NVIDIA binary driver doesn't appear to actually do
+                * any of this, my VBIOS does however.
+                */
+               /* Not a clue, needs de-magicing */
+               r = nv50_gpio_ctl[gpio->line >> 4];
+               s = (gpio->line & 0x0f);
                v = bios_rd32(bios, r) & ~(0x00010001 << s);
-               switch ((entry & 0x06000000) >> 25) {
+               switch ((gpio->entry & 0x06000000) >> 25) {
                case 1:
                        v |= (0x00000001 << s);
                        break;
@@ -3198,7 +3184,6 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int
        struct nvbios *bios = &dev_priv->vbios;
        unsigned int outputset = (dcbent->or == 4) ? 1 : 0;
        uint16_t scriptptr = 0, clktable;
-       uint8_t clktableptr = 0;
 
        /*
         * For now we assume version 3.0 table - g80 support will need some
@@ -3217,26 +3202,29 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int
                scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 11 + outputset * 2]);
                break;
        case LVDS_RESET:
+               clktable = bios->fp.lvdsmanufacturerpointer + 15;
+               if (dcbent->or == 4)
+                       clktable += 8;
+
                if (dcbent->lvdsconf.use_straps_for_mode) {
                        if (bios->fp.dual_link)
-                               clktableptr += 2;
-                       if (bios->fp.BITbit1)
-                               clktableptr++;
+                               clktable += 4;
+                       if (bios->fp.if_is_24bit)
+                               clktable += 2;
                } else {
                        /* using EDID */
-                       uint8_t fallback = bios->data[bios->fp.lvdsmanufacturerpointer + 4];
-                       int fallbackcmpval = (dcbent->or == 4) ? 4 : 1;
+                       int cmpval_24bit = (dcbent->or == 4) ? 4 : 1;
 
                        if (bios->fp.dual_link) {
-                               clktableptr += 2;
-                               fallbackcmpval *= 2;
+                               clktable += 4;
+                               cmpval_24bit <<= 1;
                        }
-                       if (fallbackcmpval & fallback)
-                               clktableptr++;
+
+                       if (bios->fp.strapless_is_24bit & cmpval_24bit)
+                               clktable += 2;
                }
 
-               /* adding outputset * 8 may not be correct */
-               clktable = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 15 + clktableptr * 2 + outputset * 8]);
+               clktable = ROM16(bios->data[clktable]);
                if (!clktable) {
                        NV_ERROR(dev, "Pixel clock comparison table not found\n");
                        return -ENOENT;
@@ -3638,37 +3626,40 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b
                *if_is_24bit = bios->data[lvdsofs] & 16;
                break;
        case 0x30:
-               /*
-                * My money would be on there being a 24 bit interface bit in
-                * this table, but I have no example of a laptop bios with a
-                * 24 bit panel to confirm that. Hence we shout loudly if any
-                * bit other than bit 0 is set (I've not even seen bit 1)
-                */
-               if (bios->data[lvdsofs] > 1)
-                       NV_ERROR(dev,
-                                "You have a very unusual laptop display; please report it\n");
+       case 0x40:
                /*
                 * No sign of the "power off for reset" or "reset for panel
                 * on" bits, but it's safer to assume we should
                 */
                bios->fp.power_off_for_reset = true;
                bios->fp.reset_after_pclk_change = true;
+
                /*
                 * It's ok lvdsofs is wrong for nv4x edid case; dual_link is
-                * over-written, and BITbit1 isn't used
+                * over-written, and if_is_24bit isn't used
                 */
                bios->fp.dual_link = bios->data[lvdsofs] & 1;
-               bios->fp.BITbit1 = bios->data[lvdsofs] & 2;
-               bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
-               break;
-       case 0x40:
-               bios->fp.dual_link = bios->data[lvdsofs] & 1;
                bios->fp.if_is_24bit = bios->data[lvdsofs] & 2;
                bios->fp.strapless_is_24bit = bios->data[bios->fp.lvdsmanufacturerpointer + 4];
                bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
                break;
        }
 
+       /* Dell Latitude D620 reports a too-high value for the dual-link
+        * transition freq, causing us to program the panel incorrectly.
+        *
+        * It doesn't appear the VBIOS actually uses its transition freq
+        * (90000kHz), instead it uses the "Number of LVDS channels" field
+        * out of the panel ID structure (http://www.spwg.org/).
+        *
+        * For the moment, a quirk will do :)
+        */
+       if ((dev->pdev->device == 0x01d7) &&
+           (dev->pdev->subsystem_vendor == 0x1028) &&
+           (dev->pdev->subsystem_device == 0x01c2)) {
+               bios->fp.duallink_transition_clk = 80000;
+       }
+
        /* set dual_link flag for EDID case */
        if (pxclk && (chip_version < 0x25 || chip_version > 0x28))
                bios->fp.dual_link = (pxclk >= bios->fp.duallink_transition_clk);
@@ -5077,25 +5068,25 @@ parse_dcb30_gpio_entry(struct nvbios *bios, uint16_t offset)
        gpio->tag = tag;
        gpio->line = line;
        gpio->invert = flags != 4;
+       gpio->entry = ent;
 }
 
 static void
 parse_dcb40_gpio_entry(struct nvbios *bios, uint16_t offset)
 {
+       uint32_t entry = ROM32(bios->data[offset]);
        struct dcb_gpio_entry *gpio;
-       uint32_t ent = ROM32(bios->data[offset]);
-       uint8_t line = ent & 0x1f,
-               tag = ent >> 8 & 0xff;
 
-       if (tag == 0xff)
+       if ((entry & 0x0000ff00) == 0x0000ff00)
                return;
 
        gpio = new_gpio_entry(bios);
-
-       /* Currently unused, we may need more fields parsed at some
-        * point. */
-       gpio->tag = tag;
-       gpio->line = line;
+       gpio->tag = (entry & 0x0000ff00) >> 8;
+       gpio->line = (entry & 0x0000001f) >> 0;
+       gpio->state_default = (entry & 0x01000000) >> 24;
+       gpio->state[0] = (entry & 0x18000000) >> 27;
+       gpio->state[1] = (entry & 0x60000000) >> 29;
+       gpio->entry = entry;
 }
 
 static void
@@ -5210,6 +5201,21 @@ divine_connector_type(struct nvbios *bios, int index)
        return type;
 }
 
+static void
+apply_dcb_connector_quirks(struct nvbios *bios, int idx)
+{
+       struct dcb_connector_table_entry *cte = &bios->dcb.connector.entry[idx];
+       struct drm_device *dev = bios->dev;
+
+       /* Gigabyte NX85T */
+       if ((dev->pdev->device == 0x0421) &&
+           (dev->pdev->subsystem_vendor == 0x1458) &&
+           (dev->pdev->subsystem_device == 0x344c)) {
+               if (cte->type == DCB_CONNECTOR_HDMI_1)
+                       cte->type = DCB_CONNECTOR_DVI_I;
+       }
+}
+
 static void
 parse_dcb_connector_table(struct nvbios *bios)
 {
@@ -5238,13 +5244,14 @@ parse_dcb_connector_table(struct nvbios *bios)
        entry = conntab + conntab[1];
        cte = &ct->entry[0];
        for (i = 0; i < conntab[2]; i++, entry += conntab[3], cte++) {
+               cte->index = i;
                if (conntab[3] == 2)
                        cte->entry = ROM16(entry[0]);
                else
                        cte->entry = ROM32(entry[0]);
 
                cte->type  = (cte->entry & 0x000000ff) >> 0;
-               cte->index = (cte->entry & 0x00000f00) >> 8;
+               cte->index2 = (cte->entry & 0x00000f00) >> 8;
                switch (cte->entry & 0x00033000) {
                case 0x00001000:
                        cte->gpio_tag = 0x07;
@@ -5266,6 +5273,8 @@ parse_dcb_connector_table(struct nvbios *bios)
                if (cte->type == 0xff)
                        continue;
 
+               apply_dcb_connector_quirks(bios, i);
+
                NV_INFO(dev, "  %d: 0x%08x: type 0x%02x idx %d tag 0x%02x\n",
                        i, cte->entry, cte->type, cte->index, cte->gpio_tag);
 
@@ -5287,10 +5296,16 @@ parse_dcb_connector_table(struct nvbios *bios)
                        break;
                default:
                        cte->type = divine_connector_type(bios, cte->index);
-                       NV_WARN(dev, "unknown type, using 0x%02x", cte->type);
+                       NV_WARN(dev, "unknown type, using 0x%02x\n", cte->type);
                        break;
                }
 
+               if (nouveau_override_conntype) {
+                       int type = divine_connector_type(bios, cte->index);
+                       if (type != cte->type)
+                               NV_WARN(dev, " -> type 0x%02x\n", cte->type);
+               }
+
        }
 }
 
index 9f688aa9a65559cb3c1febd4183e8c15b8032396..c0d7b0a3ece0a35929c3c0f07b7183136f0cd607 100644 (file)
@@ -49,6 +49,9 @@ struct dcb_gpio_entry {
        enum dcb_gpio_tag tag;
        int line;
        bool invert;
+       uint32_t entry;
+       uint8_t state_default;
+       uint8_t state[2];
 };
 
 struct dcb_gpio_table {
@@ -72,9 +75,10 @@ enum dcb_connector_type {
 };
 
 struct dcb_connector_table_entry {
+       uint8_t index;
        uint32_t entry;
        enum dcb_connector_type type;
-       uint8_t index;
+       uint8_t index2;
        uint8_t gpio_tag;
 };
 
@@ -266,7 +270,6 @@ struct nvbios {
                bool reset_after_pclk_change;
                bool dual_link;
                bool link_c_increment;
-               bool BITbit1;
                bool if_is_24bit;
                int duallink_transition_clk;
                uint8_t strapless_is_24bit;
index 028719fddf761e94b1f1ae44ef50f5fc860e2813..957d17629840254c1ccf5ad13139856cea232525 100644 (file)
@@ -34,6 +34,7 @@
 #include "nouveau_dma.h"
 
 #include <linux/log2.h>
+#include <linux/slab.h>
 
 static void
 nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
@@ -71,7 +72,7 @@ nouveau_bo_fixup_align(struct drm_device *dev,
         * many small buffers.
         */
        if (dev_priv->card_type == NV_50) {
-               uint32_t block_size = nouveau_mem_fb_amount(dev) >> 15;
+               uint32_t block_size = dev_priv->vram_size >> 15;
                int i;
 
                switch (tile_flags) {
@@ -153,7 +154,7 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
 
        nvbo->placement.fpfn = 0;
        nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0;
-       nouveau_bo_placement_set(nvbo, flags);
+       nouveau_bo_placement_set(nvbo, flags, 0);
 
        nvbo->channel = chan;
        ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size,
@@ -172,26 +173,33 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
        return 0;
 }
 
+static void
+set_placement_list(uint32_t *pl, unsigned *n, uint32_t type, uint32_t flags)
+{
+       *n = 0;
+
+       if (type & TTM_PL_FLAG_VRAM)
+               pl[(*n)++] = TTM_PL_FLAG_VRAM | flags;
+       if (type & TTM_PL_FLAG_TT)
+               pl[(*n)++] = TTM_PL_FLAG_TT | flags;
+       if (type & TTM_PL_FLAG_SYSTEM)
+               pl[(*n)++] = TTM_PL_FLAG_SYSTEM | flags;
+}
+
 void
-nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t memtype)
+nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy)
 {
-       int n = 0;
-
-       if (memtype & TTM_PL_FLAG_VRAM)
-               nvbo->placements[n++] = TTM_PL_FLAG_VRAM | TTM_PL_MASK_CACHING;
-       if (memtype & TTM_PL_FLAG_TT)
-               nvbo->placements[n++] = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
-       if (memtype & TTM_PL_FLAG_SYSTEM)
-               nvbo->placements[n++] = TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING;
-       nvbo->placement.placement = nvbo->placements;
-       nvbo->placement.busy_placement = nvbo->placements;
-       nvbo->placement.num_placement = n;
-       nvbo->placement.num_busy_placement = n;
-
-       if (nvbo->pin_refcnt) {
-               while (n--)
-                       nvbo->placements[n] |= TTM_PL_FLAG_NO_EVICT;
-       }
+       struct ttm_placement *pl = &nvbo->placement;
+       uint32_t flags = TTM_PL_MASK_CACHING |
+               (nvbo->pin_refcnt ? TTM_PL_FLAG_NO_EVICT : 0);
+
+       pl->placement = nvbo->placements;
+       set_placement_list(nvbo->placements, &pl->num_placement,
+                          type, flags);
+
+       pl->busy_placement = nvbo->busy_placements;
+       set_placement_list(nvbo->busy_placements, &pl->num_busy_placement,
+                          type | busy, flags);
 }
 
 int
@@ -199,7 +207,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
 {
        struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
        struct ttm_buffer_object *bo = &nvbo->bo;
-       int ret, i;
+       int ret;
 
        if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) {
                NV_ERROR(nouveau_bdev(bo->bdev)->dev,
@@ -215,9 +223,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
        if (ret)
                goto out;
 
-       nouveau_bo_placement_set(nvbo, memtype);
-       for (i = 0; i < nvbo->placement.num_placement; i++)
-               nvbo->placements[i] |= TTM_PL_FLAG_NO_EVICT;
+       nouveau_bo_placement_set(nvbo, memtype, 0);
 
        ret = ttm_bo_validate(bo, &nvbo->placement, false, false);
        if (ret == 0) {
@@ -244,7 +250,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo)
 {
        struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
        struct ttm_buffer_object *bo = &nvbo->bo;
-       int ret, i;
+       int ret;
 
        if (--nvbo->pin_refcnt)
                return 0;
@@ -253,8 +259,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo)
        if (ret)
                return ret;
 
-       for (i = 0; i < nvbo->placement.num_placement; i++)
-               nvbo->placements[i] &= ~TTM_PL_FLAG_NO_EVICT;
+       nouveau_bo_placement_set(nvbo, bo->mem.placement, 0);
 
        ret = ttm_bo_validate(bo, &nvbo->placement, false, false);
        if (ret == 0) {
@@ -395,8 +400,8 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
                man->io_addr = NULL;
                man->io_offset = drm_get_resource_start(dev, 1);
                man->io_size = drm_get_resource_len(dev, 1);
-               if (man->io_size > nouveau_mem_fb_amount(dev))
-                       man->io_size = nouveau_mem_fb_amount(dev);
+               if (man->io_size > dev_priv->vram_size)
+                       man->io_size = dev_priv->vram_size;
 
                man->gpu_offset = dev_priv->vm_vram_base;
                break;
@@ -439,11 +444,11 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
 
        switch (bo->mem.mem_type) {
        case TTM_PL_VRAM:
-               nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT |
+               nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT,
                                         TTM_PL_FLAG_SYSTEM);
                break;
        default:
-               nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM);
+               nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM, 0);
                break;
        }
 
index 6dfb425cbae9432f4718ae33c77b754c4ac9a8dc..1fc57ef58295091eef1e8ad979ad50b17c2fb9a4 100644 (file)
@@ -142,7 +142,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
                                           GFP_KERNEL);
        if (!dev_priv->fifos[channel])
                return -ENOMEM;
-       dev_priv->fifo_alloc_count++;
        chan = dev_priv->fifos[channel];
        INIT_LIST_HEAD(&chan->nvsw.vbl_wait);
        INIT_LIST_HEAD(&chan->fence.pending);
@@ -321,7 +320,6 @@ nouveau_channel_free(struct nouveau_channel *chan)
                iounmap(chan->user);
 
        dev_priv->fifos[chan->id] = NULL;
-       dev_priv->fifo_alloc_count--;
        kfree(chan);
 }
 
index 24327f468c4b864b459fc0af3034c6548c2d3840..14afe1e47e57dff81a70dadada1bac8ec9f88c8d 100644 (file)
@@ -302,7 +302,7 @@ nouveau_connector_detect(struct drm_connector *connector)
 
 detect_analog:
        nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG);
-       if (!nv_encoder)
+       if (!nv_encoder && !nouveau_tv_disable)
                nv_encoder = find_encoder_by_type(connector, OUTPUT_TV);
        if (nv_encoder) {
                struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
index 8ff9ef5d4b47d1bd1df4287e0c4e109b4aaed52a..a251886a0ce66f8b2b7cdf1518d0fe12d7f30560 100644 (file)
@@ -137,10 +137,9 @@ nouveau_debugfs_memory_info(struct seq_file *m, void *data)
 {
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct drm_minor *minor = node->minor;
-       struct drm_device *dev = minor->dev;
+       struct drm_nouveau_private *dev_priv = minor->dev->dev_private;
 
-       seq_printf(m, "VRAM total: %dKiB\n",
-                  (int)(nouveau_mem_fb_amount(dev) >> 10));
+       seq_printf(m, "VRAM total: %dKiB\n", (int)(dev_priv->vram_size >> 10));
        return 0;
 }
 
index c8482a108a7801c321875ecbf5ff4e041563d3e9..65c441a1999facfeeb3b9ca191198fad732583d8 100644 (file)
@@ -190,6 +190,11 @@ nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo,
        nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8);
 
        chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max;
+
+       DRM_MEMORYBARRIER();
+       /* Flush writes. */
+       nouveau_bo_rd32(pb, 0);
+
        nvchan_wr32(chan, 0x8c, chan->dma.ib_put);
        chan->dma.ib_free--;
 }
index f954ad93e81f3f17ca5385591e7dca9ff6547a49..deeb21c6865c84d6f490e7bc5e82fa7acf5cfc99 100644 (file)
@@ -483,7 +483,7 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
        ctrl |= (cmd << NV50_AUXCH_CTRL_CMD_SHIFT);
        ctrl |= ((data_nr - 1) << NV50_AUXCH_CTRL_LEN_SHIFT);
 
-       for (;;) {
+       for (i = 0; i < 16; i++) {
                nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x80000000);
                nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl);
                nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x00010000);
@@ -502,6 +502,12 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
                        break;
        }
 
+       if (i == 16) {
+               NV_ERROR(dev, "auxch DEFER too many times, bailing\n");
+               ret = -EREMOTEIO;
+               goto out;
+       }
+
        if (cmd & 1) {
                if ((stat & NV50_AUXCH_STAT_COUNT) != data_nr) {
                        ret = -EREMOTEIO;
index 30cc09e8a709383a458baab1d77ff89ca84de9da..1de974acbc656a1dc195df0e7f6b57f52f9c0d37 100644 (file)
@@ -83,6 +83,14 @@ MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration");
 int nouveau_nofbaccel = 0;
 module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400);
 
+MODULE_PARM_DESC(override_conntype, "Ignore DCB connector type");
+int nouveau_override_conntype = 0;
+module_param_named(override_conntype, nouveau_override_conntype, int, 0400);
+
+MODULE_PARM_DESC(tv_disable, "Disable TV-out detection\n");
+int nouveau_tv_disable = 0;
+module_param_named(tv_disable, nouveau_tv_disable, int, 0400);
+
 MODULE_PARM_DESC(tv_norm, "Default TV norm.\n"
                 "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n"
                 "\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n"
@@ -154,9 +162,11 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
        if (pm_state.event == PM_EVENT_PRETHAW)
                return 0;
 
+       NV_INFO(dev, "Disabling fbcon acceleration...\n");
        fbdev_flags = dev_priv->fbdev_info->flags;
        dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED;
 
+       NV_INFO(dev, "Unpinning framebuffer(s)...\n");
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
                struct nouveau_framebuffer *nouveau_fb;
 
index 4b9aaf2a8d0f0052bbafd498998e2c71b1e38434..ace630aa89e1c6b9755df63a1af28a61a6db6229 100644 (file)
@@ -76,6 +76,7 @@ struct nouveau_bo {
        struct ttm_buffer_object bo;
        struct ttm_placement placement;
        u32 placements[3];
+       u32 busy_placements[3];
        struct ttm_bo_kmap_obj kmap;
        struct list_head head;
 
@@ -519,6 +520,7 @@ struct drm_nouveau_private {
 
        struct workqueue_struct *wq;
        struct work_struct irq_work;
+       struct work_struct hpd_work;
 
        struct list_head vbl_waiting;
 
@@ -533,7 +535,6 @@ struct drm_nouveau_private {
 
        struct fb_info *fbdev_info;
 
-       int fifo_alloc_count;
        struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR];
 
        struct nouveau_engine engine;
@@ -553,12 +554,6 @@ struct drm_nouveau_private {
        uint32_t ramro_offset;
        uint32_t ramro_size;
 
-       /* base physical addresses */
-       uint64_t fb_phys;
-       uint64_t fb_available_size;
-       uint64_t fb_mappable_pages;
-       uint64_t fb_aper_free;
-
        struct {
                enum {
                        NOUVEAU_GART_NONE = 0,
@@ -572,10 +567,6 @@ struct drm_nouveau_private {
                struct nouveau_gpuobj *sg_ctxdma;
                struct page *sg_dummy_page;
                dma_addr_t sg_dummy_bus;
-
-               /* nottm hack */
-               struct drm_ttm_backend *sg_be;
-               unsigned long sg_handle;
        } gart_info;
 
        /* nv10-nv40 tiling regions */
@@ -584,6 +575,16 @@ struct drm_nouveau_private {
                spinlock_t lock;
        } tile;
 
+       /* VRAM/fb configuration */
+       uint64_t vram_size;
+       uint64_t vram_sys_base;
+
+       uint64_t fb_phys;
+       uint64_t fb_available_size;
+       uint64_t fb_mappable_pages;
+       uint64_t fb_aper_free;
+       int fb_mtrr;
+
        /* G8x/G9x virtual address space */
        uint64_t vm_gart_base;
        uint64_t vm_gart_size;
@@ -592,10 +593,6 @@ struct drm_nouveau_private {
        uint64_t vm_end;
        struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR];
        int vm_vram_pt_nr;
-       uint64_t vram_sys_base;
-
-       /* the mtrr covering the FB */
-       int fb_mtrr;
 
        struct mem_block *ramin_heap;
 
@@ -614,11 +611,7 @@ struct drm_nouveau_private {
        uint32_t dac_users[4];
 
        struct nouveau_suspend_resume {
-               uint32_t fifo_mode;
-               uint32_t graph_ctx_control;
-               uint32_t graph_state;
                uint32_t *ramin_copy;
-               uint64_t ramin_size;
        } susres;
 
        struct backlight_device *backlight;
@@ -681,6 +674,7 @@ extern int nouveau_uscript_tmds;
 extern int nouveau_vram_pushbuf;
 extern int nouveau_vram_notify;
 extern int nouveau_fbpercrtc;
+extern int nouveau_tv_disable;
 extern char *nouveau_tv_norm;
 extern int nouveau_reg_debug;
 extern char *nouveau_vbios;
@@ -688,6 +682,7 @@ extern int nouveau_ctxfw;
 extern int nouveau_ignorelid;
 extern int nouveau_nofbaccel;
 extern int nouveau_noaccel;
+extern int nouveau_override_conntype;
 
 extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state);
 extern int nouveau_pci_resume(struct pci_dev *pdev);
@@ -715,7 +710,7 @@ extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *,
                                                 struct drm_file *, int tail);
 extern void nouveau_mem_takedown(struct mem_block **heap);
 extern void nouveau_mem_free_block(struct mem_block *);
-extern uint64_t nouveau_mem_fb_amount(struct drm_device *);
+extern int  nouveau_mem_detect(struct drm_device *dev);
 extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap);
 extern int  nouveau_mem_init(struct drm_device *);
 extern int  nouveau_mem_init_agp(struct drm_device *);
@@ -926,6 +921,10 @@ extern void nv40_fb_takedown(struct drm_device *);
 extern void nv40_fb_set_region_tiling(struct drm_device *, int, uint32_t,
                                      uint32_t, uint32_t);
 
+/* nv50_fb.c */
+extern int  nv50_fb_init(struct drm_device *);
+extern void nv50_fb_takedown(struct drm_device *);
+
 /* nv04_fifo.c */
 extern int  nv04_fifo_init(struct drm_device *);
 extern void nv04_fifo_disable(struct drm_device *);
@@ -1118,7 +1117,8 @@ extern int nouveau_bo_pin(struct nouveau_bo *, uint32_t flags);
 extern int nouveau_bo_unpin(struct nouveau_bo *);
 extern int nouveau_bo_map(struct nouveau_bo *);
 extern void nouveau_bo_unmap(struct nouveau_bo *);
-extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t memtype);
+extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t type,
+                                    uint32_t busy);
 extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index);
 extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val);
 extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index);
@@ -1162,6 +1162,10 @@ extern int nouveau_gem_ioctl_info(struct drm_device *, void *,
 int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
 int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
 
+/* nv50_gpio.c */
+int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
+int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
+
 #ifndef ioread32_native
 #ifdef __BIG_ENDIAN
 #define ioread16_native ioread16be
index bc4a24029ed12a4ee5a59857975791a867699054..9f28b94e479bd1c7e7ba1f68bb59f29975559dbf 100644 (file)
@@ -47,6 +47,7 @@ struct nouveau_encoder {
 
        union {
                struct {
+                       int mc_unknown;
                        int dpcd_version;
                        int link_nr;
                        int link_bw;
index 68cedd9194fe0f3792c4152b1282b043300faf23..8e7dc1d4912a4d889938bf9741ff6fa774b51c50 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/tty.h>
-#include <linux/slab.h>
 #include <linux/sysrq.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
index 0d22f66f1c795c1784cd3078c8e87f88dd4b8044..1bc0b38a5167d49f6c2a2a6a23fe385e07135c06 100644 (file)
@@ -180,40 +180,35 @@ nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains,
 {
        struct nouveau_bo *nvbo = gem->driver_private;
        struct ttm_buffer_object *bo = &nvbo->bo;
-       uint64_t flags;
+       uint32_t domains = valid_domains &
+               (write_domains ? write_domains : read_domains);
+       uint32_t pref_flags = 0, valid_flags = 0;
 
-       if (!valid_domains || (!read_domains && !write_domains))
+       if (!domains)
                return -EINVAL;
 
-       if (write_domains) {
-               if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
-                   (write_domains & NOUVEAU_GEM_DOMAIN_VRAM))
-                       flags = TTM_PL_FLAG_VRAM;
-               else
-               if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) &&
-                   (write_domains & NOUVEAU_GEM_DOMAIN_GART))
-                       flags = TTM_PL_FLAG_TT;
-               else
-                       return -EINVAL;
-       } else {
-               if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
-                   (read_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
-                   bo->mem.mem_type == TTM_PL_VRAM)
-                       flags = TTM_PL_FLAG_VRAM;
-               else
-               if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) &&
-                   (read_domains & NOUVEAU_GEM_DOMAIN_GART) &&
-                   bo->mem.mem_type == TTM_PL_TT)
-                       flags = TTM_PL_FLAG_TT;
-               else
-               if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
-                   (read_domains & NOUVEAU_GEM_DOMAIN_VRAM))
-                       flags = TTM_PL_FLAG_VRAM;
-               else
-                       flags = TTM_PL_FLAG_TT;
-       }
+       if (valid_domains & NOUVEAU_GEM_DOMAIN_VRAM)
+               valid_flags |= TTM_PL_FLAG_VRAM;
+
+       if (valid_domains & NOUVEAU_GEM_DOMAIN_GART)
+               valid_flags |= TTM_PL_FLAG_TT;
+
+       if ((domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
+           bo->mem.mem_type == TTM_PL_VRAM)
+               pref_flags |= TTM_PL_FLAG_VRAM;
+
+       else if ((domains & NOUVEAU_GEM_DOMAIN_GART) &&
+                bo->mem.mem_type == TTM_PL_TT)
+               pref_flags |= TTM_PL_FLAG_TT;
+
+       else if (domains & NOUVEAU_GEM_DOMAIN_VRAM)
+               pref_flags |= TTM_PL_FLAG_VRAM;
+
+       else
+               pref_flags |= TTM_PL_FLAG_TT;
+
+       nouveau_bo_placement_set(nvbo, pref_flags, valid_flags);
 
-       nouveau_bo_placement_set(nvbo, flags);
        return 0;
 }
 
index c7ebec696747266f0c413a9b92ec368bb832e727..32f0e495464ca83068e0bcfb345cb9248e68185e 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #include "drmP.h"
 #include "nouveau_drv.h"
index 95220ddebb45a0f1880e3b200e161480588a9133..13e73cee4c44d6fa2764f7ff3ff710148f545c3e 100644 (file)
@@ -51,6 +51,7 @@ nouveau_irq_preinstall(struct drm_device *dev)
 
        if (dev_priv->card_type == NV_50) {
                INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh);
+               INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh);
                INIT_LIST_HEAD(&dev_priv->vbl_waiting);
        }
 }
@@ -311,6 +312,31 @@ nouveau_print_bitfield_names_(uint32_t value,
 #define nouveau_print_bitfield_names(val, namelist) \
        nouveau_print_bitfield_names_((val), (namelist), ARRAY_SIZE(namelist))
 
+struct nouveau_enum_names {
+       uint32_t value;
+       const char *name;
+};
+
+static void
+nouveau_print_enum_names_(uint32_t value,
+                               const struct nouveau_enum_names *namelist,
+                               const int namelist_len)
+{
+       /*
+        * Caller must have already printed the KERN_* log level for us.
+        * Also the caller is responsible for adding the newline.
+        */
+       int i;
+       for (i = 0; i < namelist_len; ++i) {
+               if (value == namelist[i].value) {
+                       printk("%s", namelist[i].name);
+                       return;
+               }
+       }
+       printk("unknown value 0x%08x", value);
+}
+#define nouveau_print_enum_names(val, namelist) \
+       nouveau_print_enum_names_((val), (namelist), ARRAY_SIZE(namelist))
 
 static int
 nouveau_graph_chid_from_grctx(struct drm_device *dev)
@@ -427,14 +453,16 @@ nouveau_graph_dump_trap_info(struct drm_device *dev, const char *id,
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        uint32_t nsource = trap->nsource, nstatus = trap->nstatus;
 
-       NV_INFO(dev, "%s - nSource:", id);
-       nouveau_print_bitfield_names(nsource, nsource_names);
-       printk(", nStatus:");
-       if (dev_priv->card_type < NV_10)
-               nouveau_print_bitfield_names(nstatus, nstatus_names);
-       else
-               nouveau_print_bitfield_names(nstatus, nstatus_names_nv10);
-       printk("\n");
+       if (dev_priv->card_type < NV_50) {
+               NV_INFO(dev, "%s - nSource:", id);
+               nouveau_print_bitfield_names(nsource, nsource_names);
+               printk(", nStatus:");
+               if (dev_priv->card_type < NV_10)
+                       nouveau_print_bitfield_names(nstatus, nstatus_names);
+               else
+                       nouveau_print_bitfield_names(nstatus, nstatus_names_nv10);
+               printk("\n");
+       }
 
        NV_INFO(dev, "%s - Ch %d/%d Class 0x%04x Mthd 0x%04x "
                                        "Data 0x%08x:0x%08x\n",
@@ -577,28 +605,503 @@ nouveau_pgraph_irq_handler(struct drm_device *dev)
        nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING);
 }
 
+static void
+nv50_pfb_vm_trap(struct drm_device *dev, int display, const char *name)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       uint32_t trap[6];
+       int i, ch;
+       uint32_t idx = nv_rd32(dev, 0x100c90);
+       if (idx & 0x80000000) {
+               idx &= 0xffffff;
+               if (display) {
+                       for (i = 0; i < 6; i++) {
+                               nv_wr32(dev, 0x100c90, idx | i << 24);
+                               trap[i] = nv_rd32(dev, 0x100c94);
+                       }
+                       for (ch = 0; ch < dev_priv->engine.fifo.channels; ch++) {
+                               struct nouveau_channel *chan = dev_priv->fifos[ch];
+
+                               if (!chan || !chan->ramin)
+                                       continue;
+
+                               if (trap[1] == chan->ramin->instance >> 12)
+                                       break;
+                       }
+                       NV_INFO(dev, "%s - VM: Trapped %s at %02x%04x%04x status %08x %08x channel %d\n",
+                                       name, (trap[5]&0x100?"read":"write"),
+                                       trap[5]&0xff, trap[4]&0xffff,
+                                       trap[3]&0xffff, trap[0], trap[2], ch);
+               }
+               nv_wr32(dev, 0x100c90, idx | 0x80000000);
+       } else if (display) {
+               NV_INFO(dev, "%s - no VM fault?\n", name);
+       }
+}
+
+static struct nouveau_enum_names nv50_mp_exec_error_names[] =
+{
+       { 3, "STACK_UNDERFLOW" },
+       { 4, "QUADON_ACTIVE" },
+       { 8, "TIMEOUT" },
+       { 0x10, "INVALID_OPCODE" },
+       { 0x40, "BREAKPOINT" },
+};
+
+static void
+nv50_pgraph_mp_trap(struct drm_device *dev, int tpid, int display)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       uint32_t units = nv_rd32(dev, 0x1540);
+       uint32_t addr, mp10, status, pc, oplow, ophigh;
+       int i;
+       int mps = 0;
+       for (i = 0; i < 4; i++) {
+               if (!(units & 1 << (i+24)))
+                       continue;
+               if (dev_priv->chipset < 0xa0)
+                       addr = 0x408200 + (tpid << 12) + (i << 7);
+               else
+                       addr = 0x408100 + (tpid << 11) + (i << 7);
+               mp10 = nv_rd32(dev, addr + 0x10);
+               status = nv_rd32(dev, addr + 0x14);
+               if (!status)
+                       continue;
+               if (display) {
+                       nv_rd32(dev, addr + 0x20);
+                       pc = nv_rd32(dev, addr + 0x24);
+                       oplow = nv_rd32(dev, addr + 0x70);
+                       ophigh= nv_rd32(dev, addr + 0x74);
+                       NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - "
+                                       "TP %d MP %d: ", tpid, i);
+                       nouveau_print_enum_names(status,
+                                       nv50_mp_exec_error_names);
+                       printk(" at %06x warp %d, opcode %08x %08x\n",
+                                       pc&0xffffff, pc >> 24,
+                                       oplow, ophigh);
+               }
+               nv_wr32(dev, addr + 0x10, mp10);
+               nv_wr32(dev, addr + 0x14, 0);
+               mps++;
+       }
+       if (!mps && display)
+               NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - TP %d: "
+                               "No MPs claiming errors?\n", tpid);
+}
+
+static void
+nv50_pgraph_tp_trap(struct drm_device *dev, int type, uint32_t ustatus_old,
+               uint32_t ustatus_new, int display, const char *name)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       int tps = 0;
+       uint32_t units = nv_rd32(dev, 0x1540);
+       int i, r;
+       uint32_t ustatus_addr, ustatus;
+       for (i = 0; i < 16; i++) {
+               if (!(units & (1 << i)))
+                       continue;
+               if (dev_priv->chipset < 0xa0)
+                       ustatus_addr = ustatus_old + (i << 12);
+               else
+                       ustatus_addr = ustatus_new + (i << 11);
+               ustatus = nv_rd32(dev, ustatus_addr) & 0x7fffffff;
+               if (!ustatus)
+                       continue;
+               tps++;
+               switch (type) {
+               case 6: /* texture error... unknown for now */
+                       nv50_pfb_vm_trap(dev, display, name);
+                       if (display) {
+                               NV_ERROR(dev, "magic set %d:\n", i);
+                               for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4)
+                                       NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
+                                               nv_rd32(dev, r));
+                       }
+                       break;
+               case 7: /* MP error */
+                       if (ustatus & 0x00010000) {
+                               nv50_pgraph_mp_trap(dev, i, display);
+                               ustatus &= ~0x00010000;
+                       }
+                       break;
+               case 8: /* TPDMA error */
+                       {
+                       uint32_t e0c = nv_rd32(dev, ustatus_addr + 4);
+                       uint32_t e10 = nv_rd32(dev, ustatus_addr + 8);
+                       uint32_t e14 = nv_rd32(dev, ustatus_addr + 0xc);
+                       uint32_t e18 = nv_rd32(dev, ustatus_addr + 0x10);
+                       uint32_t e1c = nv_rd32(dev, ustatus_addr + 0x14);
+                       uint32_t e20 = nv_rd32(dev, ustatus_addr + 0x18);
+                       uint32_t e24 = nv_rd32(dev, ustatus_addr + 0x1c);
+                       nv50_pfb_vm_trap(dev, display, name);
+                       /* 2d engine destination */
+                       if (ustatus & 0x00000010) {
+                               if (display) {
+                                       NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - Unknown fault at address %02x%08x\n",
+                                                       i, e14, e10);
+                                       NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n",
+                                                       i, e0c, e18, e1c, e20, e24);
+                               }
+                               ustatus &= ~0x00000010;
+                       }
+                       /* Render target */
+                       if (ustatus & 0x00000040) {
+                               if (display) {
+                                       NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - Unknown fault at address %02x%08x\n",
+                                                       i, e14, e10);
+                                       NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n",
+                                                       i, e0c, e18, e1c, e20, e24);
+                               }
+                               ustatus &= ~0x00000040;
+                       }
+                       /* CUDA memory: l[], g[] or stack. */
+                       if (ustatus & 0x00000080) {
+                               if (display) {
+                                       if (e18 & 0x80000000) {
+                                               /* g[] read fault? */
+                                               NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global read fault at address %02x%08x\n",
+                                                               i, e14, e10 | ((e18 >> 24) & 0x1f));
+                                               e18 &= ~0x1f000000;
+                                       } else if (e18 & 0xc) {
+                                               /* g[] write fault? */
+                                               NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global write fault at address %02x%08x\n",
+                                                               i, e14, e10 | ((e18 >> 7) & 0x1f));
+                                               e18 &= ~0x00000f80;
+                                       } else {
+                                               NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Unknown CUDA fault at address %02x%08x\n",
+                                                               i, e14, e10);
+                                       }
+                                       NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n",
+                                                       i, e0c, e18, e1c, e20, e24);
+                               }
+                               ustatus &= ~0x00000080;
+                       }
+                       }
+                       break;
+               }
+               if (ustatus) {
+                       if (display)
+                               NV_INFO(dev, "%s - TP%d: Unhandled ustatus 0x%08x\n", name, i, ustatus);
+               }
+               nv_wr32(dev, ustatus_addr, 0xc0000000);
+       }
+
+       if (!tps && display)
+               NV_INFO(dev, "%s - No TPs claiming errors?\n", name);
+}
+
+static void
+nv50_pgraph_trap_handler(struct drm_device *dev)
+{
+       struct nouveau_pgraph_trap trap;
+       uint32_t status = nv_rd32(dev, 0x400108);
+       uint32_t ustatus;
+       int display = nouveau_ratelimit();
+
+
+       if (!status && display) {
+               nouveau_graph_trap_info(dev, &trap);
+               nouveau_graph_dump_trap_info(dev, "PGRAPH_TRAP", &trap);
+               NV_INFO(dev, "PGRAPH_TRAP - no units reporting traps?\n");
+       }
+
+       /* DISPATCH: Relays commands to other units and handles NOTIFY,
+        * COND, QUERY. If you get a trap from it, the command is still stuck
+        * in DISPATCH and you need to do something about it. */
+       if (status & 0x001) {
+               ustatus = nv_rd32(dev, 0x400804) & 0x7fffffff;
+               if (!ustatus && display) {
+                       NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - no ustatus?\n");
+               }
+
+               /* Known to be triggered by screwed up NOTIFY and COND... */
+               if (ustatus & 0x00000001) {
+                       nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_FAULT");
+                       nv_wr32(dev, 0x400500, 0);
+                       if (nv_rd32(dev, 0x400808) & 0x80000000) {
+                               if (display) {
+                                       if (nouveau_graph_trapped_channel(dev, &trap.channel))
+                                               trap.channel = -1;
+                                       trap.class = nv_rd32(dev, 0x400814);
+                                       trap.mthd = nv_rd32(dev, 0x400808) & 0x1ffc;
+                                       trap.subc = (nv_rd32(dev, 0x400808) >> 16) & 0x7;
+                                       trap.data = nv_rd32(dev, 0x40080c);
+                                       trap.data2 = nv_rd32(dev, 0x400810);
+                                       nouveau_graph_dump_trap_info(dev,
+                                                       "PGRAPH_TRAP_DISPATCH_FAULT", &trap);
+                                       NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - 400808: %08x\n", nv_rd32(dev, 0x400808));
+                                       NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - 400848: %08x\n", nv_rd32(dev, 0x400848));
+                               }
+                               nv_wr32(dev, 0x400808, 0);
+                       } else if (display) {
+                               NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - No stuck command?\n");
+                       }
+                       nv_wr32(dev, 0x4008e8, nv_rd32(dev, 0x4008e8) & 3);
+                       nv_wr32(dev, 0x400848, 0);
+                       ustatus &= ~0x00000001;
+               }
+               if (ustatus & 0x00000002) {
+                       nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_QUERY");
+                       nv_wr32(dev, 0x400500, 0);
+                       if (nv_rd32(dev, 0x40084c) & 0x80000000) {
+                               if (display) {
+                                       if (nouveau_graph_trapped_channel(dev, &trap.channel))
+                                               trap.channel = -1;
+                                       trap.class = nv_rd32(dev, 0x400814);
+                                       trap.mthd = nv_rd32(dev, 0x40084c) & 0x1ffc;
+                                       trap.subc = (nv_rd32(dev, 0x40084c) >> 16) & 0x7;
+                                       trap.data = nv_rd32(dev, 0x40085c);
+                                       trap.data2 = 0;
+                                       nouveau_graph_dump_trap_info(dev,
+                                                       "PGRAPH_TRAP_DISPATCH_QUERY", &trap);
+                                       NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_QUERY - 40084c: %08x\n", nv_rd32(dev, 0x40084c));
+                               }
+                               nv_wr32(dev, 0x40084c, 0);
+                       } else if (display) {
+                               NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_QUERY - No stuck command?\n");
+                       }
+                       ustatus &= ~0x00000002;
+               }
+               if (ustatus && display)
+                       NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - Unhandled ustatus 0x%08x\n", ustatus);
+               nv_wr32(dev, 0x400804, 0xc0000000);
+               nv_wr32(dev, 0x400108, 0x001);
+               status &= ~0x001;
+       }
+
+       /* TRAPs other than dispatch use the "normal" trap regs. */
+       if (status && display) {
+               nouveau_graph_trap_info(dev, &trap);
+               nouveau_graph_dump_trap_info(dev,
+                               "PGRAPH_TRAP", &trap);
+       }
+
+       /* M2MF: Memory to memory copy engine. */
+       if (status & 0x002) {
+               ustatus = nv_rd32(dev, 0x406800) & 0x7fffffff;
+               if (!ustatus && display) {
+                       NV_INFO(dev, "PGRAPH_TRAP_M2MF - no ustatus?\n");
+               }
+               if (ustatus & 0x00000001) {
+                       nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_NOTIFY");
+                       ustatus &= ~0x00000001;
+               }
+               if (ustatus & 0x00000002) {
+                       nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_IN");
+                       ustatus &= ~0x00000002;
+               }
+               if (ustatus & 0x00000004) {
+                       nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_OUT");
+                       ustatus &= ~0x00000004;
+               }
+               NV_INFO (dev, "PGRAPH_TRAP_M2MF - %08x %08x %08x %08x\n",
+                               nv_rd32(dev, 0x406804),
+                               nv_rd32(dev, 0x406808),
+                               nv_rd32(dev, 0x40680c),
+                               nv_rd32(dev, 0x406810));
+               if (ustatus && display)
+                       NV_INFO(dev, "PGRAPH_TRAP_M2MF - Unhandled ustatus 0x%08x\n", ustatus);
+               /* No sane way found yet -- just reset the bugger. */
+               nv_wr32(dev, 0x400040, 2);
+               nv_wr32(dev, 0x400040, 0);
+               nv_wr32(dev, 0x406800, 0xc0000000);
+               nv_wr32(dev, 0x400108, 0x002);
+               status &= ~0x002;
+       }
+
+       /* VFETCH: Fetches data from vertex buffers. */
+       if (status & 0x004) {
+               ustatus = nv_rd32(dev, 0x400c04) & 0x7fffffff;
+               if (!ustatus && display) {
+                       NV_INFO(dev, "PGRAPH_TRAP_VFETCH - no ustatus?\n");
+               }
+               if (ustatus & 0x00000001) {
+                       nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_VFETCH_FAULT");
+                       NV_INFO (dev, "PGRAPH_TRAP_VFETCH_FAULT - %08x %08x %08x %08x\n",
+                                       nv_rd32(dev, 0x400c00),
+                                       nv_rd32(dev, 0x400c08),
+                                       nv_rd32(dev, 0x400c0c),
+                                       nv_rd32(dev, 0x400c10));
+                       ustatus &= ~0x00000001;
+               }
+               if (ustatus && display)
+                       NV_INFO(dev, "PGRAPH_TRAP_VFETCH - Unhandled ustatus 0x%08x\n", ustatus);
+               nv_wr32(dev, 0x400c04, 0xc0000000);
+               nv_wr32(dev, 0x400108, 0x004);
+               status &= ~0x004;
+       }
+
+       /* STRMOUT: DirectX streamout / OpenGL transform feedback. */
+       if (status & 0x008) {
+               ustatus = nv_rd32(dev, 0x401800) & 0x7fffffff;
+               if (!ustatus && display) {
+                       NV_INFO(dev, "PGRAPH_TRAP_STRMOUT - no ustatus?\n");
+               }
+               if (ustatus & 0x00000001) {
+                       nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_STRMOUT_FAULT");
+                       NV_INFO (dev, "PGRAPH_TRAP_STRMOUT_FAULT - %08x %08x %08x %08x\n",
+                                       nv_rd32(dev, 0x401804),
+                                       nv_rd32(dev, 0x401808),
+                                       nv_rd32(dev, 0x40180c),
+                                       nv_rd32(dev, 0x401810));
+                       ustatus &= ~0x00000001;
+               }
+               if (ustatus && display)
+                       NV_INFO(dev, "PGRAPH_TRAP_STRMOUT - Unhandled ustatus 0x%08x\n", ustatus);
+               /* No sane way found yet -- just reset the bugger. */
+               nv_wr32(dev, 0x400040, 0x80);
+               nv_wr32(dev, 0x400040, 0);
+               nv_wr32(dev, 0x401800, 0xc0000000);
+               nv_wr32(dev, 0x400108, 0x008);
+               status &= ~0x008;
+       }
+
+       /* CCACHE: Handles code and c[] caches and fills them. */
+       if (status & 0x010) {
+               ustatus = nv_rd32(dev, 0x405018) & 0x7fffffff;
+               if (!ustatus && display) {
+                       NV_INFO(dev, "PGRAPH_TRAP_CCACHE - no ustatus?\n");
+               }
+               if (ustatus & 0x00000001) {
+                       nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_CCACHE_FAULT");
+                       NV_INFO (dev, "PGRAPH_TRAP_CCACHE_FAULT - %08x %08x %08x %08x %08x %08x %08x\n",
+                                       nv_rd32(dev, 0x405800),
+                                       nv_rd32(dev, 0x405804),
+                                       nv_rd32(dev, 0x405808),
+                                       nv_rd32(dev, 0x40580c),
+                                       nv_rd32(dev, 0x405810),
+                                       nv_rd32(dev, 0x405814),
+                                       nv_rd32(dev, 0x40581c));
+                       ustatus &= ~0x00000001;
+               }
+               if (ustatus && display)
+                       NV_INFO(dev, "PGRAPH_TRAP_CCACHE - Unhandled ustatus 0x%08x\n", ustatus);
+               nv_wr32(dev, 0x405018, 0xc0000000);
+               nv_wr32(dev, 0x400108, 0x010);
+               status &= ~0x010;
+       }
+
+       /* Unknown, not seen yet... 0x402000 is the only trap status reg
+        * remaining, so try to handle it anyway. Perhaps related to that
+        * unknown DMA slot on tesla? */
+       if (status & 0x20) {
+               nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_UNKC04");
+               ustatus = nv_rd32(dev, 0x402000) & 0x7fffffff;
+               if (display)
+                       NV_INFO(dev, "PGRAPH_TRAP_UNKC04 - Unhandled ustatus 0x%08x\n", ustatus);
+               nv_wr32(dev, 0x402000, 0xc0000000);
+               /* no status modifiction on purpose */
+       }
+
+       /* TEXTURE: CUDA texturing units */
+       if (status & 0x040) {
+               nv50_pgraph_tp_trap (dev, 6, 0x408900, 0x408600, display,
+                               "PGRAPH_TRAP_TEXTURE");
+               nv_wr32(dev, 0x400108, 0x040);
+               status &= ~0x040;
+       }
+
+       /* MP: CUDA execution engines. */
+       if (status & 0x080) {
+               nv50_pgraph_tp_trap (dev, 7, 0x408314, 0x40831c, display,
+                               "PGRAPH_TRAP_MP");
+               nv_wr32(dev, 0x400108, 0x080);
+               status &= ~0x080;
+       }
+
+       /* TPDMA:  Handles TP-initiated uncached memory accesses:
+        * l[], g[], stack, 2d surfaces, render targets. */
+       if (status & 0x100) {
+               nv50_pgraph_tp_trap (dev, 8, 0x408e08, 0x408708, display,
+                               "PGRAPH_TRAP_TPDMA");
+               nv_wr32(dev, 0x400108, 0x100);
+               status &= ~0x100;
+       }
+
+       if (status) {
+               if (display)
+                       NV_INFO(dev, "PGRAPH_TRAP - Unknown trap 0x%08x\n",
+                               status);
+               nv_wr32(dev, 0x400108, status);
+       }
+}
+
+/* There must be a *lot* of these. Will take some time to gather them up. */
+static struct nouveau_enum_names nv50_data_error_names[] =
+{
+       { 4,    "INVALID_VALUE" },
+       { 5,    "INVALID_ENUM" },
+       { 8,    "INVALID_OBJECT" },
+       { 0xc,  "INVALID_BITFIELD" },
+       { 0x28, "MP_NO_REG_SPACE" },
+       { 0x2b, "MP_BLOCK_SIZE_MISMATCH" },
+};
+
 static void
 nv50_pgraph_irq_handler(struct drm_device *dev)
 {
+       struct nouveau_pgraph_trap trap;
+       int unhandled = 0;
        uint32_t status;
 
        while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) {
-               uint32_t nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
-
+               /* NOTIFY: You've set a NOTIFY an a command and it's done. */
                if (status & 0x00000001) {
-                       nouveau_pgraph_intr_notify(dev, nsource);
+                       nouveau_graph_trap_info(dev, &trap);
+                       if (nouveau_ratelimit())
+                               nouveau_graph_dump_trap_info(dev,
+                                               "PGRAPH_NOTIFY", &trap);
                        status &= ~0x00000001;
                        nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001);
                }
 
-               if (status & 0x00000010) {
-                       nouveau_pgraph_intr_error(dev, nsource |
-                                       NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD);
+               /* COMPUTE_QUERY: Purpose and exact cause unknown, happens
+                * when you write 0x200 to 0x50c0 method 0x31c. */
+               if (status & 0x00000002) {
+                       nouveau_graph_trap_info(dev, &trap);
+                       if (nouveau_ratelimit())
+                               nouveau_graph_dump_trap_info(dev,
+                                               "PGRAPH_COMPUTE_QUERY", &trap);
+                       status &= ~0x00000002;
+                       nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000002);
+               }
 
+               /* Unknown, never seen: 0x4 */
+
+               /* ILLEGAL_MTHD: You used a wrong method for this class. */
+               if (status & 0x00000010) {
+                       nouveau_graph_trap_info(dev, &trap);
+                       if (nouveau_pgraph_intr_swmthd(dev, &trap))
+                               unhandled = 1;
+                       if (unhandled && nouveau_ratelimit())
+                               nouveau_graph_dump_trap_info(dev,
+                                               "PGRAPH_ILLEGAL_MTHD", &trap);
                        status &= ~0x00000010;
                        nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010);
                }
 
+               /* ILLEGAL_CLASS: You used a wrong class. */
+               if (status & 0x00000020) {
+                       nouveau_graph_trap_info(dev, &trap);
+                       if (nouveau_ratelimit())
+                               nouveau_graph_dump_trap_info(dev,
+                                               "PGRAPH_ILLEGAL_CLASS", &trap);
+                       status &= ~0x00000020;
+                       nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000020);
+               }
+
+               /* DOUBLE_NOTIFY: You tried to set a NOTIFY on another NOTIFY. */
+               if (status & 0x00000040) {
+                       nouveau_graph_trap_info(dev, &trap);
+                       if (nouveau_ratelimit())
+                               nouveau_graph_dump_trap_info(dev,
+                                               "PGRAPH_DOUBLE_NOTIFY", &trap);
+                       status &= ~0x00000040;
+                       nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000040);
+               }
+
+               /* CONTEXT_SWITCH: PGRAPH needs us to load a new context */
                if (status & 0x00001000) {
                        nv_wr32(dev, 0x400500, 0x00000000);
                        nv_wr32(dev, NV03_PGRAPH_INTR,
@@ -613,49 +1116,59 @@ nv50_pgraph_irq_handler(struct drm_device *dev)
                        status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
                }
 
-               if (status & 0x00100000) {
-                       nouveau_pgraph_intr_error(dev, nsource |
-                                       NV03_PGRAPH_NSOURCE_DATA_ERROR);
+               /* BUFFER_NOTIFY: Your m2mf transfer finished */
+               if (status & 0x00010000) {
+                       nouveau_graph_trap_info(dev, &trap);
+                       if (nouveau_ratelimit())
+                               nouveau_graph_dump_trap_info(dev,
+                                               "PGRAPH_BUFFER_NOTIFY", &trap);
+                       status &= ~0x00010000;
+                       nv_wr32(dev, NV03_PGRAPH_INTR, 0x00010000);
+               }
 
+               /* DATA_ERROR: Invalid value for this method, or invalid
+                * state in current PGRAPH context for this operation */
+               if (status & 0x00100000) {
+                       nouveau_graph_trap_info(dev, &trap);
+                       if (nouveau_ratelimit()) {
+                               nouveau_graph_dump_trap_info(dev,
+                                               "PGRAPH_DATA_ERROR", &trap);
+                               NV_INFO (dev, "PGRAPH_DATA_ERROR - ");
+                               nouveau_print_enum_names(nv_rd32(dev, 0x400110),
+                                               nv50_data_error_names);
+                               printk("\n");
+                       }
                        status &= ~0x00100000;
                        nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000);
                }
 
+               /* TRAP: Something bad happened in the middle of command
+                * execution.  Has a billion types, subtypes, and even
+                * subsubtypes. */
                if (status & 0x00200000) {
-                       int r;
-
-                       nouveau_pgraph_intr_error(dev, nsource |
-                                       NV03_PGRAPH_NSOURCE_PROTECTION_ERROR);
-
-                       NV_ERROR(dev, "magic set 1:\n");
-                       for (r = 0x408900; r <= 0x408910; r += 4)
-                               NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
-                                       nv_rd32(dev, r));
-                       nv_wr32(dev, 0x408900,
-                               nv_rd32(dev, 0x408904) | 0xc0000000);
-                       for (r = 0x408e08; r <= 0x408e24; r += 4)
-                               NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
-                                                       nv_rd32(dev, r));
-                       nv_wr32(dev, 0x408e08,
-                               nv_rd32(dev, 0x408e08) | 0xc0000000);
-
-                       NV_ERROR(dev, "magic set 2:\n");
-                       for (r = 0x409900; r <= 0x409910; r += 4)
-                               NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
-                                       nv_rd32(dev, r));
-                       nv_wr32(dev, 0x409900,
-                               nv_rd32(dev, 0x409904) | 0xc0000000);
-                       for (r = 0x409e08; r <= 0x409e24; r += 4)
-                               NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r,
-                                       nv_rd32(dev, r));
-                       nv_wr32(dev, 0x409e08,
-                               nv_rd32(dev, 0x409e08) | 0xc0000000);
-
+                       nv50_pgraph_trap_handler(dev);
                        status &= ~0x00200000;
-                       nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource);
                        nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000);
                }
 
+               /* Unknown, never seen: 0x00400000 */
+
+               /* SINGLE_STEP: Happens on every method if you turned on
+                * single stepping in 40008c */
+               if (status & 0x01000000) {
+                       nouveau_graph_trap_info(dev, &trap);
+                       if (nouveau_ratelimit())
+                               nouveau_graph_dump_trap_info(dev,
+                                               "PGRAPH_SINGLE_STEP", &trap);
+                       status &= ~0x01000000;
+                       nv_wr32(dev, NV03_PGRAPH_INTR, 0x01000000);
+               }
+
+               /* 0x02000000 happens when you pause a ctxprog...
+                * but the only way this can happen that I know is by
+                * poking the relevant MMIO register, and we don't
+                * do that. */
+
                if (status) {
                        NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n",
                                status);
@@ -672,7 +1185,8 @@ nv50_pgraph_irq_handler(struct drm_device *dev)
        }
 
        nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING);
-       nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31));
+       if (nv_rd32(dev, 0x400824) & (1 << 31))
+               nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31));
 }
 
 static void
index 2dc09dbd817d06d178343bf7280f7187115dd555..775a7017af6437da7c149dfda2a04d172704fdb2 100644 (file)
@@ -347,6 +347,20 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
                return -EBUSY;
        }
 
+       nv_wr32(dev, 0x100c80, 0x00040001);
+       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+               return -EBUSY;
+       }
+
+       nv_wr32(dev, 0x100c80, 0x00060001);
+       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+               return -EBUSY;
+       }
+
        return 0;
 }
 
@@ -384,6 +398,20 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
        }
 
        nv_wr32(dev, 0x100c80, 0x00000001);
+       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+               return;
+       }
+
+       nv_wr32(dev, 0x100c80, 0x00040001);
+       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+               return;
+       }
+
+       nv_wr32(dev, 0x100c80, 0x00060001);
        if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
                NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
                NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
@@ -449,9 +477,30 @@ void nouveau_mem_close(struct drm_device *dev)
        }
 }
 
-/*XXX won't work on BSD because of pci_read_config_dword */
 static uint32_t
-nouveau_mem_fb_amount_igp(struct drm_device *dev)
+nouveau_mem_detect_nv04(struct drm_device *dev)
+{
+       uint32_t boot0 = nv_rd32(dev, NV03_BOOT_0);
+
+       if (boot0 & 0x00000100)
+               return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024;
+
+       switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) {
+       case NV04_BOOT_0_RAM_AMOUNT_32MB:
+               return 32 * 1024 * 1024;
+       case NV04_BOOT_0_RAM_AMOUNT_16MB:
+               return 16 * 1024 * 1024;
+       case NV04_BOOT_0_RAM_AMOUNT_8MB:
+               return 8 * 1024 * 1024;
+       case NV04_BOOT_0_RAM_AMOUNT_4MB:
+               return 4 * 1024 * 1024;
+       }
+
+       return 0;
+}
+
+static uint32_t
+nouveau_mem_detect_nforce(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct pci_dev *bridge;
@@ -463,11 +512,11 @@ nouveau_mem_fb_amount_igp(struct drm_device *dev)
                return 0;
        }
 
-       if (dev_priv->flags&NV_NFORCE) {
+       if (dev_priv->flags & NV_NFORCE) {
                pci_read_config_dword(bridge, 0x7C, &mem);
                return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024;
        } else
-       if (dev_priv->flags&NV_NFORCE2) {
+       if (dev_priv->flags & NV_NFORCE2) {
                pci_read_config_dword(bridge, 0x84, &mem);
                return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024;
        }
@@ -477,50 +526,32 @@ nouveau_mem_fb_amount_igp(struct drm_device *dev)
 }
 
 /* returns the amount of FB ram in bytes */
-uint64_t nouveau_mem_fb_amount(struct drm_device *dev)
+int
+nouveau_mem_detect(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
-       uint32_t boot0;
-
-       switch (dev_priv->card_type) {
-       case NV_04:
-               boot0 = nv_rd32(dev, NV03_BOOT_0);
-               if (boot0 & 0x00000100)
-                       return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024;
-
-               switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) {
-               case NV04_BOOT_0_RAM_AMOUNT_32MB:
-                       return 32 * 1024 * 1024;
-               case NV04_BOOT_0_RAM_AMOUNT_16MB:
-                       return 16 * 1024 * 1024;
-               case NV04_BOOT_0_RAM_AMOUNT_8MB:
-                       return 8 * 1024 * 1024;
-               case NV04_BOOT_0_RAM_AMOUNT_4MB:
-                       return 4 * 1024 * 1024;
-               }
-               break;
-       case NV_10:
-       case NV_20:
-       case NV_30:
-       case NV_40:
-       case NV_50:
-       default:
-               if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
-                       return nouveau_mem_fb_amount_igp(dev);
-               } else {
-                       uint64_t mem;
-                       mem = (nv_rd32(dev, NV04_FIFO_DATA) &
-                                       NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >>
-                                       NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT;
-                       return mem * 1024 * 1024;
-               }
-               break;
+
+       if (dev_priv->card_type == NV_04) {
+               dev_priv->vram_size = nouveau_mem_detect_nv04(dev);
+       } else
+       if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
+               dev_priv->vram_size = nouveau_mem_detect_nforce(dev);
+       } else {
+               dev_priv->vram_size  = nv_rd32(dev, NV04_FIFO_DATA);
+               dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK;
+               if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
+                       dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12;
        }
 
-       NV_ERROR(dev,
-               "Unable to detect video ram size. Please report your setup to "
-                                                       DRIVER_EMAIL "\n");
-       return 0;
+       NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20));
+       if (dev_priv->vram_sys_base) {
+               NV_INFO(dev, "Stolen system memory at: 0x%010llx\n",
+                       dev_priv->vram_sys_base);
+       }
+
+       if (dev_priv->vram_size)
+               return 0;
+       return -ENOMEM;
 }
 
 #if __OS_HAS_AGP
@@ -631,15 +662,12 @@ nouveau_mem_init(struct drm_device *dev)
        spin_lock_init(&dev_priv->ttm.bo_list_lock);
        spin_lock_init(&dev_priv->tile.lock);
 
-       dev_priv->fb_available_size = nouveau_mem_fb_amount(dev);
-
+       dev_priv->fb_available_size = dev_priv->vram_size;
        dev_priv->fb_mappable_pages = dev_priv->fb_available_size;
        if (dev_priv->fb_mappable_pages > drm_get_resource_len(dev, 1))
                dev_priv->fb_mappable_pages = drm_get_resource_len(dev, 1);
        dev_priv->fb_mappable_pages >>= PAGE_SHIFT;
 
-       NV_INFO(dev, "%d MiB VRAM\n", (int)(dev_priv->fb_available_size >> 20));
-
        /* remove reserved space at end of vram from available amount */
        dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram;
        dev_priv->fb_aper_free = dev_priv->fb_available_size;
index ed1590577b6c0d73d425be296718b440f756895b..1d6ee8b55154c95aa763ed278c31b14da32fa9a7 100644 (file)
@@ -1,6 +1,7 @@
 #include "drmP.h"
 #include "nouveau_drv.h"
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 
 #define NV_CTXDMA_PAGE_SHIFT 12
 #define NV_CTXDMA_PAGE_SIZE  (1 << NV_CTXDMA_PAGE_SHIFT)
@@ -171,6 +172,24 @@ nouveau_sgdma_unbind(struct ttm_backend *be)
        }
        dev_priv->engine.instmem.finish_access(nvbe->dev);
 
+       if (dev_priv->card_type == NV_50) {
+               nv_wr32(dev, 0x100c80, 0x00050001);
+               if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+                       NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+                       NV_ERROR(dev, "0x100c80 = 0x%08x\n",
+                                               nv_rd32(dev, 0x100c80));
+                       return -EBUSY;
+               }
+
+               nv_wr32(dev, 0x100c80, 0x00000001);
+               if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+                       NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+                       NV_ERROR(dev, "0x100c80 = 0x%08x\n",
+                                               nv_rd32(dev, 0x100c80));
+                       return -EBUSY;
+               }
+       }
+
        nvbe->bound = false;
        return 0;
 }
index eb8f084d5f537ec4edeb2444b992763e15549ade..e1710640a2786b6051a8f305eabf9951bd699b63 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include <linux/swab.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "drm_sarea.h"
@@ -35,7 +36,6 @@
 #include "nouveau_drm.h"
 #include "nv50_display.h"
 
-static int nouveau_stub_init(struct drm_device *dev) { return 0; }
 static void nouveau_stub_takedown(struct drm_device *dev) {}
 
 static int nouveau_init_engine_ptrs(struct drm_device *dev)
@@ -277,8 +277,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->timer.init              = nv04_timer_init;
                engine->timer.read              = nv04_timer_read;
                engine->timer.takedown          = nv04_timer_takedown;
-               engine->fb.init                 = nouveau_stub_init;
-               engine->fb.takedown             = nouveau_stub_takedown;
+               engine->fb.init                 = nv50_fb_init;
+               engine->fb.takedown             = nv50_fb_takedown;
                engine->graph.grclass           = nv50_graph_grclass;
                engine->graph.init              = nv50_graph_init;
                engine->graph.takedown          = nv50_graph_takedown;
@@ -341,7 +341,7 @@ nouveau_card_init_channel(struct drm_device *dev)
 
        gpuobj = NULL;
        ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
-                                    0, nouveau_mem_fb_amount(dev),
+                                    0, dev_priv->vram_size,
                                     NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM,
                                     &gpuobj);
        if (ret)
@@ -427,6 +427,10 @@ nouveau_card_init(struct drm_device *dev)
                        goto out;
        }
 
+       ret = nouveau_mem_detect(dev);
+       if (ret)
+               goto out_bios;
+
        ret = nouveau_gpuobj_early_init(dev);
        if (ret)
                goto out_bios;
@@ -502,7 +506,7 @@ nouveau_card_init(struct drm_device *dev)
                else
                        ret = nv04_display_create(dev);
                if (ret)
-                       goto out_irq;
+                       goto out_channel;
        }
 
        ret = nouveau_backlight_init(dev);
@@ -516,6 +520,11 @@ nouveau_card_init(struct drm_device *dev)
 
        return 0;
 
+out_channel:
+       if (dev_priv->channel) {
+               nouveau_channel_free(dev_priv->channel);
+               dev_priv->channel = NULL;
+       }
 out_irq:
        drm_irq_uninstall(dev);
 out_fifo:
@@ -533,6 +542,7 @@ out_mc:
 out_gpuobj:
        nouveau_gpuobj_takedown(dev);
 out_mem:
+       nouveau_sgdma_takedown(dev);
        nouveau_mem_close(dev);
 out_instmem:
        engine->instmem.takedown(dev);
index a1d1ebb073d930e64342847ebd0a6add0ec0bc03..eba687f1099e24fcb164eb7a3f3e18550acc0508 100644 (file)
@@ -230,9 +230,9 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode)
        struct drm_framebuffer *fb = crtc->fb;
 
        /* Calculate our timings */
-       int horizDisplay        = (mode->crtc_hdisplay >> 3)    - 1;
-       int horizStart          = (mode->crtc_hsync_start >> 3)         - 1;
-       int horizEnd            = (mode->crtc_hsync_end >> 3)   - 1;
+       int horizDisplay        = (mode->crtc_hdisplay >> 3)            - 1;
+       int horizStart          = (mode->crtc_hsync_start >> 3)         + 1;
+       int horizEnd            = (mode->crtc_hsync_end >> 3)           + 1;
        int horizTotal          = (mode->crtc_htotal >> 3)              - 5;
        int horizBlankStart     = (mode->crtc_hdisplay >> 3)            - 1;
        int horizBlankEnd       = (mode->crtc_htotal >> 3)              - 1;
index 3da90c2c4e634910eba368bdb691bf9684cd5b95..813b25cec7269a6ff5e1ec5ec5aeb2875480dcb3 100644 (file)
@@ -118,8 +118,8 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
                return;
        }
 
-       width = ALIGN(image->width, 32);
-       dsize = (width * image->height) >> 5;
+       width = ALIGN(image->width, 8);
+       dsize = ALIGN(width * image->height, 32) >> 5;
 
        if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
            info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
@@ -136,8 +136,8 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
                         ((image->dx + image->width) & 0xffff));
        OUT_RING(chan, bg);
        OUT_RING(chan, fg);
-       OUT_RING(chan, (image->height << 16) | image->width);
        OUT_RING(chan, (image->height << 16) | width);
+       OUT_RING(chan, (image->height << 16) | image->width);
        OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
 
        while (dsize) {
index 6b2ef4a9fce17c135c17ebe410866ef8f60d4b30..500ccfd3a0b8c664b62cdc308ebaff0cc95d3042 100644 (file)
@@ -278,7 +278,7 @@ nv40_fifo_init_ramxx(struct drm_device *dev)
        default:
                nv_wr32(dev, 0x2230, 0);
                nv_wr32(dev, NV40_PFIFO_RAMFC,
-                       ((nouveau_mem_fb_amount(dev) - 512 * 1024 +
+                       ((dev_priv->vram_size - 512 * 1024 +
                          dev_priv->ramfc_offset) >> 16) | (3 << 16));
                break;
        }
index 53e8afe1dcd1a0dc6fedf5fd9d819edc87e4b918..0616c96e4b67834f9de49511d85c93614e0bf9ea 100644 (file)
@@ -335,6 +335,27 @@ nv40_graph_init(struct drm_device *dev)
        nv_wr32(dev, 0x400b38, 0x2ffff800);
        nv_wr32(dev, 0x400b3c, 0x00006000);
 
+       /* Tiling related stuff. */
+       switch (dev_priv->chipset) {
+       case 0x44:
+       case 0x4a:
+               nv_wr32(dev, 0x400bc4, 0x1003d888);
+               nv_wr32(dev, 0x400bbc, 0xb7a7b500);
+               break;
+       case 0x46:
+               nv_wr32(dev, 0x400bc4, 0x0000e024);
+               nv_wr32(dev, 0x400bbc, 0xb7a7b520);
+               break;
+       case 0x4c:
+       case 0x4e:
+       case 0x67:
+               nv_wr32(dev, 0x400bc4, 0x1003d888);
+               nv_wr32(dev, 0x400bbc, 0xb7a7b540);
+               break;
+       default:
+               break;
+       }
+
        /* Turn all the tiling regions off. */
        for (i = 0; i < pfb->num_tiles; i++)
                nv40_graph_set_region_tiling(dev, i, 0, 0, 0);
index 61a89f2dc5535ecf1d74f08b9c342727997c1766..649db4c1b690677689dbba5627781f9efc16ce8c 100644 (file)
@@ -143,7 +143,7 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan)
        }
 
        ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoVRAM, 0, 0x19,
-                                 0, nouveau_mem_fb_amount(dev));
+                                 0, dev_priv->vram_size);
        if (ret) {
                nv50_evo_channel_del(pchan);
                return ret;
@@ -231,7 +231,7 @@ nv50_display_init(struct drm_device *dev)
        /* This used to be in crtc unblank, but seems out of place there. */
        nv_wr32(dev, NV50_PDISPLAY_UNK_380, 0);
        /* RAM is clamped to 256 MiB. */
-       ram_amount = nouveau_mem_fb_amount(dev);
+       ram_amount = dev_priv->vram_size;
        NV_DEBUG_KMS(dev, "ram_amount %d\n", ram_amount);
        if (ram_amount > 256*1024*1024)
                ram_amount = 256*1024*1024;
@@ -522,15 +522,17 @@ int nv50_display_create(struct drm_device *dev)
        }
 
        for (i = 0 ; i < dcb->connector.entries; i++) {
-               if (i != 0 && dcb->connector.entry[i].index ==
-                             dcb->connector.entry[i - 1].index)
+               if (i != 0 && dcb->connector.entry[i].index2 ==
+                             dcb->connector.entry[i - 1].index2)
                        continue;
                nouveau_connector_create(dev, &dcb->connector.entry[i]);
        }
 
        ret = nv50_display_init(dev);
-       if (ret)
+       if (ret) {
+               nv50_display_destroy(dev);
                return ret;
+       }
 
        return 0;
 }
@@ -885,10 +887,12 @@ nv50_display_error_handler(struct drm_device *dev)
        nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR, 0x90000000);
 }
 
-static void
-nv50_display_irq_hotplug(struct drm_device *dev)
+void
+nv50_display_irq_hotplug_bh(struct work_struct *work)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct drm_nouveau_private *dev_priv =
+               container_of(work, struct drm_nouveau_private, hpd_work);
+       struct drm_device *dev = dev_priv->dev;
        struct drm_connector *connector;
        const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
        uint32_t unplug_mask, plug_mask, change_mask;
@@ -949,8 +953,10 @@ nv50_display_irq_handler(struct drm_device *dev)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        uint32_t delayed = 0;
 
-       while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG)
-               nv50_display_irq_hotplug(dev);
+       if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) {
+               if (!work_pending(&dev_priv->hpd_work))
+                       queue_work(dev_priv->wq, &dev_priv->hpd_work);
+       }
 
        while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) {
                uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0);
index 3ae8d0725f635d8b41b0e797f5b1b30f4c7a79d5..581d405ac014606041e253c7830c137569e63af6 100644 (file)
@@ -37,6 +37,7 @@
 
 void nv50_display_irq_handler(struct drm_device *dev);
 void nv50_display_irq_handler_bh(struct work_struct *work);
+void nv50_display_irq_hotplug_bh(struct work_struct *work);
 int nv50_display_init(struct drm_device *dev);
 int nv50_display_create(struct drm_device *dev);
 int nv50_display_destroy(struct drm_device *dev);
diff --git a/drivers/gpu/drm/nouveau/nv50_fb.c b/drivers/gpu/drm/nouveau/nv50_fb.c
new file mode 100644 (file)
index 0000000..a95e694
--- /dev/null
@@ -0,0 +1,32 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv50_fb_init(struct drm_device *dev)
+{
+       /* This is needed to get meaningful information from 100c90
+        * on traps. No idea what these values mean exactly. */
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+       switch (dev_priv->chipset) {
+       case 0x50:
+               nv_wr32(dev, 0x100c90, 0x0707ff);
+               break;
+       case 0xa5:
+       case 0xa8:
+               nv_wr32(dev, 0x100c90, 0x0d0fff);
+               break;
+       default:
+               nv_wr32(dev, 0x100c90, 0x1d07ff);
+               break;
+       }
+
+       return 0;
+}
+
+void
+nv50_fb_takedown(struct drm_device *dev)
+{
+}
index 993c7126fbded104b6ed3a16cac2e5f07f757474..a8c70e7e9184d1a0170188641f97a00db7102ed0 100644 (file)
@@ -157,8 +157,11 @@ nv50_fbcon_accel_init(struct fb_info *info)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_channel *chan = dev_priv->channel;
        struct nouveau_gpuobj *eng2d = NULL;
+       uint64_t fb;
        int ret, format;
 
+       fb = info->fix.smem_start - dev_priv->fb_phys + dev_priv->vm_vram_base;
+
        switch (info->var.bits_per_pixel) {
        case 8:
                format = 0xf3;
@@ -233,7 +236,7 @@ nv50_fbcon_accel_init(struct fb_info *info)
        BEGIN_RING(chan, NvSub2D, 0x0808, 3);
        OUT_RING(chan, 0);
        OUT_RING(chan, 0);
-       OUT_RING(chan, 0);
+       OUT_RING(chan, 1);
        BEGIN_RING(chan, NvSub2D, 0x081c, 1);
        OUT_RING(chan, 1);
        BEGIN_RING(chan, NvSub2D, 0x0840, 4);
@@ -248,9 +251,8 @@ nv50_fbcon_accel_init(struct fb_info *info)
        OUT_RING(chan, info->fix.line_length);
        OUT_RING(chan, info->var.xres_virtual);
        OUT_RING(chan, info->var.yres_virtual);
-       OUT_RING(chan, 0);
-       OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys +
-                        dev_priv->vm_vram_base);
+       OUT_RING(chan, upper_32_bits(fb));
+       OUT_RING(chan, lower_32_bits(fb));
        BEGIN_RING(chan, NvSub2D, 0x0230, 2);
        OUT_RING(chan, format);
        OUT_RING(chan, 1);
@@ -258,9 +260,8 @@ nv50_fbcon_accel_init(struct fb_info *info)
        OUT_RING(chan, info->fix.line_length);
        OUT_RING(chan, info->var.xres_virtual);
        OUT_RING(chan, info->var.yres_virtual);
-       OUT_RING(chan, 0);
-       OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys +
-                        dev_priv->vm_vram_base);
+       OUT_RING(chan, upper_32_bits(fb));
+       OUT_RING(chan, lower_32_bits(fb));
 
        return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c
new file mode 100644 (file)
index 0000000..c61782b
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2010 Red Hat Inc.
+ *
+ * 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: Ben Skeggs
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_hw.h"
+
+static int
+nv50_gpio_location(struct dcb_gpio_entry *gpio, uint32_t *reg, uint32_t *shift)
+{
+       const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
+
+       if (gpio->line > 32)
+               return -EINVAL;
+
+       *reg = nv50_gpio_reg[gpio->line >> 3];
+       *shift = (gpio->line & 7) << 2;
+       return 0;
+}
+
+int
+nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag)
+{
+       struct dcb_gpio_entry *gpio;
+       uint32_t r, s, v;
+
+       gpio = nouveau_bios_gpio_entry(dev, tag);
+       if (!gpio)
+               return -ENOENT;
+
+       if (nv50_gpio_location(gpio, &r, &s))
+               return -EINVAL;
+
+       v = nv_rd32(dev, r) >> (s + 2);
+       return ((v & 1) == (gpio->state[1] & 1));
+}
+
+int
+nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state)
+{
+       struct dcb_gpio_entry *gpio;
+       uint32_t r, s, v;
+
+       gpio = nouveau_bios_gpio_entry(dev, tag);
+       if (!gpio)
+               return -ENOENT;
+
+       if (nv50_gpio_location(gpio, &r, &s))
+               return -EINVAL;
+
+       v  = nv_rd32(dev, r) & ~(0x3 << s);
+       v |= (gpio->state[state] ^ 2) << s;
+       nv_wr32(dev, r, v);
+       return 0;
+}
index 857a09671a394c80a534d350b659261d8f56c223..b203d06f601f4ad9e314d4eadd21a25813cf8bce 100644 (file)
@@ -56,6 +56,10 @@ nv50_graph_init_intr(struct drm_device *dev)
 static void
 nv50_graph_init_regs__nv(struct drm_device *dev)
 {
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       uint32_t units = nv_rd32(dev, 0x1540);
+       int i;
+
        NV_DEBUG(dev, "\n");
 
        nv_wr32(dev, 0x400804, 0xc0000000);
@@ -65,6 +69,20 @@ nv50_graph_init_regs__nv(struct drm_device *dev)
        nv_wr32(dev, 0x405018, 0xc0000000);
        nv_wr32(dev, 0x402000, 0xc0000000);
 
+       for (i = 0; i < 16; i++) {
+               if (units & 1 << i) {
+                       if (dev_priv->chipset < 0xa0) {
+                               nv_wr32(dev, 0x408900 + (i << 12), 0xc0000000);
+                               nv_wr32(dev, 0x408e08 + (i << 12), 0xc0000000);
+                               nv_wr32(dev, 0x408314 + (i << 12), 0xc0000000);
+                       } else {
+                               nv_wr32(dev, 0x408600 + (i << 11), 0xc0000000);
+                               nv_wr32(dev, 0x408708 + (i << 11), 0xc0000000);
+                               nv_wr32(dev, 0x40831c + (i << 11), 0xc0000000);
+                       }
+               }
+       }
+
        nv_wr32(dev, 0x400108, 0xffffffff);
 
        nv_wr32(dev, 0x400824, 0x00004000);
@@ -229,10 +247,6 @@ nv50_graph_create_context(struct nouveau_channel *chan)
                nouveau_grctx_vals_load(dev, ctx);
        }
        nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12);
-       if ((dev_priv->chipset & 0xf0) == 0xa0)
-               nv_wo32(dev, ctx, 0x00004/4, 0x00000000);
-       else
-               nv_wo32(dev, ctx, 0x0011c/4, 0x00000000);
        dev_priv->engine.instmem.finish_access(dev);
 
        return 0;
@@ -396,9 +410,10 @@ struct nouveau_pgraph_object_class nv50_graph_grclass[] = {
        { 0x5039, false, NULL }, /* m2mf */
        { 0x502d, false, NULL }, /* 2d */
        { 0x50c0, false, NULL }, /* compute */
+       { 0x85c0, false, NULL }, /* compute (nva3, nva5, nva8) */
        { 0x5097, false, NULL }, /* tesla (nv50) */
-       { 0x8297, false, NULL }, /* tesla (nv80/nv90) */
-       { 0x8397, false, NULL }, /* tesla (nva0) */
-       { 0x8597, false, NULL }, /* tesla (nva8) */
+       { 0x8297, false, NULL }, /* tesla (nv8x/nv9x) */
+       { 0x8397, false, NULL }, /* tesla (nva0, nvaa, nvac) */
+       { 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */
        {}
 };
index d105fcd42ca0d06febbed6db006b254928f8521e..42a8fb20c1e6359d698107654b46ee015c7fb36a 100644 (file)
 #define CP_FLAG_AUTO_LOAD             ((2 * 32) + 5)
 #define CP_FLAG_AUTO_LOAD_NOT_PENDING 0
 #define CP_FLAG_AUTO_LOAD_PENDING     1
+#define CP_FLAG_NEWCTX                ((2 * 32) + 10)
+#define CP_FLAG_NEWCTX_BUSY           0
+#define CP_FLAG_NEWCTX_DONE           1
 #define CP_FLAG_XFER                  ((2 * 32) + 11)
 #define CP_FLAG_XFER_IDLE             0
 #define CP_FLAG_XFER_BUSY             1
-#define CP_FLAG_NEWCTX                ((2 * 32) + 12)
-#define CP_FLAG_NEWCTX_BUSY           0
-#define CP_FLAG_NEWCTX_DONE           1
 #define CP_FLAG_ALWAYS                ((2 * 32) + 13)
 #define CP_FLAG_ALWAYS_FALSE          0
 #define CP_FLAG_ALWAYS_TRUE           1
+#define CP_FLAG_INTR                  ((2 * 32) + 15)
+#define CP_FLAG_INTR_NOT_PENDING      0
+#define CP_FLAG_INTR_PENDING          1
 
 #define CP_CTX                   0x00100000
 #define CP_CTX_COUNT             0x000f0000
@@ -174,6 +177,7 @@ nv50_grctx_init(struct nouveau_grctx *ctx)
        case 0x96:
        case 0x98:
        case 0xa0:
+       case 0xa3:
        case 0xa5:
        case 0xa8:
        case 0xaa:
@@ -214,6 +218,8 @@ nv50_grctx_init(struct nouveau_grctx *ctx)
        cp_name(ctx, cp_setup_save);
        cp_set (ctx, UNK1D, SET);
        cp_wait(ctx, STATUS, BUSY);
+       cp_wait(ctx, INTR, PENDING);
+       cp_bra (ctx, STATUS, BUSY, cp_setup_save);
        cp_set (ctx, UNK01, SET);
        cp_set (ctx, SWAP_DIRECTION, SAVE);
 
@@ -269,7 +275,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
        int offset, base;
        uint32_t units = nv_rd32 (ctx->dev, 0x1540);
 
-       /* 0800 */
+       /* 0800: DISPATCH */
        cp_ctx(ctx, 0x400808, 7);
        gr_def(ctx, 0x400814, 0x00000030);
        cp_ctx(ctx, 0x400834, 0x32);
@@ -300,7 +306,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
                gr_def(ctx, 0x400b20, 0x0001629d);
        }
 
-       /* 0C00 */
+       /* 0C00: VFETCH */
        cp_ctx(ctx, 0x400c08, 0x2);
        gr_def(ctx, 0x400c08, 0x0000fe0c);
 
@@ -326,7 +332,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
        cp_ctx(ctx, 0x401540, 0x5);
        gr_def(ctx, 0x401550, 0x00001018);
 
-       /* 1800 */
+       /* 1800: STREAMOUT */
        cp_ctx(ctx, 0x401814, 0x1);
        gr_def(ctx, 0x401814, 0x000000ff);
        if (dev_priv->chipset == 0x50) {
@@ -359,6 +365,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
        case 0xac:
                gr_def(ctx, 0x401c00, 0x042500df);
                break;
+       case 0xa3:
        case 0xa5:
        case 0xa8:
                gr_def(ctx, 0x401c00, 0x142500df);
@@ -413,6 +420,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
                break;
        case 0x84:
        case 0xa0:
+       case 0xa3:
        case 0xa5:
        case 0xa8:
        case 0xaa:
@@ -641,7 +649,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
        if (dev_priv->chipset == 0x50)
                cp_ctx(ctx, 0x4063e0, 0x1);
 
-       /* 6800 */
+       /* 6800: M2MF */
        if (dev_priv->chipset < 0x90) {
                cp_ctx(ctx, 0x406814, 0x2b);
                gr_def(ctx, 0x406818, 0x00000f80);
@@ -787,6 +795,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
                                case 0xa5:
                                        gr_def(ctx, offset + 0x1c, 0x310c0000);
                                        break;
+                               case 0xa3:
                                case 0xa8:
                                case 0xaa:
                                case 0xac:
@@ -854,6 +863,8 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
                        else
                                gr_def(ctx, offset + 0x8, 0x05010202);
                        gr_def(ctx, offset + 0xc, 0x00030201);
+                       if (dev_priv->chipset == 0xa3)
+                               cp_ctx(ctx, base + 0x36c, 1);
 
                        cp_ctx(ctx, base + 0x400, 2);
                        gr_def(ctx, base + 0x404, 0x00000040);
@@ -1154,7 +1165,9 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
                nv50_graph_construct_gene_unk8(ctx);
                if (dev_priv->chipset == 0xa0)
                        xf_emit(ctx, 0x189, 0);
-               else if (dev_priv->chipset < 0xa8)
+               else if (dev_priv->chipset == 0xa3)
+                       xf_emit(ctx, 0xd5, 0);
+               else if (dev_priv->chipset == 0xa5)
                        xf_emit(ctx, 0x99, 0);
                else if (dev_priv->chipset == 0xaa)
                        xf_emit(ctx, 0x65, 0);
@@ -1192,6 +1205,8 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
                ctx->ctxvals_pos = offset + 4;
                if (dev_priv->chipset == 0xa0)
                        xf_emit(ctx, 0xa80, 0);
+               else if (dev_priv->chipset == 0xa3)
+                       xf_emit(ctx, 0xa7c, 0);
                else
                        xf_emit(ctx, 0xa7a, 0);
                xf_emit(ctx, 1, 0x3fffff);
@@ -1336,6 +1351,7 @@ nv50_graph_construct_gene_unk1(struct nouveau_grctx *ctx)
                xf_emit(ctx, 0x942, 0);
                break;
        case 0xa0:
+       case 0xa3:
                xf_emit(ctx, 0x2042, 0);
                break;
        case 0xa5:
index de1f5b0062c551c3f9480aa0efeb326634f3f635..5f21df31f3aa7f69beac46ff65dc11885a5f02bd 100644 (file)
@@ -63,9 +63,10 @@ nv50_instmem_init(struct drm_device *dev)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_channel *chan;
        uint32_t c_offset, c_size, c_ramfc, c_vmpd, c_base, pt_size;
+       uint32_t save_nv001700;
+       uint64_t v;
        struct nv50_instmem_priv *priv;
        int ret, i;
-       uint32_t v, save_nv001700;
 
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv)
@@ -76,17 +77,12 @@ nv50_instmem_init(struct drm_device *dev)
        for (i = 0x1700; i <= 0x1710; i += 4)
                priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i);
 
-       if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
-               dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12;
-       else
-               dev_priv->vram_sys_base = 0;
-
        /* Reserve the last MiB of VRAM, we should probably try to avoid
         * setting up the below tables over the top of the VBIOS image at
         * some point.
         */
        dev_priv->ramin_rsvd_vram = 1 << 20;
-       c_offset = nouveau_mem_fb_amount(dev) - dev_priv->ramin_rsvd_vram;
+       c_offset = dev_priv->vram_size - dev_priv->ramin_rsvd_vram;
        c_size   = 128 << 10;
        c_vmpd   = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x1400 : 0x200;
        c_ramfc  = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x0 : 0x20;
@@ -106,7 +102,7 @@ nv50_instmem_init(struct drm_device *dev)
        dev_priv->vm_gart_size = NV50_VM_BLOCK;
 
        dev_priv->vm_vram_base = dev_priv->vm_gart_base + dev_priv->vm_gart_size;
-       dev_priv->vm_vram_size = nouveau_mem_fb_amount(dev);
+       dev_priv->vm_vram_size = dev_priv->vram_size;
        if (dev_priv->vm_vram_size > NV50_VM_MAX_VRAM)
                dev_priv->vm_vram_size = NV50_VM_MAX_VRAM;
        dev_priv->vm_vram_size = roundup(dev_priv->vm_vram_size, NV50_VM_BLOCK);
@@ -189,8 +185,8 @@ nv50_instmem_init(struct drm_device *dev)
 
        i = 0;
        while (v < dev_priv->vram_sys_base + c_offset + c_size) {
-               BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v);
-               BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000);
+               BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, lower_32_bits(v));
+               BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, upper_32_bits(v));
                v += 0x1000;
                i += 8;
        }
index c2fff543b06f4a1c5269e4fa8e7cfb4b69f475d2..0c68698f23df7d94b86e0a0a6ceb1a45c7b9bdae 100644 (file)
@@ -211,7 +211,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
                        mode_ctl = 0x0200;
                break;
        case OUTPUT_DP:
-               mode_ctl |= 0x00050000;
+               mode_ctl |= (nv_encoder->dp.mc_unknown << 16);
                if (nv_encoder->dcb->sorconf.link & 1)
                        mode_ctl |= 0x00000800;
                else
@@ -274,6 +274,7 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
 int
 nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
 {
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_encoder *nv_encoder = NULL;
        struct drm_encoder *encoder;
        bool dum;
@@ -319,5 +320,27 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
        encoder->possible_crtcs = entry->heads;
        encoder->possible_clones = 0;
 
+       if (nv_encoder->dcb->type == OUTPUT_DP) {
+               uint32_t mc, or = nv_encoder->or;
+
+               if (dev_priv->chipset < 0x90 ||
+                   dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0)
+                       mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(or));
+               else
+                       mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(or));
+
+               switch ((mc & 0x00000f00) >> 8) {
+               case 8:
+               case 9:
+                       nv_encoder->dp.mc_unknown = (mc & 0x000f0000) >> 16;
+                       break;
+               default:
+                       break;
+               }
+
+               if (!nv_encoder->dp.mc_unknown)
+                       nv_encoder->dp.mc_unknown = 5;
+       }
+
        return 0;
 }
index 4c39a407aa4af51b6f3554c3a40fc9bd9acffb7f..e671d0e74d4c2c626b12d2daf0e2f7faf09b05c6 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <linux/firmware.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include "drmP.h"
 #include "drm.h"
index ed38262d9985e326e4bdffceb0fca5ea865e3362..3c91312dea9a00d8aa93b097d2d5d476487fb2d8 100644 (file)
@@ -50,7 +50,7 @@ $(obj)/r600_cs.o: $(obj)/r600_reg_safe.h
 radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \
        radeon_irq.o r300_cmdbuf.o r600_cp.o
 # add KMS driver
-radeon-y += radeon_device.o radeon_kms.o \
+radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
        radeon_atombios.o radeon_agp.o atombios_crtc.o radeon_combios.o \
        atom.o radeon_fence.o radeon_ttm.o radeon_object.o radeon_gart.o \
        radeon_legacy_crtc.o radeon_legacy_encoders.o radeon_connectors.o \
index d75788feac6c6a64fe042e0e7d3e4a446d8b2e26..1d569830ed99f0b278e5ae96de52971d020d7a8d 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 #define ATOM_DEBUG
 
 typedef struct {
        struct atom_context *ctx;
-
        uint32_t *ps, *ws;
        int ps_shift;
        uint16_t start;
+       unsigned last_jump;
+       unsigned long last_jump_jiffies;
+       bool abort;
 } atom_exec_context;
 
 int atom_debug = 0;
-static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params);
-void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params);
+static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params);
+int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params);
 
 static uint32_t atom_arg_mask[8] =
     { 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000,
@@ -604,12 +607,17 @@ static void atom_op_beep(atom_exec_context *ctx, int *ptr, int arg)
 static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg)
 {
        int idx = U8((*ptr)++);
+       int r = 0;
+
        if (idx < ATOM_TABLE_NAMES_CNT)
                SDEBUG("   table: %d (%s)\n", idx, atom_table_names[idx]);
        else
                SDEBUG("   table: %d\n", idx);
        if (U16(ctx->ctx->cmd_table + 4 + 2 * idx))
-               atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
+               r = atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
+       if (r) {
+               ctx->abort = true;
+       }
 }
 
 static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg)
@@ -673,6 +681,8 @@ static void atom_op_eot(atom_exec_context *ctx, int *ptr, int arg)
 static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
 {
        int execute = 0, target = U16(*ptr);
+       unsigned long cjiffies;
+
        (*ptr) += 2;
        switch (arg) {
        case ATOM_COND_ABOVE:
@@ -700,8 +710,25 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
        if (arg != ATOM_COND_ALWAYS)
                SDEBUG("   taken: %s\n", execute ? "yes" : "no");
        SDEBUG("   target: 0x%04X\n", target);
-       if (execute)
+       if (execute) {
+               if (ctx->last_jump == (ctx->start + target)) {
+                       cjiffies = jiffies;
+                       if (time_after(cjiffies, ctx->last_jump_jiffies)) {
+                               cjiffies -= ctx->last_jump_jiffies;
+                               if ((jiffies_to_msecs(cjiffies) > 1000)) {
+                                       DRM_ERROR("atombios stuck in loop for more than 1sec aborting\n");
+                                       ctx->abort = true;
+                               }
+                       } else {
+                               /* jiffies wrap around we will just wait a little longer */
+                               ctx->last_jump_jiffies = jiffies;
+                       }
+               } else {
+                       ctx->last_jump = ctx->start + target;
+                       ctx->last_jump_jiffies = jiffies;
+               }
                *ptr = ctx->start + target;
+       }
 }
 
 static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg)
@@ -881,11 +908,16 @@ static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg)
        uint8_t attr = U8((*ptr)++), shift;
        uint32_t saved, dst;
        int dptr = *ptr;
+       uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];
        SDEBUG("   dst: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+       /* op needs to full dst value */
+       dst = saved;
        shift = atom_get_src(ctx, attr, ptr);
        SDEBUG("   shift: %d\n", shift);
        dst <<= shift;
+       dst &= atom_arg_mask[dst_align];
+       dst >>= atom_arg_shift[dst_align];
        SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
@@ -895,11 +927,16 @@ static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg)
        uint8_t attr = U8((*ptr)++), shift;
        uint32_t saved, dst;
        int dptr = *ptr;
+       uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];
        SDEBUG("   dst: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+       /* op needs to full dst value */
+       dst = saved;
        shift = atom_get_src(ctx, attr, ptr);
        SDEBUG("   shift: %d\n", shift);
        dst >>= shift;
+       dst &= atom_arg_mask[dst_align];
+       dst >>= atom_arg_shift[dst_align];
        SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
@@ -1104,15 +1141,16 @@ static struct {
        atom_op_shr, ATOM_ARG_MC}, {
 atom_op_debug, 0},};
 
-static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params)
+static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params)
 {
        int base = CU16(ctx->cmd_table + 4 + 2 * index);
        int len, ws, ps, ptr;
        unsigned char op;
        atom_exec_context ectx;
+       int ret = 0;
 
        if (!base)
-               return;
+               return -EINVAL;
 
        len = CU16(base + ATOM_CT_SIZE_PTR);
        ws = CU8(base + ATOM_CT_WS_PTR);
@@ -1125,6 +1163,8 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3
        ectx.ps_shift = ps / 4;
        ectx.start = base;
        ectx.ps = params;
+       ectx.abort = false;
+       ectx.last_jump = 0;
        if (ws)
                ectx.ws = kzalloc(4 * ws, GFP_KERNEL);
        else
@@ -1137,6 +1177,12 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3
                        SDEBUG("%s @ 0x%04X\n", atom_op_names[op], ptr - 1);
                else
                        SDEBUG("[%d] @ 0x%04X\n", op, ptr - 1);
+               if (ectx.abort) {
+                       DRM_ERROR("atombios stuck executing %04X (len %d, WS %d, PS %d) @ 0x%04X\n",
+                               base, len, ws, ps, ptr - 1);
+                       ret = -EINVAL;
+                       goto free;
+               }
 
                if (op < ATOM_OP_CNT && op > 0)
                        opcode_table[op].func(&ectx, &ptr,
@@ -1150,12 +1196,16 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3
        debug_depth--;
        SDEBUG("<<\n");
 
+free:
        if (ws)
                kfree(ectx.ws);
+       return ret;
 }
 
-void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
+int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
 {
+       int r;
+
        mutex_lock(&ctx->mutex);
        /* reset reg block */
        ctx->reg_block = 0;
@@ -1163,8 +1213,9 @@ void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
        ctx->fb_base = 0;
        /* reset io mode */
        ctx->io_mode = ATOM_IO_MM;
-       atom_execute_table_locked(ctx, index, params);
+       r = atom_execute_table_locked(ctx, index, params);
        mutex_unlock(&ctx->mutex);
+       return r;
 }
 
 static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 };
@@ -1248,9 +1299,7 @@ int atom_asic_init(struct atom_context *ctx)
 
        if (!CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_INIT))
                return 1;
-       atom_execute_table(ctx, ATOM_CMD_INIT, ps);
-
-       return 0;
+       return atom_execute_table(ctx, ATOM_CMD_INIT, ps);
 }
 
 void atom_destroy(struct atom_context *ctx)
@@ -1260,12 +1309,16 @@ void atom_destroy(struct atom_context *ctx)
        kfree(ctx);
 }
 
-void atom_parse_data_header(struct atom_context *ctx, int index,
+bool atom_parse_data_header(struct atom_context *ctx, int index,
                            uint16_t * size, uint8_t * frev, uint8_t * crev,
                            uint16_t * data_start)
 {
        int offset = index * 2 + 4;
        int idx = CU16(ctx->data_table + offset);
+       u16 *mdt = (u16 *)(ctx->bios + ctx->data_table + 4);
+
+       if (!mdt[index])
+               return false;
 
        if (size)
                *size = CU16(idx);
@@ -1274,38 +1327,42 @@ void atom_parse_data_header(struct atom_context *ctx, int index,
        if (crev)
                *crev = CU8(idx + 3);
        *data_start = idx;
-       return;
+       return true;
 }
 
-void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
+bool atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
                           uint8_t * crev)
 {
        int offset = index * 2 + 4;
        int idx = CU16(ctx->cmd_table + offset);
+       u16 *mct = (u16 *)(ctx->bios + ctx->cmd_table + 4);
+
+       if (!mct[index])
+               return false;
 
        if (frev)
                *frev = CU8(idx + 2);
        if (crev)
                *crev = CU8(idx + 3);
-       return;
+       return true;
 }
 
 int atom_allocate_fb_scratch(struct atom_context *ctx)
 {
        int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware);
        uint16_t data_offset;
-       int usage_bytes;
+       int usage_bytes = 0;
        struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage;
 
-       atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset);
+       if (atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
+               firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
 
-       firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
+               DRM_DEBUG("atom firmware requested %08x %dkb\n",
+                         firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware,
+                         firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
 
-       DRM_DEBUG("atom firmware requested %08x %dkb\n",
-                 firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware,
-                 firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
-
-       usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
+               usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
+       }
        if (usage_bytes == 0)
                usage_bytes = 20 * 1024;
        /* allocate some scratch memory */
index bc73781423a17599fadf9e2bfa1bca556b5504ca..cd1b64ab5ca7c0c4b24e29bd4dd04e8b52387b16 100644 (file)
@@ -140,11 +140,13 @@ struct atom_context {
 extern int atom_debug;
 
 struct atom_context *atom_parse(struct card_info *, void *);
-void atom_execute_table(struct atom_context *, int, uint32_t *);
+int atom_execute_table(struct atom_context *, int, uint32_t *);
 int atom_asic_init(struct atom_context *);
 void atom_destroy(struct atom_context *);
-void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start);
-void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev);
+bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size,
+                           uint8_t *frev, uint8_t *crev, uint16_t *data_start);
+bool atom_parse_cmd_header(struct atom_context *ctx, int index,
+                          uint8_t *frev, uint8_t *crev);
 int atom_allocate_fb_scratch(struct atom_context *ctx);
 #include "atom-types.h"
 #include "atombios.h"
index 6732b5dd8ff4c48f1485fbc29a3499f5b07e85e8..27e2c715be11874a57c53553d28c70abe3feff15 100644 (file)
@@ -2912,7 +2912,7 @@ typedef struct _ATOM_ANALOG_TV_INFO_V1_2
   UCHAR                    ucTV_BootUpDefaultStandard; 
   UCHAR                    ucExt_TV_ASIC_ID;
   UCHAR                    ucExt_TV_ASIC_SlaveAddr;
-  ATOM_DTD_FORMAT          aModeTimings[MAX_SUPPORTED_TV_TIMING];
+  ATOM_DTD_FORMAT          aModeTimings[MAX_SUPPORTED_TV_TIMING_V1_2];
 }ATOM_ANALOG_TV_INFO_V1_2;
 
 typedef struct _ATOM_DPCD_INFO
index dd9fdf560611521aeb49d52f90da3fc3a59290df..a87990b3ae8410f3d59ae45145a462addd6872a6 100644 (file)
@@ -353,12 +353,55 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc,
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
+static void atombios_disable_ss(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;
+       u32 ss_cntl;
+
+       if (ASIC_IS_DCE4(rdev)) {
+               switch (radeon_crtc->pll_id) {
+               case ATOM_PPLL1:
+                       ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL);
+                       ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
+                       WREG32(EVERGREEN_P1PLL_SS_CNTL, ss_cntl);
+                       break;
+               case ATOM_PPLL2:
+                       ss_cntl = RREG32(EVERGREEN_P2PLL_SS_CNTL);
+                       ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
+                       WREG32(EVERGREEN_P2PLL_SS_CNTL, ss_cntl);
+                       break;
+               case ATOM_DCPLL:
+               case ATOM_PPLL_INVALID:
+                       return;
+               }
+       } else if (ASIC_IS_AVIVO(rdev)) {
+               switch (radeon_crtc->pll_id) {
+               case ATOM_PPLL1:
+                       ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL);
+                       ss_cntl &= ~1;
+                       WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl);
+                       break;
+               case ATOM_PPLL2:
+                       ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL);
+                       ss_cntl &= ~1;
+                       WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl);
+                       break;
+               case ATOM_DCPLL:
+               case ATOM_PPLL_INVALID:
+                       return;
+               }
+       }
+}
+
+
 union atom_enable_ss {
        ENABLE_LVDS_SS_PARAMETERS legacy;
        ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1;
 };
 
-static void atombios_set_ss(struct drm_crtc *crtc, int enable)
+static void atombios_enable_ss(struct drm_crtc *crtc)
 {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
@@ -387,9 +430,9 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable)
                                        step = dig->ss->step;
                                        delay = dig->ss->delay;
                                        range = dig->ss->range;
-                               } else if (enable)
+                               } else
                                        return;
-                       } else if (enable)
+                       } else
                                return;
                        break;
                }
@@ -406,13 +449,13 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable)
                args.v1.ucSpreadSpectrumDelay = delay;
                args.v1.ucSpreadSpectrumRange = range;
                args.v1.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
-               args.v1.ucEnable = enable;
+               args.v1.ucEnable = ATOM_ENABLE;
        } else {
                args.legacy.usSpreadSpectrumPercentage = cpu_to_le16(percentage);
                args.legacy.ucSpreadSpectrumType = type;
                args.legacy.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2;
                args.legacy.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4;
-               args.legacy.ucEnable = enable;
+               args.legacy.ucEnable = ATOM_ENABLE;
        }
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
@@ -478,10 +521,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                                /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
                                if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
                                        adjusted_clock = mode->clock * 2;
-                               /* LVDS PLL quirks */
-                               if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
-                                       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
-                                       pll->algo = dig->pll_algo;
+                               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
+                                       pll->algo = PLL_ALGO_LEGACY;
+                                       pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
                                }
                        } else {
                                if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
@@ -503,8 +545,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                int index;
 
                index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
-               atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
-                                     &crev);
+               if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
+                                          &crev))
+                       return adjusted_clock;
 
                memset(&args, 0, sizeof(args));
 
@@ -542,11 +585,16 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                                        }
                                } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
                                        /* may want to enable SS on DP/eDP eventually */
-                                       args.v3.sInput.ucDispPllConfig |=
-                                               DISPPLL_CONFIG_SS_ENABLE;
-                                       if (mode->clock > 165000)
+                                       /*args.v3.sInput.ucDispPllConfig |=
+                                               DISPPLL_CONFIG_SS_ENABLE;*/
+                                       if (encoder_mode == ATOM_ENCODER_MODE_DP)
                                                args.v3.sInput.ucDispPllConfig |=
-                                                       DISPPLL_CONFIG_DUAL_LINK;
+                                                       DISPPLL_CONFIG_COHERENT_MODE;
+                                       else {
+                                               if (mode->clock > 165000)
+                                                       args.v3.sInput.ucDispPllConfig |=
+                                                               DISPPLL_CONFIG_DUAL_LINK;
+                                       }
                                }
                                atom_execute_table(rdev->mode_info.atom_context,
                                                   index, (uint32_t *)&args);
@@ -592,8 +640,9 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)
        memset(&args, 0, sizeof(args));
 
        index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
-       atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
-                             &crev);
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
+                                  &crev))
+               return;
 
        switch (frev) {
        case 1:
@@ -667,8 +716,9 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
                           &ref_div, &post_div);
 
        index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
-       atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
-                             &crev);
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
+                                  &crev))
+               return;
 
        switch (frev) {
        case 1:
@@ -1083,15 +1133,12 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
 
        /* TODO color tiling */
 
-       /* pick pll */
-       radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
-
-       atombios_set_ss(crtc, 0);
+       atombios_disable_ss(crtc);
        /* always set DCPLL */
        if (ASIC_IS_DCE4(rdev))
                atombios_crtc_set_dcpll(crtc);
        atombios_crtc_set_pll(crtc, adjusted_mode);
-       atombios_set_ss(crtc, 1);
+       atombios_enable_ss(crtc);
 
        if (ASIC_IS_DCE4(rdev))
                atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
@@ -1120,6 +1167,11 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
 
 static void atombios_crtc_prepare(struct drm_crtc *crtc)
 {
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+
+       /* pick pll */
+       radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
+
        atombios_lock_crtc(crtc, ATOM_ENABLE);
        atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 }
index 8a133bda00a25b092e764f1eec2bca80c57cb569..28b31c64f48dd4eee064356c1d8a2bd840165f0d 100644 (file)
@@ -745,14 +745,14 @@ void dp_link_train(struct drm_encoder *encoder,
                          >> DP_TRAIN_PRE_EMPHASIS_SHIFT);
 
        /* disable the training pattern on the sink */
+       dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE);
+
+       /* disable the training pattern on the source */
        if (ASIC_IS_DCE4(rdev))
                atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE);
        else
                radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
                                          dig_connector->dp_clock, enc_id, 0);
-
-       radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
-                                 dig_connector->dp_clock, enc_id, 0);
 }
 
 int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
index bd2e7aa85c1d66e710b1b6f97c7652b941db6d34..e8f447e20507313ed0367748b8fa585fdeec2bbf 100644 (file)
  */
 #include <linux/firmware.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "radeon_drm.h"
 #include "rv770d.h"
 #include "atom.h"
@@ -436,7 +438,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
 
 int evergreen_mc_init(struct radeon_device *rdev)
 {
-       fixed20_12 a;
        u32 tmp;
        int chansize, numchan;
 
@@ -481,12 +482,8 @@ int evergreen_mc_init(struct radeon_device *rdev)
                rdev->mc.real_vram_size = rdev->mc.aper_size;
        }
        r600_vram_gtt_location(rdev, &rdev->mc);
-       /* FIXME: we should enforce default clock in case GPU is not in
-        * default setup
-        */
-       a.full = rfixed_const(100);
-       rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
-       rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+       radeon_update_bandwidth_info(rdev);
+
        return 0;
 }
 
@@ -746,6 +743,7 @@ int evergreen_init(struct radeon_device *rdev)
 
 void evergreen_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        evergreen_suspend(rdev);
 #if 0
        r600_blit_fini(rdev);
index 91eb762eb3f918625f3b17f0a8360551d628480e..cf60c0b3ef155a29d44a3e76fb634ea059efd64c 100644 (file)
  *          Jerome Glisse
  */
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_drm.h"
 #include "radeon_reg.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "r100d.h"
 #include "rs100d.h"
 #include "rv200d.h"
@@ -235,9 +237,9 @@ int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
 
 void r100_pci_gart_fini(struct radeon_device *rdev)
 {
+       radeon_gart_fini(rdev);
        r100_pci_gart_disable(rdev);
        radeon_gart_table_ram_free(rdev);
-       radeon_gart_fini(rdev);
 }
 
 int r100_irq_set(struct radeon_device *rdev)
@@ -312,10 +314,12 @@ int r100_irq_process(struct radeon_device *rdev)
                /* Vertical blank interrupts */
                if (status & RADEON_CRTC_VBLANK_STAT) {
                        drm_handle_vblank(rdev->ddev, 0);
+                       rdev->pm.vblank_sync = true;
                        wake_up(&rdev->irq.vblank_queue);
                }
                if (status & RADEON_CRTC2_VBLANK_STAT) {
                        drm_handle_vblank(rdev->ddev, 1);
+                       rdev->pm.vblank_sync = true;
                        wake_up(&rdev->irq.vblank_queue);
                }
                if (status & RADEON_FP_DETECT_STAT) {
@@ -741,6 +745,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
        udelay(10);
        rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR);
        rdev->cp.wptr = RREG32(RADEON_CP_RB_WPTR);
+       /* protect against crazy HW on resume */
+       rdev->cp.wptr &= rdev->cp.ptr_mask;
        /* Set cp mode to bus mastering & enable cp*/
        WREG32(RADEON_CP_CSQ_MODE,
               REG_SET(RADEON_INDIRECT2_START, indirect2_start) |
@@ -1804,6 +1810,7 @@ void r100_set_common_regs(struct radeon_device *rdev)
 {
        struct drm_device *dev = rdev->ddev;
        bool force_dac2 = false;
+       u32 tmp;
 
        /* set these so they don't interfere with anything */
        WREG32(RADEON_OV0_SCALE_CNTL, 0);
@@ -1875,6 +1882,12 @@ void r100_set_common_regs(struct radeon_device *rdev)
                WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
                WREG32(RADEON_DAC_CNTL2, dac2_cntl);
        }
+
+       /* switch PM block to ACPI mode */
+       tmp = RREG32_PLL(RADEON_PLL_PWRMGT_CNTL);
+       tmp &= ~RADEON_PM_MODE_SEL;
+       WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp);
+
 }
 
 /*
@@ -2022,6 +2035,7 @@ void r100_mc_init(struct radeon_device *rdev)
        radeon_vram_location(rdev, &rdev->mc, base);
        if (!(rdev->flags & RADEON_IS_AGP))
                radeon_gtt_location(rdev, &rdev->mc);
+       radeon_update_bandwidth_info(rdev);
 }
 
 
@@ -2385,6 +2399,8 @@ void r100_bandwidth_update(struct radeon_device *rdev)
        uint32_t pixel_bytes1 = 0;
        uint32_t pixel_bytes2 = 0;
 
+       radeon_update_display_priority(rdev);
+
        if (rdev->mode_info.crtcs[0]->base.enabled) {
                mode1 = &rdev->mode_info.crtcs[0]->base.mode;
                pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8;
@@ -2413,11 +2429,8 @@ void r100_bandwidth_update(struct radeon_device *rdev)
        /*
         * determine is there is enough bw for current mode
         */
-       mclk_ff.full = rfixed_const(rdev->clock.default_mclk);
-       temp_ff.full = rfixed_const(100);
-       mclk_ff.full = rfixed_div(mclk_ff, temp_ff);
-       sclk_ff.full = rfixed_const(rdev->clock.default_sclk);
-       sclk_ff.full = rfixed_div(sclk_ff, temp_ff);
+       sclk_ff = rdev->pm.sclk;
+       mclk_ff = rdev->pm.mclk;
 
        temp = (rdev->mc.vram_width / 8) * (rdev->mc.vram_is_ddr ? 2 : 1);
        temp_ff.full = rfixed_const(temp);
@@ -2878,7 +2891,7 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
 {
        struct radeon_bo *robj;
        unsigned long size;
-       unsigned u, i, w, h;
+       unsigned u, i, w, h, d;
        int ret;
 
        for (u = 0; u < track->num_texture; u++) {
@@ -2910,20 +2923,25 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
                        h = h / (1 << i);
                        if (track->textures[u].roundup_h)
                                h = roundup_pow_of_two(h);
+                       if (track->textures[u].tex_coord_type == 1) {
+                               d = (1 << track->textures[u].txdepth) / (1 << i);
+                               if (!d)
+                                       d = 1;
+                       } else {
+                               d = 1;
+                       }
                        if (track->textures[u].compress_format) {
 
-                               size += r100_track_compress_size(track->textures[u].compress_format, w, h);
+                               size += r100_track_compress_size(track->textures[u].compress_format, w, h) * d;
                                /* compressed textures are block based */
                        } else
-                               size += w * h;
+                               size += w * h * d;
                }
                size *= track->textures[u].cpp;
 
                switch (track->textures[u].tex_coord_type) {
                case 0:
-                       break;
                case 1:
-                       size *= (1 << track->textures[u].txdepth);
                        break;
                case 2:
                        if (track->separate_cube) {
@@ -2957,7 +2975,7 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
 
        for (i = 0; i < track->num_cb; i++) {
                if (track->cb[i].robj == NULL) {
-                       if (!(track->fastfill || track->color_channel_mask ||
+                       if (!(track->zb_cb_clear || track->color_channel_mask ||
                              track->blend_read_enable)) {
                                continue;
                        }
@@ -2994,7 +3012,11 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
                }
        }
        prim_walk = (track->vap_vf_cntl >> 4) & 0x3;
-       nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
+       if (track->vap_vf_cntl & (1 << 14)) {
+               nverts = track->vap_alt_nverts;
+       } else {
+               nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
+       }
        switch (prim_walk) {
        case 1:
                for (i = 0; i < track->num_arrays; i++) {
@@ -3440,6 +3462,7 @@ int r100_suspend(struct radeon_device *rdev)
 
 void r100_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r100_cp_fini(rdev);
        r100_wb_fini(rdev);
        r100_ib_fini(rdev);
index b27a6999d21938413cd8ef8258e5b26d85499d93..f47cdca1c004400586d8eafcad3175d509a504fc 100644 (file)
@@ -64,6 +64,7 @@ struct r100_cs_track {
        unsigned                        maxy;
        unsigned                        vtx_size;
        unsigned                        vap_vf_cntl;
+       unsigned                        vap_alt_nverts;
        unsigned                        immd_dwords;
        unsigned                        num_arrays;
        unsigned                        max_indx;
@@ -74,7 +75,7 @@ struct r100_cs_track {
        struct r100_cs_track_texture    textures[R300_TRACK_MAX_TEXTURE];
        bool                            z_enabled;
        bool                            separate_cube;
-       bool                            fastfill;
+       bool                            zb_cb_clear;
        bool                            blend_read_enable;
 };
 
index 1146c9909c2c11457f583edf73e8b5c31e0ab5b1..85617c3112127e09bd23442d6b84566ac99a29bd 100644 (file)
@@ -30,6 +30,7 @@
 #include "radeon_drm.h"
 #include "radeon_reg.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 
 #include "r100d.h"
 #include "r200_reg_safe.h"
index 4cef90cd74e5176fe01b41b37eb38d1050db1fb4..a5ff8076b423bb477a38bc224bc6d14340a03c24 100644 (file)
  *          Jerome Glisse
  */
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_reg.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "radeon_drm.h"
 #include "r100_track.h"
 #include "r300d.h"
@@ -164,9 +166,9 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev)
 
 void rv370_pcie_gart_fini(struct radeon_device *rdev)
 {
+       radeon_gart_fini(rdev);
        rv370_pcie_gart_disable(rdev);
        radeon_gart_table_vram_free(rdev);
-       radeon_gart_fini(rdev);
 }
 
 void r300_fence_ring_emit(struct radeon_device *rdev,
@@ -322,12 +324,12 @@ void r300_gpu_init(struct radeon_device *rdev)
        uint32_t gb_tile_config, tmp;
 
        r100_hdp_reset(rdev);
-       /* FIXME: rv380 one pipes ? */
-       if ((rdev->family == CHIP_R300) || (rdev->family == CHIP_R350)) {
+       if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) ||
+           (rdev->family == CHIP_R350 && rdev->pdev->device != 0x4148)) {
                /* r300,r350 */
                rdev->num_gb_pipes = 2;
        } else {
-               /* rv350,rv370,rv380 */
+               /* rv350,rv370,rv380,r300 AD, r350 AH */
                rdev->num_gb_pipes = 1;
        }
        rdev->num_z_pipes = 1;
@@ -481,6 +483,7 @@ void r300_mc_init(struct radeon_device *rdev)
        radeon_vram_location(rdev, &rdev->mc, base);
        if (!(rdev->flags & RADEON_IS_AGP))
                radeon_gtt_location(rdev, &rdev->mc);
+       radeon_update_bandwidth_info(rdev);
 }
 
 void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes)
@@ -726,6 +729,12 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                /* VAP_VF_MAX_VTX_INDX */
                track->max_indx = idx_value & 0x00FFFFFFUL;
                break;
+       case 0x2088:
+               /* VAP_ALT_NUM_VERTICES - only valid on r500 */
+               if (p->rdev->family < CHIP_RV515)
+                       goto fail;
+               track->vap_alt_nverts = idx_value & 0xFFFFFF;
+               break;
        case 0x43E4:
                /* SC_SCISSOR1 */
                track->maxy = ((idx_value >> 13) & 0x1FFF) + 1;
@@ -763,7 +772,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                tmp = idx_value & ~(0x7 << 16);
                tmp |= tile_flags;
                ib[idx] = tmp;
-
                i = (reg - 0x4E38) >> 2;
                track->cb[i].pitch = idx_value & 0x3FFE;
                switch (((idx_value >> 21) & 0xF)) {
@@ -1036,7 +1044,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                break;
        case 0x4d1c:
                /* ZB_BW_CNTL */
-               track->fastfill = !!(idx_value & (1 << 2));
+               track->zb_cb_clear = !!(idx_value & (1 << 5));
                break;
        case 0x4e04:
                /* RB3D_BLENDCNTL */
@@ -1048,11 +1056,13 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                        break;
                /* fallthrough do not move */
        default:
-               printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
-                      reg, idx);
-               return -EINVAL;
+               goto fail;
        }
        return 0;
+fail:
+       printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
+              reg, idx);
+       return -EINVAL;
 }
 
 static int r300_packet3_check(struct radeon_cs_parser *p,
@@ -1334,6 +1344,7 @@ int r300_suspend(struct radeon_device *rdev)
 
 void r300_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r100_cp_fini(rdev);
        r100_wb_fini(rdev);
        r100_ib_fini(rdev);
index ea46d558e8f394040cd9d7b3503c8c3c2e1be5da..c5c2742e41405514364b34bfdbc39c725bc195b7 100644 (file)
@@ -921,7 +921,7 @@ static int r300_scratch(drm_radeon_private_t *dev_priv,
 
        ptr_addr = drm_buffer_read_object(cmdbuf->buffer,
                        sizeof(stack_ptr_addr), &stack_ptr_addr);
-       ref_age_base = (u32 *)(unsigned long)*ptr_addr;
+       ref_age_base = (u32 *)(unsigned long)get_unaligned(ptr_addr);
 
        for (i=0; i < header.scratch.n_bufs; i++) {
                buf_idx = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0);
index c7593b8f58eeaf61d41c8860fc0f74306071564e..c2bda4ad62e74092d348076dd67a848d09c7c379 100644 (file)
  *          Jerome Glisse
  */
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "radeon_reg.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "atom.h"
 #include "r100d.h"
 #include "r420d.h"
@@ -57,6 +59,12 @@ void r420_pipes_init(struct radeon_device *rdev)
        /* get max number of pipes */
        gb_pipe_select = RREG32(0x402C);
        num_pipes = ((gb_pipe_select >> 12) & 3) + 1;
+
+       /* SE chips have 1 pipe */
+       if ((rdev->pdev->device == 0x5e4c) ||
+           (rdev->pdev->device == 0x5e4f))
+               num_pipes = 1;
+
        rdev->num_gb_pipes = num_pipes;
        tmp = 0;
        switch (num_pipes) {
@@ -266,6 +274,7 @@ int r420_suspend(struct radeon_device *rdev)
 
 void r420_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r100_cp_fini(rdev);
        r100_wb_fini(rdev);
        r100_ib_fini(rdev);
index 2b8a5dd1351672bbacbf260d33441910514ff7a9..3c44b8d393180283c71f566656b2edc78d0017bb 100644 (file)
@@ -27,6 +27,7 @@
  */
 #include "drmP.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "atom.h"
 #include "r520d.h"
 
@@ -121,19 +122,13 @@ static void r520_vram_get_type(struct radeon_device *rdev)
 
 void r520_mc_init(struct radeon_device *rdev)
 {
-       fixed20_12 a;
 
        r520_vram_get_type(rdev);
        r100_vram_init_sizes(rdev);
        radeon_vram_location(rdev, &rdev->mc, 0);
        if (!(rdev->flags & RADEON_IS_AGP))
                radeon_gtt_location(rdev, &rdev->mc);
-       /* FIXME: we should enforce default clock in case GPU is not in
-        * default setup
-        */
-       a.full = rfixed_const(100);
-       rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
-       rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+       radeon_update_bandwidth_info(rdev);
 }
 
 void r520_mc_program(struct radeon_device *rdev)
index c52290197292a1a958d05dcd3896587055542b8b..8f3454e2056ae7520aea7dbb960833aaa72ad53c 100644 (file)
  *          Alex Deucher
  *          Jerome Glisse
  */
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/firmware.h>
 #include <linux/platform_device.h>
 #include "drmP.h"
 #include "radeon_drm.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "radeon_mode.h"
 #include "r600d.h"
 #include "atom.h"
@@ -491,9 +493,9 @@ void r600_pcie_gart_disable(struct radeon_device *rdev)
 
 void r600_pcie_gart_fini(struct radeon_device *rdev)
 {
+       radeon_gart_fini(rdev);
        r600_pcie_gart_disable(rdev);
        radeon_gart_table_vram_free(rdev);
-       radeon_gart_fini(rdev);
 }
 
 void r600_agp_enable(struct radeon_device *rdev)
@@ -675,7 +677,6 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
 
 int r600_mc_init(struct radeon_device *rdev)
 {
-       fixed20_12 a;
        u32 tmp;
        int chansize, numchan;
 
@@ -719,14 +720,10 @@ int r600_mc_init(struct radeon_device *rdev)
                rdev->mc.real_vram_size = rdev->mc.aper_size;
        }
        r600_vram_gtt_location(rdev, &rdev->mc);
-       /* FIXME: we should enforce default clock in case GPU is not in
-        * default setup
-        */
-       a.full = rfixed_const(100);
-       rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
-       rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+
        if (rdev->flags & RADEON_IS_IGP)
                rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
+       radeon_update_bandwidth_info(rdev);
        return 0;
 }
 
@@ -1132,6 +1129,7 @@ void r600_gpu_init(struct radeon_device *rdev)
        /* Setup pipes */
        WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
        WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+       WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
 
        tmp = R6XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8);
        WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK);
@@ -2119,6 +2117,7 @@ int r600_init(struct radeon_device *rdev)
 
 void r600_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r600_audio_fini(rdev);
        r600_blit_fini(rdev);
        r600_cp_fini(rdev);
@@ -2398,19 +2397,19 @@ static void r600_disable_interrupt_state(struct radeon_device *rdev)
                WREG32(DC_HPD4_INT_CONTROL, tmp);
                if (ASIC_IS_DCE32(rdev)) {
                        tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY;
-                       WREG32(DC_HPD5_INT_CONTROL, 0);
+                       WREG32(DC_HPD5_INT_CONTROL, tmp);
                        tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY;
-                       WREG32(DC_HPD6_INT_CONTROL, 0);
+                       WREG32(DC_HPD6_INT_CONTROL, tmp);
                }
        } else {
                WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
                WREG32(DACB_AUTODETECT_INT_CONTROL, 0);
                tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
-               WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, 0);
+               WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
                tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
-               WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, 0);
+               WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
                tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
-               WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, 0);
+               WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
        }
 }
 
@@ -2765,6 +2764,7 @@ restart_ih:
                        case 0: /* D1 vblank */
                                if (disp_int & LB_D1_VBLANK_INTERRUPT) {
                                        drm_handle_vblank(rdev->ddev, 0);
+                                       rdev->pm.vblank_sync = true;
                                        wake_up(&rdev->irq.vblank_queue);
                                        disp_int &= ~LB_D1_VBLANK_INTERRUPT;
                                        DRM_DEBUG("IH: D1 vblank\n");
@@ -2786,6 +2786,7 @@ restart_ih:
                        case 0: /* D2 vblank */
                                if (disp_int & LB_D2_VBLANK_INTERRUPT) {
                                        drm_handle_vblank(rdev->ddev, 1);
+                                       rdev->pm.vblank_sync = true;
                                        wake_up(&rdev->irq.vblank_queue);
                                        disp_int &= ~LB_D2_VBLANK_INTERRUPT;
                                        DRM_DEBUG("IH: D2 vblank\n");
@@ -2834,14 +2835,14 @@ restart_ih:
                                break;
                        case 10:
                                if (disp_int_cont2 & DC_HPD5_INTERRUPT) {
-                                       disp_int_cont &= ~DC_HPD5_INTERRUPT;
+                                       disp_int_cont2 &= ~DC_HPD5_INTERRUPT;
                                        queue_hotplug = true;
                                        DRM_DEBUG("IH: HPD5\n");
                                }
                                break;
                        case 12:
                                if (disp_int_cont2 & DC_HPD6_INTERRUPT) {
-                                       disp_int_cont &= ~DC_HPD6_INTERRUPT;
+                                       disp_int_cont2 &= ~DC_HPD6_INTERRUPT;
                                        queue_hotplug = true;
                                        DRM_DEBUG("IH: HPD6\n");
                                }
index db928016d034cc1e5fce5eba0718cc1a45dc3c0a..1d898051c6310fee6713e90502432a47b0c7c330 100644 (file)
@@ -35,7 +35,7 @@
  */
 static int r600_audio_chipset_supported(struct radeon_device *rdev)
 {
-       return rdev->family >= CHIP_R600
+       return (rdev->family >= CHIP_R600 && rdev->family < CHIP_CEDAR)
                || rdev->family == CHIP_RS600
                || rdev->family == CHIP_RS690
                || rdev->family == CHIP_RS740;
@@ -181,41 +181,6 @@ int r600_audio_init(struct radeon_device *rdev)
        return 0;
 }
 
-/*
- * determin how the encoders and audio interface is wired together
- */
-int r600_audio_tmds_index(struct drm_encoder *encoder)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct drm_encoder *other;
-
-       switch (radeon_encoder->encoder_id) {
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-               return 0;
-
-       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-               /* special case check if an TMDS1 is present */
-               list_for_each_entry(other, &dev->mode_config.encoder_list, head) {
-                       if (to_radeon_encoder(other)->encoder_id ==
-                               ENCODER_OBJECT_ID_INTERNAL_TMDS1)
-                               return 1;
-               }
-               return 0;
-
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-               return 1;
-
-       default:
-               DRM_ERROR("Unsupported encoder type 0x%02X\n",
-                         radeon_encoder->encoder_id);
-               return -1;
-       }
-}
-
 /*
  * atach the audio codec to the clock source of the encoder
  */
@@ -224,6 +189,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
        int base_rate = 48000;
 
        switch (radeon_encoder->encoder_id) {
@@ -231,32 +197,34 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
        case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
                WREG32_P(R600_AUDIO_TIMING, 0, ~0x301);
                break;
-
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
                WREG32_P(R600_AUDIO_TIMING, 0x100, ~0x301);
                break;
-
        default:
                DRM_ERROR("Unsupported encoder type 0x%02X\n",
                          radeon_encoder->encoder_id);
                return;
        }
 
-       switch (r600_audio_tmds_index(encoder)) {
+       switch (dig->dig_encoder) {
        case 0:
-               WREG32(R600_AUDIO_PLL1_MUL, base_rate*50);
-               WREG32(R600_AUDIO_PLL1_DIV, clock*100);
+               WREG32(R600_AUDIO_PLL1_MUL, base_rate * 50);
+               WREG32(R600_AUDIO_PLL1_DIV, clock * 100);
                WREG32(R600_AUDIO_CLK_SRCSEL, 0);
                break;
 
        case 1:
-               WREG32(R600_AUDIO_PLL2_MUL, base_rate*50);
-               WREG32(R600_AUDIO_PLL2_DIV, clock*100);
+               WREG32(R600_AUDIO_PLL2_MUL, base_rate * 50);
+               WREG32(R600_AUDIO_PLL2_DIV, clock * 100);
                WREG32(R600_AUDIO_CLK_SRCSEL, 1);
                break;
+       default:
+               dev_err(rdev->dev, "Unsupported DIG on encoder 0x%02X\n",
+                         radeon_encoder->encoder_id);
+               return;
        }
 }
 
index a112c59f9d824988a8f0a399380c4041eace903d..0271b53fa2ddb0b49f7c99539287827d38197fb7 100644 (file)
@@ -1,7 +1,42 @@
+/*
+ * Copyright 2009 Advanced Micro Devices, Inc.
+ *
+ * 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 (including the next
+ * paragraph) 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) AND/OR ITS SUPPLIERS 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:
+ *     Alex Deucher <alexander.deucher@amd.com>
+ */
 
 #include <linux/types.h>
 #include <linux/kernel.h>
 
+/*
+ * R6xx+ cards need to use the 3D engine to blit data which requires
+ * quite a bit of hw state setup.  Rather than pull the whole 3D driver
+ * (which normally generates the 3D state) into the DRM, we opt to use
+ * statically generated state tables.  The regsiter state and shaders
+ * were hand generated to support blitting functionality.  See the 3D
+ * driver or documentation for descriptions of the registers and
+ * shader instructions.
+ */
+
 const u32 r6xx_default_state[] =
 {
        0xc0002400,
index 40416c068d9f431491f85acba93462839700d22b..68e6f434930908a8ed4c1a48f702b904206f5c64 100644 (file)
@@ -1548,10 +1548,13 @@ static void r700_gfx_init(struct drm_device *dev,
 
        RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE,      cc_rb_backend_disable);
        RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG,   cc_gc_shader_pipe_config);
+       RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
 
        RADEON_WRITE(R700_CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable);
        RADEON_WRITE(R700_CGTS_SYS_TCC_DISABLE, 0);
        RADEON_WRITE(R700_CGTS_TCC_DISABLE, 0);
+       RADEON_WRITE(R700_CGTS_USER_SYS_TCC_DISABLE, 0);
+       RADEON_WRITE(R700_CGTS_USER_TCC_DISABLE, 0);
 
        num_qd_pipes =
                R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK) >> 8);
index cd2c63bce50172f6136dbeb64abfe69254e2d122..c39c1bc13016075f2bd7151937b3faadc2bf0143 100644 (file)
@@ -45,6 +45,7 @@ struct r600_cs_track {
        u32                     nbanks;
        u32                     npipes;
        /* value we track */
+       u32                     sq_config;
        u32                     nsamples;
        u32                     cb_color_base_last[8];
        struct radeon_bo        *cb_color_bo[8];
@@ -141,6 +142,8 @@ static void r600_cs_track_init(struct r600_cs_track *track)
 {
        int i;
 
+       /* assume DX9 mode */
+       track->sq_config = DX9_CONSTS;
        for (i = 0; i < 8; i++) {
                track->cb_color_base_last[i] = 0;
                track->cb_color_size[i] = 0;
@@ -715,6 +718,9 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
                tmp =radeon_get_ib_value(p, idx);
                ib[idx] = 0;
                break;
+       case SQ_CONFIG:
+               track->sq_config = radeon_get_ib_value(p, idx);
+               break;
        case R_028800_DB_DEPTH_CONTROL:
                track->db_depth_control = radeon_get_ib_value(p, idx);
                break;
@@ -869,6 +875,54 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
        case SQ_PGM_START_VS:
        case SQ_PGM_START_GS:
        case SQ_PGM_START_PS:
+       case SQ_ALU_CONST_CACHE_GS_0:
+       case SQ_ALU_CONST_CACHE_GS_1:
+       case SQ_ALU_CONST_CACHE_GS_2:
+       case SQ_ALU_CONST_CACHE_GS_3:
+       case SQ_ALU_CONST_CACHE_GS_4:
+       case SQ_ALU_CONST_CACHE_GS_5:
+       case SQ_ALU_CONST_CACHE_GS_6:
+       case SQ_ALU_CONST_CACHE_GS_7:
+       case SQ_ALU_CONST_CACHE_GS_8:
+       case SQ_ALU_CONST_CACHE_GS_9:
+       case SQ_ALU_CONST_CACHE_GS_10:
+       case SQ_ALU_CONST_CACHE_GS_11:
+       case SQ_ALU_CONST_CACHE_GS_12:
+       case SQ_ALU_CONST_CACHE_GS_13:
+       case SQ_ALU_CONST_CACHE_GS_14:
+       case SQ_ALU_CONST_CACHE_GS_15:
+       case SQ_ALU_CONST_CACHE_PS_0:
+       case SQ_ALU_CONST_CACHE_PS_1:
+       case SQ_ALU_CONST_CACHE_PS_2:
+       case SQ_ALU_CONST_CACHE_PS_3:
+       case SQ_ALU_CONST_CACHE_PS_4:
+       case SQ_ALU_CONST_CACHE_PS_5:
+       case SQ_ALU_CONST_CACHE_PS_6:
+       case SQ_ALU_CONST_CACHE_PS_7:
+       case SQ_ALU_CONST_CACHE_PS_8:
+       case SQ_ALU_CONST_CACHE_PS_9:
+       case SQ_ALU_CONST_CACHE_PS_10:
+       case SQ_ALU_CONST_CACHE_PS_11:
+       case SQ_ALU_CONST_CACHE_PS_12:
+       case SQ_ALU_CONST_CACHE_PS_13:
+       case SQ_ALU_CONST_CACHE_PS_14:
+       case SQ_ALU_CONST_CACHE_PS_15:
+       case SQ_ALU_CONST_CACHE_VS_0:
+       case SQ_ALU_CONST_CACHE_VS_1:
+       case SQ_ALU_CONST_CACHE_VS_2:
+       case SQ_ALU_CONST_CACHE_VS_3:
+       case SQ_ALU_CONST_CACHE_VS_4:
+       case SQ_ALU_CONST_CACHE_VS_5:
+       case SQ_ALU_CONST_CACHE_VS_6:
+       case SQ_ALU_CONST_CACHE_VS_7:
+       case SQ_ALU_CONST_CACHE_VS_8:
+       case SQ_ALU_CONST_CACHE_VS_9:
+       case SQ_ALU_CONST_CACHE_VS_10:
+       case SQ_ALU_CONST_CACHE_VS_11:
+       case SQ_ALU_CONST_CACHE_VS_12:
+       case SQ_ALU_CONST_CACHE_VS_13:
+       case SQ_ALU_CONST_CACHE_VS_14:
+       case SQ_ALU_CONST_CACHE_VS_15:
                r = r600_cs_packet_next_reloc(p, &reloc);
                if (r) {
                        dev_warn(p->dev, "bad SET_CONTEXT_REG "
@@ -1226,13 +1280,15 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
                }
                break;
        case PACKET3_SET_ALU_CONST:
-               start_reg = (idx_value << 2) + PACKET3_SET_ALU_CONST_OFFSET;
-               end_reg = 4 * pkt->count + start_reg - 4;
-               if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) ||
-                   (start_reg >= PACKET3_SET_ALU_CONST_END) ||
-                   (end_reg >= PACKET3_SET_ALU_CONST_END)) {
-                       DRM_ERROR("bad SET_ALU_CONST\n");
-                       return -EINVAL;
+               if (track->sq_config & DX9_CONSTS) {
+                       start_reg = (idx_value << 2) + PACKET3_SET_ALU_CONST_OFFSET;
+                       end_reg = 4 * pkt->count + start_reg - 4;
+                       if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) ||
+                           (start_reg >= PACKET3_SET_ALU_CONST_END) ||
+                           (end_reg >= PACKET3_SET_ALU_CONST_END)) {
+                               DRM_ERROR("bad SET_ALU_CONST\n");
+                               return -EINVAL;
+                       }
                }
                break;
        case PACKET3_SET_BOOL_CONST:
index fcc949df0e5d26ac8b3271b24549e88d6524a39b..2616b822ba682468532d75f8c1e4cdb81320d14d 100644 (file)
@@ -42,13 +42,13 @@ enum r600_hdmi_color_format {
  */
 enum r600_hdmi_iec_status_bits {
        AUDIO_STATUS_DIG_ENABLE   = 0x01,
-       AUDIO_STATUS_V      = 0x02,
-       AUDIO_STATUS_VCFG        = 0x04,
+       AUDIO_STATUS_V            = 0x02,
+       AUDIO_STATUS_VCFG         = 0x04,
        AUDIO_STATUS_EMPHASIS     = 0x08,
        AUDIO_STATUS_COPYRIGHT    = 0x10,
        AUDIO_STATUS_NONAUDIO     = 0x20,
        AUDIO_STATUS_PROFESSIONAL = 0x40,
-       AUDIO_STATUS_LEVEL      = 0x80
+       AUDIO_STATUS_LEVEL        = 0x80
 };
 
 struct {
@@ -85,7 +85,7 @@ struct {
 static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq)
 {
        if (*CTS == 0)
-               *CTS = clock*N/(128*freq)*1000;
+               *CTS = clock * N / (128 * freq) * 1000;
        DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n",
                  N, *CTS, freq);
 }
@@ -131,11 +131,11 @@ static void r600_hdmi_infoframe_checksum(uint8_t packetType,
                                         uint8_t length,
                                         uint8_t *frame)
 {
-    int i;
-    frame[0] = packetType + versionNumber + length;
-    for (i = 1; i <= length; i++)
-       frame[0] += frame[i];
-    frame[0] = 0x100 - frame[0];
+       int i;
+       frame[0] = packetType + versionNumber + length;
+       for (i = 1; i <= length; i++)
+               frame[0] += frame[i];
+       frame[0] = 0x100 - frame[0];
 }
 
 /*
@@ -314,6 +314,9 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
        struct radeon_device *rdev = dev->dev_private;
        uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
 
+       if (ASIC_IS_DCE4(rdev))
+               return;
+
        if (!offset)
                return;
 
@@ -417,90 +420,147 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
        WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000);
 }
 
-/*
- * enable/disable the HDMI engine
- */
-void r600_hdmi_enable(struct drm_encoder *encoder, int enable)
+static int r600_hdmi_find_free_block(struct drm_device *dev)
+{
+       struct radeon_device *rdev = dev->dev_private;
+       struct drm_encoder *encoder;
+       struct radeon_encoder *radeon_encoder;
+       bool free_blocks[3] = { true, true, true };
+
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+               radeon_encoder = to_radeon_encoder(encoder);
+               switch (radeon_encoder->hdmi_offset) {
+               case R600_HDMI_BLOCK1:
+                       free_blocks[0] = false;
+                       break;
+               case R600_HDMI_BLOCK2:
+                       free_blocks[1] = false;
+                       break;
+               case R600_HDMI_BLOCK3:
+                       free_blocks[2] = false;
+                       break;
+               }
+       }
+
+       if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690) {
+               return free_blocks[0] ? R600_HDMI_BLOCK1 : 0;
+       } else if (rdev->family >= CHIP_R600) {
+               if (free_blocks[0])
+                       return R600_HDMI_BLOCK1;
+               else if (free_blocks[1])
+                       return R600_HDMI_BLOCK2;
+       }
+       return 0;
+}
+
+static void r600_hdmi_assign_block(struct drm_encoder *encoder)
 {
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
+       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 
-       if (!offset)
+       if (!dig) {
+               dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n");
                return;
+       }
 
-       DRM_DEBUG("%s HDMI interface @ 0x%04X\n", enable ? "Enabling" : "Disabling", offset);
-
-       /* some version of atombios ignore the enable HDMI flag
-        * so enabling/disabling HDMI was moved here for TMDS1+2 */
-       switch (radeon_encoder->encoder_id) {
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-               WREG32_P(AVIVO_TMDSA_CNTL, enable ? 0x4 : 0x0, ~0x4);
-               WREG32(offset+R600_HDMI_ENABLE, enable ? 0x101 : 0x0);
-               break;
-
-       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-               WREG32_P(AVIVO_LVTMA_CNTL, enable ? 0x4 : 0x0, ~0x4);
-               WREG32(offset+R600_HDMI_ENABLE, enable ? 0x105 : 0x0);
-               break;
-
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-               /* This part is doubtfull in my opinion */
-               WREG32(offset+R600_HDMI_ENABLE, enable ? 0x110 : 0x0);
-               break;
-
-       default:
-               DRM_ERROR("unknown HDMI output type\n");
-               break;
+       if (ASIC_IS_DCE4(rdev)) {
+               /* TODO */
+       } else if (ASIC_IS_DCE3(rdev)) {
+               radeon_encoder->hdmi_offset = dig->dig_encoder ?
+                       R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1;
+               if (ASIC_IS_DCE32(rdev))
+                       radeon_encoder->hdmi_config_offset = dig->dig_encoder ?
+                               R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1;
+       } else if (rdev->family >= CHIP_R600) {
+               radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev);
        }
 }
 
 /*
- * determin at which register offset the HDMI encoder is
+ * enable the HDMI engine
  */
-void r600_hdmi_init(struct drm_encoder *encoder)
+void r600_hdmi_enable(struct drm_encoder *encoder)
 {
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 
-       switch (radeon_encoder->encoder_id) {
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-               radeon_encoder->hdmi_offset = R600_HDMI_TMDS1;
-               break;
-
-       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-               switch (r600_audio_tmds_index(encoder)) {
-               case 0:
-                       radeon_encoder->hdmi_offset = R600_HDMI_TMDS1;
+       if (ASIC_IS_DCE4(rdev))
+               return;
+
+       if (!radeon_encoder->hdmi_offset) {
+               r600_hdmi_assign_block(encoder);
+               if (!radeon_encoder->hdmi_offset) {
+                       dev_warn(rdev->dev, "Could not find HDMI block for "
+                               "0x%x encoder\n", radeon_encoder->encoder_id);
+                       return;
+               }
+       }
+
+       if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) {
+               WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1);
+       } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
+               int offset = radeon_encoder->hdmi_offset;
+               switch (radeon_encoder->encoder_id) {
+               case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+                       WREG32_P(AVIVO_TMDSA_CNTL, 0x4, ~0x4);
+                       WREG32(offset + R600_HDMI_ENABLE, 0x101);
                        break;
-               case 1:
-                       radeon_encoder->hdmi_offset = R600_HDMI_TMDS2;
+               case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+                       WREG32_P(AVIVO_LVTMA_CNTL, 0x4, ~0x4);
+                       WREG32(offset + R600_HDMI_ENABLE, 0x105);
                        break;
                default:
-                       radeon_encoder->hdmi_offset = 0;
+                       dev_err(rdev->dev, "Unknown HDMI output type\n");
                        break;
                }
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-               radeon_encoder->hdmi_offset = R600_HDMI_TMDS2;
-               break;
+       }
+
+       DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n",
+               radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
+}
+
+/*
+ * disable the HDMI engine
+ */
+void r600_hdmi_disable(struct drm_encoder *encoder)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-               radeon_encoder->hdmi_offset = R600_HDMI_DIG;
-               break;
+       if (ASIC_IS_DCE4(rdev))
+               return;
 
-       default:
-               radeon_encoder->hdmi_offset = 0;
-               break;
+       if (!radeon_encoder->hdmi_offset) {
+               dev_err(rdev->dev, "Disabling not enabled HDMI\n");
+               return;
        }
 
-       DRM_DEBUG("using HDMI engine at offset 0x%04X for encoder 0x%x\n",
-                 radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
+       DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n",
+               radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
+
+       if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) {
+               WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1);
+       } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
+               int offset = radeon_encoder->hdmi_offset;
+               switch (radeon_encoder->encoder_id) {
+               case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+                       WREG32_P(AVIVO_TMDSA_CNTL, 0, ~0x4);
+                       WREG32(offset + R600_HDMI_ENABLE, 0);
+                       break;
+               case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+                       WREG32_P(AVIVO_LVTMA_CNTL, 0, ~0x4);
+                       WREG32(offset + R600_HDMI_ENABLE, 0);
+                       break;
+               default:
+                       dev_err(rdev->dev, "Unknown HDMI output type\n");
+                       break;
+               }
+       }
 
-       /* TODO: make this configureable */
-       radeon_encoder->hdmi_audio_workaround = 0;
+       radeon_encoder->hdmi_offset = 0;
+       radeon_encoder->hdmi_config_offset = 0;
 }
index d0e28ffdeda9400564ce40cea7a22e7fca2533f5..7b1d22370f6e2bc2fb78521b3a8e61aa49e8d44f 100644 (file)
 #define R600_AUDIO_STATUS_BITS            0x73d8
 
 /* HDMI base register addresses */
-#define R600_HDMI_TMDS1                   0x7400
-#define R600_HDMI_TMDS2                   0x7700
-#define R600_HDMI_DIG                     0x7800
+#define R600_HDMI_BLOCK1                  0x7400
+#define R600_HDMI_BLOCK2                  0x7700
+#define R600_HDMI_BLOCK3                  0x7800
 
 /* HDMI registers */
 #define R600_HDMI_ENABLE           0x00
 #define R600_HDMI_AUDIO_DEBUG_2    0xe8
 #define R600_HDMI_AUDIO_DEBUG_3    0xec
 
+/* HDMI additional config base register addresses */
+#define R600_HDMI_CONFIG1                 0x7600
+#define R600_HDMI_CONFIG2                 0x7a00
+
 #endif
index 5b2e4d44282394ba85598c2ae6a91bd7ffc42b79..59c1f8793e608df971466a9545ccc32c81e529fd 100644 (file)
 #define CB_COLOR0_FRAG                                  0x280e0
 #define CB_COLOR0_MASK                                  0x28100
 
+#define SQ_ALU_CONST_CACHE_PS_0                                0x28940
+#define SQ_ALU_CONST_CACHE_PS_1                                0x28944
+#define SQ_ALU_CONST_CACHE_PS_2                                0x28948
+#define SQ_ALU_CONST_CACHE_PS_3                                0x2894c
+#define SQ_ALU_CONST_CACHE_PS_4                                0x28950
+#define SQ_ALU_CONST_CACHE_PS_5                                0x28954
+#define SQ_ALU_CONST_CACHE_PS_6                                0x28958
+#define SQ_ALU_CONST_CACHE_PS_7                                0x2895c
+#define SQ_ALU_CONST_CACHE_PS_8                                0x28960
+#define SQ_ALU_CONST_CACHE_PS_9                                0x28964
+#define SQ_ALU_CONST_CACHE_PS_10                       0x28968
+#define SQ_ALU_CONST_CACHE_PS_11                       0x2896c
+#define SQ_ALU_CONST_CACHE_PS_12                       0x28970
+#define SQ_ALU_CONST_CACHE_PS_13                       0x28974
+#define SQ_ALU_CONST_CACHE_PS_14                       0x28978
+#define SQ_ALU_CONST_CACHE_PS_15                       0x2897c
+#define SQ_ALU_CONST_CACHE_VS_0                                0x28980
+#define SQ_ALU_CONST_CACHE_VS_1                                0x28984
+#define SQ_ALU_CONST_CACHE_VS_2                                0x28988
+#define SQ_ALU_CONST_CACHE_VS_3                                0x2898c
+#define SQ_ALU_CONST_CACHE_VS_4                                0x28990
+#define SQ_ALU_CONST_CACHE_VS_5                                0x28994
+#define SQ_ALU_CONST_CACHE_VS_6                                0x28998
+#define SQ_ALU_CONST_CACHE_VS_7                                0x2899c
+#define SQ_ALU_CONST_CACHE_VS_8                                0x289a0
+#define SQ_ALU_CONST_CACHE_VS_9                                0x289a4
+#define SQ_ALU_CONST_CACHE_VS_10                       0x289a8
+#define SQ_ALU_CONST_CACHE_VS_11                       0x289ac
+#define SQ_ALU_CONST_CACHE_VS_12                       0x289b0
+#define SQ_ALU_CONST_CACHE_VS_13                       0x289b4
+#define SQ_ALU_CONST_CACHE_VS_14                       0x289b8
+#define SQ_ALU_CONST_CACHE_VS_15                       0x289bc
+#define SQ_ALU_CONST_CACHE_GS_0                                0x289c0
+#define SQ_ALU_CONST_CACHE_GS_1                                0x289c4
+#define SQ_ALU_CONST_CACHE_GS_2                                0x289c8
+#define SQ_ALU_CONST_CACHE_GS_3                                0x289cc
+#define SQ_ALU_CONST_CACHE_GS_4                                0x289d0
+#define SQ_ALU_CONST_CACHE_GS_5                                0x289d4
+#define SQ_ALU_CONST_CACHE_GS_6                                0x289d8
+#define SQ_ALU_CONST_CACHE_GS_7                                0x289dc
+#define SQ_ALU_CONST_CACHE_GS_8                                0x289e0
+#define SQ_ALU_CONST_CACHE_GS_9                                0x289e4
+#define SQ_ALU_CONST_CACHE_GS_10                       0x289e8
+#define SQ_ALU_CONST_CACHE_GS_11                       0x289ec
+#define SQ_ALU_CONST_CACHE_GS_12                       0x289f0
+#define SQ_ALU_CONST_CACHE_GS_13                       0x289f4
+#define SQ_ALU_CONST_CACHE_GS_14                       0x289f8
+#define SQ_ALU_CONST_CACHE_GS_15                       0x289fc
+
 #define        CONFIG_MEMSIZE                                  0x5428
 #define CONFIG_CNTL                                    0x5424
 #define        CP_STAT                                         0x8680
index 829e26e8a4bb877f43dc2b8f12646e5d840753cb..034218c3dbbbb11d8248606074debc81fe42df8b 100644 (file)
@@ -91,6 +91,8 @@ extern int radeon_tv;
 extern int radeon_new_pll;
 extern int radeon_dynpm;
 extern int radeon_audio;
+extern int radeon_disp_priority;
+extern int radeon_hw_i2c;
 
 /*
  * Copy from radeon_drv.h so we don't have to include both and have conflicting
@@ -168,6 +170,7 @@ struct radeon_clock {
  * Power management
  */
 int radeon_pm_init(struct radeon_device *rdev);
+void radeon_pm_fini(struct radeon_device *rdev);
 void radeon_pm_compute_clocks(struct radeon_device *rdev);
 void radeon_combios_get_power_modes(struct radeon_device *rdev);
 void radeon_atombios_get_power_modes(struct radeon_device *rdev);
@@ -687,6 +690,7 @@ struct radeon_pm {
        bool                    downclocked;
        int                     active_crtcs;
        int                     req_vblank;
+       bool                    vblank_sync;
        fixed20_12              max_bandwidth;
        fixed20_12              igp_sideport_mclk;
        fixed20_12              igp_system_mclk;
@@ -697,6 +701,7 @@ struct radeon_pm {
        fixed20_12              ht_bandwidth;
        fixed20_12              core_bandwidth;
        fixed20_12              sclk;
+       fixed20_12              mclk;
        fixed20_12              needed_bandwidth;
        /* XXX: use a define for num power modes */
        struct radeon_power_state power_state[8];
@@ -707,6 +712,7 @@ struct radeon_pm {
        struct radeon_power_state *requested_power_state;
        struct radeon_pm_clock_info *requested_clock_mode;
        struct radeon_power_state *default_power_state;
+       struct radeon_i2c_chan *i2c_bus;
 };
 
 
@@ -729,8 +735,6 @@ int radeon_debugfs_add_files(struct radeon_device *rdev,
                             struct drm_info_list *files,
                             unsigned nfiles);
 int radeon_debugfs_fence_init(struct radeon_device *rdev);
-int r100_debugfs_rbbm_init(struct radeon_device *rdev);
-int r100_debugfs_cp_init(struct radeon_device *rdev);
 
 
 /*
@@ -782,7 +786,7 @@ struct radeon_asic {
        int (*set_surface_reg)(struct radeon_device *rdev, int reg,
                               uint32_t tiling_flags, uint32_t pitch,
                               uint32_t offset, uint32_t obj_size);
-       int (*clear_surface_reg)(struct radeon_device *rdev, int reg);
+       void (*clear_surface_reg)(struct radeon_device *rdev, int reg);
        void (*bandwidth_update)(struct radeon_device *rdev);
        void (*hpd_init)(struct radeon_device *rdev);
        void (*hpd_fini)(struct radeon_device *rdev);
@@ -862,6 +866,12 @@ union radeon_asic_config {
        struct rv770_asic       rv770;
 };
 
+/*
+ * asic initizalization from radeon_asic.c
+ */
+void radeon_agp_disable(struct radeon_device *rdev);
+int radeon_asic_init(struct radeon_device *rdev);
+
 
 /*
  * IOCTL.
@@ -1172,6 +1182,8 @@ extern void radeon_gart_restore(struct radeon_device *rdev);
 extern int radeon_modeset_init(struct radeon_device *rdev);
 extern void radeon_modeset_fini(struct radeon_device *rdev);
 extern bool radeon_card_posted(struct radeon_device *rdev);
+extern void radeon_update_bandwidth_info(struct radeon_device *rdev);
+extern void radeon_update_display_priority(struct radeon_device *rdev);
 extern bool radeon_boot_test_post_card(struct radeon_device *rdev);
 extern int radeon_clocks_init(struct radeon_device *rdev);
 extern void radeon_clocks_fini(struct radeon_device *rdev);
@@ -1188,51 +1200,6 @@ extern int radeon_resume_kms(struct drm_device *dev);
 extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state);
 
 /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
-struct r100_mc_save {
-       u32     GENMO_WT;
-       u32     CRTC_EXT_CNTL;
-       u32     CRTC_GEN_CNTL;
-       u32     CRTC2_GEN_CNTL;
-       u32     CUR_OFFSET;
-       u32     CUR2_OFFSET;
-};
-extern void r100_cp_disable(struct radeon_device *rdev);
-extern int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
-extern void r100_cp_fini(struct radeon_device *rdev);
-extern void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
-extern int r100_pci_gart_init(struct radeon_device *rdev);
-extern void r100_pci_gart_fini(struct radeon_device *rdev);
-extern int r100_pci_gart_enable(struct radeon_device *rdev);
-extern void r100_pci_gart_disable(struct radeon_device *rdev);
-extern int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
-extern int r100_debugfs_mc_info_init(struct radeon_device *rdev);
-extern int r100_gui_wait_for_idle(struct radeon_device *rdev);
-extern void r100_ib_fini(struct radeon_device *rdev);
-extern int r100_ib_init(struct radeon_device *rdev);
-extern void r100_irq_disable(struct radeon_device *rdev);
-extern int r100_irq_set(struct radeon_device *rdev);
-extern void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save);
-extern void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save);
-extern void r100_vram_init_sizes(struct radeon_device *rdev);
-extern void r100_wb_disable(struct radeon_device *rdev);
-extern void r100_wb_fini(struct radeon_device *rdev);
-extern int r100_wb_init(struct radeon_device *rdev);
-extern void r100_hdp_reset(struct radeon_device *rdev);
-extern int r100_rb2d_reset(struct radeon_device *rdev);
-extern int r100_cp_reset(struct radeon_device *rdev);
-extern void r100_vga_render_disable(struct radeon_device *rdev);
-extern int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
-                                               struct radeon_cs_packet *pkt,
-                                               struct radeon_bo *robj);
-extern int r100_cs_parse_packet0(struct radeon_cs_parser *p,
-                               struct radeon_cs_packet *pkt,
-                               const unsigned *auth, unsigned n,
-                               radeon_packet0_check_t check);
-extern int r100_cs_packet_parse(struct radeon_cs_parser *p,
-                               struct radeon_cs_packet *pkt,
-                               unsigned idx);
-extern void r100_enable_bm(struct radeon_device *rdev);
-extern void r100_set_common_regs(struct radeon_device *rdev);
 
 /* rv200,rv250,rv280 */
 extern void r200_set_safe_registers(struct radeon_device *rdev);
@@ -1322,7 +1289,8 @@ extern int r600_audio_tmds_index(struct drm_encoder *encoder);
 extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock);
 extern void r600_audio_fini(struct radeon_device *rdev);
 extern void r600_hdmi_init(struct drm_encoder *encoder);
-extern void r600_hdmi_enable(struct drm_encoder *encoder, int enable);
+extern void r600_hdmi_enable(struct drm_encoder *encoder);
+extern void r600_hdmi_disable(struct drm_encoder *encoder);
 extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
 extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder);
 extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
index c4457791dff1ae606004572d52b1d69eea1f7052..28e473f1f56fd688c339c169be1a1cbf5f11aaad 100644 (file)
@@ -134,12 +134,10 @@ int radeon_agp_init(struct radeon_device *rdev)
        int ret;
 
        /* Acquire AGP. */
-       if (!rdev->ddev->agp->acquired) {
-               ret = drm_agp_acquire(rdev->ddev);
-               if (ret) {
-                       DRM_ERROR("Unable to acquire AGP: %d\n", ret);
-                       return ret;
-               }
+       ret = drm_agp_acquire(rdev->ddev);
+       if (ret) {
+               DRM_ERROR("Unable to acquire AGP: %d\n", ret);
+               return ret;
        }
 
        ret = drm_agp_info(rdev->ddev, &info);
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
new file mode 100644 (file)
index 0000000..a4b4bc9
--- /dev/null
@@ -0,0 +1,772 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * 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: Dave Airlie
+ *          Alex Deucher
+ *          Jerome Glisse
+ */
+
+#include <linux/console.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/radeon_drm.h>
+#include <linux/vgaarb.h>
+#include <linux/vga_switcheroo.h>
+#include "radeon_reg.h"
+#include "radeon.h"
+#include "radeon_asic.h"
+#include "atom.h"
+
+/*
+ * Registers accessors functions.
+ */
+static uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg)
+{
+       DRM_ERROR("Invalid callback to read register 0x%04X\n", reg);
+       BUG_ON(1);
+       return 0;
+}
+
+static void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
+{
+       DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n",
+                 reg, v);
+       BUG_ON(1);
+}
+
+static void radeon_register_accessor_init(struct radeon_device *rdev)
+{
+       rdev->mc_rreg = &radeon_invalid_rreg;
+       rdev->mc_wreg = &radeon_invalid_wreg;
+       rdev->pll_rreg = &radeon_invalid_rreg;
+       rdev->pll_wreg = &radeon_invalid_wreg;
+       rdev->pciep_rreg = &radeon_invalid_rreg;
+       rdev->pciep_wreg = &radeon_invalid_wreg;
+
+       /* Don't change order as we are overridding accessor. */
+       if (rdev->family < CHIP_RV515) {
+               rdev->pcie_reg_mask = 0xff;
+       } else {
+               rdev->pcie_reg_mask = 0x7ff;
+       }
+       /* FIXME: not sure here */
+       if (rdev->family <= CHIP_R580) {
+               rdev->pll_rreg = &r100_pll_rreg;
+               rdev->pll_wreg = &r100_pll_wreg;
+       }
+       if (rdev->family >= CHIP_R420) {
+               rdev->mc_rreg = &r420_mc_rreg;
+               rdev->mc_wreg = &r420_mc_wreg;
+       }
+       if (rdev->family >= CHIP_RV515) {
+               rdev->mc_rreg = &rv515_mc_rreg;
+               rdev->mc_wreg = &rv515_mc_wreg;
+       }
+       if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) {
+               rdev->mc_rreg = &rs400_mc_rreg;
+               rdev->mc_wreg = &rs400_mc_wreg;
+       }
+       if (rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) {
+               rdev->mc_rreg = &rs690_mc_rreg;
+               rdev->mc_wreg = &rs690_mc_wreg;
+       }
+       if (rdev->family == CHIP_RS600) {
+               rdev->mc_rreg = &rs600_mc_rreg;
+               rdev->mc_wreg = &rs600_mc_wreg;
+       }
+       if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_RV740)) {
+               rdev->pciep_rreg = &r600_pciep_rreg;
+               rdev->pciep_wreg = &r600_pciep_wreg;
+       }
+}
+
+
+/* helper to disable agp */
+void radeon_agp_disable(struct radeon_device *rdev)
+{
+       rdev->flags &= ~RADEON_IS_AGP;
+       if (rdev->family >= CHIP_R600) {
+               DRM_INFO("Forcing AGP to PCIE mode\n");
+               rdev->flags |= RADEON_IS_PCIE;
+       } else if (rdev->family >= CHIP_RV515 ||
+                       rdev->family == CHIP_RV380 ||
+                       rdev->family == CHIP_RV410 ||
+                       rdev->family == CHIP_R423) {
+               DRM_INFO("Forcing AGP to PCIE mode\n");
+               rdev->flags |= RADEON_IS_PCIE;
+               rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
+               rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
+       } else {
+               DRM_INFO("Forcing AGP to PCI mode\n");
+               rdev->flags |= RADEON_IS_PCI;
+               rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
+               rdev->asic->gart_set_page = &r100_pci_gart_set_page;
+       }
+       rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+}
+
+/*
+ * ASIC
+ */
+static struct radeon_asic r100_asic = {
+       .init = &r100_init,
+       .fini = &r100_fini,
+       .suspend = &r100_suspend,
+       .resume = &r100_resume,
+       .vga_set_state = &r100_vga_set_state,
+       .gpu_reset = &r100_gpu_reset,
+       .gart_tlb_flush = &r100_pci_gart_tlb_flush,
+       .gart_set_page = &r100_pci_gart_set_page,
+       .cp_commit = &r100_cp_commit,
+       .ring_start = &r100_ring_start,
+       .ring_test = &r100_ring_test,
+       .ring_ib_execute = &r100_ring_ib_execute,
+       .irq_set = &r100_irq_set,
+       .irq_process = &r100_irq_process,
+       .get_vblank_counter = &r100_get_vblank_counter,
+       .fence_ring_emit = &r100_fence_ring_emit,
+       .cs_parse = &r100_cs_parse,
+       .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 = &radeon_legacy_get_memory_clock,
+       .set_memory_clock = NULL,
+       .get_pcie_lanes = NULL,
+       .set_pcie_lanes = NULL,
+       .set_clock_gating = &radeon_legacy_set_clock_gating,
+       .set_surface_reg = r100_set_surface_reg,
+       .clear_surface_reg = r100_clear_surface_reg,
+       .bandwidth_update = &r100_bandwidth_update,
+       .hpd_init = &r100_hpd_init,
+       .hpd_fini = &r100_hpd_fini,
+       .hpd_sense = &r100_hpd_sense,
+       .hpd_set_polarity = &r100_hpd_set_polarity,
+       .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r200_asic = {
+       .init = &r100_init,
+       .fini = &r100_fini,
+       .suspend = &r100_suspend,
+       .resume = &r100_resume,
+       .vga_set_state = &r100_vga_set_state,
+       .gpu_reset = &r100_gpu_reset,
+       .gart_tlb_flush = &r100_pci_gart_tlb_flush,
+       .gart_set_page = &r100_pci_gart_set_page,
+       .cp_commit = &r100_cp_commit,
+       .ring_start = &r100_ring_start,
+       .ring_test = &r100_ring_test,
+       .ring_ib_execute = &r100_ring_ib_execute,
+       .irq_set = &r100_irq_set,
+       .irq_process = &r100_irq_process,
+       .get_vblank_counter = &r100_get_vblank_counter,
+       .fence_ring_emit = &r100_fence_ring_emit,
+       .cs_parse = &r100_cs_parse,
+       .copy_blit = &r100_copy_blit,
+       .copy_dma = &r200_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 = &radeon_legacy_get_memory_clock,
+       .set_memory_clock = NULL,
+       .set_pcie_lanes = NULL,
+       .set_clock_gating = &radeon_legacy_set_clock_gating,
+       .set_surface_reg = r100_set_surface_reg,
+       .clear_surface_reg = r100_clear_surface_reg,
+       .bandwidth_update = &r100_bandwidth_update,
+       .hpd_init = &r100_hpd_init,
+       .hpd_fini = &r100_hpd_fini,
+       .hpd_sense = &r100_hpd_sense,
+       .hpd_set_polarity = &r100_hpd_set_polarity,
+       .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r300_asic = {
+       .init = &r300_init,
+       .fini = &r300_fini,
+       .suspend = &r300_suspend,
+       .resume = &r300_resume,
+       .vga_set_state = &r100_vga_set_state,
+       .gpu_reset = &r300_gpu_reset,
+       .gart_tlb_flush = &r100_pci_gart_tlb_flush,
+       .gart_set_page = &r100_pci_gart_set_page,
+       .cp_commit = &r100_cp_commit,
+       .ring_start = &r300_ring_start,
+       .ring_test = &r100_ring_test,
+       .ring_ib_execute = &r100_ring_ib_execute,
+       .irq_set = &r100_irq_set,
+       .irq_process = &r100_irq_process,
+       .get_vblank_counter = &r100_get_vblank_counter,
+       .fence_ring_emit = &r300_fence_ring_emit,
+       .cs_parse = &r300_cs_parse,
+       .copy_blit = &r100_copy_blit,
+       .copy_dma = &r200_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 = &radeon_legacy_get_memory_clock,
+       .set_memory_clock = NULL,
+       .get_pcie_lanes = &rv370_get_pcie_lanes,
+       .set_pcie_lanes = &rv370_set_pcie_lanes,
+       .set_clock_gating = &radeon_legacy_set_clock_gating,
+       .set_surface_reg = r100_set_surface_reg,
+       .clear_surface_reg = r100_clear_surface_reg,
+       .bandwidth_update = &r100_bandwidth_update,
+       .hpd_init = &r100_hpd_init,
+       .hpd_fini = &r100_hpd_fini,
+       .hpd_sense = &r100_hpd_sense,
+       .hpd_set_polarity = &r100_hpd_set_polarity,
+       .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r300_asic_pcie = {
+       .init = &r300_init,
+       .fini = &r300_fini,
+       .suspend = &r300_suspend,
+       .resume = &r300_resume,
+       .vga_set_state = &r100_vga_set_state,
+       .gpu_reset = &r300_gpu_reset,
+       .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
+       .gart_set_page = &rv370_pcie_gart_set_page,
+       .cp_commit = &r100_cp_commit,
+       .ring_start = &r300_ring_start,
+       .ring_test = &r100_ring_test,
+       .ring_ib_execute = &r100_ring_ib_execute,
+       .irq_set = &r100_irq_set,
+       .irq_process = &r100_irq_process,
+       .get_vblank_counter = &r100_get_vblank_counter,
+       .fence_ring_emit = &r300_fence_ring_emit,
+       .cs_parse = &r300_cs_parse,
+       .copy_blit = &r100_copy_blit,
+       .copy_dma = &r200_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 = &radeon_legacy_get_memory_clock,
+       .set_memory_clock = NULL,
+       .set_pcie_lanes = &rv370_set_pcie_lanes,
+       .set_clock_gating = &radeon_legacy_set_clock_gating,
+       .set_surface_reg = r100_set_surface_reg,
+       .clear_surface_reg = r100_clear_surface_reg,
+       .bandwidth_update = &r100_bandwidth_update,
+       .hpd_init = &r100_hpd_init,
+       .hpd_fini = &r100_hpd_fini,
+       .hpd_sense = &r100_hpd_sense,
+       .hpd_set_polarity = &r100_hpd_set_polarity,
+       .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r420_asic = {
+       .init = &r420_init,
+       .fini = &r420_fini,
+       .suspend = &r420_suspend,
+       .resume = &r420_resume,
+       .vga_set_state = &r100_vga_set_state,
+       .gpu_reset = &r300_gpu_reset,
+       .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
+       .gart_set_page = &rv370_pcie_gart_set_page,
+       .cp_commit = &r100_cp_commit,
+       .ring_start = &r300_ring_start,
+       .ring_test = &r100_ring_test,
+       .ring_ib_execute = &r100_ring_ib_execute,
+       .irq_set = &r100_irq_set,
+       .irq_process = &r100_irq_process,
+       .get_vblank_counter = &r100_get_vblank_counter,
+       .fence_ring_emit = &r300_fence_ring_emit,
+       .cs_parse = &r300_cs_parse,
+       .copy_blit = &r100_copy_blit,
+       .copy_dma = &r200_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,
+       .get_pcie_lanes = &rv370_get_pcie_lanes,
+       .set_pcie_lanes = &rv370_set_pcie_lanes,
+       .set_clock_gating = &radeon_atom_set_clock_gating,
+       .set_surface_reg = r100_set_surface_reg,
+       .clear_surface_reg = r100_clear_surface_reg,
+       .bandwidth_update = &r100_bandwidth_update,
+       .hpd_init = &r100_hpd_init,
+       .hpd_fini = &r100_hpd_fini,
+       .hpd_sense = &r100_hpd_sense,
+       .hpd_set_polarity = &r100_hpd_set_polarity,
+       .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic rs400_asic = {
+       .init = &rs400_init,
+       .fini = &rs400_fini,
+       .suspend = &rs400_suspend,
+       .resume = &rs400_resume,
+       .vga_set_state = &r100_vga_set_state,
+       .gpu_reset = &r300_gpu_reset,
+       .gart_tlb_flush = &rs400_gart_tlb_flush,
+       .gart_set_page = &rs400_gart_set_page,
+       .cp_commit = &r100_cp_commit,
+       .ring_start = &r300_ring_start,
+       .ring_test = &r100_ring_test,
+       .ring_ib_execute = &r100_ring_ib_execute,
+       .irq_set = &r100_irq_set,
+       .irq_process = &r100_irq_process,
+       .get_vblank_counter = &r100_get_vblank_counter,
+       .fence_ring_emit = &r300_fence_ring_emit,
+       .cs_parse = &r300_cs_parse,
+       .copy_blit = &r100_copy_blit,
+       .copy_dma = &r200_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 = &radeon_legacy_get_memory_clock,
+       .set_memory_clock = NULL,
+       .get_pcie_lanes = NULL,
+       .set_pcie_lanes = NULL,
+       .set_clock_gating = &radeon_legacy_set_clock_gating,
+       .set_surface_reg = r100_set_surface_reg,
+       .clear_surface_reg = r100_clear_surface_reg,
+       .bandwidth_update = &r100_bandwidth_update,
+       .hpd_init = &r100_hpd_init,
+       .hpd_fini = &r100_hpd_fini,
+       .hpd_sense = &r100_hpd_sense,
+       .hpd_set_polarity = &r100_hpd_set_polarity,
+       .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic rs600_asic = {
+       .init = &rs600_init,
+       .fini = &rs600_fini,
+       .suspend = &rs600_suspend,
+       .resume = &rs600_resume,
+       .vga_set_state = &r100_vga_set_state,
+       .gpu_reset = &r300_gpu_reset,
+       .gart_tlb_flush = &rs600_gart_tlb_flush,
+       .gart_set_page = &rs600_gart_set_page,
+       .cp_commit = &r100_cp_commit,
+       .ring_start = &r300_ring_start,
+       .ring_test = &r100_ring_test,
+       .ring_ib_execute = &r100_ring_ib_execute,
+       .irq_set = &rs600_irq_set,
+       .irq_process = &rs600_irq_process,
+       .get_vblank_counter = &rs600_get_vblank_counter,
+       .fence_ring_emit = &r300_fence_ring_emit,
+       .cs_parse = &r300_cs_parse,
+       .copy_blit = &r100_copy_blit,
+       .copy_dma = &r200_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,
+       .get_pcie_lanes = NULL,
+       .set_pcie_lanes = NULL,
+       .set_clock_gating = &radeon_atom_set_clock_gating,
+       .set_surface_reg = r100_set_surface_reg,
+       .clear_surface_reg = r100_clear_surface_reg,
+       .bandwidth_update = &rs600_bandwidth_update,
+       .hpd_init = &rs600_hpd_init,
+       .hpd_fini = &rs600_hpd_fini,
+       .hpd_sense = &rs600_hpd_sense,
+       .hpd_set_polarity = &rs600_hpd_set_polarity,
+       .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic rs690_asic = {
+       .init = &rs690_init,
+       .fini = &rs690_fini,
+       .suspend = &rs690_suspend,
+       .resume = &rs690_resume,
+       .vga_set_state = &r100_vga_set_state,
+       .gpu_reset = &r300_gpu_reset,
+       .gart_tlb_flush = &rs400_gart_tlb_flush,
+       .gart_set_page = &rs400_gart_set_page,
+       .cp_commit = &r100_cp_commit,
+       .ring_start = &r300_ring_start,
+       .ring_test = &r100_ring_test,
+       .ring_ib_execute = &r100_ring_ib_execute,
+       .irq_set = &rs600_irq_set,
+       .irq_process = &rs600_irq_process,
+       .get_vblank_counter = &rs600_get_vblank_counter,
+       .fence_ring_emit = &r300_fence_ring_emit,
+       .cs_parse = &r300_cs_parse,
+       .copy_blit = &r100_copy_blit,
+       .copy_dma = &r200_copy_dma,
+       .copy = &r200_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,
+       .get_pcie_lanes = NULL,
+       .set_pcie_lanes = NULL,
+       .set_clock_gating = &radeon_atom_set_clock_gating,
+       .set_surface_reg = r100_set_surface_reg,
+       .clear_surface_reg = r100_clear_surface_reg,
+       .bandwidth_update = &rs690_bandwidth_update,
+       .hpd_init = &rs600_hpd_init,
+       .hpd_fini = &rs600_hpd_fini,
+       .hpd_sense = &rs600_hpd_sense,
+       .hpd_set_polarity = &rs600_hpd_set_polarity,
+       .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic rv515_asic = {
+       .init = &rv515_init,
+       .fini = &rv515_fini,
+       .suspend = &rv515_suspend,
+       .resume = &rv515_resume,
+       .vga_set_state = &r100_vga_set_state,
+       .gpu_reset = &rv515_gpu_reset,
+       .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
+       .gart_set_page = &rv370_pcie_gart_set_page,
+       .cp_commit = &r100_cp_commit,
+       .ring_start = &rv515_ring_start,
+       .ring_test = &r100_ring_test,
+       .ring_ib_execute = &r100_ring_ib_execute,
+       .irq_set = &rs600_irq_set,
+       .irq_process = &rs600_irq_process,
+       .get_vblank_counter = &rs600_get_vblank_counter,
+       .fence_ring_emit = &r300_fence_ring_emit,
+       .cs_parse = &r300_cs_parse,
+       .copy_blit = &r100_copy_blit,
+       .copy_dma = &r200_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,
+       .get_pcie_lanes = &rv370_get_pcie_lanes,
+       .set_pcie_lanes = &rv370_set_pcie_lanes,
+       .set_clock_gating = &radeon_atom_set_clock_gating,
+       .set_surface_reg = r100_set_surface_reg,
+       .clear_surface_reg = r100_clear_surface_reg,
+       .bandwidth_update = &rv515_bandwidth_update,
+       .hpd_init = &rs600_hpd_init,
+       .hpd_fini = &rs600_hpd_fini,
+       .hpd_sense = &rs600_hpd_sense,
+       .hpd_set_polarity = &rs600_hpd_set_polarity,
+       .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r520_asic = {
+       .init = &r520_init,
+       .fini = &rv515_fini,
+       .suspend = &rv515_suspend,
+       .resume = &r520_resume,
+       .vga_set_state = &r100_vga_set_state,
+       .gpu_reset = &rv515_gpu_reset,
+       .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
+       .gart_set_page = &rv370_pcie_gart_set_page,
+       .cp_commit = &r100_cp_commit,
+       .ring_start = &rv515_ring_start,
+       .ring_test = &r100_ring_test,
+       .ring_ib_execute = &r100_ring_ib_execute,
+       .irq_set = &rs600_irq_set,
+       .irq_process = &rs600_irq_process,
+       .get_vblank_counter = &rs600_get_vblank_counter,
+       .fence_ring_emit = &r300_fence_ring_emit,
+       .cs_parse = &r300_cs_parse,
+       .copy_blit = &r100_copy_blit,
+       .copy_dma = &r200_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,
+       .get_pcie_lanes = &rv370_get_pcie_lanes,
+       .set_pcie_lanes = &rv370_set_pcie_lanes,
+       .set_clock_gating = &radeon_atom_set_clock_gating,
+       .set_surface_reg = r100_set_surface_reg,
+       .clear_surface_reg = r100_clear_surface_reg,
+       .bandwidth_update = &rv515_bandwidth_update,
+       .hpd_init = &rs600_hpd_init,
+       .hpd_fini = &rs600_hpd_fini,
+       .hpd_sense = &rs600_hpd_sense,
+       .hpd_set_polarity = &rs600_hpd_set_polarity,
+       .ioctl_wait_idle = NULL,
+};
+
+static struct radeon_asic r600_asic = {
+       .init = &r600_init,
+       .fini = &r600_fini,
+       .suspend = &r600_suspend,
+       .resume = &r600_resume,
+       .cp_commit = &r600_cp_commit,
+       .vga_set_state = &r600_vga_set_state,
+       .gpu_reset = &r600_gpu_reset,
+       .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
+       .gart_set_page = &rs600_gart_set_page,
+       .ring_test = &r600_ring_test,
+       .ring_ib_execute = &r600_ring_ib_execute,
+       .irq_set = &r600_irq_set,
+       .irq_process = &r600_irq_process,
+       .get_vblank_counter = &rs600_get_vblank_counter,
+       .fence_ring_emit = &r600_fence_ring_emit,
+       .cs_parse = &r600_cs_parse,
+       .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,
+       .get_pcie_lanes = &rv370_get_pcie_lanes,
+       .set_pcie_lanes = NULL,
+       .set_clock_gating = NULL,
+       .set_surface_reg = r600_set_surface_reg,
+       .clear_surface_reg = r600_clear_surface_reg,
+       .bandwidth_update = &rv515_bandwidth_update,
+       .hpd_init = &r600_hpd_init,
+       .hpd_fini = &r600_hpd_fini,
+       .hpd_sense = &r600_hpd_sense,
+       .hpd_set_polarity = &r600_hpd_set_polarity,
+       .ioctl_wait_idle = r600_ioctl_wait_idle,
+};
+
+static struct radeon_asic rs780_asic = {
+       .init = &r600_init,
+       .fini = &r600_fini,
+       .suspend = &r600_suspend,
+       .resume = &r600_resume,
+       .cp_commit = &r600_cp_commit,
+       .vga_set_state = &r600_vga_set_state,
+       .gpu_reset = &r600_gpu_reset,
+       .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
+       .gart_set_page = &rs600_gart_set_page,
+       .ring_test = &r600_ring_test,
+       .ring_ib_execute = &r600_ring_ib_execute,
+       .irq_set = &r600_irq_set,
+       .irq_process = &r600_irq_process,
+       .get_vblank_counter = &rs600_get_vblank_counter,
+       .fence_ring_emit = &r600_fence_ring_emit,
+       .cs_parse = &r600_cs_parse,
+       .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 = NULL,
+       .set_memory_clock = NULL,
+       .get_pcie_lanes = NULL,
+       .set_pcie_lanes = NULL,
+       .set_clock_gating = NULL,
+       .set_surface_reg = r600_set_surface_reg,
+       .clear_surface_reg = r600_clear_surface_reg,
+       .bandwidth_update = &rs690_bandwidth_update,
+       .hpd_init = &r600_hpd_init,
+       .hpd_fini = &r600_hpd_fini,
+       .hpd_sense = &r600_hpd_sense,
+       .hpd_set_polarity = &r600_hpd_set_polarity,
+       .ioctl_wait_idle = r600_ioctl_wait_idle,
+};
+
+static struct radeon_asic rv770_asic = {
+       .init = &rv770_init,
+       .fini = &rv770_fini,
+       .suspend = &rv770_suspend,
+       .resume = &rv770_resume,
+       .cp_commit = &r600_cp_commit,
+       .gpu_reset = &rv770_gpu_reset,
+       .vga_set_state = &r600_vga_set_state,
+       .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
+       .gart_set_page = &rs600_gart_set_page,
+       .ring_test = &r600_ring_test,
+       .ring_ib_execute = &r600_ring_ib_execute,
+       .irq_set = &r600_irq_set,
+       .irq_process = &r600_irq_process,
+       .get_vblank_counter = &rs600_get_vblank_counter,
+       .fence_ring_emit = &r600_fence_ring_emit,
+       .cs_parse = &r600_cs_parse,
+       .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,
+       .get_pcie_lanes = &rv370_get_pcie_lanes,
+       .set_pcie_lanes = NULL,
+       .set_clock_gating = &radeon_atom_set_clock_gating,
+       .set_surface_reg = r600_set_surface_reg,
+       .clear_surface_reg = r600_clear_surface_reg,
+       .bandwidth_update = &rv515_bandwidth_update,
+       .hpd_init = &r600_hpd_init,
+       .hpd_fini = &r600_hpd_fini,
+       .hpd_sense = &r600_hpd_sense,
+       .hpd_set_polarity = &r600_hpd_set_polarity,
+       .ioctl_wait_idle = r600_ioctl_wait_idle,
+};
+
+static struct radeon_asic evergreen_asic = {
+       .init = &evergreen_init,
+       .fini = &evergreen_fini,
+       .suspend = &evergreen_suspend,
+       .resume = &evergreen_resume,
+       .cp_commit = NULL,
+       .gpu_reset = &evergreen_gpu_reset,
+       .vga_set_state = &r600_vga_set_state,
+       .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
+       .gart_set_page = &rs600_gart_set_page,
+       .ring_test = NULL,
+       .ring_ib_execute = NULL,
+       .irq_set = NULL,
+       .irq_process = NULL,
+       .get_vblank_counter = NULL,
+       .fence_ring_emit = NULL,
+       .cs_parse = NULL,
+       .copy_blit = NULL,
+       .copy_dma = NULL,
+       .copy = NULL,
+       .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 = NULL,
+       .set_surface_reg = r600_set_surface_reg,
+       .clear_surface_reg = r600_clear_surface_reg,
+       .bandwidth_update = &evergreen_bandwidth_update,
+       .hpd_init = &evergreen_hpd_init,
+       .hpd_fini = &evergreen_hpd_fini,
+       .hpd_sense = &evergreen_hpd_sense,
+       .hpd_set_polarity = &evergreen_hpd_set_polarity,
+};
+
+int radeon_asic_init(struct radeon_device *rdev)
+{
+       radeon_register_accessor_init(rdev);
+       switch (rdev->family) {
+       case CHIP_R100:
+       case CHIP_RV100:
+       case CHIP_RS100:
+       case CHIP_RV200:
+       case CHIP_RS200:
+               rdev->asic = &r100_asic;
+               break;
+       case CHIP_R200:
+       case CHIP_RV250:
+       case CHIP_RS300:
+       case CHIP_RV280:
+               rdev->asic = &r200_asic;
+               break;
+       case CHIP_R300:
+       case CHIP_R350:
+       case CHIP_RV350:
+       case CHIP_RV380:
+               if (rdev->flags & RADEON_IS_PCIE)
+                       rdev->asic = &r300_asic_pcie;
+               else
+                       rdev->asic = &r300_asic;
+               break;
+       case CHIP_R420:
+       case CHIP_R423:
+       case CHIP_RV410:
+               rdev->asic = &r420_asic;
+               break;
+       case CHIP_RS400:
+       case CHIP_RS480:
+               rdev->asic = &rs400_asic;
+               break;
+       case CHIP_RS600:
+               rdev->asic = &rs600_asic;
+               break;
+       case CHIP_RS690:
+       case CHIP_RS740:
+               rdev->asic = &rs690_asic;
+               break;
+       case CHIP_RV515:
+               rdev->asic = &rv515_asic;
+               break;
+       case CHIP_R520:
+       case CHIP_RV530:
+       case CHIP_RV560:
+       case CHIP_RV570:
+       case CHIP_R580:
+               rdev->asic = &r520_asic;
+               break;
+       case CHIP_R600:
+       case CHIP_RV610:
+       case CHIP_RV630:
+       case CHIP_RV620:
+       case CHIP_RV635:
+       case CHIP_RV670:
+               rdev->asic = &r600_asic;
+               break;
+       case CHIP_RS780:
+       case CHIP_RS880:
+               rdev->asic = &rs780_asic;
+               break;
+       case CHIP_RV770:
+       case CHIP_RV730:
+       case CHIP_RV710:
+       case CHIP_RV740:
+               rdev->asic = &rv770_asic;
+               break;
+       case CHIP_CEDAR:
+       case CHIP_REDWOOD:
+       case CHIP_JUNIPER:
+       case CHIP_CYPRESS:
+       case CHIP_HEMLOCK:
+               rdev->asic = &evergreen_asic;
+               break;
+       default:
+               /* FIXME: not supported yet */
+               return -EINVAL;
+       }
+
+       if (rdev->flags & RADEON_IS_IGP) {
+               rdev->asic->get_memory_clock = NULL;
+               rdev->asic->set_memory_clock = NULL;
+       }
+
+       /* set the number of crtcs */
+       if (rdev->flags & RADEON_SINGLE_CRTC)
+               rdev->num_crtc = 1;
+       else {
+               if (ASIC_IS_DCE4(rdev))
+                       rdev->num_crtc = 6;
+               else
+                       rdev->num_crtc = 2;
+       }
+
+       return 0;
+}
+
+/*
+ * Wrapper around modesetting bits. Move to radeon_clocks.c?
+ */
+int radeon_clocks_init(struct radeon_device *rdev)
+{
+       int r;
+
+       r = radeon_static_clocks_init(rdev->ddev);
+       if (r) {
+               return r;
+       }
+       DRM_INFO("Clocks initialized !\n");
+       return 0;
+}
+
+void radeon_clocks_fini(struct radeon_device *rdev)
+{
+}
index d3a157b2bcb73ab51e1d68d0430c65a9916a70b0..a0b8280663d1ba9d17dd6252cce1274d73b7181d 100644 (file)
@@ -45,10 +45,18 @@ void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
 /*
  * r100,rv100,rs100,rv200,rs200
  */
-extern int r100_init(struct radeon_device *rdev);
-extern void r100_fini(struct radeon_device *rdev);
-extern int r100_suspend(struct radeon_device *rdev);
-extern int r100_resume(struct radeon_device *rdev);
+struct r100_mc_save {
+       u32     GENMO_WT;
+       u32     CRTC_EXT_CNTL;
+       u32     CRTC_GEN_CNTL;
+       u32     CRTC2_GEN_CNTL;
+       u32     CUR_OFFSET;
+       u32     CUR2_OFFSET;
+};
+int r100_init(struct radeon_device *rdev);
+void r100_fini(struct radeon_device *rdev);
+int r100_suspend(struct radeon_device *rdev);
+int r100_resume(struct radeon_device *rdev);
 uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg);
 void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 void r100_vga_set_state(struct radeon_device *rdev, bool state);
@@ -73,7 +81,7 @@ int r100_copy_blit(struct radeon_device *rdev,
 int r100_set_surface_reg(struct radeon_device *rdev, int reg,
                         uint32_t tiling_flags, uint32_t pitch,
                         uint32_t offset, uint32_t obj_size);
-int r100_clear_surface_reg(struct radeon_device *rdev, int reg);
+void r100_clear_surface_reg(struct radeon_device *rdev, int reg);
 void r100_bandwidth_update(struct radeon_device *rdev);
 void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
 int r100_ring_test(struct radeon_device *rdev);
@@ -82,44 +90,42 @@ void r100_hpd_fini(struct radeon_device *rdev);
 bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
 void r100_hpd_set_polarity(struct radeon_device *rdev,
                           enum radeon_hpd_id hpd);
-
-static struct radeon_asic r100_asic = {
-       .init = &r100_init,
-       .fini = &r100_fini,
-       .suspend = &r100_suspend,
-       .resume = &r100_resume,
-       .vga_set_state = &r100_vga_set_state,
-       .gpu_reset = &r100_gpu_reset,
-       .gart_tlb_flush = &r100_pci_gart_tlb_flush,
-       .gart_set_page = &r100_pci_gart_set_page,
-       .cp_commit = &r100_cp_commit,
-       .ring_start = &r100_ring_start,
-       .ring_test = &r100_ring_test,
-       .ring_ib_execute = &r100_ring_ib_execute,
-       .irq_set = &r100_irq_set,
-       .irq_process = &r100_irq_process,
-       .get_vblank_counter = &r100_get_vblank_counter,
-       .fence_ring_emit = &r100_fence_ring_emit,
-       .cs_parse = &r100_cs_parse,
-       .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 = &radeon_legacy_get_memory_clock,
-       .set_memory_clock = NULL,
-       .get_pcie_lanes = NULL,
-       .set_pcie_lanes = NULL,
-       .set_clock_gating = &radeon_legacy_set_clock_gating,
-       .set_surface_reg = r100_set_surface_reg,
-       .clear_surface_reg = r100_clear_surface_reg,
-       .bandwidth_update = &r100_bandwidth_update,
-       .hpd_init = &r100_hpd_init,
-       .hpd_fini = &r100_hpd_fini,
-       .hpd_sense = &r100_hpd_sense,
-       .hpd_set_polarity = &r100_hpd_set_polarity,
-       .ioctl_wait_idle = NULL,
-};
+int r100_debugfs_rbbm_init(struct radeon_device *rdev);
+int r100_debugfs_cp_init(struct radeon_device *rdev);
+void r100_cp_disable(struct radeon_device *rdev);
+int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
+void r100_cp_fini(struct radeon_device *rdev);
+int r100_pci_gart_init(struct radeon_device *rdev);
+void r100_pci_gart_fini(struct radeon_device *rdev);
+int r100_pci_gart_enable(struct radeon_device *rdev);
+void r100_pci_gart_disable(struct radeon_device *rdev);
+int r100_debugfs_mc_info_init(struct radeon_device *rdev);
+int r100_gui_wait_for_idle(struct radeon_device *rdev);
+void r100_ib_fini(struct radeon_device *rdev);
+int r100_ib_init(struct radeon_device *rdev);
+void r100_irq_disable(struct radeon_device *rdev);
+void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save);
+void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save);
+void r100_vram_init_sizes(struct radeon_device *rdev);
+void r100_wb_disable(struct radeon_device *rdev);
+void r100_wb_fini(struct radeon_device *rdev);
+int r100_wb_init(struct radeon_device *rdev);
+void r100_hdp_reset(struct radeon_device *rdev);
+int r100_rb2d_reset(struct radeon_device *rdev);
+int r100_cp_reset(struct radeon_device *rdev);
+void r100_vga_render_disable(struct radeon_device *rdev);
+int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
+                                        struct radeon_cs_packet *pkt,
+                                        struct radeon_bo *robj);
+int r100_cs_parse_packet0(struct radeon_cs_parser *p,
+                         struct radeon_cs_packet *pkt,
+                         const unsigned *auth, unsigned n,
+                         radeon_packet0_check_t check);
+int r100_cs_packet_parse(struct radeon_cs_parser *p,
+                        struct radeon_cs_packet *pkt,
+                        unsigned idx);
+void r100_enable_bm(struct radeon_device *rdev);
+void r100_set_common_regs(struct radeon_device *rdev);
 
 /*
  * r200,rv250,rs300,rv280
@@ -129,43 +135,6 @@ extern int r200_copy_dma(struct radeon_device *rdev,
                        uint64_t dst_offset,
                        unsigned num_pages,
                        struct radeon_fence *fence);
-static struct radeon_asic r200_asic = {
-       .init = &r100_init,
-       .fini = &r100_fini,
-       .suspend = &r100_suspend,
-       .resume = &r100_resume,
-       .vga_set_state = &r100_vga_set_state,
-       .gpu_reset = &r100_gpu_reset,
-       .gart_tlb_flush = &r100_pci_gart_tlb_flush,
-       .gart_set_page = &r100_pci_gart_set_page,
-       .cp_commit = &r100_cp_commit,
-       .ring_start = &r100_ring_start,
-       .ring_test = &r100_ring_test,
-       .ring_ib_execute = &r100_ring_ib_execute,
-       .irq_set = &r100_irq_set,
-       .irq_process = &r100_irq_process,
-       .get_vblank_counter = &r100_get_vblank_counter,
-       .fence_ring_emit = &r100_fence_ring_emit,
-       .cs_parse = &r100_cs_parse,
-       .copy_blit = &r100_copy_blit,
-       .copy_dma = &r200_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 = &radeon_legacy_get_memory_clock,
-       .set_memory_clock = NULL,
-       .set_pcie_lanes = NULL,
-       .set_clock_gating = &radeon_legacy_set_clock_gating,
-       .set_surface_reg = r100_set_surface_reg,
-       .clear_surface_reg = r100_clear_surface_reg,
-       .bandwidth_update = &r100_bandwidth_update,
-       .hpd_init = &r100_hpd_init,
-       .hpd_fini = &r100_hpd_fini,
-       .hpd_sense = &r100_hpd_sense,
-       .hpd_set_polarity = &r100_hpd_set_polarity,
-       .ioctl_wait_idle = NULL,
-};
-
 
 /*
  * r300,r350,rv350,rv380
@@ -186,82 +155,6 @@ extern void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v
 extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes);
 extern int rv370_get_pcie_lanes(struct radeon_device *rdev);
 
-static struct radeon_asic r300_asic = {
-       .init = &r300_init,
-       .fini = &r300_fini,
-       .suspend = &r300_suspend,
-       .resume = &r300_resume,
-       .vga_set_state = &r100_vga_set_state,
-       .gpu_reset = &r300_gpu_reset,
-       .gart_tlb_flush = &r100_pci_gart_tlb_flush,
-       .gart_set_page = &r100_pci_gart_set_page,
-       .cp_commit = &r100_cp_commit,
-       .ring_start = &r300_ring_start,
-       .ring_test = &r100_ring_test,
-       .ring_ib_execute = &r100_ring_ib_execute,
-       .irq_set = &r100_irq_set,
-       .irq_process = &r100_irq_process,
-       .get_vblank_counter = &r100_get_vblank_counter,
-       .fence_ring_emit = &r300_fence_ring_emit,
-       .cs_parse = &r300_cs_parse,
-       .copy_blit = &r100_copy_blit,
-       .copy_dma = &r200_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 = &radeon_legacy_get_memory_clock,
-       .set_memory_clock = NULL,
-       .get_pcie_lanes = &rv370_get_pcie_lanes,
-       .set_pcie_lanes = &rv370_set_pcie_lanes,
-       .set_clock_gating = &radeon_legacy_set_clock_gating,
-       .set_surface_reg = r100_set_surface_reg,
-       .clear_surface_reg = r100_clear_surface_reg,
-       .bandwidth_update = &r100_bandwidth_update,
-       .hpd_init = &r100_hpd_init,
-       .hpd_fini = &r100_hpd_fini,
-       .hpd_sense = &r100_hpd_sense,
-       .hpd_set_polarity = &r100_hpd_set_polarity,
-       .ioctl_wait_idle = NULL,
-};
-
-
-static struct radeon_asic r300_asic_pcie = {
-       .init = &r300_init,
-       .fini = &r300_fini,
-       .suspend = &r300_suspend,
-       .resume = &r300_resume,
-       .vga_set_state = &r100_vga_set_state,
-       .gpu_reset = &r300_gpu_reset,
-       .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
-       .gart_set_page = &rv370_pcie_gart_set_page,
-       .cp_commit = &r100_cp_commit,
-       .ring_start = &r300_ring_start,
-       .ring_test = &r100_ring_test,
-       .ring_ib_execute = &r100_ring_ib_execute,
-       .irq_set = &r100_irq_set,
-       .irq_process = &r100_irq_process,
-       .get_vblank_counter = &r100_get_vblank_counter,
-       .fence_ring_emit = &r300_fence_ring_emit,
-       .cs_parse = &r300_cs_parse,
-       .copy_blit = &r100_copy_blit,
-       .copy_dma = &r200_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 = &radeon_legacy_get_memory_clock,
-       .set_memory_clock = NULL,
-       .set_pcie_lanes = &rv370_set_pcie_lanes,
-       .set_clock_gating = &radeon_legacy_set_clock_gating,
-       .set_surface_reg = r100_set_surface_reg,
-       .clear_surface_reg = r100_clear_surface_reg,
-       .bandwidth_update = &r100_bandwidth_update,
-       .hpd_init = &r100_hpd_init,
-       .hpd_fini = &r100_hpd_fini,
-       .hpd_sense = &r100_hpd_sense,
-       .hpd_set_polarity = &r100_hpd_set_polarity,
-       .ioctl_wait_idle = NULL,
-};
-
 /*
  * r420,r423,rv410
  */
@@ -269,44 +162,6 @@ extern int r420_init(struct radeon_device *rdev);
 extern void r420_fini(struct radeon_device *rdev);
 extern int r420_suspend(struct radeon_device *rdev);
 extern int r420_resume(struct radeon_device *rdev);
-static struct radeon_asic r420_asic = {
-       .init = &r420_init,
-       .fini = &r420_fini,
-       .suspend = &r420_suspend,
-       .resume = &r420_resume,
-       .vga_set_state = &r100_vga_set_state,
-       .gpu_reset = &r300_gpu_reset,
-       .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
-       .gart_set_page = &rv370_pcie_gart_set_page,
-       .cp_commit = &r100_cp_commit,
-       .ring_start = &r300_ring_start,
-       .ring_test = &r100_ring_test,
-       .ring_ib_execute = &r100_ring_ib_execute,
-       .irq_set = &r100_irq_set,
-       .irq_process = &r100_irq_process,
-       .get_vblank_counter = &r100_get_vblank_counter,
-       .fence_ring_emit = &r300_fence_ring_emit,
-       .cs_parse = &r300_cs_parse,
-       .copy_blit = &r100_copy_blit,
-       .copy_dma = &r200_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,
-       .get_pcie_lanes = &rv370_get_pcie_lanes,
-       .set_pcie_lanes = &rv370_set_pcie_lanes,
-       .set_clock_gating = &radeon_atom_set_clock_gating,
-       .set_surface_reg = r100_set_surface_reg,
-       .clear_surface_reg = r100_clear_surface_reg,
-       .bandwidth_update = &r100_bandwidth_update,
-       .hpd_init = &r100_hpd_init,
-       .hpd_fini = &r100_hpd_fini,
-       .hpd_sense = &r100_hpd_sense,
-       .hpd_set_polarity = &r100_hpd_set_polarity,
-       .ioctl_wait_idle = NULL,
-};
-
 
 /*
  * rs400,rs480
@@ -319,44 +174,6 @@ void rs400_gart_tlb_flush(struct radeon_device *rdev);
 int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
 uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg);
 void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
-static struct radeon_asic rs400_asic = {
-       .init = &rs400_init,
-       .fini = &rs400_fini,
-       .suspend = &rs400_suspend,
-       .resume = &rs400_resume,
-       .vga_set_state = &r100_vga_set_state,
-       .gpu_reset = &r300_gpu_reset,
-       .gart_tlb_flush = &rs400_gart_tlb_flush,
-       .gart_set_page = &rs400_gart_set_page,
-       .cp_commit = &r100_cp_commit,
-       .ring_start = &r300_ring_start,
-       .ring_test = &r100_ring_test,
-       .ring_ib_execute = &r100_ring_ib_execute,
-       .irq_set = &r100_irq_set,
-       .irq_process = &r100_irq_process,
-       .get_vblank_counter = &r100_get_vblank_counter,
-       .fence_ring_emit = &r300_fence_ring_emit,
-       .cs_parse = &r300_cs_parse,
-       .copy_blit = &r100_copy_blit,
-       .copy_dma = &r200_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 = &radeon_legacy_get_memory_clock,
-       .set_memory_clock = NULL,
-       .get_pcie_lanes = NULL,
-       .set_pcie_lanes = NULL,
-       .set_clock_gating = &radeon_legacy_set_clock_gating,
-       .set_surface_reg = r100_set_surface_reg,
-       .clear_surface_reg = r100_clear_surface_reg,
-       .bandwidth_update = &r100_bandwidth_update,
-       .hpd_init = &r100_hpd_init,
-       .hpd_fini = &r100_hpd_fini,
-       .hpd_sense = &r100_hpd_sense,
-       .hpd_set_polarity = &r100_hpd_set_polarity,
-       .ioctl_wait_idle = NULL,
-};
-
 
 /*
  * rs600.
@@ -379,45 +196,6 @@ bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
 void rs600_hpd_set_polarity(struct radeon_device *rdev,
                            enum radeon_hpd_id hpd);
 
-static struct radeon_asic rs600_asic = {
-       .init = &rs600_init,
-       .fini = &rs600_fini,
-       .suspend = &rs600_suspend,
-       .resume = &rs600_resume,
-       .vga_set_state = &r100_vga_set_state,
-       .gpu_reset = &r300_gpu_reset,
-       .gart_tlb_flush = &rs600_gart_tlb_flush,
-       .gart_set_page = &rs600_gart_set_page,
-       .cp_commit = &r100_cp_commit,
-       .ring_start = &r300_ring_start,
-       .ring_test = &r100_ring_test,
-       .ring_ib_execute = &r100_ring_ib_execute,
-       .irq_set = &rs600_irq_set,
-       .irq_process = &rs600_irq_process,
-       .get_vblank_counter = &rs600_get_vblank_counter,
-       .fence_ring_emit = &r300_fence_ring_emit,
-       .cs_parse = &r300_cs_parse,
-       .copy_blit = &r100_copy_blit,
-       .copy_dma = &r200_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,
-       .get_pcie_lanes = NULL,
-       .set_pcie_lanes = NULL,
-       .set_clock_gating = &radeon_atom_set_clock_gating,
-       .set_surface_reg = r100_set_surface_reg,
-       .clear_surface_reg = r100_clear_surface_reg,
-       .bandwidth_update = &rs600_bandwidth_update,
-       .hpd_init = &rs600_hpd_init,
-       .hpd_fini = &rs600_hpd_fini,
-       .hpd_sense = &rs600_hpd_sense,
-       .hpd_set_polarity = &rs600_hpd_set_polarity,
-       .ioctl_wait_idle = NULL,
-};
-
-
 /*
  * rs690,rs740
  */
@@ -428,44 +206,6 @@ int rs690_suspend(struct radeon_device *rdev);
 uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg);
 void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 void rs690_bandwidth_update(struct radeon_device *rdev);
-static struct radeon_asic rs690_asic = {
-       .init = &rs690_init,
-       .fini = &rs690_fini,
-       .suspend = &rs690_suspend,
-       .resume = &rs690_resume,
-       .vga_set_state = &r100_vga_set_state,
-       .gpu_reset = &r300_gpu_reset,
-       .gart_tlb_flush = &rs400_gart_tlb_flush,
-       .gart_set_page = &rs400_gart_set_page,
-       .cp_commit = &r100_cp_commit,
-       .ring_start = &r300_ring_start,
-       .ring_test = &r100_ring_test,
-       .ring_ib_execute = &r100_ring_ib_execute,
-       .irq_set = &rs600_irq_set,
-       .irq_process = &rs600_irq_process,
-       .get_vblank_counter = &rs600_get_vblank_counter,
-       .fence_ring_emit = &r300_fence_ring_emit,
-       .cs_parse = &r300_cs_parse,
-       .copy_blit = &r100_copy_blit,
-       .copy_dma = &r200_copy_dma,
-       .copy = &r200_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,
-       .get_pcie_lanes = NULL,
-       .set_pcie_lanes = NULL,
-       .set_clock_gating = &radeon_atom_set_clock_gating,
-       .set_surface_reg = r100_set_surface_reg,
-       .clear_surface_reg = r100_clear_surface_reg,
-       .bandwidth_update = &rs690_bandwidth_update,
-       .hpd_init = &rs600_hpd_init,
-       .hpd_fini = &rs600_hpd_fini,
-       .hpd_sense = &rs600_hpd_sense,
-       .hpd_set_polarity = &rs600_hpd_set_polarity,
-       .ioctl_wait_idle = NULL,
-};
-
 
 /*
  * rv515
@@ -481,87 +221,12 @@ void rv515_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 void rv515_bandwidth_update(struct radeon_device *rdev);
 int rv515_resume(struct radeon_device *rdev);
 int rv515_suspend(struct radeon_device *rdev);
-static struct radeon_asic rv515_asic = {
-       .init = &rv515_init,
-       .fini = &rv515_fini,
-       .suspend = &rv515_suspend,
-       .resume = &rv515_resume,
-       .vga_set_state = &r100_vga_set_state,
-       .gpu_reset = &rv515_gpu_reset,
-       .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
-       .gart_set_page = &rv370_pcie_gart_set_page,
-       .cp_commit = &r100_cp_commit,
-       .ring_start = &rv515_ring_start,
-       .ring_test = &r100_ring_test,
-       .ring_ib_execute = &r100_ring_ib_execute,
-       .irq_set = &rs600_irq_set,
-       .irq_process = &rs600_irq_process,
-       .get_vblank_counter = &rs600_get_vblank_counter,
-       .fence_ring_emit = &r300_fence_ring_emit,
-       .cs_parse = &r300_cs_parse,
-       .copy_blit = &r100_copy_blit,
-       .copy_dma = &r200_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,
-       .get_pcie_lanes = &rv370_get_pcie_lanes,
-       .set_pcie_lanes = &rv370_set_pcie_lanes,
-       .set_clock_gating = &radeon_atom_set_clock_gating,
-       .set_surface_reg = r100_set_surface_reg,
-       .clear_surface_reg = r100_clear_surface_reg,
-       .bandwidth_update = &rv515_bandwidth_update,
-       .hpd_init = &rs600_hpd_init,
-       .hpd_fini = &rs600_hpd_fini,
-       .hpd_sense = &rs600_hpd_sense,
-       .hpd_set_polarity = &rs600_hpd_set_polarity,
-       .ioctl_wait_idle = NULL,
-};
-
 
 /*
  * r520,rv530,rv560,rv570,r580
  */
 int r520_init(struct radeon_device *rdev);
 int r520_resume(struct radeon_device *rdev);
-static struct radeon_asic r520_asic = {
-       .init = &r520_init,
-       .fini = &rv515_fini,
-       .suspend = &rv515_suspend,
-       .resume = &r520_resume,
-       .vga_set_state = &r100_vga_set_state,
-       .gpu_reset = &rv515_gpu_reset,
-       .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
-       .gart_set_page = &rv370_pcie_gart_set_page,
-       .cp_commit = &r100_cp_commit,
-       .ring_start = &rv515_ring_start,
-       .ring_test = &r100_ring_test,
-       .ring_ib_execute = &r100_ring_ib_execute,
-       .irq_set = &rs600_irq_set,
-       .irq_process = &rs600_irq_process,
-       .get_vblank_counter = &rs600_get_vblank_counter,
-       .fence_ring_emit = &r300_fence_ring_emit,
-       .cs_parse = &r300_cs_parse,
-       .copy_blit = &r100_copy_blit,
-       .copy_dma = &r200_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,
-       .get_pcie_lanes = &rv370_get_pcie_lanes,
-       .set_pcie_lanes = &rv370_set_pcie_lanes,
-       .set_clock_gating = &radeon_atom_set_clock_gating,
-       .set_surface_reg = r100_set_surface_reg,
-       .clear_surface_reg = r100_clear_surface_reg,
-       .bandwidth_update = &rv515_bandwidth_update,
-       .hpd_init = &rs600_hpd_init,
-       .hpd_fini = &rs600_hpd_fini,
-       .hpd_sense = &rs600_hpd_sense,
-       .hpd_set_polarity = &rs600_hpd_set_polarity,
-       .ioctl_wait_idle = NULL,
-};
 
 /*
  * r600,rv610,rv630,rv620,rv635,rv670,rs780,rs880
@@ -591,7 +256,7 @@ int r600_gpu_reset(struct radeon_device *rdev);
 int r600_set_surface_reg(struct radeon_device *rdev, int reg,
                         uint32_t tiling_flags, uint32_t pitch,
                         uint32_t offset, uint32_t obj_size);
-int r600_clear_surface_reg(struct radeon_device *rdev, int reg);
+void r600_clear_surface_reg(struct radeon_device *rdev, int reg);
 void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
 int r600_ring_test(struct radeon_device *rdev);
 int r600_copy_blit(struct radeon_device *rdev,
@@ -604,43 +269,6 @@ void r600_hpd_set_polarity(struct radeon_device *rdev,
                           enum radeon_hpd_id hpd);
 extern void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo);
 
-static struct radeon_asic r600_asic = {
-       .init = &r600_init,
-       .fini = &r600_fini,
-       .suspend = &r600_suspend,
-       .resume = &r600_resume,
-       .cp_commit = &r600_cp_commit,
-       .vga_set_state = &r600_vga_set_state,
-       .gpu_reset = &r600_gpu_reset,
-       .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
-       .gart_set_page = &rs600_gart_set_page,
-       .ring_test = &r600_ring_test,
-       .ring_ib_execute = &r600_ring_ib_execute,
-       .irq_set = &r600_irq_set,
-       .irq_process = &r600_irq_process,
-       .get_vblank_counter = &rs600_get_vblank_counter,
-       .fence_ring_emit = &r600_fence_ring_emit,
-       .cs_parse = &r600_cs_parse,
-       .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,
-       .get_pcie_lanes = &rv370_get_pcie_lanes,
-       .set_pcie_lanes = NULL,
-       .set_clock_gating = NULL,
-       .set_surface_reg = r600_set_surface_reg,
-       .clear_surface_reg = r600_clear_surface_reg,
-       .bandwidth_update = &rv515_bandwidth_update,
-       .hpd_init = &r600_hpd_init,
-       .hpd_fini = &r600_hpd_fini,
-       .hpd_sense = &r600_hpd_sense,
-       .hpd_set_polarity = &r600_hpd_set_polarity,
-       .ioctl_wait_idle = r600_ioctl_wait_idle,
-};
-
 /*
  * rv770,rv730,rv710,rv740
  */
@@ -650,43 +278,6 @@ int rv770_suspend(struct radeon_device *rdev);
 int rv770_resume(struct radeon_device *rdev);
 int rv770_gpu_reset(struct radeon_device *rdev);
 
-static struct radeon_asic rv770_asic = {
-       .init = &rv770_init,
-       .fini = &rv770_fini,
-       .suspend = &rv770_suspend,
-       .resume = &rv770_resume,
-       .cp_commit = &r600_cp_commit,
-       .gpu_reset = &rv770_gpu_reset,
-       .vga_set_state = &r600_vga_set_state,
-       .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
-       .gart_set_page = &rs600_gart_set_page,
-       .ring_test = &r600_ring_test,
-       .ring_ib_execute = &r600_ring_ib_execute,
-       .irq_set = &r600_irq_set,
-       .irq_process = &r600_irq_process,
-       .get_vblank_counter = &rs600_get_vblank_counter,
-       .fence_ring_emit = &r600_fence_ring_emit,
-       .cs_parse = &r600_cs_parse,
-       .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,
-       .get_pcie_lanes = &rv370_get_pcie_lanes,
-       .set_pcie_lanes = NULL,
-       .set_clock_gating = &radeon_atom_set_clock_gating,
-       .set_surface_reg = r600_set_surface_reg,
-       .clear_surface_reg = r600_clear_surface_reg,
-       .bandwidth_update = &rv515_bandwidth_update,
-       .hpd_init = &r600_hpd_init,
-       .hpd_fini = &r600_hpd_fini,
-       .hpd_sense = &r600_hpd_sense,
-       .hpd_set_polarity = &r600_hpd_set_polarity,
-       .ioctl_wait_idle = r600_ioctl_wait_idle,
-};
-
 /*
  * evergreen
  */
@@ -701,40 +292,4 @@ void evergreen_hpd_fini(struct radeon_device *rdev);
 bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
 void evergreen_hpd_set_polarity(struct radeon_device *rdev,
                                enum radeon_hpd_id hpd);
-
-static struct radeon_asic evergreen_asic = {
-       .init = &evergreen_init,
-       .fini = &evergreen_fini,
-       .suspend = &evergreen_suspend,
-       .resume = &evergreen_resume,
-       .cp_commit = NULL,
-       .gpu_reset = &evergreen_gpu_reset,
-       .vga_set_state = &r600_vga_set_state,
-       .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
-       .gart_set_page = &rs600_gart_set_page,
-       .ring_test = NULL,
-       .ring_ib_execute = NULL,
-       .irq_set = NULL,
-       .irq_process = NULL,
-       .get_vblank_counter = NULL,
-       .fence_ring_emit = NULL,
-       .cs_parse = NULL,
-       .copy_blit = NULL,
-       .copy_dma = NULL,
-       .copy = NULL,
-       .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 = NULL,
-       .set_surface_reg = r600_set_surface_reg,
-       .clear_surface_reg = r600_clear_surface_reg,
-       .bandwidth_update = &evergreen_bandwidth_update,
-       .hpd_init = &evergreen_hpd_init,
-       .hpd_fini = &evergreen_hpd_fini,
-       .hpd_sense = &evergreen_hpd_sense,
-       .hpd_set_polarity = &evergreen_hpd_set_polarity,
-};
-
 #endif
index 93783b15c81d8226d9833c730af74250d8e3fb5e..9916d825401c18f4f3c0d49fdb61110512290d52 100644 (file)
@@ -69,52 +69,54 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev
        struct radeon_i2c_bus_rec i2c;
        int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
        struct _ATOM_GPIO_I2C_INFO *i2c_info;
-       uint16_t data_offset;
-       int i;
+       uint16_t data_offset, size;
+       int i, num_indices;
 
        memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
        i2c.valid = false;
 
-       atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset);
-
-       i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
-
-
-       for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
-               gpio = &i2c_info->asGPIO_Info[i];
-
-               if (gpio->sucI2cId.ucAccess == id) {
-                       i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
-                       i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
-                       i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
-                       i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
-                       i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
-                       i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
-                       i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
-                       i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
-                       i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
-                       i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
-                       i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
-                       i2c.en_data_mask = (1 << gpio->ucDataEnShift);
-                       i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
-                       i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
-                       i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
-                       i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
-
-                       if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
-                               i2c.hw_capable = true;
-                       else
-                               i2c.hw_capable = false;
-
-                       if (gpio->sucI2cId.ucAccess == 0xa0)
-                               i2c.mm_i2c = true;
-                       else
-                               i2c.mm_i2c = false;
-
-                       i2c.i2c_id = gpio->sucI2cId.ucAccess;
-
-                       i2c.valid = true;
-                       break;
+       if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
+               i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
+
+               num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
+                       sizeof(ATOM_GPIO_I2C_ASSIGMENT);
+
+               for (i = 0; i < num_indices; i++) {
+                       gpio = &i2c_info->asGPIO_Info[i];
+
+                       if (gpio->sucI2cId.ucAccess == id) {
+                               i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
+                               i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
+                               i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
+                               i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
+                               i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
+                               i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
+                               i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
+                               i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
+                               i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
+                               i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
+                               i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
+                               i2c.en_data_mask = (1 << gpio->ucDataEnShift);
+                               i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
+                               i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
+                               i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
+                               i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
+
+                               if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
+                                       i2c.hw_capable = true;
+                               else
+                                       i2c.hw_capable = false;
+
+                               if (gpio->sucI2cId.ucAccess == 0xa0)
+                                       i2c.mm_i2c = true;
+                               else
+                                       i2c.mm_i2c = false;
+
+                               i2c.i2c_id = gpio->sucI2cId.ucAccess;
+
+                               i2c.valid = true;
+                               break;
+                       }
                }
        }
 
@@ -135,20 +137,21 @@ static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rd
        memset(&gpio, 0, sizeof(struct radeon_gpio_rec));
        gpio.valid = false;
 
-       atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset);
+       if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
+               gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);
 
-       gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset);
+               num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
+                       sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
 
-       num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
-
-       for (i = 0; i < num_indices; i++) {
-               pin = &gpio_info->asGPIO_Pin[i];
-               if (id == pin->ucGPIO_ID) {
-                       gpio.id = pin->ucGPIO_ID;
-                       gpio.reg = pin->usGpioPin_AIndex * 4;
-                       gpio.mask = (1 << pin->ucGpioPinBitShift);
-                       gpio.valid = true;
-                       break;
+               for (i = 0; i < num_indices; i++) {
+                       pin = &gpio_info->asGPIO_Pin[i];
+                       if (id == pin->ucGPIO_ID) {
+                               gpio.id = pin->ucGPIO_ID;
+                               gpio.reg = pin->usGpioPin_AIndex * 4;
+                               gpio.mask = (1 << pin->ucGpioPinBitShift);
+                               gpio.valid = true;
+                               break;
+                       }
                }
        }
 
@@ -264,6 +267,8 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
                if ((supported_device == ATOM_DEVICE_CRT1_SUPPORT) ||
                    (supported_device == ATOM_DEVICE_DFP2_SUPPORT))
                        return false;
+               if (supported_device == ATOM_DEVICE_CRT2_SUPPORT)
+                       *line_mux = 0x90;
        }
 
        /* ASUS HD 3600 XT board lists the DVI port as HDMI */
@@ -395,9 +400,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
        struct radeon_gpio_rec gpio;
        struct radeon_hpd hpd;
 
-       atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
-
-       if (data_offset == 0)
+       if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))
                return false;
 
        if (crev < 2)
@@ -449,37 +452,43 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                                    GetIndexIntoMasterTable(DATA,
                                                            IntegratedSystemInfo);
 
-                               atom_parse_data_header(ctx, index, &size, &frev,
-                                                      &crev, &igp_offset);
-
-                               if (crev >= 2) {
-                                       igp_obj =
-                                           (ATOM_INTEGRATED_SYSTEM_INFO_V2
-                                            *) (ctx->bios + igp_offset);
-
-                                       if (igp_obj) {
-                                               uint32_t slot_config, ct;
-
-                                               if (con_obj_num == 1)
-                                                       slot_config =
-                                                           igp_obj->
-                                                           ulDDISlot1Config;
-                                               else
-                                                       slot_config =
-                                                           igp_obj->
-                                                           ulDDISlot2Config;
-
-                                               ct = (slot_config >> 16) & 0xff;
-                                               connector_type =
-                                                   object_connector_convert
-                                                   [ct];
-                                               connector_object_id = ct;
-                                               igp_lane_info =
-                                                   slot_config & 0xffff;
+                               if (atom_parse_data_header(ctx, index, &size, &frev,
+                                                          &crev, &igp_offset)) {
+
+                                       if (crev >= 2) {
+                                               igp_obj =
+                                                       (ATOM_INTEGRATED_SYSTEM_INFO_V2
+                                                        *) (ctx->bios + igp_offset);
+
+                                               if (igp_obj) {
+                                                       uint32_t slot_config, ct;
+
+                                                       if (con_obj_num == 1)
+                                                               slot_config =
+                                                                       igp_obj->
+                                                                       ulDDISlot1Config;
+                                                       else
+                                                               slot_config =
+                                                                       igp_obj->
+                                                                       ulDDISlot2Config;
+
+                                                       ct = (slot_config >> 16) & 0xff;
+                                                       connector_type =
+                                                               object_connector_convert
+                                                               [ct];
+                                                       connector_object_id = ct;
+                                                       igp_lane_info =
+                                                               slot_config & 0xffff;
+                                               } else
+                                                       continue;
                                        } else
                                                continue;
-                               } else
-                                       continue;
+                               } else {
+                                       igp_lane_info = 0;
+                                       connector_type =
+                                               object_connector_convert[con_obj_id];
+                                       connector_object_id = con_obj_id;
+                               }
                        } else {
                                igp_lane_info = 0;
                                connector_type =
@@ -627,20 +636,23 @@ static uint16_t atombios_get_connector_object_id(struct drm_device *dev,
                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 (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;
-               }
+                       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];
        } else {
                return supported_devices_connector_object_id_convert
                        [connector_type];
@@ -672,7 +684,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
        int i, j, max_device;
        struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE];
 
-       atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
+       if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))
+               return false;
 
        supported_devices =
            (union atom_supported_devices *)(ctx->bios + data_offset);
@@ -865,14 +878,11 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
        struct radeon_pll *mpll = &rdev->clock.mpll;
        uint16_t data_offset;
 
-       atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
-                              &crev, &data_offset);
-
-       firmware_info =
-           (union firmware_info *)(mode_info->atom_context->bios +
-                                   data_offset);
-
-       if (firmware_info) {
+       if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+                                  &frev, &crev, &data_offset)) {
+               firmware_info =
+                       (union firmware_info *)(mode_info->atom_context->bios +
+                                               data_offset);
                /* pixel clocks */
                p1pll->reference_freq =
                    le16_to_cpu(firmware_info->info.usReferenceClock);
@@ -887,6 +897,20 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
                p1pll->pll_out_max =
                    le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);
 
+               if (crev >= 4) {
+                       p1pll->lcd_pll_out_min =
+                               le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100;
+                       if (p1pll->lcd_pll_out_min == 0)
+                               p1pll->lcd_pll_out_min = p1pll->pll_out_min;
+                       p1pll->lcd_pll_out_max =
+                               le16_to_cpu(firmware_info->info_14.usLcdMaxPixelClockPLL_Output) * 100;
+                       if (p1pll->lcd_pll_out_max == 0)
+                               p1pll->lcd_pll_out_max = p1pll->pll_out_max;
+               } else {
+                       p1pll->lcd_pll_out_min = p1pll->pll_out_min;
+                       p1pll->lcd_pll_out_max = p1pll->pll_out_max;
+               }
+
                if (p1pll->pll_out_min == 0) {
                        if (ASIC_IS_AVIVO(rdev))
                                p1pll->pll_out_min = 64800;
@@ -992,13 +1016,10 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev)
        u8 frev, crev;
        u16 data_offset;
 
-       atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
-                              &crev, &data_offset);
-
-       igp_info = (union igp_info *)(mode_info->atom_context->bios +
+       if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+                                  &frev, &crev, &data_offset)) {
+               igp_info = (union igp_info *)(mode_info->atom_context->bios +
                                      data_offset);
-
-       if (igp_info) {
                switch (crev) {
                case 1:
                        if (igp_info->info.ucMemoryType & 0xf0)
@@ -1029,14 +1050,12 @@ bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
        uint16_t maxfreq;
        int i;
 
-       atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
-                              &crev, &data_offset);
+       if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+                                  &frev, &crev, &data_offset)) {
+               tmds_info =
+                       (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios +
+                                                  data_offset);
 
-       tmds_info =
-           (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios +
-                                      data_offset);
-
-       if (tmds_info) {
                maxfreq = le16_to_cpu(tmds_info->usMaxFrequency);
                for (i = 0; i < 4; i++) {
                        tmds->tmds_pll[i].freq =
@@ -1085,13 +1104,11 @@ static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct
        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 (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);
 
@@ -1114,30 +1131,6 @@ static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct
        return ss;
 }
 
-static void radeon_atom_apply_lvds_quirks(struct drm_device *dev,
-                                         struct radeon_encoder_atom_dig *lvds)
-{
-
-       /* Toshiba A300-1BU laptop panel doesn't like new pll divider algo */
-       if ((dev->pdev->device == 0x95c4) &&
-           (dev->pdev->subsystem_vendor == 0x1179) &&
-           (dev->pdev->subsystem_device == 0xff50)) {
-               if ((lvds->native_mode.hdisplay == 1280) &&
-                   (lvds->native_mode.vdisplay == 800))
-                       lvds->pll_algo = PLL_ALGO_LEGACY;
-       }
-
-       /* Dell Studio 15 laptop panel doesn't like new pll divider algo */
-       if ((dev->pdev->device == 0x95c4) &&
-           (dev->pdev->subsystem_vendor == 0x1028) &&
-           (dev->pdev->subsystem_device == 0x029f)) {
-               if ((lvds->native_mode.hdisplay == 1280) &&
-                   (lvds->native_mode.vdisplay == 800))
-                       lvds->pll_algo = PLL_ALGO_LEGACY;
-       }
-
-}
-
 union lvds_info {
        struct _ATOM_LVDS_INFO info;
        struct _ATOM_LVDS_INFO_V12 info_12;
@@ -1156,13 +1149,10 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
        uint8_t frev, crev;
        struct radeon_encoder_atom_dig *lvds = NULL;
 
-       atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
-                              &crev, &data_offset);
-
-       lvds_info =
-           (union lvds_info *)(mode_info->atom_context->bios + data_offset);
-
-       if (lvds_info) {
+       if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+                                  &frev, &crev, &data_offset)) {
+               lvds_info =
+                       (union lvds_info *)(mode_info->atom_context->bios + data_offset);
                lvds =
                    kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL);
 
@@ -1220,9 +1210,6 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
                                lvds->pll_algo = PLL_ALGO_LEGACY;
                }
 
-               /* LVDS quirks */
-               radeon_atom_apply_lvds_quirks(dev, lvds);
-
                encoder->native_mode = lvds->native_mode;
        }
        return lvds;
@@ -1241,11 +1228,11 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder)
        uint8_t bg, dac;
        struct radeon_encoder_primary_dac *p_dac = NULL;
 
-       atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
-
-       dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset);
+       if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+                                  &frev, &crev, &data_offset)) {
+               dac_info = (struct _COMPASSIONATE_DATA *)
+                       (mode_info->atom_context->bios + data_offset);
 
-       if (dac_info) {
                p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL);
 
                if (!p_dac)
@@ -1270,12 +1257,14 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
        u8 frev, crev;
        u16 data_offset, misc;
 
-       atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset);
+       if (!atom_parse_data_header(mode_info->atom_context, data_index, NULL,
+                                   &frev, &crev, &data_offset))
+               return false;
 
        switch (crev) {
        case 1:
                tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset);
-               if (index > MAX_SUPPORTED_TV_TIMING)
+               if (index >= MAX_SUPPORTED_TV_TIMING)
                        return false;
 
                mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);
@@ -1313,7 +1302,7 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
                break;
        case 2:
                tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset);
-               if (index > MAX_SUPPORTED_TV_TIMING_V1_2)
+               if (index >= MAX_SUPPORTED_TV_TIMING_V1_2)
                        return false;
 
                dtd_timings = &tv_info_v1_2->aModeTimings[index];
@@ -1362,47 +1351,50 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev)
        struct _ATOM_ANALOG_TV_INFO *tv_info;
        enum radeon_tv_std tv_std = TV_STD_NTSC;
 
-       atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
+       if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+                                  &frev, &crev, &data_offset)) {
 
-       tv_info = (struct _ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset);
+               tv_info = (struct _ATOM_ANALOG_TV_INFO *)
+                       (mode_info->atom_context->bios + data_offset);
 
-       switch (tv_info->ucTV_BootUpDefaultStandard) {
-       case ATOM_TV_NTSC:
-               tv_std = TV_STD_NTSC;
-               DRM_INFO("Default TV standard: NTSC\n");
-               break;
-       case ATOM_TV_NTSCJ:
-               tv_std = TV_STD_NTSC_J;
-               DRM_INFO("Default TV standard: NTSC-J\n");
-               break;
-       case ATOM_TV_PAL:
-               tv_std = TV_STD_PAL;
-               DRM_INFO("Default TV standard: PAL\n");
-               break;
-       case ATOM_TV_PALM:
-               tv_std = TV_STD_PAL_M;
-               DRM_INFO("Default TV standard: PAL-M\n");
-               break;
-       case ATOM_TV_PALN:
-               tv_std = TV_STD_PAL_N;
-               DRM_INFO("Default TV standard: PAL-N\n");
-               break;
-       case ATOM_TV_PALCN:
-               tv_std = TV_STD_PAL_CN;
-               DRM_INFO("Default TV standard: PAL-CN\n");
-               break;
-       case ATOM_TV_PAL60:
-               tv_std = TV_STD_PAL_60;
-               DRM_INFO("Default TV standard: PAL-60\n");
-               break;
-       case ATOM_TV_SECAM:
-               tv_std = TV_STD_SECAM;
-               DRM_INFO("Default TV standard: SECAM\n");
-               break;
-       default:
-               tv_std = TV_STD_NTSC;
-               DRM_INFO("Unknown TV standard; defaulting to NTSC\n");
-               break;
+               switch (tv_info->ucTV_BootUpDefaultStandard) {
+               case ATOM_TV_NTSC:
+                       tv_std = TV_STD_NTSC;
+                       DRM_INFO("Default TV standard: NTSC\n");
+                       break;
+               case ATOM_TV_NTSCJ:
+                       tv_std = TV_STD_NTSC_J;
+                       DRM_INFO("Default TV standard: NTSC-J\n");
+                       break;
+               case ATOM_TV_PAL:
+                       tv_std = TV_STD_PAL;
+                       DRM_INFO("Default TV standard: PAL\n");
+                       break;
+               case ATOM_TV_PALM:
+                       tv_std = TV_STD_PAL_M;
+                       DRM_INFO("Default TV standard: PAL-M\n");
+                       break;
+               case ATOM_TV_PALN:
+                       tv_std = TV_STD_PAL_N;
+                       DRM_INFO("Default TV standard: PAL-N\n");
+                       break;
+               case ATOM_TV_PALCN:
+                       tv_std = TV_STD_PAL_CN;
+                       DRM_INFO("Default TV standard: PAL-CN\n");
+                       break;
+               case ATOM_TV_PAL60:
+                       tv_std = TV_STD_PAL_60;
+                       DRM_INFO("Default TV standard: PAL-60\n");
+                       break;
+               case ATOM_TV_SECAM:
+                       tv_std = TV_STD_SECAM;
+                       DRM_INFO("Default TV standard: SECAM\n");
+                       break;
+               default:
+                       tv_std = TV_STD_NTSC;
+                       DRM_INFO("Unknown TV standard; defaulting to NTSC\n");
+                       break;
+               }
        }
        return tv_std;
 }
@@ -1420,11 +1412,12 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)
        uint8_t bg, dac;
        struct radeon_encoder_tv_dac *tv_dac = NULL;
 
-       atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
+       if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+                                  &frev, &crev, &data_offset)) {
 
-       dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset);
+               dac_info = (struct _COMPASSIONATE_DATA *)
+                       (mode_info->atom_context->bios + data_offset);
 
-       if (dac_info) {
                tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL);
 
                if (!tv_dac)
@@ -1447,6 +1440,30 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)
        return tv_dac;
 }
 
+static const char *thermal_controller_names[] = {
+       "NONE",
+       "LM63",
+       "ADM1032",
+       "ADM1030",
+       "MUA6649",
+       "LM64",
+       "F75375",
+       "ASC7512",
+};
+
+static const char *pp_lib_thermal_controller_names[] = {
+       "NONE",
+       "LM63",
+       "ADM1032",
+       "ADM1030",
+       "MUA6649",
+       "LM64",
+       "F75375",
+       "RV6xx",
+       "RV770",
+       "ADT7473",
+};
+
 union power_info {
        struct _ATOM_POWERPLAY_INFO info;
        struct _ATOM_POWERPLAY_INFO_V2 info_2;
@@ -1466,15 +1483,22 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
        struct _ATOM_PPLIB_STATE *power_state;
        int num_modes = 0, i, j;
        int state_index = 0, mode_index = 0;
-
-       atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
-
-       power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
+       struct radeon_i2c_bus_rec i2c_bus;
 
        rdev->pm.default_power_state = NULL;
 
-       if (power_info) {
+       if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+                                  &frev, &crev, &data_offset)) {
+               power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
                if (frev < 4) {
+                       /* add the i2c bus for thermal/fan chip */
+                       if (power_info->info.ucOverdriveThermalController > 0) {
+                               DRM_INFO("Possible %s thermal controller at 0x%02x\n",
+                                        thermal_controller_names[power_info->info.ucOverdriveThermalController],
+                                        power_info->info.ucOverdriveControllerAddress >> 1);
+                               i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine);
+                               rdev->pm.i2c_bus = radeon_i2c_create(rdev->ddev, &i2c_bus, "Thermal");
+                       }
                        num_modes = power_info->info.ucNumOfPowerModeEntries;
                        if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK)
                                num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK;
@@ -1684,6 +1708,24 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
                                }
                        }
                } else if (frev == 4) {
+                       /* add the i2c bus for thermal/fan chip */
+                       /* no support for internal controller yet */
+                       if (power_info->info_4.sThermalController.ucType > 0) {
+                               if ((power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) ||
+                                   (power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_RV770)) {
+                                       DRM_INFO("Internal thermal controller %s fan control\n",
+                                                (power_info->info_4.sThermalController.ucFanParameters &
+                                                 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
+                               } else {
+                                       DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n",
+                                                pp_lib_thermal_controller_names[power_info->info_4.sThermalController.ucType],
+                                                power_info->info_4.sThermalController.ucI2cAddress >> 1,
+                                                (power_info->info_4.sThermalController.ucFanParameters &
+                                                 ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
+                                       i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info_4.sThermalController.ucI2cLine);
+                                       rdev->pm.i2c_bus = radeon_i2c_create(rdev->ddev, &i2c_bus, "Thermal");
+                               }
+                       }
                        for (i = 0; i < power_info->info_4.ucNumStates; i++) {
                                mode_index = 0;
                                power_state = (struct _ATOM_PPLIB_STATE *)
index 3f557c4151e0bb7fe2af9e9aaa1bdbec7d2da60f..ed5dfe58f29c0845e8eb8a478560b9a01fe17677 100644 (file)
@@ -7,6 +7,7 @@
  * ATPX support for both Intel/ATI
  */
 #include <linux/vga_switcheroo.h>
+#include <linux/slab.h>
 #include <acpi/acpi.h>
 #include <acpi/acpi_bus.h>
 #include <linux/pci.h>
index 557240460526828aeef9bc3aec07cfef26800fc0..8ad71f70131624562ae4d02d6eabe159ede924e4 100644 (file)
@@ -31,6 +31,7 @@
 #include "atom.h"
 
 #include <linux/vga_switcheroo.h>
+#include <linux/slab.h>
 /*
  * BIOS.
  */
index e9ea38ece37558a6bf123b18a982b06ec252872a..37db8adb27481678b959f74f1f7432a177485ddb 100644 (file)
@@ -531,10 +531,7 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde
        case CHIP_RS300:
                switch (ddc_line) {
                case RADEON_GPIO_DVI_DDC:
-                       /* in theory this should be hw capable,
-                        * but it doesn't seem to work
-                        */
-                       i2c.hw_capable = false;
+                       i2c.hw_capable = true;
                        break;
                default:
                        i2c.hw_capable = false;
@@ -633,6 +630,8 @@ bool radeon_combios_get_clock_info(struct drm_device *dev)
                p1pll->reference_div = RBIOS16(pll_info + 0x10);
                p1pll->pll_out_min = RBIOS32(pll_info + 0x12);
                p1pll->pll_out_max = RBIOS32(pll_info + 0x16);
+               p1pll->lcd_pll_out_min = p1pll->pll_out_min;
+               p1pll->lcd_pll_out_max = p1pll->pll_out_max;
 
                if (rev > 9) {
                        p1pll->pll_in_min = RBIOS32(pll_info + 0x36);
@@ -761,7 +760,9 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct
                        dac = RBIOS8(dac_info + 0x3) & 0xf;
                        p_dac->ps2_pdac_adj = (bg << 8) | (dac);
                }
-               found = 1;
+               /* if the values are all zeros, use the table */
+               if (p_dac->ps2_pdac_adj)
+                       found = 1;
        }
 
        if (!found) /* fallback to defaults */
@@ -896,7 +897,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
                        bg = RBIOS8(dac_info + 0x10) & 0xf;
                        dac = RBIOS8(dac_info + 0x11) & 0xf;
                        tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
-                       found = 1;
+                       /* if the values are all zeros, use the table */
+                       if (tv_dac->ps2_tvdac_adj)
+                               found = 1;
                } else if (rev > 1) {
                        bg = RBIOS8(dac_info + 0xc) & 0xf;
                        dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf;
@@ -909,7 +912,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
                        bg = RBIOS8(dac_info + 0xe) & 0xf;
                        dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf;
                        tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
-                       found = 1;
+                       /* if the values are all zeros, use the table */
+                       if (tv_dac->ps2_tvdac_adj)
+                               found = 1;
                }
                tv_dac->tv_std = radeon_combios_get_tv_info(rdev);
        }
@@ -926,7 +931,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
                                    (bg << 16) | (dac << 20);
                                tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
                                tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
-                               found = 1;
+                               /* if the values are all zeros, use the table */
+                               if (tv_dac->ps2_tvdac_adj)
+                                       found = 1;
                        } else {
                                bg = RBIOS8(dac_info + 0x4) & 0xf;
                                dac = RBIOS8(dac_info + 0x5) & 0xf;
@@ -934,7 +941,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
                                    (bg << 16) | (dac << 20);
                                tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
                                tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
-                               found = 1;
+                               /* if the values are all zeros, use the table */
+                               if (tv_dac->ps2_tvdac_adj)
+                                       found = 1;
                        }
                } else {
                        DRM_INFO("No TV DAC info found in BIOS\n");
index ee0083f982d8ba2a926688e083ea930716e0de91..4559a53d5e57e55b42994671b9e0ffe2cdc42f11 100644 (file)
@@ -162,12 +162,14 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector,
 {
        struct drm_device *dev = connector->dev;
        struct drm_connector *conflict;
+       struct radeon_connector *radeon_conflict;
        int i;
 
        list_for_each_entry(conflict, &dev->mode_config.connector_list, head) {
                if (conflict == connector)
                        continue;
 
+               radeon_conflict = to_radeon_connector(conflict);
                for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
                        if (conflict->encoder_ids[i] == 0)
                                break;
@@ -177,6 +179,9 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector,
                                if (conflict->status != connector_status_connected)
                                        continue;
 
+                               if (radeon_conflict->use_digital)
+                                       continue;
+
                                if (priority == true) {
                                        DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict));
                                        DRM_INFO("in favor of %s\n", drm_get_connector_name(connector));
@@ -287,6 +292,7 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr
 
        if (property == rdev->mode_info.coherent_mode_property) {
                struct radeon_encoder_atom_dig *dig;
+               bool new_coherent_mode;
 
                /* need to find digital encoder on connector */
                encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
@@ -299,8 +305,11 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr
                        return 0;
 
                dig = radeon_encoder->enc_priv;
-               dig->coherent_mode = val ? true : false;
-               radeon_property_change_mode(&radeon_encoder->base);
+               new_coherent_mode = val ? true : false;
+               if (dig->coherent_mode != new_coherent_mode) {
+                       dig->coherent_mode = new_coherent_mode;
+                       radeon_property_change_mode(&radeon_encoder->base);
+               }
        }
 
        if (property == rdev->mode_info.tv_std_property) {
@@ -315,7 +324,7 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr
                radeon_encoder = to_radeon_encoder(encoder);
                if (!radeon_encoder->enc_priv)
                        return 0;
-               if (rdev->is_atom_bios) {
+               if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) {
                        struct radeon_encoder_atom_dac *dac_int;
                        dac_int = radeon_encoder->enc_priv;
                        dac_int->tv_std = val;
@@ -940,7 +949,7 @@ static void radeon_dp_connector_destroy(struct drm_connector *connector)
        if (radeon_connector->edid)
                kfree(radeon_connector->edid);
        if (radeon_dig_connector->dp_i2c_bus)
-               radeon_i2c_destroy_dp(radeon_dig_connector->dp_i2c_bus);
+               radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus);
        kfree(radeon_connector->con_priv);
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
@@ -1307,6 +1316,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                        radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
                        if (!radeon_connector->ddc_bus)
                                goto failed;
+               }
+               if (connector_type == DRM_MODE_CONNECTOR_DVII) {
                        radeon_connector->dac_load_detect = true;
                        drm_connector_attach_property(&radeon_connector->base,
                                                      rdev->mode_info.load_detect_property,
index dc6eba6b96dd1f5476cd3f6bda470e0cda6b245b..2f042a3c0e62bb7bbe86fefa478109be033f1bb8 100644 (file)
@@ -417,8 +417,9 @@ static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv)
        return -EBUSY;
 }
 
-static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
+static void radeon_init_pipes(struct drm_device *dev)
 {
+       drm_radeon_private_t *dev_priv = dev->dev_private;
        uint32_t gb_tile_config, gb_pipe_sel = 0;
 
        if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) {
@@ -434,13 +435,19 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
        if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) {
                gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT);
                dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
+               /* SE cards have 1 pipe */
+               if ((dev->pdev->device == 0x5e4c) ||
+                   (dev->pdev->device == 0x5e4f))
+                       dev_priv->num_gb_pipes = 1;
        } else {
                /* R3xx */
-               if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) ||
-                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) {
+               if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300 &&
+                    dev->pdev->device != 0x4144) ||
+                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350 &&
+                    dev->pdev->device != 0x4148)) {
                        dev_priv->num_gb_pipes = 2;
                } else {
-                       /* R3Vxx */
+                       /* RV3xx/R300 AD/R350 AH */
                        dev_priv->num_gb_pipes = 1;
                }
        }
@@ -736,7 +743,7 @@ static int radeon_do_engine_reset(struct drm_device * dev)
 
        /* setup the raster pipes */
        if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R300)
-           radeon_init_pipes(dev_priv);
+           radeon_init_pipes(dev);
 
        /* Reset the CP ring */
        radeon_do_cp_reset(dev_priv);
index 70ba02ed77237ba31299a7cbc56694dc3e62d57a..f9b0fe002c0ab7f27430a697f95a841667281e41 100644 (file)
@@ -193,9 +193,11 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
                radeon_bo_list_fence(&parser->validated, parser->ib->fence);
        }
        radeon_bo_list_unreserve(&parser->validated);
-       for (i = 0; i < parser->nrelocs; i++) {
-               if (parser->relocs[i].gobj)
-                       drm_gem_object_unreference_unlocked(parser->relocs[i].gobj);
+       if (parser->relocs != NULL) {
+               for (i = 0; i < parser->nrelocs; i++) {
+                       if (parser->relocs[i].gobj)
+                               drm_gem_object_unreference_unlocked(parser->relocs[i].gobj);
+               }
        }
        kfree(parser->track);
        kfree(parser->relocs);
@@ -243,7 +245,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
        }
        r = radeon_cs_parser_relocs(&parser);
        if (r) {
-               DRM_ERROR("Failed to parse relocation !\n");
+               if (r != -ERESTARTSYS)
+                       DRM_ERROR("Failed to parse relocation %d!\n", r);
                radeon_cs_parser_fini(&parser, r);
                mutex_unlock(&rdev->cs_mutex);
                return r;
index e28e4ed5f720d5340c1e23595ca099d1559273c0..7b629e30556043fb2413976133c1c9c407c097db 100644 (file)
@@ -26,6 +26,7 @@
  *          Jerome Glisse
  */
 #include <linux/console.h>
+#include <linux/slab.h>
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/radeon_drm.h>
 #include <linux/vga_switcheroo.h>
 #include "radeon_reg.h"
 #include "radeon.h"
-#include "radeon_asic.h"
 #include "atom.h"
 
+static const char radeon_family_name[][16] = {
+       "R100",
+       "RV100",
+       "RS100",
+       "RV200",
+       "RS200",
+       "R200",
+       "RV250",
+       "RS300",
+       "RV280",
+       "R300",
+       "R350",
+       "RV350",
+       "RV380",
+       "R420",
+       "R423",
+       "RV410",
+       "RS400",
+       "RS480",
+       "RS600",
+       "RS690",
+       "RS740",
+       "RV515",
+       "R520",
+       "RV530",
+       "RV560",
+       "RV570",
+       "R580",
+       "R600",
+       "RV610",
+       "RV630",
+       "RV670",
+       "RV620",
+       "RV635",
+       "RS780",
+       "RS880",
+       "RV770",
+       "RV730",
+       "RV710",
+       "RV740",
+       "CEDAR",
+       "REDWOOD",
+       "JUNIPER",
+       "CYPRESS",
+       "HEMLOCK",
+       "LAST",
+};
+
 /*
  * Clear GPU surface registers.
  */
@@ -242,6 +290,36 @@ bool radeon_card_posted(struct radeon_device *rdev)
 
 }
 
+void radeon_update_bandwidth_info(struct radeon_device *rdev)
+{
+       fixed20_12 a;
+       u32 sclk, mclk;
+
+       if (rdev->flags & RADEON_IS_IGP) {
+               sclk = radeon_get_engine_clock(rdev);
+               mclk = rdev->clock.default_mclk;
+
+               a.full = rfixed_const(100);
+               rdev->pm.sclk.full = rfixed_const(sclk);
+               rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+               rdev->pm.mclk.full = rfixed_const(mclk);
+               rdev->pm.mclk.full = rfixed_div(rdev->pm.mclk, a);
+
+               a.full = rfixed_const(16);
+               /* core_bandwidth = sclk(Mhz) * 16 */
+               rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a);
+       } else {
+               sclk = radeon_get_engine_clock(rdev);
+               mclk = radeon_get_memory_clock(rdev);
+
+               a.full = rfixed_const(100);
+               rdev->pm.sclk.full = rfixed_const(sclk);
+               rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+               rdev->pm.mclk.full = rfixed_const(mclk);
+               rdev->pm.mclk.full = rfixed_div(rdev->pm.mclk, a);
+       }
+}
+
 bool radeon_boot_test_post_card(struct radeon_device *rdev)
 {
        if (radeon_card_posted(rdev))
@@ -288,181 +366,6 @@ void radeon_dummy_page_fini(struct radeon_device *rdev)
 }
 
 
-/*
- * Registers accessors functions.
- */
-uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg)
-{
-       DRM_ERROR("Invalid callback to read register 0x%04X\n", reg);
-       BUG_ON(1);
-       return 0;
-}
-
-void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
-{
-       DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n",
-                 reg, v);
-       BUG_ON(1);
-}
-
-void radeon_register_accessor_init(struct radeon_device *rdev)
-{
-       rdev->mc_rreg = &radeon_invalid_rreg;
-       rdev->mc_wreg = &radeon_invalid_wreg;
-       rdev->pll_rreg = &radeon_invalid_rreg;
-       rdev->pll_wreg = &radeon_invalid_wreg;
-       rdev->pciep_rreg = &radeon_invalid_rreg;
-       rdev->pciep_wreg = &radeon_invalid_wreg;
-
-       /* Don't change order as we are overridding accessor. */
-       if (rdev->family < CHIP_RV515) {
-               rdev->pcie_reg_mask = 0xff;
-       } else {
-               rdev->pcie_reg_mask = 0x7ff;
-       }
-       /* FIXME: not sure here */
-       if (rdev->family <= CHIP_R580) {
-               rdev->pll_rreg = &r100_pll_rreg;
-               rdev->pll_wreg = &r100_pll_wreg;
-       }
-       if (rdev->family >= CHIP_R420) {
-               rdev->mc_rreg = &r420_mc_rreg;
-               rdev->mc_wreg = &r420_mc_wreg;
-       }
-       if (rdev->family >= CHIP_RV515) {
-               rdev->mc_rreg = &rv515_mc_rreg;
-               rdev->mc_wreg = &rv515_mc_wreg;
-       }
-       if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) {
-               rdev->mc_rreg = &rs400_mc_rreg;
-               rdev->mc_wreg = &rs400_mc_wreg;
-       }
-       if (rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) {
-               rdev->mc_rreg = &rs690_mc_rreg;
-               rdev->mc_wreg = &rs690_mc_wreg;
-       }
-       if (rdev->family == CHIP_RS600) {
-               rdev->mc_rreg = &rs600_mc_rreg;
-               rdev->mc_wreg = &rs600_mc_wreg;
-       }
-       if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_RV740)) {
-               rdev->pciep_rreg = &r600_pciep_rreg;
-               rdev->pciep_wreg = &r600_pciep_wreg;
-       }
-}
-
-
-/*
- * ASIC
- */
-int radeon_asic_init(struct radeon_device *rdev)
-{
-       radeon_register_accessor_init(rdev);
-       switch (rdev->family) {
-       case CHIP_R100:
-       case CHIP_RV100:
-       case CHIP_RS100:
-       case CHIP_RV200:
-       case CHIP_RS200:
-               rdev->asic = &r100_asic;
-               break;
-       case CHIP_R200:
-       case CHIP_RV250:
-       case CHIP_RS300:
-       case CHIP_RV280:
-               rdev->asic = &r200_asic;
-               break;
-       case CHIP_R300:
-       case CHIP_R350:
-       case CHIP_RV350:
-       case CHIP_RV380:
-               if (rdev->flags & RADEON_IS_PCIE)
-                       rdev->asic = &r300_asic_pcie;
-               else
-                       rdev->asic = &r300_asic;
-               break;
-       case CHIP_R420:
-       case CHIP_R423:
-       case CHIP_RV410:
-               rdev->asic = &r420_asic;
-               break;
-       case CHIP_RS400:
-       case CHIP_RS480:
-               rdev->asic = &rs400_asic;
-               break;
-       case CHIP_RS600:
-               rdev->asic = &rs600_asic;
-               break;
-       case CHIP_RS690:
-       case CHIP_RS740:
-               rdev->asic = &rs690_asic;
-               break;
-       case CHIP_RV515:
-               rdev->asic = &rv515_asic;
-               break;
-       case CHIP_R520:
-       case CHIP_RV530:
-       case CHIP_RV560:
-       case CHIP_RV570:
-       case CHIP_R580:
-               rdev->asic = &r520_asic;
-               break;
-       case CHIP_R600:
-       case CHIP_RV610:
-       case CHIP_RV630:
-       case CHIP_RV620:
-       case CHIP_RV635:
-       case CHIP_RV670:
-       case CHIP_RS780:
-       case CHIP_RS880:
-               rdev->asic = &r600_asic;
-               break;
-       case CHIP_RV770:
-       case CHIP_RV730:
-       case CHIP_RV710:
-       case CHIP_RV740:
-               rdev->asic = &rv770_asic;
-               break;
-       case CHIP_CEDAR:
-       case CHIP_REDWOOD:
-       case CHIP_JUNIPER:
-       case CHIP_CYPRESS:
-       case CHIP_HEMLOCK:
-               rdev->asic = &evergreen_asic;
-               break;
-       default:
-               /* FIXME: not supported yet */
-               return -EINVAL;
-       }
-
-       if (rdev->flags & RADEON_IS_IGP) {
-               rdev->asic->get_memory_clock = NULL;
-               rdev->asic->set_memory_clock = NULL;
-       }
-
-       return 0;
-}
-
-
-/*
- * Wrapper around modesetting bits.
- */
-int radeon_clocks_init(struct radeon_device *rdev)
-{
-       int r;
-
-       r = radeon_static_clocks_init(rdev->ddev);
-       if (r) {
-               return r;
-       }
-       DRM_INFO("Clocks initialized !\n");
-       return 0;
-}
-
-void radeon_clocks_fini(struct radeon_device *rdev)
-{
-}
-
 /* ATOM accessor methods */
 static uint32_t cail_pll_read(struct card_info *info, uint32_t reg)
 {
@@ -567,29 +470,6 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state)
                return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
 }
 
-void radeon_agp_disable(struct radeon_device *rdev)
-{
-       rdev->flags &= ~RADEON_IS_AGP;
-       if (rdev->family >= CHIP_R600) {
-               DRM_INFO("Forcing AGP to PCIE mode\n");
-               rdev->flags |= RADEON_IS_PCIE;
-       } else if (rdev->family >= CHIP_RV515 ||
-                       rdev->family == CHIP_RV380 ||
-                       rdev->family == CHIP_RV410 ||
-                       rdev->family == CHIP_R423) {
-               DRM_INFO("Forcing AGP to PCIE mode\n");
-               rdev->flags |= RADEON_IS_PCIE;
-               rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
-               rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
-       } else {
-               DRM_INFO("Forcing AGP to PCI mode\n");
-               rdev->flags |= RADEON_IS_PCI;
-               rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
-               rdev->asic->gart_set_page = &r100_pci_gart_set_page;
-       }
-       rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
-}
-
 void radeon_check_arguments(struct radeon_device *rdev)
 {
        /* vramlimit must be a power of two */
@@ -694,7 +574,6 @@ int radeon_device_init(struct radeon_device *rdev,
        int r;
        int dma_bits;
 
-       DRM_INFO("radeon: Initializing kernel modesetting.\n");
        rdev->shutdown = false;
        rdev->dev = &pdev->dev;
        rdev->ddev = ddev;
@@ -706,6 +585,10 @@ int radeon_device_init(struct radeon_device *rdev,
        rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
        rdev->gpu_lockup = false;
        rdev->accel_working = false;
+
+       DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n",
+               radeon_family_name[rdev->family], pdev->vendor, pdev->device);
+
        /* mutex initialization are all done here so we
         * can recall function without having locking issues */
        mutex_init(&rdev->cs_mutex);
@@ -731,6 +614,14 @@ int radeon_device_init(struct radeon_device *rdev,
                return r;
        radeon_check_arguments(rdev);
 
+       /* all of the newer IGP chips have an internal gart
+        * However some rs4xx report as AGP, so remove that here.
+        */
+       if ((rdev->family >= CHIP_RS400) &&
+           (rdev->flags & RADEON_IS_IGP)) {
+               rdev->flags &= ~RADEON_IS_AGP;
+       }
+
        if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) {
                radeon_agp_disable(rdev);
        }
index ba8d806dcf3939fe91285820793e7b733ffb0541..bb1c122cad21ba6ee4bec4fd23fb11fd828684d6 100644 (file)
@@ -86,12 +86,12 @@ static void evergreen_crtc_load_lut(struct drm_crtc *crtc)
        WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);
        WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff);
 
-       WREG32(EVERGREEN_DC_LUT_RW_MODE, radeon_crtc->crtc_id);
-       WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK, 0x00000007);
+       WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0);
+       WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
 
-       WREG32(EVERGREEN_DC_LUT_RW_INDEX, 0);
+       WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
        for (i = 0; i < 256; i++) {
-               WREG32(EVERGREEN_DC_LUT_30_COLOR,
+               WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
                       (radeon_crtc->lut_r[i] << 20) |
                       (radeon_crtc->lut_g[i] << 10) |
                       (radeon_crtc->lut_b[i] << 0));
@@ -368,10 +368,9 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)
 
        if (rdev->bios) {
                if (rdev->is_atom_bios) {
-                       if (rdev->family >= CHIP_R600)
+                       ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
+                       if (ret == false)
                                ret = radeon_get_atom_connector_info_from_object_table(dev);
-                       else
-                               ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
                } else {
                        ret = radeon_get_legacy_connector_info_from_bios(dev);
                        if (ret == false)
@@ -469,10 +468,19 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll,
        uint32_t best_error = 0xffffffff;
        uint32_t best_vco_diff = 1;
        uint32_t post_div;
+       u32 pll_out_min, pll_out_max;
 
        DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div);
        freq = freq * 1000;
 
+       if (pll->flags & RADEON_PLL_IS_LCD) {
+               pll_out_min = pll->lcd_pll_out_min;
+               pll_out_max = pll->lcd_pll_out_max;
+       } else {
+               pll_out_min = pll->pll_out_min;
+               pll_out_max = pll->pll_out_max;
+       }
+
        if (pll->flags & RADEON_PLL_USE_REF_DIV)
                min_ref_div = max_ref_div = pll->reference_div;
        else {
@@ -536,10 +544,10 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll,
                                tmp = (uint64_t)pll->reference_freq * feedback_div;
                                vco = radeon_div(tmp, ref_div);
 
-                               if (vco < pll->pll_out_min) {
+                               if (vco < pll_out_min) {
                                        min_feed_div = feedback_div + 1;
                                        continue;
-                               } else if (vco > pll->pll_out_max) {
+                               } else if (vco > pll_out_max) {
                                        max_feed_div = feedback_div;
                                        continue;
                                }
@@ -675,6 +683,15 @@ calc_fb_ref_div(struct radeon_pll *pll,
 {
        fixed20_12 ffreq, max_error, error, pll_out, a;
        u32 vco;
+       u32 pll_out_min, pll_out_max;
+
+       if (pll->flags & RADEON_PLL_IS_LCD) {
+               pll_out_min = pll->lcd_pll_out_min;
+               pll_out_max = pll->lcd_pll_out_max;
+       } else {
+               pll_out_min = pll->pll_out_min;
+               pll_out_max = pll->pll_out_max;
+       }
 
        ffreq.full = rfixed_const(freq);
        /* max_error = ffreq * 0.0025; */
@@ -686,7 +703,7 @@ calc_fb_ref_div(struct radeon_pll *pll,
                        vco = pll->reference_freq * (((*fb_div) * 10) + (*fb_div_frac));
                        vco = vco / ((*ref_div) * 10);
 
-                       if ((vco < pll->pll_out_min) || (vco > pll->pll_out_max))
+                       if ((vco < pll_out_min) || (vco > pll_out_max))
                                continue;
 
                        /* pll_out = vco / post_div; */
@@ -714,6 +731,15 @@ static void radeon_compute_pll_new(struct radeon_pll *pll,
 {
        u32 fb_div = 0, fb_div_frac = 0, post_div = 0, ref_div = 0;
        u32 best_freq = 0, vco_frequency;
+       u32 pll_out_min, pll_out_max;
+
+       if (pll->flags & RADEON_PLL_IS_LCD) {
+               pll_out_min = pll->lcd_pll_out_min;
+               pll_out_max = pll->lcd_pll_out_max;
+       } else {
+               pll_out_min = pll->pll_out_min;
+               pll_out_max = pll->pll_out_max;
+       }
 
        /* freq = freq / 10; */
        do_div(freq, 10);
@@ -724,7 +750,7 @@ static void radeon_compute_pll_new(struct radeon_pll *pll,
                        goto done;
 
                vco_frequency = freq * post_div;
-               if ((vco_frequency < pll->pll_out_min) || (vco_frequency > pll->pll_out_max))
+               if ((vco_frequency < pll_out_min) || (vco_frequency > pll_out_max))
                        goto done;
 
                if (pll->flags & RADEON_PLL_USE_REF_DIV) {
@@ -749,7 +775,7 @@ static void radeon_compute_pll_new(struct radeon_pll *pll,
                                continue;
 
                        vco_frequency = freq * post_div;
-                       if ((vco_frequency < pll->pll_out_min) || (vco_frequency > pll->pll_out_max))
+                       if ((vco_frequency < pll_out_min) || (vco_frequency > pll_out_max))
                                continue;
                        if (pll->flags & RADEON_PLL_USE_REF_DIV) {
                                ref_div = pll->reference_div;
@@ -945,6 +971,23 @@ static int radeon_modeset_create_props(struct radeon_device *rdev)
        return 0;
 }
 
+void radeon_update_display_priority(struct radeon_device *rdev)
+{
+       /* adjustment options for the display watermarks */
+       if ((radeon_disp_priority == 0) || (radeon_disp_priority > 2)) {
+               /* set display priority to high for r3xx, rv515 chips
+                * this avoids flickering due to underflow to the
+                * display controllers during heavy acceleration.
+                */
+               if (ASIC_IS_R300(rdev) || (rdev->family == CHIP_RV515))
+                       rdev->disp_priority = 2;
+               else
+                       rdev->disp_priority = 0;
+       } else
+               rdev->disp_priority = radeon_disp_priority;
+
+}
+
 int radeon_modeset_init(struct radeon_device *rdev)
 {
        int i;
@@ -976,15 +1019,6 @@ int radeon_modeset_init(struct radeon_device *rdev)
                radeon_combios_check_hardcoded_edid(rdev);
        }
 
-       if (rdev->flags & RADEON_SINGLE_CRTC)
-               rdev->num_crtc = 1;
-       else {
-               if (ASIC_IS_DCE4(rdev))
-                       rdev->num_crtc = 6;
-               else
-                       rdev->num_crtc = 2;
-       }
-
        /* allocate crtcs */
        for (i = 0; i < rdev->num_crtc; i++) {
                radeon_crtc_init(rdev->ddev, i);
index 6eec0ece6a6ccd6d14e9ae05a2fee63d0879ce41..b3749d47be7bfaa16c4a1bc082d892c2896e2194 100644 (file)
  * KMS wrapper.
  * - 2.0.0 - initial interface
  * - 2.1.0 - add square tiling interface
+ * - 2.2.0 - add r6xx/r7xx const buffer support
+ * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs
  */
 #define KMS_DRIVER_MAJOR       2
-#define KMS_DRIVER_MINOR       1
+#define KMS_DRIVER_MINOR       3
 #define KMS_DRIVER_PATCHLEVEL  0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);
@@ -91,6 +93,8 @@ int radeon_tv = 1;
 int radeon_new_pll = -1;
 int radeon_dynpm = -1;
 int radeon_audio = 1;
+int radeon_disp_priority = 0;
+int radeon_hw_i2c = 0;
 
 MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
 module_param_named(no_wb, radeon_no_wb, int, 0444);
@@ -134,6 +138,12 @@ module_param_named(dynpm, radeon_dynpm, int, 0444);
 MODULE_PARM_DESC(audio, "Audio enable (0 = disable)");
 module_param_named(audio, radeon_audio, int, 0444);
 
+MODULE_PARM_DESC(disp_priority, "Display Priority (0 = auto, 1 = normal, 2 = high)");
+module_param_named(disp_priority, radeon_disp_priority, int, 0444);
+
+MODULE_PARM_DESC(hw_i2c, "hw i2c engine enable (0 = disable)");
+module_param_named(hw_i2c, radeon_hw_i2c, int, 0444);
+
 static int radeon_suspend(struct drm_device *dev, pm_message_t state)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -206,6 +216,7 @@ static struct drm_driver driver_old = {
                 .mmap = drm_mmap,
                 .poll = drm_poll,
                 .fasync = drm_fasync,
+                .read = drm_read,
 #ifdef CONFIG_COMPAT
                 .compat_ioctl = radeon_compat_ioctl,
 #endif
@@ -294,6 +305,7 @@ static struct drm_driver kms_driver = {
                 .mmap = radeon_mmap,
                 .poll = drm_poll,
                 .fasync = drm_fasync,
+                .read = drm_read,
 #ifdef CONFIG_COMPAT
                 .compat_ioctl = radeon_kms_compat_ioctl,
 #endif
index ec55f2b23c2298f39d7b108d183bf52a59ddad34..448eba89d1e62e2dec8089480e951086c7caa2f6 100644 (file)
  * 1.30- Add support for occlusion queries
  * 1.31- Add support for num Z pipes from GET_PARAM
  * 1.32- fixes for rv740 setup
+ * 1.33- Add r6xx/r7xx const buffer support
  */
 #define DRIVER_MAJOR           1
-#define DRIVER_MINOR           32
+#define DRIVER_MINOR           33
 #define DRIVER_PATCHLEVEL      0
 
 enum radeon_cp_microcode_version {
index bc926ea0a530e014c2b075fed8ac35e0a94d04ae..c5ddaf58563a22505a283c528faf06c1587d6bb8 100644 (file)
@@ -254,6 +254,53 @@ radeon_get_atom_connector_priv_from_encoder(struct drm_encoder *encoder)
        return dig_connector;
 }
 
+void radeon_panel_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;
+       struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
+       unsigned hblank = native_mode->htotal - native_mode->hdisplay;
+       unsigned vblank = native_mode->vtotal - native_mode->vdisplay;
+       unsigned hover = native_mode->hsync_start - native_mode->hdisplay;
+       unsigned vover = native_mode->vsync_start - native_mode->vdisplay;
+       unsigned hsync_width = native_mode->hsync_end - native_mode->hsync_start;
+       unsigned vsync_width = native_mode->vsync_end - native_mode->vsync_start;
+
+       adjusted_mode->clock = native_mode->clock;
+       adjusted_mode->flags = native_mode->flags;
+
+       if (ASIC_IS_AVIVO(rdev)) {
+               adjusted_mode->hdisplay = native_mode->hdisplay;
+               adjusted_mode->vdisplay = native_mode->vdisplay;
+       }
+
+       adjusted_mode->htotal = native_mode->hdisplay + hblank;
+       adjusted_mode->hsync_start = native_mode->hdisplay + hover;
+       adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width;
+
+       adjusted_mode->vtotal = native_mode->vdisplay + vblank;
+       adjusted_mode->vsync_start = native_mode->vdisplay + vover;
+       adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width;
+
+       drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
+
+       if (ASIC_IS_AVIVO(rdev)) {
+               adjusted_mode->crtc_hdisplay = native_mode->hdisplay;
+               adjusted_mode->crtc_vdisplay = native_mode->vdisplay;
+       }
+
+       adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank;
+       adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover;
+       adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width;
+
+       adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank;
+       adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover;
+       adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width;
+
+}
+
 static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
                                   struct drm_display_mode *mode,
                                   struct drm_display_mode *adjusted_mode)
@@ -275,18 +322,8 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
                adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
 
        /* get the native mode for LVDS */
-       if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
-               struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
-               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->crtc_hdisplay = mode->hdisplay;
-                       adjusted_mode->crtc_vdisplay = mode->vdisplay;
-               }
-               adjusted_mode->base.id = mode_id;
-       }
+       if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT))
+               radeon_panel_mode_fixup(encoder, adjusted_mode);
 
        /* get the native mode for TV */
        if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
@@ -302,7 +339,7 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
        }
 
        if (ASIC_IS_DCE3(rdev) &&
-           (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT))) {
+           (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT))) {
                struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
                radeon_dp_set_link_config(connector, mode);
        }
@@ -317,12 +354,8 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        DAC_ENCODER_CONTROL_PS_ALLOCATION args;
-       int index = 0, num = 0;
+       int index = 0;
        struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
-       enum radeon_tv_std tv_std = TV_STD_NTSC;
-
-       if (dac_info->tv_std)
-               tv_std = dac_info->tv_std;
 
        memset(&args, 0, sizeof(args));
 
@@ -330,12 +363,10 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)
        case ENCODER_OBJECT_ID_INTERNAL_DAC1:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
                index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
-               num = 1;
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DAC2:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
                index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
-               num = 2;
                break;
        }
 
@@ -346,7 +377,7 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)
        else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
                args.ucDacStandard = ATOM_DAC1_CV;
        else {
-               switch (tv_std) {
+               switch (dac_info->tv_std) {
                case TV_STD_PAL:
                case TV_STD_PAL_M:
                case TV_STD_SCART_PAL:
@@ -377,10 +408,6 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)
        TV_ENCODER_CONTROL_PS_ALLOCATION args;
        int index = 0;
        struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
-       enum radeon_tv_std tv_std = TV_STD_NTSC;
-
-       if (dac_info->tv_std)
-               tv_std = dac_info->tv_std;
 
        memset(&args, 0, sizeof(args));
 
@@ -391,7 +418,7 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)
        if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
                args.sTVEncoder.ucTvStandard = ATOM_TV_CV;
        else {
-               switch (tv_std) {
+               switch (dac_info->tv_std) {
                case TV_STD_NTSC:
                        args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
                        break;
@@ -519,7 +546,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
                break;
        }
 
-       atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               return;
 
        switch (frev) {
        case 1:
@@ -593,7 +621,6 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
        }
 
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-       r600_hdmi_enable(encoder, hdmi_detected);
 }
 
 int
@@ -708,7 +735,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
        struct radeon_connector_atom_dig *dig_connector =
                radeon_get_atom_connector_priv_from_encoder(encoder);
        union dig_encoder_control args;
-       int index = 0, num = 0;
+       int index = 0;
        uint8_t frev, crev;
 
        if (!dig || !dig_connector)
@@ -724,9 +751,9 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
                else
                        index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
        }
-       num = dig->dig_encoder + 1;
 
-       atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               return;
 
        args.v1.ucAction = action;
        args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
@@ -785,7 +812,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
        struct drm_connector *connector;
        struct radeon_connector *radeon_connector;
        union dig_transmitter_control args;
-       int index = 0, num = 0;
+       int index = 0;
        uint8_t frev, crev;
        bool is_dp = false;
        int pll_id = 0;
@@ -814,7 +841,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
                }
        }
 
-       atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               return;
 
        args.v1.ucAction = action;
        if (action == ATOM_TRANSMITTER_ACTION_INIT) {
@@ -860,15 +888,12 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
                switch (radeon_encoder->encoder_id) {
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
                        args.v3.acConfig.ucTransmitterSel = 0;
-                       num = 0;
                        break;
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
                        args.v3.acConfig.ucTransmitterSel = 1;
-                       num = 1;
                        break;
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
                        args.v3.acConfig.ucTransmitterSel = 2;
-                       num = 2;
                        break;
                }
 
@@ -877,25 +902,23 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
                else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
                        if (dig->coherent_mode)
                                args.v3.acConfig.fCoherentMode = 1;
+                       if (radeon_encoder->pixel_clock > 165000)
+                               args.v3.acConfig.fDualLinkConnector = 1;
                }
        } else if (ASIC_IS_DCE32(rdev)) {
-               if (dig->dig_encoder == 1)
-                       args.v2.acConfig.ucEncoderSel = 1;
+               args.v2.acConfig.ucEncoderSel = dig->dig_encoder;
                if (dig_connector->linkb)
                        args.v2.acConfig.ucLinkSel = 1;
 
                switch (radeon_encoder->encoder_id) {
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
                        args.v2.acConfig.ucTransmitterSel = 0;
-                       num = 0;
                        break;
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
                        args.v2.acConfig.ucTransmitterSel = 1;
-                       num = 1;
                        break;
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
                        args.v2.acConfig.ucTransmitterSel = 2;
-                       num = 2;
                        break;
                }
 
@@ -904,6 +927,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
                else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
                        if (dig->coherent_mode)
                                args.v2.acConfig.fCoherentMode = 1;
+                       if (radeon_encoder->pixel_clock > 165000)
+                               args.v2.acConfig.fDualLinkConnector = 1;
                }
        } else {
                args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
@@ -913,31 +938,25 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
                else
                        args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
 
-               switch (radeon_encoder->encoder_id) {
-               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-                       if (rdev->flags & RADEON_IS_IGP) {
-                               if (radeon_encoder->pixel_clock > 165000) {
-                                       if (dig_connector->igp_lane_info & 0x3)
-                                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
-                                       else if (dig_connector->igp_lane_info & 0xc)
-                                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
-                               } else {
-                                       if (dig_connector->igp_lane_info & 0x1)
-                                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-                                       else if (dig_connector->igp_lane_info & 0x2)
-                                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
-                                       else if (dig_connector->igp_lane_info & 0x4)
-                                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
-                                       else if (dig_connector->igp_lane_info & 0x8)
-                                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
-                               }
+               if ((rdev->flags & RADEON_IS_IGP) &&
+                   (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) {
+                       if (is_dp || (radeon_encoder->pixel_clock <= 165000)) {
+                               if (dig_connector->igp_lane_info & 0x1)
+                                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+                               else if (dig_connector->igp_lane_info & 0x2)
+                                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
+                               else if (dig_connector->igp_lane_info & 0x4)
+                                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
+                               else if (dig_connector->igp_lane_info & 0x8)
+                                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
+                       } else {
+                               if (dig_connector->igp_lane_info & 0x3)
+                                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
+                               else if (dig_connector->igp_lane_info & 0xc)
+                                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
                        }
-                       break;
                }
 
-               if (radeon_encoder->pixel_clock > 165000)
-                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
-
                if (dig_connector->linkb)
                        args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;
                else
@@ -948,6 +967,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
                else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
                        if (dig->coherent_mode)
                                args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
+                       if (radeon_encoder->pixel_clock > 165000)
+                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
                }
        }
 
@@ -1054,16 +1075,25 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
        if (is_dig) {
                switch (mode) {
                case DRM_MODE_DPMS_ON:
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
-                       {
+                       if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
                                struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+
                                dp_link_train(encoder, connector);
+                               if (ASIC_IS_DCE4(rdev))
+                                       atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON);
                        }
+                       if (!ASIC_IS_DCE4(rdev))
+                               atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
                        break;
                case DRM_MODE_DPMS_STANDBY:
                case DRM_MODE_DPMS_SUSPEND:
                case DRM_MODE_DPMS_OFF:
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
+                       if (!ASIC_IS_DCE4(rdev))
+                               atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
+                       if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
+                               if (ASIC_IS_DCE4(rdev))
+                                       atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF);
+                       }
                        break;
                }
        } else {
@@ -1104,7 +1134,8 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
 
        memset(&args, 0, sizeof(args));
 
-       atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               return;
 
        switch (frev) {
        case 1:
@@ -1216,6 +1247,9 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
        }
 
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+       /* update scratch regs with new routing */
+       radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
 }
 
 static void
@@ -1326,20 +1360,10 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
 
-       if (radeon_encoder->active_device &
-           (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
-               struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
-               if (dig)
-                       dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder);
-       }
        radeon_encoder->pixel_clock = adjusted_mode->clock;
 
-       radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
-       atombios_set_encoder_crtc_source(encoder);
-
-       if (ASIC_IS_AVIVO(rdev)) {
+       if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) {
                if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
                        atombios_yuv_setup(encoder, true);
                else
@@ -1390,15 +1414,20 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
        case ENCODER_OBJECT_ID_INTERNAL_DAC2:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
                atombios_dac_setup(encoder, ATOM_ENABLE);
-               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
-                       atombios_tv_setup(encoder, ATOM_ENABLE);
+               if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) {
+                       if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
+                               atombios_tv_setup(encoder, ATOM_ENABLE);
+                       else
+                               atombios_tv_setup(encoder, ATOM_DISABLE);
+               }
                break;
        }
        atombios_apply_encoder_quirks(encoder, adjusted_mode);
 
-       /* XXX */
-       if (!ASIC_IS_DCE4(rdev))
+       if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
+               r600_hdmi_enable(encoder);
                r600_hdmi_setmode(encoder, adjusted_mode);
+       }
 }
 
 static bool
@@ -1418,7 +1447,8 @@ atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *conn
 
                memset(&args, 0, sizeof(args));
 
-               atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
+               if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+                       return false;
 
                args.sDacload.ucMisc = 0;
 
@@ -1492,8 +1522,20 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec
 
 static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
 {
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+
+       if (radeon_encoder->active_device &
+           (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
+               struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+               if (dig)
+                       dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder);
+       }
+
        radeon_atom_output_lock(encoder, true);
        radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+
+       /* this is needed for the pll/ss setup to work correctly in some cases */
+       atombios_set_encoder_crtc_source(encoder);
 }
 
 static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
@@ -1509,6 +1551,8 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
        radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
 
        if (radeon_encoder_is_digital(encoder)) {
+               if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI)
+                       r600_hdmi_disable(encoder);
                dig = radeon_encoder->enc_priv;
                dig->dig_encoder = -1;
        }
@@ -1549,12 +1593,14 @@ static const struct drm_encoder_funcs radeon_atom_enc_funcs = {
 struct radeon_encoder_atom_dac *
 radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder)
 {
+       struct drm_device *dev = radeon_encoder->base.dev;
+       struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL);
 
        if (!dac)
                return NULL;
 
-       dac->tv_std = TV_STD_NTSC;
+       dac->tv_std = radeon_atombios_get_tv_info(rdev);
        return dac;
 }
 
@@ -1632,6 +1678,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DAC1:
                drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
+               radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder);
                drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DAC2:
@@ -1659,6 +1706,4 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
                drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
                break;
        }
-
-       r600_hdmi_init(encoder);
 }
index 93c7d5d419141456cdbe8b0c455b78709b993439..e329066dcabd4d8cbe1ba44e839bc31cfbf5a905 100644 (file)
@@ -36,7 +36,7 @@
  * Radeon chip families
  */
 enum radeon_family {
-       CHIP_R100,
+       CHIP_R100 = 0,
        CHIP_RV100,
        CHIP_RS100,
        CHIP_RV200,
@@ -99,4 +99,5 @@ enum radeon_chip_flags {
        RADEON_IS_PCI = 0x00800000UL,
        RADEON_IS_IGPGART = 0x01000000UL,
 };
+
 #endif
index 8fccbf29235e76efe2e7aecf12d53253e3f896c7..9ac57a09784b08d72eb5278880f7cb98cfd560f2 100644 (file)
@@ -28,6 +28,7 @@
      */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/fb.h>
 
 #include "drmP.h"
index 8495d4e32e1890daf1626c1c963c978b969d3e61..d90f95b405c5e9942af5400719978465b03c11e9 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/wait.h>
 #include <linux/list.h>
 #include <linux/kref.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_reg.h"
index 4ae50c19589fe8b4e4f89304862515416cbe72c5..5def6f5dff38c1f7dfb0357aa5f9f8cc2583576a 100644 (file)
@@ -59,6 +59,7 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector)
        return false;
 }
 
+/* bit banging i2c */
 
 static void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state)
 {
@@ -181,13 +182,30 @@ static void set_data(void *i2c_priv, int data)
        WREG32(rec->en_data_reg, val);
 }
 
+static int pre_xfer(struct i2c_adapter *i2c_adap)
+{
+       struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
+
+       radeon_i2c_do_lock(i2c, 1);
+
+       return 0;
+}
+
+static void post_xfer(struct i2c_adapter *i2c_adap)
+{
+       struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
+
+       radeon_i2c_do_lock(i2c, 0);
+}
+
+/* hw i2c */
+
 static u32 radeon_get_i2c_prescale(struct radeon_device *rdev)
 {
-       struct radeon_pll *spll = &rdev->clock.spll;
        u32 sclk = radeon_get_engine_clock(rdev);
        u32 prescale = 0;
-       u32 nm;
-       u8 loop;
+       u32 nm;
+       u8 n, m, loop;
        int i2c_clock;
 
        switch (rdev->family) {
@@ -203,13 +221,15 @@ static u32 radeon_get_i2c_prescale(struct radeon_device *rdev)
        case CHIP_R300:
        case CHIP_R350:
        case CHIP_RV350:
-               n = (spll->reference_freq) / (4 * 6);
+               i2c_clock = 60;
+               nm = (sclk * 10) / (i2c_clock * 4);
                for (loop = 1; loop < 255; loop++) {
-                       if ((loop * (loop - 1)) > n)
+                       if ((nm / loop) < loop)
                                break;
                }
-               m = loop - 1;
-               prescale = m | (loop << 8);
+               n = loop - 1;
+               m = loop - 2;
+               prescale = m | (n << 8);
                break;
        case CHIP_RV380:
        case CHIP_RS400:
@@ -217,7 +237,6 @@ static u32 radeon_get_i2c_prescale(struct radeon_device *rdev)
        case CHIP_R420:
        case CHIP_R423:
        case CHIP_RV410:
-               sclk = radeon_get_engine_clock(rdev);
                prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128;
                break;
        case CHIP_RS600:
@@ -232,7 +251,6 @@ static u32 radeon_get_i2c_prescale(struct radeon_device *rdev)
        case CHIP_RV570:
        case CHIP_R580:
                i2c_clock = 50;
-               sclk = radeon_get_engine_clock(rdev);
                if (rdev->family == CHIP_R520)
                        prescale = (127 << 8) + ((sclk * 10) / (4 * 127 * i2c_clock));
                else
@@ -291,6 +309,7 @@ static int r100_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
        prescale = radeon_get_i2c_prescale(rdev);
 
        reg = ((prescale << RADEON_I2C_PRESCALE_SHIFT) |
+              RADEON_I2C_DRIVE_EN |
               RADEON_I2C_START |
               RADEON_I2C_STOP |
               RADEON_I2C_GO);
@@ -757,26 +776,13 @@ done:
        return ret;
 }
 
-static int radeon_sw_i2c_xfer(struct i2c_adapter *i2c_adap,
+static int radeon_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
                              struct i2c_msg *msgs, int num)
-{
-       struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
-       int ret;
-
-       radeon_i2c_do_lock(i2c, 1);
-       ret = i2c_transfer(&i2c->algo.radeon.bit_adapter, msgs, num);
-       radeon_i2c_do_lock(i2c, 0);
-
-       return ret;
-}
-
-static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,
-                          struct i2c_msg *msgs, int num)
 {
        struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
        struct radeon_device *rdev = i2c->dev->dev_private;
        struct radeon_i2c_bus_rec *rec = &i2c->rec;
-       int ret;
+       int ret = 0;
 
        switch (rdev->family) {
        case CHIP_R100:
@@ -797,16 +803,12 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,
        case CHIP_RV410:
        case CHIP_RS400:
        case CHIP_RS480:
-               if (rec->hw_capable)
-                       ret = r100_hw_i2c_xfer(i2c_adap, msgs, num);
-               else
-                       ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
+               ret = r100_hw_i2c_xfer(i2c_adap, msgs, num);
                break;
        case CHIP_RS600:
        case CHIP_RS690:
        case CHIP_RS740:
                /* XXX fill in hw i2c implementation */
-               ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
                break;
        case CHIP_RV515:
        case CHIP_R520:
@@ -814,20 +816,16 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,
        case CHIP_RV560:
        case CHIP_RV570:
        case CHIP_R580:
-               if (rec->hw_capable) {
-                       if (rec->mm_i2c)
-                               ret = r100_hw_i2c_xfer(i2c_adap, msgs, num);
-                       else
-                               ret = r500_hw_i2c_xfer(i2c_adap, msgs, num);
-               } else
-                       ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
+               if (rec->mm_i2c)
+                       ret = r100_hw_i2c_xfer(i2c_adap, msgs, num);
+               else
+                       ret = r500_hw_i2c_xfer(i2c_adap, msgs, num);
                break;
        case CHIP_R600:
        case CHIP_RV610:
        case CHIP_RV630:
        case CHIP_RV670:
                /* XXX fill in hw i2c implementation */
-               ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
                break;
        case CHIP_RV620:
        case CHIP_RV635:
@@ -838,7 +836,6 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,
        case CHIP_RV710:
        case CHIP_RV740:
                /* XXX fill in hw i2c implementation */
-               ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
                break;
        case CHIP_CEDAR:
        case CHIP_REDWOOD:
@@ -846,7 +843,6 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,
        case CHIP_CYPRESS:
        case CHIP_HEMLOCK:
                /* XXX fill in hw i2c implementation */
-               ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);
                break;
        default:
                DRM_ERROR("i2c: unhandled radeon chip\n");
@@ -857,20 +853,21 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,
        return ret;
 }
 
-static u32 radeon_i2c_func(struct i2c_adapter *adap)
+static u32 radeon_hw_i2c_func(struct i2c_adapter *adap)
 {
        return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 }
 
 static const struct i2c_algorithm radeon_i2c_algo = {
-       .master_xfer = radeon_i2c_xfer,
-       .functionality = radeon_i2c_func,
+       .master_xfer = radeon_hw_i2c_xfer,
+       .functionality = radeon_hw_i2c_func,
 };
 
 struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
                                          struct radeon_i2c_bus_rec *rec,
                                          const char *name)
 {
+       struct radeon_device *rdev = dev->dev_private;
        struct radeon_i2c_chan *i2c;
        int ret;
 
@@ -878,37 +875,43 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
        if (i2c == NULL)
                return NULL;
 
-       /* set the internal bit adapter */
-       i2c->algo.radeon.bit_adapter.owner = THIS_MODULE;
-       i2c_set_adapdata(&i2c->algo.radeon.bit_adapter, i2c);
-       sprintf(i2c->algo.radeon.bit_adapter.name, "Radeon internal i2c bit bus %s", name);
-       i2c->algo.radeon.bit_adapter.algo_data = &i2c->algo.radeon.bit_data;
-       i2c->algo.radeon.bit_data.setsda = set_data;
-       i2c->algo.radeon.bit_data.setscl = set_clock;
-       i2c->algo.radeon.bit_data.getsda = get_data;
-       i2c->algo.radeon.bit_data.getscl = get_clock;
-       i2c->algo.radeon.bit_data.udelay = 20;
-       /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always
-        * make this, 2 jiffies is a lot more reliable */
-       i2c->algo.radeon.bit_data.timeout = 2;
-       i2c->algo.radeon.bit_data.data = i2c;
-       ret = i2c_bit_add_bus(&i2c->algo.radeon.bit_adapter);
-       if (ret) {
-               DRM_ERROR("Failed to register internal bit i2c %s\n", name);
-               goto out_free;
-       }
-       /* set the radeon i2c adapter */
-       i2c->dev = dev;
        i2c->rec = *rec;
        i2c->adapter.owner = THIS_MODULE;
+       i2c->dev = dev;
        i2c_set_adapdata(&i2c->adapter, i2c);
-       sprintf(i2c->adapter.name, "Radeon i2c %s", name);
-       i2c->adapter.algo_data = &i2c->algo.radeon;
-       i2c->adapter.algo = &radeon_i2c_algo;
-       ret = i2c_add_adapter(&i2c->adapter);
-       if (ret) {
-               DRM_ERROR("Failed to register i2c %s\n", name);
-               goto out_free;
+       if (rec->mm_i2c ||
+           (rec->hw_capable &&
+            radeon_hw_i2c &&
+            ((rdev->family <= CHIP_RS480) ||
+             ((rdev->family >= CHIP_RV515) && (rdev->family <= CHIP_R580))))) {
+               /* set the radeon hw i2c adapter */
+               sprintf(i2c->adapter.name, "Radeon i2c hw bus %s", name);
+               i2c->adapter.algo = &radeon_i2c_algo;
+               ret = i2c_add_adapter(&i2c->adapter);
+               if (ret) {
+                       DRM_ERROR("Failed to register hw i2c %s\n", name);
+                       goto out_free;
+               }
+       } else {
+               /* set the radeon bit adapter */
+               sprintf(i2c->adapter.name, "Radeon i2c bit bus %s", name);
+               i2c->adapter.algo_data = &i2c->algo.bit;
+               i2c->algo.bit.pre_xfer = pre_xfer;
+               i2c->algo.bit.post_xfer = post_xfer;
+               i2c->algo.bit.setsda = set_data;
+               i2c->algo.bit.setscl = set_clock;
+               i2c->algo.bit.getsda = get_data;
+               i2c->algo.bit.getscl = get_clock;
+               i2c->algo.bit.udelay = 20;
+               /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always
+                * make this, 2 jiffies is a lot more reliable */
+               i2c->algo.bit.timeout = 2;
+               i2c->algo.bit.data = i2c;
+               ret = i2c_bit_add_bus(&i2c->adapter);
+               if (ret) {
+                       DRM_ERROR("Failed to register bit i2c %s\n", name);
+                       goto out_free;
+               }
        }
 
        return i2c;
@@ -953,16 +956,6 @@ void radeon_i2c_destroy(struct radeon_i2c_chan *i2c)
 {
        if (!i2c)
                return;
-       i2c_del_adapter(&i2c->algo.radeon.bit_adapter);
-       i2c_del_adapter(&i2c->adapter);
-       kfree(i2c);
-}
-
-void radeon_i2c_destroy_dp(struct radeon_i2c_chan *i2c)
-{
-       if (!i2c)
-               return;
-
        i2c_del_adapter(&i2c->adapter);
        kfree(i2c);
 }
index 3cfd60fd00835343f8cacececcb01ba600521133..a212041e8b0b0a5ef0d47d7949f057d38be480ed 100644 (file)
@@ -67,9 +67,10 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
 
        /* Disable *all* interrupts */
        rdev->irq.sw_int = false;
-       for (i = 0; i < 2; i++) {
+       for (i = 0; i < rdev->num_crtc; i++)
                rdev->irq.crtc_vblank_int[i] = false;
-       }
+       for (i = 0; i < 6; i++)
+               rdev->irq.hpd[i] = false;
        radeon_irq_set(rdev);
        /* Clear bits */
        radeon_irq_process(rdev);
@@ -95,34 +96,29 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
        }
        /* Disable *all* interrupts */
        rdev->irq.sw_int = false;
-       for (i = 0; i < 2; i++) {
+       for (i = 0; i < rdev->num_crtc; i++)
                rdev->irq.crtc_vblank_int[i] = false;
+       for (i = 0; i < 6; i++)
                rdev->irq.hpd[i] = false;
-       }
        radeon_irq_set(rdev);
 }
 
 int radeon_irq_kms_init(struct radeon_device *rdev)
 {
        int r = 0;
-       int num_crtc = 2;
 
-       if (rdev->flags & RADEON_SINGLE_CRTC)
-               num_crtc = 1;
        spin_lock_init(&rdev->irq.sw_lock);
-       r = drm_vblank_init(rdev->ddev, num_crtc);
+       r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
        if (r) {
                return r;
        }
        /* enable msi */
        rdev->msi_enabled = 0;
-       /* MSIs don't seem to work on my rs780;
-        * not sure about rs880 or other rs780s.
-        * Needs more investigation.
+       /* MSIs don't seem to work reliably on all IGP
+        * chips.  Disable MSI on them for now.
         */
        if ((rdev->family >= CHIP_RV380) &&
-           (rdev->family != CHIP_RS780) &&
-           (rdev->family != CHIP_RS880)) {
+           (!(rdev->flags & RADEON_IS_IGP))) {
                int ret = pci_enable_msi(rdev->pdev);
                if (!ret) {
                        rdev->msi_enabled = 1;
index 20ec276e7596c1937a2a6a4beaceb1247bdfb085..c633319f98edb47bd3f9b8ae8cabe847c909cb20 100644 (file)
@@ -31,6 +31,7 @@
 #include "radeon_drm.h"
 
 #include <linux/vga_switcheroo.h>
+#include <linux/slab.h>
 
 int radeon_driver_unload_kms(struct drm_device *dev)
 {
@@ -164,7 +165,7 @@ u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc)
 {
        struct radeon_device *rdev = dev->dev_private;
 
-       if (crtc < 0 || crtc > 1) {
+       if (crtc < 0 || crtc >= rdev->num_crtc) {
                DRM_ERROR("Invalid crtc %d\n", crtc);
                return -EINVAL;
        }
@@ -176,7 +177,7 @@ int radeon_enable_vblank_kms(struct drm_device *dev, int crtc)
 {
        struct radeon_device *rdev = dev->dev_private;
 
-       if (crtc < 0 || crtc > 1) {
+       if (crtc < 0 || crtc >= rdev->num_crtc) {
                DRM_ERROR("Invalid crtc %d\n", crtc);
                return -EINVAL;
        }
@@ -190,7 +191,7 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc)
 {
        struct radeon_device *rdev = dev->dev_private;
 
-       if (crtc < 0 || crtc > 1) {
+       if (crtc < 0 || crtc >= rdev->num_crtc) {
                DRM_ERROR("Invalid crtc %d\n", crtc);
                return;
        }
index df23d6a01d02297a8ee0832a9f800f48b4ea957c..88865e38fe30a100d2263f5a8db3c51b21a9445c 100644 (file)
@@ -603,6 +603,10 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod
                                      ? RADEON_CRTC2_INTERLACE_EN
                                      : 0));
 
+               /* rs4xx chips seem to like to have the crtc enabled when the timing is set */
+               if ((rdev->family == CHIP_RS400) || (rdev->family == CHIP_RS480))
+                       crtc2_gen_cntl |= RADEON_CRTC2_EN;
+
                disp2_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL);
                disp2_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN;
 
@@ -630,6 +634,10 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod
                                    ? RADEON_CRTC_INTERLACE_EN
                                    : 0));
 
+               /* rs4xx chips seem to like to have the crtc enabled when the timing is set */
+               if ((rdev->family == CHIP_RS400) || (rdev->family == CHIP_RS480))
+                       crtc_gen_cntl |= RADEON_CRTC_EN;
+
                crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
                crtc_ext_cntl |= (RADEON_XCRT_CNT_EN |
                                  RADEON_CRTC_VSYNC_DIS |
index cf389ce50a8a7ecb3db5a31a4829c45e690bbc20..0274abe17ad982ca8e2004e70c548fd7d55126af 100644 (file)
@@ -228,16 +228,8 @@ static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder,
        drm_mode_set_crtcinfo(adjusted_mode, 0);
 
        /* get the native mode for LVDS */
-       if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
-               struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
-               int mode_id = adjusted_mode->base.id;
-               *adjusted_mode = *native_mode;
-               adjusted_mode->hdisplay = mode->hdisplay;
-               adjusted_mode->vdisplay = mode->vdisplay;
-               adjusted_mode->crtc_hdisplay = mode->hdisplay;
-               adjusted_mode->crtc_vdisplay = mode->vdisplay;
-               adjusted_mode->base.id = mode_id;
-       }
+       if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT))
+               radeon_panel_mode_fixup(encoder, adjusted_mode);
 
        return true;
 }
@@ -830,8 +822,8 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
                                crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
 
                        if (rdev->family == CHIP_R420 ||
-                                       rdev->family == CHIP_R423 ||
-                                       rdev->family == CHIP_RV410)
+                           rdev->family == CHIP_R423 ||
+                           rdev->family == CHIP_RV410)
                                tv_dac_cntl |= (R420_TV_DAC_RDACPD |
                                                R420_TV_DAC_GDACPD |
                                                R420_TV_DAC_BDACPD |
@@ -907,35 +899,43 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
        if (rdev->family != CHIP_R200) {
                tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
                if (rdev->family == CHIP_R420 ||
-                               rdev->family == CHIP_R423 ||
-                               rdev->family == CHIP_RV410) {
+                   rdev->family == CHIP_R423 ||
+                   rdev->family == CHIP_RV410) {
                        tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
-                                       RADEON_TV_DAC_BGADJ_MASK |
-                                       R420_TV_DAC_DACADJ_MASK |
-                                       R420_TV_DAC_RDACPD |
-                                       R420_TV_DAC_GDACPD |
-                                       R420_TV_DAC_BDACPD |
-                                       R420_TV_DAC_TVENABLE);
+                                        RADEON_TV_DAC_BGADJ_MASK |
+                                        R420_TV_DAC_DACADJ_MASK |
+                                        R420_TV_DAC_RDACPD |
+                                        R420_TV_DAC_GDACPD |
+                                        R420_TV_DAC_BDACPD |
+                                        R420_TV_DAC_TVENABLE);
                } else {
                        tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
-                                       RADEON_TV_DAC_BGADJ_MASK |
-                                       RADEON_TV_DAC_DACADJ_MASK |
-                                       RADEON_TV_DAC_RDACPD |
-                                       RADEON_TV_DAC_GDACPD |
-                                       RADEON_TV_DAC_BDACPD);
+                                        RADEON_TV_DAC_BGADJ_MASK |
+                                        RADEON_TV_DAC_DACADJ_MASK |
+                                        RADEON_TV_DAC_RDACPD |
+                                        RADEON_TV_DAC_GDACPD |
+                                        RADEON_TV_DAC_BDACPD);
                }
 
-               /*  FIXME TV */
-               if (tv_dac) {
-                       struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
-                       tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
-                                       RADEON_TV_DAC_NHOLD |
-                                       RADEON_TV_DAC_STD_PS2 |
-                                       tv_dac->ps2_tvdac_adj);
+               tv_dac_cntl |= RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD;
+
+               if (is_tv) {
+                       if (tv_dac->tv_std == TV_STD_NTSC ||
+                           tv_dac->tv_std == TV_STD_NTSC_J ||
+                           tv_dac->tv_std == TV_STD_PAL_M ||
+                           tv_dac->tv_std == TV_STD_PAL_60)
+                               tv_dac_cntl |= tv_dac->ntsc_tvdac_adj;
+                       else
+                               tv_dac_cntl |= tv_dac->pal_tvdac_adj;
+
+                       if (tv_dac->tv_std == TV_STD_NTSC ||
+                           tv_dac->tv_std == TV_STD_NTSC_J)
+                               tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
+                       else
+                               tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
                } else
-                       tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
-                                       RADEON_TV_DAC_NHOLD |
-                                       RADEON_TV_DAC_STD_PS2);
+                       tv_dac_cntl |= (RADEON_TV_DAC_STD_PS2 |
+                                       tv_dac->ps2_tvdac_adj);
 
                WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
        }
index 417684daef4cb4009057caffb128b6c7533e85c6..f2ed27c8055bc90c0f9004471e063d0e89471801 100644 (file)
 #define NTSC_TV_PLL_N_14 693
 #define NTSC_TV_PLL_P_14 7
 
+#define PAL_TV_PLL_M_14 19
+#define PAL_TV_PLL_N_14 353
+#define PAL_TV_PLL_P_14 5
+
 #define VERT_LEAD_IN_LINES 2
 #define FRAC_BITS 0xe
 #define FRAC_MASK 0x3fff
@@ -205,9 +209,24 @@ static const struct radeon_tv_mode_constants available_tv_modes[] = {
                630627,             /* defRestart */
                347,                /* crtcPLL_N */
                14,                 /* crtcPLL_M */
-                       8,                  /* crtcPLL_postDiv */
+               8,                  /* crtcPLL_postDiv */
                1022,               /* pixToTV */
        },
+       { /* PAL timing for 14 Mhz ref clk */
+               800,                /* horResolution */
+               600,                /* verResolution */
+               TV_STD_PAL,         /* standard */
+               1131,               /* horTotal */
+               742,                /* verTotal */
+               813,                /* horStart */
+               840,                /* horSyncStart */
+               633,                /* verSyncStart */
+               708369,             /* defRestart */
+               211,                /* crtcPLL_N */
+               9,                  /* crtcPLL_M */
+               8,                  /* crtcPLL_postDiv */
+               759,                /* pixToTV */
+       },
 };
 
 #define N_AVAILABLE_MODES ARRAY_SIZE(available_tv_modes)
@@ -242,7 +261,7 @@ static const struct radeon_tv_mode_constants *radeon_legacy_tv_get_std_mode(stru
                if (pll->reference_freq == 2700)
                        const_ptr = &available_tv_modes[1];
                else
-                       const_ptr = &available_tv_modes[1]; /* FIX ME */
+                       const_ptr = &available_tv_modes[3];
        }
        return const_ptr;
 }
@@ -685,9 +704,9 @@ void radeon_legacy_tv_mode_set(struct drm_encoder *encoder,
                        n = PAL_TV_PLL_N_27;
                        p = PAL_TV_PLL_P_27;
                } else {
-                       m = PAL_TV_PLL_M_27;
-                       n = PAL_TV_PLL_N_27;
-                       p = PAL_TV_PLL_P_27;
+                       m = PAL_TV_PLL_M_14;
+                       n = PAL_TV_PLL_N_14;
+                       p = PAL_TV_PLL_P_14;
                }
        }
 
index 1702b820aa4d3137e0559d44bd64bc37d8c28d7c..5413fcd630869204130b357776dca363dfc33556 100644 (file)
@@ -129,6 +129,7 @@ struct radeon_tmds_pll {
 #define RADEON_PLL_USE_FRAC_FB_DIV      (1 << 10)
 #define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11)
 #define RADEON_PLL_USE_POST_DIV         (1 << 12)
+#define RADEON_PLL_IS_LCD               (1 << 13)
 
 /* pll algo */
 enum radeon_pll_algo {
@@ -149,6 +150,8 @@ struct radeon_pll {
        uint32_t pll_in_max;
        uint32_t pll_out_min;
        uint32_t pll_out_max;
+       uint32_t lcd_pll_out_min;
+       uint32_t lcd_pll_out_max;
        uint32_t best_vco;
 
        /* divider limits */
@@ -170,17 +173,12 @@ struct radeon_pll {
        enum radeon_pll_algo algo;
 };
 
-struct i2c_algo_radeon_data {
-       struct i2c_adapter bit_adapter;
-       struct i2c_algo_bit_data bit_data;
-};
-
 struct radeon_i2c_chan {
        struct i2c_adapter adapter;
        struct drm_device *dev;
        union {
+               struct i2c_algo_bit_data bit;
                struct i2c_algo_dp_aux_data dp;
-               struct i2c_algo_radeon_data radeon;
        } algo;
        struct radeon_i2c_bus_rec rec;
 };
@@ -342,6 +340,7 @@ struct radeon_encoder {
        struct drm_display_mode native_mode;
        void *enc_priv;
        int hdmi_offset;
+       int hdmi_config_offset;
        int hdmi_audio_workaround;
        int hdmi_buffer_status;
 };
@@ -431,7 +430,6 @@ extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
                                                 struct radeon_i2c_bus_rec *rec,
                                                 const char *name);
 extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c);
-extern void radeon_i2c_destroy_dp(struct radeon_i2c_chan *i2c);
 extern void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus,
                                u8 slave_addr,
                                u8 addr,
@@ -560,6 +558,8 @@ extern int radeon_static_clocks_init(struct drm_device *dev);
 bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
                                        struct drm_display_mode *mode,
                                        struct drm_display_mode *adjusted_mode);
+void radeon_panel_mode_fixup(struct drm_encoder *encoder,
+                            struct drm_display_mode *adjusted_mode);
 void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc);
 
 /* legacy tv */
index fc9d00ac6b15ff68494c437dd758aff4f3214f66..122774742bd551ebecdd6b5509f904ff24ebe660 100644 (file)
@@ -30,6 +30,7 @@
  *    Dave Airlie
  */
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <drm/drmP.h>
 #include "radeon_drm.h"
 #include "radeon.h"
@@ -185,8 +186,10 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)
                return 0;
        }
        radeon_ttm_placement_from_domain(bo, domain);
-       /* force to pin into visible video ram */
-       bo->placement.lpfn = bo->rdev->mc.visible_vram_size >> PAGE_SHIFT;
+       if (domain == RADEON_GEM_DOMAIN_VRAM) {
+               /* force to pin into visible video ram */
+               bo->placement.lpfn = bo->rdev->mc.visible_vram_size >> PAGE_SHIFT;
+       }
        for (i = 0; i < bo->placement.num_placement; i++)
                bo->placements[i] |= TTM_PL_FLAG_NO_EVICT;
        r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
index d4d1c39a0e99e4e8636dd9e1d095da4473c61e87..a4b57493aa78cca3809558f3a428262f389a7837 100644 (file)
@@ -28,6 +28,7 @@
 #define RADEON_RECLOCK_DELAY_MS 200
 #define RADEON_WAIT_VBLANK_TIMEOUT 200
 
+static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish);
 static void radeon_pm_set_clocks_locked(struct radeon_device *rdev);
 static void radeon_pm_set_clocks(struct radeon_device *rdev);
 static void radeon_pm_idle_work_handler(struct work_struct *work);
@@ -179,6 +180,16 @@ static void radeon_get_power_state(struct radeon_device *rdev,
                 rdev->pm.requested_power_state->non_clock_info.pcie_lanes);
 }
 
+static inline void radeon_sync_with_vblank(struct radeon_device *rdev)
+{
+       if (rdev->pm.active_crtcs) {
+               rdev->pm.vblank_sync = false;
+               wait_event_timeout(
+                       rdev->irq.vblank_queue, rdev->pm.vblank_sync,
+                       msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT));
+       }
+}
+
 static void radeon_set_power_state(struct radeon_device *rdev)
 {
        /* if *_clock_mode are the same, *_power_state are as well */
@@ -189,11 +200,28 @@ static void radeon_set_power_state(struct radeon_device *rdev)
                 rdev->pm.requested_clock_mode->sclk,
                 rdev->pm.requested_clock_mode->mclk,
                 rdev->pm.requested_power_state->non_clock_info.pcie_lanes);
+
        /* set pcie lanes */
+       /* TODO */
+
        /* set voltage */
+       /* TODO */
+
        /* set engine clock */
+       radeon_sync_with_vblank(rdev);
+       radeon_pm_debug_check_in_vbl(rdev, false);
        radeon_set_engine_clock(rdev, rdev->pm.requested_clock_mode->sclk);
+       radeon_pm_debug_check_in_vbl(rdev, true);
+
+#if 0
        /* set memory clock */
+       if (rdev->asic->set_memory_clock) {
+               radeon_sync_with_vblank(rdev);
+               radeon_pm_debug_check_in_vbl(rdev, false);
+               radeon_set_memory_clock(rdev, rdev->pm.requested_clock_mode->mclk);
+               radeon_pm_debug_check_in_vbl(rdev, true);
+       }
+#endif
 
        rdev->pm.current_power_state = rdev->pm.requested_power_state;
        rdev->pm.current_clock_mode = rdev->pm.requested_clock_mode;
@@ -229,6 +257,12 @@ int radeon_pm_init(struct radeon_device *rdev)
        return 0;
 }
 
+void radeon_pm_fini(struct radeon_device *rdev)
+{
+       if (rdev->pm.i2c_bus)
+               radeon_i2c_destroy(rdev->pm.i2c_bus);
+}
+
 void radeon_pm_compute_clocks(struct radeon_device *rdev)
 {
        struct drm_device *ddev = rdev->ddev;
@@ -245,7 +279,8 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)
        list_for_each_entry(connector,
                &ddev->mode_config.connector_list, head) {
                if (connector->encoder &&
-                       connector->dpms != DRM_MODE_DPMS_OFF) {
+                   connector->encoder->crtc &&
+                   connector->dpms != DRM_MODE_DPMS_OFF) {
                        radeon_crtc = to_radeon_crtc(connector->encoder->crtc);
                        rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id);
                        ++count;
@@ -333,10 +368,7 @@ static void radeon_pm_set_clocks_locked(struct radeon_device *rdev)
                break;
        }
 
-       /* check if we are in vblank */
-       radeon_pm_debug_check_in_vbl(rdev, false);
        radeon_set_power_state(rdev);
-       radeon_pm_debug_check_in_vbl(rdev, true);
        rdev->pm.planned_action = PM_ACTION_NONE;
 }
 
@@ -353,10 +385,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
                rdev->pm.req_vblank |= (1 << 1);
                drm_vblank_get(rdev->ddev, 1);
        }
-       if (rdev->pm.active_crtcs)
-               wait_event_interruptible_timeout(
-                       rdev->irq.vblank_queue, 0,
-                       msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT));
+       radeon_pm_set_clocks_locked(rdev);
        if (rdev->pm.req_vblank & (1 << 0)) {
                rdev->pm.req_vblank &= ~(1 << 0);
                drm_vblank_put(rdev->ddev, 0);
@@ -366,7 +395,6 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
                drm_vblank_put(rdev->ddev, 1);
        }
 
-       radeon_pm_set_clocks_locked(rdev);
        mutex_unlock(&rdev->cp.mutex);
 }
 
index 5c0dc082d3307752a7dbf7067ea1b98f5cafaafa..eabbc9cf30a72fede242b8b13bd19a8c61508216 100644 (file)
 #       define RADEON_TVPLL_PWRMGT_OFF      (1 << 30)
 #       define RADEON_TVCLK_TURNOFF         (1 << 31)
 #define RADEON_PLL_PWRMGT_CNTL              0x0015 /* PLL */
+#      define RADEON_PM_MODE_SEL           (1 << 13)
 #       define RADEON_TCL_BYPASS_DISABLE    (1 << 20)
 #define RADEON_CLR_CMP_CLR_3D               0x1a24
 #define RADEON_CLR_CMP_CLR_DST              0x15c8
index e50513a627351983edbea71e2d369e959434e069..f6e1e8d4d986df18bd06a2ac7ae047eeb4706182 100644 (file)
@@ -26,6 +26,7 @@
  *          Jerome Glisse
  */
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "radeon_drm.h"
 #include "radeon_reg.h"
index 40ab6d9c3736ab754f07f55201eaa5252048df1f..cc5316dcf5802e602567ab21c52f688e322a4bea 100644 (file)
@@ -424,7 +424,7 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
                if ((*cmd & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
                    (*cmd & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
                        u32 *cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3);
-                       offset = *cmd << 10;
+                       offset = *cmd3 << 10;
                        if (radeon_check_and_fixup_offset
                            (dev_priv, file_priv, &offset)) {
                                DRM_ERROR("Invalid second packet offset\n");
@@ -2895,9 +2895,12 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data,
                        return rv;
                rv = drm_buffer_copy_from_user(cmdbuf->buffer, buffer,
                                                cmdbuf->bufsz);
-               if (rv)
+               if (rv) {
+                       drm_buffer_free(cmdbuf->buffer);
                        return rv;
-       }
+               }
+       } else
+               goto done;
 
        orig_nbox = cmdbuf->nbox;
 
@@ -2905,8 +2908,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data,
                int temp;
                temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf);
 
-               if (cmdbuf->bufsz != 0)
-                       drm_buffer_free(cmdbuf->buffer);
+               drm_buffer_free(cmdbuf->buffer);
 
                return temp;
        }
@@ -3012,16 +3014,15 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data,
                }
        }
 
-       if (cmdbuf->bufsz != 0)
-               drm_buffer_free(cmdbuf->buffer);
+       drm_buffer_free(cmdbuf->buffer);
 
+      done:
        DRM_DEBUG("DONE\n");
        COMMIT_RING();
        return 0;
 
       err:
-       if (cmdbuf->bufsz != 0)
-               drm_buffer_free(cmdbuf->buffer);
+       drm_buffer_free(cmdbuf->buffer);
        return -EINVAL;
 }
 
index 43c5ab34b634bf78383b940e3e2bafdda4c5d89e..d031b6863082c9feb99dbe412ce9a92662d21f60 100644 (file)
@@ -36,6 +36,7 @@
 #include <drm/drmP.h>
 #include <drm/radeon_drm.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "radeon_reg.h"
 #include "radeon.h"
 
index 19c4663fa9c699c3c97db8349b84a254e082c9f6..1e97b2d129fd90240056630cf60357ece84a7561 100644 (file)
@@ -125,6 +125,8 @@ r300 0x4f60
 0x4000 GB_VAP_RASTER_VTX_FMT_0
 0x4004 GB_VAP_RASTER_VTX_FMT_1
 0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
index 989f7a0208329f65f8723a477b92a87b8515d387..e958980d00f19d15b113bd8b95d186add903b246 100644 (file)
@@ -125,6 +125,8 @@ r420 0x4f60
 0x4000 GB_VAP_RASTER_VTX_FMT_0
 0x4004 GB_VAP_RASTER_VTX_FMT_1
 0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
index 8f414a5f520fe50790a1c5037fbbcd13dc94fb32..af0da4ae3f55acb5223f2791940ec90c1db20bce 100644 (file)
@@ -26,20 +26,16 @@ r600 0x9400
 0x00028408 VGT_INDX_OFFSET
 0x00028AA0 VGT_INSTANCE_STEP_RATE_0
 0x00028AA4 VGT_INSTANCE_STEP_RATE_1
-0x000088C0 VGT_LAST_COPY_STATE
 0x00028400 VGT_MAX_VTX_INDX
-0x000088D8 VGT_MC_LAT_CNTL
 0x00028404 VGT_MIN_VTX_INDX
 0x00028A94 VGT_MULTI_PRIM_IB_RESET_EN
 0x0002840C VGT_MULTI_PRIM_IB_RESET_INDX
 0x00008970 VGT_NUM_INDICES
 0x00008974 VGT_NUM_INSTANCES
 0x00028A10 VGT_OUTPUT_PATH_CNTL
-0x00028C5C VGT_OUT_DEALLOC_CNTL
 0x00028A84 VGT_PRIMITIVEID_EN
 0x00008958 VGT_PRIMITIVE_TYPE
 0x00028AB4 VGT_REUSE_OFF
-0x00028C58 VGT_VERTEX_REUSE_BLOCK_CNTL
 0x00028AB8 VGT_VTX_CNT_EN
 0x000088B0 VGT_VTX_VECT_EJECT_REG
 0x00028810 PA_CL_CLIP_CNTL
@@ -280,7 +276,6 @@ r600 0x9400
 0x00028E00 PA_SU_POLY_OFFSET_FRONT_SCALE
 0x00028814 PA_SU_SC_MODE_CNTL
 0x00028C08 PA_SU_VTX_CNTL
-0x00008C00 SQ_CONFIG
 0x00008C04 SQ_GPR_RESOURCE_MGMT_1
 0x00008C08 SQ_GPR_RESOURCE_MGMT_2
 0x00008C10 SQ_STACK_RESOURCE_MGMT_1
@@ -320,18 +315,6 @@ r600 0x9400
 0x000283FC SQ_VTX_SEMANTIC_31
 0x000288E0 SQ_VTX_SEMANTIC_CLEAR
 0x0003CFF4 SQ_VTX_START_INST_LOC
-0x0003C000 SQ_TEX_SAMPLER_WORD0_0
-0x0003C004 SQ_TEX_SAMPLER_WORD1_0
-0x0003C008 SQ_TEX_SAMPLER_WORD2_0
-0x00030000 SQ_ALU_CONSTANT0_0
-0x00030004 SQ_ALU_CONSTANT1_0
-0x00030008 SQ_ALU_CONSTANT2_0
-0x0003000C SQ_ALU_CONSTANT3_0
-0x0003E380 SQ_BOOL_CONST_0
-0x0003E384 SQ_BOOL_CONST_1
-0x0003E388 SQ_BOOL_CONST_2
-0x0003E200 SQ_LOOP_CONST_0
-0x0003E200 SQ_LOOP_CONST_DX10_0
 0x000281C0 SQ_ALU_CONST_BUFFER_SIZE_GS_0
 0x000281C4 SQ_ALU_CONST_BUFFER_SIZE_GS_1
 0x000281C8 SQ_ALU_CONST_BUFFER_SIZE_GS_2
@@ -380,54 +363,6 @@ r600 0x9400
 0x000281B4 SQ_ALU_CONST_BUFFER_SIZE_VS_13
 0x000281B8 SQ_ALU_CONST_BUFFER_SIZE_VS_14
 0x000281BC SQ_ALU_CONST_BUFFER_SIZE_VS_15
-0x000289C0 SQ_ALU_CONST_CACHE_GS_0
-0x000289C4 SQ_ALU_CONST_CACHE_GS_1
-0x000289C8 SQ_ALU_CONST_CACHE_GS_2
-0x000289CC SQ_ALU_CONST_CACHE_GS_3
-0x000289D0 SQ_ALU_CONST_CACHE_GS_4
-0x000289D4 SQ_ALU_CONST_CACHE_GS_5
-0x000289D8 SQ_ALU_CONST_CACHE_GS_6
-0x000289DC SQ_ALU_CONST_CACHE_GS_7
-0x000289E0 SQ_ALU_CONST_CACHE_GS_8
-0x000289E4 SQ_ALU_CONST_CACHE_GS_9
-0x000289E8 SQ_ALU_CONST_CACHE_GS_10
-0x000289EC SQ_ALU_CONST_CACHE_GS_11
-0x000289F0 SQ_ALU_CONST_CACHE_GS_12
-0x000289F4 SQ_ALU_CONST_CACHE_GS_13
-0x000289F8 SQ_ALU_CONST_CACHE_GS_14
-0x000289FC SQ_ALU_CONST_CACHE_GS_15
-0x00028940 SQ_ALU_CONST_CACHE_PS_0
-0x00028944 SQ_ALU_CONST_CACHE_PS_1
-0x00028948 SQ_ALU_CONST_CACHE_PS_2
-0x0002894C SQ_ALU_CONST_CACHE_PS_3
-0x00028950 SQ_ALU_CONST_CACHE_PS_4
-0x00028954 SQ_ALU_CONST_CACHE_PS_5
-0x00028958 SQ_ALU_CONST_CACHE_PS_6
-0x0002895C SQ_ALU_CONST_CACHE_PS_7
-0x00028960 SQ_ALU_CONST_CACHE_PS_8
-0x00028964 SQ_ALU_CONST_CACHE_PS_9
-0x00028968 SQ_ALU_CONST_CACHE_PS_10
-0x0002896C SQ_ALU_CONST_CACHE_PS_11
-0x00028970 SQ_ALU_CONST_CACHE_PS_12
-0x00028974 SQ_ALU_CONST_CACHE_PS_13
-0x00028978 SQ_ALU_CONST_CACHE_PS_14
-0x0002897C SQ_ALU_CONST_CACHE_PS_15
-0x00028980 SQ_ALU_CONST_CACHE_VS_0
-0x00028984 SQ_ALU_CONST_CACHE_VS_1
-0x00028988 SQ_ALU_CONST_CACHE_VS_2
-0x0002898C SQ_ALU_CONST_CACHE_VS_3
-0x00028990 SQ_ALU_CONST_CACHE_VS_4
-0x00028994 SQ_ALU_CONST_CACHE_VS_5
-0x00028998 SQ_ALU_CONST_CACHE_VS_6
-0x0002899C SQ_ALU_CONST_CACHE_VS_7
-0x000289A0 SQ_ALU_CONST_CACHE_VS_8
-0x000289A4 SQ_ALU_CONST_CACHE_VS_9
-0x000289A8 SQ_ALU_CONST_CACHE_VS_10
-0x000289AC SQ_ALU_CONST_CACHE_VS_11
-0x000289B0 SQ_ALU_CONST_CACHE_VS_12
-0x000289B4 SQ_ALU_CONST_CACHE_VS_13
-0x000289B8 SQ_ALU_CONST_CACHE_VS_14
-0x000289BC SQ_ALU_CONST_CACHE_VS_15
 0x000288D8 SQ_PGM_CF_OFFSET_ES
 0x000288DC SQ_PGM_CF_OFFSET_FS
 0x000288D4 SQ_PGM_CF_OFFSET_GS
@@ -494,12 +429,7 @@ r600 0x9400
 0x00028438 SX_ALPHA_REF
 0x00028410 SX_ALPHA_TEST_CONTROL
 0x00028350 SX_MISC
-0x0000A020 SMX_DC_CTL0
-0x0000A024 SMX_DC_CTL1
-0x0000A028 SMX_DC_CTL2
-0x00009608 TC_CNTL
 0x00009604 TC_INVALIDATE
-0x00009490 TD_CNTL
 0x00009400 TD_FILTER4
 0x00009404 TD_FILTER4_1
 0x00009408 TD_FILTER4_2
@@ -824,14 +754,9 @@ r600 0x9400
 0x00028428 CB_FOG_GREEN
 0x00028424 CB_FOG_RED
 0x00008040 WAIT_UNTIL
-0x00008950 CC_GC_SHADER_PIPE_CONFIG
-0x00008954 GC_USER_SHADER_PIPE_CONFIG
 0x00009714 VC_ENHANCE
 0x00009830 DB_DEBUG
 0x00009838 DB_WATERMARKS
 0x00028D28 DB_SRESULTS_COMPARE_STATE0
 0x00028D44 DB_ALPHA_TO_MASK
-0x00009504 TA_CNTL
 0x00009700 VC_CNTL
-0x00009718 VC_CONFIG
-0x0000A02C SMX_DC_MC_INTF_CTL
index 6801b865d1c4fca2cda34bc580dad3039acdb521..83e8bc0c2bb249d9fa11e90bea35b6716bcca236 100644 (file)
@@ -125,6 +125,8 @@ rs600 0x6d40
 0x4000 GB_VAP_RASTER_VTX_FMT_0
 0x4004 GB_VAP_RASTER_VTX_FMT_1
 0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
index 38abf63bf2cd84a47025ce6130457c16ca258381..1e46233985eb265106d5011d92402375632ea3f1 100644 (file)
@@ -35,6 +35,7 @@ rv515 0x6d40
 0x1DA8 VAP_VPORT_ZSCALE
 0x1DAC VAP_VPORT_ZOFFSET
 0x2080 VAP_CNTL
+0x208C VAP_INDEX_OFFSET
 0x2090 VAP_OUT_VTX_FMT_0
 0x2094 VAP_OUT_VTX_FMT_1
 0x20B0 VAP_VTE_CNTL
@@ -158,6 +159,8 @@ rv515 0x6d40
 0x4000 GB_VAP_RASTER_VTX_FMT_0
 0x4004 GB_VAP_RASTER_VTX_FMT_1
 0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
index 626d51891ee968613efeffc6612698387b46f1d4..1a41cb268b72c7ac6594f74ee80ccc47325b4ce7 100644 (file)
  *          Jerome Glisse
  */
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <drm/drmP.h>
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "rs400d.h"
 
 /* This files gather functions specifics to : rs400,rs480 */
@@ -202,9 +204,9 @@ void rs400_gart_disable(struct radeon_device *rdev)
 
 void rs400_gart_fini(struct radeon_device *rdev)
 {
+       radeon_gart_fini(rdev);
        rs400_gart_disable(rdev);
        radeon_gart_table_ram_free(rdev);
-       radeon_gart_fini(rdev);
 }
 
 int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
@@ -264,6 +266,7 @@ void rs400_mc_init(struct radeon_device *rdev)
        base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
        radeon_vram_location(rdev, &rdev->mc, base);
        radeon_gtt_location(rdev, &rdev->mc);
+       radeon_update_bandwidth_info(rdev);
 }
 
 uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg)
@@ -388,6 +391,8 @@ static int rs400_startup(struct radeon_device *rdev)
 {
        int r;
 
+       r100_set_common_regs(rdev);
+
        rs400_mc_program(rdev);
        /* Resume clock */
        r300_clock_startup(rdev);
@@ -453,6 +458,7 @@ int rs400_suspend(struct radeon_device *rdev)
 
 void rs400_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r100_cp_fini(rdev);
        r100_wb_fini(rdev);
        r100_ib_fini(rdev);
index 47f046b78c6ba9c19c93a2560179310b92f322d6..a81bc7a21e14b967c23a218c3095031371f7d327 100644 (file)
@@ -37,6 +37,7 @@
  */
 #include "drmP.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "atom.h"
 #include "rs600d.h"
 
@@ -158,7 +159,7 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev)
        WREG32_MC(R_000100_MC_PT0_CNTL, tmp);
 
        tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
-       tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) & S_000100_INVALIDATE_L2_CACHE(1);
+       tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) | S_000100_INVALIDATE_L2_CACHE(1);
        WREG32_MC(R_000100_MC_PT0_CNTL, tmp);
 
        tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
@@ -267,9 +268,9 @@ void rs600_gart_disable(struct radeon_device *rdev)
 
 void rs600_gart_fini(struct radeon_device *rdev)
 {
+       radeon_gart_fini(rdev);
        rs600_gart_disable(rdev);
        radeon_gart_table_vram_free(rdev);
-       radeon_gart_fini(rdev);
 }
 
 #define R600_PTE_VALID     (1 << 0)
@@ -392,10 +393,12 @@ int rs600_irq_process(struct radeon_device *rdev)
                /* Vertical blank interrupts */
                if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int)) {
                        drm_handle_vblank(rdev->ddev, 0);
+                       rdev->pm.vblank_sync = true;
                        wake_up(&rdev->irq.vblank_queue);
                }
                if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) {
                        drm_handle_vblank(rdev->ddev, 1);
+                       rdev->pm.vblank_sync = true;
                        wake_up(&rdev->irq.vblank_queue);
                }
                if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) {
@@ -472,13 +475,38 @@ void rs600_mc_init(struct radeon_device *rdev)
        rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
        base = RREG32_MC(R_000004_MC_FB_LOCATION);
        base = G_000004_MC_FB_START(base) << 16;
+       rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
        radeon_vram_location(rdev, &rdev->mc, base);
        radeon_gtt_location(rdev, &rdev->mc);
+       radeon_update_bandwidth_info(rdev);
 }
 
 void rs600_bandwidth_update(struct radeon_device *rdev)
 {
-       /* FIXME: implement, should this be like rs690 ? */
+       struct drm_display_mode *mode0 = NULL;
+       struct drm_display_mode *mode1 = NULL;
+       u32 d1mode_priority_a_cnt, d2mode_priority_a_cnt;
+       /* FIXME: implement full support */
+
+       radeon_update_display_priority(rdev);
+
+       if (rdev->mode_info.crtcs[0]->base.enabled)
+               mode0 = &rdev->mode_info.crtcs[0]->base.mode;
+       if (rdev->mode_info.crtcs[1]->base.enabled)
+               mode1 = &rdev->mode_info.crtcs[1]->base.mode;
+
+       rs690_line_buffer_adjust(rdev, mode0, mode1);
+
+       if (rdev->disp_priority == 2) {
+               d1mode_priority_a_cnt = RREG32(R_006548_D1MODE_PRIORITY_A_CNT);
+               d2mode_priority_a_cnt = RREG32(R_006D48_D2MODE_PRIORITY_A_CNT);
+               d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
+               d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
+               WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+               WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
+               WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+               WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
+       }
 }
 
 uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg)
@@ -598,6 +626,7 @@ int rs600_suspend(struct radeon_device *rdev)
 
 void rs600_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r100_cp_fini(rdev);
        r100_wb_fini(rdev);
        r100_ib_fini(rdev);
index c1c8f5885cbbc0727e484c49972e21790b5d3d74..e52d2695510b7375af024f99cb15083ebbba9c7d 100644 (file)
 #define   G_00016C_INVALIDATE_L1_TLB(x)                (((x) >> 20) & 0x1)
 #define   C_00016C_INVALIDATE_L1_TLB                   0xFFEFFFFF
 
+#define R_006548_D1MODE_PRIORITY_A_CNT               0x006548
+#define   S_006548_D1MODE_PRIORITY_MARK_A(x)           (((x) & 0x7FFF) << 0)
+#define   G_006548_D1MODE_PRIORITY_MARK_A(x)           (((x) >> 0) & 0x7FFF)
+#define   C_006548_D1MODE_PRIORITY_MARK_A              0xFFFF8000
+#define   S_006548_D1MODE_PRIORITY_A_OFF(x)            (((x) & 0x1) << 16)
+#define   G_006548_D1MODE_PRIORITY_A_OFF(x)            (((x) >> 16) & 0x1)
+#define   C_006548_D1MODE_PRIORITY_A_OFF               0xFFFEFFFF
+#define   S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) & 0x1) << 20)
+#define   G_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) >> 20) & 0x1)
+#define   C_006548_D1MODE_PRIORITY_A_ALWAYS_ON         0xFFEFFFFF
+#define   S_006548_D1MODE_PRIORITY_A_FORCE_MASK(x)     (((x) & 0x1) << 24)
+#define   G_006548_D1MODE_PRIORITY_A_FORCE_MASK(x)     (((x) >> 24) & 0x1)
+#define   C_006548_D1MODE_PRIORITY_A_FORCE_MASK        0xFEFFFFFF
+#define R_00654C_D1MODE_PRIORITY_B_CNT               0x00654C
+#define   S_00654C_D1MODE_PRIORITY_MARK_B(x)           (((x) & 0x7FFF) << 0)
+#define   G_00654C_D1MODE_PRIORITY_MARK_B(x)           (((x) >> 0) & 0x7FFF)
+#define   C_00654C_D1MODE_PRIORITY_MARK_B              0xFFFF8000
+#define   S_00654C_D1MODE_PRIORITY_B_OFF(x)            (((x) & 0x1) << 16)
+#define   G_00654C_D1MODE_PRIORITY_B_OFF(x)            (((x) >> 16) & 0x1)
+#define   C_00654C_D1MODE_PRIORITY_B_OFF               0xFFFEFFFF
+#define   S_00654C_D1MODE_PRIORITY_B_ALWAYS_ON(x)      (((x) & 0x1) << 20)
+#define   G_00654C_D1MODE_PRIORITY_B_ALWAYS_ON(x)      (((x) >> 20) & 0x1)
+#define   C_00654C_D1MODE_PRIORITY_B_ALWAYS_ON         0xFFEFFFFF
+#define   S_00654C_D1MODE_PRIORITY_B_FORCE_MASK(x)     (((x) & 0x1) << 24)
+#define   G_00654C_D1MODE_PRIORITY_B_FORCE_MASK(x)     (((x) >> 24) & 0x1)
+#define   C_00654C_D1MODE_PRIORITY_B_FORCE_MASK        0xFEFFFFFF
+#define R_006D48_D2MODE_PRIORITY_A_CNT               0x006D48
+#define   S_006D48_D2MODE_PRIORITY_MARK_A(x)           (((x) & 0x7FFF) << 0)
+#define   G_006D48_D2MODE_PRIORITY_MARK_A(x)           (((x) >> 0) & 0x7FFF)
+#define   C_006D48_D2MODE_PRIORITY_MARK_A              0xFFFF8000
+#define   S_006D48_D2MODE_PRIORITY_A_OFF(x)            (((x) & 0x1) << 16)
+#define   G_006D48_D2MODE_PRIORITY_A_OFF(x)            (((x) >> 16) & 0x1)
+#define   C_006D48_D2MODE_PRIORITY_A_OFF               0xFFFEFFFF
+#define   S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) & 0x1) << 20)
+#define   G_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) >> 20) & 0x1)
+#define   C_006D48_D2MODE_PRIORITY_A_ALWAYS_ON         0xFFEFFFFF
+#define   S_006D48_D2MODE_PRIORITY_A_FORCE_MASK(x)     (((x) & 0x1) << 24)
+#define   G_006D48_D2MODE_PRIORITY_A_FORCE_MASK(x)     (((x) >> 24) & 0x1)
+#define   C_006D48_D2MODE_PRIORITY_A_FORCE_MASK        0xFEFFFFFF
+#define R_006D4C_D2MODE_PRIORITY_B_CNT               0x006D4C
+#define   S_006D4C_D2MODE_PRIORITY_MARK_B(x)           (((x) & 0x7FFF) << 0)
+#define   G_006D4C_D2MODE_PRIORITY_MARK_B(x)           (((x) >> 0) & 0x7FFF)
+#define   C_006D4C_D2MODE_PRIORITY_MARK_B              0xFFFF8000
+#define   S_006D4C_D2MODE_PRIORITY_B_OFF(x)            (((x) & 0x1) << 16)
+#define   G_006D4C_D2MODE_PRIORITY_B_OFF(x)            (((x) >> 16) & 0x1)
+#define   C_006D4C_D2MODE_PRIORITY_B_OFF               0xFFFEFFFF
+#define   S_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON(x)      (((x) & 0x1) << 20)
+#define   G_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON(x)      (((x) >> 20) & 0x1)
+#define   C_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON         0xFFEFFFFF
+#define   S_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x)     (((x) & 0x1) << 24)
+#define   G_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x)     (((x) >> 24) & 0x1)
+#define   C_006D4C_D2MODE_PRIORITY_B_FORCE_MASK        0xFEFFFFFF
+
 #endif
index 83b9174f76f255e9fb488a3fe294a87eb0fafd62..bbf3da790fd59fc7a8a03e65f260487d6fa7bca0 100644 (file)
@@ -27,6 +27,7 @@
  */
 #include "drmP.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "atom.h"
 #include "rs690d.h"
 
@@ -57,42 +58,57 @@ static void rs690_gpu_init(struct radeon_device *rdev)
        }
 }
 
+union igp_info {
+       struct _ATOM_INTEGRATED_SYSTEM_INFO info;
+       struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_v2;
+};
+
 void rs690_pm_info(struct radeon_device *rdev)
 {
        int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
-       struct _ATOM_INTEGRATED_SYSTEM_INFO *info;
-       struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 *info_v2;
-       void *ptr;
+       union igp_info *info;
        uint16_t data_offset;
        uint8_t frev, crev;
        fixed20_12 tmp;
 
-       atom_parse_data_header(rdev->mode_info.atom_context, index, NULL,
-                              &frev, &crev, &data_offset);
-       ptr = rdev->mode_info.atom_context->bios + data_offset;
-       info = (struct _ATOM_INTEGRATED_SYSTEM_INFO *)ptr;
-       info_v2 = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 *)ptr;
-       /* Get various system informations from bios */
-       switch (crev) {
-       case 1:
-               tmp.full = rfixed_const(100);
-               rdev->pm.igp_sideport_mclk.full = rfixed_const(info->ulBootUpMemoryClock);
-               rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
-               rdev->pm.igp_system_mclk.full = rfixed_const(le16_to_cpu(info->usK8MemoryClock));
-               rdev->pm.igp_ht_link_clk.full = rfixed_const(le16_to_cpu(info->usFSBClock));
-               rdev->pm.igp_ht_link_width.full = rfixed_const(info->ucHTLinkWidth);
-               break;
-       case 2:
-               tmp.full = rfixed_const(100);
-               rdev->pm.igp_sideport_mclk.full = rfixed_const(info_v2->ulBootUpSidePortClock);
-               rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
-               rdev->pm.igp_system_mclk.full = rfixed_const(info_v2->ulBootUpUMAClock);
-               rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp);
-               rdev->pm.igp_ht_link_clk.full = rfixed_const(info_v2->ulHTLinkFreq);
-               rdev->pm.igp_ht_link_clk.full = rfixed_div(rdev->pm.igp_ht_link_clk, tmp);
-               rdev->pm.igp_ht_link_width.full = rfixed_const(le16_to_cpu(info_v2->usMinHTLinkWidth));
-               break;
-       default:
+       if (atom_parse_data_header(rdev->mode_info.atom_context, index, NULL,
+                                  &frev, &crev, &data_offset)) {
+               info = (union igp_info *)(rdev->mode_info.atom_context->bios + data_offset);
+
+               /* Get various system informations from bios */
+               switch (crev) {
+               case 1:
+                       tmp.full = rfixed_const(100);
+                       rdev->pm.igp_sideport_mclk.full = rfixed_const(info->info.ulBootUpMemoryClock);
+                       rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
+                       rdev->pm.igp_system_mclk.full = rfixed_const(le16_to_cpu(info->info.usK8MemoryClock));
+                       rdev->pm.igp_ht_link_clk.full = rfixed_const(le16_to_cpu(info->info.usFSBClock));
+                       rdev->pm.igp_ht_link_width.full = rfixed_const(info->info.ucHTLinkWidth);
+                       break;
+               case 2:
+                       tmp.full = rfixed_const(100);
+                       rdev->pm.igp_sideport_mclk.full = rfixed_const(info->info_v2.ulBootUpSidePortClock);
+                       rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
+                       rdev->pm.igp_system_mclk.full = rfixed_const(info->info_v2.ulBootUpUMAClock);
+                       rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp);
+                       rdev->pm.igp_ht_link_clk.full = rfixed_const(info->info_v2.ulHTLinkFreq);
+                       rdev->pm.igp_ht_link_clk.full = rfixed_div(rdev->pm.igp_ht_link_clk, tmp);
+                       rdev->pm.igp_ht_link_width.full = rfixed_const(le16_to_cpu(info->info_v2.usMinHTLinkWidth));
+                       break;
+               default:
+                       tmp.full = rfixed_const(100);
+                       /* We assume the slower possible clock ie worst case */
+                       /* DDR 333Mhz */
+                       rdev->pm.igp_sideport_mclk.full = rfixed_const(333);
+                       /* FIXME: system clock ? */
+                       rdev->pm.igp_system_mclk.full = rfixed_const(100);
+                       rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp);
+                       rdev->pm.igp_ht_link_clk.full = rfixed_const(200);
+                       rdev->pm.igp_ht_link_width.full = rfixed_const(8);
+                       DRM_ERROR("No integrated system info for your GPU, using safe default\n");
+                       break;
+               }
+       } else {
                tmp.full = rfixed_const(100);
                /* We assume the slower possible clock ie worst case */
                /* DDR 333Mhz */
@@ -103,7 +119,6 @@ void rs690_pm_info(struct radeon_device *rdev)
                rdev->pm.igp_ht_link_clk.full = rfixed_const(200);
                rdev->pm.igp_ht_link_width.full = rfixed_const(8);
                DRM_ERROR("No integrated system info for your GPU, using safe default\n");
-               break;
        }
        /* Compute various bandwidth */
        /* k8_bandwidth = (memory_clk / 2) * 2 * 8 * 0.5 = memory_clk * 4  */
@@ -131,7 +146,6 @@ void rs690_pm_info(struct radeon_device *rdev)
 
 void rs690_mc_init(struct radeon_device *rdev)
 {
-       fixed20_12 a;
        u64 base;
 
        rs400_gart_adjust_size(rdev);
@@ -145,18 +159,10 @@ void rs690_mc_init(struct radeon_device *rdev)
        base = RREG32_MC(R_000100_MCCFG_FB_LOCATION);
        base = G_000100_MC_FB_START(base) << 16;
        rs690_pm_info(rdev);
-       /* FIXME: we should enforce default clock in case GPU is not in
-        * default setup
-        */
-       a.full = rfixed_const(100);
-       rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
-       rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
-       a.full = rfixed_const(16);
-       /* core_bandwidth = sclk(Mhz) * 16 */
-       rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a);
        rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
        radeon_vram_location(rdev, &rdev->mc, base);
        radeon_gtt_location(rdev, &rdev->mc);
+       radeon_update_bandwidth_info(rdev);
 }
 
 void rs690_line_buffer_adjust(struct radeon_device *rdev,
@@ -394,10 +400,12 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
        struct drm_display_mode *mode1 = NULL;
        struct rs690_watermark wm0;
        struct rs690_watermark wm1;
-       u32 tmp;
+       u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt;
        fixed20_12 priority_mark02, priority_mark12, fill_rate;
        fixed20_12 a, b;
 
+       radeon_update_display_priority(rdev);
+
        if (rdev->mode_info.crtcs[0]->base.enabled)
                mode0 = &rdev->mode_info.crtcs[0]->base.mode;
        if (rdev->mode_info.crtcs[1]->base.enabled)
@@ -407,7 +415,8 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
         * modes if the user specifies HIGH for displaypriority
         * option.
         */
-       if (rdev->disp_priority == 2) {
+       if ((rdev->disp_priority == 2) &&
+           ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740))) {
                tmp = RREG32_MC(R_000104_MC_INIT_MISC_LAT_TIMER);
                tmp &= C_000104_MC_DISP0R_INIT_LAT;
                tmp &= C_000104_MC_DISP1R_INIT_LAT;
@@ -482,10 +491,16 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
                        priority_mark12.full = 0;
                if (wm1.priority_mark_max.full > priority_mark12.full)
                        priority_mark12.full = wm1.priority_mark_max.full;
-               WREG32(R_006548_D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
-               WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
-               WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
-               WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
+               d1mode_priority_a_cnt = rfixed_trunc(priority_mark02);
+               d2mode_priority_a_cnt = rfixed_trunc(priority_mark12);
+               if (rdev->disp_priority == 2) {
+                       d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
+                       d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
+               }
+               WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+               WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
+               WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+               WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
        } else if (mode0) {
                if (rfixed_trunc(wm0.dbpp) > 64)
                        a.full = rfixed_mul(wm0.dbpp, wm0.num_line_pair);
@@ -512,8 +527,11 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
                        priority_mark02.full = 0;
                if (wm0.priority_mark_max.full > priority_mark02.full)
                        priority_mark02.full = wm0.priority_mark_max.full;
-               WREG32(R_006548_D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
-               WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
+               d1mode_priority_a_cnt = rfixed_trunc(priority_mark02);
+               if (rdev->disp_priority == 2)
+                       d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
+               WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+               WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
                WREG32(R_006D48_D2MODE_PRIORITY_A_CNT,
                        S_006D48_D2MODE_PRIORITY_A_OFF(1));
                WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT,
@@ -544,12 +562,15 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
                        priority_mark12.full = 0;
                if (wm1.priority_mark_max.full > priority_mark12.full)
                        priority_mark12.full = wm1.priority_mark_max.full;
+               d2mode_priority_a_cnt = rfixed_trunc(priority_mark12);
+               if (rdev->disp_priority == 2)
+                       d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
                WREG32(R_006548_D1MODE_PRIORITY_A_CNT,
                        S_006548_D1MODE_PRIORITY_A_OFF(1));
                WREG32(R_00654C_D1MODE_PRIORITY_B_CNT,
                        S_00654C_D1MODE_PRIORITY_B_OFF(1));
-               WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
-               WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
+               WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+               WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
        }
 }
 
@@ -657,6 +678,7 @@ int rs690_suspend(struct radeon_device *rdev)
 
 void rs690_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r100_cp_fini(rdev);
        r100_wb_fini(rdev);
        r100_ib_fini(rdev);
index 62d31e7a897f89e3327235d1ab91f671d26d6f8f..36e6398a98aea242520f5772bd556ea9293af48a 100644 (file)
 #define   S_006548_D1MODE_PRIORITY_A_OFF(x)            (((x) & 0x1) << 16)
 #define   G_006548_D1MODE_PRIORITY_A_OFF(x)            (((x) >> 16) & 0x1)
 #define   C_006548_D1MODE_PRIORITY_A_OFF               0xFFFEFFFF
+#define   S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) & 0x1) << 20)
+#define   G_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) >> 20) & 0x1)
+#define   C_006548_D1MODE_PRIORITY_A_ALWAYS_ON         0xFFEFFFFF
 #define   S_006548_D1MODE_PRIORITY_A_FORCE_MASK(x)     (((x) & 0x1) << 24)
 #define   G_006548_D1MODE_PRIORITY_A_FORCE_MASK(x)     (((x) >> 24) & 0x1)
 #define   C_006548_D1MODE_PRIORITY_A_FORCE_MASK        0xFEFFFFFF
index bea747da123ffef833df17c8d71e9ee1b0c02121..9035121f4b584bc1282c334130db4e0e16eefab2 100644 (file)
  *          Jerome Glisse
  */
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "rv515d.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "atom.h"
 #include "rv515_reg_safe.h"
 
@@ -279,19 +281,13 @@ static void rv515_vram_get_type(struct radeon_device *rdev)
 
 void rv515_mc_init(struct radeon_device *rdev)
 {
-       fixed20_12 a;
 
        rv515_vram_get_type(rdev);
        r100_vram_init_sizes(rdev);
        radeon_vram_location(rdev, &rdev->mc, 0);
        if (!(rdev->flags & RADEON_IS_AGP))
                radeon_gtt_location(rdev, &rdev->mc);
-       /* FIXME: we should enforce default clock in case GPU is not in
-        * default setup
-        */
-       a.full = rfixed_const(100);
-       rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
-       rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+       radeon_update_bandwidth_info(rdev);
 }
 
 uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg)
@@ -539,6 +535,7 @@ void rv515_set_safe_registers(struct radeon_device *rdev)
 
 void rv515_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r100_cp_fini(rdev);
        r100_wb_fini(rdev);
        r100_ib_fini(rdev);
@@ -1020,7 +1017,7 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
        struct drm_display_mode *mode1 = NULL;
        struct rv515_watermark wm0;
        struct rv515_watermark wm1;
-       u32 tmp;
+       u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt;
        fixed20_12 priority_mark02, priority_mark12, fill_rate;
        fixed20_12 a, b;
 
@@ -1088,10 +1085,16 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
                        priority_mark12.full = 0;
                if (wm1.priority_mark_max.full > priority_mark12.full)
                        priority_mark12.full = wm1.priority_mark_max.full;
-               WREG32(D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
-               WREG32(D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
-               WREG32(D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
-               WREG32(D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
+               d1mode_priority_a_cnt = rfixed_trunc(priority_mark02);
+               d2mode_priority_a_cnt = rfixed_trunc(priority_mark12);
+               if (rdev->disp_priority == 2) {
+                       d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
+                       d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
+               }
+               WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+               WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
+               WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+               WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
        } else if (mode0) {
                if (rfixed_trunc(wm0.dbpp) > 64)
                        a.full = rfixed_div(wm0.dbpp, wm0.num_line_pair);
@@ -1118,8 +1121,11 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
                        priority_mark02.full = 0;
                if (wm0.priority_mark_max.full > priority_mark02.full)
                        priority_mark02.full = wm0.priority_mark_max.full;
-               WREG32(D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
-               WREG32(D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
+               d1mode_priority_a_cnt = rfixed_trunc(priority_mark02);
+               if (rdev->disp_priority == 2)
+                       d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
+               WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+               WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
                WREG32(D2MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);
                WREG32(D2MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);
        } else {
@@ -1148,10 +1154,13 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
                        priority_mark12.full = 0;
                if (wm1.priority_mark_max.full > priority_mark12.full)
                        priority_mark12.full = wm1.priority_mark_max.full;
+               d2mode_priority_a_cnt = rfixed_trunc(priority_mark12);
+               if (rdev->disp_priority == 2)
+                       d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
                WREG32(D1MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);
                WREG32(D1MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);
-               WREG32(D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
-               WREG32(D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
+               WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+               WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
        }
 }
 
@@ -1161,6 +1170,8 @@ void rv515_bandwidth_update(struct radeon_device *rdev)
        struct drm_display_mode *mode0 = NULL;
        struct drm_display_mode *mode1 = NULL;
 
+       radeon_update_display_priority(rdev);
+
        if (rdev->mode_info.crtcs[0]->base.enabled)
                mode0 = &rdev->mode_info.crtcs[0]->base.mode;
        if (rdev->mode_info.crtcs[1]->base.enabled)
@@ -1170,7 +1181,8 @@ void rv515_bandwidth_update(struct radeon_device *rdev)
         * modes if the user specifies HIGH for displaypriority
         * option.
         */
-       if (rdev->disp_priority == 2) {
+       if ((rdev->disp_priority == 2) &&
+           (rdev->family == CHIP_RV515)) {
                tmp = RREG32_MC(MC_MISC_LAT_TIMER);
                tmp &= ~MC_DISP1R_INIT_LAT_MASK;
                tmp &= ~MC_DISP0R_INIT_LAT_MASK;
index 37887dee12afc48fa999fcf4f828433396604213..97958a64df1a5c7e438939d854ef95bcf47d2750 100644 (file)
  */
 #include <linux/firmware.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include "drmP.h"
 #include "radeon.h"
+#include "radeon_asic.h"
 #include "radeon_drm.h"
 #include "rv770d.h"
 #include "atom.h"
@@ -125,9 +127,9 @@ void rv770_pcie_gart_disable(struct radeon_device *rdev)
 
 void rv770_pcie_gart_fini(struct radeon_device *rdev)
 {
+       radeon_gart_fini(rdev);
        rv770_pcie_gart_disable(rdev);
        radeon_gart_table_vram_free(rdev);
-       radeon_gart_fini(rdev);
 }
 
 
@@ -647,10 +649,13 @@ static void rv770_gpu_init(struct radeon_device *rdev)
 
        WREG32(CC_RB_BACKEND_DISABLE,      cc_rb_backend_disable);
        WREG32(CC_GC_SHADER_PIPE_CONFIG,   cc_gc_shader_pipe_config);
+       WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
        WREG32(CC_SYS_RB_BACKEND_DISABLE,  cc_rb_backend_disable);
 
        WREG32(CGTS_SYS_TCC_DISABLE, 0);
        WREG32(CGTS_TCC_DISABLE, 0);
+       WREG32(CGTS_USER_SYS_TCC_DISABLE, 0);
+       WREG32(CGTS_USER_TCC_DISABLE, 0);
 
        num_qd_pipes =
                R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8);
@@ -864,7 +869,6 @@ static void rv770_gpu_init(struct radeon_device *rdev)
 
 int rv770_mc_init(struct radeon_device *rdev)
 {
-       fixed20_12 a;
        u32 tmp;
        int chansize, numchan;
 
@@ -908,12 +912,8 @@ int rv770_mc_init(struct radeon_device *rdev)
                rdev->mc.real_vram_size = rdev->mc.aper_size;
        }
        r600_vram_gtt_location(rdev, &rdev->mc);
-       /* FIXME: we should enforce default clock in case GPU is not in
-        * default setup
-        */
-       a.full = rfixed_const(100);
-       rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
-       rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+       radeon_update_bandwidth_info(rdev);
+
        return 0;
 }
 
@@ -1013,6 +1013,13 @@ int rv770_resume(struct radeon_device *rdev)
                DRM_ERROR("radeon: failled testing IB (%d).\n", r);
                return r;
        }
+
+       r = r600_audio_init(rdev);
+       if (r) {
+               dev_err(rdev->dev, "radeon: audio init failed\n");
+               return r;
+       }
+
        return r;
 
 }
@@ -1021,6 +1028,7 @@ int rv770_suspend(struct radeon_device *rdev)
 {
        int r;
 
+       r600_audio_fini(rdev);
        /* FIXME: we should wait for ring to be empty */
        r700_cp_stop(rdev);
        rdev->cp.ready = false;
@@ -1144,11 +1152,19 @@ int rv770_init(struct radeon_device *rdev)
                        }
                }
        }
+
+       r = r600_audio_init(rdev);
+       if (r) {
+               dev_err(rdev->dev, "radeon: audio init failed\n");
+               return r;
+       }
+
        return 0;
 }
 
 void rv770_fini(struct radeon_device *rdev)
 {
+       radeon_pm_fini(rdev);
        r600_blit_fini(rdev);
        r600_cp_fini(rdev);
        r600_wb_fini(rdev);
index 4648ed2f01433a4dcce37c349de3722f7a77664a..4bf69c4044913d7e890f06a93aa2e5d25ca40fb9 100644 (file)
@@ -35,6 +35,7 @@
 #include "ttm/ttm_placement.h"
 #include <linux/agp_backend.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 #include <asm/agp.h>
 
index 89c38c49066f2d87a69ecf58d528f2cf209a26af..0e3754a3a303c18391538180b702a2b0e4c66399 100644 (file)
@@ -1425,8 +1425,8 @@ int ttm_bo_global_init(struct ttm_global_reference *ref)
 
        atomic_set(&glob->bo_count, 0);
 
-       kobject_init(&glob->kobj, &ttm_bo_glob_kobj_type);
-       ret = kobject_add(&glob->kobj, ttm_get_kobj(), "buffer_objects");
+       ret = kobject_init_and_add(
+               &glob->kobj, &ttm_bo_glob_kobj_type, ttm_get_kobj(), "buffer_objects");
        if (unlikely(ret != 0))
                kobject_put(&glob->kobj);
        return ret;
@@ -1716,40 +1716,12 @@ int ttm_bo_wait(struct ttm_buffer_object *bo,
 }
 EXPORT_SYMBOL(ttm_bo_wait);
 
-void ttm_bo_unblock_reservation(struct ttm_buffer_object *bo)
-{
-       atomic_set(&bo->reserved, 0);
-       wake_up_all(&bo->event_queue);
-}
-
-int ttm_bo_block_reservation(struct ttm_buffer_object *bo, bool interruptible,
-                            bool no_wait)
-{
-       int ret;
-
-       while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) {
-               if (no_wait)
-                       return -EBUSY;
-               else if (interruptible) {
-                       ret = wait_event_interruptible
-                           (bo->event_queue, atomic_read(&bo->reserved) == 0);
-                       if (unlikely(ret != 0))
-                               return ret;
-               } else {
-                       wait_event(bo->event_queue,
-                                  atomic_read(&bo->reserved) == 0);
-               }
-       }
-       return 0;
-}
-
 int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait)
 {
        int ret = 0;
 
        /*
-        * Using ttm_bo_reserve instead of ttm_bo_block_reservation
-        * makes sure the lru lists are updated.
+        * Using ttm_bo_reserve makes sure the lru lists are updated.
         */
 
        ret = ttm_bo_reserve(bo, true, no_wait, false, 0);
index 5ca37a58a98c80be24beb227cef980f2cdbf7abf..d764e82e799b4a264618a723ad66d46aa3e9b217 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/io.h>
 #include <linux/highmem.h>
 #include <linux/wait.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/module.h>
 
index 3d172ef04ee11aceb7276a686f31b1c19daa66e1..de41e55a944ad8ef1f9ae7d5769a5ae4eb131279 100644 (file)
@@ -204,7 +204,6 @@ static int __ttm_vt_unlock(struct ttm_lock *lock)
        lock->flags &= ~TTM_VT_LOCK;
        wake_up_all(&lock->queue);
        spin_unlock(&lock->lock);
-       printk(KERN_INFO TTM_PFX "vt unlock.\n");
 
        return ret;
 }
@@ -265,10 +264,8 @@ int ttm_vt_lock(struct ttm_lock *lock,
                                   ttm_lock_type, &ttm_vt_lock_remove, NULL);
        if (ret)
                (void)__ttm_vt_unlock(lock);
-       else {
+       else
                lock->vt_holder = tfile;
-               printk(KERN_INFO TTM_PFX "vt lock.\n");
-       }
 
        return ret;
 }
index eb143e04d40242a35c99d774f981cdf610979f6b..801b702566e6d61fc94205372d886723e9459b9f 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/wait.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #define TTM_MEMORY_ALLOC_RETRIES 4
 
@@ -260,8 +261,8 @@ static int ttm_mem_init_kernel_zone(struct ttm_mem_global *glob,
        zone->used_mem = 0;
        zone->glob = glob;
        glob->zone_kernel = zone;
-       kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type);
-       ret = kobject_add(&zone->kobj, &glob->kobj, zone->name);
+       ret = kobject_init_and_add(
+               &zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name);
        if (unlikely(ret != 0)) {
                kobject_put(&zone->kobj);
                return ret;
@@ -296,8 +297,8 @@ static int ttm_mem_init_highmem_zone(struct ttm_mem_global *glob,
        zone->used_mem = 0;
        zone->glob = glob;
        glob->zone_highmem = zone;
-       kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type);
-       ret = kobject_add(&zone->kobj, &glob->kobj, zone->name);
+       ret = kobject_init_and_add(
+               &zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name);
        if (unlikely(ret != 0)) {
                kobject_put(&zone->kobj);
                return ret;
@@ -343,8 +344,8 @@ static int ttm_mem_init_dma32_zone(struct ttm_mem_global *glob,
        zone->used_mem = 0;
        zone->glob = glob;
        glob->zone_dma32 = zone;
-       kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type);
-       ret = kobject_add(&zone->kobj, &glob->kobj, zone->name);
+       ret = kobject_init_and_add(
+               &zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name);
        if (unlikely(ret != 0)) {
                kobject_put(&zone->kobj);
                return ret;
@@ -365,10 +366,8 @@ int ttm_mem_global_init(struct ttm_mem_global *glob)
        glob->swap_queue = create_singlethread_workqueue("ttm_swap");
        INIT_WORK(&glob->work, ttm_shrink_work);
        init_waitqueue_head(&glob->queue);
-       kobject_init(&glob->kobj, &ttm_mem_glob_kobj_type);
-       ret = kobject_add(&glob->kobj,
-                         ttm_get_kobj(),
-                         "memory_accounting");
+       ret = kobject_init_and_add(
+               &glob->kobj, &ttm_mem_glob_kobj_type, ttm_get_kobj(), "memory_accounting");
        if (unlikely(ret != 0)) {
                kobject_put(&glob->kobj);
                return ret;
index a759170763bb6bc2e878a26834f7aa665dff943e..d5fd5b8faeb3559ed46c2ef53a78800ecc4fc129 100644 (file)
  * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
  */
 
-#include <linux/vmalloc.h>
 #include <linux/sched.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/file.h>
 #include <linux/swap.h>
+#include <linux/slab.h>
 #include "drm_cache.h"
+#include "drm_mem_util.h"
 #include "ttm/ttm_module.h"
 #include "ttm/ttm_bo_driver.h"
 #include "ttm/ttm_placement.h"
@@ -43,32 +44,15 @@ static int ttm_tt_swapin(struct ttm_tt *ttm);
 
 /**
  * Allocates storage for pointers to the pages that back the ttm.
- *
- * Uses kmalloc if possible. Otherwise falls back to vmalloc.
  */
 static void ttm_tt_alloc_page_directory(struct ttm_tt *ttm)
 {
-       unsigned long size = ttm->num_pages * sizeof(*ttm->pages);
-       ttm->pages = NULL;
-
-       if (size <= PAGE_SIZE)
-               ttm->pages = kzalloc(size, GFP_KERNEL);
-
-       if (!ttm->pages) {
-               ttm->pages = vmalloc_user(size);
-               if (ttm->pages)
-                       ttm->page_flags |= TTM_PAGE_FLAG_VMALLOC;
-       }
+       ttm->pages = drm_calloc_large(ttm->num_pages, sizeof(*ttm->pages));
 }
 
 static void ttm_tt_free_page_directory(struct ttm_tt *ttm)
 {
-       if (ttm->page_flags & TTM_PAGE_FLAG_VMALLOC) {
-               vfree(ttm->pages);
-               ttm->page_flags &= ~TTM_PAGE_FLAG_VMALLOC;
-       } else {
-               kfree(ttm->pages);
-       }
+       drm_free_large(ttm->pages);
        ttm->pages = NULL;
 }
 
index 327380888b4a5f15880bbef8f17f93658d12ab89..4c54f043068ed3195595863f563a6c19c01bf7fc 100644 (file)
@@ -40,6 +40,7 @@
 #include "via_dmablit.h"
 
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 
 #define VIA_PGDN(x)         (((unsigned long)(x)) & PAGE_MASK)
 #define VIA_PGOFF(x)       (((unsigned long)(x)) & ~PAGE_MASK)
index 6ec04ac1245991ffea7bf1a5cf1197f4b411ea46..6efac8117c93c77a20eb7079bbdbb6c4440e58b3 100644 (file)
@@ -75,7 +75,7 @@ int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_
 
        DRM_DEBUG("\n");
 
-       if (fx->lock > VIA_NR_XVMC_LOCKS)
+       if (fx->lock >= VIA_NR_XVMC_LOCKS)
                return -EFAULT;
 
        lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx->lock);
index f20b8bcbef3998cfd447eee2a3e2d8e904827dc8..30ad13344f7b96da384ffff3209dc2683e1e282a 100644 (file)
@@ -1,6 +1,6 @@
 config DRM_VMWGFX
        tristate "DRM driver for VMware Virtual GPU"
-       depends on DRM && PCI
+       depends on DRM && PCI && FB
        select FB_DEFERRED_IO
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
index d6d1149d525d65dd1847d391e16840ed1591d7a3..c8768f38511e823afb863b88e8a55db9246fa929 100644 (file)
@@ -276,8 +276,10 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
 
        mutex_lock(&vgasr_mutex);
 
-       if (!vgasr_priv.active)
-               return -EINVAL;
+       if (!vgasr_priv.active) {
+               cnt = -EINVAL;
+               goto out;
+       }
 
        /* pwr off the device not in use */
        if (strncmp(usercmd, "OFF", 3) == 0) {
index 8827814d0735fbc7c3ff619b6f608476c82a4172..441e38c95a8535b863d924aea1c468872ba6d27a 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/spinlock.h>
 #include <linux/poll.h>
 #include <linux/miscdevice.h>
+#include <linux/slab.h>
 
 #include <linux/uaccess.h>
 
index 2370aefc86b2f6371bfca1355b2f474b2a7e00e1..c31e0be8ccea34eea7d6c0956f5a759debf324dc 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
index df474c699fb8007603c884a2e06f4b4540a20ed6..3a2b223c1da4a23e3fb346116cba22ed5278d92a 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/input.h>
 #include <linux/hid.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "hid-ids.h"
 
index 78286b184ace5ebe58850623b5ab670d1c995a64..bba05d0a8980e1b43aa8ec6548400b7cf8d174b8 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "hid-ids.h"
index 7e597d7f770fedb35284ef5a3d827cf01872559f..24663a8717b13bbc4e39657c082bf84b07a506bc 100644 (file)
@@ -59,6 +59,7 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 
 static const struct hid_device_id ch_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
        { }
 };
 MODULE_DEVICE_TABLE(hid, ch_devices);
index 368fbb0c4ca6b161d2acea66d7a10bdf4c6a36f5..143e788b729b1bdaadb4888e3568dac3a6714b0c 100644 (file)
@@ -1043,13 +1043,8 @@ void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
 
        if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
                hid->hiddev_report_event(hid, report);
-       if (hid->claimed & HID_CLAIMED_HIDRAW) {
-               /* numbered reports need to be passed with the report num */
-               if (report_enum->numbered)
-                       hidraw_report_event(hid, data - 1, size + 1);
-               else
-                       hidraw_report_event(hid, data, size);
-       }
+       if (hid->claimed & HID_CLAIMED_HIDRAW)
+               hidraw_report_event(hid, data, size);
 
        for (a = 0; a < report->maxfield; a++)
                hid_input_field(hid, report->field[a], cdata, interrupt);
@@ -1296,6 +1291,7 @@ static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
        { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
@@ -1357,6 +1353,7 @@ static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
index cd4ece6fdfb967b8fe89227742dd49e13b09df67..56f314fbd4f9e337027fe9f890171fa026e2ece2 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/poll.h>
 
@@ -564,10 +565,10 @@ void hid_debug_event(struct hid_device *hdev, char *buf)
        struct hid_debug_list *list;
 
        list_for_each_entry(list, &hdev->debug_list, node) {
-               for (i = 0; i <= strlen(buf); i++)
-                       list->hid_debug_buf[(list->tail + i) % (HID_DEBUG_BUFSIZE - 1)] =
+               for (i = 0; i < strlen(buf); i++)
+                       list->hid_debug_buf[(list->tail + i) % HID_DEBUG_BUFSIZE] =
                                buf[i];
-               list->tail = (list->tail + i) % (HID_DEBUG_BUFSIZE - 1);
+               list->tail = (list->tail + i) % HID_DEBUG_BUFSIZE;
         }
 }
 EXPORT_SYMBOL_GPL(hid_debug_event);
index a239d20ad7a5f1e08d84500f9b02d821fa604ab3..968b04f9b796cf8208c5839fb8c1f61fbc7467ee 100644 (file)
@@ -28,6 +28,7 @@
  */
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
 
index 8a11ccddaf2e4b2b1382ee809db43cc55c82336c..88dfcf49a5d72b0f2e61d9e07557c1a2e6a8cd55 100644 (file)
@@ -28,6 +28,7 @@
  */
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
 #include "hid-ids.h"
index cab13e8c7d292c7ed93a06b8a58acc6072d50fd3..62416e6baecaf7611e9d536e64ac84e5d98bbad9 100644 (file)
@@ -53,10 +53,13 @@ static int gyration_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 static int gyration_event(struct hid_device *hdev, struct hid_field *field,
                struct hid_usage *usage, __s32 value)
 {
-       struct input_dev *input = field->hidinput->input;
+
+       if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput)
+               return 0;
 
        if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK &&
                        (usage->hid & 0xff) == 0x82) {
+               struct input_dev *input = field->hidinput->input;
                input_event(input, usage->type, usage->code, 1);
                input_sync(input);
                input_event(input, usage->type, usage->code, 0);
index 72c05f90553c7ec84351a34acf2ff6fc3ca10dbc..09d27649a0f7212e7948b0a2c6afdcad199001a1 100644 (file)
 
 #define USB_VENDOR_ID_CHERRY           0x046a
 #define USB_DEVICE_ID_CHERRY_CYMOTION  0x0023
+#define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR    0x0027
 
 #define USB_VENDOR_ID_CHIC             0x05fe
 #define USB_DEVICE_ID_CHIC_GAMEPAD     0x0014
 
 #define USB_VENDOR_ID_UCLOGIC          0x5543
 #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209    0x0042
+#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U   0x0003
 
 #define USB_VENDOR_ID_VERNIER          0x08f7
 #define USB_DEVICE_ID_VERNIER_LABPRO   0x0001
index 4e6dc6e26523a22a8d109d4d71fe68d89628641b..d888f1e6794f5a48e4ddebf053d40c0826f8af9c 100644 (file)
@@ -22,6 +22,7 @@
 
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
 
index 4a3a94f2b10c93ca809b03c2d68c7a245dd7bfa1..0d471fc2ab82b9f1f2f4b5d35fb7456526dda763 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "hid-ids.h"
@@ -353,7 +354,7 @@ static int magicmouse_probe(struct hid_device *hdev,
                goto err_free;
        }
 
-       ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+       ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT);
        if (ret) {
                dev_err(&hdev->dev, "magicmouse hw start failed\n");
                goto err_free;
@@ -409,8 +410,11 @@ err_free:
 
 static void magicmouse_remove(struct hid_device *hdev)
 {
+       struct magicmouse_sc *msc = hid_get_drvdata(hdev);
+
        hid_hw_stop(hdev);
-       kfree(hid_get_drvdata(hdev));
+       input_unregister_device(msc->input);
+       kfree(msc);
 }
 
 static const struct hid_device_id magic_mice[] = {
index c8718168fe426446bfdc4175f746cf5452ed4fa6..e91437c189061cf7c862a74b3b6054f369528af7 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include "usbhid/usbhid.h"
 
index 3234c729a895f1cf733e59149c07eb5e83fac1b6..4777bbfa1cc2d85c7c0a5fff21586566a59ef4b5 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *  HID driver for N-Trig touchscreens
  *
- *  Copyright (c) 2008 Rafi Rubin
- *  Copyright (c) 2009 Stephane Chatty
+ *  Copyright (c) 2008-2010 Rafi Rubin
+ *  Copyright (c) 2009-2010 Stephane Chatty
  *
  */
 
 
 #include <linux/device.h>
 #include <linux/hid.h>
+#include <linux/usb.h>
+#include "usbhid/usbhid.h"
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "hid-ids.h"
 
 #define NTRIG_DUPLICATE_USAGES 0x001
 
-#define nt_map_key_clear(c)    hid_map_usage_clear(hi, usage, bit, max, \
-                                       EV_KEY, (c))
-
 struct ntrig_data {
        /* Incoming raw values for a single contact */
        __u16 x, y, w, h;
        __u16 id;
-       __u8 confidence;
+
+       bool tipswitch;
+       bool confidence;
+       bool first_contact_touch;
 
        bool reading_mt;
-       __u8 first_contact_confidence;
 
        __u8 mt_footer[4];
        __u8 mt_foot_count;
@@ -138,8 +140,12 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
                case 0xff000001:
                        /* Tag indicating the start of a multitouch group */
                        nd->reading_mt = 1;
-                       nd->first_contact_confidence = 0;
+                       nd->first_contact_touch = 0;
                        break;
+               case HID_DG_TIPSWITCH:
+                       nd->tipswitch = value;
+                       /* Prevent emission of touch until validated */
+                       return 1;
                case HID_DG_CONFIDENCE:
                        nd->confidence = value;
                        break;
@@ -165,8 +171,14 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
                         * to emit a normal (X, Y) position
                         */
                        if (!nd->reading_mt) {
+                               /*
+                                * TipSwitch indicates the presence of a
+                                * finger in single touch mode.
+                                */
+                               input_report_key(input, BTN_TOUCH,
+                                                nd->tipswitch);
                                input_report_key(input, BTN_TOOL_DOUBLETAP,
-                                                (nd->confidence != 0));
+                                                nd->tipswitch);
                                input_event(input, EV_ABS, ABS_X, nd->x);
                                input_event(input, EV_ABS, ABS_Y, nd->y);
                        }
@@ -205,7 +217,13 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
 
                        /* emit a normal (X, Y) for the first point only */
                        if (nd->id == 0) {
-                               nd->first_contact_confidence = nd->confidence;
+                               /*
+                                * TipSwitch is superfluous in multitouch
+                                * mode.  The footer events tell us
+                                * if there is a finger on the screen or
+                                * not.
+                                */
+                               nd->first_contact_touch = nd->confidence;
                                input_event(input, EV_ABS, ABS_X, nd->x);
                                input_event(input, EV_ABS, ABS_Y, nd->y);
                        }
@@ -235,30 +253,12 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
 
                        nd->reading_mt = 0;
 
-                       if (nd->first_contact_confidence) {
-                               switch (value) {
-                               case 0: /* for single touch devices */
-                               case 1:
-                                       input_report_key(input,
-                                                       BTN_TOOL_DOUBLETAP, 1);
-                                       break;
-                               case 2:
-                                       input_report_key(input,
-                                                       BTN_TOOL_TRIPLETAP, 1);
-                                       break;
-                               case 3:
-                               default:
-                                       input_report_key(input,
-                                                       BTN_TOOL_QUADTAP, 1);
-                               }
+                       if (nd->first_contact_touch) {
+                               input_report_key(input, BTN_TOOL_DOUBLETAP, 1);
                                input_report_key(input, BTN_TOUCH, 1);
                        } else {
-                               input_report_key(input,
-                                               BTN_TOOL_DOUBLETAP, 0);
-                               input_report_key(input,
-                                               BTN_TOOL_TRIPLETAP, 0);
-                               input_report_key(input,
-                                               BTN_TOOL_QUADTAP, 0);
+                               input_report_key(input, BTN_TOOL_DOUBLETAP, 0);
+                               input_report_key(input, BTN_TOUCH, 0);
                        }
                        break;
 
@@ -281,6 +281,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
        struct ntrig_data *nd;
        struct hid_input *hidinput;
        struct input_dev *input;
+       struct hid_report *report;
 
        if (id->driver_data)
                hdev->quirks |= HID_QUIRK_MULTI_INPUT;
@@ -308,20 +309,21 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
 
 
        list_for_each_entry(hidinput, &hdev->inputs, list) {
+               if (hidinput->report->maxfield < 1)
+                       continue;
+
                input = hidinput->input;
                switch (hidinput->report->field[0]->application) {
                case HID_DG_PEN:
                        input->name = "N-Trig Pen";
                        break;
                case HID_DG_TOUCHSCREEN:
+                       /* These keys are redundant for fingers, clear them
+                        * to prevent incorrect identification */
                        __clear_bit(BTN_TOOL_PEN, input->keybit);
-                       /*
-                        * A little something special to enable
-                        * two and three finger taps.
-                        */
+                       __clear_bit(BTN_TOOL_FINGER, input->keybit);
+                       __clear_bit(BTN_0, input->keybit);
                        __set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
-                       __set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
-                       __set_bit(BTN_TOOL_QUADTAP, input->keybit);
                        /*
                         * The physical touchscreen (single touch)
                         * input has a value for physical, whereas
@@ -337,6 +339,12 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
                }
        }
 
+       /* This is needed for devices with more recent firmware versions */
+       report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a];
+       if (report)
+               usbhid_submit_report(hdev, report, USB_DIR_OUT);
+
+
        return 0;
 err_free:
        kfree(nd);
index c6d7dbc935b18b2f7445f948f2a6f5f0f0132fab..9f41e2bd84839ed085ec15cc1c88fe6266371393 100644 (file)
@@ -39,6 +39,7 @@
 #define debug(format, arg...) pr_debug("hid-plff: " format "\n" , ## arg)
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
 
index 01dd51c4986cb42bc7aa77483f5272dd219bb0fb..54d3db50605b25e3beeecbccc9c0f96facc5e6dc 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
 MODULE_DESCRIPTION("Quanta dual-touch panel");
index 203c438b016f38bd099df7f675a839438118f881..e10a7687ebf2848e15210bf7466356a060765054 100644 (file)
@@ -27,6 +27,7 @@
 /* #define DEBUG */
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
 #include "hid-ids.h"
index 9bf00d77d92b8f7201b910fe39ab374ba1015ae0..402d5574b5747a6e39b2b6c3bc3f1ec29e35a9f9 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "hid-ids.h"
@@ -75,7 +76,7 @@ static int sony_set_operational_usb(struct hid_device *hdev)
 
 static int sony_set_operational_bt(struct hid_device *hdev)
 {
-       unsigned char buf[] = { 0x53, 0xf4,  0x42, 0x03, 0x00, 0x00 };
+       unsigned char buf[] = { 0xf4,  0x42, 0x03, 0x00, 0x00 };
        return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
 }
 
index 2e592a06654e4061e808e406125254c2f26cf64b..90df886c5e048023f6839f8fcea1c62f00e6004f 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
 MODULE_DESCRIPTION("Stantum HID multitouch panels");
index 167ea746fb9c3e5d5faa7f5cbae033baa77bfad8..15434c814793409bd7d00a2e0a4ee20ea8302456 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <linux/hid.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "hid-ids.h"
@@ -251,6 +252,8 @@ static const struct hid_device_id tm_devices[] = {
                .driver_data = (unsigned long)ff_rumble },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651),   /* FGT Rumble Force Wheel */
                .driver_data = (unsigned long)ff_rumble },
+       { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653),   /* RGT Force Feedback CLUTCH Raging Wheel */
+               .driver_data = (unsigned long)ff_joystick },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654),   /* FGT Force Feedback Wheel */
                .driver_data = (unsigned long)ff_joystick },
        { }
index 8d3b46f5d14956ea4bf60bde0f067cf8bed22105..f947d8337e212ce8bff976996496e974912b59d1 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "hid-ids.h"
 
@@ -276,7 +277,6 @@ static int __init wacom_init(void)
        ret = hid_register_driver(&wacom_driver);
        if (ret)
                printk(KERN_ERR "can't register wacom driver\n");
-       printk(KERN_ERR "wacom driver registered\n");
        return ret;
 }
 
index a79f0d78c6be23944e70b3d0f35f23f069ea1980..b7acceabba803fe8af9bba278872ed406ab6bff8 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/hid.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "hid-ids.h"
index d04476700b7b4eb792e41d381a61b535e0666f8f..6eadf1a9b3cca9b31e80fb231a85a56ec0393c45 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/poll.h>
 #include <linux/device.h>
 #include <linux/major.h>
+#include <linux/slab.h>
 #include <linux/hid.h>
 #include <linux/mutex.h>
 #include <linux/sched.h>
index 56d06cd8075b32f9cc6faec1f1909925f3f79c43..7b85b696fdabc372295d49234a14245ca14ba41f 100644 (file)
@@ -999,13 +999,6 @@ static int usbhid_start(struct hid_device *hid)
                }
        }
 
-       init_waitqueue_head(&usbhid->wait);
-       INIT_WORK(&usbhid->reset_work, hid_reset);
-       INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
-       setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
-
-       spin_lock_init(&usbhid->lock);
-
        usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
        if (!usbhid->urbctrl) {
                ret = -ENOMEM;
@@ -1179,6 +1172,12 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
        usbhid->intf = intf;
        usbhid->ifnum = interface->desc.bInterfaceNumber;
 
+       init_waitqueue_head(&usbhid->wait);
+       INIT_WORK(&usbhid->reset_work, hid_reset);
+       INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
+       setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
+       spin_lock_init(&usbhid->lock);
+
        ret = hid_add_device(hid);
        if (ret) {
                if (ret != -ENODEV)
index e565dbe91d97f6ac2d7d44f4ac72d2f166791712..ef381d79cfa81e969b14fcb3fd62cabde2dbb272 100644 (file)
@@ -25,6 +25,7 @@
 #define debug(format, arg...) pr_debug("hid-pidff: " format "\n" , ## arg)
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include <linux/hid.h>
index 7844280897d1940c1a02ac37b95305ad7ad49d39..1152f9b5fd444c13492de3ae976ef644fb36c9f7 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/hid.h>
+#include <linux/slab.h>
 
 #include "../hid-ids.h"
 
@@ -60,9 +61,11 @@ static const struct hid_blacklist {
        { 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_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET },
+       { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT },
+       { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
        { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
 
index e4595e6147b420de2a4545d45e498d5d5e886ba4..9be8e1754a0bafdc850e7af7ff0932e8b05e509b 100644 (file)
@@ -217,8 +217,8 @@ config SENSORS_ASC7621
        depends on HWMON && I2C
        help
          If you say yes here you get support for the aSC7621
-         family of SMBus sensors chip found on most Intel X48, X38, 975,
-         965 and 945 desktop boards.  Currently supported chips:
+         family of SMBus sensors chip found on most Intel X38, X48, X58,
+         945, 965 and 975 desktop boards.  Currently supported chips:
          aSC7621
          aSC7621a
 
index bfda8c80ef2473923a1ff1e38db845252b0bb16b..1e4c21fc1a890b38894e26f0b0713fef1bb0fd63 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 
 
 /* AD7414 registers */
index f97b5b356875b77857c0b69ce77d94b33a608ba7..ffc781fec18518f34c7b622ed6a384f440a64643 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "lm75.h"
 
index 74d9c5195e446ce59242be8f7b1ccb474a151dfd..fbdc7655303b71b49027828f8e125e8c6d606b5a 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/sysfs.h>
index 3471884e42d23c87724c31259498bae438ec6fe8..4086c7257f912f23608c261f1b29f68b3c04a602 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/i2c.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/slab.h>
 
 #define ADT7411_REG_INT_TEMP_VDD_LSB           0x03
 #define ADT7411_REG_EXT_TEMP_AIN14_LSB         0x04
index b8156b4893bb51f107b83da463a5906f01641553..2af0c7b6b4e4cd5a30adb5c202187913c340d95e 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/mutex.h>
 #include <linux/delay.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END };
index 3445ce1cba81e730d2bc6c4a664587be6e644517..9e775717abb7f36ab8c7aaf8103de53264e95951 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/delay.h>
 #include <linux/log2.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END };
index c1605b528e8fcccfe26241efc96c138505f67839..f085c18d2905a602d465ef01a8d08b2a29467c28 100644 (file)
@@ -142,6 +142,12 @@ static const char *temperature_sensors_sets[][41] = {
          "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", "TM9S",
          "TN0C", "TN0D", "TN0H", "TS0C", "Tp0C", "Tp1C", "Tv0S", "Tv1S",
          NULL },
+/* Set 17: iMac 9,1 */
+       { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TH0P", "TL0P",
+         "TN0D", "TN0H", "TN0P", "TO0P", "Tm0P", "Tp0P", NULL },
+/* Set 18: MacBook Pro 2,2 */
+       { "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "TM0P", "TTF0",
+         "Th0H", "Th1H", "Tm0P", "Ts0P", NULL },
 };
 
 /* List of keys used to read/write fan speeds */
@@ -189,6 +195,9 @@ static unsigned int applesmc_accelerometer;
 /* Indicates whether this computer has light sensors and keyboard backlight. */
 static unsigned int applesmc_light;
 
+/* The number of fans handled by the driver */
+static unsigned int fans_handled;
+
 /* Indicates which temperature sensors set to use. */
 static unsigned int applesmc_temperature_set;
 
@@ -1350,6 +1359,10 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = {
        { .accelerometer = 1, .light = 1, .temperature_set = 15 },
 /* MacPro3,1: temperature set 16 */
        { .accelerometer = 0, .light = 0, .temperature_set = 16 },
+/* iMac 9,1: light sensor only, temperature set 17 */
+       { .accelerometer = 0, .light = 0, .temperature_set = 17 },
+/* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */
+       { .accelerometer = 1, .light = 1, .temperature_set = 18 },
 };
 
 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
@@ -1375,6 +1388,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = {
          DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
          DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
                &applesmc_dmi_data[9]},
+       { applesmc_dmi_match, "Apple MacBook Pro 2,2", {
+         DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."),
+         DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") },
+               &applesmc_dmi_data[18]},
        { applesmc_dmi_match, "Apple MacBook Pro", {
          DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
          DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
@@ -1415,6 +1432,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = {
          DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
          DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
                &applesmc_dmi_data[4]},
+       { applesmc_dmi_match, "Apple iMac 9,1", {
+         DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
+         DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") },
+               &applesmc_dmi_data[17]},
        { applesmc_dmi_match, "Apple iMac 8", {
          DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
          DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
@@ -1474,39 +1495,24 @@ static int __init applesmc_init(void)
 
        /* create fan files */
        count = applesmc_get_fan_count();
-       if (count < 0) {
+       if (count < 0)
                printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
-       } else {
+       else
                printk(KERN_INFO "applesmc: %d fans found.\n", count);
 
-               switch (count) {
-               default:
-                       printk(KERN_WARNING "applesmc: More than 4 fans found,"
-                                       " but at most 4 fans are supported"
-                                               " by the driver.\n");
-               case 4:
-                       ret = sysfs_create_group(&pdev->dev.kobj,
-                                                &fan_attribute_groups[3]);
-                       if (ret)
-                               goto out_key_enumeration;
-               case 3:
-                       ret = sysfs_create_group(&pdev->dev.kobj,
-                                                &fan_attribute_groups[2]);
-                       if (ret)
-                               goto out_key_enumeration;
-               case 2:
-                       ret = sysfs_create_group(&pdev->dev.kobj,
-                                                &fan_attribute_groups[1]);
-                       if (ret)
-                               goto out_key_enumeration;
-               case 1:
-                       ret = sysfs_create_group(&pdev->dev.kobj,
-                                                &fan_attribute_groups[0]);
-                       if (ret)
-                               goto out_fan_1;
-               case 0:
-                       ;
-               }
+       if (count > 4) {
+               count = 4;
+               printk(KERN_WARNING "applesmc: More than 4 fans found,"
+                      " but at most 4 fans are supported"
+                      " by the driver.\n");
+       }
+
+       while (fans_handled < count) {
+               ret = sysfs_create_group(&pdev->dev.kobj,
+                                        &fan_attribute_groups[fans_handled]);
+               if (ret)
+                       goto out_fans;
+               fans_handled++;
        }
 
        for (i = 0;
@@ -1575,10 +1581,10 @@ out_accelerometer:
                applesmc_release_accelerometer();
 out_temperature:
        sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
-       sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
-out_fan_1:
-       sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
-out_key_enumeration:
+out_fans:
+       while (fans_handled)
+               sysfs_remove_group(&pdev->dev.kobj,
+                                  &fan_attribute_groups[--fans_handled]);
        sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
 out_name:
        sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
@@ -1604,8 +1610,9 @@ static void __exit applesmc_exit(void)
        if (applesmc_accelerometer)
                applesmc_release_accelerometer();
        sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
-       sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
-       sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
+       while (fans_handled)
+               sysfs_remove_group(&pdev->dev.kobj,
+                                  &fan_attribute_groups[--fans_handled]);
        sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
        sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
        platform_device_unregister(pdev);
index 7f948105d8addb79af23d7ec3e6c89b338cab79d..0f388adc61876cc3f0481de786289d724b1977a6 100644 (file)
@@ -268,8 +268,11 @@ static ssize_t store_fan16(struct device *dev,
        if (strict_strtol(buf, 10, &reqval))
                return -EINVAL;
 
+       /* If a minimum RPM of zero is requested, then we set the register to
+          0xffff. This value allows the fan to be stopped completely without
+          generating an alarm. */
        reqval =
-           (SENSORS_LIMIT((reqval) <= 0 ? 0 : 5400000 / (reqval), 0, 65534));
+           (reqval <= 0 ? 0xffff : SENSORS_LIMIT(5400000 / reqval, 0, 0xfffe));
 
        mutex_lock(&data->update_lock);
        data->reg[param->msb[0]] = (reqval >> 8) & 0xff;
@@ -285,8 +288,9 @@ static ssize_t store_fan16(struct device *dev,
  * Voltages are scaled in the device so that the nominal voltage
  * is 3/4ths of the 0-255 range (i.e. 192).
  * If all voltages are 'normal' then all voltage registers will
- * read 0xC0.  This doesn't help us if we don't have a point of refernce.
- * The data sheet however provides us with the full scale value for each
+ * read 0xC0.
+ *
+ * The data sheet provides us with the 3/4 scale value for each voltage
  * which is stored in in_scaling.  The sda->index parameter value provides
  * the index into in_scaling.
  *
@@ -295,7 +299,7 @@ static ssize_t store_fan16(struct device *dev,
  */
 
 static int asc7621_in_scaling[] = {
-       3320, 3000, 4380, 6640, 16000
+       2500, 2250, 3300, 5000, 12000
 };
 
 static ssize_t show_in10(struct device *dev, struct device_attribute *attr,
@@ -306,19 +310,12 @@ static ssize_t show_in10(struct device *dev, struct device_attribute *attr,
        u8 nr = sda->index;
 
        mutex_lock(&data->update_lock);
-       regval = (data->reg[param->msb[0]] * asc7621_in_scaling[nr]) / 256;
-
-       /* The LSB value is a 2-bit scaling of the MSB's LSbit value.
-        * I.E.  If the maximim voltage for this input is 6640 millivolts then
-        * a MSB register value of 0 = 0mv and 255 = 6640mv.
-        * A 1 step change therefore represents 25.9mv (6640 / 256).
-        * The extra 2-bits therefore represent increments of 6.48mv.
-        */
-       regval += ((asc7621_in_scaling[nr] / 256) / 4) *
-           (data->reg[param->lsb[0]] >> 6);
-
+       regval = (data->reg[param->msb[0]] << 8) | (data->reg[param->lsb[0]]);
        mutex_unlock(&data->update_lock);
 
+       /* The LSB value is a 2-bit scaling of the MSB's LSbit value. */
+       regval = (regval >> 6) * asc7621_in_scaling[nr] / (0xc0 << 2);
+
        return sprintf(buf, "%u\n", regval);
 }
 
@@ -331,7 +328,7 @@ static ssize_t show_in8(struct device *dev, struct device_attribute *attr,
 
        return sprintf(buf, "%u\n",
                       ((data->reg[param->msb[0]] *
-                        asc7621_in_scaling[nr]) / 256));
+                        asc7621_in_scaling[nr]) / 0xc0));
 }
 
 static ssize_t store_in8(struct device *dev, struct device_attribute *attr,
@@ -344,9 +341,11 @@ static ssize_t store_in8(struct device *dev, struct device_attribute *attr,
        if (strict_strtol(buf, 10, &reqval))
                return -EINVAL;
 
-       reqval = SENSORS_LIMIT(reqval, 0, asc7621_in_scaling[nr]);
+       reqval = SENSORS_LIMIT(reqval, 0, 0xffff);
+
+       reqval = reqval * 0xc0 / asc7621_in_scaling[nr];
 
-       reqval = (reqval * 255 + 128) / asc7621_in_scaling[nr];
+       reqval = SENSORS_LIMIT(reqval, 0, 0xff);
 
        mutex_lock(&data->update_lock);
        data->reg[param->msb[0]] = reqval;
@@ -846,11 +845,11 @@ static struct asc7621_param asc7621_params[] = {
        PWRITE(in3_max, 3, PRI_LOW, 0x4b, 0, 0, 0, in8),
        PWRITE(in4_max, 4, PRI_LOW, 0x4d, 0, 0, 0, in8),
 
-       PREAD(in0_alarm, 0, PRI_LOW, 0x41, 0, 0x01, 0, bitmask),
-       PREAD(in1_alarm, 1, PRI_LOW, 0x41, 0, 0x01, 1, bitmask),
-       PREAD(in2_alarm, 2, PRI_LOW, 0x41, 0, 0x01, 2, bitmask),
-       PREAD(in3_alarm, 3, PRI_LOW, 0x41, 0, 0x01, 3, bitmask),
-       PREAD(in4_alarm, 4, PRI_LOW, 0x42, 0, 0x01, 0, bitmask),
+       PREAD(in0_alarm, 0, PRI_HIGH, 0x41, 0, 0x01, 0, bitmask),
+       PREAD(in1_alarm, 1, PRI_HIGH, 0x41, 0, 0x01, 1, bitmask),
+       PREAD(in2_alarm, 2, PRI_HIGH, 0x41, 0, 0x01, 2, bitmask),
+       PREAD(in3_alarm, 3, PRI_HIGH, 0x41, 0, 0x01, 3, bitmask),
+       PREAD(in4_alarm, 4, PRI_HIGH, 0x42, 0, 0x01, 0, bitmask),
 
        PREAD(fan1_input, 0, PRI_HIGH, 0x29, 0x28, 0, 0, fan16),
        PREAD(fan2_input, 1, PRI_HIGH, 0x2b, 0x2a, 0, 0, fan16),
@@ -862,10 +861,10 @@ static struct asc7621_param asc7621_params[] = {
        PWRITE(fan3_min, 2, PRI_LOW, 0x59, 0x58, 0, 0, fan16),
        PWRITE(fan4_min, 3, PRI_LOW, 0x5b, 0x5a, 0, 0, fan16),
 
-       PREAD(fan1_alarm, 0, PRI_LOW, 0x42, 0, 0x01, 0, bitmask),
-       PREAD(fan2_alarm, 1, PRI_LOW, 0x42, 0, 0x01, 1, bitmask),
-       PREAD(fan3_alarm, 2, PRI_LOW, 0x42, 0, 0x01, 2, bitmask),
-       PREAD(fan4_alarm, 3, PRI_LOW, 0x42, 0, 0x01, 3, bitmask),
+       PREAD(fan1_alarm, 0, PRI_HIGH, 0x42, 0, 0x01, 2, bitmask),
+       PREAD(fan2_alarm, 1, PRI_HIGH, 0x42, 0, 0x01, 3, bitmask),
+       PREAD(fan3_alarm, 2, PRI_HIGH, 0x42, 0, 0x01, 4, bitmask),
+       PREAD(fan4_alarm, 3, PRI_HIGH, 0x42, 0, 0x01, 5, bitmask),
 
        PREAD(temp1_input, 0, PRI_HIGH, 0x25, 0x10, 0, 0, temp10),
        PREAD(temp2_input, 1, PRI_HIGH, 0x26, 0x15, 0, 0, temp10),
@@ -886,10 +885,10 @@ static struct asc7621_param asc7621_params[] = {
        PWRITE(temp3_max, 2, PRI_LOW, 0x53, 0, 0, 0, temp8),
        PWRITE(temp4_max, 3, PRI_LOW, 0x35, 0, 0, 0, temp8),
 
-       PREAD(temp1_alarm, 0, PRI_LOW, 0x41, 0, 0x01, 4, bitmask),
-       PREAD(temp2_alarm, 1, PRI_LOW, 0x41, 0, 0x01, 5, bitmask),
-       PREAD(temp3_alarm, 2, PRI_LOW, 0x41, 0, 0x01, 6, bitmask),
-       PREAD(temp4_alarm, 3, PRI_LOW, 0x43, 0, 0x01, 0, bitmask),
+       PREAD(temp1_alarm, 0, PRI_HIGH, 0x41, 0, 0x01, 4, bitmask),
+       PREAD(temp2_alarm, 1, PRI_HIGH, 0x41, 0, 0x01, 5, bitmask),
+       PREAD(temp3_alarm, 2, PRI_HIGH, 0x41, 0, 0x01, 6, bitmask),
+       PREAD(temp4_alarm, 3, PRI_HIGH, 0x43, 0, 0x01, 0, bitmask),
 
        PWRITE(temp1_source, 0, PRI_LOW, 0x02, 0, 0x07, 4, bitmask),
        PWRITE(temp2_source, 1, PRI_LOW, 0x02, 0, 0x07, 0, bitmask),
@@ -898,7 +897,7 @@ static struct asc7621_param asc7621_params[] = {
 
        PWRITE(temp1_smoothing_enable, 0, PRI_LOW, 0x62, 0, 0x01, 3, bitmask),
        PWRITE(temp2_smoothing_enable, 1, PRI_LOW, 0x63, 0, 0x01, 7, bitmask),
-       PWRITE(temp3_smoothing_enable, 2, PRI_LOW, 0x64, 0, 0x01, 3, bitmask),
+       PWRITE(temp3_smoothing_enable, 2, PRI_LOW, 0x63, 0, 0x01, 3, bitmask),
        PWRITE(temp4_smoothing_enable, 3, PRI_LOW, 0x3c, 0, 0x01, 3, bitmask),
 
        PWRITE(temp1_smoothing_time, 0, PRI_LOW, 0x62, 0, 0x07, 0, temp_st),
index 028284f544e306780860e97b6e5363c94b92056d..16c420240724ee72ac96933fc0953f9a12c5e9c0 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/hwmon.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <acpi/acpi.h>
 #include <acpi/acpixf.h>
@@ -1168,15 +1169,19 @@ static int atk_create_files(struct atk_data *data)
        int err;
 
        list_for_each_entry(s, &data->sensor_list, list) {
+               sysfs_attr_init(&s->input_attr.attr);
                err = device_create_file(data->hwmon_dev, &s->input_attr);
                if (err)
                        return err;
+               sysfs_attr_init(&s->label_attr.attr);
                err = device_create_file(data->hwmon_dev, &s->label_attr);
                if (err)
                        return err;
+               sysfs_attr_init(&s->limit1_attr.attr);
                err = device_create_file(data->hwmon_dev, &s->limit1_attr);
                if (err)
                        return err;
+               sysfs_attr_init(&s->limit2_attr.attr);
                err = device_create_file(data->hwmon_dev, &s->limit2_attr);
                if (err)
                        return err;
index 94cadc19f0c54d36885f80a21530905b99ab5bca..33cc143b2069442c5ba80611904b4c394436af9e 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("System voltages control via Attansic ATXP1");
index 2d7bceeed0bc3daf10a8ae2d58d106d575107eb2..e9b7fbc5a4476b9cfdb2bd01ec58719b097cf7cb 100644 (file)
@@ -228,7 +228,7 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *
                if (err) {
                        dev_warn(dev,
                                 "Unable to access MSR 0xEE, for Tjmax, left"
-                                " at default");
+                                " at default\n");
                } else if (eax & 0x40000000) {
                        tjmax = tjmax_ee;
                }
@@ -466,7 +466,7 @@ static int __init coretemp_init(void)
                           family 6 CPU */
                        if ((c->x86 == 0x6) && (c->x86_model > 0xf))
                                printk(KERN_WARNING DRVNAME ": Unknown CPU "
-                                       "model %x\n", c->x86_model);
+                                       "model 0x%x\n", c->x86_model);
                        continue;
                }
 
index 277398f9c93826dddb5233d7d4765c0f515011cc..bad2cf3ef4a448aa76a72033b527647c6434f9d3 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/f75375s.h>
+#include <linux/slab.h>
 
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END };
index be475e844c2a73b146314bf3209f487c02110f59..7580f55e67e3cf1560437b428d9fb1e5b8e411d0 100644 (file)
@@ -217,6 +217,10 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
        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),
+       AXIS_DMI_MATCH("HPB432x", "HP ProBook 432", xy_rotated_left),
+       AXIS_DMI_MATCH("HPB442x", "HP ProBook 442", xy_rotated_left),
+       AXIS_DMI_MATCH("HPB452x", "HP ProBook 452", y_inverted),
+       AXIS_DMI_MATCH("HPB522x", "HP ProBook 522", xy_swap),
        { NULL, }
 /* Laptop models without axis info (yet):
  * "NC6910" "HP Compaq 6910"
@@ -324,8 +328,8 @@ static int lis3lv02d_remove(struct acpi_device *device, int type)
        lis3lv02d_joystick_disable();
        lis3lv02d_poweroff(&lis3_dev);
 
-       flush_work(&hpled_led.work);
        led_classdev_unregister(&hpled_led.led_classdev);
+       flush_work(&hpled_led.work);
 
        return lis3lv02d_remove_fs(&lis3_dev);
 }
index 27d7f72a5f11a254ae5c2a9a6e35578683e594a7..e880e2c3871d0e2098913c7b130c3a35de7e4f65 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/log2.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #define DRVNAME "i5k_amb"
 
index 405d3fb5d76f9e90aa9115b56eb4676c4e1b03bb..eaee546af19a1c519758783ee66217a1d8bae46d 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/kdev_t.h>
 #include <linux/spinlock.h>
 #include <linux/idr.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/platform_device.h>
 #include <linux/math64.h>
index a36363312f2ff5116ef5557ae19fe7176455b68a..06d4eafcf76b231fdc74e0418341e496387b78d9 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/jiffies.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #define REFRESH_INTERVAL       (2 * HZ)
 #define DRVNAME                        "ibmpex"
index 1002befd87d5c63268e8d2a4fb7f0513e52657d0..5be09c048c5f35bc8b19914b58a20e3b4c3e32d5 100644 (file)
@@ -539,14 +539,14 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
 
        struct it87_data *data = dev_get_drvdata(dev);
        long val;
+       u8 reg;
 
        if (strict_strtol(buf, 10, &val) < 0)
                return -EINVAL;
 
-       mutex_lock(&data->update_lock);
-
-       data->sensor &= ~(1 << nr);
-       data->sensor &= ~(8 << nr);
+       reg = it87_read_value(data, IT87_REG_TEMP_ENABLE);
+       reg &= ~(1 << nr);
+       reg &= ~(8 << nr);
        if (val == 2) { /* backwards compatibility */
                dev_warn(dev, "Sensor type 2 is deprecated, please use 4 "
                         "instead\n");
@@ -554,14 +554,16 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
        }
        /* 3 = thermal diode; 4 = thermistor; 0 = disabled */
        if (val == 3)
-               data->sensor |= 1 << nr;
+               reg |= 1 << nr;
        else if (val == 4)
-               data->sensor |= 8 << nr;
-       else if (val != 0) {
-               mutex_unlock(&data->update_lock);
+               reg |= 8 << nr;
+       else if (val != 0)
                return -EINVAL;
-       }
+
+       mutex_lock(&data->update_lock);
+       data->sensor = reg;
        it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor);
+       data->valid = 0;        /* Force cache refresh */
        mutex_unlock(&data->update_lock);
        return count;
 }
@@ -1841,14 +1843,10 @@ static void __devinit it87_init_device(struct platform_device *pdev)
                        it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127);
        }
 
-       /* Check if temperature channels are reset manually or by some reason */
-       tmp = it87_read_value(data, IT87_REG_TEMP_ENABLE);
-       if ((tmp & 0x3f) == 0) {
-               /* Temp1,Temp3=thermistor; Temp2=thermal diode */
-               tmp = (tmp & 0xc0) | 0x2a;
-               it87_write_value(data, IT87_REG_TEMP_ENABLE, tmp);
-       }
-       data->sensor = tmp;
+       /* Temperature channels are not forcibly enabled, as they can be
+        * set to two different sensor types and we can't guess which one
+        * is correct for a given system. These channels can be enabled at
+        * run-time through the temp{1-3}_type sysfs accessors if needed. */
 
        /* Check if voltage monitors are reset manually or by some reason */
        tmp = it87_read_value(data, IT87_REG_VIN_ENABLE);
index ab8a5d3c769048a1a15635c09648740bad64e9ef..fd108cfc05c7c8cad39b960b484e377ded238b5a 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/mutex.h>
 #include <linux/mod_devicetable.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 
 
 #define DRVNAME                "lm70"
index c5f39ba103c0341d5a0207ec805d0b38c9f689e5..4d1b76bc81486b64dc6963d8ee415c2608c0fb82 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
index 9ac497271adfa06e160de4811fc8450b0ecf153b..12a54aa297760b1c6913a3fe772ab3dc7cb0c3ee 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 
 #define MAX1111_TX_BUF_SIZE    1
 #define MAX1111_RX_BUF_SIZE    2
index 883fa8197da42845086fb180e9196afb7e825e0e..ce3c7bc81814e3d5198d3d703824b288336c8909 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/hwmon.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/err.h>
 
index 864a371f6eb98443f0565b1d1263cb66a370e152..a610e7880fb3e5498b5d836d456ec4e25c58e278 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/err.h>
 #include <linux/sht15.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 #include <asm/atomic.h>
 
 #define SHT15_MEASURE_TEMP     3
@@ -302,13 +303,13 @@ error_ret:
  **/
 static inline int sht15_calc_temp(struct sht15_data *data)
 {
-       int d1 = 0;
+       int d1 = temppoints[0].d1;
        int i;
 
-       for (i = 1; i < ARRAY_SIZE(temppoints); i++)
+       for (i = ARRAY_SIZE(temppoints) - 1; i > 0; i--)
                /* Find pointer to interpolate */
                if (data->supply_uV > temppoints[i - 1].vdd) {
-                       d1 = (data->supply_uV/1000 - temppoints[i - 1].vdd)
+                       d1 = (data->supply_uV - temppoints[i - 1].vdd)
                                * (temppoints[i].d1 - temppoints[i - 1].d1)
                                / (temppoints[i].vdd - temppoints[i - 1].vdd)
                                + temppoints[i - 1].d1;
@@ -541,7 +542,12 @@ static int __devinit sht15_probe(struct platform_device *pdev)
 /* If a regulator is available, query what the supply voltage actually is!*/
        data->reg = regulator_get(data->dev, "vcc");
        if (!IS_ERR(data->reg)) {
-               data->supply_uV = regulator_get_voltage(data->reg);
+               int voltage;
+
+               voltage = regulator_get_voltage(data->reg);
+               if (voltage)
+                       data->supply_uV = voltage;
+
                regulator_enable(data->reg);
                /* setup a notifier block to update this if another device
                 *  causes the voltage to change */
index 9de81a4c15a2127b774766bda5244bf519d750cf..612807d9715533b3f03afcdf6738fb79767ee55e 100644 (file)
@@ -1294,7 +1294,7 @@ static int watchdog_close(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;
+       ssize_t ret;
        struct w83793_data *data = filp->private_data;
 
        if (count) {
index c16e9e74c356df56fa681104415fda5591446100..97b1f834a4714b540fd95352271bb253ef130c9c 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/err.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/auxadc.h>
index e8d568c3fb09ac2c6aefadd8e84c3aadf775a955..a39e6cff86e7ad8d64b5b786e7b5452f9290a458 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
index 6b6bd06202b20fff3db405f077bd98aab2638260..5eebf562ff31b9094fffa7c0300003223382affe 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/i2c.h>
index d0dc970d7370a8f6116f7222cb605fbbf2ece88b..2fbef27b6cd60f6af5245e41fd42591b3d3f12ca 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/i2c.h>
 #include <linux/delay.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 MODULE_LICENSE("GPL");
index fe3fb567317d08939345fa10ec960cc43fa53335..f1e14dd590c977fdbb7e128cd0dfc5285f5379dd 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/mm.h>
 #include <linux/timer.h>
index c89687a10835538307212949317042f40042129c..4523364e67221d3930cb3fd5c6ceb65b7fab7d4e 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 
index 3e72b69aa7f8a39ac8dc752a45048935d33d78b5..b664ed8bbdb3883ce3fde9bfe4f9dafd79a966a1 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 /*
  * Registers offset
index 448b4bf35eb7f3cf9788c1638f5ecc0b11676d7f..612255614a66d763527c32cf6610a4fb016bb1b3 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
index 32104eac8d3db3d61e12907558262f1fe4ecffed..c21077d248af98f342a37219ecfa19b580e65c32 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/i2c-gpio.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 
 #include <asm/gpio.h>
index 87ecace415da39ac49449c25acdd3e377c3f5a8b..ce87a902c94dbaf1081a28fa7fb7c397e3043307 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/completion.h>
 #include <linux/io.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #define SMCR           0x00
 #define SMCR_START     (1 << 0)
index 32375bddae7df6aa4fca67d17a045c00b3c9f9de..d1ff9408dc1f2d68cdbe305c6777ba259eed64e4 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/sched.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #include <mach/irqs.h>
 #include <mach/hardware.h>
@@ -145,10 +146,10 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
                                "<%s> I2C Interrupted\n", __func__);
                        return -EINTR;
                }
-               if (time_after(jiffies, orig_jiffies + HZ / 1000)) {
+               if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
                        dev_dbg(&i2c_imx->adapter.dev,
                                "<%s> I2C bus is busy\n", __func__);
-                       return -EIO;
+                       return -ETIMEDOUT;
                }
                schedule();
        }
@@ -443,6 +444,8 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
                        result = i2c_imx_read(i2c_imx, &msgs[i]);
                else
                        result = i2c_imx_write(i2c_imx, &msgs[i]);
+               if (result)
+                       goto fail0;
        }
 
 fail0:
index c016f7a2c5fc2712433dbd83ec7d1c6dd1d48f3b..5d8aed5ec21bb85863743e4855d450403074cf64 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>     /* Pick up IXP2000-specific bits */
 #include <mach/gpio.h>
index 78a15af3294231f1d1403ab593dc704c27ef1f06..f1321f7637891d09846a1c1f988856c68845c81c 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/of_platform.h>
 #include <linux/of_i2c.h>
+#include <linux/slab.h>
 
 #include <linux/io.h>
 #include <linux/fsl_devices.h>
index ed387ffa47307b1a28b90f9646e4d8dd3b6262c9..3623a44990849987bc872480122bc1d987e2b004 100644 (file)
@@ -10,6 +10,7 @@
  * or implied.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/i2c.h>
index 4a700587ef18176cf5877ee1506cf248d100a00f..4a48dd4ef7870cb7d9789ee34d12f13ca6f5b3db 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/delay.h>
 #include <linux/dmi.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 MODULE_LICENSE("GPL");
index a15f731fa451577edb92c7cb0354c791af450bcd..a4f8d33fa389ac95eb2e79e7969428565d150e31 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/err.h>
index 0dabe643ec5116faa9140505c6cc464b03bbf8e0..b4ed4ca802ed97d9f829adcc60b850548582f50f 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/interrupt.h>
 #include <linux/wait.h>
 #include <linux/i2c-ocores.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 struct ocores_i2c {
index 60375504fa49b733a2f992ce2c7c34a27c56a217..0e9f85d0a835718dac97ecd52ff270f327d84136 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #include <linux/io.h>
@@ -446,7 +447,7 @@ static struct i2c_adapter octeon_i2c_ops = {
 /**
  * octeon_i2c_setclock - Calculate and set clock divisors.
  */
-static int __init octeon_i2c_setclock(struct octeon_i2c *i2c)
+static int __devinit octeon_i2c_setclock(struct octeon_i2c *i2c)
 {
        int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff;
        int thp = 0x18, mdiv = 2, ndiv = 0, delta_hz = 1000000;
@@ -489,7 +490,7 @@ static int __init octeon_i2c_setclock(struct octeon_i2c *i2c)
        return 0;
 }
 
-static int __init octeon_i2c_initlowlevel(struct octeon_i2c *i2c)
+static int __devinit octeon_i2c_initlowlevel(struct octeon_i2c *i2c)
 {
        u8 status;
        int tries;
index c7c237537f8147d8ff72cd8d7b5eee692cbb8fbe..389ac6032a7be615c3cf78ccf618b607c9ff2bff 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 /* I2C controller revisions */
 #define OMAP_I2C_REV_2                 0x20
@@ -902,6 +903,11 @@ omap_i2c_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, dev);
 
+       if (cpu_is_omap7xx())
+               dev->reg_shift = 1;
+       else
+               dev->reg_shift = 2;
+
        if ((r = omap_i2c_get_clocks(dev)) != 0)
                goto err_iounmap;
 
@@ -925,11 +931,6 @@ omap_i2c_probe(struct platform_device *pdev)
                dev->b_hw = 1; /* Enable hardware fixes */
        }
 
-       if (cpu_is_omap7xx())
-               dev->reg_shift = 1;
-       else
-               dev->reg_shift = 2;
-
        /* reset ASAP, clearing any IRQs */
        omap_i2c_init(dev);
 
index 220fca7f23a6751e2f591df26ffb4b22d841b6d8..846583ed476352168bd4bde779adb224cad08470 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
 #include <linux/i2c-smbus.h>
+#include <linux/slab.h>
 #include "i2c-parport.h"
 
 /* ----- Device list ------------------------------------------------------ */
index 0d20ff46a518b837533078dc73dc413aaae3fea8..d3d4a4b43a1d015527f565027b761291711d8f24 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/sched.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 static struct pci_driver pasemi_smb_driver;
index 9532dee6b580b8c088bffdf04fbdcd953512451a..a97e3fec814826c8676f60743025f0ba6988ca0c 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <mach/i2c.h>
@@ -172,6 +173,9 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
                /* We still have something to talk about... */
                val = *alg_data->mif.buf++;
 
+               if (alg_data->mif.len == 1)
+                       val |= stop_bit;
+
                alg_data->mif.len--;
                iowrite32(val, I2C_REG_TX(alg_data));
 
@@ -245,6 +249,9 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
                        __func__);
 
                if (alg_data->mif.len == 1) {
+                       /* Last byte, do not acknowledge next rcv. */
+                       val |= stop_bit;
+
                        /*
                         * Enable interrupt RFDAIE (data in Rx fifo),
                         * and disable DRMIE (need data for Tx)
@@ -632,6 +639,8 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev)
         */
 
        tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2;
+       if (tmp > 0x3FF)
+               tmp = 0x3FF;
        iowrite32(tmp, I2C_REG_CKH(alg_data));
        iowrite32(tmp, I2C_REG_CKL(alg_data));
 
index 90ffbf6f9d4f23149c5a68f70f5fa00f21fd93be..14d249f5ed3f3db236b6c8664df152fc583a5003 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 #include <asm/io.h>
index 1d8c98613fa057c88f75b4a7bd793348c60b8da8..d27072b2249ff5d3236c2ee1da0469e1d694616a 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/cpufreq.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 #include <asm/io.h>
index 365e0becaf121f7261cbc31ea2f19596415646d6..388cbdc96db7306280b5d4ab6fcc99871e77b7ca 100644 (file)
@@ -33,6 +33,7 @@ struct acpi_smbus_cmi {
        u8 cap_info:1;
        u8 cap_read:1;
        u8 cap_write:1;
+       struct smbus_methods_t *methods;
 };
 
 static const struct smbus_methods_t smbus_methods = {
@@ -41,10 +42,19 @@ static const struct smbus_methods_t smbus_methods = {
        .mt_sbw  = "_SBW",
 };
 
+/* Some IBM BIOSes omit the leading underscore */
+static const struct smbus_methods_t ibm_smbus_methods = {
+       .mt_info = "SBI_",
+       .mt_sbr  = "SBR_",
+       .mt_sbw  = "SBW_",
+};
+
 static const struct acpi_device_id acpi_smbus_cmi_ids[] = {
-       {"SMBUS01", 0},
+       {"SMBUS01", (kernel_ulong_t)&smbus_methods},
+       {ACPI_SMBUS_IBM_HID, (kernel_ulong_t)&ibm_smbus_methods},
        {"", 0}
 };
+MODULE_DEVICE_TABLE(acpi, acpi_smbus_cmi_ids);
 
 #define ACPI_SMBUS_STATUS_OK                   0x00
 #define ACPI_SMBUS_STATUS_FAIL                 0x07
@@ -150,11 +160,11 @@ acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,
 
        if (read_write == I2C_SMBUS_READ) {
                protocol |= ACPI_SMBUS_PRTCL_READ;
-               method = smbus_methods.mt_sbr;
+               method = smbus_cmi->methods->mt_sbr;
                input.count = 3;
        } else {
                protocol |= ACPI_SMBUS_PRTCL_WRITE;
-               method = smbus_methods.mt_sbw;
+               method = smbus_cmi->methods->mt_sbw;
                input.count = 5;
        }
 
@@ -290,13 +300,13 @@ static int acpi_smbus_cmi_add_cap(struct acpi_smbus_cmi *smbus_cmi,
        union acpi_object *obj;
        acpi_status status;
 
-       if (!strcmp(name, smbus_methods.mt_info)) {
+       if (!strcmp(name, smbus_cmi->methods->mt_info)) {
                status = acpi_evaluate_object(smbus_cmi->handle,
-                                       smbus_methods.mt_info,
+                                       smbus_cmi->methods->mt_info,
                                        NULL, &buffer);
                if (ACPI_FAILURE(status)) {
                        ACPI_ERROR((AE_INFO, "Evaluating %s: %i",
-                                  smbus_methods.mt_info, status));
+                                  smbus_cmi->methods->mt_info, status));
                        return -EIO;
                }
 
@@ -319,9 +329,9 @@ static int acpi_smbus_cmi_add_cap(struct acpi_smbus_cmi *smbus_cmi,
 
                kfree(buffer.pointer);
                smbus_cmi->cap_info = 1;
-       } else if (!strcmp(name, smbus_methods.mt_sbr))
+       } else if (!strcmp(name, smbus_cmi->methods->mt_sbr))
                smbus_cmi->cap_read = 1;
-       else if (!strcmp(name, smbus_methods.mt_sbw))
+       else if (!strcmp(name, smbus_cmi->methods->mt_sbw))
                smbus_cmi->cap_write = 1;
        else
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported CMI method: %s\n",
@@ -349,6 +359,7 @@ static acpi_status acpi_smbus_cmi_query_methods(acpi_handle handle, u32 level,
 static int acpi_smbus_cmi_add(struct acpi_device *device)
 {
        struct acpi_smbus_cmi *smbus_cmi;
+       const struct acpi_device_id *id;
 
        smbus_cmi = kzalloc(sizeof(struct acpi_smbus_cmi), GFP_KERNEL);
        if (!smbus_cmi)
@@ -362,6 +373,11 @@ static int acpi_smbus_cmi_add(struct acpi_device *device)
        smbus_cmi->cap_read = 0;
        smbus_cmi->cap_write = 0;
 
+       for (id = acpi_smbus_cmi_ids; id->id[0]; id++)
+               if (!strcmp(id->id, acpi_device_hid(device)))
+                       smbus_cmi->methods =
+                               (struct smbus_methods_t *) id->driver_data;
+
        acpi_walk_namespace(ACPI_TYPE_METHOD, smbus_cmi->handle, 1,
                            acpi_smbus_cmi_query_methods, NULL, smbus_cmi, NULL);
 
index ccc46418ef7f16b2409c28cdf7f7f8ebdb6796d4..ffb405d7c6f24caaf61a9837e66de0b4f417d490 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 /* Transmit operation:                                                      */
 /*                                                                          */
index 6407f47bda82db92b5ba2f2926851f774a938e91..78b06107342cde80bdb33c4b25ecdc97dfebb38e 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
index d2728a28a8dba926e563957ad6339db653a7c632..495be451d326c5b860648e94ccad189c9438c0b2 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 /* the name of this kernel module */
 #define NAME "stu300"
@@ -497,7 +498,7 @@ static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate)
        int i = 0;
 
        /* Locate the apropriate clock setting */
-       while (i < ARRAY_SIZE(stu300_clktable) &&
+       while (i < ARRAY_SIZE(stu300_clktable) - 1 &&
               stu300_clktable[i].rate < clkrate)
                i++;
 
index b5b1bbf37d3c5bafc2979860c8ce33d7a4aa69bf..d03b04002f0d3cc55cf25d2aab551a9595a116dc 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 /* include interfaces to usb layer */
index 70de821634631a3e5108221ec6d1753aab0d654f..5c473833d948e3a4e5428f0fb8fb33f2ad894dfc 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/i2c-algo-bit.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
index f0ef8da6c554556c0e1c35ef23b655398f49b912..a9c419e075a511589233147d1b229d0842933e4e 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/wait.h>
 #include <linux/i2c-xiic.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME "xiic-i2c"
 
index cf994bd01d9c2ef34cf0f964578d4c68db12e21a..684395b6f3e2dc5af4343074017f47c27ad9f564 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 #include <linux/scx200.h>
index a26a34a06641bde2cf2320d5e054ebbdbe493448..7e6a63b571650b1f100c4707309f31de1af415bb 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/kernel.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/rwsem.h>
 
 #include "i2c-core.h"
index 3202a86f420e9e5b6dac41aefcefd409b3a72ed2..c2258a51fe0ce3bb09055220c645602ab467c876 100644 (file)
 #include "i2c-core.h"
 
 
-/* core_lock protects i2c_adapter_idr, userspace_devices, and guarantees
+/* core_lock protects i2c_adapter_idr, and guarantees
    that device detection, deletion of detected devices, and attach_adapter
    and detach_adapter calls are serialized */
 static DEFINE_MUTEX(core_lock);
 static DEFINE_IDR(i2c_adapter_idr);
-static LIST_HEAD(userspace_devices);
 
 static struct device_type i2c_client_type;
 static int i2c_check_addr(struct i2c_adapter *adapter, int addr);
@@ -117,8 +116,10 @@ static int i2c_device_probe(struct device *dev)
        dev_dbg(dev, "probe\n");
 
        status = driver->probe(client, i2c_match_id(driver->id_table, client));
-       if (status)
+       if (status) {
                client->driver = NULL;
+               i2c_set_clientdata(client, NULL);
+       }
        return status;
 }
 
@@ -139,8 +140,10 @@ static int i2c_device_remove(struct device *dev)
                dev->driver = NULL;
                status = 0;
        }
-       if (status == 0)
+       if (status == 0) {
                client->driver = NULL;
+               i2c_set_clientdata(client, NULL);
+       }
        return status;
 }
 
@@ -538,9 +541,9 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
                return -EEXIST;
 
        /* Keep track of the added device */
-       mutex_lock(&core_lock);
-       list_add_tail(&client->detected, &userspace_devices);
-       mutex_unlock(&core_lock);
+       i2c_lock_adapter(adap);
+       list_add_tail(&client->detected, &adap->userspace_clients);
+       i2c_unlock_adapter(adap);
        dev_info(dev, "%s: Instantiated device %s at 0x%02hx\n", "new_device",
                 info.type, info.addr);
 
@@ -579,9 +582,10 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,
 
        /* Make sure the device was added through sysfs */
        res = -ENOENT;
-       mutex_lock(&core_lock);
-       list_for_each_entry_safe(client, next, &userspace_devices, detected) {
-               if (client->addr == addr && client->adapter == adap) {
+       i2c_lock_adapter(adap);
+       list_for_each_entry_safe(client, next, &adap->userspace_clients,
+                                detected) {
+               if (client->addr == addr) {
                        dev_info(dev, "%s: Deleting device %s at 0x%02hx\n",
                                 "delete_device", client->name, client->addr);
 
@@ -591,7 +595,7 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,
                        break;
                }
        }
-       mutex_unlock(&core_lock);
+       i2c_unlock_adapter(adap);
 
        if (res < 0)
                dev_err(dev, "%s: Can't find device in list\n",
@@ -673,6 +677,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
        }
 
        rt_mutex_init(&adap->bus_lock);
+       INIT_LIST_HEAD(&adap->userspace_clients);
 
        /* Set default timeout to 1 second if not already set */
        if (adap->timeout == 0)
@@ -875,14 +880,15 @@ int i2c_del_adapter(struct i2c_adapter *adap)
                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);
-               }
+       i2c_lock_adapter(adap);
+       list_for_each_entry_safe(client, next, &adap->userspace_clients,
+                                detected) {
+               dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name,
+                       client->addr);
+               list_del(&client->detected);
+               i2c_unregister_device(client);
        }
+       i2c_unlock_adapter(adap);
 
        /* Detach any active clients. This can't fail, thus we do not
           checking the returned value. */
@@ -1260,12 +1266,23 @@ static int i2c_detect_address(struct i2c_client *temp_client,
                return 0;
 
        /* Make sure there is something at this address */
-       if (i2c_smbus_xfer(adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) < 0)
-               return 0;
+       if (addr == 0x73 && (adapter->class & I2C_CLASS_HWMON)) {
+               /* Special probe for FSC hwmon chips */
+               union i2c_smbus_data dummy;
 
-       /* Prevent 24RF08 corruption */
-       if ((addr & ~0x0f) == 0x50)
-               i2c_smbus_xfer(adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL);
+               if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_READ, 0,
+                                  I2C_SMBUS_BYTE_DATA, &dummy) < 0)
+                       return 0;
+       } else {
+               if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0,
+                                  I2C_SMBUS_QUICK, NULL) < 0)
+                       return 0;
+
+               /* Prevent 24RF08 corruption */
+               if ((addr & ~0x0f) == 0x50)
+                       i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0,
+                                      I2C_SMBUS_QUICK, NULL);
+       }
 
        /* Finally call the custom detection function */
        memset(&info, 0, sizeof(struct i2c_board_info));
index 7a8201ed21816a0fe9df1e6ca0472b710c5ed289..a24e0bfe9201a87a7012b1f42791d925aaf5b76f 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/workqueue.h>
 #include <linux/i2c.h>
 #include <linux/i2c-smbus.h>
+#include <linux/slab.h>
 
 struct i2c_smbus_alert {
        unsigned int            alert_edge_triggered:1;
index b885c1d548f505f05048dadebd290e908c8aaeba..45163693f7374c2d47e3205ae816a976ee0951a6 100644 (file)
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ide.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
index 5cb01e5c323c993c08d0226d72c16815310febc7..c26c11905ffe0063eec29b07a236b5e24a0922c9 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <acpi/acpi.h>
 #include <linux/ide.h>
 #include <linux/pci.h>
index eb2181a6a11cbe9dfd825daae8c03a73aa85fc19..f9daffd7d0e315270d9f5b7766c627ef60bdb103 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/delay.h>
 #include <linux/ide.h>
 #include <linux/scatterlist.h>
+#include <linux/gfp.h>
 
 #include <scsi/scsi.h>
 
@@ -263,8 +264,8 @@ void ide_retry_pc(ide_drive_t *drive)
         * of it.  The failed command will be retried after sense data
         * is acquired.
         */
-       blk_requeue_request(failed_rq->q, failed_rq);
        drive->hwif->rq = NULL;
+       ide_requeue_and_plug(drive, failed_rq);
        if (ide_queue_sense_rq(drive, pc)) {
                blk_start_request(failed_rq);
                ide_complete_rq(drive, -EIO, blk_rq_bytes(failed_rq));
index df3df0041eb61b8b0050703bbeb5585500bbc8fd..02712bf045c1bdece00d845d35662fd065e12c41 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/kernel.h>
 #include <linux/cdrom.h>
+#include <linux/gfp.h>
 #include <linux/ide.h>
 #include <scsi/scsi.h>
 
index ab87e4f7cec913685fc8cdff98c727f260c18811..b85450865ff0d7efe096830dbd8e6e694208cede 100644 (file)
@@ -409,6 +409,8 @@ static struct pcmcia_device_id ide_ids[] = {
        PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
        PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
        PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
+       PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 1GB", 0x2e6d1829, 0x55d5bffb),
+       PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 4GB", 0x2e6d1829, 0x531e7d10),
        PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
        PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2      ", 0x547e66dc, 0x8671043b),
        PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
@@ -429,6 +431,8 @@ static struct pcmcia_device_id ide_ids[] = {
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
+       PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF133", 0x709b1bf1, 0x7558f133),
+       PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS8GCF133", 0x709b1bf1, 0xb2f89b47),
        PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
        PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
        PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
index c6935c78757cfbfaacb06fb820223dc6fd19bec8..9e98122f646e3190c85dc3d2813102f5a00f49ec 100644 (file)
@@ -1,5 +1,6 @@
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/ide.h>
 
 DEFINE_MUTEX(ide_setting_mtx);
index 60b0590ccc9cf16be3128ba62e8a4aee6df5f37c..f9bbd904eae72651d65e33b4dba06ec4f95f69ee 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/kernel.h>
 #include <linux/ide.h>
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 
 #include "ide-disk.h"
index ee58c88dee5a61f51d437d1f618fd89745144785..06b14bc9a1d42ebccc2f5dc80774a6a89f9cd19f 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/ide.h>
 #include <linux/scatterlist.h>
@@ -492,6 +493,7 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
        if (rq) {
                hwif->rq = NULL;
                rq->errors = 0;
+               ide_requeue_and_plug(drive, rq);
        }
        return ret;
 }
index efd907623469fbc92a5e372fda19a4d6e260574d..4713bdca20b6acb447362d8ae622a5c5e276c5fd 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/major.h>
 #include <linux/errno.h>
 #include <linux/genhd.h>
-#include <linux/slab.h>
 #include <linux/cdrom.h>
 #include <linux/ide.h>
 #include <linux/hdreg.h>
index 753241429c26b4e9b370c72e388a79990a780028..c32d83996ae1dea17464b5ae9a772c6d0aec06c4 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/ide.h>
 #include <linux/hdreg.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 
 #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
 #define IDE_DISK_MINORS                (1 << PARTN_BITS)
index db96138fefcdef55f923580a0404674f8178314b..172ac92181549ce09ba58126bf0a730f497f1666 100644 (file)
@@ -566,7 +566,7 @@ plug_device_2:
                blk_plug_device(q);
 }
 
-static void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq)
+void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq)
 {
        struct request_queue *q = drive->queue;
        unsigned long flags;
index 6e7ae2b6cfc64c018131349e4474f04506b6aa36..9965ecd5078c63e37aa4fb34d1b7df722fd22d63 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/hdreg.h>
 #include <linux/ide.h>
+#include <linux/slab.h>
 
 static const struct ide_ioctl_devset ide_ioctl_settings[] = {
 { HDIO_GET_32BIT,       HDIO_SET_32BIT,        &ide_devset_io_32bit  },
index a914023d6d035d9e530178ff2422a7bf386cc2cd..88a380c5a4708bd9f396a52da5dd47128137f74f 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/ide.h>
 #include <linux/jiffies.h>
 #include <linux/blkdev.h>
index ad7be2669dcb9020bc5b91612079d80f21fd6869..1c08311b0a0e0566076b428c47ff8fbf3bebb239 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/ide.h>
 
 int generic_ide_suspend(struct device *dev, pm_message_t mesg)
index fbedd35feb449194e85fe78ee110ccb5ba101e9f..4c3d1bfec0c5b450fbbe68014e1c15fe9e29c454 100644 (file)
@@ -695,14 +695,8 @@ static int ide_probe_port(ide_hwif_t *hwif)
        if (irqd)
                disable_irq(hwif->irq);
 
-       rc = ide_port_wait_ready(hwif);
-       if (rc == -ENODEV) {
-               printk(KERN_INFO "%s: no devices on the port\n", hwif->name);
-               goto out;
-       } else if (rc == -EBUSY)
-               printk(KERN_ERR "%s: not ready before the probe\n", hwif->name);
-       else
-               rc = -ENODEV;
+       if (ide_port_wait_ready(hwif) == -EBUSY)
+               printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name);
 
        /*
         * Second drive should only exist if first drive was found,
@@ -713,7 +707,7 @@ static int ide_probe_port(ide_hwif_t *hwif)
                if (drive->dev_flags & IDE_DFLAG_PRESENT)
                        rc = 0;
        }
-out:
+
        /*
         * Use cached IRQ number. It might be (and is...) changed by probe
         * code above
index 017c09540c2f70b416af3a39eaf122a5a49287f1..a3133d7b2a0cf91b259eb3fb19db091b4c88bd86 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/ctype.h>
 #include <linux/ide.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
index cc8633cbe133db4d9b7f81330ef66a547a6176ac..67fb73559fd582e0bbd477500636c315834b7764 100644 (file)
@@ -428,13 +428,11 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
 {
        struct request *rq;
        int error;
+       int rw = !(cmd->tf_flags & IDE_TFLAG_WRITE) ? READ : WRITE;
 
-       rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+       rq = blk_get_request(drive->queue, rw, __GFP_WAIT);
        rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
 
-       if (cmd->tf_flags & IDE_TFLAG_WRITE)
-               rq->cmd_flags |= REQ_RW;
-
        /*
         * (ks) We transfer currently only whole sectors.
         * This is suffient for now.  But, it would be great,
index 16d056939f9f313119c5a0c51da62456d85669aa..3cb9c4e056ffdf0c7d2952c9c160051af7f910ab 100644 (file)
@@ -52,7 +52,6 @@
 #include <linux/major.h>
 #include <linux/errno.h>
 #include <linux/genhd.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/ide.h>
index b2709c7334852b69badfd0f0314b02b1f020d8b5..2e3169f2acda26b50e16ac56232dd5e8b5e8ca24 100644 (file)
@@ -61,6 +61,7 @@
 
 #include <linux/types.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/ide.h>
 #include <linux/init.h>
index 850ee452e9bb34db31d833cab4a9f66674b92658..159955d16c475e69314c12efa4a19166cfec4eaf 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/adb.h>
 #include <linux/pmu.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 #include <asm/prom.h>
 #include <asm/io.h>
index 00f54248f41f0d76fbf62e2c791123a0bf17dfe9..48d976aad7abaf685754ea647280c21ff4c99c38 100644 (file)
@@ -3,7 +3,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/errno.h>
 #include <linux/ide.h>
index 134f1fd138665e01d3d7a3bb84ae431104f87db4..356b9b504ffd421c4088316694f7392e34b5ed42 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ide.h>
index e65d010b708db1fcff3182d7b87a1ed1e7214f06..101f4002238601eb6be0048236df78f6ca667380 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ide.h>
@@ -110,7 +111,6 @@ struct via82cxxx_dev
 {
        struct via_isa_bridge *via_config;
        unsigned int via_80w;
-       u8 cached_device[2];
 };
 
 /**
@@ -403,66 +403,10 @@ static const struct ide_port_ops via_port_ops = {
        .cable_detect           = via82cxxx_cable_detect,
 };
 
-static void via_write_devctl(ide_hwif_t *hwif, u8 ctl)
-{
-       struct via82cxxx_dev *vdev = hwif->host->host_priv;
-
-       outb(ctl, hwif->io_ports.ctl_addr);
-       outb(vdev->cached_device[hwif->channel], hwif->io_ports.device_addr);
-}
-
-static void __via_dev_select(ide_drive_t *drive, u8 select)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       struct via82cxxx_dev *vdev = hwif->host->host_priv;
-
-       outb(select, hwif->io_ports.device_addr);
-       vdev->cached_device[hwif->channel] = select;
-}
-
-static void via_dev_select(ide_drive_t *drive)
-{
-       __via_dev_select(drive, drive->select | ATA_DEVICE_OBS);
-}
-
-static void via_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       struct ide_io_ports *io_ports = &hwif->io_ports;
-
-       if (valid & IDE_VALID_FEATURE)
-               outb(tf->feature, io_ports->feature_addr);
-       if (valid & IDE_VALID_NSECT)
-               outb(tf->nsect, io_ports->nsect_addr);
-       if (valid & IDE_VALID_LBAL)
-               outb(tf->lbal, io_ports->lbal_addr);
-       if (valid & IDE_VALID_LBAM)
-               outb(tf->lbam, io_ports->lbam_addr);
-       if (valid & IDE_VALID_LBAH)
-               outb(tf->lbah, io_ports->lbah_addr);
-       if (valid & IDE_VALID_DEVICE)
-               __via_dev_select(drive, tf->device);
-}
-
-const struct ide_tp_ops via_tp_ops = {
-       .exec_command           = ide_exec_command,
-       .read_status            = ide_read_status,
-       .read_altstatus         = ide_read_altstatus,
-       .write_devctl           = via_write_devctl,
-
-       .dev_select             = via_dev_select,
-       .tf_load                = via_tf_load,
-       .tf_read                = ide_tf_read,
-
-       .input_data             = ide_input_data,
-       .output_data            = ide_output_data,
-};
-
 static const struct ide_port_info via82cxxx_chipset __devinitdata = {
        .name           = DRV_NAME,
        .init_chipset   = init_chipset_via82cxxx,
        .enablebits     = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } },
-       .tp_ops         = &via_tp_ops,
        .port_ops       = &via_port_ops,
        .host_flags     = IDE_HFLAG_PIO_NO_BLACKLIST |
                          IDE_HFLAG_POST_SET_MODE |
index dd253002cd50c973bd8e1ffcc5041415cf0abe1b..15341fc1c68b0600e769141562bf08897c1718fe 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/notifier.h>
 #include <linux/cpumask.h>
index 8e7e3344c4b3fdfdd54ae4591843c4313fb93d7a..d178699b194a054381d5e37067f78594ae5ef480 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/scatterlist.h>
 
index c88696a6cf8aa8a5d79b726f3b22ac3790837f67..4565cb5d3d1a7e3c808c6945b899d165a321bbee 100644 (file)
@@ -56,7 +56,6 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
-#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
index abbb06996f9e008c0a5c5957a18b46d10ef032d7..0b926e45afe2f0b64824d36b6acfbb50ed0d3afa 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <linux/mutex.h>
 #include <linux/inetdevice.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <net/arp.h>
 #include <net/neighbour.h>
index 764787ebe8d80f661ba9e7edf0b0e98c38502bfc..ad63b79afac10ba071056d704119bad51877381a 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/random.h>
 #include <linux/rbtree.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/workqueue.h>
 #include <linux/kdev_t.h>
@@ -3693,7 +3694,7 @@ static void cm_add_one(struct ib_device *ib_device)
        cm_dev->device = device_create(&cm_class, &ib_device->dev,
                                       MKDEV(0, 0), NULL,
                                       "%s", ib_device->name);
-       if (!cm_dev->device) {
+       if (IS_ERR(cm_dev->device)) {
                kfree(cm_dev);
                return;
        }
index 875e34e0b235d93a68b44290fbc7f1417104773c..6d777069d86d6add74325e970d31541e699e4647 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/random.h>
 #include <linux/idr.h>
 #include <linux/inetdevice.h>
+#include <linux/slab.h>
 
 #include <net/tcp.h>
 #include <net/ipv6.h>
@@ -1683,6 +1684,7 @@ int rdma_set_ib_paths(struct rdma_cm_id *id,
        }
 
        memcpy(id->route.path_rec, path_rec, sizeof *path_rec * num_paths);
+       id->route.num_paths = num_paths;
        return 0;
 err:
        cma_comp_exch(id_priv, CMA_ROUTE_RESOLVED, CMA_ADDR_RESOLVED);
index 0f89909abce98f1e68d36289cb47642126bf4e2e..bfead5bc25f6e14efcc09c4e5be51050785acb53 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
 #include <linux/completion.h>
+#include <linux/slab.h>
 
 #include <rdma/iw_cm.h>
 #include <rdma/ib_addr.h>
index e351b15485356b5489c1e2e668bcd7eb19bfb8c0..1df1194aeba420d7288e47a4225dde559259f563 100644 (file)
@@ -34,6 +34,7 @@
  *
  */
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <rdma/ib_cache.h>
 
 #include "mad_priv.h"
index 4e0f2829e0e5f11fd0bade45cfc4bef18ccf4026..f37878c9c06eb43812b022ba72a034418a1a238e 100644 (file)
@@ -31,6 +31,8 @@
  * SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "mad_priv.h"
 #include "mad_rmpp.h"
 
index 8d82ba17135366317ba2d3e856c78c4cfb97829a..a519801dcfb758f785a885ce49259fa7b1a01f8d 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/bitops.h>
 #include <linux/random.h>
 
index 1558bb7fc74dd6c2ce19da6d9c277292c0ba0e7b..f901957abc8b54ce68815eb19a26129a0e6b8867 100644 (file)
@@ -461,6 +461,7 @@ alloc_group_attrs(ssize_t (*show)(struct ib_port *,
                element->attr.attr.mode  = S_IRUGO;
                element->attr.show       = show;
                element->index           = i;
+               sysfs_attr_init(&element->attr.attr);
 
                tab_attr[i] = &element->attr.attr;
        }
index 017d6e24448fa83f278826343cb6609f025d0df0..512b1c43460c2d40dfb5c410996dff1905ec56df 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/cdev.h>
 #include <linux/idr.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
index b2e16c332d5b038703e083057339da6cd0434749..46185084121e28b7cd233ccd9df581d4579106d0 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <linux/miscdevice.h>
+#include <linux/slab.h>
 
 #include <rdma/rdma_user_cm.h>
 #include <rdma/ib_marshall.h>
index 4f906f0614f0f10826e35cb5b447774f70de3c29..415e186eee320e5dc0295f4d7d828ceba3f59338 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/sched.h>
 #include <linux/hugetlb.h>
 #include <linux/dma-attrs.h>
+#include <linux/slab.h>
 
 #include "uverbs.h"
 
index 04b585e86cb210f9975c34104131d553de404979..e7db054fb1c888900c9e9a1df4e136e6cd7910d1 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/compat.h>
 #include <linux/sched.h>
 #include <linux/semaphore.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
index f71cf138d674109c6d3f10381f64d4ffcb8c5358..6fcfbeb24a234a419ec9313c956c7c4ba581bcf6 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <linux/file.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
index d805cf365c8d3218d81c024b50dff58d6c78f6c6..fb35262544260144c52cd7c583a1750cebd730e4 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/file.h>
 #include <linux/cdev.h>
 #include <linux/anon_inodes.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
index c61fd2b4a5563c62d18393a479f29bd72c3eae8e..dc85d777578ed087979b94829c886919c03c008a 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/tcp.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index e9110163aeffc65c79858b5fff83d710293e2136..d4f5f5d42e90e36bb417b9f613933f4c5acf0ee1 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/bitmap.h>
 
 #include "c2.h"
index 75b93e9b88100638a10c3d59b77e51a59ad420be..95f58ab1e0b881d7913bc97c9f9ae0e2ac15ad43 100644 (file)
@@ -31,6 +31,8 @@
  * SOFTWARE.
  *
  */
+#include <linux/slab.h>
+
 #include "c2.h"
 #include "c2_wr.h"
 #include "c2_vq.h"
index f5c45b194f534df104bf4be40c39c302b9788e5e..f7b0fc23f41365242300ed5fc6b66086062f2fdb 100644 (file)
@@ -35,6 +35,8 @@
  * SOFTWARE.
  *
  */
+#include <linux/gfp.h>
+
 #include "c2.h"
 #include "c2_vq.h"
 #include "c2_status.h"
index b506fe22b4d4d4f3b21cc309a66f7b6a867c3d1f..119c4f3d9791a81c44164737f5c9f147b5455139 100644 (file)
@@ -30,6 +30,8 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
+#include <linux/slab.h>
+
 #include "c2.h"
 #include "c2_vq.h"
 
index 00c709926c8dc7a9b749e9c893bb69aad610d1cd..161f2a285351a7c41ad5352318d63a91ec775197 100644 (file)
@@ -34,6 +34,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 
 #include "c2.h"
index ad723bd8bf498090560c72bc78a1a06dc72e9730..c47f618d12e89084b4ea2945ee02b03a344373c4 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/if_arp.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index ad518868df77642608281fd11d4c093c11c02711..d8f4bb8bf42e71f332abf85dd2cf846441455815 100644 (file)
@@ -36,6 +36,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 #include "c2.h"
 #include "c2_vq.h"
index dd05c48356425f30e2109cd4b17ba484c2919a0d..78c4bcc6ef608b131bfc04cf07c0da93bced375f 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/mm.h>
 #include <linux/inet.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include <linux/route.h>
 
index a8d24d53f3070466893fe47cdfc7ee7985c215a3..8bca6b4ec9af2003e40cbb48767c0f1106646e76 100644 (file)
@@ -31,6 +31,7 @@
  */
 #ifdef DEBUG
 #include <linux/types.h>
+#include <linux/slab.h>
 #include "common.h"
 #include "cxgb3_ioctl.h"
 #include "cxio_hal.h"
index a28e862f2d6881d9eec49fa8764c5539d4d418d0..35f286f1ad1e9280e261444b68a46d21e7350504 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/spinlock.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 
 #include "cxio_resource.h"
index d94388b81a4005b1e5d0dab5bdb780910c1d3665..4fef032962761062c23bdb206301cea1d51dad6d 100644 (file)
@@ -31,6 +31,7 @@
  */
 #include <linux/module.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/skbuff.h>
 #include <linux/timer.h>
index 743c5d8b880686a11357e5ed39c50a60ffde91a2..6afc89e7572c8d880db196cc34402d3a168e39d8 100644 (file)
@@ -29,7 +29,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/mman.h>
 #include <net/sock.h>
 #include "iwch_provider.h"
index e1ec65ebb016e4c7cfbfe81ca1e2095ba614ce08..5c36ee2809acf52f8f212483dfb81e5649357baf 100644 (file)
@@ -29,6 +29,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 
 #include <rdma/iw_cm.h>
index 47b35c6608d2d284d5706cc3cad521bf8a9a5ccc..19b1c4a62a2366c4018ca23ec9d5462ed8780340 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/ethtool.h>
 #include <linux/rtnetlink.h>
 #include <linux/inetdevice.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index b4d893de365059d671546d0c9f2af9f28fad1444..ae47bfd22bd525eb4d4ff2b317790a3b408cc635 100644 (file)
@@ -30,6 +30,7 @@
  * SOFTWARE.
  */
 #include <linux/sched.h>
+#include <linux/gfp.h>
 #include "iwch_provider.h"
 #include "iwch.h"
 #include "iwch_cm.h"
index 56735ea2fc576746ebb22350e8c3b18009279f79..465926319f3dc2a85d078c2d9f33e0b02e7d3e49 100644 (file)
@@ -41,6 +41,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
+
 #include "ehca_tools.h"
 #include "ehca_iverbs.h"
 #include "hcp_if.h"
index 97e4b231cdc42b66e7e52c4554a6fa035dd370ca..d9b0ebcb67d7371946f8a644d26066e3a175df28 100644 (file)
@@ -43,6 +43,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
+
 #include "ehca_iverbs.h"
 #include "ehca_classes.h"
 #include "ehca_irq.h"
index 8b92f85d4dd0eef382420e9d6dd69d7e1c594af1..73edc3668663a2cb8f2b987db1c8945016df4714 100644 (file)
@@ -39,6 +39,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/gfp.h>
+
 #include "ehca_tools.h"
 #include "ehca_iverbs.h"
 #include "hcp_if.h"
index b2b6fea2b141f3b7c933d2fb551374623689a09d..07cae552cafba60be9efb413b210d6e1ae767243 100644 (file)
@@ -41,6 +41,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
+
 #include "ehca_classes.h"
 #include "ehca_irq.h"
 #include "ehca_iverbs.h"
index 7550a534005c9a6d002a8b77284125c9522d6ccd..31a68b9c52d0c96f4739447f86918a5c4ed020fc 100644 (file)
@@ -40,6 +40,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
 #include <rdma/ib_umem.h>
 
 #include "ehca_iverbs.h"
index 2fe554855fa5bbdef4ee1ff0aa63982231393094..351577a6670a5be1c24cf61416793f763aac3510 100644 (file)
@@ -38,6 +38,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
+
 #include "ehca_tools.h"
 #include "ehca_iverbs.h"
 
index b105f664d3efb24db69d304cca6bb24c29fcf7b2..47d388ec1cdebe4555eedf54f957efbb6f345222 100644 (file)
@@ -43,6 +43,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
+
 #include "ehca_classes.h"
 #include "ehca_tools.h"
 #include "ehca_qes.h"
index f1565cae8ec6c6be02c56185121f2f913ceaff2e..45ee89b65c23fbf57350e8a5cb04840180bd2035 100644 (file)
@@ -40,6 +40,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
+
 #include "ehca_classes.h"
 #include "ehca_iverbs.h"
 #include "ehca_mrmw.h"
index 1227c593627a62b5a1e27a237a63175c4038dfe0..1596e30853443991c15c2847657935d72b5357db 100644 (file)
@@ -38,6 +38,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
+
 #include "ehca_tools.h"
 #include "ipz_pt_fn.h"
 #include "ehca_classes.h"
index d385e4168c975993e55c7667ac034b30c7ecd882..0416c6c0e126f3dd8728fe2518b0d1ce018ce6dc 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include "ipath_verbs.h"
index e90a0ea538a05b75b3fe0ca06edcda968bb4d364..644c2c74e054dce8a50fa30ac64ecfd2d59654e5 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <linux/scatterlist.h>
+#include <linux/gfp.h>
 #include <rdma/ib_verbs.h>
 
 #include "ipath_verbs.h"
index d2787fe80304e65facbd6fb90e6df953c009445a..6302626d17f005536229657b465c1be3b76c01fd 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
 #include <linux/bitmap.h>
+#include <linux/slab.h>
 
 #include "ipath_kernel.h"
 #include "ipath_verbs.h"
index 73933a41ce840ad4a3079f69259b7397fa654c67..9c5c66d16a2316fc58db3d3aa3e82b85d941b36a 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/cdev.h>
 #include <linux/swap.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <linux/highmem.h>
 #include <linux/io.h>
 #include <linux/jiffies.h>
index 100da8542bbaecf5d153a34b4d75bddc8ab61de9..2fca70836daea5d4f24f16ecc65d32f1a4249099 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/pagemap.h>
 #include <linux/init.h>
 #include <linux/namei.h>
+#include <linux/slab.h>
 
 #include "ipath_kernel.h"
 
index 077879c0bdb51a63f19326b21cf6f5350f43f6fe..776938299e4c9e91bd5a075b513773a8bae74066 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/pci.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include "ipath_kernel.h"
index b28865faf435179078a1aed86e16c38326da10c8..e73274229404f39d7ab70ce056f3f2b125b8f9a3 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <linux/module.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <asm/pgtable.h>
index 9d343b7c2f3b64b7729114a98773accab45baec8..e346d3890a0e5fbefd179fd8133cc3b4590dc8ec 100644 (file)
@@ -31,6 +31,8 @@
  * SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include <rdma/ib_umem.h>
 #include <rdma/ib_pack.h>
 #include <rdma/ib_smi.h>
index cb2d3ef2ae12426a2ee3da2937118de3145c0c61..0857a9c3cd3d3ca4e731091b5b9ef129cf5024f1 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/err.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include "ipath_verbs.h"
index 4b06985908507a355ad19dbdd115fb27d1ed7986..98ac18ec977e4099f9ee154e8a53353d6206751d 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <linux/spinlock.h>
+#include <linux/gfp.h>
 
 #include "ipath_kernel.h"
 #include "ipath_verbs.h"
index e3d80ca84c1afb6edd42eece87eb9aecb4560c18..386e2c717c53b4b03707c8a21fd027cf8121199f 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include "ipath_verbs.h"
index eb7d59abd12d283dcb8c6b307fc266870520dbe7..5e86d73eba2af2af953257f6d03d873324a81aa8 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/mm.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #include "ipath_kernel.h"
index 9289ab4b0ae86dd0a37da2d7334538d627d090a5..559f39be0dcc16a5b0e8ceff53005d30060c2303 100644 (file)
@@ -34,6 +34,7 @@
 #include <rdma/ib_mad.h>
 #include <rdma/ib_user_verbs.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/utsname.h>
 #include <linux/rculist.h>
 
index 6923e1d986da49b95e9c8e39a3a8955f2a2ffac9..6216ea9238531a9a0c10a6a0dd10a43740db4a12 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/rculist.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include "ipath_verbs.h"
 
index c75ac9463e20e477a78383debc290baa8d88a319..11a236f8d884a4902b6243139eddd6da6c98c76a 100644 (file)
@@ -30,6 +30,8 @@
  * SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "mlx4_ib.h"
 
 struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
index de5263beab4a721a8c261b8c8403996bb54e26b8..cc2ddd29ac57dc62e5f4f0d88eeb6bc64ee40c4c 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/mlx4/cq.h>
 #include <linux/mlx4/qp.h>
+#include <linux/slab.h>
 
 #include "mlx4_ib.h"
 #include "user.h"
index 19e68ab6616897b5ef8281eb8bbdff8c9ecd46c4..f38d5b1189273d8fb320374d06c3c3f044d7cec2 100644 (file)
@@ -34,6 +34,7 @@
 #include <rdma/ib_smi.h>
 
 #include <linux/mlx4/cmd.h>
+#include <linux/gfp.h>
 
 #include "mlx4_ib.h"
 
index e596537ff3533cd53b607eeb5d2e5795cca49c90..01f2a3f93355c3e6a26004f84ea5a28dce248114 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 
 #include <rdma/ib_smi.h>
index 8f3666b20ea43991d2f6f742d70161490b2851c8..1d27b9a8e2d6b6944e002296479116952456d73b 100644 (file)
@@ -31,6 +31,8 @@
  * SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "mlx4_ib.h"
 
 static u32 convert_access(int acc)
@@ -238,7 +240,7 @@ struct ib_fast_reg_page_list *mlx4_ib_alloc_fast_reg_page_list(struct ib_device
        mfrpl->mapped_page_list = dma_alloc_coherent(&dev->dev->pdev->dev,
                                                     size, &mfrpl->map,
                                                     GFP_KERNEL);
-       if (!mfrpl->ibfrpl.page_list)
+       if (!mfrpl->mapped_page_list)
                goto err_free;
 
        WARN_ON(mfrpl->map & 0x3f);
index ae75389937d6b1fe9a8100d8d6cbc406fa6b2cf1..5643f4a8ffefd2c983ed603615871dfe2ff55974 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <linux/log2.h>
+#include <linux/slab.h>
 
 #include <rdma/ib_cache.h>
 #include <rdma/ib_pack.h>
index cf8085bcbd6d294927f2c2cc44c048bf5c41da40..818b7ecace5e3c812b7f7500ba44a13ac46ef397 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/mlx4/qp.h>
 #include <linux/mlx4/srq.h>
+#include <linux/slab.h>
 
 #include "mlx4_ib.h"
 #include "user.h"
index 8c2ed994d5401cc7fa86844ee7e1eff2ab927c63..3603ae89b60692149c4fc63bf4ac64d71eb30868 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/pci.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <rdma/ib_mad.h>
 
index d9f4735c2b3766dee2f3e5907463415efa12f90d..18ee3fa4b88ccec241b0d4b866341a6b7e086af3 100644 (file)
@@ -34,6 +34,7 @@
  * SOFTWARE.
  */
 
+#include <linux/gfp.h>
 #include <linux/hardirq.h>
 #include <linux/sched.h>
 
index 8c31fa36e95e7102a96ecf9ca6b31988b0f99640..9388164b6053c71c785b1bfbc67f07e0138600de 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include "mthca_dev.h"
 #include "mthca_cmd.h"
index b01b28987874e9145d241310347e4691695c2716..5eee6665919a46480e4d0023eb3a53f228acf9c0 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/errno.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
+#include <linux/gfp.h>
 
 #include "mthca_dev.h"
 #include "mthca_config_reg.h"
index d4c81053e439fe0fa46bae57e42e92738792b9e6..515790a606e6e56369e57840e39cadc2a2ee166d 100644 (file)
@@ -31,7 +31,7 @@
  */
 
 #include <linux/string.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 
 #include "mthca_dev.h"
 #include "mthca_cmd.h"
index 1f7d1a29d2a82250182bb5a91a5902b64eda0379..8c2a83732b5d53ca1a4f019a1303de335233ec9f 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/mm.h>
 #include <linux/scatterlist.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <asm/page.h>
 
index bcf7a401482015f3b5c09afdc4177bab3d10577f..f080a784bc795da07fa380a7d72cc0aef900e0f6 100644 (file)
@@ -39,6 +39,7 @@
 #include <rdma/ib_user_verbs.h>
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 
 #include "mthca_dev.h"
index 4272c52e38a45bc65667e5ab24cff805359a7629..de7b9d7166f3a8226ef920f9c308cf1295332f00 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/init.h>
 #include <linux/if_arp.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/byteorder.h>
index 2a49ee40b52003e109b039896c773f5c3209d2bd..986d6f32ddedf8ac0d225aca4a61321469f1d3a1 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/list.h>
 #include <linux/threads.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 #include <net/neighbour.h>
 #include <net/route.h>
index 925075557dc251d449e15a3adcb5ab5039621362..c36a3f51492901d696e25f37f89ac79e5a62bc21 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/tcp.h>
 #include <linux/if_vlan.h>
 #include <linux/inet_lro.h>
+#include <linux/slab.h>
 
 #include "nes.h"
 
index 91fdde382e82e9d936d263d012993415aa2ca640..b7c813f4be43266327446692c0a8496b039fdff6 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/if_arp.h>
 #include <linux/if_vlan.h>
 #include <linux/ethtool.h>
+#include <linux/slab.h>
 #include <net/tcp.h>
 
 #include <net/inet_common.h>
index 729d525c5b70514eca4e6d3b0f1dd88f1e46b953..186623d8695987b04cee7f82222be4bafd7c8523 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/if_vlan.h>
+#include <linux/slab.h>
 #include <linux/crc32.h>
 #include <linux/in.h>
 #include <linux/ip.h>
index 69928296d74bf3b8f41e5f80449ecc66b4fc6375..e54f312e4bdc7610f96acd5f0930d34e92c6890a 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/moduleparam.h>
 #include <linux/random.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 
 #include <rdma/ib_verbs.h>
@@ -2820,11 +2821,10 @@ static int nes_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
        attr->cap.max_send_wr = nesqp->hwqp.sq_size;
        attr->cap.max_recv_wr = nesqp->hwqp.rq_size;
        attr->cap.max_recv_sge = 1;
-       if (nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) {
-               init_attr->cap.max_inline_data = 0;
-       } else {
-               init_attr->cap.max_inline_data = 64;
-       }
+       if (nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA)
+               attr->cap.max_inline_data = 0;
+       else
+               attr->cap.max_inline_data = 64;
 
        init_attr->event_handler = nesqp->ibqp.event_handler;
        init_attr->qp_context = nesqp->ibqp.qp_context;
index bc658373ad557a05d428df81697b9938e85b6d5e..bb1004114dec09c6f3b6df7c9dab66d1f09f5bae 100644 (file)
@@ -35,6 +35,7 @@
 #include <net/icmp.h>
 #include <linux/icmpv6.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include "ipoib.h"
index 961c585da216a9eb3db964b08cfc72b20b981a24..86eae229dc49eb5c12d517f4c6c8d60a139160e6 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <linux/err.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 struct file_operations;
 
index 5df40b128f81b1b13f8cd9d30133a4ea43148875..ec6b4fbe25e4416fb45ef9e76f5703093c26e86a 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <linux/ip.h>
 #include <linux/tcp.h>
index d41ea27be5e196998d97ced405837433d46586cb..b166bb75753d07c8457cdb19c9874a1582a2cc90 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/inetdevice.h>
 #include <linux/delay.h>
 #include <linux/completion.h>
+#include <linux/slab.h>
 
 #include <net/dst.h>
 
index 68325119f740da879a3d9deaa6095907ee3554bf..049a997caff35875ca8e5e1ad2870a4b3af0a933 100644 (file)
@@ -31,6 +31,8 @@
  * SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "ipoib.h"
 
 int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid, int set_qkey)
index e3bf00d8cd259cdb1f167b19aeb0bda4b9af6b86..d7e9740c724804afcdf20ba9c54fbe4fe91fdb87 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/module.h>
 
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/seq_file.h>
 
 #include <asm/uaccess.h>
index 71237f8f78f723610144cc730ce81cd9437dad3c..93399dff0c6fa8eb95217d15d4590dabcdc5b22a 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/net.h>
 #include <linux/scatterlist.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <net/sock.h>
 
@@ -613,7 +614,7 @@ static struct scsi_host_template iscsi_iser_sht = {
        .cmd_per_lun            = ISER_DEF_CMD_PER_LUN,
        .eh_abort_handler       = iscsi_eh_abort,
        .eh_device_reset_handler= iscsi_eh_device_reset,
-       .eh_target_reset_handler= iscsi_eh_target_reset,
+       .eh_target_reset_handler = iscsi_eh_recover_target,
        .target_alloc           = iscsi_target_alloc,
        .use_clustering         = DISABLE_CLUSTERING,
        .proc_name              = "iscsi_iser",
index 308d17bb514641767a109f9e65d2bcea370cee82..b89d76b39a131873dc4548bdf57e703c4eb09f5e 100644 (file)
@@ -32,6 +32,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 
 #include "iscsi_iser.h"
index b2f07aa1604bec5de42095ab7ba4fef5c5980a7d..03078c08309a09cff9b5c1011dcd1c1ce855048e 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 /*
  * Check that the effect_id is a valid effect and whether the user
index f967008f332e3a79fda20adb4d967957ab29f3e5..1d881c96ba8fc2c0db1c5ce289af448288ff42a5 100644 (file)
@@ -25,6 +25,7 @@
 
 #define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg)
 
+#include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
index 7e18bcf05a662353d395d7a7c527c61271eed097..46239e47a2605a41fafb50d6fe66498f554a41f4 100644 (file)
@@ -59,11 +59,11 @@ static unsigned int get_time_pit(void)
        unsigned long flags;
        unsigned int count;
 
-       spin_lock_irqsave(&i8253_lock, flags);
+       raw_spin_lock_irqsave(&i8253_lock, flags);
        outb_p(0x00, 0x43);
        count = inb_p(0x40);
        count |= inb_p(0x40) << 8;
-       spin_unlock_irqrestore(&i8253_lock, flags);
+       raw_spin_unlock_irqrestore(&i8253_lock, flags);
 
        return count;
 }
index 06ad36ed348329e9ff4d4dabb7141eb07cd61d56..85d6ee09f11f4b7881b66acc9eaceb068b0bde7d 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/gameport.h>
-#include <linux/slab.h>
 
 #define L4_PORT                        0x201
 #define L4_SELECT_ANALOG       0xa4
index 291d9393d359c8e0e7f82a0d20e4a2cfc0f2e8a6..10c9b0a845f07abb41b0d071133d9166e601c763 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/jiffies.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/input-polldev.h>
 
index e2aad0a51826b1214e9f55a9c6a45d7e69e1525e..9c79bd56b51acbf17d90033789801d984bc492b8 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/input.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/major.h>
 #include <linux/proc_fs.h>
@@ -659,7 +660,14 @@ static int input_default_setkeycode(struct input_dev *dev,
 int input_get_keycode(struct input_dev *dev,
                      unsigned int scancode, unsigned int *keycode)
 {
-       return dev->getkeycode(dev, scancode, keycode);
+       unsigned long flags;
+       int retval;
+
+       spin_lock_irqsave(&dev->event_lock, flags);
+       retval = dev->getkeycode(dev, scancode, keycode);
+       spin_unlock_irqrestore(&dev->event_lock, flags);
+
+       return retval;
 }
 EXPORT_SYMBOL(input_get_keycode);
 
index c52bec4d0530f632667031e023e980e78dc4fcaf..423e0e6031ab5010e542555b10bc539683efaae6 100644 (file)
@@ -929,6 +929,24 @@ static const struct input_device_id joydev_ids[] = {
                .evbit = { BIT_MASK(EV_ABS) },
                .absbit = { BIT_MASK(ABS_THROTTLE) },
        },
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+                               INPUT_DEVICE_ID_MATCH_KEYBIT,
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = {[BIT_WORD(BTN_JOYSTICK)] = BIT_MASK(BTN_JOYSTICK) },
+       },
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+                               INPUT_DEVICE_ID_MATCH_KEYBIT,
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(BTN_GAMEPAD)] = BIT_MASK(BTN_GAMEPAD) },
+       },
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+                               INPUT_DEVICE_ID_MATCH_KEYBIT,
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(BTN_TRIGGER_HAPPY)] = BIT_MASK(BTN_TRIGGER_HAPPY) },
+       },
        { }     /* Terminating entry */
 };
 
index 1c0b529c06aaa596b8fe4a663cd275ed4f39ead6..4afe0a3b4884559fbd8300ee0d7e042e674c204b 100644 (file)
@@ -146,11 +146,11 @@ static unsigned int get_time_pit(void)
         unsigned long flags;
         unsigned int count;
 
-        spin_lock_irqsave(&i8253_lock, flags);
+        raw_spin_lock_irqsave(&i8253_lock, flags);
         outb_p(0x00, 0x43);
         count = inb_p(0x40);
         count |= inb_p(0x40) << 8;
-        spin_unlock_irqrestore(&i8253_lock, flags);
+        raw_spin_unlock_irqrestore(&i8253_lock, flags);
 
         return count;
 }
index 523959484753fdabf3e9faa2dddb8ca45c8370c4..8e7de5c7754ffa98ef0fb869e7668b00b9a32be4 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/parport.h>
 #include <linux/input.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver");
index 7a55714a14866386909153cf794844918bb09a1a..fbd62abb66f9dc3017fc4f678dddd28cd889309e 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/parport.h>
 #include <linux/input.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver");
index b1edd778639c6f1fb2985e782e7a731e42bca2cb..405febd94f243539e4847475b9d4a37f6ffb0733 100644 (file)
@@ -54,6 +54,9 @@ static signed short btn_avb_wheel[] =
 static signed short abs_joystick[] =
 { ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 };
 
+static signed short abs_joystick_rudder[] =
+{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, -1 };
+
 static signed short abs_avb_pegasus[] =
 { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y,
   ABS_HAT1X, ABS_HAT1Y, -1 };
@@ -76,8 +79,9 @@ static struct iforce_device iforce_device[] = {
        { 0x061c, 0xc0a4, "ACT LABS Force RS",                          btn_wheel, abs_wheel, ff_iforce }, //?
        { 0x061c, 0xc084, "ACT LABS Force RS",                          btn_wheel, abs_wheel, ff_iforce },
        { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback",       btn_wheel, abs_wheel, ff_iforce }, //?
+       { 0x06f8, 0x0001, "Guillemot Jet Leader Force Feedback",        btn_joystick, abs_joystick_rudder, ff_iforce },
        { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel",      btn_wheel, abs_wheel, ff_iforce }, //?
-       { 0x06f8, 0x0004, "Gullemot Jet Leader 3D",                     btn_joystick, abs_joystick, ff_iforce }, //?
+       { 0x06f8, 0xa302, "Guillemot Jet Leader 3D",                    btn_joystick, abs_joystick, ff_iforce }, //?
        { 0x06d6, 0x29bc, "Trust Force Feedback Race Master",           btn_wheel, abs_wheel, ff_iforce },
        { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]",         btn_joystick, abs_joystick, ff_iforce }
 };
index b41303d3ec54c339428e60cc4684b727050e4af8..6c96631ae5d9faff42fbe8e21969e78fca1133f4 100644 (file)
@@ -212,6 +212,7 @@ static struct usb_device_id iforce_usb_ids [] = {
        { USB_DEVICE(0x061c, 0xc0a4) },         /* ACT LABS Force RS */
        { USB_DEVICE(0x061c, 0xc084) },         /* ACT LABS Force RS */
        { USB_DEVICE(0x06f8, 0x0001) },         /* Guillemot Race Leader Force Feedback */
+       { USB_DEVICE(0x06f8, 0x0003) },         /* Guillemot Jet Leader Force Feedback */
        { USB_DEVICE(0x06f8, 0x0004) },         /* Guillemot Force Feedback Racing Wheel */
        { USB_DEVICE(0x06f8, 0xa302) },         /* Guillemot Jet Leader 3D */
        { }                                     /* Terminating entry */
index b6f859869540d3b1995acc4c50b3edde52d9d4a1..d53b9e900234e7ba95c2c0b9500a830b96c07803 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("TurboGraFX parallel port interface driver");
index a7ba27fb4109e32b7fff3bb8b22e67b93eb2967e..3db8006dac3a8f93e1e31a01e56766044cd194ed 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/platform_device.h>
 #include <linux/input.h>
 #include <linux/mfd/adp5520.h>
+#include <linux/slab.h>
 
 struct adp5520_keys {
        struct input_dev *input;
index b5142d2d5112a0470cf34e924e9c0063124d56f3..4771ab172b59b22dda93eaa5437aba8019d7a208 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/input.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 #include <linux/i2c/adp5588.h>
 
index 593c052416b90c94581c65808302445b05996eff..7d989603f875f6a417c395624cffbc2b7171ac26 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/fs.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/pm.h>
 #include <linux/sysctl.h>
index d410d7a52f1d6bd3c60f85564203fb685f76f89b..a91ee941b5c1f0a5f36a6064dd59c30c85c93567 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 
index bd25a3af16644a63885e7be741bb6a97728a7329..c8242dd190d0c920f64ff105903fd76c2e5a6be1 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/input/matrix_keypad.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <mach/ep93xx_keypad.h>
index 2b708aa85553358a2b375cbb602fb07d1ea36c02..b8213fd13c3f0ab277a51ad167b7ae85ab7fcdff 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/irq.h>
 #include <linux/sched.h>
 #include <linux/pm.h>
+#include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
 #include <linux/delay.h>
index 2ee5b798024d89d3b12cceeddc701a17d933dbec..d92c15c39e683cd58eb5dc354c26f5a56559a6dd 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 
 /*
index 781fc61028606a7048bd330e85de10249264e233..5fc976dbce0b0506e466bd9aa3f7ec899c46b0b2 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/delay.h>
 #include <asm/io.h>
index 4e016d823069a65cce32c3fbd5cd94667e2de93c..2cd3e1d56ea4340a450b23974b58b4d7899871f0 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <mach/jornada720.h>
 #include <mach/hardware.h>
index 574eda2a4957a908cd4924d2ba2ae6b4fe958645..60ac4684f87508fe5a3a17c6299f04dfa688e7e0 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/input.h>
 #include <linux/leds.h>
 #include <linux/i2c/lm8323.h>
+#include <linux/slab.h>
 
 /* Commands to send to the chip. */
 #define LM8323_CMD_READ_ID             0x80 /* Read chip ID. */
index d3c8b61a941d46aa677e8f13dff3aba9edcb6f56..b443e088fd3c0c09e3f103011de69b24070e720f 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/gpio.h>
 #include <linux/input/matrix_keypad.h>
+#include <linux/slab.h>
 
 struct matrix_keypad {
        const struct matrix_keypad_platform_data *pdata;
@@ -373,7 +374,9 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)
        input_dev->name         = pdev->name;
        input_dev->id.bustype   = BUS_HOST;
        input_dev->dev.parent   = &pdev->dev;
-       input_dev->evbit[0]     = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+       input_dev->evbit[0]     = BIT_MASK(EV_KEY);
+       if (!pdata->no_autorepeat)
+               input_dev->evbit[0] |= BIT_MASK(EV_REP);
        input_dev->open         = matrix_keypad_start;
        input_dev->close        = matrix_keypad_stop;
 
index 3b5b948eba39fa79fbd38047cdb094c82b1939c9..7fc8185e5c1bd8ab914cedb0f0d78e15e974ed89 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/module.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/input/matrix_keypad.h>
index 1a494d505431a3babe4b08c6911fa8db6c9652bd..a72e61ddca919a46eb4bf276575eea3138bb0857 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <mach/gpio.h>
 #include <plat/keypad.h>
 #include <plat/menelaus.h>
index 78cccddbf551b55a8fdb15163e6867d79202a8aa..1f1a5563f60a8b7c367acbd68543d998fb50cf8f 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 struct opencores_kbd {
        struct input_dev *input;
index 79cd3e9fdf2e2f60d6266fdf4d5df85c5057325c..0e53b3bc39afe4d7925d4aec0cea66174dfc1e5e 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/input/matrix_keypad.h>
+#include <linux/slab.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
index 95fbba470e65f1190eb3de992dfee577ae7b8406..b7123a44b6ece5389989f07a7d9c1d1147a3e2d2 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/input.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/pxa930_rotary.h>
 
index 854e2035cd6e66108fb14f57ee7038991d5106fc..d7dafd9425b69b0682035822185900b8e8ac3d72 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/bitmap.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 static const struct {
        unsigned char kymd, keyout, keyin;
index 42cb3faf7336256ad8de736d7afcb2c4dc1e7756..3910f269cfc8a6a0b57ea1b184336b77b28635c0 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/input.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #include <mach/gpio.h>
 #include <mach/tosa.h>
index 21d6184efa96059ed773b6f63a09e3d37025686f..7aa59e07b6893bead02dcc97bd8035aca08a3773 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/input.h>
 #include <linux/platform_device.h>
 #include <linux/i2c/twl.h>
+#include <linux/slab.h>
 
 
 /*
index 6032def03707f34b3d4169d5944056e8bb849288..4ef764cc493c06c49fa135e735ed6dcf2e2aa93e 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/w90p910_keypad.h>
 
index 69a48e8701b9988acbfaf782f40fd51a98ff6c23..40dabd8487b5933903b8062a4b82fd7c2153da85 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/mfd/88pm860x.h>
+#include <linux/slab.h>
 
 #define PM8607_WAKEUP          0x0b
 
index 614b65d78fe9d23e44cdb612877459f16b80148b..e8bbc619f6dfda0a14423caa6764ee01dd8b19b7 100644 (file)
  * Module and Version Information, Module Parameters
  */
 
-#define ATI_REMOTE_VENDOR_ID   0x0bc7
-#define ATI_REMOTE_PRODUCT_ID  0x004
-#define LOLA_REMOTE_PRODUCT_ID 0x002
-#define MEDION_REMOTE_PRODUCT_ID 0x006
+#define ATI_REMOTE_VENDOR_ID           0x0bc7
+#define LOLA_REMOTE_PRODUCT_ID         0x0002
+#define LOLA2_REMOTE_PRODUCT_ID                0x0003
+#define ATI_REMOTE_PRODUCT_ID          0x0004
+#define NVIDIA_REMOTE_PRODUCT_ID       0x0005
+#define MEDION_REMOTE_PRODUCT_ID       0x0006
 
 #define DRIVER_VERSION         "2.2.1"
 #define DRIVER_AUTHOR           "Torrey Hoffman <thoffman@arnor.net>"
@@ -142,8 +144,10 @@ MODULE_PARM_DESC(repeat_delay, "Delay before sending repeats, default = 500 msec
 #define err(format, arg...) printk(KERN_ERR format , ## arg)
 
 static struct usb_device_id ati_remote_table[] = {
-       { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) },
        { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) },
+       { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA2_REMOTE_PRODUCT_ID) },
+       { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) },
+       { USB_DEVICE(ATI_REMOTE_VENDOR_ID, NVIDIA_REMOTE_PRODUCT_ID) },
        { USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID) },
        {}      /* Terminating entry */
 };
index 15be5430bc6d6010bc3e4e3bcc93fe7bc9d696d4..2124b99378bbb057b74809560d60bdcf428ad932 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/usb/input.h>
+#include <linux/slab.h>
 
 #define DRIVER_DESC    "ATI/Philips USB RF remote driver"
 #define DRIVER_VERSION "0.3"
index 61d10177fa83750b0162468956742564466e9e25..4f72bdd694102eb626011956d1b3b642d6d1ae63 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/pm.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 
 #include <asm/portmux.h>
 #include <asm/bfin_rotary.h>
index ee73d7219c9280c6be1a3e3c7b4c82d6ef4a0b72..fd8407a29631030b1f4a088f01e214b46eb9a4f5 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #define BUTTONS_POLL_INTERVAL  30      /* msec */
 #define BUTTONS_COUNT_THRESHOLD        3
index 766c06911f41a1adda9505d0705799b8126a980b..19af682c24fb4f567ef0f193b189efe0b177c15e 100644 (file)
@@ -10,6 +10,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
 #include <linux/platform_device.h>
index 7ea969347ca993ec34c2edb5d5679a1af25e68f6..99335c286250594933967ea3132aba3a948b4b4f 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/input.h>
 #include <linux/mfd/ezx-pcap.h>
+#include <linux/slab.h>
 
 struct pcap_keys {
        struct pcap_chip *pcap;
index 008de0c5834b711d5efbf2de439f0104a3019916..95562735728d6d5c2f472767284b778546ab529c 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/pcf50633/core.h>
 
index ea4e1fd126516c05a67a0aa58ed27421f1f8de78..f080dd31499bbe21ed509b46559ad2219546a5a4 100644 (file)
@@ -30,7 +30,7 @@ MODULE_ALIAS("platform:pcspkr");
 #include <asm/i8253.h>
 #else
 #include <asm/8253pit.h>
-static DEFINE_SPINLOCK(i8253_lock);
+static DEFINE_RAW_SPINLOCK(i8253_lock);
 #endif
 
 static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
@@ -50,7 +50,7 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c
        if (value > 20 && value < 32767)
                count = PIT_TICK_RATE / value;
 
-       spin_lock_irqsave(&i8253_lock, flags);
+       raw_spin_lock_irqsave(&i8253_lock, flags);
 
        if (count) {
                /* set command for counter 2, 2 byte write */
@@ -65,7 +65,7 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c
                outb(inb_p(0x61) & 0xFC, 0x61);
        }
 
-       spin_unlock_irqrestore(&i8253_lock, flags);
+       raw_spin_unlock_irqrestore(&i8253_lock, flags);
 
        return 0;
 }
index 4ae07935985e744f2987246ff04435034b81b5c8..1f8e0108962eff45fc03a1fc0257e39486f4aaed 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/rotary_encoder.h>
+#include <linux/slab.h>
 
 #define DRV_NAME "rotary-encoder"
 
index be3a15f5b25d85203b748a40af65defe02083e36..1a80c0dab83bce0204a6532413a759d830451fdc 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_SGI_IP22
 #include <asm/sgi/ioc.h>
index b064419b90a235fbe3ad58be8c25ab437252c6e0..0d45422f8095040f9354b3fe40d4a520218e7c88 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/of_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
index 2fb79e064da3d1b8cb348cbf5055a3a5b6927af4..fee9eac8e04ab830fbfb4fab89ef79b10138187a 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/i2c/twl.h>
 #include <linux/mfd/twl4030-codec.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 
 /* MODULE ID2 */
 #define LEDEN          0x00
index 9c155a43abc2afd811348f88808952cd9be59c75..64f1de7960c699845337ad1080c9deb78598f12a 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/io.h>
 #include <linux/bitrev.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 
 #define DRVNAME "winbond-cir"
 
index c0afb71a3a6d7a34919a8a32f98731a3b28e8001..04d5a4a3181ff847cbdfc9bf4bec1a5e9c8f1540 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/preempt.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/platform_device.h>
 #include <linux/leds.h>
index 1e54bce72db54d976f8cc882c61f71893bfb1776..c3d7ba5f5b47037c3b8c46b62ca7d6ad931e62db 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/input.h>
index 7490f1da4a532d8d04506320f840254deb91f351..99d58764ef03573e94c624625ae64f710d06ee69 100644 (file)
@@ -15,6 +15,7 @@
  * the Free Software Foundation.
  */
 
+#include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/libps2.h>
index 4f8fe0886b2a0470943eeb94625d375dd452cd1e..b89879bd860f6c08a0deb1ab5a02927b86c1ed5e 100644 (file)
@@ -803,7 +803,6 @@ static struct usb_driver bcm5974_driver = {
        .disconnect             = bcm5974_disconnect,
        .suspend                = bcm5974_suspend,
        .resume                 = bcm5974_resume,
-       .reset_resume           = bcm5974_resume,
        .id_table               = bcm5974_table,
        .supports_autosuspend   = 1,
 };
index b27684f267bf815ac30b2ba6fcd7deab01532b36..112b4ee52ff261160d61ae03b4b1ecc72528df11 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/input.h>
 #include <linux/serio.h>
                        printk(KERN_DEBUG format, ##arg);       \
        } while (0)
 
+static bool force_elantech;
+module_param_named(force_elantech, force_elantech, bool, 0644);
+MODULE_PARM_DESC(force_elantech, "Force the Elantech PS/2 protocol extension to be used, 1 = enabled, 0 = disabled (default).");
+
 /*
  * Send a Synaptics style sliced query command
  */
@@ -180,14 +185,18 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
        int fingers;
        static int old_fingers;
 
-       if (etd->fw_version_maj == 0x01) {
-               /* byte 0:  D   U  p1  p2   1  p3   R   L
-                  byte 1:  f   0  th  tw  x9  x8  y9  y8 */
+       if (etd->fw_version < 0x020000) {
+               /*
+                * byte 0:  D   U  p1  p2   1  p3   R   L
+                * byte 1:  f   0  th  tw  x9  x8  y9  y8
+                */
                fingers = ((packet[1] & 0x80) >> 7) +
                                ((packet[1] & 0x30) >> 4);
        } else {
-               /* byte 0: n1  n0  p2  p1   1  p3   R   L
-                  byte 1:  0   0   0   0  x9  x8  y9  y8 */
+               /*
+                * byte 0: n1  n0  p2  p1   1  p3   R   L
+                * byte 1:  0   0   0   0  x9  x8  y9  y8
+                */
                fingers = (packet[0] & 0xc0) >> 6;
        }
 
@@ -201,13 +210,15 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
 
        input_report_key(dev, BTN_TOUCH, fingers != 0);
 
-       /* byte 2: x7  x6  x5  x4  x3  x2  x1  x0
-          byte 3: y7  y6  y5  y4  y3  y2  y1  y0 */
+       /*
+        * byte 2: x7  x6  x5  x4  x3  x2  x1  x0
+        * byte 3: y7  y6  y5  y4  y3  y2  y1  y0
+        */
        if (fingers) {
                input_report_abs(dev, ABS_X,
                        ((packet[1] & 0x0c) << 6) | packet[2]);
-               input_report_abs(dev, ABS_Y, ETP_YMAX_V1 -
-                       (((packet[1] & 0x03) << 8) | packet[3]));
+               input_report_abs(dev, ABS_Y,
+                       ETP_YMAX_V1 - (((packet[1] & 0x03) << 8) | packet[3]));
        }
 
        input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
@@ -216,7 +227,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
        input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
        input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
 
-       if ((etd->fw_version_maj == 0x01) &&
+       if (etd->fw_version < 0x020000 &&
            (etd->capabilities & ETP_CAP_HAS_ROCKER)) {
                /* rocker up */
                input_report_key(dev, BTN_FORWARD, packet[0] & 0x40);
@@ -246,34 +257,47 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
 
        switch (fingers) {
        case 1:
-               /* byte 1: x15 x14 x13 x12 x11 x10 x9  x8
-                  byte 2: x7  x6  x5  x4  x4  x2  x1  x0 */
-               input_report_abs(dev, ABS_X, (packet[1] << 8) | packet[2]);
-               /* byte 4: y15 y14 y13 y12 y11 y10 y8  y8
-                  byte 5: y7  y6  y5  y4  y3  y2  y1  y0 */
-               input_report_abs(dev, ABS_Y, ETP_YMAX_V2 -
-                       ((packet[4] << 8) | packet[5]));
+               /*
+                * byte 1:  .   .   .   .   .  x10 x9  x8
+                * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
+                */
+               input_report_abs(dev, ABS_X,
+                       ((packet[1] & 0x07) << 8) | packet[2]);
+               /*
+                * byte 4:  .   .   .   .   .   .  y9  y8
+                * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
+                */
+               input_report_abs(dev, ABS_Y,
+                       ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5]));
                break;
 
        case 2:
-               /* The coordinate of each finger is reported separately with
-                  a lower resolution for two finger touches */
-               /* byte 0:  .   .  ay8 ax8  .   .   .   .
-                  byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 */
+               /*
+                * The coordinate of each finger is reported separately
+                * with a lower resolution for two finger touches:
+                * byte 0:  .   .  ay8 ax8  .   .   .   .
+                * byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0
+                */
                x1 = ((packet[0] & 0x10) << 4) | packet[1];
                /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */
                y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]);
-               /* byte 3:  .   .  by8 bx8  .   .   .   .
-                  byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 */
+               /*
+                * byte 3:  .   .  by8 bx8  .   .   .   .
+                * byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0
+                */
                x2 = ((packet[3] & 0x10) << 4) | packet[4];
                /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */
                y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]);
-               /* For compatibility with the X Synaptics driver scale up one
-                  coordinate and report as ordinary mouse movent */
+               /*
+                * For compatibility with the X Synaptics driver scale up
+                * one coordinate and report as ordinary mouse movent
+                */
                input_report_abs(dev, ABS_X, x1 << 2);
                input_report_abs(dev, ABS_Y, y1 << 2);
-               /* For compatibility with the proprietary X Elantech driver
-                  report both coordinates as hat coordinates */
+               /*
+                * For compatibility with the proprietary X Elantech driver
+                * report both coordinates as hat coordinates
+                */
                input_report_abs(dev, ABS_HAT0X, x1);
                input_report_abs(dev, ABS_HAT0Y, y1);
                input_report_abs(dev, ABS_HAT1X, x2);
@@ -297,7 +321,7 @@ static int elantech_check_parity_v1(struct psmouse *psmouse)
        unsigned char p1, p2, p3;
 
        /* Parity bits are placed differently */
-       if (etd->fw_version_maj == 0x01) {
+       if (etd->fw_version < 0x020000) {
                /* byte 0:  D   U  p1  p2   1  p3   R   L */
                p1 = (packet[0] & 0x20) >> 5;
                p2 = (packet[0] & 0x10) >> 4;
@@ -433,7 +457,7 @@ static void elantech_set_input_params(struct psmouse *psmouse)
        switch (etd->hw_version) {
        case 1:
                /* Rocker button */
-               if ((etd->fw_version_maj == 0x01) &&
+               if (etd->fw_version < 0x020000 &&
                    (etd->capabilities & ETP_CAP_HAS_ROCKER)) {
                        __set_bit(BTN_FORWARD, dev->keybit);
                        __set_bit(BTN_BACK, dev->keybit);
@@ -595,8 +619,12 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties)
                 param[0], param[1], param[2]);
 
        if (param[0] == 0 || param[1] != 0) {
-               pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n");
-               return -1;
+               if (!force_elantech) {
+                       pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n");
+                       return -1;
+               }
+
+               pr_debug("elantech.c: Probably not a real Elantech touchpad. Enabling anyway due to force_elantech.\n");
        }
 
        if (set_properties) {
@@ -658,14 +686,14 @@ int elantech_init(struct psmouse *psmouse)
                pr_err("elantech.c: failed to query firmware version.\n");
                goto init_fail;
        }
-       etd->fw_version_maj = param[0];
-       etd->fw_version_min = param[2];
+
+       etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2];
 
        /*
         * Assume every version greater than this is new EeePC style
         * hardware with 6 byte packets
         */
-       if (etd->fw_version_maj >= 0x02 && etd->fw_version_min >= 0x30) {
+       if (etd->fw_version >= 0x020030) {
                etd->hw_version = 2;
                /* For now show extra debug information */
                etd->debug = 1;
@@ -675,8 +703,9 @@ int elantech_init(struct psmouse *psmouse)
                etd->hw_version = 1;
                etd->paritycheck = 1;
        }
-       pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d\n",
-               etd->hw_version, etd->fw_version_maj, etd->fw_version_min);
+
+       pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d.%d\n",
+               etd->hw_version, param[0], param[1], param[2]);
 
        if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) {
                pr_err("elantech.c: failed to query capabilities.\n");
@@ -691,8 +720,8 @@ int elantech_init(struct psmouse *psmouse)
         * a touch action starts causing the mouse cursor or scrolled page
         * to jump. Enable a workaround.
         */
-       if (etd->fw_version_maj == 0x02 && etd->fw_version_min == 0x22) {
-               pr_info("elantech.c: firmware version 2.34 detected, "
+       if (etd->fw_version == 0x020022) {
+               pr_info("elantech.c: firmware version 2.0.34 detected, "
                        "enabling jumpy cursor workaround\n");
                etd->jumpy_cursor = 1;
        }
index feac5f7af966f5393b8dfaebeba2a7ceef31a70b..ac57bde1bb9f3e62fb3b891227521f0b63df3946 100644 (file)
@@ -100,11 +100,10 @@ struct elantech_data {
        unsigned char reg_26;
        unsigned char debug;
        unsigned char capabilities;
-       unsigned char fw_version_maj;
-       unsigned char fw_version_min;
-       unsigned char hw_version;
        unsigned char paritycheck;
        unsigned char jumpy_cursor;
+       unsigned char hw_version;
+       unsigned int  fw_version;
        unsigned char parity[256];
 };
 
index 9169d1591c1fea50c854c82a129bff8663d2fe12..08d66d820d2bfd94f17e736f58c3b0d3ec653e5c 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #define DEBUG
+#include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/libps2.h>
index 7c1d7d420ae3f1ae8ba19952cef65aac1fe99246..c31ad11df6bb11f5a3dbf77d000670ebd655ffbd 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/serio.h>
 #include <linux/libps2.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 
 #include "psmouse.h"
 #include "lifebook.h"
index d8c0c8d6992c92936db326dc28920350b899272d..a3c97315a4730fd5b26fc2c87313ab14f6450aee 100644 (file)
@@ -110,6 +110,7 @@ static struct workqueue_struct *kpsmoused_wq;
 struct psmouse_protocol {
        enum psmouse_type type;
        bool maxproto;
+       bool ignore_parity; /* Protocol should ignore parity errors from KBC */
        const char *name;
        const char *alias;
        int (*detect)(struct psmouse *, bool);
@@ -288,7 +289,9 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
        if (psmouse->state == PSMOUSE_IGNORE)
                goto out;
 
-       if (flags & (SERIO_PARITY|SERIO_TIMEOUT)) {
+       if (unlikely((flags & SERIO_TIMEOUT) ||
+                    ((flags & SERIO_PARITY) && !psmouse->ignore_parity))) {
+
                if (psmouse->state == PSMOUSE_ACTIVATED)
                        printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n",
                                flags & SERIO_TIMEOUT ? " timeout" : "",
@@ -759,6 +762,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
                .name           = "PS/2",
                .alias          = "bare",
                .maxproto       = true,
+               .ignore_parity  = true,
                .detect         = ps2bare_detect,
        },
 #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP
@@ -786,6 +790,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
                .name           = "ImPS/2",
                .alias          = "imps",
                .maxproto       = true,
+               .ignore_parity  = true,
                .detect         = intellimouse_detect,
        },
        {
@@ -793,6 +798,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
                .name           = "ImExPS/2",
                .alias          = "exps",
                .maxproto       = true,
+               .ignore_parity  = true,
                .detect         = im_explorer_detect,
        },
 #ifdef CONFIG_MOUSE_PS2_SYNAPTICS
@@ -1222,6 +1228,7 @@ static void psmouse_disconnect(struct serio *serio)
 static int psmouse_switch_protocol(struct psmouse *psmouse,
                                   const struct psmouse_protocol *proto)
 {
+       const struct psmouse_protocol *selected_proto;
        struct input_dev *input_dev = psmouse->dev;
 
        input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
@@ -1245,9 +1252,14 @@ static int psmouse_switch_protocol(struct psmouse *psmouse,
                        return -1;
 
                psmouse->type = proto->type;
-       } else
+               selected_proto = proto;
+       } else {
                psmouse->type = psmouse_extensions(psmouse,
                                                   psmouse_max_proto, true);
+               selected_proto = psmouse_protocol_by_type(psmouse->type);
+       }
+
+       psmouse->ignore_parity = selected_proto->ignore_parity;
 
        /*
         * If mouse's packet size is 3 there is no point in polling the
@@ -1267,7 +1279,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse,
                psmouse->resync_time = 0;
 
        snprintf(psmouse->devname, sizeof(psmouse->devname), "%s %s %s",
-                psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name);
+                selected_proto->name, psmouse->vendor, psmouse->name);
 
        input_dev->name = psmouse->devname;
        input_dev->phys = psmouse->phys;
@@ -1382,6 +1394,7 @@ static int psmouse_reconnect(struct serio *serio)
        struct psmouse *psmouse = serio_get_drvdata(serio);
        struct psmouse *parent = NULL;
        struct serio_driver *drv = serio->drv;
+       unsigned char type;
        int rc = -1;
 
        if (!drv || !psmouse) {
@@ -1401,10 +1414,15 @@ static int psmouse_reconnect(struct serio *serio)
        if (psmouse->reconnect) {
                if (psmouse->reconnect(psmouse))
                        goto out;
-       } else if (psmouse_probe(psmouse) < 0 ||
-                  psmouse->type != psmouse_extensions(psmouse,
-                                               psmouse_max_proto, false)) {
-               goto out;
+       } else {
+               psmouse_reset(psmouse);
+
+               if (psmouse_probe(psmouse) < 0)
+                       goto out;
+
+               type = psmouse_extensions(psmouse, psmouse_max_proto, false);
+               if (psmouse->type != type)
+                       goto out;
        }
 
        /* ok, the device type (and capabilities) match the old one,
index e053bdd137ff0c0a61b438571112b17ace545d1c..593e910bfc7a8ebe4c3dce7b30474df274fb3cd9 100644 (file)
@@ -47,6 +47,7 @@ struct psmouse {
        unsigned char pktcnt;
        unsigned char pktsize;
        unsigned char type;
+       bool ignore_parity;
        bool acks_disable_command;
        unsigned int model;
        unsigned long last;
index 1e827ad0afbedd58a36438cb1fe23e4a0ad3adf8..943cfec15665f336c2d21a481f55ffe4251d4ae5 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <mach/pxa930_trkball.h>
index 81a6b81cb2fe7c194a2250c7cd3366c910290f8f..1242775fee1938c498b3dda6da6e8acb6990c67b 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/libps2.h>
 #include <linux/serio.h>
 #include <linux/jiffies.h>
+#include <linux/slab.h>
 
 #include "psmouse.h"
 #include "sentelic.h"
index d3f5243fa093c8ce1152cd17f737250f0002c888..ebd7a99efeae98fcd295693901cb4a75f69fffcc 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/libps2.h>
+#include <linux/slab.h>
 #include "psmouse.h"
 #include "synaptics.h"
 
@@ -136,7 +137,8 @@ static int synaptics_capability(struct psmouse *psmouse)
        if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap))
                return -1;
        priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2];
-       priv->ext_cap = 0;
+       priv->ext_cap = priv->ext_cap_0c = 0;
+
        if (!SYN_CAP_VALID(priv->capabilities))
                return -1;
 
@@ -149,7 +151,7 @@ static int synaptics_capability(struct psmouse *psmouse)
        if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) {
                if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) {
                        printk(KERN_ERR "Synaptics claims to have extended capabilities,"
-                              " but I'm not able to read them.");
+                              " but I'm not able to read them.\n");
                } else {
                        priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2];
 
@@ -161,6 +163,16 @@ static int synaptics_capability(struct psmouse *psmouse)
                                priv->ext_cap &= 0xff0fff;
                }
        }
+
+       if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 4) {
+               if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB_0C, cap)) {
+                       printk(KERN_ERR "Synaptics claims to have extended capability 0x0c,"
+                              " but I'm not able to read it.\n");
+               } else {
+                       priv->ext_cap_0c = (cap[0] << 16) | (cap[1] << 8) | cap[2];
+               }
+       }
+
        return 0;
 }
 
@@ -347,7 +359,15 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data
                hw->left  = (buf[0] & 0x01) ? 1 : 0;
                hw->right = (buf[0] & 0x02) ? 1 : 0;
 
-               if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) {
+               if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
+                       /*
+                        * Clickpad's button is transmitted as middle button,
+                        * however, since it is primary button, we will report
+                        * it as BTN_LEFT.
+                        */
+                       hw->left = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
+
+               } else if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) {
                        hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
                        if (hw->w == 2)
                                hw->scroll = (signed char)(buf[1]);
@@ -592,6 +612,12 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
 
        dev->absres[ABS_X] = priv->x_res;
        dev->absres[ABS_Y] = priv->y_res;
+
+       if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
+               /* Clickpads report only left button */
+               __clear_bit(BTN_RIGHT, dev->keybit);
+               __clear_bit(BTN_MIDDLE, dev->keybit);
+       }
 }
 
 static void synaptics_disconnect(struct psmouse *psmouse)
@@ -696,10 +722,10 @@ int synaptics_init(struct psmouse *psmouse)
 
        priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
 
-       printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx\n",
+       printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n",
                SYN_ID_MODEL(priv->identity),
                SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity),
-               priv->model_id, priv->capabilities, priv->ext_cap);
+               priv->model_id, priv->capabilities, priv->ext_cap, priv->ext_cap_0c);
 
        set_input_params(psmouse->dev, priv);
 
index f0f40a331dc8ae7ede590deaddc08a95052d73d0..ae37c5d162a49f42dcd5e767d76f237f746f695f 100644 (file)
@@ -18,6 +18,7 @@
 #define SYN_QUE_SERIAL_NUMBER_SUFFIX   0x07
 #define SYN_QUE_RESOLUTION             0x08
 #define SYN_QUE_EXT_CAPAB              0x09
+#define SYN_QUE_EXT_CAPAB_0C           0x0c
 
 /* synatics modes */
 #define SYN_BIT_ABSOLUTE_MODE          (1 << 7)
@@ -48,6 +49,8 @@
 #define SYN_CAP_VALID(c)               ((((c) & 0x00ff00) >> 8) == 0x47)
 #define SYN_EXT_CAP_REQUESTS(c)                (((c) & 0x700000) >> 20)
 #define SYN_CAP_MULTI_BUTTON_NO(ec)    (((ec) & 0x00f000) >> 12)
+#define SYN_CAP_PRODUCT_ID(ec)         (((ec) & 0xff0000) >> 16)
+#define SYN_CAP_CLICKPAD(ex0c)         ((ex0c) & 0x100100)
 
 /* synaptics modes query bits */
 #define SYN_MODE_ABSOLUTE(m)           ((m) & (1 << 7))
@@ -96,6 +99,7 @@ struct synaptics_data {
        unsigned long int model_id;             /* Model-ID */
        unsigned long int capabilities;         /* Capabilities */
        unsigned long int ext_cap;              /* Extended Capabilities */
+       unsigned long int ext_cap_0c;           /* Ext Caps from 0x0c query */
        unsigned long int identity;             /* Identification */
        int x_res;                              /* X resolution in units/mm */
        int y_res;                              /* Y resolution in units/mm */
index 9867dfe2a638fd8b3ec345f9868f54433df6aa9e..8291e7399ffab3606d2563a8e7257e513b5179f6 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/input.h>
 #include <linux/delay.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME            "synaptics_i2c"
 /* maximum product id is 15 characters */
index 909431c31ab44a539591e6edc8210f70db2462b1..88121c59c3cc42d52f4eb37c7785ea9f90c7120f 100644 (file)
@@ -26,7 +26,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/slab.h>
 
 #include <linux/input.h>
 #include <linux/serio.h>
index 63d4a67830f2d9cda217544262abb6c27c83c162..0643e49ca6039ea239e777c0b7f695040fed53bb 100644 (file)
@@ -8,6 +8,7 @@
  * Trademarks are the property of their respective owners.
  */
 
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/serio.h>
 #include <linux/module.h>
index 320b7ca48bf8567a5c1bbdbb114ce971dcb8a960..7998560a1904cd7f98e72d763c65c4176afb8bd4 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #define DRV_NAME "altera_ps2"
 
index b54452a8c77141043011c3329ea5c70c5452597f..6ee8f0ddad51abe615325f8335a02ec99fb311e2 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 /* PSIF register offsets */
 #define PSIF_CR                                0x00
index d1380fc72cc6ee5c81da9ecd093085de57fa0930..4a3084695c00b554af42be46075047c9c5d9538c 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
index 06addfa7cc47b639979a64a272b75e2f6841d8e6..3c287dd879d32be0b68f732ab020974c38ac10f5 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/serio.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
index 6cd03ebaf5fb39e6dfb8db0445f02b4ffdf552b4..c92f4edfee7beef3a326e0af4e43275093fba8dc 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/list.h>
 
index 9302ba0e48f814ea730f5c681cf3a3add3489412..6440a8f55686de28141235cf80e3a72e2742d52a 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/rcupdate.h>
 #include <linux/platform_device.h>
 #include <linux/i8042.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
@@ -38,7 +39,7 @@ MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port.");
 
 static bool i8042_nomux;
 module_param_named(nomux, i8042_nomux, bool, 0);
-MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing conrtoller is present.");
+MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing controller is present.");
 
 static bool i8042_unlock;
 module_param_named(unlock, i8042_unlock, bool, 0);
index f3876acc3e8394e4810fcf16a67773fe96cdc0e1..980af94ba9c822aef9fc520ac41962c9b0d249a2 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/serio.h>
index b089977e0ef96b76895d9f12f47991287ff0a2bd..26b45936f9fdf3334c6f083aeaa7c5ee5bb178dd 100644 (file)
@@ -46,6 +46,7 @@
 
 #include <linux/module.h>
 #include <linux/parport.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/serio.h>
 
index 797314be7af2ffadc6361a44f7d87403fda419ed..43494742541c380a4d672134fe38fd052db182fe 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/ioport.h>
 #include <linux/input.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/serio.h>
 #include <linux/delay.h>
index e36a0901646cb2d2d91be060771946af9d60f75b..5eb84b3b67fbb7b69776fa33b15db6a690818a1f 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/err.h>
 #include <linux/bitops.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
index ed045c99f84b017d7ac4b252e5e5d33f329577e2..9da6fbcaaa7e8d2ffbc0b7d3c84abee821d5d5e3 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 #include <mach/hardware.h>
index 8298e1f68234df7cbd33afbc4d452595155530c0..f84f8e32e3f1789fac1655752eeb051b3139cb93 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/serio.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/io.h>
index e6bde55e5203c06f651dfaa7e6ef7f1cfc1633a8..014248344763775b49285db0a480e794f5c76c2e 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
+#include <linux/slab.h>
 
 MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
 MODULE_DESCRIPTION("Generic support for sparse keymaps");
@@ -67,12 +68,14 @@ static int sparse_keymap_getkeycode(struct input_dev *dev,
                                    unsigned int scancode,
                                    unsigned int *keycode)
 {
-       const struct key_entry *key =
-                       sparse_keymap_entry_from_scancode(dev, scancode);
+       const struct key_entry *key;
 
-       if (key && key->type == KE_KEY) {
-               *keycode = key->keycode;
-               return 0;
+       if (dev->keycode) {
+               key = sparse_keymap_entry_from_scancode(dev, scancode);
+               if (key && key->type == KE_KEY) {
+                       *keycode = key->keycode;
+                       return 0;
+               }
        }
 
        return -EINVAL;
@@ -85,17 +88,16 @@ static int sparse_keymap_setkeycode(struct input_dev *dev,
        struct key_entry *key;
        int old_keycode;
 
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
-
-       key = sparse_keymap_entry_from_scancode(dev, scancode);
-       if (key && key->type == KE_KEY) {
-               old_keycode = key->keycode;
-               key->keycode = keycode;
-               set_bit(keycode, dev->keybit);
-               if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
-                       clear_bit(old_keycode, dev->keybit);
-               return 0;
+       if (dev->keycode) {
+               key = sparse_keymap_entry_from_scancode(dev, scancode);
+               if (key && key->type == KE_KEY) {
+                       old_keycode = key->keycode;
+                       key->keycode = keycode;
+                       set_bit(keycode, dev->keybit);
+                       if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
+                               clear_bit(old_keycode, dev->keybit);
+                       return 0;
+               }
        }
 
        return -EINVAL;
@@ -163,7 +165,7 @@ int sparse_keymap_setup(struct input_dev *dev,
        return 0;
 
  err_out:
-       kfree(keymap);
+       kfree(map);
        return error;
 
 }
@@ -175,14 +177,27 @@ EXPORT_SYMBOL(sparse_keymap_setup);
  *
  * This function is used to free memory allocated by sparse keymap
  * in an input device that was set up by sparse_keymap_setup().
+ * NOTE: It is safe to cal this function while input device is
+ * still registered (however the drivers should care not to try to
+ * use freed keymap and thus have to shut off interrups/polling
+ * before freeing the keymap).
  */
 void sparse_keymap_free(struct input_dev *dev)
 {
+       unsigned long flags;
+
+       /*
+        * Take event lock to prevent racing with input_get_keycode()
+        * and input_set_keycode() if we are called while input device
+        * is still registered.
+        */
+       spin_lock_irqsave(&dev->event_lock, flags);
+
        kfree(dev->keycode);
        dev->keycode = NULL;
        dev->keycodemax = 0;
-       dev->getkeycode = NULL;
-       dev->setkeycode = NULL;
+
+       spin_unlock_irqrestore(&dev->event_lock, flags);
 }
 EXPORT_SYMBOL(sparse_keymap_free);
 
index 8b5d2873f0c4d4f562b39c3cb929bbba635986ea..f46502589e4eaef0ef92eb0ee6d9a127ab714d83 100644 (file)
@@ -673,13 +673,15 @@ static int wacom_resume(struct usb_interface *intf)
        int rv;
 
        mutex_lock(&wacom->lock);
-       if (wacom->open) {
+
+       /* switch to wacom mode first */
+       wacom_query_tablet_data(intf, features);
+
+       if (wacom->open)
                rv = usb_submit_urb(wacom->irq, GFP_NOIO);
-               /* switch to wacom mode if needed */
-               if (!wacom_retrieve_hid_descriptor(intf, features))
-                       wacom_query_tablet_data(intf, features);
-       } else
+       else
                rv = 0;
+
        mutex_unlock(&wacom->lock);
 
        return rv;
index b3ba3437a2eb87cc7e2d713933c73861626da2b6..4a852d815c68169c79c792dd6078c9cd5ce131b4 100644 (file)
@@ -155,19 +155,19 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 {
        struct wacom_features *features = &wacom->features;
        unsigned char *data = wacom->data;
-       int x, y, prox;
-       int rw = 0;
-       int retval = 0;
+       int x, y, rw;
+       static int penData = 0;
 
        if (data[0] != WACOM_REPORT_PENABLED) {
                dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
-               goto exit;
+               return 0;
        }
 
-       prox = data[1] & 0x80;
-       if (prox || wacom->id[0]) {
-               if (prox) {
-                       switch ((data[1] >> 5) & 3) {
+       if (data[1] & 0x80) {
+               /* in prox and not a pad data */
+               penData = 1;
+
+               switch ((data[1] >> 5) & 3) {
 
                        case 0: /* Pen */
                                wacom->tool[0] = BTN_TOOL_PEN;
@@ -181,13 +181,23 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 
                        case 2: /* Mouse with wheel */
                                wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04);
+                               if (features->type == WACOM_G4 || features->type == WACOM_MO) {
+                                       rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03);
+                                       wacom_report_rel(wcombo, REL_WHEEL, -rw);
+                               } else
+                                       wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]);
                                /* fall through */
 
                        case 3: /* Mouse without wheel */
                                wacom->tool[0] = BTN_TOOL_MOUSE;
                                wacom->id[0] = CURSOR_DEVICE_ID;
+                               wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
+                               wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
+                               if (features->type == WACOM_G4 || features->type == WACOM_MO)
+                                       wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
+                               else
+                                       wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
                                break;
-                       }
                }
                x = wacom_le16_to_cpu(&data[2]);
                y = wacom_le16_to_cpu(&data[4]);
@@ -198,32 +208,36 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01);
                        wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
                        wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
-               } else {
-                       wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
-                       wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
-                       if (features->type == WACOM_G4 ||
-                                       features->type == WACOM_MO) {
-                               wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
-                               rw = (signed)(data[7] & 0x04) - (data[7] & 0x03);
-                       } else {
-                               wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
-                               rw = -(signed)data[6];
-                       }
-                       wacom_report_rel(wcombo, REL_WHEEL, rw);
                }
-
-               if (!prox)
-                       wacom->id[0] = 0;
                wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
-               wacom_report_key(wcombo, wacom->tool[0], prox);
-               wacom_input_sync(wcombo); /* sync last event */
+               wacom_report_key(wcombo, wacom->tool[0], 1);
+       } else if (wacom->id[0]) {
+               wacom_report_abs(wcombo, ABS_X, 0);
+               wacom_report_abs(wcombo, ABS_Y, 0);
+               if (wacom->tool[0] == BTN_TOOL_MOUSE) {
+                       wacom_report_key(wcombo, BTN_LEFT, 0);
+                       wacom_report_key(wcombo, BTN_RIGHT, 0);
+                       wacom_report_abs(wcombo, ABS_DISTANCE, 0);
+               } else {
+                       wacom_report_abs(wcombo, ABS_PRESSURE, 0);
+                       wacom_report_key(wcombo, BTN_TOUCH, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS2, 0);
+               }
+               wacom->id[0] = 0;
+               wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
+               wacom_report_key(wcombo, wacom->tool[0], 0);
        }
 
        /* send pad data */
        switch (features->type) {
            case WACOM_G4:
-               prox = data[7] & 0xf8;
-               if (prox || wacom->id[1]) {
+               if (data[7] & 0xf8) {
+                       if (penData) {
+                               wacom_input_sync(wcombo); /* sync last event */
+                               if (!wacom->id[0])
+                                       penData = 0;
+                       }
                        wacom->id[1] = PAD_DEVICE_ID;
                        wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
                        wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
@@ -231,16 +245,29 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_rel(wcombo, REL_WHEEL, rw);
                        wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
                        wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
-                       if (!prox)
-                               wacom->id[1] = 0;
-                       wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
+                       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
+               } else if (wacom->id[1]) {
+                       if (penData) {
+                               wacom_input_sync(wcombo); /* sync last event */
+                               if (!wacom->id[0])
+                                       penData = 0;
+                       }
+                       wacom->id[1] = 0;
+                       wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
+                       wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
+                       wacom_report_rel(wcombo, REL_WHEEL, 0);
+                       wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
+                       wacom_report_abs(wcombo, ABS_MISC, 0);
                        wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
                }
-               retval = 1;
                break;
            case WACOM_MO:
-               prox = (data[7] & 0xf8) || data[8];
-               if (prox || wacom->id[1]) {
+               if ((data[7] & 0xf8) || (data[8] & 0xff)) {
+                       if (penData) {
+                               wacom_input_sync(wcombo); /* sync last event */
+                               if (!wacom->id[0])
+                                       penData = 0;
+                       }
                        wacom->id[1] = PAD_DEVICE_ID;
                        wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
                        wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
@@ -248,16 +275,27 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
                        wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
                        wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
-                       if (!prox)
-                               wacom->id[1] = 0;
                        wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
                        wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
+               } else if (wacom->id[1]) {
+                       if (penData) {
+                               wacom_input_sync(wcombo); /* sync last event */
+                               if (!wacom->id[0])
+                                       penData = 0;
+                       }
+                       wacom->id[1] = 0;
+                       wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
+                       wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
+                       wacom_report_key(wcombo, BTN_4, (data[7] & 0x10));
+                       wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
+                       wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
+                       wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
+                       wacom_report_abs(wcombo, ABS_MISC, 0);
+                       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
                }
-               retval = 1;
                break;
        }
-exit:
-       return retval;
+       return 1;
 }
 
 static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
@@ -598,9 +636,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
 static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx)
 {
        wacom_report_abs(wcombo, ABS_X,
-               data[2 + idx * 2] | ((data[3 + idx * 2] & 0x7f) << 8));
+               (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8));
        wacom_report_abs(wcombo, ABS_Y,
-               data[6 + idx * 2] | ((data[7 + idx * 2] & 0x7f) << 8));
+               (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8));
        wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
        wacom_report_key(wcombo, wacom->tool[idx], 1);
        if (idx)
@@ -744,24 +782,31 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
 
                touchInProx = 0;
 
-               if (!wacom->id[0]) { /* first in prox */
-                       /* Going into proximity select tool */
-                       wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
-                       if (wacom->tool[0] == BTN_TOOL_PEN)
-                               wacom->id[0] = STYLUS_DEVICE_ID;
-                       else
-                               wacom->id[0] = ERASER_DEVICE_ID;
-               }
-               wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
-               wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
-               wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
-               wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
-               pressure = ((data[7] & 0x01) << 8) | data[6];
-               if (pressure < 0)
-                       pressure = features->pressure_max + pressure + 1;
-               wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
-               wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
-               if (!prox) { /* out-prox */
+               if (prox) { /* in prox */
+                       if (!wacom->id[0]) {
+                               /* Going into proximity select tool */
+                               wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
+                               if (wacom->tool[0] == BTN_TOOL_PEN)
+                                       wacom->id[0] = STYLUS_DEVICE_ID;
+                               else
+                                       wacom->id[0] = ERASER_DEVICE_ID;
+                       }
+                       wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
+                       wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
+                       wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
+                       wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
+                       pressure = ((data[7] & 0x01) << 8) | data[6];
+                       if (pressure < 0)
+                               pressure = features->pressure_max + pressure + 1;
+                       wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
+                       wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
+               } else {
+                       wacom_report_abs(wcombo, ABS_X, 0);
+                       wacom_report_abs(wcombo, ABS_Y, 0);
+                       wacom_report_abs(wcombo, ABS_PRESSURE, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS2, 0);
+                       wacom_report_key(wcombo, BTN_TOUCH, 0);
                        wacom->id[0] = 0;
                        /* pen is out so touch can be enabled now */
                        touchInProx = 1;
index 286bb490a9f29cd16e37b4bbf5b3b0940070a272..b3aebc2166ba666256fd083da1f5c733545530fc 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/i2c.h>
 #include <linux/input.h>
 #include <linux/mfd/88pm860x.h>
+#include <linux/slab.h>
 
 #define MEAS_LEN               (8)
 #define ACCURATE_BIT           (12)
index e019d53d1ab4249f4356a9ed75d1c0ab065fe3fb..0d2d7e54b465a2d06d63e777acb260f4698f0239 100644 (file)
@@ -156,9 +156,14 @@ struct ser_req {
        u16                     reset;
        u16                     ref_on;
        u16                     command;
-       u16                     sample;
        struct spi_message      msg;
        struct spi_transfer     xfer[6];
+
+       /*
+        * DMA (thus cache coherency maintenance) requires the
+        * transfer buffers to live in their own cache lines.
+        */
+       u16 sample ____cacheline_aligned;
 };
 
 struct ad7877 {
@@ -182,8 +187,6 @@ struct ad7877 {
        u8                      averaging;
        u8                      pen_down_acc_interval;
 
-       u16                     conversion_data[AD7877_NR_SENSE];
-
        struct spi_transfer     xfer[AD7877_NR_SENSE + 2];
        struct spi_message      msg;
 
@@ -195,6 +198,12 @@ struct ad7877 {
        spinlock_t              lock;
        struct timer_list       timer;          /* P: lock */
        unsigned                pending:1;      /* P: lock */
+
+       /*
+        * DMA (thus cache coherency maintenance) requires the
+        * transfer buffers to live in their own cache lines.
+        */
+       u16 conversion_data[AD7877_NR_SENSE] ____cacheline_aligned;
 };
 
 static int gpio3;
index a12242f77e23c3937730c07488dc57e0a5ca0901..fa8e56bd9094ec8df9ac43119a5a2213c4785f09 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/timer.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #define AC97C_ICA              0x10
 #define AC97C_CBRHR            0x30
index 3ffd4c4b170c6ae21354e191d2483637e4048224..2b72a5923c16a41f9cfbd1400f958f736842fd6f 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/input.h>
 #include <linux/workqueue.h>
 #include <linux/mfd/da903x.h>
+#include <linux/slab.h>
 
 #define DA9034_MANUAL_CTRL     0x50
 #define DA9034_LDO_ADC_EN      (1 << 4)
index 9029bd3f34e5ee9b5c12e3ef41c04c09001a45b1..75f8b73010fa5aa30dd3758a7421697b16c03e46 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/timer.h>
 #include <linux/gpio.h>
 #include <linux/input/eeti_ts.h>
+#include <linux/slab.h>
 
 static int flip_x;
 module_param(flip_x, bool, 0644);
@@ -123,14 +124,25 @@ static irqreturn_t eeti_ts_isr(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static int eeti_ts_open(struct input_dev *dev)
+static void eeti_ts_start(struct eeti_ts_priv *priv)
 {
-       struct eeti_ts_priv *priv = input_get_drvdata(dev);
-
        enable_irq(priv->irq);
 
        /* Read the events once to arm the IRQ */
        eeti_ts_read(&priv->work);
+}
+
+static void eeti_ts_stop(struct eeti_ts_priv *priv)
+{
+       disable_irq(priv->irq);
+       cancel_work_sync(&priv->work);
+}
+
+static int eeti_ts_open(struct input_dev *dev)
+{
+       struct eeti_ts_priv *priv = input_get_drvdata(dev);
+
+       eeti_ts_start(priv);
 
        return 0;
 }
@@ -139,8 +151,7 @@ static void eeti_ts_close(struct input_dev *dev)
 {
        struct eeti_ts_priv *priv = input_get_drvdata(dev);
 
-       disable_irq(priv->irq);
-       cancel_work_sync(&priv->work);
+       eeti_ts_stop(priv);
 }
 
 static int __devinit eeti_ts_probe(struct i2c_client *client,
@@ -152,10 +163,12 @@ static int __devinit eeti_ts_probe(struct i2c_client *client,
        unsigned int irq_flags;
        int err = -ENOMEM;
 
-       /* In contrast to what's described in the datasheet, there seems
+       /*
+        * In contrast to what's described in the datasheet, there seems
         * to be no way of probing the presence of that device using I2C
         * commands. So we need to blindly believe it is there, and wait
-        * for interrupts to occur. */
+        * for interrupts to occur.
+        */
 
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv) {
@@ -211,9 +224,11 @@ static int __devinit eeti_ts_probe(struct i2c_client *client,
                goto err2;
        }
 
-       /* Disable the irq for now. It will be enabled once the input device
-        * is opened. */
-       disable_irq(priv->irq);
+       /*
+        * Disable the device for now. It will be enabled once the
+        * input device is opened.
+        */
+       eeti_ts_stop(priv);
 
        device_init_wakeup(&client->dev, 0);
        return 0;
@@ -234,6 +249,12 @@ static int __devexit eeti_ts_remove(struct i2c_client *client)
        struct eeti_ts_priv *priv = i2c_get_clientdata(client);
 
        free_irq(priv->irq, priv);
+       /*
+        * eeti_ts_stop() leaves IRQ disabled. We need to re-enable it
+        * so that device still works if we reload the driver.
+        */
+       enable_irq(priv->irq);
+
        input_unregister_device(priv->input);
        i2c_set_clientdata(client, NULL);
        kfree(priv);
@@ -245,6 +266,14 @@ static int __devexit eeti_ts_remove(struct i2c_client *client)
 static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg)
 {
        struct eeti_ts_priv *priv = i2c_get_clientdata(client);
+       struct input_dev *input_dev = priv->input;
+
+       mutex_lock(&input_dev->mutex);
+
+       if (input_dev->users)
+               eeti_ts_stop(priv);
+
+       mutex_unlock(&input_dev->mutex);
 
        if (device_may_wakeup(&client->dev))
                enable_irq_wake(priv->irq);
@@ -255,10 +284,18 @@ static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg)
 static int eeti_ts_resume(struct i2c_client *client)
 {
        struct eeti_ts_priv *priv = i2c_get_clientdata(client);
+       struct input_dev *input_dev = priv->input;
 
        if (device_may_wakeup(&client->dev))
                disable_irq_wake(priv->irq);
 
+       mutex_lock(&input_dev->mutex);
+
+       if (input_dev->users)
+               eeti_ts_start(priv);
+
+       mutex_unlock(&input_dev->mutex);
+
        return 0;
 }
 #else
index c8b7e8a45c4d91292c09afeb239be90efe598c79..4b0a061811ffabea4e17630b6b9b01fa31934466 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <mach/jornada720.h>
index be54fd639acaedad630ff0ab0343c44d9d29ea86..c5bc62d85bb6e1987ebd1377888de3f1ddfa6a79 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/input.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #define MC13783_TS_NAME        "mc13783-ts"
index 4c28b89757f9ebf0fbe3505cf8964afeb79287b1..ce8ab0269f6fc755f6496e90a5a4cd4c8157b816 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 
 /* Registers */
 #define MCS5000_TS_STATUS              0x00
index 141dd584330ee1106f4557a24faf3cab54048619..defe5dd3627ce98d84104ef3ffea64214ee173fc 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/i2c.h>
 #include <linux/timer.h>
index b79097e3028a10e381f1c259c78ce0259985f2f1..ea6ef16e59b428e9b7338ce57bde07d51bbb44e0 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/pm.h>
 #include <linux/timer.h>
 #include <linux/interrupt.h>
index 3755a47d053caea796fd4650c18889e0f7ea4fa4..98a7d1279486f1fb4ad7dca35314b7d021b9f6f3 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/input.h>
 #include <linux/init.h>
index 89dcbe7b4b02c770dc32c1ed753547eadf6dee05..028a5363eea14612a15dee19f0f61c858d4fe87a 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/suspend.h>
-#include <linux/slab.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/ucb1400.h>
index 6ccbdbbf33fec2725fc9495b0271af7aa82b81f5..cc18265be1a8f2266480f93841c0530d3e180cea 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/clk.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 /* ADC controller bit defines */
 #define ADC_DELAY      0xf00
index f944918466e5bd24d2909a0081b975cb3be770f7..5109bf3dd8587b79ba735dba8e0e2ed6c0cb12a5 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/wm97xx.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #define TS_NAME                        "wm97xx"
 #define WM_CORE_VERSION                "1.00"
index d30436fee4760f02486e952e9468af375432161c..e14081675bb2b5a8709570ad45e657a30381f3fb 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 
 #include <asm/xen/hypervisor.h>
 
index f774e12bb64dc4cbf816c27878813e844a814c19..05ed72c4cf59f60413950411b82fbe2e9766809c 100644 (file)
@@ -16,6 +16,7 @@
 #include "act2000_isa.h"
 #include "capi.h"
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 static unsigned short act2000_isa_ports[] =
index 8596bd1a4d26536ebf340aa43ef3ef56b31c01fa..2b83850997c3903df974e6088b81854e9d5c1ebb 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/fs.h>
 #include <linux/mount.h>
+#include <linux/slab.h>
 #include <linux/namei.h>
 #include <linux/module.h>
 #include <linux/init.h>
index fcaa1241ee7714bb835aa7d7b0db648c50e19a45..0b041df2108c644340eb937c4a9ccc7615b5a8f1 100644 (file)
@@ -1,4 +1,5 @@
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/isdn/capilli.h>
index 26626eead82857408fb7729e1f59b530b5a6d2b3..03c469e4451feae3102f96994420ebfddd1223ce 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/isdn/capiutil.h>
+#include <linux/slab.h>
 
 /* from CAPI2.0 DDK AVM Berlin GmbH */
 
index ce9b05b9e93a93ab6974ddf714a28fa3867299b3..bd00dceacaf0d6cac10a1ab8da423264f706a313 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/moduleparam.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/isdn/capicmd.h>
 #include <linux/isdn/capiutil.h>
index 3697c409bec66d5b9c2dbe0b31577f22fef2ef1c..9f49d906579177430c463d03f78dbe514237def5 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #ifdef CONFIG_PROC_FS
 #include <linux/proc_fs.h>
 #else
index 77e9fdda0597381741691709529c2006a994fc8c..70cf6bac7a5aa1041cfa6067df7a62c1964debd5 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/jiffies.h>
 
index 0be15c70c16d65d28a3882f44ca84b1be33d3b48..47a5ffec55a393173de8fd01ef8019b2d7115bdd 100644 (file)
  */
 
 #include "gigaset.h"
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/timer.h>
 #include <linux/usb.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
index 6643d6533ccb98d9a8a49502d8ae3f69f68a9693..964a55fb148608b57f99b30db5b2c859654e7cf6 100644 (file)
@@ -12,7 +12,6 @@
  */
 
 #include "gigaset.h"
-#include <linux/ctype.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/isdn/capilli.h>
@@ -1301,7 +1300,7 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
        }
 
        /* check parameter: CIP Value */
-       if (cmsg->CIPValue > ARRAY_SIZE(cip2bchlc) ||
+       if (cmsg->CIPValue >= ARRAY_SIZE(cip2bchlc) ||
            (cmsg->CIPValue > 0 && cip2bchlc[cmsg->CIPValue].bc == NULL)) {
                dev_notice(cs->dev, "%s: unknown CIP value %d\n",
                           "CONNECT_REQ", cmsg->CIPValue);
@@ -2191,36 +2190,24 @@ static const struct file_operations gigaset_proc_fops = {
        .release        = single_release,
 };
 
-static struct capi_driver capi_driver_gigaset = {
-       .name           = "gigaset",
-       .revision       = "1.0",
-};
-
 /**
- * gigaset_isdn_register() - register to LL
+ * gigaset_isdn_regdev() - register device to LL
  * @cs:                device descriptor structure.
  * @isdnid:    device name.
  *
- * Called by main module to register the device with the LL.
- *
  * Return value: 1 for success, 0 for failure
  */
-int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
+int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
 {
        struct gigaset_capi_ctr *iif;
        int rc;
 
-       pr_info("Kernel CAPI interface\n");
-
        iif = kmalloc(sizeof(*iif), GFP_KERNEL);
        if (!iif) {
                pr_err("%s: out of memory\n", __func__);
                return 0;
        }
 
-       /* register driver with CAPI (ToDo: what for?) */
-       register_capi_driver(&capi_driver_gigaset);
-
        /* prepare controller structure */
        iif->ctr.owner         = THIS_MODULE;
        iif->ctr.driverdata    = cs;
@@ -2241,7 +2228,6 @@ int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
        rc = attach_capi_ctr(&iif->ctr);
        if (rc) {
                pr_err("attach_capi_ctr failed (%d)\n", rc);
-               unregister_capi_driver(&capi_driver_gigaset);
                kfree(iif);
                return 0;
        }
@@ -2252,17 +2238,36 @@ int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
 }
 
 /**
- * gigaset_isdn_unregister() - unregister from LL
+ * gigaset_isdn_unregdev() - unregister device from LL
  * @cs:                device descriptor structure.
- *
- * Called by main module to unregister the device from the LL.
  */
-void gigaset_isdn_unregister(struct cardstate *cs)
+void gigaset_isdn_unregdev(struct cardstate *cs)
 {
        struct gigaset_capi_ctr *iif = cs->iif;
 
        detach_capi_ctr(&iif->ctr);
        kfree(iif);
        cs->iif = NULL;
+}
+
+static struct capi_driver capi_driver_gigaset = {
+       .name           = "gigaset",
+       .revision       = "1.0",
+};
+
+/**
+ * gigaset_isdn_regdrv() - register driver to LL
+ */
+void gigaset_isdn_regdrv(void)
+{
+       pr_info("Kernel CAPI interface\n");
+       register_capi_driver(&capi_driver_gigaset);
+}
+
+/**
+ * gigaset_isdn_unregdrv() - unregister driver from LL
+ */
+void gigaset_isdn_unregdrv(void)
+{
        unregister_capi_driver(&capi_driver_gigaset);
 }
index 85de3399a2f2dfb005cba5f0c0d89d6af491bab1..f6f45f2219209781aa6955153d494060f7f941ff 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include "gigaset.h"
-#include <linux/ctype.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 
@@ -507,7 +506,7 @@ void gigaset_freecs(struct cardstate *cs)
        case 2: /* error in initcshw */
                /* Deregister from LL */
                make_invalid(cs, VALID_ID);
-               gigaset_isdn_unregister(cs);
+               gigaset_isdn_unregdev(cs);
 
                /* fall through */
        case 1: /* error when registering to LL */
@@ -769,7 +768,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
        cs->cmdbytes = 0;
 
        gig_dbg(DEBUG_INIT, "setting up iif");
-       if (!gigaset_isdn_register(cs, modulename)) {
+       if (!gigaset_isdn_regdev(cs, modulename)) {
                pr_err("error registering ISDN device\n");
                goto error;
        }
@@ -1205,11 +1204,13 @@ static int __init gigaset_init_module(void)
                gigaset_debuglevel = DEBUG_DEFAULT;
 
        pr_info(DRIVER_DESC DRIVER_DESC_DEBUG "\n");
+       gigaset_isdn_regdrv();
        return 0;
 }
 
 static void __exit gigaset_exit_module(void)
 {
+       gigaset_isdn_unregdrv();
 }
 
 module_init(gigaset_init_module);
index 5b27c996af6db6ffaa9c42ae32346f3f52b2f42f..bd0b1eaa7572bf785368d7e9fa013c9b93cc10ae 100644 (file)
@@ -57,12 +57,20 @@ void gigaset_isdn_stop(struct cardstate *cs)
 {
 }
 
-int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
+int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
 {
-       pr_info("no ISDN subsystem interface\n");
        return 1;
 }
 
-void gigaset_isdn_unregister(struct cardstate *cs)
+void gigaset_isdn_unregdev(struct cardstate *cs)
+{
+}
+
+void gigaset_isdn_regdrv(void)
+{
+       pr_info("no ISDN subsystem interface\n");
+}
+
+void gigaset_isdn_unregdrv(void)
 {
 }
index c8f89b78b233525267a7cfba0d34ced7a7595a1e..206c380c52358c724aa72a06ce6c7405d9ff7164 100644 (file)
@@ -1258,14 +1258,10 @@ static void do_action(int action, struct cardstate *cs,
                 * note that bcs may be NULL if no B channel is free
                 */
                at_state2->ConState = 700;
-               kfree(at_state2->str_var[STR_NMBR]);
-               at_state2->str_var[STR_NMBR] = NULL;
-               kfree(at_state2->str_var[STR_ZCPN]);
-               at_state2->str_var[STR_ZCPN] = NULL;
-               kfree(at_state2->str_var[STR_ZBC]);
-               at_state2->str_var[STR_ZBC] = NULL;
-               kfree(at_state2->str_var[STR_ZHLC]);
-               at_state2->str_var[STR_ZHLC] = NULL;
+               for (i = 0; i < STR_NUM; ++i) {
+                       kfree(at_state2->str_var[i]);
+                       at_state2->str_var[i] = NULL;
+               }
                at_state2->int_var[VAR_ZCTP] = -1;
 
                spin_lock_irqsave(&cs->lock, flags);
index 1875ab80b3355c16e8e836655276919dd5ca1b10..05947f9c18496b8b9b197cbe61c6696f450ca24d 100644 (file)
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kernel.h>
+#include <linux/sched.h>
 #include <linux/compiler.h>
 #include <linux/types.h>
+#include <linux/ctype.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <linux/usb.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/ppp_defs.h>
@@ -675,8 +677,10 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size);
  */
 
 /* Called from common.c for setting up/shutting down with the ISDN subsystem */
-int gigaset_isdn_register(struct cardstate *cs, const char *isdnid);
-void gigaset_isdn_unregister(struct cardstate *cs);
+void gigaset_isdn_regdrv(void);
+void gigaset_isdn_unregdrv(void);
+int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid);
+void gigaset_isdn_unregdev(struct cardstate *cs);
 
 /* Called from hardware module to indicate completion of an skb */
 void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb);
index f0acb9dc9e33cb1725f98f6c9da6fde57315b418..c22e5ace8276a99fe39188eb13941e56f6b07cb4 100644 (file)
@@ -592,15 +592,13 @@ void gigaset_isdn_stop(struct cardstate *cs)
 }
 
 /**
- * gigaset_isdn_register() - register to LL
+ * gigaset_isdn_regdev() - register to LL
  * @cs:                device descriptor structure.
  * @isdnid:    device name.
  *
- * Called by main module to register the device with the LL.
- *
  * Return value: 1 for success, 0 for failure
  */
-int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
+int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
 {
        isdn_if *iif;
 
@@ -650,15 +648,29 @@ int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
 }
 
 /**
- * gigaset_isdn_unregister() - unregister from LL
+ * gigaset_isdn_unregdev() - unregister device from LL
  * @cs:                device descriptor structure.
- *
- * Called by main module to unregister the device from the LL.
  */
-void gigaset_isdn_unregister(struct cardstate *cs)
+void gigaset_isdn_unregdev(struct cardstate *cs)
 {
        gig_dbg(DEBUG_CMD, "sending UNLOAD");
        gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD);
        kfree(cs->iif);
        cs->iif = NULL;
 }
+
+/**
+ * gigaset_isdn_regdrv() - register driver to LL
+ */
+void gigaset_isdn_regdrv(void)
+{
+       /* nothing to do */
+}
+
+/**
+ * gigaset_isdn_unregdrv() - unregister driver from LL
+ */
+void gigaset_isdn_unregdrv(void)
+{
+       /* nothing to do */
+}
index a1bcbc21ff718c493a8cbc2256d801083e34cbeb..c9f28dd40d5c463d1d12821e47965655da123097 100644 (file)
@@ -13,7 +13,6 @@
 
 #include "gigaset.h"
 #include <linux/gigaset_dev.h>
-#include <linux/tty.h>
 #include <linux/tty_flip.h>
 
 /*** our ioctls ***/
@@ -628,7 +627,6 @@ void gigaset_if_receive(struct cardstate *cs,
        if (tty == NULL)
                gig_dbg(DEBUG_IF, "receive on closed device");
        else {
-               tty_buffer_request_room(tty, len);
                tty_insert_flip_string(tty, buffer, len);
                tty_flip_buffer_push(tty);
        }
index b69f73a0668f9d22567c6d23dabe3178295a04cc..b943efbff44de05cff2efae9f017607c94123244 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include "gigaset.h"
-#include <linux/ctype.h>
 
 static ssize_t show_cidmode(struct device *dev,
                            struct device_attribute *attr, char *buf)
index 168d585d64d8550e9bfe62fb6dcef5371cf5e069..e96c0586886c14b5b626427f6199144d84ae4123 100644 (file)
  */
 
 #include "gigaset.h"
-
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
-#include <linux/tty.h>
 #include <linux/completion.h>
 
 /* Version Information */
index 9430a2bbb523b138fac9dceb95dc369d47b892f9..76dbb20f3065aeb23f710b99c401286c91050bfa 100644 (file)
  */
 
 #include "gigaset.h"
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
index c38fa0f4c7296ea451fd47ba892813c69762ae77..2a57da590d797ecf82ca5aedb8e0b07ef96c1c41 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/ioport.h>
 #include <linux/capi.h>
 #include <linux/kernelcapi.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
index 124550d0dbf361f2d28a006f6b9787e83c02685a..9c8d7aa053c5ae4d2631aa22590f1967e00562e8 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/ioport.h>
 #include <linux/capi.h>
 #include <linux/kernelcapi.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
index de6e6b31181938484e0c0d425502b7fdc47f9b98..7715d3242ec81849dbd725cbbaaf52a7cd597380 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/capi.h>
 #include <linux/kernelcapi.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <linux/netdevice.h>
index baeeb3c2a3ee1cc720bb28e07bae96f02d7bfb94..08216b14be13c30a7b4b2655eb0915ca0e2072a0 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/kernelcapi.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 #include <linux/isdn/capicmd.h>
 #include <linux/isdn/capiutil.h>
index 0f073cd73763f98dc7698e3c2bec2d0ef42c7102..97a20964cfc7235785090335774e7d981230a5be 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
 #include <linux/seq_file.h>
index ae89fb89da64ae4d0a286ed7fe237f8e227f59fd..341ef17c22acb279848ced2d08747189cf128bc2 100644 (file)
@@ -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 = offsetof(T30_INFO, station_id) + 20;
+                    len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
                     w = fax_parms[5].length;
                     if (w > 20)
                       w = 20;
@@ -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 = offsetof(T30_INFO, station_id) + 20;
+            len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
             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 = offsetof(T30_INFO, station_id) + 20;
+    len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
     if (plci->fax_connect_info_length < len)
     {
       ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
@@ -6830,7 +6830,7 @@ static void nl_ind(PLCI *plci)
         if(((T30_INFO   *)plci->NL.RBuffer->P)->station_id_len)
         {
           plci->ncpi_buffer[len] = 20;
-          for (i = 0; i < 20; i++)
+          for (i = 0; i < T30_MAX_STATION_ID_LENGTH; i++)
             plci->ncpi_buffer[++len] = ((T30_INFO   *)plci->NL.RBuffer->P)->station_id[i];
         }
         if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK))
@@ -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 = offsetof(T30_INFO, station_id) + 20 + ((T30_INFO   *)plci->NL.RBuffer->P)->head_line_len;
+          i = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + ((T30_INFO   *)plci->NL.RBuffer->P)->head_line_len;
           while (i < plci->NL.RBuffer->length)
             plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++];
         }
@@ -8400,7 +8400,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
         }
       }
       /* copy station id to NLC */
-      for(i=0; i<20; i++)
+      for(i=0; i < T30_MAX_STATION_ID_LENGTH; i++)
       {
         if(i<b3_config_parms[2].length)
         {
@@ -8411,29 +8411,29 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
           ((T30_INFO *)&nlc[1])->station_id[i] = ' ';
         }
       }
-      ((T30_INFO *)&nlc[1])->station_id_len = 20;
+      ((T30_INFO *)&nlc[1])->station_id_len = T30_MAX_STATION_ID_LENGTH;
       /* copy head line to NLC */
       if(b3_config_parms[3].length)
       {
 
-        pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[20])));
+        pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[T30_MAX_STATION_ID_LENGTH])));
         if (pos != 0)
         {
           if (CAPI_MAX_DATE_TIME_LENGTH + 2 + b3_config_parms[3].length > CAPI_MAX_HEAD_LINE_SPACE)
             pos = 0;
           else
           {
-            ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' ';
-            ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' ';
+            nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
+            nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
             len = (byte)b3_config_parms[2].length;
             if (len > 20)
               len = 20;
             if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE)
             {
               for (i = 0; i < len; i++)
-                ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte   *)b3_config_parms[2].info)[1+i];
-              ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' ';
-              ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' ';
+                nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte   *)b3_config_parms[2].info)[1+i];
+              nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
+              nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
             }
           }
         }
@@ -8444,9 +8444,8 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
         ((T30_INFO *)&nlc[1])->head_line_len = (byte)(pos + len);
         nlc[0] += (byte)(pos + len);
         for (i = 0; i < len; i++)
-          ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte   *)b3_config_parms[3].info)[1+i];
-        }
-      else
+          nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] =  ((byte   *)b3_config_parms[3].info)[1+i];
+      } else
         ((T30_INFO *)&nlc[1])->head_line_len = 0;
 
       plci->nsf_control_bits = 0;
@@ -8473,7 +8472,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
             fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING;
           }
             len = nlc[0];
-          pos = offsetof(T30_INFO, station_id) + 20;
+          pos = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
    if (pos < plci->fax_connect_info_length)
    {
      for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
@@ -8525,7 +8524,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
       }
 
       PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits);
-      len = offsetof(T30_INFO, station_id) + 20;
+      len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
       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;
index 81ac541d40d9eedfb80a6338b77d757b201ace23..d4215369bb59dde8f5ab629db3ceb259d0c0480e 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/mISDNhw.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include "ipac.h"
 
index ad36df9b759ca614a922a893e85c9e43aabf1806..75e71b5d921533b0299c69db36b984f37db99279 100644 (file)
 #define HFC_MULTI_VERSION      "2.03"
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/mISDNhw.h>
@@ -5265,6 +5266,8 @@ static const struct hm_map hfcm_map[] = {
 /*31*/ {VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0,
                HFC_IO_MODE_EMBSD, XHFC_IRQ},
 /*32*/ {VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0},
+/*33*/ {VENDOR_BN, "HFC-2S Beronet Card PCIe", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
+/*34*/ {VENDOR_BN, "HFC-4S Beronet Card PCIe", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
 };
 
 #undef H
@@ -5300,6 +5303,10 @@ static struct pci_device_id hfmultipci_ids[] __devinitdata = {
                PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */
        { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
                PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */
+       { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
+               0xb761, 0, 0, H(33)}, /* BN2S PCIe */
+       { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
+               0xb762, 0, 0, H(34)}, /* BN4S PCIe */
 
        /* Cards with HFC-8S Chip */
        { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
index 70e6b0e0112132d3f07b6779d0b42075ef1e0cc7..5940a2c12074a285bce286fb6659eb73944dd96f 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/mISDNhw.h>
+#include <linux/slab.h>
 
 #include "hfc_pci.h"
 
index a64bb6c67ba7ff673cbd9bf4907bcff335798d2e..b3b7e2879bac25873da4d2666567f2c52fae434f 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/delay.h>
 #include <linux/usb.h>
 #include <linux/mISDNhw.h>
+#include <linux/slab.h>
 #include "hfcsusb.h"
 
 static const char *hfcsusb_rev = "Revision: 0.3.3 (socket), 2008-11-05";
index 36c6c616a6553355796233ff91483c7f921ad6e5..f5b3d2b26a0811455bccd1824face31364eaa372 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/mISDNhw.h>
+#include <linux/slab.h>
 #include "ipac.h"
 
 #define INFINEON_REV   "1.0"
index 613ba043537254eb57307beb8591317661fc1549..64ecc6f5ffaf8d0159bc4e3c1cd35eb82835d82c 100644 (file)
@@ -20,6 +20,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/mISDNhw.h>
 #include "ipac.h"
index f0bc6fa958097b01e4318e78b98c131cd253ee8f..38eb31439a7316102ad40110312a43230dd8cb3a 100644 (file)
@@ -25,6 +25,7 @@
  */
 /* #define DEBUG */
 
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
 #include <linux/mISDNhw.h>
index 6c1b164937a916068c728b67b6e02ffbf3409150..0a3553df065fcd38d884e939e040486760073de7 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/mISDNhw.h>
+#include <linux/slab.h>
 #include "ipac.h"
 #include "iohelper.h"
 #include "netjet.h"
index 7726afdbb40b72f043df0299ca64788a4e7599d9..d097a4e40e2ba66442ad87d4f44824927f8a0ab2 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/mISDNhw.h>
index 2952a58c7a6158a824f3afec084ea471d7179592..31f9d71fb22f7f094fc5d373b0b4e3e9a33a51c4 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/mISDNhw.h>
+#include <linux/slab.h>
 #include "w6692.h"
 
 #define W6692_REV      "2.0"
index d6fdf1f66754b5886eae439a1ad61becac5e6b4f..5d72783978784ed0bc962b9f43d438ae038d373a 100644 (file)
@@ -59,6 +59,7 @@
 #include "amd7930_fn.h"
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 
 static void Amd7930_new_ph(struct IsdnCardState *cs);
 
index 14295a155e716818bd96193bec62e33c484f8178..fcf4ed1cb4b9f2c44eef2bc1591faaf8b4343d9b 100644 (file)
@@ -17,6 +17,7 @@
 #include "isac.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/isapnp.h>
 #include <linux/interrupt.h>
 
index e5deb15cf40c9ec2a2354375ef174afe83e8e05f..8d1d63a02b341f3084410c67c43bb216e35fa1d9 100644 (file)
@@ -50,7 +50,7 @@ module_param(isdnprot, int, 0);
    handler.
 */
 
-static int avma1cs_config(struct pcmcia_device *link);
+static int avma1cs_config(struct pcmcia_device *link) __devinit ;
 static void avma1cs_release(struct pcmcia_device *link);
 
 /*
@@ -59,7 +59,7 @@ static void avma1cs_release(struct pcmcia_device *link);
    needed to manage one actual PCMCIA card.
 */
 
-static void avma1cs_detach(struct pcmcia_device *p_dev);
+static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit ;
 
 
 /*
@@ -99,7 +99,7 @@ typedef struct local_info_t {
     
 ======================================================================*/
 
-static int avma1cs_probe(struct pcmcia_device *p_dev)
+static int __devinit avma1cs_probe(struct pcmcia_device *p_dev)
 {
     local_info_t *local;
 
@@ -140,7 +140,7 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
 
 ======================================================================*/
 
-static void avma1cs_detach(struct pcmcia_device *link)
+static void __devexit avma1cs_detach(struct pcmcia_device *link)
 {
        dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link);
        avma1cs_release(link);
@@ -174,7 +174,7 @@ static int avma1cs_configcheck(struct pcmcia_device *p_dev,
 }
 
 
-static int avma1cs_config(struct pcmcia_device *link)
+static int __devinit avma1cs_config(struct pcmcia_device *link)
 {
     local_info_t *dev;
     int i;
@@ -282,7 +282,7 @@ static struct pcmcia_driver avma1cs_driver = {
                .name   = "avma1_cs",
        },
        .probe          = avma1cs_probe,
-       .remove         = avma1cs_detach,
+       .remove         = __devexit_p(avma1cs_detach),
        .id_table       = avma1cs_ids,
 };
 
index 475b1a020003fcb986de41f9fbf8d56f5167a9e5..f58ded8f403f2f8d740cffb908a939394f720bd1 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include "hisax.h"
 #include <linux/isdn/capicmd.h>
index 4fab18d4d02fecf84e42d7da99c4ef1d318a877f..544cf4b1cce3a1580b512d33d80dd92d428e754d 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #define HISAX_STATUS_BUFSIZE 4096
 
 /*
index 23c41fcd864e7cff1c70480cfd265be83aa8c542..5d9d338814aa0d09729fbfd4bf52ed0ca35e92ff 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include "hisax.h"
 #include "arcofi.h"
 #include "isac.h"
index c9a30b1c92372373a652f877dad6d62d65dbf19f..c9f2279e21f5f0812a9632f16c15081eb0e77773 100644 (file)
@@ -76,7 +76,7 @@ module_param(protocol, int, 0);
    handler.
 */
 
-static int elsa_cs_config(struct pcmcia_device *link);
+static int elsa_cs_config(struct pcmcia_device *link) __devinit ;
 static void elsa_cs_release(struct pcmcia_device *link);
 
 /*
@@ -85,7 +85,7 @@ static void elsa_cs_release(struct pcmcia_device *link);
    needed to manage one actual PCMCIA card.
 */
 
-static void elsa_cs_detach(struct pcmcia_device *p_dev);
+static void elsa_cs_detach(struct pcmcia_device *p_dev) __devexit;
 
 /*
    A driver needs to provide a dev_node_t structure for each device
@@ -121,7 +121,7 @@ typedef struct local_info_t {
 
 ======================================================================*/
 
-static int elsa_cs_probe(struct pcmcia_device *link)
+static int __devinit elsa_cs_probe(struct pcmcia_device *link)
 {
     local_info_t *local;
 
@@ -166,7 +166,7 @@ static int elsa_cs_probe(struct pcmcia_device *link)
 
 ======================================================================*/
 
-static void elsa_cs_detach(struct pcmcia_device *link)
+static void __devexit elsa_cs_detach(struct pcmcia_device *link)
 {
        local_info_t *info = link->priv;
 
@@ -210,7 +210,7 @@ static int elsa_cs_configcheck(struct pcmcia_device *p_dev,
        return -ENODEV;
 }
 
-static int elsa_cs_config(struct pcmcia_device *link)
+static int __devinit elsa_cs_config(struct pcmcia_device *link)
 {
     local_info_t *dev;
     int i;
@@ -327,7 +327,7 @@ static struct pcmcia_driver elsa_cs_driver = {
                .name   = "elsa_cs",
        },
        .probe          = elsa_cs_probe,
-       .remove         = elsa_cs_detach,
+       .remove         = __devexit_p(elsa_cs_detach),
        .id_table       = elsa_ids,
        .suspend        = elsa_suspend,
        .resume         = elsa_resume,
index 1657bba7879ee9c5ca8242b6f20864f49bd16a2e..cbda3790a10daa8a2c3d3775d498c63a331e3a15 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/serial.h>
 #include <linux/serial_reg.h>
+#include <linux/slab.h>
 
 #define MAX_MODEM_BUF  256
 #define WAKEUP_CHARS   (MAX_MODEM_BUF/2)
index 34fade96a581248834c27c6aa9ebf4f0c11ff840..732ea633758ceac7b2cae2e3bf00d276da0050f1 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include "hisax.h"
 
index ab98e135bcbb689eacb0679a50ca1557089f9d55..051b44e2556cbf7dc420a83bf93ca884de52ee37 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/skbuff.h>
 #include <linux/wait.h>
index 8d22f50760eb2e52d6919c843b2729e7b670f190..7250f56a5246f4daad7d8573f3d1f59b5ee95d21 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "hisax.h"
 #include "hfc_2bds0.h"
 #include "isdnl1.h"
index d0520ad306775a773f338a429a31936c9a97fc93..b1f6481e119371b51ce43516fb25cefd7b852502 100644 (file)
@@ -16,6 +16,7 @@
 #include "isac.h"
 #include "isdnl1.h"
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 static inline int
 WaitForBusy(struct IsdnCardState *cs)
index 419f87cad8cbeb634596f57f6c7868dde6b6e236..be5faf4aa8689b7475485a6e25d9a3b606f2a65e 100644 (file)
@@ -17,6 +17,7 @@
 #include "isdnl1.h"
 #include <linux/interrupt.h>
 #include <linux/isapnp.h>
+#include <linux/slab.h>
 
 static const char *hfcsx_revision = "$Revision: 1.12.2.5 $";
 
index aaaeaafd86f4caa0b1e92aeacc4848346081fd49..ed9527aa5f2cd8e93c3233cd6d8d53ce3a4292c8 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include "hisax.h"
 #include "hisax_if.h"
 #include "hfc_usb.h"
index d0fefcf999cb7226b89e81c50021cfc1be263ee9..a8447fa2f4705940da20ea3dbc9db9be6c0aa0ce 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include "hisax_isac.h"
index c8f9951f7914a4c8d1e387544c3d5bbab4a1cd8f..904b9100df95d63fec52ec7c29cac834f6c99b02 100644 (file)
@@ -16,6 +16,7 @@
 #include "isac.h"
 #include "isdnl1.h"
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 static char *HSCXVer[] =
 {"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
index c80cbb8a2ef9f5ceb6452162bad1b01ccb6a7b0c..63057268cc3d7d4211fe0e0d4cc1c5e130ed1771 100644 (file)
@@ -20,6 +20,7 @@
 // #include "arcofi.h"
 #include "isdnl1.h"
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #define DBUSY_TIMER_VALUE 80
 #define ARCOFI_USE 0
index 00afd553890925b21d224956646916250185ac62..751b25f2ff5811f7be494ae6457f1d73ac3b47c1 100644 (file)
@@ -10,6 +10,7 @@
  *
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include "hisax_if.h"
 #include "hisax.h"
index a19354d943433872d49c2e5c836cc2c21b030a6a..2b66728136d5d1e0b659d91872c481aa4bd4a2a9 100644 (file)
@@ -18,6 +18,7 @@
 #include "arcofi.h"
 #include "isdnl1.h"
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #define DBUSY_TIMER_VALUE 80
index 6bde16c00fb53c8e0959f1d3a05a294f77da5cfa..40b914bded8c2a3237abca74d295d8d80a02b2e3 100644 (file)
@@ -13,6 +13,7 @@
 #include "isar.h"
 #include "isdnl1.h"
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #define DBG_LOADFIRM   0
 #define DUMP_MBOXFRAME 2
index 9ce6abe05b1a242ad1508a97dffc14babc676091..d5eeacf565d696b7af80c762ed5b118fa76fd743 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include "hisax.h"
 #include "isdnl1.h"
 
index 7b9496a63b5f2d2a77f69f7395db8eec780e7c08..0858791978d8852f4171b7c7a3d0b332546d8e73 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include "hisax.h"
 #include "isdnl2.h"
 
index 06766022d3ae3440826c3d5248c9f8043f262bdd..fd0b643ab7408cfee4b288447ab30587b623796a 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include "hisax.h"
 #include "isdnl3.h"
 
index 70840a710acfe1938323f8436a07652892486310..ea8f840871d0ed81eadbf79a84e3d16417025b2d 100644 (file)
@@ -17,6 +17,7 @@
 #include "jade.h"
 #include "isdnl1.h"
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 
 int
index a12fa4d34903f699a43bcc1a62b41904279e3a8f..cc6ee2d398803a6785241968c678d5272edc9c58 100644 (file)
@@ -23,6 +23,7 @@
 #include "isdnl3.h"
 #include "l3dss1.h"
 #include <linux/ctype.h>
+#include <linux/slab.h>
 
 extern char *HiSax_getrev(const char *revision);
 static const char *dss1_revision = "$Revision: 2.32.2.3 $";
index 4622d43c7e1047d747579131451c7483b767bb25..f9584491fe8e42eca96560967892f31d0d53d8f4 100644 (file)
@@ -22,6 +22,7 @@
 #include "isdnl3.h"
 #include "l3ni1.h"
 #include <linux/ctype.h>
+#include <linux/slab.h>
 
 extern char *HiSax_getrev(const char *revision);
 static const char *ni1_revision = "$Revision: 2.8.2.3 $";
index 02c6fbaeccf82927a6e62423eff8be1efb1e0fb0..5d7f0f2ff9b9c99133272ce5e7e91bc61c9ca785 100644 (file)
@@ -21,6 +21,7 @@
 #include "isdnl1.h"
 #include <linux/interrupt.h>
 #include <linux/ppp_defs.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include "netjet.h"
 
index 7836ec3c7f86fb723131c10185a1ef432ec12d13..71b3ddef03bb790836d7d5ff63a24e8261329eb0 100644 (file)
@@ -76,7 +76,7 @@ module_param(protocol, int, 0);
    event handler. 
 */
 
-static int sedlbauer_config(struct pcmcia_device *link);
+static int sedlbauer_config(struct pcmcia_device *link) __devinit ;
 static void sedlbauer_release(struct pcmcia_device *link);
 
 /*
@@ -85,7 +85,7 @@ static void sedlbauer_release(struct pcmcia_device *link);
    needed to manage one actual PCMCIA card.
 */
 
-static void sedlbauer_detach(struct pcmcia_device *p_dev);
+static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit;
 
 /*
    You'll also need to prototype all the functions that will actually
@@ -129,7 +129,7 @@ typedef struct local_info_t {
     
 ======================================================================*/
 
-static int sedlbauer_probe(struct pcmcia_device *link)
+static int __devinit sedlbauer_probe(struct pcmcia_device *link)
 {
     local_info_t *local;
 
@@ -177,7 +177,7 @@ static int sedlbauer_probe(struct pcmcia_device *link)
 
 ======================================================================*/
 
-static void sedlbauer_detach(struct pcmcia_device *link)
+static void __devexit sedlbauer_detach(struct pcmcia_device *link)
 {
        dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link);
 
@@ -283,7 +283,7 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,
 
 
 
-static int sedlbauer_config(struct pcmcia_device *link)
+static int __devinit sedlbauer_config(struct pcmcia_device *link)
 {
     local_info_t *dev = link->priv;
     win_req_t *req;
@@ -441,7 +441,7 @@ static struct pcmcia_driver sedlbauer_driver = {
                .name   = "sedlbauer_cs",
        },
        .probe          = sedlbauer_probe,
-       .remove         = sedlbauer_detach,
+       .remove         = __devexit_p(sedlbauer_detach),
        .id_table       = sedlbauer_ids,
        .suspend        = sedlbauer_suspend,
        .resume         = sedlbauer_resume,
index 95b1cdd979584999707bbf3c84b80fed1129d66f..e56e5af889b63402dc5e3a09d9b1e2e6f70a42c2 100644 (file)
@@ -11,8 +11,8 @@
  */
 
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/usb.h>
-#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/bitrev.h>
 #include "st5481.h"
index 39e8e49cfd2de8ee0ae293eda4409a5b707f006e..b7876b19fe7348ad03ab04d3740cf610845705c5 100644 (file)
@@ -11,8 +11,8 @@
  */
 
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/usb.h>
-#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include "st5481.h"
 
index 6e65424f1f0463355fdc1fe517954e0bb53e78bf..f4cb178b0666ab3d6f9b594bb367d040bb507a3b 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "hisax.h"
 #include "isdnl2.h"
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/random.h>
 
index b0c5976cbdb356c8941d77a0dfc54a166379e4d0..d010a0da8e19bdcc04b8a78e631ba6a05f330a15 100644 (file)
@@ -57,7 +57,7 @@ module_param(protocol, int, 0);
    handler.
 */
 
-static int teles_cs_config(struct pcmcia_device *link);
+static int teles_cs_config(struct pcmcia_device *link) __devinit ;
 static void teles_cs_release(struct pcmcia_device *link);
 
 /*
@@ -66,7 +66,7 @@ static void teles_cs_release(struct pcmcia_device *link);
    needed to manage one actual PCMCIA card.
 */
 
-static void teles_detach(struct pcmcia_device *p_dev);
+static void teles_detach(struct pcmcia_device *p_dev) __devexit ;
 
 /*
    A linked list of "instances" of the teles_cs device.  Each actual
@@ -112,7 +112,7 @@ typedef struct local_info_t {
 
 ======================================================================*/
 
-static int teles_probe(struct pcmcia_device *link)
+static int __devinit teles_probe(struct pcmcia_device *link)
 {
     local_info_t *local;
 
@@ -156,7 +156,7 @@ static int teles_probe(struct pcmcia_device *link)
 
 ======================================================================*/
 
-static void teles_detach(struct pcmcia_device *link)
+static void __devexit teles_detach(struct pcmcia_device *link)
 {
        local_info_t *info = link->priv;
 
@@ -200,7 +200,7 @@ static int teles_cs_configcheck(struct pcmcia_device *p_dev,
        return -ENODEV;
 }
 
-static int teles_cs_config(struct pcmcia_device *link)
+static int __devinit teles_cs_config(struct pcmcia_device *link)
 {
     local_info_t *dev;
     int i;
@@ -319,7 +319,7 @@ static struct pcmcia_driver teles_cs_driver = {
                .name   = "teles_cs",
        },
        .probe          = teles_probe,
-       .remove         = teles_detach,
+       .remove         = __devexit_p(teles_detach),
        .id_table       = teles_ids,
        .suspend        = teles_suspend,
        .resume         = teles_resume,
index 9d6e864023fe18fd33add31997ed078edbd733a5..e2cfb6f5aa4236ee917480085204623a38a35435 100644 (file)
@@ -16,6 +16,7 @@
 #include "isdnl1.h"
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 /* table entry in the PCI devices list */
 typedef struct {
index fe874afa4f81347e773a062a1ba2546338cc8581..6299b06ae00912b64471dbb7a86b0ece1ed2ac72 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 
 #define        VER_DRIVER      0
 #define        VER_CARDTYPE    1
index be787e16bb79b99b7e501aca2e395b09e235fa86..4f541ef14f9efd845ba953faadab303478125a24 100644 (file)
@@ -143,7 +143,7 @@ pof_handle_data(hysdn_card * card, int datlen)
                                             (boot->pof_recid == TAG_CABSDATA) ? "CABSDATA" : "ABSDATA",
                                             datlen, boot->pof_recoffset);
 
-                       if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen) < 0))
+                       if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen)) < 0)
                                return (boot->last_error);      /* error writing data */
 
                        if (boot->pof_recoffset + datlen >= boot->pof_reclen)
index 90b35e1a4b7e6e85c9d8ea4374184d3c6c02f40c..80966462d6dcba0eb58caf57ba87768188a0a36b 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/poll.h>
 #include <linux/proc_fs.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <net/net_namespace.h>
 
index 8bcae28c4409ea0edbf40a65db309214463ec81c..e83f6fda32fe797065fc07049e9175ce92b0f507 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/poll.h>
 #include <linux/proc_fs.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 
 #include "hysdn_defs.h"
index fb350c567c6ba01c768c87845ed37c70db6a79b2..861bdf3421f2b5372452c610eff1fc5546e86c7c 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/isdn.h>
+#include <linux/slab.h>
 #include "isdn_audio.h"
 #include "isdn_common.h"
 
index 00c60e2e0ff70fa7c398c2b8688dc20d0ca3b793..70044ee4b2280f37a58151d995d90170f582f9fa 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/isdn.h>
 #include <linux/smp_lock.h>
index 507e13d9a57c1579ac1b29d1548949847ff4fcf5..8c85d1e88cc6259c41dff0b4615f32681edd39ac 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/isdn.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 #include <net/dst.h>
 #include <net/pkt_sched.h>
index 45df6675e8edac5c09b05090e18861db190fb3ad..f37b8f68d0aa0d3b00f7405d1f7bb31c8ab5e6bb 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/isdn.h>
 #include <linux/poll.h>
 #include <linux/ppp-comp.h>
+#include <linux/slab.h>
 #ifdef CONFIG_IPPP_FILTER
 #include <linux/filter.h>
 #endif
index 2881a66c1aa97c2e78e0c9f3029bbbd44ef0046a..fc8454d2eea5f9343be87eaf0f3e867fb4294ca4 100644 (file)
@@ -12,6 +12,7 @@
 #undef ISDN_TTY_STAT_DEBUG
 
 #include <linux/isdn.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/smp_lock.h>
 #include "isdn_common.h"
index 8b3efc243161a201fd8029d5d43900371c48b2b5..efcf1f9327e5cc408026e8535fab61a75942b091 100644 (file)
@@ -20,6 +20,7 @@
 /* #include <linux/isdn.h> */
 #include <linux/netdevice.h>
 #include <linux/concap.h>
+#include <linux/slab.h>
 #include <linux/wanrouter.h>
 #include <net/x25device.h>
 #include "isdn_x25iface.h"
index bf7997abc4ac6da27bf972677ac3283e7e68d49c..2e847a90bad0d601f8bcc5f9a7bd4d7440f929c0 100644 (file)
@@ -12,6 +12,7 @@
 #include "icn.h"
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 static int portbase = ICN_BASEADDR;
index a335c85a736e25a472c3d66157ef40a0313304da..b8a1098b66edfb07c62c3810dbe8d52beec7f8cb 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include "isdnloop.h"
index f1bbc88763b283656777209c9164a0cb9847d371..1fa629b3b940a94743267c5898ab2ee8876c1e51 100644 (file)
@@ -33,6 +33,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/stddef.h>
 #include <linux/spinlock.h>
index 21d34be5af6a2300fa49b646515e0413eea77db0..afeebb00fe0bcafc8e690e199613daa54d6e901e 100644 (file)
@@ -12,6 +12,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/stddef.h>
 #include <linux/module.h>
index 9c7c0d1ba55f1c80d13c1f21e9bb1f56010594f8..713ef2b805a2aabec1803b6f7607f9104517fc84 100644 (file)
 
 /* delay.h is required for hw_lock.h */
 
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/mISDNif.h>
 #include <linux/mISDNdsp.h>
index 6eac588e0a374c94cb8916cbc1f08cee283eedfc..6f5b548642837b44c93c18ed5318fc907e6a2192 100644 (file)
  */
 
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/mISDNif.h>
 #include <linux/mISDNdsp.h>
 #include <linux/module.h>
index e9941678edfa52ff51baa83b75a8d659017926b9..621f310070953822a3c782f0c1a73caa91d4fc29 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/string.h>
 #include <linux/mISDNif.h>
index 1debf53670de6408f98ddbbbacd681a0cef9b93f..7dbe54ed1debf77231cd7c6e6f91841e2367904d 100644 (file)
@@ -8,6 +8,7 @@
  *
  */
 
+#include <linux/gfp.h>
 #include <linux/mISDNif.h>
 #include <linux/mISDNdsp.h>
 #include "core.h"
index e8049be552aa88800dee7d749489616628a7d20a..307bd6e8988bed710830db7ddbb3ce8c3a08aac4 100644 (file)
@@ -15,6 +15,7 @@
  *
  */
 
+#include <linux/gfp.h>
 #include <linux/module.h>
 #include <linux/mISDNhw.h>
 
index 325b1ad7d4b87d8e2445fb28dad77a906d976e2b..22f38e48ac4eddca6e27afa74df9c5122b940e4f 100644 (file)
@@ -233,6 +233,7 @@ socket process and create a new one.
 #include <linux/inet.h>
 #include <linux/workqueue.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include "core.h"
 #include "l1oip.h"
index e826eeb1ecec58a45ef7483df0bb55599a2fbe7c..ac4aa18c632b0f2040cef841a4e5fd98a0cd7f5a 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/mISDNhw.h>
 #include "core.h"
index e17f0044e0b6d2869175c5faed183df60bab074f..c97371788764df3af6a45ad9f402ece12f59a1b3 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/mISDNif.h>
+#include <linux/slab.h>
 #include "core.h"
 #include "fsm.h"
 #include "layer2.h"
index fcfe17a19a612976ef87f099946210667601b071..3232206406b15bcdba06b39b837545307902d3e1 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/mISDNif.h>
+#include <linux/slab.h>
 #include "core.h"
 
 static u_int   *debug;
index 0d05ec43012cf14104cf4ef96f4ec0cc780ae6cd..b159bd59e64e1f65b898fb371ea3c73e85d81f64 100644 (file)
@@ -15,6 +15,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/mISDNif.h>
 #include <linux/kthread.h>
 #include <linux/smp_lock.h>
index 6d4da60958855a4103021b8a9a2863f7e9dae6c1..34e898fe2f4f32539d6a53144fad72e18a2b3f67 100644 (file)
@@ -16,6 +16,7 @@
  */
 #include "layer2.h"
 #include <linux/random.h>
+#include <linux/slab.h>
 #include "core.h"
 
 #define ID_REQUEST     1
index 5b7e9bf514f10c59e55f7439fc82b7c8bfabd81a..8785004e85e09759a5b9db53bd81225a7e0f5342 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/poll.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
index 43ecd0f5423567c0dc2026106512383126bf813a..976143b2346d06247e54256515fec879e2ab5180 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/kernel.h>
 
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/skbuff.h>
 
index 37e9626cebf6ccdd3d5013aee3a4f8d8be10c385..d5920ae22d730024f23c8f6175b8a260cebd94f9 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/kernel.h>
 
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/skbuff.h>
 
index 5a0774880d560640e669734ea689a1874ce4dd94..ca710ab278ec49788a50a483375c7de08b340a1b 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "includes.h"
 #include "hardware.h"
 #include "card.h"
index e0b64312e66ae070f510f9fcbae626f086791d41..505eb64c329cb67605cd6a69f4c70256fc6332f2 100644 (file)
@@ -15,6 +15,8 @@ config LEDS_CLASS
          This option enables the led sysfs class in /sys/class/leds.  You'll
          need this to do anything useful with LEDs.  If unsure, say N.
 
+if LEDS_CLASS
+
 comment "LED drivers"
 
 config LEDS_88PM860X
@@ -26,73 +28,73 @@ config LEDS_88PM860X
 
 config LEDS_ATMEL_PWM
        tristate "LED Support using Atmel PWM outputs"
-       depends on LEDS_CLASS && ATMEL_PWM
+       depends on ATMEL_PWM
        help
          This option enables support for LEDs driven using outputs
          of the dedicated PWM controller found on newer Atmel SOCs.
 
 config LEDS_LOCOMO
        tristate "LED Support for Locomo device"
-       depends on LEDS_CLASS && SHARP_LOCOMO
+       depends on SHARP_LOCOMO
        help
          This option enables support for the LEDs on Sharp Locomo.
          Zaurus models SL-5500 and SL-5600.
 
 config LEDS_MIKROTIK_RB532
        tristate "LED Support for Mikrotik Routerboard 532"
-       depends on LEDS_CLASS && MIKROTIK_RB532
+       depends on MIKROTIK_RB532
        help
          This option enables support for the so called "User LED" of
          Mikrotik's Routerboard 532.
 
 config LEDS_S3C24XX
        tristate "LED Support for Samsung S3C24XX GPIO LEDs"
-       depends on LEDS_CLASS && ARCH_S3C2410
+       depends on ARCH_S3C2410
        help
          This option enables support for LEDs connected to GPIO lines
          on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440.
 
 config LEDS_AMS_DELTA
        tristate "LED Support for the Amstrad Delta (E3)"
-       depends on LEDS_CLASS && MACH_AMS_DELTA
+       depends on MACH_AMS_DELTA
        help
          This option enables support for the LEDs on Amstrad Delta (E3).
 
 config LEDS_NET48XX
        tristate "LED Support for Soekris net48xx series Error LED"
-       depends on LEDS_CLASS && SCx200_GPIO
+       depends on SCx200_GPIO
        help
          This option enables support for the Soekris net4801 and net4826 error
          LED.
 
 config LEDS_FSG
        tristate "LED Support for the Freecom FSG-3"
-       depends on LEDS_CLASS && MACH_FSG
+       depends on MACH_FSG
        help
          This option enables support for the LEDs on the Freecom FSG-3.
 
 config LEDS_WRAP
        tristate "LED Support for the WRAP series LEDs"
-       depends on LEDS_CLASS && SCx200_GPIO
+       depends on SCx200_GPIO
        help
          This option enables support for the PCEngines WRAP programmable LEDs.
 
 config LEDS_ALIX2
        tristate "LED Support for ALIX.2 and ALIX.3 series"
-       depends on LEDS_CLASS && X86 && EXPERIMENTAL
+       depends on X86 && !GPIO_CS5535 && !CS5535_GPIO
        help
          This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs.
          You have to set leds-alix2.force=1 for boards with Award BIOS.
 
 config LEDS_H1940
        tristate "LED Support for iPAQ H1940 device"
-       depends on LEDS_CLASS && ARCH_H1940
+       depends on ARCH_H1940
        help
          This option enables support for the LEDs on the h1940.
 
 config LEDS_COBALT_QUBE
        tristate "LED Support for the Cobalt Qube series front LED"
-       depends on LEDS_CLASS && MIPS_COBALT
+       depends on MIPS_COBALT
        help
          This option enables support for the front LED on Cobalt Qube series
 
@@ -105,7 +107,7 @@ config LEDS_COBALT_RAQ
 
 config LEDS_SUNFIRE
        tristate "LED support for SunFire servers."
-       depends on LEDS_CLASS && SPARC64
+       depends on SPARC64
        select LEDS_TRIGGERS
        help
          This option enables support for the Left, Middle, and Right
@@ -113,14 +115,14 @@ config LEDS_SUNFIRE
 
 config LEDS_HP6XX
        tristate "LED Support for the HP Jornada 6xx"
-       depends on LEDS_CLASS && SH_HP6XX
+       depends on SH_HP6XX
        help
          This option enables LED support for the handheld
          HP Jornada 620/660/680/690.
 
 config LEDS_PCA9532
        tristate "LED driver for PCA9532 dimmer"
-       depends on LEDS_CLASS && I2C && INPUT && EXPERIMENTAL
+       depends on I2C && INPUT && EXPERIMENTAL
        help
          This option enables support for NXP pca9532
          LED controller. It is generally only useful
@@ -128,7 +130,7 @@ config LEDS_PCA9532
 
 config LEDS_GPIO
        tristate "LED Support for GPIO connected LEDs"
-       depends on LEDS_CLASS && GENERIC_GPIO
+       depends on GENERIC_GPIO
        help
          This option enables support for the LEDs connected to GPIO
          outputs. To be useful the particular board must have LEDs
@@ -155,7 +157,7 @@ config LEDS_GPIO_OF
 
 config LEDS_LP3944
        tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip"
-       depends on LEDS_CLASS && I2C
+       depends on I2C
        help
          This option enables support for LEDs connected to the National
          Semiconductor LP3944 Lighting Management Unit (LMU) also known as
@@ -166,7 +168,7 @@ config LEDS_LP3944
 
 config LEDS_CLEVO_MAIL
        tristate "Mail LED on Clevo notebook"
-       depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI
+       depends on X86 && SERIO_I8042 && DMI
        help
          This driver makes the mail LED accessible from userspace
          programs through the leds subsystem. This LED have three
@@ -196,7 +198,7 @@ config LEDS_CLEVO_MAIL
 
 config LEDS_PCA955X
        tristate "LED Support for PCA955x I2C chips"
-       depends on LEDS_CLASS && I2C
+       depends on I2C
        help
          This option enables support for LEDs connected to PCA955x
          LED driver chips accessed via the I2C bus.  Supported
@@ -204,54 +206,54 @@ config LEDS_PCA955X
 
 config LEDS_WM831X_STATUS
        tristate "LED support for status LEDs on WM831x PMICs"
-       depends on LEDS_CLASS && MFD_WM831X
+       depends on MFD_WM831X
        help
          This option enables support for the status LEDs of the WM831x
           series of PMICs.
 
 config LEDS_WM8350
        tristate "LED Support for WM8350 AudioPlus PMIC"
-       depends on LEDS_CLASS && MFD_WM8350
+       depends on MFD_WM8350
        help
          This option enables support for LEDs driven by the Wolfson
          Microelectronics WM8350 AudioPlus PMIC.
 
 config LEDS_DA903X
        tristate "LED Support for DA9030/DA9034 PMIC"
-       depends on LEDS_CLASS && PMIC_DA903X
+       depends on PMIC_DA903X
        help
          This option enables support for on-chip LED drivers found
          on Dialog Semiconductor DA9030/DA9034 PMICs.
 
 config LEDS_DAC124S085
        tristate "LED Support for DAC124S085 SPI DAC"
-       depends on LEDS_CLASS && SPI
+       depends on SPI
        help
          This option enables support for DAC124S085 SPI DAC from NatSemi,
          which can be used to control up to four LEDs.
 
 config LEDS_PWM
        tristate "PWM driven LED Support"
-       depends on LEDS_CLASS && HAVE_PWM
+       depends on HAVE_PWM
        help
          This option enables support for pwm driven LEDs
 
 config LEDS_REGULATOR
        tristate "REGULATOR driven LED support"
-       depends on LEDS_CLASS && REGULATOR
+       depends on REGULATOR
        help
          This option enables support for regulator driven LEDs.
 
 config LEDS_BD2802
        tristate "LED driver for BD2802 RGB LED"
-       depends on LEDS_CLASS && I2C
+       depends on I2C
        help
          This option enables support for BD2802GU RGB LED driver chips
          accessed via the I2C bus.
 
 config LEDS_INTEL_SS4200
        tristate "LED driver for Intel NAS SS4200 series"
-       depends on LEDS_CLASS && PCI && DMI
+       depends on PCI && DMI
        help
          This option enables support for the Intel SS4200 series of
          Network Attached Storage servers.  You may control the hard
@@ -260,7 +262,7 @@ config LEDS_INTEL_SS4200
 
 config LEDS_LT3593
        tristate "LED driver for LT3593 controllers"
-       depends on LEDS_CLASS && GENERIC_GPIO
+       depends on GENERIC_GPIO
        help
          This option enables support for LEDs driven by a Linear Technology
          LT3593 controller. This controller uses a special one-wire pulse
@@ -268,7 +270,7 @@ config LEDS_LT3593
 
 config LEDS_ADP5520
        tristate "LED Support for ADP5520/ADP5501 PMIC"
-       depends on LEDS_CLASS && PMIC_ADP5520
+       depends on PMIC_ADP5520
        help
          This option enables support for on-chip LED drivers found
          on Analog Devices ADP5520/ADP5501 PMICs.
@@ -276,7 +278,12 @@ config LEDS_ADP5520
          To compile this driver as a module, choose M here: the module will
          be called leds-adp5520.
 
-comment "LED Triggers"
+config LEDS_DELL_NETBOOKS
+       tristate "External LED on Dell Business Netbooks"
+       depends on X86 && ACPI_WMI
+       help
+         This adds support for the Latitude 2100 and similar
+         notebooks that have an external LED.
 
 config LEDS_TRIGGERS
        bool "LED Trigger support"
@@ -285,9 +292,12 @@ config LEDS_TRIGGERS
          These triggers allow kernel events to drive the LEDs and can
          be configured via sysfs. If unsure, say Y.
 
+if LEDS_TRIGGERS
+
+comment "LED Triggers"
+
 config LEDS_TRIGGER_TIMER
        tristate "LED Timer Trigger"
-       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be controlled by a programmable timer
          via sysfs. Some LED hardware can be programmed to start
@@ -298,14 +308,13 @@ config LEDS_TRIGGER_TIMER
 
 config LEDS_TRIGGER_IDE_DISK
        bool "LED IDE Disk Trigger"
-       depends on LEDS_TRIGGERS && IDE_GD_ATA
+       depends on IDE_GD_ATA
        help
          This allows LEDs to be controlled by IDE disk activity.
          If unsure, say Y.
 
 config LEDS_TRIGGER_HEARTBEAT
        tristate "LED Heartbeat Trigger"
-       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be controlled by a CPU load average.
          The flash frequency is a hyperbolic function of the 1-minute
@@ -314,7 +323,6 @@ config LEDS_TRIGGER_HEARTBEAT
 
 config LEDS_TRIGGER_BACKLIGHT
        tristate "LED backlight Trigger"
-       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be controlled as a backlight device: they
          turn off and on when the display is blanked and unblanked.
@@ -323,7 +331,6 @@ config LEDS_TRIGGER_BACKLIGHT
 
 config LEDS_TRIGGER_GPIO
        tristate "LED GPIO Trigger"
-       depends on LEDS_TRIGGERS
        depends on GPIOLIB
        help
          This allows LEDs to be controlled by gpio events. It's good
@@ -336,7 +343,6 @@ config LEDS_TRIGGER_GPIO
 
 config LEDS_TRIGGER_DEFAULT_ON
        tristate "LED Default ON Trigger"
-       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be initialised in the ON state.
          If unsure, say Y.
@@ -344,4 +350,8 @@ config LEDS_TRIGGER_DEFAULT_ON
 comment "iptables trigger is under Netfilter config (LED target)"
        depends on LEDS_TRIGGERS
 
+endif # LEDS_TRIGGERS
+
+endif # LEDS_CLASS
+
 endif # NEW_LEDS
index d76fb32b77c0311d341b78633c2f56a35d67d05e..0cd8b9957380d01f58acbf8aa28163fd1f1650fc 100644 (file)
@@ -34,6 +34,7 @@ obj-$(CONFIG_LEDS_REGULATOR)          += leds-regulator.o
 obj-$(CONFIG_LEDS_INTEL_SS4200)                += leds-ss4200.o
 obj-$(CONFIG_LEDS_LT3593)              += leds-lt3593.o
 obj-$(CONFIG_LEDS_ADP5520)             += leds-adp5520.o
+obj-$(CONFIG_LEDS_DELL_NETBOOKS)       += dell-led.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)          += leds-dac124s085.o
diff --git a/drivers/leds/dell-led.c b/drivers/leds/dell-led.c
new file mode 100644 (file)
index 0000000..5259029
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * dell_led.c - Dell LED Driver
+ *
+ * Copyright (C) 2010 Dell Inc.
+ * Louis Davis <louis_davis@dell.com>
+ * Jim Dailey <jim_dailey@dell.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.
+ *
+ */
+
+#include <linux/acpi.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+
+MODULE_AUTHOR("Louis Davis/Jim Dailey");
+MODULE_DESCRIPTION("Dell LED Control Driver");
+MODULE_LICENSE("GPL");
+
+#define DELL_LED_BIOS_GUID "F6E4FE6E-909D-47cb-8BAB-C9F6F2F8D396"
+MODULE_ALIAS("wmi:" DELL_LED_BIOS_GUID);
+
+/* Error Result Codes: */
+#define INVALID_DEVICE_ID      250
+#define INVALID_PARAMETER      251
+#define INVALID_BUFFER         252
+#define INTERFACE_ERROR                253
+#define UNSUPPORTED_COMMAND    254
+#define UNSPECIFIED_ERROR      255
+
+/* Device ID */
+#define DEVICE_ID_PANEL_BACK   1
+
+/* LED Commands */
+#define CMD_LED_ON     16
+#define CMD_LED_OFF    17
+#define CMD_LED_BLINK  18
+
+struct bios_args {
+       unsigned char length;
+       unsigned char result_code;
+       unsigned char device_id;
+       unsigned char command;
+       unsigned char on_time;
+       unsigned char off_time;
+};
+
+static int dell_led_perform_fn(u8 length,
+               u8 result_code,
+               u8 device_id,
+               u8 command,
+               u8 on_time,
+               u8 off_time)
+{
+       struct bios_args *bios_return;
+       u8 return_code;
+       union acpi_object *obj;
+       struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+       struct acpi_buffer input;
+       acpi_status status;
+
+       struct bios_args args;
+       args.length = length;
+       args.result_code = result_code;
+       args.device_id = device_id;
+       args.command = command;
+       args.on_time = on_time;
+       args.off_time = off_time;
+
+       input.length = sizeof(struct bios_args);
+       input.pointer = &args;
+
+       status = wmi_evaluate_method(DELL_LED_BIOS_GUID,
+               1,
+               1,
+               &input,
+               &output);
+
+       if (ACPI_FAILURE(status))
+               return status;
+
+       obj = output.pointer;
+
+       if (!obj)
+               return -EINVAL;
+       else if (obj->type != ACPI_TYPE_BUFFER) {
+               kfree(obj);
+               return -EINVAL;
+       }
+
+       bios_return = ((struct bios_args *)obj->buffer.pointer);
+       return_code = bios_return->result_code;
+
+       kfree(obj);
+
+       return return_code;
+}
+
+static int led_on(void)
+{
+       return dell_led_perform_fn(3,   /* Length of command */
+               INTERFACE_ERROR,        /* Init to  INTERFACE_ERROR */
+               DEVICE_ID_PANEL_BACK,   /* Device ID */
+               CMD_LED_ON,             /* Command */
+               0,                      /* not used */
+               0);                     /* not used */
+}
+
+static int led_off(void)
+{
+       return dell_led_perform_fn(3,   /* Length of command */
+               INTERFACE_ERROR,        /* Init to  INTERFACE_ERROR */
+               DEVICE_ID_PANEL_BACK,   /* Device ID */
+               CMD_LED_OFF,            /* Command */
+               0,                      /* not used */
+               0);                     /* not used */
+}
+
+static int led_blink(unsigned char on_eighths,
+               unsigned char off_eighths)
+{
+       return dell_led_perform_fn(5,   /* Length of command */
+               INTERFACE_ERROR,        /* Init to  INTERFACE_ERROR */
+               DEVICE_ID_PANEL_BACK,   /* Device ID */
+               CMD_LED_BLINK,          /* Command */
+               on_eighths,             /* blink on in eigths of a second */
+               off_eighths);           /* blink off in eights of a second */
+}
+
+static void dell_led_set(struct led_classdev *led_cdev,
+               enum led_brightness value)
+{
+       if (value == LED_OFF)
+               led_off();
+       else
+               led_on();
+}
+
+static int dell_led_blink(struct led_classdev *led_cdev,
+               unsigned long *delay_on,
+               unsigned long *delay_off)
+{
+       unsigned long on_eighths;
+       unsigned long off_eighths;
+
+       /* The Dell LED delay is based on 125ms intervals.
+          Need to round up to next interval. */
+
+       on_eighths = (*delay_on + 124) / 125;
+       if (0 == on_eighths)
+               on_eighths = 1;
+       if (on_eighths > 255)
+               on_eighths = 255;
+       *delay_on = on_eighths * 125;
+
+       off_eighths = (*delay_off + 124) / 125;
+       if (0 == off_eighths)
+               off_eighths = 1;
+       if (off_eighths > 255)
+               off_eighths = 255;
+       *delay_off = off_eighths * 125;
+
+       led_blink(on_eighths, off_eighths);
+
+       return 0;
+}
+
+static struct led_classdev dell_led = {
+       .name           = "dell::lid",
+       .brightness     = LED_OFF,
+       .max_brightness = 1,
+       .brightness_set = dell_led_set,
+       .blink_set      = dell_led_blink,
+       .flags          = LED_CORE_SUSPENDRESUME,
+};
+
+static int __init dell_led_init(void)
+{
+       int error = 0;
+
+       if (!wmi_has_guid(DELL_LED_BIOS_GUID))
+               return -ENODEV;
+
+       error = led_off();
+       if (error != 0)
+               return -ENODEV;
+
+       return led_classdev_register(NULL, &dell_led);
+}
+
+static void __exit dell_led_exit(void)
+{
+       led_classdev_unregister(&dell_led);
+
+       led_off();
+}
+
+module_init(dell_led_init);
+module_exit(dell_led_exit);
index 782f95822eab0867f8db83666c5ba08d3a77a23e..69e7d86a5143e36d2db68275214e4af539777be4 100644 (file)
@@ -72,11 +72,14 @@ static ssize_t led_max_brightness_show(struct device *dev,
        return sprintf(buf, "%u\n", led_cdev->max_brightness);
 }
 
-static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store);
-static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL);
+static struct device_attribute led_class_attrs[] = {
+       __ATTR(brightness, 0644, led_brightness_show, led_brightness_store),
+       __ATTR(max_brightness, 0644, led_max_brightness_show, NULL),
 #ifdef CONFIG_LEDS_TRIGGERS
-static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
+       __ATTR(trigger, 0644, led_trigger_show, led_trigger_store),
 #endif
+       __ATTR_NULL,
+};
 
 /**
  * led_classdev_suspend - suspend an led_classdev.
@@ -127,18 +130,11 @@ static int led_resume(struct device *dev)
  */
 int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
 {
-       int rc;
-
        led_cdev->dev = device_create(leds_class, parent, 0, led_cdev,
                                      "%s", led_cdev->name);
        if (IS_ERR(led_cdev->dev))
                return PTR_ERR(led_cdev->dev);
 
-       /* register the attributes */
-       rc = device_create_file(led_cdev->dev, &dev_attr_brightness);
-       if (rc)
-               goto err_out;
-
 #ifdef CONFIG_LEDS_TRIGGERS
        init_rwsem(&led_cdev->trigger_lock);
 #endif
@@ -150,36 +146,18 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
        if (!led_cdev->max_brightness)
                led_cdev->max_brightness = LED_FULL;
 
-       rc = device_create_file(led_cdev->dev, &dev_attr_max_brightness);
-       if (rc)
-               goto err_out_attr_max;
-
        led_update_brightness(led_cdev);
 
 #ifdef CONFIG_LEDS_TRIGGERS
-       rc = device_create_file(led_cdev->dev, &dev_attr_trigger);
-       if (rc)
-               goto err_out_led_list;
-
        led_trigger_set_default(led_cdev);
 #endif
 
-       printk(KERN_INFO "Registered led device: %s\n",
+       printk(KERN_DEBUG "Registered led device: %s\n",
                        led_cdev->name);
 
        return 0;
-
-#ifdef CONFIG_LEDS_TRIGGERS
-err_out_led_list:
-       device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
-#endif
-err_out_attr_max:
-       device_remove_file(led_cdev->dev, &dev_attr_brightness);
-       list_del(&led_cdev->node);
-err_out:
-       device_unregister(led_cdev->dev);
-       return rc;
 }
+
 EXPORT_SYMBOL_GPL(led_classdev_register);
 
 /**
@@ -190,10 +168,7 @@ EXPORT_SYMBOL_GPL(led_classdev_register);
  */
 void led_classdev_unregister(struct led_classdev *led_cdev)
 {
-       device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
-       device_remove_file(led_cdev->dev, &dev_attr_brightness);
 #ifdef CONFIG_LEDS_TRIGGERS
-       device_remove_file(led_cdev->dev, &dev_attr_trigger);
        down_write(&led_cdev->trigger_lock);
        if (led_cdev->trigger)
                led_trigger_set(led_cdev, NULL);
@@ -215,6 +190,7 @@ static int __init leds_init(void)
                return PTR_ERR(leds_class);
        leds_class->suspend = led_suspend;
        leds_class->resume = led_resume;
+       leds_class->dev_attrs = led_class_attrs;
        return 0;
 }
 
index d8ddd9ef89949da41b8b7b1f9e840b302772ff19..f1c00db88b5e148fd229410d5959f4c4e0e9580b 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/timer.h>
 #include <linux/rwsem.h>
 #include <linux/leds.h>
+#include <linux/slab.h>
 #include "leds.h"
 
 /*
index d196073a6aebb4442f6a889f225d8379f5df10df..16a60c06c96c62c7bd6eb4d87fac77d46af1b66a 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/leds.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/mfd/88pm860x.h>
 
index a8f315902131b5699a105de2a9df0cc064b541b5..7ba4c7b5b97e07ce6ff11d26895a154b25b5a956 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/leds.h>
 #include <linux/workqueue.h>
 #include <linux/mfd/adp5520.h>
+#include <linux/slab.h>
 
 struct adp5520_led {
        struct led_classdev     cdev;
index 52297c3ab246c38a78e3580895c21e1c00d7b6f6..c941d906bba6e585f750616480ad1cccdcf3b4b9 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/leds.h>
 #include <linux/io.h>
 #include <linux/atmel_pwm.h>
+#include <linux/slab.h>
 
 
 struct pwmled {
index 779d7f262c04c39f1355e0dd2a190ca02fb067e3..286b501a3573d3b7d0d4cec872fa7b40008c83d5 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/leds.h>
 #include <linux/leds-bd2802.h>
+#include <linux/slab.h>
 
 
 #define LED_CTL(rgb2en, rgb1en) ((rgb2en) << 4 | ((rgb1en) << 0))
index 1f3cc512eff898af0bc3b74c878d8b862c3cbad0..f28931cf6781049562018d0af5d59e014b2936d2 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/leds.h>
 #include <linux/workqueue.h>
 #include <linux/mfd/da903x.h>
+#include <linux/slab.h>
 
 #define DA9030_LED1_CONTROL    0x20
 #define DA9030_LED2_CONTROL    0x21
index 2913d76ad3d254f45d29a914dc40d8b177f20803..31cf0d60a9a546052e782d5177b8461c9673d941 100644 (file)
@@ -9,7 +9,6 @@
  * LED driver for the DAC124S085 SPI DAC
  */
 
-#include <linux/gfp.h>
 #include <linux/leds.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
index e5225d28f39245cbff44373f38947e3839847a6f..c6e4b772b7575206f9cb9a093b682f5060d2df82 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/leds.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 
 #include <asm/gpio.h>
@@ -211,7 +212,6 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev,
                                        const struct of_device_id *match)
 {
        struct device_node *np = ofdev->node, *child;
-       struct gpio_led led;
        struct gpio_led_of_platform_data *pdata;
        int count = 0, ret;
 
@@ -226,8 +226,8 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev,
        if (!pdata)
                return -ENOMEM;
 
-       memset(&led, 0, sizeof(led));
        for_each_child_of_node(np, child) {
+               struct gpio_led led = {};
                enum of_gpio_flags flags;
                const char *state;
 
index 5946208ba26e586aa42ce4fb944f011fc9ff43bf..8d5ecceba1813f4a6de912c21c7cffe95ca965c1 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <linux/module.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/leds.h>
 #include <linux/mutex.h>
 #include <linux/workqueue.h>
index fee40a84195920c814086fedc7c920b903544670..2579678f97a6c8e02ca897c363e1b1d107d67715 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/workqueue.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 struct lt3593_led_data {
        struct led_classdev cdev;
index adc561eb59d2ed022873bacf35501b9462e19bbc..6682175fa9f7c4e3c5a91d99120c83b2003f6b9a 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/module.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/leds.h>
 #include <linux/input.h>
 #include <linux/mutex.h>
index 4e2d1a42b48f41ed4ae0bcabfb672fec5b7e0600..8ff50f234190a38129342d743a14c8c7c201ad6c 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 /* LED select registers determine the source that drives LED outputs */
 #define PCA955X_LS_LED_ON      0x0     /* Output LOW */
index 88b1dd091cfb9f3887ec052f75a3f4e0620d69ad..da3fa8dcdf5b924f71a7f117c05009f0fc671514 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/err.h>
 #include <linux/pwm.h>
 #include <linux/leds_pwm.h>
+#include <linux/slab.h>
 
 struct led_pwm_data {
        struct led_classdev     cdev;
index 7f00de3ef9224a42eb4404e14e2c45f3d81d6f89..3790816643bef85bee2dd1824bcb29818a693f86 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/leds.h>
 #include <linux/leds-regulator.h>
index aa7acf3b92248e44ead8cc8da59586b11ed255f6..a77771dc2e9542fca0bf77cfa5a1466f71fa2e47 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/leds.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <mach/regs-gpio.h>
index 97f04984c1caae3175d7bd4d6a839b0ed8d2efac..51477ec7139179dd2dec53795de21273453f2c1c 100644 (file)
@@ -63,7 +63,7 @@ MODULE_LICENSE("GPL");
 /*
  * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives.
  */
-static struct pci_device_id ich7_lpc_pci_id[] =
+static const struct pci_device_id ich7_lpc_pci_id[] =
 {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) },
index 6b008f0c3f623460273cd985101e5da0d32354b4..ab6d18f5c39f343b3324fbd5d03a58fa4bcfbeda 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/leds.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/fhc.h>
 #include <asm/upa.h>
index c586d05e336a5ed6327dd331f90fb2597f2974da..ef5c24140a44deb5890a1620d66e89b071963993 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/leds.h>
 #include <linux/err.h>
 #include <linux/mfd/wm831x/core.h>
index 38c6bcb07e6c55e7113397911bae3fb0fb8a5221..5aab32ce4f4d2a18e1f7997482a79925e75aa39d 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/mfd/wm8350/pmic.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 
 /* Microamps */
 static const int isink_cur[] = {
index d3dfcfb417b89befb8706f8d8a208b904baaeb33..f948e57bd9b83018f425de0823725b95ec053a5c 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/fb.h>
 #include <linux/leds.h>
index f5913372d691a034bd18223a4494f568d337d27c..991d93be0f447313945b6925a0a196c19a9586e2 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
 #include <linux/leds.h>
+#include <linux/slab.h>
 #include "leds.h"
 
 struct gpio_trig_data {
index c1c1ea6f817b1eb7ddb7f2433cbdc917e20d164e..759c0bba4a8fa54d95b12d5434ad72a643a25f88 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/sched.h>
 #include <linux/leds.h>
index 38b3378be442b3d6501b8ffb9aa67e8eaba21ef4..82b77bd482ffdb4f952f0785c197db6efe1e8736 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/timer.h>
 #include <linux/ctype.h>
 #include <linux/leds.h>
+#include <linux/slab.h>
 #include "leds.h"
 
 struct timer_trig_data {
index 8744d24ac6e639213e4366cc7dd12d06ec039a4e..efa202499e37f792eb808188bf80652ce3cd07fc 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/cpu.h>
 #include <linux/freezer.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 #include <asm/paravirt.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
index bc28745d05af9794f756a5a29e64bb0b51a230ff..9136411fadd53e10c47c0624cf8576e7ae9d70b2 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/wait.h>
 #include <linux/hrtimer.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <asm/lguest.h>
 
index b6200bc39b5814460c4a7e451d63c680e593e1f7..69c84a1d88ea982d164ca55a94a9c8544c0cceb9 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/interrupt.h>
 #include <linux/virtio_ring.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/paravirt.h>
 #include <asm/lguest_hcall.h>
@@ -177,7 +178,7 @@ static void set_status(struct virtio_device *vdev, u8 status)
 
        /* We set the status. */
        to_lgdev(vdev)->desc->status = status;
-       kvm_hypercall1(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset);
+       hcall(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset, 0, 0, 0);
 }
 
 static void lg_set_status(struct virtio_device *vdev, u8 status)
@@ -228,7 +229,7 @@ static void lg_notify(struct virtqueue *vq)
         */
        struct lguest_vq_info *lvq = vq->priv;
 
-       kvm_hypercall1(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT);
+       hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0, 0);
 }
 
 /* An extern declaration inside a C file is bad form.  Don't do it. */
index bd1632388e4a37f0f12268e83d645b92e96632ff..85b714df8eae8d8ef372f74bedeb4497eab1f8d7 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/sched.h>
 #include <linux/eventfd.h>
 #include <linux/file.h>
+#include <linux/slab.h>
 #include "lg.h"
 
 /*L:056
index cf94326f1b597f1b46ccc3ddc996b5aa0ef84f5f..04b22128a47421cac65a6dd73480ee56c87ded1d 100644 (file)
@@ -10,6 +10,7 @@
 /* Copyright (C) Rusty Russell IBM Corporation 2006.
  * GPL v2 and any later version */
 #include <linux/mm.h>
+#include <linux/gfp.h>
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <linux/random.h>
index fb2b7ef7868ef6e0126c932049122f729fab7cb1..b4eb675a807e6c71f021de8c84133bd6c26bc50b 100644 (file)
@@ -287,6 +287,18 @@ static int emulate_insn(struct lg_cpu *cpu)
        /* Decoding x86 instructions is icky. */
        insn = lgread(cpu, physaddr, u8);
 
+       /*
+        * Around 2.6.33, the kernel started using an emulation for the
+        * cmpxchg8b instruction in early boot on many configurations.  This
+        * code isn't paravirtualized, and it tries to disable interrupts.
+        * Ignore it, which will Mostly Work.
+        */
+       if (insn == 0xfa) {
+               /* "cli", or Clear Interrupt Enable instruction.  Skip it. */
+               cpu->regs->eip++;
+               return 1;
+       }
+
        /*
         * 0x66 is an "operand prefix".  It means it's using the upper 16 bits
         * of the eax register.
index e943d2a29253d53b60d35c08cfe89e83902508ac..067f9962f499e4941c1e97b11dbf469c8b27e043 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/sysctl.h>
 #include <linux/input.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 MODULE_LICENSE("GPL");
 
index 93fb32038b14cf2e822708763669dfc855f4e49d..7c54d80c4fb2309e1873cd52981fe7ff186853b5 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
index f96feeb6b9ce0da9d22acb9a47697eac4f1e3efb..888448cf7f1f1fedf4af2212ca242f06f88d04f7 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/mutex.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 
 #include <asm/byteorder.h>
 #include <asm/io.h>
index 921373e4e3af9b1c5d4d9f022df5bb2555e301d5..b18fa948f3d1be64c3f3df73cbc715596fb05de7 100644 (file)
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/wait.h>
index 7fb8b4da35a7a740c81dbd005e2d05d1f656926d..0839770e4ec54faa6c742c4c7f06ac81fecb7080 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/i2c.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/kthread.h>
 #include <linux/of_platform.h>
index 4f3c4479c16aa16da18efd22bbc37e12dc39d2c7..1cec02f6c431a0af52f8360f262c2cdb6859e14e 100644 (file)
@@ -144,6 +144,7 @@ void pmu_backlight_set_sleep(int sleep)
 
 void __init pmu_backlight_init()
 {
+       struct backlight_properties props;
        struct backlight_device *bd;
        char name[10];
        int level, autosave;
@@ -161,13 +162,15 @@ void __init pmu_backlight_init()
 
        snprintf(name, sizeof(name), "pmubl");
 
-       bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+       bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data,
+                                      &props);
        if (IS_ERR(bd)) {
                printk(KERN_ERR "PMU Backlight registration failed\n");
                return;
        }
        uses_pmu_bl = 1;
-       bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
        pmu_backlight_init_curve(0x7F, 0x46, 0x0E);
 
        level = bd->props.max_brightness;
index fb9fa614a0e8e2f1f4ff0792c3b0ec1e476239ff..aeb30d07d5a29bd9981759d3cc91ab535520ea9c 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/miscdevice.h>
 #include <linux/blkdev.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 
index 419795f4a2aabb7ce5c311d42d075f2e6038bcf2..ce8897933a84daeccddd318438b939face4aec8f 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/kthread.h>
@@ -209,6 +210,7 @@ int wf_register_control(struct wf_control *new_ct)
        kref_init(&new_ct->ref);
        list_add(&new_ct->link, &wf_controls);
 
+       sysfs_attr_init(&new_ct->attr.attr);
        new_ct->attr.attr.name = new_ct->name;
        new_ct->attr.attr.mode = 0644;
        new_ct->attr.show = wf_show_control;
index 7ac2c1450d1004c4de300df3aab50fead2cfe5e0..1ed0094f064b351aa121e0858fbb31cbaee9f166 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <linux/bio.h>
+#include <linux/slab.h>
 #include <linux/dm-dirty-log.h>
 #include <linux/device-mapper.h>
 #include <linux/dm-log-userspace.h>
index f1c8cae70b4ba0c8de108a88ee72ecc26def140a..075cbcf8a9f51ab4607810c6071a7d54c0a38c38 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <linux/workqueue.h>
 #include <linux/connector.h>
index 168bd38f50060968cf59e3543708701f1f1f575a..bd5c58b2886849a795b762823246c55b9d8e49ea 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include "dm.h"
index cfa668f46c40f1b746cb1e2c230385855f5a5997..9c6c2e47ad625a6a12328d33d3491c7b413ca8f4 100644 (file)
@@ -11,6 +11,8 @@
 #include "dm.h"
 #include "dm-path-selector.h"
 
+#include <linux/slab.h>
+
 #define DM_MSG_PREFIX  "multipath service-time"
 #define ST_MIN_IO      1
 #define ST_MAX_RELATIVE_THROUGHPUT     100
index 04feccf2a997947968260029419e7813cb222553..11dea11dc0b649e16594e071163f79647c274293 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/bio.h>
-#include <linux/slab.h>
 
 #define DM_MSG_PREFIX "target"
 
index 713acd02ab39f1cd9662b5238c6e770fcc73c00c..8e3850b98cca508f2bb60de9aa0c843c3328779b 100644 (file)
@@ -64,6 +64,7 @@
 #define MaxFault       50
 #include <linux/blkdev.h>
 #include <linux/raid/md_u.h>
+#include <linux/slab.h>
 #include "md.h"
 #include <linux/seq_file.h>
 
index af2d39d603c74446c3c792d6bdc3ee334067d639..09437e958235e469c75aaab913d6b651ccde9f64 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/blkdev.h>
 #include <linux/raid/md_u.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "md.h"
 #include "linear.h"
 
@@ -172,12 +173,14 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
                disk_stack_limits(mddev->gendisk, rdev->bdev,
                                  rdev->data_offset << 9);
                /* as we don't honour merge_bvec_fn, we must never risk
-                * violating it, so limit ->max_sector to one PAGE, as
-                * a one page request is never in violation.
+                * violating it, so limit max_segments to 1 lying within
+                * a single page.
                 */
-               if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
-                   queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
-                       blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9);
+               if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+                       blk_queue_max_segments(mddev->queue, 1);
+                       blk_queue_segment_boundary(mddev->queue,
+                                                  PAGE_CACHE_SIZE - 1);
+               }
 
                conf->array_sectors += rdev->sectors;
                cnt++;
index fdc1890b6ac58310bd988f518ca4751df1a95cd4..cefd63daff3109ee6f54474e1d03f617c61d10f7 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/delay.h>
 #include <linux/raid/md_p.h>
 #include <linux/raid/md_u.h>
+#include <linux/slab.h>
 #include "md.h"
 #include "bitmap.h"
 
@@ -2108,12 +2109,18 @@ repeat:
                if (!mddev->in_sync || mddev->recovery_cp != MaxSector) { /* not clean */
                        /* .. if the array isn't clean, an 'even' event must also go
                         * to spares. */
-                       if ((mddev->events&1)==0)
+                       if ((mddev->events&1)==0) {
                                nospares = 0;
+                               sync_req = 2; /* force a second update to get the
+                                              * even/odd in sync */
+                       }
                } else {
                        /* otherwise an 'odd' event must go to spares */
-                       if ((mddev->events&1))
+                       if ((mddev->events&1)) {
                                nospares = 0;
+                               sync_req = 2; /* force a second update to get the
+                                              * even/odd in sync */
+                       }
                }
        }
 
index 4b323f45ad74a357432c6115822f4cc5347ef0c3..789bf535d29cbd7d9b6b00b9f825dd6c6f663791 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/blkdev.h>
 #include <linux/raid/md_u.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "md.h"
 #include "multipath.h"
 
@@ -301,14 +302,16 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
                                          rdev->data_offset << 9);
 
                /* as we don't honour merge_bvec_fn, we must never risk
-                * violating it, so limit ->max_sector to one PAGE, as
-                * a one page request is never in violation.
+                * violating it, so limit ->max_segments to one, lying
+                * within a single page.
                 * (Note: it is very unlikely that a device with
                 * merge_bvec_fn will be involved in multipath.)
                 */
-                       if (q->merge_bvec_fn &&
-                           queue_max_sectors(q) > (PAGE_SIZE>>9))
-                               blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9);
+                       if (q->merge_bvec_fn) {
+                               blk_queue_max_segments(mddev->queue, 1);
+                               blk_queue_segment_boundary(mddev->queue,
+                                                          PAGE_CACHE_SIZE - 1);
+                       }
 
                        conf->working_disks++;
                        mddev->degraded--;
@@ -476,9 +479,11 @@ static int multipath_run (mddev_t *mddev)
                /* as we don't honour merge_bvec_fn, we must never risk
                 * violating it, not that we ever expect a device with
                 * a merge_bvec_fn to be involved in multipath */
-               if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
-                   queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
-                       blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9);
+               if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+                       blk_queue_max_segments(mddev->queue, 1);
+                       blk_queue_segment_boundary(mddev->queue,
+                                                  PAGE_CACHE_SIZE - 1);
+               }
 
                if (!test_bit(Faulty, &rdev->flags))
                        conf->working_disks++;
index a1f7147b757fd6f79231ef52721b587fbbfe4432..c3bec024612e63682a9367cc58579c89c1303f5f 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/blkdev.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "md.h"
 #include "raid0.h"
 
@@ -176,14 +177,15 @@ static int create_strip_zones(mddev_t *mddev)
                disk_stack_limits(mddev->gendisk, rdev1->bdev,
                                  rdev1->data_offset << 9);
                /* as we don't honour merge_bvec_fn, we must never risk
-                * violating it, so limit ->max_sector to one PAGE, as
-                * a one page request is never in violation.
+                * violating it, so limit ->max_segments to 1, lying within
+                * a single page.
                 */
 
-               if (rdev1->bdev->bd_disk->queue->merge_bvec_fn &&
-                   queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
-                       blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9);
-
+               if (rdev1->bdev->bd_disk->queue->merge_bvec_fn) {
+                       blk_queue_max_segments(mddev->queue, 1);
+                       blk_queue_segment_boundary(mddev->queue,
+                                                  PAGE_CACHE_SIZE - 1);
+               }
                if (!smallest || (rdev1->sectors < smallest->sectors))
                        smallest = rdev1;
                cnt++;
index 5a06122abd3bbd9d49a121675e37dd95bd5ba4ff..e59b10e66edb961c8a270b8ebd11830a62551ca3 100644 (file)
@@ -31,6 +31,7 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/seq_file.h>
@@ -1152,13 +1153,17 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
 
                        disk_stack_limits(mddev->gendisk, rdev->bdev,
                                          rdev->data_offset << 9);
-                       /* as we don't honour merge_bvec_fn, we must never risk
-                        * violating it, so limit ->max_sector to one PAGE, as
-                        * a one page request is never in violation.
+                       /* as we don't honour merge_bvec_fn, we must
+                        * never risk violating it, so limit
+                        * ->max_segments to one lying with a single
+                        * page, as a one page request is never in
+                        * violation.
                         */
-                       if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
-                           queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
-                               blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9);
+                       if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+                               blk_queue_max_segments(mddev->queue, 1);
+                               blk_queue_segment_boundary(mddev->queue,
+                                                          PAGE_CACHE_SIZE - 1);
+                       }
 
                        p->head_position = 0;
                        rdev->raid_disk = mirror;
@@ -2098,12 +2103,14 @@ static int run(mddev_t *mddev)
                disk_stack_limits(mddev->gendisk, rdev->bdev,
                                  rdev->data_offset << 9);
                /* as we don't honour merge_bvec_fn, we must never risk
-                * violating it, so limit ->max_sector to one PAGE, as
-                * a one page request is never in violation.
+                * violating it, so limit ->max_segments to 1 lying within
+                * a single page, as a one page request is never in violation.
                 */
-               if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
-                   queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
-                       blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9);
+               if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+                       blk_queue_max_segments(mddev->queue, 1);
+                       blk_queue_segment_boundary(mddev->queue,
+                                                  PAGE_CACHE_SIZE - 1);
+               }
        }
 
        mddev->degraded = 0;
index 7584f9ab9bcfedf159bf94fd1238f9321d14e866..e2766d8251a184a6c28a67430ca34c7e68d0df67 100644 (file)
@@ -18,6 +18,7 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/seq_file.h>
@@ -1155,13 +1156,17 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
 
                        disk_stack_limits(mddev->gendisk, rdev->bdev,
                                          rdev->data_offset << 9);
-                       /* as we don't honour merge_bvec_fn, we must never risk
-                        * violating it, so limit ->max_sector to one PAGE, as
-                        * a one page request is never in violation.
+                       /* as we don't honour merge_bvec_fn, we must
+                        * never risk violating it, so limit
+                        * ->max_segments to one lying with a single
+                        * page, as a one page request is never in
+                        * violation.
                         */
-                       if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
-                           queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
-                               blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9);
+                       if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+                               blk_queue_max_segments(mddev->queue, 1);
+                               blk_queue_segment_boundary(mddev->queue,
+                                                          PAGE_CACHE_SIZE - 1);
+                       }
 
                        p->head_position = 0;
                        rdev->raid_disk = mirror;
@@ -2255,12 +2260,14 @@ static int run(mddev_t *mddev)
                disk_stack_limits(mddev->gendisk, rdev->bdev,
                                  rdev->data_offset << 9);
                /* as we don't honour merge_bvec_fn, we must never risk
-                * violating it, so limit ->max_sector to one PAGE, as
-                * a one page request is never in violation.
+                * violating it, so limit max_segments to 1 lying
+                * within a single page.
                 */
-               if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
-                   queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9))
-                       blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9);
+               if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
+                       blk_queue_max_segments(mddev->queue, 1);
+                       blk_queue_segment_boundary(mddev->queue,
+                                                  PAGE_CACHE_SIZE - 1);
+               }
 
                disk->head_position = 0;
        }
index 70ffbd071b2e797be6f715dd40de19a93c6567d3..15348c393b5daeb59ad11a9050f66eef428b4314 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/async.h>
 #include <linux/seq_file.h>
 #include <linux/cpu.h>
+#include <linux/slab.h>
 #include "md.h"
 #include "raid5.h"
 #include "bitmap.h"
@@ -1526,7 +1527,7 @@ static void raid5_end_read_request(struct bio * bi, int error)
 
                clear_bit(R5_UPTODATE, &sh->dev[i].flags);
                atomic_inc(&rdev->read_errors);
-               if (conf->mddev->degraded)
+               if (conf->mddev->degraded >= conf->max_degraded)
                        printk_rl(KERN_WARNING
                                  "raid5:%s: read error not correctable "
                                  "(sector %llu on %s).\n",
@@ -1649,8 +1650,8 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
                                     int previous, int *dd_idx,
                                     struct stripe_head *sh)
 {
-       long stripe;
-       unsigned long chunk_number;
+       sector_t stripe, stripe2;
+       sector_t chunk_number;
        unsigned int chunk_offset;
        int pd_idx, qd_idx;
        int ddf_layout = 0;
@@ -1670,18 +1671,13 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
         */
        chunk_offset = sector_div(r_sector, sectors_per_chunk);
        chunk_number = r_sector;
-       BUG_ON(r_sector != chunk_number);
 
        /*
         * Compute the stripe number
         */
-       stripe = chunk_number / data_disks;
-
-       /*
-        * Compute the data disk and parity disk indexes inside the stripe
-        */
-       *dd_idx = chunk_number % data_disks;
-
+       stripe = chunk_number;
+       *dd_idx = sector_div(stripe, data_disks);
+       stripe2 = stripe;
        /*
         * Select the parity disk based on the user selected algorithm.
         */
@@ -1693,21 +1689,21 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
        case 5:
                switch (algorithm) {
                case ALGORITHM_LEFT_ASYMMETRIC:
-                       pd_idx = data_disks - stripe % raid_disks;
+                       pd_idx = data_disks - sector_div(stripe2, raid_disks);
                        if (*dd_idx >= pd_idx)
                                (*dd_idx)++;
                        break;
                case ALGORITHM_RIGHT_ASYMMETRIC:
-                       pd_idx = stripe % raid_disks;
+                       pd_idx = sector_div(stripe2, raid_disks);
                        if (*dd_idx >= pd_idx)
                                (*dd_idx)++;
                        break;
                case ALGORITHM_LEFT_SYMMETRIC:
-                       pd_idx = data_disks - stripe % raid_disks;
+                       pd_idx = data_disks - sector_div(stripe2, raid_disks);
                        *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
                        break;
                case ALGORITHM_RIGHT_SYMMETRIC:
-                       pd_idx = stripe % raid_disks;
+                       pd_idx = sector_div(stripe2, raid_disks);
                        *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
                        break;
                case ALGORITHM_PARITY_0:
@@ -1727,7 +1723,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
 
                switch (algorithm) {
                case ALGORITHM_LEFT_ASYMMETRIC:
-                       pd_idx = raid_disks - 1 - (stripe % raid_disks);
+                       pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks);
                        qd_idx = pd_idx + 1;
                        if (pd_idx == raid_disks-1) {
                                (*dd_idx)++;    /* Q D D D P */
@@ -1736,7 +1732,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
                                (*dd_idx) += 2; /* D D P Q D */
                        break;
                case ALGORITHM_RIGHT_ASYMMETRIC:
-                       pd_idx = stripe % raid_disks;
+                       pd_idx = sector_div(stripe2, raid_disks);
                        qd_idx = pd_idx + 1;
                        if (pd_idx == raid_disks-1) {
                                (*dd_idx)++;    /* Q D D D P */
@@ -1745,12 +1741,12 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
                                (*dd_idx) += 2; /* D D P Q D */
                        break;
                case ALGORITHM_LEFT_SYMMETRIC:
-                       pd_idx = raid_disks - 1 - (stripe % raid_disks);
+                       pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks);
                        qd_idx = (pd_idx + 1) % raid_disks;
                        *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
                        break;
                case ALGORITHM_RIGHT_SYMMETRIC:
-                       pd_idx = stripe % raid_disks;
+                       pd_idx = sector_div(stripe2, raid_disks);
                        qd_idx = (pd_idx + 1) % raid_disks;
                        *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
                        break;
@@ -1769,7 +1765,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
                        /* Exactly the same as RIGHT_ASYMMETRIC, but or
                         * of blocks for computing Q is different.
                         */
-                       pd_idx = stripe % raid_disks;
+                       pd_idx = sector_div(stripe2, raid_disks);
                        qd_idx = pd_idx + 1;
                        if (pd_idx == raid_disks-1) {
                                (*dd_idx)++;    /* Q D D D P */
@@ -1784,7 +1780,8 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
                         * D D D P Q  rather than
                         * Q D D D P
                         */
-                       pd_idx = raid_disks - 1 - ((stripe + 1) % raid_disks);
+                       stripe2 += 1;
+                       pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks);
                        qd_idx = pd_idx + 1;
                        if (pd_idx == raid_disks-1) {
                                (*dd_idx)++;    /* Q D D D P */
@@ -1796,7 +1793,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
 
                case ALGORITHM_ROTATING_N_CONTINUE:
                        /* Same as left_symmetric but Q is before P */
-                       pd_idx = raid_disks - 1 - (stripe % raid_disks);
+                       pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks);
                        qd_idx = (pd_idx + raid_disks - 1) % raid_disks;
                        *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
                        ddf_layout = 1;
@@ -1804,27 +1801,27 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
 
                case ALGORITHM_LEFT_ASYMMETRIC_6:
                        /* RAID5 left_asymmetric, with Q on last device */
-                       pd_idx = data_disks - stripe % (raid_disks-1);
+                       pd_idx = data_disks - sector_div(stripe2, raid_disks-1);
                        if (*dd_idx >= pd_idx)
                                (*dd_idx)++;
                        qd_idx = raid_disks - 1;
                        break;
 
                case ALGORITHM_RIGHT_ASYMMETRIC_6:
-                       pd_idx = stripe % (raid_disks-1);
+                       pd_idx = sector_div(stripe2, raid_disks-1);
                        if (*dd_idx >= pd_idx)
                                (*dd_idx)++;
                        qd_idx = raid_disks - 1;
                        break;
 
                case ALGORITHM_LEFT_SYMMETRIC_6:
-                       pd_idx = data_disks - stripe % (raid_disks-1);
+                       pd_idx = data_disks - sector_div(stripe2, raid_disks-1);
                        *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
                        qd_idx = raid_disks - 1;
                        break;
 
                case ALGORITHM_RIGHT_SYMMETRIC_6:
-                       pd_idx = stripe % (raid_disks-1);
+                       pd_idx = sector_div(stripe2, raid_disks-1);
                        *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
                        qd_idx = raid_disks - 1;
                        break;
@@ -1869,14 +1866,14 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
                                 : conf->algorithm;
        sector_t stripe;
        int chunk_offset;
-       int chunk_number, dummy1, dd_idx = i;
+       sector_t chunk_number;
+       int dummy1, dd_idx = i;
        sector_t r_sector;
        struct stripe_head sh2;
 
 
        chunk_offset = sector_div(new_sector, sectors_per_chunk);
        stripe = new_sector;
-       BUG_ON(new_sector != stripe);
 
        if (i == sh->pd_idx)
                return 0;
@@ -1969,7 +1966,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
        }
 
        chunk_number = stripe * data_disks + i;
-       r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset;
+       r_sector = chunk_number * sectors_per_chunk + chunk_offset;
 
        check = raid5_compute_sector(conf, r_sector,
                                     previous, &dummy1, &sh2);
index bffc61bff5ab7c743d4ce0da3d716cd8642112f0..1f8784bfd44de61972e655363e01105840c29445 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/raid/pq.h>
+#include <linux/gfp.h>
 #ifndef __KERNEL__
 #include <sys/mman.h>
 #include <stdio.h>
index 0a3b4ed38e488ebd3015042c2b8a5b0c1b0160ba..bfca26d51827823fdb42c15778843bb2f5889c51 100644 (file)
@@ -14,6 +14,7 @@
 
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <media/ir-common.h>
 
 #define IR_TAB_MIN_SIZE        32
index bf5fbcd84238c670ccd7893d77f8ca482153e774..e14e6c486b52ce8eae41db83bc8f6acd0b4ce493 100644 (file)
@@ -12,6 +12,7 @@
  *  GNU General Public License for more details.
  */
 
+#include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/device.h>
 #include <media/ir-core.h>
index fd8e1f45be369343e2e7973de54fe5f0faef5dad..7364b9642d005c0579838c4efdf7c61888767f98 100644 (file)
@@ -423,15 +423,14 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status)
        }
 }
 
-int saa7146_vv_devinit(struct saa7146_dev *dev)
-{
-       return v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev);
-}
-EXPORT_SYMBOL_GPL(saa7146_vv_devinit);
-
 int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
 {
        struct saa7146_vv *vv;
+       int err;
+
+       err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev);
+       if (err)
+               return err;
 
        vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL);
        if (vv == NULL) {
index 5ed75263340a91c966cdf58f0a4390efeeab3fd8..b8b2c551a1e2d07aae91c983103c29fb52820080 100644 (file)
@@ -558,9 +558,11 @@ static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f
        /* ok, accept it */
        vv->ov_fb = *fb;
        vv->ov_fmt = fmt;
-       if (0 == vv->ov_fb.fmt.bytesperline)
-               vv->ov_fb.fmt.bytesperline =
-                       vv->ov_fb.fmt.width * fmt->depth / 8;
+
+       if (vv->ov_fb.fmt.bytesperline < vv->ov_fb.fmt.width) {
+               vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width * fmt->depth / 8;
+               DEB_D(("setting bytesperline to %d\n", vv->ov_fb.fmt.bytesperline));
+       }
 
        mutex_unlock(&dev->lock);
        return 0;
index 3d03640cf1fe42aab8475419755f9294467e4968..937e4b00d7eea162e9a966f01d8456f41db14587 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/dvb/frontend.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 
index 20c4485ce16a642a9724af9efb1cfed2667e64b3..fe5c4b8d83eeddaa203806da48726822e93eeb49 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/dvb/frontend.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 
index c7abe3d8f90e1eccdfface5dd7471d3fd0a5fef5..2d0e7689c6a224eae8757c5c054972f1ab03d2a6 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/dvb/frontend.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 
index 44608ad4e2d205132e2b9f86cfc62beaddd67fd4..d0e70e10a7178214d8cee4a7892f4c73ea2d232f 100644 (file)
@@ -6,6 +6,7 @@
  */
 #include <linux/delay.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/videodev2.h>
 #include "tuner-i2c.h"
 #include "mt20xx.h"
index e8d3c48f86059d13aab958f0465346413439b2b8..a4f830bb25d1346a8961f15fd477d64023424604 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/dvb/frontend.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 
index 54b18f94b14bc427511a69fd9a116d3197bc98bb..25a8ea342c466d60a767d7d4b4ea622003125add 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/dvb/frontend.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "mt2266.h"
index 36a7bc7585ab6c12473033a12ceeb72cb12e4861..b21b6ea68b2501164fa503ac77f6ffb02f9b3aba 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/types.h>
 #include <linux/dvb/frontend.h>
 #include <linux/videodev2.h>
index 2833137fa8195bdc41c8337267bcbee81168082a..c9062ceddc719d25cb05fbe253c1f8d3dc46b8ae 100644 (file)
@@ -21,6 +21,7 @@
 */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/videodev2.h>
 #include "tuner-i2c.h"
index a71c100c95df674c60ff3033624f675f420f14c9..bf14bd79e2fc599b7216e43d0a1c78564479dd7e 100644 (file)
@@ -4,7 +4,6 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
index 60ed872f3d44681c4e85656dcf38b10fbd77105c..925399dffbed6c4f2820841d2139325edaaf43ed 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/videodev2.h>
 #include <media/tuner.h>
index 223a226d20a19e6b137a6316913fca8de46fd5c8..36e85d81acb2ca10c953ab83966502c138035392 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/videodev2.h>
 #include "tuner-i2c.h"
index cb1c7141f0c6d9e96d76110e6ce657ae18148c15..18f005634c676e9789e08e644541cdf650508e79 100644 (file)
@@ -22,6 +22,7 @@
 #define __TUNER_I2C_H__
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 struct tuner_i2c_props {
        u8 addr;
index be51c294b375b5a17a33d8a48e2ab3b4db88e923..96d61707f501cfc28b7caf1136741fcfc415f0aa 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/delay.h>
 #include <media/tuner.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include "tuner-i2c.h"
 #include "tuner-xc2028.h"
index 0e246eaad05ab441360963e02672945e6d61534b..770243c720d2e3d06a5fb733ff05ba505c0eb88b 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
 #include <linux/string.h>
index 383cca378b8c5bb38e8b5935a013405c0bcac315..b6d46961a99e8726954f4adb2381e59fa05d60a3 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <media/ir-common.h>
 
 #include "demux.h"
index c1379b56dfb4d47f4da21caa8c6c399a51c8003e..02ebe28f830d811b9ea7079ad450cc626a6b3863 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <linux/dvb/dmx.h>
 
index 80dda308ff740bf67479f7397d6b107bfac44069..bf0e6bed28dd13bb0b49648a7d73a4dd6e579317 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <linux/dvb/frontend.h>
 
index d7975383d31b58a7257cc42266afb335af6bf8ef..74d94e45324d8d1bc4fe8acdd5533fdc1e640c42 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/hash.h>
+#include <linux/slab.h>
 
 #include "af9015.h"
 #include "af9013.h"
index a7b8405c291e472570958ba713b1712223b37c68..960376da7d59b4e5a23fe3014e9f3a99aca9f95d 100644 (file)
@@ -25,6 +25,7 @@
  */
 #include <media/tuner.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include "cxusb.h"
 
index c3e0ec2dcfca56641b680162e5420ed976d19e4c..26333b4f4d3e9b039460513189383fcf45199745 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
 
index 599d66e5843dcd51668077ad7404618336d10ae5..fcf3828472b847b537887c8a6f996fe4d2093f79 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/bitops.h>
 #include <linux/input.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
index 956b80f4979ca95af361162ec6adde484a1c9c89..a1fed0fa8ed4905ba8a31b92e2664f66a1c25ac1 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include "dvb_frontend.h"
 #include "au8522.h"
index 0d12763603b47d7bdcb2f4f008fb1eff875f97ae..d4e466a90e43d08d0e3fb6c3a24589ccd8f91857 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 
 #include "dvb_frontend.h"
index 7eac178f57b2c10093198c653b4e03e332c9e431..65240b7801e83c9dbfed88aa03ec1ea0eb94ff28 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 
 #include "dvb_frontend.h"
index fa851601e7d4af1baae5312cce3819380df2a523..40a099810279315b3b5502be0db64ddece9f584c 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 
 #include "dvb_frontend.h"
index 0109720353bd475e6458c347ea42dfca0663d3de..0f09fd31cb293cbcaa2bd5a34414411fca4459da 100644 (file)
@@ -9,6 +9,7 @@
  *     published by the Free Software Foundation, version 2.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 
 #include "dvb_frontend.h"
index 750ae61a20f4ba7555581f15710f187d584692f6..85468a45c344d96b15c321a250edfa022da38bfd 100644 (file)
@@ -8,6 +8,7 @@
  *     published by the Free Software Foundation, version 2.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 
 #include "dvb_math.h"
index 2aa97dd6a8afdb71e93b49a1e20b0c6fac32df1c..df17b91b3250b45596619a6a752d63061f4c8a45 100644 (file)
@@ -8,6 +8,7 @@
  *  published by the Free Software Foundation, version 2.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include "dvb_math.h"
 
index 868b78bfae75e4b3cf8e6ba9e11ceec27311e384..f74cca6dc26b278ba657834de7660b93e02de8f2 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <asm/div64.h>
 
 #include "dvb_frontend.h"
index 6d865d6161d78b33ffe05472de147bdf5360d06b..4d4d0bb5920ac1821dfcc2d2a28de3b016a9573a 100644 (file)
@@ -18,6 +18,7 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/dvb/frontend.h>
 #include <asm/types.h>
index 600dad6b41ea8a59641bea1bc5bc36b3aea36e71..f7a40a18777a0e13a90dfdc7f4e75ce87a952955 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/dvb/frontend.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 
index e334b5d4e5785d1ad93a07f46d808cbea87edecd..45a529b06b9d31b13531d0181a29259ae54b8f98 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include "dvb_frontend.h"
 #include "lgdt3304.h"
index fde8c59700fbee05d63b6b6433adedd7ec9499a9..d69c775f8645419116f13befc0d4476cc2629016 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <asm/div64.h>
 #include <linux/dvb/frontend.h>
+#include <linux/slab.h>
 #include "dvb_math.h"
 #include "lgdt3305.h"
 
index d05f7500e0c514fb966fdc12b2db8824e017ab70..599d1aa519a31ca160306471c237a1ba362a7ba3 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "mb86a16.h"
index 3156b64cfc9642d2d0c7230716091fc70e38d26f..0eefff61cc50cac76952427539bd47445c505e23 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include "dvb_frontend.h"
 #include "s921_module.h"
index 1570669837ea72aae6646dd333ee6d9df0418774..8e38fcee564e918bb107c13bda376d1c6e962872 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
 #include <linux/dvb/frontend.h>
index 0e2cb0df144171cffa183a72b813dede4078d026..ed699647050e5eec49422391e98f660d7c9611cf 100644 (file)
@@ -20,6 +20,7 @@
 
   */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/dvb/frontend.h>
 #include <asm/types.h>
index 60ee18a94f43228b74a944cadad7c5ed430301d2..f73c13323e902166e64746e30d67acd12acc419f 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
 #include "dvb_frontend.h"
index c52c3357dc54dc71900f332c8e5c91e4b1f50cd5..96972804f4ad3f412d98d111265051faa666fb27 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 
 #include <linux/dvb/frontend.h>
@@ -4469,6 +4470,10 @@ static int stv090x_setup(struct dvb_frontend *fe)
        if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0)
                goto err;
 
+       /* workaround for stuck DiSEqC output */
+       if (config->diseqc_envelope_mode)
+               stv090x_send_diseqc_burst(fe, SEC_MINI_A);
+
        return 0;
 err:
        dprintk(FE_ERROR, 1, "I/O error");
index bef0cc83847129e25a87f83bcc13c5a39935ba2f..2dca7c8e5148bb989b1e75b7ec5605afdf72851d 100644 (file)
@@ -22,6 +22,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/dvb/frontend.h>
 
index f931ed07e92d6083b088db293e43931f69cbe4b8..dea4245f077c9b2a9fff430a0287bf131ffda3c1 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
 #include "dvb_frontend.h"
index c44fefe92d97c9614e36876707b72b8bfcadce76..2c1c759a4f42f2ee1b073bba1b4d127da1d00f6b 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "tda665x.h"
index 614afcec05f119c6cea50540d551503a19dbedbc..1742056a34e8c0a8270aee6a81a8ecba4917fc9e 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "tda8261.h"
index a051554b5e2589aeb32060ebb0a41c1c38b65e84..06c94800b9402955ccbf799f8ee66e93c2a4f956 100644 (file)
@@ -20,6 +20,7 @@
 
   */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/dvb/frontend.h>
 #include <asm/types.h>
index 1790baee014c4c7cb0f1f3cdf749d386d978ebbc..bcb95c2ef296092dfb50fcc18196cd5204fe97eb 100644 (file)
@@ -28,6 +28,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/dvb/frontend.h>
 #include <asm/types.h>
index 34c5de491d2b416287c1ccdfa05e24a9744be76d..4627f491656bcf90f239ff419a1a627672ddb38f 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <linux/module.h>
 #include <linux/dvb/frontend.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #include "zl10036.h"
index d073c61e3c0d1101404911ac8fc6db17b0b3fb29..09e9fc785189c2196fb04fe2273efcc4e867a1c3 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <asm/irq.h>
 #include <linux/interrupt.h>
 
index 403ce043d00e7a91b4bf7564806468eb3dbea4ea..330216febd780652ae393d88b31fd9d1e05ebe27 100644 (file)
@@ -19,6 +19,7 @@
 */
 
 #include <linux/signal.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 
index 16f1708fd3bc9fc28a70c0cac0b6ae9930cda44d..cf4b39ffdaad608dc0e5399def4f74ca63e10543 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <asm/irq.h>
 #include <linux/interrupt.h>
 
index 0150dfe7cfbb9c85c50d04b0e21552ab20e63304..645e8b8a71377664dc3a02e1e80957beaa7c0839 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/poll.h>
 #include <linux/io.h>
 #include <asm/div64.h>
index 80d14a065bad0755fda4af3f27edb0b9fbe18308..1c798219dc7ce02205205576b763a25e9da9de66 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include "demux.h"
 #include "dmxdev.h"
index 81e623a90f09d70905ec1080f545f93e1cdd43ec..6aded234aa61daafdeb92de9846eed6d9cb74952 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/pci.h>
 #include <linux/kthread.h>
index 4bfd3451b5682ca5a49a9f6b8fdea2726f554d63..0c87a3c3899ada10eceee75b0cd2ec07be1030fc 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <linux/firmware.h>
 #include <linux/wait.h>
index 5f3939821ca3eef3c786678cc91b9ef5ca326382..b80d09b035a1ad56f5f746213f34cbd289c16262 100644 (file)
@@ -20,6 +20,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ****************************************************************/
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #include "dmxdev.h"
index 195244a3e69b35400df3dd83a9856c76417cef9b..e57d38b0197c65e7c2d64e475a9a7c5b56beef43 100644 (file)
@@ -33,6 +33,7 @@
  */
 
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/delay.h>
 #include <linux/mmc/card.h>
index 5eac27287d9ceff598d346348581106466440069..a9c27fb69ba747272393bb033c65d4f48a7e194d 100644 (file)
@@ -23,6 +23,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include <linux/init.h>
 #include <linux/usb.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #include "smscoreapi.h"
 #include "sms-cards.h"
index baf3159a3aa63cb7f646e867e9463e8221da5ee1..38915591c6e52402938ac193c27739b174ad32f0 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/crc32.h>
 #include <linux/i2c.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include <asm/byteorder.h>
 
index c7a65b1544a330e34a2e500883981336ba23c6c4..ac7779c45c5b15e561d70ecc23e3de5b270ff5f5 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/fs.h>
 #include <linux/timer.h>
 #include <linux/poll.h>
+#include <linux/gfp.h>
 
 #include "av7110.h"
 #include "av7110_hw.h"
index 9fdf26cc6998054952c47290ed47fd457c408930..1500210c06cf6aff6ccd8c5b5db0fffa32a75d76 100644 (file)
@@ -643,9 +643,6 @@ static void frontend_init(struct budget *budget)
                                        &budget->i2c_adap,
                                        &tt1600_isl6423_config);
 
-                       } else {
-                               dvb_frontend_detach(budget->dvb_frontend);
-                               budget->dvb_frontend = NULL;
                        }
                }
                break;
index 000f4d34087ce2352fbd9c4ae8b47846f49aaa82..79039674a0e0bddff9976de584437a60b948e789 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/errno.h>
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 
index f8213b7c8ddc2a6c97ac94e8c52846fe9606711a..08f1051979cae6f7508026dc0e957a23de775795 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/pci.h>
 #include <linux/videodev2.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 
index 44b4dbedb322a57108483494f4785b7b02252076..4349213b403b55944f0ecac6edfbd3fe9e18f2bb 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/videodev2.h>
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 
index 170bbe554787b9c54aca8c85ed7186aa70ba3d2f..13554ab13f76afd8c29893aabde59a1c3d5d6a20 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
index 8e718bfcdad3200041b3bf458bf893f26cbedf2e..789d2ec66e1948d2d071c3424f92dc820b0bcc0b 100644 (file)
@@ -32,6 +32,7 @@
  *  add RDS support
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>                        /* Initdata                     */
 #include <linux/videodev2.h>           /* kernel radio structs         */
index 0de457f6e6eb3efe1efe65cdb275c4e498497452..b8bb3ef47df5c72153e7e1964ddbc679b3c1b8ed 100644 (file)
@@ -22,6 +22,7 @@
 #include <media/v4l2-device.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <media/timb_radio.h>
 
index 5db5528a8b2593d53af6a9cfe52a0985f66d01e6..585680ffbfb64b121a4eb01eff27da0346660f6b 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
 
index 5466015346a10be27b191659ff285d20b7d195bc..a5844d08d8b7917c19702d9f7879a1bc0244aba4 100644 (file)
@@ -31,6 +31,7 @@
 
 /* kernel includes */
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 
index 6f60841828dace59eda8b836475dc70a9b35e6c7..5ec13e50a9f0c22a3a81a6900cc2ee426ae14a2c 100644 (file)
@@ -37,6 +37,7 @@
 /* kernel includes */
 #include <linux/usb.h>
 #include <linux/hid.h>
+#include <linux/slab.h>
 
 #include "radio-si470x.h"
 
index 6a0028eb461f91ea767a609c56c09a9732ec2544..ab63dd5b25c44798523f51a6b4d88199b9e95c7a 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-common.h>
index 6e607ff0c1699b4c0366b757f69e3201da75980e..90cae90277e7dc6ea35e170f70d5301914b124dc 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
+#include <linux/slab.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
index f8fc8654693dde77814735e4deba5ed92991a109..9644cf760aaa62b51378986de160efff286347b6 100644 (file)
@@ -361,7 +361,7 @@ config VIDEO_SAA717X
 
 config VIDEO_SAA7191
        tristate "Philips SAA7191 video decoder"
-       depends on VIDEO_V4L1 && I2C
+       depends on VIDEO_V4L2 && I2C
        ---help---
          Support for the Philips SAA7191 video decoder.
 
@@ -756,7 +756,7 @@ source "drivers/media/video/saa7134/Kconfig"
 
 config VIDEO_MXB
        tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
-       depends on PCI && VIDEO_V4L1 && I2C
+       depends on PCI && VIDEO_V4L2 && I2C
        select VIDEO_SAA7146_VV
        select VIDEO_TUNER
        select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
index b88b6174a3313dc0b4982f8e19055a3556ae952c..c51c386559f2eafc77bd01fe15f3821076ee9ba1 100644 (file)
@@ -160,8 +160,6 @@ obj-$(CONFIG_VIDEO_MX3)                     += mx3_camera.o
 obj-$(CONFIG_VIDEO_PXA27x)             += pxa_camera.o
 obj-$(CONFIG_VIDEO_SH_MOBILE_CEU)      += sh_mobile_ceu_camera.o
 
-obj-$(CONFIG_ARCH_DAVINCI)             += davinci/
-
 obj-$(CONFIG_VIDEO_AU0828) += au0828/
 
 obj-$(CONFIG_USB_VIDEO_CLASS)  += uvc/
index 97b003449c91f33e3df579d06f188634031931cd..48e89fbf391b1399ed2662c7d8c4a51cc039f813 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
index cf8c06c85ded992adf227ac24d306af3c2813868..f1ba0d742c65a934c2c08b8b0b0713c975f30e7b 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
index 0826f0dabc172a72ad2aaa70f931ac2b0b05463a..23e610f6273663b8e46707ed0f31ca6b4f9a5a3f 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
+#include <linux/slab.h>
 #include <media/v4l2-ioctl.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
index df26f2fe44ebd23a5b37abd1efb865b498777bdd..41b2930d0ce4e59640ab946e81db7e234f5aca06 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/device.h>
 #include <linux/delay.h>
index 3544a2f12f13a1497f54ca30609a26e8e9ba8a49..ca342e4c61fcdc5bf59108a5a2bb38ebbbea81b0 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <linux/mutex.h>
index b8a4b52e8d472c3041230d8600d25371f399ba16..f1edf1d4afe8e4c3d1111cb59ff333b18827f679 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/suspend.h>
index dc67bc40f36fb60e4d21973f966a2fab39b64522..8c140c01c5e62e05b155331936ebebd141efe865 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/suspend.h>
index 547e1a93c421d004f78b0adc091eb098bcece593..770cb9accf81c6a55013ea05ab6318790dc8e3e6 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-i2c-drv.h>
index d0b4d4925ff84502e7ea09b0dd26aeecfce9106b..ae333739250552255ec61afdf8d5cb426545c27f 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
index af7e3a5bac9ff3adf96302f7eb0626137c3a6d04..62ac422bb1596a86527f77bfb6398796bb8216ea 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
index cb46e8fa8aaa3b9ce2d64a4d565a47a098950674..f4860f03dfc369d6478d7b132b1d456653b32d99 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
index 74c325e594a2eaf3509b139ef6b46a7a2f4d242a..fd604d32bbb9ae767bde852e94f8111f5633961e 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 #include "bttvp.h"
index b320dbd635aab0844b69ad2c2a99ed0e5b8b52b7..aa153a986ade3e7e264ab27815dd71db0538af18 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 
 #include "bttv.h"
 #include "bttvp.h"
index d16af28363798d45a19336b3d621836b9b9dcb85..c24b1c100e13fe0fb1c225950c6427da7b50db7f 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/interrupt.h>
index cbbf7e80d2cf856b5de2aed6ab6ca4d14b8d76f9..be35e6965829115a44b3f3a6c9a2ce5f1776ee4c 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-chip-ident.h>
index c431df8248d659199c66da758e6afcd35a918575..f5604c16a0927d5217b83de41ceb2692935c02fb 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/delay.h>
 #include <linux/workqueue.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <linux/kmod.h>
 
index 57dc1704b6c000d2bba62df2c398c1fa1b2dce7d..8362db509e2c60610aa334656bc0ee5b370b1ede 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-i2c-drv.h>
index 80bca8df9fbfddbfdf6ed0d4f786dc563206e44b..3cc135a98d827d624c35fda62020857d8da7abc1 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
index eb41d7ec65b95fc919a5858c6e6f511c7045941d..b5d7cbf4528ab9d0d455e76ab6ff278493f56ec1 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
index 93f0dae01350316d9c13110504df129baa4f5ecb..7fa589240ff2ab03ae71a6ad39172fd19a6465bc 100644 (file)
@@ -21,6 +21,7 @@
  *  02111-1307  USA
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include "cx18-driver.h"
 #include "cx18-cards.h"
index 23ad6d548dc52c51b45e6cd5ace9371e57f13c2d..b9728e8eee40b7e00cf4dc6d4c0811307045cf01 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/pagemap.h>
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 
 #include <linux/dvb/video.h>
index a549082350095311121ba0694045eb55cfdeeb70..6bdc0ef18119716dadc5facc2347f22fda5c6192 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/usb.h>
index 4a60dfbc347deaf06f3e1f0ec707cda91690340b..b24eee115e7e19af226ea70b932685435b1e3282 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/vmalloc.h>
 #include <media/v4l2-common.h>
index 64e025e2bdf1a477b255bd2a0cfcda719568e5da..4ea3776b39fba2a4c46abb0f7c238887184d01ed 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "cx231xx.h"
index c5771db3bfce8d6269113f3c1eb5f4cab2e1ffc6..b473cd8367f59ba170de3b76d187cd725c0a297f 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 #include "cx231xx.h"
 
index e97b8023a6557a8fe15c39c921b0c36038733730..689c5e25776c1f545cf4de9c192bef53a00fa1ae 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/i2c.h>
 #include <linux/mm.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
index d4f546f11d7490a833628a4017fa843f6e972b00..16a73eab6726aa9b7b3f1d381c1d0cb42672ba08 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/version.h>
 #include <linux/mm.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
index 2ab97ad7b6fb6d26f32fef3dcf3b614666a2a291..a8ddc227cf8643410846737038f92ac892b89015 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/cx2341x.h>
index 9c6620f86dcae8531649001b731718d3a19ecf50..8e9d990dbe9385b223fa5c3d95e1dff5c2a54ecc 100644 (file)
@@ -36,6 +36,7 @@
  */
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <media/ir-common.h>
 #include <media/v4l2-subdev.h>
 
index 5b297f0323b6485a5099a255d9bf8511414db848..708a8c766d1ad3377bdbce956a62fbe467bef546 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 
 #include "cx23885.h"
 
index 0e3a98d243c5529179dd78dbbb543160def4fec4..8d6a55e54ee7da7b12350a65bedfb135fd62ae1a 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
 #include <linux/kdev_t.h>
+#include <linux/slab.h>
 
 #include <media/v4l2-device.h>
 #include <media/tuner.h>
index 2bf57a4527d3484167e42ddde0c4bfb7b41d61de..ad728d767d699eba750ebbe5b65915d857a42b50 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/kfifo.h>
+#include <linux/slab.h>
 
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
index 64b350df78e3ab2c1efc7ead7bbe08c6b3183d49..33082c96745ed91d9eb23aceba34562cc66e4c4a 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/vmalloc.h>
 #include <linux/dma-mapping.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include <asm/delay.h>
 #include <sound/core.h>
index 6fe30e6c426221283c8df5c0984083f7daf6fbcb..e46e1ceef72c3f1f074cad2acc82171b730d3070 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/delay.h>
 #include <linux/device.h>
index eaf0ee7de832ecb599e4c95ff31955a15b6fadc6..2918a6e38fe8e5fa9039a0e088c59024443e7f71 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "cx88.h"
 #include "tea5767.h"
index 3e5eaf3fe2a6c05cfaad26d17fe0fbf6d6aafeaf..a94e00a4ac5d7a699d866fbf1ca21f3aafd490c6 100644 (file)
@@ -19,6 +19,7 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/jiffies.h>
index de180d4d5a2139c3a7c430e484724421df4e305d..6b6abf062c21bd7c08f9fedefd751526b54fbf46 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/hrtimer.h>
 #include <linux/input.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 
 #include "cx88.h"
index 338af77f7f01f2df2ff8dc9c4f9efb214e616365..6aba7af9160afbdf4137dde92f62629830a4b9dd 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
index e8316cf7f32f70b8e76b78eac4569b205cddf15d..239631568f3b50aa3e5ccbf69853717ba03d8ff6 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/errno.h>
 #include <linux/freezer.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/poll.h>
 #include <linux/signal.h>
index 0943060682bcd4ebf6039f32e3288f3d391fa76b..d9445b0e7ab2e294ca07db9acbdbf25d28cd3944 100644 (file)
@@ -3,7 +3,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 
 #include "cx88.h"
 
index 20800425c51ed5d1f5c4e08f82ecaf183d75deec..794f2932b75554bee6cb1adef6e24e9856b9f74a 100644 (file)
@@ -23,6 +23,7 @@
 */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #include <asm/io.h>
index 0c394cade22a5919173c0ea9b0e612d480f2022b..b4cc96dc99ef46eb358c9f731d27c35c7979fca9 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/platform_device.h>
 #include <linux/uaccess.h>
 #include <linux/videodev2.h>
+#include <linux/gfp.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 
index 885cd54499cf6952abbae826e7526ca5ac186673..398dbe71cb82aa60ca07e104b84c89f4274b959e 100644 (file)
@@ -67,6 +67,7 @@
  *             - Support for control ioctls
  */
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
@@ -222,7 +223,6 @@ int vpfe_register_ccdc_device(struct ccdc_hw_device *dev)
        BUG_ON(!dev->hw_ops.get_frame_format);
        BUG_ON(!dev->hw_ops.get_pixel_format);
        BUG_ON(!dev->hw_ops.set_pixel_format);
-       BUG_ON(!dev->hw_ops.set_params);
        BUG_ON(!dev->hw_ops.set_image_window);
        BUG_ON(!dev->hw_ops.get_image_window);
        BUG_ON(!dev->hw_ops.get_line_length);
@@ -1688,11 +1688,12 @@ static long vpfe_param_handler(struct file *file, void *priv,
        struct vpfe_device *vpfe_dev = video_drvdata(file);
        int ret = 0;
 
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_param_handler\n");
+       v4l2_dbg(2, debug, &vpfe_dev->v4l2_dev, "vpfe_param_handler\n");
 
        if (vpfe_dev->started) {
                /* only allowed if streaming is not started */
-               v4l2_err(&vpfe_dev->v4l2_dev, "device already started\n");
+               v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+                       "device already started\n");
                return -EBUSY;
        }
 
@@ -1704,16 +1705,23 @@ static long vpfe_param_handler(struct file *file, void *priv,
        case VPFE_CMD_S_CCDC_RAW_PARAMS:
                v4l2_warn(&vpfe_dev->v4l2_dev,
                          "VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n");
-               ret = ccdc_dev->hw_ops.set_params(param);
-               if (ret) {
-                       v4l2_err(&vpfe_dev->v4l2_dev,
-                               "Error in setting parameters in CCDC\n");
-                       goto unlock_out;
-               }
-               if (vpfe_get_ccdc_image_format(vpfe_dev, &vpfe_dev->fmt) < 0) {
-                       v4l2_err(&vpfe_dev->v4l2_dev,
-                               "Invalid image format at CCDC\n");
-                       goto unlock_out;
+               if (ccdc_dev->hw_ops.set_params) {
+                       ret = ccdc_dev->hw_ops.set_params(param);
+                       if (ret) {
+                               v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+                                       "Error setting parameters in CCDC\n");
+                               goto unlock_out;
+                       }
+                       if (vpfe_get_ccdc_image_format(vpfe_dev,
+                                                      &vpfe_dev->fmt) < 0) {
+                               v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+                                       "Invalid image format at CCDC\n");
+                               goto unlock_out;
+                       }
+               } else {
+                       ret = -EINVAL;
+                       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+                               "VPFE_CMD_S_CCDC_RAW_PARAMS not supported\n");
                }
                break;
        default:
@@ -1829,7 +1837,7 @@ static __init int vpfe_probe(struct platform_device *pdev)
        if (NULL == ccdc_cfg) {
                v4l2_err(pdev->dev.driver,
                         "Memory allocation failed for ccdc_cfg\n");
-               goto probe_free_dev_mem;
+               goto probe_free_lock;
        }
 
        strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32);
@@ -1981,8 +1989,9 @@ probe_out_video_release:
 probe_out_release_irq:
        free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
 probe_free_ccdc_cfg_mem:
-       mutex_unlock(&ccdc_lock);
        kfree(ccdc_cfg);
+probe_free_lock:
+       mutex_unlock(&ccdc_lock);
 probe_free_dev_mem:
        kfree(vpfe_dev);
        return ret;
index 78130721f578fc9bd310a92ac4b6c63771737b3d..2e5a7fb2d0c9e0e678f9f34f800c3c545611418b 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/version.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 
index dfddef7228dd2c08d40f1b2ec462cec93085a303..13c3a1b9776076d8db80da930f3e01c30f14f49f 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/version.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 #include <asm/page.h>
index ecbcefb08739db90ea57f60db7ebff0b237579e3..b0fb083377107f6b1f7ffc6668c32c5e665823d4 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/usb.h>
index 5a37eccbd7d681001e509539060bea638e16e77d..a41cc55667783e610db233b963605ff85e8909b3 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/vmalloc.h>
 #include <media/v4l2-common.h>
index 1b96356b3ab270c2e195c520b3d455c16092a24d..bcd3c371009b9467ac6cdf4551cc2adc0b858a93 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "em28xx.h"
index 1fb754e208752fa93ec4995740a72dc12abe099e..20a0001e88850c97e3f1282eeb82f1700a5b5d32 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 #include "em28xx.h"
 
index c7dce39823d89ef9e88438074c5353a6597f853c..7f1c4a2173b68fb4bb6450129c383f8f30fa99d7 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 
 #include "em28xx.h"
 
index ac2bd935927e713e19e0ee67ef861f0154e33a86..0fe20110bfd679404337acded2f2c20df7517d63 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/version.h>
 #include <linux/mm.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include "em28xx.h"
 #include <media/v4l2-common.h>
index 02c696a22be005fb4df1eeb4c052b735c9bb3aa5..8bb242fb79dec93e9f3f4bb05bac0724b4ab6372 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 /* compilation option */
 #define GSPCA_DEBUG 1
index 2019b04f9235261fc92e06b5168ce23ff9b06633..84ecd56c64709d722988008dba531e929ead1027 100644 (file)
@@ -24,6 +24,7 @@
 #define MODULE_NAME "jeilinj"
 
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 #include "gspca.h"
 #include "jpeg.h"
 
index fbd91545497a8e6b36d36ecae38898664c8e4d34..6b3be4fa2c067be5a9045ea0926f040528608692 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include "m5602_s5k83a.h"
 
 static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
index 4a1bc08f82b9a85719a007912165a3cd25648f65..3dee3e5844b6b4ea790aeddc1b51dc72212f6231 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/freezer.h>
 #include <linux/usb/input.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 #endif
 
 #include "gspca.h"
@@ -1426,7 +1427,7 @@ static int input_kthread(void *data)
        struct gspca_dev *gspca_dev = (struct gspca_dev *)data;
        struct sd *sd = (struct sd *) gspca_dev;
 
-       DECLARE_WAIT_QUEUE_HEAD(wait);
+       DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait);
        set_freezable();
        for (;;) {
                if (kthread_should_stop())
index 83d5773d4629efda315fd96899541aa5f00f1155..1d61b92f6bfc8dc280904aef066249917448971d 100644 (file)
@@ -22,6 +22,7 @@
 #define MODULE_NAME "sonixj"
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include "gspca.h"
 #include "jpeg.h"
 
index 15b2eef8a3f64258a65a105393f1eadbf03e5419..edf0fe157501f538b12b5140a093e249c2cf114b 100644 (file)
@@ -1513,7 +1513,6 @@ static const struct sd_desc sd_desc = {
 static const __devinitdata struct usb_device_id device_table[] = {
        {USB_DEVICE(0x0130, 0x0130), .driver_info = HamaUSBSightcam},
        {USB_DEVICE(0x041e, 0x4018), .driver_info = CreativeVista},
-       {USB_DEVICE(0x0461, 0x0815), .driver_info = MicroInnovationIC200},
        {USB_DEVICE(0x0733, 0x0110), .driver_info = ViewQuestVQ110},
        {USB_DEVICE(0x0af9, 0x0010), .driver_info = HamaUSBSightcam},
        {USB_DEVICE(0x0af9, 0x0011), .driver_info = HamaUSBSightcam2},
index dc7f2b0fbc793035724302b80e104178b0dfc34e..b9c80e2103b9c99a1f76dae1406e6006c00464d1 100644 (file)
@@ -1053,6 +1053,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
        {USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
        {USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
        {USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
+       {USB_DEVICE(0x0461, 0x0815), .driver_info = Rev072A},
        {USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},
        {USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},
        {USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},
index 1fcaca6a87f7f161352941ce5d7f4f95f11de64c..09b3f93fa4d6ddfad07accab20f867fa1ae3b20e 100644 (file)
@@ -36,6 +36,7 @@
 #define MODULE_NAME "sq905"
 
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 #include "gspca.h"
 
 MODULE_AUTHOR("Adam Baker <linux@baker-net.org.uk>, "
index e646620529920d3656e17301777c16d79870bbe6..4c70628ca615e5b16543ffc85ba53f787e744c1d 100644 (file)
@@ -30,6 +30,7 @@
 #define MODULE_NAME "sq905c"
 
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 #include "gspca.h"
 
 MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
index af73da34c83fb61f01b4cd46f9bee1384bf6002a..14f179a19485d290105a38b22b13ce5dcf7a8016 100644 (file)
@@ -524,8 +524,6 @@ static const __devinitdata struct usb_device_id device_table[] = {
        {USB_DEVICE(0x046D, 0x08F5), .driver_info = BRIDGE_ST6422 },
        /* QuickCam Messenger (new) */
        {USB_DEVICE(0x046D, 0x08F6), .driver_info = BRIDGE_ST6422 },
-       /* QuickCam Messenger (new) */
-       {USB_DEVICE(0x046D, 0x08DA), .driver_info = BRIDGE_ST6422 },
        {}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
index 50986da3d912038d28c875d9820bea1d0d87d787..7d7814c43f9245f2cb46bed6c1107423f34f5c2b 100644 (file)
@@ -22,6 +22,7 @@
 #define MODULE_NAME "zc3xx"
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include "gspca.h"
 #include "jpeg.h"
 
index 296330a0e1e55cd0dc732680dfa3a79d2c52dcd5..463b81bef6e29585e2c3f0802adc40863f9845f2 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 
 #include "hdpvr.h"
 
index e620a3a92f254691ff2db5de8c8e93728bc1d246..ad2c232baa6dce37bffb524bc68cf34591859bcc 100644 (file)
@@ -356,9 +356,6 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
 
        DEB_EE((".\n"));
 
-       ret = saa7146_vv_devinit(dev);
-       if (ret)
-               return ret;
        hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
        if (NULL == hexium) {
                printk("hexium_gemini: not enough kernel memory in hexium_attach().\n");
index fe596a1c12a81a7a71b15559dfd6747f7ae993ce..938a1f8f880a0a2ca4471d3e2fc81ca722fad09e 100644 (file)
@@ -216,10 +216,6 @@ static int hexium_probe(struct saa7146_dev *dev)
                return -EFAULT;
        }
 
-       err = saa7146_vv_devinit(dev);
-       if (err)
-               return err;
-
        hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
        if (NULL == hexium) {
                printk("hexium_orion: hexium_probe: not enough kernel memory.\n");
index 4a9c8ce0ecb307cc07d167a0c6685bcd3583fefe..b59475bfc243990a7397281ca90ac2c2b9170402 100644 (file)
@@ -18,6 +18,7 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include "ivtv-driver.h"
 #include "ivtv-cards.h"
index e4816da6482b655d9b5be7311a5e1b25cafca036..5028e31c564a9aeed1f395b5a5274c88f61c7439 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/scatterlist.h>
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/byteorder.h>
index fa6bb85cb4b06ebf7626f5dd6557b9d345107bee..de2ff1c6ac3476453ef1c3c59732b81510b959fe 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/kernel.h>
 #include <linux/fb.h>
 #include <linux/ivtvfb.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_MTRR
 #include <asm/mtrr.h>
index fab8e0254bbc1c7ad7bbd76406df973c24622545..94734828053b92bbec041df93638c3ef9625802e 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-i2c-drv.h>
index d7317e798cc474cb86bbca07a3fc945fbf800502..4491d018eba6518c0e663419bc7e7a3a292f6511 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
index b421858ccf907f8fe6a9cc06c62782b11d026ec1..4404e5ef818fdc92159cdbb527a83c3dce576593 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/videodev.h>
+#include <linux/gfp.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <asm/uaccess.h>
index 168bca703614e589cfb02e213f41f8f4d8e6f9ec..d5a69c5ee5e4f45a370ea266b1379f96f4c071bd 100644 (file)
@@ -22,7 +22,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/freezer.h>
 #include <linux/videodev2.h>
index cc85f77a570694e39fc0cc0fbc37eef118a568fa..72e55be0b4abae5fdc59651117613e84c6f4e348 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/delay.h>
 #include <asm/div64.h>
index c167cc3de4928cee1f0a28b1dbade61320d1bcf7..34a66019190ef0feef198cddc7c3a471d1db208f 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/version.h>
 #include <linux/videodev2.h>
@@ -48,8 +49,6 @@
 /*
  * CSI registers
  */
-#define DMA_CCR(x)     (0x8c + ((x) << 6))     /* Control Registers */
-#define DMA_DIMR       0x08                    /* Interrupt mask Register */
 #define CSICR1         0x00                    /* CSI Control Register 1 */
 #define CSISR          0x08                    /* CSI Status Register */
 #define CSIRXR         0x10                    /* CSI RxFIFO Register */
@@ -783,7 +782,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
                               pcdev);
 
        imx_dma_config_channel(pcdev->dma_chan, IMX_DMA_TYPE_FIFO,
-                              IMX_DMA_MEMSIZE_32, DMA_REQ_CSI_R, 0);
+                              IMX_DMA_MEMSIZE_32, MX1_DMA_REQ_CSI_R, 0);
        /* burst length : 16 words = 64 bytes */
        imx_dma_config_burstlen(pcdev->dma_chan, 0);
 
@@ -797,8 +796,8 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
        set_fiq_handler(&mx1_camera_sof_fiq_start, &mx1_camera_sof_fiq_end -
                                                   &mx1_camera_sof_fiq_start);
 
-       regs.ARM_r8 = DMA_BASE + DMA_DIMR;
-       regs.ARM_r9 = DMA_BASE + DMA_CCR(pcdev->dma_chan);
+       regs.ARM_r8 = (long)MX1_DMA_DIMR;
+       regs.ARM_r9 = (long)MX1_DMA_CCR(pcdev->dma_chan);
        regs.ARM_r10 = (long)pcdev->base + CSICR1;
        regs.ARM_fp = (long)pcdev->base + CSISR;
        regs.ARM_sp = 1 << pcdev->dma_chan;
index 9f01f14e4aa2e5d21fa353666e7a45220909fc9a..ef0c8178f2559c6d4e11054acf96bdb2c6d71894 100644 (file)
@@ -169,11 +169,7 @@ static struct saa7146_extension extension;
 static int mxb_probe(struct saa7146_dev *dev)
 {
        struct mxb *mxb = NULL;
-       int err;
 
-       err = saa7146_vv_devinit(dev);
-       if (err)
-               return err;
        mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
        if (mxb == NULL) {
                DEB_D(("not enough kernel memory.\n"));
@@ -699,14 +695,17 @@ static struct saa7146_ext_vv vv_data;
 /* this function only gets called when the probing was successful */
 static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
 {
-       struct mxb *mxb = (struct mxb *)dev->ext_priv;
+       struct mxb *mxb;
 
        DEB_EE(("dev:%p\n", dev));
 
-       /* checking for i2c-devices can be omitted here, because we
-          already did this in "mxb_vl42_probe" */
-
        saa7146_vv_init(dev, &vv_data);
+       if (mxb_probe(dev)) {
+               saa7146_vv_release(dev);
+               return -1;
+       }
+       mxb = (struct mxb *)dev->ext_priv;
+
        vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
        vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
        vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
@@ -726,6 +725,7 @@ static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data
        vv_data.ops.vidioc_default = vidioc_default;
        if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
                ERR(("cannot register capture v4l2 device. skipping.\n"));
+               saa7146_vv_release(dev);
                return -1;
        }
 
@@ -846,7 +846,6 @@ static struct saa7146_extension extension = {
        .pci_tbl        = &pci_tbl[0],
        .module         = THIS_MODULE,
 
-       .probe          = mxb_probe,
        .attach         = mxb_attach,
        .detach         = mxb_detach,
 
index 142c327afb321e053938e5d26b905c08f95843bf..ce76d952e1613682b1948762d6be26caffee21b4 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
@@ -1404,7 +1405,7 @@ static int omap24xxcam_mmap_buffers(struct file *file,
        }
 
        size = 0;
-       for (i = first; i <= last; i++) {
+       for (i = first; i <= last && i < VIDEO_MAX_FRAME; i++) {
                struct videobuf_dmabuf *dma = videobuf_to_dma(vbq->bufs[i]);
 
                for (j = 0; j < dma->sglen; j++) {
index 0e2184ec994efa0ee4b39ed55031e139ecb6de97..aaa50f9b8e7809cfb386a981c060ff955f726764 100644 (file)
@@ -12,6 +12,7 @@
  */
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
 #include <linux/videodev2.h>
index 11a2c26399b53d846945a2afdbc74033a063fc97..0598bbd3f368da323398fedbf378ebedcc21ff3d 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
index 68980e19409f8f4a053388530b2c03d8d9e05e8c..88320900dbd4815affc177264613a474a3b4c206 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 
 struct routing_scheme {
        const int *def;
index 82c13583575350ded7b32edabb8efb2f498a9ca0..2222da8d0ca67cf97985388a6d42e1428e9d4c8e 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 
 
 struct routing_scheme_item {
index ae977668c4969d29fd1e9d983e1b394dbcd9e968..e9b11e119f629f72c001945c39b6f77c38b47798 100644 (file)
@@ -19,7 +19,6 @@
  */
 
 #include <linux/string.h>
-#include <linux/slab.h>
 #include "pvrusb2-debugifc.h"
 #include "pvrusb2-hdw.h"
 #include "pvrusb2-debug.h"
index b7f5c49b1dbc19f35bc7ce59461d9996cef111a6..8c95793433e79b8d93470e4b9b757dc7ef656dd6 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/kthread.h>
 #include <linux/freezer.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include "dvbdev.h"
 #include "pvrusb2-debug.h"
index 299afa4fa96953ac804ef778a50cd3329dc6741d..aeed1c2945fb2cb4cd8705777a4747c99d75207b 100644 (file)
@@ -19,6 +19,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include "pvrusb2-eeprom.h"
 #include "pvrusb2-hdw-internal.h"
 #include "pvrusb2-debug.h"
index 8689ddb54420d05c0fb3b4e428aff6647a5ab719..eeacd0f67855d118b49aa8ad5cd4a11bfe9d3ce6 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/videodev2.h>
index 6c23456e0bda2c2661030deb5737fb8ca120e2a5..71f50565f637c804f19fac089cf62af55134bf55 100644 (file)
@@ -423,10 +423,12 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
 
        dip = kzalloc(sizeof(*dip),GFP_KERNEL);
        if (!dip) return;
+       sysfs_attr_init(&dip->attr_debugcmd.attr);
        dip->attr_debugcmd.attr.name = "debugcmd";
        dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP;
        dip->attr_debugcmd.show = debugcmd_show;
        dip->attr_debugcmd.store = debugcmd_store;
+       sysfs_attr_init(&dip->attr_debuginfo.attr);
        dip->attr_debuginfo.attr.name = "debuginfo";
        dip->attr_debuginfo.attr.mode = S_IRUGO;
        dip->attr_debuginfo.show = debuginfo_show;
@@ -644,6 +646,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
                return;
        }
 
+       sysfs_attr_init(&sfp->attr_v4l_minor_number.attr);
        sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number";
        sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
        sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
@@ -658,6 +661,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
                sfp->v4l_minor_number_created_ok = !0;
        }
 
+       sysfs_attr_init(&sfp->attr_v4l_radio_minor_number.attr);
        sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number";
        sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO;
        sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show;
@@ -672,6 +676,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
                sfp->v4l_radio_minor_number_created_ok = !0;
        }
 
+       sysfs_attr_init(&sfp->attr_unit_number.attr);
        sfp->attr_unit_number.attr.name = "unit_number";
        sfp->attr_unit_number.attr.mode = S_IRUGO;
        sfp->attr_unit_number.show = unit_number_show;
@@ -685,6 +690,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
                sfp->unit_number_created_ok = !0;
        }
 
+       sysfs_attr_init(&sfp->attr_bus_info.attr);
        sfp->attr_bus_info.attr.name = "bus_info_str";
        sfp->attr_bus_info.attr.mode = S_IRUGO;
        sfp->attr_bus_info.show = bus_info_show;
@@ -699,6 +705,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
                sfp->bus_info_created_ok = !0;
        }
 
+       sysfs_attr_init(&sfp->attr_hdw_name.attr);
        sfp->attr_hdw_name.attr.name = "device_hardware_type";
        sfp->attr_hdw_name.attr.mode = S_IRUGO;
        sfp->attr_hdw_name.show = hdw_name_show;
@@ -713,6 +720,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
                sfp->hdw_name_created_ok = !0;
        }
 
+       sysfs_attr_init(&sfp->attr_hdw_desc.attr);
        sfp->attr_hdw_desc.attr.name = "device_hardware_description";
        sfp->attr_hdw_desc.attr.mode = S_IRUGO;
        sfp->attr_hdw_desc.show = hdw_desc_show;
index cc8ddb2d2382902bb8e67194e3b79dfeaad0a65c..bf1e0fe9f4d237b9c6feecf53b4a4596e72b85fd 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include "pvrusb2-context.h"
 #include "pvrusb2-hdw.h"
index 4c96cf48c79627125b10cce2178141015c4d03d2..2e205c99eb969933eec6a5de339efecfd48f87ff 100644 (file)
@@ -37,7 +37,6 @@
 #include <media/v4l2-common.h>
 #include <media/saa7115.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 
 struct routing_scheme {
        const int *def;
index 8c1eae05aa08837072c54298e2d136885862022f..3ac8d751a5c0f6b0e19d1599baa66d558423f68e 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 
 void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 {
index 9e2d91f26bfe065ca6c72ba716d5506929d0c771..0c801b8f3eca5a621f635a63eb8e48238254d851 100644 (file)
@@ -30,6 +30,7 @@
 #include <media/pwc-ioctl.h>
 
 #include <linux/string.h>
+#include <linux/slab.h>
 
 /*
  * USE_LOOKUP_TABLE_TO_CLAMP
index bdb4ced57496c34b45c93709d7a6ddac8a25a97c..62d89b3113a402e04cd00da06ff2c035ffde01d6 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/poll.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <asm/io.h>
 
index 0902355dfa77a3daadaa7f025ac359d66e3171b1..f1b20663295760206202884f2b766e75f8749c30 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/version.h>
 #include <linux/mutex.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <asm/errno.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
index 322ac4eecf0ae0cf39b82e33baaa2ef5294a6fe4..04bf5c11308d4318fc105d8245a847d6a9031cb9 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
@@ -608,12 +609,9 @@ static void pxa_dma_add_tail_buf(struct pxa_camera_dev *pcdev,
  */
 static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
 {
-       unsigned long cicr0, cifr;
+       unsigned long cicr0;
 
        dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s\n", __func__);
-       /* Reset the FIFOs */
-       cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
-       __raw_writel(cifr, pcdev->base + CIFR);
        /* Enable End-Of-Frame Interrupt */
        cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_ENB;
        cicr0 &= ~CICR0_EOFM;
@@ -934,7 +932,7 @@ static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
 static irqreturn_t pxa_camera_irq(int irq, void *data)
 {
        struct pxa_camera_dev *pcdev = data;
-       unsigned long status, cicr0;
+       unsigned long status, cifr, cicr0;
        struct pxa_buffer *buf;
        struct videobuf_buffer *vb;
 
@@ -948,6 +946,10 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
        __raw_writel(status, pcdev->base + CISR);
 
        if (status & CISR_EOF) {
+               /* Reset the FIFOs */
+               cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
+               __raw_writel(cifr, pcdev->base + CIFR);
+
                pcdev->active = list_first_entry(&pcdev->capture,
                                           struct pxa_buffer, vb.queue);
                vb = &pcdev->active->vb;
index fb742f1ae711a6a5408586810b1726d6ce208f32..3de914deb8ee6991ec3f0c9a5a8da5d58fba91a9 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/firmware.h>
 #include <linux/kernel.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/version.h>
 #include <linux/mm.h>
index 5ab6a0f901c022e190087926a40173131cdf7348..6b3b09ef89787cbc86830dae1f269c391cd534a3 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/videotext.h>
 #include <linux/videodev2.h>
index 12835fb82c9557c56d09d16825d954dd0d24920e..31ff27df4cbf652d0ff7dd7a604e4c39504852f9 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/delay.h>
 #include <linux/videotext.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ioctl.h>
index 73739d2a63dd529857461087fd95d60383667599..4ab4a987c9b9593006eced5106f946e8ec6268ed 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
 #include <linux/suspend.h>
index ee5bff02a92cb098a669c2f8204e24da90659bf5..ea877a50f52d9b65963e1edfcf81b81f356b807e 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/delay.h>
 
index 8096dace5f6c77d9b2eafde934300aea74a05f50..da41b6b1e64a2239569256ca3c7eaffef1b43382 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 
 #include "saa7134-reg.h"
index 9499000f66b6bc8a6e640cfd57ae9d7492a9e821..58a0cdc8414a36a654e8d2e067fd0821e89624ec 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 
 #include "saa7134-reg.h"
 #include "saa7134.h"
index b9817d74943fa014b9f4861c58e002dec19dcd43..2e3f4b412d8c8d667efda9fff55b70a6a810acd5 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 
 #include "saa7134-reg.h"
index 76b16407b01e89ac3b7e0ef8cb8cd94869da0a03..3e7d2fd1688f3b27b669e7e603bd76c04f6958c6 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/kthread.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/freezer.h>
 #include <asm/div64.h>
index cb0304298a96ec27419ba219259012ab021037b4..e9aa94b807f11271d5a0b9c61500566fbed4b508 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 
 #include "saa7134-reg.h"
 #include "saa7134.h"
index 1d487c1503408decf21a9f407ceff3d6fbc048e9..3f1262b00cc0b78c54947bb10538e36a6bb80336 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/wait.h>
+#include <linux/slab.h>
 
 #include "saa7164.h"
 
index 9ca5c83d165b636d410323e21a37bcb808f3a03f..5713f3a4b76c952bf9b1db333bb547caf3e40376 100644 (file)
@@ -19,6 +19,8 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
+
 #include "saa7164.h"
 
 /* The PCI address space for buffer handling looks like this:
index ee0af3534ede39a0e22f9683a81d17e03fb13856..270245d275abe967b7e8ebaf97b87ee6143b61cf 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #include "saa7164.h"
 
index 6818df571168660229f743b3183334f20a727dfc..d521c648e15706fa29e2d26dd012330519aaedff 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #include <linux/videodev2.h>
index 212baa10829bf4535ed5bd6d396cfd5b14f8c453..77db2039291032a925b2242e96157635db5e28d7 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
index fb88c63188f3c02ab7b8930938a0168fbc79a332..1ad980f8e770adc44c5f1659e4d29c6da180a6d4 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/moduleparam.h>
 #include <linux/time.h>
 #include <linux/version.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/videodev2.h>
@@ -1632,7 +1633,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
        height = pix->height;
 
        pix->bytesperline = soc_mbus_bytes_per_line(width, xlate->host_fmt);
-       if (pix->bytesperline < 0)
+       if ((int)pix->bytesperline < 0)
                return pix->bytesperline;
        pix->sizeimage = height * pix->bytesperline;
 
index 80f6bfa2632bcb7e5fd140147c10d83e32bd8524..a24174ddec4631b7171e05c06cd64fb0daa253b4 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/mutex.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include <media/soc_camera.h>
index d381fce3db407c6062f73dc4d75162ccb77d5f4a..92d22d8931c130888820e7e163709ba931e0dd12 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <linux/module.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
index 1585839bd0bd3d352270a6f1f2caa039a1a00bff..3021a1e6b7bb846910a63b574dca35cbeebce33c 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <linux/module.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
index 6bf6bc7dbc7f2540e73090de0ec69c537581c6d2..49dafc5e1e2f584219eefee65b9cbddca47e7ad0 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <linux/module.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
index 21781f8a0e8e897da916182f8c1e56241631c51d..61b1dd118364f905078d72ff7a49ffd6a9a07e54 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/device.h>
 #include <linux/delay.h>
index 6f42621ad478a1fc09e2914907ae6797a3b2b0e9..9f8b7da56b671fe2eeee8f942e490dbb8b65c154 100644 (file)
@@ -4,10 +4,10 @@
 #include <linux/sound.h>
 #include <linux/spinlock.h>
 #include <linux/soundcard.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/proc_fs.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 4133aee568bf13e981f958dfef9367c561395830..ebd9cb5bec7429c6251bec628cd91d501796d9ec 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/usb.h>
 #include <linux/dvb/dmx.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 #include "vendorcmds.h"
 #include <linux/sched.h>
index becfba6a304173d7b89dc1a1033d6f026d8bd12a..cf8f18c007e6cdd65e883f873743f415fbd895f7 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/usb.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-dev.h>
index 07789c64814cf4d133da0b83b84090a730c54721..9ddb32bc7af05164b34be594646bba23eb218406 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
index 26b4e718cd6d74226cd0320c1a633cedae16041c..e4815a1806e30e03482c55ca17390f6e4c95ba4c 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/videodev2.h>
 
index 2d38e253f14e395416cbec779ffb6e31452f55ee..908ffb68e926efb87f25a1b4a6322ffecd9c0b37 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/delay.h>
 #include <media/v4l2-device.h>
index 5a878bca02d419da34d0b1369b953d146a0e3e32..4a69bcc738f33069c6cd57136d431e59184e03fe 100644 (file)
@@ -26,6 +26,7 @@
  */
 #include <linux/delay.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <media/tvp7002.h>
 #include <media/v4l2-device.h>
index a07a3fbb51eb8aad3af201289ff9a677e765dc5f..36c0c461d8be8af15d029c38b45ee2174ddca1d2 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-i2c-drv.h>
index 6eb0e5b00c3282012c8437d45a3d78fdd6bca068..c5af93b30a2b170f1c66f2a4c17911fe903911d4 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-i2c-drv.h>
index a0addcb04295078d758ae95dcf96320b8d1d2fad..562e1d170be0123955d570336e4488b31dd8b43c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb/input.h>
+#include <linux/gfp.h>
 
 #include "usbvideo.h"
 
index c4d1b96b5cee3d83e34252a393667c97f4eb9251..fab48ec6c0eae57bc8386766b1aa9603ee0d7469 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/usb/input.h>
+#include <linux/slab.h>
 
 #include "usbvideo.h"
 #include "quickcam_messenger.h"
index e0f91e4ab653ccb975676a908e6f2b11db5eedd0..f7aae2293758eeae3999f247688407a96c61fb95 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/timer.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/vmalloc.h>
index 0613922997e0c588ac1f9e1884b92ba54bc82e77..083765238a6a5d9a34e45df6bd3a9337459b0b34 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
 #include <linux/ioport.h>
index 3b2e7800d56f9a2f134abcbe29670d7b53b3a189..6d3850b37161ed21914deb4f06c7569f549a68ee 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/videodev2.h>
index a814820a3f6ee8fceb812645274dd88210369d7e..86ff8c12ea58f591609819d3347aadcbe79ae027 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/videodev2.h>
 #include <linux/vmalloc.h>
index 1ca6dff7361241069f2a05ba4631bb00ec5b11d5..85019bdacdf757a31952e2602bd074d829fa4169 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/kernel.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/input.h>
 
index 43152aa522271763ca831edf15671bb6efac3b59..7c9ab2933496ea4515f6b0544c561b7769f87052 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/version.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/videodev2.h>
 #include <linux/vmalloc.h>
index 6b0666be370fdb6e6cc23398f2939b5865fa828d..821a9969b7bf8a09fa87044e4a342f574fee53cb 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/videodev2.h>
 #include <linux/vmalloc.h>
index 4b11257c31846759132243f39a7a6a885a9cbff6..7d59c107f13b52baf31661044e5fed9f86fb6ce6 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 
index 22c01097e8a821f95c04ae9d8ae9432623381d46..dce4f3aa4af1adc1f77aee4d58484a6b13b38f40 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/pagemap.h>
 #include <linux/dma-mapping.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <media/videobuf-dma-contig.h>
 
 struct videobuf_dma_contig_memory {
index a56cf0d3a6d618134d70f046059df84919f3b1d0..0afb62e63d99f615d29c76ef508f67209b27d28a 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/fs.h>
 #include <linux/kthread.h>
 #include <linux/file.h>
+#include <linux/slab.h>
 
 #include <linux/freezer.h>
 
index a15d1e7cbed8529dc69bbe37304a5eba0ac42523..3eb15f72ac092bc98cce5c9bdc04387fa62f21a1 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/fs.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/time.h>
 #include <linux/version.h>
index 38e53b303cc35bd836361c9e0652aaec23a67489..ca8303bd2401f06b29b01ec90a24e2d8400c6974 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
index 33205d7537d8f59524edb2dc617f54468f642785..77ebcea7c3da6f66dafeeaecf31d406339c25678 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
index dcade619cbd8454db5ba93166064eba0ccf39c35..bf9bf650a317de709506c989a6bb2f342a526250 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/videodev.h>
+#include <linux/slab.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <linux/parport.h>
index b572ce288e14857d2e6f3f9fffe2675a5f111d89..a11b99b4226b86c864595bfbe09a0c8fd78228d8 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
index f1f261a35245830b4217268e92b6b34af66d43fd..5c2ba599c0c731735ce5dc08170ae8217723b665 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
index be70574870de4f5eeda5ed13d6c634c6c7322065..bfcd3aef50f95913aa37244987ddba60f091f053 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include <linux/proc_fs.h>
 #include <linux/i2c.h>
index b3bf1c44d74d92c67452b96e89cf4d9741d68d4f..c00fe8253c517970bca643dcd68bb63e7f4d2e98 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/idr.h>
 #include <linux/fs.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME "memstick"
 
index 972b87069d55aad0e6d27eba6b7fbbba55064598..8327e248520ac654596b41560fb51f4d913eedcb 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/hdreg.h>
 #include <linux/kthread.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/memstick.h>
 
 #define DRIVER_NAME "mspro_block"
index f4a162a4bece30532ca15cf4a4f49e247787b160..f2b894cd8b026b49d9bdd1cec95ef55535abde8d 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/highmem.h>
 #include <linux/memstick.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME "jmb38x_ms"
 
index 612ab3c51a6b7c9e31ff2eaacd460fa87e09a916..33f7256055b1ae08011122163f18de6c895245a2 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/reboot.h>      /* notifier code */
 #include <linux/workqueue.h>
 #include <linux/sort.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index 34f3f36f819befac8ef345e24a3c85abe3e814c9..4fa9665cbe933c5fabb78b33f86037570055a3ff 100644 (file)
@@ -57,6 +57,7 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #define my_VERSION     MPT_LINUX_VERSION_COMMON
 #define MYNAM          "mptlan"
index c20bbe45da82d4811d57618cb1144fa8af44f662..76687126b573c99082f93e7b7c533e94d1c8f973 100644 (file)
@@ -45,6 +45,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/jiffies.h>
index 4a7d1afcb666aabda50adb4f6122a91a9c824713..6796597dcee0c122be63e927f19ff85f49e796e4 100644 (file)
@@ -46,6 +46,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/kdev_t.h>
index 69f4257419b59d0cce00ec984a33382dae0f785d..e44365193fdf581d963734700d0c5510b967cc78 100644 (file)
@@ -46,6 +46,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/kdev_t.h>
index 2658b1484a2c7ba0480d99ad413087fb70cf523b..fc593fbab6963896446bb4e7e14133186e71af15 100644 (file)
@@ -51,6 +51,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/i2o.h>
 
 #include <linux/mempool.h>
index 3d5f40cd69df2e70d5d1ffee42b91e31d36473e4..11073fa3d9f49106a3c1384e1dfbea23a3c1351c 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/miscdevice.h>
 #include <linux/smp_lock.h>
 #include <linux/compat.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
index 949a648f8e2e16c9dcd6447ccbb66d526dbfd088..07dbeaf9df997b1ff6a64ded115062b183ef7e50 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/i2o.h>
+#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
index ef5ce2676f0534686132caf1534c0a99391d7724..090d2a3a6548e0aa2d56ca5350a6ae2d012945a7 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/i2o.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "core.h"
 
 #define OSM_NAME       "i2o"
index 35ba2ae38b4233d541efed5ae35b7af98586a511..73e4658af53c5216b27c029cdc078ee0d379148e 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <linux/pci.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/i2o.h>
 #include "core.h"
 
index c37e12bf3004b943cdbcd9d9d7b58936cd9c5687..4a6e7186334e31ce4eccea8b0937312c20b5e29f 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/mfd/88pm860x.h>
+#include <linux/slab.h>
 
 static inline int pm860x_read_device(struct i2c_client *i2c,
                                     int reg, int bytes, void *dest)
index a2ce3b6af4a21855651055202456772ae21c6900..e4ca5909e4242261ac9a2588954607ec129f18d4 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/mutex.h>
 #include <linux/list.h>
 #include <linux/notifier.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/device.h>
index b603469dff698807d961d8dbbcd2d8459014ac2d..2d14655fdebdfb722b57cfaa15f24e798d5fa18c 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/ab3100.h>
index 1c44c19e073a10455e971143df832a9e3dd6a0dc..c275daa3ab1a03bc5a0881993b792f1f89a05eaa 100644 (file)
@@ -15,6 +15,7 @@
  * Interrupt management to be added - TODO.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
index b26644772d02fee2fc32ef6dd97ed69d0c052f5b..005532865654b0bbfa036bc873a37858220ffac1 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/err.h>
index 95c1e6bd1729d84c3e176f3990a95655628f6c17..7de708d15d7251e62f490ca1f6eed1b75e8ff098 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/irq.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/platform_device.h>
 
index e5ffe561739387837a37bd66454ee089b580f4d9..67181b147ab3a2265b1ea27be0fe3a21b6145044 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/mfd/da903x.h>
+#include <linux/slab.h>
 
 #define DA9030_CHIP_ID         0x00
 #define DA9030_EVENT_A         0x01
index df405af968fa2f1f1237b1b45a828249ecde65a1..134c69aa47909142c20a292e61c56ed65267eaf0 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/mfd/ezx-pcap.h>
 #include <linux/spi/spi.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #define PCAP_ADC_MAXQ          8
 struct pcap_adc_request {
index addb846c1e34940e59400a1bb2b9f7a09471c161..d3e74f8585e0b087507c47618bc344d751c8800c 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/spinlock.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/mfd/htc-egpio.h>
 
index 37b9fdab4f36391a958539560beff8bcd04505a6..594c9a8e25e160b43a90bf8eceea7c5661b2709d 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/spinlock.h>
 #include <linux/htcpld.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 struct htcpld_chip {
        spinlock_t              lock;
index cb73051e43db8ca04e1eabbdafd65af4966f47ef..f04300e05fd611d79e1c0acaf72bf79df57a44b3 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/ds1wm.h>
 #include <linux/mfd/htc-pasic3.h>
+#include <linux/slab.h>
 
 struct pasic3_data {
        void __iomem *mapping;
index c0b883c14f41c15ff5c81084b367b97a13317af0..d9fd8785da4d76a78a9e9a95661d1f93c7d46e72 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/mfd/max8925.h>
+#include <linux/slab.h>
 
 #define RTC_I2C_ADDR           0x68
 #define ADC_I2C_ADDR           0x47
index 62a847e4c2d840f8f6c28c06785a0c49a1604c57..1f68ecadddc24a17ab37d37e6aa6e28cb32dd3d9 100644 (file)
@@ -9,6 +9,7 @@
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
  */
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/spi/spi.h>
 #include <linux/mfd/core.h>
index 25842723272858ccaace40d73d02f3c8d2c2d8ab..2dab02d9ac8b6f87168e3e6e1069023f9372fe93 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
-#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/mcp.h>
 
index 970afa103261db15172eb189457888ec2adcfd2c..a94b131a18efc72a2a7a6ebb4ec8bce6ef8ada2a 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/delay.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
+#include <linux/slab.h>
 
 #include <asm/mach/irq.h>
 
index aa17f4bddc56a1a77fee6f1a641e064f3aed1059..8ffbb7a85a7e67091105408f643e170f58bdcb1d 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/acpi.h>
 #include <linux/mfd/core.h>
+#include <linux/slab.h>
 
 static int mfd_add_device(struct device *parent, int id,
                          const struct mfd_cell *cell,
index 6d2e8466df1dd804d2943144f9a8564309f76f96..fe8f922f6654b6b43efe26670cdaae96b32c6eb7 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/device.h>
index 03dcc92007070605b2ec0e7f7a8164eeca00183a..63a614d696c1994ab037320b5d8fdbb51e7125c1 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/pcf50633/core.h>
 
index 468fd366d4dabbf3a7c82dc3827e79a0dd6f70d6..497f91b6138edc4dba97ff82c9c1845a83ca6454 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/kernel.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/mmc/host.h>
 #include <linux/mfd/core.h>
index 7b6652f6011731a016597d6540da78ff50d4fa15..bc9275c12133f2817c54dafb04fd1856a54870c1 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/platform_device.h>
 #include <linux/pci.h>
 #include <linux/i2c-gpio.h>
+#include <linux/slab.h>
 
 #include <linux/sm501.h>
 #include <linux/sm501-regs.h>
index 26d9176fca91968b3b450c698bc0dd1e1fca3d8d..da6383a934ac33ac57a39a010f23f94ba1c9daa1 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/irq.h>
 #include <linux/clk.h>
 #include <linux/platform_device.h>
index 5c7f04343d5c3be1d8ce446d1b2d206df4044915..517f9bcdeaacb4b7435273e3e278d0b703da9cae 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/tmio.h>
 #include <linux/mfd/tc6387xb.h>
+#include <linux/slab.h>
 
 enum {
        TC6387XB_CELL_MMC,
index c59e5c5737d05fb2961eed8528a98e114fa29b2a..fcf9068810fb24eb73af3f05fce1c3e89133e886 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/mfd/tmio.h>
 #include <linux/mfd/tc6393xb.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #define SCR_REVID      0x08            /* b Revision ID        */
 #define SCR_ISR                0x50            /* b Interrupt Status   */
index 1ed44d283803803989295cae91efdc35659bdb14..7f478ec4184b47d8aa0f04b54cbeccf2a418e258 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/pci.h>
 #include <linux/msi.h>
 #include <linux/mfd/core.h>
+#include <linux/slab.h>
 
 #include <linux/timb_gpio.h>
 
index 700b149c1b918251285cd2a0d80582521cf1f976..add6f67d80323a42824709337958fe90df55e443 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/platform_device.h>
index 9df9a5ad38f9142ebc0c53e58d51541a0a0c133f..202bdd59632d4e90355ea4bf8c733e1ee3719d18 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 #include <linux/i2c/twl.h>
 
index 85fd9421be94240f30dd35c9f4f6c76bb1c7dfb0..dbe280153f9e769d2c24d9211c5768587c8fb78c 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/ucb1400.h>
 
 unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel,
index 07101e9e1cba14dfc71aaaf4f9300c2660c3e032..f2ab025ad97a3cad7532ad95b21684cf4561ff5e 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/bcd.h>
 #include <linux/delay.h>
 #include <linux/mfd/core.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/pdata.h>
@@ -348,6 +349,9 @@ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
                goto disable;
        }
 
+       /* If an interrupt arrived late clean up after it */
+       try_wait_for_completion(&wm831x->auxadc_done);
+
        /* Ignore the result to allow us to soldier on without IRQ hookup */
        wait_for_completion_timeout(&wm831x->auxadc_done, msecs_to_jiffies(5));
 
index bd75807d5302e7f60649bd1b133ee1c75d5e77ba..b5807484b4c92424e04b7232c5ab41b3b020db95 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/bug.h>
 #include <linux/device.h>
 #include <linux/delay.h>
@@ -362,6 +363,10 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
        reg |= 1 << channel | WM8350_AUXADC_POLL;
        wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg);
 
+       /* If a late IRQ left the completion signalled then consume
+        * the completion. */
+       try_wait_for_completion(&wm8350->auxadc_done);
+
        /* We ignore the result of the completion and just check for a
         * conversion result, allowing us to soldier on if the IRQ
         * infrastructure is not set up for the chip. */
index 8d8c932175729621f77b43b360b5fea9871b3b4c..65830f57c093574baace391c8fb8bb78d78c4473 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/wm8350/core.h>
+#include <linux/slab.h>
 
 static int wm8350_i2c_read_device(struct wm8350 *wm8350, char reg,
                                  int bytes, void *dest)
index ecfc8bbe89b9fc37ad03d3bcfa97738d7dcd9d00..865ce013a821fafffd7def52636d45c77900eb8a 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/wm8400-private.h>
 #include <linux/mfd/wm8400-audio.h>
+#include <linux/slab.h>
 
 static struct {
        u16  readable;    /* Mask of readable bits */
index 844e1c1b7d9033c22d7c4a4b511031bb76b8f527..cc524df10aa1fad0e8abd7c4d39780954d256e2a 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
 #include <linux/mfd/core.h>
index 2191c8d896a0c69f00d85323f522c3c347a893e0..0d0d625fece28849e985487fdebb9607c0c372cc 100644 (file)
@@ -311,6 +311,22 @@ config TI_DAC7512
          This driver can also be built as a module. If so, the module
          will be calles ti_dac7512.
 
+config VMWARE_BALLOON
+       tristate "VMware Balloon Driver"
+       depends on X86
+       help
+         This is VMware physical memory management driver which acts
+         like a "balloon" that can be inflated to reclaim physical pages
+         by reserving them in the guest and invalidating them in the
+         monitor, freeing up the underlying machine pages so they can
+         be allocated to other guests. The balloon can also be deflated
+         to allow the guest to use more physical memory.
+
+         If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called vmware_balloon.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
index 27c484355414cca3bcea2de7da9b0d4c7cc2150b..7b6f7eefdf8d537013dfcc066edd308bf406313c 100644 (file)
@@ -29,3 +29,4 @@ obj-$(CONFIG_C2PORT)          += c2port/
 obj-$(CONFIG_IWMC3200TOP)      += iwmc3200top/
 obj-y                          += eeprom/
 obj-y                          += cb710/
+obj-$(CONFIG_VMWARE_BALLOON)   += vmware_balloon.o
index 558bf3f2c27698154a6088c43a8daa781577c42b..4afffe610f99d09a34e28790cbf67971012c70ea 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/spinlock.h>
 #include <linux/atmel-ssc.h>
+#include <linux/slab.h>
 
 /* Serialize access to ssc_list and user count */
 static DEFINE_SPINLOCK(user_lock);
index 6aa5294dfec4fc681305b03a63c1f8e63aecf0ee..0f3fb4f03bdf0b93851cfa10156296c6303d7557 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
index 05dc8a31f2806e181d975981f787edb21196e273..3891124001f28331946b284a22564e15b029ce6a 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 /* Number of bytes to reserve for the iomem resource */
 #define ATMEL_TC_IOMEM_SIZE    256
index b5346b4db91a2021d43c470b09bd53fbdc7a4170..ed090e77c9cd4d65fec1402972f59bd84246c60b 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/idr.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <linux/c2port.h>
 
@@ -912,8 +913,8 @@ struct c2port_device *c2port_device_register(char *name,
 
        c2dev->dev = device_create(c2port_class, NULL, 0, c2dev,
                                        "c2port%d", id);
-       if (unlikely(!c2dev->dev)) {
-               ret = -ENOMEM;
+       if (unlikely(IS_ERR(c2dev->dev))) {
+               ret = PTR_ERR(c2dev->dev);
                goto error_device_create;
        }
        dev_set_drvdata(c2dev->dev, c2dev);
index b14eab0f2ba584b77e226b68ab335c65478d389e..efec4139c3f68f512cded3fd51631e7097895d19 100644 (file)
@@ -9,11 +9,11 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/idr.h>
 #include <linux/cb710.h>
+#include <linux/gfp.h>
 
 static DEFINE_IDA(cb710_ida);
 static DEFINE_SPINLOCK(cb710_ida_lock);
index 02358d086e030e6a25b56561f8613cd864b7eb24..fcb3b8e30c528c4202736a50fa2c1e34a1779c6c 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/cb710.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 
 #define CB710_REG_COUNT                0x80
 
index 8110460558ff96c4e698f04666a96a84d8356f34..9bec24db4d41385efe8a1c891f0a6e9daf072488 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/cs5535.h>
+#include <linux/slab.h>
 
 #define DRV_NAME "cs5535-mfgpt"
 #define MFGPT_BAR 2
index f3ee4a1abb7714fa2dca513043dce44947d8b962..9197cfc550158b532be740c914d7b64c1ee1b435 100644 (file)
@@ -33,7 +33,6 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/string.h>
 #include <linux/list.h>
index 1eac626e710a38dddab8673b1cc5f751a1df7366..48c84a58163e460b36ac68c7951b55e01f06bc09 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 static LIST_HEAD(container_list);
 static DEFINE_MUTEX(container_list_lock);
index ba4694169d796ca97580ffcbb1c4791b325f026b..46b3439673e9036ed9f46e4a275819c7e45da061 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
index a92a3a742b439fdf2e6277929ccdd5ed3fff2dcf..98ad0120aa9bc6a134af1a5da728f0c6d8f9c8c8 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/io.h>
 #include <linux/wait.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include "hpilo.h"
 
 static struct class *ilo_class;
index e2031739aa29fda4a188d4ac35101bc9f7439ee0..5c766b4fb2380763011ae6a05b10bf4fd997d5e4 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "ibmasm.h"
 #include "lowlevel.h"
 
index 572d41ffc186a37fbd4d90dbea14554570681ecf..76bfda1ffaa9106adbc41d65d42ffae086284456 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "ibmasm.h"
 #include "lowlevel.h"
 
index aecf40ecb3a4f560a57cc699094c80f7fd194f50..8844a3f45381e8bd34c2a13901f77810fe87aa95 100644 (file)
@@ -75,6 +75,7 @@
 
 #include <linux/fs.h>
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include "ibmasm.h"
index dc14b0b9cbfa27ff0bfb0cc2e97ed93e0e8d52a7..a234d965243bcb8b1e42024a41259955dc7b7347 100644 (file)
@@ -52,6 +52,7 @@
 
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include "ibmasm.h"
 #include "lowlevel.h"
 #include "remote.h"
index 395a4ea64e9cd81623abc06be926d5f3e4eadd6b..152e9d93eecb2881fa5b804f791ef6db7b74ed6b 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/mutex.h>
 #include <linux/delay.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x69, I2C_CLIENT_END };
index 09dcb699e6674e4ba5d3301149be994fcf17c46d..193206602d88946112f02e189bee1ee9b2b2ab65 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/pci.h>
 #include <linux/ioc4.h>
 #include <linux/ktime.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/time.h>
 #include <asm/io.h>
index 0c8ea0a1c8a3197c5a7edd53d408ec58901617e7..e9eda471f6e0fd9ee4e2781e8d9176761a752591 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
 #include <linux/mmc/sdio_func.h>
index 9dbaeb574e6380c936381a781617cde8bb8c9412..e27afde6e99f056c39f24419d753b90fb3acde15 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/firmware.h>
 #include <linux/mmc/sdio_func.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 #include "iwmc3200top.h"
index d569279698f654dc76ab2dba27ee1fe55742eadd..a36a55a49cac7855eaaa597acab0d0c380ed1e41 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/kernel.h>
 #include <linux/mmc/sdio_func.h>
+#include <linux/slab.h>
 #include <linux/ctype.h>
 #include "fw-msg.h"
 #include "iwmc3200top.h"
index 3b7292a5cea95916cdf4574393c6664a38bc648b..c73cef2c3c5e076a94501967a824a0df953bff1d 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/debugfs.h>
index fcb6ec1af173dfe22e3130ef6016f348c3f24858..72450237a0f418e0a41552cbdefd7943545add78 100644 (file)
@@ -295,6 +295,10 @@ static int check_and_rewind_pc(char *put_str, char *arg)
        /* On x86 a breakpoint stop requires it to be decremented */
        if (addr + 1 == kgdbts_regs.ip)
                offset = -1;
+#elif defined(CONFIG_SUPERH)
+       /* On SUPERH a breakpoint stop requires it to be decremented */
+       if (addr + 2 == kgdbts_regs.pc)
+               offset = -2;
 #endif
        if (strcmp(arg, "silent") &&
                instruction_pointer(&kgdbts_regs) + offset != addr) {
@@ -305,6 +309,8 @@ static int check_and_rewind_pc(char *put_str, char *arg)
 #ifdef CONFIG_X86
        /* On x86 adjust the instruction pointer if needed */
        kgdbts_regs.ip += offset;
+#elif defined(CONFIG_SUPERH)
+       kgdbts_regs.pc += offset;
 #endif
        return 0;
 }
index 4a0648301fdfc4af0762c76e891ad3cfa0c3de9d..31a991161f0a0f984ab73354d1281ccf8aa4943b 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/hrtimer.h>
+#include <linux/slab.h>
 #include <scsi/scsi_cmnd.h>
 #include <linux/debugfs.h>
 
index 779aa8ebe4cfc2ab3f4f5108a8a8e4b966075b74..75ee0d3f6f457707d79cbf5f5d021469710eb06d 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/poll.h>
 #include <linux/interrupt.h>
 #include <linux/cdev.h>
+#include <linux/slab.h>
 #include <linux/phantom.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
index 832ed4c88cf759f022cca50021055e67142eb725..8d082b46426b756681c0590581501b8d8cac198a 100644 (file)
@@ -44,6 +44,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/device.h>
 #include <linux/delay.h>
index 9a6268c89fddc0c49f65001941e13d045a5063a5..d551f09ccb792175d49a83c4a929df7394f50a8a 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/device.h>
 #include <linux/hardirq.h>
+#include <linux/slab.h>
 #include "xpc.h"
 #include <asm/uv/uv_hub.h>
 
index 8b70e03f939f9c0a78f3708a0393b46d8f61e8c8..7d71c04fc938873fa1798dfcc0e6a6b7a043346a 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/uncached.h>
 #include <asm/sn/mspec.h>
 #include <asm/sn/sn_sal.h>
index 8725d5e8ab0c29bff2f6ab27fbacbc33891b48aa..1f59ee2226ca4220e470842326ec64fba62377a2 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <asm/uv/uv_hub.h>
 #if defined CONFIG_X86_64
 #include <asm/uv/bios.h>
index 57b152f8d1b9c8dc1a90a09af32f8bdb8bfd874d..ee5109a3cd984f287c824fd71d3221ead361bccd 100644 (file)
@@ -20,6 +20,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
index 98bcba521da2ab6c8d658f07a547476a51b3326c..5f6852dff40bd3d04d82704e59ae4ef0335d3491 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/tifm.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/idr.h>
 
diff --git a/drivers/misc/vmware_balloon.c b/drivers/misc/vmware_balloon.c
new file mode 100644 (file)
index 0000000..db9cd02
--- /dev/null
@@ -0,0 +1,832 @@
+/*
+ * VMware Balloon driver.
+ *
+ * Copyright (C) 2000-2010, 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.
+ *
+ * Maintained by: Dmitry Torokhov <dtor@vmware.com>
+ */
+
+/*
+ * This is VMware physical memory management driver for Linux. The driver
+ * acts like a "balloon" that can be inflated to reclaim physical pages by
+ * reserving them in the guest and invalidating them in the monitor,
+ * freeing up the underlying machine pages so they can be allocated to
+ * other guests.  The balloon can also be deflated to allow the guest to
+ * use more physical memory. Higher level policies can control the sizes
+ * of balloons in VMs in order to manage physical memory resources.
+ */
+
+//#define DEBUG
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <asm/hypervisor.h>
+
+MODULE_AUTHOR("VMware, Inc.");
+MODULE_DESCRIPTION("VMware Memory Control (Balloon) Driver");
+MODULE_VERSION("1.2.1.0-K");
+MODULE_ALIAS("dmi:*:svnVMware*:*");
+MODULE_ALIAS("vmware_vmmemctl");
+MODULE_LICENSE("GPL");
+
+/*
+ * Various constants controlling rate of inflaint/deflating balloon,
+ * measured in pages.
+ */
+
+/*
+ * Rate of allocating memory when there is no memory pressure
+ * (driver performs non-sleeping allocations).
+ */
+#define VMW_BALLOON_NOSLEEP_ALLOC_MAX  16384U
+
+/*
+ * Rates of memory allocaton when guest experiences memory pressure
+ * (driver performs sleeping allocations).
+ */
+#define VMW_BALLOON_RATE_ALLOC_MIN     512U
+#define VMW_BALLOON_RATE_ALLOC_MAX     2048U
+#define VMW_BALLOON_RATE_ALLOC_INC     16U
+
+/*
+ * Rates for releasing pages while deflating balloon.
+ */
+#define VMW_BALLOON_RATE_FREE_MIN      512U
+#define VMW_BALLOON_RATE_FREE_MAX      16384U
+#define VMW_BALLOON_RATE_FREE_INC      16U
+
+/*
+ * When guest is under memory pressure, use a reduced page allocation
+ * rate for next several cycles.
+ */
+#define VMW_BALLOON_SLOW_CYCLES                4
+
+/*
+ * Use __GFP_HIGHMEM to allow pages from HIGHMEM zone. We don't
+ * allow wait (__GFP_WAIT) for NOSLEEP page allocations. Use
+ * __GFP_NOWARN, to suppress page allocation failure warnings.
+ */
+#define VMW_PAGE_ALLOC_NOSLEEP         (__GFP_HIGHMEM|__GFP_NOWARN)
+
+/*
+ * Use GFP_HIGHUSER when executing in a separate kernel thread
+ * context and allocation can sleep.  This is less stressful to
+ * the guest memory system, since it allows the thread to block
+ * while memory is reclaimed, and won't take pages from emergency
+ * low-memory pools.
+ */
+#define VMW_PAGE_ALLOC_CANSLEEP                (GFP_HIGHUSER)
+
+/* Maximum number of page allocations without yielding processor */
+#define VMW_BALLOON_YIELD_THRESHOLD    1024
+
+
+/*
+ * Hypervisor communication port definitions.
+ */
+#define VMW_BALLOON_HV_PORT            0x5670
+#define VMW_BALLOON_HV_MAGIC           0x456c6d6f
+#define VMW_BALLOON_PROTOCOL_VERSION   2
+#define VMW_BALLOON_GUEST_ID           1       /* Linux */
+
+#define VMW_BALLOON_CMD_START          0
+#define VMW_BALLOON_CMD_GET_TARGET     1
+#define VMW_BALLOON_CMD_LOCK           2
+#define VMW_BALLOON_CMD_UNLOCK         3
+#define VMW_BALLOON_CMD_GUEST_ID       4
+
+/* error codes */
+#define VMW_BALLOON_SUCCESS            0
+#define VMW_BALLOON_FAILURE            -1
+#define VMW_BALLOON_ERROR_CMD_INVALID  1
+#define VMW_BALLOON_ERROR_PPN_INVALID  2
+#define VMW_BALLOON_ERROR_PPN_LOCKED   3
+#define VMW_BALLOON_ERROR_PPN_UNLOCKED 4
+#define VMW_BALLOON_ERROR_PPN_PINNED   5
+#define VMW_BALLOON_ERROR_PPN_NOTNEEDED        6
+#define VMW_BALLOON_ERROR_RESET                7
+#define VMW_BALLOON_ERROR_BUSY         8
+
+#define VMWARE_BALLOON_CMD(cmd, data, result)          \
+({                                                     \
+       unsigned long __stat, __dummy1, __dummy2;       \
+       __asm__ __volatile__ ("inl (%%dx)" :            \
+               "=a"(__stat),                           \
+               "=c"(__dummy1),                         \
+               "=d"(__dummy2),                         \
+               "=b"(result) :                          \
+               "0"(VMW_BALLOON_HV_MAGIC),              \
+               "1"(VMW_BALLOON_CMD_##cmd),             \
+               "2"(VMW_BALLOON_HV_PORT),               \
+               "3"(data) :                             \
+               "memory");                              \
+       result &= -1UL;                                 \
+       __stat & -1UL;                                  \
+})
+
+#ifdef CONFIG_DEBUG_FS
+struct vmballoon_stats {
+       unsigned int timer;
+
+       /* allocation statustics */
+       unsigned int alloc;
+       unsigned int alloc_fail;
+       unsigned int sleep_alloc;
+       unsigned int sleep_alloc_fail;
+       unsigned int refused_alloc;
+       unsigned int refused_free;
+       unsigned int free;
+
+       /* monitor operations */
+       unsigned int lock;
+       unsigned int lock_fail;
+       unsigned int unlock;
+       unsigned int unlock_fail;
+       unsigned int target;
+       unsigned int target_fail;
+       unsigned int start;
+       unsigned int start_fail;
+       unsigned int guest_type;
+       unsigned int guest_type_fail;
+};
+
+#define STATS_INC(stat) (stat)++
+#else
+#define STATS_INC(stat)
+#endif
+
+struct vmballoon {
+
+       /* list of reserved physical pages */
+       struct list_head pages;
+
+       /* transient list of non-balloonable pages */
+       struct list_head refused_pages;
+
+       /* balloon size in pages */
+       unsigned int size;
+       unsigned int target;
+
+       /* reset flag */
+       bool reset_required;
+
+       /* adjustment rates (pages per second) */
+       unsigned int rate_alloc;
+       unsigned int rate_free;
+
+       /* slowdown page allocations for next few cycles */
+       unsigned int slow_allocation_cycles;
+
+#ifdef CONFIG_DEBUG_FS
+       /* statistics */
+       struct vmballoon_stats stats;
+
+       /* debugfs file exporting statistics */
+       struct dentry *dbg_entry;
+#endif
+
+       struct sysinfo sysinfo;
+
+       struct delayed_work dwork;
+};
+
+static struct vmballoon balloon;
+static struct workqueue_struct *vmballoon_wq;
+
+/*
+ * Send "start" command to the host, communicating supported version
+ * of the protocol.
+ */
+static bool vmballoon_send_start(struct vmballoon *b)
+{
+       unsigned long status, dummy;
+
+       STATS_INC(b->stats.start);
+
+       status = VMWARE_BALLOON_CMD(START, VMW_BALLOON_PROTOCOL_VERSION, dummy);
+       if (status == VMW_BALLOON_SUCCESS)
+               return true;
+
+       pr_debug("%s - failed, hv returns %ld\n", __func__, status);
+       STATS_INC(b->stats.start_fail);
+       return false;
+}
+
+static bool vmballoon_check_status(struct vmballoon *b, unsigned long status)
+{
+       switch (status) {
+       case VMW_BALLOON_SUCCESS:
+               return true;
+
+       case VMW_BALLOON_ERROR_RESET:
+               b->reset_required = true;
+               /* fall through */
+
+       default:
+               return false;
+       }
+}
+
+/*
+ * Communicate guest type to the host so that it can adjust ballooning
+ * algorithm to the one most appropriate for the guest. This command
+ * is normally issued after sending "start" command and is part of
+ * standard reset sequence.
+ */
+static bool vmballoon_send_guest_id(struct vmballoon *b)
+{
+       unsigned long status, dummy;
+
+       status = VMWARE_BALLOON_CMD(GUEST_ID, VMW_BALLOON_GUEST_ID, dummy);
+
+       STATS_INC(b->stats.guest_type);
+
+       if (vmballoon_check_status(b, status))
+               return true;
+
+       pr_debug("%s - failed, hv returns %ld\n", __func__, status);
+       STATS_INC(b->stats.guest_type_fail);
+       return false;
+}
+
+/*
+ * Retrieve desired balloon size from the host.
+ */
+static bool vmballoon_send_get_target(struct vmballoon *b, u32 *new_target)
+{
+       unsigned long status;
+       unsigned long target;
+       unsigned long limit;
+       u32 limit32;
+
+       /*
+        * si_meminfo() is cheap. Moreover, we want to provide dynamic
+        * max balloon size later. So let us call si_meminfo() every
+        * iteration.
+        */
+       si_meminfo(&b->sysinfo);
+       limit = b->sysinfo.totalram;
+
+       /* Ensure limit fits in 32-bits */
+       limit32 = (u32)limit;
+       if (limit != limit32)
+               return false;
+
+       /* update stats */
+       STATS_INC(b->stats.target);
+
+       status = VMWARE_BALLOON_CMD(GET_TARGET, limit, target);
+       if (vmballoon_check_status(b, status)) {
+               *new_target = target;
+               return true;
+       }
+
+       pr_debug("%s - failed, hv returns %ld\n", __func__, status);
+       STATS_INC(b->stats.target_fail);
+       return false;
+}
+
+/*
+ * Notify the host about allocated page so that host can use it without
+ * fear that guest will need it. Host may reject some pages, we need to
+ * check the return value and maybe submit a different page.
+ */
+static bool vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn)
+{
+       unsigned long status, dummy;
+       u32 pfn32;
+
+       pfn32 = (u32)pfn;
+       if (pfn32 != pfn)
+               return false;
+
+       STATS_INC(b->stats.lock);
+
+       status = VMWARE_BALLOON_CMD(LOCK, pfn, dummy);
+       if (vmballoon_check_status(b, status))
+               return true;
+
+       pr_debug("%s - ppn %lx, hv returns %ld\n", __func__, pfn, status);
+       STATS_INC(b->stats.lock_fail);
+       return false;
+}
+
+/*
+ * Notify the host that guest intends to release given page back into
+ * the pool of available (to the guest) pages.
+ */
+static bool vmballoon_send_unlock_page(struct vmballoon *b, unsigned long pfn)
+{
+       unsigned long status, dummy;
+       u32 pfn32;
+
+       pfn32 = (u32)pfn;
+       if (pfn32 != pfn)
+               return false;
+
+       STATS_INC(b->stats.unlock);
+
+       status = VMWARE_BALLOON_CMD(UNLOCK, pfn, dummy);
+       if (vmballoon_check_status(b, status))
+               return true;
+
+       pr_debug("%s - ppn %lx, hv returns %ld\n", __func__, pfn, status);
+       STATS_INC(b->stats.unlock_fail);
+       return false;
+}
+
+/*
+ * Quickly release all pages allocated for the balloon. This function is
+ * called when host decides to "reset" balloon for one reason or another.
+ * Unlike normal "deflate" we do not (shall not) notify host of the pages
+ * being released.
+ */
+static void vmballoon_pop(struct vmballoon *b)
+{
+       struct page *page, *next;
+       unsigned int count = 0;
+
+       list_for_each_entry_safe(page, next, &b->pages, lru) {
+               list_del(&page->lru);
+               __free_page(page);
+               STATS_INC(b->stats.free);
+               b->size--;
+
+               if (++count >= b->rate_free) {
+                       count = 0;
+                       cond_resched();
+               }
+       }
+}
+
+/*
+ * Perform standard reset sequence by popping the balloon (in case it
+ * is not  empty) and then restarting protocol. This operation normally
+ * happens when host responds with VMW_BALLOON_ERROR_RESET to a command.
+ */
+static void vmballoon_reset(struct vmballoon *b)
+{
+       /* free all pages, skipping monitor unlock */
+       vmballoon_pop(b);
+
+       if (vmballoon_send_start(b)) {
+               b->reset_required = false;
+               if (!vmballoon_send_guest_id(b))
+                       pr_err("failed to send guest ID to the host\n");
+       }
+}
+
+/*
+ * Allocate (or reserve) a page for the balloon and notify the host.  If host
+ * refuses the page put it on "refuse" list and allocate another one until host
+ * is satisfied. "Refused" pages are released at the end of inflation cycle
+ * (when we allocate b->rate_alloc pages).
+ */
+static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep)
+{
+       struct page *page;
+       gfp_t flags;
+       bool locked = false;
+
+       do {
+               if (!can_sleep)
+                       STATS_INC(b->stats.alloc);
+               else
+                       STATS_INC(b->stats.sleep_alloc);
+
+               flags = can_sleep ? VMW_PAGE_ALLOC_CANSLEEP : VMW_PAGE_ALLOC_NOSLEEP;
+               page = alloc_page(flags);
+               if (!page) {
+                       if (!can_sleep)
+                               STATS_INC(b->stats.alloc_fail);
+                       else
+                               STATS_INC(b->stats.sleep_alloc_fail);
+                       return -ENOMEM;
+               }
+
+               /* inform monitor */
+               locked = vmballoon_send_lock_page(b, page_to_pfn(page));
+               if (!locked) {
+                       if (b->reset_required) {
+                               __free_page(page);
+                               return -EIO;
+                       }
+
+                       /* place on list of non-balloonable pages, retry allocation */
+                       list_add(&page->lru, &b->refused_pages);
+                       STATS_INC(b->stats.refused_alloc);
+               }
+       } while (!locked);
+
+       /* track allocated page */
+       list_add(&page->lru, &b->pages);
+
+       /* update balloon size */
+       b->size++;
+
+       return 0;
+}
+
+/*
+ * Release the page allocated for the balloon. Note that we first notify
+ * the host so it can make sure the page will be available for the guest
+ * to use, if needed.
+ */
+static int vmballoon_release_page(struct vmballoon *b, struct page *page)
+{
+       if (!vmballoon_send_unlock_page(b, page_to_pfn(page)))
+               return -EIO;
+
+       list_del(&page->lru);
+
+       /* deallocate page */
+       __free_page(page);
+       STATS_INC(b->stats.free);
+
+       /* update balloon size */
+       b->size--;
+
+       return 0;
+}
+
+/*
+ * Release pages that were allocated while attempting to inflate the
+ * balloon but were refused by the host for one reason or another.
+ */
+static void vmballoon_release_refused_pages(struct vmballoon *b)
+{
+       struct page *page, *next;
+
+       list_for_each_entry_safe(page, next, &b->refused_pages, lru) {
+               list_del(&page->lru);
+               __free_page(page);
+               STATS_INC(b->stats.refused_free);
+       }
+}
+
+/*
+ * Inflate the balloon towards its target size. Note that we try to limit
+ * the rate of allocation to make sure we are not choking the rest of the
+ * system.
+ */
+static void vmballoon_inflate(struct vmballoon *b)
+{
+       unsigned int goal;
+       unsigned int rate;
+       unsigned int i;
+       unsigned int allocations = 0;
+       int error = 0;
+       bool alloc_can_sleep = false;
+
+       pr_debug("%s - size: %d, target %d\n", __func__, b->size, b->target);
+
+       /*
+        * First try NOSLEEP page allocations to inflate balloon.
+        *
+        * If we do not throttle nosleep allocations, we can drain all
+        * free pages in the guest quickly (if the balloon target is high).
+        * As a side-effect, draining free pages helps to inform (force)
+        * the guest to start swapping if balloon target is not met yet,
+        * which is a desired behavior. However, balloon driver can consume
+        * all available CPU cycles if too many pages are allocated in a
+        * second. Therefore, we throttle nosleep allocations even when
+        * the guest is not under memory pressure. OTOH, if we have already
+        * predicted that the guest is under memory pressure, then we
+        * slowdown page allocations considerably.
+        */
+
+       goal = b->target - b->size;
+       /*
+        * Start with no sleep allocation rate which may be higher
+        * than sleeping allocation rate.
+        */
+       rate = b->slow_allocation_cycles ?
+                       b->rate_alloc : VMW_BALLOON_NOSLEEP_ALLOC_MAX;
+
+       pr_debug("%s - goal: %d, no-sleep rate: %d, sleep rate: %d\n",
+                __func__, goal, rate, b->rate_alloc);
+
+       for (i = 0; i < goal; i++) {
+
+               error = vmballoon_reserve_page(b, alloc_can_sleep);
+               if (error) {
+                       if (error != -ENOMEM) {
+                               /*
+                                * Not a page allocation failure, stop this
+                                * cycle. Maybe we'll get new target from
+                                * the host soon.
+                                */
+                               break;
+                       }
+
+                       if (alloc_can_sleep) {
+                               /*
+                                * CANSLEEP page allocation failed, so guest
+                                * is under severe memory pressure. Quickly
+                                * decrease allocation rate.
+                                */
+                               b->rate_alloc = max(b->rate_alloc / 2,
+                                                   VMW_BALLOON_RATE_ALLOC_MIN);
+                               break;
+                       }
+
+                       /*
+                        * NOSLEEP page allocation failed, so the guest is
+                        * under memory pressure. Let us slow down page
+                        * allocations for next few cycles so that the guest
+                        * gets out of memory pressure. Also, if we already
+                        * allocated b->rate_alloc pages, let's pause,
+                        * otherwise switch to sleeping allocations.
+                        */
+                       b->slow_allocation_cycles = VMW_BALLOON_SLOW_CYCLES;
+
+                       if (i >= b->rate_alloc)
+                               break;
+
+                       alloc_can_sleep = true;
+                       /* Lower rate for sleeping allocations. */
+                       rate = b->rate_alloc;
+               }
+
+               if (++allocations > VMW_BALLOON_YIELD_THRESHOLD) {
+                       cond_resched();
+                       allocations = 0;
+               }
+
+               if (i >= rate) {
+                       /* We allocated enough pages, let's take a break. */
+                       break;
+               }
+       }
+
+       /*
+        * We reached our goal without failures so try increasing
+        * allocation rate.
+        */
+       if (error == 0 && i >= b->rate_alloc) {
+               unsigned int mult = i / b->rate_alloc;
+
+               b->rate_alloc =
+                       min(b->rate_alloc + mult * VMW_BALLOON_RATE_ALLOC_INC,
+                           VMW_BALLOON_RATE_ALLOC_MAX);
+       }
+
+       vmballoon_release_refused_pages(b);
+}
+
+/*
+ * Decrease the size of the balloon allowing guest to use more memory.
+ */
+static void vmballoon_deflate(struct vmballoon *b)
+{
+       struct page *page, *next;
+       unsigned int i = 0;
+       unsigned int goal;
+       int error;
+
+       pr_debug("%s - size: %d, target %d\n", __func__, b->size, b->target);
+
+       /* limit deallocation rate */
+       goal = min(b->size - b->target, b->rate_free);
+
+       pr_debug("%s - goal: %d, rate: %d\n", __func__, goal, b->rate_free);
+
+       /* free pages to reach target */
+       list_for_each_entry_safe(page, next, &b->pages, lru) {
+               error = vmballoon_release_page(b, page);
+               if (error) {
+                       /* quickly decrease rate in case of error */
+                       b->rate_free = max(b->rate_free / 2,
+                                          VMW_BALLOON_RATE_FREE_MIN);
+                       return;
+               }
+
+               if (++i >= goal)
+                       break;
+       }
+
+       /* slowly increase rate if there were no errors */
+       b->rate_free = min(b->rate_free + VMW_BALLOON_RATE_FREE_INC,
+                          VMW_BALLOON_RATE_FREE_MAX);
+}
+
+/*
+ * Balloon work function: reset protocol, if needed, get the new size and
+ * adjust balloon as needed. Repeat in 1 sec.
+ */
+static void vmballoon_work(struct work_struct *work)
+{
+       struct delayed_work *dwork = to_delayed_work(work);
+       struct vmballoon *b = container_of(dwork, struct vmballoon, dwork);
+       unsigned int target;
+
+       STATS_INC(b->stats.timer);
+
+       if (b->reset_required)
+               vmballoon_reset(b);
+
+       if (b->slow_allocation_cycles > 0)
+               b->slow_allocation_cycles--;
+
+       if (vmballoon_send_get_target(b, &target)) {
+               /* update target, adjust size */
+               b->target = target;
+
+               if (b->size < target)
+                       vmballoon_inflate(b);
+               else if (b->size > target)
+                       vmballoon_deflate(b);
+       }
+
+       queue_delayed_work(vmballoon_wq, dwork, round_jiffies_relative(HZ));
+}
+
+/*
+ * DEBUGFS Interface
+ */
+#ifdef CONFIG_DEBUG_FS
+
+static int vmballoon_debug_show(struct seq_file *f, void *offset)
+{
+       struct vmballoon *b = f->private;
+       struct vmballoon_stats *stats = &b->stats;
+
+       /* format size info */
+       seq_printf(f,
+                  "target:             %8d pages\n"
+                  "current:            %8d pages\n",
+                  b->target, b->size);
+
+       /* format rate info */
+       seq_printf(f,
+                  "rateNoSleepAlloc:   %8d pages/sec\n"
+                  "rateSleepAlloc:     %8d pages/sec\n"
+                  "rateFree:           %8d pages/sec\n",
+                  VMW_BALLOON_NOSLEEP_ALLOC_MAX,
+                  b->rate_alloc, b->rate_free);
+
+       seq_printf(f,
+                  "\n"
+                  "timer:              %8u\n"
+                  "start:              %8u (%4u failed)\n"
+                  "guestType:          %8u (%4u failed)\n"
+                  "lock:               %8u (%4u failed)\n"
+                  "unlock:             %8u (%4u failed)\n"
+                  "target:             %8u (%4u failed)\n"
+                  "primNoSleepAlloc:   %8u (%4u failed)\n"
+                  "primCanSleepAlloc:  %8u (%4u failed)\n"
+                  "primFree:           %8u\n"
+                  "errAlloc:           %8u\n"
+                  "errFree:            %8u\n",
+                  stats->timer,
+                  stats->start, stats->start_fail,
+                  stats->guest_type, stats->guest_type_fail,
+                  stats->lock,  stats->lock_fail,
+                  stats->unlock, stats->unlock_fail,
+                  stats->target, stats->target_fail,
+                  stats->alloc, stats->alloc_fail,
+                  stats->sleep_alloc, stats->sleep_alloc_fail,
+                  stats->free,
+                  stats->refused_alloc, stats->refused_free);
+
+       return 0;
+}
+
+static int vmballoon_debug_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, vmballoon_debug_show, inode->i_private);
+}
+
+static const struct file_operations vmballoon_debug_fops = {
+       .owner          = THIS_MODULE,
+       .open           = vmballoon_debug_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init vmballoon_debugfs_init(struct vmballoon *b)
+{
+       int error;
+
+       b->dbg_entry = debugfs_create_file("vmmemctl", S_IRUGO, NULL, b,
+                                          &vmballoon_debug_fops);
+       if (IS_ERR(b->dbg_entry)) {
+               error = PTR_ERR(b->dbg_entry);
+               pr_err("failed to create debugfs entry, error: %d\n", error);
+               return error;
+       }
+
+       return 0;
+}
+
+static void __exit vmballoon_debugfs_exit(struct vmballoon *b)
+{
+       debugfs_remove(b->dbg_entry);
+}
+
+#else
+
+static inline int vmballoon_debugfs_init(struct vmballoon *b)
+{
+       return 0;
+}
+
+static inline void vmballoon_debugfs_exit(struct vmballoon *b)
+{
+}
+
+#endif /* CONFIG_DEBUG_FS */
+
+static int __init vmballoon_init(void)
+{
+       int error;
+
+       /*
+        * Check if we are running on VMware's hypervisor and bail out
+        * if we are not.
+        */
+       if (x86_hyper != &x86_hyper_vmware)
+               return -ENODEV;
+
+       vmballoon_wq = create_freezeable_workqueue("vmmemctl");
+       if (!vmballoon_wq) {
+               pr_err("failed to create workqueue\n");
+               return -ENOMEM;
+       }
+
+       INIT_LIST_HEAD(&balloon.pages);
+       INIT_LIST_HEAD(&balloon.refused_pages);
+
+       /* initialize rates */
+       balloon.rate_alloc = VMW_BALLOON_RATE_ALLOC_MAX;
+       balloon.rate_free = VMW_BALLOON_RATE_FREE_MAX;
+
+       INIT_DELAYED_WORK(&balloon.dwork, vmballoon_work);
+
+       /*
+        * Start balloon.
+        */
+       if (!vmballoon_send_start(&balloon)) {
+               pr_err("failed to send start command to the host\n");
+               error = -EIO;
+               goto fail;
+       }
+
+       if (!vmballoon_send_guest_id(&balloon)) {
+               pr_err("failed to send guest ID to the host\n");
+               error = -EIO;
+               goto fail;
+       }
+
+       error = vmballoon_debugfs_init(&balloon);
+       if (error)
+               goto fail;
+
+       queue_delayed_work(vmballoon_wq, &balloon.dwork, 0);
+
+       return 0;
+
+fail:
+       destroy_workqueue(vmballoon_wq);
+       return error;
+}
+module_init(vmballoon_init);
+
+static void __exit vmballoon_exit(void)
+{
+       cancel_delayed_work_sync(&balloon.dwork);
+       destroy_workqueue(vmballoon_wq);
+
+       vmballoon_debugfs_exit(&balloon);
+
+       /*
+        * Deallocate all reserved memory, and reset connection with monitor.
+        * Reset connection before deallocating memory to avoid potential for
+        * additional spurious resets from guest touching deallocated pages.
+        */
+       vmballoon_send_start(&balloon);
+       vmballoon_pop(&balloon);
+}
+module_exit(vmballoon_exit);
index 1f552c6e7579b5a42a665e89a69b5e7f798d161c..cb9fbc83b09095f8a0aa77572c0e9304641f300b 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/kernel.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/hdreg.h>
 #include <linux/kdev_t.h>
index e7f8027165e697b3f2a1ef3926f2ce0b3e2153f1..445d7db2277e4c91fbf9770cff6d1b04ddc76a5a 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
+#include <linux/slab.h>
 
 #include <linux/scatterlist.h>
 
index 381fe032caa129039c89da492a0b092f5540aed1..d6ded247d941197734c289e36f665a2bdeb96737 100644 (file)
@@ -9,6 +9,7 @@
  * published by the Free Software Foundation.
  *
  */
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/blkdev.h>
 #include <linux/freezer.h>
index 723e50894db9c769a08235aa99cca0ce630f1e57..a0716967b7c867f4cd6a88003b41678de69cd22a 100644 (file)
 #include <linux/seq_file.h>
 #include <linux/serial_reg.h>
 #include <linux/circ_buf.h>
-#include <linux/gfp.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/kfifo.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/core.h>
 #include <linux/mmc/card.h>
index bdb165f93046f9cdce780a614ddafcc41f3cab91..49d9dcaeca493ddea3b108e98a06315a9c3768c6 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
index 96d10f40fb23e1ba6db97359c53c4e6a8415660f..53cb380c0987d9d5e460828c801e2f25790c1f40 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/debugfs.h>
 #include <linux/fs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/stat.h>
 
 #include <linux/mmc/card.h>
index a268d12f1af0d0276787642ff4728060a1ab2624..47353909e345caaafa8a37f51a535fc734d5af4c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/idr.h>
 #include <linux/pagemap.h>
 #include <linux/leds.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/host.h>
 
index 0eac6c81490462fb640d768edbbdec54659510fa..89f7a25b7ac12ab17f7baa9a18e0d980fe1c50eb 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
@@ -225,7 +226,7 @@ static int mmc_read_ext_csd(struct mmc_card *card)
                        mmc_card_set_blockaddr(card);
        }
 
-       switch (ext_csd[EXT_CSD_CARD_TYPE]) {
+       switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
        case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
                card->ext_csd.hs_max_dtr = 52000000;
                break;
@@ -237,7 +238,6 @@ static int mmc_read_ext_csd(struct mmc_card *card)
                printk(KERN_WARNING "%s: card is mmc v4 but doesn't "
                        "support any high-speed modes.\n",
                        mmc_hostname(card->host));
-               goto out;
        }
 
        if (card->ext_csd.rev >= 3) {
index d2cb5c6343920371e6c6ba367a3b8c14a1282b4c..326447c9ede8aa5a9153f8019a47f706f20917ec 100644 (file)
@@ -9,6 +9,7 @@
  * your option) any later version.
  */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/scatterlist.h>
 
index fdd414eded09a9eef14968a59d026e369c046aa5..5eac21df4809feb070a2c5943c5c3a45538c8288 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
index 9e060c87e64db6775fc5aa7b8aa07033dae7e365..4a890dcb95ab413c14ac5a457036d57a1ea6b1b0 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/sdio_func.h>
index 9538389783c10e17d4494e875499c302b93ed01b..541bdb89e0c5e03cadcbad743bea8814542446d4 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
index 91dc60cd032b37b676226f508d87329b6af065ae..336d9f553f3e85ae6240b5a22c83ae0eb33fe3b0 100644 (file)
@@ -65,6 +65,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
 #include <linux/atmel_pdc.h>
+#include <linux/gfp.h>
 
 #include <linux/mmc/host.h>
 
@@ -313,8 +314,8 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
                        dmabuf = (unsigned *)tmpv;
                }
 
+               flush_kernel_dcache_page(sg_page(sg));
                kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);
-               dmac_flush_range((void *)sgbuffer, ((void *)sgbuffer) + amount);
                data->bytes_xfered += amount;
                if (size == 0)
                        break;
index 8072128e933b80a8ff6f68f2ed160a964ed04bc2..fb279f4ed8b3591ca538276fd23739e9fbfb2ecb 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/scatterlist.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/stat.h>
 
 #include <linux/mmc/host.h>
@@ -265,7 +266,7 @@ static int atmci_req_show(struct seq_file *s, void *v)
                                "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
                                cmd->opcode, cmd->arg, cmd->flags,
                                cmd->resp[0], cmd->resp[1], cmd->resp[2],
-                               cmd->resp[2], cmd->error);
+                               cmd->resp[3], cmd->error);
                if (data)
                        seq_printf(s, "DATA %u / %u * %u flg %x err %d\n",
                                data->bytes_xfered, data->blocks,
@@ -275,7 +276,7 @@ static int atmci_req_show(struct seq_file *s, void *v)
                                "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
                                stop->opcode, stop->arg, stop->flags,
                                stop->resp[0], stop->resp[1], stop->resp[2],
-                               stop->resp[2], stop->error);
+                               stop->resp[3], stop->error);
        }
 
        spin_unlock_bh(&slot->host->lock);
@@ -568,9 +569,10 @@ static void atmci_dma_cleanup(struct atmel_mci *host)
 {
        struct mmc_data                 *data = host->data;
 
-       dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len,
-                    ((data->flags & MMC_DATA_WRITE)
-                     ? DMA_TO_DEVICE : DMA_FROM_DEVICE));
+       if (data)
+               dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len,
+                            ((data->flags & MMC_DATA_WRITE)
+                             ? DMA_TO_DEVICE : DMA_FROM_DEVICE));
 }
 
 static void atmci_stop_dma(struct atmel_mci *host)
@@ -1098,8 +1100,8 @@ static void atmci_command_complete(struct atmel_mci *host,
                        "command error: status=0x%08x\n", status);
 
                if (cmd->data) {
-                       host->data = NULL;
                        atmci_stop_dma(host);
+                       host->data = NULL;
                        mci_writel(host, IDR, MCI_NOTBUSY
                                        | MCI_TXRDY | MCI_RXRDY
                                        | ATMCI_DATA_ERROR_FLAGS);
@@ -1292,6 +1294,7 @@ static void atmci_tasklet_func(unsigned long priv)
                        } else {
                                data->bytes_xfered = data->blocks * data->blksz;
                                data->error = 0;
+                               mci_writel(host, IDR, ATMCI_DATA_ERROR_FLAGS);
                        }
 
                        if (!data->stop) {
@@ -1750,13 +1753,13 @@ static int __init atmci_probe(struct platform_device *pdev)
        ret = -ENODEV;
        if (pdata->slot[0].bus_width) {
                ret = atmci_init_slot(host, &pdata->slot[0],
-                               MCI_SDCSEL_SLOT_A, 0);
+                               0, MCI_SDCSEL_SLOT_A);
                if (!ret)
                        nr_slots++;
        }
        if (pdata->slot[1].bus_width) {
                ret = atmci_init_slot(host, &pdata->slot[1],
-                               MCI_SDCSEL_SLOT_B, 1);
+                               1, MCI_SDCSEL_SLOT_B);
                if (!ret)
                        nr_slots++;
        }
index 57b21198828fbd18ad8ac980b667b7e9dc41b2a6..f5834449400e0b06d6cd4d60f85c9ce4d303705a 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/scatterlist.h>
 #include <linux/leds.h>
 #include <linux/mmc/host.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/mach-au1x00/au1000.h>
index 56f7b448b9112e8360e4d31c2178431243d545bd..6919e844072c9dbf683359764ea6fe55a763906b 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/mmc/host.h>
 #include <linux/proc_fs.h>
+#include <linux/gfp.h>
 
 #include <asm/cacheflush.h>
 #include <asm/dma.h>
index 4e72964a7b431345c37cd0868056de1145b1c76f..92a324f7417c3eb0a710a19fcd47b1f792b067f7 100644 (file)
@@ -9,7 +9,6 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include "cb710-mmc.h"
index d55fe4fb793559430c9557a9e67f2e43c402f9d8..ad847a24a6756f8f88ec97f6ea8031b8a7169842 100644 (file)
@@ -26,6 +26,7 @@
  */
 #include <linux/sched.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/bio.h>
 #include <linux/dma-mapping.h>
 #include <linux/crc7.h>
index 4c068e5fe6b2502ec45df9c9edd60a462b5fc0e7..04ae884383f690d6fdc41cae87da020afbbbfad9 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/debugfs.h>
 #include <linux/io.h>
 #include <linux/memory.h>
+#include <linux/gfp.h>
 
 #include <asm/cacheflush.h>
 #include <asm/div64.h>
index 0c7a63c1f12f4c9aeed7679b28da66e1a5f9a9b8..bb6cc54b558ee235f17b28990f5e80da8304f2b6 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
index c6d7e8ecadbf586691d484cdbf7b94b7f4550913..84d280406341f1bf071e07430e6118766cea87c5 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/clk.h>
 #include <linux/scatterlist.h>
 #include <linux/i2c/tps65010.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index 83f0affadcae638fcbc0abc8cc0e892c23e16142..e9caf694c59e200e57eed9cc1cc29847139cf9b4 100644 (file)
@@ -1179,15 +1179,10 @@ static void omap_hsmmc_detect(struct work_struct *work)
                carddetect = -ENOSYS;
        }
 
-       if (carddetect) {
+       if (carddetect)
                mmc_detect_change(host->mmc, (HZ * 200) / 1000);
-       } else {
-               mmc_host_enable(host->mmc);
-               omap_hsmmc_reset_controller_fsm(host, SRD);
-               mmc_host_lazy_disable(host->mmc);
-
+       else
                mmc_detect_change(host->mmc, (HZ * 50) / 1000);
-       }
 }
 
 /*
index 0d783f3e79edf609f2297c7eaab42240d678feb0..0ed48959b590e81b3e6e9a8754fc7da23df0bc26 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/io.h>
 #include <linux/regulator/consumer.h>
 #include <linux/gpio.h>
+#include <linux/gfp.h>
 
 #include <asm/sizes.h>
 
index 8e1020cf73f42dfdeb85c1e9abe0a65f5b2b259f..6701af629c30e3b8c0fb86c606f546cddf7519b7 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/highmem.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/host.h>
 
index 50997d2a63e7effcd533d9d95fea45b9ebf34efc..2136794c0cfaf66fed55c5433f8e4bc574e19604 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 
index d6ab62d539fb2aa03f084eee2a305fcee3d5bd84..9d4fdfa685e57521a711c29904c100a66df4cd48 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/highmem.h>
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <linux/scatterlist.h>
 
 #include <linux/leds.h>
index 89bf8cd25cacec9a6df3d9d231a429c82ce36e40..69efe01eece829cb2f0011b8771471d91245818a 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/highmem.h>
 #include <linux/mmc/host.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
index 82d1e4de475bba283870d8a590416f9fc55161a8..4521b1ecce452607987b3d32c6251264de02d2b8 100644 (file)
@@ -4,7 +4,7 @@
 
 # Core functionality.
 obj-$(CONFIG_MTD)              += mtd.o
-mtd-y                          := mtdcore.o mtdsuper.o mtdbdi.o
+mtd-y                          := mtdcore.o mtdsuper.o
 mtd-$(CONFIG_MTD_PARTITIONS)   += mtdpart.o
 
 obj-$(CONFIG_MTD_CONCAT)       += mtdconcat.o
index 8c295f40d2acfd3dde7f2cab8c753a01a2c07aff..ce6424008ed9c38bbb11e2794a0522592ae7f948 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/buffer_head.h>
 #include <linux/mutex.h>
 #include <linux/mount.h>
+#include <linux/slab.h>
 
 #define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
 #define INFO(fmt, args...) printk(KERN_INFO "block2mtd: " fmt "\n" , ## args)
index f3f4768d6e18df89ba99e4efc5723c5e6593715d..81e49a9b017e32efd4137618c5ad4593e18c3658 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <linux/math64.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/mod_devicetable.h>
 
index 0a11721f146e0857947af8fddbdcd49b8f318d7c..fe17054ee2fe69c4190b38f26afde0a6620c861d 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/device.h>
 #include <linux/mutex.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #include <linux/mtd/mtd.h>
diff --git a/drivers/mtd/internal.h b/drivers/mtd/internal.h
deleted file mode 100644 (file)
index c658fe7..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Internal MTD definitions
- *
- * Copyright Â© 2006 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 License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-/*
- * mtdbdi.c
- */
-extern struct backing_dev_info mtd_bdi_unmappable;
-extern struct backing_dev_info mtd_bdi_ro_mappable;
-extern struct backing_dev_info mtd_bdi_rw_mappable;
index e22ca49583e78beb9f2b7609ae76c963d8b4737b..a73ee12aad81387f44032203e1f63bbdf7caf48b 100644 (file)
@@ -26,6 +26,7 @@
  */
 #include <linux/mtd/pfow.h>
 #include <linux/mtd/qinfo.h>
+#include <linux/slab.h>
 
 static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len,
                                        size_t *retlen, u_char *buf);
index 237733d094c41feb17170d97ff1a72ce7c657350..19fe92db0c46fb90051c97146be5a170dff46a9a 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
index a7c808b577d376a5f99edc98adcf5dd49cc2cba0..c0fd99b0c525d7173674cadf017ab43e1b8ad361 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #include <asm/blackfin.h>
index 424f17d6ffd1270bfae71befae6975781814f168..ddb462bea9b51727593cdb5c67ca809f5807edeb 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
index 11a2f57df9cf5d8c87f0a5f907a239d409f7e544..d12c93dc1aad9aa843decb459f6d4964fbe24eff 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
index 1ad5caf9fe693e2fbf500f626bc65ad50c5fbe8d..32e89d773b4ead7dbaa6172e331fb6c9f11f17ec 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); })
index c32bc28920b35fe3927f960a528a52fd2f6fa5c6..f102bf243a7418b5482b71ec8833ea205fc50355 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
index 1e7814ae212a2eb372b9d3ad7791f0be1baa18e8..fc1998512eb407bd26e9cf235cbf8a2f92ecfa26 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/mtd/mtd.h>
index 2b2e45093218fca47a36a80fba14f6505421e67c..23fe1786770f140c686215cc05925a5d4f6c2d8d 100644 (file)
@@ -24,7 +24,6 @@
    ##################################################################### */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <asm/io.h>
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
deleted file mode 100644 (file)
index e69de29..0000000
index 61e4eb48bb2d5a37dfad765e3399e3b22d6270f9..101ee6ead05c16af55f34434df390ba859bcd27b 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/mtd/concat.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 
 struct of_flash_list {
        struct mtd_info *mtd;
index 30e12c88d1dae5b98bb3098628ac4b3db9c738a0..60c068db452d8678718790947340464ad61acc58 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
index c8fd8da4bc8780407b7b5e07a633da68c1909572..acb13fa5001ca7a14c3f872be849b7cc6001c722 100644 (file)
@@ -28,6 +28,7 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
index b13f6417b5b262a81b149713184fe4de9364bea9..91dc6331053f512fc881ee6b28376da93616c294 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
index 1b1c0b7e11ef410e64921cdb34db049d86968183..04b2781fc6278ba852b47f4e7208f3dc228e6209 100644 (file)
@@ -45,7 +45,6 @@ separate MTD devices.
 // Includes
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <asm/io.h>
index fd7a1017399a069da8f8e78dd62a08d1ad6dcf3e..fadc4c45b455aaabfab873d35c09a1e7c05c1960 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/ioport.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/slab.h>
 #include <asm/prom.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
index 6d452dcdfe34756656e2014739ccdabeb9d29064..6adaa6acc1936716ad74e063613c84abe7c5d856 100644 (file)
@@ -16,7 +16,6 @@
    ##################################################################### */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
index 82afad0ddd726ca0efd0dbaa6e6a0c040219d718..4afc167731ef5e980383d0f442c9417ab58494f4 100644 (file)
@@ -8,6 +8,7 @@
  * GNU General Public Licence
  */
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/maple.h>
diff --git a/drivers/mtd/mtdbdi.c b/drivers/mtd/mtdbdi.c
deleted file mode 100644 (file)
index 5ca5aed..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* MTD backing device capabilities
- *
- * Copyright Â© 2006 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 License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/backing-dev.h>
-#include <linux/mtd/mtd.h>
-#include "internal.h"
-
-/*
- * backing device capabilities for non-mappable devices (such as NAND flash)
- * - permits private mappings, copies are taken of the data
- */
-struct backing_dev_info mtd_bdi_unmappable = {
-       .capabilities   = BDI_CAP_MAP_COPY,
-};
-
-/*
- * backing device capabilities for R/O mappable devices (such as ROM)
- * - permits private mappings, copies are taken of the data
- * - permits non-writable shared mappings
- */
-struct backing_dev_info mtd_bdi_ro_mappable = {
-       .capabilities   = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
-                          BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP),
-};
-
-/*
- * backing device capabilities for writable mappable devices (such as RAM)
- * - permits private mappings, copies are taken of the data
- * - permits non-writable shared mappings
- */
-struct backing_dev_info mtd_bdi_rw_mappable = {
-       .capabilities   = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
-                          BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP |
-                          BDI_CAP_WRITE_MAP),
-};
index c356c0a30c3e46b82d5dca258491390494098c82..b177e750efc364b91b646a81d9fa9570cfec5430 100644 (file)
@@ -2,12 +2,14 @@
  * Core registration and callback routines for MTD
  * drivers and users.
  *
+ * bdi bits are:
+ * Copyright Â© 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
  */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/major.h>
 #include <linux/init.h>
 #include <linux/mtd/compatmac.h>
 #include <linux/proc_fs.h>
+#include <linux/backing-dev.h>
 
 #include <linux/mtd/mtd.h>
-#include "internal.h"
 
 #include "mtdcore.h"
+/*
+ * backing device capabilities for non-mappable devices (such as NAND flash)
+ * - permits private mappings, copies are taken of the data
+ */
+struct backing_dev_info mtd_bdi_unmappable = {
+       .capabilities   = BDI_CAP_MAP_COPY,
+};
+
+/*
+ * backing device capabilities for R/O mappable devices (such as ROM)
+ * - permits private mappings, copies are taken of the data
+ * - permits non-writable shared mappings
+ */
+struct backing_dev_info mtd_bdi_ro_mappable = {
+       .capabilities   = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
+                          BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP),
+};
+
+/*
+ * backing device capabilities for writable mappable devices (such as RAM)
+ * - permits private mappings, copies are taken of the data
+ * - permits non-writable shared mappings
+ */
+struct backing_dev_info mtd_bdi_rw_mappable = {
+       .capabilities   = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
+                          BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP |
+                          BDI_CAP_WRITE_MAP),
+};
 
 static int mtd_cls_suspend(struct device *dev, pm_message_t state);
 static int mtd_cls_resume(struct device *dev);
@@ -629,20 +659,55 @@ done:
 /*====================================================================*/
 /* Init code */
 
+static int __init mtd_bdi_init(struct backing_dev_info *bdi, const char *name)
+{
+       int ret;
+
+       ret = bdi_init(bdi);
+       if (!ret)
+               ret = bdi_register(bdi, NULL, name);
+
+       if (ret)
+               bdi_destroy(bdi);
+
+       return ret;
+}
+
 static int __init init_mtd(void)
 {
        int ret;
+
        ret = class_register(&mtd_class);
+       if (ret)
+               goto err_reg;
+
+       ret = mtd_bdi_init(&mtd_bdi_unmappable, "mtd-unmap");
+       if (ret)
+               goto err_bdi1;
+
+       ret = mtd_bdi_init(&mtd_bdi_ro_mappable, "mtd-romap");
+       if (ret)
+               goto err_bdi2;
+
+       ret = mtd_bdi_init(&mtd_bdi_rw_mappable, "mtd-rwmap");
+       if (ret)
+               goto err_bdi3;
 
-       if (ret) {
-               pr_err("Error registering mtd class: %d\n", ret);
-               return ret;
-       }
 #ifdef CONFIG_PROC_FS
        if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
                proc_mtd->read_proc = mtd_read_proc;
 #endif /* CONFIG_PROC_FS */
        return 0;
+
+err_bdi3:
+       bdi_destroy(&mtd_bdi_ro_mappable);
+err_bdi2:
+       bdi_destroy(&mtd_bdi_unmappable);
+err_bdi1:
+       class_unregister(&mtd_class);
+err_reg:
+       pr_err("Error registering mtd class or bdi: %d\n", ret);
+       return ret;
 }
 
 static void __exit cleanup_mtd(void)
@@ -652,6 +717,9 @@ static void __exit cleanup_mtd(void)
                remove_proc_entry( "mtd", NULL);
 #endif /* CONFIG_PROC_FS */
        class_unregister(&mtd_class);
+       bdi_destroy(&mtd_bdi_unmappable);
+       bdi_destroy(&mtd_bdi_ro_mappable);
+       bdi_destroy(&mtd_bdi_rw_mappable);
 }
 
 module_init(init_mtd);
index af8b42e0a55bedfaf3fdae1fc02fa3367e09d011..7c003191fca444aa191119f485fd609727aa62d8 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/mtd/super.h>
 #include <linux/namei.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 
 /*
  * compare superblocks to see if they're equivalent
@@ -44,6 +45,7 @@ static int get_sb_mtd_set(struct super_block *sb, void *_mtd)
 
        sb->s_mtd = mtd;
        sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+       sb->s_bdi = mtd->backing_dev_info;
        return 0;
 }
 
index 1157d5679e66fc5d33eddab6964f3be40708d9f9..42e5ea49e97504adc1e354c7e9534e1c3054aed6 100644 (file)
@@ -457,7 +457,7 @@ config MTD_NAND_NOMADIK
 
 config MTD_NAND_SH_FLCTL
        tristate "Support for NAND on Renesas SuperH FLCTL"
-       depends on MTD_NAND && SUPERH
+       depends on MTD_NAND && (SUPERH || ARCH_SHMOBILE)
        help
          Several Renesas SuperH CPU has FLCTL. This option enables support
          for NAND Flash using FLCTL.
index 7d1cca7a31a9ec7ff6d5880dd5bc1853518ca2cf..c997f98eeb3de717730fc3aee2395a9c61e7f31b 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/ioport.h>
 #include <linux/device.h>
index c828d9ac7bd71a7709fac3ea16bd1e9419e062f6..e5a9f9ccea60ff48b376a59eaf9a1d84c91434fd 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 #define CAFE_NAND_CTRL1                0x00
index 826cacffcefc81b94229bcb77334603839b3460c..6e6495278258f040e51bcfc1e41f6b0f6d45f1d2 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/slab.h>
 #include <linux/gpio.h>
 
 #include <asm/io.h>
index fe3eba87de40687225658d2aea50f1760b15de1f..76e2dc8e62f71b7fbabc73c2b5078d9184be75c4 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/io.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/slab.h>
 
 #include <mach/nand.h>
 
index b126cf8874763b318fa2d045ff33e96b60b08594..47067bc98248bec58f547e72d89713961ff89983 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/rslib.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 #include <linux/mtd/mtd.h>
index 071a60cb42041b4d660189a1b01223a17b081b00..4b96296af321e5d5e0dba823b1e1ed7568943279 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <asm/fsl_lbc.h>
 
 #define FSL_UPM_WAIT_RUN_PATTERN  0x1
index 40b5658bdbe6f39ae574fb8b41257c64c17c14b5..b983cae8c298288a2d2942e4170114f047182559 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/ndfc.h>
+#include <linux/slab.h>
 #include <linux/mtd/mtd.h>
 #include <linux/of_platform.h>
 #include <asm/io.h>
index 66123419f65d4561f4912a60e68d499d9e0406e7..1f6f741af5da786cd101d6e13ebcdb89059dfb0a 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/platform_device.h>
 #include <linux/mtd/partitions.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <mach/nand.h>
 #include <mach/fsmc.h>
 
index 26aec00801848590333a62252599c5406a345904..7545568fce479dda7f12d31383948fb23ca5d321 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <plat/dma.h>
 #include <plat/gpmc.h>
index f59c07427af3eda9c71dd18cb4244200375f5216..d60fc5719fef33e29ff29e970aadc735a00f40de 100644 (file)
@@ -60,7 +60,13 @@ static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
        }
        buf64 = (uint64_t *)buf;
        while (i < len/8) {
-               uint64_t x;
+               /*
+                * Since GCC has no proper constraint (PR 43518)
+                * force x variable to r2/r3 registers as ldrd instruction
+                * requires first register to be even.
+                */
+               register uint64_t x asm ("r2");
+
                asm volatile ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base));
                buf64[i++] = x;
        }
index 1a5a0365c9835784d38b635f1fa87bc46fb62924..5d55152162cf5c4e2e09b738535388f55cf4b512 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 
 #include <mach/dma.h>
 #include <plat/pxa3xx_nand.h>
index 1842df8bdd934fcec9955f445984af556ebf13bb..34752fce079305b6f41a73bcead9ed18d1166d1c 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
index 92c73344a669eebbd56f2b450161260d07872409..fa28f01ae009439d24f7332109e682e2e8a5c346 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
+#include <linux/slab.h>
 
 /*--------------------------------------------------------------------------*/
 
index 62d6a78c4eeea43ae34aac65508d270b163b985d..4f0d635674f334a0dd5d1699edff8659f82451d0 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/of.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include <linux/mtd/partitions.h>
 
 int __devinit of_mtd_parse_partitions(struct device *dev,
index 75f38b95811ea729b0e9f2494399253d93ed8472..fd406348fdfd5b269cbadb8c10de362320ba4bb7 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/mach/flash.h>
 #include <plat/gpmc.h>
index f63b1db3ffb3f0266658a787bc59dd09dd7f2a2a..32f0ed33afe09bdc776f84b644944ea6d4e79622 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
index f6e3c8aebd3a107b43c711a05fdebcdc283e05f8..8b246061d511ad5c7ed1cd4f6f833833863e6ee5 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/vmalloc.h>
index c1f31051784c895a244aeef144f20ff5f0cddd70..70d6d7d0d65696b5cae7b5a1dd2aa57674a6f264 100644 (file)
@@ -1,7 +1,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/list.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/string.h>
 #include <linux/bitops.h>
index 5813920e79a5f346278247de54990a03062e91c8..dec92ae6111a190b0ad8493ad5098c996a7a0616 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/moduleparam.h>
 #include <linux/err.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #define PRINT_PREF KERN_INFO "mtd_oobtest: "
index ce17cbe918c5a1e4fe411a51eb7d92eafa22308e..921a85df9196fafa08393da12ffb46407e8fb5d7 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/moduleparam.h>
 #include <linux/err.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #define PRINT_PREF KERN_INFO "mtd_pagetest: "
index 25c5dd03a8373c93a692578ffb1a0724dcd2b33e..7107fccbc7dec049b72585e1ab38a4f330145ea9 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/moduleparam.h>
 #include <linux/err.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #define PRINT_PREF KERN_INFO "mtd_readtest: "
index 7fbb51d4eabec7897811265d0fba5ee0e2ee1369..56ca62bb96bf5e14e0a2a60a624717900b0033d7 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/moduleparam.h>
 #include <linux/err.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #define PRINT_PREF KERN_INFO "mtd_speedtest: "
index a99d3cd737d82caf30ffcce266bebdd56fa9e0f5..3854afec56d0575b65d00c824d898c2347d69529 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/moduleparam.h>
 #include <linux/err.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/vmalloc.h>
 
index 5b889724268ed020a04fcf0d9732aa6daf9743fe..700237a3d120ecc2169a0329eedc42c8cf2cec0d 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/moduleparam.h>
 #include <linux/err.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #define PRINT_PREF KERN_INFO "mtd_subpagetest: "
index 631a0ab3a33c506ef575fff3b5e5fd1769f3e6f6..5c6c3d2489014960056a5f27916a8c2924810549 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/moduleparam.h>
 #include <linux/err.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #define PRINT_PREF KERN_INFO "mtd_torturetest: "
index fad40aa6f099c3070c64d8ba9c7321e20fcb88db..55c726dde9427838a8ab6501b32f74acd18a43a1 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/kthread.h>
 #include <linux/reboot.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include "ubi.h"
 
 /* Maximum length of the 'mtd=' parameter */
index 111ea41c4ecd7aa956be1f21c26d775dc68270e4..72ebb3f06b86b835658870247cdf582b61724704 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <linux/module.h>
 #include <linux/stat.h>
+#include <linux/slab.h>
 #include <linux/ioctl.h>
 #include <linux/capability.h>
 #include <linux/uaccess.h>
index b5e478fa26612b188aa664541503457b2e58d2af..9aa81584c8a29dc4afbbba437613c85b51f60ca8 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <linux/err.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/math64.h>
 #include <linux/module.h>
index b4ecc84c75490dea7405dea6198b3e1614339585..533b1a4b9af16bc2df1d7153b7d51ea80e6e8d06 100644 (file)
@@ -88,6 +88,7 @@
 
 #include <linux/crc32.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include "ubi.h"
 
 #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
index 1361574e2b00157bb2ab98fcc1be6254b1e002f9..17f287decc36dfba8a291122bda31a5e44d4c5f2 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/namei.h>
 #include <linux/fs.h>
 #include <asm/div64.h>
index 594184bbd56a816526129d432a9522306ac92e70..dc5f688699dad6ab3db196e684092a495d7cfb09 100644 (file)
@@ -41,6 +41,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/crc32.h>
 #include <linux/math64.h>
 #include "ubi.h"
index 1af08178defd57bc346f9056f57f7b5816bba9ff..5176d4886518fa12a9b2ac5bab24e986484ce543 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/fs.h>
 #include <linux/cdev.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
 #include <linux/notifier.h>
index ab64cb56df6e11c3bce686035bc5ac34251a6374..e42afab9a9fe2c290585a0f3111ca2543581a7ee 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/err.h>
 #include <linux/math64.h>
+#include <linux/slab.h>
 #include "ubi.h"
 
 #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
index 40044028d6824e217a6e5f5cbe9e1ea232a291f8..cd90ff3b76b139b5d8971dbc537da3cd6614d4dc 100644 (file)
@@ -58,6 +58,7 @@
 
 #include <linux/crc32.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <asm/div64.h>
 #include "ubi.h"
 
index b6de7b1e2a5cbaeff1ae9caf47b13836e4f63244..3ea42ff176577900c734b5e9d7bbd67973a1d324 100644 (file)
@@ -117,7 +117,6 @@ static const char version[] =
 #include <linux/fcntl.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/spinlock.h>
index 04b5bba19021c8c93f340b0aa814dc93e3305a60..29b8d1d63bdeacdfb6cc7b432590216a448ab7e5 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/errno.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/spinlock.h>
 #include <linux/ethtool.h>
 #include <linux/delay.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
index 77cf0901a441146b99292755353d25bfd50222ae..b32b7a1710b735dd3a074d4073baf94b3256b301 100644 (file)
@@ -58,7 +58,6 @@ static const char version[] =
 #include <linux/etherdevice.h>
 #include <linux/if_ether.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
 
index 902435a7646664e61aa870656dcc446c85b26a67..ab9bb3c520020f3a047181c58f957aadddd58f7a 100644 (file)
@@ -76,7 +76,6 @@
 #include <linux/interrupt.h>
 #include <linux/errno.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
index 1e898b1c80682ab190434b3f02cb82dca55332d6..2e17837be546b2d5f0a90e7984ae80a4fc15ea6c 100644 (file)
@@ -65,7 +65,6 @@ static int max_interrupt_work = 20;
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/etherdevice.h>
 #include <linux/interrupt.h>
index beed4fa10c6e69662057c83ee5d55912f50c1782..1719079cc498f86c0289e904c3f54ce16fcbf824 100644 (file)
@@ -99,7 +99,6 @@
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/mca-legacy.h>
index f965431f4924f16b6599cb52e8c504460651a7df..5f92fdbe66e2d3d43ab79f839e408adfd3978c6e 100644 (file)
@@ -77,7 +77,6 @@ static int vortex_debug = 1;
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/mii.h>
@@ -90,6 +89,7 @@ static int vortex_debug = 1;
 #include <linux/eisa.h>
 #include <linux/bitops.h>
 #include <linux/jiffies.h>
+#include <linux/gfp.h>
 #include <asm/irq.h>                   /* For nr_irqs only. */
 #include <asm/io.h>
 #include <asm/uaccess.h>
index 4e9a5a20b6a671941c0f4dfb5d1a627bf50b0f52..500e135723bd0f8ab4f0d031eba8db02f2d03c30 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/ioport.h>
 #include <linux/in.h>
 #include <linux/route.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/skbuff.h>
 #include <asm/irq.h>
index 3d4406b1665814b64b31d06e9d29eba20f9b459d..a09e6ce3eaa0a66f12b6efd93652bf8a2b2b2e23 100644 (file)
@@ -64,6 +64,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/ethtool.h>
+#include <linux/gfp.h>
 #include <linux/mii.h>
 #include <linux/if_vlan.h>
 #include <linux/crc32.h>
index b4efc913978bb2330cc1040519d52cbcaad01fa4..f0d23de3296752e05fb4f0deeba538ff0d90e0c8 100644 (file)
 #include <linux/crc32.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
+#include <linux/gfp.h>
 #include <asm/irq.h>
 
 #define RTL8139_DRIVER_NAME   DRV_NAME " Fast Ethernet driver " DRV_VERSION
@@ -1943,7 +1944,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
                netif_dbg(tp, rx_status, dev, "%s() status %04x, size %04x, cur %04x\n",
                          __func__, rx_status, rx_size, cur_rx);
 #if RTL8139_DEBUG > 2
-               print_dump_hex(KERN_DEBUG, "Frame contents: ",
+               print_hex_dump(KERN_DEBUG, "Frame contents: ",
                               DUMP_PREFIX_OFFSET, 16, 1,
                               &rx_ring[ring_offset], 70, true);
 #endif
index f94d17d78bb0a6145d66389870dd0dfd1c8078ec..56e68db488610d4375445481c53bc1a189e9de86 100644 (file)
@@ -45,7 +45,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
@@ -53,6 +52,7 @@
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
index 0ba5b8e50a7cde9fba5ba976e656682dedfa2164..7b832c727f873b6964b1faa1c121a73796b113e4 100644 (file)
@@ -2582,6 +2582,31 @@ config CHELSIO_T3
          To compile this driver as a module, choose M here: the module
          will be called cxgb3.
 
+config CHELSIO_T4_DEPENDS
+       tristate
+       depends on PCI && INET
+       default y
+
+config CHELSIO_T4
+       tristate "Chelsio Communications T4 Ethernet support"
+       depends on CHELSIO_T4_DEPENDS
+       select FW_LOADER
+       select MDIO
+       help
+         This driver supports Chelsio T4-based gigabit and 10Gb Ethernet
+         adapters.
+
+         For general information about Chelsio and our products, visit
+         our website at <http://www.chelsio.com>.
+
+         For customer support, please visit our customer support page at
+         <http://www.chelsio.com/support.htm>.
+
+         Please send feedback to <linux-bugs@chelsio.com>.
+
+         To compile this driver as a module choose M here; the module
+         will be called cxgb4.
+
 config EHEA
        tristate "eHEA Ethernet support"
        depends on IBMEBUS && INET && SPARSEMEM
index 478886234c285dd43ff082ab2d170c469df89233..12b280afdd5186216254b82c6b0f481e221de129 100644 (file)
@@ -19,6 +19,7 @@ obj-$(CONFIG_IXGB) += ixgb/
 obj-$(CONFIG_IP1000) += ipg.o
 obj-$(CONFIG_CHELSIO_T1) += chelsio/
 obj-$(CONFIG_CHELSIO_T3) += cxgb3/
+obj-$(CONFIG_CHELSIO_T4) += cxgb4/
 obj-$(CONFIG_EHEA) += ehea/
 obj-$(CONFIG_CAN) += can/
 obj-$(CONFIG_BONDING) += bonding/
@@ -272,6 +273,7 @@ obj-$(CONFIG_USB_RTL8150)       += usb/
 obj-$(CONFIG_USB_HSO)          += usb/
 obj-$(CONFIG_USB_USBNET)        += usb/
 obj-$(CONFIG_USB_ZD1201)        += usb/
+obj-$(CONFIG_USB_IPHETH)        += usb/
 
 obj-y += wireless/
 obj-$(CONFIG_NET_TULIP) += tulip/
index bd4d829eca129cc93acb5f5f2c20728a3105a471..a8f0512bad38a0035d92f934670f2765a47a5537 100644 (file)
@@ -46,7 +46,6 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
@@ -675,6 +674,7 @@ static struct zorro_device_id a2065_zorro_tbl[] __devinitdata = {
        { ZORRO_PROD_AMERISTAR_A2065 },
        { 0 }
 };
+MODULE_DEVICE_TABLE(zorro, a2065_zorro_tbl);
 
 static struct zorro_driver a2065_driver = {
        .name           = "a2065",
index 4ae750ef1e104c28991df24453b9bcc492820e3a..97a3dfd94dfa4878dc84c28ce0d1e710e46a816d 100644 (file)
@@ -67,6 +67,7 @@
 #include <linux/highmem.h>
 #include <linux/sockios.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 #include <linux/if_vlan.h>
index b8a59d255b49882313069d020e980b92db14899b..8d58f0a8f42f74f16fa06a388aaf80a4434a557d 100644 (file)
@@ -73,7 +73,6 @@ Revision History:
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/compiler.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
index 73b38c204eb91872df4c16e0bbebf2acac3fe052..6f8d6206b5c483a6bbac6102a57a0a96813bcb59 100644 (file)
@@ -56,7 +56,6 @@ static const char *version =
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/init.h>
index eb0448b03f413d10620c93b06310b98318df7634..79636ee35829f60fff841a677db4065bd5231064 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/ip.h>
 #include <linux/atalk.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 #include <net/route.h>
 #include <asm/uaccess.h>
 
index 8ea4ec705bef1a1f9934801f451d678d023c3f7c..6af65b656f31e7e6e64a7234a53e385bc23168a3 100644 (file)
@@ -215,7 +215,6 @@ static int dma;
 #include <linux/ioport.h>
 #include <linux/spinlock.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -228,6 +227,7 @@ static int dma;
 #include <linux/timer.h>
 #include <linux/atalk.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/dma.h>
index 8ea9c7545c12b815dc899ec64e00de1e56d95c59..705e6ce2eb90b9debb4e635af396ddfdbb53a594 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/if_arp.h>
 #include <net/arp.h>
index e6afab2455b1ebe1e5cf30f95f23a14d091544ef..9efbbbae47ca966485474d405de869bebf758f8c 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/bootmem.h>
index 66bcbbb6babc057480676a4b413419b016681b8c..355797f7004808938ef9684df1693457c5b0a7ca 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/if_arp.h>
 #include <net/arp.h>
index db08fc24047a5b569a3f0e411b1cafea435cd5e2..0402da30a4ed22c9781a051a2b65cda98767bae2 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
index b68e1eb405ff4d4622c59ef453fc9ecb0b608fab..2c712af6c2653ba4de8694dae5b962cfb1a523ee 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
 #include <linux/init.h>
index 0a74f21409c5c91a7362ac9aa78460ba30c5dc66..c9e459400ff967dca9a6561d0f3395ed96595780 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
index 28dea518d554bcca703171f5472c30699c214438..4cb401813b7e7ec9af98ec10334ec8a99b53069f 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/bootmem.h>
index 112e230cb13d22d46f6c7d2bc38db1075c9ddb94..f3b46f71e293d9ac7bb39dda6bd0a2937a1452cd 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/arcdevice.h>
 
index 06f8fa2f8f2fb90b0317bf02cdacb3476a2823c7..f81db4070a574500172fa4dd5521859cc6e063e3 100644 (file)
@@ -24,6 +24,7 @@
  * **********************
  */
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/if_arp.h>
 #include <net/arp.h>
index 745530651c454c3fd25ab85313e90e40b69624a9..b71431aae0846ee8cb69101974f341246265fe59 100644 (file)
@@ -23,6 +23,7 @@
  *
  * **********************
  */
+#include <linux/gfp.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/if_arp.h>
index 08d8be47dae00c8bd1859d1765c86571da4e816c..4b30a46486e2561333c58b1280b324abd286ad70 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/interrupt.h>
@@ -146,6 +145,7 @@ static struct zorro_device_id ariadne_zorro_tbl[] __devinitdata = {
     { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE },
     { 0 }
 };
+MODULE_DEVICE_TABLE(zorro, ariadne_zorro_tbl);
 
 static struct zorro_driver ariadne_driver = {
     .name      = "ariadne",
index 8b23d5a175bfed5581541f5f8da590cc3190352f..aed5b5479b505d1268bc31063edb1c40ba27bd02 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/ethtool.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
index bf72d57a0afdab7c8f48467d9b7d664935ea8144..cd17d09f385cfc60d5e70eb555672e9b0c3b55d6 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 
@@ -310,11 +311,6 @@ err:
                processed++;
        }
 
-       if (processed) {
-               wrw(ep, REG_RXDENQ, processed);
-               wrw(ep, REG_RXSTSENQ, processed);
-       }
-
        return processed;
 }
 
@@ -349,6 +345,11 @@ poll_some_more:
                        goto poll_some_more;
        }
 
+       if (rx) {
+               wrw(ep, REG_RXDENQ, rx);
+               wrw(ep, REG_RXSTSENQ, rx);
+       }
+
        return rx;
 }
 
index f52f668c49bfae5fcf526d299f9368661dd0d32c..4af235d41fda656990a7a280976ecd6e477d2a49 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
index 6e2ae1d06df16c54b6aaaf129c3b8a339fb42315..6be8b098b8b48b58be55df6aaf529dabee07decc 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/kernel.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <mach/npe.h>
 #include <mach/qmgr.h>
 
index a1d4188c430b6d1ecc321482bba6f46736e88b4f..84f8a8f73802f4b6b54bbc51c3665a146185f102 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/platform_device.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 
@@ -449,11 +450,10 @@ ks8695_rx_irq(int irq, void *dev_id)
 }
 
 /**
- *     ks8695_rx - Receive packets  called by NAPI poll method
+ *     ks8695_rx - Receive packets called by NAPI poll method
  *     @ksp: Private data for the KS8695 Ethernet
- *     @budget: The max packets would be receive
+ *     @budget: Number of packets allowed to process
  */
-
 static int ks8695_rx(struct ks8695_priv *ksp, int budget)
 {
        struct net_device *ndev = ksp->ndev;
@@ -461,7 +461,6 @@ static int ks8695_rx(struct ks8695_priv *ksp, int budget)
        int buff_n;
        u32 flags;
        int pktlen;
-       int last_rx_processed = -1;
        int received = 0;
 
        buff_n = ksp->next_rx_desc_read;
@@ -471,6 +470,7 @@ static int ks8695_rx(struct ks8695_priv *ksp, int budget)
                                        cpu_to_le32(RDES_OWN)))) {
                        rmb();
                        flags = le32_to_cpu(ksp->rx_ring[buff_n].status);
+
                        /* Found an SKB which we own, this means we
                         * received a packet
                         */
@@ -533,23 +533,18 @@ rx_failure:
                        ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN);
 rx_finished:
                        received++;
-                       /* And note this as processed so we can start
-                        * from here next time
-                        */
-                       last_rx_processed = buff_n;
                        buff_n = (buff_n + 1) & MAX_RX_DESC_MASK;
-                       /*And note which RX descriptor we last did */
-                       if (likely(last_rx_processed != -1))
-                               ksp->next_rx_desc_read =
-                                       (last_rx_processed + 1) &
-                                       MAX_RX_DESC_MASK;
        }
+
+       /* And note which RX descriptor we last did */
+       ksp->next_rx_desc_read = buff_n;
+
        /* And refill the buffers */
        ks8695_refill_rxbuffers(ksp);
 
-       /* Kick the RX DMA engine, in case it became
-        *  suspended */
+       /* Kick the RX DMA engine, in case it became suspended */
        ks8695_writereg(ksp, KS8695_DRSC, 0);
+
        return received;
 }
 
index febd813c916d06474b05b55b861b0f136f19dacc..f7c9ca1dfb17b67664a7656ef2d74bf1105e5efa 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/ethtool.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/gfp.h>
 
 #define DRV_MODULE_NAME                "w90p910-emc"
 #define DRV_MODULE_VERSION     "0.1"
index 309843ab886925e7a1a1fe3b745d86de01824bd2..10a20fb9ae6518f808232fd5439519cceffc9d4b 100644 (file)
@@ -47,7 +47,6 @@
 #include <linux/ioport.h>
 #include <linux/in.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
index 280cfff48b49fc91160276c3e31e33c55a18ac00..a8686bfec7a18c7c7537308b73750635aef33628 100644 (file)
@@ -53,7 +53,6 @@ static char version[] = "atarilance.c: v1.3 04/04/96 "
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
index 61a0f2ff11e98437057711aebafea9797a22a93f..32339243d61f84dd4f644cbd04f033605ac634ba 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
+#include <linux/slab.h>
 
 #include "atl1c.h"
 
index a76006c1bc6ba46e65a482fa80b0363338844150..ffd696ee7c8ed5ebc13e53438282424c24049317 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
+#include <linux/slab.h>
 
 #include "atl1e.h"
 
index 9ba547069db3c44d13005532e550837ea1bb8350..0ebd8208f606afdaf0f387ad3353ccb7b3d958e8 100644 (file)
@@ -84,7 +84,7 @@
 
 #define ATLX_DRIVER_VERSION "2.1.3"
 MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \
-       Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
+Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(ATLX_DRIVER_VERSION);
 
index 7061d7108f08b8cc6e1e1a293a63c93718319f4f..54662f24f9bb0587b841e43776ae0aa2a426bbcf 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/pci_ids.h>
 #include <linux/pm.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/tcp.h>
index 6ad16205dc1781cfcb9c760246b56020b4a8d166..55039d44dc474545062e942a39b0b1ef46b4cb03 100644 (file)
@@ -129,7 +129,6 @@ static int xcvr[NUM_UNITS];                         /* The data transfer mode. */
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/init.h>
index 1dd4403247ca02d972fdd0f9e2a3651c862a5ce7..b718dc60afc4114783c13697e88787f31077d94e 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/eeprom_93cx6.h>
+#include <linux/slab.h>
 
 #include <net/ax88796.h>
 
index 332c60356285688fe7807b0f692fcce9a9c153ff..69d9f3d368aee82a817f6d5645df275a9f2497dc 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 #include <linux/ssb/ssb.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
index 8cdcab7655c0751c70aaf93b74ca48982b4f3936..17460aba3baee4614e41b4222f131336580df8a5 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/ethtool.h>
 #include <linux/crc32.h>
index 8f0752553681f6c2df21f559f055c9a907df2651..56387b191c963aed41549412b7f1697f72ac7424 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #include "be_hw.h"
 
index c59215361f4ee29a2a265f5277a40c05b5e2c0ef..d0ef4ac987cde52db2ecb24e2144c43d1339c997 100644 (file)
@@ -673,7 +673,7 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
                        OPCODE_COMMON_MCC_CREATE, sizeof(*req));
 
-       req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
+       req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
 
        AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
        AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
@@ -1464,8 +1464,8 @@ int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
 
        req->params.op_type = cpu_to_le32(IMG_TYPE_REDBOOT);
        req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT);
-       req->params.offset = offset;
-       req->params.data_buf_size = 0x4;
+       req->params.offset = cpu_to_le32(offset);
+       req->params.data_buf_size = cpu_to_le32(0x4);
 
        status = be_mcc_notify_wait(adapter);
        if (!status)
index 9560d48944ab526a49737b6fcfdb23f668e8af20..51e1065e78977df6f27a06eaf58dcdba64da5502 100644 (file)
@@ -490,7 +490,7 @@ be_test_ddr_dma(struct be_adapter *adapter)
 {
        int ret, i;
        struct be_dma_mem ddrdma_cmd;
-       u64 pattern[2] = {0x5a5a5a5a5a5a5a5a, 0xa5a5a5a5a5a5a5a5};
+       u64 pattern[2] = {0x5a5a5a5a5a5a5a5aULL, 0xa5a5a5a5a5a5a5a5ULL};
 
        ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test);
        ddrdma_cmd.va = pci_alloc_consistent(adapter->pdev, ddrdma_cmd.size,
index 43e8032f9236f5e27809aba771434c76550ef89c..ec6ace802256087c4bd310c4669c48fc919999ae 100644 (file)
@@ -807,7 +807,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
                        return;
                }
                vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp);
-               vid = be16_to_cpu(vid);
+               vid = swab16(vid);
                vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, vid);
        } else {
                netif_receive_skb(skb);
@@ -884,7 +884,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
                napi_gro_frags(&eq_obj->napi);
        } else {
                vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp);
-               vid = be16_to_cpu(vid);
+               vid = swab16(vid);
 
                if (!adapter->vlan_grp || adapter->vlans_added == 0)
                        return;
@@ -1855,7 +1855,7 @@ static bool be_flash_redboot(struct be_adapter *adapter,
        p += crc_offset;
 
        status = be_cmd_get_flash_crc(adapter, flashed_crc,
-                       (img_start + image_size - 4));
+                       (image_size - 4));
        if (status) {
                dev_err(&adapter->pdev->dev,
                "could not get crc from flash, not flashing redboot\n");
@@ -1991,7 +1991,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
        struct flash_file_hdr_g3 *fhdr3;
        struct image_hdr *img_hdr_ptr = NULL;
        struct be_dma_mem flash_cmd;
-       int status, i = 0;
+       int status, i = 0, num_imgs = 0;
        const u8 *p;
 
        strcpy(fw_file, func);
@@ -2017,15 +2017,14 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
        if ((adapter->generation == BE_GEN3) &&
                        (get_ufigen_type(fhdr) == BE_GEN3)) {
                fhdr3 = (struct flash_file_hdr_g3 *) fw->data;
-               for (i = 0; i < fhdr3->num_imgs; i++) {
+               num_imgs = le32_to_cpu(fhdr3->num_imgs);
+               for (i = 0; i < num_imgs; i++) {
                        img_hdr_ptr = (struct image_hdr *) (fw->data +
                                        (sizeof(struct flash_file_hdr_g3) +
-                                       i * sizeof(struct image_hdr)));
-                       if (img_hdr_ptr->imageid == 1) {
-                               status = be_flash_data(adapter, fw,
-                                               &flash_cmd, fhdr3->num_imgs);
-                       }
-
+                                        i * sizeof(struct image_hdr)));
+                       if (le32_to_cpu(img_hdr_ptr->imageid) == 1)
+                               status = be_flash_data(adapter, fw, &flash_cmd,
+                                                       num_imgs);
                }
        } else if ((adapter->generation == BE_GEN2) &&
                        (get_ufigen_type(fhdr) == BE_GEN2)) {
index 119468e76323de626291e3d0af96790fc9907f5b..598b007f1991dfac42c54bd0e263f2b1694176cc 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/crc32.h>
 #include <linux/bitrev.h>
 #include <linux/ethtool.h>
+#include <linux/slab.h>
 #include <asm/prom.h>
 #include <asm/dbdma.h>
 #include <asm/io.h>
index 381887ba677c36b39e422e7f76273a5dbfa4f2ff..ac90a3828f69fd3f56efd3443a785b15af0ffb1e 100644 (file)
@@ -58,8 +58,8 @@
 #include "bnx2_fw.h"
 
 #define DRV_MODULE_NAME                "bnx2"
-#define DRV_MODULE_VERSION     "2.0.8"
-#define DRV_MODULE_RELDATE     "Feb 15, 2010"
+#define DRV_MODULE_VERSION     "2.0.9"
+#define DRV_MODULE_RELDATE     "April 27, 2010"
 #define FW_MIPS_FILE_06                "bnx2/bnx2-mips-06-5.0.0.j6.fw"
 #define FW_RV2P_FILE_06                "bnx2/bnx2-rv2p-06-5.0.0.j3.fw"
 #define FW_MIPS_FILE_09                "bnx2/bnx2-mips-09-5.0.0.j9.fw"
@@ -246,6 +246,8 @@ static const struct flash_spec flash_5709 = {
 
 MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
 
+static void bnx2_init_napi(struct bnx2 *bp);
+
 static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr)
 {
        u32 diff;
@@ -649,9 +651,10 @@ bnx2_napi_enable(struct bnx2 *bp)
 }
 
 static void
-bnx2_netif_stop(struct bnx2 *bp)
+bnx2_netif_stop(struct bnx2 *bp, bool stop_cnic)
 {
-       bnx2_cnic_stop(bp);
+       if (stop_cnic)
+               bnx2_cnic_stop(bp);
        if (netif_running(bp->dev)) {
                int i;
 
@@ -669,14 +672,15 @@ bnx2_netif_stop(struct bnx2 *bp)
 }
 
 static void
-bnx2_netif_start(struct bnx2 *bp)
+bnx2_netif_start(struct bnx2 *bp, bool start_cnic)
 {
        if (atomic_dec_and_test(&bp->intr_sem)) {
                if (netif_running(bp->dev)) {
                        netif_tx_wake_all_queues(bp->dev);
                        bnx2_napi_enable(bp);
                        bnx2_enable_int(bp);
-                       bnx2_cnic_start(bp);
+                       if (start_cnic)
+                               bnx2_cnic_start(bp);
                }
        }
 }
@@ -4757,8 +4761,12 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
                rc = bnx2_alloc_bad_rbuf(bp);
        }
 
-       if (bp->flags & BNX2_FLAG_USING_MSIX)
+       if (bp->flags & BNX2_FLAG_USING_MSIX) {
                bnx2_setup_msix_tbl(bp);
+               /* Prevent MSIX table reads and write from timing out */
+               REG_WR(bp, BNX2_MISC_ECO_HW_CTL,
+                       BNX2_MISC_ECO_HW_CTL_LARGE_GRC_TMOUT_EN);
+       }
 
        return rc;
 }
@@ -6197,6 +6205,7 @@ bnx2_open(struct net_device *dev)
        bnx2_disable_int(bp);
 
        bnx2_setup_int_mode(bp, disable_msi);
+       bnx2_init_napi(bp);
        bnx2_napi_enable(bp);
        rc = bnx2_alloc_mem(bp);
        if (rc)
@@ -6270,12 +6279,12 @@ bnx2_reset_task(struct work_struct *work)
                return;
        }
 
-       bnx2_netif_stop(bp);
+       bnx2_netif_stop(bp, true);
 
        bnx2_init_nic(bp, 1);
 
        atomic_set(&bp->intr_sem, 1);
-       bnx2_netif_start(bp);
+       bnx2_netif_start(bp, true);
        rtnl_unlock();
 }
 
@@ -6317,7 +6326,7 @@ bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
        struct bnx2 *bp = netdev_priv(dev);
 
        if (netif_running(dev))
-               bnx2_netif_stop(bp);
+               bnx2_netif_stop(bp, false);
 
        bp->vlgrp = vlgrp;
 
@@ -6328,7 +6337,7 @@ bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
        if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
                bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1);
 
-       bnx2_netif_start(bp);
+       bnx2_netif_start(bp, false);
 }
 #endif
 
@@ -7048,9 +7057,9 @@ bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
        bp->stats_ticks &= BNX2_HC_STATS_TICKS_HC_STAT_TICKS;
 
        if (netif_running(bp->dev)) {
-               bnx2_netif_stop(bp);
+               bnx2_netif_stop(bp, true);
                bnx2_init_nic(bp, 0);
-               bnx2_netif_start(bp);
+               bnx2_netif_start(bp, true);
        }
 
        return 0;
@@ -7080,7 +7089,7 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
                /* Reset will erase chipset stats; save them */
                bnx2_save_stats(bp);
 
-               bnx2_netif_stop(bp);
+               bnx2_netif_stop(bp, true);
                bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
                bnx2_free_skbs(bp);
                bnx2_free_mem(bp);
@@ -7108,7 +7117,7 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
                        bnx2_setup_cnic_irq_info(bp);
                mutex_unlock(&bp->cnic_lock);
 #endif
-               bnx2_netif_start(bp);
+               bnx2_netif_start(bp, true);
        }
        return 0;
 }
@@ -7361,7 +7370,7 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
        if (etest->flags & ETH_TEST_FL_OFFLINE) {
                int i;
 
-               bnx2_netif_stop(bp);
+               bnx2_netif_stop(bp, true);
                bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_DIAG);
                bnx2_free_skbs(bp);
 
@@ -7380,7 +7389,7 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
                        bnx2_shutdown_chip(bp);
                else {
                        bnx2_init_nic(bp, 1);
-                       bnx2_netif_start(bp);
+                       bnx2_netif_start(bp, true);
                }
 
                /* wait for link up */
@@ -7643,9 +7652,11 @@ poll_bnx2(struct net_device *dev)
        int i;
 
        for (i = 0; i < bp->irq_nvecs; i++) {
-               disable_irq(bp->irq_tbl[i].vector);
-               bnx2_interrupt(bp->irq_tbl[i].vector, &bp->bnx2_napi[i]);
-               enable_irq(bp->irq_tbl[i].vector);
+               struct bnx2_irq *irq = &bp->irq_tbl[i];
+
+               disable_irq(irq->vector);
+               irq->handler(irq->vector, &bp->bnx2_napi[i]);
+               enable_irq(irq->vector);
        }
 }
 #endif
@@ -8207,7 +8218,7 @@ bnx2_init_napi(struct bnx2 *bp)
 {
        int i;
 
-       for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
+       for (i = 0; i < bp->irq_nvecs; i++) {
                struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
                int (*poll)(struct napi_struct *, int);
 
@@ -8276,7 +8287,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        dev->ethtool_ops = &bnx2_ethtool_ops;
 
        bp = netdev_priv(dev);
-       bnx2_init_napi(bp);
 
        pci_set_drvdata(pdev, dev);
 
@@ -8373,7 +8383,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state)
                return 0;
 
        flush_scheduled_work();
-       bnx2_netif_stop(bp);
+       bnx2_netif_stop(bp, true);
        netif_device_detach(dev);
        del_timer_sync(&bp->timer);
        bnx2_shutdown_chip(bp);
@@ -8395,7 +8405,7 @@ bnx2_resume(struct pci_dev *pdev)
        bnx2_set_power_state(bp, PCI_D0);
        netif_device_attach(dev);
        bnx2_init_nic(bp, 1);
-       bnx2_netif_start(bp);
+       bnx2_netif_start(bp, true);
        return 0;
 }
 
@@ -8422,7 +8432,7 @@ static pci_ers_result_t bnx2_io_error_detected(struct pci_dev *pdev,
        }
 
        if (netif_running(dev)) {
-               bnx2_netif_stop(bp);
+               bnx2_netif_stop(bp, true);
                del_timer_sync(&bp->timer);
                bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET);
        }
@@ -8479,7 +8489,7 @@ static void bnx2_io_resume(struct pci_dev *pdev)
 
        rtnl_lock();
        if (netif_running(dev))
-               bnx2_netif_start(bp);
+               bnx2_netif_start(bp, true);
 
        netif_device_attach(dev);
        rtnl_unlock();
index ed785a30e98bbcadaa0de666d6763c0608f221fc..6c042a72d6ccb0ef460bf5ad0700e3aedf7ff7ed 100644 (file)
@@ -893,7 +893,6 @@ static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp)
        u16 prod;
        u16 cons;
 
-       barrier(); /* Tell compiler that prod and cons can change */
        prod = fp->tx_bd_prod;
        cons = fp->tx_bd_cons;
 
@@ -963,7 +962,7 @@ static int bnx2x_tx_int(struct bnx2x_fastpath *fp)
         * start_xmit() will miss it and cause the queue to be stopped
         * forever.
         */
-       smp_wmb();
+       smp_mb();
 
        /* TBD need a thresh? */
        if (unlikely(netif_tx_queue_stopped(txq))) {
@@ -11429,9 +11428,12 @@ static netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) {
                netif_tx_stop_queue(txq);
-               /* We want bnx2x_tx_int to "see" the updated tx_bd_prod
-                  if we put Tx into XOFF state. */
+
+               /* paired memory barrier is in bnx2x_tx_int(), we have to keep
+                * ordering of set_bit() in netif_tx_stop_queue() and read of
+                * fp->bd_tx_cons */
                smp_mb();
+
                fp->eth_q_stats.driver_xoff++;
                if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
                        netif_tx_wake_queue(txq);
index 430c02267d7e9ec26d3c8b59922d919fc5fedb97..0075514bf32fc1d78e15bab0a717c91f945227d6 100644 (file)
@@ -1235,6 +1235,11 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
                        write_lock_bh(&bond->curr_slave_lock);
                }
        }
+
+       /* resend IGMP joins since all were sent on curr_active_slave */
+       if (bond->params.mode == BOND_MODE_ROUNDROBIN) {
+               bond_resend_igmp_join_requests(bond);
+       }
 }
 
 /**
@@ -4138,22 +4143,41 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
        struct bonding *bond = netdev_priv(bond_dev);
        struct slave *slave, *start_at;
        int i, slave_no, res = 1;
+       struct iphdr *iph = ip_hdr(skb);
 
        read_lock(&bond->lock);
 
        if (!BOND_IS_OK(bond))
                goto out;
-
        /*
-        * Concurrent TX may collide on rr_tx_counter; we accept that
-        * as being rare enough not to justify using an atomic op here
+        * Start with the curr_active_slave that joined the bond as the
+        * default for sending IGMP traffic.  For failover purposes one
+        * needs to maintain some consistency for the interface that will
+        * send the join/membership reports.  The curr_active_slave found
+        * will send all of this type of traffic.
         */
-       slave_no = bond->rr_tx_counter++ % bond->slave_cnt;
+       if ((iph->protocol == IPPROTO_IGMP) &&
+           (skb->protocol == htons(ETH_P_IP))) {
 
-       bond_for_each_slave(bond, slave, i) {
-               slave_no--;
-               if (slave_no < 0)
-                       break;
+               read_lock(&bond->curr_slave_lock);
+               slave = bond->curr_active_slave;
+               read_unlock(&bond->curr_slave_lock);
+
+               if (!slave)
+                       goto out;
+       } else {
+               /*
+                * Concurrent TX may collide on rr_tx_counter; we accept
+                * that as being rare enough not to justify using an
+                * atomic op here.
+                */
+               slave_no = bond->rr_tx_counter++ % bond->slave_cnt;
+
+               bond_for_each_slave(bond, slave, i) {
+                       slave_no--;
+                       if (slave_no < 0)
+                               break;
+               }
        }
 
        start_at = slave;
@@ -4426,6 +4450,14 @@ static const struct net_device_ops bond_netdev_ops = {
        .ndo_vlan_rx_kill_vid   = bond_vlan_rx_kill_vid,
 };
 
+static void bond_destructor(struct net_device *bond_dev)
+{
+       struct bonding *bond = netdev_priv(bond_dev);
+       if (bond->wq)
+               destroy_workqueue(bond->wq);
+       free_netdev(bond_dev);
+}
+
 static void bond_setup(struct net_device *bond_dev)
 {
        struct bonding *bond = netdev_priv(bond_dev);
@@ -4446,7 +4478,7 @@ static void bond_setup(struct net_device *bond_dev)
        bond_dev->ethtool_ops = &bond_ethtool_ops;
        bond_set_mode_ops(bond, bond->params.mode);
 
-       bond_dev->destructor = free_netdev;
+       bond_dev->destructor = bond_destructor;
 
        /* Initialize the device options */
        bond_dev->tx_queue_len = 0;
@@ -4518,9 +4550,6 @@ static void bond_uninit(struct net_device *bond_dev)
 
        bond_remove_proc_entry(bond);
 
-       if (bond->wq)
-               destroy_workqueue(bond->wq);
-
        netif_addr_lock_bh(bond_dev);
        bond_mc_list_destroy(bond);
        netif_addr_unlock_bh(bond_dev);
@@ -4932,8 +4961,8 @@ int bond_create(struct net *net, const char *name)
                                bond_setup);
        if (!bond_dev) {
                pr_err("%s: eek! can't alloc netdev!\n", name);
-               res = -ENOMEM;
-               goto out;
+               rtnl_unlock();
+               return -ENOMEM;
        }
 
        dev_net_set(bond_dev, net);
@@ -4942,19 +4971,16 @@ int bond_create(struct net *net, const char *name)
        if (!name) {
                res = dev_alloc_name(bond_dev, "bond%d");
                if (res < 0)
-                       goto out_netdev;
+                       goto out;
        }
 
        res = register_netdevice(bond_dev);
-       if (res < 0)
-               goto out_netdev;
 
 out:
        rtnl_unlock();
+       if (res < 0)
+               bond_destructor(bond_dev);
        return res;
-out_netdev:
-       free_netdev(bond_dev);
-       goto out;
 }
 
 static int __net_init bond_net_init(struct net *net)
index 866905fa4119e5c66d18d56875b7e9525a4713c2..03489864376df7ca060927c3afd3d058b41e088b 100644 (file)
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
 
+#include <asm/bfin_can.h>
 #include <asm/portmux.h>
 
 #define DRV_NAME "bfin_can"
 #define BFIN_CAN_TIMEOUT 100
 #define TX_ECHO_SKB_MAX  1
 
-/*
- * transmit and receive channels
- */
-#define TRANSMIT_CHL            24
-#define RECEIVE_STD_CHL         0
-#define RECEIVE_EXT_CHL         4
-#define RECEIVE_RTR_CHL         8
-#define RECEIVE_EXT_RTR_CHL     12
-#define MAX_CHL_NUMBER          32
-
-/*
- * bfin can registers layout
- */
-struct bfin_can_mask_regs {
-       u16 aml;
-       u16 dummy1;
-       u16 amh;
-       u16 dummy2;
-};
-
-struct bfin_can_channel_regs {
-       u16 data[8];
-       u16 dlc;
-       u16 dummy1;
-       u16 tsv;
-       u16 dummy2;
-       u16 id0;
-       u16 dummy3;
-       u16 id1;
-       u16 dummy4;
-};
-
-struct bfin_can_regs {
-       /*
-        * global control and status registers
-        */
-       u16 mc1;           /* offset 0 */
-       u16 dummy1;
-       u16 md1;           /* offset 4 */
-       u16 rsv1[13];
-       u16 mbtif1;        /* offset 0x20 */
-       u16 dummy2;
-       u16 mbrif1;        /* offset 0x24 */
-       u16 dummy3;
-       u16 mbim1;         /* offset 0x28 */
-       u16 rsv2[11];
-       u16 mc2;           /* offset 0x40 */
-       u16 dummy4;
-       u16 md2;           /* offset 0x44 */
-       u16 dummy5;
-       u16 trs2;          /* offset 0x48 */
-       u16 rsv3[11];
-       u16 mbtif2;        /* offset 0x60 */
-       u16 dummy6;
-       u16 mbrif2;        /* offset 0x64 */
-       u16 dummy7;
-       u16 mbim2;         /* offset 0x68 */
-       u16 rsv4[11];
-       u16 clk;           /* offset 0x80 */
-       u16 dummy8;
-       u16 timing;        /* offset 0x84 */
-       u16 rsv5[3];
-       u16 status;        /* offset 0x8c */
-       u16 dummy9;
-       u16 cec;           /* offset 0x90 */
-       u16 dummy10;
-       u16 gis;           /* offset 0x94 */
-       u16 dummy11;
-       u16 gim;           /* offset 0x98 */
-       u16 rsv6[3];
-       u16 ctrl;          /* offset 0xa0 */
-       u16 dummy12;
-       u16 intr;          /* offset 0xa4 */
-       u16 rsv7[7];
-       u16 esr;           /* offset 0xb4 */
-       u16 rsv8[37];
-
-       /*
-        * channel(mailbox) mask and message registers
-        */
-       struct bfin_can_mask_regs msk[MAX_CHL_NUMBER];    /* offset 0x100 */
-       struct bfin_can_channel_regs chl[MAX_CHL_NUMBER]; /* offset 0x200 */
-};
-
 /*
  * bfin can private data
  */
@@ -163,7 +80,7 @@ static int bfin_can_set_bittiming(struct net_device *dev)
        if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
                timing |= SAM;
 
-       bfin_write16(&reg->clk, clk);
+       bfin_write16(&reg->clock, clk);
        bfin_write16(&reg->timing, timing);
 
        dev_info(dev->dev.parent, "setting CLOCK=0x%04x TIMING=0x%04x\n",
@@ -185,11 +102,11 @@ static void bfin_can_set_reset_mode(struct net_device *dev)
        bfin_write16(&reg->gim, 0);
 
        /* reset can and enter configuration mode */
-       bfin_write16(&reg->ctrl, SRS | CCR);
+       bfin_write16(&reg->control, SRS | CCR);
        SSYNC();
-       bfin_write16(&reg->ctrl, CCR);
+       bfin_write16(&reg->control, CCR);
        SSYNC();
-       while (!(bfin_read16(&reg->ctrl) & CCA)) {
+       while (!(bfin_read16(&reg->control) & CCA)) {
                udelay(10);
                if (--timeout == 0) {
                        dev_err(dev->dev.parent,
@@ -244,7 +161,7 @@ static void bfin_can_set_normal_mode(struct net_device *dev)
        /*
         * leave configuration mode
         */
-       bfin_write16(&reg->ctrl, bfin_read16(&reg->ctrl) & ~CCR);
+       bfin_write16(&reg->control, bfin_read16(&reg->control) & ~CCR);
 
        while (bfin_read16(&reg->status) & CCA) {
                udelay(10);
@@ -726,7 +643,7 @@ static int bfin_can_suspend(struct platform_device *pdev, pm_message_t mesg)
 
        if (netif_running(dev)) {
                /* enter sleep mode */
-               bfin_write16(&reg->ctrl, bfin_read16(&reg->ctrl) | SMR);
+               bfin_write16(&reg->control, bfin_read16(&reg->control) | SMR);
                SSYNC();
                while (!(bfin_read16(&reg->intr) & SMACK)) {
                        udelay(10);
index 904aa369f80e13c0d02a664fa23aee2019246b8d..d0f8c7e67e7d2a738c2716a68f80b4b7a22a21f2 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/can.h>
index f8cc168ec76cd29db433bee4face5726c11bd43a..b39b108318b48cfa584d25a124babe936af1a9ec 100644 (file)
@@ -73,6 +73,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/spi/spi.h>
 #include <linux/uaccess.h>
 
index 87300606abb9db79bb683ca4b92deb3206d456b7..5f53da0bc40ceddc2ce58c8949b536f789b1b15d 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/can.h>
 #include <linux/can/dev.h>
index 6b46a6395f80218a76c1d1c5da70d24ab49b8b5e..4aff4070db96236a90229380cebcf1e2e7f1e53c 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/can.h>
 #include <linux/can/dev.h>
index 33451092b8e8a1c66530686c95577daf770ced61..d800b598ae3d008cfb13149ac098d19c6e0ae25c 100644 (file)
@@ -1006,7 +1006,7 @@ static int ems_usb_probe(struct usb_interface *intf,
 
        netdev = alloc_candev(sizeof(struct ems_usb), MAX_TX_URBS);
        if (!netdev) {
-               dev_err(netdev->dev.parent, "Couldn't alloc candev\n");
+               dev_err(&intf->dev, "ems_usb: Couldn't alloc candev\n");
                return -ENOMEM;
        }
 
@@ -1036,20 +1036,20 @@ static int ems_usb_probe(struct usb_interface *intf,
 
        dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!dev->intr_urb) {
-               dev_err(netdev->dev.parent, "Couldn't alloc intr URB\n");
+               dev_err(&intf->dev, "Couldn't alloc intr URB\n");
                goto cleanup_candev;
        }
 
        dev->intr_in_buffer = kzalloc(INTR_IN_BUFFER_SIZE, GFP_KERNEL);
        if (!dev->intr_in_buffer) {
-               dev_err(netdev->dev.parent, "Couldn't alloc Intr buffer\n");
+               dev_err(&intf->dev, "Couldn't alloc Intr buffer\n");
                goto cleanup_intr_urb;
        }
 
        dev->tx_msg_buffer = kzalloc(CPC_HEADER_SIZE +
                                     sizeof(struct ems_cpc_msg), GFP_KERNEL);
        if (!dev->tx_msg_buffer) {
-               dev_err(netdev->dev.parent, "Couldn't alloc Tx buffer\n");
+               dev_err(&intf->dev, "Couldn't alloc Tx buffer\n");
                goto cleanup_intr_in_buffer;
        }
 
index d124d837ae58c4c1c5de7ce1d6a90d3fc86c5d52..a30b8f480f611f35b56493062ac907c042bdefce 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/if_ether.h>
 #include <linux/can.h>
 #include <linux/can/dev.h>
+#include <linux/slab.h>
 #include <net/rtnetlink.h>
 
 static __initdata const char banner[] =
index 2d11afe4531069ead920b4c8a0d660169cdd57ba..036b2dfb1d40b2c1155d54a34ecfb0ae75056acc 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/mdio.h>
 #include <linux/crc32.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/pci_ids.h>
 
index a6eb30a6e2b98a74cf7060bbbc2e56bcd4f92a67..9e631b9d3948cb9d04e6461c66b23db4f2afe893 100644 (file)
@@ -44,6 +44,7 @@
 #include "suni1x10gexp_regs.h"
 
 #include <linux/crc32.h>
+#include <linux/slab.h>
 
 #define OFFSET(REG_ADDR)    ((REG_ADDR) << 2)
 
index 55d99ca82f8ad5a67785aed9a1ecf684ba404a09..df3a1410696eeb6f53e36a5ed0609f466d27cedf 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/ip.h>
 #include <linux/in.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 
 #include "cpl5_cmd.h"
 #include "sge.h"
index 9781942992e9a77c460cd339592716c0372899b7..4b451a7c03e9191ea7e06ebb46245b87a35ce3ea 100644 (file)
@@ -2334,13 +2334,13 @@ static int cnic_service_bnx2x(void *data, void *status_blk)
        struct cnic_local *cp = dev->cnic_priv;
        u16 prod = cp->kcq_prod_idx & MAX_KCQ_IDX;
 
-       prefetch(cp->status_blk.bnx2x);
-       prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
+       if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags))) {
+               prefetch(cp->status_blk.bnx2x);
+               prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
 
-       if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags)))
                tasklet_schedule(&cp->cnic_irq_task);
-
-       cnic_chk_pkt_rings(cp);
+               cnic_chk_pkt_rings(cp);
+       }
 
        return 0;
 }
index dd24aadb778ca8be8e48c534697468cb324e61b8..61a33914e96f87b4550404247748cf9248305666 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/spinlock.h>
 #include <linux/errno.h>
index b0208e474f7eabaebebc646491e76747b378ba4b..4c38491b8efb02584e9e543a650494641bbd2692 100644 (file)
 #include <linux/ioport.h>
 #include <linux/in.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
index 5248f9e0b2f4c4a934a78cf8209381da57077978..35cd36729155ee18a7dcd44d883890a980c0b87d 100644 (file)
@@ -934,7 +934,7 @@ static struct cphy_ops xaui_direct_ops = {
 int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
                            int phy_addr, const struct mdio_ops *mdio_ops)
 {
-       cphy_init(phy, adapter, MDIO_PRTAD_NONE, &xaui_direct_ops, mdio_ops,
+       cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops,
                  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
                  "10GBASE-CX4");
        return 0;
index 9e3e8750b46a69dcbcead02cb0281c0d4fd084be..e3f1b856649521b1c0c1841254b6e9d21a361305 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/log2.h>
 #include <linux/stringify.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 #include "common.h"
@@ -438,7 +439,7 @@ static void free_irq_resources(struct adapter *adapter)
 static int await_mgmt_replies(struct adapter *adap, unsigned long init_cnt,
                              unsigned long n)
 {
-       int attempts = 5;
+       int attempts = 10;
 
        while (adap->sge.qs[0].rspq.offload_pkts < init_cnt + n) {
                if (!--attempts)
index 9498361119d6747dfdd7190a90982bcc9c8b87f5..c6485b39eb0e630c67a5f91cd683ab7365362928 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <net/neighbour.h>
 #include <linux/notifier.h>
 #include <asm/atomic.h>
index ff1611f90e7aab04436c71d3851708ff51695650..2f3ee721c3e11c7075e327f74e1b4cdde1be1024 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <linux/jhash.h>
+#include <linux/slab.h>
 #include <net/neighbour.h>
 #include "common.h"
 #include "t3cdev.h"
index 67e61b2a8c42332b2b2d678d560111fb134a203c..07d7e7fab3f5683e4189f349973940d9e9a99d9a 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 #include "common.h"
 #include "regs.h"
diff --git a/drivers/net/cxgb4/Makefile b/drivers/net/cxgb4/Makefile
new file mode 100644 (file)
index 0000000..4986674
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Chelsio T4 driver
+#
+
+obj-$(CONFIG_CHELSIO_T4) += cxgb4.o
+
+cxgb4-objs := cxgb4_main.o l2t.o t4_hw.o sge.o
diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h
new file mode 100644 (file)
index 0000000..3d8ff48
--- /dev/null
@@ -0,0 +1,741 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ */
+
+#ifndef __CXGB4_H__
+#define __CXGB4_H__
+
+#include <linux/bitops.h>
+#include <linux/cache.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include "cxgb4_uld.h"
+#include "t4_hw.h"
+
+#define FW_VERSION_MAJOR 1
+#define FW_VERSION_MINOR 1
+#define FW_VERSION_MICRO 0
+
+enum {
+       MAX_NPORTS = 4,     /* max # of ports */
+       SERNUM_LEN = 16,    /* Serial # length */
+       EC_LEN     = 16,    /* E/C length */
+       ID_LEN     = 16,    /* ID length */
+};
+
+enum {
+       MEM_EDC0,
+       MEM_EDC1,
+       MEM_MC
+};
+
+enum dev_master {
+       MASTER_CANT,
+       MASTER_MAY,
+       MASTER_MUST
+};
+
+enum dev_state {
+       DEV_STATE_UNINIT,
+       DEV_STATE_INIT,
+       DEV_STATE_ERR
+};
+
+enum {
+       PAUSE_RX      = 1 << 0,
+       PAUSE_TX      = 1 << 1,
+       PAUSE_AUTONEG = 1 << 2
+};
+
+struct port_stats {
+       u64 tx_octets;            /* total # of octets in good frames */
+       u64 tx_frames;            /* all good frames */
+       u64 tx_bcast_frames;      /* all broadcast frames */
+       u64 tx_mcast_frames;      /* all multicast frames */
+       u64 tx_ucast_frames;      /* all unicast frames */
+       u64 tx_error_frames;      /* all error frames */
+
+       u64 tx_frames_64;         /* # of Tx frames in a particular range */
+       u64 tx_frames_65_127;
+       u64 tx_frames_128_255;
+       u64 tx_frames_256_511;
+       u64 tx_frames_512_1023;
+       u64 tx_frames_1024_1518;
+       u64 tx_frames_1519_max;
+
+       u64 tx_drop;              /* # of dropped Tx frames */
+       u64 tx_pause;             /* # of transmitted pause frames */
+       u64 tx_ppp0;              /* # of transmitted PPP prio 0 frames */
+       u64 tx_ppp1;              /* # of transmitted PPP prio 1 frames */
+       u64 tx_ppp2;              /* # of transmitted PPP prio 2 frames */
+       u64 tx_ppp3;              /* # of transmitted PPP prio 3 frames */
+       u64 tx_ppp4;              /* # of transmitted PPP prio 4 frames */
+       u64 tx_ppp5;              /* # of transmitted PPP prio 5 frames */
+       u64 tx_ppp6;              /* # of transmitted PPP prio 6 frames */
+       u64 tx_ppp7;              /* # of transmitted PPP prio 7 frames */
+
+       u64 rx_octets;            /* total # of octets in good frames */
+       u64 rx_frames;            /* all good frames */
+       u64 rx_bcast_frames;      /* all broadcast frames */
+       u64 rx_mcast_frames;      /* all multicast frames */
+       u64 rx_ucast_frames;      /* all unicast frames */
+       u64 rx_too_long;          /* # of frames exceeding MTU */
+       u64 rx_jabber;            /* # of jabber frames */
+       u64 rx_fcs_err;           /* # of received frames with bad FCS */
+       u64 rx_len_err;           /* # of received frames with length error */
+       u64 rx_symbol_err;        /* symbol errors */
+       u64 rx_runt;              /* # of short frames */
+
+       u64 rx_frames_64;         /* # of Rx frames in a particular range */
+       u64 rx_frames_65_127;
+       u64 rx_frames_128_255;
+       u64 rx_frames_256_511;
+       u64 rx_frames_512_1023;
+       u64 rx_frames_1024_1518;
+       u64 rx_frames_1519_max;
+
+       u64 rx_pause;             /* # of received pause frames */
+       u64 rx_ppp0;              /* # of received PPP prio 0 frames */
+       u64 rx_ppp1;              /* # of received PPP prio 1 frames */
+       u64 rx_ppp2;              /* # of received PPP prio 2 frames */
+       u64 rx_ppp3;              /* # of received PPP prio 3 frames */
+       u64 rx_ppp4;              /* # of received PPP prio 4 frames */
+       u64 rx_ppp5;              /* # of received PPP prio 5 frames */
+       u64 rx_ppp6;              /* # of received PPP prio 6 frames */
+       u64 rx_ppp7;              /* # of received PPP prio 7 frames */
+
+       u64 rx_ovflow0;           /* drops due to buffer-group 0 overflows */
+       u64 rx_ovflow1;           /* drops due to buffer-group 1 overflows */
+       u64 rx_ovflow2;           /* drops due to buffer-group 2 overflows */
+       u64 rx_ovflow3;           /* drops due to buffer-group 3 overflows */
+       u64 rx_trunc0;            /* buffer-group 0 truncated packets */
+       u64 rx_trunc1;            /* buffer-group 1 truncated packets */
+       u64 rx_trunc2;            /* buffer-group 2 truncated packets */
+       u64 rx_trunc3;            /* buffer-group 3 truncated packets */
+};
+
+struct lb_port_stats {
+       u64 octets;
+       u64 frames;
+       u64 bcast_frames;
+       u64 mcast_frames;
+       u64 ucast_frames;
+       u64 error_frames;
+
+       u64 frames_64;
+       u64 frames_65_127;
+       u64 frames_128_255;
+       u64 frames_256_511;
+       u64 frames_512_1023;
+       u64 frames_1024_1518;
+       u64 frames_1519_max;
+
+       u64 drop;
+
+       u64 ovflow0;
+       u64 ovflow1;
+       u64 ovflow2;
+       u64 ovflow3;
+       u64 trunc0;
+       u64 trunc1;
+       u64 trunc2;
+       u64 trunc3;
+};
+
+struct tp_tcp_stats {
+       u32 tcpOutRsts;
+       u64 tcpInSegs;
+       u64 tcpOutSegs;
+       u64 tcpRetransSegs;
+};
+
+struct tp_err_stats {
+       u32 macInErrs[4];
+       u32 hdrInErrs[4];
+       u32 tcpInErrs[4];
+       u32 tnlCongDrops[4];
+       u32 ofldChanDrops[4];
+       u32 tnlTxDrops[4];
+       u32 ofldVlanDrops[4];
+       u32 tcp6InErrs[4];
+       u32 ofldNoNeigh;
+       u32 ofldCongDefer;
+};
+
+struct tp_params {
+       unsigned int ntxchan;        /* # of Tx channels */
+       unsigned int tre;            /* log2 of core clocks per TP tick */
+};
+
+struct vpd_params {
+       unsigned int cclk;
+       u8 ec[EC_LEN + 1];
+       u8 sn[SERNUM_LEN + 1];
+       u8 id[ID_LEN + 1];
+};
+
+struct pci_params {
+       unsigned char speed;
+       unsigned char width;
+};
+
+struct adapter_params {
+       struct tp_params  tp;
+       struct vpd_params vpd;
+       struct pci_params pci;
+
+       unsigned int fw_vers;
+       unsigned int tp_vers;
+       u8 api_vers[7];
+
+       unsigned short mtus[NMTUS];
+       unsigned short a_wnd[NCCTRL_WIN];
+       unsigned short b_wnd[NCCTRL_WIN];
+
+       unsigned char nports;             /* # of ethernet ports */
+       unsigned char portvec;
+       unsigned char rev;                /* chip revision */
+       unsigned char offload;
+
+       unsigned int ofldq_wr_cred;
+};
+
+struct trace_params {
+       u32 data[TRACE_LEN / 4];
+       u32 mask[TRACE_LEN / 4];
+       unsigned short snap_len;
+       unsigned short min_len;
+       unsigned char skip_ofst;
+       unsigned char skip_len;
+       unsigned char invert;
+       unsigned char port;
+};
+
+struct link_config {
+       unsigned short supported;        /* link capabilities */
+       unsigned short advertising;      /* advertised capabilities */
+       unsigned short requested_speed;  /* speed user has requested */
+       unsigned short speed;            /* actual link speed */
+       unsigned char  requested_fc;     /* flow control user has requested */
+       unsigned char  fc;               /* actual link flow control */
+       unsigned char  autoneg;          /* autonegotiating? */
+       unsigned char  link_ok;          /* link up? */
+};
+
+#define FW_LEN16(fw_struct) FW_CMD_LEN16(sizeof(fw_struct) / 16)
+
+enum {
+       MAX_ETH_QSETS = 32,           /* # of Ethernet Tx/Rx queue sets */
+       MAX_OFLD_QSETS = 16,          /* # of offload Tx/Rx queue sets */
+       MAX_CTRL_QUEUES = NCHAN,      /* # of control Tx queues */
+       MAX_RDMA_QUEUES = NCHAN,      /* # of streaming RDMA Rx queues */
+};
+
+enum {
+       MAX_EGRQ = 128,         /* max # of egress queues, including FLs */
+       MAX_INGQ = 64           /* max # of interrupt-capable ingress queues */
+};
+
+struct adapter;
+struct vlan_group;
+struct sge_rspq;
+
+struct port_info {
+       struct adapter *adapter;
+       struct vlan_group *vlan_grp;
+       u16    viid;
+       s16    xact_addr_filt;        /* index of exact MAC address filter */
+       u16    rss_size;              /* size of VI's RSS table slice */
+       s8     mdio_addr;
+       u8     port_type;
+       u8     mod_type;
+       u8     port_id;
+       u8     tx_chan;
+       u8     lport;                 /* associated offload logical port */
+       u8     rx_offload;            /* CSO, etc */
+       u8     nqsets;                /* # of qsets */
+       u8     first_qset;            /* index of first qset */
+       struct link_config link_cfg;
+};
+
+/* port_info.rx_offload flags */
+enum {
+       RX_CSO = 1 << 0,
+};
+
+struct dentry;
+struct work_struct;
+
+enum {                                 /* adapter flags */
+       FULL_INIT_DONE     = (1 << 0),
+       USING_MSI          = (1 << 1),
+       USING_MSIX         = (1 << 2),
+       QUEUES_BOUND       = (1 << 3),
+       FW_OK              = (1 << 4),
+};
+
+struct rx_sw_desc;
+
+struct sge_fl {                     /* SGE free-buffer queue state */
+       unsigned int avail;         /* # of available Rx buffers */
+       unsigned int pend_cred;     /* new buffers since last FL DB ring */
+       unsigned int cidx;          /* consumer index */
+       unsigned int pidx;          /* producer index */
+       unsigned long alloc_failed; /* # of times buffer allocation failed */
+       unsigned long large_alloc_failed;
+       unsigned long starving;
+       /* RO fields */
+       unsigned int cntxt_id;      /* SGE context id for the free list */
+       unsigned int size;          /* capacity of free list */
+       struct rx_sw_desc *sdesc;   /* address of SW Rx descriptor ring */
+       __be64 *desc;               /* address of HW Rx descriptor ring */
+       dma_addr_t addr;            /* bus address of HW ring start */
+};
+
+/* A packet gather list */
+struct pkt_gl {
+       skb_frag_t frags[MAX_SKB_FRAGS];
+       void *va;                         /* virtual address of first byte */
+       unsigned int nfrags;              /* # of fragments */
+       unsigned int tot_len;             /* total length of fragments */
+};
+
+typedef int (*rspq_handler_t)(struct sge_rspq *q, const __be64 *rsp,
+                             const struct pkt_gl *gl);
+
+struct sge_rspq {                   /* state for an SGE response queue */
+       struct napi_struct napi;
+       const __be64 *cur_desc;     /* current descriptor in queue */
+       unsigned int cidx;          /* consumer index */
+       u8 gen;                     /* current generation bit */
+       u8 intr_params;             /* interrupt holdoff parameters */
+       u8 next_intr_params;        /* holdoff params for next interrupt */
+       u8 pktcnt_idx;              /* interrupt packet threshold */
+       u8 uld;                     /* ULD handling this queue */
+       u8 idx;                     /* queue index within its group */
+       int offset;                 /* offset into current Rx buffer */
+       u16 cntxt_id;               /* SGE context id for the response q */
+       u16 abs_id;                 /* absolute SGE id for the response q */
+       __be64 *desc;               /* address of HW response ring */
+       dma_addr_t phys_addr;       /* physical address of the ring */
+       unsigned int iqe_len;       /* entry size */
+       unsigned int size;          /* capacity of response queue */
+       struct adapter *adap;
+       struct net_device *netdev;  /* associated net device */
+       rspq_handler_t handler;
+};
+
+struct sge_eth_stats {              /* Ethernet queue statistics */
+       unsigned long pkts;         /* # of ethernet packets */
+       unsigned long lro_pkts;     /* # of LRO super packets */
+       unsigned long lro_merged;   /* # of wire packets merged by LRO */
+       unsigned long rx_cso;       /* # of Rx checksum offloads */
+       unsigned long vlan_ex;      /* # of Rx VLAN extractions */
+       unsigned long rx_drops;     /* # of packets dropped due to no mem */
+};
+
+struct sge_eth_rxq {                /* SW Ethernet Rx queue */
+       struct sge_rspq rspq;
+       struct sge_fl fl;
+       struct sge_eth_stats stats;
+} ____cacheline_aligned_in_smp;
+
+struct sge_ofld_stats {             /* offload queue statistics */
+       unsigned long pkts;         /* # of packets */
+       unsigned long imm;          /* # of immediate-data packets */
+       unsigned long an;           /* # of asynchronous notifications */
+       unsigned long nomem;        /* # of responses deferred due to no mem */
+};
+
+struct sge_ofld_rxq {               /* SW offload Rx queue */
+       struct sge_rspq rspq;
+       struct sge_fl fl;
+       struct sge_ofld_stats stats;
+} ____cacheline_aligned_in_smp;
+
+struct tx_desc {
+       __be64 flit[8];
+};
+
+struct tx_sw_desc;
+
+struct sge_txq {
+       unsigned int  in_use;       /* # of in-use Tx descriptors */
+       unsigned int  size;         /* # of descriptors */
+       unsigned int  cidx;         /* SW consumer index */
+       unsigned int  pidx;         /* producer index */
+       unsigned long stops;        /* # of times q has been stopped */
+       unsigned long restarts;     /* # of queue restarts */
+       unsigned int  cntxt_id;     /* SGE context id for the Tx q */
+       struct tx_desc *desc;       /* address of HW Tx descriptor ring */
+       struct tx_sw_desc *sdesc;   /* address of SW Tx descriptor ring */
+       struct sge_qstat *stat;     /* queue status entry */
+       dma_addr_t    phys_addr;    /* physical address of the ring */
+};
+
+struct sge_eth_txq {                /* state for an SGE Ethernet Tx queue */
+       struct sge_txq q;
+       struct netdev_queue *txq;   /* associated netdev TX queue */
+       unsigned long tso;          /* # of TSO requests */
+       unsigned long tx_cso;       /* # of Tx checksum offloads */
+       unsigned long vlan_ins;     /* # of Tx VLAN insertions */
+       unsigned long mapping_err;  /* # of I/O MMU packet mapping errors */
+} ____cacheline_aligned_in_smp;
+
+struct sge_ofld_txq {               /* state for an SGE offload Tx queue */
+       struct sge_txq q;
+       struct adapter *adap;
+       struct sk_buff_head sendq;  /* list of backpressured packets */
+       struct tasklet_struct qresume_tsk; /* restarts the queue */
+       u8 full;                    /* the Tx ring is full */
+       unsigned long mapping_err;  /* # of I/O MMU packet mapping errors */
+} ____cacheline_aligned_in_smp;
+
+struct sge_ctrl_txq {               /* state for an SGE control Tx queue */
+       struct sge_txq q;
+       struct adapter *adap;
+       struct sk_buff_head sendq;  /* list of backpressured packets */
+       struct tasklet_struct qresume_tsk; /* restarts the queue */
+       u8 full;                    /* the Tx ring is full */
+} ____cacheline_aligned_in_smp;
+
+struct sge {
+       struct sge_eth_txq ethtxq[MAX_ETH_QSETS];
+       struct sge_ofld_txq ofldtxq[MAX_OFLD_QSETS];
+       struct sge_ctrl_txq ctrlq[MAX_CTRL_QUEUES];
+
+       struct sge_eth_rxq ethrxq[MAX_ETH_QSETS];
+       struct sge_ofld_rxq ofldrxq[MAX_OFLD_QSETS];
+       struct sge_ofld_rxq rdmarxq[MAX_RDMA_QUEUES];
+       struct sge_rspq fw_evtq ____cacheline_aligned_in_smp;
+
+       struct sge_rspq intrq ____cacheline_aligned_in_smp;
+       spinlock_t intrq_lock;
+
+       u16 max_ethqsets;           /* # of available Ethernet queue sets */
+       u16 ethqsets;               /* # of active Ethernet queue sets */
+       u16 ethtxq_rover;           /* Tx queue to clean up next */
+       u16 ofldqsets;              /* # of active offload queue sets */
+       u16 rdmaqs;                 /* # of available RDMA Rx queues */
+       u16 ofld_rxq[MAX_OFLD_QSETS];
+       u16 rdma_rxq[NCHAN];
+       u16 timer_val[SGE_NTIMERS];
+       u8 counter_val[SGE_NCOUNTERS];
+       unsigned int starve_thres;
+       u8 idma_state[2];
+       void *egr_map[MAX_EGRQ];    /* qid->queue egress queue map */
+       struct sge_rspq *ingr_map[MAX_INGQ]; /* qid->queue ingress queue map */
+       DECLARE_BITMAP(starving_fl, MAX_EGRQ);
+       DECLARE_BITMAP(txq_maperr, MAX_EGRQ);
+       struct timer_list rx_timer; /* refills starving FLs */
+       struct timer_list tx_timer; /* checks Tx queues */
+};
+
+#define for_each_ethrxq(sge, i) for (i = 0; i < (sge)->ethqsets; i++)
+#define for_each_ofldrxq(sge, i) for (i = 0; i < (sge)->ofldqsets; i++)
+#define for_each_rdmarxq(sge, i) for (i = 0; i < (sge)->rdmaqs; i++)
+
+struct l2t_data;
+
+struct adapter {
+       void __iomem *regs;
+       struct pci_dev *pdev;
+       struct device *pdev_dev;
+       unsigned long registered_device_map;
+       unsigned long open_device_map;
+       unsigned long flags;
+
+       const char *name;
+       int msg_enable;
+
+       struct adapter_params params;
+       struct cxgb4_virt_res vres;
+       unsigned int swintr;
+
+       unsigned int wol;
+
+       struct {
+               unsigned short vec;
+               char desc[14];
+       } msix_info[MAX_INGQ + 1];
+
+       struct sge sge;
+
+       struct net_device *port[MAX_NPORTS];
+       u8 chan_map[NCHAN];                   /* channel -> port map */
+
+       struct l2t_data *l2t;
+       void *uld_handle[CXGB4_ULD_MAX];
+       struct list_head list_node;
+
+       struct tid_info tids;
+       void **tid_release_head;
+       spinlock_t tid_release_lock;
+       struct work_struct tid_release_task;
+       bool tid_release_task_busy;
+
+       struct dentry *debugfs_root;
+
+       spinlock_t stats_lock;
+};
+
+static inline u32 t4_read_reg(struct adapter *adap, u32 reg_addr)
+{
+       return readl(adap->regs + reg_addr);
+}
+
+static inline void t4_write_reg(struct adapter *adap, u32 reg_addr, u32 val)
+{
+       writel(val, adap->regs + reg_addr);
+}
+
+#ifndef readq
+static inline u64 readq(const volatile void __iomem *addr)
+{
+       return readl(addr) + ((u64)readl(addr + 4) << 32);
+}
+
+static inline void writeq(u64 val, volatile void __iomem *addr)
+{
+       writel(val, addr);
+       writel(val >> 32, addr + 4);
+}
+#endif
+
+static inline u64 t4_read_reg64(struct adapter *adap, u32 reg_addr)
+{
+       return readq(adap->regs + reg_addr);
+}
+
+static inline void t4_write_reg64(struct adapter *adap, u32 reg_addr, u64 val)
+{
+       writeq(val, adap->regs + reg_addr);
+}
+
+/**
+ * netdev2pinfo - return the port_info structure associated with a net_device
+ * @dev: the netdev
+ *
+ * Return the struct port_info associated with a net_device
+ */
+static inline struct port_info *netdev2pinfo(const struct net_device *dev)
+{
+       return netdev_priv(dev);
+}
+
+/**
+ * adap2pinfo - return the port_info of a port
+ * @adap: the adapter
+ * @idx: the port index
+ *
+ * Return the port_info structure for the port of the given index.
+ */
+static inline struct port_info *adap2pinfo(struct adapter *adap, int idx)
+{
+       return netdev_priv(adap->port[idx]);
+}
+
+/**
+ * netdev2adap - return the adapter structure associated with a net_device
+ * @dev: the netdev
+ *
+ * Return the struct adapter associated with a net_device
+ */
+static inline struct adapter *netdev2adap(const struct net_device *dev)
+{
+       return netdev2pinfo(dev)->adapter;
+}
+
+void t4_os_portmod_changed(const struct adapter *adap, int port_id);
+void t4_os_link_changed(struct adapter *adap, int port_id, int link_stat);
+
+void *t4_alloc_mem(size_t size);
+void t4_free_mem(void *addr);
+
+void t4_free_sge_resources(struct adapter *adap);
+irq_handler_t t4_intr_handler(struct adapter *adap);
+netdev_tx_t t4_eth_xmit(struct sk_buff *skb, struct net_device *dev);
+int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
+                    const struct pkt_gl *gl);
+int t4_mgmt_tx(struct adapter *adap, struct sk_buff *skb);
+int t4_ofld_send(struct adapter *adap, struct sk_buff *skb);
+int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
+                    struct net_device *dev, int intr_idx,
+                    struct sge_fl *fl, rspq_handler_t hnd);
+int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
+                        struct net_device *dev, struct netdev_queue *netdevq,
+                        unsigned int iqid);
+int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq,
+                         struct net_device *dev, unsigned int iqid,
+                         unsigned int cmplqid);
+int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq,
+                         struct net_device *dev, unsigned int iqid);
+irqreturn_t t4_sge_intr_msix(int irq, void *cookie);
+void t4_sge_init(struct adapter *adap);
+void t4_sge_start(struct adapter *adap);
+void t4_sge_stop(struct adapter *adap);
+
+#define for_each_port(adapter, iter) \
+       for (iter = 0; iter < (adapter)->params.nports; ++iter)
+
+static inline unsigned int core_ticks_per_usec(const struct adapter *adap)
+{
+       return adap->params.vpd.cclk / 1000;
+}
+
+static inline unsigned int us_to_core_ticks(const struct adapter *adap,
+                                           unsigned int us)
+{
+       return (us * adap->params.vpd.cclk) / 1000;
+}
+
+void t4_set_reg_field(struct adapter *adap, unsigned int addr, u32 mask,
+                     u32 val);
+
+int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
+                   void *rpl, bool sleep_ok);
+
+static inline int t4_wr_mbox(struct adapter *adap, int mbox, const void *cmd,
+                            int size, void *rpl)
+{
+       return t4_wr_mbox_meat(adap, mbox, cmd, size, rpl, true);
+}
+
+static inline int t4_wr_mbox_ns(struct adapter *adap, int mbox, const void *cmd,
+                               int size, void *rpl)
+{
+       return t4_wr_mbox_meat(adap, mbox, cmd, size, rpl, false);
+}
+
+void t4_intr_enable(struct adapter *adapter);
+void t4_intr_disable(struct adapter *adapter);
+void t4_intr_clear(struct adapter *adapter);
+int t4_slow_intr_handler(struct adapter *adapter);
+
+int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port,
+                 struct link_config *lc);
+int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port);
+int t4_seeprom_wp(struct adapter *adapter, bool enable);
+int t4_read_flash(struct adapter *adapter, unsigned int addr,
+                 unsigned int nwords, u32 *data, int byte_oriented);
+int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size);
+int t4_check_fw_version(struct adapter *adapter);
+int t4_prep_adapter(struct adapter *adapter);
+int t4_port_init(struct adapter *adap, int mbox, int pf, int vf);
+void t4_fatal_err(struct adapter *adapter);
+void t4_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on);
+int t4_set_trace_filter(struct adapter *adapter, const struct trace_params *tp,
+                       int filter_index, int enable);
+void t4_get_trace_filter(struct adapter *adapter, struct trace_params *tp,
+                        int filter_index, int *enabled);
+int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
+                       int start, int n, const u16 *rspq, unsigned int nrspq);
+int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode,
+                      unsigned int flags);
+int t4_read_rss(struct adapter *adapter, u16 *entries);
+int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *parity);
+int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data,
+               u64 *parity);
+
+void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p);
+void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p);
+
+void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log);
+void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st);
+void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4,
+                        struct tp_tcp_stats *v6);
+void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
+                 const unsigned short *alpha, const unsigned short *beta);
+
+void t4_wol_magic_enable(struct adapter *adap, unsigned int port,
+                        const u8 *addr);
+int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map,
+                     u64 mask0, u64 mask1, unsigned int crc, bool enable);
+
+int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox,
+               enum dev_master master, enum dev_state *state);
+int t4_fw_bye(struct adapter *adap, unsigned int mbox);
+int t4_early_init(struct adapter *adap, unsigned int mbox);
+int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset);
+int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
+                   unsigned int vf, unsigned int nparams, const u32 *params,
+                   u32 *val);
+int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
+                 unsigned int vf, unsigned int nparams, const u32 *params,
+                 const u32 *val);
+int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf,
+               unsigned int vf, unsigned int txq, unsigned int txq_eth_ctrl,
+               unsigned int rxqi, unsigned int rxq, unsigned int tc,
+               unsigned int vi, unsigned int cmask, unsigned int pmask,
+               unsigned int nexact, unsigned int rcaps, unsigned int wxcaps);
+int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port,
+               unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac,
+               unsigned int *rss_size);
+int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf,
+              unsigned int vf, unsigned int viid);
+int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid,
+               int mtu, int promisc, int all_multi, int bcast, bool sleep_ok);
+int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox,
+                     unsigned int viid, bool free, unsigned int naddr,
+                     const u8 **addr, u16 *idx, u64 *hash, bool sleep_ok);
+int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid,
+                 int idx, const u8 *addr, bool persist, bool add_smt);
+int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid,
+                    bool ucast, u64 vec, bool sleep_ok);
+int t4_enable_vi(struct adapter *adap, unsigned int mbox, unsigned int viid,
+                bool rx_en, bool tx_en);
+int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid,
+                    unsigned int nblinks);
+int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
+              unsigned int mmd, unsigned int reg, u16 *valp);
+int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
+              unsigned int mmd, unsigned int reg, u16 val);
+int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start,
+                    unsigned int pf, unsigned int vf, unsigned int iqid,
+                    unsigned int fl0id, unsigned int fl1id);
+int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+              unsigned int vf, unsigned int iqtype, unsigned int iqid,
+              unsigned int fl0id, unsigned int fl1id);
+int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+                  unsigned int vf, unsigned int eqid);
+int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+                   unsigned int vf, unsigned int eqid);
+int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+                   unsigned int vf, unsigned int eqid);
+int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl);
+#endif /* __CXGB4_H__ */
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
new file mode 100644 (file)
index 0000000..a7e30a2
--- /dev/null
@@ -0,0 +1,3388 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/bitmap.h>
+#include <linux/crc32.h>
+#include <linux/ctype.h>
+#include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/etherdevice.h>
+#include <linux/firmware.h>
+#include <linux/if_vlan.h>
+#include <linux/init.h>
+#include <linux/log2.h>
+#include <linux/mdio.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mutex.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/aer.h>
+#include <linux/rtnetlink.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/sockios.h>
+#include <linux/vmalloc.h>
+#include <linux/workqueue.h>
+#include <net/neighbour.h>
+#include <net/netevent.h>
+#include <asm/uaccess.h>
+
+#include "cxgb4.h"
+#include "t4_regs.h"
+#include "t4_msg.h"
+#include "t4fw_api.h"
+#include "l2t.h"
+
+#define DRV_VERSION "1.0.0-ko"
+#define DRV_DESC "Chelsio T4 Network Driver"
+
+/*
+ * Max interrupt hold-off timer value in us.  Queues fall back to this value
+ * under extreme memory pressure so it's largish to give the system time to
+ * recover.
+ */
+#define MAX_SGE_TIMERVAL 200U
+
+enum {
+       MEMWIN0_APERTURE = 65536,
+       MEMWIN0_BASE     = 0x30000,
+       MEMWIN1_APERTURE = 32768,
+       MEMWIN1_BASE     = 0x28000,
+       MEMWIN2_APERTURE = 2048,
+       MEMWIN2_BASE     = 0x1b800,
+};
+
+enum {
+       MAX_TXQ_ENTRIES      = 16384,
+       MAX_CTRL_TXQ_ENTRIES = 1024,
+       MAX_RSPQ_ENTRIES     = 16384,
+       MAX_RX_BUFFERS       = 16384,
+       MIN_TXQ_ENTRIES      = 32,
+       MIN_CTRL_TXQ_ENTRIES = 32,
+       MIN_RSPQ_ENTRIES     = 128,
+       MIN_FL_ENTRIES       = 16
+};
+
+#define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \
+                        NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\
+                        NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
+
+#define CH_DEVICE(devid) { PCI_VDEVICE(CHELSIO, devid), 0 }
+
+static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = {
+       CH_DEVICE(0xa000),  /* PE10K */
+       { 0, }
+};
+
+#define FW_FNAME "cxgb4/t4fw.bin"
+
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_AUTHOR("Chelsio Communications");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(DRV_VERSION);
+MODULE_DEVICE_TABLE(pci, cxgb4_pci_tbl);
+MODULE_FIRMWARE(FW_FNAME);
+
+static int dflt_msg_enable = DFLT_MSG_ENABLE;
+
+module_param(dflt_msg_enable, int, 0644);
+MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T4 default message enable bitmap");
+
+/*
+ * The driver uses the best interrupt scheme available on a platform in the
+ * order MSI-X, MSI, legacy INTx interrupts.  This parameter determines which
+ * of these schemes the driver may consider as follows:
+ *
+ * msi = 2: choose from among all three options
+ * msi = 1: only consider MSI and INTx interrupts
+ * msi = 0: force INTx interrupts
+ */
+static int msi = 2;
+
+module_param(msi, int, 0644);
+MODULE_PARM_DESC(msi, "whether to use INTx (0), MSI (1) or MSI-X (2)");
+
+/*
+ * Queue interrupt hold-off timer values.  Queues default to the first of these
+ * upon creation.
+ */
+static unsigned int intr_holdoff[SGE_NTIMERS - 1] = { 5, 10, 20, 50, 100 };
+
+module_param_array(intr_holdoff, uint, NULL, 0644);
+MODULE_PARM_DESC(intr_holdoff, "values for queue interrupt hold-off timers "
+                "0..4 in microseconds");
+
+static unsigned int intr_cnt[SGE_NCOUNTERS - 1] = { 4, 8, 16 };
+
+module_param_array(intr_cnt, uint, NULL, 0644);
+MODULE_PARM_DESC(intr_cnt,
+                "thresholds 1..3 for queue interrupt packet counters");
+
+static int vf_acls;
+
+#ifdef CONFIG_PCI_IOV
+module_param(vf_acls, bool, 0644);
+MODULE_PARM_DESC(vf_acls, "if set enable virtualization L2 ACL enforcement");
+
+static unsigned int num_vf[4];
+
+module_param_array(num_vf, uint, NULL, 0644);
+MODULE_PARM_DESC(num_vf, "number of VFs for each of PFs 0-3");
+#endif
+
+static struct dentry *cxgb4_debugfs_root;
+
+static LIST_HEAD(adapter_list);
+static DEFINE_MUTEX(uld_mutex);
+static struct cxgb4_uld_info ulds[CXGB4_ULD_MAX];
+static const char *uld_str[] = { "RDMA", "iSCSI" };
+
+static void link_report(struct net_device *dev)
+{
+       if (!netif_carrier_ok(dev))
+               netdev_info(dev, "link down\n");
+       else {
+               static const char *fc[] = { "no", "Rx", "Tx", "Tx/Rx" };
+
+               const char *s = "10Mbps";
+               const struct port_info *p = netdev_priv(dev);
+
+               switch (p->link_cfg.speed) {
+               case SPEED_10000:
+                       s = "10Gbps";
+                       break;
+               case SPEED_1000:
+                       s = "1000Mbps";
+                       break;
+               case SPEED_100:
+                       s = "100Mbps";
+                       break;
+               }
+
+               netdev_info(dev, "link up, %s, full-duplex, %s PAUSE\n", s,
+                           fc[p->link_cfg.fc]);
+       }
+}
+
+void t4_os_link_changed(struct adapter *adapter, int port_id, int link_stat)
+{
+       struct net_device *dev = adapter->port[port_id];
+
+       /* Skip changes from disabled ports. */
+       if (netif_running(dev) && link_stat != netif_carrier_ok(dev)) {
+               if (link_stat)
+                       netif_carrier_on(dev);
+               else
+                       netif_carrier_off(dev);
+
+               link_report(dev);
+       }
+}
+
+void t4_os_portmod_changed(const struct adapter *adap, int port_id)
+{
+       static const char *mod_str[] = {
+               NULL, "LR", "SR", "ER", "passive DA", "active DA"
+       };
+
+       const struct net_device *dev = adap->port[port_id];
+       const struct port_info *pi = netdev_priv(dev);
+
+       if (pi->mod_type == FW_PORT_MOD_TYPE_NONE)
+               netdev_info(dev, "port module unplugged\n");
+       else
+               netdev_info(dev, "%s module inserted\n", mod_str[pi->mod_type]);
+}
+
+/*
+ * Configure the exact and hash address filters to handle a port's multicast
+ * and secondary unicast MAC addresses.
+ */
+static int set_addr_filters(const struct net_device *dev, bool sleep)
+{
+       u64 mhash = 0;
+       u64 uhash = 0;
+       bool free = true;
+       u16 filt_idx[7];
+       const u8 *addr[7];
+       int ret, naddr = 0;
+       const struct dev_addr_list *d;
+       const struct netdev_hw_addr *ha;
+       int uc_cnt = netdev_uc_count(dev);
+       const struct port_info *pi = netdev_priv(dev);
+
+       /* first do the secondary unicast addresses */
+       netdev_for_each_uc_addr(ha, dev) {
+               addr[naddr++] = ha->addr;
+               if (--uc_cnt == 0 || naddr >= ARRAY_SIZE(addr)) {
+                       ret = t4_alloc_mac_filt(pi->adapter, 0, pi->viid, free,
+                                       naddr, addr, filt_idx, &uhash, sleep);
+                       if (ret < 0)
+                               return ret;
+
+                       free = false;
+                       naddr = 0;
+               }
+       }
+
+       /* next set up the multicast addresses */
+       netdev_for_each_mc_addr(d, dev) {
+               addr[naddr++] = d->dmi_addr;
+               if (naddr >= ARRAY_SIZE(addr) || d->next == NULL) {
+                       ret = t4_alloc_mac_filt(pi->adapter, 0, pi->viid, free,
+                                       naddr, addr, filt_idx, &mhash, sleep);
+                       if (ret < 0)
+                               return ret;
+
+                       free = false;
+                       naddr = 0;
+               }
+       }
+
+       return t4_set_addr_hash(pi->adapter, 0, pi->viid, uhash != 0,
+                               uhash | mhash, sleep);
+}
+
+/*
+ * Set Rx properties of a port, such as promiscruity, address filters, and MTU.
+ * If @mtu is -1 it is left unchanged.
+ */
+static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok)
+{
+       int ret;
+       struct port_info *pi = netdev_priv(dev);
+
+       ret = set_addr_filters(dev, sleep_ok);
+       if (ret == 0)
+               ret = t4_set_rxmode(pi->adapter, 0, pi->viid, mtu,
+                                   (dev->flags & IFF_PROMISC) ? 1 : 0,
+                                   (dev->flags & IFF_ALLMULTI) ? 1 : 0, 1,
+                                   sleep_ok);
+       return ret;
+}
+
+/**
+ *     link_start - enable a port
+ *     @dev: the port to enable
+ *
+ *     Performs the MAC and PHY actions needed to enable a port.
+ */
+static int link_start(struct net_device *dev)
+{
+       int ret;
+       struct port_info *pi = netdev_priv(dev);
+
+       /*
+        * We do not set address filters and promiscuity here, the stack does
+        * that step explicitly.
+        */
+       ret = t4_set_rxmode(pi->adapter, 0, pi->viid, dev->mtu, -1, -1, -1,
+                           true);
+       if (ret == 0) {
+               ret = t4_change_mac(pi->adapter, 0, pi->viid,
+                                   pi->xact_addr_filt, dev->dev_addr, true,
+                                   false);
+               if (ret >= 0) {
+                       pi->xact_addr_filt = ret;
+                       ret = 0;
+               }
+       }
+       if (ret == 0)
+               ret = t4_link_start(pi->adapter, 0, pi->tx_chan, &pi->link_cfg);
+       if (ret == 0)
+               ret = t4_enable_vi(pi->adapter, 0, pi->viid, true, true);
+       return ret;
+}
+
+/*
+ * Response queue handler for the FW event queue.
+ */
+static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,
+                         const struct pkt_gl *gl)
+{
+       u8 opcode = ((const struct rss_header *)rsp)->opcode;
+
+       rsp++;                                          /* skip RSS header */
+       if (likely(opcode == CPL_SGE_EGR_UPDATE)) {
+               const struct cpl_sge_egr_update *p = (void *)rsp;
+               unsigned int qid = EGR_QID(ntohl(p->opcode_qid));
+               struct sge_txq *txq = q->adap->sge.egr_map[qid];
+
+               txq->restarts++;
+               if ((u8 *)txq < (u8 *)q->adap->sge.ethrxq) {
+                       struct sge_eth_txq *eq;
+
+                       eq = container_of(txq, struct sge_eth_txq, q);
+                       netif_tx_wake_queue(eq->txq);
+               } else {
+                       struct sge_ofld_txq *oq;
+
+                       oq = container_of(txq, struct sge_ofld_txq, q);
+                       tasklet_schedule(&oq->qresume_tsk);
+               }
+       } else if (opcode == CPL_FW6_MSG || opcode == CPL_FW4_MSG) {
+               const struct cpl_fw6_msg *p = (void *)rsp;
+
+               if (p->type == 0)
+                       t4_handle_fw_rpl(q->adap, p->data);
+       } else if (opcode == CPL_L2T_WRITE_RPL) {
+               const struct cpl_l2t_write_rpl *p = (void *)rsp;
+
+               do_l2t_write_rpl(q->adap, p);
+       } else
+               dev_err(q->adap->pdev_dev,
+                       "unexpected CPL %#x on FW event queue\n", opcode);
+       return 0;
+}
+
+/**
+ *     uldrx_handler - response queue handler for ULD queues
+ *     @q: the response queue that received the packet
+ *     @rsp: the response queue descriptor holding the offload message
+ *     @gl: the gather list of packet fragments
+ *
+ *     Deliver an ingress offload packet to a ULD.  All processing is done by
+ *     the ULD, we just maintain statistics.
+ */
+static int uldrx_handler(struct sge_rspq *q, const __be64 *rsp,
+                        const struct pkt_gl *gl)
+{
+       struct sge_ofld_rxq *rxq = container_of(q, struct sge_ofld_rxq, rspq);
+
+       if (ulds[q->uld].rx_handler(q->adap->uld_handle[q->uld], rsp, gl)) {
+               rxq->stats.nomem++;
+               return -1;
+       }
+       if (gl == NULL)
+               rxq->stats.imm++;
+       else if (gl == CXGB4_MSG_AN)
+               rxq->stats.an++;
+       else
+               rxq->stats.pkts++;
+       return 0;
+}
+
+static void disable_msi(struct adapter *adapter)
+{
+       if (adapter->flags & USING_MSIX) {
+               pci_disable_msix(adapter->pdev);
+               adapter->flags &= ~USING_MSIX;
+       } else if (adapter->flags & USING_MSI) {
+               pci_disable_msi(adapter->pdev);
+               adapter->flags &= ~USING_MSI;
+       }
+}
+
+/*
+ * Interrupt handler for non-data events used with MSI-X.
+ */
+static irqreturn_t t4_nondata_intr(int irq, void *cookie)
+{
+       struct adapter *adap = cookie;
+
+       u32 v = t4_read_reg(adap, MYPF_REG(PL_PF_INT_CAUSE));
+       if (v & PFSW) {
+               adap->swintr = 1;
+               t4_write_reg(adap, MYPF_REG(PL_PF_INT_CAUSE), v);
+       }
+       t4_slow_intr_handler(adap);
+       return IRQ_HANDLED;
+}
+
+/*
+ * Name the MSI-X interrupts.
+ */
+static void name_msix_vecs(struct adapter *adap)
+{
+       int i, j, msi_idx = 2, n = sizeof(adap->msix_info[0].desc) - 1;
+
+       /* non-data interrupts */
+       snprintf(adap->msix_info[0].desc, n, "%s", adap->name);
+       adap->msix_info[0].desc[n] = 0;
+
+       /* FW events */
+       snprintf(adap->msix_info[1].desc, n, "%s-FWeventq", adap->name);
+       adap->msix_info[1].desc[n] = 0;
+
+       /* Ethernet queues */
+       for_each_port(adap, j) {
+               struct net_device *d = adap->port[j];
+               const struct port_info *pi = netdev_priv(d);
+
+               for (i = 0; i < pi->nqsets; i++, msi_idx++) {
+                       snprintf(adap->msix_info[msi_idx].desc, n, "%s-Rx%d",
+                                d->name, i);
+                       adap->msix_info[msi_idx].desc[n] = 0;
+               }
+       }
+
+       /* offload queues */
+       for_each_ofldrxq(&adap->sge, i) {
+               snprintf(adap->msix_info[msi_idx].desc, n, "%s-ofld%d",
+                        adap->name, i);
+               adap->msix_info[msi_idx++].desc[n] = 0;
+       }
+       for_each_rdmarxq(&adap->sge, i) {
+               snprintf(adap->msix_info[msi_idx].desc, n, "%s-rdma%d",
+                        adap->name, i);
+               adap->msix_info[msi_idx++].desc[n] = 0;
+       }
+}
+
+static int request_msix_queue_irqs(struct adapter *adap)
+{
+       struct sge *s = &adap->sge;
+       int err, ethqidx, ofldqidx = 0, rdmaqidx = 0, msi = 2;
+
+       err = request_irq(adap->msix_info[1].vec, t4_sge_intr_msix, 0,
+                         adap->msix_info[1].desc, &s->fw_evtq);
+       if (err)
+               return err;
+
+       for_each_ethrxq(s, ethqidx) {
+               err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0,
+                                 adap->msix_info[msi].desc,
+                                 &s->ethrxq[ethqidx].rspq);
+               if (err)
+                       goto unwind;
+               msi++;
+       }
+       for_each_ofldrxq(s, ofldqidx) {
+               err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0,
+                                 adap->msix_info[msi].desc,
+                                 &s->ofldrxq[ofldqidx].rspq);
+               if (err)
+                       goto unwind;
+               msi++;
+       }
+       for_each_rdmarxq(s, rdmaqidx) {
+               err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0,
+                                 adap->msix_info[msi].desc,
+                                 &s->rdmarxq[rdmaqidx].rspq);
+               if (err)
+                       goto unwind;
+               msi++;
+       }
+       return 0;
+
+unwind:
+       while (--rdmaqidx >= 0)
+               free_irq(adap->msix_info[--msi].vec,
+                        &s->rdmarxq[rdmaqidx].rspq);
+       while (--ofldqidx >= 0)
+               free_irq(adap->msix_info[--msi].vec,
+                        &s->ofldrxq[ofldqidx].rspq);
+       while (--ethqidx >= 0)
+               free_irq(adap->msix_info[--msi].vec, &s->ethrxq[ethqidx].rspq);
+       free_irq(adap->msix_info[1].vec, &s->fw_evtq);
+       return err;
+}
+
+static void free_msix_queue_irqs(struct adapter *adap)
+{
+       int i, msi = 2;
+       struct sge *s = &adap->sge;
+
+       free_irq(adap->msix_info[1].vec, &s->fw_evtq);
+       for_each_ethrxq(s, i)
+               free_irq(adap->msix_info[msi++].vec, &s->ethrxq[i].rspq);
+       for_each_ofldrxq(s, i)
+               free_irq(adap->msix_info[msi++].vec, &s->ofldrxq[i].rspq);
+       for_each_rdmarxq(s, i)
+               free_irq(adap->msix_info[msi++].vec, &s->rdmarxq[i].rspq);
+}
+
+/**
+ *     setup_rss - configure RSS
+ *     @adap: the adapter
+ *
+ *     Sets up RSS to distribute packets to multiple receive queues.  We
+ *     configure the RSS CPU lookup table to distribute to the number of HW
+ *     receive queues, and the response queue lookup table to narrow that
+ *     down to the response queues actually configured for each port.
+ *     We always configure the RSS mapping for all ports since the mapping
+ *     table has plenty of entries.
+ */
+static int setup_rss(struct adapter *adap)
+{
+       int i, j, err;
+       u16 rss[MAX_ETH_QSETS];
+
+       for_each_port(adap, i) {
+               const struct port_info *pi = adap2pinfo(adap, i);
+               const struct sge_eth_rxq *q = &adap->sge.ethrxq[pi->first_qset];
+
+               for (j = 0; j < pi->nqsets; j++)
+                       rss[j] = q[j].rspq.abs_id;
+
+               err = t4_config_rss_range(adap, 0, pi->viid, 0, pi->rss_size,
+                                         rss, pi->nqsets);
+               if (err)
+                       return err;
+       }
+       return 0;
+}
+
+/*
+ * Wait until all NAPI handlers are descheduled.
+ */
+static void quiesce_rx(struct adapter *adap)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(adap->sge.ingr_map); i++) {
+               struct sge_rspq *q = adap->sge.ingr_map[i];
+
+               if (q && q->handler)
+                       napi_disable(&q->napi);
+       }
+}
+
+/*
+ * Enable NAPI scheduling and interrupt generation for all Rx queues.
+ */
+static void enable_rx(struct adapter *adap)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(adap->sge.ingr_map); i++) {
+               struct sge_rspq *q = adap->sge.ingr_map[i];
+
+               if (!q)
+                       continue;
+               if (q->handler)
+                       napi_enable(&q->napi);
+               /* 0-increment GTS to start the timer and enable interrupts */
+               t4_write_reg(adap, MYPF_REG(SGE_PF_GTS),
+                            SEINTARM(q->intr_params) |
+                            INGRESSQID(q->cntxt_id));
+       }
+}
+
+/**
+ *     setup_sge_queues - configure SGE Tx/Rx/response queues
+ *     @adap: the adapter
+ *
+ *     Determines how many sets of SGE queues to use and initializes them.
+ *     We support multiple queue sets per port if we have MSI-X, otherwise
+ *     just one queue set per port.
+ */
+static int setup_sge_queues(struct adapter *adap)
+{
+       int err, msi_idx, i, j;
+       struct sge *s = &adap->sge;
+
+       bitmap_zero(s->starving_fl, MAX_EGRQ);
+       bitmap_zero(s->txq_maperr, MAX_EGRQ);
+
+       if (adap->flags & USING_MSIX)
+               msi_idx = 1;         /* vector 0 is for non-queue interrupts */
+       else {
+               err = t4_sge_alloc_rxq(adap, &s->intrq, false, adap->port[0], 0,
+                                      NULL, NULL);
+               if (err)
+                       return err;
+               msi_idx = -((int)s->intrq.abs_id + 1);
+       }
+
+       err = t4_sge_alloc_rxq(adap, &s->fw_evtq, true, adap->port[0],
+                              msi_idx, NULL, fwevtq_handler);
+       if (err) {
+freeout:       t4_free_sge_resources(adap);
+               return err;
+       }
+
+       for_each_port(adap, i) {
+               struct net_device *dev = adap->port[i];
+               struct port_info *pi = netdev_priv(dev);
+               struct sge_eth_rxq *q = &s->ethrxq[pi->first_qset];
+               struct sge_eth_txq *t = &s->ethtxq[pi->first_qset];
+
+               for (j = 0; j < pi->nqsets; j++, q++) {
+                       if (msi_idx > 0)
+                               msi_idx++;
+                       err = t4_sge_alloc_rxq(adap, &q->rspq, false, dev,
+                                              msi_idx, &q->fl,
+                                              t4_ethrx_handler);
+                       if (err)
+                               goto freeout;
+                       q->rspq.idx = j;
+                       memset(&q->stats, 0, sizeof(q->stats));
+               }
+               for (j = 0; j < pi->nqsets; j++, t++) {
+                       err = t4_sge_alloc_eth_txq(adap, t, dev,
+                                       netdev_get_tx_queue(dev, j),
+                                       s->fw_evtq.cntxt_id);
+                       if (err)
+                               goto freeout;
+               }
+       }
+
+       j = s->ofldqsets / adap->params.nports; /* ofld queues per channel */
+       for_each_ofldrxq(s, i) {
+               struct sge_ofld_rxq *q = &s->ofldrxq[i];
+               struct net_device *dev = adap->port[i / j];
+
+               if (msi_idx > 0)
+                       msi_idx++;
+               err = t4_sge_alloc_rxq(adap, &q->rspq, false, dev, msi_idx,
+                                      &q->fl, uldrx_handler);
+               if (err)
+                       goto freeout;
+               memset(&q->stats, 0, sizeof(q->stats));
+               s->ofld_rxq[i] = q->rspq.abs_id;
+               err = t4_sge_alloc_ofld_txq(adap, &s->ofldtxq[i], dev,
+                                           s->fw_evtq.cntxt_id);
+               if (err)
+                       goto freeout;
+       }
+
+       for_each_rdmarxq(s, i) {
+               struct sge_ofld_rxq *q = &s->rdmarxq[i];
+
+               if (msi_idx > 0)
+                       msi_idx++;
+               err = t4_sge_alloc_rxq(adap, &q->rspq, false, adap->port[i],
+                                      msi_idx, &q->fl, uldrx_handler);
+               if (err)
+                       goto freeout;
+               memset(&q->stats, 0, sizeof(q->stats));
+               s->rdma_rxq[i] = q->rspq.abs_id;
+       }
+
+       for_each_port(adap, i) {
+               /*
+                * Note that ->rdmarxq[i].rspq.cntxt_id below is 0 if we don't
+                * have RDMA queues, and that's the right value.
+                */
+               err = t4_sge_alloc_ctrl_txq(adap, &s->ctrlq[i], adap->port[i],
+                                           s->fw_evtq.cntxt_id,
+                                           s->rdmarxq[i].rspq.cntxt_id);
+               if (err)
+                       goto freeout;
+       }
+
+       t4_write_reg(adap, MPS_TRC_RSS_CONTROL,
+                    RSSCONTROL(netdev2pinfo(adap->port[0])->tx_chan) |
+                    QUEUENUMBER(s->ethrxq[0].rspq.abs_id));
+       return 0;
+}
+
+/*
+ * Returns 0 if new FW was successfully loaded, a positive errno if a load was
+ * started but failed, and a negative errno if flash load couldn't start.
+ */
+static int upgrade_fw(struct adapter *adap)
+{
+       int ret;
+       u32 vers;
+       const struct fw_hdr *hdr;
+       const struct firmware *fw;
+       struct device *dev = adap->pdev_dev;
+
+       ret = request_firmware(&fw, FW_FNAME, dev);
+       if (ret < 0) {
+               dev_err(dev, "unable to load firmware image " FW_FNAME
+                       ", error %d\n", ret);
+               return ret;
+       }
+
+       hdr = (const struct fw_hdr *)fw->data;
+       vers = ntohl(hdr->fw_ver);
+       if (FW_HDR_FW_VER_MAJOR_GET(vers) != FW_VERSION_MAJOR) {
+               ret = -EINVAL;              /* wrong major version, won't do */
+               goto out;
+       }
+
+       /*
+        * If the flash FW is unusable or we found something newer, load it.
+        */
+       if (FW_HDR_FW_VER_MAJOR_GET(adap->params.fw_vers) != FW_VERSION_MAJOR ||
+           vers > adap->params.fw_vers) {
+               ret = -t4_load_fw(adap, fw->data, fw->size);
+               if (!ret)
+                       dev_info(dev, "firmware upgraded to version %pI4 from "
+                                FW_FNAME "\n", &hdr->fw_ver);
+       }
+out:   release_firmware(fw);
+       return ret;
+}
+
+/*
+ * Allocate a chunk of memory using kmalloc or, if that fails, vmalloc.
+ * The allocated memory is cleared.
+ */
+void *t4_alloc_mem(size_t size)
+{
+       void *p = kmalloc(size, GFP_KERNEL);
+
+       if (!p)
+               p = vmalloc(size);
+       if (p)
+               memset(p, 0, size);
+       return p;
+}
+
+/*
+ * Free memory allocated through alloc_mem().
+ */
+void t4_free_mem(void *addr)
+{
+       if (is_vmalloc_addr(addr))
+               vfree(addr);
+       else
+               kfree(addr);
+}
+
+static inline int is_offload(const struct adapter *adap)
+{
+       return adap->params.offload;
+}
+
+/*
+ * Implementation of ethtool operations.
+ */
+
+static u32 get_msglevel(struct net_device *dev)
+{
+       return netdev2adap(dev)->msg_enable;
+}
+
+static void set_msglevel(struct net_device *dev, u32 val)
+{
+       netdev2adap(dev)->msg_enable = val;
+}
+
+static char stats_strings[][ETH_GSTRING_LEN] = {
+       "TxOctetsOK         ",
+       "TxFramesOK         ",
+       "TxBroadcastFrames  ",
+       "TxMulticastFrames  ",
+       "TxUnicastFrames    ",
+       "TxErrorFrames      ",
+
+       "TxFrames64         ",
+       "TxFrames65To127    ",
+       "TxFrames128To255   ",
+       "TxFrames256To511   ",
+       "TxFrames512To1023  ",
+       "TxFrames1024To1518 ",
+       "TxFrames1519ToMax  ",
+
+       "TxFramesDropped    ",
+       "TxPauseFrames      ",
+       "TxPPP0Frames       ",
+       "TxPPP1Frames       ",
+       "TxPPP2Frames       ",
+       "TxPPP3Frames       ",
+       "TxPPP4Frames       ",
+       "TxPPP5Frames       ",
+       "TxPPP6Frames       ",
+       "TxPPP7Frames       ",
+
+       "RxOctetsOK         ",
+       "RxFramesOK         ",
+       "RxBroadcastFrames  ",
+       "RxMulticastFrames  ",
+       "RxUnicastFrames    ",
+
+       "RxFramesTooLong    ",
+       "RxJabberErrors     ",
+       "RxFCSErrors        ",
+       "RxLengthErrors     ",
+       "RxSymbolErrors     ",
+       "RxRuntFrames       ",
+
+       "RxFrames64         ",
+       "RxFrames65To127    ",
+       "RxFrames128To255   ",
+       "RxFrames256To511   ",
+       "RxFrames512To1023  ",
+       "RxFrames1024To1518 ",
+       "RxFrames1519ToMax  ",
+
+       "RxPauseFrames      ",
+       "RxPPP0Frames       ",
+       "RxPPP1Frames       ",
+       "RxPPP2Frames       ",
+       "RxPPP3Frames       ",
+       "RxPPP4Frames       ",
+       "RxPPP5Frames       ",
+       "RxPPP6Frames       ",
+       "RxPPP7Frames       ",
+
+       "RxBG0FramesDropped ",
+       "RxBG1FramesDropped ",
+       "RxBG2FramesDropped ",
+       "RxBG3FramesDropped ",
+       "RxBG0FramesTrunc   ",
+       "RxBG1FramesTrunc   ",
+       "RxBG2FramesTrunc   ",
+       "RxBG3FramesTrunc   ",
+
+       "TSO                ",
+       "TxCsumOffload      ",
+       "RxCsumGood         ",
+       "VLANextractions    ",
+       "VLANinsertions     ",
+};
+
+static int get_sset_count(struct net_device *dev, int sset)
+{
+       switch (sset) {
+       case ETH_SS_STATS:
+               return ARRAY_SIZE(stats_strings);
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+#define T4_REGMAP_SIZE (160 * 1024)
+
+static int get_regs_len(struct net_device *dev)
+{
+       return T4_REGMAP_SIZE;
+}
+
+static int get_eeprom_len(struct net_device *dev)
+{
+       return EEPROMSIZE;
+}
+
+static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+       struct adapter *adapter = netdev2adap(dev);
+
+       strcpy(info->driver, KBUILD_MODNAME);
+       strcpy(info->version, DRV_VERSION);
+       strcpy(info->bus_info, pci_name(adapter->pdev));
+
+       if (!adapter->params.fw_vers)
+               strcpy(info->fw_version, "N/A");
+       else
+               snprintf(info->fw_version, sizeof(info->fw_version),
+                       "%u.%u.%u.%u, TP %u.%u.%u.%u",
+                       FW_HDR_FW_VER_MAJOR_GET(adapter->params.fw_vers),
+                       FW_HDR_FW_VER_MINOR_GET(adapter->params.fw_vers),
+                       FW_HDR_FW_VER_MICRO_GET(adapter->params.fw_vers),
+                       FW_HDR_FW_VER_BUILD_GET(adapter->params.fw_vers),
+                       FW_HDR_FW_VER_MAJOR_GET(adapter->params.tp_vers),
+                       FW_HDR_FW_VER_MINOR_GET(adapter->params.tp_vers),
+                       FW_HDR_FW_VER_MICRO_GET(adapter->params.tp_vers),
+                       FW_HDR_FW_VER_BUILD_GET(adapter->params.tp_vers));
+}
+
+static void get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+       if (stringset == ETH_SS_STATS)
+               memcpy(data, stats_strings, sizeof(stats_strings));
+}
+
+/*
+ * port stats maintained per queue of the port.  They should be in the same
+ * order as in stats_strings above.
+ */
+struct queue_port_stats {
+       u64 tso;
+       u64 tx_csum;
+       u64 rx_csum;
+       u64 vlan_ex;
+       u64 vlan_ins;
+};
+
+static void collect_sge_port_stats(const struct adapter *adap,
+               const struct port_info *p, struct queue_port_stats *s)
+{
+       int i;
+       const struct sge_eth_txq *tx = &adap->sge.ethtxq[p->first_qset];
+       const struct sge_eth_rxq *rx = &adap->sge.ethrxq[p->first_qset];
+
+       memset(s, 0, sizeof(*s));
+       for (i = 0; i < p->nqsets; i++, rx++, tx++) {
+               s->tso += tx->tso;
+               s->tx_csum += tx->tx_cso;
+               s->rx_csum += rx->stats.rx_cso;
+               s->vlan_ex += rx->stats.vlan_ex;
+               s->vlan_ins += tx->vlan_ins;
+       }
+}
+
+static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
+                     u64 *data)
+{
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
+
+       t4_get_port_stats(adapter, pi->tx_chan, (struct port_stats *)data);
+
+       data += sizeof(struct port_stats) / sizeof(u64);
+       collect_sge_port_stats(adapter, pi, (struct queue_port_stats *)data);
+}
+
+/*
+ * Return a version number to identify the type of adapter.  The scheme is:
+ * - bits 0..9: chip version
+ * - bits 10..15: chip revision
+ */
+static inline unsigned int mk_adap_vers(const struct adapter *ap)
+{
+       return 4 | (ap->params.rev << 10);
+}
+
+static void reg_block_dump(struct adapter *ap, void *buf, unsigned int start,
+                          unsigned int end)
+{
+       u32 *p = buf + start;
+
+       for ( ; start <= end; start += sizeof(u32))
+               *p++ = t4_read_reg(ap, start);
+}
+
+static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
+                    void *buf)
+{
+       static const unsigned int reg_ranges[] = {
+               0x1008, 0x1108,
+               0x1180, 0x11b4,
+               0x11fc, 0x123c,
+               0x1300, 0x173c,
+               0x1800, 0x18fc,
+               0x3000, 0x30d8,
+               0x30e0, 0x5924,
+               0x5960, 0x59d4,
+               0x5a00, 0x5af8,
+               0x6000, 0x6098,
+               0x6100, 0x6150,
+               0x6200, 0x6208,
+               0x6240, 0x6248,
+               0x6280, 0x6338,
+               0x6370, 0x638c,
+               0x6400, 0x643c,
+               0x6500, 0x6524,
+               0x6a00, 0x6a38,
+               0x6a60, 0x6a78,
+               0x6b00, 0x6b84,
+               0x6bf0, 0x6c84,
+               0x6cf0, 0x6d84,
+               0x6df0, 0x6e84,
+               0x6ef0, 0x6f84,
+               0x6ff0, 0x7084,
+               0x70f0, 0x7184,
+               0x71f0, 0x7284,
+               0x72f0, 0x7384,
+               0x73f0, 0x7450,
+               0x7500, 0x7530,
+               0x7600, 0x761c,
+               0x7680, 0x76cc,
+               0x7700, 0x7798,
+               0x77c0, 0x77fc,
+               0x7900, 0x79fc,
+               0x7b00, 0x7c38,
+               0x7d00, 0x7efc,
+               0x8dc0, 0x8e1c,
+               0x8e30, 0x8e78,
+               0x8ea0, 0x8f6c,
+               0x8fc0, 0x9074,
+               0x90fc, 0x90fc,
+               0x9400, 0x9458,
+               0x9600, 0x96bc,
+               0x9800, 0x9808,
+               0x9820, 0x983c,
+               0x9850, 0x9864,
+               0x9c00, 0x9c6c,
+               0x9c80, 0x9cec,
+               0x9d00, 0x9d6c,
+               0x9d80, 0x9dec,
+               0x9e00, 0x9e6c,
+               0x9e80, 0x9eec,
+               0x9f00, 0x9f6c,
+               0x9f80, 0x9fec,
+               0xd004, 0xd03c,
+               0xdfc0, 0xdfe0,
+               0xe000, 0xea7c,
+               0xf000, 0x11190,
+               0x19040, 0x19124,
+               0x19150, 0x191b0,
+               0x191d0, 0x191e8,
+               0x19238, 0x1924c,
+               0x193f8, 0x19474,
+               0x19490, 0x194f8,
+               0x19800, 0x19f30,
+               0x1a000, 0x1a06c,
+               0x1a0b0, 0x1a120,
+               0x1a128, 0x1a138,
+               0x1a190, 0x1a1c4,
+               0x1a1fc, 0x1a1fc,
+               0x1e040, 0x1e04c,
+               0x1e240, 0x1e28c,
+               0x1e2c0, 0x1e2c0,
+               0x1e2e0, 0x1e2e0,
+               0x1e300, 0x1e384,
+               0x1e3c0, 0x1e3c8,
+               0x1e440, 0x1e44c,
+               0x1e640, 0x1e68c,
+               0x1e6c0, 0x1e6c0,
+               0x1e6e0, 0x1e6e0,
+               0x1e700, 0x1e784,
+               0x1e7c0, 0x1e7c8,
+               0x1e840, 0x1e84c,
+               0x1ea40, 0x1ea8c,
+               0x1eac0, 0x1eac0,
+               0x1eae0, 0x1eae0,
+               0x1eb00, 0x1eb84,
+               0x1ebc0, 0x1ebc8,
+               0x1ec40, 0x1ec4c,
+               0x1ee40, 0x1ee8c,
+               0x1eec0, 0x1eec0,
+               0x1eee0, 0x1eee0,
+               0x1ef00, 0x1ef84,
+               0x1efc0, 0x1efc8,
+               0x1f040, 0x1f04c,
+               0x1f240, 0x1f28c,
+               0x1f2c0, 0x1f2c0,
+               0x1f2e0, 0x1f2e0,
+               0x1f300, 0x1f384,
+               0x1f3c0, 0x1f3c8,
+               0x1f440, 0x1f44c,
+               0x1f640, 0x1f68c,
+               0x1f6c0, 0x1f6c0,
+               0x1f6e0, 0x1f6e0,
+               0x1f700, 0x1f784,
+               0x1f7c0, 0x1f7c8,
+               0x1f840, 0x1f84c,
+               0x1fa40, 0x1fa8c,
+               0x1fac0, 0x1fac0,
+               0x1fae0, 0x1fae0,
+               0x1fb00, 0x1fb84,
+               0x1fbc0, 0x1fbc8,
+               0x1fc40, 0x1fc4c,
+               0x1fe40, 0x1fe8c,
+               0x1fec0, 0x1fec0,
+               0x1fee0, 0x1fee0,
+               0x1ff00, 0x1ff84,
+               0x1ffc0, 0x1ffc8,
+               0x20000, 0x2002c,
+               0x20100, 0x2013c,
+               0x20190, 0x201c8,
+               0x20200, 0x20318,
+               0x20400, 0x20528,
+               0x20540, 0x20614,
+               0x21000, 0x21040,
+               0x2104c, 0x21060,
+               0x210c0, 0x210ec,
+               0x21200, 0x21268,
+               0x21270, 0x21284,
+               0x212fc, 0x21388,
+               0x21400, 0x21404,
+               0x21500, 0x21518,
+               0x2152c, 0x2153c,
+               0x21550, 0x21554,
+               0x21600, 0x21600,
+               0x21608, 0x21628,
+               0x21630, 0x2163c,
+               0x21700, 0x2171c,
+               0x21780, 0x2178c,
+               0x21800, 0x21c38,
+               0x21c80, 0x21d7c,
+               0x21e00, 0x21e04,
+               0x22000, 0x2202c,
+               0x22100, 0x2213c,
+               0x22190, 0x221c8,
+               0x22200, 0x22318,
+               0x22400, 0x22528,
+               0x22540, 0x22614,
+               0x23000, 0x23040,
+               0x2304c, 0x23060,
+               0x230c0, 0x230ec,
+               0x23200, 0x23268,
+               0x23270, 0x23284,
+               0x232fc, 0x23388,
+               0x23400, 0x23404,
+               0x23500, 0x23518,
+               0x2352c, 0x2353c,
+               0x23550, 0x23554,
+               0x23600, 0x23600,
+               0x23608, 0x23628,
+               0x23630, 0x2363c,
+               0x23700, 0x2371c,
+               0x23780, 0x2378c,
+               0x23800, 0x23c38,
+               0x23c80, 0x23d7c,
+               0x23e00, 0x23e04,
+               0x24000, 0x2402c,
+               0x24100, 0x2413c,
+               0x24190, 0x241c8,
+               0x24200, 0x24318,
+               0x24400, 0x24528,
+               0x24540, 0x24614,
+               0x25000, 0x25040,
+               0x2504c, 0x25060,
+               0x250c0, 0x250ec,
+               0x25200, 0x25268,
+               0x25270, 0x25284,
+               0x252fc, 0x25388,
+               0x25400, 0x25404,
+               0x25500, 0x25518,
+               0x2552c, 0x2553c,
+               0x25550, 0x25554,
+               0x25600, 0x25600,
+               0x25608, 0x25628,
+               0x25630, 0x2563c,
+               0x25700, 0x2571c,
+               0x25780, 0x2578c,
+               0x25800, 0x25c38,
+               0x25c80, 0x25d7c,
+               0x25e00, 0x25e04,
+               0x26000, 0x2602c,
+               0x26100, 0x2613c,
+               0x26190, 0x261c8,
+               0x26200, 0x26318,
+               0x26400, 0x26528,
+               0x26540, 0x26614,
+               0x27000, 0x27040,
+               0x2704c, 0x27060,
+               0x270c0, 0x270ec,
+               0x27200, 0x27268,
+               0x27270, 0x27284,
+               0x272fc, 0x27388,
+               0x27400, 0x27404,
+               0x27500, 0x27518,
+               0x2752c, 0x2753c,
+               0x27550, 0x27554,
+               0x27600, 0x27600,
+               0x27608, 0x27628,
+               0x27630, 0x2763c,
+               0x27700, 0x2771c,
+               0x27780, 0x2778c,
+               0x27800, 0x27c38,
+               0x27c80, 0x27d7c,
+               0x27e00, 0x27e04
+       };
+
+       int i;
+       struct adapter *ap = netdev2adap(dev);
+
+       regs->version = mk_adap_vers(ap);
+
+       memset(buf, 0, T4_REGMAP_SIZE);
+       for (i = 0; i < ARRAY_SIZE(reg_ranges); i += 2)
+               reg_block_dump(ap, buf, reg_ranges[i], reg_ranges[i + 1]);
+}
+
+static int restart_autoneg(struct net_device *dev)
+{
+       struct port_info *p = netdev_priv(dev);
+
+       if (!netif_running(dev))
+               return -EAGAIN;
+       if (p->link_cfg.autoneg != AUTONEG_ENABLE)
+               return -EINVAL;
+       t4_restart_aneg(p->adapter, 0, p->tx_chan);
+       return 0;
+}
+
+static int identify_port(struct net_device *dev, u32 data)
+{
+       if (data == 0)
+               data = 2;     /* default to 2 seconds */
+
+       return t4_identify_port(netdev2adap(dev), 0, netdev2pinfo(dev)->viid,
+                               data * 5);
+}
+
+static unsigned int from_fw_linkcaps(unsigned int type, unsigned int caps)
+{
+       unsigned int v = 0;
+
+       if (type == FW_PORT_TYPE_BT_SGMII || type == FW_PORT_TYPE_BT_XAUI) {
+               v |= SUPPORTED_TP;
+               if (caps & FW_PORT_CAP_SPEED_100M)
+                       v |= SUPPORTED_100baseT_Full;
+               if (caps & FW_PORT_CAP_SPEED_1G)
+                       v |= SUPPORTED_1000baseT_Full;
+               if (caps & FW_PORT_CAP_SPEED_10G)
+                       v |= SUPPORTED_10000baseT_Full;
+       } else if (type == FW_PORT_TYPE_KX4 || type == FW_PORT_TYPE_KX) {
+               v |= SUPPORTED_Backplane;
+               if (caps & FW_PORT_CAP_SPEED_1G)
+                       v |= SUPPORTED_1000baseKX_Full;
+               if (caps & FW_PORT_CAP_SPEED_10G)
+                       v |= SUPPORTED_10000baseKX4_Full;
+       } else if (type == FW_PORT_TYPE_KR)
+               v |= SUPPORTED_Backplane | SUPPORTED_10000baseKR_Full;
+       else if (type == FW_PORT_TYPE_FIBER)
+               v |= SUPPORTED_FIBRE;
+
+       if (caps & FW_PORT_CAP_ANEG)
+               v |= SUPPORTED_Autoneg;
+       return v;
+}
+
+static unsigned int to_fw_linkcaps(unsigned int caps)
+{
+       unsigned int v = 0;
+
+       if (caps & ADVERTISED_100baseT_Full)
+               v |= FW_PORT_CAP_SPEED_100M;
+       if (caps & ADVERTISED_1000baseT_Full)
+               v |= FW_PORT_CAP_SPEED_1G;
+       if (caps & ADVERTISED_10000baseT_Full)
+               v |= FW_PORT_CAP_SPEED_10G;
+       return v;
+}
+
+static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       const struct port_info *p = netdev_priv(dev);
+
+       if (p->port_type == FW_PORT_TYPE_BT_SGMII ||
+           p->port_type == FW_PORT_TYPE_BT_XAUI)
+               cmd->port = PORT_TP;
+       else if (p->port_type == FW_PORT_TYPE_FIBER)
+               cmd->port = PORT_FIBRE;
+       else if (p->port_type == FW_PORT_TYPE_TWINAX)
+               cmd->port = PORT_DA;
+       else
+               cmd->port = PORT_OTHER;
+
+       if (p->mdio_addr >= 0) {
+               cmd->phy_address = p->mdio_addr;
+               cmd->transceiver = XCVR_EXTERNAL;
+               cmd->mdio_support = p->port_type == FW_PORT_TYPE_BT_SGMII ?
+                       MDIO_SUPPORTS_C22 : MDIO_SUPPORTS_C45;
+       } else {
+               cmd->phy_address = 0;  /* not really, but no better option */
+               cmd->transceiver = XCVR_INTERNAL;
+               cmd->mdio_support = 0;
+       }
+
+       cmd->supported = from_fw_linkcaps(p->port_type, p->link_cfg.supported);
+       cmd->advertising = from_fw_linkcaps(p->port_type,
+                                           p->link_cfg.advertising);
+       cmd->speed = netif_carrier_ok(dev) ? p->link_cfg.speed : 0;
+       cmd->duplex = DUPLEX_FULL;
+       cmd->autoneg = p->link_cfg.autoneg;
+       cmd->maxtxpkt = 0;
+       cmd->maxrxpkt = 0;
+       return 0;
+}
+
+static unsigned int speed_to_caps(int speed)
+{
+       if (speed == SPEED_100)
+               return FW_PORT_CAP_SPEED_100M;
+       if (speed == SPEED_1000)
+               return FW_PORT_CAP_SPEED_1G;
+       if (speed == SPEED_10000)
+               return FW_PORT_CAP_SPEED_10G;
+       return 0;
+}
+
+static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       unsigned int cap;
+       struct port_info *p = netdev_priv(dev);
+       struct link_config *lc = &p->link_cfg;
+
+       if (cmd->duplex != DUPLEX_FULL)     /* only full-duplex supported */
+               return -EINVAL;
+
+       if (!(lc->supported & FW_PORT_CAP_ANEG)) {
+               /*
+                * PHY offers a single speed.  See if that's what's
+                * being requested.
+                */
+               if (cmd->autoneg == AUTONEG_DISABLE &&
+                   (lc->supported & speed_to_caps(cmd->speed)))
+                               return 0;
+               return -EINVAL;
+       }
+
+       if (cmd->autoneg == AUTONEG_DISABLE) {
+               cap = speed_to_caps(cmd->speed);
+
+               if (!(lc->supported & cap) || cmd->speed == SPEED_1000 ||
+                   cmd->speed == SPEED_10000)
+                       return -EINVAL;
+               lc->requested_speed = cap;
+               lc->advertising = 0;
+       } else {
+               cap = to_fw_linkcaps(cmd->advertising);
+               if (!(lc->supported & cap))
+                       return -EINVAL;
+               lc->requested_speed = 0;
+               lc->advertising = cap | FW_PORT_CAP_ANEG;
+       }
+       lc->autoneg = cmd->autoneg;
+
+       if (netif_running(dev))
+               return t4_link_start(p->adapter, 0, p->tx_chan, lc);
+       return 0;
+}
+
+static void get_pauseparam(struct net_device *dev,
+                          struct ethtool_pauseparam *epause)
+{
+       struct port_info *p = netdev_priv(dev);
+
+       epause->autoneg = (p->link_cfg.requested_fc & PAUSE_AUTONEG) != 0;
+       epause->rx_pause = (p->link_cfg.fc & PAUSE_RX) != 0;
+       epause->tx_pause = (p->link_cfg.fc & PAUSE_TX) != 0;
+}
+
+static int set_pauseparam(struct net_device *dev,
+                         struct ethtool_pauseparam *epause)
+{
+       struct port_info *p = netdev_priv(dev);
+       struct link_config *lc = &p->link_cfg;
+
+       if (epause->autoneg == AUTONEG_DISABLE)
+               lc->requested_fc = 0;
+       else if (lc->supported & FW_PORT_CAP_ANEG)
+               lc->requested_fc = PAUSE_AUTONEG;
+       else
+               return -EINVAL;
+
+       if (epause->rx_pause)
+               lc->requested_fc |= PAUSE_RX;
+       if (epause->tx_pause)
+               lc->requested_fc |= PAUSE_TX;
+       if (netif_running(dev))
+               return t4_link_start(p->adapter, 0, p->tx_chan, lc);
+       return 0;
+}
+
+static u32 get_rx_csum(struct net_device *dev)
+{
+       struct port_info *p = netdev_priv(dev);
+
+       return p->rx_offload & RX_CSO;
+}
+
+static int set_rx_csum(struct net_device *dev, u32 data)
+{
+       struct port_info *p = netdev_priv(dev);
+
+       if (data)
+               p->rx_offload |= RX_CSO;
+       else
+               p->rx_offload &= ~RX_CSO;
+       return 0;
+}
+
+static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
+{
+       const struct port_info *pi = netdev_priv(dev);
+       const struct sge *s = &pi->adapter->sge;
+
+       e->rx_max_pending = MAX_RX_BUFFERS;
+       e->rx_mini_max_pending = MAX_RSPQ_ENTRIES;
+       e->rx_jumbo_max_pending = 0;
+       e->tx_max_pending = MAX_TXQ_ENTRIES;
+
+       e->rx_pending = s->ethrxq[pi->first_qset].fl.size - 8;
+       e->rx_mini_pending = s->ethrxq[pi->first_qset].rspq.size;
+       e->rx_jumbo_pending = 0;
+       e->tx_pending = s->ethtxq[pi->first_qset].q.size;
+}
+
+static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
+{
+       int i;
+       const struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
+       struct sge *s = &adapter->sge;
+
+       if (e->rx_pending > MAX_RX_BUFFERS || e->rx_jumbo_pending ||
+           e->tx_pending > MAX_TXQ_ENTRIES ||
+           e->rx_mini_pending > MAX_RSPQ_ENTRIES ||
+           e->rx_mini_pending < MIN_RSPQ_ENTRIES ||
+           e->rx_pending < MIN_FL_ENTRIES || e->tx_pending < MIN_TXQ_ENTRIES)
+               return -EINVAL;
+
+       if (adapter->flags & FULL_INIT_DONE)
+               return -EBUSY;
+
+       for (i = 0; i < pi->nqsets; ++i) {
+               s->ethtxq[pi->first_qset + i].q.size = e->tx_pending;
+               s->ethrxq[pi->first_qset + i].fl.size = e->rx_pending + 8;
+               s->ethrxq[pi->first_qset + i].rspq.size = e->rx_mini_pending;
+       }
+       return 0;
+}
+
+static int closest_timer(const struct sge *s, int time)
+{
+       int i, delta, match = 0, min_delta = INT_MAX;
+
+       for (i = 0; i < ARRAY_SIZE(s->timer_val); i++) {
+               delta = time - s->timer_val[i];
+               if (delta < 0)
+                       delta = -delta;
+               if (delta < min_delta) {
+                       min_delta = delta;
+                       match = i;
+               }
+       }
+       return match;
+}
+
+static int closest_thres(const struct sge *s, int thres)
+{
+       int i, delta, match = 0, min_delta = INT_MAX;
+
+       for (i = 0; i < ARRAY_SIZE(s->counter_val); i++) {
+               delta = thres - s->counter_val[i];
+               if (delta < 0)
+                       delta = -delta;
+               if (delta < min_delta) {
+                       min_delta = delta;
+                       match = i;
+               }
+       }
+       return match;
+}
+
+/*
+ * Return a queue's interrupt hold-off time in us.  0 means no timer.
+ */
+static unsigned int qtimer_val(const struct adapter *adap,
+                              const struct sge_rspq *q)
+{
+       unsigned int idx = q->intr_params >> 1;
+
+       return idx < SGE_NTIMERS ? adap->sge.timer_val[idx] : 0;
+}
+
+/**
+ *     set_rxq_intr_params - set a queue's interrupt holdoff parameters
+ *     @adap: the adapter
+ *     @q: the Rx queue
+ *     @us: the hold-off time in us, or 0 to disable timer
+ *     @cnt: the hold-off packet count, or 0 to disable counter
+ *
+ *     Sets an Rx queue's interrupt hold-off time and packet count.  At least
+ *     one of the two needs to be enabled for the queue to generate interrupts.
+ */
+static int set_rxq_intr_params(struct adapter *adap, struct sge_rspq *q,
+                              unsigned int us, unsigned int cnt)
+{
+       if ((us | cnt) == 0)
+               cnt = 1;
+
+       if (cnt) {
+               int err;
+               u32 v, new_idx;
+
+               new_idx = closest_thres(&adap->sge, cnt);
+               if (q->desc && q->pktcnt_idx != new_idx) {
+                       /* the queue has already been created, update it */
+                       v = FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) |
+                           FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DMAQ_IQ_INTCNTTHRESH) |
+                           FW_PARAMS_PARAM_YZ(q->cntxt_id);
+                       err = t4_set_params(adap, 0, 0, 0, 1, &v, &new_idx);
+                       if (err)
+                               return err;
+               }
+               q->pktcnt_idx = new_idx;
+       }
+
+       us = us == 0 ? 6 : closest_timer(&adap->sge, us);
+       q->intr_params = QINTR_TIMER_IDX(us) | (cnt > 0 ? QINTR_CNT_EN : 0);
+       return 0;
+}
+
+static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
+{
+       const struct port_info *pi = netdev_priv(dev);
+       struct adapter *adap = pi->adapter;
+
+       return set_rxq_intr_params(adap, &adap->sge.ethrxq[pi->first_qset].rspq,
+                       c->rx_coalesce_usecs, c->rx_max_coalesced_frames);
+}
+
+static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
+{
+       const struct port_info *pi = netdev_priv(dev);
+       const struct adapter *adap = pi->adapter;
+       const struct sge_rspq *rq = &adap->sge.ethrxq[pi->first_qset].rspq;
+
+       c->rx_coalesce_usecs = qtimer_val(adap, rq);
+       c->rx_max_coalesced_frames = (rq->intr_params & QINTR_CNT_EN) ?
+               adap->sge.counter_val[rq->pktcnt_idx] : 0;
+       return 0;
+}
+
+/*
+ * Translate a physical EEPROM address to virtual.  The first 1K is accessed
+ * through virtual addresses starting at 31K, the rest is accessed through
+ * virtual addresses starting at 0.  This mapping is correct only for PF0.
+ */
+static int eeprom_ptov(unsigned int phys_addr)
+{
+       if (phys_addr < 1024)
+               return phys_addr + (31 << 10);
+       if (phys_addr < EEPROMSIZE)
+               return phys_addr - 1024;
+       return -EINVAL;
+}
+
+/*
+ * The next two routines implement eeprom read/write from physical addresses.
+ * The physical->virtual translation is correct only for PF0.
+ */
+static int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v)
+{
+       int vaddr = eeprom_ptov(phys_addr);
+
+       if (vaddr >= 0)
+               vaddr = pci_read_vpd(adap->pdev, vaddr, sizeof(u32), v);
+       return vaddr < 0 ? vaddr : 0;
+}
+
+static int eeprom_wr_phys(struct adapter *adap, unsigned int phys_addr, u32 v)
+{
+       int vaddr = eeprom_ptov(phys_addr);
+
+       if (vaddr >= 0)
+               vaddr = pci_write_vpd(adap->pdev, vaddr, sizeof(u32), &v);
+       return vaddr < 0 ? vaddr : 0;
+}
+
+#define EEPROM_MAGIC 0x38E2F10C
+
+static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
+                     u8 *data)
+{
+       int i, err = 0;
+       struct adapter *adapter = netdev2adap(dev);
+
+       u8 *buf = kmalloc(EEPROMSIZE, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       e->magic = EEPROM_MAGIC;
+       for (i = e->offset & ~3; !err && i < e->offset + e->len; i += 4)
+               err = eeprom_rd_phys(adapter, i, (u32 *)&buf[i]);
+
+       if (!err)
+               memcpy(data, buf + e->offset, e->len);
+       kfree(buf);
+       return err;
+}
+
+static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+                     u8 *data)
+{
+       u8 *buf;
+       int err = 0;
+       u32 aligned_offset, aligned_len, *p;
+       struct adapter *adapter = netdev2adap(dev);
+
+       if (eeprom->magic != EEPROM_MAGIC)
+               return -EINVAL;
+
+       aligned_offset = eeprom->offset & ~3;
+       aligned_len = (eeprom->len + (eeprom->offset & 3) + 3) & ~3;
+
+       if (aligned_offset != eeprom->offset || aligned_len != eeprom->len) {
+               /*
+                * RMW possibly needed for first or last words.
+                */
+               buf = kmalloc(aligned_len, GFP_KERNEL);
+               if (!buf)
+                       return -ENOMEM;
+               err = eeprom_rd_phys(adapter, aligned_offset, (u32 *)buf);
+               if (!err && aligned_len > 4)
+                       err = eeprom_rd_phys(adapter,
+                                            aligned_offset + aligned_len - 4,
+                                            (u32 *)&buf[aligned_len - 4]);
+               if (err)
+                       goto out;
+               memcpy(buf + (eeprom->offset & 3), data, eeprom->len);
+       } else
+               buf = data;
+
+       err = t4_seeprom_wp(adapter, false);
+       if (err)
+               goto out;
+
+       for (p = (u32 *)buf; !err && aligned_len; aligned_len -= 4, p++) {
+               err = eeprom_wr_phys(adapter, aligned_offset, *p);
+               aligned_offset += 4;
+       }
+
+       if (!err)
+               err = t4_seeprom_wp(adapter, true);
+out:
+       if (buf != data)
+               kfree(buf);
+       return err;
+}
+
+static int set_flash(struct net_device *netdev, struct ethtool_flash *ef)
+{
+       int ret;
+       const struct firmware *fw;
+       struct adapter *adap = netdev2adap(netdev);
+
+       ef->data[sizeof(ef->data) - 1] = '\0';
+       ret = request_firmware(&fw, ef->data, adap->pdev_dev);
+       if (ret < 0)
+               return ret;
+
+       ret = t4_load_fw(adap, fw->data, fw->size);
+       release_firmware(fw);
+       if (!ret)
+               dev_info(adap->pdev_dev, "loaded firmware %s\n", ef->data);
+       return ret;
+}
+
+#define WOL_SUPPORTED (WAKE_BCAST | WAKE_MAGIC)
+#define BCAST_CRC 0xa0ccc1a6
+
+static void get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       wol->supported = WAKE_BCAST | WAKE_MAGIC;
+       wol->wolopts = netdev2adap(dev)->wol;
+       memset(&wol->sopass, 0, sizeof(wol->sopass));
+}
+
+static int set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       int err = 0;
+       struct port_info *pi = netdev_priv(dev);
+
+       if (wol->wolopts & ~WOL_SUPPORTED)
+               return -EINVAL;
+       t4_wol_magic_enable(pi->adapter, pi->tx_chan,
+                           (wol->wolopts & WAKE_MAGIC) ? dev->dev_addr : NULL);
+       if (wol->wolopts & WAKE_BCAST) {
+               err = t4_wol_pat_enable(pi->adapter, pi->tx_chan, 0xfe, ~0ULL,
+                                       ~0ULL, 0, false);
+               if (!err)
+                       err = t4_wol_pat_enable(pi->adapter, pi->tx_chan, 1,
+                                               ~6ULL, ~0ULL, BCAST_CRC, true);
+       } else
+               t4_wol_pat_enable(pi->adapter, pi->tx_chan, 0, 0, 0, 0, false);
+       return err;
+}
+
+static int set_tso(struct net_device *dev, u32 value)
+{
+       if (value)
+               dev->features |= NETIF_F_TSO | NETIF_F_TSO6;
+       else
+               dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+       return 0;
+}
+
+static struct ethtool_ops cxgb_ethtool_ops = {
+       .get_settings      = get_settings,
+       .set_settings      = set_settings,
+       .get_drvinfo       = get_drvinfo,
+       .get_msglevel      = get_msglevel,
+       .set_msglevel      = set_msglevel,
+       .get_ringparam     = get_sge_param,
+       .set_ringparam     = set_sge_param,
+       .get_coalesce      = get_coalesce,
+       .set_coalesce      = set_coalesce,
+       .get_eeprom_len    = get_eeprom_len,
+       .get_eeprom        = get_eeprom,
+       .set_eeprom        = set_eeprom,
+       .get_pauseparam    = get_pauseparam,
+       .set_pauseparam    = set_pauseparam,
+       .get_rx_csum       = get_rx_csum,
+       .set_rx_csum       = set_rx_csum,
+       .set_tx_csum       = ethtool_op_set_tx_ipv6_csum,
+       .set_sg            = ethtool_op_set_sg,
+       .get_link          = ethtool_op_get_link,
+       .get_strings       = get_strings,
+       .phys_id           = identify_port,
+       .nway_reset        = restart_autoneg,
+       .get_sset_count    = get_sset_count,
+       .get_ethtool_stats = get_stats,
+       .get_regs_len      = get_regs_len,
+       .get_regs          = get_regs,
+       .get_wol           = get_wol,
+       .set_wol           = set_wol,
+       .set_tso           = set_tso,
+       .flash_device      = set_flash,
+};
+
+/*
+ * debugfs support
+ */
+
+static int mem_open(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       return 0;
+}
+
+static ssize_t mem_read(struct file *file, char __user *buf, size_t count,
+                       loff_t *ppos)
+{
+       loff_t pos = *ppos;
+       loff_t avail = file->f_path.dentry->d_inode->i_size;
+       unsigned int mem = (uintptr_t)file->private_data & 3;
+       struct adapter *adap = file->private_data - mem;
+
+       if (pos < 0)
+               return -EINVAL;
+       if (pos >= avail)
+               return 0;
+       if (count > avail - pos)
+               count = avail - pos;
+
+       while (count) {
+               size_t len;
+               int ret, ofst;
+               __be32 data[16];
+
+               if (mem == MEM_MC)
+                       ret = t4_mc_read(adap, pos, data, NULL);
+               else
+                       ret = t4_edc_read(adap, mem, pos, data, NULL);
+               if (ret)
+                       return ret;
+
+               ofst = pos % sizeof(data);
+               len = min(count, sizeof(data) - ofst);
+               if (copy_to_user(buf, (u8 *)data + ofst, len))
+                       return -EFAULT;
+
+               buf += len;
+               pos += len;
+               count -= len;
+       }
+       count = pos - *ppos;
+       *ppos = pos;
+       return count;
+}
+
+static const struct file_operations mem_debugfs_fops = {
+       .owner   = THIS_MODULE,
+       .open    = mem_open,
+       .read    = mem_read,
+};
+
+static void __devinit add_debugfs_mem(struct adapter *adap, const char *name,
+                                     unsigned int idx, unsigned int size_mb)
+{
+       struct dentry *de;
+
+       de = debugfs_create_file(name, S_IRUSR, adap->debugfs_root,
+                                (void *)adap + idx, &mem_debugfs_fops);
+       if (de && de->d_inode)
+               de->d_inode->i_size = size_mb << 20;
+}
+
+static int __devinit setup_debugfs(struct adapter *adap)
+{
+       int i;
+
+       if (IS_ERR_OR_NULL(adap->debugfs_root))
+               return -1;
+
+       i = t4_read_reg(adap, MA_TARGET_MEM_ENABLE);
+       if (i & EDRAM0_ENABLE)
+               add_debugfs_mem(adap, "edc0", MEM_EDC0, 5);
+       if (i & EDRAM1_ENABLE)
+               add_debugfs_mem(adap, "edc1", MEM_EDC1, 5);
+       if (i & EXT_MEM_ENABLE)
+               add_debugfs_mem(adap, "mc", MEM_MC,
+                       EXT_MEM_SIZE_GET(t4_read_reg(adap, MA_EXT_MEMORY_BAR)));
+       if (adap->l2t)
+               debugfs_create_file("l2t", S_IRUSR, adap->debugfs_root, adap,
+                                   &t4_l2t_fops);
+       return 0;
+}
+
+/*
+ * upper-layer driver support
+ */
+
+/*
+ * Allocate an active-open TID and set it to the supplied value.
+ */
+int cxgb4_alloc_atid(struct tid_info *t, void *data)
+{
+       int atid = -1;
+
+       spin_lock_bh(&t->atid_lock);
+       if (t->afree) {
+               union aopen_entry *p = t->afree;
+
+               atid = p - t->atid_tab;
+               t->afree = p->next;
+               p->data = data;
+               t->atids_in_use++;
+       }
+       spin_unlock_bh(&t->atid_lock);
+       return atid;
+}
+EXPORT_SYMBOL(cxgb4_alloc_atid);
+
+/*
+ * Release an active-open TID.
+ */
+void cxgb4_free_atid(struct tid_info *t, unsigned int atid)
+{
+       union aopen_entry *p = &t->atid_tab[atid];
+
+       spin_lock_bh(&t->atid_lock);
+       p->next = t->afree;
+       t->afree = p;
+       t->atids_in_use--;
+       spin_unlock_bh(&t->atid_lock);
+}
+EXPORT_SYMBOL(cxgb4_free_atid);
+
+/*
+ * Allocate a server TID and set it to the supplied value.
+ */
+int cxgb4_alloc_stid(struct tid_info *t, int family, void *data)
+{
+       int stid;
+
+       spin_lock_bh(&t->stid_lock);
+       if (family == PF_INET) {
+               stid = find_first_zero_bit(t->stid_bmap, t->nstids);
+               if (stid < t->nstids)
+                       __set_bit(stid, t->stid_bmap);
+               else
+                       stid = -1;
+       } else {
+               stid = bitmap_find_free_region(t->stid_bmap, t->nstids, 2);
+               if (stid < 0)
+                       stid = -1;
+       }
+       if (stid >= 0) {
+               t->stid_tab[stid].data = data;
+               stid += t->stid_base;
+               t->stids_in_use++;
+       }
+       spin_unlock_bh(&t->stid_lock);
+       return stid;
+}
+EXPORT_SYMBOL(cxgb4_alloc_stid);
+
+/*
+ * Release a server TID.
+ */
+void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family)
+{
+       stid -= t->stid_base;
+       spin_lock_bh(&t->stid_lock);
+       if (family == PF_INET)
+               __clear_bit(stid, t->stid_bmap);
+       else
+               bitmap_release_region(t->stid_bmap, stid, 2);
+       t->stid_tab[stid].data = NULL;
+       t->stids_in_use--;
+       spin_unlock_bh(&t->stid_lock);
+}
+EXPORT_SYMBOL(cxgb4_free_stid);
+
+/*
+ * Populate a TID_RELEASE WR.  Caller must properly size the skb.
+ */
+static void mk_tid_release(struct sk_buff *skb, unsigned int chan,
+                          unsigned int tid)
+{
+       struct cpl_tid_release *req;
+
+       set_wr_txq(skb, CPL_PRIORITY_SETUP, chan);
+       req = (struct cpl_tid_release *)__skb_put(skb, sizeof(*req));
+       INIT_TP_WR(req, tid);
+       OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, tid));
+}
+
+/*
+ * Queue a TID release request and if necessary schedule a work queue to
+ * process it.
+ */
+void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan,
+                            unsigned int tid)
+{
+       void **p = &t->tid_tab[tid];
+       struct adapter *adap = container_of(t, struct adapter, tids);
+
+       spin_lock_bh(&adap->tid_release_lock);
+       *p = adap->tid_release_head;
+       /* Low 2 bits encode the Tx channel number */
+       adap->tid_release_head = (void **)((uintptr_t)p | chan);
+       if (!adap->tid_release_task_busy) {
+               adap->tid_release_task_busy = true;
+               schedule_work(&adap->tid_release_task);
+       }
+       spin_unlock_bh(&adap->tid_release_lock);
+}
+EXPORT_SYMBOL(cxgb4_queue_tid_release);
+
+/*
+ * Process the list of pending TID release requests.
+ */
+static void process_tid_release_list(struct work_struct *work)
+{
+       struct sk_buff *skb;
+       struct adapter *adap;
+
+       adap = container_of(work, struct adapter, tid_release_task);
+
+       spin_lock_bh(&adap->tid_release_lock);
+       while (adap->tid_release_head) {
+               void **p = adap->tid_release_head;
+               unsigned int chan = (uintptr_t)p & 3;
+               p = (void *)p - chan;
+
+               adap->tid_release_head = *p;
+               *p = NULL;
+               spin_unlock_bh(&adap->tid_release_lock);
+
+               while (!(skb = alloc_skb(sizeof(struct cpl_tid_release),
+                                        GFP_KERNEL)))
+                       schedule_timeout_uninterruptible(1);
+
+               mk_tid_release(skb, chan, p - adap->tids.tid_tab);
+               t4_ofld_send(adap, skb);
+               spin_lock_bh(&adap->tid_release_lock);
+       }
+       adap->tid_release_task_busy = false;
+       spin_unlock_bh(&adap->tid_release_lock);
+}
+
+/*
+ * Release a TID and inform HW.  If we are unable to allocate the release
+ * message we defer to a work queue.
+ */
+void cxgb4_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid)
+{
+       void *old;
+       struct sk_buff *skb;
+       struct adapter *adap = container_of(t, struct adapter, tids);
+
+       old = t->tid_tab[tid];
+       skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_ATOMIC);
+       if (likely(skb)) {
+               t->tid_tab[tid] = NULL;
+               mk_tid_release(skb, chan, tid);
+               t4_ofld_send(adap, skb);
+       } else
+               cxgb4_queue_tid_release(t, chan, tid);
+       if (old)
+               atomic_dec(&t->tids_in_use);
+}
+EXPORT_SYMBOL(cxgb4_remove_tid);
+
+/*
+ * Allocate and initialize the TID tables.  Returns 0 on success.
+ */
+static int tid_init(struct tid_info *t)
+{
+       size_t size;
+       unsigned int natids = t->natids;
+
+       size = t->ntids * sizeof(*t->tid_tab) + natids * sizeof(*t->atid_tab) +
+              t->nstids * sizeof(*t->stid_tab) +
+              BITS_TO_LONGS(t->nstids) * sizeof(long);
+       t->tid_tab = t4_alloc_mem(size);
+       if (!t->tid_tab)
+               return -ENOMEM;
+
+       t->atid_tab = (union aopen_entry *)&t->tid_tab[t->ntids];
+       t->stid_tab = (struct serv_entry *)&t->atid_tab[natids];
+       t->stid_bmap = (unsigned long *)&t->stid_tab[t->nstids];
+       spin_lock_init(&t->stid_lock);
+       spin_lock_init(&t->atid_lock);
+
+       t->stids_in_use = 0;
+       t->afree = NULL;
+       t->atids_in_use = 0;
+       atomic_set(&t->tids_in_use, 0);
+
+       /* Setup the free list for atid_tab and clear the stid bitmap. */
+       if (natids) {
+               while (--natids)
+                       t->atid_tab[natids - 1].next = &t->atid_tab[natids];
+               t->afree = t->atid_tab;
+       }
+       bitmap_zero(t->stid_bmap, t->nstids);
+       return 0;
+}
+
+/**
+ *     cxgb4_create_server - create an IP server
+ *     @dev: the device
+ *     @stid: the server TID
+ *     @sip: local IP address to bind server to
+ *     @sport: the server's TCP port
+ *     @queue: queue to direct messages from this server to
+ *
+ *     Create an IP server for the given port and address.
+ *     Returns <0 on error and one of the %NET_XMIT_* values on success.
+ */
+int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
+                       __be32 sip, __be16 sport, unsigned int queue)
+{
+       unsigned int chan;
+       struct sk_buff *skb;
+       struct adapter *adap;
+       struct cpl_pass_open_req *req;
+
+       skb = alloc_skb(sizeof(*req), GFP_KERNEL);
+       if (!skb)
+               return -ENOMEM;
+
+       adap = netdev2adap(dev);
+       req = (struct cpl_pass_open_req *)__skb_put(skb, sizeof(*req));
+       INIT_TP_WR(req, 0);
+       OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ, stid));
+       req->local_port = sport;
+       req->peer_port = htons(0);
+       req->local_ip = sip;
+       req->peer_ip = htonl(0);
+       chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan;
+       req->opt0 = cpu_to_be64(TX_CHAN(chan));
+       req->opt1 = cpu_to_be64(CONN_POLICY_ASK |
+                               SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue));
+       return t4_mgmt_tx(adap, skb);
+}
+EXPORT_SYMBOL(cxgb4_create_server);
+
+/**
+ *     cxgb4_create_server6 - create an IPv6 server
+ *     @dev: the device
+ *     @stid: the server TID
+ *     @sip: local IPv6 address to bind server to
+ *     @sport: the server's TCP port
+ *     @queue: queue to direct messages from this server to
+ *
+ *     Create an IPv6 server for the given port and address.
+ *     Returns <0 on error and one of the %NET_XMIT_* values on success.
+ */
+int cxgb4_create_server6(const struct net_device *dev, unsigned int stid,
+                        const struct in6_addr *sip, __be16 sport,
+                        unsigned int queue)
+{
+       unsigned int chan;
+       struct sk_buff *skb;
+       struct adapter *adap;
+       struct cpl_pass_open_req6 *req;
+
+       skb = alloc_skb(sizeof(*req), GFP_KERNEL);
+       if (!skb)
+               return -ENOMEM;
+
+       adap = netdev2adap(dev);
+       req = (struct cpl_pass_open_req6 *)__skb_put(skb, sizeof(*req));
+       INIT_TP_WR(req, 0);
+       OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ6, stid));
+       req->local_port = sport;
+       req->peer_port = htons(0);
+       req->local_ip_hi = *(__be64 *)(sip->s6_addr);
+       req->local_ip_lo = *(__be64 *)(sip->s6_addr + 8);
+       req->peer_ip_hi = cpu_to_be64(0);
+       req->peer_ip_lo = cpu_to_be64(0);
+       chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan;
+       req->opt0 = cpu_to_be64(TX_CHAN(chan));
+       req->opt1 = cpu_to_be64(CONN_POLICY_ASK |
+                               SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue));
+       return t4_mgmt_tx(adap, skb);
+}
+EXPORT_SYMBOL(cxgb4_create_server6);
+
+/**
+ *     cxgb4_best_mtu - find the entry in the MTU table closest to an MTU
+ *     @mtus: the HW MTU table
+ *     @mtu: the target MTU
+ *     @idx: index of selected entry in the MTU table
+ *
+ *     Returns the index and the value in the HW MTU table that is closest to
+ *     but does not exceed @mtu, unless @mtu is smaller than any value in the
+ *     table, in which case that smallest available value is selected.
+ */
+unsigned int cxgb4_best_mtu(const unsigned short *mtus, unsigned short mtu,
+                           unsigned int *idx)
+{
+       unsigned int i = 0;
+
+       while (i < NMTUS - 1 && mtus[i + 1] <= mtu)
+               ++i;
+       if (idx)
+               *idx = i;
+       return mtus[i];
+}
+EXPORT_SYMBOL(cxgb4_best_mtu);
+
+/**
+ *     cxgb4_port_chan - get the HW channel of a port
+ *     @dev: the net device for the port
+ *
+ *     Return the HW Tx channel of the given port.
+ */
+unsigned int cxgb4_port_chan(const struct net_device *dev)
+{
+       return netdev2pinfo(dev)->tx_chan;
+}
+EXPORT_SYMBOL(cxgb4_port_chan);
+
+/**
+ *     cxgb4_port_viid - get the VI id of a port
+ *     @dev: the net device for the port
+ *
+ *     Return the VI id of the given port.
+ */
+unsigned int cxgb4_port_viid(const struct net_device *dev)
+{
+       return netdev2pinfo(dev)->viid;
+}
+EXPORT_SYMBOL(cxgb4_port_viid);
+
+/**
+ *     cxgb4_port_idx - get the index of a port
+ *     @dev: the net device for the port
+ *
+ *     Return the index of the given port.
+ */
+unsigned int cxgb4_port_idx(const struct net_device *dev)
+{
+       return netdev2pinfo(dev)->port_id;
+}
+EXPORT_SYMBOL(cxgb4_port_idx);
+
+/**
+ *     cxgb4_netdev_by_hwid - return the net device of a HW port
+ *     @pdev: identifies the adapter
+ *     @id: the HW port id
+ *
+ *     Return the net device associated with the interface with the given HW
+ *     id.
+ */
+struct net_device *cxgb4_netdev_by_hwid(struct pci_dev *pdev, unsigned int id)
+{
+       const struct adapter *adap = pci_get_drvdata(pdev);
+
+       if (!adap || id >= NCHAN)
+               return NULL;
+       id = adap->chan_map[id];
+       return id < MAX_NPORTS ? adap->port[id] : NULL;
+}
+EXPORT_SYMBOL(cxgb4_netdev_by_hwid);
+
+void cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4,
+                        struct tp_tcp_stats *v6)
+{
+       struct adapter *adap = pci_get_drvdata(pdev);
+
+       spin_lock(&adap->stats_lock);
+       t4_tp_get_tcp_stats(adap, v4, v6);
+       spin_unlock(&adap->stats_lock);
+}
+EXPORT_SYMBOL(cxgb4_get_tcp_stats);
+
+void cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask,
+                     const unsigned int *pgsz_order)
+{
+       struct adapter *adap = netdev2adap(dev);
+
+       t4_write_reg(adap, ULP_RX_ISCSI_TAGMASK, tag_mask);
+       t4_write_reg(adap, ULP_RX_ISCSI_PSZ, HPZ0(pgsz_order[0]) |
+                    HPZ1(pgsz_order[1]) | HPZ2(pgsz_order[2]) |
+                    HPZ3(pgsz_order[3]));
+}
+EXPORT_SYMBOL(cxgb4_iscsi_init);
+
+static struct pci_driver cxgb4_driver;
+
+static void check_neigh_update(struct neighbour *neigh)
+{
+       const struct device *parent;
+       const struct net_device *netdev = neigh->dev;
+
+       if (netdev->priv_flags & IFF_802_1Q_VLAN)
+               netdev = vlan_dev_real_dev(netdev);
+       parent = netdev->dev.parent;
+       if (parent && parent->driver == &cxgb4_driver.driver)
+               t4_l2t_update(dev_get_drvdata(parent), neigh);
+}
+
+static int netevent_cb(struct notifier_block *nb, unsigned long event,
+                      void *data)
+{
+       switch (event) {
+       case NETEVENT_NEIGH_UPDATE:
+               check_neigh_update(data);
+               break;
+       case NETEVENT_PMTU_UPDATE:
+       case NETEVENT_REDIRECT:
+       default:
+               break;
+       }
+       return 0;
+}
+
+static bool netevent_registered;
+static struct notifier_block cxgb4_netevent_nb = {
+       .notifier_call = netevent_cb
+};
+
+static void uld_attach(struct adapter *adap, unsigned int uld)
+{
+       void *handle;
+       struct cxgb4_lld_info lli;
+
+       lli.pdev = adap->pdev;
+       lli.l2t = adap->l2t;
+       lli.tids = &adap->tids;
+       lli.ports = adap->port;
+       lli.vr = &adap->vres;
+       lli.mtus = adap->params.mtus;
+       if (uld == CXGB4_ULD_RDMA) {
+               lli.rxq_ids = adap->sge.rdma_rxq;
+               lli.nrxq = adap->sge.rdmaqs;
+       } else if (uld == CXGB4_ULD_ISCSI) {
+               lli.rxq_ids = adap->sge.ofld_rxq;
+               lli.nrxq = adap->sge.ofldqsets;
+       }
+       lli.ntxq = adap->sge.ofldqsets;
+       lli.nchan = adap->params.nports;
+       lli.nports = adap->params.nports;
+       lli.wr_cred = adap->params.ofldq_wr_cred;
+       lli.adapter_type = adap->params.rev;
+       lli.iscsi_iolen = MAXRXDATA_GET(t4_read_reg(adap, TP_PARA_REG2));
+       lli.udb_density = 1 << QUEUESPERPAGEPF0_GET(
+                       t4_read_reg(adap, SGE_EGRESS_QUEUES_PER_PAGE_PF));
+       lli.ucq_density = 1 << QUEUESPERPAGEPF0_GET(
+                       t4_read_reg(adap, SGE_INGRESS_QUEUES_PER_PAGE_PF));
+       lli.gts_reg = adap->regs + MYPF_REG(SGE_PF_GTS);
+       lli.db_reg = adap->regs + MYPF_REG(SGE_PF_KDOORBELL);
+       lli.fw_vers = adap->params.fw_vers;
+
+       handle = ulds[uld].add(&lli);
+       if (IS_ERR(handle)) {
+               dev_warn(adap->pdev_dev,
+                        "could not attach to the %s driver, error %ld\n",
+                        uld_str[uld], PTR_ERR(handle));
+               return;
+       }
+
+       adap->uld_handle[uld] = handle;
+
+       if (!netevent_registered) {
+               register_netevent_notifier(&cxgb4_netevent_nb);
+               netevent_registered = true;
+       }
+}
+
+static void attach_ulds(struct adapter *adap)
+{
+       unsigned int i;
+
+       mutex_lock(&uld_mutex);
+       list_add_tail(&adap->list_node, &adapter_list);
+       for (i = 0; i < CXGB4_ULD_MAX; i++)
+               if (ulds[i].add)
+                       uld_attach(adap, i);
+       mutex_unlock(&uld_mutex);
+}
+
+static void detach_ulds(struct adapter *adap)
+{
+       unsigned int i;
+
+       mutex_lock(&uld_mutex);
+       list_del(&adap->list_node);
+       for (i = 0; i < CXGB4_ULD_MAX; i++)
+               if (adap->uld_handle[i]) {
+                       ulds[i].state_change(adap->uld_handle[i],
+                                            CXGB4_STATE_DETACH);
+                       adap->uld_handle[i] = NULL;
+               }
+       if (netevent_registered && list_empty(&adapter_list)) {
+               unregister_netevent_notifier(&cxgb4_netevent_nb);
+               netevent_registered = false;
+       }
+       mutex_unlock(&uld_mutex);
+}
+
+static void notify_ulds(struct adapter *adap, enum cxgb4_state new_state)
+{
+       unsigned int i;
+
+       mutex_lock(&uld_mutex);
+       for (i = 0; i < CXGB4_ULD_MAX; i++)
+               if (adap->uld_handle[i])
+                       ulds[i].state_change(adap->uld_handle[i], new_state);
+       mutex_unlock(&uld_mutex);
+}
+
+/**
+ *     cxgb4_register_uld - register an upper-layer driver
+ *     @type: the ULD type
+ *     @p: the ULD methods
+ *
+ *     Registers an upper-layer driver with this driver and notifies the ULD
+ *     about any presently available devices that support its type.  Returns
+ *     %-EBUSY if a ULD of the same type is already registered.
+ */
+int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p)
+{
+       int ret = 0;
+       struct adapter *adap;
+
+       if (type >= CXGB4_ULD_MAX)
+               return -EINVAL;
+       mutex_lock(&uld_mutex);
+       if (ulds[type].add) {
+               ret = -EBUSY;
+               goto out;
+       }
+       ulds[type] = *p;
+       list_for_each_entry(adap, &adapter_list, list_node)
+               uld_attach(adap, type);
+out:   mutex_unlock(&uld_mutex);
+       return ret;
+}
+EXPORT_SYMBOL(cxgb4_register_uld);
+
+/**
+ *     cxgb4_unregister_uld - unregister an upper-layer driver
+ *     @type: the ULD type
+ *
+ *     Unregisters an existing upper-layer driver.
+ */
+int cxgb4_unregister_uld(enum cxgb4_uld type)
+{
+       struct adapter *adap;
+
+       if (type >= CXGB4_ULD_MAX)
+               return -EINVAL;
+       mutex_lock(&uld_mutex);
+       list_for_each_entry(adap, &adapter_list, list_node)
+               adap->uld_handle[type] = NULL;
+       ulds[type].add = NULL;
+       mutex_unlock(&uld_mutex);
+       return 0;
+}
+EXPORT_SYMBOL(cxgb4_unregister_uld);
+
+/**
+ *     cxgb_up - enable the adapter
+ *     @adap: adapter being enabled
+ *
+ *     Called when the first port is enabled, this function performs the
+ *     actions necessary to make an adapter operational, such as completing
+ *     the initialization of HW modules, and enabling interrupts.
+ *
+ *     Must be called with the rtnl lock held.
+ */
+static int cxgb_up(struct adapter *adap)
+{
+       int err = 0;
+
+       if (!(adap->flags & FULL_INIT_DONE)) {
+               err = setup_sge_queues(adap);
+               if (err)
+                       goto out;
+               err = setup_rss(adap);
+               if (err) {
+                       t4_free_sge_resources(adap);
+                       goto out;
+               }
+               if (adap->flags & USING_MSIX)
+                       name_msix_vecs(adap);
+               adap->flags |= FULL_INIT_DONE;
+       }
+
+       if (adap->flags & USING_MSIX) {
+               err = request_irq(adap->msix_info[0].vec, t4_nondata_intr, 0,
+                                 adap->msix_info[0].desc, adap);
+               if (err)
+                       goto irq_err;
+
+               err = request_msix_queue_irqs(adap);
+               if (err) {
+                       free_irq(adap->msix_info[0].vec, adap);
+                       goto irq_err;
+               }
+       } else {
+               err = request_irq(adap->pdev->irq, t4_intr_handler(adap),
+                                 (adap->flags & USING_MSI) ? 0 : IRQF_SHARED,
+                                 adap->name, adap);
+               if (err)
+                       goto irq_err;
+       }
+       enable_rx(adap);
+       t4_sge_start(adap);
+       t4_intr_enable(adap);
+       notify_ulds(adap, CXGB4_STATE_UP);
+ out:
+       return err;
+ irq_err:
+       dev_err(adap->pdev_dev, "request_irq failed, err %d\n", err);
+       goto out;
+}
+
+static void cxgb_down(struct adapter *adapter)
+{
+       t4_intr_disable(adapter);
+       cancel_work_sync(&adapter->tid_release_task);
+       adapter->tid_release_task_busy = false;
+
+       if (adapter->flags & USING_MSIX) {
+               free_msix_queue_irqs(adapter);
+               free_irq(adapter->msix_info[0].vec, adapter);
+       } else
+               free_irq(adapter->pdev->irq, adapter);
+       quiesce_rx(adapter);
+}
+
+/*
+ * net_device operations
+ */
+static int cxgb_open(struct net_device *dev)
+{
+       int err;
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
+
+       if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0)
+               return err;
+
+       dev->real_num_tx_queues = pi->nqsets;
+       set_bit(pi->tx_chan, &adapter->open_device_map);
+       link_start(dev);
+       netif_tx_start_all_queues(dev);
+       return 0;
+}
+
+static int cxgb_close(struct net_device *dev)
+{
+       int ret;
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
+
+       netif_tx_stop_all_queues(dev);
+       netif_carrier_off(dev);
+       ret = t4_enable_vi(adapter, 0, pi->viid, false, false);
+
+       clear_bit(pi->tx_chan, &adapter->open_device_map);
+
+       if (!adapter->open_device_map)
+               cxgb_down(adapter);
+       return 0;
+}
+
+static struct net_device_stats *cxgb_get_stats(struct net_device *dev)
+{
+       struct port_stats stats;
+       struct port_info *p = netdev_priv(dev);
+       struct adapter *adapter = p->adapter;
+       struct net_device_stats *ns = &dev->stats;
+
+       spin_lock(&adapter->stats_lock);
+       t4_get_port_stats(adapter, p->tx_chan, &stats);
+       spin_unlock(&adapter->stats_lock);
+
+       ns->tx_bytes   = stats.tx_octets;
+       ns->tx_packets = stats.tx_frames;
+       ns->rx_bytes   = stats.rx_octets;
+       ns->rx_packets = stats.rx_frames;
+       ns->multicast  = stats.rx_mcast_frames;
+
+       /* detailed rx_errors */
+       ns->rx_length_errors = stats.rx_jabber + stats.rx_too_long +
+                              stats.rx_runt;
+       ns->rx_over_errors   = 0;
+       ns->rx_crc_errors    = stats.rx_fcs_err;
+       ns->rx_frame_errors  = stats.rx_symbol_err;
+       ns->rx_fifo_errors   = stats.rx_ovflow0 + stats.rx_ovflow1 +
+                              stats.rx_ovflow2 + stats.rx_ovflow3 +
+                              stats.rx_trunc0 + stats.rx_trunc1 +
+                              stats.rx_trunc2 + stats.rx_trunc3;
+       ns->rx_missed_errors = 0;
+
+       /* detailed tx_errors */
+       ns->tx_aborted_errors   = 0;
+       ns->tx_carrier_errors   = 0;
+       ns->tx_fifo_errors      = 0;
+       ns->tx_heartbeat_errors = 0;
+       ns->tx_window_errors    = 0;
+
+       ns->tx_errors = stats.tx_error_frames;
+       ns->rx_errors = stats.rx_symbol_err + stats.rx_fcs_err +
+               ns->rx_length_errors + stats.rx_len_err + ns->rx_fifo_errors;
+       return ns;
+}
+
+static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+{
+       int ret = 0, prtad, devad;
+       struct port_info *pi = netdev_priv(dev);
+       struct mii_ioctl_data *data = (struct mii_ioctl_data *)&req->ifr_data;
+
+       switch (cmd) {
+       case SIOCGMIIPHY:
+               if (pi->mdio_addr < 0)
+                       return -EOPNOTSUPP;
+               data->phy_id = pi->mdio_addr;
+               break;
+       case SIOCGMIIREG:
+       case SIOCSMIIREG:
+               if (mdio_phy_id_is_c45(data->phy_id)) {
+                       prtad = mdio_phy_id_prtad(data->phy_id);
+                       devad = mdio_phy_id_devad(data->phy_id);
+               } else if (data->phy_id < 32) {
+                       prtad = data->phy_id;
+                       devad = 0;
+                       data->reg_num &= 0x1f;
+               } else
+                       return -EINVAL;
+
+               if (cmd == SIOCGMIIREG)
+                       ret = t4_mdio_rd(pi->adapter, 0, prtad, devad,
+                                        data->reg_num, &data->val_out);
+               else
+                       ret = t4_mdio_wr(pi->adapter, 0, prtad, devad,
+                                        data->reg_num, data->val_in);
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+       return ret;
+}
+
+static void cxgb_set_rxmode(struct net_device *dev)
+{
+       /* unfortunately we can't return errors to the stack */
+       set_rxmode(dev, -1, false);
+}
+
+static int cxgb_change_mtu(struct net_device *dev, int new_mtu)
+{
+       int ret;
+       struct port_info *pi = netdev_priv(dev);
+
+       if (new_mtu < 81 || new_mtu > MAX_MTU)         /* accommodate SACK */
+               return -EINVAL;
+       ret = t4_set_rxmode(pi->adapter, 0, pi->viid, new_mtu, -1, -1, -1,
+                           true);
+       if (!ret)
+               dev->mtu = new_mtu;
+       return ret;
+}
+
+static int cxgb_set_mac_addr(struct net_device *dev, void *p)
+{
+       int ret;
+       struct sockaddr *addr = p;
+       struct port_info *pi = netdev_priv(dev);
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EINVAL;
+
+       ret = t4_change_mac(pi->adapter, 0, pi->viid, pi->xact_addr_filt,
+                           addr->sa_data, true, true);
+       if (ret < 0)
+               return ret;
+
+       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+       pi->xact_addr_filt = ret;
+       return 0;
+}
+
+static void vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+{
+       struct port_info *pi = netdev_priv(dev);
+
+       pi->vlan_grp = grp;
+       t4_set_vlan_accel(pi->adapter, 1 << pi->tx_chan, grp != NULL);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void cxgb_netpoll(struct net_device *dev)
+{
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adap = pi->adapter;
+
+       if (adap->flags & USING_MSIX) {
+               int i;
+               struct sge_eth_rxq *rx = &adap->sge.ethrxq[pi->first_qset];
+
+               for (i = pi->nqsets; i; i--, rx++)
+                       t4_sge_intr_msix(0, &rx->rspq);
+       } else
+               t4_intr_handler(adap)(0, adap);
+}
+#endif
+
+static const struct net_device_ops cxgb4_netdev_ops = {
+       .ndo_open             = cxgb_open,
+       .ndo_stop             = cxgb_close,
+       .ndo_start_xmit       = t4_eth_xmit,
+       .ndo_get_stats        = cxgb_get_stats,
+       .ndo_set_rx_mode      = cxgb_set_rxmode,
+       .ndo_set_mac_address  = cxgb_set_mac_addr,
+       .ndo_validate_addr    = eth_validate_addr,
+       .ndo_do_ioctl         = cxgb_ioctl,
+       .ndo_change_mtu       = cxgb_change_mtu,
+       .ndo_vlan_rx_register = vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller  = cxgb_netpoll,
+#endif
+};
+
+void t4_fatal_err(struct adapter *adap)
+{
+       t4_set_reg_field(adap, SGE_CONTROL, GLOBALENABLE, 0);
+       t4_intr_disable(adap);
+       dev_alert(adap->pdev_dev, "encountered fatal error, adapter stopped\n");
+}
+
+static void setup_memwin(struct adapter *adap)
+{
+       u32 bar0;
+
+       bar0 = pci_resource_start(adap->pdev, 0);  /* truncation intentional */
+       t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 0),
+                    (bar0 + MEMWIN0_BASE) | BIR(0) |
+                    WINDOW(ilog2(MEMWIN0_APERTURE) - 10));
+       t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 1),
+                    (bar0 + MEMWIN1_BASE) | BIR(0) |
+                    WINDOW(ilog2(MEMWIN1_APERTURE) - 10));
+       t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 2),
+                    (bar0 + MEMWIN2_BASE) | BIR(0) |
+                    WINDOW(ilog2(MEMWIN2_APERTURE) - 10));
+}
+
+/*
+ * Max # of ATIDs.  The absolute HW max is 16K but we keep it lower.
+ */
+#define MAX_ATIDS 8192U
+
+/*
+ * Phase 0 of initialization: contact FW, obtain config, perform basic init.
+ */
+static int adap_init0(struct adapter *adap)
+{
+       int ret;
+       u32 v, port_vec;
+       enum dev_state state;
+       u32 params[7], val[7];
+       struct fw_caps_config_cmd c;
+
+       ret = t4_check_fw_version(adap);
+       if (ret == -EINVAL || ret > 0) {
+               if (upgrade_fw(adap) >= 0)             /* recache FW version */
+                       ret = t4_check_fw_version(adap);
+       }
+       if (ret < 0)
+               return ret;
+
+       /* contact FW, request master */
+       ret = t4_fw_hello(adap, 0, 0, MASTER_MUST, &state);
+       if (ret < 0) {
+               dev_err(adap->pdev_dev, "could not connect to FW, error %d\n",
+                       ret);
+               return ret;
+       }
+
+       /* reset device */
+       ret = t4_fw_reset(adap, 0, PIORSTMODE | PIORST);
+       if (ret < 0)
+               goto bye;
+
+       /* get device capabilities */
+       memset(&c, 0, sizeof(c));
+       c.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
+                             FW_CMD_REQUEST | FW_CMD_READ);
+       c.retval_len16 = htonl(FW_LEN16(c));
+       ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c);
+       if (ret < 0)
+               goto bye;
+
+       /* select capabilities we'll be using */
+       if (c.niccaps & htons(FW_CAPS_CONFIG_NIC_VM)) {
+               if (!vf_acls)
+                       c.niccaps ^= htons(FW_CAPS_CONFIG_NIC_VM);
+               else
+                       c.niccaps = htons(FW_CAPS_CONFIG_NIC_VM);
+       } else if (vf_acls) {
+               dev_err(adap->pdev_dev, "virtualization ACLs not supported");
+               goto bye;
+       }
+       c.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
+                             FW_CMD_REQUEST | FW_CMD_WRITE);
+       ret = t4_wr_mbox(adap, 0, &c, sizeof(c), NULL);
+       if (ret < 0)
+               goto bye;
+
+       ret = t4_config_glbl_rss(adap, 0,
+                                FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL,
+                                FW_RSS_GLB_CONFIG_CMD_TNLMAPEN |
+                                FW_RSS_GLB_CONFIG_CMD_TNLALLLKP);
+       if (ret < 0)
+               goto bye;
+
+       ret = t4_cfg_pfvf(adap, 0, 0, 0, 64, 64, 64, 0, 0, 4, 0xf, 0xf, 16,
+                         FW_CMD_CAP_PF, FW_CMD_CAP_PF);
+       if (ret < 0)
+               goto bye;
+
+       for (v = 0; v < SGE_NTIMERS - 1; v++)
+               adap->sge.timer_val[v] = min(intr_holdoff[v], MAX_SGE_TIMERVAL);
+       adap->sge.timer_val[SGE_NTIMERS - 1] = MAX_SGE_TIMERVAL;
+       adap->sge.counter_val[0] = 1;
+       for (v = 1; v < SGE_NCOUNTERS; v++)
+               adap->sge.counter_val[v] = min(intr_cnt[v - 1],
+                                              THRESHOLD_3_MASK);
+       t4_sge_init(adap);
+
+       /* get basic stuff going */
+       ret = t4_early_init(adap, 0);
+       if (ret < 0)
+               goto bye;
+
+#define FW_PARAM_DEV(param) \
+       (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | \
+        FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_##param))
+
+#define FW_PARAM_PFVF(param) \
+       (FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | \
+        FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param))
+
+       params[0] = FW_PARAM_DEV(PORTVEC);
+       params[1] = FW_PARAM_PFVF(L2T_START);
+       params[2] = FW_PARAM_PFVF(L2T_END);
+       params[3] = FW_PARAM_PFVF(FILTER_START);
+       params[4] = FW_PARAM_PFVF(FILTER_END);
+       ret = t4_query_params(adap, 0, 0, 0, 5, params, val);
+       if (ret < 0)
+               goto bye;
+       port_vec = val[0];
+       adap->tids.ftid_base = val[3];
+       adap->tids.nftids = val[4] - val[3] + 1;
+
+       if (c.ofldcaps) {
+               /* query offload-related parameters */
+               params[0] = FW_PARAM_DEV(NTID);
+               params[1] = FW_PARAM_PFVF(SERVER_START);
+               params[2] = FW_PARAM_PFVF(SERVER_END);
+               params[3] = FW_PARAM_PFVF(TDDP_START);
+               params[4] = FW_PARAM_PFVF(TDDP_END);
+               params[5] = FW_PARAM_DEV(FLOWC_BUFFIFO_SZ);
+               ret = t4_query_params(adap, 0, 0, 0, 6, params, val);
+               if (ret < 0)
+                       goto bye;
+               adap->tids.ntids = val[0];
+               adap->tids.natids = min(adap->tids.ntids / 2, MAX_ATIDS);
+               adap->tids.stid_base = val[1];
+               adap->tids.nstids = val[2] - val[1] + 1;
+               adap->vres.ddp.start = val[3];
+               adap->vres.ddp.size = val[4] - val[3] + 1;
+               adap->params.ofldq_wr_cred = val[5];
+               adap->params.offload = 1;
+       }
+       if (c.rdmacaps) {
+               params[0] = FW_PARAM_PFVF(STAG_START);
+               params[1] = FW_PARAM_PFVF(STAG_END);
+               params[2] = FW_PARAM_PFVF(RQ_START);
+               params[3] = FW_PARAM_PFVF(RQ_END);
+               params[4] = FW_PARAM_PFVF(PBL_START);
+               params[5] = FW_PARAM_PFVF(PBL_END);
+               ret = t4_query_params(adap, 0, 0, 0, 6, params, val);
+               if (ret < 0)
+                       goto bye;
+               adap->vres.stag.start = val[0];
+               adap->vres.stag.size = val[1] - val[0] + 1;
+               adap->vres.rq.start = val[2];
+               adap->vres.rq.size = val[3] - val[2] + 1;
+               adap->vres.pbl.start = val[4];
+               adap->vres.pbl.size = val[5] - val[4] + 1;
+       }
+       if (c.iscsicaps) {
+               params[0] = FW_PARAM_PFVF(ISCSI_START);
+               params[1] = FW_PARAM_PFVF(ISCSI_END);
+               ret = t4_query_params(adap, 0, 0, 0, 2, params, val);
+               if (ret < 0)
+                       goto bye;
+               adap->vres.iscsi.start = val[0];
+               adap->vres.iscsi.size = val[1] - val[0] + 1;
+       }
+#undef FW_PARAM_PFVF
+#undef FW_PARAM_DEV
+
+       adap->params.nports = hweight32(port_vec);
+       adap->params.portvec = port_vec;
+       adap->flags |= FW_OK;
+
+       /* These are finalized by FW initialization, load their values now */
+       v = t4_read_reg(adap, TP_TIMER_RESOLUTION);
+       adap->params.tp.tre = TIMERRESOLUTION_GET(v);
+       t4_read_mtu_tbl(adap, adap->params.mtus, NULL);
+       t4_load_mtus(adap, adap->params.mtus, adap->params.a_wnd,
+                    adap->params.b_wnd);
+
+       /* tweak some settings */
+       t4_write_reg(adap, TP_SHIFT_CNT, 0x64f8849);
+       t4_write_reg(adap, ULP_RX_TDDP_PSZ, HPZ0(PAGE_SHIFT - 12));
+       t4_write_reg(adap, TP_PIO_ADDR, TP_INGRESS_CONFIG);
+       v = t4_read_reg(adap, TP_PIO_DATA);
+       t4_write_reg(adap, TP_PIO_DATA, v & ~CSUM_HAS_PSEUDO_HDR);
+       setup_memwin(adap);
+       return 0;
+
+       /*
+        * If a command timed out or failed with EIO FW does not operate within
+        * its spec or something catastrophic happened to HW/FW, stop issuing
+        * commands.
+        */
+bye:   if (ret != -ETIMEDOUT && ret != -EIO)
+               t4_fw_bye(adap, 0);
+       return ret;
+}
+
+static inline bool is_10g_port(const struct link_config *lc)
+{
+       return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0;
+}
+
+static inline void init_rspq(struct sge_rspq *q, u8 timer_idx, u8 pkt_cnt_idx,
+                            unsigned int size, unsigned int iqe_size)
+{
+       q->intr_params = QINTR_TIMER_IDX(timer_idx) |
+                        (pkt_cnt_idx < SGE_NCOUNTERS ? QINTR_CNT_EN : 0);
+       q->pktcnt_idx = pkt_cnt_idx < SGE_NCOUNTERS ? pkt_cnt_idx : 0;
+       q->iqe_len = iqe_size;
+       q->size = size;
+}
+
+/*
+ * Perform default configuration of DMA queues depending on the number and type
+ * of ports we found and the number of available CPUs.  Most settings can be
+ * modified by the admin prior to actual use.
+ */
+static void __devinit cfg_queues(struct adapter *adap)
+{
+       struct sge *s = &adap->sge;
+       int i, q10g = 0, n10g = 0, qidx = 0;
+
+       for_each_port(adap, i)
+               n10g += is_10g_port(&adap2pinfo(adap, i)->link_cfg);
+
+       /*
+        * We default to 1 queue per non-10G port and up to # of cores queues
+        * per 10G port.
+        */
+       if (n10g)
+               q10g = (MAX_ETH_QSETS - (adap->params.nports - n10g)) / n10g;
+       if (q10g > num_online_cpus())
+               q10g = num_online_cpus();
+
+       for_each_port(adap, i) {
+               struct port_info *pi = adap2pinfo(adap, i);
+
+               pi->first_qset = qidx;
+               pi->nqsets = is_10g_port(&pi->link_cfg) ? q10g : 1;
+               qidx += pi->nqsets;
+       }
+
+       s->ethqsets = qidx;
+       s->max_ethqsets = qidx;   /* MSI-X may lower it later */
+
+       if (is_offload(adap)) {
+               /*
+                * For offload we use 1 queue/channel if all ports are up to 1G,
+                * otherwise we divide all available queues amongst the channels
+                * capped by the number of available cores.
+                */
+               if (n10g) {
+                       i = min_t(int, ARRAY_SIZE(s->ofldrxq),
+                                 num_online_cpus());
+                       s->ofldqsets = roundup(i, adap->params.nports);
+               } else
+                       s->ofldqsets = adap->params.nports;
+               /* For RDMA one Rx queue per channel suffices */
+               s->rdmaqs = adap->params.nports;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(s->ethrxq); i++) {
+               struct sge_eth_rxq *r = &s->ethrxq[i];
+
+               init_rspq(&r->rspq, 0, 0, 1024, 64);
+               r->fl.size = 72;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(s->ethtxq); i++)
+               s->ethtxq[i].q.size = 1024;
+
+       for (i = 0; i < ARRAY_SIZE(s->ctrlq); i++)
+               s->ctrlq[i].q.size = 512;
+
+       for (i = 0; i < ARRAY_SIZE(s->ofldtxq); i++)
+               s->ofldtxq[i].q.size = 1024;
+
+       for (i = 0; i < ARRAY_SIZE(s->ofldrxq); i++) {
+               struct sge_ofld_rxq *r = &s->ofldrxq[i];
+
+               init_rspq(&r->rspq, 0, 0, 1024, 64);
+               r->rspq.uld = CXGB4_ULD_ISCSI;
+               r->fl.size = 72;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(s->rdmarxq); i++) {
+               struct sge_ofld_rxq *r = &s->rdmarxq[i];
+
+               init_rspq(&r->rspq, 0, 0, 511, 64);
+               r->rspq.uld = CXGB4_ULD_RDMA;
+               r->fl.size = 72;
+       }
+
+       init_rspq(&s->fw_evtq, 6, 0, 512, 64);
+       init_rspq(&s->intrq, 6, 0, 2 * MAX_INGQ, 64);
+}
+
+/*
+ * Reduce the number of Ethernet queues across all ports to at most n.
+ * n provides at least one queue per port.
+ */
+static void __devinit reduce_ethqs(struct adapter *adap, int n)
+{
+       int i;
+       struct port_info *pi;
+
+       while (n < adap->sge.ethqsets)
+               for_each_port(adap, i) {
+                       pi = adap2pinfo(adap, i);
+                       if (pi->nqsets > 1) {
+                               pi->nqsets--;
+                               adap->sge.ethqsets--;
+                               if (adap->sge.ethqsets <= n)
+                                       break;
+                       }
+               }
+
+       n = 0;
+       for_each_port(adap, i) {
+               pi = adap2pinfo(adap, i);
+               pi->first_qset = n;
+               n += pi->nqsets;
+       }
+}
+
+/* 2 MSI-X vectors needed for the FW queue and non-data interrupts */
+#define EXTRA_VECS 2
+
+static int __devinit enable_msix(struct adapter *adap)
+{
+       int ofld_need = 0;
+       int i, err, want, need;
+       struct sge *s = &adap->sge;
+       unsigned int nchan = adap->params.nports;
+       struct msix_entry entries[MAX_INGQ + 1];
+
+       for (i = 0; i < ARRAY_SIZE(entries); ++i)
+               entries[i].entry = i;
+
+       want = s->max_ethqsets + EXTRA_VECS;
+       if (is_offload(adap)) {
+               want += s->rdmaqs + s->ofldqsets;
+               /* need nchan for each possible ULD */
+               ofld_need = 2 * nchan;
+       }
+       need = adap->params.nports + EXTRA_VECS + ofld_need;
+
+       while ((err = pci_enable_msix(adap->pdev, entries, want)) >= need)
+               want = err;
+
+       if (!err) {
+               /*
+                * Distribute available vectors to the various queue groups.
+                * Every group gets its minimum requirement and NIC gets top
+                * priority for leftovers.
+                */
+               i = want - EXTRA_VECS - ofld_need;
+               if (i < s->max_ethqsets) {
+                       s->max_ethqsets = i;
+                       if (i < s->ethqsets)
+                               reduce_ethqs(adap, i);
+               }
+               if (is_offload(adap)) {
+                       i = want - EXTRA_VECS - s->max_ethqsets;
+                       i -= ofld_need - nchan;
+                       s->ofldqsets = (i / nchan) * nchan;  /* round down */
+               }
+               for (i = 0; i < want; ++i)
+                       adap->msix_info[i].vec = entries[i].vector;
+       } else if (err > 0)
+               dev_info(adap->pdev_dev,
+                        "only %d MSI-X vectors left, not using MSI-X\n", err);
+       return err;
+}
+
+#undef EXTRA_VECS
+
+static void __devinit print_port_info(struct adapter *adap)
+{
+       static const char *base[] = {
+               "R", "KX4", "T", "KX", "T", "KR", "CX4"
+       };
+
+       int i;
+       char buf[80];
+
+       for_each_port(adap, i) {
+               struct net_device *dev = adap->port[i];
+               const struct port_info *pi = netdev_priv(dev);
+               char *bufp = buf;
+
+               if (!test_bit(i, &adap->registered_device_map))
+                       continue;
+
+               if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100M)
+                       bufp += sprintf(bufp, "100/");
+               if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_1G)
+                       bufp += sprintf(bufp, "1000/");
+               if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G)
+                       bufp += sprintf(bufp, "10G/");
+               if (bufp != buf)
+                       --bufp;
+               sprintf(bufp, "BASE-%s", base[pi->port_type]);
+
+               netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s\n",
+                           adap->params.vpd.id, adap->params.rev,
+                           buf, is_offload(adap) ? "R" : "",
+                           adap->params.pci.width,
+                           (adap->flags & USING_MSIX) ? " MSI-X" :
+                           (adap->flags & USING_MSI) ? " MSI" : "");
+               if (adap->name == dev->name)
+                       netdev_info(dev, "S/N: %s, E/C: %s\n",
+                                   adap->params.vpd.sn, adap->params.vpd.ec);
+       }
+}
+
+#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | NETIF_F_TSO6 |\
+                  NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA)
+
+static int __devinit init_one(struct pci_dev *pdev,
+                             const struct pci_device_id *ent)
+{
+       int func, i, err;
+       struct port_info *pi;
+       unsigned int highdma = 0;
+       struct adapter *adapter = NULL;
+
+       printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION);
+
+       err = pci_request_regions(pdev, KBUILD_MODNAME);
+       if (err) {
+               /* Just info, some other driver may have claimed the device. */
+               dev_info(&pdev->dev, "cannot obtain PCI resources\n");
+               return err;
+       }
+
+       /* We control everything through PF 0 */
+       func = PCI_FUNC(pdev->devfn);
+       if (func > 0)
+               goto sriov;
+
+       err = pci_enable_device(pdev);
+       if (err) {
+               dev_err(&pdev->dev, "cannot enable PCI device\n");
+               goto out_release_regions;
+       }
+
+       if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+               highdma = NETIF_F_HIGHDMA;
+               err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+               if (err) {
+                       dev_err(&pdev->dev, "unable to obtain 64-bit DMA for "
+                               "coherent allocations\n");
+                       goto out_disable_device;
+               }
+       } else {
+               err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+               if (err) {
+                       dev_err(&pdev->dev, "no usable DMA configuration\n");
+                       goto out_disable_device;
+               }
+       }
+
+       pci_enable_pcie_error_reporting(pdev);
+       pci_set_master(pdev);
+       pci_save_state(pdev);
+
+       adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
+       if (!adapter) {
+               err = -ENOMEM;
+               goto out_disable_device;
+       }
+
+       adapter->regs = pci_ioremap_bar(pdev, 0);
+       if (!adapter->regs) {
+               dev_err(&pdev->dev, "cannot map device registers\n");
+               err = -ENOMEM;
+               goto out_free_adapter;
+       }
+
+       adapter->pdev = pdev;
+       adapter->pdev_dev = &pdev->dev;
+       adapter->name = pci_name(pdev);
+       adapter->msg_enable = dflt_msg_enable;
+       memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map));
+
+       spin_lock_init(&adapter->stats_lock);
+       spin_lock_init(&adapter->tid_release_lock);
+
+       INIT_WORK(&adapter->tid_release_task, process_tid_release_list);
+
+       err = t4_prep_adapter(adapter);
+       if (err)
+               goto out_unmap_bar;
+       err = adap_init0(adapter);
+       if (err)
+               goto out_unmap_bar;
+
+       for_each_port(adapter, i) {
+               struct net_device *netdev;
+
+               netdev = alloc_etherdev_mq(sizeof(struct port_info),
+                                          MAX_ETH_QSETS);
+               if (!netdev) {
+                       err = -ENOMEM;
+                       goto out_free_dev;
+               }
+
+               SET_NETDEV_DEV(netdev, &pdev->dev);
+
+               adapter->port[i] = netdev;
+               pi = netdev_priv(netdev);
+               pi->adapter = adapter;
+               pi->xact_addr_filt = -1;
+               pi->rx_offload = RX_CSO;
+               pi->port_id = i;
+               netif_carrier_off(netdev);
+               netif_tx_stop_all_queues(netdev);
+               netdev->irq = pdev->irq;
+
+               netdev->features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6;
+               netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+               netdev->features |= NETIF_F_GRO | highdma;
+               netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+               netdev->vlan_features = netdev->features & VLAN_FEAT;
+
+               netdev->netdev_ops = &cxgb4_netdev_ops;
+               SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
+       }
+
+       pci_set_drvdata(pdev, adapter);
+
+       if (adapter->flags & FW_OK) {
+               err = t4_port_init(adapter, 0, 0, 0);
+               if (err)
+                       goto out_free_dev;
+       }
+
+       /*
+        * Configure queues and allocate tables now, they can be needed as
+        * soon as the first register_netdev completes.
+        */
+       cfg_queues(adapter);
+
+       adapter->l2t = t4_init_l2t();
+       if (!adapter->l2t) {
+               /* We tolerate a lack of L2T, giving up some functionality */
+               dev_warn(&pdev->dev, "could not allocate L2T, continuing\n");
+               adapter->params.offload = 0;
+       }
+
+       if (is_offload(adapter) && tid_init(&adapter->tids) < 0) {
+               dev_warn(&pdev->dev, "could not allocate TID table, "
+                        "continuing\n");
+               adapter->params.offload = 0;
+       }
+
+       /*
+        * The card is now ready to go.  If any errors occur during device
+        * registration we do not fail the whole card but rather proceed only
+        * with the ports we manage to register successfully.  However we must
+        * register at least one net device.
+        */
+       for_each_port(adapter, i) {
+               err = register_netdev(adapter->port[i]);
+               if (err)
+                       dev_warn(&pdev->dev,
+                                "cannot register net device %s, skipping\n",
+                                adapter->port[i]->name);
+               else {
+                       /*
+                        * Change the name we use for messages to the name of
+                        * the first successfully registered interface.
+                        */
+                       if (!adapter->registered_device_map)
+                               adapter->name = adapter->port[i]->name;
+
+                       __set_bit(i, &adapter->registered_device_map);
+                       adapter->chan_map[adap2pinfo(adapter, i)->tx_chan] = i;
+               }
+       }
+       if (!adapter->registered_device_map) {
+               dev_err(&pdev->dev, "could not register any net devices\n");
+               goto out_free_dev;
+       }
+
+       if (cxgb4_debugfs_root) {
+               adapter->debugfs_root = debugfs_create_dir(pci_name(pdev),
+                                                          cxgb4_debugfs_root);
+               setup_debugfs(adapter);
+       }
+
+       /* See what interrupts we'll be using */
+       if (msi > 1 && enable_msix(adapter) == 0)
+               adapter->flags |= USING_MSIX;
+       else if (msi > 0 && pci_enable_msi(pdev) == 0)
+               adapter->flags |= USING_MSI;
+
+       if (is_offload(adapter))
+               attach_ulds(adapter);
+
+       print_port_info(adapter);
+
+sriov:
+#ifdef CONFIG_PCI_IOV
+       if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0)
+               if (pci_enable_sriov(pdev, num_vf[func]) == 0)
+                       dev_info(&pdev->dev,
+                                "instantiated %u virtual functions\n",
+                                num_vf[func]);
+#endif
+       return 0;
+
+ out_free_dev:
+       t4_free_mem(adapter->tids.tid_tab);
+       t4_free_mem(adapter->l2t);
+       for_each_port(adapter, i)
+               if (adapter->port[i])
+                       free_netdev(adapter->port[i]);
+       if (adapter->flags & FW_OK)
+               t4_fw_bye(adapter, 0);
+ out_unmap_bar:
+       iounmap(adapter->regs);
+ out_free_adapter:
+       kfree(adapter);
+ out_disable_device:
+       pci_disable_pcie_error_reporting(pdev);
+       pci_disable_device(pdev);
+ out_release_regions:
+       pci_release_regions(pdev);
+       pci_set_drvdata(pdev, NULL);
+       return err;
+}
+
+static void __devexit remove_one(struct pci_dev *pdev)
+{
+       struct adapter *adapter = pci_get_drvdata(pdev);
+
+       pci_disable_sriov(pdev);
+
+       if (adapter) {
+               int i;
+
+               if (is_offload(adapter))
+                       detach_ulds(adapter);
+
+               for_each_port(adapter, i)
+                       if (test_bit(i, &adapter->registered_device_map))
+                               unregister_netdev(adapter->port[i]);
+
+               if (adapter->debugfs_root)
+                       debugfs_remove_recursive(adapter->debugfs_root);
+
+               t4_sge_stop(adapter);
+               t4_free_sge_resources(adapter);
+               t4_free_mem(adapter->l2t);
+               t4_free_mem(adapter->tids.tid_tab);
+               disable_msi(adapter);
+
+               for_each_port(adapter, i)
+                       if (adapter->port[i])
+                               free_netdev(adapter->port[i]);
+
+               if (adapter->flags & FW_OK)
+                       t4_fw_bye(adapter, 0);
+               iounmap(adapter->regs);
+               kfree(adapter);
+               pci_disable_pcie_error_reporting(pdev);
+               pci_disable_device(pdev);
+               pci_release_regions(pdev);
+               pci_set_drvdata(pdev, NULL);
+       } else if (PCI_FUNC(pdev->devfn) > 0)
+               pci_release_regions(pdev);
+}
+
+static struct pci_driver cxgb4_driver = {
+       .name     = KBUILD_MODNAME,
+       .id_table = cxgb4_pci_tbl,
+       .probe    = init_one,
+       .remove   = __devexit_p(remove_one),
+};
+
+static int __init cxgb4_init_module(void)
+{
+       int ret;
+
+       /* Debugfs support is optional, just warn if this fails */
+       cxgb4_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
+       if (!cxgb4_debugfs_root)
+               pr_warning("could not create debugfs entry, continuing\n");
+
+       ret = pci_register_driver(&cxgb4_driver);
+       if (ret < 0)
+               debugfs_remove(cxgb4_debugfs_root);
+       return ret;
+}
+
+static void __exit cxgb4_cleanup_module(void)
+{
+       pci_unregister_driver(&cxgb4_driver);
+       debugfs_remove(cxgb4_debugfs_root);  /* NULL ok */
+}
+
+module_init(cxgb4_init_module);
+module_exit(cxgb4_cleanup_module);
diff --git a/drivers/net/cxgb4/cxgb4_uld.h b/drivers/net/cxgb4/cxgb4_uld.h
new file mode 100644 (file)
index 0000000..5b98546
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ */
+
+#ifndef __CXGB4_OFLD_H
+#define __CXGB4_OFLD_H
+
+#include <linux/cache.h>
+#include <linux/spinlock.h>
+#include <linux/skbuff.h>
+#include <asm/atomic.h>
+
+/* CPL message priority levels */
+enum {
+       CPL_PRIORITY_DATA     = 0,  /* data messages */
+       CPL_PRIORITY_SETUP    = 1,  /* connection setup messages */
+       CPL_PRIORITY_TEARDOWN = 0,  /* connection teardown messages */
+       CPL_PRIORITY_LISTEN   = 1,  /* listen start/stop messages */
+       CPL_PRIORITY_ACK      = 1,  /* RX ACK messages */
+       CPL_PRIORITY_CONTROL  = 1   /* control messages */
+};
+
+#define INIT_TP_WR(w, tid) do { \
+       (w)->wr.wr_hi = htonl(FW_WR_OP(FW_TP_WR) | \
+                             FW_WR_IMMDLEN(sizeof(*w) - sizeof(w->wr))); \
+       (w)->wr.wr_mid = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*w), 16)) | \
+                              FW_WR_FLOWID(tid)); \
+       (w)->wr.wr_lo = cpu_to_be64(0); \
+} while (0)
+
+#define INIT_TP_WR_CPL(w, cpl, tid) do { \
+       INIT_TP_WR(w, tid); \
+       OPCODE_TID(w) = htonl(MK_OPCODE_TID(cpl, tid)); \
+} while (0)
+
+#define INIT_ULPTX_WR(w, wrlen, atomic, tid) do { \
+       (w)->wr.wr_hi = htonl(FW_WR_OP(FW_ULPTX_WR) | FW_WR_ATOMIC(atomic)); \
+       (w)->wr.wr_mid = htonl(FW_WR_LEN16(DIV_ROUND_UP(wrlen, 16)) | \
+                              FW_WR_FLOWID(tid)); \
+       (w)->wr.wr_lo = cpu_to_be64(0); \
+} while (0)
+
+/* Special asynchronous notification message */
+#define CXGB4_MSG_AN ((void *)1)
+
+struct serv_entry {
+       void *data;
+};
+
+union aopen_entry {
+       void *data;
+       union aopen_entry *next;
+};
+
+/*
+ * Holds the size, base address, free list start, etc of the TID, server TID,
+ * and active-open TID tables.  The tables themselves are allocated dynamically.
+ */
+struct tid_info {
+       void **tid_tab;
+       unsigned int ntids;
+
+       struct serv_entry *stid_tab;
+       unsigned long *stid_bmap;
+       unsigned int nstids;
+       unsigned int stid_base;
+
+       union aopen_entry *atid_tab;
+       unsigned int natids;
+
+       unsigned int nftids;
+       unsigned int ftid_base;
+
+       spinlock_t atid_lock ____cacheline_aligned_in_smp;
+       union aopen_entry *afree;
+       unsigned int atids_in_use;
+
+       spinlock_t stid_lock;
+       unsigned int stids_in_use;
+
+       atomic_t tids_in_use;
+};
+
+static inline void *lookup_tid(const struct tid_info *t, unsigned int tid)
+{
+       return tid < t->ntids ? t->tid_tab[tid] : NULL;
+}
+
+static inline void *lookup_atid(const struct tid_info *t, unsigned int atid)
+{
+       return atid < t->natids ? t->atid_tab[atid].data : NULL;
+}
+
+static inline void *lookup_stid(const struct tid_info *t, unsigned int stid)
+{
+       stid -= t->stid_base;
+       return stid < t->nstids ? t->stid_tab[stid].data : NULL;
+}
+
+static inline void cxgb4_insert_tid(struct tid_info *t, void *data,
+                                   unsigned int tid)
+{
+       t->tid_tab[tid] = data;
+       atomic_inc(&t->tids_in_use);
+}
+
+int cxgb4_alloc_atid(struct tid_info *t, void *data);
+int cxgb4_alloc_stid(struct tid_info *t, int family, void *data);
+void cxgb4_free_atid(struct tid_info *t, unsigned int atid);
+void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family);
+void cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid);
+void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan,
+                            unsigned int tid);
+
+struct in6_addr;
+
+int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
+                       __be32 sip, __be16 sport, unsigned int queue);
+int cxgb4_create_server6(const struct net_device *dev, unsigned int stid,
+                        const struct in6_addr *sip, __be16 sport,
+                        unsigned int queue);
+
+static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue)
+{
+       skb_set_queue_mapping(skb, (queue << 1) | prio);
+}
+
+enum cxgb4_uld {
+       CXGB4_ULD_RDMA,
+       CXGB4_ULD_ISCSI,
+       CXGB4_ULD_MAX
+};
+
+enum cxgb4_state {
+       CXGB4_STATE_UP,
+       CXGB4_STATE_START_RECOVERY,
+       CXGB4_STATE_DOWN,
+       CXGB4_STATE_DETACH
+};
+
+struct pci_dev;
+struct l2t_data;
+struct net_device;
+struct pkt_gl;
+struct tp_tcp_stats;
+
+struct cxgb4_range {
+       unsigned int start;
+       unsigned int size;
+};
+
+struct cxgb4_virt_res {                      /* virtualized HW resources */
+       struct cxgb4_range ddp;
+       struct cxgb4_range iscsi;
+       struct cxgb4_range stag;
+       struct cxgb4_range rq;
+       struct cxgb4_range pbl;
+};
+
+/*
+ * Block of information the LLD provides to ULDs attaching to a device.
+ */
+struct cxgb4_lld_info {
+       struct pci_dev *pdev;                /* associated PCI device */
+       struct l2t_data *l2t;                /* L2 table */
+       struct tid_info *tids;               /* TID table */
+       struct net_device **ports;           /* device ports */
+       const struct cxgb4_virt_res *vr;     /* assorted HW resources */
+       const unsigned short *mtus;          /* MTU table */
+       const unsigned short *rxq_ids;       /* the ULD's Rx queue ids */
+       unsigned short nrxq;                 /* # of Rx queues */
+       unsigned short ntxq;                 /* # of Tx queues */
+       unsigned char nchan:4;               /* # of channels */
+       unsigned char nports:4;              /* # of ports */
+       unsigned char wr_cred;               /* WR 16-byte credits */
+       unsigned char adapter_type;          /* type of adapter */
+       unsigned char fw_api_ver;            /* FW API version */
+       unsigned int fw_vers;                /* FW version */
+       unsigned int iscsi_iolen;            /* iSCSI max I/O length */
+       unsigned short udb_density;          /* # of user DB/page */
+       unsigned short ucq_density;          /* # of user CQs/page */
+       void __iomem *gts_reg;               /* address of GTS register */
+       void __iomem *db_reg;                /* address of kernel doorbell */
+};
+
+struct cxgb4_uld_info {
+       const char *name;
+       void *(*add)(const struct cxgb4_lld_info *p);
+       int (*rx_handler)(void *handle, const __be64 *rsp,
+                         const struct pkt_gl *gl);
+       int (*state_change)(void *handle, enum cxgb4_state new_state);
+};
+
+int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p);
+int cxgb4_unregister_uld(enum cxgb4_uld type);
+int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb);
+unsigned int cxgb4_port_chan(const struct net_device *dev);
+unsigned int cxgb4_port_viid(const struct net_device *dev);
+unsigned int cxgb4_port_idx(const struct net_device *dev);
+struct net_device *cxgb4_netdev_by_hwid(struct pci_dev *pdev, unsigned int id);
+unsigned int cxgb4_best_mtu(const unsigned short *mtus, unsigned short mtu,
+                           unsigned int *idx);
+void cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4,
+                        struct tp_tcp_stats *v6);
+void cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask,
+                     const unsigned int *pgsz_order);
+struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl,
+                                  unsigned int skb_len, unsigned int pull_len);
+#endif  /* !__CXGB4_OFLD_H */
diff --git a/drivers/net/cxgb4/l2t.c b/drivers/net/cxgb4/l2t.c
new file mode 100644 (file)
index 0000000..9f96724
--- /dev/null
@@ -0,0 +1,624 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ */
+
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/if.h>
+#include <linux/if_vlan.h>
+#include <linux/jhash.h>
+#include <net/neighbour.h>
+#include "cxgb4.h"
+#include "l2t.h"
+#include "t4_msg.h"
+#include "t4fw_api.h"
+
+#define VLAN_NONE 0xfff
+
+/* identifies sync vs async L2T_WRITE_REQs */
+#define F_SYNC_WR    (1 << 12)
+
+enum {
+       L2T_STATE_VALID,      /* entry is up to date */
+       L2T_STATE_STALE,      /* entry may be used but needs revalidation */
+       L2T_STATE_RESOLVING,  /* entry needs address resolution */
+       L2T_STATE_SYNC_WRITE, /* synchronous write of entry underway */
+
+       /* when state is one of the below the entry is not hashed */
+       L2T_STATE_SWITCHING,  /* entry is being used by a switching filter */
+       L2T_STATE_UNUSED      /* entry not in use */
+};
+
+struct l2t_data {
+       rwlock_t lock;
+       atomic_t nfree;             /* number of free entries */
+       struct l2t_entry *rover;    /* starting point for next allocation */
+       struct l2t_entry l2tab[L2T_SIZE];
+};
+
+static inline unsigned int vlan_prio(const struct l2t_entry *e)
+{
+       return e->vlan >> 13;
+}
+
+static inline void l2t_hold(struct l2t_data *d, struct l2t_entry *e)
+{
+       if (atomic_add_return(1, &e->refcnt) == 1)  /* 0 -> 1 transition */
+               atomic_dec(&d->nfree);
+}
+
+/*
+ * To avoid having to check address families we do not allow v4 and v6
+ * neighbors to be on the same hash chain.  We keep v4 entries in the first
+ * half of available hash buckets and v6 in the second.
+ */
+enum {
+       L2T_SZ_HALF = L2T_SIZE / 2,
+       L2T_HASH_MASK = L2T_SZ_HALF - 1
+};
+
+static inline unsigned int arp_hash(const u32 *key, int ifindex)
+{
+       return jhash_2words(*key, ifindex, 0) & L2T_HASH_MASK;
+}
+
+static inline unsigned int ipv6_hash(const u32 *key, int ifindex)
+{
+       u32 xor = key[0] ^ key[1] ^ key[2] ^ key[3];
+
+       return L2T_SZ_HALF + (jhash_2words(xor, ifindex, 0) & L2T_HASH_MASK);
+}
+
+static unsigned int addr_hash(const u32 *addr, int addr_len, int ifindex)
+{
+       return addr_len == 4 ? arp_hash(addr, ifindex) :
+                              ipv6_hash(addr, ifindex);
+}
+
+/*
+ * Checks if an L2T entry is for the given IP/IPv6 address.  It does not check
+ * whether the L2T entry and the address are of the same address family.
+ * Callers ensure an address is only checked against L2T entries of the same
+ * family, something made trivial by the separation of IP and IPv6 hash chains
+ * mentioned above.  Returns 0 if there's a match,
+ */
+static int addreq(const struct l2t_entry *e, const u32 *addr)
+{
+       if (e->v6)
+               return (e->addr[0] ^ addr[0]) | (e->addr[1] ^ addr[1]) |
+                      (e->addr[2] ^ addr[2]) | (e->addr[3] ^ addr[3]);
+       return e->addr[0] ^ addr[0];
+}
+
+static void neigh_replace(struct l2t_entry *e, struct neighbour *n)
+{
+       neigh_hold(n);
+       if (e->neigh)
+               neigh_release(e->neigh);
+       e->neigh = n;
+}
+
+/*
+ * Write an L2T entry.  Must be called with the entry locked.
+ * The write may be synchronous or asynchronous.
+ */
+static int write_l2e(struct adapter *adap, struct l2t_entry *e, int sync)
+{
+       struct sk_buff *skb;
+       struct cpl_l2t_write_req *req;
+
+       skb = alloc_skb(sizeof(*req), GFP_ATOMIC);
+       if (!skb)
+               return -ENOMEM;
+
+       req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req));
+       INIT_TP_WR(req, 0);
+
+       OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ,
+                                       e->idx | (sync ? F_SYNC_WR : 0) |
+                                       TID_QID(adap->sge.fw_evtq.abs_id)));
+       req->params = htons(L2T_W_PORT(e->lport) | L2T_W_NOREPLY(!sync));
+       req->l2t_idx = htons(e->idx);
+       req->vlan = htons(e->vlan);
+       if (e->neigh)
+               memcpy(e->dmac, e->neigh->ha, sizeof(e->dmac));
+       memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac));
+
+       set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0);
+       t4_ofld_send(adap, skb);
+
+       if (sync && e->state != L2T_STATE_SWITCHING)
+               e->state = L2T_STATE_SYNC_WRITE;
+       return 0;
+}
+
+/*
+ * Send packets waiting in an L2T entry's ARP queue.  Must be called with the
+ * entry locked.
+ */
+static void send_pending(struct adapter *adap, struct l2t_entry *e)
+{
+       while (e->arpq_head) {
+               struct sk_buff *skb = e->arpq_head;
+
+               e->arpq_head = skb->next;
+               skb->next = NULL;
+               t4_ofld_send(adap, skb);
+       }
+       e->arpq_tail = NULL;
+}
+
+/*
+ * Process a CPL_L2T_WRITE_RPL.  Wake up the ARP queue if it completes a
+ * synchronous L2T_WRITE.  Note that the TID in the reply is really the L2T
+ * index it refers to.
+ */
+void do_l2t_write_rpl(struct adapter *adap, const struct cpl_l2t_write_rpl *rpl)
+{
+       unsigned int tid = GET_TID(rpl);
+       unsigned int idx = tid & (L2T_SIZE - 1);
+
+       if (unlikely(rpl->status != CPL_ERR_NONE)) {
+               dev_err(adap->pdev_dev,
+                       "Unexpected L2T_WRITE_RPL status %u for entry %u\n",
+                       rpl->status, idx);
+               return;
+       }
+
+       if (tid & F_SYNC_WR) {
+               struct l2t_entry *e = &adap->l2t->l2tab[idx];
+
+               spin_lock(&e->lock);
+               if (e->state != L2T_STATE_SWITCHING) {
+                       send_pending(adap, e);
+                       e->state = (e->neigh->nud_state & NUD_STALE) ?
+                                       L2T_STATE_STALE : L2T_STATE_VALID;
+               }
+               spin_unlock(&e->lock);
+       }
+}
+
+/*
+ * Add a packet to an L2T entry's queue of packets awaiting resolution.
+ * Must be called with the entry's lock held.
+ */
+static inline void arpq_enqueue(struct l2t_entry *e, struct sk_buff *skb)
+{
+       skb->next = NULL;
+       if (e->arpq_head)
+               e->arpq_tail->next = skb;
+       else
+               e->arpq_head = skb;
+       e->arpq_tail = skb;
+}
+
+int cxgb4_l2t_send(struct net_device *dev, struct sk_buff *skb,
+                  struct l2t_entry *e)
+{
+       struct adapter *adap = netdev2adap(dev);
+
+again:
+       switch (e->state) {
+       case L2T_STATE_STALE:     /* entry is stale, kick off revalidation */
+               neigh_event_send(e->neigh, NULL);
+               spin_lock_bh(&e->lock);
+               if (e->state == L2T_STATE_STALE)
+                       e->state = L2T_STATE_VALID;
+               spin_unlock_bh(&e->lock);
+       case L2T_STATE_VALID:     /* fast-path, send the packet on */
+               return t4_ofld_send(adap, skb);
+       case L2T_STATE_RESOLVING:
+       case L2T_STATE_SYNC_WRITE:
+               spin_lock_bh(&e->lock);
+               if (e->state != L2T_STATE_SYNC_WRITE &&
+                   e->state != L2T_STATE_RESOLVING) {
+                       spin_unlock_bh(&e->lock);
+                       goto again;
+               }
+               arpq_enqueue(e, skb);
+               spin_unlock_bh(&e->lock);
+
+               if (e->state == L2T_STATE_RESOLVING &&
+                   !neigh_event_send(e->neigh, NULL)) {
+                       spin_lock_bh(&e->lock);
+                       if (e->state == L2T_STATE_RESOLVING && e->arpq_head)
+                               write_l2e(adap, e, 1);
+                       spin_unlock_bh(&e->lock);
+               }
+       }
+       return 0;
+}
+EXPORT_SYMBOL(cxgb4_l2t_send);
+
+/*
+ * Allocate a free L2T entry.  Must be called with l2t_data.lock held.
+ */
+static struct l2t_entry *alloc_l2e(struct l2t_data *d)
+{
+       struct l2t_entry *end, *e, **p;
+
+       if (!atomic_read(&d->nfree))
+               return NULL;
+
+       /* there's definitely a free entry */
+       for (e = d->rover, end = &d->l2tab[L2T_SIZE]; e != end; ++e)
+               if (atomic_read(&e->refcnt) == 0)
+                       goto found;
+
+       for (e = d->l2tab; atomic_read(&e->refcnt); ++e)
+               ;
+found:
+       d->rover = e + 1;
+       atomic_dec(&d->nfree);
+
+       /*
+        * The entry we found may be an inactive entry that is
+        * presently in the hash table.  We need to remove it.
+        */
+       if (e->state < L2T_STATE_SWITCHING)
+               for (p = &d->l2tab[e->hash].first; *p; p = &(*p)->next)
+                       if (*p == e) {
+                               *p = e->next;
+                               e->next = NULL;
+                               break;
+                       }
+
+       e->state = L2T_STATE_UNUSED;
+       return e;
+}
+
+/*
+ * Called when an L2T entry has no more users.
+ */
+static void t4_l2e_free(struct l2t_entry *e)
+{
+       struct l2t_data *d;
+
+       spin_lock_bh(&e->lock);
+       if (atomic_read(&e->refcnt) == 0) {  /* hasn't been recycled */
+               if (e->neigh) {
+                       neigh_release(e->neigh);
+                       e->neigh = NULL;
+               }
+       }
+       spin_unlock_bh(&e->lock);
+
+       d = container_of(e, struct l2t_data, l2tab[e->idx]);
+       atomic_inc(&d->nfree);
+}
+
+void cxgb4_l2t_release(struct l2t_entry *e)
+{
+       if (atomic_dec_and_test(&e->refcnt))
+               t4_l2e_free(e);
+}
+EXPORT_SYMBOL(cxgb4_l2t_release);
+
+/*
+ * Update an L2T entry that was previously used for the same next hop as neigh.
+ * Must be called with softirqs disabled.
+ */
+static void reuse_entry(struct l2t_entry *e, struct neighbour *neigh)
+{
+       unsigned int nud_state;
+
+       spin_lock(&e->lock);                /* avoid race with t4_l2t_free */
+       if (neigh != e->neigh)
+               neigh_replace(e, neigh);
+       nud_state = neigh->nud_state;
+       if (memcmp(e->dmac, neigh->ha, sizeof(e->dmac)) ||
+           !(nud_state & NUD_VALID))
+               e->state = L2T_STATE_RESOLVING;
+       else if (nud_state & NUD_CONNECTED)
+               e->state = L2T_STATE_VALID;
+       else
+               e->state = L2T_STATE_STALE;
+       spin_unlock(&e->lock);
+}
+
+struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh,
+                               const struct net_device *physdev,
+                               unsigned int priority)
+{
+       u8 lport;
+       u16 vlan;
+       struct l2t_entry *e;
+       int addr_len = neigh->tbl->key_len;
+       u32 *addr = (u32 *)neigh->primary_key;
+       int ifidx = neigh->dev->ifindex;
+       int hash = addr_hash(addr, addr_len, ifidx);
+
+       if (neigh->dev->flags & IFF_LOOPBACK)
+               lport = netdev2pinfo(physdev)->tx_chan + 4;
+       else
+               lport = netdev2pinfo(physdev)->lport;
+
+       if (neigh->dev->priv_flags & IFF_802_1Q_VLAN)
+               vlan = vlan_dev_vlan_id(neigh->dev);
+       else
+               vlan = VLAN_NONE;
+
+       write_lock_bh(&d->lock);
+       for (e = d->l2tab[hash].first; e; e = e->next)
+               if (!addreq(e, addr) && e->ifindex == ifidx &&
+                   e->vlan == vlan && e->lport == lport) {
+                       l2t_hold(d, e);
+                       if (atomic_read(&e->refcnt) == 1)
+                               reuse_entry(e, neigh);
+                       goto done;
+               }
+
+       /* Need to allocate a new entry */
+       e = alloc_l2e(d);
+       if (e) {
+               spin_lock(&e->lock);          /* avoid race with t4_l2t_free */
+               e->state = L2T_STATE_RESOLVING;
+               memcpy(e->addr, addr, addr_len);
+               e->ifindex = ifidx;
+               e->hash = hash;
+               e->lport = lport;
+               e->v6 = addr_len == 16;
+               atomic_set(&e->refcnt, 1);
+               neigh_replace(e, neigh);
+               e->vlan = vlan;
+               e->next = d->l2tab[hash].first;
+               d->l2tab[hash].first = e;
+               spin_unlock(&e->lock);
+       }
+done:
+       write_unlock_bh(&d->lock);
+       return e;
+}
+EXPORT_SYMBOL(cxgb4_l2t_get);
+
+/*
+ * Called when address resolution fails for an L2T entry to handle packets
+ * on the arpq head.  If a packet specifies a failure handler it is invoked,
+ * otherwise the packet is sent to the device.
+ */
+static void handle_failed_resolution(struct adapter *adap, struct sk_buff *arpq)
+{
+       while (arpq) {
+               struct sk_buff *skb = arpq;
+               const struct l2t_skb_cb *cb = L2T_SKB_CB(skb);
+
+               arpq = skb->next;
+               skb->next = NULL;
+               if (cb->arp_err_handler)
+                       cb->arp_err_handler(cb->handle, skb);
+               else
+                       t4_ofld_send(adap, skb);
+       }
+}
+
+/*
+ * Called when the host's neighbor layer makes a change to some entry that is
+ * loaded into the HW L2 table.
+ */
+void t4_l2t_update(struct adapter *adap, struct neighbour *neigh)
+{
+       struct l2t_entry *e;
+       struct sk_buff *arpq = NULL;
+       struct l2t_data *d = adap->l2t;
+       int addr_len = neigh->tbl->key_len;
+       u32 *addr = (u32 *) neigh->primary_key;
+       int ifidx = neigh->dev->ifindex;
+       int hash = addr_hash(addr, addr_len, ifidx);
+
+       read_lock_bh(&d->lock);
+       for (e = d->l2tab[hash].first; e; e = e->next)
+               if (!addreq(e, addr) && e->ifindex == ifidx) {
+                       spin_lock(&e->lock);
+                       if (atomic_read(&e->refcnt))
+                               goto found;
+                       spin_unlock(&e->lock);
+                       break;
+               }
+       read_unlock_bh(&d->lock);
+       return;
+
+ found:
+       read_unlock(&d->lock);
+
+       if (neigh != e->neigh)
+               neigh_replace(e, neigh);
+
+       if (e->state == L2T_STATE_RESOLVING) {
+               if (neigh->nud_state & NUD_FAILED) {
+                       arpq = e->arpq_head;
+                       e->arpq_head = e->arpq_tail = NULL;
+               } else if ((neigh->nud_state & (NUD_CONNECTED | NUD_STALE)) &&
+                          e->arpq_head) {
+                       write_l2e(adap, e, 1);
+               }
+       } else {
+               e->state = neigh->nud_state & NUD_CONNECTED ?
+                       L2T_STATE_VALID : L2T_STATE_STALE;
+               if (memcmp(e->dmac, neigh->ha, sizeof(e->dmac)))
+                       write_l2e(adap, e, 0);
+       }
+
+       spin_unlock_bh(&e->lock);
+
+       if (arpq)
+               handle_failed_resolution(adap, arpq);
+}
+
+/*
+ * Allocate an L2T entry for use by a switching rule.  Such entries need to be
+ * explicitly freed and while busy they are not on any hash chain, so normal
+ * address resolution updates do not see them.
+ */
+struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d)
+{
+       struct l2t_entry *e;
+
+       write_lock_bh(&d->lock);
+       e = alloc_l2e(d);
+       if (e) {
+               spin_lock(&e->lock);          /* avoid race with t4_l2t_free */
+               e->state = L2T_STATE_SWITCHING;
+               atomic_set(&e->refcnt, 1);
+               spin_unlock(&e->lock);
+       }
+       write_unlock_bh(&d->lock);
+       return e;
+}
+
+/*
+ * Sets/updates the contents of a switching L2T entry that has been allocated
+ * with an earlier call to @t4_l2t_alloc_switching.
+ */
+int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan,
+                        u8 port, u8 *eth_addr)
+{
+       e->vlan = vlan;
+       e->lport = port;
+       memcpy(e->dmac, eth_addr, ETH_ALEN);
+       return write_l2e(adap, e, 0);
+}
+
+struct l2t_data *t4_init_l2t(void)
+{
+       int i;
+       struct l2t_data *d;
+
+       d = t4_alloc_mem(sizeof(*d));
+       if (!d)
+               return NULL;
+
+       d->rover = d->l2tab;
+       atomic_set(&d->nfree, L2T_SIZE);
+       rwlock_init(&d->lock);
+
+       for (i = 0; i < L2T_SIZE; ++i) {
+               d->l2tab[i].idx = i;
+               d->l2tab[i].state = L2T_STATE_UNUSED;
+               spin_lock_init(&d->l2tab[i].lock);
+               atomic_set(&d->l2tab[i].refcnt, 0);
+       }
+       return d;
+}
+
+#include <linux/module.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static inline void *l2t_get_idx(struct seq_file *seq, loff_t pos)
+{
+       struct l2t_entry *l2tab = seq->private;
+
+       return pos >= L2T_SIZE ? NULL : &l2tab[pos];
+}
+
+static void *l2t_seq_start(struct seq_file *seq, loff_t *pos)
+{
+       return *pos ? l2t_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+}
+
+static void *l2t_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+       v = l2t_get_idx(seq, *pos);
+       if (v)
+               ++*pos;
+       return v;
+}
+
+static void l2t_seq_stop(struct seq_file *seq, void *v)
+{
+}
+
+static char l2e_state(const struct l2t_entry *e)
+{
+       switch (e->state) {
+       case L2T_STATE_VALID: return 'V';
+       case L2T_STATE_STALE: return 'S';
+       case L2T_STATE_SYNC_WRITE: return 'W';
+       case L2T_STATE_RESOLVING: return e->arpq_head ? 'A' : 'R';
+       case L2T_STATE_SWITCHING: return 'X';
+       default:
+               return 'U';
+       }
+}
+
+static int l2t_seq_show(struct seq_file *seq, void *v)
+{
+       if (v == SEQ_START_TOKEN)
+               seq_puts(seq, " Idx IP address                "
+                        "Ethernet address  VLAN/P LP State Users Port\n");
+       else {
+               char ip[60];
+               struct l2t_entry *e = v;
+
+               spin_lock_bh(&e->lock);
+               if (e->state == L2T_STATE_SWITCHING)
+                       ip[0] = '\0';
+               else
+                       sprintf(ip, e->v6 ? "%pI6c" : "%pI4", e->addr);
+               seq_printf(seq, "%4u %-25s %17pM %4d %u %2u   %c   %5u %s\n",
+                          e->idx, ip, e->dmac,
+                          e->vlan & VLAN_VID_MASK, vlan_prio(e), e->lport,
+                          l2e_state(e), atomic_read(&e->refcnt),
+                          e->neigh ? e->neigh->dev->name : "");
+               spin_unlock_bh(&e->lock);
+       }
+       return 0;
+}
+
+static const struct seq_operations l2t_seq_ops = {
+       .start = l2t_seq_start,
+       .next = l2t_seq_next,
+       .stop = l2t_seq_stop,
+       .show = l2t_seq_show
+};
+
+static int l2t_seq_open(struct inode *inode, struct file *file)
+{
+       int rc = seq_open(file, &l2t_seq_ops);
+
+       if (!rc) {
+               struct adapter *adap = inode->i_private;
+               struct seq_file *seq = file->private_data;
+
+               seq->private = adap->l2t->l2tab;
+       }
+       return rc;
+}
+
+const struct file_operations t4_l2t_fops = {
+       .owner = THIS_MODULE,
+       .open = l2t_seq_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = seq_release,
+};
diff --git a/drivers/net/cxgb4/l2t.h b/drivers/net/cxgb4/l2t.h
new file mode 100644 (file)
index 0000000..643f27e
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ */
+
+#ifndef __CXGB4_L2T_H
+#define __CXGB4_L2T_H
+
+#include <linux/spinlock.h>
+#include <linux/if_ether.h>
+#include <asm/atomic.h>
+
+struct adapter;
+struct l2t_data;
+struct neighbour;
+struct net_device;
+struct file_operations;
+struct cpl_l2t_write_rpl;
+
+/*
+ * Each L2T entry plays multiple roles.  First of all, it keeps state for the
+ * corresponding entry of the HW L2 table and maintains a queue of offload
+ * packets awaiting address resolution.  Second, it is a node of a hash table
+ * chain, where the nodes of the chain are linked together through their next
+ * pointer.  Finally, each node is a bucket of a hash table, pointing to the
+ * first element in its chain through its first pointer.
+ */
+struct l2t_entry {
+       u16 state;                  /* entry state */
+       u16 idx;                    /* entry index */
+       u32 addr[4];                /* next hop IP or IPv6 address */
+       int ifindex;                /* neighbor's net_device's ifindex */
+       struct neighbour *neigh;    /* associated neighbour */
+       struct l2t_entry *first;    /* start of hash chain */
+       struct l2t_entry *next;     /* next l2t_entry on chain */
+       struct sk_buff *arpq_head;  /* queue of packets awaiting resolution */
+       struct sk_buff *arpq_tail;
+       spinlock_t lock;
+       atomic_t refcnt;            /* entry reference count */
+       u16 hash;                   /* hash bucket the entry is on */
+       u16 vlan;                   /* VLAN TCI (id: bits 0-11, prio: 13-15 */
+       u8 v6;                      /* whether entry is for IPv6 */
+       u8 lport;                   /* associated offload logical interface */
+       u8 dmac[ETH_ALEN];          /* neighbour's MAC address */
+};
+
+typedef void (*arp_err_handler_t)(void *handle, struct sk_buff *skb);
+
+/*
+ * Callback stored in an skb to handle address resolution failure.
+ */
+struct l2t_skb_cb {
+       void *handle;
+       arp_err_handler_t arp_err_handler;
+};
+
+#define L2T_SKB_CB(skb) ((struct l2t_skb_cb *)(skb)->cb)
+
+static inline void t4_set_arp_err_handler(struct sk_buff *skb, void *handle,
+                                         arp_err_handler_t handler)
+{
+       L2T_SKB_CB(skb)->handle = handle;
+       L2T_SKB_CB(skb)->arp_err_handler = handler;
+}
+
+void cxgb4_l2t_release(struct l2t_entry *e);
+int cxgb4_l2t_send(struct net_device *dev, struct sk_buff *skb,
+                  struct l2t_entry *e);
+struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh,
+                               const struct net_device *physdev,
+                               unsigned int priority);
+
+void t4_l2t_update(struct adapter *adap, struct neighbour *neigh);
+struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d);
+int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan,
+                        u8 port, u8 *eth_addr);
+struct l2t_data *t4_init_l2t(void);
+void do_l2t_write_rpl(struct adapter *p, const struct cpl_l2t_write_rpl *rpl);
+
+extern const struct file_operations t4_l2t_fops;
+#endif  /* __CXGB4_L2T_H */
diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c
new file mode 100644 (file)
index 0000000..14adc58
--- /dev/null
@@ -0,0 +1,2431 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ */
+
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
+#include <linux/ip.h>
+#include <linux/dma-mapping.h>
+#include <linux/jiffies.h>
+#include <net/ipv6.h>
+#include <net/tcp.h>
+#include "cxgb4.h"
+#include "t4_regs.h"
+#include "t4_msg.h"
+#include "t4fw_api.h"
+
+/*
+ * Rx buffer size.  We use largish buffers if possible but settle for single
+ * pages under memory shortage.
+ */
+#if PAGE_SHIFT >= 16
+# define FL_PG_ORDER 0
+#else
+# define FL_PG_ORDER (16 - PAGE_SHIFT)
+#endif
+
+/* RX_PULL_LEN should be <= RX_COPY_THRES */
+#define RX_COPY_THRES    256
+#define RX_PULL_LEN      128
+
+/*
+ * Main body length for sk_buffs used for Rx Ethernet packets with fragments.
+ * Should be >= RX_PULL_LEN but possibly bigger to give pskb_may_pull some room.
+ */
+#define RX_PKT_SKB_LEN   512
+
+/* Ethernet header padding prepended to RX_PKTs */
+#define RX_PKT_PAD 2
+
+/*
+ * Max number of Tx descriptors we clean up at a time.  Should be modest as
+ * freeing skbs isn't cheap and it happens while holding locks.  We just need
+ * to free packets faster than they arrive, we eventually catch up and keep
+ * the amortized cost reasonable.  Must be >= 2 * TXQ_STOP_THRES.
+ */
+#define MAX_TX_RECLAIM 16
+
+/*
+ * Max number of Rx buffers we replenish at a time.  Again keep this modest,
+ * allocating buffers isn't cheap either.
+ */
+#define MAX_RX_REFILL 16U
+
+/*
+ * Period of the Rx queue check timer.  This timer is infrequent as it has
+ * something to do only when the system experiences severe memory shortage.
+ */
+#define RX_QCHECK_PERIOD (HZ / 2)
+
+/*
+ * Period of the Tx queue check timer.
+ */
+#define TX_QCHECK_PERIOD (HZ / 2)
+
+/*
+ * Max number of Tx descriptors to be reclaimed by the Tx timer.
+ */
+#define MAX_TIMER_TX_RECLAIM 100
+
+/*
+ * Timer index used when backing off due to memory shortage.
+ */
+#define NOMEM_TMR_IDX (SGE_NTIMERS - 1)
+
+/*
+ * An FL with <= FL_STARVE_THRES buffers is starving and a periodic timer will
+ * attempt to refill it.
+ */
+#define FL_STARVE_THRES 4
+
+/*
+ * Suspend an Ethernet Tx queue with fewer available descriptors than this.
+ * This is the same as calc_tx_descs() for a TSO packet with
+ * nr_frags == MAX_SKB_FRAGS.
+ */
+#define ETHTXQ_STOP_THRES \
+       (1 + DIV_ROUND_UP((3 * MAX_SKB_FRAGS) / 2 + (MAX_SKB_FRAGS & 1), 8))
+
+/*
+ * Suspension threshold for non-Ethernet Tx queues.  We require enough room
+ * for a full sized WR.
+ */
+#define TXQ_STOP_THRES (SGE_MAX_WR_LEN / sizeof(struct tx_desc))
+
+/*
+ * Max Tx descriptor space we allow for an Ethernet packet to be inlined
+ * into a WR.
+ */
+#define MAX_IMM_TX_PKT_LEN 128
+
+/*
+ * Max size of a WR sent through a control Tx queue.
+ */
+#define MAX_CTRL_WR_LEN SGE_MAX_WR_LEN
+
+enum {
+       /* packet alignment in FL buffers */
+       FL_ALIGN = L1_CACHE_BYTES < 32 ? 32 : L1_CACHE_BYTES,
+       /* egress status entry size */
+       STAT_LEN = L1_CACHE_BYTES > 64 ? 128 : 64
+};
+
+struct tx_sw_desc {                /* SW state per Tx descriptor */
+       struct sk_buff *skb;
+       struct ulptx_sgl *sgl;
+};
+
+struct rx_sw_desc {                /* SW state per Rx descriptor */
+       struct page *page;
+       dma_addr_t dma_addr;
+};
+
+/*
+ * The low bits of rx_sw_desc.dma_addr have special meaning.
+ */
+enum {
+       RX_LARGE_BUF    = 1 << 0, /* buffer is larger than PAGE_SIZE */
+       RX_UNMAPPED_BUF = 1 << 1, /* buffer is not mapped */
+};
+
+static inline dma_addr_t get_buf_addr(const struct rx_sw_desc *d)
+{
+       return d->dma_addr & ~(dma_addr_t)(RX_LARGE_BUF | RX_UNMAPPED_BUF);
+}
+
+static inline bool is_buf_mapped(const struct rx_sw_desc *d)
+{
+       return !(d->dma_addr & RX_UNMAPPED_BUF);
+}
+
+/**
+ *     txq_avail - return the number of available slots in a Tx queue
+ *     @q: the Tx queue
+ *
+ *     Returns the number of descriptors in a Tx queue available to write new
+ *     packets.
+ */
+static inline unsigned int txq_avail(const struct sge_txq *q)
+{
+       return q->size - 1 - q->in_use;
+}
+
+/**
+ *     fl_cap - return the capacity of a free-buffer list
+ *     @fl: the FL
+ *
+ *     Returns the capacity of a free-buffer list.  The capacity is less than
+ *     the size because one descriptor needs to be left unpopulated, otherwise
+ *     HW will think the FL is empty.
+ */
+static inline unsigned int fl_cap(const struct sge_fl *fl)
+{
+       return fl->size - 8;   /* 1 descriptor = 8 buffers */
+}
+
+static inline bool fl_starving(const struct sge_fl *fl)
+{
+       return fl->avail - fl->pend_cred <= FL_STARVE_THRES;
+}
+
+static int map_skb(struct device *dev, const struct sk_buff *skb,
+                  dma_addr_t *addr)
+{
+       const skb_frag_t *fp, *end;
+       const struct skb_shared_info *si;
+
+       *addr = dma_map_single(dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
+       if (dma_mapping_error(dev, *addr))
+               goto out_err;
+
+       si = skb_shinfo(skb);
+       end = &si->frags[si->nr_frags];
+
+       for (fp = si->frags; fp < end; fp++) {
+               *++addr = dma_map_page(dev, fp->page, fp->page_offset, fp->size,
+                                      DMA_TO_DEVICE);
+               if (dma_mapping_error(dev, *addr))
+                       goto unwind;
+       }
+       return 0;
+
+unwind:
+       while (fp-- > si->frags)
+               dma_unmap_page(dev, *--addr, fp->size, DMA_TO_DEVICE);
+
+       dma_unmap_single(dev, addr[-1], skb_headlen(skb), DMA_TO_DEVICE);
+out_err:
+       return -ENOMEM;
+}
+
+#ifdef CONFIG_NEED_DMA_MAP_STATE
+static void unmap_skb(struct device *dev, const struct sk_buff *skb,
+                     const dma_addr_t *addr)
+{
+       const skb_frag_t *fp, *end;
+       const struct skb_shared_info *si;
+
+       dma_unmap_single(dev, *addr++, skb_headlen(skb), DMA_TO_DEVICE);
+
+       si = skb_shinfo(skb);
+       end = &si->frags[si->nr_frags];
+       for (fp = si->frags; fp < end; fp++)
+               dma_unmap_page(dev, *addr++, fp->size, DMA_TO_DEVICE);
+}
+
+/**
+ *     deferred_unmap_destructor - unmap a packet when it is freed
+ *     @skb: the packet
+ *
+ *     This is the packet destructor used for Tx packets that need to remain
+ *     mapped until they are freed rather than until their Tx descriptors are
+ *     freed.
+ */
+static void deferred_unmap_destructor(struct sk_buff *skb)
+{
+       unmap_skb(skb->dev->dev.parent, skb, (dma_addr_t *)skb->head);
+}
+#endif
+
+static void unmap_sgl(struct device *dev, const struct sk_buff *skb,
+                     const struct ulptx_sgl *sgl, const struct sge_txq *q)
+{
+       const struct ulptx_sge_pair *p;
+       unsigned int nfrags = skb_shinfo(skb)->nr_frags;
+
+       if (likely(skb_headlen(skb)))
+               dma_unmap_single(dev, be64_to_cpu(sgl->addr0), ntohl(sgl->len0),
+                                DMA_TO_DEVICE);
+       else {
+               dma_unmap_page(dev, be64_to_cpu(sgl->addr0), ntohl(sgl->len0),
+                              DMA_TO_DEVICE);
+               nfrags--;
+       }
+
+       /*
+        * the complexity below is because of the possibility of a wrap-around
+        * in the middle of an SGL
+        */
+       for (p = sgl->sge; nfrags >= 2; nfrags -= 2) {
+               if (likely((u8 *)(p + 1) <= (u8 *)q->stat)) {
+unmap:                 dma_unmap_page(dev, be64_to_cpu(p->addr[0]),
+                                      ntohl(p->len[0]), DMA_TO_DEVICE);
+                       dma_unmap_page(dev, be64_to_cpu(p->addr[1]),
+                                      ntohl(p->len[1]), DMA_TO_DEVICE);
+                       p++;
+               } else if ((u8 *)p == (u8 *)q->stat) {
+                       p = (const struct ulptx_sge_pair *)q->desc;
+                       goto unmap;
+               } else if ((u8 *)p + 8 == (u8 *)q->stat) {
+                       const __be64 *addr = (const __be64 *)q->desc;
+
+                       dma_unmap_page(dev, be64_to_cpu(addr[0]),
+                                      ntohl(p->len[0]), DMA_TO_DEVICE);
+                       dma_unmap_page(dev, be64_to_cpu(addr[1]),
+                                      ntohl(p->len[1]), DMA_TO_DEVICE);
+                       p = (const struct ulptx_sge_pair *)&addr[2];
+               } else {
+                       const __be64 *addr = (const __be64 *)q->desc;
+
+                       dma_unmap_page(dev, be64_to_cpu(p->addr[0]),
+                                      ntohl(p->len[0]), DMA_TO_DEVICE);
+                       dma_unmap_page(dev, be64_to_cpu(addr[0]),
+                                      ntohl(p->len[1]), DMA_TO_DEVICE);
+                       p = (const struct ulptx_sge_pair *)&addr[1];
+               }
+       }
+       if (nfrags) {
+               __be64 addr;
+
+               if ((u8 *)p == (u8 *)q->stat)
+                       p = (const struct ulptx_sge_pair *)q->desc;
+               addr = (u8 *)p + 16 <= (u8 *)q->stat ? p->addr[0] :
+                                                      *(const __be64 *)q->desc;
+               dma_unmap_page(dev, be64_to_cpu(addr), ntohl(p->len[0]),
+                              DMA_TO_DEVICE);
+       }
+}
+
+/**
+ *     free_tx_desc - reclaims Tx descriptors and their buffers
+ *     @adapter: the adapter
+ *     @q: the Tx queue to reclaim descriptors from
+ *     @n: the number of descriptors to reclaim
+ *     @unmap: whether the buffers should be unmapped for DMA
+ *
+ *     Reclaims Tx descriptors from an SGE Tx queue and frees the associated
+ *     Tx buffers.  Called with the Tx queue lock held.
+ */
+static void free_tx_desc(struct adapter *adap, struct sge_txq *q,
+                        unsigned int n, bool unmap)
+{
+       struct tx_sw_desc *d;
+       unsigned int cidx = q->cidx;
+       struct device *dev = adap->pdev_dev;
+
+       d = &q->sdesc[cidx];
+       while (n--) {
+               if (d->skb) {                       /* an SGL is present */
+                       if (unmap)
+                               unmap_sgl(dev, d->skb, d->sgl, q);
+                       kfree_skb(d->skb);
+                       d->skb = NULL;
+               }
+               ++d;
+               if (++cidx == q->size) {
+                       cidx = 0;
+                       d = q->sdesc;
+               }
+       }
+       q->cidx = cidx;
+}
+
+/*
+ * Return the number of reclaimable descriptors in a Tx queue.
+ */
+static inline int reclaimable(const struct sge_txq *q)
+{
+       int hw_cidx = ntohs(q->stat->cidx);
+       hw_cidx -= q->cidx;
+       return hw_cidx < 0 ? hw_cidx + q->size : hw_cidx;
+}
+
+/**
+ *     reclaim_completed_tx - reclaims completed Tx descriptors
+ *     @adap: the adapter
+ *     @q: the Tx queue to reclaim completed descriptors from
+ *     @unmap: whether the buffers should be unmapped for DMA
+ *
+ *     Reclaims Tx descriptors that the SGE has indicated it has processed,
+ *     and frees the associated buffers if possible.  Called with the Tx
+ *     queue locked.
+ */
+static inline void reclaim_completed_tx(struct adapter *adap, struct sge_txq *q,
+                                       bool unmap)
+{
+       int avail = reclaimable(q);
+
+       if (avail) {
+               /*
+                * Limit the amount of clean up work we do at a time to keep
+                * the Tx lock hold time O(1).
+                */
+               if (avail > MAX_TX_RECLAIM)
+                       avail = MAX_TX_RECLAIM;
+
+               free_tx_desc(adap, q, avail, unmap);
+               q->in_use -= avail;
+       }
+}
+
+static inline int get_buf_size(const struct rx_sw_desc *d)
+{
+#if FL_PG_ORDER > 0
+       return (d->dma_addr & RX_LARGE_BUF) ? (PAGE_SIZE << FL_PG_ORDER) :
+                                             PAGE_SIZE;
+#else
+       return PAGE_SIZE;
+#endif
+}
+
+/**
+ *     free_rx_bufs - free the Rx buffers on an SGE free list
+ *     @adap: the adapter
+ *     @q: the SGE free list to free buffers from
+ *     @n: how many buffers to free
+ *
+ *     Release the next @n buffers on an SGE free-buffer Rx queue.   The
+ *     buffers must be made inaccessible to HW before calling this function.
+ */
+static void free_rx_bufs(struct adapter *adap, struct sge_fl *q, int n)
+{
+       while (n--) {
+               struct rx_sw_desc *d = &q->sdesc[q->cidx];
+
+               if (is_buf_mapped(d))
+                       dma_unmap_page(adap->pdev_dev, get_buf_addr(d),
+                                      get_buf_size(d), PCI_DMA_FROMDEVICE);
+               put_page(d->page);
+               d->page = NULL;
+               if (++q->cidx == q->size)
+                       q->cidx = 0;
+               q->avail--;
+       }
+}
+
+/**
+ *     unmap_rx_buf - unmap the current Rx buffer on an SGE free list
+ *     @adap: the adapter
+ *     @q: the SGE free list
+ *
+ *     Unmap the current buffer on an SGE free-buffer Rx queue.   The
+ *     buffer must be made inaccessible to HW before calling this function.
+ *
+ *     This is similar to @free_rx_bufs above but does not free the buffer.
+ *     Do note that the FL still loses any further access to the buffer.
+ */
+static void unmap_rx_buf(struct adapter *adap, struct sge_fl *q)
+{
+       struct rx_sw_desc *d = &q->sdesc[q->cidx];
+
+       if (is_buf_mapped(d))
+               dma_unmap_page(adap->pdev_dev, get_buf_addr(d),
+                              get_buf_size(d), PCI_DMA_FROMDEVICE);
+       d->page = NULL;
+       if (++q->cidx == q->size)
+               q->cidx = 0;
+       q->avail--;
+}
+
+static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
+{
+       if (q->pend_cred >= 8) {
+               wmb();
+               t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), DBPRIO |
+                            QID(q->cntxt_id) | PIDX(q->pend_cred / 8));
+               q->pend_cred &= 7;
+       }
+}
+
+static inline void set_rx_sw_desc(struct rx_sw_desc *sd, struct page *pg,
+                                 dma_addr_t mapping)
+{
+       sd->page = pg;
+       sd->dma_addr = mapping;      /* includes size low bits */
+}
+
+/**
+ *     refill_fl - refill an SGE Rx buffer ring
+ *     @adap: the adapter
+ *     @q: the ring to refill
+ *     @n: the number of new buffers to allocate
+ *     @gfp: the gfp flags for the allocations
+ *
+ *     (Re)populate an SGE free-buffer queue with up to @n new packet buffers,
+ *     allocated with the supplied gfp flags.  The caller must assure that
+ *     @n does not exceed the queue's capacity.  If afterwards the queue is
+ *     found critically low mark it as starving in the bitmap of starving FLs.
+ *
+ *     Returns the number of buffers allocated.
+ */
+static unsigned int refill_fl(struct adapter *adap, struct sge_fl *q, int n,
+                             gfp_t gfp)
+{
+       struct page *pg;
+       dma_addr_t mapping;
+       unsigned int cred = q->avail;
+       __be64 *d = &q->desc[q->pidx];
+       struct rx_sw_desc *sd = &q->sdesc[q->pidx];
+
+       gfp |= __GFP_NOWARN;         /* failures are expected */
+
+#if FL_PG_ORDER > 0
+       /*
+        * Prefer large buffers
+        */
+       while (n) {
+               pg = alloc_pages(gfp | __GFP_COMP, FL_PG_ORDER);
+               if (unlikely(!pg)) {
+                       q->large_alloc_failed++;
+                       break;       /* fall back to single pages */
+               }
+
+               mapping = dma_map_page(adap->pdev_dev, pg, 0,
+                                      PAGE_SIZE << FL_PG_ORDER,
+                                      PCI_DMA_FROMDEVICE);
+               if (unlikely(dma_mapping_error(adap->pdev_dev, mapping))) {
+                       __free_pages(pg, FL_PG_ORDER);
+                       goto out;   /* do not try small pages for this error */
+               }
+               mapping |= RX_LARGE_BUF;
+               *d++ = cpu_to_be64(mapping);
+
+               set_rx_sw_desc(sd, pg, mapping);
+               sd++;
+
+               q->avail++;
+               if (++q->pidx == q->size) {
+                       q->pidx = 0;
+                       sd = q->sdesc;
+                       d = q->desc;
+               }
+               n--;
+       }
+#endif
+
+       while (n--) {
+               pg = __netdev_alloc_page(adap->port[0], gfp);
+               if (unlikely(!pg)) {
+                       q->alloc_failed++;
+                       break;
+               }
+
+               mapping = dma_map_page(adap->pdev_dev, pg, 0, PAGE_SIZE,
+                                      PCI_DMA_FROMDEVICE);
+               if (unlikely(dma_mapping_error(adap->pdev_dev, mapping))) {
+                       netdev_free_page(adap->port[0], pg);
+                       goto out;
+               }
+               *d++ = cpu_to_be64(mapping);
+
+               set_rx_sw_desc(sd, pg, mapping);
+               sd++;
+
+               q->avail++;
+               if (++q->pidx == q->size) {
+                       q->pidx = 0;
+                       sd = q->sdesc;
+                       d = q->desc;
+               }
+       }
+
+out:   cred = q->avail - cred;
+       q->pend_cred += cred;
+       ring_fl_db(adap, q);
+
+       if (unlikely(fl_starving(q))) {
+               smp_wmb();
+               set_bit(q->cntxt_id, adap->sge.starving_fl);
+       }
+
+       return cred;
+}
+
+static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl)
+{
+       refill_fl(adap, fl, min(MAX_RX_REFILL, fl_cap(fl) - fl->avail),
+                 GFP_ATOMIC);
+}
+
+/**
+ *     alloc_ring - allocate resources for an SGE descriptor ring
+ *     @dev: the PCI device's core device
+ *     @nelem: the number of descriptors
+ *     @elem_size: the size of each descriptor
+ *     @sw_size: the size of the SW state associated with each ring element
+ *     @phys: the physical address of the allocated ring
+ *     @metadata: address of the array holding the SW state for the ring
+ *     @stat_size: extra space in HW ring for status information
+ *
+ *     Allocates resources for an SGE descriptor ring, such as Tx queues,
+ *     free buffer lists, or response queues.  Each SGE ring requires
+ *     space for its HW descriptors plus, optionally, space for the SW state
+ *     associated with each HW entry (the metadata).  The function returns
+ *     three values: the virtual address for the HW ring (the return value
+ *     of the function), the bus address of the HW ring, and the address
+ *     of the SW ring.
+ */
+static void *alloc_ring(struct device *dev, size_t nelem, size_t elem_size,
+                       size_t sw_size, dma_addr_t *phys, void *metadata,
+                       size_t stat_size)
+{
+       size_t len = nelem * elem_size + stat_size;
+       void *s = NULL;
+       void *p = dma_alloc_coherent(dev, len, phys, GFP_KERNEL);
+
+       if (!p)
+               return NULL;
+       if (sw_size) {
+               s = kcalloc(nelem, sw_size, GFP_KERNEL);
+
+               if (!s) {
+                       dma_free_coherent(dev, len, p, *phys);
+                       return NULL;
+               }
+       }
+       if (metadata)
+               *(void **)metadata = s;
+       memset(p, 0, len);
+       return p;
+}
+
+/**
+ *     sgl_len - calculates the size of an SGL of the given capacity
+ *     @n: the number of SGL entries
+ *
+ *     Calculates the number of flits needed for a scatter/gather list that
+ *     can hold the given number of entries.
+ */
+static inline unsigned int sgl_len(unsigned int n)
+{
+       n--;
+       return (3 * n) / 2 + (n & 1) + 2;
+}
+
+/**
+ *     flits_to_desc - returns the num of Tx descriptors for the given flits
+ *     @n: the number of flits
+ *
+ *     Returns the number of Tx descriptors needed for the supplied number
+ *     of flits.
+ */
+static inline unsigned int flits_to_desc(unsigned int n)
+{
+       BUG_ON(n > SGE_MAX_WR_LEN / 8);
+       return DIV_ROUND_UP(n, 8);
+}
+
+/**
+ *     is_eth_imm - can an Ethernet packet be sent as immediate data?
+ *     @skb: the packet
+ *
+ *     Returns whether an Ethernet packet is small enough to fit as
+ *     immediate data.
+ */
+static inline int is_eth_imm(const struct sk_buff *skb)
+{
+       return skb->len <= MAX_IMM_TX_PKT_LEN - sizeof(struct cpl_tx_pkt);
+}
+
+/**
+ *     calc_tx_flits - calculate the number of flits for a packet Tx WR
+ *     @skb: the packet
+ *
+ *     Returns the number of flits needed for a Tx WR for the given Ethernet
+ *     packet, including the needed WR and CPL headers.
+ */
+static inline unsigned int calc_tx_flits(const struct sk_buff *skb)
+{
+       unsigned int flits;
+
+       if (is_eth_imm(skb))
+               return DIV_ROUND_UP(skb->len + sizeof(struct cpl_tx_pkt), 8);
+
+       flits = sgl_len(skb_shinfo(skb)->nr_frags + 1) + 4;
+       if (skb_shinfo(skb)->gso_size)
+               flits += 2;
+       return flits;
+}
+
+/**
+ *     calc_tx_descs - calculate the number of Tx descriptors for a packet
+ *     @skb: the packet
+ *
+ *     Returns the number of Tx descriptors needed for the given Ethernet
+ *     packet, including the needed WR and CPL headers.
+ */
+static inline unsigned int calc_tx_descs(const struct sk_buff *skb)
+{
+       return flits_to_desc(calc_tx_flits(skb));
+}
+
+/**
+ *     write_sgl - populate a scatter/gather list for a packet
+ *     @skb: the packet
+ *     @q: the Tx queue we are writing into
+ *     @sgl: starting location for writing the SGL
+ *     @end: points right after the end of the SGL
+ *     @start: start offset into skb main-body data to include in the SGL
+ *     @addr: the list of bus addresses for the SGL elements
+ *
+ *     Generates a gather list for the buffers that make up a packet.
+ *     The caller must provide adequate space for the SGL that will be written.
+ *     The SGL includes all of the packet's page fragments and the data in its
+ *     main body except for the first @start bytes.  @sgl must be 16-byte
+ *     aligned and within a Tx descriptor with available space.  @end points
+ *     right after the end of the SGL but does not account for any potential
+ *     wrap around, i.e., @end > @sgl.
+ */
+static void write_sgl(const struct sk_buff *skb, struct sge_txq *q,
+                     struct ulptx_sgl *sgl, u64 *end, unsigned int start,
+                     const dma_addr_t *addr)
+{
+       unsigned int i, len;
+       struct ulptx_sge_pair *to;
+       const struct skb_shared_info *si = skb_shinfo(skb);
+       unsigned int nfrags = si->nr_frags;
+       struct ulptx_sge_pair buf[MAX_SKB_FRAGS / 2 + 1];
+
+       len = skb_headlen(skb) - start;
+       if (likely(len)) {
+               sgl->len0 = htonl(len);
+               sgl->addr0 = cpu_to_be64(addr[0] + start);
+               nfrags++;
+       } else {
+               sgl->len0 = htonl(si->frags[0].size);
+               sgl->addr0 = cpu_to_be64(addr[1]);
+       }
+
+       sgl->cmd_nsge = htonl(ULPTX_CMD(ULP_TX_SC_DSGL) | ULPTX_NSGE(nfrags));
+       if (likely(--nfrags == 0))
+               return;
+       /*
+        * Most of the complexity below deals with the possibility we hit the
+        * end of the queue in the middle of writing the SGL.  For this case
+        * only we create the SGL in a temporary buffer and then copy it.
+        */
+       to = (u8 *)end > (u8 *)q->stat ? buf : sgl->sge;
+
+       for (i = (nfrags != si->nr_frags); nfrags >= 2; nfrags -= 2, to++) {
+               to->len[0] = cpu_to_be32(si->frags[i].size);
+               to->len[1] = cpu_to_be32(si->frags[++i].size);
+               to->addr[0] = cpu_to_be64(addr[i]);
+               to->addr[1] = cpu_to_be64(addr[++i]);
+       }
+       if (nfrags) {
+               to->len[0] = cpu_to_be32(si->frags[i].size);
+               to->len[1] = cpu_to_be32(0);
+               to->addr[0] = cpu_to_be64(addr[i + 1]);
+       }
+       if (unlikely((u8 *)end > (u8 *)q->stat)) {
+               unsigned int part0 = (u8 *)q->stat - (u8 *)sgl->sge, part1;
+
+               if (likely(part0))
+                       memcpy(sgl->sge, buf, part0);
+               part1 = (u8 *)end - (u8 *)q->stat;
+               memcpy(q->desc, (u8 *)buf + part0, part1);
+               end = (void *)q->desc + part1;
+       }
+       if ((uintptr_t)end & 8)           /* 0-pad to multiple of 16 */
+               *(u64 *)end = 0;
+}
+
+/**
+ *     ring_tx_db - check and potentially ring a Tx queue's doorbell
+ *     @adap: the adapter
+ *     @q: the Tx queue
+ *     @n: number of new descriptors to give to HW
+ *
+ *     Ring the doorbel for a Tx queue.
+ */
+static inline void ring_tx_db(struct adapter *adap, struct sge_txq *q, int n)
+{
+       wmb();            /* write descriptors before telling HW */
+       t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL),
+                    QID(q->cntxt_id) | PIDX(n));
+}
+
+/**
+ *     inline_tx_skb - inline a packet's data into Tx descriptors
+ *     @skb: the packet
+ *     @q: the Tx queue where the packet will be inlined
+ *     @pos: starting position in the Tx queue where to inline the packet
+ *
+ *     Inline a packet's contents directly into Tx descriptors, starting at
+ *     the given position within the Tx DMA ring.
+ *     Most of the complexity of this operation is dealing with wrap arounds
+ *     in the middle of the packet we want to inline.
+ */
+static void inline_tx_skb(const struct sk_buff *skb, const struct sge_txq *q,
+                         void *pos)
+{
+       u64 *p;
+       int left = (void *)q->stat - pos;
+
+       if (likely(skb->len <= left)) {
+               if (likely(!skb->data_len))
+                       skb_copy_from_linear_data(skb, pos, skb->len);
+               else
+                       skb_copy_bits(skb, 0, pos, skb->len);
+               pos += skb->len;
+       } else {
+               skb_copy_bits(skb, 0, pos, left);
+               skb_copy_bits(skb, left, q->desc, skb->len - left);
+               pos = (void *)q->desc + (skb->len - left);
+       }
+
+       /* 0-pad to multiple of 16 */
+       p = PTR_ALIGN(pos, 8);
+       if ((uintptr_t)p & 8)
+               *p = 0;
+}
+
+/*
+ * Figure out what HW csum a packet wants and return the appropriate control
+ * bits.
+ */
+static u64 hwcsum(const struct sk_buff *skb)
+{
+       int csum_type;
+       const struct iphdr *iph = ip_hdr(skb);
+
+       if (iph->version == 4) {
+               if (iph->protocol == IPPROTO_TCP)
+                       csum_type = TX_CSUM_TCPIP;
+               else if (iph->protocol == IPPROTO_UDP)
+                       csum_type = TX_CSUM_UDPIP;
+               else {
+nocsum:                        /*
+                        * unknown protocol, disable HW csum
+                        * and hope a bad packet is detected
+                        */
+                       return TXPKT_L4CSUM_DIS;
+               }
+       } else {
+               /*
+                * this doesn't work with extension headers
+                */
+               const struct ipv6hdr *ip6h = (const struct ipv6hdr *)iph;
+
+               if (ip6h->nexthdr == IPPROTO_TCP)
+                       csum_type = TX_CSUM_TCPIP6;
+               else if (ip6h->nexthdr == IPPROTO_UDP)
+                       csum_type = TX_CSUM_UDPIP6;
+               else
+                       goto nocsum;
+       }
+
+       if (likely(csum_type >= TX_CSUM_TCPIP))
+               return TXPKT_CSUM_TYPE(csum_type) |
+                       TXPKT_IPHDR_LEN(skb_network_header_len(skb)) |
+                       TXPKT_ETHHDR_LEN(skb_network_offset(skb) - ETH_HLEN);
+       else {
+               int start = skb_transport_offset(skb);
+
+               return TXPKT_CSUM_TYPE(csum_type) | TXPKT_CSUM_START(start) |
+                       TXPKT_CSUM_LOC(start + skb->csum_offset);
+       }
+}
+
+static void eth_txq_stop(struct sge_eth_txq *q)
+{
+       netif_tx_stop_queue(q->txq);
+       q->q.stops++;
+}
+
+static inline void txq_advance(struct sge_txq *q, unsigned int n)
+{
+       q->in_use += n;
+       q->pidx += n;
+       if (q->pidx >= q->size)
+               q->pidx -= q->size;
+}
+
+/**
+ *     t4_eth_xmit - add a packet to an Ethernet Tx queue
+ *     @skb: the packet
+ *     @dev: the egress net device
+ *
+ *     Add a packet to an SGE Ethernet Tx queue.  Runs with softirqs disabled.
+ */
+netdev_tx_t t4_eth_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       u32 wr_mid;
+       u64 cntrl, *end;
+       int qidx, credits;
+       unsigned int flits, ndesc;
+       struct adapter *adap;
+       struct sge_eth_txq *q;
+       const struct port_info *pi;
+       struct fw_eth_tx_pkt_wr *wr;
+       struct cpl_tx_pkt_core *cpl;
+       const struct skb_shared_info *ssi;
+       dma_addr_t addr[MAX_SKB_FRAGS + 1];
+
+       /*
+        * The chip min packet length is 10 octets but play safe and reject
+        * anything shorter than an Ethernet header.
+        */
+       if (unlikely(skb->len < ETH_HLEN)) {
+out_free:      dev_kfree_skb(skb);
+               return NETDEV_TX_OK;
+       }
+
+       pi = netdev_priv(dev);
+       adap = pi->adapter;
+       qidx = skb_get_queue_mapping(skb);
+       q = &adap->sge.ethtxq[qidx + pi->first_qset];
+
+       reclaim_completed_tx(adap, &q->q, true);
+
+       flits = calc_tx_flits(skb);
+       ndesc = flits_to_desc(flits);
+       credits = txq_avail(&q->q) - ndesc;
+
+       if (unlikely(credits < 0)) {
+               eth_txq_stop(q);
+               dev_err(adap->pdev_dev,
+                       "%s: Tx ring %u full while queue awake!\n",
+                       dev->name, qidx);
+               return NETDEV_TX_BUSY;
+       }
+
+       if (!is_eth_imm(skb) &&
+           unlikely(map_skb(adap->pdev_dev, skb, addr) < 0)) {
+               q->mapping_err++;
+               goto out_free;
+       }
+
+       wr_mid = FW_WR_LEN16(DIV_ROUND_UP(flits, 2));
+       if (unlikely(credits < ETHTXQ_STOP_THRES)) {
+               eth_txq_stop(q);
+               wr_mid |= FW_WR_EQUEQ | FW_WR_EQUIQ;
+       }
+
+       wr = (void *)&q->q.desc[q->q.pidx];
+       wr->equiq_to_len16 = htonl(wr_mid);
+       wr->r3 = cpu_to_be64(0);
+       end = (u64 *)wr + flits;
+
+       ssi = skb_shinfo(skb);
+       if (ssi->gso_size) {
+               struct cpl_tx_pkt_lso *lso = (void *)wr;
+               bool v6 = (ssi->gso_type & SKB_GSO_TCPV6) != 0;
+               int l3hdr_len = skb_network_header_len(skb);
+               int eth_xtra_len = skb_network_offset(skb) - ETH_HLEN;
+
+               wr->op_immdlen = htonl(FW_WR_OP(FW_ETH_TX_PKT_WR) |
+                                      FW_WR_IMMDLEN(sizeof(*lso)));
+               lso->lso_ctrl = htonl(LSO_OPCODE(CPL_TX_PKT_LSO) |
+                                     LSO_FIRST_SLICE | LSO_LAST_SLICE |
+                                     LSO_IPV6(v6) |
+                                     LSO_ETHHDR_LEN(eth_xtra_len / 4) |
+                                     LSO_IPHDR_LEN(l3hdr_len / 4) |
+                                     LSO_TCPHDR_LEN(tcp_hdr(skb)->doff));
+               lso->ipid_ofst = htons(0);
+               lso->mss = htons(ssi->gso_size);
+               lso->seqno_offset = htonl(0);
+               lso->len = htonl(skb->len);
+               cpl = (void *)(lso + 1);
+               cntrl = TXPKT_CSUM_TYPE(v6 ? TX_CSUM_TCPIP6 : TX_CSUM_TCPIP) |
+                       TXPKT_IPHDR_LEN(l3hdr_len) |
+                       TXPKT_ETHHDR_LEN(eth_xtra_len);
+               q->tso++;
+               q->tx_cso += ssi->gso_segs;
+       } else {
+               int len;
+
+               len = is_eth_imm(skb) ? skb->len + sizeof(*cpl) : sizeof(*cpl);
+               wr->op_immdlen = htonl(FW_WR_OP(FW_ETH_TX_PKT_WR) |
+                                      FW_WR_IMMDLEN(len));
+               cpl = (void *)(wr + 1);
+               if (skb->ip_summed == CHECKSUM_PARTIAL) {
+                       cntrl = hwcsum(skb) | TXPKT_IPCSUM_DIS;
+                       q->tx_cso++;
+               } else
+                       cntrl = TXPKT_L4CSUM_DIS | TXPKT_IPCSUM_DIS;
+       }
+
+       if (vlan_tx_tag_present(skb)) {
+               q->vlan_ins++;
+               cntrl |= TXPKT_VLAN_VLD | TXPKT_VLAN(vlan_tx_tag_get(skb));
+       }
+
+       cpl->ctrl0 = htonl(TXPKT_OPCODE(CPL_TX_PKT_XT) |
+                          TXPKT_INTF(pi->tx_chan) | TXPKT_PF(0));
+       cpl->pack = htons(0);
+       cpl->len = htons(skb->len);
+       cpl->ctrl1 = cpu_to_be64(cntrl);
+
+       if (is_eth_imm(skb)) {
+               inline_tx_skb(skb, &q->q, cpl + 1);
+               dev_kfree_skb(skb);
+       } else {
+               int last_desc;
+
+               write_sgl(skb, &q->q, (struct ulptx_sgl *)(cpl + 1), end, 0,
+                         addr);
+               skb_orphan(skb);
+
+               last_desc = q->q.pidx + ndesc - 1;
+               if (last_desc >= q->q.size)
+                       last_desc -= q->q.size;
+               q->q.sdesc[last_desc].skb = skb;
+               q->q.sdesc[last_desc].sgl = (struct ulptx_sgl *)(cpl + 1);
+       }
+
+       txq_advance(&q->q, ndesc);
+
+       ring_tx_db(adap, &q->q, ndesc);
+       return NETDEV_TX_OK;
+}
+
+/**
+ *     reclaim_completed_tx_imm - reclaim completed control-queue Tx descs
+ *     @q: the SGE control Tx queue
+ *
+ *     This is a variant of reclaim_completed_tx() that is used for Tx queues
+ *     that send only immediate data (presently just the control queues) and
+ *     thus do not have any sk_buffs to release.
+ */
+static inline void reclaim_completed_tx_imm(struct sge_txq *q)
+{
+       int hw_cidx = ntohs(q->stat->cidx);
+       int reclaim = hw_cidx - q->cidx;
+
+       if (reclaim < 0)
+               reclaim += q->size;
+
+       q->in_use -= reclaim;
+       q->cidx = hw_cidx;
+}
+
+/**
+ *     is_imm - check whether a packet can be sent as immediate data
+ *     @skb: the packet
+ *
+ *     Returns true if a packet can be sent as a WR with immediate data.
+ */
+static inline int is_imm(const struct sk_buff *skb)
+{
+       return skb->len <= MAX_CTRL_WR_LEN;
+}
+
+/**
+ *     ctrlq_check_stop - check if a control queue is full and should stop
+ *     @q: the queue
+ *     @wr: most recent WR written to the queue
+ *
+ *     Check if a control queue has become full and should be stopped.
+ *     We clean up control queue descriptors very lazily, only when we are out.
+ *     If the queue is still full after reclaiming any completed descriptors
+ *     we suspend it and have the last WR wake it up.
+ */
+static void ctrlq_check_stop(struct sge_ctrl_txq *q, struct fw_wr_hdr *wr)
+{
+       reclaim_completed_tx_imm(&q->q);
+       if (unlikely(txq_avail(&q->q) < TXQ_STOP_THRES)) {
+               wr->lo |= htonl(FW_WR_EQUEQ | FW_WR_EQUIQ);
+               q->q.stops++;
+               q->full = 1;
+       }
+}
+
+/**
+ *     ctrl_xmit - send a packet through an SGE control Tx queue
+ *     @q: the control queue
+ *     @skb: the packet
+ *
+ *     Send a packet through an SGE control Tx queue.  Packets sent through
+ *     a control queue must fit entirely as immediate data.
+ */
+static int ctrl_xmit(struct sge_ctrl_txq *q, struct sk_buff *skb)
+{
+       unsigned int ndesc;
+       struct fw_wr_hdr *wr;
+
+       if (unlikely(!is_imm(skb))) {
+               WARN_ON(1);
+               dev_kfree_skb(skb);
+               return NET_XMIT_DROP;
+       }
+
+       ndesc = DIV_ROUND_UP(skb->len, sizeof(struct tx_desc));
+       spin_lock(&q->sendq.lock);
+
+       if (unlikely(q->full)) {
+               skb->priority = ndesc;                  /* save for restart */
+               __skb_queue_tail(&q->sendq, skb);
+               spin_unlock(&q->sendq.lock);
+               return NET_XMIT_CN;
+       }
+
+       wr = (struct fw_wr_hdr *)&q->q.desc[q->q.pidx];
+       inline_tx_skb(skb, &q->q, wr);
+
+       txq_advance(&q->q, ndesc);
+       if (unlikely(txq_avail(&q->q) < TXQ_STOP_THRES))
+               ctrlq_check_stop(q, wr);
+
+       ring_tx_db(q->adap, &q->q, ndesc);
+       spin_unlock(&q->sendq.lock);
+
+       kfree_skb(skb);
+       return NET_XMIT_SUCCESS;
+}
+
+/**
+ *     restart_ctrlq - restart a suspended control queue
+ *     @data: the control queue to restart
+ *
+ *     Resumes transmission on a suspended Tx control queue.
+ */
+static void restart_ctrlq(unsigned long data)
+{
+       struct sk_buff *skb;
+       unsigned int written = 0;
+       struct sge_ctrl_txq *q = (struct sge_ctrl_txq *)data;
+
+       spin_lock(&q->sendq.lock);
+       reclaim_completed_tx_imm(&q->q);
+       BUG_ON(txq_avail(&q->q) < TXQ_STOP_THRES);  /* q should be empty */
+
+       while ((skb = __skb_dequeue(&q->sendq)) != NULL) {
+               struct fw_wr_hdr *wr;
+               unsigned int ndesc = skb->priority;     /* previously saved */
+
+               /*
+                * Write descriptors and free skbs outside the lock to limit
+                * wait times.  q->full is still set so new skbs will be queued.
+                */
+               spin_unlock(&q->sendq.lock);
+
+               wr = (struct fw_wr_hdr *)&q->q.desc[q->q.pidx];
+               inline_tx_skb(skb, &q->q, wr);
+               kfree_skb(skb);
+
+               written += ndesc;
+               txq_advance(&q->q, ndesc);
+               if (unlikely(txq_avail(&q->q) < TXQ_STOP_THRES)) {
+                       unsigned long old = q->q.stops;
+
+                       ctrlq_check_stop(q, wr);
+                       if (q->q.stops != old) {          /* suspended anew */
+                               spin_lock(&q->sendq.lock);
+                               goto ringdb;
+                       }
+               }
+               if (written > 16) {
+                       ring_tx_db(q->adap, &q->q, written);
+                       written = 0;
+               }
+               spin_lock(&q->sendq.lock);
+       }
+       q->full = 0;
+ringdb: if (written)
+               ring_tx_db(q->adap, &q->q, written);
+       spin_unlock(&q->sendq.lock);
+}
+
+/**
+ *     t4_mgmt_tx - send a management message
+ *     @adap: the adapter
+ *     @skb: the packet containing the management message
+ *
+ *     Send a management message through control queue 0.
+ */
+int t4_mgmt_tx(struct adapter *adap, struct sk_buff *skb)
+{
+       int ret;
+
+       local_bh_disable();
+       ret = ctrl_xmit(&adap->sge.ctrlq[0], skb);
+       local_bh_enable();
+       return ret;
+}
+
+/**
+ *     is_ofld_imm - check whether a packet can be sent as immediate data
+ *     @skb: the packet
+ *
+ *     Returns true if a packet can be sent as an offload WR with immediate
+ *     data.  We currently use the same limit as for Ethernet packets.
+ */
+static inline int is_ofld_imm(const struct sk_buff *skb)
+{
+       return skb->len <= MAX_IMM_TX_PKT_LEN;
+}
+
+/**
+ *     calc_tx_flits_ofld - calculate # of flits for an offload packet
+ *     @skb: the packet
+ *
+ *     Returns the number of flits needed for the given offload packet.
+ *     These packets are already fully constructed and no additional headers
+ *     will be added.
+ */
+static inline unsigned int calc_tx_flits_ofld(const struct sk_buff *skb)
+{
+       unsigned int flits, cnt;
+
+       if (is_ofld_imm(skb))
+               return DIV_ROUND_UP(skb->len, 8);
+
+       flits = skb_transport_offset(skb) / 8U;   /* headers */
+       cnt = skb_shinfo(skb)->nr_frags;
+       if (skb->tail != skb->transport_header)
+               cnt++;
+       return flits + sgl_len(cnt);
+}
+
+/**
+ *     txq_stop_maperr - stop a Tx queue due to I/O MMU exhaustion
+ *     @adap: the adapter
+ *     @q: the queue to stop
+ *
+ *     Mark a Tx queue stopped due to I/O MMU exhaustion and resulting
+ *     inability to map packets.  A periodic timer attempts to restart
+ *     queues so marked.
+ */
+static void txq_stop_maperr(struct sge_ofld_txq *q)
+{
+       q->mapping_err++;
+       q->q.stops++;
+       set_bit(q->q.cntxt_id, q->adap->sge.txq_maperr);
+}
+
+/**
+ *     ofldtxq_stop - stop an offload Tx queue that has become full
+ *     @q: the queue to stop
+ *     @skb: the packet causing the queue to become full
+ *
+ *     Stops an offload Tx queue that has become full and modifies the packet
+ *     being written to request a wakeup.
+ */
+static void ofldtxq_stop(struct sge_ofld_txq *q, struct sk_buff *skb)
+{
+       struct fw_wr_hdr *wr = (struct fw_wr_hdr *)skb->data;
+
+       wr->lo |= htonl(FW_WR_EQUEQ | FW_WR_EQUIQ);
+       q->q.stops++;
+       q->full = 1;
+}
+
+/**
+ *     service_ofldq - restart a suspended offload queue
+ *     @q: the offload queue
+ *
+ *     Services an offload Tx queue by moving packets from its packet queue
+ *     to the HW Tx ring.  The function starts and ends with the queue locked.
+ */
+static void service_ofldq(struct sge_ofld_txq *q)
+{
+       u64 *pos;
+       int credits;
+       struct sk_buff *skb;
+       unsigned int written = 0;
+       unsigned int flits, ndesc;
+
+       while ((skb = skb_peek(&q->sendq)) != NULL && !q->full) {
+               /*
+                * We drop the lock but leave skb on sendq, thus retaining
+                * exclusive access to the state of the queue.
+                */
+               spin_unlock(&q->sendq.lock);
+
+               reclaim_completed_tx(q->adap, &q->q, false);
+
+               flits = skb->priority;                /* previously saved */
+               ndesc = flits_to_desc(flits);
+               credits = txq_avail(&q->q) - ndesc;
+               BUG_ON(credits < 0);
+               if (unlikely(credits < TXQ_STOP_THRES))
+                       ofldtxq_stop(q, skb);
+
+               pos = (u64 *)&q->q.desc[q->q.pidx];
+               if (is_ofld_imm(skb))
+                       inline_tx_skb(skb, &q->q, pos);
+               else if (map_skb(q->adap->pdev_dev, skb,
+                                (dma_addr_t *)skb->head)) {
+                       txq_stop_maperr(q);
+                       spin_lock(&q->sendq.lock);
+                       break;
+               } else {
+                       int last_desc, hdr_len = skb_transport_offset(skb);
+
+                       memcpy(pos, skb->data, hdr_len);
+                       write_sgl(skb, &q->q, (void *)pos + hdr_len,
+                                 pos + flits, hdr_len,
+                                 (dma_addr_t *)skb->head);
+#ifdef CONFIG_NEED_DMA_MAP_STATE
+                       skb->dev = q->adap->port[0];
+                       skb->destructor = deferred_unmap_destructor;
+#endif
+                       last_desc = q->q.pidx + ndesc - 1;
+                       if (last_desc >= q->q.size)
+                               last_desc -= q->q.size;
+                       q->q.sdesc[last_desc].skb = skb;
+               }
+
+               txq_advance(&q->q, ndesc);
+               written += ndesc;
+               if (unlikely(written > 32)) {
+                       ring_tx_db(q->adap, &q->q, written);
+                       written = 0;
+               }
+
+               spin_lock(&q->sendq.lock);
+               __skb_unlink(skb, &q->sendq);
+               if (is_ofld_imm(skb))
+                       kfree_skb(skb);
+       }
+       if (likely(written))
+               ring_tx_db(q->adap, &q->q, written);
+}
+
+/**
+ *     ofld_xmit - send a packet through an offload queue
+ *     @q: the Tx offload queue
+ *     @skb: the packet
+ *
+ *     Send an offload packet through an SGE offload queue.
+ */
+static int ofld_xmit(struct sge_ofld_txq *q, struct sk_buff *skb)
+{
+       skb->priority = calc_tx_flits_ofld(skb);       /* save for restart */
+       spin_lock(&q->sendq.lock);
+       __skb_queue_tail(&q->sendq, skb);
+       if (q->sendq.qlen == 1)
+               service_ofldq(q);
+       spin_unlock(&q->sendq.lock);
+       return NET_XMIT_SUCCESS;
+}
+
+/**
+ *     restart_ofldq - restart a suspended offload queue
+ *     @data: the offload queue to restart
+ *
+ *     Resumes transmission on a suspended Tx offload queue.
+ */
+static void restart_ofldq(unsigned long data)
+{
+       struct sge_ofld_txq *q = (struct sge_ofld_txq *)data;
+
+       spin_lock(&q->sendq.lock);
+       q->full = 0;            /* the queue actually is completely empty now */
+       service_ofldq(q);
+       spin_unlock(&q->sendq.lock);
+}
+
+/**
+ *     skb_txq - return the Tx queue an offload packet should use
+ *     @skb: the packet
+ *
+ *     Returns the Tx queue an offload packet should use as indicated by bits
+ *     1-15 in the packet's queue_mapping.
+ */
+static inline unsigned int skb_txq(const struct sk_buff *skb)
+{
+       return skb->queue_mapping >> 1;
+}
+
+/**
+ *     is_ctrl_pkt - return whether an offload packet is a control packet
+ *     @skb: the packet
+ *
+ *     Returns whether an offload packet should use an OFLD or a CTRL
+ *     Tx queue as indicated by bit 0 in the packet's queue_mapping.
+ */
+static inline unsigned int is_ctrl_pkt(const struct sk_buff *skb)
+{
+       return skb->queue_mapping & 1;
+}
+
+static inline int ofld_send(struct adapter *adap, struct sk_buff *skb)
+{
+       unsigned int idx = skb_txq(skb);
+
+       if (unlikely(is_ctrl_pkt(skb)))
+               return ctrl_xmit(&adap->sge.ctrlq[idx], skb);
+       return ofld_xmit(&adap->sge.ofldtxq[idx], skb);
+}
+
+/**
+ *     t4_ofld_send - send an offload packet
+ *     @adap: the adapter
+ *     @skb: the packet
+ *
+ *     Sends an offload packet.  We use the packet queue_mapping to select the
+ *     appropriate Tx queue as follows: bit 0 indicates whether the packet
+ *     should be sent as regular or control, bits 1-15 select the queue.
+ */
+int t4_ofld_send(struct adapter *adap, struct sk_buff *skb)
+{
+       int ret;
+
+       local_bh_disable();
+       ret = ofld_send(adap, skb);
+       local_bh_enable();
+       return ret;
+}
+
+/**
+ *     cxgb4_ofld_send - send an offload packet
+ *     @dev: the net device
+ *     @skb: the packet
+ *
+ *     Sends an offload packet.  This is an exported version of @t4_ofld_send,
+ *     intended for ULDs.
+ */
+int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb)
+{
+       return t4_ofld_send(netdev2adap(dev), skb);
+}
+EXPORT_SYMBOL(cxgb4_ofld_send);
+
+static inline void copy_frags(struct skb_shared_info *ssi,
+                             const struct pkt_gl *gl, unsigned int offset)
+{
+       unsigned int n;
+
+       /* usually there's just one frag */
+       ssi->frags[0].page = gl->frags[0].page;
+       ssi->frags[0].page_offset = gl->frags[0].page_offset + offset;
+       ssi->frags[0].size = gl->frags[0].size - offset;
+       ssi->nr_frags = gl->nfrags;
+       n = gl->nfrags - 1;
+       if (n)
+               memcpy(&ssi->frags[1], &gl->frags[1], n * sizeof(skb_frag_t));
+
+       /* get a reference to the last page, we don't own it */
+       get_page(gl->frags[n].page);
+}
+
+/**
+ *     cxgb4_pktgl_to_skb - build an sk_buff from a packet gather list
+ *     @gl: the gather list
+ *     @skb_len: size of sk_buff main body if it carries fragments
+ *     @pull_len: amount of data to move to the sk_buff's main body
+ *
+ *     Builds an sk_buff from the given packet gather list.  Returns the
+ *     sk_buff or %NULL if sk_buff allocation failed.
+ */
+struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl,
+                                  unsigned int skb_len, unsigned int pull_len)
+{
+       struct sk_buff *skb;
+
+       /*
+        * Below we rely on RX_COPY_THRES being less than the smallest Rx buffer
+        * size, which is expected since buffers are at least PAGE_SIZEd.
+        * In this case packets up to RX_COPY_THRES have only one fragment.
+        */
+       if (gl->tot_len <= RX_COPY_THRES) {
+               skb = dev_alloc_skb(gl->tot_len);
+               if (unlikely(!skb))
+                       goto out;
+               __skb_put(skb, gl->tot_len);
+               skb_copy_to_linear_data(skb, gl->va, gl->tot_len);
+       } else {
+               skb = dev_alloc_skb(skb_len);
+               if (unlikely(!skb))
+                       goto out;
+               __skb_put(skb, pull_len);
+               skb_copy_to_linear_data(skb, gl->va, pull_len);
+
+               copy_frags(skb_shinfo(skb), gl, pull_len);
+               skb->len = gl->tot_len;
+               skb->data_len = skb->len - pull_len;
+               skb->truesize += skb->data_len;
+       }
+out:   return skb;
+}
+EXPORT_SYMBOL(cxgb4_pktgl_to_skb);
+
+/**
+ *     t4_pktgl_free - free a packet gather list
+ *     @gl: the gather list
+ *
+ *     Releases the pages of a packet gather list.  We do not own the last
+ *     page on the list and do not free it.
+ */
+void t4_pktgl_free(const struct pkt_gl *gl)
+{
+       int n;
+       const skb_frag_t *p;
+
+       for (p = gl->frags, n = gl->nfrags - 1; n--; p++)
+               put_page(p->page);
+}
+
+/*
+ * Process an MPS trace packet.  Give it an unused protocol number so it won't
+ * be delivered to anyone and send it to the stack for capture.
+ */
+static noinline int handle_trace_pkt(struct adapter *adap,
+                                    const struct pkt_gl *gl)
+{
+       struct sk_buff *skb;
+       struct cpl_trace_pkt *p;
+
+       skb = cxgb4_pktgl_to_skb(gl, RX_PULL_LEN, RX_PULL_LEN);
+       if (unlikely(!skb)) {
+               t4_pktgl_free(gl);
+               return 0;
+       }
+
+       p = (struct cpl_trace_pkt *)skb->data;
+       __skb_pull(skb, sizeof(*p));
+       skb_reset_mac_header(skb);
+       skb->protocol = htons(0xffff);
+       skb->dev = adap->port[0];
+       netif_receive_skb(skb);
+       return 0;
+}
+
+static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl,
+                  const struct cpl_rx_pkt *pkt)
+{
+       int ret;
+       struct sk_buff *skb;
+
+       skb = napi_get_frags(&rxq->rspq.napi);
+       if (unlikely(!skb)) {
+               t4_pktgl_free(gl);
+               rxq->stats.rx_drops++;
+               return;
+       }
+
+       copy_frags(skb_shinfo(skb), gl, RX_PKT_PAD);
+       skb->len = gl->tot_len - RX_PKT_PAD;
+       skb->data_len = skb->len;
+       skb->truesize += skb->data_len;
+       skb->ip_summed = CHECKSUM_UNNECESSARY;
+       skb_record_rx_queue(skb, rxq->rspq.idx);
+
+       if (unlikely(pkt->vlan_ex)) {
+               struct port_info *pi = netdev_priv(rxq->rspq.netdev);
+               struct vlan_group *grp = pi->vlan_grp;
+
+               rxq->stats.vlan_ex++;
+               if (likely(grp)) {
+                       ret = vlan_gro_frags(&rxq->rspq.napi, grp,
+                                            ntohs(pkt->vlan));
+                       goto stats;
+               }
+       }
+       ret = napi_gro_frags(&rxq->rspq.napi);
+stats: if (ret == GRO_HELD)
+               rxq->stats.lro_pkts++;
+       else if (ret == GRO_MERGED || ret == GRO_MERGED_FREE)
+               rxq->stats.lro_merged++;
+       rxq->stats.pkts++;
+       rxq->stats.rx_cso++;
+}
+
+/**
+ *     t4_ethrx_handler - process an ingress ethernet packet
+ *     @q: the response queue that received the packet
+ *     @rsp: the response queue descriptor holding the RX_PKT message
+ *     @si: the gather list of packet fragments
+ *
+ *     Process an ingress ethernet packet and deliver it to the stack.
+ */
+int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
+                    const struct pkt_gl *si)
+{
+       bool csum_ok;
+       struct sk_buff *skb;
+       struct port_info *pi;
+       const struct cpl_rx_pkt *pkt;
+       struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq);
+
+       if (unlikely(*(u8 *)rsp == CPL_TRACE_PKT))
+               return handle_trace_pkt(q->adap, si);
+
+       pkt = (void *)&rsp[1];
+       csum_ok = pkt->csum_calc && !pkt->err_vec;
+       if ((pkt->l2info & htonl(RXF_TCP)) &&
+           (q->netdev->features & NETIF_F_GRO) && csum_ok && !pkt->ip_frag) {
+               do_gro(rxq, si, pkt);
+               return 0;
+       }
+
+       skb = cxgb4_pktgl_to_skb(si, RX_PKT_SKB_LEN, RX_PULL_LEN);
+       if (unlikely(!skb)) {
+               t4_pktgl_free(si);
+               rxq->stats.rx_drops++;
+               return 0;
+       }
+
+       __skb_pull(skb, RX_PKT_PAD);      /* remove ethernet header padding */
+       skb->protocol = eth_type_trans(skb, q->netdev);
+       skb_record_rx_queue(skb, q->idx);
+       pi = netdev_priv(skb->dev);
+       rxq->stats.pkts++;
+
+       if (csum_ok && (pi->rx_offload & RX_CSO) &&
+           (pkt->l2info & htonl(RXF_UDP | RXF_TCP))) {
+               if (!pkt->ip_frag)
+                       skb->ip_summed = CHECKSUM_UNNECESSARY;
+               else {
+                       __sum16 c = (__force __sum16)pkt->csum;
+                       skb->csum = csum_unfold(c);
+                       skb->ip_summed = CHECKSUM_COMPLETE;
+               }
+               rxq->stats.rx_cso++;
+       } else
+               skb->ip_summed = CHECKSUM_NONE;
+
+       if (unlikely(pkt->vlan_ex)) {
+               struct vlan_group *grp = pi->vlan_grp;
+
+               rxq->stats.vlan_ex++;
+               if (likely(grp))
+                       vlan_hwaccel_receive_skb(skb, grp, ntohs(pkt->vlan));
+               else
+                       dev_kfree_skb_any(skb);
+       } else
+               netif_receive_skb(skb);
+
+       return 0;
+}
+
+/**
+ *     restore_rx_bufs - put back a packet's Rx buffers
+ *     @si: the packet gather list
+ *     @q: the SGE free list
+ *     @frags: number of FL buffers to restore
+ *
+ *     Puts back on an FL the Rx buffers associated with @si.  The buffers
+ *     have already been unmapped and are left unmapped, we mark them so to
+ *     prevent further unmapping attempts.
+ *
+ *     This function undoes a series of @unmap_rx_buf calls when we find out
+ *     that the current packet can't be processed right away afterall and we
+ *     need to come back to it later.  This is a very rare event and there's
+ *     no effort to make this particularly efficient.
+ */
+static void restore_rx_bufs(const struct pkt_gl *si, struct sge_fl *q,
+                           int frags)
+{
+       struct rx_sw_desc *d;
+
+       while (frags--) {
+               if (q->cidx == 0)
+                       q->cidx = q->size - 1;
+               else
+                       q->cidx--;
+               d = &q->sdesc[q->cidx];
+               d->page = si->frags[frags].page;
+               d->dma_addr |= RX_UNMAPPED_BUF;
+               q->avail++;
+       }
+}
+
+/**
+ *     is_new_response - check if a response is newly written
+ *     @r: the response descriptor
+ *     @q: the response queue
+ *
+ *     Returns true if a response descriptor contains a yet unprocessed
+ *     response.
+ */
+static inline bool is_new_response(const struct rsp_ctrl *r,
+                                  const struct sge_rspq *q)
+{
+       return RSPD_GEN(r->type_gen) == q->gen;
+}
+
+/**
+ *     rspq_next - advance to the next entry in a response queue
+ *     @q: the queue
+ *
+ *     Updates the state of a response queue to advance it to the next entry.
+ */
+static inline void rspq_next(struct sge_rspq *q)
+{
+       q->cur_desc = (void *)q->cur_desc + q->iqe_len;
+       if (unlikely(++q->cidx == q->size)) {
+               q->cidx = 0;
+               q->gen ^= 1;
+               q->cur_desc = q->desc;
+       }
+}
+
+/**
+ *     process_responses - process responses from an SGE response queue
+ *     @q: the ingress queue to process
+ *     @budget: how many responses can be processed in this round
+ *
+ *     Process responses from an SGE response queue up to the supplied budget.
+ *     Responses include received packets as well as control messages from FW
+ *     or HW.
+ *
+ *     Additionally choose the interrupt holdoff time for the next interrupt
+ *     on this queue.  If the system is under memory shortage use a fairly
+ *     long delay to help recovery.
+ */
+static int process_responses(struct sge_rspq *q, int budget)
+{
+       int ret, rsp_type;
+       int budget_left = budget;
+       const struct rsp_ctrl *rc;
+       struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq);
+
+       while (likely(budget_left)) {
+               rc = (void *)q->cur_desc + (q->iqe_len - sizeof(*rc));
+               if (!is_new_response(rc, q))
+                       break;
+
+               rmb();
+               rsp_type = RSPD_TYPE(rc->type_gen);
+               if (likely(rsp_type == RSP_TYPE_FLBUF)) {
+                       skb_frag_t *fp;
+                       struct pkt_gl si;
+                       const struct rx_sw_desc *rsd;
+                       u32 len = ntohl(rc->pldbuflen_qid), bufsz, frags;
+
+                       if (len & RSPD_NEWBUF) {
+                               if (likely(q->offset > 0)) {
+                                       free_rx_bufs(q->adap, &rxq->fl, 1);
+                                       q->offset = 0;
+                               }
+                               len &= RSPD_LEN;
+                       }
+                       si.tot_len = len;
+
+                       /* gather packet fragments */
+                       for (frags = 0, fp = si.frags; ; frags++, fp++) {
+                               rsd = &rxq->fl.sdesc[rxq->fl.cidx];
+                               bufsz = get_buf_size(rsd);
+                               fp->page = rsd->page;
+                               fp->page_offset = q->offset;
+                               fp->size = min(bufsz, len);
+                               len -= fp->size;
+                               if (!len)
+                                       break;
+                               unmap_rx_buf(q->adap, &rxq->fl);
+                       }
+
+                       /*
+                        * Last buffer remains mapped so explicitly make it
+                        * coherent for CPU access.
+                        */
+                       dma_sync_single_for_cpu(q->adap->pdev_dev,
+                                               get_buf_addr(rsd),
+                                               fp->size, DMA_FROM_DEVICE);
+
+                       si.va = page_address(si.frags[0].page) +
+                               si.frags[0].page_offset;
+                       prefetch(si.va);
+
+                       si.nfrags = frags + 1;
+                       ret = q->handler(q, q->cur_desc, &si);
+                       if (likely(ret == 0))
+                               q->offset += ALIGN(fp->size, FL_ALIGN);
+                       else
+                               restore_rx_bufs(&si, &rxq->fl, frags);
+               } else if (likely(rsp_type == RSP_TYPE_CPL)) {
+                       ret = q->handler(q, q->cur_desc, NULL);
+               } else {
+                       ret = q->handler(q, (const __be64 *)rc, CXGB4_MSG_AN);
+               }
+
+               if (unlikely(ret)) {
+                       /* couldn't process descriptor, back off for recovery */
+                       q->next_intr_params = QINTR_TIMER_IDX(NOMEM_TMR_IDX);
+                       break;
+               }
+
+               rspq_next(q);
+               budget_left--;
+       }
+
+       if (q->offset >= 0 && rxq->fl.size - rxq->fl.avail >= 16)
+               __refill_fl(q->adap, &rxq->fl);
+       return budget - budget_left;
+}
+
+/**
+ *     napi_rx_handler - the NAPI handler for Rx processing
+ *     @napi: the napi instance
+ *     @budget: how many packets we can process in this round
+ *
+ *     Handler for new data events when using NAPI.  This does not need any
+ *     locking or protection from interrupts as data interrupts are off at
+ *     this point and other adapter interrupts do not interfere (the latter
+ *     in not a concern at all with MSI-X as non-data interrupts then have
+ *     a separate handler).
+ */
+static int napi_rx_handler(struct napi_struct *napi, int budget)
+{
+       unsigned int params;
+       struct sge_rspq *q = container_of(napi, struct sge_rspq, napi);
+       int work_done = process_responses(q, budget);
+
+       if (likely(work_done < budget)) {
+               napi_complete(napi);
+               params = q->next_intr_params;
+               q->next_intr_params = q->intr_params;
+       } else
+               params = QINTR_TIMER_IDX(7);
+
+       t4_write_reg(q->adap, MYPF_REG(SGE_PF_GTS), CIDXINC(work_done) |
+                    INGRESSQID((u32)q->cntxt_id) | SEINTARM(params));
+       return work_done;
+}
+
+/*
+ * The MSI-X interrupt handler for an SGE response queue.
+ */
+irqreturn_t t4_sge_intr_msix(int irq, void *cookie)
+{
+       struct sge_rspq *q = cookie;
+
+       napi_schedule(&q->napi);
+       return IRQ_HANDLED;
+}
+
+/*
+ * Process the indirect interrupt entries in the interrupt queue and kick off
+ * NAPI for each queue that has generated an entry.
+ */
+static unsigned int process_intrq(struct adapter *adap)
+{
+       unsigned int credits;
+       const struct rsp_ctrl *rc;
+       struct sge_rspq *q = &adap->sge.intrq;
+
+       spin_lock(&adap->sge.intrq_lock);
+       for (credits = 0; ; credits++) {
+               rc = (void *)q->cur_desc + (q->iqe_len - sizeof(*rc));
+               if (!is_new_response(rc, q))
+                       break;
+
+               rmb();
+               if (RSPD_TYPE(rc->type_gen) == RSP_TYPE_INTR) {
+                       unsigned int qid = ntohl(rc->pldbuflen_qid);
+
+                       napi_schedule(&adap->sge.ingr_map[qid]->napi);
+               }
+
+               rspq_next(q);
+       }
+
+       t4_write_reg(adap, MYPF_REG(SGE_PF_GTS), CIDXINC(credits) |
+                    INGRESSQID(q->cntxt_id) | SEINTARM(q->intr_params));
+       spin_unlock(&adap->sge.intrq_lock);
+       return credits;
+}
+
+/*
+ * The MSI interrupt handler, which handles data events from SGE response queues
+ * as well as error and other async events as they all use the same MSI vector.
+ */
+static irqreturn_t t4_intr_msi(int irq, void *cookie)
+{
+       struct adapter *adap = cookie;
+
+       t4_slow_intr_handler(adap);
+       process_intrq(adap);
+       return IRQ_HANDLED;
+}
+
+/*
+ * Interrupt handler for legacy INTx interrupts.
+ * Handles data events from SGE response queues as well as error and other
+ * async events as they all use the same interrupt line.
+ */
+static irqreturn_t t4_intr_intx(int irq, void *cookie)
+{
+       struct adapter *adap = cookie;
+
+       t4_write_reg(adap, MYPF_REG(PCIE_PF_CLI), 0);
+       if (t4_slow_intr_handler(adap) | process_intrq(adap))
+               return IRQ_HANDLED;
+       return IRQ_NONE;             /* probably shared interrupt */
+}
+
+/**
+ *     t4_intr_handler - select the top-level interrupt handler
+ *     @adap: the adapter
+ *
+ *     Selects the top-level interrupt handler based on the type of interrupts
+ *     (MSI-X, MSI, or INTx).
+ */
+irq_handler_t t4_intr_handler(struct adapter *adap)
+{
+       if (adap->flags & USING_MSIX)
+               return t4_sge_intr_msix;
+       if (adap->flags & USING_MSI)
+               return t4_intr_msi;
+       return t4_intr_intx;
+}
+
+static void sge_rx_timer_cb(unsigned long data)
+{
+       unsigned long m;
+       unsigned int i, cnt[2];
+       struct adapter *adap = (struct adapter *)data;
+       struct sge *s = &adap->sge;
+
+       for (i = 0; i < ARRAY_SIZE(s->starving_fl); i++)
+               for (m = s->starving_fl[i]; m; m &= m - 1) {
+                       struct sge_eth_rxq *rxq;
+                       unsigned int id = __ffs(m) + i * BITS_PER_LONG;
+                       struct sge_fl *fl = s->egr_map[id];
+
+                       clear_bit(id, s->starving_fl);
+                       smp_mb__after_clear_bit();
+
+                       if (fl_starving(fl)) {
+                               rxq = container_of(fl, struct sge_eth_rxq, fl);
+                               if (napi_reschedule(&rxq->rspq.napi))
+                                       fl->starving++;
+                               else
+                                       set_bit(id, s->starving_fl);
+                       }
+               }
+
+       t4_write_reg(adap, SGE_DEBUG_INDEX, 13);
+       cnt[0] = t4_read_reg(adap, SGE_DEBUG_DATA_HIGH);
+       cnt[1] = t4_read_reg(adap, SGE_DEBUG_DATA_LOW);
+
+       for (i = 0; i < 2; i++)
+               if (cnt[i] >= s->starve_thres) {
+                       if (s->idma_state[i] || cnt[i] == 0xffffffff)
+                               continue;
+                       s->idma_state[i] = 1;
+                       t4_write_reg(adap, SGE_DEBUG_INDEX, 11);
+                       m = t4_read_reg(adap, SGE_DEBUG_DATA_LOW) >> (i * 16);
+                       dev_warn(adap->pdev_dev,
+                                "SGE idma%u starvation detected for "
+                                "queue %lu\n", i, m & 0xffff);
+               } else if (s->idma_state[i])
+                       s->idma_state[i] = 0;
+
+       mod_timer(&s->rx_timer, jiffies + RX_QCHECK_PERIOD);
+}
+
+static void sge_tx_timer_cb(unsigned long data)
+{
+       unsigned long m;
+       unsigned int i, budget;
+       struct adapter *adap = (struct adapter *)data;
+       struct sge *s = &adap->sge;
+
+       for (i = 0; i < ARRAY_SIZE(s->txq_maperr); i++)
+               for (m = s->txq_maperr[i]; m; m &= m - 1) {
+                       unsigned long id = __ffs(m) + i * BITS_PER_LONG;
+                       struct sge_ofld_txq *txq = s->egr_map[id];
+
+                       clear_bit(id, s->txq_maperr);
+                       tasklet_schedule(&txq->qresume_tsk);
+               }
+
+       budget = MAX_TIMER_TX_RECLAIM;
+       i = s->ethtxq_rover;
+       do {
+               struct sge_eth_txq *q = &s->ethtxq[i];
+
+               if (q->q.in_use &&
+                   time_after_eq(jiffies, q->txq->trans_start + HZ / 100) &&
+                   __netif_tx_trylock(q->txq)) {
+                       int avail = reclaimable(&q->q);
+
+                       if (avail) {
+                               if (avail > budget)
+                                       avail = budget;
+
+                               free_tx_desc(adap, &q->q, avail, true);
+                               q->q.in_use -= avail;
+                               budget -= avail;
+                       }
+                       __netif_tx_unlock(q->txq);
+               }
+
+               if (++i >= s->ethqsets)
+                       i = 0;
+       } while (budget && i != s->ethtxq_rover);
+       s->ethtxq_rover = i;
+       mod_timer(&s->tx_timer, jiffies + (budget ? TX_QCHECK_PERIOD : 2));
+}
+
+int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
+                    struct net_device *dev, int intr_idx,
+                    struct sge_fl *fl, rspq_handler_t hnd)
+{
+       int ret, flsz = 0;
+       struct fw_iq_cmd c;
+       struct port_info *pi = netdev_priv(dev);
+
+       /* Size needs to be multiple of 16, including status entry. */
+       iq->size = roundup(iq->size, 16);
+
+       iq->desc = alloc_ring(adap->pdev_dev, iq->size, iq->iqe_len, 0,
+                             &iq->phys_addr, NULL, 0);
+       if (!iq->desc)
+               return -ENOMEM;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST |
+                           FW_CMD_WRITE | FW_CMD_EXEC |
+                           FW_IQ_CMD_PFN(0) | FW_IQ_CMD_VFN(0));
+       c.alloc_to_len16 = htonl(FW_IQ_CMD_ALLOC | FW_IQ_CMD_IQSTART(1) |
+                                FW_LEN16(c));
+       c.type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE(FW_IQ_TYPE_FL_INT_CAP) |
+               FW_IQ_CMD_IQASYNCH(fwevtq) | FW_IQ_CMD_VIID(pi->viid) |
+               FW_IQ_CMD_IQANDST(intr_idx < 0) | FW_IQ_CMD_IQANUD(1) |
+               FW_IQ_CMD_IQANDSTINDEX(intr_idx >= 0 ? intr_idx :
+                                                       -intr_idx - 1));
+       c.iqdroprss_to_iqesize = htons(FW_IQ_CMD_IQPCIECH(pi->tx_chan) |
+               FW_IQ_CMD_IQGTSMODE |
+               FW_IQ_CMD_IQINTCNTTHRESH(iq->pktcnt_idx) |
+               FW_IQ_CMD_IQESIZE(ilog2(iq->iqe_len) - 4));
+       c.iqsize = htons(iq->size);
+       c.iqaddr = cpu_to_be64(iq->phys_addr);
+
+       if (fl) {
+               fl->size = roundup(fl->size, 8);
+               fl->desc = alloc_ring(adap->pdev_dev, fl->size, sizeof(__be64),
+                                     sizeof(struct rx_sw_desc), &fl->addr,
+                                     &fl->sdesc, STAT_LEN);
+               if (!fl->desc)
+                       goto fl_nomem;
+
+               flsz = fl->size / 8 + STAT_LEN / sizeof(struct tx_desc);
+               c.iqns_to_fl0congen = htonl(FW_IQ_CMD_FL0PACKEN |
+                                           FW_IQ_CMD_FL0PADEN);
+               c.fl0dcaen_to_fl0cidxfthresh = htons(FW_IQ_CMD_FL0FBMIN(2) |
+                               FW_IQ_CMD_FL0FBMAX(3));
+               c.fl0size = htons(flsz);
+               c.fl0addr = cpu_to_be64(fl->addr);
+       }
+
+       ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c);
+       if (ret)
+               goto err;
+
+       netif_napi_add(dev, &iq->napi, napi_rx_handler, 64);
+       iq->cur_desc = iq->desc;
+       iq->cidx = 0;
+       iq->gen = 1;
+       iq->next_intr_params = iq->intr_params;
+       iq->cntxt_id = ntohs(c.iqid);
+       iq->abs_id = ntohs(c.physiqid);
+       iq->size--;                           /* subtract status entry */
+       iq->adap = adap;
+       iq->netdev = dev;
+       iq->handler = hnd;
+
+       /* set offset to -1 to distinguish ingress queues without FL */
+       iq->offset = fl ? 0 : -1;
+
+       adap->sge.ingr_map[iq->cntxt_id] = iq;
+
+       if (fl) {
+               fl->cntxt_id = htons(c.fl0id);
+               fl->avail = fl->pend_cred = 0;
+               fl->pidx = fl->cidx = 0;
+               fl->alloc_failed = fl->large_alloc_failed = fl->starving = 0;
+               adap->sge.egr_map[fl->cntxt_id] = fl;
+               refill_fl(adap, fl, fl_cap(fl), GFP_KERNEL);
+       }
+       return 0;
+
+fl_nomem:
+       ret = -ENOMEM;
+err:
+       if (iq->desc) {
+               dma_free_coherent(adap->pdev_dev, iq->size * iq->iqe_len,
+                                 iq->desc, iq->phys_addr);
+               iq->desc = NULL;
+       }
+       if (fl && fl->desc) {
+               kfree(fl->sdesc);
+               fl->sdesc = NULL;
+               dma_free_coherent(adap->pdev_dev, flsz * sizeof(struct tx_desc),
+                                 fl->desc, fl->addr);
+               fl->desc = NULL;
+       }
+       return ret;
+}
+
+static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id)
+{
+       q->in_use = 0;
+       q->cidx = q->pidx = 0;
+       q->stops = q->restarts = 0;
+       q->stat = (void *)&q->desc[q->size];
+       q->cntxt_id = id;
+       adap->sge.egr_map[id] = q;
+}
+
+int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
+                        struct net_device *dev, struct netdev_queue *netdevq,
+                        unsigned int iqid)
+{
+       int ret, nentries;
+       struct fw_eq_eth_cmd c;
+       struct port_info *pi = netdev_priv(dev);
+
+       /* Add status entries */
+       nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc);
+
+       txq->q.desc = alloc_ring(adap->pdev_dev, txq->q.size,
+                       sizeof(struct tx_desc), sizeof(struct tx_sw_desc),
+                       &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN);
+       if (!txq->q.desc)
+               return -ENOMEM;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_ETH_CMD) | FW_CMD_REQUEST |
+                           FW_CMD_WRITE | FW_CMD_EXEC |
+                           FW_EQ_ETH_CMD_PFN(0) | FW_EQ_ETH_CMD_VFN(0));
+       c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_ALLOC |
+                                FW_EQ_ETH_CMD_EQSTART | FW_LEN16(c));
+       c.viid_pkd = htonl(FW_EQ_ETH_CMD_VIID(pi->viid));
+       c.fetchszm_to_iqid = htonl(FW_EQ_ETH_CMD_HOSTFCMODE(2) |
+                                  FW_EQ_ETH_CMD_PCIECHN(pi->tx_chan) |
+                                  FW_EQ_ETH_CMD_IQID(iqid));
+       c.dcaen_to_eqsize = htonl(FW_EQ_ETH_CMD_FBMIN(2) |
+                                 FW_EQ_ETH_CMD_FBMAX(3) |
+                                 FW_EQ_ETH_CMD_CIDXFTHRESH(5) |
+                                 FW_EQ_ETH_CMD_EQSIZE(nentries));
+       c.eqaddr = cpu_to_be64(txq->q.phys_addr);
+
+       ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c);
+       if (ret) {
+               kfree(txq->q.sdesc);
+               txq->q.sdesc = NULL;
+               dma_free_coherent(adap->pdev_dev,
+                                 nentries * sizeof(struct tx_desc),
+                                 txq->q.desc, txq->q.phys_addr);
+               txq->q.desc = NULL;
+               return ret;
+       }
+
+       init_txq(adap, &txq->q, FW_EQ_ETH_CMD_EQID_GET(ntohl(c.eqid_pkd)));
+       txq->txq = netdevq;
+       txq->tso = txq->tx_cso = txq->vlan_ins = 0;
+       txq->mapping_err = 0;
+       return 0;
+}
+
+int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq,
+                         struct net_device *dev, unsigned int iqid,
+                         unsigned int cmplqid)
+{
+       int ret, nentries;
+       struct fw_eq_ctrl_cmd c;
+       struct port_info *pi = netdev_priv(dev);
+
+       /* Add status entries */
+       nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc);
+
+       txq->q.desc = alloc_ring(adap->pdev_dev, nentries,
+                                sizeof(struct tx_desc), 0, &txq->q.phys_addr,
+                                NULL, 0);
+       if (!txq->q.desc)
+               return -ENOMEM;
+
+       c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_CTRL_CMD) | FW_CMD_REQUEST |
+                           FW_CMD_WRITE | FW_CMD_EXEC |
+                           FW_EQ_CTRL_CMD_PFN(0) | FW_EQ_CTRL_CMD_VFN(0));
+       c.alloc_to_len16 = htonl(FW_EQ_CTRL_CMD_ALLOC |
+                                FW_EQ_CTRL_CMD_EQSTART | FW_LEN16(c));
+       c.cmpliqid_eqid = htonl(FW_EQ_CTRL_CMD_CMPLIQID(cmplqid));
+       c.physeqid_pkd = htonl(0);
+       c.fetchszm_to_iqid = htonl(FW_EQ_CTRL_CMD_HOSTFCMODE(2) |
+                                  FW_EQ_CTRL_CMD_PCIECHN(pi->tx_chan) |
+                                  FW_EQ_CTRL_CMD_IQID(iqid));
+       c.dcaen_to_eqsize = htonl(FW_EQ_CTRL_CMD_FBMIN(2) |
+                                 FW_EQ_CTRL_CMD_FBMAX(3) |
+                                 FW_EQ_CTRL_CMD_CIDXFTHRESH(5) |
+                                 FW_EQ_CTRL_CMD_EQSIZE(nentries));
+       c.eqaddr = cpu_to_be64(txq->q.phys_addr);
+
+       ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c);
+       if (ret) {
+               dma_free_coherent(adap->pdev_dev,
+                                 nentries * sizeof(struct tx_desc),
+                                 txq->q.desc, txq->q.phys_addr);
+               txq->q.desc = NULL;
+               return ret;
+       }
+
+       init_txq(adap, &txq->q, FW_EQ_CTRL_CMD_EQID_GET(ntohl(c.cmpliqid_eqid)));
+       txq->adap = adap;
+       skb_queue_head_init(&txq->sendq);
+       tasklet_init(&txq->qresume_tsk, restart_ctrlq, (unsigned long)txq);
+       txq->full = 0;
+       return 0;
+}
+
+int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq,
+                         struct net_device *dev, unsigned int iqid)
+{
+       int ret, nentries;
+       struct fw_eq_ofld_cmd c;
+       struct port_info *pi = netdev_priv(dev);
+
+       /* Add status entries */
+       nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc);
+
+       txq->q.desc = alloc_ring(adap->pdev_dev, txq->q.size,
+                       sizeof(struct tx_desc), sizeof(struct tx_sw_desc),
+                       &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN);
+       if (!txq->q.desc)
+               return -ENOMEM;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST |
+                           FW_CMD_WRITE | FW_CMD_EXEC |
+                           FW_EQ_OFLD_CMD_PFN(0) | FW_EQ_OFLD_CMD_VFN(0));
+       c.alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_ALLOC |
+                                FW_EQ_OFLD_CMD_EQSTART | FW_LEN16(c));
+       c.fetchszm_to_iqid = htonl(FW_EQ_OFLD_CMD_HOSTFCMODE(2) |
+                                  FW_EQ_OFLD_CMD_PCIECHN(pi->tx_chan) |
+                                  FW_EQ_OFLD_CMD_IQID(iqid));
+       c.dcaen_to_eqsize = htonl(FW_EQ_OFLD_CMD_FBMIN(2) |
+                                 FW_EQ_OFLD_CMD_FBMAX(3) |
+                                 FW_EQ_OFLD_CMD_CIDXFTHRESH(5) |
+                                 FW_EQ_OFLD_CMD_EQSIZE(nentries));
+       c.eqaddr = cpu_to_be64(txq->q.phys_addr);
+
+       ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c);
+       if (ret) {
+               kfree(txq->q.sdesc);
+               txq->q.sdesc = NULL;
+               dma_free_coherent(adap->pdev_dev,
+                                 nentries * sizeof(struct tx_desc),
+                                 txq->q.desc, txq->q.phys_addr);
+               txq->q.desc = NULL;
+               return ret;
+       }
+
+       init_txq(adap, &txq->q, FW_EQ_OFLD_CMD_EQID_GET(ntohl(c.eqid_pkd)));
+       txq->adap = adap;
+       skb_queue_head_init(&txq->sendq);
+       tasklet_init(&txq->qresume_tsk, restart_ofldq, (unsigned long)txq);
+       txq->full = 0;
+       txq->mapping_err = 0;
+       return 0;
+}
+
+static void free_txq(struct adapter *adap, struct sge_txq *q)
+{
+       dma_free_coherent(adap->pdev_dev,
+                         q->size * sizeof(struct tx_desc) + STAT_LEN,
+                         q->desc, q->phys_addr);
+       q->cntxt_id = 0;
+       q->sdesc = NULL;
+       q->desc = NULL;
+}
+
+static void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq,
+                        struct sge_fl *fl)
+{
+       unsigned int fl_id = fl ? fl->cntxt_id : 0xffff;
+
+       adap->sge.ingr_map[rq->cntxt_id] = NULL;
+       t4_iq_free(adap, 0, 0, 0, FW_IQ_TYPE_FL_INT_CAP, rq->cntxt_id, fl_id,
+                  0xffff);
+       dma_free_coherent(adap->pdev_dev, (rq->size + 1) * rq->iqe_len,
+                         rq->desc, rq->phys_addr);
+       netif_napi_del(&rq->napi);
+       rq->netdev = NULL;
+       rq->cntxt_id = rq->abs_id = 0;
+       rq->desc = NULL;
+
+       if (fl) {
+               free_rx_bufs(adap, fl, fl->avail);
+               dma_free_coherent(adap->pdev_dev, fl->size * 8 + STAT_LEN,
+                                 fl->desc, fl->addr);
+               kfree(fl->sdesc);
+               fl->sdesc = NULL;
+               fl->cntxt_id = 0;
+               fl->desc = NULL;
+       }
+}
+
+/**
+ *     t4_free_sge_resources - free SGE resources
+ *     @adap: the adapter
+ *
+ *     Frees resources used by the SGE queue sets.
+ */
+void t4_free_sge_resources(struct adapter *adap)
+{
+       int i;
+       struct sge_eth_rxq *eq = adap->sge.ethrxq;
+       struct sge_eth_txq *etq = adap->sge.ethtxq;
+       struct sge_ofld_rxq *oq = adap->sge.ofldrxq;
+
+       /* clean up Ethernet Tx/Rx queues */
+       for (i = 0; i < adap->sge.ethqsets; i++, eq++, etq++) {
+               if (eq->rspq.desc)
+                       free_rspq_fl(adap, &eq->rspq, &eq->fl);
+               if (etq->q.desc) {
+                       t4_eth_eq_free(adap, 0, 0, 0, etq->q.cntxt_id);
+                       free_tx_desc(adap, &etq->q, etq->q.in_use, true);
+                       kfree(etq->q.sdesc);
+                       free_txq(adap, &etq->q);
+               }
+       }
+
+       /* clean up RDMA and iSCSI Rx queues */
+       for (i = 0; i < adap->sge.ofldqsets; i++, oq++) {
+               if (oq->rspq.desc)
+                       free_rspq_fl(adap, &oq->rspq, &oq->fl);
+       }
+       for (i = 0, oq = adap->sge.rdmarxq; i < adap->sge.rdmaqs; i++, oq++) {
+               if (oq->rspq.desc)
+                       free_rspq_fl(adap, &oq->rspq, &oq->fl);
+       }
+
+       /* clean up offload Tx queues */
+       for (i = 0; i < ARRAY_SIZE(adap->sge.ofldtxq); i++) {
+               struct sge_ofld_txq *q = &adap->sge.ofldtxq[i];
+
+               if (q->q.desc) {
+                       tasklet_kill(&q->qresume_tsk);
+                       t4_ofld_eq_free(adap, 0, 0, 0, q->q.cntxt_id);
+                       free_tx_desc(adap, &q->q, q->q.in_use, false);
+                       kfree(q->q.sdesc);
+                       __skb_queue_purge(&q->sendq);
+                       free_txq(adap, &q->q);
+               }
+       }
+
+       /* clean up control Tx queues */
+       for (i = 0; i < ARRAY_SIZE(adap->sge.ctrlq); i++) {
+               struct sge_ctrl_txq *cq = &adap->sge.ctrlq[i];
+
+               if (cq->q.desc) {
+                       tasklet_kill(&cq->qresume_tsk);
+                       t4_ctrl_eq_free(adap, 0, 0, 0, cq->q.cntxt_id);
+                       __skb_queue_purge(&cq->sendq);
+                       free_txq(adap, &cq->q);
+               }
+       }
+
+       if (adap->sge.fw_evtq.desc)
+               free_rspq_fl(adap, &adap->sge.fw_evtq, NULL);
+
+       if (adap->sge.intrq.desc)
+               free_rspq_fl(adap, &adap->sge.intrq, NULL);
+
+       /* clear the reverse egress queue map */
+       memset(adap->sge.egr_map, 0, sizeof(adap->sge.egr_map));
+}
+
+void t4_sge_start(struct adapter *adap)
+{
+       adap->sge.ethtxq_rover = 0;
+       mod_timer(&adap->sge.rx_timer, jiffies + RX_QCHECK_PERIOD);
+       mod_timer(&adap->sge.tx_timer, jiffies + TX_QCHECK_PERIOD);
+}
+
+/**
+ *     t4_sge_stop - disable SGE operation
+ *     @adap: the adapter
+ *
+ *     Stop tasklets and timers associated with the DMA engine.  Note that
+ *     this is effective only if measures have been taken to disable any HW
+ *     events that may restart them.
+ */
+void t4_sge_stop(struct adapter *adap)
+{
+       int i;
+       struct sge *s = &adap->sge;
+
+       if (in_interrupt())  /* actions below require waiting */
+               return;
+
+       if (s->rx_timer.function)
+               del_timer_sync(&s->rx_timer);
+       if (s->tx_timer.function)
+               del_timer_sync(&s->tx_timer);
+
+       for (i = 0; i < ARRAY_SIZE(s->ofldtxq); i++) {
+               struct sge_ofld_txq *q = &s->ofldtxq[i];
+
+               if (q->q.desc)
+                       tasklet_kill(&q->qresume_tsk);
+       }
+       for (i = 0; i < ARRAY_SIZE(s->ctrlq); i++) {
+               struct sge_ctrl_txq *cq = &s->ctrlq[i];
+
+               if (cq->q.desc)
+                       tasklet_kill(&cq->qresume_tsk);
+       }
+}
+
+/**
+ *     t4_sge_init - initialize SGE
+ *     @adap: the adapter
+ *
+ *     Performs SGE initialization needed every time after a chip reset.
+ *     We do not initialize any of the queues here, instead the driver
+ *     top-level must request them individually.
+ */
+void t4_sge_init(struct adapter *adap)
+{
+       struct sge *s = &adap->sge;
+       unsigned int fl_align_log = ilog2(FL_ALIGN);
+
+       t4_set_reg_field(adap, SGE_CONTROL, PKTSHIFT_MASK |
+                        INGPADBOUNDARY_MASK | EGRSTATUSPAGESIZE,
+                        INGPADBOUNDARY(fl_align_log - 5) | PKTSHIFT(2) |
+                        RXPKTCPLMODE |
+                        (STAT_LEN == 128 ? EGRSTATUSPAGESIZE : 0));
+       t4_set_reg_field(adap, SGE_HOST_PAGE_SIZE, HOSTPAGESIZEPF0_MASK,
+                        HOSTPAGESIZEPF0(PAGE_SHIFT - 10));
+       t4_write_reg(adap, SGE_FL_BUFFER_SIZE0, PAGE_SIZE);
+#if FL_PG_ORDER > 0
+       t4_write_reg(adap, SGE_FL_BUFFER_SIZE1, PAGE_SIZE << FL_PG_ORDER);
+#endif
+       t4_write_reg(adap, SGE_INGRESS_RX_THRESHOLD,
+                    THRESHOLD_0(s->counter_val[0]) |
+                    THRESHOLD_1(s->counter_val[1]) |
+                    THRESHOLD_2(s->counter_val[2]) |
+                    THRESHOLD_3(s->counter_val[3]));
+       t4_write_reg(adap, SGE_TIMER_VALUE_0_AND_1,
+                    TIMERVALUE0(us_to_core_ticks(adap, s->timer_val[0])) |
+                    TIMERVALUE1(us_to_core_ticks(adap, s->timer_val[1])));
+       t4_write_reg(adap, SGE_TIMER_VALUE_2_AND_3,
+                    TIMERVALUE0(us_to_core_ticks(adap, s->timer_val[2])) |
+                    TIMERVALUE1(us_to_core_ticks(adap, s->timer_val[3])));
+       t4_write_reg(adap, SGE_TIMER_VALUE_4_AND_5,
+                    TIMERVALUE0(us_to_core_ticks(adap, s->timer_val[4])) |
+                    TIMERVALUE1(us_to_core_ticks(adap, s->timer_val[5])));
+       setup_timer(&s->rx_timer, sge_rx_timer_cb, (unsigned long)adap);
+       setup_timer(&s->tx_timer, sge_tx_timer_cb, (unsigned long)adap);
+       s->starve_thres = core_ticks_per_usec(adap) * 1000000;  /* 1 s */
+       s->idma_state[0] = s->idma_state[1] = 0;
+       spin_lock_init(&s->intrq_lock);
+}
diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c
new file mode 100644 (file)
index 0000000..a814a3a
--- /dev/null
@@ -0,0 +1,3131 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/delay.h>
+#include "cxgb4.h"
+#include "t4_regs.h"
+#include "t4fw_api.h"
+
+/**
+ *     t4_wait_op_done_val - wait until an operation is completed
+ *     @adapter: the adapter performing the operation
+ *     @reg: the register to check for completion
+ *     @mask: a single-bit field within @reg that indicates completion
+ *     @polarity: the value of the field when the operation is completed
+ *     @attempts: number of check iterations
+ *     @delay: delay in usecs between iterations
+ *     @valp: where to store the value of the register at completion time
+ *
+ *     Wait until an operation is completed by checking a bit in a register
+ *     up to @attempts times.  If @valp is not NULL the value of the register
+ *     at the time it indicated completion is stored there.  Returns 0 if the
+ *     operation completes and -EAGAIN otherwise.
+ */
+int t4_wait_op_done_val(struct adapter *adapter, int reg, u32 mask,
+                       int polarity, int attempts, int delay, u32 *valp)
+{
+       while (1) {
+               u32 val = t4_read_reg(adapter, reg);
+
+               if (!!(val & mask) == polarity) {
+                       if (valp)
+                               *valp = val;
+                       return 0;
+               }
+               if (--attempts == 0)
+                       return -EAGAIN;
+               if (delay)
+                       udelay(delay);
+       }
+}
+
+static inline int t4_wait_op_done(struct adapter *adapter, int reg, u32 mask,
+                                 int polarity, int attempts, int delay)
+{
+       return t4_wait_op_done_val(adapter, reg, mask, polarity, attempts,
+                                  delay, NULL);
+}
+
+/**
+ *     t4_set_reg_field - set a register field to a value
+ *     @adapter: the adapter to program
+ *     @addr: the register address
+ *     @mask: specifies the portion of the register to modify
+ *     @val: the new value for the register field
+ *
+ *     Sets a register field specified by the supplied mask to the
+ *     given value.
+ */
+void t4_set_reg_field(struct adapter *adapter, unsigned int addr, u32 mask,
+                     u32 val)
+{
+       u32 v = t4_read_reg(adapter, addr) & ~mask;
+
+       t4_write_reg(adapter, addr, v | val);
+       (void) t4_read_reg(adapter, addr);      /* flush */
+}
+
+/**
+ *     t4_read_indirect - read indirectly addressed registers
+ *     @adap: the adapter
+ *     @addr_reg: register holding the indirect address
+ *     @data_reg: register holding the value of the indirect register
+ *     @vals: where the read register values are stored
+ *     @nregs: how many indirect registers to read
+ *     @start_idx: index of first indirect register to read
+ *
+ *     Reads registers that are accessed indirectly through an address/data
+ *     register pair.
+ */
+void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
+                     unsigned int data_reg, u32 *vals, unsigned int nregs,
+                     unsigned int start_idx)
+{
+       while (nregs--) {
+               t4_write_reg(adap, addr_reg, start_idx);
+               *vals++ = t4_read_reg(adap, data_reg);
+               start_idx++;
+       }
+}
+
+/**
+ *     t4_write_indirect - write indirectly addressed registers
+ *     @adap: the adapter
+ *     @addr_reg: register holding the indirect addresses
+ *     @data_reg: register holding the value for the indirect registers
+ *     @vals: values to write
+ *     @nregs: how many indirect registers to write
+ *     @start_idx: address of first indirect register to write
+ *
+ *     Writes a sequential block of registers that are accessed indirectly
+ *     through an address/data register pair.
+ */
+void t4_write_indirect(struct adapter *adap, unsigned int addr_reg,
+                      unsigned int data_reg, const u32 *vals,
+                      unsigned int nregs, unsigned int start_idx)
+{
+       while (nregs--) {
+               t4_write_reg(adap, addr_reg, start_idx++);
+               t4_write_reg(adap, data_reg, *vals++);
+       }
+}
+
+/*
+ * Get the reply to a mailbox command and store it in @rpl in big-endian order.
+ */
+static void get_mbox_rpl(struct adapter *adap, __be64 *rpl, int nflit,
+                        u32 mbox_addr)
+{
+       for ( ; nflit; nflit--, mbox_addr += 8)
+               *rpl++ = cpu_to_be64(t4_read_reg64(adap, mbox_addr));
+}
+
+/*
+ * Handle a FW assertion reported in a mailbox.
+ */
+static void fw_asrt(struct adapter *adap, u32 mbox_addr)
+{
+       struct fw_debug_cmd asrt;
+
+       get_mbox_rpl(adap, (__be64 *)&asrt, sizeof(asrt) / 8, mbox_addr);
+       dev_alert(adap->pdev_dev,
+                 "FW assertion at %.16s:%u, val0 %#x, val1 %#x\n",
+                 asrt.u.assert.filename_0_7, ntohl(asrt.u.assert.line),
+                 ntohl(asrt.u.assert.x), ntohl(asrt.u.assert.y));
+}
+
+static void dump_mbox(struct adapter *adap, int mbox, u32 data_reg)
+{
+       dev_err(adap->pdev_dev,
+               "mbox %d: %llx %llx %llx %llx %llx %llx %llx %llx\n", mbox,
+               (unsigned long long)t4_read_reg64(adap, data_reg),
+               (unsigned long long)t4_read_reg64(adap, data_reg + 8),
+               (unsigned long long)t4_read_reg64(adap, data_reg + 16),
+               (unsigned long long)t4_read_reg64(adap, data_reg + 24),
+               (unsigned long long)t4_read_reg64(adap, data_reg + 32),
+               (unsigned long long)t4_read_reg64(adap, data_reg + 40),
+               (unsigned long long)t4_read_reg64(adap, data_reg + 48),
+               (unsigned long long)t4_read_reg64(adap, data_reg + 56));
+}
+
+/**
+ *     t4_wr_mbox_meat - send a command to FW through the given mailbox
+ *     @adap: the adapter
+ *     @mbox: index of the mailbox to use
+ *     @cmd: the command to write
+ *     @size: command length in bytes
+ *     @rpl: where to optionally store the reply
+ *     @sleep_ok: if true we may sleep while awaiting command completion
+ *
+ *     Sends the given command to FW through the selected mailbox and waits
+ *     for the FW to execute the command.  If @rpl is not %NULL it is used to
+ *     store the FW's reply to the command.  The command and its optional
+ *     reply are of the same length.  FW can take up to %FW_CMD_MAX_TIMEOUT ms
+ *     to respond.  @sleep_ok determines whether we may sleep while awaiting
+ *     the response.  If sleeping is allowed we use progressive backoff
+ *     otherwise we spin.
+ *
+ *     The return value is 0 on success or a negative errno on failure.  A
+ *     failure can happen either because we are not able to execute the
+ *     command or FW executes it but signals an error.  In the latter case
+ *     the return value is the error code indicated by FW (negated).
+ */
+int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
+                   void *rpl, bool sleep_ok)
+{
+       static int delay[] = {
+               1, 1, 3, 5, 10, 10, 20, 50, 100, 200
+       };
+
+       u32 v;
+       u64 res;
+       int i, ms, delay_idx;
+       const __be64 *p = cmd;
+       u32 data_reg = PF_REG(mbox, CIM_PF_MAILBOX_DATA);
+       u32 ctl_reg = PF_REG(mbox, CIM_PF_MAILBOX_CTRL);
+
+       if ((size & 15) || size > MBOX_LEN)
+               return -EINVAL;
+
+       v = MBOWNER_GET(t4_read_reg(adap, ctl_reg));
+       for (i = 0; v == MBOX_OWNER_NONE && i < 3; i++)
+               v = MBOWNER_GET(t4_read_reg(adap, ctl_reg));
+
+       if (v != MBOX_OWNER_DRV)
+               return v ? -EBUSY : -ETIMEDOUT;
+
+       for (i = 0; i < size; i += 8)
+               t4_write_reg64(adap, data_reg + i, be64_to_cpu(*p++));
+
+       t4_write_reg(adap, ctl_reg, MBMSGVALID | MBOWNER(MBOX_OWNER_FW));
+       t4_read_reg(adap, ctl_reg);          /* flush write */
+
+       delay_idx = 0;
+       ms = delay[0];
+
+       for (i = 0; i < FW_CMD_MAX_TIMEOUT; i += ms) {
+               if (sleep_ok) {
+                       ms = delay[delay_idx];  /* last element may repeat */
+                       if (delay_idx < ARRAY_SIZE(delay) - 1)
+                               delay_idx++;
+                       msleep(ms);
+               } else
+                       mdelay(ms);
+
+               v = t4_read_reg(adap, ctl_reg);
+               if (MBOWNER_GET(v) == MBOX_OWNER_DRV) {
+                       if (!(v & MBMSGVALID)) {
+                               t4_write_reg(adap, ctl_reg, 0);
+                               continue;
+                       }
+
+                       res = t4_read_reg64(adap, data_reg);
+                       if (FW_CMD_OP_GET(res >> 32) == FW_DEBUG_CMD) {
+                               fw_asrt(adap, data_reg);
+                               res = FW_CMD_RETVAL(EIO);
+                       } else if (rpl)
+                               get_mbox_rpl(adap, rpl, size / 8, data_reg);
+
+                       if (FW_CMD_RETVAL_GET((int)res))
+                               dump_mbox(adap, mbox, data_reg);
+                       t4_write_reg(adap, ctl_reg, 0);
+                       return -FW_CMD_RETVAL_GET((int)res);
+               }
+       }
+
+       dump_mbox(adap, mbox, data_reg);
+       dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n",
+               *(const u8 *)cmd, mbox);
+       return -ETIMEDOUT;
+}
+
+/**
+ *     t4_mc_read - read from MC through backdoor accesses
+ *     @adap: the adapter
+ *     @addr: address of first byte requested
+ *     @data: 64 bytes of data containing the requested address
+ *     @ecc: where to store the corresponding 64-bit ECC word
+ *
+ *     Read 64 bytes of data from MC starting at a 64-byte-aligned address
+ *     that covers the requested address @addr.  If @parity is not %NULL it
+ *     is assigned the 64-bit ECC word for the read data.
+ */
+int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *ecc)
+{
+       int i;
+
+       if (t4_read_reg(adap, MC_BIST_CMD) & START_BIST)
+               return -EBUSY;
+       t4_write_reg(adap, MC_BIST_CMD_ADDR, addr & ~0x3fU);
+       t4_write_reg(adap, MC_BIST_CMD_LEN, 64);
+       t4_write_reg(adap, MC_BIST_DATA_PATTERN, 0xc);
+       t4_write_reg(adap, MC_BIST_CMD, BIST_OPCODE(1) | START_BIST |
+                    BIST_CMD_GAP(1));
+       i = t4_wait_op_done(adap, MC_BIST_CMD, START_BIST, 0, 10, 1);
+       if (i)
+               return i;
+
+#define MC_DATA(i) MC_BIST_STATUS_REG(MC_BIST_STATUS_RDATA, i)
+
+       for (i = 15; i >= 0; i--)
+               *data++ = htonl(t4_read_reg(adap, MC_DATA(i)));
+       if (ecc)
+               *ecc = t4_read_reg64(adap, MC_DATA(16));
+#undef MC_DATA
+       return 0;
+}
+
+/**
+ *     t4_edc_read - read from EDC through backdoor accesses
+ *     @adap: the adapter
+ *     @idx: which EDC to access
+ *     @addr: address of first byte requested
+ *     @data: 64 bytes of data containing the requested address
+ *     @ecc: where to store the corresponding 64-bit ECC word
+ *
+ *     Read 64 bytes of data from EDC starting at a 64-byte-aligned address
+ *     that covers the requested address @addr.  If @parity is not %NULL it
+ *     is assigned the 64-bit ECC word for the read data.
+ */
+int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc)
+{
+       int i;
+
+       idx *= EDC_STRIDE;
+       if (t4_read_reg(adap, EDC_BIST_CMD + idx) & START_BIST)
+               return -EBUSY;
+       t4_write_reg(adap, EDC_BIST_CMD_ADDR + idx, addr & ~0x3fU);
+       t4_write_reg(adap, EDC_BIST_CMD_LEN + idx, 64);
+       t4_write_reg(adap, EDC_BIST_DATA_PATTERN + idx, 0xc);
+       t4_write_reg(adap, EDC_BIST_CMD + idx,
+                    BIST_OPCODE(1) | BIST_CMD_GAP(1) | START_BIST);
+       i = t4_wait_op_done(adap, EDC_BIST_CMD + idx, START_BIST, 0, 10, 1);
+       if (i)
+               return i;
+
+#define EDC_DATA(i) (EDC_BIST_STATUS_REG(EDC_BIST_STATUS_RDATA, i) + idx)
+
+       for (i = 15; i >= 0; i--)
+               *data++ = htonl(t4_read_reg(adap, EDC_DATA(i)));
+       if (ecc)
+               *ecc = t4_read_reg64(adap, EDC_DATA(16));
+#undef EDC_DATA
+       return 0;
+}
+
+#define VPD_ENTRY(name, len) \
+       u8 name##_kword[2]; u8 name##_len; u8 name##_data[len]
+
+/*
+ * Partial EEPROM Vital Product Data structure.  Includes only the ID and
+ * VPD-R sections.
+ */
+struct t4_vpd {
+       u8  id_tag;
+       u8  id_len[2];
+       u8  id_data[ID_LEN];
+       u8  vpdr_tag;
+       u8  vpdr_len[2];
+       VPD_ENTRY(pn, 16);                     /* part number */
+       VPD_ENTRY(ec, EC_LEN);                 /* EC level */
+       VPD_ENTRY(sn, SERNUM_LEN);             /* serial number */
+       VPD_ENTRY(na, 12);                     /* MAC address base */
+       VPD_ENTRY(port_type, 8);               /* port types */
+       VPD_ENTRY(gpio, 14);                   /* GPIO usage */
+       VPD_ENTRY(cclk, 6);                    /* core clock */
+       VPD_ENTRY(port_addr, 8);               /* port MDIO addresses */
+       VPD_ENTRY(rv, 1);                      /* csum */
+       u32 pad;                  /* for multiple-of-4 sizing and alignment */
+};
+
+#define EEPROM_STAT_ADDR   0x7bfc
+#define VPD_BASE           0
+
+/**
+ *     t4_seeprom_wp - enable/disable EEPROM write protection
+ *     @adapter: the adapter
+ *     @enable: whether to enable or disable write protection
+ *
+ *     Enables or disables write protection on the serial EEPROM.
+ */
+int t4_seeprom_wp(struct adapter *adapter, bool enable)
+{
+       unsigned int v = enable ? 0xc : 0;
+       int ret = pci_write_vpd(adapter->pdev, EEPROM_STAT_ADDR, 4, &v);
+       return ret < 0 ? ret : 0;
+}
+
+/**
+ *     get_vpd_params - read VPD parameters from VPD EEPROM
+ *     @adapter: adapter to read
+ *     @p: where to store the parameters
+ *
+ *     Reads card parameters stored in VPD EEPROM.
+ */
+static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
+{
+       int ret;
+       struct t4_vpd vpd;
+       u8 *q = (u8 *)&vpd, csum;
+
+       ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(vpd), &vpd);
+       if (ret < 0)
+               return ret;
+
+       for (csum = 0; q <= vpd.rv_data; q++)
+               csum += *q;
+
+       if (csum) {
+               dev_err(adapter->pdev_dev,
+                       "corrupted VPD EEPROM, actual csum %u\n", csum);
+               return -EINVAL;
+       }
+
+       p->cclk = simple_strtoul(vpd.cclk_data, NULL, 10);
+       memcpy(p->id, vpd.id_data, sizeof(vpd.id_data));
+       strim(p->id);
+       memcpy(p->ec, vpd.ec_data, sizeof(vpd.ec_data));
+       strim(p->ec);
+       memcpy(p->sn, vpd.sn_data, sizeof(vpd.sn_data));
+       strim(p->sn);
+       return 0;
+}
+
+/* serial flash and firmware constants */
+enum {
+       SF_ATTEMPTS = 10,             /* max retries for SF operations */
+
+       /* flash command opcodes */
+       SF_PROG_PAGE    = 2,          /* program page */
+       SF_WR_DISABLE   = 4,          /* disable writes */
+       SF_RD_STATUS    = 5,          /* read status register */
+       SF_WR_ENABLE    = 6,          /* enable writes */
+       SF_RD_DATA_FAST = 0xb,        /* read flash */
+       SF_ERASE_SECTOR = 0xd8,       /* erase sector */
+
+       FW_START_SEC = 8,             /* first flash sector for FW */
+       FW_END_SEC = 15,              /* last flash sector for FW */
+       FW_IMG_START = FW_START_SEC * SF_SEC_SIZE,
+       FW_MAX_SIZE = (FW_END_SEC - FW_START_SEC + 1) * SF_SEC_SIZE,
+};
+
+/**
+ *     sf1_read - read data from the serial flash
+ *     @adapter: the adapter
+ *     @byte_cnt: number of bytes to read
+ *     @cont: whether another operation will be chained
+ *     @lock: whether to lock SF for PL access only
+ *     @valp: where to store the read data
+ *
+ *     Reads up to 4 bytes of data from the serial flash.  The location of
+ *     the read needs to be specified prior to calling this by issuing the
+ *     appropriate commands to the serial flash.
+ */
+static int sf1_read(struct adapter *adapter, unsigned int byte_cnt, int cont,
+                   int lock, u32 *valp)
+{
+       int ret;
+
+       if (!byte_cnt || byte_cnt > 4)
+               return -EINVAL;
+       if (t4_read_reg(adapter, SF_OP) & BUSY)
+               return -EBUSY;
+       cont = cont ? SF_CONT : 0;
+       lock = lock ? SF_LOCK : 0;
+       t4_write_reg(adapter, SF_OP, lock | cont | BYTECNT(byte_cnt - 1));
+       ret = t4_wait_op_done(adapter, SF_OP, BUSY, 0, SF_ATTEMPTS, 5);
+       if (!ret)
+               *valp = t4_read_reg(adapter, SF_DATA);
+       return ret;
+}
+
+/**
+ *     sf1_write - write data to the serial flash
+ *     @adapter: the adapter
+ *     @byte_cnt: number of bytes to write
+ *     @cont: whether another operation will be chained
+ *     @lock: whether to lock SF for PL access only
+ *     @val: value to write
+ *
+ *     Writes up to 4 bytes of data to the serial flash.  The location of
+ *     the write needs to be specified prior to calling this by issuing the
+ *     appropriate commands to the serial flash.
+ */
+static int sf1_write(struct adapter *adapter, unsigned int byte_cnt, int cont,
+                    int lock, u32 val)
+{
+       if (!byte_cnt || byte_cnt > 4)
+               return -EINVAL;
+       if (t4_read_reg(adapter, SF_OP) & BUSY)
+               return -EBUSY;
+       cont = cont ? SF_CONT : 0;
+       lock = lock ? SF_LOCK : 0;
+       t4_write_reg(adapter, SF_DATA, val);
+       t4_write_reg(adapter, SF_OP, lock |
+                    cont | BYTECNT(byte_cnt - 1) | OP_WR);
+       return t4_wait_op_done(adapter, SF_OP, BUSY, 0, SF_ATTEMPTS, 5);
+}
+
+/**
+ *     flash_wait_op - wait for a flash operation to complete
+ *     @adapter: the adapter
+ *     @attempts: max number of polls of the status register
+ *     @delay: delay between polls in ms
+ *
+ *     Wait for a flash operation to complete by polling the status register.
+ */
+static int flash_wait_op(struct adapter *adapter, int attempts, int delay)
+{
+       int ret;
+       u32 status;
+
+       while (1) {
+               if ((ret = sf1_write(adapter, 1, 1, 1, SF_RD_STATUS)) != 0 ||
+                   (ret = sf1_read(adapter, 1, 0, 1, &status)) != 0)
+                       return ret;
+               if (!(status & 1))
+                       return 0;
+               if (--attempts == 0)
+                       return -EAGAIN;
+               if (delay)
+                       msleep(delay);
+       }
+}
+
+/**
+ *     t4_read_flash - read words from serial flash
+ *     @adapter: the adapter
+ *     @addr: the start address for the read
+ *     @nwords: how many 32-bit words to read
+ *     @data: where to store the read data
+ *     @byte_oriented: whether to store data as bytes or as words
+ *
+ *     Read the specified number of 32-bit words from the serial flash.
+ *     If @byte_oriented is set the read data is stored as a byte array
+ *     (i.e., big-endian), otherwise as 32-bit words in the platform's
+ *     natural endianess.
+ */
+int t4_read_flash(struct adapter *adapter, unsigned int addr,
+                 unsigned int nwords, u32 *data, int byte_oriented)
+{
+       int ret;
+
+       if (addr + nwords * sizeof(u32) > SF_SIZE || (addr & 3))
+               return -EINVAL;
+
+       addr = swab32(addr) | SF_RD_DATA_FAST;
+
+       if ((ret = sf1_write(adapter, 4, 1, 0, addr)) != 0 ||
+           (ret = sf1_read(adapter, 1, 1, 0, data)) != 0)
+               return ret;
+
+       for ( ; nwords; nwords--, data++) {
+               ret = sf1_read(adapter, 4, nwords > 1, nwords == 1, data);
+               if (nwords == 1)
+                       t4_write_reg(adapter, SF_OP, 0);    /* unlock SF */
+               if (ret)
+                       return ret;
+               if (byte_oriented)
+                       *data = htonl(*data);
+       }
+       return 0;
+}
+
+/**
+ *     t4_write_flash - write up to a page of data to the serial flash
+ *     @adapter: the adapter
+ *     @addr: the start address to write
+ *     @n: length of data to write in bytes
+ *     @data: the data to write
+ *
+ *     Writes up to a page of data (256 bytes) to the serial flash starting
+ *     at the given address.  All the data must be written to the same page.
+ */
+static int t4_write_flash(struct adapter *adapter, unsigned int addr,
+                         unsigned int n, const u8 *data)
+{
+       int ret;
+       u32 buf[64];
+       unsigned int i, c, left, val, offset = addr & 0xff;
+
+       if (addr >= SF_SIZE || offset + n > SF_PAGE_SIZE)
+               return -EINVAL;
+
+       val = swab32(addr) | SF_PROG_PAGE;
+
+       if ((ret = sf1_write(adapter, 1, 0, 1, SF_WR_ENABLE)) != 0 ||
+           (ret = sf1_write(adapter, 4, 1, 1, val)) != 0)
+               goto unlock;
+
+       for (left = n; left; left -= c) {
+               c = min(left, 4U);
+               for (val = 0, i = 0; i < c; ++i)
+                       val = (val << 8) + *data++;
+
+               ret = sf1_write(adapter, c, c != left, 1, val);
+               if (ret)
+                       goto unlock;
+       }
+       ret = flash_wait_op(adapter, 5, 1);
+       if (ret)
+               goto unlock;
+
+       t4_write_reg(adapter, SF_OP, 0);    /* unlock SF */
+
+       /* Read the page to verify the write succeeded */
+       ret = t4_read_flash(adapter, addr & ~0xff, ARRAY_SIZE(buf), buf, 1);
+       if (ret)
+               return ret;
+
+       if (memcmp(data - n, (u8 *)buf + offset, n)) {
+               dev_err(adapter->pdev_dev,
+                       "failed to correctly write the flash page at %#x\n",
+                       addr);
+               return -EIO;
+       }
+       return 0;
+
+unlock:
+       t4_write_reg(adapter, SF_OP, 0);    /* unlock SF */
+       return ret;
+}
+
+/**
+ *     get_fw_version - read the firmware version
+ *     @adapter: the adapter
+ *     @vers: where to place the version
+ *
+ *     Reads the FW version from flash.
+ */
+static int get_fw_version(struct adapter *adapter, u32 *vers)
+{
+       return t4_read_flash(adapter,
+                            FW_IMG_START + offsetof(struct fw_hdr, fw_ver), 1,
+                            vers, 0);
+}
+
+/**
+ *     get_tp_version - read the TP microcode version
+ *     @adapter: the adapter
+ *     @vers: where to place the version
+ *
+ *     Reads the TP microcode version from flash.
+ */
+static int get_tp_version(struct adapter *adapter, u32 *vers)
+{
+       return t4_read_flash(adapter, FW_IMG_START + offsetof(struct fw_hdr,
+                                                             tp_microcode_ver),
+                            1, vers, 0);
+}
+
+/**
+ *     t4_check_fw_version - check if the FW is compatible with this driver
+ *     @adapter: the adapter
+ *
+ *     Checks if an adapter's FW is compatible with the driver.  Returns 0
+ *     if there's exact match, a negative error if the version could not be
+ *     read or there's a major version mismatch, and a positive value if the
+ *     expected major version is found but there's a minor version mismatch.
+ */
+int t4_check_fw_version(struct adapter *adapter)
+{
+       u32 api_vers[2];
+       int ret, major, minor, micro;
+
+       ret = get_fw_version(adapter, &adapter->params.fw_vers);
+       if (!ret)
+               ret = get_tp_version(adapter, &adapter->params.tp_vers);
+       if (!ret)
+               ret = t4_read_flash(adapter,
+                       FW_IMG_START + offsetof(struct fw_hdr, intfver_nic),
+                       2, api_vers, 1);
+       if (ret)
+               return ret;
+
+       major = FW_HDR_FW_VER_MAJOR_GET(adapter->params.fw_vers);
+       minor = FW_HDR_FW_VER_MINOR_GET(adapter->params.fw_vers);
+       micro = FW_HDR_FW_VER_MICRO_GET(adapter->params.fw_vers);
+       memcpy(adapter->params.api_vers, api_vers,
+              sizeof(adapter->params.api_vers));
+
+       if (major != FW_VERSION_MAJOR) {            /* major mismatch - fail */
+               dev_err(adapter->pdev_dev,
+                       "card FW has major version %u, driver wants %u\n",
+                       major, FW_VERSION_MAJOR);
+               return -EINVAL;
+       }
+
+       if (minor == FW_VERSION_MINOR && micro == FW_VERSION_MICRO)
+               return 0;                                   /* perfect match */
+
+       /* Minor/micro version mismatch.  Report it but often it's OK. */
+       return 1;
+}
+
+/**
+ *     t4_flash_erase_sectors - erase a range of flash sectors
+ *     @adapter: the adapter
+ *     @start: the first sector to erase
+ *     @end: the last sector to erase
+ *
+ *     Erases the sectors in the given inclusive range.
+ */
+static int t4_flash_erase_sectors(struct adapter *adapter, int start, int end)
+{
+       int ret = 0;
+
+       while (start <= end) {
+               if ((ret = sf1_write(adapter, 1, 0, 1, SF_WR_ENABLE)) != 0 ||
+                   (ret = sf1_write(adapter, 4, 0, 1,
+                                    SF_ERASE_SECTOR | (start << 8))) != 0 ||
+                   (ret = flash_wait_op(adapter, 5, 500)) != 0) {
+                       dev_err(adapter->pdev_dev,
+                               "erase of flash sector %d failed, error %d\n",
+                               start, ret);
+                       break;
+               }
+               start++;
+       }
+       t4_write_reg(adapter, SF_OP, 0);    /* unlock SF */
+       return ret;
+}
+
+/**
+ *     t4_load_fw - download firmware
+ *     @adap: the adapter
+ *     @fw_data: the firmware image to write
+ *     @size: image size
+ *
+ *     Write the supplied firmware image to the card's serial flash.
+ */
+int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
+{
+       u32 csum;
+       int ret, addr;
+       unsigned int i;
+       u8 first_page[SF_PAGE_SIZE];
+       const u32 *p = (const u32 *)fw_data;
+       const struct fw_hdr *hdr = (const struct fw_hdr *)fw_data;
+
+       if (!size) {
+               dev_err(adap->pdev_dev, "FW image has no data\n");
+               return -EINVAL;
+       }
+       if (size & 511) {
+               dev_err(adap->pdev_dev,
+                       "FW image size not multiple of 512 bytes\n");
+               return -EINVAL;
+       }
+       if (ntohs(hdr->len512) * 512 != size) {
+               dev_err(adap->pdev_dev,
+                       "FW image size differs from size in FW header\n");
+               return -EINVAL;
+       }
+       if (size > FW_MAX_SIZE) {
+               dev_err(adap->pdev_dev, "FW image too large, max is %u bytes\n",
+                       FW_MAX_SIZE);
+               return -EFBIG;
+       }
+
+       for (csum = 0, i = 0; i < size / sizeof(csum); i++)
+               csum += ntohl(p[i]);
+
+       if (csum != 0xffffffff) {
+               dev_err(adap->pdev_dev,
+                       "corrupted firmware image, checksum %#x\n", csum);
+               return -EINVAL;
+       }
+
+       i = DIV_ROUND_UP(size, SF_SEC_SIZE);        /* # of sectors spanned */
+       ret = t4_flash_erase_sectors(adap, FW_START_SEC, FW_START_SEC + i - 1);
+       if (ret)
+               goto out;
+
+       /*
+        * We write the correct version at the end so the driver can see a bad
+        * version if the FW write fails.  Start by writing a copy of the
+        * first page with a bad version.
+        */
+       memcpy(first_page, fw_data, SF_PAGE_SIZE);
+       ((struct fw_hdr *)first_page)->fw_ver = htonl(0xffffffff);
+       ret = t4_write_flash(adap, FW_IMG_START, SF_PAGE_SIZE, first_page);
+       if (ret)
+               goto out;
+
+       addr = FW_IMG_START;
+       for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) {
+               addr += SF_PAGE_SIZE;
+               fw_data += SF_PAGE_SIZE;
+               ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, fw_data);
+               if (ret)
+                       goto out;
+       }
+
+       ret = t4_write_flash(adap,
+                            FW_IMG_START + offsetof(struct fw_hdr, fw_ver),
+                            sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver);
+out:
+       if (ret)
+               dev_err(adap->pdev_dev, "firmware download failed, error %d\n",
+                       ret);
+       return ret;
+}
+
+#define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\
+                    FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_ANEG)
+
+/**
+ *     t4_link_start - apply link configuration to MAC/PHY
+ *     @phy: the PHY to setup
+ *     @mac: the MAC to setup
+ *     @lc: the requested link configuration
+ *
+ *     Set up a port's MAC and PHY according to a desired link configuration.
+ *     - If the PHY can auto-negotiate first decide what to advertise, then
+ *       enable/disable auto-negotiation as desired, and reset.
+ *     - If the PHY does not auto-negotiate just reset it.
+ *     - If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
+ *       otherwise do it later based on the outcome of auto-negotiation.
+ */
+int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port,
+                 struct link_config *lc)
+{
+       struct fw_port_cmd c;
+       unsigned int fc = 0, mdi = FW_PORT_MDI(FW_PORT_MDI_AUTO);
+
+       lc->link_ok = 0;
+       if (lc->requested_fc & PAUSE_RX)
+               fc |= FW_PORT_CAP_FC_RX;
+       if (lc->requested_fc & PAUSE_TX)
+               fc |= FW_PORT_CAP_FC_TX;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD) | FW_CMD_REQUEST |
+                              FW_CMD_EXEC | FW_PORT_CMD_PORTID(port));
+       c.action_to_len16 = htonl(FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) |
+                                 FW_LEN16(c));
+
+       if (!(lc->supported & FW_PORT_CAP_ANEG)) {
+               c.u.l1cfg.rcap = htonl((lc->supported & ADVERT_MASK) | fc);
+               lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
+       } else if (lc->autoneg == AUTONEG_DISABLE) {
+               c.u.l1cfg.rcap = htonl(lc->requested_speed | fc | mdi);
+               lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
+       } else
+               c.u.l1cfg.rcap = htonl(lc->advertising | fc | mdi);
+
+       return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *     t4_restart_aneg - restart autonegotiation
+ *     @adap: the adapter
+ *     @mbox: mbox to use for the FW command
+ *     @port: the port id
+ *
+ *     Restarts autonegotiation for the selected port.
+ */
+int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port)
+{
+       struct fw_port_cmd c;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD) | FW_CMD_REQUEST |
+                              FW_CMD_EXEC | FW_PORT_CMD_PORTID(port));
+       c.action_to_len16 = htonl(FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) |
+                                 FW_LEN16(c));
+       c.u.l1cfg.rcap = htonl(FW_PORT_CAP_ANEG);
+       return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *     t4_set_vlan_accel - configure HW VLAN extraction
+ *     @adap: the adapter
+ *     @ports: bitmap of adapter ports to operate on
+ *     @on: enable (1) or disable (0) HW VLAN extraction
+ *
+ *     Enables or disables HW extraction of VLAN tags for the ports specified
+ *     by @ports.  @ports is a bitmap with the ith bit designating the port
+ *     associated with the ith adapter channel.
+ */
+void t4_set_vlan_accel(struct adapter *adap, unsigned int ports, int on)
+{
+       ports <<= VLANEXTENABLE_SHIFT;
+       t4_set_reg_field(adap, TP_OUT_CONFIG, ports, on ? ports : 0);
+}
+
+struct intr_info {
+       unsigned int mask;       /* bits to check in interrupt status */
+       const char *msg;         /* message to print or NULL */
+       short stat_idx;          /* stat counter to increment or -1 */
+       unsigned short fatal;    /* whether the condition reported is fatal */
+};
+
+/**
+ *     t4_handle_intr_status - table driven interrupt handler
+ *     @adapter: the adapter that generated the interrupt
+ *     @reg: the interrupt status register to process
+ *     @acts: table of interrupt actions
+ *
+ *     A table driven interrupt handler that applies a set of masks to an
+ *     interrupt status word and performs the corresponding actions if the
+ *     interrupts described by the mask have occured.  The actions include
+ *     optionally emitting a warning or alert message.  The table is terminated
+ *     by an entry specifying mask 0.  Returns the number of fatal interrupt
+ *     conditions.
+ */
+static int t4_handle_intr_status(struct adapter *adapter, unsigned int reg,
+                                const struct intr_info *acts)
+{
+       int fatal = 0;
+       unsigned int mask = 0;
+       unsigned int status = t4_read_reg(adapter, reg);
+
+       for ( ; acts->mask; ++acts) {
+               if (!(status & acts->mask))
+                       continue;
+               if (acts->fatal) {
+                       fatal++;
+                       dev_alert(adapter->pdev_dev, "%s (0x%x)\n", acts->msg,
+                                 status & acts->mask);
+               } else if (acts->msg && printk_ratelimit())
+                       dev_warn(adapter->pdev_dev, "%s (0x%x)\n", acts->msg,
+                                status & acts->mask);
+               mask |= acts->mask;
+       }
+       status &= mask;
+       if (status)                           /* clear processed interrupts */
+               t4_write_reg(adapter, reg, status);
+       return fatal;
+}
+
+/*
+ * Interrupt handler for the PCIE module.
+ */
+static void pcie_intr_handler(struct adapter *adapter)
+{
+       static struct intr_info sysbus_intr_info[] = {
+               { RNPP, "RXNP array parity error", -1, 1 },
+               { RPCP, "RXPC array parity error", -1, 1 },
+               { RCIP, "RXCIF array parity error", -1, 1 },
+               { RCCP, "Rx completions control array parity error", -1, 1 },
+               { RFTP, "RXFT array parity error", -1, 1 },
+               { 0 }
+       };
+       static struct intr_info pcie_port_intr_info[] = {
+               { TPCP, "TXPC array parity error", -1, 1 },
+               { TNPP, "TXNP array parity error", -1, 1 },
+               { TFTP, "TXFT array parity error", -1, 1 },
+               { TCAP, "TXCA array parity error", -1, 1 },
+               { TCIP, "TXCIF array parity error", -1, 1 },
+               { RCAP, "RXCA array parity error", -1, 1 },
+               { OTDD, "outbound request TLP discarded", -1, 1 },
+               { RDPE, "Rx data parity error", -1, 1 },
+               { TDUE, "Tx uncorrectable data error", -1, 1 },
+               { 0 }
+       };
+       static struct intr_info pcie_intr_info[] = {
+               { MSIADDRLPERR, "MSI AddrL parity error", -1, 1 },
+               { MSIADDRHPERR, "MSI AddrH parity error", -1, 1 },
+               { MSIDATAPERR, "MSI data parity error", -1, 1 },
+               { MSIXADDRLPERR, "MSI-X AddrL parity error", -1, 1 },
+               { MSIXADDRHPERR, "MSI-X AddrH parity error", -1, 1 },
+               { MSIXDATAPERR, "MSI-X data parity error", -1, 1 },
+               { MSIXDIPERR, "MSI-X DI parity error", -1, 1 },
+               { PIOCPLPERR, "PCI PIO completion FIFO parity error", -1, 1 },
+               { PIOREQPERR, "PCI PIO request FIFO parity error", -1, 1 },
+               { TARTAGPERR, "PCI PCI target tag FIFO parity error", -1, 1 },
+               { CCNTPERR, "PCI CMD channel count parity error", -1, 1 },
+               { CREQPERR, "PCI CMD channel request parity error", -1, 1 },
+               { CRSPPERR, "PCI CMD channel response parity error", -1, 1 },
+               { DCNTPERR, "PCI DMA channel count parity error", -1, 1 },
+               { DREQPERR, "PCI DMA channel request parity error", -1, 1 },
+               { DRSPPERR, "PCI DMA channel response parity error", -1, 1 },
+               { HCNTPERR, "PCI HMA channel count parity error", -1, 1 },
+               { HREQPERR, "PCI HMA channel request parity error", -1, 1 },
+               { HRSPPERR, "PCI HMA channel response parity error", -1, 1 },
+               { CFGSNPPERR, "PCI config snoop FIFO parity error", -1, 1 },
+               { FIDPERR, "PCI FID parity error", -1, 1 },
+               { INTXCLRPERR, "PCI INTx clear parity error", -1, 1 },
+               { MATAGPERR, "PCI MA tag parity error", -1, 1 },
+               { PIOTAGPERR, "PCI PIO tag parity error", -1, 1 },
+               { RXCPLPERR, "PCI Rx completion parity error", -1, 1 },
+               { RXWRPERR, "PCI Rx write parity error", -1, 1 },
+               { RPLPERR, "PCI replay buffer parity error", -1, 1 },
+               { PCIESINT, "PCI core secondary fault", -1, 1 },
+               { PCIEPINT, "PCI core primary fault", -1, 1 },
+               { UNXSPLCPLERR, "PCI unexpected split completion error", -1, 0 },
+               { 0 }
+       };
+
+       int fat;
+
+       fat = t4_handle_intr_status(adapter,
+                                   PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS,
+                                   sysbus_intr_info) +
+             t4_handle_intr_status(adapter,
+                                   PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS,
+                                   pcie_port_intr_info) +
+             t4_handle_intr_status(adapter, PCIE_INT_CAUSE, pcie_intr_info);
+       if (fat)
+               t4_fatal_err(adapter);
+}
+
+/*
+ * TP interrupt handler.
+ */
+static void tp_intr_handler(struct adapter *adapter)
+{
+       static struct intr_info tp_intr_info[] = {
+               { 0x3fffffff, "TP parity error", -1, 1 },
+               { FLMTXFLSTEMPTY, "TP out of Tx pages", -1, 1 },
+               { 0 }
+       };
+
+       if (t4_handle_intr_status(adapter, TP_INT_CAUSE, tp_intr_info))
+               t4_fatal_err(adapter);
+}
+
+/*
+ * SGE interrupt handler.
+ */
+static void sge_intr_handler(struct adapter *adapter)
+{
+       u64 v;
+
+       static struct intr_info sge_intr_info[] = {
+               { ERR_CPL_EXCEED_IQE_SIZE,
+                 "SGE received CPL exceeding IQE size", -1, 1 },
+               { ERR_INVALID_CIDX_INC,
+                 "SGE GTS CIDX increment too large", -1, 0 },
+               { ERR_CPL_OPCODE_0, "SGE received 0-length CPL", -1, 0 },
+               { ERR_DROPPED_DB, "SGE doorbell dropped", -1, 0 },
+               { ERR_DATA_CPL_ON_HIGH_QID1 | ERR_DATA_CPL_ON_HIGH_QID0,
+                 "SGE IQID > 1023 received CPL for FL", -1, 0 },
+               { ERR_BAD_DB_PIDX3, "SGE DBP 3 pidx increment too large", -1,
+                 0 },
+               { ERR_BAD_DB_PIDX2, "SGE DBP 2 pidx increment too large", -1,
+                 0 },
+               { ERR_BAD_DB_PIDX1, "SGE DBP 1 pidx increment too large", -1,
+                 0 },
+               { ERR_BAD_DB_PIDX0, "SGE DBP 0 pidx increment too large", -1,
+                 0 },
+               { ERR_ING_CTXT_PRIO,
+                 "SGE too many priority ingress contexts", -1, 0 },
+               { ERR_EGR_CTXT_PRIO,
+                 "SGE too many priority egress contexts", -1, 0 },
+               { INGRESS_SIZE_ERR, "SGE illegal ingress QID", -1, 0 },
+               { EGRESS_SIZE_ERR, "SGE illegal egress QID", -1, 0 },
+               { 0 }
+       };
+
+       v = (u64)t4_read_reg(adapter, SGE_INT_CAUSE1) |
+           ((u64)t4_read_reg(adapter, SGE_INT_CAUSE2) << 32);
+       if (v) {
+               dev_alert(adapter->pdev_dev, "SGE parity error (%#llx)\n",
+                        (unsigned long long)v);
+               t4_write_reg(adapter, SGE_INT_CAUSE1, v);
+               t4_write_reg(adapter, SGE_INT_CAUSE2, v >> 32);
+       }
+
+       if (t4_handle_intr_status(adapter, SGE_INT_CAUSE3, sge_intr_info) ||
+           v != 0)
+               t4_fatal_err(adapter);
+}
+
+/*
+ * CIM interrupt handler.
+ */
+static void cim_intr_handler(struct adapter *adapter)
+{
+       static struct intr_info cim_intr_info[] = {
+               { PREFDROPINT, "CIM control register prefetch drop", -1, 1 },
+               { OBQPARERR, "CIM OBQ parity error", -1, 1 },
+               { IBQPARERR, "CIM IBQ parity error", -1, 1 },
+               { MBUPPARERR, "CIM mailbox uP parity error", -1, 1 },
+               { MBHOSTPARERR, "CIM mailbox host parity error", -1, 1 },
+               { TIEQINPARERRINT, "CIM TIEQ outgoing parity error", -1, 1 },
+               { TIEQOUTPARERRINT, "CIM TIEQ incoming parity error", -1, 1 },
+               { 0 }
+       };
+       static struct intr_info cim_upintr_info[] = {
+               { RSVDSPACEINT, "CIM reserved space access", -1, 1 },
+               { ILLTRANSINT, "CIM illegal transaction", -1, 1 },
+               { ILLWRINT, "CIM illegal write", -1, 1 },
+               { ILLRDINT, "CIM illegal read", -1, 1 },
+               { ILLRDBEINT, "CIM illegal read BE", -1, 1 },
+               { ILLWRBEINT, "CIM illegal write BE", -1, 1 },
+               { SGLRDBOOTINT, "CIM single read from boot space", -1, 1 },
+               { SGLWRBOOTINT, "CIM single write to boot space", -1, 1 },
+               { BLKWRBOOTINT, "CIM block write to boot space", -1, 1 },
+               { SGLRDFLASHINT, "CIM single read from flash space", -1, 1 },
+               { SGLWRFLASHINT, "CIM single write to flash space", -1, 1 },
+               { BLKWRFLASHINT, "CIM block write to flash space", -1, 1 },
+               { SGLRDEEPROMINT, "CIM single EEPROM read", -1, 1 },
+               { SGLWREEPROMINT, "CIM single EEPROM write", -1, 1 },
+               { BLKRDEEPROMINT, "CIM block EEPROM read", -1, 1 },
+               { BLKWREEPROMINT, "CIM block EEPROM write", -1, 1 },
+               { SGLRDCTLINT , "CIM single read from CTL space", -1, 1 },
+               { SGLWRCTLINT , "CIM single write to CTL space", -1, 1 },
+               { BLKRDCTLINT , "CIM block read from CTL space", -1, 1 },
+               { BLKWRCTLINT , "CIM block write to CTL space", -1, 1 },
+               { SGLRDPLINT , "CIM single read from PL space", -1, 1 },
+               { SGLWRPLINT , "CIM single write to PL space", -1, 1 },
+               { BLKRDPLINT , "CIM block read from PL space", -1, 1 },
+               { BLKWRPLINT , "CIM block write to PL space", -1, 1 },
+               { REQOVRLOOKUPINT , "CIM request FIFO overwrite", -1, 1 },
+               { RSPOVRLOOKUPINT , "CIM response FIFO overwrite", -1, 1 },
+               { TIMEOUTINT , "CIM PIF timeout", -1, 1 },
+               { TIMEOUTMAINT , "CIM PIF MA timeout", -1, 1 },
+               { 0 }
+       };
+
+       int fat;
+
+       fat = t4_handle_intr_status(adapter, CIM_HOST_INT_CAUSE,
+                                   cim_intr_info) +
+             t4_handle_intr_status(adapter, CIM_HOST_UPACC_INT_CAUSE,
+                                   cim_upintr_info);
+       if (fat)
+               t4_fatal_err(adapter);
+}
+
+/*
+ * ULP RX interrupt handler.
+ */
+static void ulprx_intr_handler(struct adapter *adapter)
+{
+       static struct intr_info ulprx_intr_info[] = {
+               { 0x7fffff, "ULPRX parity error", -1, 1 },
+               { 0 }
+       };
+
+       if (t4_handle_intr_status(adapter, ULP_RX_INT_CAUSE, ulprx_intr_info))
+               t4_fatal_err(adapter);
+}
+
+/*
+ * ULP TX interrupt handler.
+ */
+static void ulptx_intr_handler(struct adapter *adapter)
+{
+       static struct intr_info ulptx_intr_info[] = {
+               { PBL_BOUND_ERR_CH3, "ULPTX channel 3 PBL out of bounds", -1,
+                 0 },
+               { PBL_BOUND_ERR_CH2, "ULPTX channel 2 PBL out of bounds", -1,
+                 0 },
+               { PBL_BOUND_ERR_CH1, "ULPTX channel 1 PBL out of bounds", -1,
+                 0 },
+               { PBL_BOUND_ERR_CH0, "ULPTX channel 0 PBL out of bounds", -1,
+                 0 },
+               { 0xfffffff, "ULPTX parity error", -1, 1 },
+               { 0 }
+       };
+
+       if (t4_handle_intr_status(adapter, ULP_TX_INT_CAUSE, ulptx_intr_info))
+               t4_fatal_err(adapter);
+}
+
+/*
+ * PM TX interrupt handler.
+ */
+static void pmtx_intr_handler(struct adapter *adapter)
+{
+       static struct intr_info pmtx_intr_info[] = {
+               { PCMD_LEN_OVFL0, "PMTX channel 0 pcmd too large", -1, 1 },
+               { PCMD_LEN_OVFL1, "PMTX channel 1 pcmd too large", -1, 1 },
+               { PCMD_LEN_OVFL2, "PMTX channel 2 pcmd too large", -1, 1 },
+               { ZERO_C_CMD_ERROR, "PMTX 0-length pcmd", -1, 1 },
+               { PMTX_FRAMING_ERROR, "PMTX framing error", -1, 1 },
+               { OESPI_PAR_ERROR, "PMTX oespi parity error", -1, 1 },
+               { DB_OPTIONS_PAR_ERROR, "PMTX db_options parity error", -1, 1 },
+               { ICSPI_PAR_ERROR, "PMTX icspi parity error", -1, 1 },
+               { C_PCMD_PAR_ERROR, "PMTX c_pcmd parity error", -1, 1},
+               { 0 }
+       };
+
+       if (t4_handle_intr_status(adapter, PM_TX_INT_CAUSE, pmtx_intr_info))
+               t4_fatal_err(adapter);
+}
+
+/*
+ * PM RX interrupt handler.
+ */
+static void pmrx_intr_handler(struct adapter *adapter)
+{
+       static struct intr_info pmrx_intr_info[] = {
+               { ZERO_E_CMD_ERROR, "PMRX 0-length pcmd", -1, 1 },
+               { PMRX_FRAMING_ERROR, "PMRX framing error", -1, 1 },
+               { OCSPI_PAR_ERROR, "PMRX ocspi parity error", -1, 1 },
+               { DB_OPTIONS_PAR_ERROR, "PMRX db_options parity error", -1, 1 },
+               { IESPI_PAR_ERROR, "PMRX iespi parity error", -1, 1 },
+               { E_PCMD_PAR_ERROR, "PMRX e_pcmd parity error", -1, 1},
+               { 0 }
+       };
+
+       if (t4_handle_intr_status(adapter, PM_RX_INT_CAUSE, pmrx_intr_info))
+               t4_fatal_err(adapter);
+}
+
+/*
+ * CPL switch interrupt handler.
+ */
+static void cplsw_intr_handler(struct adapter *adapter)
+{
+       static struct intr_info cplsw_intr_info[] = {
+               { CIM_OP_MAP_PERR, "CPLSW CIM op_map parity error", -1, 1 },
+               { CIM_OVFL_ERROR, "CPLSW CIM overflow", -1, 1 },
+               { TP_FRAMING_ERROR, "CPLSW TP framing error", -1, 1 },
+               { SGE_FRAMING_ERROR, "CPLSW SGE framing error", -1, 1 },
+               { CIM_FRAMING_ERROR, "CPLSW CIM framing error", -1, 1 },
+               { ZERO_SWITCH_ERROR, "CPLSW no-switch error", -1, 1 },
+               { 0 }
+       };
+
+       if (t4_handle_intr_status(adapter, CPL_INTR_CAUSE, cplsw_intr_info))
+               t4_fatal_err(adapter);
+}
+
+/*
+ * LE interrupt handler.
+ */
+static void le_intr_handler(struct adapter *adap)
+{
+       static struct intr_info le_intr_info[] = {
+               { LIPMISS, "LE LIP miss", -1, 0 },
+               { LIP0, "LE 0 LIP error", -1, 0 },
+               { PARITYERR, "LE parity error", -1, 1 },
+               { UNKNOWNCMD, "LE unknown command", -1, 1 },
+               { REQQPARERR, "LE request queue parity error", -1, 1 },
+               { 0 }
+       };
+
+       if (t4_handle_intr_status(adap, LE_DB_INT_CAUSE, le_intr_info))
+               t4_fatal_err(adap);
+}
+
+/*
+ * MPS interrupt handler.
+ */
+static void mps_intr_handler(struct adapter *adapter)
+{
+       static struct intr_info mps_rx_intr_info[] = {
+               { 0xffffff, "MPS Rx parity error", -1, 1 },
+               { 0 }
+       };
+       static struct intr_info mps_tx_intr_info[] = {
+               { TPFIFO, "MPS Tx TP FIFO parity error", -1, 1 },
+               { NCSIFIFO, "MPS Tx NC-SI FIFO parity error", -1, 1 },
+               { TXDATAFIFO, "MPS Tx data FIFO parity error", -1, 1 },
+               { TXDESCFIFO, "MPS Tx desc FIFO parity error", -1, 1 },
+               { BUBBLE, "MPS Tx underflow", -1, 1 },
+               { SECNTERR, "MPS Tx SOP/EOP error", -1, 1 },
+               { FRMERR, "MPS Tx framing error", -1, 1 },
+               { 0 }
+       };
+       static struct intr_info mps_trc_intr_info[] = {
+               { FILTMEM, "MPS TRC filter parity error", -1, 1 },
+               { PKTFIFO, "MPS TRC packet FIFO parity error", -1, 1 },
+               { MISCPERR, "MPS TRC misc parity error", -1, 1 },
+               { 0 }
+       };
+       static struct intr_info mps_stat_sram_intr_info[] = {
+               { 0x1fffff, "MPS statistics SRAM parity error", -1, 1 },
+               { 0 }
+       };
+       static struct intr_info mps_stat_tx_intr_info[] = {
+               { 0xfffff, "MPS statistics Tx FIFO parity error", -1, 1 },
+               { 0 }
+       };
+       static struct intr_info mps_stat_rx_intr_info[] = {
+               { 0xffffff, "MPS statistics Rx FIFO parity error", -1, 1 },
+               { 0 }
+       };
+       static struct intr_info mps_cls_intr_info[] = {
+               { MATCHSRAM, "MPS match SRAM parity error", -1, 1 },
+               { MATCHTCAM, "MPS match TCAM parity error", -1, 1 },
+               { HASHSRAM, "MPS hash SRAM parity error", -1, 1 },
+               { 0 }
+       };
+
+       int fat;
+
+       fat = t4_handle_intr_status(adapter, MPS_RX_PERR_INT_CAUSE,
+                                   mps_rx_intr_info) +
+             t4_handle_intr_status(adapter, MPS_TX_INT_CAUSE,
+                                   mps_tx_intr_info) +
+             t4_handle_intr_status(adapter, MPS_TRC_INT_CAUSE,
+                                   mps_trc_intr_info) +
+             t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_SRAM,
+                                   mps_stat_sram_intr_info) +
+             t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_TX_FIFO,
+                                   mps_stat_tx_intr_info) +
+             t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_RX_FIFO,
+                                   mps_stat_rx_intr_info) +
+             t4_handle_intr_status(adapter, MPS_CLS_INT_CAUSE,
+                                   mps_cls_intr_info);
+
+       t4_write_reg(adapter, MPS_INT_CAUSE, CLSINT | TRCINT |
+                    RXINT | TXINT | STATINT);
+       t4_read_reg(adapter, MPS_INT_CAUSE);                    /* flush */
+       if (fat)
+               t4_fatal_err(adapter);
+}
+
+#define MEM_INT_MASK (PERR_INT_CAUSE | ECC_CE_INT_CAUSE | ECC_UE_INT_CAUSE)
+
+/*
+ * EDC/MC interrupt handler.
+ */
+static void mem_intr_handler(struct adapter *adapter, int idx)
+{
+       static const char name[3][5] = { "EDC0", "EDC1", "MC" };
+
+       unsigned int addr, cnt_addr, v;
+
+       if (idx <= MEM_EDC1) {
+               addr = EDC_REG(EDC_INT_CAUSE, idx);
+               cnt_addr = EDC_REG(EDC_ECC_STATUS, idx);
+       } else {
+               addr = MC_INT_CAUSE;
+               cnt_addr = MC_ECC_STATUS;
+       }
+
+       v = t4_read_reg(adapter, addr) & MEM_INT_MASK;
+       if (v & PERR_INT_CAUSE)
+               dev_alert(adapter->pdev_dev, "%s FIFO parity error\n",
+                         name[idx]);
+       if (v & ECC_CE_INT_CAUSE) {
+               u32 cnt = ECC_CECNT_GET(t4_read_reg(adapter, cnt_addr));
+
+               t4_write_reg(adapter, cnt_addr, ECC_CECNT_MASK);
+               if (printk_ratelimit())
+                       dev_warn(adapter->pdev_dev,
+                                "%u %s correctable ECC data error%s\n",
+                                cnt, name[idx], cnt > 1 ? "s" : "");
+       }
+       if (v & ECC_UE_INT_CAUSE)
+               dev_alert(adapter->pdev_dev,
+                         "%s uncorrectable ECC data error\n", name[idx]);
+
+       t4_write_reg(adapter, addr, v);
+       if (v & (PERR_INT_CAUSE | ECC_UE_INT_CAUSE))
+               t4_fatal_err(adapter);
+}
+
+/*
+ * MA interrupt handler.
+ */
+static void ma_intr_handler(struct adapter *adap)
+{
+       u32 v, status = t4_read_reg(adap, MA_INT_CAUSE);
+
+       if (status & MEM_PERR_INT_CAUSE)
+               dev_alert(adap->pdev_dev,
+                         "MA parity error, parity status %#x\n",
+                         t4_read_reg(adap, MA_PARITY_ERROR_STATUS));
+       if (status & MEM_WRAP_INT_CAUSE) {
+               v = t4_read_reg(adap, MA_INT_WRAP_STATUS);
+               dev_alert(adap->pdev_dev, "MA address wrap-around error by "
+                         "client %u to address %#x\n",
+                         MEM_WRAP_CLIENT_NUM_GET(v),
+                         MEM_WRAP_ADDRESS_GET(v) << 4);
+       }
+       t4_write_reg(adap, MA_INT_CAUSE, status);
+       t4_fatal_err(adap);
+}
+
+/*
+ * SMB interrupt handler.
+ */
+static void smb_intr_handler(struct adapter *adap)
+{
+       static struct intr_info smb_intr_info[] = {
+               { MSTTXFIFOPARINT, "SMB master Tx FIFO parity error", -1, 1 },
+               { MSTRXFIFOPARINT, "SMB master Rx FIFO parity error", -1, 1 },
+               { SLVFIFOPARINT, "SMB slave FIFO parity error", -1, 1 },
+               { 0 }
+       };
+
+       if (t4_handle_intr_status(adap, SMB_INT_CAUSE, smb_intr_info))
+               t4_fatal_err(adap);
+}
+
+/*
+ * NC-SI interrupt handler.
+ */
+static void ncsi_intr_handler(struct adapter *adap)
+{
+       static struct intr_info ncsi_intr_info[] = {
+               { CIM_DM_PRTY_ERR, "NC-SI CIM parity error", -1, 1 },
+               { MPS_DM_PRTY_ERR, "NC-SI MPS parity error", -1, 1 },
+               { TXFIFO_PRTY_ERR, "NC-SI Tx FIFO parity error", -1, 1 },
+               { RXFIFO_PRTY_ERR, "NC-SI Rx FIFO parity error", -1, 1 },
+               { 0 }
+       };
+
+       if (t4_handle_intr_status(adap, NCSI_INT_CAUSE, ncsi_intr_info))
+               t4_fatal_err(adap);
+}
+
+/*
+ * XGMAC interrupt handler.
+ */
+static void xgmac_intr_handler(struct adapter *adap, int port)
+{
+       u32 v = t4_read_reg(adap, PORT_REG(port, XGMAC_PORT_INT_CAUSE));
+
+       v &= TXFIFO_PRTY_ERR | RXFIFO_PRTY_ERR;
+       if (!v)
+               return;
+
+       if (v & TXFIFO_PRTY_ERR)
+               dev_alert(adap->pdev_dev, "XGMAC %d Tx FIFO parity error\n",
+                         port);
+       if (v & RXFIFO_PRTY_ERR)
+               dev_alert(adap->pdev_dev, "XGMAC %d Rx FIFO parity error\n",
+                         port);
+       t4_write_reg(adap, PORT_REG(port, XGMAC_PORT_INT_CAUSE), v);
+       t4_fatal_err(adap);
+}
+
+/*
+ * PL interrupt handler.
+ */
+static void pl_intr_handler(struct adapter *adap)
+{
+       static struct intr_info pl_intr_info[] = {
+               { FATALPERR, "T4 fatal parity error", -1, 1 },
+               { PERRVFID, "PL VFID_MAP parity error", -1, 1 },
+               { 0 }
+       };
+
+       if (t4_handle_intr_status(adap, PL_PL_INT_CAUSE, pl_intr_info))
+               t4_fatal_err(adap);
+}
+
+#define PF_INTR_MASK (PFSW | PFCIM)
+#define GLBL_INTR_MASK (CIM | MPS | PL | PCIE | MC | EDC0 | \
+               EDC1 | LE | TP | MA | PM_TX | PM_RX | ULP_RX | \
+               CPL_SWITCH | SGE | ULP_TX)
+
+/**
+ *     t4_slow_intr_handler - control path interrupt handler
+ *     @adapter: the adapter
+ *
+ *     T4 interrupt handler for non-data global interrupt events, e.g., errors.
+ *     The designation 'slow' is because it involves register reads, while
+ *     data interrupts typically don't involve any MMIOs.
+ */
+int t4_slow_intr_handler(struct adapter *adapter)
+{
+       u32 cause = t4_read_reg(adapter, PL_INT_CAUSE);
+
+       if (!(cause & GLBL_INTR_MASK))
+               return 0;
+       if (cause & CIM)
+               cim_intr_handler(adapter);
+       if (cause & MPS)
+               mps_intr_handler(adapter);
+       if (cause & NCSI)
+               ncsi_intr_handler(adapter);
+       if (cause & PL)
+               pl_intr_handler(adapter);
+       if (cause & SMB)
+               smb_intr_handler(adapter);
+       if (cause & XGMAC0)
+               xgmac_intr_handler(adapter, 0);
+       if (cause & XGMAC1)
+               xgmac_intr_handler(adapter, 1);
+       if (cause & XGMAC_KR0)
+               xgmac_intr_handler(adapter, 2);
+       if (cause & XGMAC_KR1)
+               xgmac_intr_handler(adapter, 3);
+       if (cause & PCIE)
+               pcie_intr_handler(adapter);
+       if (cause & MC)
+               mem_intr_handler(adapter, MEM_MC);
+       if (cause & EDC0)
+               mem_intr_handler(adapter, MEM_EDC0);
+       if (cause & EDC1)
+               mem_intr_handler(adapter, MEM_EDC1);
+       if (cause & LE)
+               le_intr_handler(adapter);
+       if (cause & TP)
+               tp_intr_handler(adapter);
+       if (cause & MA)
+               ma_intr_handler(adapter);
+       if (cause & PM_TX)
+               pmtx_intr_handler(adapter);
+       if (cause & PM_RX)
+               pmrx_intr_handler(adapter);
+       if (cause & ULP_RX)
+               ulprx_intr_handler(adapter);
+       if (cause & CPL_SWITCH)
+               cplsw_intr_handler(adapter);
+       if (cause & SGE)
+               sge_intr_handler(adapter);
+       if (cause & ULP_TX)
+               ulptx_intr_handler(adapter);
+
+       /* Clear the interrupts just processed for which we are the master. */
+       t4_write_reg(adapter, PL_INT_CAUSE, cause & GLBL_INTR_MASK);
+       (void) t4_read_reg(adapter, PL_INT_CAUSE); /* flush */
+       return 1;
+}
+
+/**
+ *     t4_intr_enable - enable interrupts
+ *     @adapter: the adapter whose interrupts should be enabled
+ *
+ *     Enable PF-specific interrupts for the calling function and the top-level
+ *     interrupt concentrator for global interrupts.  Interrupts are already
+ *     enabled at each module, here we just enable the roots of the interrupt
+ *     hierarchies.
+ *
+ *     Note: this function should be called only when the driver manages
+ *     non PF-specific interrupts from the various HW modules.  Only one PCI
+ *     function at a time should be doing this.
+ */
+void t4_intr_enable(struct adapter *adapter)
+{
+       u32 pf = SOURCEPF_GET(t4_read_reg(adapter, PL_WHOAMI));
+
+       t4_write_reg(adapter, SGE_INT_ENABLE3, ERR_CPL_EXCEED_IQE_SIZE |
+                    ERR_INVALID_CIDX_INC | ERR_CPL_OPCODE_0 |
+                    ERR_DROPPED_DB | ERR_DATA_CPL_ON_HIGH_QID1 |
+                    ERR_DATA_CPL_ON_HIGH_QID0 | ERR_BAD_DB_PIDX3 |
+                    ERR_BAD_DB_PIDX2 | ERR_BAD_DB_PIDX1 |
+                    ERR_BAD_DB_PIDX0 | ERR_ING_CTXT_PRIO |
+                    ERR_EGR_CTXT_PRIO | INGRESS_SIZE_ERR |
+                    EGRESS_SIZE_ERR);
+       t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE), PF_INTR_MASK);
+       t4_set_reg_field(adapter, PL_INT_MAP0, 0, 1 << pf);
+}
+
+/**
+ *     t4_intr_disable - disable interrupts
+ *     @adapter: the adapter whose interrupts should be disabled
+ *
+ *     Disable interrupts.  We only disable the top-level interrupt
+ *     concentrators.  The caller must be a PCI function managing global
+ *     interrupts.
+ */
+void t4_intr_disable(struct adapter *adapter)
+{
+       u32 pf = SOURCEPF_GET(t4_read_reg(adapter, PL_WHOAMI));
+
+       t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE), 0);
+       t4_set_reg_field(adapter, PL_INT_MAP0, 1 << pf, 0);
+}
+
+/**
+ *     t4_intr_clear - clear all interrupts
+ *     @adapter: the adapter whose interrupts should be cleared
+ *
+ *     Clears all interrupts.  The caller must be a PCI function managing
+ *     global interrupts.
+ */
+void t4_intr_clear(struct adapter *adapter)
+{
+       static const unsigned int cause_reg[] = {
+               SGE_INT_CAUSE1, SGE_INT_CAUSE2, SGE_INT_CAUSE3,
+               PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS,
+               PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS,
+               PCIE_NONFAT_ERR, PCIE_INT_CAUSE,
+               MC_INT_CAUSE,
+               MA_INT_WRAP_STATUS, MA_PARITY_ERROR_STATUS, MA_INT_CAUSE,
+               EDC_INT_CAUSE, EDC_REG(EDC_INT_CAUSE, 1),
+               CIM_HOST_INT_CAUSE, CIM_HOST_UPACC_INT_CAUSE,
+               MYPF_REG(CIM_PF_HOST_INT_CAUSE),
+               TP_INT_CAUSE,
+               ULP_RX_INT_CAUSE, ULP_TX_INT_CAUSE,
+               PM_RX_INT_CAUSE, PM_TX_INT_CAUSE,
+               MPS_RX_PERR_INT_CAUSE,
+               CPL_INTR_CAUSE,
+               MYPF_REG(PL_PF_INT_CAUSE),
+               PL_PL_INT_CAUSE,
+               LE_DB_INT_CAUSE,
+       };
+
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(cause_reg); ++i)
+               t4_write_reg(adapter, cause_reg[i], 0xffffffff);
+
+       t4_write_reg(adapter, PL_INT_CAUSE, GLBL_INTR_MASK);
+       (void) t4_read_reg(adapter, PL_INT_CAUSE);          /* flush */
+}
+
+/**
+ *     hash_mac_addr - return the hash value of a MAC address
+ *     @addr: the 48-bit Ethernet MAC address
+ *
+ *     Hashes a MAC address according to the hash function used by HW inexact
+ *     (hash) address matching.
+ */
+static int hash_mac_addr(const u8 *addr)
+{
+       u32 a = ((u32)addr[0] << 16) | ((u32)addr[1] << 8) | addr[2];
+       u32 b = ((u32)addr[3] << 16) | ((u32)addr[4] << 8) | addr[5];
+       a ^= b;
+       a ^= (a >> 12);
+       a ^= (a >> 6);
+       return a & 0x3f;
+}
+
+/**
+ *     t4_config_rss_range - configure a portion of the RSS mapping table
+ *     @adapter: the adapter
+ *     @mbox: mbox to use for the FW command
+ *     @viid: virtual interface whose RSS subtable is to be written
+ *     @start: start entry in the table to write
+ *     @n: how many table entries to write
+ *     @rspq: values for the response queue lookup table
+ *     @nrspq: number of values in @rspq
+ *
+ *     Programs the selected part of the VI's RSS mapping table with the
+ *     provided values.  If @nrspq < @n the supplied values are used repeatedly
+ *     until the full table range is populated.
+ *
+ *     The caller must ensure the values in @rspq are in the range allowed for
+ *     @viid.
+ */
+int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
+                       int start, int n, const u16 *rspq, unsigned int nrspq)
+{
+       int ret;
+       const u16 *rsp = rspq;
+       const u16 *rsp_end = rspq + nrspq;
+       struct fw_rss_ind_tbl_cmd cmd;
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.op_to_viid = htonl(FW_CMD_OP(FW_RSS_IND_TBL_CMD) |
+                              FW_CMD_REQUEST | FW_CMD_WRITE |
+                              FW_RSS_IND_TBL_CMD_VIID(viid));
+       cmd.retval_len16 = htonl(FW_LEN16(cmd));
+
+       /* each fw_rss_ind_tbl_cmd takes up to 32 entries */
+       while (n > 0) {
+               int nq = min(n, 32);
+               __be32 *qp = &cmd.iq0_to_iq2;
+
+               cmd.niqid = htons(nq);
+               cmd.startidx = htons(start);
+
+               start += nq;
+               n -= nq;
+
+               while (nq > 0) {
+                       unsigned int v;
+
+                       v = FW_RSS_IND_TBL_CMD_IQ0(*rsp);
+                       if (++rsp >= rsp_end)
+                               rsp = rspq;
+                       v |= FW_RSS_IND_TBL_CMD_IQ1(*rsp);
+                       if (++rsp >= rsp_end)
+                               rsp = rspq;
+                       v |= FW_RSS_IND_TBL_CMD_IQ2(*rsp);
+                       if (++rsp >= rsp_end)
+                               rsp = rspq;
+
+                       *qp++ = htonl(v);
+                       nq -= 3;
+               }
+
+               ret = t4_wr_mbox(adapter, mbox, &cmd, sizeof(cmd), NULL);
+               if (ret)
+                       return ret;
+       }
+       return 0;
+}
+
+/**
+ *     t4_config_glbl_rss - configure the global RSS mode
+ *     @adapter: the adapter
+ *     @mbox: mbox to use for the FW command
+ *     @mode: global RSS mode
+ *     @flags: mode-specific flags
+ *
+ *     Sets the global RSS mode.
+ */
+int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode,
+                      unsigned int flags)
+{
+       struct fw_rss_glb_config_cmd c;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_write = htonl(FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) |
+                             FW_CMD_REQUEST | FW_CMD_WRITE);
+       c.retval_len16 = htonl(FW_LEN16(c));
+       if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL) {
+               c.u.manual.mode_pkd = htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode));
+       } else if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL) {
+               c.u.basicvirtual.mode_pkd =
+                       htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode));
+               c.u.basicvirtual.synmapen_to_hashtoeplitz = htonl(flags);
+       } else
+               return -EINVAL;
+       return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL);
+}
+
+/* Read an RSS table row */
+static int rd_rss_row(struct adapter *adap, int row, u32 *val)
+{
+       t4_write_reg(adap, TP_RSS_LKP_TABLE, 0xfff00000 | row);
+       return t4_wait_op_done_val(adap, TP_RSS_LKP_TABLE, LKPTBLROWVLD, 1,
+                                  5, 0, val);
+}
+
+/**
+ *     t4_read_rss - read the contents of the RSS mapping table
+ *     @adapter: the adapter
+ *     @map: holds the contents of the RSS mapping table
+ *
+ *     Reads the contents of the RSS hash->queue mapping table.
+ */
+int t4_read_rss(struct adapter *adapter, u16 *map)
+{
+       u32 val;
+       int i, ret;
+
+       for (i = 0; i < RSS_NENTRIES / 2; ++i) {
+               ret = rd_rss_row(adapter, i, &val);
+               if (ret)
+                       return ret;
+               *map++ = LKPTBLQUEUE0_GET(val);
+               *map++ = LKPTBLQUEUE1_GET(val);
+       }
+       return 0;
+}
+
+/**
+ *     t4_tp_get_tcp_stats - read TP's TCP MIB counters
+ *     @adap: the adapter
+ *     @v4: holds the TCP/IP counter values
+ *     @v6: holds the TCP/IPv6 counter values
+ *
+ *     Returns the values of TP's TCP/IP and TCP/IPv6 MIB counters.
+ *     Either @v4 or @v6 may be %NULL to skip the corresponding stats.
+ */
+void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4,
+                        struct tp_tcp_stats *v6)
+{
+       u32 val[TP_MIB_TCP_RXT_SEG_LO - TP_MIB_TCP_OUT_RST + 1];
+
+#define STAT_IDX(x) ((TP_MIB_TCP_##x) - TP_MIB_TCP_OUT_RST)
+#define STAT(x)     val[STAT_IDX(x)]
+#define STAT64(x)   (((u64)STAT(x##_HI) << 32) | STAT(x##_LO))
+
+       if (v4) {
+               t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, val,
+                                ARRAY_SIZE(val), TP_MIB_TCP_OUT_RST);
+               v4->tcpOutRsts = STAT(OUT_RST);
+               v4->tcpInSegs  = STAT64(IN_SEG);
+               v4->tcpOutSegs = STAT64(OUT_SEG);
+               v4->tcpRetransSegs = STAT64(RXT_SEG);
+       }
+       if (v6) {
+               t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, val,
+                                ARRAY_SIZE(val), TP_MIB_TCP_V6OUT_RST);
+               v6->tcpOutRsts = STAT(OUT_RST);
+               v6->tcpInSegs  = STAT64(IN_SEG);
+               v6->tcpOutSegs = STAT64(OUT_SEG);
+               v6->tcpRetransSegs = STAT64(RXT_SEG);
+       }
+#undef STAT64
+#undef STAT
+#undef STAT_IDX
+}
+
+/**
+ *     t4_tp_get_err_stats - read TP's error MIB counters
+ *     @adap: the adapter
+ *     @st: holds the counter values
+ *
+ *     Returns the values of TP's error counters.
+ */
+void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st)
+{
+       t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->macInErrs,
+                        12, TP_MIB_MAC_IN_ERR_0);
+       t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tnlCongDrops,
+                        8, TP_MIB_TNL_CNG_DROP_0);
+       t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tnlTxDrops,
+                        4, TP_MIB_TNL_DROP_0);
+       t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->ofldVlanDrops,
+                        4, TP_MIB_OFD_VLN_DROP_0);
+       t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tcp6InErrs,
+                        4, TP_MIB_TCP_V6IN_ERR_0);
+       t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, &st->ofldNoNeigh,
+                        2, TP_MIB_OFD_ARP_DROP);
+}
+
+/**
+ *     t4_read_mtu_tbl - returns the values in the HW path MTU table
+ *     @adap: the adapter
+ *     @mtus: where to store the MTU values
+ *     @mtu_log: where to store the MTU base-2 log (may be %NULL)
+ *
+ *     Reads the HW path MTU table.
+ */
+void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log)
+{
+       u32 v;
+       int i;
+
+       for (i = 0; i < NMTUS; ++i) {
+               t4_write_reg(adap, TP_MTU_TABLE,
+                            MTUINDEX(0xff) | MTUVALUE(i));
+               v = t4_read_reg(adap, TP_MTU_TABLE);
+               mtus[i] = MTUVALUE_GET(v);
+               if (mtu_log)
+                       mtu_log[i] = MTUWIDTH_GET(v);
+       }
+}
+
+/**
+ *     init_cong_ctrl - initialize congestion control parameters
+ *     @a: the alpha values for congestion control
+ *     @b: the beta values for congestion control
+ *
+ *     Initialize the congestion control parameters.
+ */
+static void __devinit init_cong_ctrl(unsigned short *a, unsigned short *b)
+{
+       a[0] = a[1] = a[2] = a[3] = a[4] = a[5] = a[6] = a[7] = a[8] = 1;
+       a[9] = 2;
+       a[10] = 3;
+       a[11] = 4;
+       a[12] = 5;
+       a[13] = 6;
+       a[14] = 7;
+       a[15] = 8;
+       a[16] = 9;
+       a[17] = 10;
+       a[18] = 14;
+       a[19] = 17;
+       a[20] = 21;
+       a[21] = 25;
+       a[22] = 30;
+       a[23] = 35;
+       a[24] = 45;
+       a[25] = 60;
+       a[26] = 80;
+       a[27] = 100;
+       a[28] = 200;
+       a[29] = 300;
+       a[30] = 400;
+       a[31] = 500;
+
+       b[0] = b[1] = b[2] = b[3] = b[4] = b[5] = b[6] = b[7] = b[8] = 0;
+       b[9] = b[10] = 1;
+       b[11] = b[12] = 2;
+       b[13] = b[14] = b[15] = b[16] = 3;
+       b[17] = b[18] = b[19] = b[20] = b[21] = 4;
+       b[22] = b[23] = b[24] = b[25] = b[26] = b[27] = 5;
+       b[28] = b[29] = 6;
+       b[30] = b[31] = 7;
+}
+
+/* The minimum additive increment value for the congestion control table */
+#define CC_MIN_INCR 2U
+
+/**
+ *     t4_load_mtus - write the MTU and congestion control HW tables
+ *     @adap: the adapter
+ *     @mtus: the values for the MTU table
+ *     @alpha: the values for the congestion control alpha parameter
+ *     @beta: the values for the congestion control beta parameter
+ *
+ *     Write the HW MTU table with the supplied MTUs and the high-speed
+ *     congestion control table with the supplied alpha, beta, and MTUs.
+ *     We write the two tables together because the additive increments
+ *     depend on the MTUs.
+ */
+void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
+                 const unsigned short *alpha, const unsigned short *beta)
+{
+       static const unsigned int avg_pkts[NCCTRL_WIN] = {
+               2, 6, 10, 14, 20, 28, 40, 56, 80, 112, 160, 224, 320, 448, 640,
+               896, 1281, 1792, 2560, 3584, 5120, 7168, 10240, 14336, 20480,
+               28672, 40960, 57344, 81920, 114688, 163840, 229376
+       };
+
+       unsigned int i, w;
+
+       for (i = 0; i < NMTUS; ++i) {
+               unsigned int mtu = mtus[i];
+               unsigned int log2 = fls(mtu);
+
+               if (!(mtu & ((1 << log2) >> 2)))     /* round */
+                       log2--;
+               t4_write_reg(adap, TP_MTU_TABLE, MTUINDEX(i) |
+                            MTUWIDTH(log2) | MTUVALUE(mtu));
+
+               for (w = 0; w < NCCTRL_WIN; ++w) {
+                       unsigned int inc;
+
+                       inc = max(((mtu - 40) * alpha[w]) / avg_pkts[w],
+                                 CC_MIN_INCR);
+
+                       t4_write_reg(adap, TP_CCTRL_TABLE, (i << 21) |
+                                    (w << 16) | (beta[w] << 13) | inc);
+               }
+       }
+}
+
+/**
+ *     t4_set_trace_filter - configure one of the tracing filters
+ *     @adap: the adapter
+ *     @tp: the desired trace filter parameters
+ *     @idx: which filter to configure
+ *     @enable: whether to enable or disable the filter
+ *
+ *     Configures one of the tracing filters available in HW.  If @enable is
+ *     %0 @tp is not examined and may be %NULL.
+ */
+int t4_set_trace_filter(struct adapter *adap, const struct trace_params *tp,
+                       int idx, int enable)
+{
+       int i, ofst = idx * 4;
+       u32 data_reg, mask_reg, cfg;
+       u32 multitrc = TRCMULTIFILTER;
+
+       if (!enable) {
+               t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, 0);
+               goto out;
+       }
+
+       if (tp->port > 11 || tp->invert > 1 || tp->skip_len > 0x1f ||
+           tp->skip_ofst > 0x1f || tp->min_len > 0x1ff ||
+           tp->snap_len > 9600 || (idx && tp->snap_len > 256))
+               return -EINVAL;
+
+       if (tp->snap_len > 256) {            /* must be tracer 0 */
+               if ((t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 4) |
+                    t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 8) |
+                    t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 12)) & TFEN)
+                       return -EINVAL;  /* other tracers are enabled */
+               multitrc = 0;
+       } else if (idx) {
+               i = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B);
+               if (TFCAPTUREMAX_GET(i) > 256 &&
+                   (t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A) & TFEN))
+                       return -EINVAL;
+       }
+
+       /* stop the tracer we'll be changing */
+       t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, 0);
+
+       /* disable tracing globally if running in the wrong single/multi mode */
+       cfg = t4_read_reg(adap, MPS_TRC_CFG);
+       if ((cfg & TRCEN) && multitrc != (cfg & TRCMULTIFILTER)) {
+               t4_write_reg(adap, MPS_TRC_CFG, cfg ^ TRCEN);
+               t4_read_reg(adap, MPS_TRC_CFG);                  /* flush */
+               msleep(1);
+               if (!(t4_read_reg(adap, MPS_TRC_CFG) & TRCFIFOEMPTY))
+                       return -ETIMEDOUT;
+       }
+       /*
+        * At this point either the tracing is enabled and in the right mode or
+        * disabled.
+        */
+
+       idx *= (MPS_TRC_FILTER1_MATCH - MPS_TRC_FILTER0_MATCH);
+       data_reg = MPS_TRC_FILTER0_MATCH + idx;
+       mask_reg = MPS_TRC_FILTER0_DONT_CARE + idx;
+
+       for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) {
+               t4_write_reg(adap, data_reg, tp->data[i]);
+               t4_write_reg(adap, mask_reg, ~tp->mask[i]);
+       }
+       t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B + ofst,
+                    TFCAPTUREMAX(tp->snap_len) |
+                    TFMINPKTSIZE(tp->min_len));
+       t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst,
+                    TFOFFSET(tp->skip_ofst) | TFLENGTH(tp->skip_len) |
+                    TFPORT(tp->port) | TFEN |
+                    (tp->invert ? TFINVERTMATCH : 0));
+
+       cfg &= ~TRCMULTIFILTER;
+       t4_write_reg(adap, MPS_TRC_CFG, cfg | TRCEN | multitrc);
+out:   t4_read_reg(adap, MPS_TRC_CFG);  /* flush */
+       return 0;
+}
+
+/**
+ *     t4_get_trace_filter - query one of the tracing filters
+ *     @adap: the adapter
+ *     @tp: the current trace filter parameters
+ *     @idx: which trace filter to query
+ *     @enabled: non-zero if the filter is enabled
+ *
+ *     Returns the current settings of one of the HW tracing filters.
+ */
+void t4_get_trace_filter(struct adapter *adap, struct trace_params *tp, int idx,
+                        int *enabled)
+{
+       u32 ctla, ctlb;
+       int i, ofst = idx * 4;
+       u32 data_reg, mask_reg;
+
+       ctla = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst);
+       ctlb = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B + ofst);
+
+       *enabled = !!(ctla & TFEN);
+       tp->snap_len = TFCAPTUREMAX_GET(ctlb);
+       tp->min_len = TFMINPKTSIZE_GET(ctlb);
+       tp->skip_ofst = TFOFFSET_GET(ctla);
+       tp->skip_len = TFLENGTH_GET(ctla);
+       tp->invert = !!(ctla & TFINVERTMATCH);
+       tp->port = TFPORT_GET(ctla);
+
+       ofst = (MPS_TRC_FILTER1_MATCH - MPS_TRC_FILTER0_MATCH) * idx;
+       data_reg = MPS_TRC_FILTER0_MATCH + ofst;
+       mask_reg = MPS_TRC_FILTER0_DONT_CARE + ofst;
+
+       for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) {
+               tp->mask[i] = ~t4_read_reg(adap, mask_reg);
+               tp->data[i] = t4_read_reg(adap, data_reg) & tp->mask[i];
+       }
+}
+
+/**
+ *     get_mps_bg_map - return the buffer groups associated with a port
+ *     @adap: the adapter
+ *     @idx: the port index
+ *
+ *     Returns a bitmap indicating which MPS buffer groups are associated
+ *     with the given port.  Bit i is set if buffer group i is used by the
+ *     port.
+ */
+static unsigned int get_mps_bg_map(struct adapter *adap, int idx)
+{
+       u32 n = NUMPORTS_GET(t4_read_reg(adap, MPS_CMN_CTL));
+
+       if (n == 0)
+               return idx == 0 ? 0xf : 0;
+       if (n == 1)
+               return idx < 2 ? (3 << (2 * idx)) : 0;
+       return 1 << idx;
+}
+
+/**
+ *     t4_get_port_stats - collect port statistics
+ *     @adap: the adapter
+ *     @idx: the port index
+ *     @p: the stats structure to fill
+ *
+ *     Collect statistics related to the given port from HW.
+ */
+void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p)
+{
+       u32 bgmap = get_mps_bg_map(adap, idx);
+
+#define GET_STAT(name) \
+       t4_read_reg64(adap, PORT_REG(idx, MPS_PORT_STAT_##name##_L))
+#define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L)
+
+       p->tx_octets           = GET_STAT(TX_PORT_BYTES);
+       p->tx_frames           = GET_STAT(TX_PORT_FRAMES);
+       p->tx_bcast_frames     = GET_STAT(TX_PORT_BCAST);
+       p->tx_mcast_frames     = GET_STAT(TX_PORT_MCAST);
+       p->tx_ucast_frames     = GET_STAT(TX_PORT_UCAST);
+       p->tx_error_frames     = GET_STAT(TX_PORT_ERROR);
+       p->tx_frames_64        = GET_STAT(TX_PORT_64B);
+       p->tx_frames_65_127    = GET_STAT(TX_PORT_65B_127B);
+       p->tx_frames_128_255   = GET_STAT(TX_PORT_128B_255B);
+       p->tx_frames_256_511   = GET_STAT(TX_PORT_256B_511B);
+       p->tx_frames_512_1023  = GET_STAT(TX_PORT_512B_1023B);
+       p->tx_frames_1024_1518 = GET_STAT(TX_PORT_1024B_1518B);
+       p->tx_frames_1519_max  = GET_STAT(TX_PORT_1519B_MAX);
+       p->tx_drop             = GET_STAT(TX_PORT_DROP);
+       p->tx_pause            = GET_STAT(TX_PORT_PAUSE);
+       p->tx_ppp0             = GET_STAT(TX_PORT_PPP0);
+       p->tx_ppp1             = GET_STAT(TX_PORT_PPP1);
+       p->tx_ppp2             = GET_STAT(TX_PORT_PPP2);
+       p->tx_ppp3             = GET_STAT(TX_PORT_PPP3);
+       p->tx_ppp4             = GET_STAT(TX_PORT_PPP4);
+       p->tx_ppp5             = GET_STAT(TX_PORT_PPP5);
+       p->tx_ppp6             = GET_STAT(TX_PORT_PPP6);
+       p->tx_ppp7             = GET_STAT(TX_PORT_PPP7);
+
+       p->rx_octets           = GET_STAT(RX_PORT_BYTES);
+       p->rx_frames           = GET_STAT(RX_PORT_FRAMES);
+       p->rx_bcast_frames     = GET_STAT(RX_PORT_BCAST);
+       p->rx_mcast_frames     = GET_STAT(RX_PORT_MCAST);
+       p->rx_ucast_frames     = GET_STAT(RX_PORT_UCAST);
+       p->rx_too_long         = GET_STAT(RX_PORT_MTU_ERROR);
+       p->rx_jabber           = GET_STAT(RX_PORT_MTU_CRC_ERROR);
+       p->rx_fcs_err          = GET_STAT(RX_PORT_CRC_ERROR);
+       p->rx_len_err          = GET_STAT(RX_PORT_LEN_ERROR);
+       p->rx_symbol_err       = GET_STAT(RX_PORT_SYM_ERROR);
+       p->rx_runt             = GET_STAT(RX_PORT_LESS_64B);
+       p->rx_frames_64        = GET_STAT(RX_PORT_64B);
+       p->rx_frames_65_127    = GET_STAT(RX_PORT_65B_127B);
+       p->rx_frames_128_255   = GET_STAT(RX_PORT_128B_255B);
+       p->rx_frames_256_511   = GET_STAT(RX_PORT_256B_511B);
+       p->rx_frames_512_1023  = GET_STAT(RX_PORT_512B_1023B);
+       p->rx_frames_1024_1518 = GET_STAT(RX_PORT_1024B_1518B);
+       p->rx_frames_1519_max  = GET_STAT(RX_PORT_1519B_MAX);
+       p->rx_pause            = GET_STAT(RX_PORT_PAUSE);
+       p->rx_ppp0             = GET_STAT(RX_PORT_PPP0);
+       p->rx_ppp1             = GET_STAT(RX_PORT_PPP1);
+       p->rx_ppp2             = GET_STAT(RX_PORT_PPP2);
+       p->rx_ppp3             = GET_STAT(RX_PORT_PPP3);
+       p->rx_ppp4             = GET_STAT(RX_PORT_PPP4);
+       p->rx_ppp5             = GET_STAT(RX_PORT_PPP5);
+       p->rx_ppp6             = GET_STAT(RX_PORT_PPP6);
+       p->rx_ppp7             = GET_STAT(RX_PORT_PPP7);
+
+       p->rx_ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_DROP_FRAME) : 0;
+       p->rx_ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_MAC_DROP_FRAME) : 0;
+       p->rx_ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_MAC_DROP_FRAME) : 0;
+       p->rx_ovflow3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_MAC_DROP_FRAME) : 0;
+       p->rx_trunc0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_TRUNC_FRAME) : 0;
+       p->rx_trunc1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_MAC_TRUNC_FRAME) : 0;
+       p->rx_trunc2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_MAC_TRUNC_FRAME) : 0;
+       p->rx_trunc3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_MAC_TRUNC_FRAME) : 0;
+
+#undef GET_STAT
+#undef GET_STAT_COM
+}
+
+/**
+ *     t4_get_lb_stats - collect loopback port statistics
+ *     @adap: the adapter
+ *     @idx: the loopback port index
+ *     @p: the stats structure to fill
+ *
+ *     Return HW statistics for the given loopback port.
+ */
+void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p)
+{
+       u32 bgmap = get_mps_bg_map(adap, idx);
+
+#define GET_STAT(name) \
+       t4_read_reg64(adap, PORT_REG(idx, MPS_PORT_STAT_LB_PORT_##name##_L))
+#define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L)
+
+       p->octets           = GET_STAT(BYTES);
+       p->frames           = GET_STAT(FRAMES);
+       p->bcast_frames     = GET_STAT(BCAST);
+       p->mcast_frames     = GET_STAT(MCAST);
+       p->ucast_frames     = GET_STAT(UCAST);
+       p->error_frames     = GET_STAT(ERROR);
+
+       p->frames_64        = GET_STAT(64B);
+       p->frames_65_127    = GET_STAT(65B_127B);
+       p->frames_128_255   = GET_STAT(128B_255B);
+       p->frames_256_511   = GET_STAT(256B_511B);
+       p->frames_512_1023  = GET_STAT(512B_1023B);
+       p->frames_1024_1518 = GET_STAT(1024B_1518B);
+       p->frames_1519_max  = GET_STAT(1519B_MAX);
+       p->drop             = t4_read_reg(adap, PORT_REG(idx,
+                                         MPS_PORT_STAT_LB_PORT_DROP_FRAMES));
+
+       p->ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_DROP_FRAME) : 0;
+       p->ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_DROP_FRAME) : 0;
+       p->ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_DROP_FRAME) : 0;
+       p->ovflow3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_DROP_FRAME) : 0;
+       p->trunc0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_TRUNC_FRAME) : 0;
+       p->trunc1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_TRUNC_FRAME) : 0;
+       p->trunc2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_TRUNC_FRAME) : 0;
+       p->trunc3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_TRUNC_FRAME) : 0;
+
+#undef GET_STAT
+#undef GET_STAT_COM
+}
+
+/**
+ *     t4_wol_magic_enable - enable/disable magic packet WoL
+ *     @adap: the adapter
+ *     @port: the physical port index
+ *     @addr: MAC address expected in magic packets, %NULL to disable
+ *
+ *     Enables/disables magic packet wake-on-LAN for the selected port.
+ */
+void t4_wol_magic_enable(struct adapter *adap, unsigned int port,
+                        const u8 *addr)
+{
+       if (addr) {
+               t4_write_reg(adap, PORT_REG(port, XGMAC_PORT_MAGIC_MACID_LO),
+                            (addr[2] << 24) | (addr[3] << 16) |
+                            (addr[4] << 8) | addr[5]);
+               t4_write_reg(adap, PORT_REG(port, XGMAC_PORT_MAGIC_MACID_HI),
+                            (addr[0] << 8) | addr[1]);
+       }
+       t4_set_reg_field(adap, PORT_REG(port, XGMAC_PORT_CFG2), MAGICEN,
+                        addr ? MAGICEN : 0);
+}
+
+/**
+ *     t4_wol_pat_enable - enable/disable pattern-based WoL
+ *     @adap: the adapter
+ *     @port: the physical port index
+ *     @map: bitmap of which HW pattern filters to set
+ *     @mask0: byte mask for bytes 0-63 of a packet
+ *     @mask1: byte mask for bytes 64-127 of a packet
+ *     @crc: Ethernet CRC for selected bytes
+ *     @enable: enable/disable switch
+ *
+ *     Sets the pattern filters indicated in @map to mask out the bytes
+ *     specified in @mask0/@mask1 in received packets and compare the CRC of
+ *     the resulting packet against @crc.  If @enable is %true pattern-based
+ *     WoL is enabled, otherwise disabled.
+ */
+int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map,
+                     u64 mask0, u64 mask1, unsigned int crc, bool enable)
+{
+       int i;
+
+       if (!enable) {
+               t4_set_reg_field(adap, PORT_REG(port, XGMAC_PORT_CFG2),
+                                PATEN, 0);
+               return 0;
+       }
+       if (map > 0xff)
+               return -EINVAL;
+
+#define EPIO_REG(name) PORT_REG(port, XGMAC_PORT_EPIO_##name)
+
+       t4_write_reg(adap, EPIO_REG(DATA1), mask0 >> 32);
+       t4_write_reg(adap, EPIO_REG(DATA2), mask1);
+       t4_write_reg(adap, EPIO_REG(DATA3), mask1 >> 32);
+
+       for (i = 0; i < NWOL_PAT; i++, map >>= 1) {
+               if (!(map & 1))
+                       continue;
+
+               /* write byte masks */
+               t4_write_reg(adap, EPIO_REG(DATA0), mask0);
+               t4_write_reg(adap, EPIO_REG(OP), ADDRESS(i) | EPIOWR);
+               t4_read_reg(adap, EPIO_REG(OP));                /* flush */
+               if (t4_read_reg(adap, EPIO_REG(OP)) & BUSY)
+                       return -ETIMEDOUT;
+
+               /* write CRC */
+               t4_write_reg(adap, EPIO_REG(DATA0), crc);
+               t4_write_reg(adap, EPIO_REG(OP), ADDRESS(i + 32) | EPIOWR);
+               t4_read_reg(adap, EPIO_REG(OP));                /* flush */
+               if (t4_read_reg(adap, EPIO_REG(OP)) & BUSY)
+                       return -ETIMEDOUT;
+       }
+#undef EPIO_REG
+
+       t4_set_reg_field(adap, PORT_REG(port, XGMAC_PORT_CFG2), 0, PATEN);
+       return 0;
+}
+
+#define INIT_CMD(var, cmd, rd_wr) do { \
+       (var).op_to_write = htonl(FW_CMD_OP(FW_##cmd##_CMD) | \
+                                 FW_CMD_REQUEST | FW_CMD_##rd_wr); \
+       (var).retval_len16 = htonl(FW_LEN16(var)); \
+} while (0)
+
+/**
+ *     t4_mdio_rd - read a PHY register through MDIO
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @phy_addr: the PHY address
+ *     @mmd: the PHY MMD to access (0 for clause 22 PHYs)
+ *     @reg: the register to read
+ *     @valp: where to store the value
+ *
+ *     Issues a FW command through the given mailbox to read a PHY register.
+ */
+int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
+              unsigned int mmd, unsigned int reg, u16 *valp)
+{
+       int ret;
+       struct fw_ldst_cmd c;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_addrspace = htonl(FW_CMD_OP(FW_LDST_CMD) | FW_CMD_REQUEST |
+               FW_CMD_READ | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MDIO));
+       c.cycles_to_len16 = htonl(FW_LEN16(c));
+       c.u.mdio.paddr_mmd = htons(FW_LDST_CMD_PADDR(phy_addr) |
+                                  FW_LDST_CMD_MMD(mmd));
+       c.u.mdio.raddr = htons(reg);
+
+       ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+       if (ret == 0)
+               *valp = ntohs(c.u.mdio.rval);
+       return ret;
+}
+
+/**
+ *     t4_mdio_wr - write a PHY register through MDIO
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @phy_addr: the PHY address
+ *     @mmd: the PHY MMD to access (0 for clause 22 PHYs)
+ *     @reg: the register to write
+ *     @valp: value to write
+ *
+ *     Issues a FW command through the given mailbox to write a PHY register.
+ */
+int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
+              unsigned int mmd, unsigned int reg, u16 val)
+{
+       struct fw_ldst_cmd c;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_addrspace = htonl(FW_CMD_OP(FW_LDST_CMD) | FW_CMD_REQUEST |
+               FW_CMD_WRITE | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MDIO));
+       c.cycles_to_len16 = htonl(FW_LEN16(c));
+       c.u.mdio.paddr_mmd = htons(FW_LDST_CMD_PADDR(phy_addr) |
+                                  FW_LDST_CMD_MMD(mmd));
+       c.u.mdio.raddr = htons(reg);
+       c.u.mdio.rval = htons(val);
+
+       return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *     t4_fw_hello - establish communication with FW
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @evt_mbox: mailbox to receive async FW events
+ *     @master: specifies the caller's willingness to be the device master
+ *     @state: returns the current device state
+ *
+ *     Issues a command to establish communication with FW.
+ */
+int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox,
+               enum dev_master master, enum dev_state *state)
+{
+       int ret;
+       struct fw_hello_cmd c;
+
+       INIT_CMD(c, HELLO, WRITE);
+       c.err_to_mbasyncnot = htonl(
+               FW_HELLO_CMD_MASTERDIS(master == MASTER_CANT) |
+               FW_HELLO_CMD_MASTERFORCE(master == MASTER_MUST) |
+               FW_HELLO_CMD_MBMASTER(master == MASTER_MUST ? mbox : 0xff) |
+               FW_HELLO_CMD_MBASYNCNOT(evt_mbox));
+
+       ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+       if (ret == 0 && state) {
+               u32 v = ntohl(c.err_to_mbasyncnot);
+               if (v & FW_HELLO_CMD_INIT)
+                       *state = DEV_STATE_INIT;
+               else if (v & FW_HELLO_CMD_ERR)
+                       *state = DEV_STATE_ERR;
+               else
+                       *state = DEV_STATE_UNINIT;
+       }
+       return ret;
+}
+
+/**
+ *     t4_fw_bye - end communication with FW
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *
+ *     Issues a command to terminate communication with FW.
+ */
+int t4_fw_bye(struct adapter *adap, unsigned int mbox)
+{
+       struct fw_bye_cmd c;
+
+       INIT_CMD(c, BYE, WRITE);
+       return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *     t4_init_cmd - ask FW to initialize the device
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *
+ *     Issues a command to FW to partially initialize the device.  This
+ *     performs initialization that generally doesn't depend on user input.
+ */
+int t4_early_init(struct adapter *adap, unsigned int mbox)
+{
+       struct fw_initialize_cmd c;
+
+       INIT_CMD(c, INITIALIZE, WRITE);
+       return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *     t4_fw_reset - issue a reset to FW
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @reset: specifies the type of reset to perform
+ *
+ *     Issues a reset command of the specified type to FW.
+ */
+int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset)
+{
+       struct fw_reset_cmd c;
+
+       INIT_CMD(c, RESET, WRITE);
+       c.val = htonl(reset);
+       return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *     t4_query_params - query FW or device parameters
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @pf: the PF
+ *     @vf: the VF
+ *     @nparams: the number of parameters
+ *     @params: the parameter names
+ *     @val: the parameter values
+ *
+ *     Reads the value of FW or device parameters.  Up to 7 parameters can be
+ *     queried at once.
+ */
+int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
+                   unsigned int vf, unsigned int nparams, const u32 *params,
+                   u32 *val)
+{
+       int i, ret;
+       struct fw_params_cmd c;
+       __be32 *p = &c.param[0].mnem;
+
+       if (nparams > 7)
+               return -EINVAL;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_vfn = htonl(FW_CMD_OP(FW_PARAMS_CMD) | FW_CMD_REQUEST |
+                           FW_CMD_READ | FW_PARAMS_CMD_PFN(pf) |
+                           FW_PARAMS_CMD_VFN(vf));
+       c.retval_len16 = htonl(FW_LEN16(c));
+       for (i = 0; i < nparams; i++, p += 2)
+               *p = htonl(*params++);
+
+       ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+       if (ret == 0)
+               for (i = 0, p = &c.param[0].val; i < nparams; i++, p += 2)
+                       *val++ = ntohl(*p);
+       return ret;
+}
+
+/**
+ *     t4_set_params - sets FW or device parameters
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @pf: the PF
+ *     @vf: the VF
+ *     @nparams: the number of parameters
+ *     @params: the parameter names
+ *     @val: the parameter values
+ *
+ *     Sets the value of FW or device parameters.  Up to 7 parameters can be
+ *     specified at once.
+ */
+int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
+                 unsigned int vf, unsigned int nparams, const u32 *params,
+                 const u32 *val)
+{
+       struct fw_params_cmd c;
+       __be32 *p = &c.param[0].mnem;
+
+       if (nparams > 7)
+               return -EINVAL;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_vfn = htonl(FW_CMD_OP(FW_PARAMS_CMD) | FW_CMD_REQUEST |
+                           FW_CMD_WRITE | FW_PARAMS_CMD_PFN(pf) |
+                           FW_PARAMS_CMD_VFN(vf));
+       c.retval_len16 = htonl(FW_LEN16(c));
+       while (nparams--) {
+               *p++ = htonl(*params++);
+               *p++ = htonl(*val++);
+       }
+
+       return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *     t4_cfg_pfvf - configure PF/VF resource limits
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @pf: the PF being configured
+ *     @vf: the VF being configured
+ *     @txq: the max number of egress queues
+ *     @txq_eth_ctrl: the max number of egress Ethernet or control queues
+ *     @rxqi: the max number of interrupt-capable ingress queues
+ *     @rxq: the max number of interruptless ingress queues
+ *     @tc: the PCI traffic class
+ *     @vi: the max number of virtual interfaces
+ *     @cmask: the channel access rights mask for the PF/VF
+ *     @pmask: the port access rights mask for the PF/VF
+ *     @nexact: the maximum number of exact MPS filters
+ *     @rcaps: read capabilities
+ *     @wxcaps: write/execute capabilities
+ *
+ *     Configures resource limits and capabilities for a physical or virtual
+ *     function.
+ */
+int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf,
+               unsigned int vf, unsigned int txq, unsigned int txq_eth_ctrl,
+               unsigned int rxqi, unsigned int rxq, unsigned int tc,
+               unsigned int vi, unsigned int cmask, unsigned int pmask,
+               unsigned int nexact, unsigned int rcaps, unsigned int wxcaps)
+{
+       struct fw_pfvf_cmd c;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_vfn = htonl(FW_CMD_OP(FW_PFVF_CMD) | FW_CMD_REQUEST |
+                           FW_CMD_WRITE | FW_PFVF_CMD_PFN(pf) |
+                           FW_PFVF_CMD_VFN(vf));
+       c.retval_len16 = htonl(FW_LEN16(c));
+       c.niqflint_niq = htonl(FW_PFVF_CMD_NIQFLINT(rxqi) |
+                              FW_PFVF_CMD_NIQ(rxq));
+       c.cmask_to_neq = htonl(FW_PFVF_CMD_CMASK(cmask) |
+                              FW_PFVF_CMD_PMASK(pmask) |
+                              FW_PFVF_CMD_NEQ(txq));
+       c.tc_to_nexactf = htonl(FW_PFVF_CMD_TC(tc) | FW_PFVF_CMD_NVI(vi) |
+                               FW_PFVF_CMD_NEXACTF(nexact));
+       c.r_caps_to_nethctrl = htonl(FW_PFVF_CMD_R_CAPS(rcaps) |
+                                    FW_PFVF_CMD_WX_CAPS(wxcaps) |
+                                    FW_PFVF_CMD_NETHCTRL(txq_eth_ctrl));
+       return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *     t4_alloc_vi - allocate a virtual interface
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @port: physical port associated with the VI
+ *     @pf: the PF owning the VI
+ *     @vf: the VF owning the VI
+ *     @nmac: number of MAC addresses needed (1 to 5)
+ *     @mac: the MAC addresses of the VI
+ *     @rss_size: size of RSS table slice associated with this VI
+ *
+ *     Allocates a virtual interface for the given physical port.  If @mac is
+ *     not %NULL it contains the MAC addresses of the VI as assigned by FW.
+ *     @mac should be large enough to hold @nmac Ethernet addresses, they are
+ *     stored consecutively so the space needed is @nmac * 6 bytes.
+ *     Returns a negative error number or the non-negative VI id.
+ */
+int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port,
+               unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac,
+               unsigned int *rss_size)
+{
+       int ret;
+       struct fw_vi_cmd c;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_vfn = htonl(FW_CMD_OP(FW_VI_CMD) | FW_CMD_REQUEST |
+                           FW_CMD_WRITE | FW_CMD_EXEC |
+                           FW_VI_CMD_PFN(pf) | FW_VI_CMD_VFN(vf));
+       c.alloc_to_len16 = htonl(FW_VI_CMD_ALLOC | FW_LEN16(c));
+       c.portid_pkd = FW_VI_CMD_PORTID(port);
+       c.nmac = nmac - 1;
+
+       ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+       if (ret)
+               return ret;
+
+       if (mac) {
+               memcpy(mac, c.mac, sizeof(c.mac));
+               switch (nmac) {
+               case 5:
+                       memcpy(mac + 24, c.nmac3, sizeof(c.nmac3));
+               case 4:
+                       memcpy(mac + 18, c.nmac2, sizeof(c.nmac2));
+               case 3:
+                       memcpy(mac + 12, c.nmac1, sizeof(c.nmac1));
+               case 2:
+                       memcpy(mac + 6,  c.nmac0, sizeof(c.nmac0));
+               }
+       }
+       if (rss_size)
+               *rss_size = FW_VI_CMD_RSSSIZE_GET(ntohs(c.rsssize_pkd));
+       return ntohs(c.viid_pkd);
+}
+
+/**
+ *     t4_free_vi - free a virtual interface
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @pf: the PF owning the VI
+ *     @vf: the VF owning the VI
+ *     @viid: virtual interface identifiler
+ *
+ *     Free a previously allocated virtual interface.
+ */
+int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf,
+              unsigned int vf, unsigned int viid)
+{
+       struct fw_vi_cmd c;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_vfn = htonl(FW_CMD_OP(FW_VI_CMD) | FW_CMD_REQUEST |
+                           FW_CMD_EXEC | FW_VI_CMD_PFN(pf) |
+                           FW_VI_CMD_VFN(vf));
+       c.alloc_to_len16 = htonl(FW_VI_CMD_FREE | FW_LEN16(c));
+       c.viid_pkd = htons(FW_VI_CMD_VIID(viid));
+       return t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+}
+
+/**
+ *     t4_set_rxmode - set Rx properties of a virtual interface
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @viid: the VI id
+ *     @mtu: the new MTU or -1
+ *     @promisc: 1 to enable promiscuous mode, 0 to disable it, -1 no change
+ *     @all_multi: 1 to enable all-multi mode, 0 to disable it, -1 no change
+ *     @bcast: 1 to enable broadcast Rx, 0 to disable it, -1 no change
+ *     @sleep_ok: if true we may sleep while awaiting command completion
+ *
+ *     Sets Rx properties of a virtual interface.
+ */
+int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid,
+                 int mtu, int promisc, int all_multi, int bcast, bool sleep_ok)
+{
+       struct fw_vi_rxmode_cmd c;
+
+       /* convert to FW values */
+       if (mtu < 0)
+               mtu = FW_RXMODE_MTU_NO_CHG;
+       if (promisc < 0)
+               promisc = FW_VI_RXMODE_CMD_PROMISCEN_MASK;
+       if (all_multi < 0)
+               all_multi = FW_VI_RXMODE_CMD_ALLMULTIEN_MASK;
+       if (bcast < 0)
+               bcast = FW_VI_RXMODE_CMD_BROADCASTEN_MASK;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_viid = htonl(FW_CMD_OP(FW_VI_RXMODE_CMD) | FW_CMD_REQUEST |
+                            FW_CMD_WRITE | FW_VI_RXMODE_CMD_VIID(viid));
+       c.retval_len16 = htonl(FW_LEN16(c));
+       c.mtu_to_broadcasten = htonl(FW_VI_RXMODE_CMD_MTU(mtu) |
+                                    FW_VI_RXMODE_CMD_PROMISCEN(promisc) |
+                                    FW_VI_RXMODE_CMD_ALLMULTIEN(all_multi) |
+                                    FW_VI_RXMODE_CMD_BROADCASTEN(bcast));
+       return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok);
+}
+
+/**
+ *     t4_alloc_mac_filt - allocates exact-match filters for MAC addresses
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @viid: the VI id
+ *     @free: if true any existing filters for this VI id are first removed
+ *     @naddr: the number of MAC addresses to allocate filters for (up to 7)
+ *     @addr: the MAC address(es)
+ *     @idx: where to store the index of each allocated filter
+ *     @hash: pointer to hash address filter bitmap
+ *     @sleep_ok: call is allowed to sleep
+ *
+ *     Allocates an exact-match filter for each of the supplied addresses and
+ *     sets it to the corresponding address.  If @idx is not %NULL it should
+ *     have at least @naddr entries, each of which will be set to the index of
+ *     the filter allocated for the corresponding MAC address.  If a filter
+ *     could not be allocated for an address its index is set to 0xffff.
+ *     If @hash is not %NULL addresses that fail to allocate an exact filter
+ *     are hashed and update the hash filter bitmap pointed at by @hash.
+ *
+ *     Returns a negative error number or the number of filters allocated.
+ */
+int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox,
+                     unsigned int viid, bool free, unsigned int naddr,
+                     const u8 **addr, u16 *idx, u64 *hash, bool sleep_ok)
+{
+       int i, ret;
+       struct fw_vi_mac_cmd c;
+       struct fw_vi_mac_exact *p;
+
+       if (naddr > 7)
+               return -EINVAL;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_viid = htonl(FW_CMD_OP(FW_VI_MAC_CMD) | FW_CMD_REQUEST |
+                            FW_CMD_WRITE | (free ? FW_CMD_EXEC : 0) |
+                            FW_VI_MAC_CMD_VIID(viid));
+       c.freemacs_to_len16 = htonl(FW_VI_MAC_CMD_FREEMACS(free) |
+                                   FW_CMD_LEN16((naddr + 2) / 2));
+
+       for (i = 0, p = c.u.exact; i < naddr; i++, p++) {
+               p->valid_to_idx = htons(FW_VI_MAC_CMD_VALID |
+                                     FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
+               memcpy(p->macaddr, addr[i], sizeof(p->macaddr));
+       }
+
+       ret = t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), &c, sleep_ok);
+       if (ret)
+               return ret;
+
+       for (i = 0, p = c.u.exact; i < naddr; i++, p++) {
+               u16 index = FW_VI_MAC_CMD_IDX_GET(ntohs(p->valid_to_idx));
+
+               if (idx)
+                       idx[i] = index >= NEXACT_MAC ? 0xffff : index;
+               if (index < NEXACT_MAC)
+                       ret++;
+               else if (hash)
+                       *hash |= (1 << hash_mac_addr(addr[i]));
+       }
+       return ret;
+}
+
+/**
+ *     t4_change_mac - modifies the exact-match filter for a MAC address
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @viid: the VI id
+ *     @idx: index of existing filter for old value of MAC address, or -1
+ *     @addr: the new MAC address value
+ *     @persist: whether a new MAC allocation should be persistent
+ *     @add_smt: if true also add the address to the HW SMT
+ *
+ *     Modifies an exact-match filter and sets it to the new MAC address.
+ *     Note that in general it is not possible to modify the value of a given
+ *     filter so the generic way to modify an address filter is to free the one
+ *     being used by the old address value and allocate a new filter for the
+ *     new address value.  @idx can be -1 if the address is a new addition.
+ *
+ *     Returns a negative error number or the index of the filter with the new
+ *     MAC value.
+ */
+int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid,
+                 int idx, const u8 *addr, bool persist, bool add_smt)
+{
+       int ret, mode;
+       struct fw_vi_mac_cmd c;
+       struct fw_vi_mac_exact *p = c.u.exact;
+
+       if (idx < 0)                             /* new allocation */
+               idx = persist ? FW_VI_MAC_ADD_PERSIST_MAC : FW_VI_MAC_ADD_MAC;
+       mode = add_smt ? FW_VI_MAC_SMT_AND_MPSTCAM : FW_VI_MAC_MPS_TCAM_ENTRY;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_viid = htonl(FW_CMD_OP(FW_VI_MAC_CMD) | FW_CMD_REQUEST |
+                            FW_CMD_WRITE | FW_VI_MAC_CMD_VIID(viid));
+       c.freemacs_to_len16 = htonl(FW_CMD_LEN16(1));
+       p->valid_to_idx = htons(FW_VI_MAC_CMD_VALID |
+                               FW_VI_MAC_CMD_SMAC_RESULT(mode) |
+                               FW_VI_MAC_CMD_IDX(idx));
+       memcpy(p->macaddr, addr, sizeof(p->macaddr));
+
+       ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+       if (ret == 0) {
+               ret = FW_VI_MAC_CMD_IDX_GET(ntohs(p->valid_to_idx));
+               if (ret >= NEXACT_MAC)
+                       ret = -ENOMEM;
+       }
+       return ret;
+}
+
+/**
+ *     t4_set_addr_hash - program the MAC inexact-match hash filter
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @viid: the VI id
+ *     @ucast: whether the hash filter should also match unicast addresses
+ *     @vec: the value to be written to the hash filter
+ *     @sleep_ok: call is allowed to sleep
+ *
+ *     Sets the 64-bit inexact-match hash filter for a virtual interface.
+ */
+int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid,
+                    bool ucast, u64 vec, bool sleep_ok)
+{
+       struct fw_vi_mac_cmd c;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_viid = htonl(FW_CMD_OP(FW_VI_MAC_CMD) | FW_CMD_REQUEST |
+                            FW_CMD_WRITE | FW_VI_ENABLE_CMD_VIID(viid));
+       c.freemacs_to_len16 = htonl(FW_VI_MAC_CMD_HASHVECEN |
+                                   FW_VI_MAC_CMD_HASHUNIEN(ucast) |
+                                   FW_CMD_LEN16(1));
+       c.u.hash.hashvec = cpu_to_be64(vec);
+       return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok);
+}
+
+/**
+ *     t4_enable_vi - enable/disable a virtual interface
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @viid: the VI id
+ *     @rx_en: 1=enable Rx, 0=disable Rx
+ *     @tx_en: 1=enable Tx, 0=disable Tx
+ *
+ *     Enables/disables a virtual interface.
+ */
+int t4_enable_vi(struct adapter *adap, unsigned int mbox, unsigned int viid,
+                bool rx_en, bool tx_en)
+{
+       struct fw_vi_enable_cmd c;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST |
+                            FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid));
+       c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_IEN(rx_en) |
+                              FW_VI_ENABLE_CMD_EEN(tx_en) | FW_LEN16(c));
+       return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *     t4_identify_port - identify a VI's port by blinking its LED
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @viid: the VI id
+ *     @nblinks: how many times to blink LED at 2.5 Hz
+ *
+ *     Identifies a VI's port by blinking its LED.
+ */
+int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid,
+                    unsigned int nblinks)
+{
+       struct fw_vi_enable_cmd c;
+
+       c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST |
+                            FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid));
+       c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c));
+       c.blinkdur = htons(nblinks);
+       return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *     t4_iq_start_stop - enable/disable an ingress queue and its FLs
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @start: %true to enable the queues, %false to disable them
+ *     @pf: the PF owning the queues
+ *     @vf: the VF owning the queues
+ *     @iqid: ingress queue id
+ *     @fl0id: FL0 queue id or 0xffff if no attached FL0
+ *     @fl1id: FL1 queue id or 0xffff if no attached FL1
+ *
+ *     Starts or stops an ingress queue and its associated FLs, if any.
+ */
+int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start,
+                    unsigned int pf, unsigned int vf, unsigned int iqid,
+                    unsigned int fl0id, unsigned int fl1id)
+{
+       struct fw_iq_cmd c;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST |
+                           FW_CMD_EXEC | FW_IQ_CMD_PFN(pf) |
+                           FW_IQ_CMD_VFN(vf));
+       c.alloc_to_len16 = htonl(FW_IQ_CMD_IQSTART(start) |
+                                FW_IQ_CMD_IQSTOP(!start) | FW_LEN16(c));
+       c.iqid = htons(iqid);
+       c.fl0id = htons(fl0id);
+       c.fl1id = htons(fl1id);
+       return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *     t4_iq_free - free an ingress queue and its FLs
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @pf: the PF owning the queues
+ *     @vf: the VF owning the queues
+ *     @iqtype: the ingress queue type
+ *     @iqid: ingress queue id
+ *     @fl0id: FL0 queue id or 0xffff if no attached FL0
+ *     @fl1id: FL1 queue id or 0xffff if no attached FL1
+ *
+ *     Frees an ingress queue and its associated FLs, if any.
+ */
+int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+              unsigned int vf, unsigned int iqtype, unsigned int iqid,
+              unsigned int fl0id, unsigned int fl1id)
+{
+       struct fw_iq_cmd c;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST |
+                           FW_CMD_EXEC | FW_IQ_CMD_PFN(pf) |
+                           FW_IQ_CMD_VFN(vf));
+       c.alloc_to_len16 = htonl(FW_IQ_CMD_FREE | FW_LEN16(c));
+       c.type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE(iqtype));
+       c.iqid = htons(iqid);
+       c.fl0id = htons(fl0id);
+       c.fl1id = htons(fl1id);
+       return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *     t4_eth_eq_free - free an Ethernet egress queue
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @pf: the PF owning the queue
+ *     @vf: the VF owning the queue
+ *     @eqid: egress queue id
+ *
+ *     Frees an Ethernet egress queue.
+ */
+int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+                  unsigned int vf, unsigned int eqid)
+{
+       struct fw_eq_eth_cmd c;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_ETH_CMD) | FW_CMD_REQUEST |
+                           FW_CMD_EXEC | FW_EQ_ETH_CMD_PFN(pf) |
+                           FW_EQ_ETH_CMD_VFN(vf));
+       c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_FREE | FW_LEN16(c));
+       c.eqid_pkd = htonl(FW_EQ_ETH_CMD_EQID(eqid));
+       return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *     t4_ctrl_eq_free - free a control egress queue
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @pf: the PF owning the queue
+ *     @vf: the VF owning the queue
+ *     @eqid: egress queue id
+ *
+ *     Frees a control egress queue.
+ */
+int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+                   unsigned int vf, unsigned int eqid)
+{
+       struct fw_eq_ctrl_cmd c;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_CTRL_CMD) | FW_CMD_REQUEST |
+                           FW_CMD_EXEC | FW_EQ_CTRL_CMD_PFN(pf) |
+                           FW_EQ_CTRL_CMD_VFN(vf));
+       c.alloc_to_len16 = htonl(FW_EQ_CTRL_CMD_FREE | FW_LEN16(c));
+       c.cmpliqid_eqid = htonl(FW_EQ_CTRL_CMD_EQID(eqid));
+       return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *     t4_ofld_eq_free - free an offload egress queue
+ *     @adap: the adapter
+ *     @mbox: mailbox to use for the FW command
+ *     @pf: the PF owning the queue
+ *     @vf: the VF owning the queue
+ *     @eqid: egress queue id
+ *
+ *     Frees a control egress queue.
+ */
+int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
+                   unsigned int vf, unsigned int eqid)
+{
+       struct fw_eq_ofld_cmd c;
+
+       memset(&c, 0, sizeof(c));
+       c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST |
+                           FW_CMD_EXEC | FW_EQ_OFLD_CMD_PFN(pf) |
+                           FW_EQ_OFLD_CMD_VFN(vf));
+       c.alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_FREE | FW_LEN16(c));
+       c.eqid_pkd = htonl(FW_EQ_OFLD_CMD_EQID(eqid));
+       return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
+ *     t4_handle_fw_rpl - process a FW reply message
+ *     @adap: the adapter
+ *     @rpl: start of the FW message
+ *
+ *     Processes a FW message, such as link state change messages.
+ */
+int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
+{
+       u8 opcode = *(const u8 *)rpl;
+
+       if (opcode == FW_PORT_CMD) {    /* link/module state change message */
+               int speed = 0, fc = 0;
+               const struct fw_port_cmd *p = (void *)rpl;
+               int chan = FW_PORT_CMD_PORTID_GET(ntohl(p->op_to_portid));
+               int port = adap->chan_map[chan];
+               struct port_info *pi = adap2pinfo(adap, port);
+               struct link_config *lc = &pi->link_cfg;
+               u32 stat = ntohl(p->u.info.lstatus_to_modtype);
+               int link_ok = (stat & FW_PORT_CMD_LSTATUS) != 0;
+               u32 mod = FW_PORT_CMD_MODTYPE_GET(stat);
+
+               if (stat & FW_PORT_CMD_RXPAUSE)
+                       fc |= PAUSE_RX;
+               if (stat & FW_PORT_CMD_TXPAUSE)
+                       fc |= PAUSE_TX;
+               if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
+                       speed = SPEED_100;
+               else if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
+                       speed = SPEED_1000;
+               else if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
+                       speed = SPEED_10000;
+
+               if (link_ok != lc->link_ok || speed != lc->speed ||
+                   fc != lc->fc) {                    /* something changed */
+                       lc->link_ok = link_ok;
+                       lc->speed = speed;
+                       lc->fc = fc;
+                       t4_os_link_changed(adap, port, link_ok);
+               }
+               if (mod != pi->mod_type) {
+                       pi->mod_type = mod;
+                       t4_os_portmod_changed(adap, port);
+               }
+       }
+       return 0;
+}
+
+static void __devinit get_pci_mode(struct adapter *adapter,
+                                  struct pci_params *p)
+{
+       u16 val;
+       u32 pcie_cap = pci_pcie_cap(adapter->pdev);
+
+       if (pcie_cap) {
+               pci_read_config_word(adapter->pdev, pcie_cap + PCI_EXP_LNKSTA,
+                                    &val);
+               p->speed = val & PCI_EXP_LNKSTA_CLS;
+               p->width = (val & PCI_EXP_LNKSTA_NLW) >> 4;
+       }
+}
+
+/**
+ *     init_link_config - initialize a link's SW state
+ *     @lc: structure holding the link state
+ *     @caps: link capabilities
+ *
+ *     Initializes the SW state maintained for each link, including the link's
+ *     capabilities and default speed/flow-control/autonegotiation settings.
+ */
+static void __devinit init_link_config(struct link_config *lc,
+                                      unsigned int caps)
+{
+       lc->supported = caps;
+       lc->requested_speed = 0;
+       lc->speed = 0;
+       lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
+       if (lc->supported & FW_PORT_CAP_ANEG) {
+               lc->advertising = lc->supported & ADVERT_MASK;
+               lc->autoneg = AUTONEG_ENABLE;
+               lc->requested_fc |= PAUSE_AUTONEG;
+       } else {
+               lc->advertising = 0;
+               lc->autoneg = AUTONEG_DISABLE;
+       }
+}
+
+static int __devinit wait_dev_ready(struct adapter *adap)
+{
+       if (t4_read_reg(adap, PL_WHOAMI) != 0xffffffff)
+               return 0;
+       msleep(500);
+       return t4_read_reg(adap, PL_WHOAMI) != 0xffffffff ? 0 : -EIO;
+}
+
+/**
+ *     t4_prep_adapter - prepare SW and HW for operation
+ *     @adapter: the adapter
+ *     @reset: if true perform a HW reset
+ *
+ *     Initialize adapter SW state for the various HW modules, set initial
+ *     values for some adapter tunables, take PHYs out of reset, and
+ *     initialize the MDIO interface.
+ */
+int __devinit t4_prep_adapter(struct adapter *adapter)
+{
+       int ret;
+
+       ret = wait_dev_ready(adapter);
+       if (ret < 0)
+               return ret;
+
+       get_pci_mode(adapter, &adapter->params.pci);
+       adapter->params.rev = t4_read_reg(adapter, PL_REV);
+
+       ret = get_vpd_params(adapter, &adapter->params.vpd);
+       if (ret < 0)
+               return ret;
+
+       init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd);
+
+       /*
+        * Default port for debugging in case we can't reach FW.
+        */
+       adapter->params.nports = 1;
+       adapter->params.portvec = 1;
+       return 0;
+}
+
+int __devinit t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
+{
+       u8 addr[6];
+       int ret, i, j = 0;
+       struct fw_port_cmd c;
+
+       memset(&c, 0, sizeof(c));
+
+       for_each_port(adap, i) {
+               unsigned int rss_size;
+               struct port_info *p = adap2pinfo(adap, i);
+
+               while ((adap->params.portvec & (1 << j)) == 0)
+                       j++;
+
+               c.op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD) |
+                                      FW_CMD_REQUEST | FW_CMD_READ |
+                                      FW_PORT_CMD_PORTID(j));
+               c.action_to_len16 = htonl(
+                       FW_PORT_CMD_ACTION(FW_PORT_ACTION_GET_PORT_INFO) |
+                       FW_LEN16(c));
+               ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+               if (ret)
+                       return ret;
+
+               ret = t4_alloc_vi(adap, mbox, j, pf, vf, 1, addr, &rss_size);
+               if (ret < 0)
+                       return ret;
+
+               p->viid = ret;
+               p->tx_chan = j;
+               p->lport = j;
+               p->rss_size = rss_size;
+               memcpy(adap->port[i]->dev_addr, addr, ETH_ALEN);
+               memcpy(adap->port[i]->perm_addr, addr, ETH_ALEN);
+
+               ret = ntohl(c.u.info.lstatus_to_modtype);
+               p->mdio_addr = (ret & FW_PORT_CMD_MDIOCAP) ?
+                       FW_PORT_CMD_MDIOADDR_GET(ret) : -1;
+               p->port_type = FW_PORT_CMD_PTYPE_GET(ret);
+               p->mod_type = FW_PORT_CMD_MODTYPE_GET(ret);
+
+               init_link_config(&p->link_cfg, ntohs(c.u.info.pcap));
+               j++;
+       }
+       return 0;
+}
diff --git a/drivers/net/cxgb4/t4_hw.h b/drivers/net/cxgb4/t4_hw.h
new file mode 100644 (file)
index 0000000..0256232
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ */
+
+#ifndef __T4_HW_H
+#define __T4_HW_H
+
+#include <linux/types.h>
+
+enum {
+       NCHAN          = 4,     /* # of HW channels */
+       MAX_MTU        = 9600,  /* max MAC MTU, excluding header + FCS */
+       EEPROMSIZE     = 17408, /* Serial EEPROM physical size */
+       EEPROMVSIZE    = 32768, /* Serial EEPROM virtual address space size */
+       RSS_NENTRIES   = 2048,  /* # of entries in RSS mapping table */
+       TCB_SIZE       = 128,   /* TCB size */
+       NMTUS          = 16,    /* size of MTU table */
+       NCCTRL_WIN     = 32,    /* # of congestion control windows */
+       NEXACT_MAC     = 336,   /* # of exact MAC address filters */
+       L2T_SIZE       = 4096,  /* # of L2T entries */
+       MBOX_LEN       = 64,    /* mailbox size in bytes */
+       TRACE_LEN      = 112,   /* length of trace data and mask */
+       FILTER_OPT_LEN = 36,    /* filter tuple width for optional components */
+       NWOL_PAT       = 8,     /* # of WoL patterns */
+       WOL_PAT_LEN    = 128,   /* length of WoL patterns */
+};
+
+enum {
+       SF_PAGE_SIZE = 256,           /* serial flash page size */
+       SF_SEC_SIZE = 64 * 1024,      /* serial flash sector size */
+       SF_SIZE = SF_SEC_SIZE * 16,   /* serial flash size */
+};
+
+enum { RSP_TYPE_FLBUF, RSP_TYPE_CPL, RSP_TYPE_INTR }; /* response entry types */
+
+enum { MBOX_OWNER_NONE, MBOX_OWNER_FW, MBOX_OWNER_DRV };    /* mailbox owners */
+
+enum {
+       SGE_MAX_WR_LEN = 512,     /* max WR size in bytes */
+       SGE_NTIMERS = 6,          /* # of interrupt holdoff timer values */
+       SGE_NCOUNTERS = 4,        /* # of interrupt packet counter values */
+};
+
+struct sge_qstat {                /* data written to SGE queue status entries */
+       __be32 qid;
+       __be16 cidx;
+       __be16 pidx;
+};
+
+/*
+ * Structure for last 128 bits of response descriptors
+ */
+struct rsp_ctrl {
+       __be32 hdrbuflen_pidx;
+       __be32 pldbuflen_qid;
+       union {
+               u8 type_gen;
+               __be64 last_flit;
+       };
+};
+
+#define RSPD_NEWBUF 0x80000000U
+#define RSPD_LEN    0x7fffffffU
+
+#define RSPD_GEN(x)  ((x) >> 7)
+#define RSPD_TYPE(x) (((x) >> 4) & 3)
+
+#define QINTR_CNT_EN       0x1
+#define QINTR_TIMER_IDX(x) ((x) << 1)
+#endif /* __T4_HW_H */
diff --git a/drivers/net/cxgb4/t4_msg.h b/drivers/net/cxgb4/t4_msg.h
new file mode 100644 (file)
index 0000000..fdb1174
--- /dev/null
@@ -0,0 +1,664 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ */
+
+#ifndef __T4_MSG_H
+#define __T4_MSG_H
+
+#include <linux/types.h>
+
+enum {
+       CPL_PASS_OPEN_REQ     = 0x1,
+       CPL_PASS_ACCEPT_RPL   = 0x2,
+       CPL_ACT_OPEN_REQ      = 0x3,
+       CPL_SET_TCB_FIELD     = 0x5,
+       CPL_GET_TCB           = 0x6,
+       CPL_CLOSE_CON_REQ     = 0x8,
+       CPL_CLOSE_LISTSRV_REQ = 0x9,
+       CPL_ABORT_REQ         = 0xA,
+       CPL_ABORT_RPL         = 0xB,
+       CPL_RX_DATA_ACK       = 0xD,
+       CPL_TX_PKT            = 0xE,
+       CPL_L2T_WRITE_REQ     = 0x12,
+       CPL_TID_RELEASE       = 0x1A,
+
+       CPL_CLOSE_LISTSRV_RPL = 0x20,
+       CPL_L2T_WRITE_RPL     = 0x23,
+       CPL_PASS_OPEN_RPL     = 0x24,
+       CPL_ACT_OPEN_RPL      = 0x25,
+       CPL_PEER_CLOSE        = 0x26,
+       CPL_ABORT_REQ_RSS     = 0x2B,
+       CPL_ABORT_RPL_RSS     = 0x2D,
+
+       CPL_CLOSE_CON_RPL     = 0x32,
+       CPL_ISCSI_HDR         = 0x33,
+       CPL_RDMA_CQE          = 0x35,
+       CPL_RDMA_CQE_READ_RSP = 0x36,
+       CPL_RDMA_CQE_ERR      = 0x37,
+       CPL_RX_DATA           = 0x39,
+       CPL_SET_TCB_RPL       = 0x3A,
+       CPL_RX_PKT            = 0x3B,
+       CPL_RX_DDP_COMPLETE   = 0x3F,
+
+       CPL_ACT_ESTABLISH     = 0x40,
+       CPL_PASS_ESTABLISH    = 0x41,
+       CPL_RX_DATA_DDP       = 0x42,
+       CPL_PASS_ACCEPT_REQ   = 0x44,
+
+       CPL_RDMA_READ_REQ     = 0x60,
+
+       CPL_PASS_OPEN_REQ6    = 0x81,
+       CPL_ACT_OPEN_REQ6     = 0x83,
+
+       CPL_RDMA_TERMINATE    = 0xA2,
+       CPL_RDMA_WRITE        = 0xA4,
+       CPL_SGE_EGR_UPDATE    = 0xA5,
+
+       CPL_TRACE_PKT         = 0xB0,
+
+       CPL_FW4_MSG           = 0xC0,
+       CPL_FW4_PLD           = 0xC1,
+       CPL_FW4_ACK           = 0xC3,
+
+       CPL_FW6_MSG           = 0xE0,
+       CPL_FW6_PLD           = 0xE1,
+       CPL_TX_PKT_LSO        = 0xED,
+       CPL_TX_PKT_XT         = 0xEE,
+
+       NUM_CPL_CMDS
+};
+
+enum CPL_error {
+       CPL_ERR_NONE               = 0,
+       CPL_ERR_TCAM_FULL          = 3,
+       CPL_ERR_BAD_LENGTH         = 15,
+       CPL_ERR_BAD_ROUTE          = 18,
+       CPL_ERR_CONN_RESET         = 20,
+       CPL_ERR_CONN_EXIST_SYNRECV = 21,
+       CPL_ERR_CONN_EXIST         = 22,
+       CPL_ERR_ARP_MISS           = 23,
+       CPL_ERR_BAD_SYN            = 24,
+       CPL_ERR_CONN_TIMEDOUT      = 30,
+       CPL_ERR_XMIT_TIMEDOUT      = 31,
+       CPL_ERR_PERSIST_TIMEDOUT   = 32,
+       CPL_ERR_FINWAIT2_TIMEDOUT  = 33,
+       CPL_ERR_KEEPALIVE_TIMEDOUT = 34,
+       CPL_ERR_RTX_NEG_ADVICE     = 35,
+       CPL_ERR_PERSIST_NEG_ADVICE = 36,
+       CPL_ERR_ABORT_FAILED       = 42,
+       CPL_ERR_IWARP_FLM          = 50,
+};
+
+enum {
+       ULP_MODE_NONE          = 0,
+       ULP_MODE_ISCSI         = 2,
+       ULP_MODE_RDMA          = 4,
+       ULP_MODE_FCOE          = 6,
+};
+
+enum {
+       ULP_CRC_HEADER = 1 << 0,
+       ULP_CRC_DATA   = 1 << 1
+};
+
+enum {
+       CPL_ABORT_SEND_RST = 0,
+       CPL_ABORT_NO_RST,
+};
+
+enum {                     /* TX_PKT_XT checksum types */
+       TX_CSUM_TCP    = 0,
+       TX_CSUM_UDP    = 1,
+       TX_CSUM_CRC16  = 4,
+       TX_CSUM_CRC32  = 5,
+       TX_CSUM_CRC32C = 6,
+       TX_CSUM_FCOE   = 7,
+       TX_CSUM_TCPIP  = 8,
+       TX_CSUM_UDPIP  = 9,
+       TX_CSUM_TCPIP6 = 10,
+       TX_CSUM_UDPIP6 = 11,
+       TX_CSUM_IP     = 12,
+};
+
+union opcode_tid {
+       __be32 opcode_tid;
+       u8 opcode;
+};
+
+#define CPL_OPCODE(x) ((x) << 24)
+#define MK_OPCODE_TID(opcode, tid) (CPL_OPCODE(opcode) | (tid))
+#define OPCODE_TID(cmd) ((cmd)->ot.opcode_tid)
+#define GET_TID(cmd) (ntohl(OPCODE_TID(cmd)) & 0xFFFFFF)
+
+/* partitioning of TID fields that also carry a queue id */
+#define GET_TID_TID(x) ((x) & 0x3fff)
+#define GET_TID_QID(x) (((x) >> 14) & 0x3ff)
+#define TID_QID(x)     ((x) << 14)
+
+struct rss_header {
+       u8 opcode;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+       u8 channel:2;
+       u8 filter_hit:1;
+       u8 filter_tid:1;
+       u8 hash_type:2;
+       u8 ipv6:1;
+       u8 send2fw:1;
+#else
+       u8 send2fw:1;
+       u8 ipv6:1;
+       u8 hash_type:2;
+       u8 filter_tid:1;
+       u8 filter_hit:1;
+       u8 channel:2;
+#endif
+       __be16 qid;
+       __be32 hash_val;
+};
+
+struct work_request_hdr {
+       __be32 wr_hi;
+       __be32 wr_mid;
+       __be64 wr_lo;
+};
+
+#define WR_HDR struct work_request_hdr wr
+
+struct cpl_pass_open_req {
+       WR_HDR;
+       union opcode_tid ot;
+       __be16 local_port;
+       __be16 peer_port;
+       __be32 local_ip;
+       __be32 peer_ip;
+       __be64 opt0;
+#define TX_CHAN(x)    ((x) << 2)
+#define DELACK(x)     ((x) << 5)
+#define ULP_MODE(x)   ((x) << 8)
+#define RCV_BUFSIZ(x) ((x) << 12)
+#define DSCP(x)       ((x) << 22)
+#define SMAC_SEL(x)   ((u64)(x) << 28)
+#define L2T_IDX(x)    ((u64)(x) << 36)
+#define NAGLE(x)      ((u64)(x) << 49)
+#define WND_SCALE(x)  ((u64)(x) << 50)
+#define KEEP_ALIVE(x) ((u64)(x) << 54)
+#define MSS_IDX(x)    ((u64)(x) << 60)
+       __be64 opt1;
+#define SYN_RSS_ENABLE   (1 << 0)
+#define SYN_RSS_QUEUE(x) ((x) << 2)
+#define CONN_POLICY_ASK  (1 << 22)
+};
+
+struct cpl_pass_open_req6 {
+       WR_HDR;
+       union opcode_tid ot;
+       __be16 local_port;
+       __be16 peer_port;
+       __be64 local_ip_hi;
+       __be64 local_ip_lo;
+       __be64 peer_ip_hi;
+       __be64 peer_ip_lo;
+       __be64 opt0;
+       __be64 opt1;
+};
+
+struct cpl_pass_open_rpl {
+       union opcode_tid ot;
+       u8 rsvd[3];
+       u8 status;
+};
+
+struct cpl_pass_accept_rpl {
+       WR_HDR;
+       union opcode_tid ot;
+       __be32 opt2;
+#define RSS_QUEUE(x)         ((x) << 0)
+#define RSS_QUEUE_VALID      (1 << 10)
+#define RX_COALESCE_VALID(x) ((x) << 11)
+#define RX_COALESCE(x)       ((x) << 12)
+#define TX_QUEUE(x)          ((x) << 23)
+#define RX_CHANNEL(x)        ((x) << 26)
+#define WND_SCALE_EN(x)      ((x) << 28)
+#define TSTAMPS_EN(x)        ((x) << 29)
+#define SACK_EN(x)           ((x) << 30)
+       __be64 opt0;
+};
+
+struct cpl_act_open_req {
+       WR_HDR;
+       union opcode_tid ot;
+       __be16 local_port;
+       __be16 peer_port;
+       __be32 local_ip;
+       __be32 peer_ip;
+       __be64 opt0;
+       __be32 params;
+       __be32 opt2;
+};
+
+struct cpl_act_open_req6 {
+       WR_HDR;
+       union opcode_tid ot;
+       __be16 local_port;
+       __be16 peer_port;
+       __be64 local_ip_hi;
+       __be64 local_ip_lo;
+       __be64 peer_ip_hi;
+       __be64 peer_ip_lo;
+       __be64 opt0;
+       __be32 params;
+       __be32 opt2;
+};
+
+struct cpl_act_open_rpl {
+       union opcode_tid ot;
+       __be32 atid_status;
+#define GET_AOPEN_STATUS(x) ((x) & 0xff)
+#define GET_AOPEN_ATID(x)   (((x) >> 8) & 0xffffff)
+};
+
+struct cpl_pass_establish {
+       union opcode_tid ot;
+       __be32 rsvd;
+       __be32 tos_stid;
+#define GET_POPEN_TID(x) ((x) & 0xffffff)
+#define GET_POPEN_TOS(x) (((x) >> 24) & 0xff)
+       __be16 mac_idx;
+       __be16 tcp_opt;
+#define GET_TCPOPT_WSCALE_OK(x)  (((x) >> 5) & 1)
+#define GET_TCPOPT_SACK(x)       (((x) >> 6) & 1)
+#define GET_TCPOPT_TSTAMP(x)     (((x) >> 7) & 1)
+#define GET_TCPOPT_SND_WSCALE(x) (((x) >> 8) & 0xf)
+#define GET_TCPOPT_MSS(x)        (((x) >> 12) & 0xf)
+       __be32 snd_isn;
+       __be32 rcv_isn;
+};
+
+struct cpl_act_establish {
+       union opcode_tid ot;
+       __be32 rsvd;
+       __be32 tos_atid;
+       __be16 mac_idx;
+       __be16 tcp_opt;
+       __be32 snd_isn;
+       __be32 rcv_isn;
+};
+
+struct cpl_get_tcb {
+       WR_HDR;
+       union opcode_tid ot;
+       __be16 reply_ctrl;
+#define QUEUENO(x)    ((x) << 0)
+#define REPLY_CHAN(x) ((x) << 14)
+#define NO_REPLY(x)   ((x) << 15)
+       __be16 cookie;
+};
+
+struct cpl_set_tcb_field {
+       WR_HDR;
+       union opcode_tid ot;
+       __be16 reply_ctrl;
+       __be16 word_cookie;
+#define TCB_WORD(x)   ((x) << 0)
+#define TCB_COOKIE(x) ((x) << 5)
+       __be64 mask;
+       __be64 val;
+};
+
+struct cpl_set_tcb_rpl {
+       union opcode_tid ot;
+       __be16 rsvd;
+       u8 cookie;
+       u8 status;
+       __be64 oldval;
+};
+
+struct cpl_close_con_req {
+       WR_HDR;
+       union opcode_tid ot;
+       __be32 rsvd;
+};
+
+struct cpl_close_con_rpl {
+       union opcode_tid ot;
+       u8 rsvd[3];
+       u8 status;
+       __be32 snd_nxt;
+       __be32 rcv_nxt;
+};
+
+struct cpl_close_listsvr_req {
+       WR_HDR;
+       union opcode_tid ot;
+       __be16 reply_ctrl;
+#define LISTSVR_IPV6 (1 << 14)
+       __be16 rsvd;
+};
+
+struct cpl_close_listsvr_rpl {
+       union opcode_tid ot;
+       u8 rsvd[3];
+       u8 status;
+};
+
+struct cpl_abort_req_rss {
+       union opcode_tid ot;
+       u8 rsvd[3];
+       u8 status;
+};
+
+struct cpl_abort_req {
+       WR_HDR;
+       union opcode_tid ot;
+       __be32 rsvd0;
+       u8 rsvd1;
+       u8 cmd;
+       u8 rsvd2[6];
+};
+
+struct cpl_abort_rpl_rss {
+       union opcode_tid ot;
+       u8 rsvd[3];
+       u8 status;
+};
+
+struct cpl_abort_rpl {
+       WR_HDR;
+       union opcode_tid ot;
+       __be32 rsvd0;
+       u8 rsvd1;
+       u8 cmd;
+       u8 rsvd2[6];
+};
+
+struct cpl_peer_close {
+       union opcode_tid ot;
+       __be32 rcv_nxt;
+};
+
+struct cpl_tid_release {
+       WR_HDR;
+       union opcode_tid ot;
+       __be32 rsvd;
+};
+
+struct cpl_tx_pkt_core {
+       __be32 ctrl0;
+#define TXPKT_VF(x)        ((x) << 0)
+#define TXPKT_PF(x)        ((x) << 8)
+#define TXPKT_VF_VLD       (1 << 11)
+#define TXPKT_OVLAN_IDX(x) ((x) << 12)
+#define TXPKT_INTF(x)      ((x) << 16)
+#define TXPKT_INS_OVLAN    (1 << 21)
+#define TXPKT_OPCODE(x)    ((x) << 24)
+       __be16 pack;
+       __be16 len;
+       __be64 ctrl1;
+#define TXPKT_CSUM_END(x)   ((x) << 12)
+#define TXPKT_CSUM_START(x) ((x) << 20)
+#define TXPKT_IPHDR_LEN(x)  ((u64)(x) << 20)
+#define TXPKT_CSUM_LOC(x)   ((u64)(x) << 30)
+#define TXPKT_ETHHDR_LEN(x) ((u64)(x) << 34)
+#define TXPKT_CSUM_TYPE(x)  ((u64)(x) << 40)
+#define TXPKT_VLAN(x)       ((u64)(x) << 44)
+#define TXPKT_VLAN_VLD      (1ULL << 60)
+#define TXPKT_IPCSUM_DIS    (1ULL << 62)
+#define TXPKT_L4CSUM_DIS    (1ULL << 63)
+};
+
+struct cpl_tx_pkt {
+       WR_HDR;
+       struct cpl_tx_pkt_core c;
+};
+
+#define cpl_tx_pkt_xt cpl_tx_pkt
+
+struct cpl_tx_pkt_lso {
+       WR_HDR;
+       __be32 lso_ctrl;
+#define LSO_TCPHDR_LEN(x) ((x) << 0)
+#define LSO_IPHDR_LEN(x)  ((x) << 4)
+#define LSO_ETHHDR_LEN(x) ((x) << 16)
+#define LSO_IPV6(x)       ((x) << 20)
+#define LSO_LAST_SLICE    (1 << 22)
+#define LSO_FIRST_SLICE   (1 << 23)
+#define LSO_OPCODE(x)     ((x) << 24)
+       __be16 ipid_ofst;
+       __be16 mss;
+       __be32 seqno_offset;
+       __be32 len;
+       /* encapsulated CPL (TX_PKT, TX_PKT_XT or TX_DATA) follows here */
+};
+
+struct cpl_iscsi_hdr {
+       union opcode_tid ot;
+       __be16 pdu_len_ddp;
+#define ISCSI_PDU_LEN(x) ((x) & 0x7FFF)
+#define ISCSI_DDP        (1 << 15)
+       __be16 len;
+       __be32 seq;
+       __be16 urg;
+       u8 rsvd;
+       u8 status;
+};
+
+struct cpl_rx_data {
+       union opcode_tid ot;
+       __be16 rsvd;
+       __be16 len;
+       __be32 seq;
+       __be16 urg;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+       u8 dack_mode:2;
+       u8 psh:1;
+       u8 heartbeat:1;
+       u8 ddp_off:1;
+       u8 :3;
+#else
+       u8 :3;
+       u8 ddp_off:1;
+       u8 heartbeat:1;
+       u8 psh:1;
+       u8 dack_mode:2;
+#endif
+       u8 status;
+};
+
+struct cpl_rx_data_ack {
+       WR_HDR;
+       union opcode_tid ot;
+       __be32 credit_dack;
+#define RX_CREDITS(x)   ((x) << 0)
+#define RX_FORCE_ACK(x) ((x) << 28)
+};
+
+struct cpl_rx_pkt {
+       u8 opcode;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+       u8 iff:4;
+       u8 csum_calc:1;
+       u8 ipmi_pkt:1;
+       u8 vlan_ex:1;
+       u8 ip_frag:1;
+#else
+       u8 ip_frag:1;
+       u8 vlan_ex:1;
+       u8 ipmi_pkt:1;
+       u8 csum_calc:1;
+       u8 iff:4;
+#endif
+       __be16 csum;
+       __be16 vlan;
+       __be16 len;
+       __be32 l2info;
+#define RXF_UDP (1 << 22)
+#define RXF_TCP (1 << 23)
+       __be16 hdr_len;
+       __be16 err_vec;
+};
+
+struct cpl_trace_pkt {
+       u8 opcode;
+       u8 intf;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+       u8 runt:4;
+       u8 filter_hit:4;
+       u8 :6;
+       u8 err:1;
+       u8 trunc:1;
+#else
+       u8 filter_hit:4;
+       u8 runt:4;
+       u8 trunc:1;
+       u8 err:1;
+       u8 :6;
+#endif
+       __be16 rsvd;
+       __be16 len;
+       __be64 tstamp;
+};
+
+struct cpl_l2t_write_req {
+       WR_HDR;
+       union opcode_tid ot;
+       __be16 params;
+#define L2T_W_INFO(x)    ((x) << 2)
+#define L2T_W_PORT(x)    ((x) << 8)
+#define L2T_W_NOREPLY(x) ((x) << 15)
+       __be16 l2t_idx;
+       __be16 vlan;
+       u8 dst_mac[6];
+};
+
+struct cpl_l2t_write_rpl {
+       union opcode_tid ot;
+       u8 status;
+       u8 rsvd[3];
+};
+
+struct cpl_rdma_terminate {
+       union opcode_tid ot;
+       __be16 rsvd;
+       __be16 len;
+};
+
+struct cpl_sge_egr_update {
+       __be32 opcode_qid;
+#define EGR_QID(x) ((x) & 0x1FFFF)
+       __be16 cidx;
+       __be16 pidx;
+};
+
+struct cpl_fw4_pld {
+       u8 opcode;
+       u8 rsvd0[3];
+       u8 type;
+       u8 rsvd1;
+       __be16 len;
+       __be64 data;
+       __be64 rsvd2;
+};
+
+struct cpl_fw6_pld {
+       u8 opcode;
+       u8 rsvd[5];
+       __be16 len;
+       __be64 data[4];
+};
+
+struct cpl_fw4_msg {
+       u8 opcode;
+       u8 type;
+       __be16 rsvd0;
+       __be32 rsvd1;
+       __be64 data[2];
+};
+
+struct cpl_fw4_ack {
+       union opcode_tid ot;
+       u8 credits;
+       u8 rsvd0[2];
+       u8 seq_vld;
+       __be32 snd_nxt;
+       __be32 snd_una;
+       __be64 rsvd1;
+};
+
+struct cpl_fw6_msg {
+       u8 opcode;
+       u8 type;
+       __be16 rsvd0;
+       __be32 rsvd1;
+       __be64 data[4];
+};
+
+enum {
+       ULP_TX_MEM_READ = 2,
+       ULP_TX_MEM_WRITE = 3,
+       ULP_TX_PKT = 4
+};
+
+enum {
+       ULP_TX_SC_NOOP = 0x80,
+       ULP_TX_SC_IMM  = 0x81,
+       ULP_TX_SC_DSGL = 0x82,
+       ULP_TX_SC_ISGL = 0x83
+};
+
+struct ulptx_sge_pair {
+       __be32 len[2];
+       __be64 addr[2];
+};
+
+struct ulptx_sgl {
+       __be32 cmd_nsge;
+#define ULPTX_CMD(x) ((x) << 24)
+#define ULPTX_NSGE(x) ((x) << 0)
+       __be32 len0;
+       __be64 addr0;
+       struct ulptx_sge_pair sge[0];
+};
+
+struct ulp_mem_io {
+       WR_HDR;
+       __be32 cmd;
+#define ULP_MEMIO_ORDER(x) ((x) << 23)
+       __be32 len16;             /* command length */
+       __be32 dlen;              /* data length in 32-byte units */
+#define ULP_MEMIO_DATA_LEN(x) ((x) << 0)
+       __be32 lock_addr;
+#define ULP_MEMIO_ADDR(x) ((x) << 0)
+#define ULP_MEMIO_LOCK(x) ((x) << 31)
+};
+
+#endif  /* __T4_MSG_H */
diff --git a/drivers/net/cxgb4/t4_regs.h b/drivers/net/cxgb4/t4_regs.h
new file mode 100644 (file)
index 0000000..5ed5648
--- /dev/null
@@ -0,0 +1,878 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ */
+
+#ifndef __T4_REGS_H
+#define __T4_REGS_H
+
+#define MYPF_BASE 0x1b000
+#define MYPF_REG(reg_addr) (MYPF_BASE + (reg_addr))
+
+#define PF0_BASE 0x1e000
+#define PF0_REG(reg_addr) (PF0_BASE + (reg_addr))
+
+#define PF_STRIDE 0x400
+#define PF_BASE(idx) (PF0_BASE + (idx) * PF_STRIDE)
+#define PF_REG(idx, reg) (PF_BASE(idx) + (reg))
+
+#define MYPORT_BASE 0x1c000
+#define MYPORT_REG(reg_addr) (MYPORT_BASE + (reg_addr))
+
+#define PORT0_BASE 0x20000
+#define PORT0_REG(reg_addr) (PORT0_BASE + (reg_addr))
+
+#define PORT_STRIDE 0x2000
+#define PORT_BASE(idx) (PORT0_BASE + (idx) * PORT_STRIDE)
+#define PORT_REG(idx, reg) (PORT_BASE(idx) + (reg))
+
+#define EDC_STRIDE (EDC_1_BASE_ADDR - EDC_0_BASE_ADDR)
+#define EDC_REG(reg, idx) (reg + EDC_STRIDE * idx)
+
+#define PCIE_MEM_ACCESS_REG(reg_addr, idx) ((reg_addr) + (idx) * 8)
+#define PCIE_MAILBOX_REG(reg_addr, idx) ((reg_addr) + (idx) * 8)
+#define MC_BIST_STATUS_REG(reg_addr, idx) ((reg_addr) + (idx) * 4)
+#define EDC_BIST_STATUS_REG(reg_addr, idx) ((reg_addr) + (idx) * 4)
+
+#define SGE_PF_KDOORBELL 0x0
+#define  QID_MASK    0xffff8000U
+#define  QID_SHIFT   15
+#define  QID(x)      ((x) << QID_SHIFT)
+#define  DBPRIO      0x00004000U
+#define  PIDX_MASK   0x00003fffU
+#define  PIDX_SHIFT  0
+#define  PIDX(x)     ((x) << PIDX_SHIFT)
+
+#define SGE_PF_GTS 0x4
+#define  INGRESSQID_MASK   0xffff0000U
+#define  INGRESSQID_SHIFT  16
+#define  INGRESSQID(x)     ((x) << INGRESSQID_SHIFT)
+#define  TIMERREG_MASK     0x0000e000U
+#define  TIMERREG_SHIFT    13
+#define  TIMERREG(x)       ((x) << TIMERREG_SHIFT)
+#define  SEINTARM_MASK     0x00001000U
+#define  SEINTARM_SHIFT    12
+#define  SEINTARM(x)       ((x) << SEINTARM_SHIFT)
+#define  CIDXINC_MASK      0x00000fffU
+#define  CIDXINC_SHIFT     0
+#define  CIDXINC(x)        ((x) << CIDXINC_SHIFT)
+
+#define SGE_CONTROL 0x1008
+#define  DCASYSTYPE             0x00080000U
+#define  RXPKTCPLMODE           0x00040000U
+#define  EGRSTATUSPAGESIZE      0x00020000U
+#define  PKTSHIFT_MASK          0x00001c00U
+#define  PKTSHIFT_SHIFT         10
+#define  PKTSHIFT(x)            ((x) << PKTSHIFT_SHIFT)
+#define  INGPCIEBOUNDARY_MASK   0x00000380U
+#define  INGPCIEBOUNDARY_SHIFT  7
+#define  INGPCIEBOUNDARY(x)     ((x) << INGPCIEBOUNDARY_SHIFT)
+#define  INGPADBOUNDARY_MASK    0x00000070U
+#define  INGPADBOUNDARY_SHIFT   4
+#define  INGPADBOUNDARY(x)      ((x) << INGPADBOUNDARY_SHIFT)
+#define  EGRPCIEBOUNDARY_MASK   0x0000000eU
+#define  EGRPCIEBOUNDARY_SHIFT  1
+#define  EGRPCIEBOUNDARY(x)     ((x) << EGRPCIEBOUNDARY_SHIFT)
+#define  GLOBALENABLE           0x00000001U
+
+#define SGE_HOST_PAGE_SIZE 0x100c
+#define  HOSTPAGESIZEPF0_MASK   0x0000000fU
+#define  HOSTPAGESIZEPF0_SHIFT  0
+#define  HOSTPAGESIZEPF0(x)     ((x) << HOSTPAGESIZEPF0_SHIFT)
+
+#define SGE_EGRESS_QUEUES_PER_PAGE_PF 0x1010
+#define  QUEUESPERPAGEPF0_MASK   0x0000000fU
+#define  QUEUESPERPAGEPF0_GET(x) ((x) & QUEUESPERPAGEPF0_MASK)
+
+#define SGE_INT_CAUSE1 0x1024
+#define SGE_INT_CAUSE2 0x1030
+#define SGE_INT_CAUSE3 0x103c
+#define  ERR_FLM_DBP               0x80000000U
+#define  ERR_FLM_IDMA1             0x40000000U
+#define  ERR_FLM_IDMA0             0x20000000U
+#define  ERR_FLM_HINT              0x10000000U
+#define  ERR_PCIE_ERROR3           0x08000000U
+#define  ERR_PCIE_ERROR2           0x04000000U
+#define  ERR_PCIE_ERROR1           0x02000000U
+#define  ERR_PCIE_ERROR0           0x01000000U
+#define  ERR_TIMER_ABOVE_MAX_QID   0x00800000U
+#define  ERR_CPL_EXCEED_IQE_SIZE   0x00400000U
+#define  ERR_INVALID_CIDX_INC      0x00200000U
+#define  ERR_ITP_TIME_PAUSED       0x00100000U
+#define  ERR_CPL_OPCODE_0          0x00080000U
+#define  ERR_DROPPED_DB            0x00040000U
+#define  ERR_DATA_CPL_ON_HIGH_QID1 0x00020000U
+#define  ERR_DATA_CPL_ON_HIGH_QID0 0x00010000U
+#define  ERR_BAD_DB_PIDX3          0x00008000U
+#define  ERR_BAD_DB_PIDX2          0x00004000U
+#define  ERR_BAD_DB_PIDX1          0x00002000U
+#define  ERR_BAD_DB_PIDX0          0x00001000U
+#define  ERR_ING_PCIE_CHAN         0x00000800U
+#define  ERR_ING_CTXT_PRIO         0x00000400U
+#define  ERR_EGR_CTXT_PRIO         0x00000200U
+#define  DBFIFO_HP_INT             0x00000100U
+#define  DBFIFO_LP_INT             0x00000080U
+#define  REG_ADDRESS_ERR           0x00000040U
+#define  INGRESS_SIZE_ERR          0x00000020U
+#define  EGRESS_SIZE_ERR           0x00000010U
+#define  ERR_INV_CTXT3             0x00000008U
+#define  ERR_INV_CTXT2             0x00000004U
+#define  ERR_INV_CTXT1             0x00000002U
+#define  ERR_INV_CTXT0             0x00000001U
+
+#define SGE_INT_ENABLE3 0x1040
+#define SGE_FL_BUFFER_SIZE0 0x1044
+#define SGE_FL_BUFFER_SIZE1 0x1048
+#define SGE_INGRESS_RX_THRESHOLD 0x10a0
+#define  THRESHOLD_0_MASK   0x3f000000U
+#define  THRESHOLD_0_SHIFT  24
+#define  THRESHOLD_0(x)     ((x) << THRESHOLD_0_SHIFT)
+#define  THRESHOLD_0_GET(x) (((x) & THRESHOLD_0_MASK) >> THRESHOLD_0_SHIFT)
+#define  THRESHOLD_1_MASK   0x003f0000U
+#define  THRESHOLD_1_SHIFT  16
+#define  THRESHOLD_1(x)     ((x) << THRESHOLD_1_SHIFT)
+#define  THRESHOLD_1_GET(x) (((x) & THRESHOLD_1_MASK) >> THRESHOLD_1_SHIFT)
+#define  THRESHOLD_2_MASK   0x00003f00U
+#define  THRESHOLD_2_SHIFT  8
+#define  THRESHOLD_2(x)     ((x) << THRESHOLD_2_SHIFT)
+#define  THRESHOLD_2_GET(x) (((x) & THRESHOLD_2_MASK) >> THRESHOLD_2_SHIFT)
+#define  THRESHOLD_3_MASK   0x0000003fU
+#define  THRESHOLD_3_SHIFT  0
+#define  THRESHOLD_3(x)     ((x) << THRESHOLD_3_SHIFT)
+#define  THRESHOLD_3_GET(x) (((x) & THRESHOLD_3_MASK) >> THRESHOLD_3_SHIFT)
+
+#define SGE_TIMER_VALUE_0_AND_1 0x10b8
+#define  TIMERVALUE0_MASK   0xffff0000U
+#define  TIMERVALUE0_SHIFT  16
+#define  TIMERVALUE0(x)     ((x) << TIMERVALUE0_SHIFT)
+#define  TIMERVALUE0_GET(x) (((x) & TIMERVALUE0_MASK) >> TIMERVALUE0_SHIFT)
+#define  TIMERVALUE1_MASK   0x0000ffffU
+#define  TIMERVALUE1_SHIFT  0
+#define  TIMERVALUE1(x)     ((x) << TIMERVALUE1_SHIFT)
+#define  TIMERVALUE1_GET(x) (((x) & TIMERVALUE1_MASK) >> TIMERVALUE1_SHIFT)
+
+#define SGE_TIMER_VALUE_2_AND_3 0x10bc
+#define SGE_TIMER_VALUE_4_AND_5 0x10c0
+#define SGE_DEBUG_INDEX 0x10cc
+#define SGE_DEBUG_DATA_HIGH 0x10d0
+#define SGE_DEBUG_DATA_LOW 0x10d4
+#define SGE_INGRESS_QUEUES_PER_PAGE_PF 0x10f4
+
+#define PCIE_PF_CLI 0x44
+#define PCIE_INT_CAUSE 0x3004
+#define  UNXSPLCPLERR  0x20000000U
+#define  PCIEPINT      0x10000000U
+#define  PCIESINT      0x08000000U
+#define  RPLPERR       0x04000000U
+#define  RXWRPERR      0x02000000U
+#define  RXCPLPERR     0x01000000U
+#define  PIOTAGPERR    0x00800000U
+#define  MATAGPERR     0x00400000U
+#define  INTXCLRPERR   0x00200000U
+#define  FIDPERR       0x00100000U
+#define  CFGSNPPERR    0x00080000U
+#define  HRSPPERR      0x00040000U
+#define  HREQPERR      0x00020000U
+#define  HCNTPERR      0x00010000U
+#define  DRSPPERR      0x00008000U
+#define  DREQPERR      0x00004000U
+#define  DCNTPERR      0x00002000U
+#define  CRSPPERR      0x00001000U
+#define  CREQPERR      0x00000800U
+#define  CCNTPERR      0x00000400U
+#define  TARTAGPERR    0x00000200U
+#define  PIOREQPERR    0x00000100U
+#define  PIOCPLPERR    0x00000080U
+#define  MSIXDIPERR    0x00000040U
+#define  MSIXDATAPERR  0x00000020U
+#define  MSIXADDRHPERR 0x00000010U
+#define  MSIXADDRLPERR 0x00000008U
+#define  MSIDATAPERR   0x00000004U
+#define  MSIADDRHPERR  0x00000002U
+#define  MSIADDRLPERR  0x00000001U
+
+#define PCIE_NONFAT_ERR 0x3010
+#define PCIE_MEM_ACCESS_BASE_WIN 0x3068
+#define  PCIEOFST_MASK   0xfffffc00U
+#define  BIR_MASK        0x00000300U
+#define  BIR_SHIFT       8
+#define  BIR(x)          ((x) << BIR_SHIFT)
+#define  WINDOW_MASK     0x000000ffU
+#define  WINDOW_SHIFT    0
+#define  WINDOW(x)       ((x) << WINDOW_SHIFT)
+
+#define PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS 0x5908
+#define  RNPP 0x80000000U
+#define  RPCP 0x20000000U
+#define  RCIP 0x08000000U
+#define  RCCP 0x04000000U
+#define  RFTP 0x00800000U
+#define  PTRP 0x00100000U
+
+#define PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS 0x59a4
+#define  TPCP 0x40000000U
+#define  TNPP 0x20000000U
+#define  TFTP 0x10000000U
+#define  TCAP 0x08000000U
+#define  TCIP 0x04000000U
+#define  RCAP 0x02000000U
+#define  PLUP 0x00800000U
+#define  PLDN 0x00400000U
+#define  OTDD 0x00200000U
+#define  GTRP 0x00100000U
+#define  RDPE 0x00040000U
+#define  TDCE 0x00020000U
+#define  TDUE 0x00010000U
+
+#define MC_INT_CAUSE 0x7518
+#define  ECC_UE_INT_CAUSE 0x00000004U
+#define  ECC_CE_INT_CAUSE 0x00000002U
+#define  PERR_INT_CAUSE   0x00000001U
+
+#define MC_ECC_STATUS 0x751c
+#define  ECC_CECNT_MASK   0xffff0000U
+#define  ECC_CECNT_SHIFT  16
+#define  ECC_CECNT(x)     ((x) << ECC_CECNT_SHIFT)
+#define  ECC_CECNT_GET(x) (((x) & ECC_CECNT_MASK) >> ECC_CECNT_SHIFT)
+#define  ECC_UECNT_MASK   0x0000ffffU
+#define  ECC_UECNT_SHIFT  0
+#define  ECC_UECNT(x)     ((x) << ECC_UECNT_SHIFT)
+#define  ECC_UECNT_GET(x) (((x) & ECC_UECNT_MASK) >> ECC_UECNT_SHIFT)
+
+#define MC_BIST_CMD 0x7600
+#define  START_BIST          0x80000000U
+#define  BIST_CMD_GAP_MASK   0x0000ff00U
+#define  BIST_CMD_GAP_SHIFT  8
+#define  BIST_CMD_GAP(x)     ((x) << BIST_CMD_GAP_SHIFT)
+#define  BIST_OPCODE_MASK    0x00000003U
+#define  BIST_OPCODE_SHIFT   0
+#define  BIST_OPCODE(x)      ((x) << BIST_OPCODE_SHIFT)
+
+#define MC_BIST_CMD_ADDR 0x7604
+#define MC_BIST_CMD_LEN 0x7608
+#define MC_BIST_DATA_PATTERN 0x760c
+#define  BIST_DATA_TYPE_MASK   0x0000000fU
+#define  BIST_DATA_TYPE_SHIFT  0
+#define  BIST_DATA_TYPE(x)     ((x) << BIST_DATA_TYPE_SHIFT)
+
+#define MC_BIST_STATUS_RDATA 0x7688
+
+#define MA_EXT_MEMORY_BAR 0x77c8
+#define  EXT_MEM_SIZE_MASK   0x00000fffU
+#define  EXT_MEM_SIZE_SHIFT  0
+#define  EXT_MEM_SIZE_GET(x) (((x) & EXT_MEM_SIZE_MASK) >> EXT_MEM_SIZE_SHIFT)
+
+#define MA_TARGET_MEM_ENABLE 0x77d8
+#define  EXT_MEM_ENABLE 0x00000004U
+#define  EDRAM1_ENABLE  0x00000002U
+#define  EDRAM0_ENABLE  0x00000001U
+
+#define MA_INT_CAUSE 0x77e0
+#define  MEM_PERR_INT_CAUSE 0x00000002U
+#define  MEM_WRAP_INT_CAUSE 0x00000001U
+
+#define MA_INT_WRAP_STATUS 0x77e4
+#define  MEM_WRAP_ADDRESS_MASK   0xfffffff0U
+#define  MEM_WRAP_ADDRESS_SHIFT  4
+#define  MEM_WRAP_ADDRESS_GET(x) (((x) & MEM_WRAP_ADDRESS_MASK) >> MEM_WRAP_ADDRESS_SHIFT)
+#define  MEM_WRAP_CLIENT_NUM_MASK   0x0000000fU
+#define  MEM_WRAP_CLIENT_NUM_SHIFT  0
+#define  MEM_WRAP_CLIENT_NUM_GET(x) (((x) & MEM_WRAP_CLIENT_NUM_MASK) >> MEM_WRAP_CLIENT_NUM_SHIFT)
+
+#define MA_PARITY_ERROR_STATUS 0x77f4
+
+#define EDC_0_BASE_ADDR 0x7900
+
+#define EDC_BIST_CMD 0x7904
+#define EDC_BIST_CMD_ADDR 0x7908
+#define EDC_BIST_CMD_LEN 0x790c
+#define EDC_BIST_DATA_PATTERN 0x7910
+#define EDC_BIST_STATUS_RDATA 0x7928
+#define EDC_INT_CAUSE 0x7978
+#define  ECC_UE_PAR     0x00000020U
+#define  ECC_CE_PAR     0x00000010U
+#define  PERR_PAR_CAUSE 0x00000008U
+
+#define EDC_ECC_STATUS 0x797c
+
+#define EDC_1_BASE_ADDR 0x7980
+
+#define CIM_PF_MAILBOX_DATA 0x240
+#define CIM_PF_MAILBOX_CTRL 0x280
+#define  MBMSGVALID     0x00000008U
+#define  MBINTREQ       0x00000004U
+#define  MBOWNER_MASK   0x00000003U
+#define  MBOWNER_SHIFT  0
+#define  MBOWNER(x)     ((x) << MBOWNER_SHIFT)
+#define  MBOWNER_GET(x) (((x) & MBOWNER_MASK) >> MBOWNER_SHIFT)
+
+#define CIM_PF_HOST_INT_CAUSE 0x28c
+#define  MBMSGRDYINT 0x00080000U
+
+#define CIM_HOST_INT_CAUSE 0x7b2c
+#define  TIEQOUTPARERRINT  0x00100000U
+#define  TIEQINPARERRINT   0x00080000U
+#define  MBHOSTPARERR      0x00040000U
+#define  MBUPPARERR        0x00020000U
+#define  IBQPARERR         0x0001f800U
+#define  IBQTP0PARERR      0x00010000U
+#define  IBQTP1PARERR      0x00008000U
+#define  IBQULPPARERR      0x00004000U
+#define  IBQSGELOPARERR    0x00002000U
+#define  IBQSGEHIPARERR    0x00001000U
+#define  IBQNCSIPARERR     0x00000800U
+#define  OBQPARERR         0x000007e0U
+#define  OBQULP0PARERR     0x00000400U
+#define  OBQULP1PARERR     0x00000200U
+#define  OBQULP2PARERR     0x00000100U
+#define  OBQULP3PARERR     0x00000080U
+#define  OBQSGEPARERR      0x00000040U
+#define  OBQNCSIPARERR     0x00000020U
+#define  PREFDROPINT       0x00000002U
+#define  UPACCNONZERO      0x00000001U
+
+#define CIM_HOST_UPACC_INT_CAUSE 0x7b34
+#define  EEPROMWRINT      0x40000000U
+#define  TIMEOUTMAINT     0x20000000U
+#define  TIMEOUTINT       0x10000000U
+#define  RSPOVRLOOKUPINT  0x08000000U
+#define  REQOVRLOOKUPINT  0x04000000U
+#define  BLKWRPLINT       0x02000000U
+#define  BLKRDPLINT       0x01000000U
+#define  SGLWRPLINT       0x00800000U
+#define  SGLRDPLINT       0x00400000U
+#define  BLKWRCTLINT      0x00200000U
+#define  BLKRDCTLINT      0x00100000U
+#define  SGLWRCTLINT      0x00080000U
+#define  SGLRDCTLINT      0x00040000U
+#define  BLKWREEPROMINT   0x00020000U
+#define  BLKRDEEPROMINT   0x00010000U
+#define  SGLWREEPROMINT   0x00008000U
+#define  SGLRDEEPROMINT   0x00004000U
+#define  BLKWRFLASHINT    0x00002000U
+#define  BLKRDFLASHINT    0x00001000U
+#define  SGLWRFLASHINT    0x00000800U
+#define  SGLRDFLASHINT    0x00000400U
+#define  BLKWRBOOTINT     0x00000200U
+#define  BLKRDBOOTINT     0x00000100U
+#define  SGLWRBOOTINT     0x00000080U
+#define  SGLRDBOOTINT     0x00000040U
+#define  ILLWRBEINT       0x00000020U
+#define  ILLRDBEINT       0x00000010U
+#define  ILLRDINT         0x00000008U
+#define  ILLWRINT         0x00000004U
+#define  ILLTRANSINT      0x00000002U
+#define  RSVDSPACEINT     0x00000001U
+
+#define TP_OUT_CONFIG 0x7d04
+#define  VLANEXTENABLE_MASK  0x0000f000U
+#define  VLANEXTENABLE_SHIFT 12
+
+#define TP_PARA_REG2 0x7d68
+#define  MAXRXDATA_MASK    0xffff0000U
+#define  MAXRXDATA_SHIFT   16
+#define  MAXRXDATA_GET(x) (((x) & MAXRXDATA_MASK) >> MAXRXDATA_SHIFT)
+
+#define TP_TIMER_RESOLUTION 0x7d90
+#define  TIMERRESOLUTION_MASK   0x00ff0000U
+#define  TIMERRESOLUTION_SHIFT  16
+#define  TIMERRESOLUTION_GET(x) (((x) & TIMERRESOLUTION_MASK) >> TIMERRESOLUTION_SHIFT)
+
+#define TP_SHIFT_CNT 0x7dc0
+
+#define TP_CCTRL_TABLE 0x7ddc
+#define TP_MTU_TABLE 0x7de4
+#define  MTUINDEX_MASK   0xff000000U
+#define  MTUINDEX_SHIFT  24
+#define  MTUINDEX(x)     ((x) << MTUINDEX_SHIFT)
+#define  MTUWIDTH_MASK   0x000f0000U
+#define  MTUWIDTH_SHIFT  16
+#define  MTUWIDTH(x)     ((x) << MTUWIDTH_SHIFT)
+#define  MTUWIDTH_GET(x) (((x) & MTUWIDTH_MASK) >> MTUWIDTH_SHIFT)
+#define  MTUVALUE_MASK   0x00003fffU
+#define  MTUVALUE_SHIFT  0
+#define  MTUVALUE(x)     ((x) << MTUVALUE_SHIFT)
+#define  MTUVALUE_GET(x) (((x) & MTUVALUE_MASK) >> MTUVALUE_SHIFT)
+
+#define TP_RSS_LKP_TABLE 0x7dec
+#define  LKPTBLROWVLD        0x80000000U
+#define  LKPTBLQUEUE1_MASK   0x000ffc00U
+#define  LKPTBLQUEUE1_SHIFT  10
+#define  LKPTBLQUEUE1(x)     ((x) << LKPTBLQUEUE1_SHIFT)
+#define  LKPTBLQUEUE1_GET(x) (((x) & LKPTBLQUEUE1_MASK) >> LKPTBLQUEUE1_SHIFT)
+#define  LKPTBLQUEUE0_MASK   0x000003ffU
+#define  LKPTBLQUEUE0_SHIFT  0
+#define  LKPTBLQUEUE0(x)     ((x) << LKPTBLQUEUE0_SHIFT)
+#define  LKPTBLQUEUE0_GET(x) (((x) & LKPTBLQUEUE0_MASK) >> LKPTBLQUEUE0_SHIFT)
+
+#define TP_PIO_ADDR 0x7e40
+#define TP_PIO_DATA 0x7e44
+#define TP_MIB_INDEX 0x7e50
+#define TP_MIB_DATA 0x7e54
+#define TP_INT_CAUSE 0x7e74
+#define  FLMTXFLSTEMPTY 0x40000000U
+
+#define TP_INGRESS_CONFIG 0x141
+#define  VNIC                0x00000800U
+#define  CSUM_HAS_PSEUDO_HDR 0x00000400U
+#define  RM_OVLAN            0x00000200U
+#define  LOOKUPEVERYPKT      0x00000100U
+
+#define TP_MIB_MAC_IN_ERR_0 0x0
+#define TP_MIB_TCP_OUT_RST 0xc
+#define TP_MIB_TCP_IN_SEG_HI 0x10
+#define TP_MIB_TCP_IN_SEG_LO 0x11
+#define TP_MIB_TCP_OUT_SEG_HI 0x12
+#define TP_MIB_TCP_OUT_SEG_LO 0x13
+#define TP_MIB_TCP_RXT_SEG_HI 0x14
+#define TP_MIB_TCP_RXT_SEG_LO 0x15
+#define TP_MIB_TNL_CNG_DROP_0 0x18
+#define TP_MIB_TCP_V6IN_ERR_0 0x28
+#define TP_MIB_TCP_V6OUT_RST 0x2c
+#define TP_MIB_OFD_ARP_DROP 0x36
+#define TP_MIB_TNL_DROP_0 0x44
+#define TP_MIB_OFD_VLN_DROP_0 0x58
+
+#define ULP_TX_INT_CAUSE 0x8dcc
+#define  PBL_BOUND_ERR_CH3 0x80000000U
+#define  PBL_BOUND_ERR_CH2 0x40000000U
+#define  PBL_BOUND_ERR_CH1 0x20000000U
+#define  PBL_BOUND_ERR_CH0 0x10000000U
+
+#define PM_RX_INT_CAUSE 0x8fdc
+#define  ZERO_E_CMD_ERROR     0x00400000U
+#define  PMRX_FRAMING_ERROR   0x003ffff0U
+#define  OCSPI_PAR_ERROR      0x00000008U
+#define  DB_OPTIONS_PAR_ERROR 0x00000004U
+#define  IESPI_PAR_ERROR      0x00000002U
+#define  E_PCMD_PAR_ERROR     0x00000001U
+
+#define PM_TX_INT_CAUSE 0x8ffc
+#define  PCMD_LEN_OVFL0     0x80000000U
+#define  PCMD_LEN_OVFL1     0x40000000U
+#define  PCMD_LEN_OVFL2     0x20000000U
+#define  ZERO_C_CMD_ERROR   0x10000000U
+#define  PMTX_FRAMING_ERROR 0x0ffffff0U
+#define  OESPI_PAR_ERROR    0x00000008U
+#define  ICSPI_PAR_ERROR    0x00000002U
+#define  C_PCMD_PAR_ERROR   0x00000001U
+
+#define MPS_PORT_STAT_TX_PORT_BYTES_L 0x400
+#define MPS_PORT_STAT_TX_PORT_BYTES_H 0x404
+#define MPS_PORT_STAT_TX_PORT_FRAMES_L 0x408
+#define MPS_PORT_STAT_TX_PORT_FRAMES_H 0x40c
+#define MPS_PORT_STAT_TX_PORT_BCAST_L 0x410
+#define MPS_PORT_STAT_TX_PORT_BCAST_H 0x414
+#define MPS_PORT_STAT_TX_PORT_MCAST_L 0x418
+#define MPS_PORT_STAT_TX_PORT_MCAST_H 0x41c
+#define MPS_PORT_STAT_TX_PORT_UCAST_L 0x420
+#define MPS_PORT_STAT_TX_PORT_UCAST_H 0x424
+#define MPS_PORT_STAT_TX_PORT_ERROR_L 0x428
+#define MPS_PORT_STAT_TX_PORT_ERROR_H 0x42c
+#define MPS_PORT_STAT_TX_PORT_64B_L 0x430
+#define MPS_PORT_STAT_TX_PORT_64B_H 0x434
+#define MPS_PORT_STAT_TX_PORT_65B_127B_L 0x438
+#define MPS_PORT_STAT_TX_PORT_65B_127B_H 0x43c
+#define MPS_PORT_STAT_TX_PORT_128B_255B_L 0x440
+#define MPS_PORT_STAT_TX_PORT_128B_255B_H 0x444
+#define MPS_PORT_STAT_TX_PORT_256B_511B_L 0x448
+#define MPS_PORT_STAT_TX_PORT_256B_511B_H 0x44c
+#define MPS_PORT_STAT_TX_PORT_512B_1023B_L 0x450
+#define MPS_PORT_STAT_TX_PORT_512B_1023B_H 0x454
+#define MPS_PORT_STAT_TX_PORT_1024B_1518B_L 0x458
+#define MPS_PORT_STAT_TX_PORT_1024B_1518B_H 0x45c
+#define MPS_PORT_STAT_TX_PORT_1519B_MAX_L 0x460
+#define MPS_PORT_STAT_TX_PORT_1519B_MAX_H 0x464
+#define MPS_PORT_STAT_TX_PORT_DROP_L 0x468
+#define MPS_PORT_STAT_TX_PORT_DROP_H 0x46c
+#define MPS_PORT_STAT_TX_PORT_PAUSE_L 0x470
+#define MPS_PORT_STAT_TX_PORT_PAUSE_H 0x474
+#define MPS_PORT_STAT_TX_PORT_PPP0_L 0x478
+#define MPS_PORT_STAT_TX_PORT_PPP0_H 0x47c
+#define MPS_PORT_STAT_TX_PORT_PPP1_L 0x480
+#define MPS_PORT_STAT_TX_PORT_PPP1_H 0x484
+#define MPS_PORT_STAT_TX_PORT_PPP2_L 0x488
+#define MPS_PORT_STAT_TX_PORT_PPP2_H 0x48c
+#define MPS_PORT_STAT_TX_PORT_PPP3_L 0x490
+#define MPS_PORT_STAT_TX_PORT_PPP3_H 0x494
+#define MPS_PORT_STAT_TX_PORT_PPP4_L 0x498
+#define MPS_PORT_STAT_TX_PORT_PPP4_H 0x49c
+#define MPS_PORT_STAT_TX_PORT_PPP5_L 0x4a0
+#define MPS_PORT_STAT_TX_PORT_PPP5_H 0x4a4
+#define MPS_PORT_STAT_TX_PORT_PPP6_L 0x4a8
+#define MPS_PORT_STAT_TX_PORT_PPP6_H 0x4ac
+#define MPS_PORT_STAT_TX_PORT_PPP7_L 0x4b0
+#define MPS_PORT_STAT_TX_PORT_PPP7_H 0x4b4
+#define MPS_PORT_STAT_LB_PORT_BYTES_L 0x4c0
+#define MPS_PORT_STAT_LB_PORT_BYTES_H 0x4c4
+#define MPS_PORT_STAT_LB_PORT_FRAMES_L 0x4c8
+#define MPS_PORT_STAT_LB_PORT_FRAMES_H 0x4cc
+#define MPS_PORT_STAT_LB_PORT_BCAST_L 0x4d0
+#define MPS_PORT_STAT_LB_PORT_BCAST_H 0x4d4
+#define MPS_PORT_STAT_LB_PORT_MCAST_L 0x4d8
+#define MPS_PORT_STAT_LB_PORT_MCAST_H 0x4dc
+#define MPS_PORT_STAT_LB_PORT_UCAST_L 0x4e0
+#define MPS_PORT_STAT_LB_PORT_UCAST_H 0x4e4
+#define MPS_PORT_STAT_LB_PORT_ERROR_L 0x4e8
+#define MPS_PORT_STAT_LB_PORT_ERROR_H 0x4ec
+#define MPS_PORT_STAT_LB_PORT_64B_L 0x4f0
+#define MPS_PORT_STAT_LB_PORT_64B_H 0x4f4
+#define MPS_PORT_STAT_LB_PORT_65B_127B_L 0x4f8
+#define MPS_PORT_STAT_LB_PORT_65B_127B_H 0x4fc
+#define MPS_PORT_STAT_LB_PORT_128B_255B_L 0x500
+#define MPS_PORT_STAT_LB_PORT_128B_255B_H 0x504
+#define MPS_PORT_STAT_LB_PORT_256B_511B_L 0x508
+#define MPS_PORT_STAT_LB_PORT_256B_511B_H 0x50c
+#define MPS_PORT_STAT_LB_PORT_512B_1023B_L 0x510
+#define MPS_PORT_STAT_LB_PORT_512B_1023B_H 0x514
+#define MPS_PORT_STAT_LB_PORT_1024B_1518B_L 0x518
+#define MPS_PORT_STAT_LB_PORT_1024B_1518B_H 0x51c
+#define MPS_PORT_STAT_LB_PORT_1519B_MAX_L 0x520
+#define MPS_PORT_STAT_LB_PORT_1519B_MAX_H 0x524
+#define MPS_PORT_STAT_LB_PORT_DROP_FRAMES 0x528
+#define MPS_PORT_STAT_RX_PORT_BYTES_L 0x540
+#define MPS_PORT_STAT_RX_PORT_BYTES_H 0x544
+#define MPS_PORT_STAT_RX_PORT_FRAMES_L 0x548
+#define MPS_PORT_STAT_RX_PORT_FRAMES_H 0x54c
+#define MPS_PORT_STAT_RX_PORT_BCAST_L 0x550
+#define MPS_PORT_STAT_RX_PORT_BCAST_H 0x554
+#define MPS_PORT_STAT_RX_PORT_MCAST_L 0x558
+#define MPS_PORT_STAT_RX_PORT_MCAST_H 0x55c
+#define MPS_PORT_STAT_RX_PORT_UCAST_L 0x560
+#define MPS_PORT_STAT_RX_PORT_UCAST_H 0x564
+#define MPS_PORT_STAT_RX_PORT_MTU_ERROR_L 0x568
+#define MPS_PORT_STAT_RX_PORT_MTU_ERROR_H 0x56c
+#define MPS_PORT_STAT_RX_PORT_MTU_CRC_ERROR_L 0x570
+#define MPS_PORT_STAT_RX_PORT_MTU_CRC_ERROR_H 0x574
+#define MPS_PORT_STAT_RX_PORT_CRC_ERROR_L 0x578
+#define MPS_PORT_STAT_RX_PORT_CRC_ERROR_H 0x57c
+#define MPS_PORT_STAT_RX_PORT_LEN_ERROR_L 0x580
+#define MPS_PORT_STAT_RX_PORT_LEN_ERROR_H 0x584
+#define MPS_PORT_STAT_RX_PORT_SYM_ERROR_L 0x588
+#define MPS_PORT_STAT_RX_PORT_SYM_ERROR_H 0x58c
+#define MPS_PORT_STAT_RX_PORT_64B_L 0x590
+#define MPS_PORT_STAT_RX_PORT_64B_H 0x594
+#define MPS_PORT_STAT_RX_PORT_65B_127B_L 0x598
+#define MPS_PORT_STAT_RX_PORT_65B_127B_H 0x59c
+#define MPS_PORT_STAT_RX_PORT_128B_255B_L 0x5a0
+#define MPS_PORT_STAT_RX_PORT_128B_255B_H 0x5a4
+#define MPS_PORT_STAT_RX_PORT_256B_511B_L 0x5a8
+#define MPS_PORT_STAT_RX_PORT_256B_511B_H 0x5ac
+#define MPS_PORT_STAT_RX_PORT_512B_1023B_L 0x5b0
+#define MPS_PORT_STAT_RX_PORT_512B_1023B_H 0x5b4
+#define MPS_PORT_STAT_RX_PORT_1024B_1518B_L 0x5b8
+#define MPS_PORT_STAT_RX_PORT_1024B_1518B_H 0x5bc
+#define MPS_PORT_STAT_RX_PORT_1519B_MAX_L 0x5c0
+#define MPS_PORT_STAT_RX_PORT_1519B_MAX_H 0x5c4
+#define MPS_PORT_STAT_RX_PORT_PAUSE_L 0x5c8
+#define MPS_PORT_STAT_RX_PORT_PAUSE_H 0x5cc
+#define MPS_PORT_STAT_RX_PORT_PPP0_L 0x5d0
+#define MPS_PORT_STAT_RX_PORT_PPP0_H 0x5d4
+#define MPS_PORT_STAT_RX_PORT_PPP1_L 0x5d8
+#define MPS_PORT_STAT_RX_PORT_PPP1_H 0x5dc
+#define MPS_PORT_STAT_RX_PORT_PPP2_L 0x5e0
+#define MPS_PORT_STAT_RX_PORT_PPP2_H 0x5e4
+#define MPS_PORT_STAT_RX_PORT_PPP3_L 0x5e8
+#define MPS_PORT_STAT_RX_PORT_PPP3_H 0x5ec
+#define MPS_PORT_STAT_RX_PORT_PPP4_L 0x5f0
+#define MPS_PORT_STAT_RX_PORT_PPP4_H 0x5f4
+#define MPS_PORT_STAT_RX_PORT_PPP5_L 0x5f8
+#define MPS_PORT_STAT_RX_PORT_PPP5_H 0x5fc
+#define MPS_PORT_STAT_RX_PORT_PPP6_L 0x600
+#define MPS_PORT_STAT_RX_PORT_PPP6_H 0x604
+#define MPS_PORT_STAT_RX_PORT_PPP7_L 0x608
+#define MPS_PORT_STAT_RX_PORT_PPP7_H 0x60c
+#define MPS_PORT_STAT_RX_PORT_LESS_64B_L 0x610
+#define MPS_PORT_STAT_RX_PORT_LESS_64B_H 0x614
+#define MPS_CMN_CTL 0x9000
+#define  NUMPORTS_MASK   0x00000003U
+#define  NUMPORTS_SHIFT  0
+#define  NUMPORTS_GET(x) (((x) & NUMPORTS_MASK) >> NUMPORTS_SHIFT)
+
+#define MPS_INT_CAUSE 0x9008
+#define  STATINT 0x00000020U
+#define  TXINT   0x00000010U
+#define  RXINT   0x00000008U
+#define  TRCINT  0x00000004U
+#define  CLSINT  0x00000002U
+#define  PLINT   0x00000001U
+
+#define MPS_TX_INT_CAUSE 0x9408
+#define  PORTERR    0x00010000U
+#define  FRMERR     0x00008000U
+#define  SECNTERR   0x00004000U
+#define  BUBBLE     0x00002000U
+#define  TXDESCFIFO 0x00001e00U
+#define  TXDATAFIFO 0x000001e0U
+#define  NCSIFIFO   0x00000010U
+#define  TPFIFO     0x0000000fU
+
+#define MPS_STAT_PERR_INT_CAUSE_SRAM 0x9614
+#define MPS_STAT_PERR_INT_CAUSE_TX_FIFO 0x9620
+#define MPS_STAT_PERR_INT_CAUSE_RX_FIFO 0x962c
+
+#define MPS_STAT_RX_BG_0_MAC_DROP_FRAME_L 0x9640
+#define MPS_STAT_RX_BG_0_MAC_DROP_FRAME_H 0x9644
+#define MPS_STAT_RX_BG_1_MAC_DROP_FRAME_L 0x9648
+#define MPS_STAT_RX_BG_1_MAC_DROP_FRAME_H 0x964c
+#define MPS_STAT_RX_BG_2_MAC_DROP_FRAME_L 0x9650
+#define MPS_STAT_RX_BG_2_MAC_DROP_FRAME_H 0x9654
+#define MPS_STAT_RX_BG_3_MAC_DROP_FRAME_L 0x9658
+#define MPS_STAT_RX_BG_3_MAC_DROP_FRAME_H 0x965c
+#define MPS_STAT_RX_BG_0_LB_DROP_FRAME_L 0x9660
+#define MPS_STAT_RX_BG_0_LB_DROP_FRAME_H 0x9664
+#define MPS_STAT_RX_BG_1_LB_DROP_FRAME_L 0x9668
+#define MPS_STAT_RX_BG_1_LB_DROP_FRAME_H 0x966c
+#define MPS_STAT_RX_BG_2_LB_DROP_FRAME_L 0x9670
+#define MPS_STAT_RX_BG_2_LB_DROP_FRAME_H 0x9674
+#define MPS_STAT_RX_BG_3_LB_DROP_FRAME_L 0x9678
+#define MPS_STAT_RX_BG_3_LB_DROP_FRAME_H 0x967c
+#define MPS_STAT_RX_BG_0_MAC_TRUNC_FRAME_L 0x9680
+#define MPS_STAT_RX_BG_0_MAC_TRUNC_FRAME_H 0x9684
+#define MPS_STAT_RX_BG_1_MAC_TRUNC_FRAME_L 0x9688
+#define MPS_STAT_RX_BG_1_MAC_TRUNC_FRAME_H 0x968c
+#define MPS_STAT_RX_BG_2_MAC_TRUNC_FRAME_L 0x9690
+#define MPS_STAT_RX_BG_2_MAC_TRUNC_FRAME_H 0x9694
+#define MPS_STAT_RX_BG_3_MAC_TRUNC_FRAME_L 0x9698
+#define MPS_STAT_RX_BG_3_MAC_TRUNC_FRAME_H 0x969c
+#define MPS_STAT_RX_BG_0_LB_TRUNC_FRAME_L 0x96a0
+#define MPS_STAT_RX_BG_0_LB_TRUNC_FRAME_H 0x96a4
+#define MPS_STAT_RX_BG_1_LB_TRUNC_FRAME_L 0x96a8
+#define MPS_STAT_RX_BG_1_LB_TRUNC_FRAME_H 0x96ac
+#define MPS_STAT_RX_BG_2_LB_TRUNC_FRAME_L 0x96b0
+#define MPS_STAT_RX_BG_2_LB_TRUNC_FRAME_H 0x96b4
+#define MPS_STAT_RX_BG_3_LB_TRUNC_FRAME_L 0x96b8
+#define MPS_STAT_RX_BG_3_LB_TRUNC_FRAME_H 0x96bc
+#define MPS_TRC_CFG 0x9800
+#define  TRCFIFOEMPTY       0x00000010U
+#define  TRCIGNOREDROPINPUT 0x00000008U
+#define  TRCKEEPDUPLICATES  0x00000004U
+#define  TRCEN              0x00000002U
+#define  TRCMULTIFILTER     0x00000001U
+
+#define MPS_TRC_RSS_CONTROL 0x9808
+#define  RSSCONTROL_MASK    0x00ff0000U
+#define  RSSCONTROL_SHIFT   16
+#define  RSSCONTROL(x)      ((x) << RSSCONTROL_SHIFT)
+#define  QUEUENUMBER_MASK   0x0000ffffU
+#define  QUEUENUMBER_SHIFT  0
+#define  QUEUENUMBER(x)     ((x) << QUEUENUMBER_SHIFT)
+
+#define MPS_TRC_FILTER_MATCH_CTL_A 0x9810
+#define  TFINVERTMATCH   0x01000000U
+#define  TFPKTTOOLARGE   0x00800000U
+#define  TFEN            0x00400000U
+#define  TFPORT_MASK     0x003c0000U
+#define  TFPORT_SHIFT    18
+#define  TFPORT(x)       ((x) << TFPORT_SHIFT)
+#define  TFPORT_GET(x)   (((x) & TFPORT_MASK) >> TFPORT_SHIFT)
+#define  TFDROP          0x00020000U
+#define  TFSOPEOPERR     0x00010000U
+#define  TFLENGTH_MASK   0x00001f00U
+#define  TFLENGTH_SHIFT  8
+#define  TFLENGTH(x)     ((x) << TFLENGTH_SHIFT)
+#define  TFLENGTH_GET(x) (((x) & TFLENGTH_MASK) >> TFLENGTH_SHIFT)
+#define  TFOFFSET_MASK   0x0000001fU
+#define  TFOFFSET_SHIFT  0
+#define  TFOFFSET(x)     ((x) << TFOFFSET_SHIFT)
+#define  TFOFFSET_GET(x) (((x) & TFOFFSET_MASK) >> TFOFFSET_SHIFT)
+
+#define MPS_TRC_FILTER_MATCH_CTL_B 0x9820
+#define  TFMINPKTSIZE_MASK   0x01ff0000U
+#define  TFMINPKTSIZE_SHIFT  16
+#define  TFMINPKTSIZE(x)     ((x) << TFMINPKTSIZE_SHIFT)
+#define  TFMINPKTSIZE_GET(x) (((x) & TFMINPKTSIZE_MASK) >> TFMINPKTSIZE_SHIFT)
+#define  TFCAPTUREMAX_MASK   0x00003fffU
+#define  TFCAPTUREMAX_SHIFT  0
+#define  TFCAPTUREMAX(x)     ((x) << TFCAPTUREMAX_SHIFT)
+#define  TFCAPTUREMAX_GET(x) (((x) & TFCAPTUREMAX_MASK) >> TFCAPTUREMAX_SHIFT)
+
+#define MPS_TRC_INT_CAUSE 0x985c
+#define  MISCPERR 0x00000100U
+#define  PKTFIFO  0x000000f0U
+#define  FILTMEM  0x0000000fU
+
+#define MPS_TRC_FILTER0_MATCH 0x9c00
+#define MPS_TRC_FILTER0_DONT_CARE 0x9c80
+#define MPS_TRC_FILTER1_MATCH 0x9d00
+#define MPS_CLS_INT_CAUSE 0xd028
+#define  PLERRENB  0x00000008U
+#define  HASHSRAM  0x00000004U
+#define  MATCHTCAM 0x00000002U
+#define  MATCHSRAM 0x00000001U
+
+#define MPS_RX_PERR_INT_CAUSE 0x11074
+
+#define CPL_INTR_CAUSE 0x19054
+#define  CIM_OP_MAP_PERR   0x00000020U
+#define  CIM_OVFL_ERROR    0x00000010U
+#define  TP_FRAMING_ERROR  0x00000008U
+#define  SGE_FRAMING_ERROR 0x00000004U
+#define  CIM_FRAMING_ERROR 0x00000002U
+#define  ZERO_SWITCH_ERROR 0x00000001U
+
+#define SMB_INT_CAUSE 0x19090
+#define  MSTTXFIFOPARINT 0x00200000U
+#define  MSTRXFIFOPARINT 0x00100000U
+#define  SLVFIFOPARINT   0x00080000U
+
+#define ULP_RX_INT_CAUSE 0x19158
+#define ULP_RX_ISCSI_TAGMASK 0x19164
+#define ULP_RX_ISCSI_PSZ 0x19168
+#define  HPZ3_MASK   0x0f000000U
+#define  HPZ3_SHIFT  24
+#define  HPZ3(x)     ((x) << HPZ3_SHIFT)
+#define  HPZ2_MASK   0x000f0000U
+#define  HPZ2_SHIFT  16
+#define  HPZ2(x)     ((x) << HPZ2_SHIFT)
+#define  HPZ1_MASK   0x00000f00U
+#define  HPZ1_SHIFT  8
+#define  HPZ1(x)     ((x) << HPZ1_SHIFT)
+#define  HPZ0_MASK   0x0000000fU
+#define  HPZ0_SHIFT  0
+#define  HPZ0(x)     ((x) << HPZ0_SHIFT)
+
+#define ULP_RX_TDDP_PSZ 0x19178
+
+#define SF_DATA 0x193f8
+#define SF_OP 0x193fc
+#define  BUSY          0x80000000U
+#define  SF_LOCK       0x00000010U
+#define  SF_CONT       0x00000008U
+#define  BYTECNT_MASK  0x00000006U
+#define  BYTECNT_SHIFT 1
+#define  BYTECNT(x)    ((x) << BYTECNT_SHIFT)
+#define  OP_WR         0x00000001U
+
+#define PL_PF_INT_CAUSE 0x3c0
+#define  PFSW  0x00000008U
+#define  PFSGE 0x00000004U
+#define  PFCIM 0x00000002U
+#define  PFMPS 0x00000001U
+
+#define PL_PF_INT_ENABLE 0x3c4
+#define PL_PF_CTL 0x3c8
+#define  SWINT 0x00000001U
+
+#define PL_WHOAMI 0x19400
+#define  SOURCEPF_MASK   0x00000700U
+#define  SOURCEPF_SHIFT  8
+#define  SOURCEPF(x)     ((x) << SOURCEPF_SHIFT)
+#define  SOURCEPF_GET(x) (((x) & SOURCEPF_MASK) >> SOURCEPF_SHIFT)
+#define  ISVF            0x00000080U
+#define  VFID_MASK       0x0000007fU
+#define  VFID_SHIFT      0
+#define  VFID(x)         ((x) << VFID_SHIFT)
+#define  VFID_GET(x)     (((x) & VFID_MASK) >> VFID_SHIFT)
+
+#define PL_INT_CAUSE 0x1940c
+#define  ULP_TX     0x08000000U
+#define  SGE        0x04000000U
+#define  HMA        0x02000000U
+#define  CPL_SWITCH 0x01000000U
+#define  ULP_RX     0x00800000U
+#define  PM_RX      0x00400000U
+#define  PM_TX      0x00200000U
+#define  MA         0x00100000U
+#define  TP         0x00080000U
+#define  LE         0x00040000U
+#define  EDC1       0x00020000U
+#define  EDC0       0x00010000U
+#define  MC         0x00008000U
+#define  PCIE       0x00004000U
+#define  PMU        0x00002000U
+#define  XGMAC_KR1  0x00001000U
+#define  XGMAC_KR0  0x00000800U
+#define  XGMAC1     0x00000400U
+#define  XGMAC0     0x00000200U
+#define  SMB        0x00000100U
+#define  SF         0x00000080U
+#define  PL         0x00000040U
+#define  NCSI       0x00000020U
+#define  MPS        0x00000010U
+#define  MI         0x00000008U
+#define  DBG        0x00000004U
+#define  I2CM       0x00000002U
+#define  CIM        0x00000001U
+
+#define PL_INT_MAP0 0x19414
+#define PL_RST 0x19428
+#define  PIORST     0x00000002U
+#define  PIORSTMODE 0x00000001U
+
+#define PL_PL_INT_CAUSE 0x19430
+#define  FATALPERR 0x00000010U
+#define  PERRVFID  0x00000001U
+
+#define PL_REV 0x1943c
+
+#define LE_DB_CONFIG 0x19c04
+#define  HASHEN 0x00100000U
+
+#define LE_DB_SERVER_INDEX 0x19c18
+#define LE_DB_ACT_CNT_IPV4 0x19c20
+#define LE_DB_ACT_CNT_IPV6 0x19c24
+
+#define LE_DB_INT_CAUSE 0x19c3c
+#define  REQQPARERR 0x00010000U
+#define  UNKNOWNCMD 0x00008000U
+#define  PARITYERR  0x00000040U
+#define  LIPMISS    0x00000020U
+#define  LIP0       0x00000010U
+
+#define LE_DB_TID_HASHBASE 0x19df8
+
+#define NCSI_INT_CAUSE 0x1a0d8
+#define  CIM_DM_PRTY_ERR 0x00000100U
+#define  MPS_DM_PRTY_ERR 0x00000080U
+#define  TXFIFO_PRTY_ERR 0x00000002U
+#define  RXFIFO_PRTY_ERR 0x00000001U
+
+#define XGMAC_PORT_CFG2 0x1018
+#define  PATEN   0x00040000U
+#define  MAGICEN 0x00020000U
+
+#define XGMAC_PORT_MAGIC_MACID_LO 0x1024
+#define XGMAC_PORT_MAGIC_MACID_HI 0x1028
+
+#define XGMAC_PORT_EPIO_DATA0 0x10c0
+#define XGMAC_PORT_EPIO_DATA1 0x10c4
+#define XGMAC_PORT_EPIO_DATA2 0x10c8
+#define XGMAC_PORT_EPIO_DATA3 0x10cc
+#define XGMAC_PORT_EPIO_OP 0x10d0
+#define  EPIOWR         0x00000100U
+#define  ADDRESS_MASK   0x000000ffU
+#define  ADDRESS_SHIFT  0
+#define  ADDRESS(x)     ((x) << ADDRESS_SHIFT)
+
+#define XGMAC_PORT_INT_CAUSE 0x10dc
+#endif /* __T4_REGS_H */
diff --git a/drivers/net/cxgb4/t4fw_api.h b/drivers/net/cxgb4/t4fw_api.h
new file mode 100644 (file)
index 0000000..3393d05
--- /dev/null
@@ -0,0 +1,1580 @@
+/*
+ * This file is part of the Chelsio T4 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2009-2010 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ */
+
+#ifndef _T4FW_INTERFACE_H_
+#define _T4FW_INTERFACE_H_
+
+#define FW_T4VF_SGE_BASE_ADDR      0x0000
+#define FW_T4VF_MPS_BASE_ADDR      0x0100
+#define FW_T4VF_PL_BASE_ADDR       0x0200
+#define FW_T4VF_MBDATA_BASE_ADDR   0x0240
+#define FW_T4VF_CIM_BASE_ADDR      0x0300
+
+enum fw_wr_opcodes {
+       FW_FILTER_WR                   = 0x02,
+       FW_ULPTX_WR                    = 0x04,
+       FW_TP_WR                       = 0x05,
+       FW_ETH_TX_PKT_WR               = 0x08,
+       FW_FLOWC_WR                    = 0x0a,
+       FW_OFLD_TX_DATA_WR             = 0x0b,
+       FW_CMD_WR                      = 0x10,
+       FW_ETH_TX_PKT_VM_WR            = 0x11,
+       FW_RI_RES_WR                   = 0x0c,
+       FW_RI_INIT_WR                  = 0x0d,
+       FW_RI_RDMA_WRITE_WR            = 0x14,
+       FW_RI_SEND_WR                  = 0x15,
+       FW_RI_RDMA_READ_WR             = 0x16,
+       FW_RI_RECV_WR                  = 0x17,
+       FW_RI_BIND_MW_WR               = 0x18,
+       FW_RI_FR_NSMR_WR               = 0x19,
+       FW_RI_INV_LSTAG_WR             = 0x1a,
+       FW_LASTC2E_WR                  = 0x40
+};
+
+struct fw_wr_hdr {
+       __be32 hi;
+       __be32 lo;
+};
+
+#define FW_WR_OP(x)     ((x) << 24)
+#define FW_WR_ATOMIC(x)         ((x) << 23)
+#define FW_WR_FLUSH(x)   ((x) << 22)
+#define FW_WR_COMPL(x)   ((x) << 21)
+#define FW_WR_IMMDLEN(x) ((x) << 0)
+
+#define FW_WR_EQUIQ    (1U << 31)
+#define FW_WR_EQUEQ    (1U << 30)
+#define FW_WR_FLOWID(x)        ((x) << 8)
+#define FW_WR_LEN16(x) ((x) << 0)
+
+struct fw_ulptx_wr {
+       __be32 op_to_compl;
+       __be32 flowid_len16;
+       u64 cookie;
+};
+
+struct fw_tp_wr {
+       __be32 op_to_immdlen;
+       __be32 flowid_len16;
+       u64 cookie;
+};
+
+struct fw_eth_tx_pkt_wr {
+       __be32 op_immdlen;
+       __be32 equiq_to_len16;
+       __be64 r3;
+};
+
+enum fw_flowc_mnem {
+       FW_FLOWC_MNEM_PFNVFN,           /* PFN [15:8] VFN [7:0] */
+       FW_FLOWC_MNEM_CH,
+       FW_FLOWC_MNEM_PORT,
+       FW_FLOWC_MNEM_IQID,
+       FW_FLOWC_MNEM_SNDNXT,
+       FW_FLOWC_MNEM_RCVNXT,
+       FW_FLOWC_MNEM_SNDBUF,
+       FW_FLOWC_MNEM_MSS,
+};
+
+struct fw_flowc_mnemval {
+       u8 mnemonic;
+       u8 r4[3];
+       __be32 val;
+};
+
+struct fw_flowc_wr {
+       __be32 op_to_nparams;
+#define FW_FLOWC_WR_NPARAMS(x) ((x) << 0)
+       __be32 flowid_len16;
+       struct fw_flowc_mnemval mnemval[0];
+};
+
+struct fw_ofld_tx_data_wr {
+       __be32 op_to_immdlen;
+       __be32 flowid_len16;
+       __be32 plen;
+       __be32 tunnel_to_proxy;
+#define FW_OFLD_TX_DATA_WR_TUNNEL(x)    ((x) << 19)
+#define FW_OFLD_TX_DATA_WR_SAVE(x)      ((x) << 18)
+#define FW_OFLD_TX_DATA_WR_FLUSH(x)     ((x) << 17)
+#define FW_OFLD_TX_DATA_WR_URGENT(x)    ((x) << 16)
+#define FW_OFLD_TX_DATA_WR_MORE(x)      ((x) << 15)
+#define FW_OFLD_TX_DATA_WR_SHOVE(x)     ((x) << 14)
+#define FW_OFLD_TX_DATA_WR_ULPMODE(x)   ((x) << 10)
+#define FW_OFLD_TX_DATA_WR_ULPSUBMODE(x) ((x) << 6)
+};
+
+struct fw_cmd_wr {
+       __be32 op_dma;
+#define FW_CMD_WR_DMA (1U << 17)
+       __be32 len16_pkd;
+       __be64 cookie_daddr;
+};
+
+struct fw_eth_tx_pkt_vm_wr {
+       __be32 op_immdlen;
+       __be32 equiq_to_len16;
+       __be32 r3[2];
+       u8 ethmacdst[6];
+       u8 ethmacsrc[6];
+       __be16 ethtype;
+       __be16 vlantci;
+};
+
+#define FW_CMD_MAX_TIMEOUT 3000
+
+enum fw_cmd_opcodes {
+       FW_LDST_CMD                    = 0x01,
+       FW_RESET_CMD                   = 0x03,
+       FW_HELLO_CMD                   = 0x04,
+       FW_BYE_CMD                     = 0x05,
+       FW_INITIALIZE_CMD              = 0x06,
+       FW_CAPS_CONFIG_CMD             = 0x07,
+       FW_PARAMS_CMD                  = 0x08,
+       FW_PFVF_CMD                    = 0x09,
+       FW_IQ_CMD                      = 0x10,
+       FW_EQ_MNGT_CMD                 = 0x11,
+       FW_EQ_ETH_CMD                  = 0x12,
+       FW_EQ_CTRL_CMD                 = 0x13,
+       FW_EQ_OFLD_CMD                 = 0x21,
+       FW_VI_CMD                      = 0x14,
+       FW_VI_MAC_CMD                  = 0x15,
+       FW_VI_RXMODE_CMD               = 0x16,
+       FW_VI_ENABLE_CMD               = 0x17,
+       FW_ACL_MAC_CMD                 = 0x18,
+       FW_ACL_VLAN_CMD                = 0x19,
+       FW_VI_STATS_CMD                = 0x1a,
+       FW_PORT_CMD                    = 0x1b,
+       FW_PORT_STATS_CMD              = 0x1c,
+       FW_PORT_LB_STATS_CMD           = 0x1d,
+       FW_PORT_TRACE_CMD              = 0x1e,
+       FW_PORT_TRACE_MMAP_CMD         = 0x1f,
+       FW_RSS_IND_TBL_CMD             = 0x20,
+       FW_RSS_GLB_CONFIG_CMD          = 0x22,
+       FW_RSS_VI_CONFIG_CMD           = 0x23,
+       FW_LASTC2E_CMD                 = 0x40,
+       FW_ERROR_CMD                   = 0x80,
+       FW_DEBUG_CMD                   = 0x81,
+};
+
+enum fw_cmd_cap {
+       FW_CMD_CAP_PF                  = 0x01,
+       FW_CMD_CAP_DMAQ                = 0x02,
+       FW_CMD_CAP_PORT                = 0x04,
+       FW_CMD_CAP_PORTPROMISC         = 0x08,
+       FW_CMD_CAP_PORTSTATS           = 0x10,
+       FW_CMD_CAP_VF                  = 0x80,
+};
+
+/*
+ * Generic command header flit0
+ */
+struct fw_cmd_hdr {
+       __be32 hi;
+       __be32 lo;
+};
+
+#define FW_CMD_OP(x)           ((x) << 24)
+#define FW_CMD_OP_GET(x)        (((x) >> 24) & 0xff)
+#define FW_CMD_REQUEST          (1U << 23)
+#define FW_CMD_READ            (1U << 22)
+#define FW_CMD_WRITE           (1U << 21)
+#define FW_CMD_EXEC            (1U << 20)
+#define FW_CMD_RAMASK(x)       ((x) << 20)
+#define FW_CMD_RETVAL(x)       ((x) << 8)
+#define FW_CMD_RETVAL_GET(x)   (((x) >> 8) & 0xff)
+#define FW_CMD_LEN16(x)         ((x) << 0)
+
+enum fw_ldst_addrspc {
+       FW_LDST_ADDRSPC_FIRMWARE  = 0x0001,
+       FW_LDST_ADDRSPC_SGE_EGRC  = 0x0008,
+       FW_LDST_ADDRSPC_SGE_INGC  = 0x0009,
+       FW_LDST_ADDRSPC_SGE_FLMC  = 0x000a,
+       FW_LDST_ADDRSPC_SGE_CONMC = 0x000b,
+       FW_LDST_ADDRSPC_TP_PIO    = 0x0010,
+       FW_LDST_ADDRSPC_TP_TM_PIO = 0x0011,
+       FW_LDST_ADDRSPC_TP_MIB    = 0x0012,
+       FW_LDST_ADDRSPC_MDIO      = 0x0018,
+       FW_LDST_ADDRSPC_MPS       = 0x0020,
+       FW_LDST_ADDRSPC_FUNC      = 0x0028
+};
+
+enum fw_ldst_mps_fid {
+       FW_LDST_MPS_ATRB,
+       FW_LDST_MPS_RPLC
+};
+
+enum fw_ldst_func_access_ctl {
+       FW_LDST_FUNC_ACC_CTL_VIID,
+       FW_LDST_FUNC_ACC_CTL_FID
+};
+
+enum fw_ldst_func_mod_index {
+       FW_LDST_FUNC_MPS
+};
+
+struct fw_ldst_cmd {
+       __be32 op_to_addrspace;
+#define FW_LDST_CMD_ADDRSPACE(x) ((x) << 0)
+       __be32 cycles_to_len16;
+       union fw_ldst {
+               struct fw_ldst_addrval {
+                       __be32 addr;
+                       __be32 val;
+               } addrval;
+               struct fw_ldst_idctxt {
+                       __be32 physid;
+                       __be32 msg_pkd;
+                       __be32 ctxt_data7;
+                       __be32 ctxt_data6;
+                       __be32 ctxt_data5;
+                       __be32 ctxt_data4;
+                       __be32 ctxt_data3;
+                       __be32 ctxt_data2;
+                       __be32 ctxt_data1;
+                       __be32 ctxt_data0;
+               } idctxt;
+               struct fw_ldst_mdio {
+                       __be16 paddr_mmd;
+                       __be16 raddr;
+                       __be16 vctl;
+                       __be16 rval;
+               } mdio;
+               struct fw_ldst_mps {
+                       __be16 fid_ctl;
+                       __be16 rplcpf_pkd;
+                       __be32 rplc127_96;
+                       __be32 rplc95_64;
+                       __be32 rplc63_32;
+                       __be32 rplc31_0;
+                       __be32 atrb;
+                       __be16 vlan[16];
+               } mps;
+               struct fw_ldst_func {
+                       u8 access_ctl;
+                       u8 mod_index;
+                       __be16 ctl_id;
+                       __be32 offset;
+                       __be64 data0;
+                       __be64 data1;
+               } func;
+       } u;
+};
+
+#define FW_LDST_CMD_MSG(x)     ((x) << 31)
+#define FW_LDST_CMD_PADDR(x)   ((x) << 8)
+#define FW_LDST_CMD_MMD(x)     ((x) << 0)
+#define FW_LDST_CMD_FID(x)     ((x) << 15)
+#define FW_LDST_CMD_CTL(x)     ((x) << 0)
+#define FW_LDST_CMD_RPLCPF(x)  ((x) << 0)
+
+struct fw_reset_cmd {
+       __be32 op_to_write;
+       __be32 retval_len16;
+       __be32 val;
+       __be32 r3;
+};
+
+struct fw_hello_cmd {
+       __be32 op_to_write;
+       __be32 retval_len16;
+       __be32 err_to_mbasyncnot;
+#define FW_HELLO_CMD_ERR           (1U << 31)
+#define FW_HELLO_CMD_INIT          (1U << 30)
+#define FW_HELLO_CMD_MASTERDIS(x)   ((x) << 29)
+#define FW_HELLO_CMD_MASTERFORCE(x) ((x) << 28)
+#define FW_HELLO_CMD_MBMASTER(x)    ((x) << 24)
+#define FW_HELLO_CMD_MBASYNCNOT(x)  ((x) << 20)
+       __be32 fwrev;
+};
+
+struct fw_bye_cmd {
+       __be32 op_to_write;
+       __be32 retval_len16;
+       __be64 r3;
+};
+
+struct fw_initialize_cmd {
+       __be32 op_to_write;
+       __be32 retval_len16;
+       __be64 r3;
+};
+
+enum fw_caps_config_hm {
+       FW_CAPS_CONFIG_HM_PCIE          = 0x00000001,
+       FW_CAPS_CONFIG_HM_PL            = 0x00000002,
+       FW_CAPS_CONFIG_HM_SGE           = 0x00000004,
+       FW_CAPS_CONFIG_HM_CIM           = 0x00000008,
+       FW_CAPS_CONFIG_HM_ULPTX         = 0x00000010,
+       FW_CAPS_CONFIG_HM_TP            = 0x00000020,
+       FW_CAPS_CONFIG_HM_ULPRX         = 0x00000040,
+       FW_CAPS_CONFIG_HM_PMRX          = 0x00000080,
+       FW_CAPS_CONFIG_HM_PMTX          = 0x00000100,
+       FW_CAPS_CONFIG_HM_MC            = 0x00000200,
+       FW_CAPS_CONFIG_HM_LE            = 0x00000400,
+       FW_CAPS_CONFIG_HM_MPS           = 0x00000800,
+       FW_CAPS_CONFIG_HM_XGMAC         = 0x00001000,
+       FW_CAPS_CONFIG_HM_CPLSWITCH     = 0x00002000,
+       FW_CAPS_CONFIG_HM_T4DBG         = 0x00004000,
+       FW_CAPS_CONFIG_HM_MI            = 0x00008000,
+       FW_CAPS_CONFIG_HM_I2CM          = 0x00010000,
+       FW_CAPS_CONFIG_HM_NCSI          = 0x00020000,
+       FW_CAPS_CONFIG_HM_SMB           = 0x00040000,
+       FW_CAPS_CONFIG_HM_MA            = 0x00080000,
+       FW_CAPS_CONFIG_HM_EDRAM         = 0x00100000,
+       FW_CAPS_CONFIG_HM_PMU           = 0x00200000,
+       FW_CAPS_CONFIG_HM_UART          = 0x00400000,
+       FW_CAPS_CONFIG_HM_SF            = 0x00800000,
+};
+
+enum fw_caps_config_nbm {
+       FW_CAPS_CONFIG_NBM_IPMI         = 0x00000001,
+       FW_CAPS_CONFIG_NBM_NCSI         = 0x00000002,
+};
+
+enum fw_caps_config_link {
+       FW_CAPS_CONFIG_LINK_PPP         = 0x00000001,
+       FW_CAPS_CONFIG_LINK_QFC         = 0x00000002,
+       FW_CAPS_CONFIG_LINK_DCBX        = 0x00000004,
+};
+
+enum fw_caps_config_switch {
+       FW_CAPS_CONFIG_SWITCH_INGRESS   = 0x00000001,
+       FW_CAPS_CONFIG_SWITCH_EGRESS    = 0x00000002,
+};
+
+enum fw_caps_config_nic {
+       FW_CAPS_CONFIG_NIC              = 0x00000001,
+       FW_CAPS_CONFIG_NIC_VM           = 0x00000002,
+};
+
+enum fw_caps_config_ofld {
+       FW_CAPS_CONFIG_OFLD             = 0x00000001,
+};
+
+enum fw_caps_config_rdma {
+       FW_CAPS_CONFIG_RDMA_RDDP        = 0x00000001,
+       FW_CAPS_CONFIG_RDMA_RDMAC       = 0x00000002,
+};
+
+enum fw_caps_config_iscsi {
+       FW_CAPS_CONFIG_ISCSI_INITIATOR_PDU = 0x00000001,
+       FW_CAPS_CONFIG_ISCSI_TARGET_PDU = 0x00000002,
+       FW_CAPS_CONFIG_ISCSI_INITIATOR_CNXOFLD = 0x00000004,
+       FW_CAPS_CONFIG_ISCSI_TARGET_CNXOFLD = 0x00000008,
+};
+
+enum fw_caps_config_fcoe {
+       FW_CAPS_CONFIG_FCOE_INITIATOR   = 0x00000001,
+       FW_CAPS_CONFIG_FCOE_TARGET      = 0x00000002,
+};
+
+struct fw_caps_config_cmd {
+       __be32 op_to_write;
+       __be32 retval_len16;
+       __be32 r2;
+       __be32 hwmbitmap;
+       __be16 nbmcaps;
+       __be16 linkcaps;
+       __be16 switchcaps;
+       __be16 r3;
+       __be16 niccaps;
+       __be16 ofldcaps;
+       __be16 rdmacaps;
+       __be16 r4;
+       __be16 iscsicaps;
+       __be16 fcoecaps;
+       __be32 r5;
+       __be64 r6;
+};
+
+/*
+ * params command mnemonics
+ */
+enum fw_params_mnem {
+       FW_PARAMS_MNEM_DEV              = 1,    /* device params */
+       FW_PARAMS_MNEM_PFVF             = 2,    /* function params */
+       FW_PARAMS_MNEM_REG              = 3,    /* limited register access */
+       FW_PARAMS_MNEM_DMAQ             = 4,    /* dma queue params */
+       FW_PARAMS_MNEM_LAST
+};
+
+/*
+ * device parameters
+ */
+enum fw_params_param_dev {
+       FW_PARAMS_PARAM_DEV_CCLK        = 0x00, /* chip core clock in khz */
+       FW_PARAMS_PARAM_DEV_PORTVEC     = 0x01, /* the port vector */
+       FW_PARAMS_PARAM_DEV_NTID        = 0x02, /* reads the number of TIDs
+                                                * allocated by the device's
+                                                * Lookup Engine
+                                                */
+       FW_PARAMS_PARAM_DEV_FLOWC_BUFFIFO_SZ = 0x03,
+       FW_PARAMS_PARAM_DEV_INTVER_NIC  = 0x04,
+       FW_PARAMS_PARAM_DEV_INTVER_VNIC = 0x05,
+       FW_PARAMS_PARAM_DEV_INTVER_OFLD = 0x06,
+       FW_PARAMS_PARAM_DEV_INTVER_RI   = 0x07,
+       FW_PARAMS_PARAM_DEV_INTVER_ISCSIPDU = 0x08,
+       FW_PARAMS_PARAM_DEV_INTVER_ISCSI = 0x09,
+       FW_PARAMS_PARAM_DEV_INTVER_FCOE = 0x0A
+};
+
+/*
+ * physical and virtual function parameters
+ */
+enum fw_params_param_pfvf {
+       FW_PARAMS_PARAM_PFVF_RWXCAPS    = 0x00,
+       FW_PARAMS_PARAM_PFVF_ROUTE_START = 0x01,
+       FW_PARAMS_PARAM_PFVF_ROUTE_END = 0x02,
+       FW_PARAMS_PARAM_PFVF_CLIP_START = 0x03,
+       FW_PARAMS_PARAM_PFVF_CLIP_END = 0x04,
+       FW_PARAMS_PARAM_PFVF_FILTER_START = 0x05,
+       FW_PARAMS_PARAM_PFVF_FILTER_END = 0x06,
+       FW_PARAMS_PARAM_PFVF_SERVER_START = 0x07,
+       FW_PARAMS_PARAM_PFVF_SERVER_END = 0x08,
+       FW_PARAMS_PARAM_PFVF_TDDP_START = 0x09,
+       FW_PARAMS_PARAM_PFVF_TDDP_END = 0x0A,
+       FW_PARAMS_PARAM_PFVF_ISCSI_START = 0x0B,
+       FW_PARAMS_PARAM_PFVF_ISCSI_END = 0x0C,
+       FW_PARAMS_PARAM_PFVF_STAG_START = 0x0D,
+       FW_PARAMS_PARAM_PFVF_STAG_END = 0x0E,
+       FW_PARAMS_PARAM_PFVF_RQ_START = 0x1F,
+       FW_PARAMS_PARAM_PFVF_RQ_END     = 0x10,
+       FW_PARAMS_PARAM_PFVF_PBL_START = 0x11,
+       FW_PARAMS_PARAM_PFVF_PBL_END    = 0x12,
+       FW_PARAMS_PARAM_PFVF_L2T_START = 0x13,
+       FW_PARAMS_PARAM_PFVF_L2T_END = 0x14,
+       FW_PARAMS_PARAM_PFVF_SCHEDCLASS_ETH = 0x20,
+};
+
+/*
+ * dma queue parameters
+ */
+enum fw_params_param_dmaq {
+       FW_PARAMS_PARAM_DMAQ_IQ_DCAEN_DCACPU = 0x00,
+       FW_PARAMS_PARAM_DMAQ_IQ_INTCNTTHRESH = 0x01,
+       FW_PARAMS_PARAM_DMAQ_EQ_CMPLIQID_MNGT = 0x10,
+       FW_PARAMS_PARAM_DMAQ_EQ_CMPLIQID_CTRL = 0x11,
+       FW_PARAMS_PARAM_DMAQ_EQ_SCHEDCLASS_ETH = 0x12,
+};
+
+#define FW_PARAMS_MNEM(x)      ((x) << 24)
+#define FW_PARAMS_PARAM_X(x)   ((x) << 16)
+#define FW_PARAMS_PARAM_Y(x)   ((x) << 8)
+#define FW_PARAMS_PARAM_Z(x)   ((x) << 0)
+#define FW_PARAMS_PARAM_XYZ(x) ((x) << 0)
+#define FW_PARAMS_PARAM_YZ(x)  ((x) << 0)
+
+struct fw_params_cmd {
+       __be32 op_to_vfn;
+       __be32 retval_len16;
+       struct fw_params_param {
+               __be32 mnem;
+               __be32 val;
+       } param[7];
+};
+
+#define FW_PARAMS_CMD_PFN(x) ((x) << 8)
+#define FW_PARAMS_CMD_VFN(x) ((x) << 0)
+
+struct fw_pfvf_cmd {
+       __be32 op_to_vfn;
+       __be32 retval_len16;
+       __be32 niqflint_niq;
+       __be32 cmask_to_neq;
+       __be32 tc_to_nexactf;
+       __be32 r_caps_to_nethctrl;
+       __be16 nricq;
+       __be16 nriqp;
+       __be32 r4;
+};
+
+#define FW_PFVF_CMD_PFN(x) ((x) << 8)
+#define FW_PFVF_CMD_VFN(x) ((x) << 0)
+
+#define FW_PFVF_CMD_NIQFLINT(x) ((x) << 20)
+#define FW_PFVF_CMD_NIQFLINT_GET(x) (((x) >> 20) & 0xfff)
+
+#define FW_PFVF_CMD_NIQ(x) ((x) << 0)
+#define FW_PFVF_CMD_NIQ_GET(x) (((x) >> 0) & 0xfffff)
+
+#define FW_PFVF_CMD_CMASK(x) ((x) << 24)
+#define FW_PFVF_CMD_CMASK_GET(x) (((x) >> 24) & 0xf)
+
+#define FW_PFVF_CMD_PMASK(x) ((x) << 20)
+#define FW_PFVF_CMD_PMASK_GET(x) (((x) >> 20) & 0xf)
+
+#define FW_PFVF_CMD_NEQ(x) ((x) << 0)
+#define FW_PFVF_CMD_NEQ_GET(x) (((x) >> 0) & 0xfffff)
+
+#define FW_PFVF_CMD_TC(x) ((x) << 24)
+#define FW_PFVF_CMD_TC_GET(x) (((x) >> 24) & 0xff)
+
+#define FW_PFVF_CMD_NVI(x) ((x) << 16)
+#define FW_PFVF_CMD_NVI_GET(x) (((x) >> 16) & 0xff)
+
+#define FW_PFVF_CMD_NEXACTF(x) ((x) << 0)
+#define FW_PFVF_CMD_NEXACTF_GET(x) (((x) >> 0) & 0xffff)
+
+#define FW_PFVF_CMD_R_CAPS(x) ((x) << 24)
+#define FW_PFVF_CMD_R_CAPS_GET(x) (((x) >> 24) & 0xff)
+
+#define FW_PFVF_CMD_WX_CAPS(x) ((x) << 16)
+#define FW_PFVF_CMD_WX_CAPS_GET(x) (((x) >> 16) & 0xff)
+
+#define FW_PFVF_CMD_NETHCTRL(x) ((x) << 0)
+#define FW_PFVF_CMD_NETHCTRL_GET(x) (((x) >> 0) & 0xffff)
+
+enum fw_iq_type {
+       FW_IQ_TYPE_FL_INT_CAP,
+       FW_IQ_TYPE_NO_FL_INT_CAP
+};
+
+struct fw_iq_cmd {
+       __be32 op_to_vfn;
+       __be32 alloc_to_len16;
+       __be16 physiqid;
+       __be16 iqid;
+       __be16 fl0id;
+       __be16 fl1id;
+       __be32 type_to_iqandstindex;
+       __be16 iqdroprss_to_iqesize;
+       __be16 iqsize;
+       __be64 iqaddr;
+       __be32 iqns_to_fl0congen;
+       __be16 fl0dcaen_to_fl0cidxfthresh;
+       __be16 fl0size;
+       __be64 fl0addr;
+       __be32 fl1cngchmap_to_fl1congen;
+       __be16 fl1dcaen_to_fl1cidxfthresh;
+       __be16 fl1size;
+       __be64 fl1addr;
+};
+
+#define FW_IQ_CMD_PFN(x) ((x) << 8)
+#define FW_IQ_CMD_VFN(x) ((x) << 0)
+
+#define FW_IQ_CMD_ALLOC (1U << 31)
+#define FW_IQ_CMD_FREE (1U << 30)
+#define FW_IQ_CMD_MODIFY (1U << 29)
+#define FW_IQ_CMD_IQSTART(x) ((x) << 28)
+#define FW_IQ_CMD_IQSTOP(x) ((x) << 27)
+
+#define FW_IQ_CMD_TYPE(x) ((x) << 29)
+#define FW_IQ_CMD_IQASYNCH(x) ((x) << 28)
+#define FW_IQ_CMD_VIID(x) ((x) << 16)
+#define FW_IQ_CMD_IQANDST(x) ((x) << 15)
+#define FW_IQ_CMD_IQANUS(x) ((x) << 14)
+#define FW_IQ_CMD_IQANUD(x) ((x) << 12)
+#define FW_IQ_CMD_IQANDSTINDEX(x) ((x) << 0)
+
+#define FW_IQ_CMD_IQDROPRSS (1U << 15)
+#define FW_IQ_CMD_IQGTSMODE (1U << 14)
+#define FW_IQ_CMD_IQPCIECH(x) ((x) << 12)
+#define FW_IQ_CMD_IQDCAEN(x) ((x) << 11)
+#define FW_IQ_CMD_IQDCACPU(x) ((x) << 6)
+#define FW_IQ_CMD_IQINTCNTTHRESH(x) ((x) << 4)
+#define FW_IQ_CMD_IQO (1U << 3)
+#define FW_IQ_CMD_IQCPRIO(x) ((x) << 2)
+#define FW_IQ_CMD_IQESIZE(x) ((x) << 0)
+
+#define FW_IQ_CMD_IQNS(x) ((x) << 31)
+#define FW_IQ_CMD_IQRO(x) ((x) << 30)
+#define FW_IQ_CMD_IQFLINTIQHSEN(x) ((x) << 28)
+#define FW_IQ_CMD_IQFLINTCONGEN(x) ((x) << 27)
+#define FW_IQ_CMD_IQFLINTISCSIC(x) ((x) << 26)
+#define FW_IQ_CMD_FL0CNGCHMAP(x) ((x) << 20)
+#define FW_IQ_CMD_FL0CACHELOCK(x) ((x) << 15)
+#define FW_IQ_CMD_FL0DBP(x) ((x) << 14)
+#define FW_IQ_CMD_FL0DATANS(x) ((x) << 13)
+#define FW_IQ_CMD_FL0DATARO(x) ((x) << 12)
+#define FW_IQ_CMD_FL0CONGCIF(x) ((x) << 11)
+#define FW_IQ_CMD_FL0ONCHIP(x) ((x) << 10)
+#define FW_IQ_CMD_FL0STATUSPGNS(x) ((x) << 9)
+#define FW_IQ_CMD_FL0STATUSPGRO(x) ((x) << 8)
+#define FW_IQ_CMD_FL0FETCHNS(x) ((x) << 7)
+#define FW_IQ_CMD_FL0FETCHRO(x) ((x) << 6)
+#define FW_IQ_CMD_FL0HOSTFCMODE(x) ((x) << 4)
+#define FW_IQ_CMD_FL0CPRIO(x) ((x) << 3)
+#define FW_IQ_CMD_FL0PADEN (1U << 2)
+#define FW_IQ_CMD_FL0PACKEN (1U << 1)
+#define FW_IQ_CMD_FL0CONGEN (1U << 0)
+
+#define FW_IQ_CMD_FL0DCAEN(x) ((x) << 15)
+#define FW_IQ_CMD_FL0DCACPU(x) ((x) << 10)
+#define FW_IQ_CMD_FL0FBMIN(x) ((x) << 7)
+#define FW_IQ_CMD_FL0FBMAX(x) ((x) << 4)
+#define FW_IQ_CMD_FL0CIDXFTHRESHO (1U << 3)
+#define FW_IQ_CMD_FL0CIDXFTHRESH(x) ((x) << 0)
+
+#define FW_IQ_CMD_FL1CNGCHMAP(x) ((x) << 20)
+#define FW_IQ_CMD_FL1CACHELOCK(x) ((x) << 15)
+#define FW_IQ_CMD_FL1DBP(x) ((x) << 14)
+#define FW_IQ_CMD_FL1DATANS(x) ((x) << 13)
+#define FW_IQ_CMD_FL1DATARO(x) ((x) << 12)
+#define FW_IQ_CMD_FL1CONGCIF(x) ((x) << 11)
+#define FW_IQ_CMD_FL1ONCHIP(x) ((x) << 10)
+#define FW_IQ_CMD_FL1STATUSPGNS(x) ((x) << 9)
+#define FW_IQ_CMD_FL1STATUSPGRO(x) ((x) << 8)
+#define FW_IQ_CMD_FL1FETCHNS(x) ((x) << 7)
+#define FW_IQ_CMD_FL1FETCHRO(x) ((x) << 6)
+#define FW_IQ_CMD_FL1HOSTFCMODE(x) ((x) << 4)
+#define FW_IQ_CMD_FL1CPRIO(x) ((x) << 3)
+#define FW_IQ_CMD_FL1PADEN (1U << 2)
+#define FW_IQ_CMD_FL1PACKEN (1U << 1)
+#define FW_IQ_CMD_FL1CONGEN (1U << 0)
+
+#define FW_IQ_CMD_FL1DCAEN(x) ((x) << 15)
+#define FW_IQ_CMD_FL1DCACPU(x) ((x) << 10)
+#define FW_IQ_CMD_FL1FBMIN(x) ((x) << 7)
+#define FW_IQ_CMD_FL1FBMAX(x) ((x) << 4)
+#define FW_IQ_CMD_FL1CIDXFTHRESHO (1U << 3)
+#define FW_IQ_CMD_FL1CIDXFTHRESH(x) ((x) << 0)
+
+struct fw_eq_eth_cmd {
+       __be32 op_to_vfn;
+       __be32 alloc_to_len16;
+       __be32 eqid_pkd;
+       __be32 physeqid_pkd;
+       __be32 fetchszm_to_iqid;
+       __be32 dcaen_to_eqsize;
+       __be64 eqaddr;
+       __be32 viid_pkd;
+       __be32 r8_lo;
+       __be64 r9;
+};
+
+#define FW_EQ_ETH_CMD_PFN(x) ((x) << 8)
+#define FW_EQ_ETH_CMD_VFN(x) ((x) << 0)
+#define FW_EQ_ETH_CMD_ALLOC (1U << 31)
+#define FW_EQ_ETH_CMD_FREE (1U << 30)
+#define FW_EQ_ETH_CMD_MODIFY (1U << 29)
+#define FW_EQ_ETH_CMD_EQSTART (1U << 28)
+#define FW_EQ_ETH_CMD_EQSTOP (1U << 27)
+
+#define FW_EQ_ETH_CMD_EQID(x) ((x) << 0)
+#define FW_EQ_ETH_CMD_EQID_GET(x) (((x) >> 0) & 0xfffff)
+#define FW_EQ_ETH_CMD_PHYSEQID(x) ((x) << 0)
+
+#define FW_EQ_ETH_CMD_FETCHSZM(x) ((x) << 26)
+#define FW_EQ_ETH_CMD_STATUSPGNS(x) ((x) << 25)
+#define FW_EQ_ETH_CMD_STATUSPGRO(x) ((x) << 24)
+#define FW_EQ_ETH_CMD_FETCHNS(x) ((x) << 23)
+#define FW_EQ_ETH_CMD_FETCHRO(x) ((x) << 22)
+#define FW_EQ_ETH_CMD_HOSTFCMODE(x) ((x) << 20)
+#define FW_EQ_ETH_CMD_CPRIO(x) ((x) << 19)
+#define FW_EQ_ETH_CMD_ONCHIP(x) ((x) << 18)
+#define FW_EQ_ETH_CMD_PCIECHN(x) ((x) << 16)
+#define FW_EQ_ETH_CMD_IQID(x) ((x) << 0)
+
+#define FW_EQ_ETH_CMD_DCAEN(x) ((x) << 31)
+#define FW_EQ_ETH_CMD_DCACPU(x) ((x) << 26)
+#define FW_EQ_ETH_CMD_FBMIN(x) ((x) << 23)
+#define FW_EQ_ETH_CMD_FBMAX(x) ((x) << 20)
+#define FW_EQ_ETH_CMD_CIDXFTHRESHO(x) ((x) << 19)
+#define FW_EQ_ETH_CMD_CIDXFTHRESH(x) ((x) << 16)
+#define FW_EQ_ETH_CMD_EQSIZE(x) ((x) << 0)
+
+#define FW_EQ_ETH_CMD_VIID(x) ((x) << 16)
+
+struct fw_eq_ctrl_cmd {
+       __be32 op_to_vfn;
+       __be32 alloc_to_len16;
+       __be32 cmpliqid_eqid;
+       __be32 physeqid_pkd;
+       __be32 fetchszm_to_iqid;
+       __be32 dcaen_to_eqsize;
+       __be64 eqaddr;
+};
+
+#define FW_EQ_CTRL_CMD_PFN(x) ((x) << 8)
+#define FW_EQ_CTRL_CMD_VFN(x) ((x) << 0)
+
+#define FW_EQ_CTRL_CMD_ALLOC (1U << 31)
+#define FW_EQ_CTRL_CMD_FREE (1U << 30)
+#define FW_EQ_CTRL_CMD_MODIFY (1U << 29)
+#define FW_EQ_CTRL_CMD_EQSTART (1U << 28)
+#define FW_EQ_CTRL_CMD_EQSTOP (1U << 27)
+
+#define FW_EQ_CTRL_CMD_CMPLIQID(x) ((x) << 20)
+#define FW_EQ_CTRL_CMD_EQID(x) ((x) << 0)
+#define FW_EQ_CTRL_CMD_EQID_GET(x) (((x) >> 0) & 0xfffff)
+#define FW_EQ_CTRL_CMD_PHYSEQID_GET(x) (((x) >> 0) & 0xfffff)
+
+#define FW_EQ_CTRL_CMD_FETCHSZM (1U << 26)
+#define FW_EQ_CTRL_CMD_STATUSPGNS (1U << 25)
+#define FW_EQ_CTRL_CMD_STATUSPGRO (1U << 24)
+#define FW_EQ_CTRL_CMD_FETCHNS (1U << 23)
+#define FW_EQ_CTRL_CMD_FETCHRO (1U << 22)
+#define FW_EQ_CTRL_CMD_HOSTFCMODE(x) ((x) << 20)
+#define FW_EQ_CTRL_CMD_CPRIO(x) ((x) << 19)
+#define FW_EQ_CTRL_CMD_ONCHIP(x) ((x) << 18)
+#define FW_EQ_CTRL_CMD_PCIECHN(x) ((x) << 16)
+#define FW_EQ_CTRL_CMD_IQID(x) ((x) << 0)
+
+#define FW_EQ_CTRL_CMD_DCAEN(x) ((x) << 31)
+#define FW_EQ_CTRL_CMD_DCACPU(x) ((x) << 26)
+#define FW_EQ_CTRL_CMD_FBMIN(x) ((x) << 23)
+#define FW_EQ_CTRL_CMD_FBMAX(x) ((x) << 20)
+#define FW_EQ_CTRL_CMD_CIDXFTHRESHO(x) ((x) << 19)
+#define FW_EQ_CTRL_CMD_CIDXFTHRESH(x) ((x) << 16)
+#define FW_EQ_CTRL_CMD_EQSIZE(x) ((x) << 0)
+
+struct fw_eq_ofld_cmd {
+       __be32 op_to_vfn;
+       __be32 alloc_to_len16;
+       __be32 eqid_pkd;
+       __be32 physeqid_pkd;
+       __be32 fetchszm_to_iqid;
+       __be32 dcaen_to_eqsize;
+       __be64 eqaddr;
+};
+
+#define FW_EQ_OFLD_CMD_PFN(x) ((x) << 8)
+#define FW_EQ_OFLD_CMD_VFN(x) ((x) << 0)
+
+#define FW_EQ_OFLD_CMD_ALLOC (1U << 31)
+#define FW_EQ_OFLD_CMD_FREE (1U << 30)
+#define FW_EQ_OFLD_CMD_MODIFY (1U << 29)
+#define FW_EQ_OFLD_CMD_EQSTART (1U << 28)
+#define FW_EQ_OFLD_CMD_EQSTOP (1U << 27)
+
+#define FW_EQ_OFLD_CMD_EQID(x) ((x) << 0)
+#define FW_EQ_OFLD_CMD_EQID_GET(x) (((x) >> 0) & 0xfffff)
+#define FW_EQ_OFLD_CMD_PHYSEQID_GET(x) (((x) >> 0) & 0xfffff)
+
+#define FW_EQ_OFLD_CMD_FETCHSZM(x) ((x) << 26)
+#define FW_EQ_OFLD_CMD_STATUSPGNS(x) ((x) << 25)
+#define FW_EQ_OFLD_CMD_STATUSPGRO(x) ((x) << 24)
+#define FW_EQ_OFLD_CMD_FETCHNS(x) ((x) << 23)
+#define FW_EQ_OFLD_CMD_FETCHRO(x) ((x) << 22)
+#define FW_EQ_OFLD_CMD_HOSTFCMODE(x) ((x) << 20)
+#define FW_EQ_OFLD_CMD_CPRIO(x) ((x) << 19)
+#define FW_EQ_OFLD_CMD_ONCHIP(x) ((x) << 18)
+#define FW_EQ_OFLD_CMD_PCIECHN(x) ((x) << 16)
+#define FW_EQ_OFLD_CMD_IQID(x) ((x) << 0)
+
+#define FW_EQ_OFLD_CMD_DCAEN(x) ((x) << 31)
+#define FW_EQ_OFLD_CMD_DCACPU(x) ((x) << 26)
+#define FW_EQ_OFLD_CMD_FBMIN(x) ((x) << 23)
+#define FW_EQ_OFLD_CMD_FBMAX(x) ((x) << 20)
+#define FW_EQ_OFLD_CMD_CIDXFTHRESHO(x) ((x) << 19)
+#define FW_EQ_OFLD_CMD_CIDXFTHRESH(x) ((x) << 16)
+#define FW_EQ_OFLD_CMD_EQSIZE(x) ((x) << 0)
+
+/*
+ * Macros for VIID parsing:
+ * VIID - [10:8] PFN, [7] VI Valid, [6:0] VI number
+ */
+#define FW_VIID_PFN_GET(x) (((x) >> 8) & 0x7)
+#define FW_VIID_VIVLD_GET(x) (((x) >> 7) & 0x1)
+#define FW_VIID_VIN_GET(x) (((x) >> 0) & 0x7F)
+
+struct fw_vi_cmd {
+       __be32 op_to_vfn;
+       __be32 alloc_to_len16;
+       __be16 viid_pkd;
+       u8 mac[6];
+       u8 portid_pkd;
+       u8 nmac;
+       u8 nmac0[6];
+       __be16 rsssize_pkd;
+       u8 nmac1[6];
+       __be16 r7;
+       u8 nmac2[6];
+       __be16 r8;
+       u8 nmac3[6];
+       __be64 r9;
+       __be64 r10;
+};
+
+#define FW_VI_CMD_PFN(x) ((x) << 8)
+#define FW_VI_CMD_VFN(x) ((x) << 0)
+#define FW_VI_CMD_ALLOC (1U << 31)
+#define FW_VI_CMD_FREE (1U << 30)
+#define FW_VI_CMD_VIID(x) ((x) << 0)
+#define FW_VI_CMD_PORTID(x) ((x) << 4)
+#define FW_VI_CMD_RSSSIZE_GET(x) (((x) >> 0) & 0x7ff)
+
+/* Special VI_MAC command index ids */
+#define FW_VI_MAC_ADD_MAC              0x3FF
+#define FW_VI_MAC_ADD_PERSIST_MAC      0x3FE
+#define FW_VI_MAC_MAC_BASED_FREE       0x3FD
+
+enum fw_vi_mac_smac {
+       FW_VI_MAC_MPS_TCAM_ENTRY,
+       FW_VI_MAC_MPS_TCAM_ONLY,
+       FW_VI_MAC_SMT_ONLY,
+       FW_VI_MAC_SMT_AND_MPSTCAM
+};
+
+enum fw_vi_mac_result {
+       FW_VI_MAC_R_SUCCESS,
+       FW_VI_MAC_R_F_NONEXISTENT_NOMEM,
+       FW_VI_MAC_R_SMAC_FAIL,
+       FW_VI_MAC_R_F_ACL_CHECK
+};
+
+struct fw_vi_mac_cmd {
+       __be32 op_to_viid;
+       __be32 freemacs_to_len16;
+       union fw_vi_mac {
+               struct fw_vi_mac_exact {
+                       __be16 valid_to_idx;
+                       u8 macaddr[6];
+               } exact[7];
+               struct fw_vi_mac_hash {
+                       __be64 hashvec;
+               } hash;
+       } u;
+};
+
+#define FW_VI_MAC_CMD_VIID(x) ((x) << 0)
+#define FW_VI_MAC_CMD_FREEMACS(x) ((x) << 31)
+#define FW_VI_MAC_CMD_HASHVECEN (1U << 23)
+#define FW_VI_MAC_CMD_HASHUNIEN(x) ((x) << 22)
+#define FW_VI_MAC_CMD_VALID (1U << 15)
+#define FW_VI_MAC_CMD_PRIO(x) ((x) << 12)
+#define FW_VI_MAC_CMD_SMAC_RESULT(x) ((x) << 10)
+#define FW_VI_MAC_CMD_SMAC_RESULT_GET(x) (((x) >> 10) & 0x3)
+#define FW_VI_MAC_CMD_IDX(x) ((x) << 0)
+#define FW_VI_MAC_CMD_IDX_GET(x) (((x) >> 0) & 0x3ff)
+
+#define FW_RXMODE_MTU_NO_CHG   65535
+
+struct fw_vi_rxmode_cmd {
+       __be32 op_to_viid;
+       __be32 retval_len16;
+       __be32 mtu_to_broadcasten;
+       __be32 r4_lo;
+};
+
+#define FW_VI_RXMODE_CMD_VIID(x) ((x) << 0)
+#define FW_VI_RXMODE_CMD_MTU(x) ((x) << 16)
+#define FW_VI_RXMODE_CMD_PROMISCEN_MASK 0x3
+#define FW_VI_RXMODE_CMD_PROMISCEN(x) ((x) << 14)
+#define FW_VI_RXMODE_CMD_ALLMULTIEN_MASK 0x3
+#define FW_VI_RXMODE_CMD_ALLMULTIEN(x) ((x) << 12)
+#define FW_VI_RXMODE_CMD_BROADCASTEN_MASK 0x3
+#define FW_VI_RXMODE_CMD_BROADCASTEN(x) ((x) << 10)
+
+struct fw_vi_enable_cmd {
+       __be32 op_to_viid;
+       __be32 ien_to_len16;
+       __be16 blinkdur;
+       __be16 r3;
+       __be32 r4;
+};
+
+#define FW_VI_ENABLE_CMD_VIID(x) ((x) << 0)
+#define FW_VI_ENABLE_CMD_IEN(x) ((x) << 31)
+#define FW_VI_ENABLE_CMD_EEN(x) ((x) << 30)
+#define FW_VI_ENABLE_CMD_LED (1U << 29)
+
+/* VI VF stats offset definitions */
+#define VI_VF_NUM_STATS        16
+enum fw_vi_stats_vf_index {
+       FW_VI_VF_STAT_TX_BCAST_BYTES_IX,
+       FW_VI_VF_STAT_TX_BCAST_FRAMES_IX,
+       FW_VI_VF_STAT_TX_MCAST_BYTES_IX,
+       FW_VI_VF_STAT_TX_MCAST_FRAMES_IX,
+       FW_VI_VF_STAT_TX_UCAST_BYTES_IX,
+       FW_VI_VF_STAT_TX_UCAST_FRAMES_IX,
+       FW_VI_VF_STAT_TX_DROP_FRAMES_IX,
+       FW_VI_VF_STAT_TX_OFLD_BYTES_IX,
+       FW_VI_VF_STAT_TX_OFLD_FRAMES_IX,
+       FW_VI_VF_STAT_RX_BCAST_BYTES_IX,
+       FW_VI_VF_STAT_RX_BCAST_FRAMES_IX,
+       FW_VI_VF_STAT_RX_MCAST_BYTES_IX,
+       FW_VI_VF_STAT_RX_MCAST_FRAMES_IX,
+       FW_VI_VF_STAT_RX_UCAST_BYTES_IX,
+       FW_VI_VF_STAT_RX_UCAST_FRAMES_IX,
+       FW_VI_VF_STAT_RX_ERR_FRAMES_IX
+};
+
+/* VI PF stats offset definitions */
+#define VI_PF_NUM_STATS        17
+enum fw_vi_stats_pf_index {
+       FW_VI_PF_STAT_TX_BCAST_BYTES_IX,
+       FW_VI_PF_STAT_TX_BCAST_FRAMES_IX,
+       FW_VI_PF_STAT_TX_MCAST_BYTES_IX,
+       FW_VI_PF_STAT_TX_MCAST_FRAMES_IX,
+       FW_VI_PF_STAT_TX_UCAST_BYTES_IX,
+       FW_VI_PF_STAT_TX_UCAST_FRAMES_IX,
+       FW_VI_PF_STAT_TX_OFLD_BYTES_IX,
+       FW_VI_PF_STAT_TX_OFLD_FRAMES_IX,
+       FW_VI_PF_STAT_RX_BYTES_IX,
+       FW_VI_PF_STAT_RX_FRAMES_IX,
+       FW_VI_PF_STAT_RX_BCAST_BYTES_IX,
+       FW_VI_PF_STAT_RX_BCAST_FRAMES_IX,
+       FW_VI_PF_STAT_RX_MCAST_BYTES_IX,
+       FW_VI_PF_STAT_RX_MCAST_FRAMES_IX,
+       FW_VI_PF_STAT_RX_UCAST_BYTES_IX,
+       FW_VI_PF_STAT_RX_UCAST_FRAMES_IX,
+       FW_VI_PF_STAT_RX_ERR_FRAMES_IX
+};
+
+struct fw_vi_stats_cmd {
+       __be32 op_to_viid;
+       __be32 retval_len16;
+       union fw_vi_stats {
+               struct fw_vi_stats_ctl {
+                       __be16 nstats_ix;
+                       __be16 r6;
+                       __be32 r7;
+                       __be64 stat0;
+                       __be64 stat1;
+                       __be64 stat2;
+                       __be64 stat3;
+                       __be64 stat4;
+                       __be64 stat5;
+               } ctl;
+               struct fw_vi_stats_pf {
+                       __be64 tx_bcast_bytes;
+                       __be64 tx_bcast_frames;
+                       __be64 tx_mcast_bytes;
+                       __be64 tx_mcast_frames;
+                       __be64 tx_ucast_bytes;
+                       __be64 tx_ucast_frames;
+                       __be64 tx_offload_bytes;
+                       __be64 tx_offload_frames;
+                       __be64 rx_pf_bytes;
+                       __be64 rx_pf_frames;
+                       __be64 rx_bcast_bytes;
+                       __be64 rx_bcast_frames;
+                       __be64 rx_mcast_bytes;
+                       __be64 rx_mcast_frames;
+                       __be64 rx_ucast_bytes;
+                       __be64 rx_ucast_frames;
+                       __be64 rx_err_frames;
+               } pf;
+               struct fw_vi_stats_vf {
+                       __be64 tx_bcast_bytes;
+                       __be64 tx_bcast_frames;
+                       __be64 tx_mcast_bytes;
+                       __be64 tx_mcast_frames;
+                       __be64 tx_ucast_bytes;
+                       __be64 tx_ucast_frames;
+                       __be64 tx_drop_frames;
+                       __be64 tx_offload_bytes;
+                       __be64 tx_offload_frames;
+                       __be64 rx_bcast_bytes;
+                       __be64 rx_bcast_frames;
+                       __be64 rx_mcast_bytes;
+                       __be64 rx_mcast_frames;
+                       __be64 rx_ucast_bytes;
+                       __be64 rx_ucast_frames;
+                       __be64 rx_err_frames;
+               } vf;
+       } u;
+};
+
+#define FW_VI_STATS_CMD_VIID(x) ((x) << 0)
+#define FW_VI_STATS_CMD_NSTATS(x) ((x) << 12)
+#define FW_VI_STATS_CMD_IX(x) ((x) << 0)
+
+struct fw_acl_mac_cmd {
+       __be32 op_to_vfn;
+       __be32 en_to_len16;
+       u8 nmac;
+       u8 r3[7];
+       __be16 r4;
+       u8 macaddr0[6];
+       __be16 r5;
+       u8 macaddr1[6];
+       __be16 r6;
+       u8 macaddr2[6];
+       __be16 r7;
+       u8 macaddr3[6];
+};
+
+#define FW_ACL_MAC_CMD_PFN(x) ((x) << 8)
+#define FW_ACL_MAC_CMD_VFN(x) ((x) << 0)
+#define FW_ACL_MAC_CMD_EN(x) ((x) << 31)
+
+struct fw_acl_vlan_cmd {
+       __be32 op_to_vfn;
+       __be32 en_to_len16;
+       u8 nvlan;
+       u8 dropnovlan_fm;
+       u8 r3_lo[6];
+       __be16 vlanid[16];
+};
+
+#define FW_ACL_VLAN_CMD_PFN(x) ((x) << 8)
+#define FW_ACL_VLAN_CMD_VFN(x) ((x) << 0)
+#define FW_ACL_VLAN_CMD_EN(x) ((x) << 31)
+#define FW_ACL_VLAN_CMD_DROPNOVLAN(x) ((x) << 7)
+#define FW_ACL_VLAN_CMD_FM(x) ((x) << 6)
+
+enum fw_port_cap {
+       FW_PORT_CAP_SPEED_100M          = 0x0001,
+       FW_PORT_CAP_SPEED_1G            = 0x0002,
+       FW_PORT_CAP_SPEED_2_5G          = 0x0004,
+       FW_PORT_CAP_SPEED_10G           = 0x0008,
+       FW_PORT_CAP_SPEED_40G           = 0x0010,
+       FW_PORT_CAP_SPEED_100G          = 0x0020,
+       FW_PORT_CAP_FC_RX               = 0x0040,
+       FW_PORT_CAP_FC_TX               = 0x0080,
+       FW_PORT_CAP_ANEG                = 0x0100,
+       FW_PORT_CAP_MDI_0               = 0x0200,
+       FW_PORT_CAP_MDI_1               = 0x0400,
+       FW_PORT_CAP_BEAN                = 0x0800,
+       FW_PORT_CAP_PMA_LPBK            = 0x1000,
+       FW_PORT_CAP_PCS_LPBK            = 0x2000,
+       FW_PORT_CAP_PHYXS_LPBK          = 0x4000,
+       FW_PORT_CAP_FAR_END_LPBK        = 0x8000,
+};
+
+enum fw_port_mdi {
+       FW_PORT_MDI_UNCHANGED,
+       FW_PORT_MDI_AUTO,
+       FW_PORT_MDI_F_STRAIGHT,
+       FW_PORT_MDI_F_CROSSOVER
+};
+
+#define FW_PORT_MDI(x) ((x) << 9)
+
+enum fw_port_action {
+       FW_PORT_ACTION_L1_CFG           = 0x0001,
+       FW_PORT_ACTION_L2_CFG           = 0x0002,
+       FW_PORT_ACTION_GET_PORT_INFO    = 0x0003,
+       FW_PORT_ACTION_L2_PPP_CFG       = 0x0004,
+       FW_PORT_ACTION_L2_DCB_CFG       = 0x0005,
+       FW_PORT_ACTION_LOW_PWR_TO_NORMAL = 0x0010,
+       FW_PORT_ACTION_L1_LOW_PWR_EN    = 0x0011,
+       FW_PORT_ACTION_L2_WOL_MODE_EN   = 0x0012,
+       FW_PORT_ACTION_LPBK_TO_NORMAL   = 0x0020,
+       FW_PORT_ACTION_L1_LPBK          = 0x0021,
+       FW_PORT_ACTION_L1_PMA_LPBK      = 0x0022,
+       FW_PORT_ACTION_L1_PCS_LPBK      = 0x0023,
+       FW_PORT_ACTION_L1_PHYXS_CSIDE_LPBK = 0x0024,
+       FW_PORT_ACTION_L1_PHYXS_ESIDE_LPBK = 0x0025,
+       FW_PORT_ACTION_PHY_RESET        = 0x0040,
+       FW_PORT_ACTION_PMA_RESET        = 0x0041,
+       FW_PORT_ACTION_PCS_RESET        = 0x0042,
+       FW_PORT_ACTION_PHYXS_RESET      = 0x0043,
+       FW_PORT_ACTION_DTEXS_REEST      = 0x0044,
+       FW_PORT_ACTION_AN_RESET         = 0x0045
+};
+
+enum fw_port_l2cfg_ctlbf {
+       FW_PORT_L2_CTLBF_OVLAN0 = 0x01,
+       FW_PORT_L2_CTLBF_OVLAN1 = 0x02,
+       FW_PORT_L2_CTLBF_OVLAN2 = 0x04,
+       FW_PORT_L2_CTLBF_OVLAN3 = 0x08,
+       FW_PORT_L2_CTLBF_IVLAN  = 0x10,
+       FW_PORT_L2_CTLBF_TXIPG  = 0x20
+};
+
+enum fw_port_dcb_cfg {
+       FW_PORT_DCB_CFG_PG      = 0x01,
+       FW_PORT_DCB_CFG_PFC     = 0x02,
+       FW_PORT_DCB_CFG_APPL    = 0x04
+};
+
+enum fw_port_dcb_cfg_rc {
+       FW_PORT_DCB_CFG_SUCCESS = 0x0,
+       FW_PORT_DCB_CFG_ERROR   = 0x1
+};
+
+struct fw_port_cmd {
+       __be32 op_to_portid;
+       __be32 action_to_len16;
+       union fw_port {
+               struct fw_port_l1cfg {
+                       __be32 rcap;
+                       __be32 r;
+               } l1cfg;
+               struct fw_port_l2cfg {
+                       __be16 ctlbf_to_ivlan0;
+                       __be16 ivlantype;
+                       __be32 txipg_pkd;
+                       __be16 ovlan0mask;
+                       __be16 ovlan0type;
+                       __be16 ovlan1mask;
+                       __be16 ovlan1type;
+                       __be16 ovlan2mask;
+                       __be16 ovlan2type;
+                       __be16 ovlan3mask;
+                       __be16 ovlan3type;
+               } l2cfg;
+               struct fw_port_info {
+                       __be32 lstatus_to_modtype;
+                       __be16 pcap;
+                       __be16 acap;
+               } info;
+               struct fw_port_ppp {
+                       __be32 pppen_to_ncsich;
+                       __be32 r11;
+               } ppp;
+               struct fw_port_dcb {
+                       __be16 cfg;
+                       u8 up_map;
+                       u8 sf_cfgrc;
+                       __be16 prot_ix;
+                       u8 pe7_to_pe0;
+                       u8 numTCPFCs;
+                       __be32 pgid0_to_pgid7;
+                       __be32 numTCs_oui;
+                       u8 pgpc[8];
+               } dcb;
+       } u;
+};
+
+#define FW_PORT_CMD_READ (1U << 22)
+
+#define FW_PORT_CMD_PORTID(x) ((x) << 0)
+#define FW_PORT_CMD_PORTID_GET(x) (((x) >> 0) & 0xf)
+
+#define FW_PORT_CMD_ACTION(x) ((x) << 16)
+
+#define FW_PORT_CMD_CTLBF(x) ((x) << 10)
+#define FW_PORT_CMD_OVLAN3(x) ((x) << 7)
+#define FW_PORT_CMD_OVLAN2(x) ((x) << 6)
+#define FW_PORT_CMD_OVLAN1(x) ((x) << 5)
+#define FW_PORT_CMD_OVLAN0(x) ((x) << 4)
+#define FW_PORT_CMD_IVLAN0(x) ((x) << 3)
+
+#define FW_PORT_CMD_TXIPG(x) ((x) << 19)
+
+#define FW_PORT_CMD_LSTATUS (1U << 31)
+#define FW_PORT_CMD_LSPEED(x) ((x) << 24)
+#define FW_PORT_CMD_LSPEED_GET(x) (((x) >> 24) & 0x3f)
+#define FW_PORT_CMD_TXPAUSE (1U << 23)
+#define FW_PORT_CMD_RXPAUSE (1U << 22)
+#define FW_PORT_CMD_MDIOCAP (1U << 21)
+#define FW_PORT_CMD_MDIOADDR_GET(x) (((x) >> 16) & 0x1f)
+#define FW_PORT_CMD_LPTXPAUSE (1U << 15)
+#define FW_PORT_CMD_LPRXPAUSE (1U << 14)
+#define FW_PORT_CMD_PTYPE_MASK 0x1f
+#define FW_PORT_CMD_PTYPE_GET(x) (((x) >> 8) & FW_PORT_CMD_PTYPE_MASK)
+#define FW_PORT_CMD_MODTYPE_MASK 0x1f
+#define FW_PORT_CMD_MODTYPE_GET(x) (((x) >> 0) & FW_PORT_CMD_MODTYPE_MASK)
+
+#define FW_PORT_CMD_PPPEN(x) ((x) << 31)
+#define FW_PORT_CMD_TPSRC(x) ((x) << 28)
+#define FW_PORT_CMD_NCSISRC(x) ((x) << 24)
+
+#define FW_PORT_CMD_CH0(x) ((x) << 20)
+#define FW_PORT_CMD_CH1(x) ((x) << 16)
+#define FW_PORT_CMD_CH2(x) ((x) << 12)
+#define FW_PORT_CMD_CH3(x) ((x) << 8)
+#define FW_PORT_CMD_NCSICH(x) ((x) << 4)
+
+enum fw_port_type {
+       FW_PORT_TYPE_FIBER,
+       FW_PORT_TYPE_KX4,
+       FW_PORT_TYPE_BT_SGMII,
+       FW_PORT_TYPE_KX,
+       FW_PORT_TYPE_BT_XAUI,
+       FW_PORT_TYPE_KR,
+       FW_PORT_TYPE_CX4,
+       FW_PORT_TYPE_TWINAX,
+
+       FW_PORT_TYPE_NONE = FW_PORT_CMD_PTYPE_MASK
+};
+
+enum fw_port_module_type {
+       FW_PORT_MOD_TYPE_NA,
+       FW_PORT_MOD_TYPE_LR,
+       FW_PORT_MOD_TYPE_SR,
+       FW_PORT_MOD_TYPE_ER,
+
+       FW_PORT_MOD_TYPE_NONE = FW_PORT_CMD_MODTYPE_MASK
+};
+
+/* port stats */
+#define FW_NUM_PORT_STATS 50
+#define FW_NUM_PORT_TX_STATS 23
+#define FW_NUM_PORT_RX_STATS 27
+
+enum fw_port_stats_tx_index {
+       FW_STAT_TX_PORT_BYTES_IX,
+       FW_STAT_TX_PORT_FRAMES_IX,
+       FW_STAT_TX_PORT_BCAST_IX,
+       FW_STAT_TX_PORT_MCAST_IX,
+       FW_STAT_TX_PORT_UCAST_IX,
+       FW_STAT_TX_PORT_ERROR_IX,
+       FW_STAT_TX_PORT_64B_IX,
+       FW_STAT_TX_PORT_65B_127B_IX,
+       FW_STAT_TX_PORT_128B_255B_IX,
+       FW_STAT_TX_PORT_256B_511B_IX,
+       FW_STAT_TX_PORT_512B_1023B_IX,
+       FW_STAT_TX_PORT_1024B_1518B_IX,
+       FW_STAT_TX_PORT_1519B_MAX_IX,
+       FW_STAT_TX_PORT_DROP_IX,
+       FW_STAT_TX_PORT_PAUSE_IX,
+       FW_STAT_TX_PORT_PPP0_IX,
+       FW_STAT_TX_PORT_PPP1_IX,
+       FW_STAT_TX_PORT_PPP2_IX,
+       FW_STAT_TX_PORT_PPP3_IX,
+       FW_STAT_TX_PORT_PPP4_IX,
+       FW_STAT_TX_PORT_PPP5_IX,
+       FW_STAT_TX_PORT_PPP6_IX,
+       FW_STAT_TX_PORT_PPP7_IX
+};
+
+enum fw_port_stat_rx_index {
+       FW_STAT_RX_PORT_BYTES_IX,
+       FW_STAT_RX_PORT_FRAMES_IX,
+       FW_STAT_RX_PORT_BCAST_IX,
+       FW_STAT_RX_PORT_MCAST_IX,
+       FW_STAT_RX_PORT_UCAST_IX,
+       FW_STAT_RX_PORT_MTU_ERROR_IX,
+       FW_STAT_RX_PORT_MTU_CRC_ERROR_IX,
+       FW_STAT_RX_PORT_CRC_ERROR_IX,
+       FW_STAT_RX_PORT_LEN_ERROR_IX,
+       FW_STAT_RX_PORT_SYM_ERROR_IX,
+       FW_STAT_RX_PORT_64B_IX,
+       FW_STAT_RX_PORT_65B_127B_IX,
+       FW_STAT_RX_PORT_128B_255B_IX,
+       FW_STAT_RX_PORT_256B_511B_IX,
+       FW_STAT_RX_PORT_512B_1023B_IX,
+       FW_STAT_RX_PORT_1024B_1518B_IX,
+       FW_STAT_RX_PORT_1519B_MAX_IX,
+       FW_STAT_RX_PORT_PAUSE_IX,
+       FW_STAT_RX_PORT_PPP0_IX,
+       FW_STAT_RX_PORT_PPP1_IX,
+       FW_STAT_RX_PORT_PPP2_IX,
+       FW_STAT_RX_PORT_PPP3_IX,
+       FW_STAT_RX_PORT_PPP4_IX,
+       FW_STAT_RX_PORT_PPP5_IX,
+       FW_STAT_RX_PORT_PPP6_IX,
+       FW_STAT_RX_PORT_PPP7_IX,
+       FW_STAT_RX_PORT_LESS_64B_IX
+};
+
+struct fw_port_stats_cmd {
+       __be32 op_to_portid;
+       __be32 retval_len16;
+       union fw_port_stats {
+               struct fw_port_stats_ctl {
+                       u8 nstats_bg_bm;
+                       u8 tx_ix;
+                       __be16 r6;
+                       __be32 r7;
+                       __be64 stat0;
+                       __be64 stat1;
+                       __be64 stat2;
+                       __be64 stat3;
+                       __be64 stat4;
+                       __be64 stat5;
+               } ctl;
+               struct fw_port_stats_all {
+                       __be64 tx_bytes;
+                       __be64 tx_frames;
+                       __be64 tx_bcast;
+                       __be64 tx_mcast;
+                       __be64 tx_ucast;
+                       __be64 tx_error;
+                       __be64 tx_64b;
+                       __be64 tx_65b_127b;
+                       __be64 tx_128b_255b;
+                       __be64 tx_256b_511b;
+                       __be64 tx_512b_1023b;
+                       __be64 tx_1024b_1518b;
+                       __be64 tx_1519b_max;
+                       __be64 tx_drop;
+                       __be64 tx_pause;
+                       __be64 tx_ppp0;
+                       __be64 tx_ppp1;
+                       __be64 tx_ppp2;
+                       __be64 tx_ppp3;
+                       __be64 tx_ppp4;
+                       __be64 tx_ppp5;
+                       __be64 tx_ppp6;
+                       __be64 tx_ppp7;
+                       __be64 rx_bytes;
+                       __be64 rx_frames;
+                       __be64 rx_bcast;
+                       __be64 rx_mcast;
+                       __be64 rx_ucast;
+                       __be64 rx_mtu_error;
+                       __be64 rx_mtu_crc_error;
+                       __be64 rx_crc_error;
+                       __be64 rx_len_error;
+                       __be64 rx_sym_error;
+                       __be64 rx_64b;
+                       __be64 rx_65b_127b;
+                       __be64 rx_128b_255b;
+                       __be64 rx_256b_511b;
+                       __be64 rx_512b_1023b;
+                       __be64 rx_1024b_1518b;
+                       __be64 rx_1519b_max;
+                       __be64 rx_pause;
+                       __be64 rx_ppp0;
+                       __be64 rx_ppp1;
+                       __be64 rx_ppp2;
+                       __be64 rx_ppp3;
+                       __be64 rx_ppp4;
+                       __be64 rx_ppp5;
+                       __be64 rx_ppp6;
+                       __be64 rx_ppp7;
+                       __be64 rx_less_64b;
+                       __be64 rx_bg_drop;
+                       __be64 rx_bg_trunc;
+               } all;
+       } u;
+};
+
+#define FW_PORT_STATS_CMD_NSTATS(x) ((x) << 4)
+#define FW_PORT_STATS_CMD_BG_BM(x) ((x) << 0)
+#define FW_PORT_STATS_CMD_TX(x) ((x) << 7)
+#define FW_PORT_STATS_CMD_IX(x) ((x) << 0)
+
+/* port loopback stats */
+#define FW_NUM_LB_STATS 16
+enum fw_port_lb_stats_index {
+       FW_STAT_LB_PORT_BYTES_IX,
+       FW_STAT_LB_PORT_FRAMES_IX,
+       FW_STAT_LB_PORT_BCAST_IX,
+       FW_STAT_LB_PORT_MCAST_IX,
+       FW_STAT_LB_PORT_UCAST_IX,
+       FW_STAT_LB_PORT_ERROR_IX,
+       FW_STAT_LB_PORT_64B_IX,
+       FW_STAT_LB_PORT_65B_127B_IX,
+       FW_STAT_LB_PORT_128B_255B_IX,
+       FW_STAT_LB_PORT_256B_511B_IX,
+       FW_STAT_LB_PORT_512B_1023B_IX,
+       FW_STAT_LB_PORT_1024B_1518B_IX,
+       FW_STAT_LB_PORT_1519B_MAX_IX,
+       FW_STAT_LB_PORT_DROP_FRAMES_IX
+};
+
+struct fw_port_lb_stats_cmd {
+       __be32 op_to_lbport;
+       __be32 retval_len16;
+       union fw_port_lb_stats {
+               struct fw_port_lb_stats_ctl {
+                       u8 nstats_bg_bm;
+                       u8 ix_pkd;
+                       __be16 r6;
+                       __be32 r7;
+                       __be64 stat0;
+                       __be64 stat1;
+                       __be64 stat2;
+                       __be64 stat3;
+                       __be64 stat4;
+                       __be64 stat5;
+               } ctl;
+               struct fw_port_lb_stats_all {
+                       __be64 tx_bytes;
+                       __be64 tx_frames;
+                       __be64 tx_bcast;
+                       __be64 tx_mcast;
+                       __be64 tx_ucast;
+                       __be64 tx_error;
+                       __be64 tx_64b;
+                       __be64 tx_65b_127b;
+                       __be64 tx_128b_255b;
+                       __be64 tx_256b_511b;
+                       __be64 tx_512b_1023b;
+                       __be64 tx_1024b_1518b;
+                       __be64 tx_1519b_max;
+                       __be64 rx_lb_drop;
+                       __be64 rx_lb_trunc;
+               } all;
+       } u;
+};
+
+#define FW_PORT_LB_STATS_CMD_LBPORT(x) ((x) << 0)
+#define FW_PORT_LB_STATS_CMD_NSTATS(x) ((x) << 4)
+#define FW_PORT_LB_STATS_CMD_BG_BM(x) ((x) << 0)
+#define FW_PORT_LB_STATS_CMD_IX(x) ((x) << 0)
+
+struct fw_rss_ind_tbl_cmd {
+       __be32 op_to_viid;
+#define FW_RSS_IND_TBL_CMD_VIID(x) ((x) << 0)
+       __be32 retval_len16;
+       __be16 niqid;
+       __be16 startidx;
+       __be32 r3;
+       __be32 iq0_to_iq2;
+#define FW_RSS_IND_TBL_CMD_IQ0(x) ((x) << 20)
+#define FW_RSS_IND_TBL_CMD_IQ1(x) ((x) << 10)
+#define FW_RSS_IND_TBL_CMD_IQ2(x) ((x) << 0)
+       __be32 iq3_to_iq5;
+       __be32 iq6_to_iq8;
+       __be32 iq9_to_iq11;
+       __be32 iq12_to_iq14;
+       __be32 iq15_to_iq17;
+       __be32 iq18_to_iq20;
+       __be32 iq21_to_iq23;
+       __be32 iq24_to_iq26;
+       __be32 iq27_to_iq29;
+       __be32 iq30_iq31;
+       __be32 r15_lo;
+};
+
+struct fw_rss_glb_config_cmd {
+       __be32 op_to_write;
+       __be32 retval_len16;
+       union fw_rss_glb_config {
+               struct fw_rss_glb_config_manual {
+                       __be32 mode_pkd;
+                       __be32 r3;
+                       __be64 r4;
+                       __be64 r5;
+               } manual;
+               struct fw_rss_glb_config_basicvirtual {
+                       __be32 mode_pkd;
+                       __be32 synmapen_to_hashtoeplitz;
+#define FW_RSS_GLB_CONFIG_CMD_SYNMAPEN      (1U << 8)
+#define FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6 (1U << 7)
+#define FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6 (1U << 6)
+#define FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4 (1U << 5)
+#define FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4 (1U << 4)
+#define FW_RSS_GLB_CONFIG_CMD_OFDMAPEN      (1U << 3)
+#define FW_RSS_GLB_CONFIG_CMD_TNLMAPEN      (1U << 2)
+#define FW_RSS_GLB_CONFIG_CMD_TNLALLLKP     (1U << 1)
+#define FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ  (1U << 0)
+                       __be64 r8;
+                       __be64 r9;
+               } basicvirtual;
+       } u;
+};
+
+#define FW_RSS_GLB_CONFIG_CMD_MODE(x)  ((x) << 28)
+
+#define FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL      0
+#define FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL        1
+
+struct fw_rss_vi_config_cmd {
+       __be32 op_to_viid;
+#define FW_RSS_VI_CONFIG_CMD_VIID(x) ((x) << 0)
+       __be32 retval_len16;
+       union fw_rss_vi_config {
+               struct fw_rss_vi_config_manual {
+                       __be64 r3;
+                       __be64 r4;
+                       __be64 r5;
+               } manual;
+               struct fw_rss_vi_config_basicvirtual {
+                       __be32 r6;
+                       __be32 defaultq_to_ip4udpen;
+#define FW_RSS_VI_CONFIG_CMD_DEFAULTQ(x)  ((x) << 16)
+#define FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN (1U << 4)
+#define FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN  (1U << 3)
+#define FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN (1U << 2)
+#define FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN  (1U << 1)
+#define FW_RSS_VI_CONFIG_CMD_IP4UDPEN     (1U << 0)
+                       __be64 r9;
+                       __be64 r10;
+               } basicvirtual;
+       } u;
+};
+
+enum fw_error_type {
+       FW_ERROR_TYPE_EXCEPTION         = 0x0,
+       FW_ERROR_TYPE_HWMODULE          = 0x1,
+       FW_ERROR_TYPE_WR                = 0x2,
+       FW_ERROR_TYPE_ACL               = 0x3,
+};
+
+struct fw_error_cmd {
+       __be32 op_to_type;
+       __be32 len16_pkd;
+       union fw_error {
+               struct fw_error_exception {
+                       __be32 info[6];
+               } exception;
+               struct fw_error_hwmodule {
+                       __be32 regaddr;
+                       __be32 regval;
+               } hwmodule;
+               struct fw_error_wr {
+                       __be16 cidx;
+                       __be16 pfn_vfn;
+                       __be32 eqid;
+                       u8 wrhdr[16];
+               } wr;
+               struct fw_error_acl {
+                       __be16 cidx;
+                       __be16 pfn_vfn;
+                       __be32 eqid;
+                       __be16 mv_pkd;
+                       u8 val[6];
+                       __be64 r4;
+               } acl;
+       } u;
+};
+
+struct fw_debug_cmd {
+       __be32 op_type;
+#define FW_DEBUG_CMD_TYPE_GET(x) ((x) & 0xff)
+       __be32 len16_pkd;
+       union fw_debug {
+               struct fw_debug_assert {
+                       __be32 fcid;
+                       __be32 line;
+                       __be32 x;
+                       __be32 y;
+                       u8 filename_0_7[8];
+                       u8 filename_8_15[8];
+                       __be64 r3;
+               } assert;
+               struct fw_debug_prt {
+                       __be16 dprtstridx;
+                       __be16 r3[3];
+                       __be32 dprtstrparam0;
+                       __be32 dprtstrparam1;
+                       __be32 dprtstrparam2;
+                       __be32 dprtstrparam3;
+               } prt;
+       } u;
+};
+
+struct fw_hdr {
+       u8 ver;
+       u8 reserved1;
+       __be16  len512;                 /* bin length in units of 512-bytes */
+       __be32  fw_ver;                 /* firmware version */
+       __be32  tp_microcode_ver;
+       u8 intfver_nic;
+       u8 intfver_vnic;
+       u8 intfver_ofld;
+       u8 intfver_ri;
+       u8 intfver_iscsipdu;
+       u8 intfver_iscsi;
+       u8 intfver_fcoe;
+       u8 reserved2;
+       __be32  reserved3[27];
+};
+
+#define FW_HDR_FW_VER_MAJOR_GET(x) (((x) >> 24) & 0xff)
+#define FW_HDR_FW_VER_MINOR_GET(x) (((x) >> 16) & 0xff)
+#define FW_HDR_FW_VER_MICRO_GET(x) (((x) >> 8) & 0xff)
+#define FW_HDR_FW_VER_BUILD_GET(x) (((x) >> 0) & 0xff)
+#endif /* _T4FW_INTERFACE_H_ */
index 8bd086aee56dc02144ba68b4ab2d958a7783c5c8..2b8edd2efbf608994946f1a1cb9ae40f71938ae7 100644 (file)
  *     PHY layer usage
  */
 
-/** Pending Items in this driver:
- * 1. Use Linux cache infrastcture for DMA'ed memory (dma_xxx functions)
- */
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -504,12 +500,6 @@ static unsigned long mdio_max_freq;
 
 /* Cache macros - Packet buffers would be from skb pool which is cached */
 #define EMAC_VIRT_NOCACHE(addr) (addr)
-#define EMAC_CACHE_INVALIDATE(addr, size) \
-       dma_cache_maint((void *)addr, size, DMA_FROM_DEVICE)
-#define EMAC_CACHE_WRITEBACK(addr, size) \
-       dma_cache_maint((void *)addr, size, DMA_TO_DEVICE)
-#define EMAC_CACHE_WRITEBACK_INVALIDATE(addr, size) \
-       dma_cache_maint((void *)addr, size, DMA_BIDIRECTIONAL)
 
 /* DM644x does not have BD's in cached memory - so no cache functions */
 #define BD_CACHE_INVALIDATE(addr, size)
@@ -1235,6 +1225,10 @@ static void emac_txch_teardown(struct emac_priv *priv, u32 ch)
        if (1 == txch->queue_active) {
                curr_bd = txch->active_queue_head;
                while (curr_bd != NULL) {
+                       dma_unmap_single(emac_dev, curr_bd->buff_ptr,
+                               curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE,
+                               DMA_TO_DEVICE);
+
                        emac_net_tx_complete(priv, (void __force *)
                                        &curr_bd->buf_token, 1, ch);
                        if (curr_bd != txch->active_queue_tail)
@@ -1327,6 +1321,11 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
                                txch->queue_active = 0; /* end of queue */
                        }
                }
+
+               dma_unmap_single(emac_dev, curr_bd->buff_ptr,
+                               curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE,
+                               DMA_TO_DEVICE);
+
                *tx_complete_ptr = (u32) curr_bd->buf_token;
                ++tx_complete_ptr;
                ++tx_complete_cnt;
@@ -1387,8 +1386,8 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch)
 
        txch->bd_pool_head = curr_bd->next;
        curr_bd->buf_token = buf_list->buf_token;
-       /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */
-       curr_bd->buff_ptr = virt_to_phys(buf_list->data_ptr);
+       curr_bd->buff_ptr = dma_map_single(&priv->ndev->dev, buf_list->data_ptr,
+                       buf_list->length, DMA_TO_DEVICE);
        curr_bd->off_b_len = buf_list->length;
        curr_bd->h_next = 0;
        curr_bd->next = NULL;
@@ -1468,7 +1467,6 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev)
        tx_buf.length = skb->len;
        tx_buf.buf_token = (void *)skb;
        tx_buf.data_ptr = skb->data;
-       EMAC_CACHE_WRITEBACK((unsigned long)skb->data, skb->len);
        ndev->trans_start = jiffies;
        ret_code = emac_send(priv, &tx_packet, EMAC_DEF_TX_CH);
        if (unlikely(ret_code != 0)) {
@@ -1543,7 +1541,6 @@ static void *emac_net_alloc_rx_buf(struct emac_priv *priv, int buf_size,
        p_skb->dev = ndev;
        skb_reserve(p_skb, NET_IP_ALIGN);
        *data_token = (void *) p_skb;
-       EMAC_CACHE_WRITEBACK_INVALIDATE((unsigned long)p_skb->data, buf_size);
        return p_skb->data;
 }
 
@@ -1612,8 +1609,8 @@ static int emac_init_rxch(struct emac_priv *priv, u32 ch, char *param)
                /* populate the hardware descriptor */
                curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head,
                                priv);
-               /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */
-               curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr);
+               curr_bd->buff_ptr = dma_map_single(emac_dev, curr_bd->data_ptr,
+                               rxch->buf_size, DMA_FROM_DEVICE);
                curr_bd->off_b_len = rxch->buf_size;
                curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
 
@@ -1697,6 +1694,12 @@ static void emac_cleanup_rxch(struct emac_priv *priv, u32 ch)
                curr_bd = rxch->active_queue_head;
                while (curr_bd) {
                        if (curr_bd->buf_token) {
+                               dma_unmap_single(&priv->ndev->dev,
+                                       curr_bd->buff_ptr,
+                                       curr_bd->off_b_len
+                                               & EMAC_RX_BD_BUF_SIZE,
+                                       DMA_FROM_DEVICE);
+
                                dev_kfree_skb_any((struct sk_buff *)\
                                                  curr_bd->buf_token);
                        }
@@ -1871,8 +1874,8 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch,
 
        /* populate the hardware descriptor */
        curr_bd->h_next = 0;
-       /* FIXME buff_ptr = dma_map_single(... buffer ...) */
-       curr_bd->buff_ptr = virt_to_phys(buffer);
+       curr_bd->buff_ptr = dma_map_single(&priv->ndev->dev, buffer,
+                               rxch->buf_size, DMA_FROM_DEVICE);
        curr_bd->off_b_len = rxch->buf_size;
        curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
        curr_bd->next = NULL;
@@ -1927,7 +1930,6 @@ static int emac_net_rx_cb(struct emac_priv *priv,
        p_skb = (struct sk_buff *)net_pkt_list->pkt_token;
        /* set length of packet */
        skb_put(p_skb, net_pkt_list->pkt_length);
-       EMAC_CACHE_INVALIDATE((unsigned long)p_skb->data, p_skb->len);
        p_skb->protocol = eth_type_trans(p_skb, priv->ndev);
        netif_receive_skb(p_skb);
        priv->net_dev_stats.rx_bytes += net_pkt_list->pkt_length;
@@ -1990,6 +1992,11 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
                rx_buf_obj->data_ptr = (char *)curr_bd->data_ptr;
                rx_buf_obj->length = curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE;
                rx_buf_obj->buf_token = curr_bd->buf_token;
+
+               dma_unmap_single(&priv->ndev->dev, curr_bd->buff_ptr,
+                               curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE,
+                               DMA_FROM_DEVICE);
+
                curr_pkt->pkt_token = curr_pkt->buf_list->buf_token;
                curr_pkt->num_bufs = 1;
                curr_pkt->pkt_length =
@@ -2820,31 +2827,37 @@ static int __devexit davinci_emac_remove(struct platform_device *pdev)
        return 0;
 }
 
-static
-int davinci_emac_suspend(struct platform_device *pdev, pm_message_t state)
+static int davinci_emac_suspend(struct device *dev)
 {
-       struct net_device *dev = platform_get_drvdata(pdev);
+       struct platform_device *pdev = to_platform_device(dev);
+       struct net_device *ndev = platform_get_drvdata(pdev);
 
-       if (netif_running(dev))
-               emac_dev_stop(dev);
+       if (netif_running(ndev))
+               emac_dev_stop(ndev);
 
        clk_disable(emac_clk);
 
        return 0;
 }
 
-static int davinci_emac_resume(struct platform_device *pdev)
+static int davinci_emac_resume(struct device *dev)
 {
-       struct net_device *dev = platform_get_drvdata(pdev);
+       struct platform_device *pdev = to_platform_device(dev);
+       struct net_device *ndev = platform_get_drvdata(pdev);
 
        clk_enable(emac_clk);
 
-       if (netif_running(dev))
-               emac_dev_open(dev);
+       if (netif_running(ndev))
+               emac_dev_open(ndev);
 
        return 0;
 }
 
+static const struct dev_pm_ops davinci_emac_pm_ops = {
+       .suspend        = davinci_emac_suspend,
+       .resume         = davinci_emac_resume,
+};
+
 /**
  * davinci_emac_driver: EMAC platform driver structure
  */
@@ -2852,11 +2865,10 @@ static struct platform_driver davinci_emac_driver = {
        .driver = {
                .name    = "davinci_emac",
                .owner   = THIS_MODULE,
+               .pm      = &davinci_emac_pm_ops,
        },
        .probe = davinci_emac_probe,
        .remove = __devexit_p(davinci_emac_remove),
-       .suspend = davinci_emac_suspend,
-       .resume = davinci_emac_resume,
 };
 
 /**
index 1c67f1138ca7edb90b56124d08da15c80e7ce0c3..7f9960f718e35972dabedc30fb3f8faa3f7a3155 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 
 #include <asm/delay.h>
 #include <asm/irq.h>
index a26ccab057d56fe305c760eb4e64ac4744c3e4e2..791080303db100cf7f5f53d961253846e6e3049e 100644 (file)
 #include <linux/ethtool.h>
 #include <linux/string.h>
 #include <linux/firmware.h>
+#include <linux/rtnetlink.h>
 #include <asm/unaligned.h>
 
 
@@ -2265,8 +2266,13 @@ static void e100_tx_timeout_task(struct work_struct *work)
 
        DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n",
                ioread8(&nic->csr->scb.status));
-       e100_down(netdev_priv(netdev));
-       e100_up(netdev_priv(netdev));
+
+       rtnl_lock();
+       if (netif_running(netdev)) {
+               e100_down(netdev_priv(netdev));
+               e100_up(netdev_priv(netdev));
+       }
+       rtnl_unlock();
 }
 
 static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
@@ -2858,7 +2864,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
        }
        nic->cbs_pool = pci_pool_create(netdev->name,
                           nic->pdev,
-                          nic->params.cbs.count * sizeof(struct cb),
+                          nic->params.cbs.max * sizeof(struct cb),
                           sizeof(u32),
                           0);
        DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n",
index 9902b33b716052f7974cad7126b923a3068a27be..2f29c213185113c4d36eb095cc88b1190bef6603 100644 (file)
@@ -261,7 +261,6 @@ struct e1000_adapter {
        /* TX */
        struct e1000_tx_ring *tx_ring;      /* One per active queue */
        unsigned int restart_queue;
-       unsigned long tx_queue_len;
        u32 txd_cmd;
        u32 tx_int_delay;
        u32 tx_abs_int_delay;
index 8be6faee43e6e519519d015dd6c1d63a864d7b05..b15ece26ed8469136df4d40eced1b98839e4acce 100644 (file)
@@ -383,8 +383,6 @@ static void e1000_configure(struct e1000_adapter *adapter)
                adapter->alloc_rx_buf(adapter, ring,
                                      E1000_DESC_UNUSED(ring));
        }
-
-       adapter->tx_queue_len = netdev->tx_queue_len;
 }
 
 int e1000_up(struct e1000_adapter *adapter)
@@ -503,7 +501,6 @@ void e1000_down(struct e1000_adapter *adapter)
        del_timer_sync(&adapter->watchdog_timer);
        del_timer_sync(&adapter->phy_info_timer);
 
-       netdev->tx_queue_len = adapter->tx_queue_len;
        adapter->link_speed = 0;
        adapter->link_duplex = 0;
        netif_carrier_off(netdev);
@@ -2316,19 +2313,15 @@ static void e1000_watchdog(unsigned long data)
                                E1000_CTRL_RFCE) ? "RX" : ((ctrl &
                                E1000_CTRL_TFCE) ? "TX" : "None" )));
 
-                       /* tweak tx_queue_len according to speed/duplex
-                        * and adjust the timeout factor */
-                       netdev->tx_queue_len = adapter->tx_queue_len;
+                       /* adjust timeout factor according to speed/duplex */
                        adapter->tx_timeout_factor = 1;
                        switch (adapter->link_speed) {
                        case SPEED_10:
                                txb2b = false;
-                               netdev->tx_queue_len = 10;
                                adapter->tx_timeout_factor = 16;
                                break;
                        case SPEED_100:
                                txb2b = false;
-                               netdev->tx_queue_len = 100;
                                /* maybe add some timeout factor ? */
                                break;
                        }
index 712ccc66ba25b5f1a6b1059a2b7e537a91aad7db..90155552ea0927670fdf412b647c2ae54d3e6af4 100644 (file)
@@ -336,7 +336,6 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
        struct e1000_hw *hw = &adapter->hw;
        static int global_quad_port_a; /* global port a indication */
        struct pci_dev *pdev = adapter->pdev;
-       u16 eeprom_data = 0;
        int is_port_b = er32(STATUS) & E1000_STATUS_FUNC_1;
        s32 rc;
 
@@ -387,16 +386,15 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
                if (pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD)
                        adapter->flags &= ~FLAG_HAS_WOL;
                break;
-
        case e1000_82573:
+       case e1000_82574:
+       case e1000_82583:
+               /* Disable ASPM L0s due to hardware errata */
+               e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L0S);
+
                if (pdev->device == E1000_DEV_ID_82573L) {
-                       if (e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1,
-                                      &eeprom_data) < 0)
-                               break;
-                       if (!(eeprom_data & NVM_WORD1A_ASPM_MASK)) {
-                               adapter->flags |= FLAG_HAS_JUMBO_FRAMES;
-                               adapter->max_hw_frame_size = DEFAULT_JUMBO;
-                       }
+                       adapter->flags |= FLAG_HAS_JUMBO_FRAMES;
+                       adapter->max_hw_frame_size = DEFAULT_JUMBO;
                }
                break;
        default:
@@ -1792,6 +1790,7 @@ struct e1000_info e1000_82571_info = {
                                  | FLAG_RESET_OVERWRITES_LAA /* errata */
                                  | FLAG_TARC_SPEED_MODE_BIT /* errata */
                                  | FLAG_APME_CHECK_PORT_B,
+       .flags2                 = FLAG2_DISABLE_ASPM_L1, /* errata 13 */
        .pba                    = 38,
        .max_hw_frame_size      = DEFAULT_JUMBO,
        .get_variants           = e1000_get_variants_82571,
@@ -1809,6 +1808,7 @@ struct e1000_info e1000_82572_info = {
                                  | FLAG_RX_CSUM_ENABLED
                                  | FLAG_HAS_CTRLEXT_ON_LOAD
                                  | FLAG_TARC_SPEED_MODE_BIT, /* errata */
+       .flags2                 = FLAG2_DISABLE_ASPM_L1, /* errata 13 */
        .pba                    = 38,
        .max_hw_frame_size      = DEFAULT_JUMBO,
        .get_variants           = e1000_get_variants_82571,
@@ -1820,13 +1820,11 @@ struct e1000_info e1000_82572_info = {
 struct e1000_info e1000_82573_info = {
        .mac                    = e1000_82573,
        .flags                  = FLAG_HAS_HW_VLAN_FILTER
-                                 | FLAG_HAS_JUMBO_FRAMES
                                  | FLAG_HAS_WOL
                                  | FLAG_APME_IN_CTRL3
                                  | FLAG_RX_CSUM_ENABLED
                                  | FLAG_HAS_SMART_POWER_DOWN
                                  | FLAG_HAS_AMT
-                                 | FLAG_HAS_ERT
                                  | FLAG_HAS_SWSM_ON_LOAD,
        .pba                    = 20,
        .max_hw_frame_size      = ETH_FRAME_LEN + ETH_FCS_LEN,
index c2ec095d2163980953e0bd4ad464fdb8736a9450..ee32b9b27a9fc7c8eda3b74931a887db2a0ae98b 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/io.h>
 #include <linux/netdevice.h>
 #include <linux/pci.h>
+#include <linux/pci-aspm.h>
 
 #include "hw.h"
 
@@ -279,7 +280,6 @@ struct e1000_adapter {
 
        struct napi_struct napi;
 
-       unsigned long tx_queue_len;
        unsigned int restart_queue;
        u32 txd_cmd;
 
@@ -375,7 +375,7 @@ struct e1000_adapter {
 struct e1000_info {
        enum e1000_mac_type     mac;
        unsigned int            flags;
-       unsigned int            flags2;
+       unsigned int            flags2;
        u32                     pba;
        u32                     max_hw_frame_size;
        s32                     (*get_variants)(struct e1000_adapter *);
@@ -422,6 +422,7 @@ struct e1000_info {
 #define FLAG2_CRC_STRIPPING               (1 << 0)
 #define FLAG2_HAS_PHY_WAKEUP              (1 << 1)
 #define FLAG2_IS_DISCARDING               (1 << 2)
+#define FLAG2_DISABLE_ASPM_L1             (1 << 3)
 
 #define E1000_RX_DESC_PS(R, i)     \
        (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
@@ -462,6 +463,7 @@ extern void e1000e_update_stats(struct e1000_adapter *adapter);
 extern bool e1000e_has_link(struct e1000_adapter *adapter);
 extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter);
 extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter);
+extern void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
 
 extern unsigned int copybreak;
 
index b33e3cbe9ab03dd22fb8d97c104b9080e94b2b68..983493f2330c37e6e89fb89e1525310ed779c6f2 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 
 #include "e1000.h"
index 88d54d3efcef2ff78bd66bd2cd358c8809c22820..dbf81788bb406f29e7bf9f5c3c3f50ab22016c16 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/netdevice.h>
 #include <linux/tcp.h>
 #include <linux/ipv6.h>
+#include <linux/slab.h>
 #include <net/checksum.h>
 #include <net/ip6_checksum.h>
 #include <linux/mii.h>
@@ -660,6 +661,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
                                i = 0;
                }
 
+               if (i == tx_ring->next_to_use)
+                       break;
                eop = tx_ring->buffer_info[i].next_to_watch;
                eop_desc = E1000_TX_DESC(*tx_ring, eop);
        }
@@ -2289,8 +2292,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
        ew32(TCTL, tctl);
 
        e1000e_config_collision_dist(hw);
-
-       adapter->tx_queue_len = adapter->netdev->tx_queue_len;
 }
 
 /**
@@ -2877,7 +2878,6 @@ void e1000e_down(struct e1000_adapter *adapter)
        del_timer_sync(&adapter->watchdog_timer);
        del_timer_sync(&adapter->phy_info_timer);
 
-       netdev->tx_queue_len = adapter->tx_queue_len;
        netif_carrier_off(netdev);
        adapter->link_speed = 0;
        adapter->link_duplex = 0;
@@ -3588,21 +3588,15 @@ static void e1000_watchdog_task(struct work_struct *work)
                                               "link gets many collisions.\n");
                        }
 
-                       /*
-                        * tweak tx_queue_len according to speed/duplex
-                        * and adjust the timeout factor
-                        */
-                       netdev->tx_queue_len = adapter->tx_queue_len;
+                       /* adjust timeout factor according to speed/duplex */
                        adapter->tx_timeout_factor = 1;
                        switch (adapter->link_speed) {
                        case SPEED_10:
                                txb2b = 0;
-                               netdev->tx_queue_len = 10;
                                adapter->tx_timeout_factor = 16;
                                break;
                        case SPEED_100:
                                txb2b = 0;
-                               netdev->tx_queue_len = 100;
                                adapter->tx_timeout_factor = 10;
                                break;
                        }
@@ -4289,6 +4283,14 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
                return -EINVAL;
        }
 
+       /* 82573 Errata 17 */
+       if (((adapter->hw.mac.type == e1000_82573) ||
+            (adapter->hw.mac.type == e1000_82574)) &&
+           (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN)) {
+               adapter->flags2 |= FLAG2_DISABLE_ASPM_L1;
+               e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L1);
+       }
+
        while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
                msleep(1);
        /* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
@@ -4611,29 +4613,42 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
        }
 }
 
-static void e1000e_disable_l1aspm(struct pci_dev *pdev)
+#ifdef CONFIG_PCIEASPM
+static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
+{
+       pci_disable_link_state(pdev, state);
+}
+#else
+static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
 {
        int pos;
-       u16 val;
+       u16 reg16;
 
        /*
-        * 82573 workaround - disable L1 ASPM on mobile chipsets
-        *
-        * L1 ASPM on various mobile (ich7) chipsets do not behave properly
-        * resulting in lost data or garbage information on the pci-e link
-        * level. This could result in (false) bad EEPROM checksum errors,
-        * long ping times (up to 2s) or even a system freeze/hang.
-        *
-        * Unfortunately this feature saves about 1W power consumption when
-        * active.
+        * Both device and parent should have the same ASPM setting.
+        * Disable ASPM in downstream component first and then upstream.
         */
-       pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
-       pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val);
-       if (val & 0x2) {
-               dev_warn(&pdev->dev, "Disabling L1 ASPM\n");
-               val &= ~0x2;
-               pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, val);
-       }
+       pos = pci_pcie_cap(pdev);
+       pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
+       reg16 &= ~state;
+       pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
+
+       if (!pdev->bus->self)
+               return;
+
+       pos = pci_pcie_cap(pdev->bus->self);
+       pci_read_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, &reg16);
+       reg16 &= ~state;
+       pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16);
+}
+#endif
+void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
+{
+       dev_info(&pdev->dev, "Disabling ASPM %s %s\n",
+                (state & PCIE_LINK_STATE_L0S) ? "L0s" : "",
+                (state & PCIE_LINK_STATE_L1) ? "L1" : "");
+
+       __e1000e_disable_aspm(pdev, state);
 }
 
 #ifdef CONFIG_PM
@@ -4659,7 +4674,8 @@ static int e1000_resume(struct pci_dev *pdev)
        pci_set_power_state(pdev, PCI_D0);
        pci_restore_state(pdev);
        pci_save_state(pdev);
-       e1000e_disable_l1aspm(pdev);
+       if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
+               e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
 
        err = pci_enable_device_mem(pdev);
        if (err) {
@@ -4801,7 +4817,8 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
        int err;
        pci_ers_result_t result;
 
-       e1000e_disable_l1aspm(pdev);
+       if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
+               e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
        err = pci_enable_device_mem(pdev);
        if (err) {
                dev_err(&pdev->dev,
@@ -4895,13 +4912,6 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter)
                dev_warn(&adapter->pdev->dev,
                         "Warning: detected DSPD enabled in EEPROM\n");
        }
-
-       ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf);
-       if (!ret_val && (le16_to_cpu(buf) & (3 << 2))) {
-               /* ASPM enable */
-               dev_warn(&adapter->pdev->dev,
-                        "Warning: detected ASPM enabled in EEPROM\n");
-       }
 }
 
 static const struct net_device_ops e1000e_netdev_ops = {
@@ -4950,7 +4960,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        u16 eeprom_data = 0;
        u16 eeprom_apme_mask = E1000_EEPROM_APME;
 
-       e1000e_disable_l1aspm(pdev);
+       if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
+               e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
 
        err = pci_enable_device_mem(pdev);
        if (err)
index 1b05bdf62c3ceffb6f8f61a215d3c34585c7d56c..27c7bdbfa0030a2d6274716d6c91eaa0fb926341 100644 (file)
@@ -137,7 +137,6 @@ static const char version[] =
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
index 7013dc8a6cbcde21c52f338aa456f536b4633dc6..1a7322b80ea7e6dfee43d84f7a0d793753d26fdd 100644 (file)
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/mca-legacy.h>
 #include <linux/spinlock.h>
 #include <linux/bitops.h>
index b004eaba3d7bc334f12d8136961cf50cb8e8133e..809ccc9ff09cc8913a8e19ab1982cf76e7d69000 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/udp.h>
 #include <linux/if.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/if_ether.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
index 18d405f78c0f953f402f93da0dcb260af070a0d0..a1b4c7e563679f854b698e7f5f5f0f585a2d9fa6 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include "ehea.h"
 #include "ehea_phyp.h"
 #include "ehea_qmr.h"
index 3ee32e58c7ecaeba0ff0d5ce51f618e95ab95833..ff27f728fd9db290132db8f6a0a91952a1962079 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/init.h>
index 69b9b70c7da08c441f5cfa77c45a4ab1e3ab9745..cf22de71014e2ef5729928766d085ea0b1aa1d56 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/if_ether.h>
+#include <linux/slab.h>
 
 #include "vnic_resource.h"
 #include "vnic_devcmd.h"
index 75583978a5e54f01fd37f6f921fab22027ccb641..e186efaf9da1fc0c5d552fdb90aac7885b553a86 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "vnic_dev.h"
 #include "vnic_rq.h"
index d2e00e51b7b56a1fdafb032b0cc9332b60b54efe..d5f984357f5cb2437a3a48172e75bcaf93f77db1 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "vnic_dev.h"
 #include "vnic_wq.h"
index 39c271b6be443a689d5eacc6cf32cdeed2ba6b4a..7a567201e8295f8c17763c2f350e96f3b8495a0c 100644 (file)
@@ -73,7 +73,6 @@ static int rx_copybreak;
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
index f5b96cadeb2544994c4aadeeb45f30113c082116..b34a2ddeef4c810b37dca41faad2ed4cc12955b9 100644 (file)
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/netdevice.h>
 #include <net/net_namespace.h>
index d3abeee3f1104d390e5f9e0f8e87e78d116a3ae1..d4e24f08b3ba3bb0c51d925109cd0ffc88964b1c 100644 (file)
@@ -152,7 +152,6 @@ static char *version =
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/init.h>
index 209742304e209121dc314a80099494a62558d329..a8d92503226e3d00a9e68ade94e97a2b892ec1cc 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/phy.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <net/ethoc.h>
 
 static int buffer_size = 0x8000; /* 32 KBytes */
index 9d5ad08a119f4c73a71fb1857840900b14e33729..d11ae5197f01533f20cf141f023d1516b2b37765 100644 (file)
@@ -74,7 +74,6 @@ static int full_duplex[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
index 9f98c1c4a344e21cc558e090ee3e2be313ccd8c5..9b4e8f797a7ad76d7ae8c36b8efe5d08a94f530d 100644 (file)
@@ -1653,7 +1653,7 @@ fec_set_mac_address(struct net_device *dev, void *p)
                (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24),
                fep->hwp + FEC_ADDR_LOW);
        writel((dev->dev_addr[5] << 16) | (dev->dev_addr[4] << 24),
-               fep + FEC_ADDR_HIGH);
+               fep->hwp + FEC_ADDR_HIGH);
        return 0;
 }
 
index 0dbd7219bbde2fa067134666cab69bc37325a147..4a43e56b739496fddaf8daba5202f2f20831271d 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
index ee0f3c6d3f888e636c6da076a83d5b3ac4187d72..7658a082e390cd4c8d86c066cdf0d76aa1d72d80 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/netdevice.h>
 #include <linux/phy.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 #include <linux/of_mdio.h>
 #include <asm/io.h>
 #include <asm/mpc52xx.h>
index ca05e5662029d8a4566a2d95fbcde3a55ba27ce3..5c98f7c22425ee0c0209205219ea53075c9577cc 100644 (file)
@@ -59,6 +59,7 @@
 #include <linux/init.h>
 #include <linux/if_vlan.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 #include <asm/io.h>
@@ -5898,7 +5899,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
        /* Limit the number of tx's outstanding for hw bug */
        if (id->driver_data & DEV_NEED_TX_LIMIT) {
                np->tx_limit = 1;
-               if ((id->driver_data & DEV_NEED_TX_LIMIT2) &&
+               if (((id->driver_data & DEV_NEED_TX_LIMIT2) == DEV_NEED_TX_LIMIT2) &&
                    pci_dev->revision >= 0xA2)
                        np->tx_limit = 0;
        }
index cf4f674f9e2eed1cc66600881b3f819434dfe007..0a973e71876b591e2fc371e90dd1a8437ced969d 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
@@ -34,6 +33,7 @@
 #include <linux/platform_device.h>
 #include <linux/phy.h>
 #include <linux/of_device.h>
+#include <linux/gfp.h>
 
 #include <asm/immap_cpm2.h>
 #include <asm/mpc8260.h>
index cd2c6cca5f2425d2333ffd91ba76b39cdf8bfdf5..ec81f50d59196aac31d58fcc6146a9a44e72f01b 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
@@ -33,6 +32,7 @@
 #include <linux/fs.h>
 #include <linux/platform_device.h>
 #include <linux/of_device.h>
+#include <linux/gfp.h>
 
 #include <asm/irq.h>
 #include <asm/uaccess.h>
index c490a466cae15010403f091ce77160deb40250f9..34d3da751eb4001bc8925848de903cc7ce4a9270 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index d5160edf2fcf2d06d319f0f26be3da2d68016bc2..3acac5f930c8f7d3fd8563d46d046df94725673d 100644 (file)
@@ -205,8 +205,6 @@ static int fsl_pq_mdio_find_free(struct mii_bus *new_bus)
 static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct device_node *np)
 {
        struct gfar __iomem *enet_regs;
-       u32 __iomem *ioremap_tbipa;
-       u64 addr, size;
 
        /*
         * This is mildly evil, but so is our hardware for doing this.
@@ -220,9 +218,7 @@ static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct devi
                return &enet_regs->tbipa;
        } else if (of_device_is_compatible(np, "fsl,etsec2-mdio") ||
                        of_device_is_compatible(np, "fsl,etsec2-tbi")) {
-               addr = of_translate_address(np, of_get_address(np, 1, &size, NULL));
-               ioremap_tbipa = ioremap(addr, size);
-               return ioremap_tbipa;
+               return of_iomap(np, 1);
        } else
                return NULL;
 }
@@ -279,6 +275,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
        u32 __iomem *tbipa;
        struct mii_bus *new_bus;
        int tbiaddr = -1;
+       const u32 *addrp;
        u64 addr = 0, size = 0;
        int err = 0;
 
@@ -297,8 +294,19 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
        new_bus->priv = priv;
        fsl_pq_mdio_bus_name(new_bus->id, np);
 
+       addrp = of_get_address(np, 0, &size, NULL);
+       if (!addrp) {
+               err = -EINVAL;
+               goto err_free_bus;
+       }
+
        /* Set the PHY base address */
-       addr = of_translate_address(np, of_get_address(np, 0, &size, NULL));
+       addr = of_translate_address(np, addrp);
+       if (addr == OF_BAD_ADDR) {
+               err = -EINVAL;
+               goto err_free_bus;
+       }
+
        map = ioremap(addr, size);
        if (!map) {
                err = -ENOMEM;
index b6715553cf173e44bb5dc86be57745ed12009b1b..5d3763fb3472c4247933dec887767643728b693b 100644 (file)
@@ -549,12 +549,8 @@ static int gfar_parse_group(struct device_node *np,
                struct gfar_private *priv, const char *model)
 {
        u32 *queue_mask;
-       u64 addr, size;
-
-       addr = of_translate_address(np,
-                       of_get_address(np, 0, &size, NULL));
-       priv->gfargrp[priv->num_grps].regs = ioremap(addr, size);
 
+       priv->gfargrp[priv->num_grps].regs = of_iomap(np, 0);
        if (!priv->gfargrp[priv->num_grps].regs)
                return -ENOMEM;
 
@@ -676,7 +672,7 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev)
                priv->rx_queue[i] = NULL;
 
        for (i = 0; i < priv->num_tx_queues; i++) {
-               priv->tx_queue[i] =  (struct gfar_priv_tx_q *)kmalloc(
+               priv->tx_queue[i] =  (struct gfar_priv_tx_q *)kzalloc(
                                sizeof (struct gfar_priv_tx_q), GFP_KERNEL);
                if (!priv->tx_queue[i]) {
                        err = -ENOMEM;
@@ -689,7 +685,7 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev)
        }
 
        for (i = 0; i < priv->num_rx_queues; i++) {
-               priv->rx_queue[i] = (struct gfar_priv_rx_q *)kmalloc(
+               priv->rx_queue[i] = (struct gfar_priv_rx_q *)kzalloc(
                                        sizeof (struct gfar_priv_rx_q), GFP_KERNEL);
                if (!priv->rx_queue[i]) {
                        err = -ENOMEM;
@@ -1120,10 +1116,10 @@ static int gfar_probe(struct of_device *ofdev,
        /* provided which set of benchmarks. */
        printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name);
        for (i = 0; i < priv->num_rx_queues; i++)
-               printk(KERN_INFO "%s: :RX BD ring size for Q[%d]: %d\n",
+               printk(KERN_INFO "%s: RX BD ring size for Q[%d]: %d\n",
                        dev->name, i, priv->rx_queue[i]->rx_ring_size);
        for(i = 0; i < priv->num_tx_queues; i++)
-                printk(KERN_INFO "%s:TX BD ring size for Q[%d]: %d\n",
+                printk(KERN_INFO "%s: TX BD ring size for Q[%d]: %d\n",
                        dev->name, i, priv->tx_queue[i]->tx_ring_size);
 
        return 0;
@@ -1515,9 +1511,9 @@ static void gfar_halt_nodisable(struct net_device *dev)
                tempval |= (DMACTRL_GRS | DMACTRL_GTS);
                gfar_write(&regs->dmactrl, tempval);
 
-               while (!(gfar_read(&regs->ievent) &
-                        (IEVENT_GRSC | IEVENT_GTSC)))
-                       cpu_relax();
+               spin_event_timeout(((gfar_read(&regs->ievent) &
+                        (IEVENT_GRSC | IEVENT_GTSC)) ==
+                        (IEVENT_GRSC | IEVENT_GTSC)), -1, 0);
        }
 }
 
@@ -1638,13 +1634,13 @@ static void free_skb_resources(struct gfar_private *priv)
        /* Go through all the buffer descriptors and free their data buffers */
        for (i = 0; i < priv->num_tx_queues; i++) {
                tx_queue = priv->tx_queue[i];
-               if(!tx_queue->tx_skbuff)
+               if(tx_queue->tx_skbuff)
                        free_skb_tx_queue(tx_queue);
        }
 
        for (i = 0; i < priv->num_rx_queues; i++) {
                rx_queue = priv->rx_queue[i];
-               if(!rx_queue->rx_skbuff)
+               if(rx_queue->rx_skbuff)
                        free_skb_rx_queue(rx_queue);
        }
 
@@ -1653,6 +1649,7 @@ static void free_skb_resources(struct gfar_private *priv)
                        sizeof(struct rxbd8) * priv->total_rx_ring_size,
                        priv->tx_queue[0]->tx_bd_base,
                        priv->tx_queue[0]->tx_bd_dma_base);
+       skb_queue_purge(&priv->rx_recycle);
 }
 
 void gfar_start(struct net_device *dev)
@@ -2092,7 +2089,6 @@ static int gfar_close(struct net_device *dev)
 
        disable_napi(priv);
 
-       skb_queue_purge(&priv->rx_recycle);
        cancel_work_sync(&priv->reset_task);
        stop_gfar(dev);
 
@@ -2393,6 +2389,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev)
         * as many bytes as needed to align the data properly
         */
        skb_reserve(skb, alignamount);
+       GFAR_CB(skb)->alignamount = alignamount;
 
        return skb;
 }
@@ -2533,13 +2530,13 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)
                                newskb = skb;
                        else if (skb) {
                                /*
-                                * We need to reset ->data to what it
+                                * We need to un-reserve() the skb to what it
                                 * was before gfar_new_skb() re-aligned
                                 * it to an RXBUF_ALIGNMENT boundary
                                 * before we put the skb back on the
                                 * recycle list.
                                 */
-                               skb->data = skb->head + NET_SKB_PAD;
+                               skb_reserve(skb, -GFAR_CB(skb)->alignamount);
                                __skb_queue_head(&priv->rx_recycle, skb);
                        }
                } else {
index 3d72dc43dca56bdbaba7a510e4e9cb624aa8044f..17d25e714236f305908670efc53fc0c6ace07a08 100644 (file)
@@ -566,6 +566,12 @@ struct rxfcb {
        u16     vlctl;  /* VLAN control word */
 };
 
+struct gianfar_skb_cb {
+       int alignamount;
+};
+
+#define GFAR_CB(skb) ((struct gianfar_skb_cb *)((skb)->cb))
+
 struct rmon_mib
 {
        u32     tr64;   /* 0x.680 - Transmit and Receive 64-byte Frame Counter */
index 1010367695e46c7659704080eb067e90a9784b47..9bda023c0235664f9000411fa543ce182371259f 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index b98c6c512299d94305f71a57e072dcadd072a409..64f4094ac7f16f63ca2227d966e5d59b5d689325 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
index 2b9c1cbc9ec1b3e33d2275aa1682a78fe7becbf1..3a90430de918bc1b1a1de8bd05e0d0f5f11bda6e 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/mii.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 #include <asm/cacheflush.h>
 #include <asm/byteorder.h>
 
index 373546dd083116da8b21c8220725ac32d85fb840..5d6f138795925dc2fecf2e729a918b01d6d7e8e1 100644 (file)
@@ -153,7 +153,6 @@ static int tx_params[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 #include <linux/time.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
index 689b9bd377a52bd3f571aac96c43acfb403f12d2..4b52c767ad056ced9aafcafea8299384b807c169 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/errno.h>
 #include <linux/netdevice.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
index bdadf3e23c94be378b148a006f415fa74cb053f1..14f01d156db9cf588a7640de77998cbba65a3c75 100644 (file)
@@ -61,6 +61,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index 9ee76b42668fa5c2c27a767f1a3e4936d6dbfe32..52b14256e2c0818be269f34e7e9475dfc2ec1470 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/rtnetlink.h>
 #include <linux/sockios.h>
 #include <linux/workqueue.h>
index 91c5790c9581ded3ad1cdc790b99eb77913accc5..b8bdf9d51cd44c5b145af8c860e0f2a0a771a898 100644 (file)
@@ -48,7 +48,6 @@
 #include <linux/net.h>
 #include <linux/in.h>
 #include <linux/if.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
index 7db0a1c3216c7b8dc86703ac23074b9afbe82867..66e88bd59caada26f9cdaa4b6dbb7c1a78026e1f 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
index 35c936175bba2eab1fdf30f813ebeea04256ec95..f3a96b8439110856b1446ab32876161205226ec9 100644 (file)
 #include <linux/in.h>
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
index b766a69bf0caa15fc8704d9522e80539bb61d550..4daad8cd56ea885af08391c9c0cef4481e7ad416 100644 (file)
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/eisa.h>
 #include <linux/pci.h>
index 3e3528ade259d73f072d614f2181fe04c2083940..b6060f7538dfc42d250ef9bbd59bb93221fd6fd7 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/init.h>
index d496b6f4a478d127f193c07212ca6ac2633a3725..07d8e5b634f36caeec8e8df868e3ab586807c774 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -72,6 +71,7 @@ static struct zorro_device_id hydra_zorro_tbl[] __devinitdata = {
     { ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET },
     { 0 }
 };
+MODULE_DEVICE_TABLE(zorro, hydra_zorro_tbl);
 
 static struct zorro_driver hydra_driver = {
     .name      = "hydra",
index fb0ac6d7c0400eb6f5034d0b618bbbe9643e918f..dd873cc41c2b718262c053642593c5461134f458 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/bitops.h>
 #include <linux/workqueue.h>
 #include <linux/of.h>
+#include <linux/slab.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
index 18d56c6c4238e75673e34c3bdd7c0ec2a55563bb..b1cbe6fdfc7a05802294c5bbcd8926aad4e0b7f4 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/dcr.h>
index 2a2fc17b28780678eff7efaf0f6d17586e09e7c2..5b3d94419fe6aa1ba94c2e1c8e00cc30f925ccdc 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "core.h"
 #include <asm/dcr-regs.h>
index 8d76cb89dbd61e6d252ed30fbe1bf211f5081732..5b90d34c845502dc789b4c87b6bc35e9f2a89f64 100644 (file)
@@ -21,6 +21,7 @@
  * option) any later version.
  *
  */
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/ethtool.h>
 #include <asm/io.h>
index 17b154124943e5baf89e6640f26643ade28be72c..1f038f808ab32512fdb78ae01b4f54f9f152d5a2 100644 (file)
@@ -21,6 +21,7 @@
  * option) any later version.
  *
  */
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/ethtool.h>
 #include <asm/io.h>
index b5d0f4e973f70cbb9fa68eff005b4ff594104f11..7d6cf3340c113041216fbca52ea23a3c9514d8c3 100644 (file)
@@ -79,7 +79,6 @@ History:
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/time.h>
index 0bc777bac9b47dd4ac45c29a30be13f347e2e706..cd508a8ee25b3f9a5a81b568e5a733e68e4d961e 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/proc_fs.h>
 #include <linux/in.h>
 #include <linux/ip.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <asm/hvcall.h>
 #include <asm/atomic.h>
index 9d7fa2fb85ea0cb9de0b7582da337d03d7b9c917..4a32bed77c719acab24f459e2a4f57b3600a777e 100644 (file)
@@ -30,7 +30,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/if_ether.h>
 
 #include "e1000_mac.h"
@@ -94,6 +93,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
        case E1000_DEV_ID_82576_FIBER:
        case E1000_DEV_ID_82576_SERDES:
        case E1000_DEV_ID_82576_QUAD_COPPER:
+       case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
        case E1000_DEV_ID_82576_SERDES_QUAD:
                mac->type = e1000_82576;
                break;
index 448005276b26b68bdba25be9606aa41185a7ebe6..82a533f5192a545e5d6d631b2cc671e0bb042a5b 100644 (file)
@@ -41,6 +41,7 @@ struct e1000_hw;
 #define E1000_DEV_ID_82576_FIBER              0x10E6
 #define E1000_DEV_ID_82576_SERDES             0x10E7
 #define E1000_DEV_ID_82576_QUAD_COPPER        0x10E8
+#define E1000_DEV_ID_82576_QUAD_COPPER_ET2    0x1526
 #define E1000_DEV_ID_82576_NS                 0x150A
 #define E1000_DEV_ID_82576_NS_SERDES          0x1518
 #define E1000_DEV_ID_82576_SERDES_QUAD        0x150D
index 2a8a886b37eb698bfed13f145b3e677cf363e9c2..be8d010e40213a7b51616fad0e320464a43c751a 100644 (file)
@@ -1367,7 +1367,8 @@ out:
  *  igb_enable_mng_pass_thru - Enable processing of ARP's
  *  @hw: pointer to the HW structure
  *
- *  Verifies the hardware needs to allow ARPs to be processed by the host.
+ *  Verifies the hardware needs to leave interface enabled so that frames can
+ *  be directed to and from the management interface.
  **/
 bool igb_enable_mng_pass_thru(struct e1000_hw *hw)
 {
@@ -1380,8 +1381,7 @@ bool igb_enable_mng_pass_thru(struct e1000_hw *hw)
 
        manc = rd32(E1000_MANC);
 
-       if (!(manc & E1000_MANC_RCV_TCO_EN) ||
-           !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
+       if (!(manc & E1000_MANC_RCV_TCO_EN))
                goto out;
 
        if (hw->mac.arc_subsystem_valid) {
index a1775705b24c93759daf7d63cf0d02a0fd36f089..3b772b822a5dcc61548c8bc98297c8bd9c47efb6 100644 (file)
@@ -267,7 +267,6 @@ struct igb_adapter {
 
        /* TX */
        struct igb_ring *tx_ring[16];
-       unsigned long tx_queue_len;
        u32 tx_timeout_count;
 
        /* RX */
index a4cead12fd987541a48e5f840f94e0bc22b50ce0..743038490104bbc51b054e2600a71132fbfb86e4 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/if_ether.h>
 #include <linux/ethtool.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include "igb.h"
 
@@ -1813,6 +1814,7 @@ static int igb_wol_exclusion(struct igb_adapter *adapter,
                retval = 0;
                break;
        case E1000_DEV_ID_82576_QUAD_COPPER:
+       case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
                /* quad port adapters only support WoL on port A */
                if (!(adapter->flags & IGB_FLAG_QUAD_PORT_A)) {
                        wol->supported = 0;
index 0ed25f059a00732345f34ecbf721a167ed9c1cc2..c9baa2aa98cd640268924ef2ef891afbdd29ba33 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/pagemap.h>
 #include <linux/netdevice.h>
 #include <linux/ipv6.h>
+#include <linux/slab.h>
 #include <net/checksum.h>
 #include <net/ip6_checksum.h>
 #include <linux/net_tstamp.h>
@@ -72,6 +73,7 @@ static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = {
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES_QUAD), board_82575 },
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER_ET2), board_82575 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER), board_82575 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 },
@@ -1104,9 +1106,6 @@ static void igb_configure(struct igb_adapter *adapter)
                struct igb_ring *ring = adapter->rx_ring[i];
                igb_alloc_rx_buffers_adv(ring, igb_desc_unused(ring));
        }
-
-
-       adapter->tx_queue_len = netdev->tx_queue_len;
 }
 
 /**
@@ -1212,7 +1211,6 @@ void igb_down(struct igb_adapter *adapter)
        del_timer_sync(&adapter->watchdog_timer);
        del_timer_sync(&adapter->phy_info_timer);
 
-       netdev->tx_queue_len = adapter->tx_queue_len;
        netif_carrier_off(netdev);
 
        /* record the stats before reset*/
@@ -1614,6 +1612,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
                        adapter->eeprom_wol = 0;
                break;
        case E1000_DEV_ID_82576_QUAD_COPPER:
+       case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
                /* if quad port adapter, disable WoL on all but port A */
                if (global_quad_port_a != 0)
                        adapter->eeprom_wol = 0;
@@ -3105,17 +3104,13 @@ static void igb_watchdog_task(struct work_struct *work)
                               ((ctrl & E1000_CTRL_RFCE) ?  "RX" :
                               ((ctrl & E1000_CTRL_TFCE) ?  "TX" : "None")));
 
-                       /* tweak tx_queue_len according to speed/duplex and
-                        * adjust the timeout factor */
-                       netdev->tx_queue_len = adapter->tx_queue_len;
+                       /* adjust timeout factor according to speed/duplex */
                        adapter->tx_timeout_factor = 1;
                        switch (adapter->link_speed) {
                        case SPEED_10:
-                               netdev->tx_queue_len = 10;
                                adapter->tx_timeout_factor = 14;
                                break;
                        case SPEED_100:
-                               netdev->tx_queue_len = 100;
                                /* maybe add some timeout factor ? */
                                break;
                        }
@@ -3962,7 +3957,7 @@ void igb_update_stats(struct igb_adapter *adapter)
        struct net_device_stats *net_stats = igb_get_stats(adapter->netdev);
        struct e1000_hw *hw = &adapter->hw;
        struct pci_dev *pdev = adapter->pdev;
-       u32 rnbc, reg;
+       u32 reg, mpc;
        u16 phy_tmp;
        int i;
        u64 bytes, packets;
@@ -4020,7 +4015,9 @@ void igb_update_stats(struct igb_adapter *adapter)
        adapter->stats.symerrs += rd32(E1000_SYMERRS);
        adapter->stats.sec += rd32(E1000_SEC);
 
-       adapter->stats.mpc += rd32(E1000_MPC);
+       mpc = rd32(E1000_MPC);
+       adapter->stats.mpc += mpc;
+       net_stats->rx_fifo_errors += mpc;
        adapter->stats.scc += rd32(E1000_SCC);
        adapter->stats.ecol += rd32(E1000_ECOL);
        adapter->stats.mcc += rd32(E1000_MCC);
@@ -4035,9 +4032,7 @@ void igb_update_stats(struct igb_adapter *adapter)
        adapter->stats.gptc += rd32(E1000_GPTC);
        adapter->stats.gotc += rd32(E1000_GOTCL);
        rd32(E1000_GOTCH); /* clear GOTCL */
-       rnbc = rd32(E1000_RNBC);
-       adapter->stats.rnbc += rnbc;
-       net_stats->rx_fifo_errors += rnbc;
+       adapter->stats.rnbc += rd32(E1000_RNBC);
        adapter->stats.ruc += rd32(E1000_RUC);
        adapter->stats.rfc += rd32(E1000_RFC);
        adapter->stats.rjc += rd32(E1000_RJC);
@@ -5109,7 +5104,7 @@ static void igb_receive_skb(struct igb_q_vector *q_vector,
 {
        struct igb_adapter *adapter = q_vector->adapter;
 
-       if (vlan_tag)
+       if (vlan_tag && adapter->vlgrp)
                vlan_gro_receive(&q_vector->napi, adapter->vlgrp,
                                 vlan_tag, skb);
        else
index a1774b29d222093851ce46e29d5871d9cc69e286..debeee2dc717c6f86261c53ea93f46b84a07e9ca 100644 (file)
@@ -198,7 +198,6 @@ struct igbvf_adapter {
        struct igbvf_ring *tx_ring /* One per active queue */
        ____cacheline_aligned_in_smp;
 
-       unsigned long tx_queue_len;
        unsigned int restart_queue;
        u32 txd_cmd;
 
index a77afd8a14bbfd30fed68c02cb1861e6113f50fa..1b1edad1eb5e68de5a583a2a1ac14d68e6a2a7dd 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/netdevice.h>
 #include <linux/tcp.h>
 #include <linux/ipv6.h>
+#include <linux/slab.h>
 #include <net/checksum.h>
 #include <net/ip6_checksum.h>
 #include <linux/mii.h>
@@ -1304,8 +1305,6 @@ static void igbvf_configure_tx(struct igbvf_adapter *adapter)
 
        /* enable Report Status bit */
        adapter->txd_cmd |= E1000_ADVTXD_DCMD_RS;
-
-       adapter->tx_queue_len = adapter->netdev->tx_queue_len;
 }
 
 /**
@@ -1524,7 +1523,6 @@ void igbvf_down(struct igbvf_adapter *adapter)
 
        del_timer_sync(&adapter->watchdog_timer);
 
-       netdev->tx_queue_len = adapter->tx_queue_len;
        netif_carrier_off(netdev);
 
        /* record the stats before reset*/
@@ -1857,21 +1855,15 @@ static void igbvf_watchdog_task(struct work_struct *work)
                                                  &adapter->link_duplex);
                        igbvf_print_link_info(adapter);
 
-                       /*
-                        * tweak tx_queue_len according to speed/duplex
-                        * and adjust the timeout factor
-                        */
-                       netdev->tx_queue_len = adapter->tx_queue_len;
+                       /* adjust timeout factor according to speed/duplex */
                        adapter->tx_timeout_factor = 1;
                        switch (adapter->link_speed) {
                        case SPEED_10:
                                txb2b = 0;
-                               netdev->tx_queue_len = 10;
                                adapter->tx_timeout_factor = 16;
                                break;
                        case SPEED_100:
                                txb2b = 0;
-                               netdev->tx_queue_len = 100;
                                /* maybe add some timeout factor ? */
                                break;
                        }
index 70871b9b045a05c9d2221724fade93d77dfd64ca..8f6197d647c0433a227dd74f4057df0cc9905fbf 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #ifdef CONFIG_SERIAL_8250
 #include <linux/serial_core.h>
index 150415e83f61e21e3cdc25f85a9d892b849c7016..639bf9fb027974b65b0376a5a2a188f3171dec26 100644 (file)
@@ -22,6 +22,7 @@
  */
 #include <linux/crc32.h>
 #include <linux/ethtool.h>
+#include <linux/gfp.h>
 #include <linux/mii.h>
 #include <linux/mutex.h>
 
index 12c7b006f767cbf5b2eac5442306d2c079d5959c..28992c815cba14282dc17a999ca32c8a6fd450c9 100644 (file)
@@ -22,6 +22,7 @@
  ********************************************************************/
 
 #include <linux/module.h>
+#include <linux/gfp.h>
 
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -29,7 +30,6 @@
 #include <linux/netdevice.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/serial_reg.h>
index dac71b1f4f9bcaa2f38cea6b0829efdf3192f1d1..b54a6f08db45917ebf25890bf45040b7be5c4a2c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/wrapper.h>
index 20f9bc6266882eae0dae82707d9935f6bee1b8d4..ee1dde52e8fcf1b6ddd620b06fb989972e1528e3 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
index 2413295ebd903980eb335c85357a892e9dc68eda..e30cdbb1474567885d64a9c4cd2d281fcf6d32c8 100644 (file)
@@ -43,6 +43,7 @@
  ********************************************************************/
 
 #include <linux/module.h>
+#include <linux/gfp.h>
 
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -50,7 +51,6 @@
 #include <linux/netdevice.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/dma-mapping.h>
index 84db145d2b59ad3ed3ef02ce8d621c7bf9eedea9..1a54f6bb68c5066612af0125c358abcf9285ccdc 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irmod.h>
index d7c983dc91adff1436c7b3ac24d5aa9d6bf8d8c1..0745581c4b5ec873d7ba06e9e817f93d7dd0e16d 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <net/irda/wrapper.h>
 #include <net/irda/irda_device.h>
 #include <asm/clock.h>
index 4b2a1a9eac2afad94d29e85745ba3d1a25d5f9fe..de91cd14016be75de37513939d018d8b35df806e 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 
index 8f7d0d146f240c32208bee6d7f5464c90f3540b5..6af84d88cd03c960237927ee71752a06c087de60 100644 (file)
 #include <linux/netdevice.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/serial_reg.h>
 #include <linux/dma-mapping.h>
 #include <linux/pnp.h>
 #include <linux/platform_device.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
index 6533c010cf5c494f1e574da6ca43d64b507e9e53..b0a6cd815be198e11334880d9ce8a728ee28d4e4 100644 (file)
@@ -45,11 +45,11 @@ F02 Oct/28/02: Add SB device ID for 3147 and 3177.
 #include <linux/netdevice.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
index 551810fd29760ccbd8f52345a0d7feb49fb4b1d2..cb0cb758be64a23e5eae893b296bc2d642451975 100644 (file)
 #include <linux/netdevice.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -65,7 +65,6 @@
 #undef  CONFIG_NETWINDER_TX_DMA_PROBLEMS /* Not needed */
 #define CONFIG_NETWINDER_RX_DMA_PROBLEMS /* Must have this one! */
 #endif
-#undef  CONFIG_USE_INTERNAL_TIMER  /* Just cannot make that timer work */
 #define CONFIG_USE_W977_PNP        /* Currently needed */
 #define PIO_MAX_SPEED       115200 
 
@@ -533,25 +532,6 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
                self->tx_buff.len = skb->len;
                
                mtt = irda_get_mtt(skb);
-#ifdef CONFIG_USE_INTERNAL_TIMER
-               if (mtt > 50) {
-                       /* Adjust for timer resolution */
-                       mtt /= 1000+1;
-
-                       /* Setup timer */
-                       switch_bank(iobase, SET4);
-                       outb(mtt & 0xff, iobase+TMRL);
-                       outb((mtt >> 8) & 0x0f, iobase+TMRH);
-                       
-                       /* Start timer */
-                       outb(IR_MSL_EN_TMR, iobase+IR_MSL);
-                       self->io.direction = IO_XMIT;
-                       
-                       /* Enable timer interrupt */
-                       switch_bank(iobase, SET0);
-                       outb(ICR_ETMRI, iobase+ICR);
-               } else {
-#endif
                        IRDA_DEBUG(4, "%s(%ld), mtt=%d\n", __func__ , jiffies, mtt);
                        if (mtt)
                                udelay(mtt);
@@ -560,9 +540,6 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
                        switch_bank(iobase, SET0);
                        outb(ICR_EDMAI, iobase+ICR);
                        w83977af_dma_write(self, iobase);
-#ifdef CONFIG_USE_INTERNAL_TIMER
-               }
-#endif
        } else {
                self->tx_buff.data = self->tx_buff.head;
                self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, 
@@ -876,20 +853,7 @@ static int w83977af_dma_receive_complete(struct w83977af_ir *self)
                        /* Check if we have transferred all data to memory */
                        switch_bank(iobase, SET0);
                        if (inb(iobase+USR) & USR_RDR) {
-#ifdef CONFIG_USE_INTERNAL_TIMER
-                               /* Put this entry back in fifo */
-                               st_fifo->head--;
-                               st_fifo->len++;
-                               st_fifo->entries[st_fifo->head].status = status;
-                               st_fifo->entries[st_fifo->head].len = len;
-                               
-                               /* Restore set register */
-                               outb(set, iobase+SSR);
-                       
-                               return FALSE;   /* I'll be back! */
-#else
                                udelay(80); /* Should be enough!? */
-#endif
                        }
                                                
                        skb = dev_alloc_skb(len+1);
index e6e972d9b7ca40b63e1b5ea6a525d5e1daaff2b8..773c59c8969162fac202202b854e6e77a6c43a67 100644 (file)
@@ -69,6 +69,7 @@
 #include <linux/mm.h>
 #include <linux/ethtool.h>
 #include <linux/if_ether.h>
+#include <linux/slab.h>
 
 #include <asm/abs_addr.h>
 #include <asm/iseries/mf.h>
index 19e94ee155a265f09a7560d3e78ae5d796528e31..79c35ae3718c96186898452e286d59d5e0482814 100644 (file)
@@ -204,14 +204,17 @@ enum ixgbe_ring_f_enum {
 #define IXGBE_MAX_FDIR_INDICES 64
 #ifdef IXGBE_FCOE
 #define IXGBE_MAX_FCOE_INDICES  8
+#define MAX_RX_QUEUES (IXGBE_MAX_FDIR_INDICES + IXGBE_MAX_FCOE_INDICES)
+#define MAX_TX_QUEUES (IXGBE_MAX_FDIR_INDICES + IXGBE_MAX_FCOE_INDICES)
+#else
+#define MAX_RX_QUEUES IXGBE_MAX_FDIR_INDICES
+#define MAX_TX_QUEUES IXGBE_MAX_FDIR_INDICES
 #endif /* IXGBE_FCOE */
 struct ixgbe_ring_feature {
        int indices;
        int mask;
 } ____cacheline_internodealigned_in_smp;
 
-#define MAX_RX_QUEUES 128
-#define MAX_TX_QUEUES 128
 
 #define MAX_RX_PACKET_BUFFERS ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) \
                               ? 8 : 1)
index 1f30e163bd9cc2ff904b4349acb3960ff6974035..12fc0e7ba2ca3bbf10034fa8e906bc34bb06a689 100644 (file)
@@ -39,6 +39,9 @@
 #define IXGBE_82599_MC_TBL_SIZE   128
 #define IXGBE_82599_VFT_TBL_SIZE  128
 
+void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
+void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
+void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
 s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                                           ixgbe_link_speed speed,
                                           bool autoneg,
@@ -68,7 +71,15 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
        if (hw->phy.multispeed_fiber) {
                /* Set up dual speed SFP+ support */
                mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber;
+               mac->ops.disable_tx_laser =
+                                      &ixgbe_disable_tx_laser_multispeed_fiber;
+               mac->ops.enable_tx_laser =
+                                       &ixgbe_enable_tx_laser_multispeed_fiber;
+               mac->ops.flap_tx_laser = &ixgbe_flap_tx_laser_multispeed_fiber;
        } else {
+               mac->ops.disable_tx_laser = NULL;
+               mac->ops.enable_tx_laser = NULL;
+               mac->ops.flap_tx_laser = NULL;
                if ((mac->ops.get_media_type(hw) ==
                     ixgbe_media_type_backplane) &&
                    (hw->phy.smart_speed == ixgbe_smart_speed_auto ||
@@ -412,6 +423,67 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
        return status;
 }
 
+ /**
+  *  ixgbe_disable_tx_laser_multispeed_fiber - Disable Tx laser
+  *  @hw: pointer to hardware structure
+  *
+  *  The base drivers may require better control over SFP+ module
+  *  PHY states.  This includes selectively shutting down the Tx
+  *  laser on the PHY, effectively halting physical link.
+  **/
+void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
+{
+       u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
+
+       /* Disable tx laser; allow 100us to go dark per spec */
+       esdp_reg |= IXGBE_ESDP_SDP3;
+       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+       IXGBE_WRITE_FLUSH(hw);
+       udelay(100);
+}
+
+/**
+ *  ixgbe_enable_tx_laser_multispeed_fiber - Enable Tx laser
+ *  @hw: pointer to hardware structure
+ *
+ *  The base drivers may require better control over SFP+ module
+ *  PHY states.  This includes selectively turning on the Tx
+ *  laser on the PHY, effectively starting physical link.
+ **/
+void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
+{
+       u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
+
+       /* Enable tx laser; allow 100ms to light up */
+       esdp_reg &= ~IXGBE_ESDP_SDP3;
+       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+       IXGBE_WRITE_FLUSH(hw);
+       msleep(100);
+}
+
+/**
+ *  ixgbe_flap_tx_laser_multispeed_fiber - Flap Tx laser
+ *  @hw: pointer to hardware structure
+ *
+ *  When the driver changes the link speeds that it can support,
+ *  it sets autotry_restart to true to indicate that we need to
+ *  initiate a new autotry session with the link partner.  To do
+ *  so, we set the speed then disable and re-enable the tx laser, to
+ *  alert the link partner that it also needs to restart autotry on its
+ *  end.  This is consistent with true clause 37 autoneg, which also
+ *  involves a loss of signal.
+ **/
+void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
+{
+       hw_dbg(hw, "ixgbe_flap_tx_laser_multispeed_fiber\n");
+
+       if (hw->mac.autotry_restart) {
+               ixgbe_disable_tx_laser_multispeed_fiber(hw);
+               ixgbe_enable_tx_laser_multispeed_fiber(hw);
+               hw->mac.autotry_restart = false;
+       }
+}
+
 /**
  *  ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
  *  @hw: pointer to hardware structure
@@ -439,16 +511,6 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
        hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation);
        speed &= phy_link_speed;
 
-       /*
-        * When the driver changes the link speeds that it can support,
-        * it sets autotry_restart to true to indicate that we need to
-        * initiate a new autotry session with the link partner.  To do
-        * so, we set the speed then disable and re-enable the tx laser, to
-        * alert the link partner that it also needs to restart autotry on its
-        * end.  This is consistent with true clause 37 autoneg, which also
-        * involves a loss of signal.
-        */
-
        /*
         * Try each speed one by one, highest priority first.  We do this in
         * software because 10gb fiber doesn't support speed autonegotiation.
@@ -466,6 +528,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                /* Set the module link speed */
                esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
                IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+               IXGBE_WRITE_FLUSH(hw);
 
                /* Allow module to change analog characteristics (1G->10G) */
                msleep(40);
@@ -478,19 +541,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                        return status;
 
                /* Flap the tx laser if it has not already been done */
-               if (hw->mac.autotry_restart) {
-                       /* Disable tx laser; allow 100us to go dark per spec */
-                       esdp_reg |= IXGBE_ESDP_SDP3;
-                       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
-                       udelay(100);
-
-                       /* Enable tx laser; allow 2ms to light up per spec */
-                       esdp_reg &= ~IXGBE_ESDP_SDP3;
-                       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
-                       msleep(2);
-
-                       hw->mac.autotry_restart = false;
-               }
+               hw->mac.ops.flap_tx_laser(hw);
 
                /*
                 * Wait for the controller to acquire link.  Per IEEE 802.3ap,
@@ -525,6 +576,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                esdp_reg &= ~IXGBE_ESDP_SDP5;
                esdp_reg |= IXGBE_ESDP_SDP5_DIR;
                IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+               IXGBE_WRITE_FLUSH(hw);
 
                /* Allow module to change analog characteristics (10G->1G) */
                msleep(40);
@@ -537,19 +589,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                        return status;
 
                /* Flap the tx laser if it has not already been done */
-               if (hw->mac.autotry_restart) {
-                       /* Disable tx laser; allow 100us to go dark per spec */
-                       esdp_reg |= IXGBE_ESDP_SDP3;
-                       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
-                       udelay(100);
-
-                       /* Enable tx laser; allow 2ms to light up per spec */
-                       esdp_reg &= ~IXGBE_ESDP_SDP3;
-                       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
-                       msleep(2);
-
-                       hw->mac.autotry_restart = false;
-               }
+               hw->mac.ops.flap_tx_laser(hw);
 
                /* Wait for the link partner to also set speed */
                msleep(100);
index 7949a446e4c7673f2587ec6da3b33c1a06574cae..8f461d5cee7775da632822317da4151ac02a2ff4 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <linux/types.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
@@ -1853,6 +1854,26 @@ static void ixgbe_diag_test(struct net_device *netdev,
                if (ixgbe_link_test(adapter, &data[4]))
                        eth_test->flags |= ETH_TEST_FL_FAILED;
 
+               if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
+                       int i;
+                       for (i = 0; i < adapter->num_vfs; i++) {
+                               if (adapter->vfinfo[i].clear_to_send) {
+                                       netdev_warn(netdev, "%s",
+                                                   "offline diagnostic is not "
+                                                   "supported when VFs are "
+                                                   "present\n");
+                                       data[0] = 1;
+                                       data[1] = 1;
+                                       data[2] = 1;
+                                       data[3] = 1;
+                                       eth_test->flags |= ETH_TEST_FL_FAILED;
+                                       clear_bit(__IXGBE_TESTING,
+                                                 &adapter->state);
+                                       goto skip_ol_tests;
+                               }
+                       }
+               }
+
                if (if_running)
                        /* indicate we're in test mode */
                        dev_close(netdev);
@@ -1908,6 +1929,7 @@ skip_loopback:
 
                clear_bit(__IXGBE_TESTING, &adapter->state);
        }
+skip_ol_tests:
        msleep_interruptible(4 * 1000);
 }
 
index 4123dec0dfb7aa39554624f01b6258579f44f004..6493049b663d95e13f73ea5c252bffcd88e0c2cd 100644 (file)
@@ -31,6 +31,7 @@
 #include "ixgbe_dcb_82599.h"
 #endif /* CONFIG_IXGBE_DCB */
 #include <linux/if_ether.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
 #include <scsi/fc/fc_fs.h>
@@ -202,6 +203,15 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
                addr = sg_dma_address(sg);
                len = sg_dma_len(sg);
                while (len) {
+                       /* max number of buffers allowed in one DDP context */
+                       if (j >= IXGBE_BUFFCNT_MAX) {
+                               netif_err(adapter, drv, adapter->netdev,
+                                         "xid=%x:%d,%d,%d:addr=%llx "
+                                         "not enough descriptors\n",
+                                         xid, i, j, dmacount, (u64)addr);
+                               goto out_noddp_free;
+                       }
+
                        /* get the offset of length of current buffer */
                        thisoff = addr & ((dma_addr_t)bufflen - 1);
                        thislen = min((bufflen - thisoff), len);
@@ -227,20 +237,13 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
                        len -= thislen;
                        addr += thislen;
                        j++;
-                       /* max number of buffers allowed in one DDP context */
-                       if (j > IXGBE_BUFFCNT_MAX) {
-                               DPRINTK(DRV, ERR, "xid=%x:%d,%d,%d:addr=%llx "
-                                       "not enough descriptors\n",
-                                       xid, i, j, dmacount, (u64)addr);
-                               goto out_noddp_free;
-                       }
                }
        }
        /* only the last buffer may have non-full bufflen */
        lastsize = thisoff + thislen;
 
        fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT);
-       fcbuff |= (j << IXGBE_FCBUFF_BUFFCNT_SHIFT);
+       fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT);
        fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT);
        fcbuff |= (IXGBE_FCBUFF_VALID);
 
@@ -520,6 +523,9 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
        /* Enable L2 eth type filter for FCoE */
        IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FCOE),
                        (ETH_P_FCOE | IXGBE_ETQF_FCOE | IXGBE_ETQF_FILTER_EN));
+       /* Enable L2 eth type filter for FIP */
+       IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FIP),
+                       (ETH_P_FIP | IXGBE_ETQF_FILTER_EN));
        if (adapter->ring_feature[RING_F_FCOE].indices) {
                /* Use multiple rx queues for FCoE by redirection table */
                for (i = 0; i < IXGBE_FCRETA_SIZE; i++) {
@@ -530,6 +536,12 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
                }
                IXGBE_WRITE_REG(hw, IXGBE_FCRECTL, IXGBE_FCRECTL_ENA);
                IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE), 0);
+               fcoe_i = f->mask;
+               fcoe_i &= IXGBE_FCRETA_ENTRY_MASK;
+               fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx;
+               IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FIP),
+                               IXGBE_ETQS_QUEUE_EN |
+                               (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
        } else  {
                /* Use single rx queue for FCoE */
                fcoe_i = f->mask;
@@ -539,6 +551,12 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
                                IXGBE_ETQS_QUEUE_EN |
                                (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
        }
+       /* send FIP frames to the first FCoE queue */
+       fcoe_i = f->mask;
+       fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx;
+       IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FIP),
+                       IXGBE_ETQS_QUEUE_EN |
+                       (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
 
        IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL,
                        IXGBE_FCRXCTRL_FCOELLI |
@@ -614,9 +632,9 @@ int ixgbe_fcoe_enable(struct net_device *netdev)
        netdev->vlan_features |= NETIF_F_FSO;
        netdev->vlan_features |= NETIF_F_FCOE_MTU;
        netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1;
-       netdev_features_change(netdev);
 
        ixgbe_init_interrupt_scheme(adapter);
+       netdev_features_change(netdev);
 
        if (netif_running(netdev))
                netdev->netdev_ops->ndo_open(netdev);
@@ -660,11 +678,11 @@ int ixgbe_fcoe_disable(struct net_device *netdev)
        netdev->vlan_features &= ~NETIF_F_FSO;
        netdev->vlan_features &= ~NETIF_F_FCOE_MTU;
        netdev->fcoe_ddp_xid = 0;
-       netdev_features_change(netdev);
 
        ixgbe_cleanup_fcoe(adapter);
-
        ixgbe_init_interrupt_scheme(adapter);
+       netdev_features_change(netdev);
+
        if (netif_running(netdev))
                netdev->netdev_ops->ndo_open(netdev);
        rc = 0;
index 684af371462dc32975f955ef0e96ac8063c09b02..6c00ee493a3bb1c1bae50b59fdb2afb58688c22e 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/tcp.h>
 #include <linux/pkt_sched.h>
 #include <linux/ipv6.h>
+#include <linux/slab.h>
 #include <net/checksum.h>
 #include <net/ip6_checksum.h>
 #include <linux/ethtool.h>
@@ -935,10 +936,12 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
                        if (skb->prev)
                                skb = ixgbe_transform_rsc_queue(skb, &(rx_ring->rsc_count));
                        if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
-                               if (IXGBE_RSC_CB(skb)->dma)
+                               if (IXGBE_RSC_CB(skb)->dma) {
                                        pci_unmap_single(pdev, IXGBE_RSC_CB(skb)->dma,
                                                         rx_ring->rx_buf_len,
                                                         PCI_DMA_FROMDEVICE);
+                                       IXGBE_RSC_CB(skb)->dma = 0;
+                               }
                                if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)
                                        rx_ring->rsc_count += skb_shinfo(skb)->nr_frags;
                                else
@@ -2979,6 +2982,10 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
        else
                ixgbe_configure_msi_and_legacy(adapter);
 
+       /* enable the optics */
+       if (hw->phy.multispeed_fiber)
+               hw->mac.ops.enable_tx_laser(hw);
+
        clear_bit(__IXGBE_DOWN, &adapter->state);
        ixgbe_napi_enable_all(adapter);
 
@@ -3054,6 +3061,14 @@ void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)
        while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
                msleep(1);
        ixgbe_down(adapter);
+       /*
+        * If SR-IOV enabled then wait a bit before bringing the adapter
+        * back up to give the VFs time to respond to the reset.  The
+        * two second wait is based upon the watchdog timer cycle in
+        * the VF driver.
+        */
+       if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
+               msleep(2000);
        ixgbe_up(adapter);
        clear_bit(__IXGBE_RESETTING, &adapter->state);
 }
@@ -3126,10 +3141,12 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
                        rx_buffer_info->skb = NULL;
                        do {
                                struct sk_buff *this = skb;
-                               if (IXGBE_RSC_CB(this)->dma)
+                               if (IXGBE_RSC_CB(this)->dma) {
                                        pci_unmap_single(pdev, IXGBE_RSC_CB(this)->dma,
                                                         rx_ring->rx_buf_len,
                                                         PCI_DMA_FROMDEVICE);
+                                       IXGBE_RSC_CB(this)->dma = 0;
+                               }
                                skb = skb->prev;
                                dev_kfree_skb(this);
                        } while (skb);
@@ -3230,15 +3247,21 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
        /* signal that we are down to the interrupt handler */
        set_bit(__IXGBE_DOWN, &adapter->state);
 
+       /* power down the optics */
+       if (hw->phy.multispeed_fiber)
+               hw->mac.ops.disable_tx_laser(hw);
+
        /* disable receive for all VFs and wait one second */
        if (adapter->num_vfs) {
-               for (i = 0 ; i < adapter->num_vfs; i++)
-                       adapter->vfinfo[i].clear_to_send = 0;
-
                /* ping all the active vfs to let them know we are going down */
                ixgbe_ping_all_vfs(adapter);
+
                /* Disable all VFTE/VFRE TX/RX */
                ixgbe_disable_tx_rx(adapter);
+
+               /* Mark all the VFs as inactive */
+               for (i = 0 ; i < adapter->num_vfs; i++)
+                       adapter->vfinfo[i].clear_to_send = 0;
        }
 
        /* disable receives */
@@ -5018,6 +5041,7 @@ static void ixgbe_multispeed_fiber_task(struct work_struct *work)
        autoneg = hw->phy.autoneg_advertised;
        if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
                hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation);
+       hw->mac.autotry_restart = false;
        if (hw->mac.ops.setup_link)
                hw->mac.ops.setup_link(hw, autoneg, negotiation, true);
        adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -5633,7 +5657,8 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
 
 #ifdef IXGBE_FCOE
        if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
-           (skb->protocol == htons(ETH_P_FCOE))) {
+           ((skb->protocol == htons(ETH_P_FCOE)) ||
+            (skb->protocol == htons(ETH_P_FIP)))) {
                txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1);
                txq += adapter->ring_feature[RING_F_FCOE].mask;
                return txq;
@@ -5680,18 +5705,25 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
 
        tx_ring = adapter->tx_ring[skb->queue_mapping];
 
-       if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
-           (skb->protocol == htons(ETH_P_FCOE))) {
-               tx_flags |= IXGBE_TX_FLAGS_FCOE;
 #ifdef IXGBE_FCOE
+       if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
 #ifdef CONFIG_IXGBE_DCB
-               tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK
-                             << IXGBE_TX_FLAGS_VLAN_SHIFT);
-               tx_flags |= ((adapter->fcoe.up << 13)
-                             << IXGBE_TX_FLAGS_VLAN_SHIFT);
-#endif
+               /* for FCoE with DCB, we force the priority to what
+                * was specified by the switch */
+               if ((skb->protocol == htons(ETH_P_FCOE)) ||
+                   (skb->protocol == htons(ETH_P_FIP))) {
+                       tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK
+                                     << IXGBE_TX_FLAGS_VLAN_SHIFT);
+                       tx_flags |= ((adapter->fcoe.up << 13)
+                                    << IXGBE_TX_FLAGS_VLAN_SHIFT);
+               }
 #endif
+               /* flag for FCoE offloads */
+               if (skb->protocol == htons(ETH_P_FCOE))
+                       tx_flags |= IXGBE_TX_FLAGS_FCOE;
        }
+#endif
+
        /* four things can cause us to need a context descriptor */
        if (skb_is_gso(skb) ||
            (skb->ip_summed == CHECKSUM_PARTIAL) ||
@@ -6046,7 +6078,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        indices += min_t(unsigned int, num_possible_cpus(),
                         IXGBE_MAX_FCOE_INDICES);
 #endif
-       indices = min_t(unsigned int, indices, MAX_TX_QUEUES);
        netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices);
        if (!netdev) {
                err = -ENOMEM;
@@ -6230,6 +6261,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
                goto err_eeprom;
        }
 
+       /* power down the optics */
+       if (hw->phy.multispeed_fiber)
+               hw->mac.ops.disable_tx_laser(hw);
+
        init_timer(&adapter->watchdog_timer);
        adapter->watchdog_timer.function = &ixgbe_watchdog;
        adapter->watchdog_timer.data = (unsigned long)adapter;
@@ -6245,9 +6280,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        case IXGBE_DEV_ID_82599_KX4:
                adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX |
                                IXGBE_WUFC_MC | IXGBE_WUFC_BC);
-               /* Enable ACPI wakeup in GRC */
-               IXGBE_WRITE_REG(hw, IXGBE_GRC,
-                            (IXGBE_READ_REG(hw, IXGBE_GRC) & ~IXGBE_GRC_APME));
                break;
        default:
                adapter->wol = 0;
index 2be907466593a6e1c119403981226a6155be869c..534affcc38ca0208a9376e4565a2b65773349b26 100644 (file)
 #define IXGBE_ETQF_FILTER_BCN            1
 #define IXGBE_ETQF_FILTER_FCOE           2
 #define IXGBE_ETQF_FILTER_1588           3
+#define IXGBE_ETQF_FILTER_FIP            4
 /* VLAN Control Bit Masks */
 #define IXGBE_VLNCTRL_VET       0x0000FFFF  /* bits 0-15 */
 #define IXGBE_VLNCTRL_CFI       0x10000000  /* bit 28 */
@@ -2397,6 +2398,9 @@ struct ixgbe_mac_operations {
        s32 (*enable_rx_dma)(struct ixgbe_hw *, u32);
 
        /* Link */
+       void (*disable_tx_laser)(struct ixgbe_hw *);
+       void (*enable_tx_laser)(struct ixgbe_hw *);
+       void (*flap_tx_laser)(struct ixgbe_hw *);
        s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool);
        s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool);
        s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *,
index 399be0c34c36d8593cc8c513745be26d0448775d..4680b069b84fe5d953841ecdf98717088ce21bb1 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <linux/types.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
@@ -46,22 +47,32 @@ struct ixgbe_stats {
        int sizeof_stat;
        int stat_offset;
        int base_stat_offset;
+       int saved_reset_offset;
 };
 
-#define IXGBEVF_STAT(m, b)  sizeof(((struct ixgbevf_adapter *)0)->m), \
-                           offsetof(struct ixgbevf_adapter, m),      \
-                           offsetof(struct ixgbevf_adapter, b)
+#define IXGBEVF_STAT(m, b, r)  sizeof(((struct ixgbevf_adapter *)0)->m), \
+                           offsetof(struct ixgbevf_adapter, m),         \
+                           offsetof(struct ixgbevf_adapter, b),         \
+                           offsetof(struct ixgbevf_adapter, r)
 static struct ixgbe_stats ixgbe_gstrings_stats[] = {
-       {"rx_packets", IXGBEVF_STAT(stats.vfgprc, stats.base_vfgprc)},
-       {"tx_packets", IXGBEVF_STAT(stats.vfgptc, stats.base_vfgptc)},
-       {"rx_bytes", IXGBEVF_STAT(stats.vfgorc, stats.base_vfgorc)},
-       {"tx_bytes", IXGBEVF_STAT(stats.vfgotc, stats.base_vfgotc)},
-       {"tx_busy", IXGBEVF_STAT(tx_busy, zero_base)},
-       {"multicast", IXGBEVF_STAT(stats.vfmprc, stats.base_vfmprc)},
-       {"rx_csum_offload_good", IXGBEVF_STAT(hw_csum_rx_good, zero_base)},
-       {"rx_csum_offload_errors", IXGBEVF_STAT(hw_csum_rx_error, zero_base)},
-       {"tx_csum_offload_ctxt", IXGBEVF_STAT(hw_csum_tx_good, zero_base)},
-       {"rx_header_split", IXGBEVF_STAT(rx_hdr_split, zero_base)},
+       {"rx_packets", IXGBEVF_STAT(stats.vfgprc, stats.base_vfgprc,
+                                   stats.saved_reset_vfgprc)},
+       {"tx_packets", IXGBEVF_STAT(stats.vfgptc, stats.base_vfgptc,
+                                   stats.saved_reset_vfgptc)},
+       {"rx_bytes", IXGBEVF_STAT(stats.vfgorc, stats.base_vfgorc,
+                                 stats.saved_reset_vfgorc)},
+       {"tx_bytes", IXGBEVF_STAT(stats.vfgotc, stats.base_vfgotc,
+                                 stats.saved_reset_vfgotc)},
+       {"tx_busy", IXGBEVF_STAT(tx_busy, zero_base, zero_base)},
+       {"multicast", IXGBEVF_STAT(stats.vfmprc, stats.base_vfmprc,
+                                  stats.saved_reset_vfmprc)},
+       {"rx_csum_offload_good", IXGBEVF_STAT(hw_csum_rx_good, zero_base,
+                                             zero_base)},
+       {"rx_csum_offload_errors", IXGBEVF_STAT(hw_csum_rx_error, zero_base,
+                                               zero_base)},
+       {"tx_csum_offload_ctxt", IXGBEVF_STAT(hw_csum_tx_good, zero_base,
+                                             zero_base)},
+       {"rx_header_split", IXGBEVF_STAT(rx_hdr_split, zero_base, zero_base)},
 };
 
 #define IXGBE_QUEUE_STATS_LEN 0
@@ -455,10 +466,14 @@ static void ixgbevf_get_ethtool_stats(struct net_device *netdev,
                        ixgbe_gstrings_stats[i].stat_offset;
                char *b = (char *)adapter +
                        ixgbe_gstrings_stats[i].base_stat_offset;
+               char *r = (char *)adapter +
+                       ixgbe_gstrings_stats[i].saved_reset_offset;
                data[i] = ((ixgbe_gstrings_stats[i].sizeof_stat ==
                            sizeof(u64)) ? *(u64 *)p : *(u32 *)p) -
                          ((ixgbe_gstrings_stats[i].sizeof_stat ==
-                           sizeof(u64)) ? *(u64 *)b : *(u32 *)b);
+                           sizeof(u64)) ? *(u64 *)b : *(u32 *)b) +
+                         ((ixgbe_gstrings_stats[i].sizeof_stat ==
+                           sizeof(u64)) ? *(u64 *)r : *(u32 *)r);
        }
 }
 
index ca653c49b765ecd44d9b45616bcf91c7e6372d48..0cd6202dfaccfc541c0aee86471997e5189f2cf5 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/ipv6.h>
+#include <linux/slab.h>
 #include <net/checksum.h>
 #include <net/ip6_checksum.h>
 #include <linux/ethtool.h>
@@ -965,7 +966,7 @@ static irqreturn_t ixgbevf_msix_mbx(int irq, void *data)
 
        if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG)
                mod_timer(&adapter->watchdog_timer,
-                         round_jiffies(jiffies + 10));
+                         round_jiffies(jiffies + 1));
 
        return IRQ_HANDLED;
 }
@@ -1610,6 +1611,44 @@ static inline void ixgbevf_rx_desc_queue_enable(struct ixgbevf_adapter *adapter,
                                (adapter->rx_ring[rxr].count - 1));
 }
 
+static void ixgbevf_save_reset_stats(struct ixgbevf_adapter *adapter)
+{
+       /* Only save pre-reset stats if there are some */
+       if (adapter->stats.vfgprc || adapter->stats.vfgptc) {
+               adapter->stats.saved_reset_vfgprc += adapter->stats.vfgprc -
+                       adapter->stats.base_vfgprc;
+               adapter->stats.saved_reset_vfgptc += adapter->stats.vfgptc -
+                       adapter->stats.base_vfgptc;
+               adapter->stats.saved_reset_vfgorc += adapter->stats.vfgorc -
+                       adapter->stats.base_vfgorc;
+               adapter->stats.saved_reset_vfgotc += adapter->stats.vfgotc -
+                       adapter->stats.base_vfgotc;
+               adapter->stats.saved_reset_vfmprc += adapter->stats.vfmprc -
+                       adapter->stats.base_vfmprc;
+       }
+}
+
+static void ixgbevf_init_last_counter_stats(struct ixgbevf_adapter *adapter)
+{
+       struct ixgbe_hw *hw = &adapter->hw;
+
+       adapter->stats.last_vfgprc = IXGBE_READ_REG(hw, IXGBE_VFGPRC);
+       adapter->stats.last_vfgorc = IXGBE_READ_REG(hw, IXGBE_VFGORC_LSB);
+       adapter->stats.last_vfgorc |=
+               (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGORC_MSB))) << 32);
+       adapter->stats.last_vfgptc = IXGBE_READ_REG(hw, IXGBE_VFGPTC);
+       adapter->stats.last_vfgotc = IXGBE_READ_REG(hw, IXGBE_VFGOTC_LSB);
+       adapter->stats.last_vfgotc |=
+               (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGOTC_MSB))) << 32);
+       adapter->stats.last_vfmprc = IXGBE_READ_REG(hw, IXGBE_VFMPRC);
+
+       adapter->stats.base_vfgprc = adapter->stats.last_vfgprc;
+       adapter->stats.base_vfgorc = adapter->stats.last_vfgorc;
+       adapter->stats.base_vfgptc = adapter->stats.last_vfgptc;
+       adapter->stats.base_vfgotc = adapter->stats.last_vfgotc;
+       adapter->stats.base_vfmprc = adapter->stats.last_vfmprc;
+}
+
 static int ixgbevf_up_complete(struct ixgbevf_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
@@ -1656,6 +1695,9 @@ static int ixgbevf_up_complete(struct ixgbevf_adapter *adapter)
        /* enable transmits */
        netif_tx_start_all_queues(netdev);
 
+       ixgbevf_save_reset_stats(adapter);
+       ixgbevf_init_last_counter_stats(adapter);
+
        /* bring the link up in the watchdog, this could race with our first
         * link up interrupt but shouldn't be a problem */
        adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -2228,27 +2270,6 @@ out:
        return err;
 }
 
-static void ixgbevf_init_last_counter_stats(struct ixgbevf_adapter *adapter)
-{
-       struct ixgbe_hw *hw = &adapter->hw;
-
-       adapter->stats.last_vfgprc = IXGBE_READ_REG(hw, IXGBE_VFGPRC);
-       adapter->stats.last_vfgorc = IXGBE_READ_REG(hw, IXGBE_VFGORC_LSB);
-       adapter->stats.last_vfgorc |=
-               (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGORC_MSB))) << 32);
-       adapter->stats.last_vfgptc = IXGBE_READ_REG(hw, IXGBE_VFGPTC);
-       adapter->stats.last_vfgotc = IXGBE_READ_REG(hw, IXGBE_VFGOTC_LSB);
-       adapter->stats.last_vfgotc |=
-               (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGOTC_MSB))) << 32);
-       adapter->stats.last_vfmprc = IXGBE_READ_REG(hw, IXGBE_VFMPRC);
-
-       adapter->stats.base_vfgprc = adapter->stats.last_vfgprc;
-       adapter->stats.base_vfgorc = adapter->stats.last_vfgorc;
-       adapter->stats.base_vfgptc = adapter->stats.last_vfgptc;
-       adapter->stats.base_vfgotc = adapter->stats.last_vfgotc;
-       adapter->stats.base_vfmprc = adapter->stats.last_vfmprc;
-}
-
 #define UPDATE_VF_COUNTER_32bit(reg, last_counter, counter)    \
        {                                                       \
                u32 current_counter = IXGBE_READ_REG(hw, reg);  \
@@ -2399,7 +2420,7 @@ static void ixgbevf_watchdog_task(struct work_struct *work)
                if (!netif_carrier_ok(netdev)) {
                        hw_dbg(&adapter->hw, "NIC Link is Up %s, ",
                               ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
-                               "10 Gbps" : "1 Gbps"));
+                               "10 Gbps\n" : "1 Gbps\n"));
                        netif_carrier_on(netdev);
                        netif_tx_wake_all_queues(netdev);
                } else {
@@ -2416,9 +2437,9 @@ static void ixgbevf_watchdog_task(struct work_struct *work)
                }
        }
 
-pf_has_reset:
        ixgbevf_update_stats(adapter);
 
+pf_has_reset:
        /* Force detection of hung controller every watchdog period */
        adapter->detect_tx_hung = true;
 
@@ -2675,7 +2696,7 @@ static int ixgbevf_open(struct net_device *netdev)
                if (hw->adapter_stopped) {
                        err = IXGBE_ERR_MBX;
                        printk(KERN_ERR "Unable to start - perhaps the PF"
-                              "Driver isn't up yet\n");
+                              " Driver isn't up yet\n");
                        goto err_setup_reset;
                }
        }
@@ -2923,9 +2944,10 @@ static int ixgbevf_tx_map(struct ixgbevf_adapter *adapter,
        struct ixgbevf_tx_buffer *tx_buffer_info;
        unsigned int len;
        unsigned int total = skb->len;
-       unsigned int offset = 0, size, count = 0, i;
+       unsigned int offset = 0, size, count = 0;
        unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
        unsigned int f;
+       int i;
 
        i = tx_ring->next_to_use;
 
@@ -3390,8 +3412,6 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
        /* setup the private structure */
        err = ixgbevf_sw_init(adapter);
 
-       ixgbevf_init_last_counter_stats(adapter);
-
 #ifdef MAX_SKB_FRAGS
        netdev->features = NETIF_F_SG |
                           NETIF_F_IP_CSUM |
@@ -3449,6 +3469,8 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
 
        adapter->netdev_registered = true;
 
+       ixgbevf_init_last_counter_stats(adapter);
+
        /* print the MAC address */
        hw_dbg(hw, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
               netdev->dev_addr[0],
index 799600e927002863c7003b6529ba3c0c758241b9..1f31b052d4b4b788a7e670199b6c16503cfc5b08 100644 (file)
@@ -157,6 +157,12 @@ struct ixgbevf_hw_stats {
        u64 vfgorc;
        u64 vfgotc;
        u64 vfmprc;
+
+       u64 saved_reset_vfgprc;
+       u64 saved_reset_vfgptc;
+       u64 saved_reset_vfgorc;
+       u64 saved_reset_vfgotc;
+       u64 saved_reset_vfmprc;
 };
 
 struct ixgbevf_info {
index e9d9d595e1b705635d12aefee9655030b5b88512..d5932ca3e27db3700c84f19e9518edf447f71250 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/etherdevice.h>
 #include <linux/init.h>
 #include <linux/moduleparam.h>
+#include <linux/gfp.h>
 #include <asm/hardware/uengine.h>
 #include <asm/io.h>
 #include "ixp2400_rx.ucode"
index f47d4d663b1901db46568d430c6806e4c32cb481..3e6aaf9e5ce7c4060b1bc042cf4d46608549297a 100644 (file)
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
+#include <linux/gfp.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
@@ -35,6 +35,7 @@
 #include <linux/skbuff.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <asm/bootinfo.h>
 #include <asm/system.h>
index 0f31497833df518795f34fadeb4f1f5af85772c6..b705ad3a53a785a0f64c5f83f831177b192b8c6a 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/if_vlan.h>
+#include <linux/slab.h>
 #include <net/ip6_checksum.h>
 #include "jme.h"
 
@@ -946,6 +947,8 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx)
                                jme->jme_vlan_rx(skb, jme->vlgrp,
                                        le16_to_cpu(rxdesc->descwb.vlan));
                                NET_STAT(jme).rx_bytes += 4;
+                       } else {
+                               dev_kfree_skb(skb);
                        }
                } else {
                        jme->jme_rx(skb);
@@ -2081,12 +2084,45 @@ jme_tx_timeout(struct net_device *netdev)
        jme_reset_link(jme);
 }
 
+static inline void jme_pause_rx(struct jme_adapter *jme)
+{
+       atomic_dec(&jme->link_changing);
+
+       jme_set_rx_pcc(jme, PCC_OFF);
+       if (test_bit(JME_FLAG_POLL, &jme->flags)) {
+               JME_NAPI_DISABLE(jme);
+       } else {
+               tasklet_disable(&jme->rxclean_task);
+               tasklet_disable(&jme->rxempty_task);
+       }
+}
+
+static inline void jme_resume_rx(struct jme_adapter *jme)
+{
+       struct dynpcc_info *dpi = &(jme->dpi);
+
+       if (test_bit(JME_FLAG_POLL, &jme->flags)) {
+               JME_NAPI_ENABLE(jme);
+       } else {
+               tasklet_hi_enable(&jme->rxclean_task);
+               tasklet_hi_enable(&jme->rxempty_task);
+       }
+       dpi->cur                = PCC_P1;
+       dpi->attempt            = PCC_P1;
+       dpi->cnt                = 0;
+       jme_set_rx_pcc(jme, PCC_P1);
+
+       atomic_inc(&jme->link_changing);
+}
+
 static void
 jme_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
 {
        struct jme_adapter *jme = netdev_priv(netdev);
 
+       jme_pause_rx(jme);
        jme->vlgrp = grp;
+       jme_resume_rx(jme);
 }
 
 static void
index c19db9146a2f38ef44d4a776d0df9f5b39a26e8d..07ad3a457185c3f440c65e9d2a04cb6de1214aa3 100644 (file)
@@ -25,7 +25,7 @@
 #define __JME_H_INCLUDED__
 
 #define DRV_NAME       "jme"
-#define DRV_VERSION    "1.0.5"
+#define DRV_VERSION    "1.0.6"
 #define PFX            DRV_NAME ": "
 
 #define PCI_DEVICE_ID_JMICRON_JMC250   0x0250
index 0573e0bb4444162e5153043532023b82b7a16bb0..9e9f9b3497669fbc5c1ce063a28a48e28392c432 100644 (file)
@@ -722,12 +722,14 @@ static void ks8851_tx_work(struct work_struct *work)
                txb = skb_dequeue(&ks->txq);
                last = skb_queue_empty(&ks->txq);
 
-               ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA);
-               ks8851_wrpkt(ks, txb, last);
-               ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr);
-               ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE);
+               if (txb != NULL) {
+                       ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA);
+                       ks8851_wrpkt(ks, txb, last);
+                       ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr);
+                       ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE);
 
-               ks8851_done_tx(ks, txb);
+                       ks8851_done_tx(ks, txb);
+               }
        }
 
        mutex_unlock(&ks->lock);
@@ -976,7 +978,6 @@ static void ks8851_set_rx_mode(struct net_device *dev)
                        crc >>= (32 - 6);  /* get top six bits */
 
                        rxctrl.mchash[crc >> 4] |= (1 << (crc & 0xf));
-                       mcptr = mcptr->next;
                }
 
                rxctrl.rxcr1 = RXCR1_RXME | RXCR1_RXPAFMA;
index 84b0e15831f943d0bf46327cb44b7c6be42b49c1..6354ab3a45a651beb59e5b47d97c7d909357a7a9 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/mii.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #define        DRV_NAME        "ks8851_mll"
 
index 7264a3e5c2c0880316576a00680815634da25ad5..0606a1f359fb8a2c2d1ca47fe6907565ce3e489c 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/if_vlan.h>
 #include <linux/crc32.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 
 /* DMA Registers */
@@ -4899,8 +4900,10 @@ static int netdev_tx(struct sk_buff *skb, struct net_device *dev)
                        struct sk_buff *org_skb = skb;
 
                        skb = dev_alloc_skb(org_skb->len);
-                       if (!skb)
-                               return NETDEV_TX_BUSY;
+                       if (!skb) {
+                               rc = NETDEV_TX_BUSY;
+                               goto unlock;
+                       }
                        skb_copy_and_csum_dev(org_skb, skb->data);
                        org_skb->ip_summed = 0;
                        skb->len = org_skb->len;
@@ -4914,7 +4917,7 @@ static int netdev_tx(struct sk_buff *skb, struct net_device *dev)
                netif_stop_queue(dev);
                rc = NETDEV_TX_BUSY;
        }
-
+unlock:
        spin_unlock_irq(&hw_priv->hwlock);
 
        return rc;
@@ -6320,7 +6323,7 @@ static int netdev_set_eeprom(struct net_device *dev,
        int len;
 
        if (eeprom->magic != EEPROM_MAGIC)
-               return 1;
+               return -EINVAL;
 
        len = (eeprom->offset + eeprom->len + 1) / 2;
        for (i = eeprom->offset / 2; i < len; i++)
index b77238dbafb85182dc154e8faaf51857cc493b62..6eba352c52e0809127d7e02ffea24e413ca82a47 100644 (file)
@@ -74,7 +74,6 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
index 443c39a3732f30ea494175793b80566423099bd5..973390b82ec28850cf17f1ab26c18e7538f656a9 100644 (file)
@@ -73,7 +73,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
@@ -85,6 +84,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/gfp.h>
 
 /* DEBUG flags
  */
index a18e3485476e51fa96ce9c1af9994026538bf0e7..ba617e3cf1bbd6c9442419e8fd591bcc582eaab2 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/in.h>
 #include <linux/io.h>
 #include <linux/ip.h>
+#include <linux/slab.h>
 
 #include "ll_temac.h"
 
index da0e462308d51a82c367aa73628f4c26c4bc7d84..5ae28c975b384bf64ff7a7dc763a3d1766669b5a 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/phy.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/slab.h>
 #include <linux/of_mdio.h>
 
 #include "ll_temac.h"
index a8768672dc5aece9741081e3cde63835b5d80c01..c8e68fde0664862dd0af4da936f4f0d1ae87f32e 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/ioport.h>
 #include <linux/nubus.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/init.h>
index c292a608f9a9c1d04bd1dabd8f439f22a60b6b73..c0876e915eed7afe6adf84df917bf426a497707b 100644 (file)
@@ -88,7 +88,6 @@ static char *version =
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/nubus.h>
 #include <linux/errno.h>
@@ -98,6 +97,7 @@ static char *version =
 #include <linux/skbuff.h>
 #include <linux/delay.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
index ab5f0bf6d1ae8531d7042ad6c0edc7a8a3a0fe0b..962c41d0c8dfb07d7837ee79d3c836fdf2cd90fb 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/crc32.h>
 #include <linux/spinlock.h>
 #include <linux/bitrev.h>
+#include <linux/slab.h>
 #include <asm/prom.h>
 #include <asm/dbdma.h>
 #include <asm/io.h>
index 13ba8f4afb7e6712f34bca4203e1f5e36b058373..52e9a51c4c4fcf0788d2b33f74f033284779271a 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/bitrev.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
+#include <linux/gfp.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/macintosh.h>
index 24109c288108109575fdba9d7e0b8cff3c917d9c..adb54fe2d82a3e024880c64657ffb88253a40d2b 100644 (file)
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
+#include <linux/gfp.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/nubus.h>
@@ -50,6 +50,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/bitrev.h>
+#include <linux/slab.h>
 
 #include <asm/bootinfo.h>
 #include <asm/system.h>
index 55ceae09738e91c68e44046b7c21646e7fa27528..abba3cc81f129d99116f6e8dccafa29a0ad5dc75 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/cache.h>
 #include <linux/sched.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/wait.h>
 #include <linux/cdev.h>
index 65ec77dc31f5b5c4a542a22a2f7d11c464a9d664..23cee7b6af918c146f2f447291bf180a6af4bb58 100644 (file)
@@ -33,6 +33,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/errno.h>
 
index ccfe276943f09f7e036899d90a09ea6220ab77cf..7cd34e9c7c7efdf42af40cce389c20b3cbf09e94 100644 (file)
@@ -35,6 +35,7 @@
  */
 
 #include <linux/hardirq.h>
+#include <linux/gfp.h>
 
 #include <linux/mlx4/cmd.h>
 #include <linux/mlx4/cq.h>
index 507e11fce9ed7f202e9d6aa59e3135326d6aa94d..cbabf14f95d027aa57be9cf77126cd30bae4b0d2 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 
 #include <linux/mlx4/driver.h>
 #include <linux/mlx4/device.h>
index c48b0f4b17b7c395bcecf527413035aa82166657..73c3d20c64534248768d29385b5cb6799b2fc8ba 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/tcp.h>
 #include <linux/if_vlan.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <linux/mlx4/driver.h>
 #include <linux/mlx4/device.h>
index 16256784a943bf13b0ebe8fd5184eaa8fea83033..0dfb4ec8a9dd09295de01eb422b68511ab891c5e 100644 (file)
@@ -31,6 +31,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/mlx4/qp.h>
 
index 64394647dddc2a1a64a9ab15ba149ee347f0cd81..8e2fcb7103c3a12a3072549881a7529d3062bc85 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <linux/mlx4/cq.h>
+#include <linux/slab.h>
 #include <linux/mlx4/qp.h>
 #include <linux/skbuff.h>
 #include <linux/if_ether.h>
index 3d1396af9462795f123c4602e7ff01f6d3022549..580968f304eb9d24f752e38fc368e64208700510 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <asm/page.h>
 #include <linux/mlx4/cq.h>
+#include <linux/slab.h>
 #include <linux/mlx4/qp.h>
 #include <linux/skbuff.h>
 #include <linux/if_vlan.h>
index bffb7995cb70a4f6a9b09bdcc137cd317e3a641e..7365bf488b81a6a1572971da726b7f9662f042e6 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
 
index 04b382fcb8c881c2ab76fea05636deb63c64effd..57288ca1395f1e6b0974655396afb5341566b37a 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/errno.h>
 #include <linux/mm.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 #include <linux/mlx4/cmd.h>
 
index 0e7eb1038f9f443e8b0af3525a5fd9b871c608d7..5550678027513fa6f7b443bffe63e72198f4ec1c 100644 (file)
@@ -31,6 +31,8 @@
  * SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "mlx4.h"
 
 struct mlx4_device_context {
index 8f6e816a7395f78dadfa12c7a64269ce820d0b7d..e3e0d54a7c87851ca15df3f640326de174dc9a42 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/errno.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <linux/mlx4/device.h>
 #include <linux/mlx4/doorbell.h>
@@ -1023,6 +1024,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port)
        info->port_attr.attr.mode = S_IRUGO | S_IWUSR;
        info->port_attr.show      = show_port_type;
        info->port_attr.store     = set_port_type;
+       sysfs_attr_init(&info->port_attr.attr);
 
        err = device_create_file(&dev->pdev->dev, &info->port_attr);
        if (err) {
index 5ccbce9866fe0b70918f362fba4b9a6e4bef8da3..c4f88b7ef7b6dbc33a4d6d08bb2bca1b9a010ff3 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include <linux/string.h>
-#include <linux/slab.h>
 
 #include <linux/mlx4/cmd.h>
 
index ca7ab8e7b4cc3917cc94599315f6d16f8e930150..3dc69be4949f2b175418273a2905c866dad4acd0 100644 (file)
@@ -33,6 +33,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/slab.h>
 
 #include <linux/mlx4/cmd.h>
 
index ca25b9dc837853e979650a3c5fc8b01f6a71e961..5caf0115fa5b4e923e3d10d760c6c1284a21c694 100644 (file)
@@ -32,6 +32,8 @@
  * SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "mlx4.h"
 #include "fw.h"
 
index 42ab9fc01d3e1f04e40623f194903fbecc11568e..ec9350e5f21ab7072dc00a062b28cb9781af2d7b 100644 (file)
@@ -33,6 +33,7 @@
  * SOFTWARE.
  */
 
+#include <linux/gfp.h>
 #include <linux/mlx4/cmd.h>
 #include <linux/mlx4/qp.h>
 
index 1377d0dc8f1f41d7de9f35d9a97bf49c0e0c433b..3b07b80a0456baec10d02146c1a71aa1feed872e 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <linux/mlx4/cmd.h>
+#include <linux/gfp.h>
 
 #include "mlx4.h"
 #include "icm.h"
index c97b6e4365a96c1af84515f0d1f95864e0ccec79..8613a52ddf171b59a78ca652203cef2a8ccb409d 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/io.h>
 #include <linux/types.h>
 #include <linux/inet_lro.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 
 static char mv643xx_eth_driver_name[] = "mv643xx_eth";
index 93c709d63e2f5abc9f91d2cefacf2651057e7708..3a7ad840d5b5b36c54f676bd97b66d60417f4e1d 100644 (file)
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 /* Used for the temporal inet entries and routing */
 #include <linux/socket.h>
 #include <linux/route.h>
index 676c513e12fc486eae515e6d539a7d95db4c8852..ecde0876a78583fc8c4e063875be3e4975015d52 100644 (file)
@@ -64,6 +64,7 @@
 #include <linux/moduleparam.h>
 #include <linux/io.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 #include <net/checksum.h>
 #include <net/ip.h>
 #include <net/tcp.h>
@@ -1689,7 +1690,7 @@ myri10ge_set_pauseparam(struct net_device *netdev,
        if (pause->tx_pause != mgp->pause)
                return myri10ge_change_pause(mgp, pause->tx_pause);
        if (pause->rx_pause != mgp->pause)
-               return myri10ge_change_pause(mgp, pause->tx_pause);
+               return myri10ge_change_pause(mgp, pause->rx_pause);
        if (pause->autoneg != 0)
                return -EINVAL;
        return 0;
@@ -3687,7 +3688,6 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
        if (status != 0) {
                dev_err(&mgp->pdev->dev, "failed reset\n");
                goto abort_with_fw;
-               return;
        }
 
        mgp->max_intr_slots = cmd.data0 / sizeof(struct mcp_slot);
index 8b4313085359ce703f2f4bd6c91c815c43a2c030..b72e749afdf102d5bb690be5e29617044a927a75 100644 (file)
@@ -14,7 +14,6 @@ static char version[] =
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -26,6 +25,7 @@ static char version[] =
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/firmware.h>
+#include <linux/gfp.h>
 
 #include <net/dst.h>
 #include <net/arp.h>
index 992dbfffdb05ece983205f5ffe71d5e6073af208..f4347f88b6f2c62d73754bbee75adc416ecf8462 100644 (file)
@@ -142,7 +142,7 @@ bad_clone_list[] __initdata = {
     {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
     {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
 #ifdef CONFIG_MACH_TX49XX
-    {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}},  /* Toshiba built-in */
+    {"RBHMA4X00-RTL8019", "RBHMA4X00-RTL8019", {0x00, 0x60, 0x0a}},  /* Toshiba built-in */
 #endif
     {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
     {NULL,}
index a53bb201d3c7612f92ba6015fbfd4ae15726ae32..ff3c4c81498847c825869ff009ac8d74ab2243d2 100644 (file)
@@ -66,7 +66,6 @@ static const char *version = "ne2.c:v0.91 Nov 16 1998 Wim Dumon <wimpie@kotnet.o
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/init.h>
index bf4af5248cb75549a46415f21ab7685c948e1b42..a361dea35574db454a82d25ddcc9050f057c4a90 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/console.h>
 #include <linux/moduleparam.h>
 #include <linux/string.h>
index 144d2e8804225a16e20f3799eface6c1f8a6f165..0f703838e21ad73b5ad775e35b9984146d60cf5f 100644 (file)
@@ -53,8 +53,8 @@
 
 #define _NETXEN_NIC_LINUX_MAJOR 4
 #define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 72
-#define NETXEN_NIC_LINUX_VERSIONID  "4.0.72"
+#define _NETXEN_NIC_LINUX_SUBVERSION 73
+#define NETXEN_NIC_LINUX_VERSIONID  "4.0.73"
 
 #define NETXEN_VERSION_CODE(a, b, c)   (((a) << 24) + ((b) << 16) + (c))
 #define _major(v)      (((v) >> 24) & 0xff)
index 2a8ef5fc9663b094bcfdfb5fc24c2f4adbff31be..f26e54716c886569f9e30d9a8a5c34d6056b58e6 100644 (file)
@@ -669,13 +669,15 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
                }
                sds_ring->desc_head = (struct status_desc *)addr;
 
-               sds_ring->crb_sts_consumer =
-                       netxen_get_ioaddr(adapter,
-                       recv_crb_registers[port].crb_sts_consumer[ring]);
+               if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+                       sds_ring->crb_sts_consumer =
+                               netxen_get_ioaddr(adapter,
+                               recv_crb_registers[port].crb_sts_consumer[ring]);
 
-               sds_ring->crb_intr_mask =
-                       netxen_get_ioaddr(adapter,
-                       recv_crb_registers[port].sw_int_mask[ring]);
+                       sds_ring->crb_intr_mask =
+                               netxen_get_ioaddr(adapter,
+                               recv_crb_registers[port].sw_int_mask[ring]);
+               }
        }
 
 
index a945591298a8519b314144bd86e8c751bf8cc272..b1cf46a0c48c887c7c0903b2a6343fbcd2ba9135 100644 (file)
@@ -23,6 +23,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include "netxen_nic.h"
 #include "netxen_nic_hw.h"
 
index 1c63610ead422a29b4628e525b7c1be37de300dd..02876f59cbb21bbcf7f4660868e4f47a8f778f44 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include "netxen_nic.h"
 #include "netxen_nic_hw.h"
 
@@ -761,7 +762,7 @@ nx_get_bios_version(struct netxen_adapter *adapter)
        if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) {
                bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off])
                                                + NX_UNI_BIOS_VERSION_OFF));
-               return (bios_ver << 24) + ((bios_ver >> 8) & 0xff00) +
+               return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) +
                                                        (bios_ver >> 24);
        } else
                return cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]);
index 08780ef1c1f885d56b38d9c4ff68b4f790711f58..ce838f7c8b0f3e1cd33702fc72cf5f2a82b6c3ae 100644 (file)
@@ -23,6 +23,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/interrupt.h>
 #include "netxen_nic_hw.h"
@@ -604,16 +605,14 @@ netxen_cleanup_pci_map(struct netxen_adapter *adapter)
 static int
 netxen_setup_pci_map(struct netxen_adapter *adapter)
 {
-       void __iomem *mem_ptr0 = NULL;
-       void __iomem *mem_ptr1 = NULL;
-       void __iomem *mem_ptr2 = NULL;
        void __iomem *db_ptr = NULL;
 
        resource_size_t mem_base, db_base;
-       unsigned long mem_len, db_len = 0, pci_len0 = 0;
+       unsigned long mem_len, db_len = 0;
 
        struct pci_dev *pdev = adapter->pdev;
        int pci_func = adapter->ahw.pci_func;
+       struct netxen_hardware_context *ahw = &adapter->ahw;
 
        int err = 0;
 
@@ -630,24 +629,40 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
 
        /* 128 Meg of memory */
        if (mem_len == NETXEN_PCI_128MB_SIZE) {
-               mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE);
-               mem_ptr1 = ioremap(mem_base + SECOND_PAGE_GROUP_START,
+
+               ahw->pci_base0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE);
+               ahw->pci_base1 = ioremap(mem_base + SECOND_PAGE_GROUP_START,
                                SECOND_PAGE_GROUP_SIZE);
-               mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START,
+               ahw->pci_base2 = ioremap(mem_base + THIRD_PAGE_GROUP_START,
                                THIRD_PAGE_GROUP_SIZE);
-               pci_len0 = FIRST_PAGE_GROUP_SIZE;
+               if (ahw->pci_base0 == NULL || ahw->pci_base1 == NULL ||
+                                               ahw->pci_base2 == NULL) {
+                       dev_err(&pdev->dev, "failed to map PCI bar 0\n");
+                       err = -EIO;
+                       goto err_out;
+               }
+
+               ahw->pci_len0 = FIRST_PAGE_GROUP_SIZE;
+
        } else if (mem_len == NETXEN_PCI_32MB_SIZE) {
-               mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE);
-               mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
+
+               ahw->pci_base1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE);
+               ahw->pci_base2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
                        SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
+               if (ahw->pci_base1 == NULL || ahw->pci_base2 == NULL) {
+                       dev_err(&pdev->dev, "failed to map PCI bar 0\n");
+                       err = -EIO;
+                       goto err_out;
+               }
+
        } else if (mem_len == NETXEN_PCI_2MB_SIZE) {
 
-               mem_ptr0 = pci_ioremap_bar(pdev, 0);
-               if (mem_ptr0 == NULL) {
+               ahw->pci_base0 = pci_ioremap_bar(pdev, 0);
+               if (ahw->pci_base0 == NULL) {
                        dev_err(&pdev->dev, "failed to map PCI bar 0\n");
                        return -EIO;
                }
-               pci_len0 = mem_len;
+               ahw->pci_len0 = mem_len;
        } else {
                return -EIO;
        }
@@ -656,11 +671,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
 
        dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20));
 
-       adapter->ahw.pci_base0 = mem_ptr0;
-       adapter->ahw.pci_len0 = pci_len0;
-       adapter->ahw.pci_base1 = mem_ptr1;
-       adapter->ahw.pci_base2 = mem_ptr2;
-
        if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) {
                adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter,
                        NETXEN_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func)));
@@ -1246,8 +1256,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        int pci_func_id = PCI_FUNC(pdev->devfn);
        uint8_t revision_id;
 
-       if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) {
-               pr_warning("%s: chip revisions between 0x%x-0x%x"
+       if (pdev->revision >= NX_P3_A0 && pdev->revision <= NX_P3_B1) {
+               pr_warning("%s: chip revisions between 0x%x-0x%x "
                                "will not be enabled.\n",
                                module_name(THIS_MODULE), NX_P3_A0, NX_P3_B1);
                return -ENODEV;
index c16cbfb4061b716beb8c24fcc594140e9d47eaba..3892330f244a0e65b6a96bf3be8e2b72236f6e79 100644 (file)
@@ -51,7 +51,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/init.h>
index 05c29c2cef2a62327e3932796b1026961914d528..f7a8f707361e8bbf60bc9071f40e3bb715a7ee5e 100644 (file)
@@ -109,7 +109,6 @@ static int fifo = 0x8;      /* don't change */
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/init.h>
index 0678f3106cbcca5981cd1aa50df08919e04968e2..d5cd16bfc907b32a3e287258c9cf41761cd5de1d 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/jiffies.h>
 #include <linux/crc32.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 
 #include <linux/io.h>
 
index 8dd509c09bc8cd19cff96535e9ea0d0ab13f4bc0..e88e97cd1b10805803fb876c73af9c06848cb47f 100644 (file)
 #include <linux/if_vlan.h>
 #include <linux/rtnetlink.h>
 #include <linux/jiffies.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
index be368e5cbf7589a1897a6b8bd88f752767d928b2..8aadc8e2ddd7e062bde2c2a0757019bcfd746ae6 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/if_vlan.h>
+#include <linux/slab.h>
 #include <linux/phy.h>
 #include <linux/spinlock.h>
 
index d44d4a208bbf144ceecd4f7ba6dab36d16e6eb38..370c147d08a3d6d1759a55ad8db01a95ad28e71f 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/dmaengine.h>
 #include <linux/delay.h>
index 3d1d3a7b7ed3cc6065968ff1f1d1c434d0e84aae..757f87bb1db30e75fd5835ef0b209c30867d95ed 100644 (file)
@@ -781,8 +781,13 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
                  inw(ioaddr + EL3_STATUS));
 
        spin_lock_irqsave(&lp->window_lock, flags);
+
+       dev->stats.tx_bytes += skb->len;
+
+       /* Put out the doubleword header... */
        outw(skb->len, ioaddr + TX_FIFO);
        outw(0, ioaddr + TX_FIFO);
+       /* ... and the packet rounded to a doubleword. */
        outsl(ioaddr + TX_FIFO, skb->data, (skb->len+3)>>2);
 
        dev->trans_start = jiffies;
@@ -1021,8 +1026,6 @@ static void update_stats(struct net_device *dev)
        /* BadSSD */                               inb(ioaddr + 12);
        up                                       = inb(ioaddr + 13);
 
-       dev->stats.tx_bytes                     += tx + ((up & 0xf0) << 12);
-
        EL3WINDOW(1);
 }
 
index 09291e60d309a38cf5563e06ddcdbfdfc11b5504..9f3d593f14edba92882e3283fcadcfccfa371f64 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/delay.h>
index 776cad2f57150d1ecf209ec7063a0ed393bc3fec..4c0368de18158e29161e965cbdf33875d762d3e5 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/delay.h>
@@ -1549,6 +1548,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
        PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x021b, 0x0101),
        PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x08a1, 0xc0ab),
        PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4),
+       PCMCIA_PFC_DEVICE_PROD_ID12(0, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e),
        PCMCIA_PFC_DEVICE_PROD_ID12(0, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
        PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
        PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
@@ -1740,7 +1740,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
        PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),
        PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
        PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"),
-       PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"),
+       PCMCIA_DEVICE_CIS_PROD_ID12("Allied Telesis,K.K", "Ethernet LAN Card", 0x2ad62f3c, 0x9fd2f0a2, "cis/LA-PCM.cis"),
        PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "cis/PE520.cis"),
        PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"),
        PCMCIA_DEVICE_CIS_PROD_ID12("PMX   ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"),
index 5adc662c4bfbd3b15d42ab80c47f1d9b5b633506..ccc553782a0d807eac5fbe22b69cdb467575746b 100644 (file)
@@ -493,13 +493,14 @@ static int pcmcia_get_versmac(struct pcmcia_device *p_dev,
 {
        struct net_device *dev = priv;
        cisparse_t parse;
+       u8 *buf;
 
        if (pcmcia_parse_tuple(tuple, &parse))
                return -EINVAL;
 
-       if ((parse.version_1.ns > 3) &&
-           (cvt_ascii_address(dev,
-                              (parse.version_1.str + parse.version_1.ofs[3]))))
+       buf = parse.version_1.str + parse.version_1.ofs[3];
+
+       if ((parse.version_1.ns > 3) && (cvt_ascii_address(dev, buf) == 0))
                return 0;
 
        return -EINVAL;
@@ -528,7 +529,7 @@ static int mhz_setup(struct pcmcia_device *link)
     len = pcmcia_get_tuple(link, 0x81, &buf);
     if (buf && len >= 13) {
            buf[12] = '\0';
-           if (cvt_ascii_address(dev, buf))
+           if (cvt_ascii_address(dev, buf) == 0)
                    rc = 0;
     }
     kfree(buf);
@@ -910,7 +911,7 @@ static int smc91c92_config(struct pcmcia_device *link)
 
     if (i != 0) {
        printk(KERN_NOTICE "smc91c92_cs: Unable to find hardware address.\n");
-       goto config_undo;
+       goto config_failed;
     }
 
     smc->duplex = 0;
@@ -998,6 +999,7 @@ config_undo:
     unregister_netdev(dev);
 config_failed:
     smc91c92_release(link);
+    free_netdev(dev);
     return -ENODEV;
 } /* smc91c92_config */
 
@@ -1606,9 +1608,12 @@ static void set_rx_mode(struct net_device *dev)
 {
     unsigned int ioaddr = dev->base_addr;
     struct smc_private *smc = netdev_priv(dev);
-    u_int multicast_table[ 2 ] = { 0, };
+    unsigned char multicast_table[8];
     unsigned long flags;
     u_short rx_cfg_setting;
+    int i;
+
+    memset(multicast_table, 0, sizeof(multicast_table));
 
     if (dev->flags & IFF_PROMISC) {
        rx_cfg_setting = RxStripCRC | RxEnable | RxPromisc | RxAllMulti;
@@ -1620,10 +1625,6 @@ static void set_rx_mode(struct net_device *dev)
 
            netdev_for_each_mc_addr(mc_addr, dev) {
                u_int position = ether_crc(6, mc_addr->dmi_addr);
-#ifndef final_version          /* Verify multicast address. */
-               if ((mc_addr->dmi_addr[0] & 1) == 0)
-                   continue;
-#endif
                multicast_table[position >> 29] |= 1 << ((position >> 26) & 7);
            }
        }
@@ -1633,8 +1634,8 @@ static void set_rx_mode(struct net_device *dev)
     /* Load MC table and Rx setting into the chip without interrupts. */
     spin_lock_irqsave(&smc->lock, flags);
     SMC_SELECT_BANK(3);
-    outl(multicast_table[0], ioaddr + MULTICAST0);
-    outl(multicast_table[1], ioaddr + MULTICAST4);
+    for (i = 0; i < 8; i++)
+       outb(multicast_table[i], ioaddr + MULTICAST0 + i);
     SMC_SELECT_BANK(0);
     outw(rx_cfg_setting, ioaddr + RCR);
     SMC_SELECT_BANK(2);
@@ -1803,23 +1804,30 @@ static void media_check(u_long arg)
     SMC_SELECT_BANK(1);
     media |= (inw(ioaddr + CONFIG) & CFG_AUI_SELECT) ? 2 : 1;
 
+    SMC_SELECT_BANK(saved_bank);
+    spin_unlock_irqrestore(&smc->lock, flags);
+
     /* Check for pending interrupt with watchdog flag set: with
        this, we can limp along even if the interrupt is blocked */
     if (smc->watchdog++ && ((i>>8) & i)) {
        if (!smc->fast_poll)
            printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+       local_irq_save(flags);
        smc_interrupt(dev->irq, dev);
+       local_irq_restore(flags);
        smc->fast_poll = HZ;
     }
     if (smc->fast_poll) {
        smc->fast_poll--;
        smc->media.expires = jiffies + HZ/100;
        add_timer(&smc->media);
-       SMC_SELECT_BANK(saved_bank);
-       spin_unlock_irqrestore(&smc->lock, flags);
        return;
     }
 
+    spin_lock_irqsave(&smc->lock, flags);
+
+    saved_bank = inw(ioaddr + BANK_SELECT);
+
     if (smc->cfg & CFG_MII_SELECT) {
        if (smc->mii_if.phy_id < 0)
            goto reschedule;
@@ -1977,15 +1985,16 @@ static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        unsigned int ioaddr = dev->base_addr;
        u16 saved_bank = inw(ioaddr + BANK_SELECT);
        int ret;
+       unsigned long flags;
 
-       spin_lock_irq(&smc->lock);
+       spin_lock_irqsave(&smc->lock, flags);
        SMC_SELECT_BANK(3);
        if (smc->cfg & CFG_MII_SELECT)
                ret = mii_ethtool_gset(&smc->mii_if, ecmd);
        else
                ret = smc_netdev_get_ecmd(dev, ecmd);
        SMC_SELECT_BANK(saved_bank);
-       spin_unlock_irq(&smc->lock);
+       spin_unlock_irqrestore(&smc->lock, flags);
        return ret;
 }
 
@@ -1995,15 +2004,16 @@ static int smc_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        unsigned int ioaddr = dev->base_addr;
        u16 saved_bank = inw(ioaddr + BANK_SELECT);
        int ret;
+       unsigned long flags;
 
-       spin_lock_irq(&smc->lock);
+       spin_lock_irqsave(&smc->lock, flags);
        SMC_SELECT_BANK(3);
        if (smc->cfg & CFG_MII_SELECT)
                ret = mii_ethtool_sset(&smc->mii_if, ecmd);
        else
                ret = smc_netdev_set_ecmd(dev, ecmd);
        SMC_SELECT_BANK(saved_bank);
-       spin_unlock_irq(&smc->lock);
+       spin_unlock_irqrestore(&smc->lock, flags);
        return ret;
 }
 
@@ -2013,12 +2023,13 @@ static u32 smc_get_link(struct net_device *dev)
        unsigned int ioaddr = dev->base_addr;
        u16 saved_bank = inw(ioaddr + BANK_SELECT);
        u32 ret;
+       unsigned long flags;
 
-       spin_lock_irq(&smc->lock);
+       spin_lock_irqsave(&smc->lock, flags);
        SMC_SELECT_BANK(3);
        ret = smc_link_ok(dev);
        SMC_SELECT_BANK(saved_bank);
-       spin_unlock_irq(&smc->lock);
+       spin_unlock_irqrestore(&smc->lock, flags);
        return ret;
 }
 
@@ -2055,16 +2066,17 @@ static int smc_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
        int rc = 0;
        u16 saved_bank;
        unsigned int ioaddr = dev->base_addr;
+       unsigned long flags;
 
        if (!netif_running(dev))
                return -EINVAL;
 
-       spin_lock_irq(&smc->lock);
+       spin_lock_irqsave(&smc->lock, flags);
        saved_bank = inw(ioaddr + BANK_SELECT);
        SMC_SELECT_BANK(3);
        rc = generic_mii_ioctl(&smc->mii_if, mii, cmd, NULL);
        SMC_SELECT_BANK(saved_bank);
-       spin_unlock_irq(&smc->lock);
+       spin_unlock_irqrestore(&smc->lock, flags);
        return rc;
 }
 
index fc5938ba3d7874f591cc16a05aa6aa084bccd6aa..a527e37728cd9fe4566445b78bd2c1cf47bc0a88 100644 (file)
@@ -88,6 +88,11 @@ config LSI_ET1011C_PHY
        ---help---
          Supports the LSI ET1011C PHY.
 
+config MICREL_PHY
+       tristate "Driver for Micrel PHYs"
+       ---help---
+         Supports the KSZ9021, VSC8201, KS8001 PHYs.
+
 config FIXED_PHY
        bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
        depends on PHYLIB=y
index 1342585af3812de222ccd99f8d7090e127c916df..13bebab65d027c9a9c3c3c6aef2a823d1033859a 100644 (file)
@@ -20,4 +20,5 @@ obj-$(CONFIG_MDIO_BITBANG)    += mdio-bitbang.o
 obj-$(CONFIG_MDIO_GPIO)                += mdio-gpio.o
 obj-$(CONFIG_NATIONAL_PHY)     += national.o
 obj-$(CONFIG_STE10XP)          += ste10Xp.o
+obj-$(CONFIG_MICREL_PHY)       += micrel.o
 obj-$(CONFIG_MDIO_OCTEON)      += mdio-octeon.o
index a1bd599c8a5b5014c1465cd4e7f56be3701567a5..92282b31d94bf64d5c53617f385140b305ad14f9 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index d926168bc7809c62e46d32d5d9fe98e493ad6e7e..c722e95853ff5d9d775191504f9d7e918680cc83 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index b031fa21f1aa0a6f4640e9a61099210ab0a88306..7712ebeba9bf0a6881f3cb6a03c2124579546046 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index e7070515d2e360d68f25c76f0795f0f1943ab323..1fa4d73c3cca5e0d6ff4579abd986a910ab67305 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/phy.h>
 #include <linux/phy_fixed.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #define MII_REGS_NUM 29
 
index af3f1f2a9f8721aafe0dbfff30859967b43717f9..904208b95d4b81221fa96271492ee6fd85707cce 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index 4cf3324ba166405ef45a86f4161cc97ac16802fb..057ecaacde6b77fa275b0805aced7259c652724d 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index 65ed385c2ceb430f091cf26ef0b1acfc87a6978a..64c7fbe0a8e7e09a451a4c8e000e075e149c4c0d 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index 2576055b350be1101ae699a8f5c75b98b0534b24..19e70d7e27ab15e68eda7830bcc674015c282c30 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <linux/module.h>
 #include <linux/mdio-bitbang.h>
-#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/delay.h>
 
index 61a4461cbda5ccf3a9642be06f67c252b750a5e9..f443d43edd80e242fba17e9ea3cf9de7c7b403fb 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright (C) 2009 Cavium Networks
  */
 
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -87,6 +88,7 @@ static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id,
 static int __init octeon_mdiobus_probe(struct platform_device *pdev)
 {
        struct octeon_mdiobus *bus;
+       union cvmx_smix_en smi_en;
        int i;
        int err = -ENOENT;
 
@@ -102,6 +104,10 @@ static int __init octeon_mdiobus_probe(struct platform_device *pdev)
        if (!bus->mii_bus)
                goto err;
 
+       smi_en.u64 = 0;
+       smi_en.s.en = 1;
+       cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64);
+
        /*
         * Standard Octeon evaluation boards don't support phy
         * interrupts, we need to poll.
@@ -132,17 +138,22 @@ err_register:
 
 err:
        devm_kfree(&pdev->dev, bus);
+       smi_en.u64 = 0;
+       cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64);
        return err;
 }
 
 static int __exit octeon_mdiobus_remove(struct platform_device *pdev)
 {
        struct octeon_mdiobus *bus;
+       union cvmx_smix_en smi_en;
 
        bus = dev_get_drvdata(&pdev->dev);
 
        mdiobus_unregister(bus->mii_bus);
        mdiobus_free(bus->mii_bus);
+       smi_en.u64 = 0;
+       cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64);
        return 0;
 }
 
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
new file mode 100644 (file)
index 0000000..e67691d
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * drivers/net/phy/micrel.c
+ *
+ * Driver for Micrel PHYs
+ *
+ * Author: David J. Choi
+ *
+ * Copyright (c) 2010 Micrel, 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.
+ *
+ * Support : ksz9021 , vsc8201, ks8001
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+
+#define        PHY_ID_KSZ9021                  0x00221611
+#define        PHY_ID_VSC8201                  0x000FC413
+#define        PHY_ID_KS8001                   0x0022161A
+
+
+static int kszphy_config_init(struct phy_device *phydev)
+{
+       return 0;
+}
+
+
+static struct phy_driver ks8001_driver = {
+       .phy_id         = PHY_ID_KS8001,
+       .name           = "Micrel KS8001",
+       .phy_id_mask    = 0x00fffff0,
+       .features       = PHY_BASIC_FEATURES,
+       .flags          = PHY_POLL,
+       .config_init    = kszphy_config_init,
+       .config_aneg    = genphy_config_aneg,
+       .read_status    = genphy_read_status,
+       .driver         = { .owner = THIS_MODULE,},
+};
+
+static struct phy_driver vsc8201_driver = {
+       .phy_id         = PHY_ID_VSC8201,
+       .name           = "Micrel VSC8201",
+       .phy_id_mask    = 0x00fffff0,
+       .features       = PHY_BASIC_FEATURES,
+       .flags          = PHY_POLL,
+       .config_init    = kszphy_config_init,
+       .config_aneg    = genphy_config_aneg,
+       .read_status    = genphy_read_status,
+       .driver         = { .owner = THIS_MODULE,},
+};
+
+static struct phy_driver ksz9021_driver = {
+       .phy_id         = PHY_ID_KSZ9021,
+       .phy_id_mask    = 0x000fff10,
+       .name           = "Micrel KSZ9021 Gigabit PHY",
+       .features       = PHY_GBIT_FEATURES | SUPPORTED_Pause,
+       .flags          = PHY_POLL,
+       .config_init    = kszphy_config_init,
+       .config_aneg    = genphy_config_aneg,
+       .read_status    = genphy_read_status,
+       .driver         = { .owner = THIS_MODULE, },
+};
+
+static int __init ksphy_init(void)
+{
+       int ret;
+
+       ret = phy_driver_register(&ks8001_driver);
+       if (ret)
+               goto err1;
+       ret = phy_driver_register(&vsc8201_driver);
+       if (ret)
+               goto err2;
+
+       ret = phy_driver_register(&ksz9021_driver);
+       if (ret)
+               goto err3;
+       return 0;
+
+err3:
+       phy_driver_unregister(&vsc8201_driver);
+err2:
+       phy_driver_unregister(&ks8001_driver);
+err1:
+       return ret;
+}
+
+static void __exit ksphy_exit(void)
+{
+       phy_driver_unregister(&ks8001_driver);
+       phy_driver_unregister(&vsc8201_driver);
+       phy_driver_unregister(&ksz9021_driver);
+}
+
+module_init(ksphy_init);
+module_exit(ksphy_exit);
+
+MODULE_DESCRIPTION("Micrel PHY driver");
+MODULE_AUTHOR("David J. Choi");
+MODULE_LICENSE("GPL");
index 0295097d6c4435c7fb720e6fe580bd637be33173..64be4664ccab0c906f34ce05f49c66d7cbf6def3 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index 23062d0672314a3e5a9fb8d130cab45e43acc824..f6e190f73c3215c1c0c6c4877a9e7552c06e831e 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/unistd.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index 3327e9fc7b51336c2628968fde94dfa64ac3564d..9a2103a69e172280e933de679b8cf303ff8ce767 100644 (file)
@@ -94,6 +94,7 @@ static const char version[] = "NET3 PLIP version 2.4-parport gniibe@mri.co.jp\n"
 #include <linux/fcntl.h>
 #include <linux/interrupt.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/if_ether.h>
 #include <linux/in.h>
 #include <linux/errno.h>
index 6a375ea4947de45164268bf382151ee4e7cb80a8..6c2e8fa0ca31cd2865ad9f80d2f0fdc99103498b 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/spinlock.h>
 #include <linux/init.h>
 #include <linux/jiffies.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/string.h>
 
index 6d61602208c1f1470409c34717e7641e038b86a5..8518a2e58e5362254221ba11a0ba34146d84f47b 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/stddef.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <net/slhc_vj.h>
 #include <asm/atomic.h>
 
@@ -404,6 +405,7 @@ static ssize_t ppp_read(struct file *file, char __user *buf,
        DECLARE_WAITQUEUE(wait, current);
        ssize_t ret;
        struct sk_buff *skb = NULL;
+       struct iovec iov;
 
        ret = count;
 
@@ -447,7 +449,9 @@ static ssize_t ppp_read(struct file *file, char __user *buf,
        if (skb->len > count)
                goto outf;
        ret = -EFAULT;
-       if (copy_to_user(buf, skb->data, skb->len))
+       iov.iov_base = buf;
+       iov.iov_len = count;
+       if (skb_copy_datagram_iovec(skb, 0, &iov, skb->len))
                goto outf;
        ret = skb->len;
 
@@ -1566,13 +1570,22 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
        struct channel *pch = chan->ppp;
        int proto;
 
-       if (!pch || skb->len == 0) {
+       if (!pch) {
                kfree_skb(skb);
                return;
        }
 
-       proto = PPP_PROTO(skb);
        read_lock_bh(&pch->upl);
+       if (!pskb_may_pull(skb, 2)) {
+               kfree_skb(skb);
+               if (pch->ppp) {
+                       ++pch->ppp->dev->stats.rx_length_errors;
+                       ppp_receive_error(pch->ppp);
+               }
+               goto done;
+       }
+
+       proto = PPP_PROTO(skb);
        if (!pch->ppp || proto >= 0xc000 || proto == PPP_CCPFRAG) {
                /* put it on the channel queue */
                skb_queue_tail(&pch->file.rq, skb);
@@ -1584,6 +1597,8 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
        } else {
                ppp_do_recv(pch->ppp, skb, pch);
        }
+
+done:
        read_unlock_bh(&pch->upl);
 }
 
@@ -1616,7 +1631,8 @@ ppp_input_error(struct ppp_channel *chan, int code)
 static void
 ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
 {
-       if (pskb_may_pull(skb, 2)) {
+       /* note: a 0-length skb is used as an error indication */
+       if (skb->len > 0) {
 #ifdef CONFIG_PPP_MULTILINK
                /* XXX do channel-level decompression here */
                if (PPP_PROTO(skb) == PPP_MP)
@@ -1624,15 +1640,10 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
                else
 #endif /* CONFIG_PPP_MULTILINK */
                        ppp_receive_nonmp_frame(ppp, skb);
-               return;
+       } else {
+               kfree_skb(skb);
+               ppp_receive_error(ppp);
        }
-
-       if (skb->len > 0)
-               /* note: a 0-length skb is used as an error indication */
-               ++ppp->dev->stats.rx_length_errors;
-
-       kfree_skb(skb);
-       ppp_receive_error(ppp);
 }
 
 static void
index 3a13cecae3e2f29df464d486f68b20d545bdfcf2..52938da1e5420554db460c5c88680a4a349c0f24 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 #define PPP_VERSION    "2.4.2"
index 9fbb2eba9a06747ea6aeb98c37506d49e149b895..449a9825200d5775d8bf221a36657ec87588f8fc 100644 (file)
@@ -756,6 +756,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
 
        /* Try to dequeue as many skbs from reorder_q as we can. */
        pppol2tp_recv_dequeue(session);
+       sock_put(sock);
 
        return 0;
 
@@ -772,6 +773,7 @@ discard_bad_csum:
        UDP_INC_STATS_USER(&init_net, UDP_MIB_INERRORS, 0);
        tunnel->stats.rx_errors++;
        kfree_skb(skb);
+       sock_put(sock);
 
        return 0;
 
@@ -1180,7 +1182,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
        /* Calculate UDP checksum if configured to do so */
        if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT)
                skb->ip_summed = CHECKSUM_NONE;
-       else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
+       else if ((skb_dst(skb) && skb_dst(skb)->dev) &&
+                (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) {
                skb->ip_summed = CHECKSUM_COMPLETE;
                csum = skb_checksum(skb, 0, udp_len, 0);
                uh->check = csum_tcpudp_magic(inet->inet_saddr,
@@ -1661,6 +1664,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
                if (tunnel_sock == NULL)
                        goto end;
 
+               sock_hold(tunnel_sock);
                tunnel = tunnel_sock->sk_user_data;
        } else {
                tunnel = pppol2tp_tunnel_find(sock_net(sk), sp->pppol2tp.s_tunnel);
index ac806b27c658a66f73e3614c9715a674db0d3453..d4191ef9cad14fed8d1cd6c0d284ddb7e51c8163 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/string.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
 #include <linux/net.h>
index a849f6f23a17f8e5d9c11624042f0fdb577c4005..5bf229bb34c26e55879ddc62e13be82183e028c7 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
index 2663b2fdc0bb0170b6054188e02defdfb74241f1..f0be507e5324a69c5fe2a7c308e38eb122ec0537 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
index da00e162b6d348c62558a0aa9194b193e4a844c2..e73ba455aa204c43c1a2d4ec02a1ba1106370247 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "qlcnic.h"
 
+#include <linux/slab.h>
 #include <net/ip.h>
 
 #define MASK(n) ((1ULL<<(n))-1)
@@ -430,6 +431,9 @@ void qlcnic_set_multi(struct net_device *netdev)
        u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
        u32 mode = VPORT_MISS_MODE_DROP;
 
+       if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+               return;
+
        qlcnic_nic_add_mac(adapter, adapter->mac_addr);
        qlcnic_nic_add_mac(adapter, bcast_addr);
 
index 7c34e4e29b3f79e64d2e3ac8f926c7dc0b48b57e..9d2c124048fa3934fadf15b68fcf3278e6dc5824 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include "qlcnic.h"
 
 struct crb_addr_pair {
index fc721564e69ef60f12210b86cd293bbd8d988c2a..234dab1f99823c588e2532ba6ea0a6e35ed6a8e0 100644 (file)
@@ -22,6 +22,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/interrupt.h>
 
index ff8550d2ca827cd266b1ad40e255f7ee2c531432..3626646289376c6b5940774ee8868818ad60bc3a 100644 (file)
@@ -1,3 +1,5 @@
+#include <linux/slab.h>
+
 #include "qlge.h"
 
 /* Read a NIC register from the alternate function. */
index 7dbff87480dc6d6d844ae5bce2230c561a5ea7f9..7e09ff4a57554d72bd546356c654db5aa7aaa401 100644 (file)
@@ -7,7 +7,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/pagemap.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/dmapool.h>
 #include <linux/mempool.h>
 #include <linux/spinlock.h>
index 15d5373dc8f30b70747941e26a8808e03236a601..0298d8c1dcb6fa002cb2f58bb50a61fd79d748a6 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #define RX_DESC_SIZE   (RX_DCNT * sizeof(struct r6040_descriptor))
 #define TX_DESC_SIZE   (TX_DCNT * sizeof(struct r6040_descriptor))
 #define MBCR_DEFAULT   0x012A  /* MAC Bus Control Register */
-#define MCAST_MAX      4       /* Max number multicast addresses to filter */
+#define MCAST_MAX      3       /* Max number multicast addresses to filter */
 
 /* Descriptor status */
 #define DSC_OWNER_MAC  0x8000  /* MAC is the owner of this descriptor */
@@ -983,9 +982,6 @@ static void r6040_multicast_list(struct net_device *dev)
                        crc >>= 26;
                        hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf));
                }
-               /* Write the index of the hash table */
-               for (i = 0; i < 4; i++)
-                       iowrite16(hash_table[i] << 14, ioaddr + MCR1);
                /* Fill the MAC hash tables with their values */
                iowrite16(hash_table[0], ioaddr + MAR0);
                iowrite16(hash_table[1], ioaddr + MAR1);
@@ -1001,9 +997,9 @@ static void r6040_multicast_list(struct net_device *dev)
                        iowrite16(adrp[1], ioaddr + MID_1M + 8 * i);
                        iowrite16(adrp[2], ioaddr + MID_1H + 8 * i);
                } else {
-                       iowrite16(0xffff, ioaddr + MID_0L + 8 * i);
-                       iowrite16(0xffff, ioaddr + MID_0M + 8 * i);
-                       iowrite16(0xffff, ioaddr + MID_0H + 8 * i);
+                       iowrite16(0xffff, ioaddr + MID_1L + 8 * i);
+                       iowrite16(0xffff, ioaddr + MID_1M + 8 * i);
+                       iowrite16(0xffff, ioaddr + MID_1H + 8 * i);
                }
                i++;
        }
index 9d3ebf3e975e0abfe5519bf2cd3371ed9278743d..dd8106ff35aae6a4035b4cba6a351bd06f0c8d59 100644 (file)
@@ -186,8 +186,13 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = {
 
 MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
 
-static int rx_copybreak = 200;
-static int use_dac = -1;
+/*
+ * we set our copybreak very high so that we don't have
+ * to allocate 16k frames all the time (see note in
+ * rtl8169_open()
+ */
+static int rx_copybreak = 16383;
+static int use_dac;
 static struct {
        u32 msg_enable;
 } debug = { -1 };
@@ -511,8 +516,7 @@ MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
 module_param(rx_copybreak, int, 0);
 MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
 module_param(use_dac, int, 0);
-MODULE_PARM_DESC(use_dac, "Enable PCI DAC. -1 defaults on for PCI Express only."
-" Unsafe on 32 bit PCI slot.");
+MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot.");
 module_param_named(debug, debug.msg_enable, int, 0);
 MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)");
 MODULE_LICENSE("GPL");
@@ -1038,14 +1042,14 @@ static void rtl8169_vlan_rx_register(struct net_device *dev,
 }
 
 static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
-                              struct sk_buff *skb)
+                              struct sk_buff *skb, int polling)
 {
        u32 opts2 = le32_to_cpu(desc->opts2);
        struct vlan_group *vlgrp = tp->vlgrp;
        int ret;
 
        if (vlgrp && (opts2 & RxVlanTag)) {
-               vlan_hwaccel_receive_skb(skb, vlgrp, swab16(opts2 & 0xffff));
+               __vlan_hwaccel_rx(skb, vlgrp, swab16(opts2 & 0xffff), polling);
                ret = 0;
        } else
                ret = -1;
@@ -1062,7 +1066,7 @@ static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp,
 }
 
 static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
-                              struct sk_buff *skb)
+                              struct sk_buff *skb, int polling)
 {
        return -1;
 }
@@ -2755,6 +2759,7 @@ static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev,
 {
        iounmap(ioaddr);
        pci_release_regions(pdev);
+       pci_clear_mwi(pdev);
        pci_disable_device(pdev);
        free_netdev(dev);
 }
@@ -2821,8 +2826,13 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
        spin_lock_irq(&tp->lock);
 
        RTL_W8(Cfg9346, Cfg9346_Unlock);
-       RTL_W32(MAC0, low);
+
        RTL_W32(MAC4, high);
+       RTL_R32(MAC4);
+
+       RTL_W32(MAC0, low);
+       RTL_R32(MAC0);
+
        RTL_W8(Cfg9346, Cfg9346_Lock);
 
        spin_unlock_irq(&tp->lock);
@@ -2974,7 +2984,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        void __iomem *ioaddr;
        unsigned int i;
        int rc;
-       int this_use_dac = use_dac;
 
        if (netif_msg_drv(&debug)) {
                printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
@@ -3011,9 +3020,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto err_out_free_dev_1;
        }
 
-       rc = pci_set_mwi(pdev);
-       if (rc < 0)
-               goto err_out_disable_2;
+       if (pci_set_mwi(pdev) < 0)
+               netif_info(tp, probe, dev, "Mem-Wr-Inval unavailable\n");
 
        /* make sure PCI base addr 1 is MMIO */
        if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) {
@@ -3021,7 +3029,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                          "region #%d not an MMIO resource, aborting\n",
                          region);
                rc = -ENODEV;
-               goto err_out_mwi_3;
+               goto err_out_mwi_2;
        }
 
        /* check for weird/broken PCI region reporting */
@@ -3029,35 +3037,26 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                netif_err(tp, probe, dev,
                          "Invalid PCI region size(s), aborting\n");
                rc = -ENODEV;
-               goto err_out_mwi_3;
+               goto err_out_mwi_2;
        }
 
        rc = pci_request_regions(pdev, MODULENAME);
        if (rc < 0) {
                netif_err(tp, probe, dev, "could not request regions\n");
-               goto err_out_mwi_3;
+               goto err_out_mwi_2;
        }
 
        tp->cp_cmd = PCIMulRW | RxChkSum;
 
-       tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
-       if (!tp->pcie_cap)
-               netif_info(tp, probe, dev, "no PCI Express capability\n");
-
-       if (this_use_dac < 0)
-               this_use_dac = tp->pcie_cap != 0;
-
        if ((sizeof(dma_addr_t) > 4) &&
-           this_use_dac &&
-           !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
-               netif_info(tp, probe, dev, "using 64-bit DMA\n");
+           !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) {
                tp->cp_cmd |= PCIDAC;
                dev->features |= NETIF_F_HIGHDMA;
        } else {
                rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
                if (rc < 0) {
                        netif_err(tp, probe, dev, "DMA configuration failed\n");
-                       goto err_out_free_res_4;
+                       goto err_out_free_res_3;
                }
        }
 
@@ -3066,9 +3065,13 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (!ioaddr) {
                netif_err(tp, probe, dev, "cannot remap MMIO, aborting\n");
                rc = -EIO;
-               goto err_out_free_res_4;
+               goto err_out_free_res_3;
        }
 
+       tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+       if (!tp->pcie_cap)
+               netif_info(tp, probe, dev, "no PCI Express capability\n");
+
        RTL_W16(IntrMask, 0x0000);
 
        /* Soft reset the chip. */
@@ -3104,7 +3107,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (i == ARRAY_SIZE(rtl_chip_info)) {
                dev_err(&pdev->dev,
                        "driver bug, MAC version not found in rtl_chip_info\n");
-               goto err_out_msi_5;
+               goto err_out_msi_4;
        }
        tp->chipset = i;
 
@@ -3169,7 +3172,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        rc = register_netdev(dev);
        if (rc < 0)
-               goto err_out_msi_5;
+               goto err_out_msi_4;
 
        pci_set_drvdata(pdev, dev);
 
@@ -3192,14 +3195,13 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 out:
        return rc;
 
-err_out_msi_5:
+err_out_msi_4:
        rtl_disable_msi(pdev, tp);
        iounmap(ioaddr);
-err_out_free_res_4:
+err_out_free_res_3:
        pci_release_regions(pdev);
-err_out_mwi_3:
+err_out_mwi_2:
        pci_clear_mwi(pdev);
-err_out_disable_2:
        pci_disable_device(pdev);
 err_out_free_dev_1:
        free_netdev(dev);
@@ -3224,9 +3226,13 @@ 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)
 {
-       unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
+       unsigned int max_frame = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
+
+       if (max_frame != 16383)
+               printk(KERN_WARNING PFX "WARNING! Changing of MTU on this "
+                       "NIC may lead to frame reception errors!\n");
 
        tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE;
 }
@@ -3238,7 +3244,17 @@ static int rtl8169_open(struct net_device *dev)
        int retval = -ENOMEM;
 
 
-       rtl8169_set_rxbufsize(tp, dev);
+       /*
+        * Note that we use a magic value here, its wierd I know
+        * its done because, some subset of rtl8169 hardware suffers from
+        * a problem in which frames received that are longer than
+        * the size set in RxMaxSize register return garbage sizes
+        * when received.  To avoid this we need to turn off filtering,
+        * which is done by setting a value of 16383 in the RxMaxSize register
+        * and allocating 16k frames to handle the largest possible rx value
+        * thats what the magic math below does.
+        */
+       rtl8169_set_rxbufsize(tp, 16383 - VLAN_ETH_HLEN - ETH_FCS_LEN);
 
        /*
         * Rx and Tx desscriptors needs 256 bytes alignment.
@@ -3891,7 +3907,7 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
 
        rtl8169_down(dev);
 
-       rtl8169_set_rxbufsize(tp, dev);
+       rtl8169_set_rxbufsize(tp, dev->mtu);
 
        ret = rtl8169_init_ring(dev);
        if (ret < 0)
@@ -4429,12 +4445,20 @@ out:
        return done;
 }
 
+/*
+ * Warning : rtl8169_rx_interrupt() might be called :
+ * 1) from NAPI (softirq) context
+ *     (polling = 1 : we should call netif_receive_skb())
+ * 2) from process context (rtl8169_reset_task())
+ *     (polling = 0 : we must call netif_rx() instead)
+ */
 static int rtl8169_rx_interrupt(struct net_device *dev,
                                struct rtl8169_private *tp,
                                void __iomem *ioaddr, u32 budget)
 {
        unsigned int cur_rx, rx_left;
        unsigned int delta, count;
+       int polling = (budget != ~(u32)0) ? 1 : 0;
 
        cur_rx = tp->cur_rx;
        rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
@@ -4496,8 +4520,12 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
                        skb_put(skb, pkt_size);
                        skb->protocol = eth_type_trans(skb, dev);
 
-                       if (rtl8169_rx_vlan_skb(tp, desc, skb) < 0)
-                               netif_receive_skb(skb);
+                       if (rtl8169_rx_vlan_skb(tp, desc, skb, polling) < 0) {
+                               if (likely(polling))
+                                       netif_receive_skb(skb);
+                               else
+                                       netif_rx(skb);
+                       }
 
                        dev->stats.rx_bytes += pkt_size;
                        dev->stats.rx_packets++;
@@ -4754,8 +4782,8 @@ static void rtl_set_rx_mode(struct net_device *dev)
                mc_filter[1] = swab32(data);
        }
 
-       RTL_W32(MAR0 + 0, mc_filter[0]);
        RTL_W32(MAR0 + 4, mc_filter[1]);
+       RTL_W32(MAR0 + 0, mc_filter[0]);
 
        RTL_W32(RxConfig, tmp);
 
index ede937ee50c704e373554f9881782dea7840b31b..07eb884ff982405c3d15204a04d6188394e329f3 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/rio.h>
 #include <linux/rio_drv.h>
+#include <linux/slab.h>
 #include <linux/rio_ids.h>
 
 #include <linux/netdevice.h>
index 266baf5349641ffef8f2afd578b79c684030d657..f2e335f0d1b760d7e8c0d23ae9cb5999d24f013c 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 
 #include <asm/system.h>
index df70657260dd8805a3a383208f4c392ba9474691..92ae8d3de39be642cccc50321696895bac745f1c 100644 (file)
@@ -79,6 +79,7 @@
 #include <linux/tcp.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <net/tcp.h>
 
 #include <asm/system.h>
@@ -5819,10 +5820,8 @@ static void s2io_vpd_read(struct s2io_nic *nic)
                }
        }
 
-       if ((!fail) && (vpd_data[1] < VPD_STRING_LEN)) {
-               memset(nic->product_name, 0, vpd_data[1]);
+       if ((!fail) && (vpd_data[1] < VPD_STRING_LEN))
                memcpy(nic->product_name, &vpd_data[3], vpd_data[1]);
-       }
        kfree(vpd_data);
        swstats->mem_freed += 256;
 }
index 9f83a11973750a2711eee50e7b985af5159c5cec..abc8eefdd4b6bcd7c7b075d2cccfd7c70e9b92d3 100644 (file)
@@ -42,7 +42,6 @@ static char version[] = "sb1000.c:v1.1.2 6/01/98 (fventuri@mediaone.net)\n";
 #include <linux/errno.h>
 #include <linux/if_cablemodem.h> /* for SIOGCM/SIOSCM stuff */
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
@@ -52,6 +51,7 @@ static char version[] = "sb1000.c:v1.1.2 6/01/98 (fventuri@mediaone.net)\n";
 #include <linux/pnp.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/processor.h>
index 9944e5d662c0fff7d975cce45bb708301512aa67..04efc0c1bda93b95bfbd840c7778d8a57ac2c5ad 100644 (file)
@@ -2353,17 +2353,36 @@ static int sbmac_init(struct platform_device *pldev, long long base)
 
        sc->mii_bus = mdiobus_alloc();
        if (sc->mii_bus == NULL) {
-               sbmac_uninitctx(sc);
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto uninit_ctx;
        }
 
+       sc->mii_bus->name = sbmac_mdio_string;
+       snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx);
+       sc->mii_bus->priv = sc;
+       sc->mii_bus->read = sbmac_mii_read;
+       sc->mii_bus->write = sbmac_mii_write;
+       sc->mii_bus->irq = sc->phy_irq;
+       for (i = 0; i < PHY_MAX_ADDR; ++i)
+               sc->mii_bus->irq[i] = SBMAC_PHY_INT;
+
+       sc->mii_bus->parent = &pldev->dev;
+       /*
+        * Probe PHY address
+        */
+       err = mdiobus_register(sc->mii_bus);
+       if (err) {
+               printk(KERN_ERR "%s: unable to register MDIO bus\n",
+                      dev->name);
+               goto free_mdio;
+       }
+       dev_set_drvdata(&pldev->dev, sc->mii_bus);
+
        err = register_netdev(dev);
        if (err) {
                printk(KERN_ERR "%s.%d: unable to register netdev\n",
                       sbmac_string, idx);
-               mdiobus_free(sc->mii_bus);
-               sbmac_uninitctx(sc);
-               return err;
+               goto unreg_mdio;
        }
 
        pr_info("%s.%d: registered as %s\n", sbmac_string, idx, dev->name);
@@ -2379,19 +2398,15 @@ static int sbmac_init(struct platform_device *pldev, long long base)
        pr_info("%s: SiByte Ethernet at 0x%08Lx, address: %pM\n",
               dev->name, base, eaddr);
 
-       sc->mii_bus->name = sbmac_mdio_string;
-       snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx);
-       sc->mii_bus->priv = sc;
-       sc->mii_bus->read = sbmac_mii_read;
-       sc->mii_bus->write = sbmac_mii_write;
-       sc->mii_bus->irq = sc->phy_irq;
-       for (i = 0; i < PHY_MAX_ADDR; ++i)
-               sc->mii_bus->irq[i] = SBMAC_PHY_INT;
-
-       sc->mii_bus->parent = &pldev->dev;
-       dev_set_drvdata(&pldev->dev, sc->mii_bus);
-
        return 0;
+unreg_mdio:
+       mdiobus_unregister(sc->mii_bus);
+       dev_set_drvdata(&pldev->dev, NULL);
+free_mdio:
+       mdiobus_free(sc->mii_bus);
+uninit_ctx:
+       sbmac_uninitctx(sc);
+       return err;
 }
 
 
@@ -2417,16 +2432,6 @@ static int sbmac_open(struct net_device *dev)
                goto out_err;
        }
 
-       /*
-        * Probe PHY address
-        */
-       err = mdiobus_register(sc->mii_bus);
-       if (err) {
-               printk(KERN_ERR "%s: unable to register MDIO bus\n",
-                      dev->name);
-               goto out_unirq;
-       }
-
        sc->sbm_speed = sbmac_speed_none;
        sc->sbm_duplex = sbmac_duplex_none;
        sc->sbm_fc = sbmac_fc_none;
@@ -2457,11 +2462,7 @@ static int sbmac_open(struct net_device *dev)
        return 0;
 
 out_unregister:
-       mdiobus_unregister(sc->mii_bus);
-
-out_unirq:
        free_irq(dev->irq, dev);
-
 out_err:
        return err;
 }
@@ -2650,9 +2651,6 @@ static int sbmac_close(struct net_device *dev)
 
        phy_disconnect(sc->phy_dev);
        sc->phy_dev = NULL;
-
-       mdiobus_unregister(sc->mii_bus);
-
        free_irq(dev->irq, dev);
 
        sbdma_emptyring(&(sc->sbm_txdma));
@@ -2760,6 +2758,7 @@ static int __exit sbmac_remove(struct platform_device *pldev)
 
        unregister_netdev(dev);
        sbmac_uninitctx(sc);
+       mdiobus_unregister(sc->mii_bus);
        mdiobus_free(sc->mii_bus);
        iounmap(sc->sbm_base);
        free_netdev(dev);
index fe806bd9b95f662e3093f024cd087f525f701629..374832cca11fd092a42ee15719a8421f106e4f24 100644 (file)
@@ -37,7 +37,6 @@ static const char version[] =
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index 88f2fb193abe5de97f3a5972ff183e4129649e35..649a264d6a81b80ee35f54850fce49a4545565c1 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/crc32.h>
 #include <linux/ethtool.h>
 #include <linux/topology.h>
+#include <linux/gfp.h>
 #include "net_driver.h"
 #include "efx.h"
 #include "mdio_10g.h"
@@ -1860,6 +1861,7 @@ out:
        }
 
        if (disabled) {
+               dev_close(efx->net_dev);
                EFX_ERR(efx, "has been disabled\n");
                efx->state = STATE_DISABLED;
        } else {
@@ -1883,8 +1885,7 @@ static void efx_reset_work(struct work_struct *data)
        }
 
        rtnl_lock();
-       if (efx_reset(efx, efx->reset_pending))
-               dev_close(efx->net_dev);
+       (void)efx_reset(efx, efx->reset_pending);
        rtnl_unlock();
 }
 
index 1b8d83657aaa85e235e87686e6135775f0afd799..08278e7302b386145f75c408c1c3eef193981978 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/seq_file.h>
 #include <linux/i2c.h>
 #include <linux/mii.h>
+#include <linux/slab.h>
 #include "net_driver.h"
 #include "bitfield.h"
 #include "efx.h"
@@ -1319,7 +1320,9 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
 
        EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mdio.prtad);
 
-       falcon_probe_board(efx, board_rev);
+       rc = falcon_probe_board(efx, board_rev);
+       if (rc)
+               goto fail2;
 
        kfree(nvconfig);
        return 0;
index 5712fddd72f2ea839985c3a4cd5f3a05729dc0c1..c7a933a3292e6797b6bc55e87d8499268a63976a 100644 (file)
@@ -728,15 +728,7 @@ static const struct falcon_board_type board_types[] = {
        },
 };
 
-static const struct falcon_board_type falcon_dummy_board = {
-       .init           = efx_port_dummy_op_int,
-       .init_phy       = efx_port_dummy_op_void,
-       .fini           = efx_port_dummy_op_void,
-       .set_id_led     = efx_port_dummy_op_set_id_led,
-       .monitor        = efx_port_dummy_op_int,
-};
-
-void falcon_probe_board(struct efx_nic *efx, u16 revision_info)
+int falcon_probe_board(struct efx_nic *efx, u16 revision_info)
 {
        struct falcon_board *board = falcon_board(efx);
        u8 type_id = FALCON_BOARD_TYPE(revision_info);
@@ -754,8 +746,9 @@ void falcon_probe_board(struct efx_nic *efx, u16 revision_info)
                         (efx->pci_dev->subsystem_vendor == EFX_VENDID_SFC)
                         ? board->type->ref_model : board->type->gen_type,
                         'A' + board->major, board->minor);
+               return 0;
        } else {
                EFX_ERR(efx, "unknown board type %d\n", type_id);
-               board->type = &falcon_dummy_board;
+               return -ENODEV;
        }
 }
index 34c22fa986e2b3147a08a27666a7f0dd4a545b6b..2f2354696663cc8f207af5bc8449b8f7d3d31e2a 100644 (file)
@@ -11,6 +11,7 @@
  * Driver for PHY related operations via MCDI.
  */
 
+#include <linux/slab.h>
 #include "efx.h"
 #include "phy.h"
 #include "mcdi.h"
index 407bbaddfea6e88a95fcd5a869f6715aae4511a5..f3ac7f30b5e718e3178dbdcf2797b5a0d13703d7 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/mtd/mtd.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/rtnetlink.h>
 
 #define EFX_DRIVER_NAME "sfc_mtd"
index 9351c0331a47f028ff0cbf15211f66873e94117f..3166bafdfbefc617d6df6fe1cf1589008c66b19f 100644 (file)
@@ -156,7 +156,7 @@ extern struct efx_nic_type siena_a0_nic_type;
  **************************************************************************
  */
 
-extern void falcon_probe_board(struct efx_nic *efx, u16 revision_info);
+extern int falcon_probe_board(struct efx_nic *efx, u16 revision_info);
 
 /* TX data path */
 extern int efx_nic_probe_tx(struct efx_tx_queue *tx_queue);
index 1bee62c83001e18515d05cca6cbfbb4da100b30f..e077bef08a504258a4e37778c1778600cd640f92 100644 (file)
@@ -10,6 +10,7 @@
  * Driver for AMCC QT202x SFP+ and XFP adapters; see www.amcc.com for details
  */
 
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/delay.h>
 #include "efx.h"
index a97c923b560c4e177e82eac628771b47382c884e..e308818b9f5512e8679c9ac486ea141daa6285a9 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/socket.h>
 #include <linux/in.h>
+#include <linux/slab.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
index cf0139a7d9a42a8b6115a711dfe8b038ccea845f..0106b1d9aae216312f344d6d25e5899c4ae4c2e6 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/in.h>
 #include <linux/udp.h>
 #include <linux/rtnetlink.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include "net_driver.h"
 #include "efx.h"
index 1619fb5a64f5c0574b3dca25cdb49abd7d5f5571..e0c46f59d1f8793d365710d1e80d6c51ae469b9d 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include "net_driver.h"
 #include "bitfield.h"
 #include "efx.h"
@@ -455,8 +456,17 @@ static int siena_try_update_nic_stats(struct efx_nic *efx)
 
 static void siena_update_nic_stats(struct efx_nic *efx)
 {
-       while (siena_try_update_nic_stats(efx) == -EAGAIN)
-               cpu_relax();
+       int retry;
+
+       /* If we're unlucky enough to read statistics wduring the DMA, wait
+        * up to 10ms for it to finish (typically takes <500us) */
+       for (retry = 0; retry < 100; ++retry) {
+               if (siena_try_update_nic_stats(efx) == 0)
+                       return;
+               udelay(100);
+       }
+
+       /* Use the old values instead */
 }
 
 static void siena_start_nic_stats(struct efx_nic *efx)
index 10db071bd8378c29822b4f360f7f729b16f3ccc1..f21efe7bd316e3618664cbcd0f1e94ef42a97ea9 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/delay.h>
 #include <linux/rtnetlink.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "efx.h"
 #include "mdio_10g.h"
 #include "nic.h"
index a8b70ef6d817ea51a867c217f25fa78871cf5624..be0e110a1f73b4584582868e475cf3492cead862 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/ip.h>
 #include <linux/in.h>
 #include <linux/ipv6.h>
+#include <linux/slab.h>
 #include <net/ipv6.h>
 #include <linux/if_ether.h>
 #include <linux/highmem.h>
index ed999d31f1fa802e4738d466c68ea7e03f263ce0..c8fc896fc4600dfc348d0229f0cf91b8755be037 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/types.h>
@@ -592,8 +593,10 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* Setup... */
        len = skb->len;
        if (len < ETH_ZLEN) {
-               if (skb_padto(skb, ETH_ZLEN))
+               if (skb_padto(skb, ETH_ZLEN)) {
+                       spin_unlock_irqrestore(&sp->tx_lock, flags);
                        return NETDEV_TX_OK;
+               }
                len = ETH_ZLEN;
        }
 
index 42a35f086a9f5dccc9fc466340525f6154918df7..6242b85d5d1589bfeb8728308ad4e5a93b7bf4d3 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/cache.h>
 #include <linux/io.h>
 #include <linux/pm_runtime.h>
+#include <linux/slab.h>
 #include <asm/cacheflush.h>
 
 #include "sh_eth.h"
index 760d9e83a46514fb603d97e7d1abdf667968a86f..b30ce752bbf3986987061a9b7323c4b59892ea98 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/delay.h>
 #include <linux/crc32.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <asm/irq.h>
 
 #define PHY_MAX_ADDR           32
index 1921a54ea9952edcd4ea8b51bbce9d9582921869..d9016b75abc2d023e64da67db02acf172a4598dc 100644 (file)
@@ -78,13 +78,13 @@ static const char * const boot_msg =
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/fddidevice.h>
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 
 #include <asm/byteorder.h>
 #include <asm/io.h>
index d0058e5bb6aeba703784eaef9e25f4631db0e179..50eb70609f2039622feb551c981cbdc848c2e45e 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/mii.h>
+#include <linux/slab.h>
 #include <asm/irq.h>
 
 #include "skge.h"
index d8ec4c11fd49fec6a52bab0b8914cd1749419644..088c797eb73b8a215e36fa09ef6f8e96ffa42b79 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/ethtool.h>
 #include <linux/pci.h>
 #include <linux/ip.h>
+#include <linux/slab.h>
 #include <net/ip.h>
 #include <linux/tcp.h>
 #include <linux/in.h>
index d640c0f5470be3bf315c5f53a5d37274a2afdbce..140d63f3cafa8ff2b976e3d26fd5ef488c9cb4d7 100644 (file)
@@ -51,6 +51,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/errno.h>
index ba5bbc503446134ee77a1000b08cfc541bfa8ea4..89696156c059a826231dd8c6bb8c2ae14ca6645e 100644 (file)
@@ -83,6 +83,7 @@
 #include <linux/compat.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include "slip.h"
 #ifdef CONFIG_INET
 #include <linux/ip.h>
index 9871a2b61f869c65e051e8515540e7089c158c75..635820d42b194252004bda1426d6c0d796c345f1 100644 (file)
@@ -59,7 +59,6 @@ static const char version[] =
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
index f9a960e7fc1fdc351e69f34bb74c694560f77235..3f2f7843aa4eacb86fc2923dec080695fd67647c 100644 (file)
@@ -64,7 +64,6 @@ static const char version[] =
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
index fc1b5a1a3583d7d15983400ab384a81f6c1732b3..860339d51d586c14915596807b31dfa322ccc921 100644 (file)
@@ -70,7 +70,6 @@ static const char version[] =
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
index 4fd1d8b38788b6c7f68889c94ff5990d755f20c7..cbf520d38eacf02a25a1f902168210505c4a4758 100644 (file)
@@ -41,7 +41,6 @@
 #include <linux/netdevice.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/bug.h>
 #include <linux/bitops.h>
index 34fa10d8ad40077e085d571633b59329a28672af..aafaebf4574895689ea2aa15da6e7a34f2cb44cd 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/if_vlan.h>
 #include <linux/dma-mapping.h>
 #include <linux/crc32.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include "smsc9420.h"
 
index 854ccf2b4105efd1958a46eb942bb96928d511d2..6b2a888174732e613ec5094153fd68f29505d749 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
index 5ba9d989f8fc6819ca02e0dd21e8be5d042057f5..dd3cb0f2d21fe5b2af2643b25d1b2076595024f9 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/if_vlan.h>
 #include <linux/in.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/ioport.h>
 #include <linux/ip.h>
 #include <linux/kernel.h>
@@ -40,7 +41,6 @@
 #include <linux/device.h>
 #include <linux/pci.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
 #include <linux/vmalloc.h>
index fb287649a3054a16e55bda06027be354431e7990..eb63d44748a76cd3182e002284afe84296552d1e 100644 (file)
@@ -2,6 +2,7 @@ config STMMAC_ETH
        tristate "STMicroelectronics 10/100/1000 Ethernet driver"
        select MII
        select PHYLIB
+       select CRC32
        depends on NETDEVICES && CPU_SUBTYPE_ST40
        help
          This is the driver for the Ethernet IPs are built around a
index 803b0373d843229447d68cbd88c75d49fb25c850..4cacca614fc12b10e3ba44adc79c136655839a5e 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/crc32.h>
 #include <linux/mii.h>
 #include <linux/phy.h>
+#include <linux/slab.h>
 
 #include "common.h"
 #include "dwmac100.h"
index a6538ae4694cfc864172083246d377faf855fa5a..5bd95ebfe498837ec0313ac49b7df51e42a41636 100644 (file)
@@ -27,6 +27,7 @@
 *******************************************************************************/
 
 #include <linux/crc32.h>
+#include <linux/slab.h>
 #include "dwmac1000.h"
 
 static void dwmac1000_core_init(unsigned long ioaddr)
index a6733612d64a66fb5f083699254d792da867bacf..4111a85ec80eb0030f5570b3fc1aaba957e6c21c 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/phy.h>
 #include <linux/if_vlan.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include "stmmac.h"
 
 #define STMMAC_RESOURCE_NAME   "stmmaceth"
@@ -1685,7 +1686,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
        }
        pr_info("done!\n");
 
-       if (!request_mem_region(res->start, (res->end - res->start),
+       if (!request_mem_region(res->start, resource_size(res),
                                pdev->name)) {
                pr_err("%s: ERROR: memory allocation failed"
                       "cannot get the I/O addr 0x%x\n",
@@ -1694,9 +1695,9 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
                goto out;
        }
 
-       addr = ioremap(res->start, (res->end - res->start));
+       addr = ioremap(res->start, resource_size(res));
        if (!addr) {
-               pr_err("%s: ERROR: memory mapping failed \n", __func__);
+               pr_err("%s: ERROR: memory mapping failed\n", __func__);
                ret = -ENOMEM;
                goto out;
        }
@@ -1774,7 +1775,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
 out:
        if (ret < 0) {
                platform_set_drvdata(pdev, NULL);
-               release_mem_region(res->start, (res->end - res->start));
+               release_mem_region(res->start, resource_size(res));
                if (addr != NULL)
                        iounmap(addr);
        }
@@ -1812,7 +1813,7 @@ static int stmmac_dvr_remove(struct platform_device *pdev)
 
        iounmap((void *)ndev->base_addr);
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       release_mem_region(res->start, (res->end - res->start));
+       release_mem_region(res->start, resource_size(res));
 
        free_netdev(ndev);
 
index fffe1d037fe667bfd2d2d6a39822e821d1227009..40b2c79297192455e954ad73f7ea195709fc56e1 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/mii.h>
 #include <linux/phy.h>
+#include <linux/slab.h>
 
 #include "stmmac.h"
 
index 2f6a760e5f21b5f5c68594ec4007d39fae0b81a0..8b28c89a9a77c50566ddb39601f37ed2d765a5b5 100644 (file)
@@ -33,7 +33,6 @@ static int fifo=0x8;  /* don't change */
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/init.h>
index 99998862c22e018ca1c3b8fe27184af9d31b7486..1694ca5bfb41a4f85c5ebee6e1b067938e982130 100644 (file)
@@ -28,7 +28,6 @@ static char *version = "sun3lance.c: v1.2 1/12/2001  Sam Creasey (sammy@sammy.ne
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
index a0bd361d5eca713fb52d6d6c77ec3db7c37852d3..ed7865a0b5b2efeacebda8db16aff1cab2aa5058 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -25,6 +24,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/gfp.h>
 
 #include <asm/auxio.h>
 #include <asm/byteorder.h>
index a855934dfc3b4f433e61c9d8c68c948361646420..8249a394a4e16b68df683f52acbac224f9ef2649 100644 (file)
@@ -84,7 +84,6 @@ static char *media[MAX_UNITS];
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
index 70196bc5fe61973de756b5d41793546e3e93b73a..e6880f1c4e8cf872320656761aa416ec75a3a3d7 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/ioport.h>
 #include <linux/in.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -58,6 +57,7 @@
 #include <linux/bitops.h>
 #include <linux/mutex.h>
 #include <linux/mm.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
index d7c73f478ef5f989bd1d05417e6ab35eebec7cd1..0c21653ff9f90d3022d8e6e4e83d1bb03ee9f874 100644 (file)
@@ -78,7 +78,6 @@ static char lancestr[] = "LANCE";
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -94,6 +93,7 @@ static char lancestr[] = "LANCE";
 #include <linux/dma-mapping.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
index a19dcf8b6b5611632ffb9d1f582c81845046b87c..cff98d07cba8c0a44e3751cbe5c87a449bf9423c 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/firmware.h>
 #include <asm/byteorder.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 /* Compile Time Switches */
 /* start */
index 22cf1c446de3fbbe4afe37b3eaf7fc766e189a8b..ecc41cffb470d3d16b97e5fe61768f57c4822d65 100644 (file)
@@ -8633,6 +8633,7 @@ static int tg3_test_msi(struct tg3 *tp)
        pci_disable_msi(tp->pdev);
 
        tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
+       tp->napi[0].irq_vec = tp->pdev->irq;
 
        err = tg3_request_irq(tp, 0);
        if (err)
index 0fb930feea4566130fc3cc6dfc0816bb1c9a78cf..7d7f3eef1ab3e4d71aad3fa6cf2d3c934dda5536 100644 (file)
@@ -63,6 +63,7 @@
 #include <linux/spinlock.h>
 #include <linux/bitops.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #include <net/checksum.h>
 
index dd028fee9dc2d6a130895f6bdde2057a1b159c6e..7a5fbf5a9d7136afa7bf39afa643dbcf788426e1 100644 (file)
 #include <linux/spinlock.h>
 #include <linux/bitops.h>
 #include <linux/jiffies.h>
+#include <linux/slab.h>
 
 #include <net/net_namespace.h>
 #include <net/checksum.h>
index 456f8bff40bec45f65ebffae80dfe34c326b9a3f..53f631ebb162d55021739a4bd4898b023eda5c8d 100644 (file)
@@ -21,6 +21,7 @@ static const char version[] = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n";
 
 #include <linux/module.h>
 #include <linux/mca.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
index 5401d86a7be413199f1fbd3e3058e4f920202395..e40560137c460938633c4750986d9b4a9d1cdd7c 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/time.h>
 #include <linux/errno.h>
index ee71bcfb3753021ce13a454b0ff78f12ddaa860b..8b508c922410cf4e010aa6b1bcbe8cd72b634bb2 100644 (file)
@@ -85,7 +85,6 @@ static const char version[] = "tms380tr.c: v1.10 30/12/2002 by Christoph Goos, A
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/time.h>
 #include <linux/errno.h>
index 647cdd1d4e20a555182deb64352603d4a83d7d72..5b1fbb3c3b516871635d3a3aa6cd68c245ce0d76 100644 (file)
@@ -38,7 +38,6 @@
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/delay.h>
 #include <linux/crc32.h>
@@ -48,6 +47,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/timer.h>
 #include <linux/platform_device.h>
+#include <linux/gfp.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
index cb429723b2c8ea705aa47a343f7fa642660d366b..19cafc2b418dab716bebfab2005eee7efd61bb1e 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/compiler.h>
 #include <linux/rtnetlink.h>
 #include <linux/crc32.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index c4ecb9a954097f212fcbad7637222094017116b5..09b57193a16a146784aca8f2ccae616242e11b24 100644 (file)
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/eisa.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/moduleparam.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
index 95b38d803e9b445e5ca5f1084e2c0cc54962c4da..9568156dea982aa8058479774a2ad1e59c8c7846 100644 (file)
@@ -74,7 +74,6 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
index 49f05d1431f5c6a67b3ffdff698e6866010ed259..6002e651b9ea5f4f9510f89fa008b439f25fa664 100644 (file)
@@ -13,6 +13,7 @@
 */
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include "tulip.h"
 #include <linux/init.h>
 #include <asm/unaligned.h>
index 7f544ef2f5fcfcad23aa77b148f165cab8b82936..3810db9dc2de3a4ae17067b1ba087e32004fbc66 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include "tulip.h"
 #include <linux/init.h>
 #include <linux/etherdevice.h>
index 0ab05af237e5c78d68d110c40fe3efe55edb07c9..a589dd34891ee646e279b7a8de15c42d5c49a393 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -851,13 +850,15 @@ static void uli526x_rx_packet(struct net_device *dev, struct uli526x_board_info
 
                        if ( !(rdes0 & 0x8000) ||
                                ((db->cr6_data & CR6_PM) && (rxlen>6)) ) {
+                               struct sk_buff *new_skb = NULL;
+
                                skb = rxptr->rx_skb_ptr;
 
                                /* Good packet, send to upper layer */
                                /* Shorst packet used new SKB */
-                               if ( (rxlen < RX_COPY_SIZE) &&
-                                       ( (skb = dev_alloc_skb(rxlen + 2) )
-                                       != NULL) ) {
+                               if ((rxlen < RX_COPY_SIZE) &&
+                                   (((new_skb = dev_alloc_skb(rxlen + 2)) != NULL))) {
+                                       skb = new_skb;
                                        /* size less than COPY_SIZE, allocate a rxlen SKB */
                                        skb_reserve(skb, 2); /* 16byte align */
                                        memcpy(skb_put(skb, rxlen),
index 304f43866c4482e9b204e1be25585ad43e8d0f6a..98dbf6cc1d683d5e6fc5746ae76b85d8ba696e01 100644 (file)
@@ -114,7 +114,6 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
index 96c39bddc78c049e85411f6f298485b531356c78..43265207d46370c97789a4ac264acc2d4238dbad 100644 (file)
@@ -387,6 +387,10 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
                }
        }
 
+       /* Orphan the skb - required as we might hang on to it
+        * for indefinite time. */
+       skb_orphan(skb);
+
        /* Enqueue packet */
        skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb);
        dev->trans_start = jiffies;
index cd24e5f2b2a27944054f9ee4192910a81ab01795..98d818daa77ecae5f95b8ac8b4cfe0b7f6ca4d41 100644 (file)
@@ -109,7 +109,6 @@ static const int multicast_filter_limit = 32;
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
index 7075f26e97daa22bd090ebd9ef125c24836fceae..6f92e48f02d33f5ffccd2510384976441a2a2bb2 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/stddef.h>
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
index 32d93564a74d4839207fef67859c7bc1f967e3e7..d7b7018a1de1d180a003af42e43d967b5441b38e 100644 (file)
@@ -204,6 +204,14 @@ config USB_NET_DM9601
          This option adds support for Davicom DM9601 based USB 1.1
          10/100 Ethernet adapters.
 
+config USB_NET_SMSC75XX
+       tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices"
+       depends on USB_USBNET
+       select CRC32
+       help
+         This option adds support for SMSC LAN95XX based USB 2.0
+         Gigabit Ethernet adapters.
+
 config USB_NET_SMSC95XX
        tristate "SMSC LAN95XX based USB 2.0 10/100 ethernet devices"
        depends on USB_USBNET
@@ -377,4 +385,25 @@ config USB_CDC_PHONET
          cellular modem, as found on most Nokia handsets with the
          "PC suite" USB profile.
 
+config USB_IPHETH
+       tristate "Apple iPhone USB Ethernet driver"
+       default n
+       ---help---
+         Module used to share Internet connection (tethering) from your
+         iPhone (Original, 3G and 3GS) to your system.
+         Note that you need userspace libraries and programs that are needed
+         to pair your device with your system and that understand the iPhone
+         protocol.
+
+         For more information: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver
+
+config USB_SIERRA_NET
+       tristate "USB-to-WWAN Driver for Sierra Wireless modems"
+       depends on USB_USBNET
+       help
+         Choose this option if you have a Sierra Wireless USB-to-WWAN device.
+
+         To compile this driver as a module, choose M here: the
+         module will be called sierra_net.
+
 endmenu
index e17afb78f37220df2c8c6a13eb420aa14280fd09..b13a279663ba11b250a838c85619186d5e08eb56 100644 (file)
@@ -11,6 +11,7 @@ obj-$(CONFIG_USB_NET_AX8817X) += asix.o
 obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
 obj-$(CONFIG_USB_NET_CDC_EEM)  += cdc_eem.o
 obj-$(CONFIG_USB_NET_DM9601)   += dm9601.o
+obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o
 obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o
 obj-$(CONFIG_USB_NET_GL620A)   += gl620a.o
 obj-$(CONFIG_USB_NET_NET1080)  += net1080.o
@@ -22,4 +23,6 @@ obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o
 obj-$(CONFIG_USB_USBNET)       += usbnet.o
 obj-$(CONFIG_USB_NET_INT51X1)  += int51x1.o
 obj-$(CONFIG_USB_CDC_PHONET)   += cdc-phonet.o
+obj-$(CONFIG_USB_IPHETH)       += ipheth.o
+obj-$(CONFIG_USB_SIERRA_NET)   += sierra_net.o
 
index 9e05639435f2397a36a143545c78be1c56bd9080..35f56fc828032090512658216b56b712bf035999 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/usb.h>
 #include <linux/crc32.h>
 #include <linux/usb/usbnet.h>
+#include <linux/slab.h>
 
 #define DRIVER_VERSION "14-Jun-2006"
 static const char driver_name [] = "asix";
index 96f1ebe0d3484d490fb1bb1d514e6df15c4aa1c0..602e123b2741672994755fa9884a57f167b39bda 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
@@ -44,6 +43,7 @@
 #include <linux/ethtool.h>
 #include <linux/crc32.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 #include <asm/uaccess.h>
 
 #undef DEBUG
index 6491c9c00c83ac174857e2025b4002151ff851cf..dc9444525b4901c2035d50e5c84b7f39b510bc6d 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/usb.h>
 #include <linux/usb/cdc.h>
 #include <linux/netdevice.h>
index a4a85a6ed86de394e1bd532e5a10566275b3f5ed..5f3b97668e63c80ae37cb07dcd556d04a113c696 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/crc32.h>
 #include <linux/usb/cdc.h>
 #include <linux/usb/usbnet.h>
+#include <linux/gfp.h>
 
 
 /*
index c8cdb7f30adc05b0bba34d767dc29447c6d613c9..3547cf13d219c07ca56e7468ac2905b830c4959e 100644 (file)
@@ -431,6 +431,7 @@ static const struct driver_info mbm_info = {
        .bind =         cdc_bind,
        .unbind =       usbnet_cdc_unbind,
        .status =       cdc_status,
+       .manage_power = cdc_manage_power,
 };
 
 /*-------------------------------------------------------------------------*/
index 269339769f476cd1643b3f75087d7c1fc1a508a3..5dfed9297b22fbe4f5b8aa568e20ed416ee8df72 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/usb.h>
 #include <linux/crc32.h>
 #include <linux/usb/usbnet.h>
+#include <linux/slab.h>
 
 /* datasheet:
  http://ptm2.cc.utu.fi/ftp/network/cards/DM9601/From_NET/DM9601-DS-P01-930914.pdf
@@ -239,7 +240,7 @@ static int dm_write_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 valu
                goto out;
 
        dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg);
-       dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1c : 0x14);
+       dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1a : 0x12);
 
        for (i = 0; i < DM_TIMEOUT; i++) {
                u8 tmp;
index f7ccfad9384e60024bccb27ce03a8391089a52a5..dcd57c37ef733322a894cfebcb3956aa2d4705c7 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/usb/usbnet.h>
+#include <linux/gfp.h>
 
 
 /*
index 6895f15312380b146925d9ba17e71961ef177508..be0cc99e881a6c4c41c8b8f502d0392f4be343e5 100644 (file)
@@ -1155,9 +1155,6 @@ static void _hso_serial_set_termios(struct tty_struct *tty,
 static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb)
 {
        int result;
-#ifdef CONFIG_HSO_AUTOPM
-       usb_mark_last_busy(urb->dev);
-#endif
        /* We are done with this URB, resubmit it. Prep the USB to wait for
         * another frame */
        usb_fill_bulk_urb(urb, serial->parent->usb,
index 3c228df57062d2cc86212eeb410b27795dfa3869..be02a25da71a4572fc96ac9d3c699da4db248822 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
+#include <linux/slab.h>
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/usb/usbnet.h>
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
new file mode 100644 (file)
index 0000000..418825d
--- /dev/null
@@ -0,0 +1,569 @@
+/*
+ * ipheth.c - Apple iPhone USB Ethernet driver
+ *
+ * Copyright (c) 2009 Diego Giagio <diego@giagio.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of GIAGIO.COM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * The provided data structures and external interfaces from this code
+ * are not restricted to be used by modules with a GPL compatible license.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * Attention: iPhone device must be paired, otherwise it won't respond to our
+ * driver. For more info: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/usb.h>
+#include <linux/workqueue.h>
+
+#define USB_VENDOR_APPLE        0x05ac
+#define USB_PRODUCT_IPHONE      0x1290
+#define USB_PRODUCT_IPHONE_3G   0x1292
+#define USB_PRODUCT_IPHONE_3GS  0x1294
+
+#define IPHETH_USBINTF_CLASS    255
+#define IPHETH_USBINTF_SUBCLASS 253
+#define IPHETH_USBINTF_PROTO    1
+
+#define IPHETH_BUF_SIZE         1516
+#define IPHETH_TX_TIMEOUT       (5 * HZ)
+
+#define IPHETH_INTFNUM          2
+#define IPHETH_ALT_INTFNUM      1
+
+#define IPHETH_CTRL_ENDP        0x00
+#define IPHETH_CTRL_BUF_SIZE    0x40
+#define IPHETH_CTRL_TIMEOUT     (5 * HZ)
+
+#define IPHETH_CMD_GET_MACADDR   0x00
+#define IPHETH_CMD_CARRIER_CHECK 0x45
+
+#define IPHETH_CARRIER_CHECK_TIMEOUT round_jiffies_relative(1 * HZ)
+#define IPHETH_CARRIER_ON       0x04
+
+static struct usb_device_id ipheth_table[] = {
+       { USB_DEVICE_AND_INTERFACE_INFO(
+               USB_VENDOR_APPLE, USB_PRODUCT_IPHONE,
+               IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+               IPHETH_USBINTF_PROTO) },
+       { USB_DEVICE_AND_INTERFACE_INFO(
+               USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3G,
+               IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+               IPHETH_USBINTF_PROTO) },
+       { USB_DEVICE_AND_INTERFACE_INFO(
+               USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3GS,
+               IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+               IPHETH_USBINTF_PROTO) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, ipheth_table);
+
+struct ipheth_device {
+       struct usb_device *udev;
+       struct usb_interface *intf;
+       struct net_device *net;
+       struct sk_buff *tx_skb;
+       struct urb *tx_urb;
+       struct urb *rx_urb;
+       unsigned char *tx_buf;
+       unsigned char *rx_buf;
+       unsigned char *ctrl_buf;
+       u8 bulk_in;
+       u8 bulk_out;
+       struct delayed_work carrier_work;
+};
+
+static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags);
+
+static int ipheth_alloc_urbs(struct ipheth_device *iphone)
+{
+       struct urb *tx_urb = NULL;
+       struct urb *rx_urb = NULL;
+       u8 *tx_buf = NULL;
+       u8 *rx_buf = NULL;
+
+       tx_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (tx_urb == NULL)
+               goto error_nomem;
+
+       rx_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (rx_urb == NULL)
+               goto free_tx_urb;
+
+       tx_buf = usb_buffer_alloc(iphone->udev,
+                                 IPHETH_BUF_SIZE,
+                                 GFP_KERNEL,
+                                 &tx_urb->transfer_dma);
+       if (tx_buf == NULL)
+               goto free_rx_urb;
+
+       rx_buf = usb_buffer_alloc(iphone->udev,
+                                 IPHETH_BUF_SIZE,
+                                 GFP_KERNEL,
+                                 &rx_urb->transfer_dma);
+       if (rx_buf == NULL)
+               goto free_tx_buf;
+
+
+       iphone->tx_urb = tx_urb;
+       iphone->rx_urb = rx_urb;
+       iphone->tx_buf = tx_buf;
+       iphone->rx_buf = rx_buf;
+       return 0;
+
+free_tx_buf:
+       usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, tx_buf,
+                       tx_urb->transfer_dma);
+free_rx_urb:
+       usb_free_urb(rx_urb);
+free_tx_urb:
+       usb_free_urb(tx_urb);
+error_nomem:
+       return -ENOMEM;
+}
+
+static void ipheth_free_urbs(struct ipheth_device *iphone)
+{
+       usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, iphone->rx_buf,
+                       iphone->rx_urb->transfer_dma);
+       usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf,
+                       iphone->tx_urb->transfer_dma);
+       usb_free_urb(iphone->rx_urb);
+       usb_free_urb(iphone->tx_urb);
+}
+
+static void ipheth_kill_urbs(struct ipheth_device *dev)
+{
+       usb_kill_urb(dev->tx_urb);
+       usb_kill_urb(dev->rx_urb);
+}
+
+static void ipheth_rcvbulk_callback(struct urb *urb)
+{
+       struct ipheth_device *dev;
+       struct sk_buff *skb;
+       int status;
+       char *buf;
+       int len;
+
+       dev = urb->context;
+       if (dev == NULL)
+               return;
+
+       status = urb->status;
+       switch (status) {
+       case -ENOENT:
+       case -ECONNRESET:
+       case -ESHUTDOWN:
+               return;
+       case 0:
+               break;
+       default:
+               err("%s: urb status: %d", __func__, urb->status);
+               return;
+       }
+
+       len = urb->actual_length;
+       buf = urb->transfer_buffer;
+
+       skb = dev_alloc_skb(NET_IP_ALIGN + len);
+       if (!skb) {
+               err("%s: dev_alloc_skb: -ENOMEM", __func__);
+               dev->net->stats.rx_dropped++;
+               return;
+       }
+
+       skb_reserve(skb, NET_IP_ALIGN);
+       memcpy(skb_put(skb, len), buf + NET_IP_ALIGN, len - NET_IP_ALIGN);
+       skb->dev = dev->net;
+       skb->protocol = eth_type_trans(skb, dev->net);
+
+       dev->net->stats.rx_packets++;
+       dev->net->stats.rx_bytes += len;
+
+       netif_rx(skb);
+       ipheth_rx_submit(dev, GFP_ATOMIC);
+}
+
+static void ipheth_sndbulk_callback(struct urb *urb)
+{
+       struct ipheth_device *dev;
+
+       dev = urb->context;
+       if (dev == NULL)
+               return;
+
+       if (urb->status != 0 &&
+           urb->status != -ENOENT &&
+           urb->status != -ECONNRESET &&
+           urb->status != -ESHUTDOWN)
+               err("%s: urb status: %d", __func__, urb->status);
+
+       dev_kfree_skb_irq(dev->tx_skb);
+       netif_wake_queue(dev->net);
+}
+
+static int ipheth_carrier_set(struct ipheth_device *dev)
+{
+       struct usb_device *udev = dev->udev;
+       int retval;
+
+       retval = usb_control_msg(udev,
+                       usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP),
+                       IPHETH_CMD_CARRIER_CHECK, /* request */
+                       0xc0, /* request type */
+                       0x00, /* value */
+                       0x02, /* index */
+                       dev->ctrl_buf, IPHETH_CTRL_BUF_SIZE,
+                       IPHETH_CTRL_TIMEOUT);
+       if (retval < 0) {
+               err("%s: usb_control_msg: %d", __func__, retval);
+               return retval;
+       }
+
+       if (dev->ctrl_buf[0] == IPHETH_CARRIER_ON)
+               netif_carrier_on(dev->net);
+       else
+               netif_carrier_off(dev->net);
+
+       return 0;
+}
+
+static void ipheth_carrier_check_work(struct work_struct *work)
+{
+       struct ipheth_device *dev = container_of(work, struct ipheth_device,
+                                                carrier_work.work);
+
+       ipheth_carrier_set(dev);
+       schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT);
+}
+
+static int ipheth_get_macaddr(struct ipheth_device *dev)
+{
+       struct usb_device *udev = dev->udev;
+       struct net_device *net = dev->net;
+       int retval;
+
+       retval = usb_control_msg(udev,
+                                usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP),
+                                IPHETH_CMD_GET_MACADDR, /* request */
+                                0xc0, /* request type */
+                                0x00, /* value */
+                                0x02, /* index */
+                                dev->ctrl_buf,
+                                IPHETH_CTRL_BUF_SIZE,
+                                IPHETH_CTRL_TIMEOUT);
+       if (retval < 0) {
+               err("%s: usb_control_msg: %d", __func__, retval);
+       } else if (retval < ETH_ALEN) {
+               err("%s: usb_control_msg: short packet: %d bytes",
+                       __func__, retval);
+               retval = -EINVAL;
+       } else {
+               memcpy(net->dev_addr, dev->ctrl_buf, ETH_ALEN);
+               retval = 0;
+       }
+
+       return retval;
+}
+
+static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags)
+{
+       struct usb_device *udev = dev->udev;
+       int retval;
+
+       usb_fill_bulk_urb(dev->rx_urb, udev,
+                         usb_rcvbulkpipe(udev, dev->bulk_in),
+                         dev->rx_buf, IPHETH_BUF_SIZE,
+                         ipheth_rcvbulk_callback,
+                         dev);
+       dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+       retval = usb_submit_urb(dev->rx_urb, mem_flags);
+       if (retval)
+               err("%s: usb_submit_urb: %d", __func__, retval);
+       return retval;
+}
+
+static int ipheth_open(struct net_device *net)
+{
+       struct ipheth_device *dev = netdev_priv(net);
+       struct usb_device *udev = dev->udev;
+       int retval = 0;
+
+       usb_set_interface(udev, IPHETH_INTFNUM, IPHETH_ALT_INTFNUM);
+
+       retval = ipheth_carrier_set(dev);
+       if (retval)
+               return retval;
+
+       retval = ipheth_rx_submit(dev, GFP_KERNEL);
+       if (retval)
+               return retval;
+
+       schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT);
+       netif_start_queue(net);
+       return retval;
+}
+
+static int ipheth_close(struct net_device *net)
+{
+       struct ipheth_device *dev = netdev_priv(net);
+
+       cancel_delayed_work_sync(&dev->carrier_work);
+       netif_stop_queue(net);
+       return 0;
+}
+
+static int ipheth_tx(struct sk_buff *skb, struct net_device *net)
+{
+       struct ipheth_device *dev = netdev_priv(net);
+       struct usb_device *udev = dev->udev;
+       int retval;
+
+       /* Paranoid */
+       if (skb->len > IPHETH_BUF_SIZE) {
+               WARN(1, "%s: skb too large: %d bytes", __func__, skb->len);
+               dev->net->stats.tx_dropped++;
+               dev_kfree_skb_irq(skb);
+               return NETDEV_TX_OK;
+       }
+
+       memcpy(dev->tx_buf, skb->data, skb->len);
+       if (skb->len < IPHETH_BUF_SIZE)
+               memset(dev->tx_buf + skb->len, 0, IPHETH_BUF_SIZE - skb->len);
+
+       usb_fill_bulk_urb(dev->tx_urb, udev,
+                         usb_sndbulkpipe(udev, dev->bulk_out),
+                         dev->tx_buf, IPHETH_BUF_SIZE,
+                         ipheth_sndbulk_callback,
+                         dev);
+       dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+       retval = usb_submit_urb(dev->tx_urb, GFP_ATOMIC);
+       if (retval) {
+               err("%s: usb_submit_urb: %d", __func__, retval);
+               dev->net->stats.tx_errors++;
+               dev_kfree_skb_irq(skb);
+       } else {
+               dev->tx_skb = skb;
+
+               dev->net->stats.tx_packets++;
+               dev->net->stats.tx_bytes += skb->len;
+               netif_stop_queue(net);
+       }
+
+       return NETDEV_TX_OK;
+}
+
+static void ipheth_tx_timeout(struct net_device *net)
+{
+       struct ipheth_device *dev = netdev_priv(net);
+
+       err("%s: TX timeout", __func__);
+       dev->net->stats.tx_errors++;
+       usb_unlink_urb(dev->tx_urb);
+}
+
+static struct net_device_stats *ipheth_stats(struct net_device *net)
+{
+       struct ipheth_device *dev = netdev_priv(net);
+       return &dev->net->stats;
+}
+
+static u32 ipheth_ethtool_op_get_link(struct net_device *net)
+{
+       struct ipheth_device *dev = netdev_priv(net);
+       return netif_carrier_ok(dev->net);
+}
+
+static struct ethtool_ops ops = {
+       .get_link = ipheth_ethtool_op_get_link
+};
+
+static const struct net_device_ops ipheth_netdev_ops = {
+       .ndo_open = &ipheth_open,
+       .ndo_stop = &ipheth_close,
+       .ndo_start_xmit = &ipheth_tx,
+       .ndo_tx_timeout = &ipheth_tx_timeout,
+       .ndo_get_stats = &ipheth_stats,
+};
+
+static struct device_type ipheth_type = {
+       .name   = "wwan",
+};
+
+static int ipheth_probe(struct usb_interface *intf,
+                       const struct usb_device_id *id)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct usb_host_interface *hintf;
+       struct usb_endpoint_descriptor *endp;
+       struct ipheth_device *dev;
+       struct net_device *netdev;
+       int i;
+       int retval;
+
+       netdev = alloc_etherdev(sizeof(struct ipheth_device));
+       if (!netdev)
+               return -ENOMEM;
+
+       netdev->netdev_ops = &ipheth_netdev_ops;
+       netdev->watchdog_timeo = IPHETH_TX_TIMEOUT;
+       strcpy(netdev->name, "wwan%d");
+
+       dev = netdev_priv(netdev);
+       dev->udev = udev;
+       dev->net = netdev;
+       dev->intf = intf;
+
+       /* Set up endpoints */
+       hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM);
+       if (hintf == NULL) {
+               retval = -ENODEV;
+               err("Unable to find alternate settings interface");
+               goto err_endpoints;
+       }
+
+       for (i = 0; i < hintf->desc.bNumEndpoints; i++) {
+               endp = &hintf->endpoint[i].desc;
+               if (usb_endpoint_is_bulk_in(endp))
+                       dev->bulk_in = endp->bEndpointAddress;
+               else if (usb_endpoint_is_bulk_out(endp))
+                       dev->bulk_out = endp->bEndpointAddress;
+       }
+       if (!(dev->bulk_in && dev->bulk_out)) {
+               retval = -ENODEV;
+               err("Unable to find endpoints");
+               goto err_endpoints;
+       }
+
+       dev->ctrl_buf = kmalloc(IPHETH_CTRL_BUF_SIZE, GFP_KERNEL);
+       if (dev->ctrl_buf == NULL) {
+               retval = -ENOMEM;
+               goto err_alloc_ctrl_buf;
+       }
+
+       retval = ipheth_get_macaddr(dev);
+       if (retval)
+               goto err_get_macaddr;
+
+       INIT_DELAYED_WORK(&dev->carrier_work, ipheth_carrier_check_work);
+
+       retval = ipheth_alloc_urbs(dev);
+       if (retval) {
+               err("error allocating urbs: %d", retval);
+               goto err_alloc_urbs;
+       }
+
+       usb_set_intfdata(intf, dev);
+
+       SET_NETDEV_DEV(netdev, &intf->dev);
+       SET_ETHTOOL_OPS(netdev, &ops);
+       SET_NETDEV_DEVTYPE(netdev, &ipheth_type);
+
+       retval = register_netdev(netdev);
+       if (retval) {
+               err("error registering netdev: %d", retval);
+               retval = -EIO;
+               goto err_register_netdev;
+       }
+
+       dev_info(&intf->dev, "Apple iPhone USB Ethernet device attached\n");
+       return 0;
+
+err_register_netdev:
+       ipheth_free_urbs(dev);
+err_alloc_urbs:
+err_get_macaddr:
+err_alloc_ctrl_buf:
+       kfree(dev->ctrl_buf);
+err_endpoints:
+       free_netdev(netdev);
+       return retval;
+}
+
+static void ipheth_disconnect(struct usb_interface *intf)
+{
+       struct ipheth_device *dev;
+
+       dev = usb_get_intfdata(intf);
+       if (dev != NULL) {
+               unregister_netdev(dev->net);
+               ipheth_kill_urbs(dev);
+               ipheth_free_urbs(dev);
+               kfree(dev->ctrl_buf);
+               free_netdev(dev->net);
+       }
+       usb_set_intfdata(intf, NULL);
+       dev_info(&intf->dev, "Apple iPhone USB Ethernet now disconnected\n");
+}
+
+static struct usb_driver ipheth_driver = {
+       .name =         "ipheth",
+       .probe =        ipheth_probe,
+       .disconnect =   ipheth_disconnect,
+       .id_table =     ipheth_table,
+};
+
+static int __init ipheth_init(void)
+{
+       int retval;
+
+       retval = usb_register(&ipheth_driver);
+       if (retval) {
+               err("usb_register failed: %d", retval);
+               return retval;
+       }
+       return 0;
+}
+
+static void __exit ipheth_exit(void)
+{
+       usb_deregister(&ipheth_driver);
+}
+
+module_init(ipheth_init);
+module_exit(ipheth_exit);
+
+MODULE_AUTHOR("Diego Giagio <diego@giagio.com>");
+MODULE_DESCRIPTION("Apple iPhone USB Ethernet driver");
+MODULE_LICENSE("Dual BSD/GPL");
index 52671ea043a776bd1e2a12bc41e27a015769b9dd..c4c334d9770f9916f2f67c85661c6694fa5f4c25 100644 (file)
@@ -145,6 +145,7 @@ static struct usb_device_id usb_klsi_table[] = {
        { USB_DEVICE(0x0707, 0x0100) }, /* SMC 2202USB */
        { USB_DEVICE(0x07aa, 0x0001) }, /* Correga K.K. */
        { USB_DEVICE(0x07b8, 0x4000) }, /* D-Link DU-E10 */
+       { USB_DEVICE(0x07c9, 0xb010) }, /* Allied Telesyn AT-USB10 USB Ethernet Adapter */
        { USB_DEVICE(0x0846, 0x1001) }, /* NetGear EA-101 */
        { USB_DEVICE(0x0846, 0x1002) }, /* NetGear EA-101 */
        { USB_DEVICE(0x085a, 0x0008) }, /* PortGear Ethernet Adapter */
index 70978219e98afb8005a1519e4120a6f8acd7e23d..9f24e3f871e1ff67cdff9e9e4327cca53da3e867 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/mii.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/usbnet.h>
 
index bdcad45954a3a4d59217dfb3c6119eae6743491a..961a8ed38d8f40622a49f9929184a0c7c4f6042c 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/usb/usbnet.h>
+#include <linux/slab.h>
 
 #include <asm/unaligned.h>
 
index 4ce331fb1e1e980eb18f6b9ab76a6ee6afb81d23..dd8a4adf48cadf3d1c85507dc9c71c9d9c316004 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/usb/cdc.h>
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
new file mode 100644 (file)
index 0000000..f1942d6
--- /dev/null
@@ -0,0 +1,1004 @@
+/*
+ * USB-to-WWAN Driver for Sierra Wireless modems
+ *
+ * Copyright (C) 2008, 2009, 2010 Paxton Smith, Matthew Safar, Rory Filer
+ *                          <linux@sierrawireless.com>
+ *
+ * Portions of this based on the cdc_ether driver by David Brownell (2003-2005)
+ * and Ole Andre Vadla Ravnas (ActiveSync) (2006).
+ *
+ * IMPORTANT DISCLAIMER: This driver is not commercially supported by
+ * Sierra Wireless. Use at your own risk.
+ *
+ * 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 DRIVER_VERSION "v.2.0"
+#define DRIVER_AUTHOR "Paxton Smith, Matthew Safar, Rory Filer"
+#define DRIVER_DESC "USB-to-WWAN Driver for Sierra Wireless modems"
+static const char driver_name[] = "sierra_net";
+
+/* if defined debug messages enabled */
+/*#define      DEBUG*/
+
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/usb.h>
+#include <linux/usb/cdc.h>
+#include <net/ip.h>
+#include <net/udp.h>
+#include <asm/unaligned.h>
+#include <linux/usb/usbnet.h>
+
+#define SWI_USB_REQUEST_GET_FW_ATTR    0x06
+#define SWI_GET_FW_ATTR_MASK           0x08
+
+/* atomic counter partially included in MAC address to make sure 2 devices
+ * do not end up with the same MAC - concept breaks in case of > 255 ifaces
+ */
+static atomic_t iface_counter = ATOMIC_INIT(0);
+
+/*
+ * SYNC Timer Delay definition used to set the expiry time
+ */
+#define SIERRA_NET_SYNCDELAY (2*HZ)
+
+/* Max. MTU supported. The modem buffers are limited to 1500 */
+#define SIERRA_NET_MAX_SUPPORTED_MTU   1500
+
+/* The SIERRA_NET_USBCTL_BUF_LEN defines a buffer size allocated for control
+ * message reception ... and thus the max. received packet.
+ * (May be the cause for parse_hip returning -EINVAL)
+ */
+#define SIERRA_NET_USBCTL_BUF_LEN      1024
+
+/* list of interface numbers - used for constructing interface lists */
+struct sierra_net_iface_info {
+       const u32 infolen;      /* number of interface numbers on list */
+       const u8  *ifaceinfo;   /* pointer to the array holding the numbers */
+};
+
+struct sierra_net_info_data {
+       u16 rx_urb_size;
+       struct sierra_net_iface_info whitelist;
+};
+
+/* Private data structure */
+struct sierra_net_data {
+
+       u8 ethr_hdr_tmpl[ETH_HLEN]; /* ethernet header template for rx'd pkts */
+
+       u16 link_up;            /* air link up or down */
+       u8 tx_hdr_template[4];  /* part of HIP hdr for tx'd packets */
+
+       u8 sync_msg[4];         /* SYNC message */
+       u8 shdwn_msg[4];        /* Shutdown message */
+
+       /* Backpointer to the container */
+       struct usbnet *usbnet;
+
+       u8 ifnum;       /* interface number */
+
+/* Bit masks, must be a power of 2 */
+#define SIERRA_NET_EVENT_RESP_AVAIL    0x01
+#define SIERRA_NET_TIMER_EXPIRY        0x02
+       unsigned long kevent_flags;
+       struct work_struct sierra_net_kevent;
+       struct timer_list sync_timer; /* For retrying SYNC sequence */
+};
+
+struct param {
+       int is_present;
+       union {
+               void  *ptr;
+               u32    dword;
+               u16    word;
+               u8     byte;
+       };
+};
+
+/* HIP message type */
+#define SIERRA_NET_HIP_EXTENDEDID      0x7F
+#define SIERRA_NET_HIP_HSYNC_ID                0x60    /* Modem -> host */
+#define SIERRA_NET_HIP_RESTART_ID      0x62    /* Modem -> host */
+#define SIERRA_NET_HIP_MSYNC_ID                0x20    /* Host -> modem */
+#define SIERRA_NET_HIP_SHUTD_ID                0x26    /* Host -> modem */
+
+#define SIERRA_NET_HIP_EXT_IP_IN_ID   0x0202
+#define SIERRA_NET_HIP_EXT_IP_OUT_ID  0x0002
+
+/* 3G UMTS Link Sense Indication definitions */
+#define SIERRA_NET_HIP_LSI_UMTSID      0x78
+
+/* Reverse Channel Grant Indication HIP message */
+#define SIERRA_NET_HIP_RCGI            0x64
+
+/* LSI Protocol types */
+#define SIERRA_NET_PROTOCOL_UMTS      0x01
+/* LSI Coverage */
+#define SIERRA_NET_COVERAGE_NONE      0x00
+#define SIERRA_NET_COVERAGE_NOPACKET  0x01
+
+/* LSI Session */
+#define SIERRA_NET_SESSION_IDLE       0x00
+/* LSI Link types */
+#define SIERRA_NET_AS_LINK_TYPE_IPv4  0x00
+
+struct lsi_umts {
+       u8 protocol;
+       u8 unused1;
+       __be16 length;
+       /* eventually use a union for the rest - assume umts for now */
+       u8 coverage;
+       u8 unused2[41];
+       u8 session_state;
+       u8 unused3[33];
+       u8 link_type;
+       u8 pdp_addr_len; /* NW-supplied PDP address len */
+       u8 pdp_addr[16]; /* NW-supplied PDP address (bigendian)) */
+       u8 unused4[23];
+       u8 dns1_addr_len; /* NW-supplied 1st DNS address len (bigendian) */
+       u8 dns1_addr[16]; /* NW-supplied 1st DNS address */
+       u8 dns2_addr_len; /* NW-supplied 2nd DNS address len */
+       u8 dns2_addr[16]; /* NW-supplied 2nd DNS address (bigendian)*/
+       u8 wins1_addr_len; /* NW-supplied 1st Wins address len */
+       u8 wins1_addr[16]; /* NW-supplied 1st Wins address (bigendian)*/
+       u8 wins2_addr_len; /* NW-supplied 2nd Wins address len */
+       u8 wins2_addr[16]; /* NW-supplied 2nd Wins address (bigendian) */
+       u8 unused5[4];
+       u8 gw_addr_len; /* NW-supplied GW address len */
+       u8 gw_addr[16]; /* NW-supplied GW address (bigendian) */
+       u8 reserved[8];
+} __attribute__ ((packed));
+
+#define SIERRA_NET_LSI_COMMON_LEN      4
+#define SIERRA_NET_LSI_UMTS_LEN        (sizeof(struct lsi_umts))
+#define SIERRA_NET_LSI_UMTS_STATUS_LEN \
+       (SIERRA_NET_LSI_UMTS_LEN - SIERRA_NET_LSI_COMMON_LEN)
+
+/* Forward definitions */
+static void sierra_sync_timer(unsigned long syncdata);
+static int sierra_net_change_mtu(struct net_device *net, int new_mtu);
+
+/* Our own net device operations structure */
+static const struct net_device_ops sierra_net_device_ops = {
+       .ndo_open               = usbnet_open,
+       .ndo_stop               = usbnet_stop,
+       .ndo_start_xmit         = usbnet_start_xmit,
+       .ndo_tx_timeout         = usbnet_tx_timeout,
+       .ndo_change_mtu         = sierra_net_change_mtu,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
+/* get private data associated with passed in usbnet device */
+static inline struct sierra_net_data *sierra_net_get_private(struct usbnet *dev)
+{
+       return (struct sierra_net_data *)dev->data[0];
+}
+
+/* set private data associated with passed in usbnet device */
+static inline void sierra_net_set_private(struct usbnet *dev,
+                       struct sierra_net_data *priv)
+{
+       dev->data[0] = (unsigned long)priv;
+}
+
+/* is packet IPv4 */
+static inline int is_ip(struct sk_buff *skb)
+{
+       return (skb->protocol == cpu_to_be16(ETH_P_IP));
+}
+
+/*
+ * check passed in packet and make sure that:
+ *  - it is linear (no scatter/gather)
+ *  - it is ethernet (mac_header properly set)
+ */
+static int check_ethip_packet(struct sk_buff *skb, struct usbnet *dev)
+{
+       skb_reset_mac_header(skb); /* ethernet header */
+
+       if (skb_is_nonlinear(skb)) {
+               netdev_err(dev->net, "Non linear buffer-dropping\n");
+               return 0;
+       }
+
+       if (!pskb_may_pull(skb, ETH_HLEN))
+               return 0;
+       skb->protocol = eth_hdr(skb)->h_proto;
+
+       return 1;
+}
+
+static const u8 *save16bit(struct param *p, const u8 *datap)
+{
+       p->is_present = 1;
+       p->word = get_unaligned_be16(datap);
+       return datap + sizeof(p->word);
+}
+
+static const u8 *save8bit(struct param *p, const u8 *datap)
+{
+       p->is_present = 1;
+       p->byte = *datap;
+       return datap + sizeof(p->byte);
+}
+
+/*----------------------------------------------------------------------------*
+ *                              BEGIN HIP                                     *
+ *----------------------------------------------------------------------------*/
+/* HIP header */
+#define SIERRA_NET_HIP_HDR_LEN 4
+/* Extended HIP header */
+#define SIERRA_NET_HIP_EXT_HDR_LEN 6
+
+struct hip_hdr {
+       int    hdrlen;
+       struct param payload_len;
+       struct param msgid;
+       struct param msgspecific;
+       struct param extmsgid;
+};
+
+static int parse_hip(const u8 *buf, const u32 buflen, struct hip_hdr *hh)
+{
+       const u8 *curp = buf;
+       int    padded;
+
+       if (buflen < SIERRA_NET_HIP_HDR_LEN)
+               return -EPROTO;
+
+       curp = save16bit(&hh->payload_len, curp);
+       curp = save8bit(&hh->msgid, curp);
+       curp = save8bit(&hh->msgspecific, curp);
+
+       padded = hh->msgid.byte & 0x80;
+       hh->msgid.byte &= 0x7F;                 /* 7 bits */
+
+       hh->extmsgid.is_present = (hh->msgid.byte == SIERRA_NET_HIP_EXTENDEDID);
+       if (hh->extmsgid.is_present) {
+               if (buflen < SIERRA_NET_HIP_EXT_HDR_LEN)
+                       return -EPROTO;
+
+               hh->payload_len.word &= 0x3FFF; /* 14 bits */
+
+               curp = save16bit(&hh->extmsgid, curp);
+               hh->extmsgid.word &= 0x03FF;    /* 10 bits */
+
+               hh->hdrlen = SIERRA_NET_HIP_EXT_HDR_LEN;
+       } else {
+               hh->payload_len.word &= 0x07FF; /* 11 bits */
+               hh->hdrlen = SIERRA_NET_HIP_HDR_LEN;
+       }
+
+       if (padded) {
+               hh->hdrlen++;
+               hh->payload_len.word--;
+       }
+
+       /* if real packet shorter than the claimed length */
+       if (buflen < (hh->hdrlen + hh->payload_len.word))
+               return -EINVAL;
+
+       return 0;
+}
+
+static void build_hip(u8 *buf, const u16 payloadlen,
+               struct sierra_net_data *priv)
+{
+       /* the following doesn't have the full functionality. We
+        * currently build only one kind of header, so it is faster this way
+        */
+       put_unaligned_be16(payloadlen, buf);
+       memcpy(buf+2, priv->tx_hdr_template, sizeof(priv->tx_hdr_template));
+}
+/*----------------------------------------------------------------------------*
+ *                              END HIP                                       *
+ *----------------------------------------------------------------------------*/
+
+static int sierra_net_send_cmd(struct usbnet *dev,
+               u8 *cmd, int cmdlen, const char * cmd_name)
+{
+       struct sierra_net_data *priv = sierra_net_get_private(dev);
+       int  status;
+
+       status = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+                       USB_CDC_SEND_ENCAPSULATED_COMMAND,
+                       USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE, 0,
+                       priv->ifnum, cmd, cmdlen, USB_CTRL_SET_TIMEOUT);
+
+       if (status != cmdlen && status != -ENODEV)
+               netdev_err(dev->net, "Submit %s failed %d\n", cmd_name, status);
+
+       return status;
+}
+
+static int sierra_net_send_sync(struct usbnet *dev)
+{
+       int  status;
+       struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+       dev_dbg(&dev->udev->dev, "%s", __func__);
+
+       status = sierra_net_send_cmd(dev, priv->sync_msg,
+                       sizeof(priv->sync_msg), "SYNC");
+
+       return status;
+}
+
+static void sierra_net_set_ctx_index(struct sierra_net_data *priv, u8 ctx_ix)
+{
+       dev_dbg(&(priv->usbnet->udev->dev), "%s %d", __func__, ctx_ix);
+       priv->tx_hdr_template[0] = 0x3F;
+       priv->tx_hdr_template[1] = ctx_ix;
+       *((u16 *)&priv->tx_hdr_template[2]) =
+               cpu_to_be16(SIERRA_NET_HIP_EXT_IP_OUT_ID);
+}
+
+static inline int sierra_net_is_valid_addrlen(u8 len)
+{
+       return (len == sizeof(struct in_addr));
+}
+
+static int sierra_net_parse_lsi(struct usbnet *dev, char *data, int datalen)
+{
+       struct lsi_umts *lsi = (struct lsi_umts *)data;
+
+       if (datalen < sizeof(struct lsi_umts)) {
+               netdev_err(dev->net, "%s: Data length %d, exp %Zu\n",
+                               __func__, datalen,
+                               sizeof(struct lsi_umts));
+               return -1;
+       }
+
+       if (lsi->length != cpu_to_be16(SIERRA_NET_LSI_UMTS_STATUS_LEN)) {
+               netdev_err(dev->net, "%s: LSI_UMTS_STATUS_LEN %d, exp %u\n",
+                               __func__, be16_to_cpu(lsi->length),
+                               (u32)SIERRA_NET_LSI_UMTS_STATUS_LEN);
+               return -1;
+       }
+
+       /* Validate the protocol  - only support UMTS for now */
+       if (lsi->protocol != SIERRA_NET_PROTOCOL_UMTS) {
+               netdev_err(dev->net, "Protocol unsupported, 0x%02x\n",
+                       lsi->protocol);
+               return -1;
+       }
+
+       /* Validate the link type */
+       if (lsi->link_type != SIERRA_NET_AS_LINK_TYPE_IPv4) {
+               netdev_err(dev->net, "Link type unsupported: 0x%02x\n",
+                       lsi->link_type);
+               return -1;
+       }
+
+       /* Validate the coverage */
+       if (lsi->coverage == SIERRA_NET_COVERAGE_NONE
+          || lsi->coverage == SIERRA_NET_COVERAGE_NOPACKET) {
+               netdev_err(dev->net, "No coverage, 0x%02x\n", lsi->coverage);
+               return 0;
+       }
+
+       /* Validate the session state */
+       if (lsi->session_state == SIERRA_NET_SESSION_IDLE) {
+               netdev_err(dev->net, "Session idle, 0x%02x\n",
+                       lsi->session_state);
+               return 0;
+       }
+
+       /* Set link_sense true */
+       return 1;
+}
+
+static void sierra_net_handle_lsi(struct usbnet *dev, char *data,
+               struct hip_hdr  *hh)
+{
+       struct sierra_net_data *priv = sierra_net_get_private(dev);
+       int link_up;
+
+       link_up = sierra_net_parse_lsi(dev, data + hh->hdrlen,
+                                       hh->payload_len.word);
+       if (link_up < 0) {
+               netdev_err(dev->net, "Invalid LSI\n");
+               return;
+       }
+       if (link_up) {
+               sierra_net_set_ctx_index(priv, hh->msgspecific.byte);
+               priv->link_up = 1;
+               netif_carrier_on(dev->net);
+       } else {
+               priv->link_up = 0;
+               netif_carrier_off(dev->net);
+       }
+}
+
+static void sierra_net_dosync(struct usbnet *dev)
+{
+       int status;
+       struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+       dev_dbg(&dev->udev->dev, "%s", __func__);
+
+       /* tell modem we are ready */
+       status = sierra_net_send_sync(dev);
+       if (status < 0)
+               netdev_err(dev->net,
+                       "Send SYNC failed, status %d\n", status);
+       status = sierra_net_send_sync(dev);
+       if (status < 0)
+               netdev_err(dev->net,
+                       "Send SYNC failed, status %d\n", status);
+
+       /* Now, start a timer and make sure we get the Restart Indication */
+       priv->sync_timer.function = sierra_sync_timer;
+       priv->sync_timer.data = (unsigned long) dev;
+       priv->sync_timer.expires = jiffies + SIERRA_NET_SYNCDELAY;
+       add_timer(&priv->sync_timer);
+}
+
+static void sierra_net_kevent(struct work_struct *work)
+{
+       struct sierra_net_data *priv =
+               container_of(work, struct sierra_net_data, sierra_net_kevent);
+       struct usbnet *dev = priv->usbnet;
+       int  len;
+       int  err;
+       u8  *buf;
+       u8   ifnum;
+
+       if (test_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags)) {
+               clear_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags);
+
+               /* Query the modem for the LSI message */
+               buf = kzalloc(SIERRA_NET_USBCTL_BUF_LEN, GFP_KERNEL);
+               if (!buf) {
+                       netdev_err(dev->net,
+                               "failed to allocate buf for LS msg\n");
+                       return;
+               }
+               ifnum = priv->ifnum;
+               len = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
+                               USB_CDC_GET_ENCAPSULATED_RESPONSE,
+                               USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE,
+                               0, ifnum, buf, SIERRA_NET_USBCTL_BUF_LEN,
+                               USB_CTRL_SET_TIMEOUT);
+
+               if (len < 0) {
+                       netdev_err(dev->net,
+                               "usb_control_msg failed, status %d\n", len);
+               } else {
+                       struct hip_hdr  hh;
+
+                       dev_dbg(&dev->udev->dev, "%s: Received status message,"
+                               " %04x bytes", __func__, len);
+
+                       err = parse_hip(buf, len, &hh);
+                       if (err) {
+                               netdev_err(dev->net, "%s: Bad packet,"
+                                       " parse result %d\n", __func__, err);
+                               kfree(buf);
+                               return;
+                       }
+
+                       /* Validate packet length */
+                       if (len != hh.hdrlen + hh.payload_len.word) {
+                               netdev_err(dev->net, "%s: Bad packet, received"
+                                       " %d, expected %d\n",   __func__, len,
+                                       hh.hdrlen + hh.payload_len.word);
+                               kfree(buf);
+                               return;
+                       }
+
+                       /* Switch on received message types */
+                       switch (hh.msgid.byte) {
+                       case SIERRA_NET_HIP_LSI_UMTSID:
+                               dev_dbg(&dev->udev->dev, "LSI for ctx:%d",
+                                       hh.msgspecific.byte);
+                               sierra_net_handle_lsi(dev, buf, &hh);
+                               break;
+                       case SIERRA_NET_HIP_RESTART_ID:
+                               dev_dbg(&dev->udev->dev, "Restart reported: %d,"
+                                               " stopping sync timer",
+                                               hh.msgspecific.byte);
+                               /* Got sync resp - stop timer & clear mask */
+                               del_timer_sync(&priv->sync_timer);
+                               clear_bit(SIERRA_NET_TIMER_EXPIRY,
+                                         &priv->kevent_flags);
+                               break;
+                       case SIERRA_NET_HIP_HSYNC_ID:
+                               dev_dbg(&dev->udev->dev, "SYNC received");
+                               err = sierra_net_send_sync(dev);
+                               if (err < 0)
+                                       netdev_err(dev->net,
+                                               "Send SYNC failed %d\n", err);
+                               break;
+                       case SIERRA_NET_HIP_EXTENDEDID:
+                               netdev_err(dev->net, "Unrecognized HIP msg, "
+                                       "extmsgid 0x%04x\n", hh.extmsgid.word);
+                               break;
+                       case SIERRA_NET_HIP_RCGI:
+                               /* Ignored */
+                               break;
+                       default:
+                               netdev_err(dev->net, "Unrecognized HIP msg, "
+                                       "msgid 0x%02x\n", hh.msgid.byte);
+                               break;
+                       }
+               }
+               kfree(buf);
+       }
+       /* The sync timer bit might be set */
+       if (test_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags)) {
+               clear_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags);
+               dev_dbg(&dev->udev->dev, "Deferred sync timer expiry");
+               sierra_net_dosync(priv->usbnet);
+       }
+
+       if (priv->kevent_flags)
+               dev_dbg(&dev->udev->dev, "sierra_net_kevent done, "
+                       "kevent_flags = 0x%lx", priv->kevent_flags);
+}
+
+static void sierra_net_defer_kevent(struct usbnet *dev, int work)
+{
+       struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+       set_bit(work, &priv->kevent_flags);
+       schedule_work(&priv->sierra_net_kevent);
+}
+
+/*
+ * Sync Retransmit Timer Handler. On expiry, kick the work queue
+ */
+void sierra_sync_timer(unsigned long syncdata)
+{
+       struct usbnet *dev = (struct usbnet *)syncdata;
+
+       dev_dbg(&dev->udev->dev, "%s", __func__);
+       /* Kick the tasklet */
+       sierra_net_defer_kevent(dev, SIERRA_NET_TIMER_EXPIRY);
+}
+
+static void sierra_net_status(struct usbnet *dev, struct urb *urb)
+{
+       struct usb_cdc_notification *event;
+
+       dev_dbg(&dev->udev->dev, "%s", __func__);
+
+       if (urb->actual_length < sizeof *event)
+               return;
+
+       /* Add cases to handle other standard notifications. */
+       event = urb->transfer_buffer;
+       switch (event->bNotificationType) {
+       case USB_CDC_NOTIFY_NETWORK_CONNECTION:
+       case USB_CDC_NOTIFY_SPEED_CHANGE:
+               /* USB 305 sends those */
+               break;
+       case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
+               sierra_net_defer_kevent(dev, SIERRA_NET_EVENT_RESP_AVAIL);
+               break;
+       default:
+               netdev_err(dev->net, ": unexpected notification %02x!\n",
+                               event->bNotificationType);
+               break;
+       }
+}
+
+static void sierra_net_get_drvinfo(struct net_device *net,
+               struct ethtool_drvinfo *info)
+{
+       /* Inherit standard device info */
+       usbnet_get_drvinfo(net, info);
+       strncpy(info->driver, driver_name, sizeof info->driver);
+       strncpy(info->version, DRIVER_VERSION, sizeof info->version);
+}
+
+static u32 sierra_net_get_link(struct net_device *net)
+{
+       struct usbnet *dev = netdev_priv(net);
+       /* Report link is down whenever the interface is down */
+       return sierra_net_get_private(dev)->link_up && netif_running(net);
+}
+
+static struct ethtool_ops sierra_net_ethtool_ops = {
+       .get_drvinfo = sierra_net_get_drvinfo,
+       .get_link = sierra_net_get_link,
+       .get_msglevel = usbnet_get_msglevel,
+       .set_msglevel = usbnet_set_msglevel,
+       .get_settings = usbnet_get_settings,
+       .set_settings = usbnet_set_settings,
+       .nway_reset = usbnet_nway_reset,
+};
+
+/* MTU can not be more than 1500 bytes, enforce it. */
+static int sierra_net_change_mtu(struct net_device *net, int new_mtu)
+{
+       if (new_mtu > SIERRA_NET_MAX_SUPPORTED_MTU)
+               return -EINVAL;
+
+       return usbnet_change_mtu(net, new_mtu);
+}
+
+static int is_whitelisted(const u8 ifnum,
+                       const struct sierra_net_iface_info *whitelist)
+{
+       if (whitelist) {
+               const u8 *list = whitelist->ifaceinfo;
+               int i;
+
+               for (i = 0; i < whitelist->infolen; i++) {
+                       if (list[i] == ifnum)
+                               return 1;
+               }
+       }
+       return 0;
+}
+
+static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap)
+{
+       int result = 0;
+       u16 *attrdata;
+
+       attrdata = kmalloc(sizeof(*attrdata), GFP_KERNEL);
+       if (!attrdata)
+               return -ENOMEM;
+
+       result = usb_control_msg(
+                       dev->udev,
+                       usb_rcvctrlpipe(dev->udev, 0),
+                       /* _u8 vendor specific request */
+                       SWI_USB_REQUEST_GET_FW_ATTR,
+                       USB_DIR_IN | USB_TYPE_VENDOR,   /* __u8 request type */
+                       0x0000,         /* __u16 value not used */
+                       0x0000,         /* __u16 index  not used */
+                       attrdata,       /* char *data */
+                       sizeof(*attrdata),              /* __u16 size */
+                       USB_CTRL_SET_TIMEOUT);  /* int timeout */
+
+       if (result < 0) {
+               kfree(attrdata);
+               return -EIO;
+       }
+
+       *datap = *attrdata;
+
+       kfree(attrdata);
+       return result;
+}
+
+/*
+ * collects the bulk endpoints, the status endpoint.
+ */
+static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       u8      ifacenum;
+       u8      numendpoints;
+       u16     fwattr = 0;
+       int     status;
+       struct ethhdr *eth;
+       struct sierra_net_data *priv;
+       static const u8 sync_tmplate[sizeof(priv->sync_msg)] = {
+               0x00, 0x00, SIERRA_NET_HIP_MSYNC_ID, 0x00};
+       static const u8 shdwn_tmplate[sizeof(priv->shdwn_msg)] = {
+               0x00, 0x00, SIERRA_NET_HIP_SHUTD_ID, 0x00};
+
+       struct sierra_net_info_data *data =
+                       (struct sierra_net_info_data *)dev->driver_info->data;
+
+       dev_dbg(&dev->udev->dev, "%s", __func__);
+
+       ifacenum = intf->cur_altsetting->desc.bInterfaceNumber;
+       /* We only accept certain interfaces */
+       if (!is_whitelisted(ifacenum, &data->whitelist)) {
+               dev_dbg(&dev->udev->dev, "Ignoring interface: %d", ifacenum);
+               return -ENODEV;
+       }
+       numendpoints = intf->cur_altsetting->desc.bNumEndpoints;
+       /* We have three endpoints, bulk in and out, and a status */
+       if (numendpoints != 3) {
+               dev_err(&dev->udev->dev, "Expected 3 endpoints, found: %d",
+                       numendpoints);
+               return -ENODEV;
+       }
+       /* Status endpoint set in usbnet_get_endpoints() */
+       dev->status = NULL;
+       status = usbnet_get_endpoints(dev, intf);
+       if (status < 0) {
+               dev_err(&dev->udev->dev, "Error in usbnet_get_endpoints (%d)",
+                       status);
+               return -ENODEV;
+       }
+       /* Initialize sierra private data */
+       priv = kzalloc(sizeof *priv, GFP_KERNEL);
+       if (!priv) {
+               dev_err(&dev->udev->dev, "No memory");
+               return -ENOMEM;
+       }
+
+       priv->usbnet = dev;
+       priv->ifnum = ifacenum;
+       dev->net->netdev_ops = &sierra_net_device_ops;
+
+       /* change MAC addr to include, ifacenum, and to be unique */
+       dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return(&iface_counter);
+       dev->net->dev_addr[ETH_ALEN-1] = ifacenum;
+
+       /* we will have to manufacture ethernet headers, prepare template */
+       eth = (struct ethhdr *)priv->ethr_hdr_tmpl;
+       memcpy(&eth->h_dest, dev->net->dev_addr, ETH_ALEN);
+       eth->h_proto = cpu_to_be16(ETH_P_IP);
+
+       /* prepare shutdown message template */
+       memcpy(priv->shdwn_msg, shdwn_tmplate, sizeof(priv->shdwn_msg));
+       /* set context index initially to 0 - prepares tx hdr template */
+       sierra_net_set_ctx_index(priv, 0);
+
+       /* decrease the rx_urb_size and max_tx_size to 4k on USB 1.1 */
+       dev->rx_urb_size  = data->rx_urb_size;
+       if (dev->udev->speed != USB_SPEED_HIGH)
+               dev->rx_urb_size  = min_t(size_t, 4096, data->rx_urb_size);
+
+       dev->net->hard_header_len += SIERRA_NET_HIP_EXT_HDR_LEN;
+       dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
+
+       /* Set up the netdev */
+       dev->net->flags |= IFF_NOARP;
+       dev->net->ethtool_ops = &sierra_net_ethtool_ops;
+       netif_carrier_off(dev->net);
+
+       sierra_net_set_private(dev, priv);
+
+       priv->kevent_flags = 0;
+
+       /* Use the shared workqueue */
+       INIT_WORK(&priv->sierra_net_kevent, sierra_net_kevent);
+
+       /* Only need to do this once */
+       init_timer(&priv->sync_timer);
+
+       /* verify fw attributes */
+       status = sierra_net_get_fw_attr(dev, &fwattr);
+       dev_dbg(&dev->udev->dev, "Fw attr: %x\n", fwattr);
+
+       /* test whether firmware supports DHCP */
+       if (!(status == sizeof(fwattr) && (fwattr & SWI_GET_FW_ATTR_MASK))) {
+               /* found incompatible firmware version */
+               dev_err(&dev->udev->dev, "Incompatible driver and firmware"
+                       " versions\n");
+               kfree(priv);
+               return -ENODEV;
+       }
+       /* prepare sync message from template */
+       memcpy(priv->sync_msg, sync_tmplate, sizeof(priv->sync_msg));
+
+       /* initiate the sync sequence */
+       sierra_net_dosync(dev);
+
+       return 0;
+}
+
+static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+       int status;
+       struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+       dev_dbg(&dev->udev->dev, "%s", __func__);
+
+       /* Kill the timer then flush the work queue */
+       del_timer_sync(&priv->sync_timer);
+
+       flush_scheduled_work();
+
+       /* tell modem we are going away */
+       status = sierra_net_send_cmd(dev, priv->shdwn_msg,
+                       sizeof(priv->shdwn_msg), "Shutdown");
+       if (status < 0)
+               netdev_err(dev->net,
+                       "usb_control_msg failed, status %d\n", status);
+
+       sierra_net_set_private(dev, NULL);
+
+       kfree(priv);
+}
+
+static struct sk_buff *sierra_net_skb_clone(struct usbnet *dev,
+               struct sk_buff *skb, int len)
+{
+       struct sk_buff *new_skb;
+
+       /* clone skb */
+       new_skb = skb_clone(skb, GFP_ATOMIC);
+
+       /* remove len bytes from original */
+       skb_pull(skb, len);
+
+       /* trim next packet to it's length */
+       if (new_skb) {
+               skb_trim(new_skb, len);
+       } else {
+               if (netif_msg_rx_err(dev))
+                       netdev_err(dev->net, "failed to get skb\n");
+               dev->net->stats.rx_dropped++;
+       }
+
+       return new_skb;
+}
+
+/* ---------------------------- Receive data path ----------------------*/
+static int sierra_net_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+       int err;
+       struct hip_hdr  hh;
+       struct sk_buff *new_skb;
+
+       dev_dbg(&dev->udev->dev, "%s", __func__);
+
+       /* could contain multiple packets */
+       while (likely(skb->len)) {
+               err = parse_hip(skb->data, skb->len, &hh);
+               if (err) {
+                       if (netif_msg_rx_err(dev))
+                               netdev_err(dev->net, "Invalid HIP header %d\n",
+                                       err);
+                       /* dev->net->stats.rx_errors incremented by caller */
+                       dev->net->stats.rx_length_errors++;
+                       return 0;
+               }
+
+               /* Validate Extended HIP header */
+               if (!hh.extmsgid.is_present
+                   || hh.extmsgid.word != SIERRA_NET_HIP_EXT_IP_IN_ID) {
+                       if (netif_msg_rx_err(dev))
+                               netdev_err(dev->net, "HIP/ETH: Invalid pkt\n");
+
+                       dev->net->stats.rx_frame_errors++;
+                       /* dev->net->stats.rx_errors incremented by caller */;
+                       return 0;
+               }
+
+               skb_pull(skb, hh.hdrlen);
+
+               /* We are going to accept this packet, prepare it */
+               memcpy(skb->data, sierra_net_get_private(dev)->ethr_hdr_tmpl,
+                       ETH_HLEN);
+
+               /* Last packet in batch handled by usbnet */
+               if (hh.payload_len.word == skb->len)
+                       return 1;
+
+               new_skb = sierra_net_skb_clone(dev, skb, hh.payload_len.word);
+               if (new_skb)
+                       usbnet_skb_return(dev, new_skb);
+
+       } /* while */
+
+       return 0;
+}
+
+/* ---------------------------- Transmit data path ----------------------*/
+struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+               gfp_t flags)
+{
+       struct sierra_net_data *priv = sierra_net_get_private(dev);
+       u16 len;
+       bool need_tail;
+
+       dev_dbg(&dev->udev->dev, "%s", __func__);
+       if (priv->link_up && check_ethip_packet(skb, dev) && is_ip(skb)) {
+               /* enough head room as is? */
+               if (SIERRA_NET_HIP_EXT_HDR_LEN <= skb_headroom(skb)) {
+                       /* Save the Eth/IP length and set up HIP hdr */
+                       len = skb->len;
+                       skb_push(skb, SIERRA_NET_HIP_EXT_HDR_LEN);
+                       /* Handle ZLP issue */
+                       need_tail = ((len + SIERRA_NET_HIP_EXT_HDR_LEN)
+                               % dev->maxpacket == 0);
+                       if (need_tail) {
+                               if (unlikely(skb_tailroom(skb) == 0)) {
+                                       netdev_err(dev->net, "tx_fixup:"
+                                               "no room for packet\n");
+                                       dev_kfree_skb_any(skb);
+                                       return NULL;
+                               } else {
+                                       skb->data[skb->len] = 0;
+                                       __skb_put(skb, 1);
+                                       len = len + 1;
+                               }
+                       }
+                       build_hip(skb->data, len, priv);
+                       return skb;
+               } else {
+                       /*
+                        * compensate in the future if necessary
+                        */
+                       netdev_err(dev->net, "tx_fixup: no room for HIP\n");
+               } /* headroom */
+       }
+
+       if (!priv->link_up)
+               dev->net->stats.tx_carrier_errors++;
+
+       /* tx_dropped incremented by usbnet */
+
+       /* filter the packet out, release it  */
+       dev_kfree_skb_any(skb);
+       return NULL;
+}
+
+static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 };
+static const struct sierra_net_info_data sierra_net_info_data_68A3 = {
+       .rx_urb_size = 8 * 1024,
+       .whitelist = {
+               .infolen = ARRAY_SIZE(sierra_net_ifnum_list),
+               .ifaceinfo = sierra_net_ifnum_list
+       }
+};
+
+static const struct driver_info sierra_net_info_68A3 = {
+       .description = "Sierra Wireless USB-to-WWAN Modem",
+       .flags = FLAG_WWAN | FLAG_SEND_ZLP,
+       .bind = sierra_net_bind,
+       .unbind = sierra_net_unbind,
+       .status = sierra_net_status,
+       .rx_fixup = sierra_net_rx_fixup,
+       .tx_fixup = sierra_net_tx_fixup,
+       .data = (unsigned long)&sierra_net_info_data_68A3,
+};
+
+static const struct usb_device_id products[] = {
+       {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */
+       .driver_info = (unsigned long) &sierra_net_info_68A3},
+
+       {}, /* last item */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+/* We are based on usbnet, so let it handle the USB driver specifics */
+static struct usb_driver sierra_net_driver = {
+       .name = "sierra_net",
+       .id_table = products,
+       .probe = usbnet_probe,
+       .disconnect = usbnet_disconnect,
+       .suspend = usbnet_suspend,
+       .resume = usbnet_resume,
+       .no_dynamic_id = 1,
+};
+
+static int __init sierra_net_init(void)
+{
+       BUILD_BUG_ON(FIELD_SIZEOF(struct usbnet, data)
+                               < sizeof(struct cdc_state));
+
+       return usb_register(&sierra_net_driver);
+}
+
+static void __exit sierra_net_exit(void)
+{
+       usb_deregister(&sierra_net_driver);
+}
+
+module_exit(sierra_net_exit);
+module_init(sierra_net_init);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
new file mode 100644 (file)
index 0000000..35b98b1
--- /dev/null
@@ -0,0 +1,1289 @@
+ /***************************************************************************
+ *
+ * Copyright (C) 2007-2010 SMSC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/kmod.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+#include <linux/usb/usbnet.h>
+#include <linux/slab.h>
+#include "smsc75xx.h"
+
+#define SMSC_CHIPNAME                  "smsc75xx"
+#define SMSC_DRIVER_VERSION            "1.0.0"
+#define HS_USB_PKT_SIZE                        (512)
+#define FS_USB_PKT_SIZE                        (64)
+#define DEFAULT_HS_BURST_CAP_SIZE      (16 * 1024 + 5 * HS_USB_PKT_SIZE)
+#define DEFAULT_FS_BURST_CAP_SIZE      (6 * 1024 + 33 * FS_USB_PKT_SIZE)
+#define DEFAULT_BULK_IN_DELAY          (0x00002000)
+#define MAX_SINGLE_PACKET_SIZE         (9000)
+#define LAN75XX_EEPROM_MAGIC           (0x7500)
+#define EEPROM_MAC_OFFSET              (0x01)
+#define DEFAULT_TX_CSUM_ENABLE         (true)
+#define DEFAULT_RX_CSUM_ENABLE         (true)
+#define DEFAULT_TSO_ENABLE             (true)
+#define SMSC75XX_INTERNAL_PHY_ID       (1)
+#define SMSC75XX_TX_OVERHEAD           (8)
+#define MAX_RX_FIFO_SIZE               (20 * 1024)
+#define MAX_TX_FIFO_SIZE               (12 * 1024)
+#define USB_VENDOR_ID_SMSC             (0x0424)
+#define USB_PRODUCT_ID_LAN7500         (0x7500)
+#define USB_PRODUCT_ID_LAN7505         (0x7505)
+
+#define check_warn(ret, fmt, args...) \
+       ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); })
+
+#define check_warn_return(ret, fmt, args...) \
+       ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); return ret; } })
+
+#define check_warn_goto_done(ret, fmt, args...) \
+       ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); goto done; } })
+
+struct smsc75xx_priv {
+       struct usbnet *dev;
+       u32 rfe_ctl;
+       u32 multicast_hash_table[DP_SEL_VHF_HASH_LEN];
+       bool use_rx_csum;
+       struct mutex dataport_mutex;
+       spinlock_t rfe_ctl_lock;
+       struct work_struct set_multicast;
+};
+
+struct usb_context {
+       struct usb_ctrlrequest req;
+       struct usbnet *dev;
+};
+
+static int turbo_mode = true;
+module_param(turbo_mode, bool, 0644);
+MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
+
+static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index,
+                                         u32 *data)
+{
+       u32 *buf = kmalloc(4, GFP_KERNEL);
+       int ret;
+
+       BUG_ON(!dev);
+
+       if (!buf)
+               return -ENOMEM;
+
+       ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
+               USB_VENDOR_REQUEST_READ_REGISTER,
+               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+               00, index, buf, 4, USB_CTRL_GET_TIMEOUT);
+
+       if (unlikely(ret < 0))
+               netdev_warn(dev->net,
+                       "Failed to read register index 0x%08x", index);
+
+       le32_to_cpus(buf);
+       *data = *buf;
+       kfree(buf);
+
+       return ret;
+}
+
+static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index,
+                                          u32 data)
+{
+       u32 *buf = kmalloc(4, GFP_KERNEL);
+       int ret;
+
+       BUG_ON(!dev);
+
+       if (!buf)
+               return -ENOMEM;
+
+       *buf = data;
+       cpu_to_le32s(buf);
+
+       ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+               USB_VENDOR_REQUEST_WRITE_REGISTER,
+               USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+               00, index, buf, 4, USB_CTRL_SET_TIMEOUT);
+
+       if (unlikely(ret < 0))
+               netdev_warn(dev->net,
+                       "Failed to write register index 0x%08x", index);
+
+       kfree(buf);
+
+       return ret;
+}
+
+/* Loop until the read is completed with timeout
+ * called with phy_mutex held */
+static int smsc75xx_phy_wait_not_busy(struct usbnet *dev)
+{
+       unsigned long start_time = jiffies;
+       u32 val;
+       int ret;
+
+       do {
+               ret = smsc75xx_read_reg(dev, MII_ACCESS, &val);
+               check_warn_return(ret, "Error reading MII_ACCESS");
+
+               if (!(val & MII_ACCESS_BUSY))
+                       return 0;
+       } while (!time_after(jiffies, start_time + HZ));
+
+       return -EIO;
+}
+
+static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       u32 val, addr;
+       int ret;
+
+       mutex_lock(&dev->phy_mutex);
+
+       /* confirm MII not busy */
+       ret = smsc75xx_phy_wait_not_busy(dev);
+       check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_read");
+
+       /* set the address, index & direction (read from PHY) */
+       phy_id &= dev->mii.phy_id_mask;
+       idx &= dev->mii.reg_num_mask;
+       addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
+               | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
+               | MII_ACCESS_READ;
+       ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
+       check_warn_goto_done(ret, "Error writing MII_ACCESS");
+
+       ret = smsc75xx_phy_wait_not_busy(dev);
+       check_warn_goto_done(ret, "Timed out reading MII reg %02X", idx);
+
+       ret = smsc75xx_read_reg(dev, MII_DATA, &val);
+       check_warn_goto_done(ret, "Error reading MII_DATA");
+
+       ret = (u16)(val & 0xFFFF);
+
+done:
+       mutex_unlock(&dev->phy_mutex);
+       return ret;
+}
+
+static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx,
+                               int regval)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       u32 val, addr;
+       int ret;
+
+       mutex_lock(&dev->phy_mutex);
+
+       /* confirm MII not busy */
+       ret = smsc75xx_phy_wait_not_busy(dev);
+       check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_write");
+
+       val = regval;
+       ret = smsc75xx_write_reg(dev, MII_DATA, val);
+       check_warn_goto_done(ret, "Error writing MII_DATA");
+
+       /* set the address, index & direction (write to PHY) */
+       phy_id &= dev->mii.phy_id_mask;
+       idx &= dev->mii.reg_num_mask;
+       addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
+               | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
+               | MII_ACCESS_WRITE;
+       ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
+       check_warn_goto_done(ret, "Error writing MII_ACCESS");
+
+       ret = smsc75xx_phy_wait_not_busy(dev);
+       check_warn_goto_done(ret, "Timed out writing MII reg %02X", idx);
+
+done:
+       mutex_unlock(&dev->phy_mutex);
+}
+
+static int smsc75xx_wait_eeprom(struct usbnet *dev)
+{
+       unsigned long start_time = jiffies;
+       u32 val;
+       int ret;
+
+       do {
+               ret = smsc75xx_read_reg(dev, E2P_CMD, &val);
+               check_warn_return(ret, "Error reading E2P_CMD");
+
+               if (!(val & E2P_CMD_BUSY) || (val & E2P_CMD_TIMEOUT))
+                       break;
+               udelay(40);
+       } while (!time_after(jiffies, start_time + HZ));
+
+       if (val & (E2P_CMD_TIMEOUT | E2P_CMD_BUSY)) {
+               netdev_warn(dev->net, "EEPROM read operation timeout");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int smsc75xx_eeprom_confirm_not_busy(struct usbnet *dev)
+{
+       unsigned long start_time = jiffies;
+       u32 val;
+       int ret;
+
+       do {
+               ret = smsc75xx_read_reg(dev, E2P_CMD, &val);
+               check_warn_return(ret, "Error reading E2P_CMD");
+
+               if (!(val & E2P_CMD_BUSY))
+                       return 0;
+
+               udelay(40);
+       } while (!time_after(jiffies, start_time + HZ));
+
+       netdev_warn(dev->net, "EEPROM is busy");
+       return -EIO;
+}
+
+static int smsc75xx_read_eeprom(struct usbnet *dev, u32 offset, u32 length,
+                               u8 *data)
+{
+       u32 val;
+       int i, ret;
+
+       BUG_ON(!dev);
+       BUG_ON(!data);
+
+       ret = smsc75xx_eeprom_confirm_not_busy(dev);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < length; i++) {
+               val = E2P_CMD_BUSY | E2P_CMD_READ | (offset & E2P_CMD_ADDR);
+               ret = smsc75xx_write_reg(dev, E2P_CMD, val);
+               check_warn_return(ret, "Error writing E2P_CMD");
+
+               ret = smsc75xx_wait_eeprom(dev);
+               if (ret < 0)
+                       return ret;
+
+               ret = smsc75xx_read_reg(dev, E2P_DATA, &val);
+               check_warn_return(ret, "Error reading E2P_DATA");
+
+               data[i] = val & 0xFF;
+               offset++;
+       }
+
+       return 0;
+}
+
+static int smsc75xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length,
+                                u8 *data)
+{
+       u32 val;
+       int i, ret;
+
+       BUG_ON(!dev);
+       BUG_ON(!data);
+
+       ret = smsc75xx_eeprom_confirm_not_busy(dev);
+       if (ret)
+               return ret;
+
+       /* Issue write/erase enable command */
+       val = E2P_CMD_BUSY | E2P_CMD_EWEN;
+       ret = smsc75xx_write_reg(dev, E2P_CMD, val);
+       check_warn_return(ret, "Error writing E2P_CMD");
+
+       ret = smsc75xx_wait_eeprom(dev);
+       if (ret < 0)
+               return ret;
+
+       for (i = 0; i < length; i++) {
+
+               /* Fill data register */
+               val = data[i];
+               ret = smsc75xx_write_reg(dev, E2P_DATA, val);
+               check_warn_return(ret, "Error writing E2P_DATA");
+
+               /* Send "write" command */
+               val = E2P_CMD_BUSY | E2P_CMD_WRITE | (offset & E2P_CMD_ADDR);
+               ret = smsc75xx_write_reg(dev, E2P_CMD, val);
+               check_warn_return(ret, "Error writing E2P_CMD");
+
+               ret = smsc75xx_wait_eeprom(dev);
+               if (ret < 0)
+                       return ret;
+
+               offset++;
+       }
+
+       return 0;
+}
+
+static int smsc75xx_dataport_wait_not_busy(struct usbnet *dev)
+{
+       int i, ret;
+
+       for (i = 0; i < 100; i++) {
+               u32 dp_sel;
+               ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel);
+               check_warn_return(ret, "Error reading DP_SEL");
+
+               if (dp_sel & DP_SEL_DPRDY)
+                       return 0;
+
+               udelay(40);
+       }
+
+       netdev_warn(dev->net, "smsc75xx_dataport_wait_not_busy timed out");
+
+       return -EIO;
+}
+
+static int smsc75xx_dataport_write(struct usbnet *dev, u32 ram_select, u32 addr,
+                                  u32 length, u32 *buf)
+{
+       struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+       u32 dp_sel;
+       int i, ret;
+
+       mutex_lock(&pdata->dataport_mutex);
+
+       ret = smsc75xx_dataport_wait_not_busy(dev);
+       check_warn_goto_done(ret, "smsc75xx_dataport_write busy on entry");
+
+       ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel);
+       check_warn_goto_done(ret, "Error reading DP_SEL");
+
+       dp_sel &= ~DP_SEL_RSEL;
+       dp_sel |= ram_select;
+       ret = smsc75xx_write_reg(dev, DP_SEL, dp_sel);
+       check_warn_goto_done(ret, "Error writing DP_SEL");
+
+       for (i = 0; i < length; i++) {
+               ret = smsc75xx_write_reg(dev, DP_ADDR, addr + i);
+               check_warn_goto_done(ret, "Error writing DP_ADDR");
+
+               ret = smsc75xx_write_reg(dev, DP_DATA, buf[i]);
+               check_warn_goto_done(ret, "Error writing DP_DATA");
+
+               ret = smsc75xx_write_reg(dev, DP_CMD, DP_CMD_WRITE);
+               check_warn_goto_done(ret, "Error writing DP_CMD");
+
+               ret = smsc75xx_dataport_wait_not_busy(dev);
+               check_warn_goto_done(ret, "smsc75xx_dataport_write timeout");
+       }
+
+done:
+       mutex_unlock(&pdata->dataport_mutex);
+       return ret;
+}
+
+/* returns hash bit number for given MAC address */
+static u32 smsc75xx_hash(char addr[ETH_ALEN])
+{
+       return (ether_crc(ETH_ALEN, addr) >> 23) & 0x1ff;
+}
+
+static void smsc75xx_deferred_multicast_write(struct work_struct *param)
+{
+       struct smsc75xx_priv *pdata =
+               container_of(param, struct smsc75xx_priv, set_multicast);
+       struct usbnet *dev = pdata->dev;
+       int ret;
+
+       netif_dbg(dev, drv, dev->net, "deferred multicast write 0x%08x",
+               pdata->rfe_ctl);
+
+       smsc75xx_dataport_write(dev, DP_SEL_VHF, DP_SEL_VHF_VLAN_LEN,
+               DP_SEL_VHF_HASH_LEN, pdata->multicast_hash_table);
+
+       ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+       check_warn(ret, "Error writing RFE_CRL");
+}
+
+static void smsc75xx_set_multicast(struct net_device *netdev)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+       unsigned long flags;
+       int i;
+
+       spin_lock_irqsave(&pdata->rfe_ctl_lock, flags);
+
+       pdata->rfe_ctl &=
+               ~(RFE_CTL_AU | RFE_CTL_AM | RFE_CTL_DPF | RFE_CTL_MHF);
+       pdata->rfe_ctl |= RFE_CTL_AB;
+
+       for (i = 0; i < DP_SEL_VHF_HASH_LEN; i++)
+               pdata->multicast_hash_table[i] = 0;
+
+       if (dev->net->flags & IFF_PROMISC) {
+               netif_dbg(dev, drv, dev->net, "promiscuous mode enabled");
+               pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_AU;
+       } else if (dev->net->flags & IFF_ALLMULTI) {
+               netif_dbg(dev, drv, dev->net, "receive all multicast enabled");
+               pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_DPF;
+       } else if (!netdev_mc_empty(dev->net)) {
+               struct dev_mc_list *mc_list;
+
+               netif_dbg(dev, drv, dev->net, "receive multicast hash filter");
+
+               pdata->rfe_ctl |= RFE_CTL_MHF | RFE_CTL_DPF;
+
+               netdev_for_each_mc_addr(mc_list, netdev) {
+                       u32 bitnum = smsc75xx_hash(mc_list->dmi_addr);
+                       pdata->multicast_hash_table[bitnum / 32] |=
+                               (1 << (bitnum % 32));
+               }
+       } else {
+               netif_dbg(dev, drv, dev->net, "receive own packets only");
+               pdata->rfe_ctl |= RFE_CTL_DPF;
+       }
+
+       spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags);
+
+       /* defer register writes to a sleepable context */
+       schedule_work(&pdata->set_multicast);
+}
+
+static int smsc75xx_update_flowcontrol(struct usbnet *dev, u8 duplex,
+                                           u16 lcladv, u16 rmtadv)
+{
+       u32 flow = 0, fct_flow = 0;
+       int ret;
+
+       if (duplex == DUPLEX_FULL) {
+               u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv);
+
+               if (cap & FLOW_CTRL_TX) {
+                       flow = (FLOW_TX_FCEN | 0xFFFF);
+                       /* set fct_flow thresholds to 20% and 80% */
+                       fct_flow = (8 << 8) | 32;
+               }
+
+               if (cap & FLOW_CTRL_RX)
+                       flow |= FLOW_RX_FCEN;
+
+               netif_dbg(dev, link, dev->net, "rx pause %s, tx pause %s",
+                       (cap & FLOW_CTRL_RX ? "enabled" : "disabled"),
+                       (cap & FLOW_CTRL_TX ? "enabled" : "disabled"));
+       } else {
+               netif_dbg(dev, link, dev->net, "half duplex");
+       }
+
+       ret = smsc75xx_write_reg(dev, FLOW, flow);
+       check_warn_return(ret, "Error writing FLOW");
+
+       ret = smsc75xx_write_reg(dev, FCT_FLOW, fct_flow);
+       check_warn_return(ret, "Error writing FCT_FLOW");
+
+       return 0;
+}
+
+static int smsc75xx_link_reset(struct usbnet *dev)
+{
+       struct mii_if_info *mii = &dev->mii;
+       struct ethtool_cmd ecmd;
+       u16 lcladv, rmtadv;
+       int ret;
+
+       /* clear interrupt status */
+       ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC);
+       check_warn_return(ret, "Error reading PHY_INT_SRC");
+
+       ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
+       check_warn_return(ret, "Error writing INT_STS");
+
+       mii_check_media(mii, 1, 1);
+       mii_ethtool_gset(&dev->mii, &ecmd);
+       lcladv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE);
+       rmtadv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_LPA);
+
+       netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x"
+               " rmtadv: %04x", ecmd.speed, ecmd.duplex, lcladv, rmtadv);
+
+       return smsc75xx_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv);
+}
+
+static void smsc75xx_status(struct usbnet *dev, struct urb *urb)
+{
+       u32 intdata;
+
+       if (urb->actual_length != 4) {
+               netdev_warn(dev->net,
+                       "unexpected urb length %d", urb->actual_length);
+               return;
+       }
+
+       memcpy(&intdata, urb->transfer_buffer, 4);
+       le32_to_cpus(&intdata);
+
+       netif_dbg(dev, link, dev->net, "intdata: 0x%08X", intdata);
+
+       if (intdata & INT_ENP_PHY_INT)
+               usbnet_defer_kevent(dev, EVENT_LINK_RESET);
+       else
+               netdev_warn(dev->net,
+                       "unexpected interrupt, intdata=0x%08X", intdata);
+}
+
+/* Enable or disable Rx checksum offload engine */
+static int smsc75xx_set_rx_csum_offload(struct usbnet *dev)
+{
+       struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&pdata->rfe_ctl_lock, flags);
+
+       if (pdata->use_rx_csum)
+               pdata->rfe_ctl |= RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM;
+       else
+               pdata->rfe_ctl &= ~(RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM);
+
+       spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags);
+
+       ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+       check_warn_return(ret, "Error writing RFE_CTL");
+
+       return 0;
+}
+
+static int smsc75xx_ethtool_get_eeprom_len(struct net_device *net)
+{
+       return MAX_EEPROM_SIZE;
+}
+
+static int smsc75xx_ethtool_get_eeprom(struct net_device *netdev,
+                                      struct ethtool_eeprom *ee, u8 *data)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+
+       ee->magic = LAN75XX_EEPROM_MAGIC;
+
+       return smsc75xx_read_eeprom(dev, ee->offset, ee->len, data);
+}
+
+static int smsc75xx_ethtool_set_eeprom(struct net_device *netdev,
+                                      struct ethtool_eeprom *ee, u8 *data)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+
+       if (ee->magic != LAN75XX_EEPROM_MAGIC) {
+               netdev_warn(dev->net,
+                       "EEPROM: magic value mismatch: 0x%x", ee->magic);
+               return -EINVAL;
+       }
+
+       return smsc75xx_write_eeprom(dev, ee->offset, ee->len, data);
+}
+
+static u32 smsc75xx_ethtool_get_rx_csum(struct net_device *netdev)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+
+       return pdata->use_rx_csum;
+}
+
+static int smsc75xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+
+       pdata->use_rx_csum = !!val;
+
+       return smsc75xx_set_rx_csum_offload(dev);
+}
+
+static int smsc75xx_ethtool_set_tso(struct net_device *netdev, u32 data)
+{
+       if (data)
+               netdev->features |= NETIF_F_TSO | NETIF_F_TSO6;
+       else
+               netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+
+       return 0;
+}
+
+static const struct ethtool_ops smsc75xx_ethtool_ops = {
+       .get_link       = usbnet_get_link,
+       .nway_reset     = usbnet_nway_reset,
+       .get_drvinfo    = usbnet_get_drvinfo,
+       .get_msglevel   = usbnet_get_msglevel,
+       .set_msglevel   = usbnet_set_msglevel,
+       .get_settings   = usbnet_get_settings,
+       .set_settings   = usbnet_set_settings,
+       .get_eeprom_len = smsc75xx_ethtool_get_eeprom_len,
+       .get_eeprom     = smsc75xx_ethtool_get_eeprom,
+       .set_eeprom     = smsc75xx_ethtool_set_eeprom,
+       .get_tx_csum    = ethtool_op_get_tx_csum,
+       .set_tx_csum    = ethtool_op_set_tx_hw_csum,
+       .get_rx_csum    = smsc75xx_ethtool_get_rx_csum,
+       .set_rx_csum    = smsc75xx_ethtool_set_rx_csum,
+       .get_tso        = ethtool_op_get_tso,
+       .set_tso        = smsc75xx_ethtool_set_tso,
+};
+
+static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+
+       if (!netif_running(netdev))
+               return -EINVAL;
+
+       return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
+}
+
+static void smsc75xx_init_mac_address(struct usbnet *dev)
+{
+       /* try reading mac address from EEPROM */
+       if (smsc75xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN,
+                       dev->net->dev_addr) == 0) {
+               if (is_valid_ether_addr(dev->net->dev_addr)) {
+                       /* eeprom values are valid so use them */
+                       netif_dbg(dev, ifup, dev->net,
+                               "MAC address read from EEPROM");
+                       return;
+               }
+       }
+
+       /* no eeprom, or eeprom values are invalid. generate random MAC */
+       random_ether_addr(dev->net->dev_addr);
+       netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr");
+}
+
+static int smsc75xx_set_mac_address(struct usbnet *dev)
+{
+       u32 addr_lo = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 |
+               dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24;
+       u32 addr_hi = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8;
+
+       int ret = smsc75xx_write_reg(dev, RX_ADDRH, addr_hi);
+       check_warn_return(ret, "Failed to write RX_ADDRH: %d", ret);
+
+       ret = smsc75xx_write_reg(dev, RX_ADDRL, addr_lo);
+       check_warn_return(ret, "Failed to write RX_ADDRL: %d", ret);
+
+       addr_hi |= ADDR_FILTX_FB_VALID;
+       ret = smsc75xx_write_reg(dev, ADDR_FILTX, addr_hi);
+       check_warn_return(ret, "Failed to write ADDR_FILTX: %d", ret);
+
+       ret = smsc75xx_write_reg(dev, ADDR_FILTX + 4, addr_lo);
+       check_warn_return(ret, "Failed to write ADDR_FILTX+4: %d", ret);
+
+       return 0;
+}
+
+static int smsc75xx_phy_initialize(struct usbnet *dev)
+{
+       int bmcr, timeout = 0;
+
+       /* Initialize MII structure */
+       dev->mii.dev = dev->net;
+       dev->mii.mdio_read = smsc75xx_mdio_read;
+       dev->mii.mdio_write = smsc75xx_mdio_write;
+       dev->mii.phy_id_mask = 0x1f;
+       dev->mii.reg_num_mask = 0x1f;
+       dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID;
+
+       /* reset phy and wait for reset to complete */
+       smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
+
+       do {
+               msleep(10);
+               bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
+               check_warn_return(bmcr, "Error reading MII_BMCR");
+               timeout++;
+       } while ((bmcr & MII_BMCR) && (timeout < 100));
+
+       if (timeout >= 100) {
+               netdev_warn(dev->net, "timeout on PHY Reset");
+               return -EIO;
+       }
+
+       smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
+               ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
+               ADVERTISE_PAUSE_ASYM);
+
+       /* read to clear */
+       smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
+       check_warn_return(bmcr, "Error reading PHY_INT_SRC");
+
+       smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK,
+               PHY_INT_MASK_DEFAULT);
+       mii_nway_restart(&dev->mii);
+
+       netif_dbg(dev, ifup, dev->net, "phy initialised successfully");
+       return 0;
+}
+
+static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size)
+{
+       int ret = 0;
+       u32 buf;
+       bool rxenabled;
+
+       ret = smsc75xx_read_reg(dev, MAC_RX, &buf);
+       check_warn_return(ret, "Failed to read MAC_RX: %d", ret);
+
+       rxenabled = ((buf & MAC_RX_RXEN) != 0);
+
+       if (rxenabled) {
+               buf &= ~MAC_RX_RXEN;
+               ret = smsc75xx_write_reg(dev, MAC_RX, buf);
+               check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
+       }
+
+       /* add 4 to size for FCS */
+       buf &= ~MAC_RX_MAX_SIZE;
+       buf |= (((size + 4) << MAC_RX_MAX_SIZE_SHIFT) & MAC_RX_MAX_SIZE);
+
+       ret = smsc75xx_write_reg(dev, MAC_RX, buf);
+       check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
+
+       if (rxenabled) {
+               buf |= MAC_RX_RXEN;
+               ret = smsc75xx_write_reg(dev, MAC_RX, buf);
+               check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
+       }
+
+       return 0;
+}
+
+static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+
+       int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu);
+       check_warn_return(ret, "Failed to set mac rx frame length");
+
+       return usbnet_change_mtu(netdev, new_mtu);
+}
+
+static int smsc75xx_reset(struct usbnet *dev)
+{
+       struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+       u32 buf;
+       int ret = 0, timeout;
+
+       netif_dbg(dev, ifup, dev->net, "entering smsc75xx_reset");
+
+       ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+       check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+       buf |= HW_CFG_LRST;
+
+       ret = smsc75xx_write_reg(dev, HW_CFG, buf);
+       check_warn_return(ret, "Failed to write HW_CFG: %d", ret);
+
+       timeout = 0;
+       do {
+               msleep(10);
+               ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+               check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+               timeout++;
+       } while ((buf & HW_CFG_LRST) && (timeout < 100));
+
+       if (timeout >= 100) {
+               netdev_warn(dev->net, "timeout on completion of Lite Reset");
+               return -EIO;
+       }
+
+       netif_dbg(dev, ifup, dev->net, "Lite reset complete, resetting PHY");
+
+       ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
+       check_warn_return(ret, "Failed to read PMT_CTL: %d", ret);
+
+       buf |= PMT_CTL_PHY_RST;
+
+       ret = smsc75xx_write_reg(dev, PMT_CTL, buf);
+       check_warn_return(ret, "Failed to write PMT_CTL: %d", ret);
+
+       timeout = 0;
+       do {
+               msleep(10);
+               ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
+               check_warn_return(ret, "Failed to read PMT_CTL: %d", ret);
+               timeout++;
+       } while ((buf & PMT_CTL_PHY_RST) && (timeout < 100));
+
+       if (timeout >= 100) {
+               netdev_warn(dev->net, "timeout waiting for PHY Reset");
+               return -EIO;
+       }
+
+       netif_dbg(dev, ifup, dev->net, "PHY reset complete");
+
+       smsc75xx_init_mac_address(dev);
+
+       ret = smsc75xx_set_mac_address(dev);
+       check_warn_return(ret, "Failed to set mac address");
+
+       netif_dbg(dev, ifup, dev->net, "MAC Address: %pM", dev->net->dev_addr);
+
+       ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+       check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG : 0x%08x", buf);
+
+       buf |= HW_CFG_BIR;
+
+       ret = smsc75xx_write_reg(dev, HW_CFG, buf);
+       check_warn_return(ret, "Failed to write HW_CFG: %d", ret);
+
+       ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+       check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG after "
+                       "writing HW_CFG_BIR: 0x%08x", buf);
+
+       if (!turbo_mode) {
+               buf = 0;
+               dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE;
+       } else if (dev->udev->speed == USB_SPEED_HIGH) {
+               buf = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
+               dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE;
+       } else {
+               buf = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE;
+               dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE;
+       }
+
+       netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld",
+               (ulong)dev->rx_urb_size);
+
+       ret = smsc75xx_write_reg(dev, BURST_CAP, buf);
+       check_warn_return(ret, "Failed to write BURST_CAP: %d", ret);
+
+       ret = smsc75xx_read_reg(dev, BURST_CAP, &buf);
+       check_warn_return(ret, "Failed to read BURST_CAP: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net,
+               "Read Value from BURST_CAP after writing: 0x%08x", buf);
+
+       ret = smsc75xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY);
+       check_warn_return(ret, "Failed to write BULK_IN_DLY: %d", ret);
+
+       ret = smsc75xx_read_reg(dev, BULK_IN_DLY, &buf);
+       check_warn_return(ret, "Failed to read BULK_IN_DLY: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net,
+               "Read Value from BULK_IN_DLY after writing: 0x%08x", buf);
+
+       if (turbo_mode) {
+               ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+               check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+               netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf);
+
+               buf |= (HW_CFG_MEF | HW_CFG_BCE);
+
+               ret = smsc75xx_write_reg(dev, HW_CFG, buf);
+               check_warn_return(ret, "Failed to write HW_CFG: %d", ret);
+
+               ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+               check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+               netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf);
+       }
+
+       /* set FIFO sizes */
+       buf = (MAX_RX_FIFO_SIZE - 512) / 512;
+       ret = smsc75xx_write_reg(dev, FCT_RX_FIFO_END, buf);
+       check_warn_return(ret, "Failed to write FCT_RX_FIFO_END: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "FCT_RX_FIFO_END set to 0x%08x", buf);
+
+       buf = (MAX_TX_FIFO_SIZE - 512) / 512;
+       ret = smsc75xx_write_reg(dev, FCT_TX_FIFO_END, buf);
+       check_warn_return(ret, "Failed to write FCT_TX_FIFO_END: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "FCT_TX_FIFO_END set to 0x%08x", buf);
+
+       ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
+       check_warn_return(ret, "Failed to write INT_STS: %d", ret);
+
+       ret = smsc75xx_read_reg(dev, ID_REV, &buf);
+       check_warn_return(ret, "Failed to read ID_REV: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x", buf);
+
+       /* Configure GPIO pins as LED outputs */
+       ret = smsc75xx_read_reg(dev, LED_GPIO_CFG, &buf);
+       check_warn_return(ret, "Failed to read LED_GPIO_CFG: %d", ret);
+
+       buf &= ~(LED_GPIO_CFG_LED2_FUN_SEL | LED_GPIO_CFG_LED10_FUN_SEL);
+       buf |= LED_GPIO_CFG_LEDGPIO_EN | LED_GPIO_CFG_LED2_FUN_SEL;
+
+       ret = smsc75xx_write_reg(dev, LED_GPIO_CFG, buf);
+       check_warn_return(ret, "Failed to write LED_GPIO_CFG: %d", ret);
+
+       ret = smsc75xx_write_reg(dev, FLOW, 0);
+       check_warn_return(ret, "Failed to write FLOW: %d", ret);
+
+       ret = smsc75xx_write_reg(dev, FCT_FLOW, 0);
+       check_warn_return(ret, "Failed to write FCT_FLOW: %d", ret);
+
+       /* Don't need rfe_ctl_lock during initialisation */
+       ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
+       check_warn_return(ret, "Failed to read RFE_CTL: %d", ret);
+
+       pdata->rfe_ctl |= RFE_CTL_AB | RFE_CTL_DPF;
+
+       ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+       check_warn_return(ret, "Failed to write RFE_CTL: %d", ret);
+
+       ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
+       check_warn_return(ret, "Failed to read RFE_CTL: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "RFE_CTL set to 0x%08x", pdata->rfe_ctl);
+
+       /* Enable or disable checksum offload engines */
+       ethtool_op_set_tx_hw_csum(dev->net, DEFAULT_TX_CSUM_ENABLE);
+       ret = smsc75xx_set_rx_csum_offload(dev);
+       check_warn_return(ret, "Failed to set rx csum offload: %d", ret);
+
+       smsc75xx_ethtool_set_tso(dev->net, DEFAULT_TSO_ENABLE);
+
+       smsc75xx_set_multicast(dev->net);
+
+       ret = smsc75xx_phy_initialize(dev);
+       check_warn_return(ret, "Failed to initialize PHY: %d", ret);
+
+       ret = smsc75xx_read_reg(dev, INT_EP_CTL, &buf);
+       check_warn_return(ret, "Failed to read INT_EP_CTL: %d", ret);
+
+       /* enable PHY interrupts */
+       buf |= INT_ENP_PHY_INT;
+
+       ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf);
+       check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret);
+
+       ret = smsc75xx_read_reg(dev, MAC_TX, &buf);
+       check_warn_return(ret, "Failed to read MAC_TX: %d", ret);
+
+       buf |= MAC_TX_TXEN;
+
+       ret = smsc75xx_write_reg(dev, MAC_TX, buf);
+       check_warn_return(ret, "Failed to write MAC_TX: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "MAC_TX set to 0x%08x", buf);
+
+       ret = smsc75xx_read_reg(dev, FCT_TX_CTL, &buf);
+       check_warn_return(ret, "Failed to read FCT_TX_CTL: %d", ret);
+
+       buf |= FCT_TX_CTL_EN;
+
+       ret = smsc75xx_write_reg(dev, FCT_TX_CTL, buf);
+       check_warn_return(ret, "Failed to write FCT_TX_CTL: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x", buf);
+
+       ret = smsc75xx_set_rx_max_frame_length(dev, 1514);
+       check_warn_return(ret, "Failed to set max rx frame length");
+
+       ret = smsc75xx_read_reg(dev, MAC_RX, &buf);
+       check_warn_return(ret, "Failed to read MAC_RX: %d", ret);
+
+       buf |= MAC_RX_RXEN;
+
+       ret = smsc75xx_write_reg(dev, MAC_RX, buf);
+       check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "MAC_RX set to 0x%08x", buf);
+
+       ret = smsc75xx_read_reg(dev, FCT_RX_CTL, &buf);
+       check_warn_return(ret, "Failed to read FCT_RX_CTL: %d", ret);
+
+       buf |= FCT_RX_CTL_EN;
+
+       ret = smsc75xx_write_reg(dev, FCT_RX_CTL, buf);
+       check_warn_return(ret, "Failed to write FCT_RX_CTL: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "FCT_RX_CTL set to 0x%08x", buf);
+
+       netif_dbg(dev, ifup, dev->net, "smsc75xx_reset, return 0");
+       return 0;
+}
+
+static const struct net_device_ops smsc75xx_netdev_ops = {
+       .ndo_open               = usbnet_open,
+       .ndo_stop               = usbnet_stop,
+       .ndo_start_xmit         = usbnet_start_xmit,
+       .ndo_tx_timeout         = usbnet_tx_timeout,
+       .ndo_change_mtu         = smsc75xx_change_mtu,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_do_ioctl           = smsc75xx_ioctl,
+       .ndo_set_multicast_list = smsc75xx_set_multicast,
+};
+
+static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       struct smsc75xx_priv *pdata = NULL;
+       int ret;
+
+       printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n");
+
+       ret = usbnet_get_endpoints(dev, intf);
+       check_warn_return(ret, "usbnet_get_endpoints failed: %d", ret);
+
+       dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc75xx_priv),
+               GFP_KERNEL);
+
+       pdata = (struct smsc75xx_priv *)(dev->data[0]);
+       if (!pdata) {
+               netdev_warn(dev->net, "Unable to allocate smsc75xx_priv");
+               return -ENOMEM;
+       }
+
+       pdata->dev = dev;
+
+       spin_lock_init(&pdata->rfe_ctl_lock);
+       mutex_init(&pdata->dataport_mutex);
+
+       INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write);
+
+       pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE;
+
+       /* We have to advertise SG otherwise TSO cannot be enabled */
+       dev->net->features |= NETIF_F_SG;
+
+       /* Init all registers */
+       ret = smsc75xx_reset(dev);
+
+       dev->net->netdev_ops = &smsc75xx_netdev_ops;
+       dev->net->ethtool_ops = &smsc75xx_ethtool_ops;
+       dev->net->flags |= IFF_MULTICAST;
+       dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD;
+       return 0;
+}
+
+static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+       struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+       if (pdata) {
+               netif_dbg(dev, ifdown, dev->net, "free pdata");
+               kfree(pdata);
+               pdata = NULL;
+               dev->data[0] = 0;
+       }
+}
+
+static void smsc75xx_rx_csum_offload(struct sk_buff *skb, u32 rx_cmd_a,
+                                    u32 rx_cmd_b)
+{
+       if (unlikely(rx_cmd_a & RX_CMD_A_LCSM)) {
+               skb->ip_summed = CHECKSUM_NONE;
+       } else {
+               skb->csum = ntohs((u16)(rx_cmd_b >> RX_CMD_B_CSUM_SHIFT));
+               skb->ip_summed = CHECKSUM_COMPLETE;
+       }
+}
+
+static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+       struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+
+       while (skb->len > 0) {
+               u32 rx_cmd_a, rx_cmd_b, align_count, size;
+               struct sk_buff *ax_skb;
+               unsigned char *packet;
+
+               memcpy(&rx_cmd_a, skb->data, sizeof(rx_cmd_a));
+               le32_to_cpus(&rx_cmd_a);
+               skb_pull(skb, 4);
+
+               memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b));
+               le32_to_cpus(&rx_cmd_b);
+               skb_pull(skb, 4 + NET_IP_ALIGN);
+
+               packet = skb->data;
+
+               /* get the packet length */
+               size = (rx_cmd_a & RX_CMD_A_LEN) - NET_IP_ALIGN;
+               align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4;
+
+               if (unlikely(rx_cmd_a & RX_CMD_A_RED)) {
+                       netif_dbg(dev, rx_err, dev->net,
+                               "Error rx_cmd_a=0x%08x", rx_cmd_a);
+                       dev->net->stats.rx_errors++;
+                       dev->net->stats.rx_dropped++;
+
+                       if (rx_cmd_a & RX_CMD_A_FCS)
+                               dev->net->stats.rx_crc_errors++;
+                       else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT))
+                               dev->net->stats.rx_frame_errors++;
+               } else {
+                       /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */
+                       if (unlikely(size > (ETH_FRAME_LEN + 12))) {
+                               netif_dbg(dev, rx_err, dev->net,
+                                       "size err rx_cmd_a=0x%08x", rx_cmd_a);
+                               return 0;
+                       }
+
+                       /* last frame in this batch */
+                       if (skb->len == size) {
+                               if (pdata->use_rx_csum)
+                                       smsc75xx_rx_csum_offload(skb, rx_cmd_a,
+                                               rx_cmd_b);
+                               else
+                                       skb->ip_summed = CHECKSUM_NONE;
+
+                               skb_trim(skb, skb->len - 4); /* remove fcs */
+                               skb->truesize = size + sizeof(struct sk_buff);
+
+                               return 1;
+                       }
+
+                       ax_skb = skb_clone(skb, GFP_ATOMIC);
+                       if (unlikely(!ax_skb)) {
+                               netdev_warn(dev->net, "Error allocating skb");
+                               return 0;
+                       }
+
+                       ax_skb->len = size;
+                       ax_skb->data = packet;
+                       skb_set_tail_pointer(ax_skb, size);
+
+                       if (pdata->use_rx_csum)
+                               smsc75xx_rx_csum_offload(ax_skb, rx_cmd_a,
+                                       rx_cmd_b);
+                       else
+                               ax_skb->ip_summed = CHECKSUM_NONE;
+
+                       skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
+                       ax_skb->truesize = size + sizeof(struct sk_buff);
+
+                       usbnet_skb_return(dev, ax_skb);
+               }
+
+               skb_pull(skb, size);
+
+               /* padding bytes before the next frame starts */
+               if (skb->len)
+                       skb_pull(skb, align_count);
+       }
+
+       if (unlikely(skb->len < 0)) {
+               netdev_warn(dev->net, "invalid rx length<0 %d", skb->len);
+               return 0;
+       }
+
+       return 1;
+}
+
+static struct sk_buff *smsc75xx_tx_fixup(struct usbnet *dev,
+                                        struct sk_buff *skb, gfp_t flags)
+{
+       u32 tx_cmd_a, tx_cmd_b;
+
+       skb_linearize(skb);
+
+       if (skb_headroom(skb) < SMSC75XX_TX_OVERHEAD) {
+               struct sk_buff *skb2 =
+                       skb_copy_expand(skb, SMSC75XX_TX_OVERHEAD, 0, flags);
+               dev_kfree_skb_any(skb);
+               skb = skb2;
+               if (!skb)
+                       return NULL;
+       }
+
+       tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN) | TX_CMD_A_FCS;
+
+       if (skb->ip_summed == CHECKSUM_PARTIAL)
+               tx_cmd_a |= TX_CMD_A_IPE | TX_CMD_A_TPE;
+
+       if (skb_is_gso(skb)) {
+               u16 mss = max(skb_shinfo(skb)->gso_size, TX_MSS_MIN);
+               tx_cmd_b = (mss << TX_CMD_B_MSS_SHIFT) & TX_CMD_B_MSS;
+
+               tx_cmd_a |= TX_CMD_A_LSO;
+       } else {
+               tx_cmd_b = 0;
+       }
+
+       skb_push(skb, 4);
+       cpu_to_le32s(&tx_cmd_b);
+       memcpy(skb->data, &tx_cmd_b, 4);
+
+       skb_push(skb, 4);
+       cpu_to_le32s(&tx_cmd_a);
+       memcpy(skb->data, &tx_cmd_a, 4);
+
+       return skb;
+}
+
+static const struct driver_info smsc75xx_info = {
+       .description    = "smsc75xx USB 2.0 Gigabit Ethernet",
+       .bind           = smsc75xx_bind,
+       .unbind         = smsc75xx_unbind,
+       .link_reset     = smsc75xx_link_reset,
+       .reset          = smsc75xx_reset,
+       .rx_fixup       = smsc75xx_rx_fixup,
+       .tx_fixup       = smsc75xx_tx_fixup,
+       .status         = smsc75xx_status,
+       .flags          = FLAG_ETHER | FLAG_SEND_ZLP,
+};
+
+static const struct usb_device_id products[] = {
+       {
+               /* SMSC7500 USB Gigabit Ethernet Device */
+               USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7500),
+               .driver_info = (unsigned long) &smsc75xx_info,
+       },
+       {
+               /* SMSC7500 USB Gigabit Ethernet Device */
+               USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7505),
+               .driver_info = (unsigned long) &smsc75xx_info,
+       },
+       { },            /* END */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver smsc75xx_driver = {
+       .name           = SMSC_CHIPNAME,
+       .id_table       = products,
+       .probe          = usbnet_probe,
+       .suspend        = usbnet_suspend,
+       .resume         = usbnet_resume,
+       .disconnect     = usbnet_disconnect,
+};
+
+static int __init smsc75xx_init(void)
+{
+       return usb_register(&smsc75xx_driver);
+}
+module_init(smsc75xx_init);
+
+static void __exit smsc75xx_exit(void)
+{
+       usb_deregister(&smsc75xx_driver);
+}
+module_exit(smsc75xx_exit);
+
+MODULE_AUTHOR("Nancy Lin");
+MODULE_AUTHOR("Steve Glendinning <steve.glendinning@smsc.com>");
+MODULE_DESCRIPTION("SMSC75XX USB 2.0 Gigabit Ethernet Devices");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/usb/smsc75xx.h b/drivers/net/usb/smsc75xx.h
new file mode 100644 (file)
index 0000000..16e98c7
--- /dev/null
@@ -0,0 +1,421 @@
+ /***************************************************************************
+ *
+ * Copyright (C) 2007-2010 SMSC
+ *
+ * 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.
+ *
+ *****************************************************************************/
+
+#ifndef _SMSC75XX_H
+#define _SMSC75XX_H
+
+/* Tx command words */
+#define TX_CMD_A_LSO                   (0x08000000)
+#define TX_CMD_A_IPE                   (0x04000000)
+#define TX_CMD_A_TPE                   (0x02000000)
+#define TX_CMD_A_IVTG                  (0x01000000)
+#define TX_CMD_A_RVTG                  (0x00800000)
+#define TX_CMD_A_FCS                   (0x00400000)
+#define TX_CMD_A_LEN                   (0x000FFFFF)
+
+#define TX_CMD_B_MSS                   (0x3FFF0000)
+#define TX_CMD_B_MSS_SHIFT             (16)
+#define TX_MSS_MIN                     ((u16)8)
+#define TX_CMD_B_VTAG                  (0x0000FFFF)
+
+/* Rx command words */
+#define RX_CMD_A_ICE                   (0x80000000)
+#define RX_CMD_A_TCE                   (0x40000000)
+#define RX_CMD_A_IPV                   (0x20000000)
+#define RX_CMD_A_PID                   (0x18000000)
+#define RX_CMD_A_PID_NIP               (0x00000000)
+#define RX_CMD_A_PID_TCP               (0x08000000)
+#define RX_CMD_A_PID_UDP               (0x10000000)
+#define RX_CMD_A_PID_PP                        (0x18000000)
+#define RX_CMD_A_PFF                   (0x04000000)
+#define RX_CMD_A_BAM                   (0x02000000)
+#define RX_CMD_A_MAM                   (0x01000000)
+#define RX_CMD_A_FVTG                  (0x00800000)
+#define RX_CMD_A_RED                   (0x00400000)
+#define RX_CMD_A_RWT                   (0x00200000)
+#define RX_CMD_A_RUNT                  (0x00100000)
+#define RX_CMD_A_LONG                  (0x00080000)
+#define RX_CMD_A_RXE                   (0x00040000)
+#define RX_CMD_A_DRB                   (0x00020000)
+#define RX_CMD_A_FCS                   (0x00010000)
+#define RX_CMD_A_UAM                   (0x00008000)
+#define RX_CMD_A_LCSM                  (0x00004000)
+#define RX_CMD_A_LEN                   (0x00003FFF)
+
+#define RX_CMD_B_CSUM                  (0xFFFF0000)
+#define RX_CMD_B_CSUM_SHIFT            (16)
+#define RX_CMD_B_VTAG                  (0x0000FFFF)
+
+/* SCSRs */
+#define ID_REV                         (0x0000)
+
+#define FPGA_REV                       (0x0004)
+
+#define BOND_CTL                       (0x0008)
+
+#define INT_STS                                (0x000C)
+#define INT_STS_RDFO_INT               (0x00400000)
+#define INT_STS_TXE_INT                        (0x00200000)
+#define INT_STS_MACRTO_INT             (0x00100000)
+#define INT_STS_TX_DIS_INT             (0x00080000)
+#define INT_STS_RX_DIS_INT             (0x00040000)
+#define INT_STS_PHY_INT_               (0x00020000)
+#define INT_STS_MAC_ERR_INT            (0x00008000)
+#define INT_STS_TDFU                   (0x00004000)
+#define INT_STS_TDFO                   (0x00002000)
+#define INT_STS_GPIOS                  (0x00000FFF)
+#define INT_STS_CLEAR_ALL              (0xFFFFFFFF)
+
+#define HW_CFG                         (0x0010)
+#define HW_CFG_SMDET_STS               (0x00008000)
+#define HW_CFG_SMDET_EN                        (0x00004000)
+#define HW_CFG_EEM                     (0x00002000)
+#define HW_CFG_RST_PROTECT             (0x00001000)
+#define HW_CFG_PORT_SWAP               (0x00000800)
+#define HW_CFG_PHY_BOOST               (0x00000600)
+#define HW_CFG_PHY_BOOST_NORMAL                (0x00000000)
+#define HW_CFG_PHY_BOOST_4             (0x00002000)
+#define HW_CFG_PHY_BOOST_8             (0x00004000)
+#define HW_CFG_PHY_BOOST_12            (0x00006000)
+#define HW_CFG_LEDB                    (0x00000100)
+#define HW_CFG_BIR                     (0x00000080)
+#define HW_CFG_SBP                     (0x00000040)
+#define HW_CFG_IME                     (0x00000020)
+#define HW_CFG_MEF                     (0x00000010)
+#define HW_CFG_ETC                     (0x00000008)
+#define HW_CFG_BCE                     (0x00000004)
+#define HW_CFG_LRST                    (0x00000002)
+#define HW_CFG_SRST                    (0x00000001)
+
+#define PMT_CTL                                (0x0014)
+#define PMT_CTL_PHY_PWRUP              (0x00000400)
+#define PMT_CTL_RES_CLR_WKP_EN         (0x00000100)
+#define PMT_CTL_DEV_RDY                        (0x00000080)
+#define PMT_CTL_SUS_MODE               (0x00000060)
+#define PMT_CTL_SUS_MODE_0             (0x00000000)
+#define PMT_CTL_SUS_MODE_1             (0x00000020)
+#define PMT_CTL_SUS_MODE_2             (0x00000040)
+#define PMT_CTL_SUS_MODE_3             (0x00000060)
+#define PMT_CTL_PHY_RST                        (0x00000010)
+#define PMT_CTL_WOL_EN                 (0x00000008)
+#define PMT_CTL_ED_EN                  (0x00000004)
+#define PMT_CTL_WUPS                   (0x00000003)
+#define PMT_CTL_WUPS_NO                        (0x00000000)
+#define PMT_CTL_WUPS_ED                        (0x00000001)
+#define PMT_CTL_WUPS_WOL               (0x00000002)
+#define PMT_CTL_WUPS_MULTI             (0x00000003)
+
+#define LED_GPIO_CFG                   (0x0018)
+#define LED_GPIO_CFG_LED2_FUN_SEL      (0x80000000)
+#define LED_GPIO_CFG_LED10_FUN_SEL     (0x40000000)
+#define LED_GPIO_CFG_LEDGPIO_EN                (0x0000F000)
+#define LED_GPIO_CFG_LEDGPIO_EN_0      (0x00001000)
+#define LED_GPIO_CFG_LEDGPIO_EN_1      (0x00002000)
+#define LED_GPIO_CFG_LEDGPIO_EN_2      (0x00004000)
+#define LED_GPIO_CFG_LEDGPIO_EN_3      (0x00008000)
+#define LED_GPIO_CFG_GPBUF             (0x00000F00)
+#define LED_GPIO_CFG_GPBUF_0           (0x00000100)
+#define LED_GPIO_CFG_GPBUF_1           (0x00000200)
+#define LED_GPIO_CFG_GPBUF_2           (0x00000400)
+#define LED_GPIO_CFG_GPBUF_3           (0x00000800)
+#define LED_GPIO_CFG_GPDIR             (0x000000F0)
+#define LED_GPIO_CFG_GPDIR_0           (0x00000010)
+#define LED_GPIO_CFG_GPDIR_1           (0x00000020)
+#define LED_GPIO_CFG_GPDIR_2           (0x00000040)
+#define LED_GPIO_CFG_GPDIR_3           (0x00000080)
+#define LED_GPIO_CFG_GPDATA            (0x0000000F)
+#define LED_GPIO_CFG_GPDATA_0          (0x00000001)
+#define LED_GPIO_CFG_GPDATA_1          (0x00000002)
+#define LED_GPIO_CFG_GPDATA_2          (0x00000004)
+#define LED_GPIO_CFG_GPDATA_3          (0x00000008)
+
+#define GPIO_CFG                       (0x001C)
+#define GPIO_CFG_SHIFT                 (24)
+#define GPIO_CFG_GPEN                  (0xFF000000)
+#define GPIO_CFG_GPBUF                 (0x00FF0000)
+#define GPIO_CFG_GPDIR                 (0x0000FF00)
+#define GPIO_CFG_GPDATA                        (0x000000FF)
+
+#define GPIO_WAKE                      (0x0020)
+#define GPIO_WAKE_PHY_LINKUP_EN                (0x80000000)
+#define GPIO_WAKE_POL                  (0x0FFF0000)
+#define GPIO_WAKE_POL_SHIFT            (16)
+#define GPIO_WAKE_WK                   (0x00000FFF)
+
+#define DP_SEL                         (0x0024)
+#define DP_SEL_DPRDY                   (0x80000000)
+#define DP_SEL_RSEL                    (0x0000000F)
+#define DP_SEL_URX                     (0x00000000)
+#define DP_SEL_VHF                     (0x00000001)
+#define DP_SEL_VHF_HASH_LEN            (16)
+#define DP_SEL_VHF_VLAN_LEN            (128)
+#define DP_SEL_LSO_HEAD                        (0x00000002)
+#define DP_SEL_FCT_RX                  (0x00000003)
+#define DP_SEL_FCT_TX                  (0x00000004)
+#define DP_SEL_DESCRIPTOR              (0x00000005)
+#define DP_SEL_WOL                     (0x00000006)
+
+#define DP_CMD                         (0x0028)
+#define DP_CMD_WRITE                   (0x01)
+#define DP_CMD_READ                    (0x00)
+
+#define DP_ADDR                                (0x002C)
+
+#define DP_DATA                                (0x0030)
+
+#define BURST_CAP                      (0x0034)
+#define BURST_CAP_MASK                 (0x0000000F)
+
+#define INT_EP_CTL                     (0x0038)
+#define INT_EP_CTL_INTEP_ON            (0x80000000)
+#define INT_EP_CTL_RDFO_EN             (0x00400000)
+#define INT_EP_CTL_TXE_EN              (0x00200000)
+#define INT_EP_CTL_MACROTO_EN          (0x00100000)
+#define INT_EP_CTL_TX_DIS_EN           (0x00080000)
+#define INT_EP_CTL_RX_DIS_EN           (0x00040000)
+#define INT_EP_CTL_PHY_EN_             (0x00020000)
+#define INT_EP_CTL_MAC_ERR_EN          (0x00008000)
+#define INT_EP_CTL_TDFU_EN             (0x00004000)
+#define INT_EP_CTL_TDFO_EN             (0x00002000)
+#define INT_EP_CTL_RX_FIFO_EN          (0x00001000)
+#define INT_EP_CTL_GPIOX_EN            (0x00000FFF)
+
+#define BULK_IN_DLY                    (0x003C)
+#define BULK_IN_DLY_MASK               (0xFFFF)
+
+#define E2P_CMD                                (0x0040)
+#define E2P_CMD_BUSY                   (0x80000000)
+#define E2P_CMD_MASK                   (0x70000000)
+#define E2P_CMD_READ                   (0x00000000)
+#define E2P_CMD_EWDS                   (0x10000000)
+#define E2P_CMD_EWEN                   (0x20000000)
+#define E2P_CMD_WRITE                  (0x30000000)
+#define E2P_CMD_WRAL                   (0x40000000)
+#define E2P_CMD_ERASE                  (0x50000000)
+#define E2P_CMD_ERAL                   (0x60000000)
+#define E2P_CMD_RELOAD                 (0x70000000)
+#define E2P_CMD_TIMEOUT                        (0x00000400)
+#define E2P_CMD_LOADED                 (0x00000200)
+#define E2P_CMD_ADDR                   (0x000001FF)
+
+#define MAX_EEPROM_SIZE                        (512)
+
+#define E2P_DATA                       (0x0044)
+#define E2P_DATA_MASK_                 (0x000000FF)
+
+#define RFE_CTL                                (0x0060)
+#define RFE_CTL_TCPUDP_CKM             (0x00001000)
+#define RFE_CTL_IP_CKM                 (0x00000800)
+#define RFE_CTL_AB                     (0x00000400)
+#define RFE_CTL_AM                     (0x00000200)
+#define RFE_CTL_AU                     (0x00000100)
+#define RFE_CTL_VS                     (0x00000080)
+#define RFE_CTL_UF                     (0x00000040)
+#define RFE_CTL_VF                     (0x00000020)
+#define RFE_CTL_SPF                    (0x00000010)
+#define RFE_CTL_MHF                    (0x00000008)
+#define RFE_CTL_DHF                    (0x00000004)
+#define RFE_CTL_DPF                    (0x00000002)
+#define RFE_CTL_RST_RF                 (0x00000001)
+
+#define VLAN_TYPE                      (0x0064)
+#define VLAN_TYPE_MASK                 (0x0000FFFF)
+
+#define FCT_RX_CTL                     (0x0090)
+#define FCT_RX_CTL_EN                  (0x80000000)
+#define FCT_RX_CTL_RST                 (0x40000000)
+#define FCT_RX_CTL_SBF                 (0x02000000)
+#define FCT_RX_CTL_OVERFLOW            (0x01000000)
+#define FCT_RX_CTL_FRM_DROP            (0x00800000)
+#define FCT_RX_CTL_RX_NOT_EMPTY                (0x00400000)
+#define FCT_RX_CTL_RX_EMPTY            (0x00200000)
+#define FCT_RX_CTL_RX_DISABLED         (0x00100000)
+#define FCT_RX_CTL_RXUSED              (0x0000FFFF)
+
+#define FCT_TX_CTL                     (0x0094)
+#define FCT_TX_CTL_EN                  (0x80000000)
+#define FCT_TX_CTL_RST                 (0x40000000)
+#define FCT_TX_CTL_TX_NOT_EMPTY                (0x00400000)
+#define FCT_TX_CTL_TX_EMPTY            (0x00200000)
+#define FCT_TX_CTL_TX_DISABLED         (0x00100000)
+#define FCT_TX_CTL_TXUSED              (0x0000FFFF)
+
+#define FCT_RX_FIFO_END                        (0x0098)
+#define FCT_RX_FIFO_END_MASK           (0x0000007F)
+
+#define FCT_TX_FIFO_END                        (0x009C)
+#define FCT_TX_FIFO_END_MASK           (0x0000003F)
+
+#define FCT_FLOW                       (0x00A0)
+#define FCT_FLOW_THRESHOLD_OFF         (0x00007F00)
+#define FCT_FLOW_THRESHOLD_OFF_SHIFT   (8)
+#define FCT_FLOW_THRESHOLD_ON          (0x0000007F)
+
+/* MAC CSRs */
+#define MAC_CR                         (0x100)
+#define MAC_CR_ADP                     (0x00002000)
+#define MAC_CR_ADD                     (0x00001000)
+#define MAC_CR_ASD                     (0x00000800)
+#define MAC_CR_INT_LOOP                        (0x00000400)
+#define MAC_CR_BOLMT                   (0x000000C0)
+#define MAC_CR_FDPX                    (0x00000008)
+#define MAC_CR_CFG                     (0x00000006)
+#define MAC_CR_CFG_10                  (0x00000000)
+#define MAC_CR_CFG_100                 (0x00000002)
+#define MAC_CR_CFG_1000                        (0x00000004)
+#define MAC_CR_RST                     (0x00000001)
+
+#define MAC_RX                         (0x104)
+#define MAC_RX_MAX_SIZE                        (0x3FFF0000)
+#define MAC_RX_MAX_SIZE_SHIFT          (16)
+#define MAC_RX_FCS_STRIP               (0x00000010)
+#define MAC_RX_FSE                     (0x00000004)
+#define MAC_RX_RXD                     (0x00000002)
+#define MAC_RX_RXEN                    (0x00000001)
+
+#define MAC_TX                         (0x108)
+#define MAC_TX_BFCS                    (0x00000004)
+#define MAC_TX_TXD                     (0x00000002)
+#define MAC_TX_TXEN                    (0x00000001)
+
+#define FLOW                           (0x10C)
+#define FLOW_FORCE_FC                  (0x80000000)
+#define FLOW_TX_FCEN                   (0x40000000)
+#define FLOW_RX_FCEN                   (0x20000000)
+#define FLOW_FPF                       (0x10000000)
+#define FLOW_PAUSE_TIME                        (0x0000FFFF)
+
+#define RAND_SEED                      (0x110)
+#define RAND_SEED_MASK                 (0x0000FFFF)
+
+#define ERR_STS                                (0x114)
+#define ERR_STS_FCS_ERR                        (0x00000100)
+#define ERR_STS_LFRM_ERR               (0x00000080)
+#define ERR_STS_RUNT_ERR               (0x00000040)
+#define ERR_STS_COLLISION_ERR          (0x00000010)
+#define ERR_STS_ALIGN_ERR              (0x00000008)
+#define ERR_STS_URUN_ERR               (0x00000004)
+
+#define RX_ADDRH                       (0x118)
+#define RX_ADDRH_MASK                  (0x0000FFFF)
+
+#define RX_ADDRL                       (0x11C)
+
+#define MII_ACCESS                     (0x120)
+#define MII_ACCESS_PHY_ADDR            (0x0000F800)
+#define MII_ACCESS_PHY_ADDR_SHIFT      (11)
+#define MII_ACCESS_REG_ADDR            (0x000007C0)
+#define MII_ACCESS_REG_ADDR_SHIFT      (6)
+#define MII_ACCESS_READ                        (0x00000000)
+#define MII_ACCESS_WRITE               (0x00000002)
+#define MII_ACCESS_BUSY                        (0x00000001)
+
+#define MII_DATA                       (0x124)
+#define MII_DATA_MASK                  (0x0000FFFF)
+
+#define WUCSR                          (0x140)
+#define WUCSR_PFDA_FR                  (0x00000080)
+#define WUCSR_WUFR                     (0x00000040)
+#define WUCSR_MPR                      (0x00000020)
+#define WUCSR_BCAST_FR                 (0x00000010)
+#define WUCSR_PFDA_EN                  (0x00000008)
+#define WUCSR_WUEN                     (0x00000004)
+#define WUCSR_MPEN                     (0x00000002)
+#define WUCSR_BCST_EN                  (0x00000001)
+
+#define WUF_CFGX                       (0x144)
+#define WUF_CFGX_EN                    (0x80000000)
+#define WUF_CFGX_ATYPE                 (0x03000000)
+#define WUF_CFGX_ATYPE_UNICAST         (0x00000000)
+#define WUF_CFGX_ATYPE_MULTICAST       (0x02000000)
+#define WUF_CFGX_ATYPE_ALL             (0x03000000)
+#define WUF_CFGX_PATTERN_OFFSET                (0x007F0000)
+#define WUF_CFGX_PATTERN_OFFSET_SHIFT  (16)
+#define WUF_CFGX_CRC16                 (0x0000FFFF)
+#define WUF_NUM                                (8)
+
+#define WUF_MASKX                      (0x170)
+#define WUF_MASKX_AVALID               (0x80000000)
+#define WUF_MASKX_ATYPE                        (0x40000000)
+
+#define ADDR_FILTX                     (0x300)
+#define ADDR_FILTX_FB_VALID            (0x80000000)
+#define ADDR_FILTX_FB_TYPE             (0x40000000)
+#define ADDR_FILTX_FB_ADDRHI           (0x0000FFFF)
+#define ADDR_FILTX_SB_ADDRLO           (0xFFFFFFFF)
+
+#define WUCSR2                         (0x500)
+#define WUCSR2_NS_RCD                  (0x00000040)
+#define WUCSR2_ARP_RCD                 (0x00000020)
+#define WUCSR2_TCPSYN_RCD              (0x00000010)
+#define WUCSR2_NS_OFFLOAD              (0x00000004)
+#define WUCSR2_ARP_OFFLOAD             (0x00000002)
+#define WUCSR2_TCPSYN_OFFLOAD          (0x00000001)
+
+#define WOL_FIFO_STS                   (0x504)
+
+#define IPV6_ADDRX                     (0x510)
+
+#define IPV4_ADDRX                     (0x590)
+
+
+/* Vendor-specific PHY Definitions */
+
+/* Mode Control/Status Register */
+#define PHY_MODE_CTRL_STS              (17)
+#define MODE_CTRL_STS_EDPWRDOWN                ((u16)0x2000)
+#define MODE_CTRL_STS_ENERGYON         ((u16)0x0002)
+
+#define PHY_INT_SRC                    (29)
+#define PHY_INT_SRC_ENERGY_ON          ((u16)0x0080)
+#define PHY_INT_SRC_ANEG_COMP          ((u16)0x0040)
+#define PHY_INT_SRC_REMOTE_FAULT       ((u16)0x0020)
+#define PHY_INT_SRC_LINK_DOWN          ((u16)0x0010)
+
+#define PHY_INT_MASK                   (30)
+#define PHY_INT_MASK_ENERGY_ON         ((u16)0x0080)
+#define PHY_INT_MASK_ANEG_COMP         ((u16)0x0040)
+#define PHY_INT_MASK_REMOTE_FAULT      ((u16)0x0020)
+#define PHY_INT_MASK_LINK_DOWN         ((u16)0x0010)
+#define PHY_INT_MASK_DEFAULT           (PHY_INT_MASK_ANEG_COMP | \
+                                        PHY_INT_MASK_LINK_DOWN)
+
+#define PHY_SPECIAL                    (31)
+#define PHY_SPECIAL_SPD                        ((u16)0x001C)
+#define PHY_SPECIAL_SPD_10HALF         ((u16)0x0004)
+#define PHY_SPECIAL_SPD_10FULL         ((u16)0x0014)
+#define PHY_SPECIAL_SPD_100HALF                ((u16)0x0008)
+#define PHY_SPECIAL_SPD_100FULL                ((u16)0x0018)
+
+/* USB Vendor Requests */
+#define USB_VENDOR_REQUEST_WRITE_REGISTER      0xA0
+#define USB_VENDOR_REQUEST_READ_REGISTER       0xA1
+#define USB_VENDOR_REQUEST_GET_STATS           0xA2
+
+/* Interrupt Endpoint status word bitfields */
+#define INT_ENP_RDFO_INT               ((u32)BIT(22))
+#define INT_ENP_TXE_INT                        ((u32)BIT(21))
+#define INT_ENP_TX_DIS_INT             ((u32)BIT(19))
+#define INT_ENP_RX_DIS_INT             ((u32)BIT(18))
+#define INT_ENP_PHY_INT                        ((u32)BIT(17))
+#define INT_ENP_MAC_ERR_INT            ((u32)BIT(15))
+#define INT_ENP_RX_FIFO_DATA_INT       ((u32)BIT(12))
+
+#endif /* _SMSC75XX_H */
index df9179a1c93bfb22c1f104ea27233a036da3f49a..3135af63d3785f8ba38cfe3b516841bfdc2a1c92 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/usb.h>
 #include <linux/crc32.h>
 #include <linux/usb/usbnet.h>
+#include <linux/slab.h>
 #include "smsc95xx.h"
 
 #define SMSC_CHIPNAME                  "smsc95xx"
@@ -709,6 +710,8 @@ static void smsc95xx_start_rx_path(struct usbnet *dev)
 
 static int smsc95xx_phy_initialize(struct usbnet *dev)
 {
+       int bmcr, timeout = 0;
+
        /* Initialize MII structure */
        dev->mii.dev = dev->net;
        dev->mii.mdio_read = smsc95xx_mdio_read;
@@ -717,7 +720,20 @@ static int smsc95xx_phy_initialize(struct usbnet *dev)
        dev->mii.reg_num_mask = 0x1f;
        dev->mii.phy_id = SMSC95XX_INTERNAL_PHY_ID;
 
+       /* reset phy and wait for reset to complete */
        smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
+
+       do {
+               msleep(10);
+               bmcr = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
+               timeout++;
+       } while ((bmcr & MII_BMCR) && (timeout < 100));
+
+       if (timeout >= 100) {
+               netdev_warn(dev->net, "timeout on PHY Reset");
+               return -EIO;
+       }
+
        smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
                ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
                ADVERTISE_PAUSE_ASYM);
@@ -1174,9 +1190,21 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
        }
 
        if (csum) {
-               u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
-               skb_push(skb, 4);
-               memcpy(skb->data, &csum_preamble, 4);
+               if (skb->len <= 45) {
+                       /* workaround - hardware tx checksum does not work
+                        * properly with extremely small packets */
+                       long csstart = skb->csum_start - skb_headroom(skb);
+                       __wsum calc = csum_partial(skb->data + csstart,
+                               skb->len - csstart, 0);
+                       *((__sum16 *)(skb->data + csstart
+                               + skb->csum_offset)) = csum_fold(calc);
+
+                       csum = false;
+               } else {
+                       u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
+                       skb_push(skb, 4);
+                       memcpy(skb->data, &csum_preamble, 4);
+               }
        }
 
        skb_push(skb, 4);
index 17b6a62d206e0d6825b8a7b0e83794fed4930e02..7177abc78dc6b664fbe722a8bb18263ad7c3d1b1 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/mii.h>
 #include <linux/usb.h>
 #include <linux/usb/usbnet.h>
+#include <linux/slab.h>
 
 #define DRIVER_VERSION         "22-Aug-2005"
 
index b583d4968add5064b57417b25f9e67f8a6549240..5ec542dd5b5007825cf47991cab64894623767ec 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/ethtool.h>
 #include <linux/etherdevice.h>
 
@@ -186,7 +187,6 @@ tx_drop:
        return NETDEV_TX_OK;
 
 rx_drop:
-       kfree_skb(skb);
        rcv_stats->rx_dropped++;
        return NETDEV_TX_OK;
 }
index 50f881aa3939a50606f34412bd05cdbe2d2ad381..388751aa66e05f287ec40422936a30bac95d4407 100644 (file)
@@ -89,7 +89,6 @@ static const int multicast_filter_limit = 32;
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
index 3a486f3bad3ddd6477c0fa15102e47c668ea3566..bc278d4ee89debb359c4d70ef21e06bfd7479ae3 100644 (file)
@@ -812,7 +812,7 @@ static void set_mii_flow_control(struct velocity_info *vptr)
 
        case FLOW_CNTL_TX_RX:
                MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
-               MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
+               MII_REG_BITS_OFF(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
                break;
 
        case FLOW_CNTL_DISABLE:
index 25dc77ccbf5876f3bbf27100fdd7b77be3c01a02..b0577dd1a42dc838eae1e9ca6bb14bc018192b4d 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/virtio_net.h>
 #include <linux/scatterlist.h>
 #include <linux/if_vlan.h>
+#include <linux/slab.h>
 
 static int napi_weight = 128;
 module_param(napi_weight, int, 0444);
@@ -326,6 +327,7 @@ static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp)
        struct scatterlist sg[2];
        int err;
 
+       sg_init_table(sg, 2);
        skb = netdev_alloc_skb_ip_align(vi->dev, MAX_PACKET_LEN);
        if (unlikely(!skb))
                return -ENOMEM;
@@ -351,6 +353,7 @@ static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)
        char *p;
        int i, err, offset;
 
+       sg_init_table(sg, MAX_SKB_FRAGS + 2);
        /* page in sg[MAX_SKB_FRAGS + 1] is list tail */
        for (i = MAX_SKB_FRAGS + 1; i > 1; --i) {
                first = get_a_page(vi, gfp);
index 32a75fa935ed4cc892c86ab6715a9db43f2802c9..a21a25d218b695c737a2647d6407c4acc448605d 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/etherdevice.h>
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
+#include <linux/slab.h>
 
 #include "vxge-traffic.h"
 #include "vxge-config.h"
index e7877df092f357bb3d4085858a35ce69ab2873b3..13f5416307f8013ed5259137b5470fc99ce0445b 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef VXGE_CONFIG_H
 #define VXGE_CONFIG_H
 #include <linux/list.h>
+#include <linux/slab.h>
 
 #ifndef VXGE_CACHE_LINE_SIZE
 #define VXGE_CACHE_LINE_SIZE 128
index c6736b9726352b07044693af19c7d4545b249500..aaf374cfd322d641024c8e1921e3881b630888e3 100644 (file)
@@ -12,6 +12,7 @@
  * Copyright(c) 2002-2009 Neterion Inc.
  ******************************************************************************/
 #include<linux/ethtool.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/etherdevice.h>
 
index 46a7c9e689ec7dc26d2e29d6760f606562ea5dc5..ba6d0da78c3019b111e537ef894ce66940fca324 100644 (file)
@@ -43,6 +43,7 @@
 
 #include <linux/if_vlan.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/tcp.h>
 #include <net/ip.h>
 #include <linux/netdevice.h>
index f88c07c131978dfd58e046543b04d818e037fbd9..a4859f7a7cc0c9aa62ce537dcef3740999890b29 100644 (file)
@@ -89,6 +89,7 @@
 #include <linux/pci.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/cache.h>
index 40d724a8e02044fbfc8d144fa520c47c7681b472..e087b9a6daaa50078fa761acc2deabbb70b315b5 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/version.h>
 #include <linux/pci.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/if.h>
index 80114c93bae74c52db4d53c32f3681938022c49d..4dde2ea4a189d75ae6e7c3da6ec03469c13bc253 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <asm/io.h>
index 84f01373e11fb769794dd885b0586e61607c9692..aad9ed45c254c52af53510ba2158b2a11b22ced0 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <asm/io.h>
index 1ceccf1ca6c7952e277dbf11e43421206657b8a6..ee7083fbea50708a076c68af7e289320cb4d355c 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/poll.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 
 #undef DEBUG_HARD_HEADER
 
index b9b9d6b01c0baa8d5e2589ec1f5185d4ce392149..941f053e650e573a5626ad20bd7cd66bd7ace474 100644 (file)
@@ -628,9 +628,15 @@ static void ppp_stop(struct net_device *dev)
        ppp_cp_event(dev, PID_LCP, STOP, 0, 0, 0, NULL);
 }
 
+static void ppp_close(struct net_device *dev)
+{
+       ppp_tx_flush();
+}
+
 static struct hdlc_proto proto = {
        .start          = ppp_start,
        .stop           = ppp_stop,
+       .close          = ppp_close,
        .type_trans     = ppp_type_trans,
        .ioctl          = ppp_ioctl,
        .netif_rx       = ppp_rx,
index 19f51fdd55227debdbcae8b10ab100feb93ee3d6..5dc153e8a29d14d9d0a68579dbe85718ea6d7955 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/poll.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 
 
 static int raw_ioctl(struct net_device *dev, struct ifreq *ifr);
index 1b30fcc2414531edc8be3fff8175ae8685ea3e6b..05c9b0b96239d17f9896000f409bdd8d17cdff46 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/errno.h>
 #include <linux/etherdevice.h>
+#include <linux/gfp.h>
 #include <linux/hdlc.h>
 #include <linux/if_arp.h>
 #include <linux/inetdevice.h>
@@ -21,7 +22,6 @@
 #include <linux/poll.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 
 static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr);
 
index 6e1ca256effd8f8752b3387c23ca75d7522cb1d8..c7adbb79f7cc34daf5c1b13f1398ff654d143b33 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/hdlc.h>
 #include <linux/if_arp.h>
 #include <linux/inetdevice.h>
@@ -21,7 +22,6 @@
 #include <linux/poll.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <net/x25device.h>
 
 static int x25_ioctl(struct net_device *dev, struct ifreq *ifr);
index 74164d29524c92be79f490861fb3bf9ea39711ee..48edc5f4dac8e4bba19a7366e95463e6426f80b3 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/delay.h>
 #include <linux/hdlc.h>
 #include <linux/ioport.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 
 #include <asm/irq.h>
index c705046d86158f0cbe8de8e521ef364808ba34a3..0c2cdde686a03fd6f50efa58fa9d3538c2f8407a 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <mach/npe.h>
 #include <mach/qmgr.h>
 
index d1e3c673e9b298376344bb501dca4d2bdd3850d6..98e2f99903d775e7ddfdd78ea93a56f9304ea77d 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/types.h>
 #include <linux/socket.h>
 #include <linux/in.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/net.h>
index f327674fc93ae139c88d70a7881d38ab393e10ee..5920c996fcdf24679944920fac6e577c0c4c472b 100644 (file)
@@ -6,7 +6,6 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/if_arp.h>
index 044a48175c42e4d4076d950cc23b0a2ffc162765..f600075e84a248c9afd481f6cd7e8453e5eeb8b4 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/if_arp.h>
index f4f1c00d0d23737cfc7b6b8e0066c2d2e6490743..3f744c6430946905cc312eb257d77eaef57c7878 100644 (file)
@@ -228,6 +228,7 @@ static char rcsid[] =
 #include <linux/etherdevice.h>
 #include <linux/spinlock.h>
 #include <linux/if.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 
 #include <asm/io.h>
index 25477b5cde4769d3a0be456bb07e3ac6f3e95ce3..cff13a9597cd27ee80de90089423df8ea660bdde 100644 (file)
@@ -43,7 +43,6 @@
 #include <linux/fcntl.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
index 61249f489e3782e5be8ea90a9f15b69b5dde1e6e..e91457d6023ecd7a2d8512a0a151368491261ec6 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/hdlc.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 
 #include <asm/irq.h>
index b9f520b7db6adb71f4cb26bc3a64fde1a3400423..80d5c5834a0bf976c0446a02e7a3050823158c4a 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/compat.h>
+#include <linux/slab.h>
 #include "x25_asy.h"
 
 #include <net/x25device.h>
index 0be7ec7299dbb960641f7c385b2dace9482ca7fd..fbf5e843d48c1fd9f88b55ef993ea74474488041 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/hdlc.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <asm/dma.h>
 #include <asm/io.h>
 #define RT_LOCK
index 9449455403911266fb05c1c49fde856765dd2cdc..6180772dcc092011bf98f995048b45b81df2efa5 100644 (file)
@@ -76,6 +76,7 @@
 #include <stdarg.h>
 #include "i2400m.h"
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/wimax/i2400m.h>
 
 
index 6cead321bc15d664f924105852f5deef740cf392..94dc83c3969d7498d7a625d48685741c1642a788 100644 (file)
@@ -69,6 +69,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/suspend.h>
+#include <linux/slab.h>
 
 #define D_SUBMODULE driver
 #include "debug-levels.h"
index 25c24f0368d8d4c921cacb60582e21708ef66cc9..3f283bff0ff7146447419ea714ef7cdd78884b12 100644 (file)
  */
 #include <linux/firmware.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include "i2400m.h"
 
index 599aa4eb9baa9bc8dd51cfd4ef3ac076583e99b4..b811c2f1f5e978dc42e8cacea806307a6cff70c7 100644 (file)
@@ -73,6 +73,7 @@
  *                        alloc_netdev.
  */
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
 #include "i2400m.h"
index 43927b5d7ad6158a959b06f305e008b56bb306b5..035e4cf3e6ed1a9b7d7b0184dc4f95128b366b0a 100644 (file)
@@ -34,6 +34,7 @@
  */
 #include "i2400m.h"
 #include <linux/wimax/i2400m.h>
+#include <linux/slab.h>
 
 
 
index 7ddb173fd4a7b4f2470adfce618e6612375fa534..fa2e11e5b4b9cb32718bb827f41ecbe1c3c580ef 100644 (file)
  *       i2400m_msg_size_check
  *       wimax_msg
  */
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
index 8adf6c9b6f8f245e16e153c4fe132f6dbb3eef53..d619da33f20b9adad0642678545810a143d93aea 100644 (file)
@@ -65,6 +65,7 @@
 #include <linux/skbuff.h>
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/sdio_func.h>
+#include <linux/slab.h>
 #include "i2400m-sdio.h"
 
 #define D_SUBMODULE rx
index 14f876b1358b8e78b56c0b90782fd935768553ba..7632f80954e3e56620b95b474ccf79d4e90037c8 100644 (file)
@@ -48,6 +48,7 @@
  *     __i2400ms_send_barker()
  */
 
+#include <linux/slab.h>
 #include <linux/debugfs.h>
 #include <linux/mmc/sdio_ids.h>
 #include <linux/mmc/sdio.h>
index 54480e8947f1a6acd0b306798ad25b81c2b76fd9..b0cb90624cf62f4f25d6f30732a00da538e558c2 100644 (file)
  *                               (FIFO empty).
  */
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include "i2400m.h"
 
 
index ce6b9938fde08ed80bd99ad6d2c6c8f94424394e..b58ec56b86f8b29556cc9fe2a9b1453cf0d5baa9 100644 (file)
@@ -73,6 +73,7 @@
  *   i2400m_notif_submit
  */
 #include <linux/usb.h>
+#include <linux/gfp.h>
 #include "i2400m-usb.h"
 
 
index f88d1c6e35cbb056a69666366505ba6adab25bbd..7b6a1d98bd74321af344c47916422dae6002108a 100644 (file)
@@ -56,6 +56,7 @@
  *     i2400mu_rx_kick()
  */
 #include <linux/usb.h>
+#include <linux/slab.h>
 #include "i2400m-usb.h"
 
 
index ba1b02362dfcba8b7daaabe3872ee133711b6da4..a26483a812a50679088b6f9fae058821275d3dc0 100644 (file)
@@ -83,6 +83,7 @@
  * i2400mu_rx_release()            called from i2400mu_bus_dev_stop()
  */
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include "i2400m-usb.h"
 
index 99f04c4758981425f6a95dd89697edb75b1fb581..d8c4d6497fdfb8dc4b4d97baafd55210833ea89a 100644 (file)
@@ -66,6 +66,7 @@
 #include "i2400m-usb.h"
 #include <linux/wimax/i2400m.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 
 
 #define D_SUBMODULE usb
index 547912e6843f2efeac20f9361409707f64233302..ab61d2b558d6c944cb9f653f609e511256d90a6c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/if.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/etherdevice.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
index 257c734733d1d362a6290631075b790bc17b9fc5..c53692980990153ca3b05562978cb3d010d6d215 100644 (file)
@@ -38,6 +38,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/etherdevice.h>
 #include <net/mac80211.h>
index 4e30197afff6702e5630373d893b2615db53d1cb..e1c2fcaa8bed92889a3cc30d0dd8fcd6c3bffb00 100644 (file)
@@ -38,6 +38,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
@@ -94,6 +95,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
        { USB_DEVICE(0x04bb, 0x093f) },
        /* AVM FRITZ!WLAN USB Stick N */
        { USB_DEVICE(0x057C, 0x8401) },
+       /* NEC WL300NU-G */
+       { USB_DEVICE(0x0409, 0x0249) },
        /* AVM FRITZ!WLAN USB Stick N 2.4 */
        { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
 
@@ -416,7 +419,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
        spin_unlock_irqrestore(&aru->common.cmdlock, flags);
 
        usb_fill_int_urb(urb, aru->udev,
-                        usb_sndbulkpipe(aru->udev, AR9170_EP_CMD),
+                        usb_sndintpipe(aru->udev, AR9170_EP_CMD),
                         aru->common.cmdbuf, plen + 4,
                         ar9170_usb_tx_urb_complete, NULL, 1);
 
@@ -724,12 +727,16 @@ static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
 {
        struct device *parent = aru->udev->dev.parent;
 
+       complete(&aru->firmware_loading_complete);
+
        /* unbind anything failed */
        if (parent)
                down(&parent->sem);
        device_release_driver(&aru->udev->dev);
        if (parent)
                up(&parent->sem);
+
+       usb_put_dev(aru->udev);
 }
 
 static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
@@ -758,6 +765,8 @@ static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
        if (err)
                goto err_unrx;
 
+       complete(&aru->firmware_loading_complete);
+       usb_put_dev(aru->udev);
        return;
 
  err_unrx:
@@ -855,6 +864,7 @@ static int ar9170_usb_probe(struct usb_interface *intf,
        init_usb_anchor(&aru->tx_pending);
        init_usb_anchor(&aru->tx_submitted);
        init_completion(&aru->cmd_wait);
+       init_completion(&aru->firmware_loading_complete);
        spin_lock_init(&aru->tx_urb_lock);
 
        aru->tx_pending_urbs = 0;
@@ -874,6 +884,7 @@ static int ar9170_usb_probe(struct usb_interface *intf,
        if (err)
                goto err_freehw;
 
+       usb_get_dev(aru->udev);
        return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw",
                                       &aru->udev->dev, GFP_KERNEL, aru,
                                       ar9170_usb_firmware_step2);
@@ -893,6 +904,9 @@ static void ar9170_usb_disconnect(struct usb_interface *intf)
                return;
 
        aru->common.state = AR9170_IDLE;
+
+       wait_for_completion(&aru->firmware_loading_complete);
+
        ar9170_unregister(&aru->common);
        ar9170_usb_cancel_urbs(aru);
 
index a2ce3b169ceb3ea43757716ef03716114678506a..919b06046eb3eb5390550d04a804fef8c434dee2 100644 (file)
@@ -71,6 +71,7 @@ struct ar9170_usb {
        unsigned int tx_pending_urbs;
 
        struct completion cmd_wait;
+       struct completion firmware_loading_complete;
        int readlen;
        u8 *readbuf;
 
index 42284445b75e72beeb6cc68d0356c74cc4ba21fc..dc0786cc26393666f3d63ffdb56b5c4e11c4318f 100644 (file)
@@ -21,6 +21,7 @@
 \*************************************/
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include "ath5k.h"
 #include "reg.h"
 #include "debug.h"
index 8dce0077b02355b3b6f91bdf0aa808cb1091e0c6..3abbe7513ab5602df918ae91d0702a2487c4d706 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/pci.h>
 #include <linux/ethtool.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 
 #include <net/ieee80211_radiotap.h>
 
index 10b52262b23219a5eacdc28ada3dc28abca2032a..67665cdc7afe256822f610968c292dc8031d1549 100644 (file)
@@ -21,6 +21,8 @@
 * EEPROM access functions and helpers *
 \*************************************/
 
+#include <linux/slab.h>
+
 #include "ath5k.h"
 #include "reg.h"
 #include "debug.h"
index eff3323efb4bf82afc965fa30ab83110e1ac6114..68e2bccd90d34418d3b85070b0f7b09ee468a93f 100644 (file)
@@ -23,6 +23,7 @@
 #define _ATH5K_PHY
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "ath5k.h"
 #include "reg.h"
index 42d2a506845a43ea929b0d8159bb12b44bcb5e17..081e0085ed4ce3460c82d2ba8f44eab5a090a4e7 100644 (file)
@@ -14,6 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 #include "ath9k.h"
index 2e767cf22f1ef8bf6f41f07a51addfd2aefe8c33..78b571129c92a57e8cf921f7f02040aa0f47b959 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 #include "hw.h"
index 623c2f884987fbc25502dab79bf06132e84a24c1..3d4d897add6d9bc07f250dcee458633e4ae7355f 100644 (file)
@@ -14,6 +14,8 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "ath9k.h"
 
 static char *dev_info = "ath9k";
index 67ca4e5a60177c848d8c9b73ed472a5094789f62..115e1aeedb592128c615026ed8bc677276fbd91e 100644 (file)
@@ -1532,8 +1532,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
                all_wiphys_idle =  ath9k_all_wiphys_idle(sc);
                ath9k_set_wiphy_idle(aphy, idle);
 
-               if (!idle && all_wiphys_idle)
-                       enable_radio = true;
+               enable_radio = (!idle && all_wiphys_idle);
 
                /*
                 * After we unlock here its possible another wiphy
index c3b59390fe386ac6b6cd7a6f524476805c7636e4..2547b3c4a26cd841efc5cd1fb2aeb00fbd63c0a2 100644 (file)
@@ -39,6 +39,8 @@
  * AR9287 - 11n single-band 1x1 MIMO for USB
  */
 
+#include <linux/slab.h>
+
 #include "hw.h"
 
 /**
index 0e79e58cf4c96fb4704390645b0974516d995828..244e1c6291776dc9f5c0a931ef1cb7cdcbbfb14a 100644 (file)
@@ -15,6 +15,8 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "ath9k.h"
 
 static const struct ath_rate_table ar5416_11na_ratetable = {
index a43fbf84dab9c7c5efc45029a2a0b85a9c0eee11..00c0e21a4af77269fb2b013a3bf25291ce39adc3 100644 (file)
@@ -14,6 +14,8 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/slab.h>
+
 #include "ath9k.h"
 
 struct ath9k_vif_iter_data {
index b2c8207f7bc17790b55c42e18a70e47f9a40320a..294b486bc3ed2043d09fc679a9ad76983e854286 100644 (file)
@@ -1353,25 +1353,6 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
        return htype;
 }
 
-static bool is_pae(struct sk_buff *skb)
-{
-       struct ieee80211_hdr *hdr;
-       __le16 fc;
-
-       hdr = (struct ieee80211_hdr *)skb->data;
-       fc = hdr->frame_control;
-
-       if (ieee80211_is_data(fc)) {
-               if (ieee80211_is_nullfunc(fc) ||
-                   /* Port Access Entity (IEEE 802.1X) */
-                   (skb->protocol == cpu_to_be16(ETH_P_PAE))) {
-                       return true;
-               }
-       }
-
-       return false;
-}
-
 static int get_hw_crypto_keytype(struct sk_buff *skb)
 {
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -1696,7 +1677,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
                        goto tx_done;
                }
 
-               if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && !is_pae(skb)) {
+               if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
                        /*
                         * Try aggregation if it's a unicast data frame
                         * and the destination is HT capable.
index 04abd1f556b78a2863f352da74972b76f6c15a37..00489c40be0cb66ec6993122bc3b2c8793fa1798 100644 (file)
@@ -15,7 +15,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <net/cfg80211.h>
 #include <net/mac80211.h>
 #include "regd.h"
index be7abf8916ad3af2100fc74b902d7f91a09f790b..fa40fdfea719da1b24767550d2d17c932ba10993 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <asm/div64.h>
 
 
index 976104f634a10f9448056233db1057d5f85c8ff3..94e4f1378fc3c5660bd42b008c3e6384768d798d 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <linux/delay.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 
 static struct b43_lo_calib *b43_find_lo_calib(struct b43_txpower_lo_control *lo,
index 1521b1e78d2194309a0b12cd836925b07b9d5a85..9a374ef83a224e151b5dc66c7fb4956dace905de 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/skbuff.h>
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 #include "b43.h"
index 984174bc7b0ff5411b7961f59b494cd8edeafc36..609e7051e01806a015660e029a8eb545e98bb85a 100644 (file)
@@ -24,6 +24,7 @@
 #include "pcmcia.h"
 
 #include <linux/ssb/ssb.h>
+#include <linux/slab.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
index d90217c3a70623cb165af8b1c2f4ef81289ed349..b6428ec16dd638faf0fe167616ab2c9efb21d91a 100644 (file)
@@ -26,6 +26,8 @@
 
 */
 
+#include <linux/slab.h>
+
 #include "b43.h"
 #include "phy_a.h"
 #include "phy_common.h"
index 382826a8da822c49434a2d6028be1544e959f50e..29bf34ced86552cb35ec284cf45d297c2f0479f7 100644 (file)
@@ -33,6 +33,7 @@
 #include "main.h"
 
 #include <linux/bitrev.h>
+#include <linux/slab.h>
 
 
 static const s8 b43_tssi2dbm_g_table[] = {
index 185219e0a55243deed19cb3a6d50c0640d5ccb32..c6afe9d94590f2e15cf66db6d908ded47d94ac92 100644 (file)
@@ -23,6 +23,8 @@
 
 */
 
+#include <linux/slab.h>
+
 #include "b43.h"
 #include "main.h"
 #include "phy_lp.h"
index 795bb1e3345dce2d4756520b875aba514a0c0782..9c7cd282e46c5c9423e9f976f4098a688942f58f 100644 (file)
@@ -23,6 +23,7 @@
 */
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #include "b43.h"
index a6062c3e89a571305ac05106164b59ae00a84443..aa12273ae716482544f71f0733beb8d70c45ff84 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <linux/delay.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 
 static u16 generate_cookie(struct b43_pio_txqueue *q,
index 0d3ac64147a5713e8190b6c01481911a3f35f1d4..4e56b7bbcebd0b46c4a56c7822713b62be29446b 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mmc/card.h>
 #include <linux/mmc/sdio_func.h>
 #include <linux/mmc/sdio_ids.h>
+#include <linux/slab.h>
 #include <linux/ssb/ssb.h>
 
 #include "sdio.h"
index 8b9387c6ff36936d31680e97c8e028ac39e4ba57..e91520d0312e1d18d8b3c944afaa72975686d1d7 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/dst.h>
 
 /* 32bit DMA ops. */
index 1d070be5a678de09584f49adb88fa8da2212b3c9..bb2dd9329aa0fd88ff7f7b2dc85d841e1a193209 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/sched.h>
 #include <linux/skbuff.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <net/dst.h>
 #include <asm/unaligned.h>
 
index aaf227203a98f94dd93854bf936e95ec0c6841d1..35033dd342ce2e7fb63cc31a7bf9a0e3d2810d57 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #include "b43legacy.h"
index 017c0e9c37ef4dc6f67f3884a1d084675ae3fd9e..b033b0ed4ca099dc63a9dbea167fdb88fed64c2d 100644 (file)
@@ -29,6 +29,7 @@
 #include "xmit.h"
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 
 static void tx_start(struct b43legacy_pioqueue *queue)
index 3816df96a663e0f544dcf6a53694d8bcf1c33895..f4c56121d3878307f63fa9552b3e084ae89af130 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <net/lib80211.h>
 #include <linux/if_arp.h>
 
index 90108b698f11acfe43d572dff28165d571bcfe78..c34a3b7f12924db3cbc2c75b3b173bcfc4da3d73 100644 (file)
@@ -1,3 +1,5 @@
+#include <linux/slab.h>
+
 #include "hostap_80211.h"
 #include "hostap_common.h"
 #include "hostap_wlan.h"
index a2a203c90ba3da30dae1d041df49a3b8c683a295..7e72ac1de49b96b4abb8672240e26d3c3f121eb4 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/random.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 
 #include "hostap_wlan.h"
 #include "hostap.h"
index d19748d90aaf42d423936c0b8906d9ea5d11a6bc..a36501dbbe02471ecdb3eb58f455134b0ac130d4 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/if.h>
+#include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/timer.h>
 #include <linux/skbuff.h>
index 4dfb40a84c96ed9d54d83ef8b091bafabc28b215..d737091cf6acc1c4abd45d0a8d058e3e3b9799d3 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <linux/if_arp.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "hostap_wlan.h"
 #include "hostap.h"
 #include "hostap_ap.h"
index 9419cebca8a582f8d9dab12bc442a67409ddebea..9a082308a9d467ae5e431b5ffb716df9f944d67a 100644 (file)
@@ -1,5 +1,6 @@
 /* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/ethtool.h>
index 4d97ae37499bd7a64e9368c8d48d4d8c4bd0d8ca..d24dc7dc072328fcecab649193ed4cbad0c17caa 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/if.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
index fc04ccdc5befa36f3126c4e2a0b888b6d6d7b700..33e79037770b38673e2e5c0fa18ec39a4619cba5 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/if.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
index 5c7aa1b1eb566e0bac134294874ffcadd3366a39..8d72e3d1958680bfaa9dbb79974cabf889e7b0ac 100644 (file)
@@ -31,6 +31,7 @@
 ******************************************************************************/
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "ipw2200.h"
 
 
index 65e8c175a4a0c356d5b3e5879dddd654ddb24409..c9fe3c99cb003c087729b12380b16df014827f8b 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/netdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
 #include <linux/wireless.h>
index 282b1f7ff1e9543d937308ba3275f0a232c50d0d..39a34da52d52858d89c439067066cfa2110ae23a 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/errno.h>
 #include <linux/if_arp.h>
 #include <linux/in6.h>
+#include <linux/gfp.h>
 #include <linux/in.h>
 #include <linux/ip.h>
 #include <linux/kernel.h>
@@ -24,7 +25,6 @@
 #include <linux/netdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
 #include <linux/wireless.h>
index 4d89f66f53b2b0233eaae018b969d7504c0ef53f..3633c6682e4967575ef040ad620fbb8550531c35 100644 (file)
@@ -31,6 +31,7 @@
 ******************************************************************************/
 
 #include <linux/kmod.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/jiffies.h>
 
index 47909f94271e1d41ac73a7c90921f6906b2d45ba..902c4d4293e9634bbcfd135c880c79d7a3b27772 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/wireless.h>
 #include <net/mac80211.h>
 
index e0678d92105537fc169eee73c12628f4ca4cd97b..0728054a22d4f15f7cbfa9801300fb598bee7fa0 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
index 1bd2cd8360262f265ec329a174a9f4fa23476442..8972166386cb5f79f1c214dda5f8e9a1164e341f 100644 (file)
@@ -2015,7 +2015,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
                        IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
                                           "%d index %d\n", scd_ssn , index);
                        freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-                       iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
+                       if (qc)
+                               iwl_free_tfds_in_queue(priv, sta_id,
+                                                      tid, freed);
 
                        if (priv->mac80211_registered &&
                            (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
@@ -2042,13 +2044,14 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
 
                freed = iwl_tx_queue_reclaim(priv, txq_id, index);
                if (qc && likely(sta_id != IWL_INVALID_STATION))
-                       priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+                       iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
+               else if (sta_id == IWL_INVALID_STATION)
+                       IWL_DEBUG_TX_REPLY(priv, "Station not known\n");
 
                if (priv->mac80211_registered &&
                    (iwl_queue_space(&txq->q) > txq->q.low_mark))
                        iwl_wake_queue(priv, txq_id);
        }
-
        if (qc && likely(sta_id != IWL_INVALID_STATION))
                iwl_txq_check_empty(priv, sta_id, tid, txq_id);
 
index c4844adff92a3a9adc923493975eb8ea50c56f65..92b3e64fc14dd941f80831a107d958740e87c662 100644 (file)
@@ -259,7 +259,7 @@ static struct iwl_lib_ops iwl6000_lib = {
                        EEPROM_5000_REG_BAND_3_CHANNELS,
                        EEPROM_5000_REG_BAND_4_CHANNELS,
                        EEPROM_5000_REG_BAND_5_CHANNELS,
-                       EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
+                       EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_5000_REG_BAND_52_HT40_CHANNELS
                },
                .verify_signature  = iwlcore_eeprom_verify_signature,
@@ -323,7 +323,7 @@ static struct iwl_lib_ops iwl6050_lib = {
                        EEPROM_5000_REG_BAND_3_CHANNELS,
                        EEPROM_5000_REG_BAND_4_CHANNELS,
                        EEPROM_5000_REG_BAND_5_CHANNELS,
-                       EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
+                       EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_5000_REG_BAND_52_HT40_CHANNELS
                },
                .verify_signature  = iwlcore_eeprom_verify_signature,
index 8bf7c20b9d3928b4aba502062800ee006092aae9..1460116d329f2c65b39d88ed295069295648b1f2 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/wireless.h>
 #include <net/mac80211.h>
 
@@ -345,6 +346,17 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
               !!(rate_n_flags & RATE_MCS_ANT_C_MSK);
 }
 
+/*
+ * Static function to get the expected throughput from an iwl_scale_tbl_info
+ * that wraps a NULL pointer check
+ */
+static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
+{
+       if (tbl->expected_tpt)
+               return tbl->expected_tpt[rs_index];
+       return 0;
+}
+
 /**
  * rs_collect_tx_data - Update the success/failure sliding window
  *
@@ -352,19 +364,21 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
  * at this rate.  window->data contains the bitmask of successful
  * packets.
  */
-static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
-                             int scale_index, s32 tpt, int attempts,
-                             int successes)
+static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
+                             int scale_index, int attempts, int successes)
 {
        struct iwl_rate_scale_data *window = NULL;
        static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
-       s32 fail_count;
+       s32 fail_count, tpt;
 
        if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
                return -EINVAL;
 
        /* Select window for current tx bit rate */
-       window = &(windows[scale_index]);
+       window = &(tbl->win[scale_index]);
+
+       /* Get expected throughput */
+       tpt = get_expected_tpt(tbl, scale_index);
 
        /*
         * Keep track of only the latest 62 tx frame attempts in this rate's
@@ -738,16 +752,6 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a,
        return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&
                (a->is_SGI == b->is_SGI);
 }
-/*
- * Static function to get the expected throughput from an iwl_scale_tbl_info
- * that wraps a NULL pointer check
- */
-static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
-{
-       if (tbl->expected_tpt)
-               return tbl->expected_tpt[rs_index];
-       return 0;
-}
 
 /*
  * mac80211 sends us Tx status
@@ -764,12 +768,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct iwl_priv *priv = (struct iwl_priv *)priv_r;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct iwl_rate_scale_data *window = NULL;
        enum mac80211_rate_control_flags mac_flags;
        u32 tx_rate;
        struct iwl_scale_tbl_info tbl_type;
-       struct iwl_scale_tbl_info *curr_tbl, *other_tbl;
-       s32 tpt = 0;
+       struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
 
        IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
 
@@ -852,7 +854,6 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
                IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
                return;
        }
-       window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
 
        /*
         * Updating the frame history depends on whether packets were
@@ -865,8 +866,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
                tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
                rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type,
                                &rs_index);
-               tpt = get_expected_tpt(curr_tbl, rs_index);
-               rs_collect_tx_data(window, rs_index, tpt,
+               rs_collect_tx_data(curr_tbl, rs_index,
                                   info->status.ampdu_ack_len,
                                   info->status.ampdu_ack_map);
 
@@ -896,19 +896,13 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
                         * table as active/search.
                         */
                        if (table_type_matches(&tbl_type, curr_tbl))
-                               tpt = get_expected_tpt(curr_tbl, rs_index);
+                               tmp_tbl = curr_tbl;
                        else if (table_type_matches(&tbl_type, other_tbl))
-                               tpt = get_expected_tpt(other_tbl, rs_index);
+                               tmp_tbl = other_tbl;
                        else
                                continue;
-
-                       /* Constants mean 1 transmission, 0 successes */
-                       if (i < retries)
-                               rs_collect_tx_data(window, rs_index, tpt, 1,
-                                               0);
-                       else
-                               rs_collect_tx_data(window, rs_index, tpt, 1,
-                                               legacy_success);
+                       rs_collect_tx_data(tmp_tbl, rs_index, 1,
+                                          i < retries ? 0 : legacy_success);
                }
 
                /* Update success/fail counts if not searching for new mode */
index 818367b57babfa0d3b00a0b173245e48cb1bf238..bdff56583e114ea6120a21976be0dd9559bdc765 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
@@ -1258,7 +1259,15 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        /* Ack/clear/reset pending uCode interrupts.
         * Note:  Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
         */
-       iwl_write32(priv, CSR_INT, priv->inta);
+       /* There is a hardware bug in the interrupt mask function that some
+        * interrupts (i.e. CSR_INT_BIT_SCD) can still be generated even if
+        * they are disabled in the CSR_INT_MASK register. Furthermore the
+        * ICT interrupt handling mechanism has another bug that might cause
+        * these unmasked interrupts fail to be detected. We workaround the
+        * hardware bugs here by ACKing all the possible interrupts so that
+        * interrupt coalescing can still be achieved.
+        */
+       iwl_write32(priv, CSR_INT, priv->inta | ~priv->inta_mask);
 
        inta = priv->inta;
 
@@ -2644,7 +2653,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv)
                BIT(NL80211_IFTYPE_STATION) |
                BIT(NL80211_IFTYPE_ADHOC);
 
-       hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY |
+       hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
                            WIPHY_FLAG_DISABLE_BEACON_HINTS;
 
        /*
@@ -3322,6 +3331,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
 
        cancel_delayed_work_sync(&priv->init_alive_start);
        cancel_delayed_work(&priv->scan_check);
+       cancel_work_sync(&priv->start_internal_scan);
        cancel_delayed_work(&priv->alive_start);
        cancel_work_sync(&priv->beacon_update);
        del_timer_sync(&priv->statistics_periodic);
index 845831ac053e2fa4bb320abb5024b87d4a5632b9..8b516c5ff0bb5f2ba4ad8143aa159968478877bc 100644 (file)
@@ -60,6 +60,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
+#include <linux/slab.h>
 #include <net/mac80211.h>
 
 #include "iwl-dev.h"
@@ -807,6 +808,18 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
                }
        }
 
+       /*
+        * The above algorithm sometimes fails when the ucode
+        * reports 0 for all chains. It's not clear why that
+        * happens to start with, but it is then causing trouble
+        * because this can make us enable more chains than the
+        * hardware really has.
+        *
+        * To be safe, simply mask out any chains that we know
+        * are not on the device.
+        */
+       active_chains &= priv->hw_params.valid_rx_ant;
+
        num_tx_chains = 0;
        for (i = 0; i < NUM_RX_CHAINS; i++) {
                /* loops on all the bits of
index 6383d9f8c9b3e561cadfaf5dd322e532b364a192..f4e59ae07f8e5a70c0d4e39ab57af34b64bf753d 100644 (file)
@@ -2621,7 +2621,9 @@ struct iwl_ssid_ie {
 #define PROBE_OPTION_MAX_3945          4
 #define PROBE_OPTION_MAX               20
 #define TX_CMD_LIFE_TIME_INFINITE      cpu_to_le32(0xFFFFFFFF)
-#define IWL_GOOD_CRC_TH                        cpu_to_le16(1)
+#define IWL_GOOD_CRC_TH_DISABLED       0
+#define IWL_GOOD_CRC_TH_DEFAULT                cpu_to_le16(1)
+#define IWL_GOOD_CRC_TH_NEVER          cpu_to_le16(0xffff)
 #define IWL_MAX_SCAN_SIZE 1024
 #define IWL_MAX_CMD_SIZE 4096
 #define IWL_MAX_PROBE_REQUEST          200
index 112149e9b31e40d9951ddd25581b2df1c2a1e780..049b652bcb5e61dc2c656248c455d0d2ec559f2a 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/etherdevice.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 
 #include "iwl-eeprom.h"
@@ -307,10 +308,13 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       /* Allocate and init all Tx and Command queues */
-       ret = iwl_txq_ctx_reset(priv);
-       if (ret)
-               return ret;
+       /* Allocate or reset and init all Tx and Command queues */
+       if (!priv->txq) {
+               ret = iwl_txq_ctx_alloc(priv);
+               if (ret)
+                       return ret;
+       } else
+               iwl_txq_ctx_reset(priv);
 
        set_bit(STATUS_INIT, &priv->status);
 
@@ -3354,7 +3358,6 @@ static void iwl_force_rf_reset(struct iwl_priv *priv)
         */
        IWL_DEBUG_INFO(priv, "perform radio reset.\n");
        iwl_internal_short_hw_scan(priv);
-       return;
 }
 
 
index 4ef7739f9e8e614c99293b9904039ad7bfa965cc..36940a9ec6b93442021af5b2f1053a607b5bd50f 100644 (file)
@@ -442,7 +442,8 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
 /*****************************************************
 * TX
 ******************************************************/
-int iwl_txq_ctx_reset(struct iwl_priv *priv);
+int iwl_txq_ctx_alloc(struct iwl_priv *priv);
+void iwl_txq_ctx_reset(struct iwl_priv *priv);
 void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
 int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
                                 struct iwl_tx_queue *txq,
@@ -456,6 +457,8 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
 void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
 int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
                      int slots_num, u32 txq_id);
+void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+                       int slots_num, u32 txq_id);
 void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
 int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
 int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
@@ -503,7 +506,7 @@ void iwl_init_scan_params(struct iwl_priv *priv);
 int iwl_scan_cancel(struct iwl_priv *priv);
 int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
 int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
-int iwl_internal_short_hw_scan(struct iwl_priv *priv);
+void iwl_internal_short_hw_scan(struct iwl_priv *priv);
 int iwl_force_reset(struct iwl_priv *priv, int mode);
 u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
                       const u8 *ie, int ie_len, int left);
index 7bf44f1467993d911d3f95bd18892cea408306aa..b6e1b0ebe230075292d5c2f4676f7bd9685e086d 100644 (file)
@@ -26,6 +26,7 @@
  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  *****************************************************************************/
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/debugfs.h>
index 6054c5fba0c1da74e9eee3dee878a40fbdbbe3f7..ef1720a852e9954a2f42b32b5e1704115e68ce7e 100644 (file)
@@ -1296,6 +1296,7 @@ struct iwl_priv {
        struct work_struct tt_work;
        struct work_struct ct_enter;
        struct work_struct ct_exit;
+       struct work_struct start_internal_scan;
 
        struct tasklet_struct irq_tasklet;
 
index 36580d8d8b8db4cbb6e5b38b2242d69ec8153045..2ffc2edbf4f08c0e189a09802f62080e31281aca 100644 (file)
@@ -28,6 +28,8 @@
 
 /* sparse doesn't like tracepoint macros */
 #ifndef __CHECKER__
+#include "iwl-dev.h"
+
 #define CREATE_TRACE_POINTS
 #include "iwl-devtrace.h"
 
index ff4d012ce2600dfbaf5ac7317138daa628e15880..ae7319bb3a9973f675e409d8e7c64968069adbcd 100644 (file)
@@ -28,7 +28,6 @@
 #define __IWLWIFI_DEVICE_TRACE
 
 #include <linux/tracepoint.h>
-#include "iwl-dev.h"
 
 #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__)
 #undef TRACE_EVENT
index fd37152abae3afe3f393e99ce93e929e36f50576..fb5bb487f3bc9991bbfd63ecb645454fae161202 100644 (file)
@@ -63,6 +63,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #include <net/mac80211.h>
index 4e1ba824dc50521ba84ebe191bc25da1fb688235..8171c701e4e15e53610a0068e8d79bfeb72c0ec2 100644 (file)
@@ -203,6 +203,10 @@ struct iwl_eeprom_enhanced_txpwr {
 #define EEPROM_5000_REG_BAND_52_HT40_CHANNELS  ((0x92)\
                | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 22  bytes */
 
+/* 6000 regulatory - indirect access */
+#define EEPROM_6000_REG_BAND_24_HT40_CHANNELS  ((0x80)\
+               | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 14  bytes */
+
 /* 6000 and up regulatory tx power - indirect access */
 /* max. elements per section */
 #define EEPROM_MAX_TXPOWER_SECTION_ELEMENTS    (8)
index c719baf2585a49583f2cef7a4b02107e044830a5..16eb3ced9b30c1f9301f0327b31487322c2248c3 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <linux/io.h>
 
+#include "iwl-dev.h"
 #include "iwl-debug.h"
 #include "iwl-devtrace.h"
 
index 1a1a9f081cc712288b552e49f667601bc7e5d5a9..548dac2f6a960363b5046f1df0e8f5cf034941ae 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #include <net/mac80211.h>
index df257bc15f495c02fff299ef1c91f46836772419..e5eb339107ddfd6ef65c838a14a9d2cbf9b2ae49 100644 (file)
@@ -28,6 +28,7 @@
  *****************************************************************************/
 
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 #include <asm/unaligned.h>
 #include "iwl-eeprom.h"
index bd2f7c420563611bbba6437c7fb51b9134417164..741e65ec8301dce638b5952378d832a0ef7457c0 100644 (file)
@@ -25,6 +25,7 @@
  *  Intel Linux Wireless <ilw@linux.intel.com>
  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  *****************************************************************************/
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/etherdevice.h>
 #include <net/mac80211.h>
@@ -469,6 +470,8 @@ EXPORT_SYMBOL(iwl_init_scan_params);
 
 static int iwl_scan_initiate(struct iwl_priv *priv)
 {
+       WARN_ON(!mutex_is_locked(&priv->mutex));
+
        IWL_DEBUG_INFO(priv, "Starting scan...\n");
        set_bit(STATUS_SCANNING, &priv->status);
        priv->is_internal_short_scan = false;
@@ -546,24 +549,31 @@ EXPORT_SYMBOL(iwl_mac_hw_scan);
  * internal short scan, this function should only been called while associated.
  * It will reset and tune the radio to prevent possible RF related problem
  */
-int iwl_internal_short_hw_scan(struct iwl_priv *priv)
+void iwl_internal_short_hw_scan(struct iwl_priv *priv)
 {
-       int ret = 0;
+       queue_work(priv->workqueue, &priv->start_internal_scan);
+}
+
+static void iwl_bg_start_internal_scan(struct work_struct *work)
+{
+       struct iwl_priv *priv =
+               container_of(work, struct iwl_priv, start_internal_scan);
+
+       mutex_lock(&priv->mutex);
 
        if (!iwl_is_ready_rf(priv)) {
-               ret = -EIO;
                IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
-               goto out;
+               goto unlock;
        }
+
        if (test_bit(STATUS_SCANNING, &priv->status)) {
                IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
-               ret = -EAGAIN;
-               goto out;
+               goto unlock;
        }
+
        if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
                IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
-               ret = -EAGAIN;
-               goto out;
+               goto unlock;
        }
 
        priv->scan_bands = 0;
@@ -576,9 +586,8 @@ int iwl_internal_short_hw_scan(struct iwl_priv *priv)
        set_bit(STATUS_SCANNING, &priv->status);
        priv->is_internal_short_scan = true;
        queue_work(priv->workqueue, &priv->request_scan);
-
-out:
-       return ret;
+ unlock:
+       mutex_unlock(&priv->mutex);
 }
 EXPORT_SYMBOL(iwl_internal_short_hw_scan);
 
@@ -804,16 +813,29 @@ static void iwl_bg_request_scan(struct work_struct *data)
                        rate = IWL_RATE_1M_PLCP;
                        rate_flags = RATE_MCS_CCK_MSK;
                }
-               scan->good_CRC_th = 0;
+               scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED;
        } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
                band = IEEE80211_BAND_5GHZ;
                rate = IWL_RATE_6M_PLCP;
                /*
-                * If active scaning is requested but a certain channel
-                * is marked passive, we can do active scanning if we
-                * detect transmissions.
+                * If active scanning is requested but a certain channel is
+                * marked passive, we can do active scanning if we detect
+                * transmissions.
+                *
+                * There is an issue with some firmware versions that triggers
+                * a sysassert on a "good CRC threshold" of zero (== disabled),
+                * on a radar channel even though this means that we should NOT
+                * send probes.
+                *
+                * The "good CRC threshold" is the number of frames that we
+                * need to receive during our dwell time on a channel before
+                * sending out probes -- setting this to a huge value will
+                * mean we never reach it, but at the same time work around
+                * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
+                * here instead of IWL_GOOD_CRC_TH_DISABLED.
                 */
-               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
+               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+                                               IWL_GOOD_CRC_TH_NEVER;
 
                /* Force use of chains B and C (0x6) for scan Rx for 4965
                 * Avoid A (0x1) because of its off-channel reception on A-band.
@@ -964,6 +986,7 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
        INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
        INIT_WORK(&priv->request_scan, iwl_bg_request_scan);
        INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
+       INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan);
        INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
 }
 EXPORT_SYMBOL(iwl_setup_scan_deferred_work);
index 1ed5206721ecb587688bbd8b463f172e0f5d2de1..8dd0c036d547d4abca46d9bd80eeaea4c5334e12 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <linux/etherdevice.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
@@ -124,7 +125,7 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
        if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
                priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
        else {
-               IWL_ERR(priv, "free more than tfds_in_queue (%u:%d)\n",
+               IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n",
                        priv->stations[sta_id].tid[tid].tfds_in_queue,
                        freed);
                priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
@@ -193,10 +194,34 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
        struct iwl_queue *q = &txq->q;
        struct device *dev = &priv->pci_dev->dev;
        int i;
+       bool huge = false;
 
        if (q->n_bd == 0)
                return;
 
+       for (; q->read_ptr != q->write_ptr;
+            q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+               /* we have no way to tell if it is a huge cmd ATM */
+               i = get_cmd_index(q, q->read_ptr, 0);
+
+               if (txq->meta[i].flags & CMD_SIZE_HUGE) {
+                       huge = true;
+                       continue;
+               }
+
+               pci_unmap_single(priv->pci_dev,
+                                pci_unmap_addr(&txq->meta[i], mapping),
+                                pci_unmap_len(&txq->meta[i], len),
+                                PCI_DMA_BIDIRECTIONAL);
+       }
+       if (huge) {
+               i = q->n_window;
+               pci_unmap_single(priv->pci_dev,
+                                pci_unmap_addr(&txq->meta[i], mapping),
+                                pci_unmap_len(&txq->meta[i], len),
+                                PCI_DMA_BIDIRECTIONAL);
+       }
+
        /* De-alloc array of command/tx buffers */
        for (i = 0; i <= TFD_CMD_SLOTS; i++)
                kfree(txq->cmd[i]);
@@ -409,6 +434,26 @@ out_free_arrays:
 }
 EXPORT_SYMBOL(iwl_tx_queue_init);
 
+void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+                       int slots_num, u32 txq_id)
+{
+       int actual_slots = slots_num;
+
+       if (txq_id == IWL_CMD_QUEUE_NUM)
+               actual_slots++;
+
+       memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots);
+
+       txq->need_update = 0;
+
+       /* Initialize queue's high/low-water marks, and head/tail indexes */
+       iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+
+       /* Tell device where to find queue */
+       priv->cfg->ops->lib->txq_init(priv, txq);
+}
+EXPORT_SYMBOL(iwl_tx_queue_reset);
+
 /**
  * iwl_hw_txq_ctx_free - Free TXQ Context
  *
@@ -420,8 +465,7 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
 
        /* Tx queues */
        if (priv->txq) {
-               for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
-                    txq_id++)
+               for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
                        if (txq_id == IWL_CMD_QUEUE_NUM)
                                iwl_cmd_queue_free(priv);
                        else
@@ -437,15 +481,15 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
 EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
 
 /**
- * iwl_txq_ctx_reset - Reset TX queue context
- * Destroys all DMA structures and initialize them again
+ * iwl_txq_ctx_alloc - allocate TX queue context
+ * Allocate all Tx DMA structures and initialize them
  *
  * @param priv
  * @return error code
  */
-int iwl_txq_ctx_reset(struct iwl_priv *priv)
+int iwl_txq_ctx_alloc(struct iwl_priv *priv)
 {
-       int ret = 0;
+       int ret;
        int txq_id, slots_num;
        unsigned long flags;
 
@@ -503,8 +547,31 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
        return ret;
 }
 
+void iwl_txq_ctx_reset(struct iwl_priv *priv)
+{
+       int txq_id, slots_num;
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       /* Turn off all Tx DMA fifos */
+       priv->cfg->ops->lib->txq_set_sched(priv, 0);
+
+       /* Tell NIC where to find the "keep warm" buffer */
+       iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       /* Alloc and init all Tx queues, including the command queue (#4) */
+       for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
+               slots_num = txq_id == IWL_CMD_QUEUE_NUM ?
+                           TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
+               iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id);
+       }
+}
+
 /**
- * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory
+ * iwl_txq_ctx_stop - Stop all Tx DMA channels
  */
 void iwl_txq_ctx_stop(struct iwl_priv *priv)
 {
@@ -524,9 +591,6 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv)
                                    1000);
        }
        spin_unlock_irqrestore(&priv->lock, flags);
-
-       /* Deallocate memory for all Tx queues */
-       iwl_hw_txq_ctx_free(priv);
 }
 EXPORT_SYMBOL(iwl_txq_ctx_stop);
 
@@ -1049,6 +1113,14 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 
        spin_lock_irqsave(&priv->hcmd_lock, flags);
 
+       /* If this is a huge cmd, mark the huge flag also on the meta.flags
+        * of the _original_ cmd. This is used for DMA mapping clean up.
+        */
+       if (cmd->flags & CMD_SIZE_HUGE) {
+               idx = get_cmd_index(q, q->write_ptr, 0);
+               txq->meta[idx].flags = CMD_SIZE_HUGE;
+       }
+
        idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
        out_cmd = txq->cmd[idx];
        out_meta = &txq->meta[idx];
@@ -1226,6 +1298,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
        bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
        struct iwl_device_cmd *cmd;
        struct iwl_cmd_meta *meta;
+       struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
 
        /* If a Tx command is being handled and it isn't in the actual
         * command queue then there a command routing bug has been introduced
@@ -1239,9 +1312,17 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
                return;
        }
 
-       cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
-       cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
-       meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index];
+       /* If this is a huge cmd, clear the huge flag on the meta.flags
+        * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap
+        * the DMA buffer for the scan (huge) command.
+        */
+       if (huge) {
+               cmd_index = get_cmd_index(&txq->q, index, 0);
+               txq->meta[cmd_index].flags = 0;
+       }
+       cmd_index = get_cmd_index(&txq->q, index, huge);
+       cmd = txq->cmd[cmd_index];
+       meta = &txq->meta[cmd_index];
 
        pci_unmap_single(priv->pci_dev,
                         pci_unmap_addr(meta, mapping),
@@ -1263,6 +1344,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
                               get_cmd_string(cmd->hdr.cmd));
                wake_up_interruptible(&priv->wait_command_queue);
        }
+       meta->flags = 0;
 }
 EXPORT_SYMBOL(iwl_tx_cmd_complete);
 
index 54daa38ecba3b1475bcff226be08b8be1375f9d1..b74a56c48d2698eeda2007afa0db58b9383526fd 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
@@ -1955,7 +1956,7 @@ static void iwl3945_init_hw_rates(struct iwl_priv *priv,
 {
        int i;
 
-       for (i = 0; i < IWL_RATE_COUNT; i++) {
+       for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
                rates[i].bitrate = iwl3945_rates[i].ieee * 5;
                rates[i].hw_value = i; /* Rate scaling will work on indexes */
                rates[i].hw_value_short = i;
@@ -2966,7 +2967,8 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
                 * is marked passive, we can do active scanning if we
                 * detect transmissions.
                 */
-               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
+               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+                                               IWL_GOOD_CRC_TH_DISABLED;
                band = IEEE80211_BAND_5GHZ;
        } else {
                IWL_WARN(priv, "Invalid scan band count\n");
@@ -3921,7 +3923,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
                BIT(NL80211_IFTYPE_STATION) |
                BIT(NL80211_IFTYPE_ADHOC);
 
-       hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY |
+       hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
                            WIPHY_FLAG_DISABLE_BEACON_HINTS;
 
        hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;
index 7c4f44a9c3e6b2a8429fe168a08ce53588feb9c8..a1d45cce0ebcab1f7b92568cafacf0dea4537014 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
 #include <linux/ieee80211.h>
+#include <linux/slab.h>
 #include <net/cfg80211.h>
 
 #include "iwm.h"
index 1e41ad0fcad5c8cd5989dcadf0fa1345e6634dc5..42df7262f9f7391d1c71faed6193ea3066052428 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/etherdevice.h>
 #include <linux/ieee80211.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include "iwm.h"
 #include "bus.h"
index c29c994de0e252867eeba263a032fca5b4982f70..cbb81befdb5596ed85eb3af77fd84a095d777bbb 100644 (file)
@@ -21,6 +21,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/bitops.h>
 #include <linux/debugfs.h>
index 8091421ee5e5da1d1a94595f89d147fff1e62f52..e80e776b74f78a35aebd708a6da2d38416fa8b73 100644 (file)
@@ -37,6 +37,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include "iwm.h"
 #include "umac.h"
index d13c8853ee8281048ac836cd26f2f2c5ca8303f1..229de990379c151b5b1a31c2434b92a7b488bc31 100644 (file)
@@ -98,6 +98,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 
 #include "iwm.h"
 #include "bus.h"
index 7f34d6dd3c41a8158055798c665293aada555419..23856d359e123b40ce080a2f6f7511c3fcc258bd 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/sched.h>
 #include <linux/ieee80211.h>
 #include <linux/wireless.h>
+#include <linux/slab.h>
 
 #include "iwm.h"
 #include "debug.h"
index c4c0d23c63ecbcefc6a8b7896849bbd779ece0dc..13a69ebf2a94cbe67834f5dd9dec9c752e6deaf2 100644 (file)
@@ -46,6 +46,7 @@
  *              -> sdio_disable_func()
  */
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 
 #include "iwm.h"
 #include "commands.h"
index 8456b4dbd14694dd22fbbfad751a07daeeac8533..3257d4fad835a03c3cd45e01abca00b60f453142 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/ieee80211.h>
 #include <linux/if_arp.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <net/iw_handler.h>
 
 #include "iwm.h"
index a7ec7eac913796576a191653816663c4198232cb..1eafd6dec3fd1536766983f8c5a67ef994cbb0a2 100644 (file)
@@ -63,6 +63,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/debugfs.h>
 #include <linux/mmc/sdio_ids.h>
index 55905f02309c1d2a41fbf4e9022fdcbca49b8e6f..f6a02f123f31b182927b2071627eb7de274e372e 100644 (file)
@@ -64,6 +64,7 @@
  * (i.e. half of the max size). [iwm_tx_worker]
  */
 
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/ieee80211.h>
index f03d5e4e59c31c1da78c271d4665f158825c712f..12a2ef9dacea9aca87c59f0cd8d41b2d8732d6c1 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/etherdevice.h>
 #include <linux/ieee80211.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 #include <net/lib80211.h>
 
 #include "assoc.h"
index 4396dccd12ac127b27dda8134e1edefccd00324a..ce7bec402a33bbc885647b733d0e00dff50c6022 100644 (file)
@@ -6,6 +6,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <net/cfg80211.h>
 
 #include "cfg.h"
@@ -172,6 +173,8 @@ int lbs_cfg_register(struct lbs_private *priv)
        if (ret < 0)
                lbs_pr_err("cannot register wiphy device\n");
 
+       priv->wiphy_registered = true;
+
        ret = register_netdev(priv->dev);
        if (ret)
                lbs_pr_err("cannot register network device\n");
@@ -190,9 +193,11 @@ void lbs_cfg_free(struct lbs_private *priv)
        if (!wdev)
                return;
 
-       if (wdev->wiphy) {
+       if (priv->wiphy_registered)
                wiphy_unregister(wdev->wiphy);
+
+       if (wdev->wiphy)
                wiphy_free(wdev->wiphy);
-       }
+
        kfree(wdev);
 }
index 82371ef395241901d175ea73ed6dddfa755d5ff6..cdb9b9650d73aaf1de0114966e398defa4cae8d1 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/kfifo.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include "host.h"
 #include "decl.h"
index e7470442f76b5852bebf6661622d98f7a4dd772b..88f7131d66e9cba7e62f6a46076a2878a3c05716 100644 (file)
@@ -2,6 +2,7 @@
   * This file contains the handling of command
   * responses as well as events generated by firmware.
   */
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/if_arp.h>
index 587b0cb0088da57baa26be6fe34059bf0aeac670..a48ccaffb288a785c78c944953943cf5296eed9b 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/delay.h>
 #include <linux/mm.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <net/iw_handler.h>
 #include <net/lib80211.h>
 
index 6977ee82021411ecebba130a2a10c6b5c40992df..6875e1498bd57e36f54e826c763bb041a9bd3283 100644 (file)
@@ -36,6 +36,7 @@ struct lbs_private {
 
        /* CFG80211 */
        struct wireless_dev *wdev;
+       bool wiphy_registered;
 
        /* Mesh */
        struct net_device *mesh_dev; /* Virtual device */
index 1f6cb58dd66c08051a78f4b081f92f8790d65c95..6d55439a7b97a59f32a309cc43a35ca7484b7178 100644 (file)
@@ -22,6 +22,7 @@
 */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
index 7a73f625273ba7730aac480e377a85df64161aa5..7d1a3c6b6ce0cd0f86b05d7a8959bafcf6d97feb 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <linux/kernel.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/netdevice.h>
 #include <linux/delay.h>
index 3ea03f259ee764c864b29fc819917f7750d4c2ae..fe3f08028eb3a07881ea62bc33cc34b931d34883 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/list.h>
 #include <linux/netdevice.h>
 #include <linux/semaphore.h>
+#include <linux/slab.h>
 #include <linux/spi/libertas_spi.h>
 #include <linux/spi/spi.h>
 
index 65e174595d12f89bbd8fcdc2fb1ae9ba9d1a6b01..fcea5741ba62b9c295cea309de05f21fb9f285e9 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #ifdef CONFIG_OLPC
index 28a1c9d1627a7cb0a73c36d07b25d594d17d00d3..598080414b173654f25fb6d4767298b23462b865 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kfifo.h>
 #include <linux/stddef.h>
 #include <linux/ieee80211.h>
+#include <linux/slab.h>
 #include <net/iw_handler.h>
 #include <net/cfg80211.h>
 
index 2daf8ffdb7e18ee8ef0ee9d593b51d4c2b8cb8cd..784dae7147055b64b91821b5366887e4c72c6bb0 100644 (file)
@@ -2,6 +2,7 @@
   * This file contains the handling of RX in wlan driver.
   */
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #include "host.h"
index 220361e69cd3adc7a8a2f680457b49cec2711aaa..24cd54b3a8060955ec7138caf30ce4c95aa5416c 100644 (file)
@@ -4,6 +4,7 @@
   * IOCTL handlers as well as command preperation and response routines
   *  for sending scan commands to the firmware.
   */
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/etherdevice.h>
index 71f88a08e0906200b6053fcb5875dbeed91da894..9b555884b08a99dd1c936f49245549a5b87266db 100644 (file)
@@ -2,6 +2,7 @@
   * This file contains ioctl functions
   */
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/if.h>
 #include <linux/if_arp.h>
index 28790e03dc43ef797a2150d9cbb48a1afdf99a76..b620daf59ef7fa3927c3e323779d70d3ec4e49bd 100644 (file)
@@ -7,6 +7,8 @@
  *  the Free Software Foundation; either version 2 of the License, or (at
  *  your option) any later version.
  */
+#include <linux/slab.h>
+
 #include "libertas_tf.h"
 
 static const struct channel_range channel_ranges[] = {
index 3691c307e6741950f499889756c746fb37f73178..8cc9db60c14b5c8e52fe8183feac773406cdcbc1 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #define DRV_NAME "lbtf_usb"
index 6ab30033c26c07fff18b1c54a0fc5d1bd19cca82..7945ff5aa3345fc5013ed7942878b598483482b4 100644 (file)
@@ -7,6 +7,8 @@
  *  the Free Software Foundation; either version 2 of the License, or (at
  *  your option) any later version.
  */
+#include <linux/slab.h>
+
 #include "libertas_tf.h"
 #include "linux/etherdevice.h"
 
index 6ea77e95277ba52d4b04fe58ef38bf76ff16bba6..7cd5f56662fcfe1176deeeffc2a010b7ed843a3e 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <net/dst.h>
 #include <net/xfrm.h>
index ac65e13eb0de8ea31fed54c02dd42add8528b85f..12fdcb25fd382dfc245aafd85dcb462ebdfa8f77 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/completion.h>
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
@@ -3851,6 +3852,7 @@ MODULE_FIRMWARE("mwl8k/helper_8366.fw");
 MODULE_FIRMWARE("mwl8k/fmimage_8366.fw");
 
 static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
+       { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },
        { PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, },
        { PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, },
        { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, },
index cfa72962052bca7db982368db0441233743b80c7..5ea0f7cf85b1d2f8653eb0941f2a50eeaf7861dc 100644 (file)
@@ -3,6 +3,7 @@
  * See copyright notice in main.c
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/device.h>
 
index b42634c614b5814a9822ef3011efd11b6ab30345..413e9ab6cab3bb1fb70782f85c07066ec55eac31 100644 (file)
@@ -78,6 +78,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/device.h>
index d2f10e9c21627a71059b82b5992d6a5ac47bf212..330d42d453330ddbe7209fe81cff1de7b1f2b608 100644 (file)
@@ -3,6 +3,7 @@
  * See copyright notice in main.c
  */
 
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/ieee80211.h>
index 31ca241f775351a7129ff3007c1eea0f6e621b0d..fbcc6e1a2e1d55f9631304e1f4562db55118bb01 100644 (file)
@@ -2,6 +2,7 @@
  *
  * See copyright notice in main.c
  */
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/if_arp.h>
 #include <linux/wireless.h>
index 8e3818f6832e12987b6294eb4fdb304e0454ede1..187e263b045ae813dae3fb59a7c0b27b9d85c4fe 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/sort.h>
+#include <linux/slab.h>
 
 #include <net/mac80211.h>
 
index e7b9e9cb39f5520d2cacd2bf0f89eeb37accd156..c43a5d461ab21feb6a2e9ad98854bb929c06e770 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 
index 4f752a21495f77aa265a6569e8548beb953c9c58..a7cb9eb759a154023acbaa72e87a1d42788727c2 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 
index ed4bdffdd63e4ede90f262760dd1abbae27ffb88..c24067f1a0cb526560f40247aa647c1c57e2f734 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
@@ -245,7 +246,7 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
        u32 idx, i;
 
        i = (*index) % ring_limit;
-       (*index) = idx = le32_to_cpu(ring_control->device_idx[1]);
+       (*index) = idx = le32_to_cpu(ring_control->device_idx[ring_index]);
        idx %= ring_limit;
 
        while (i != idx) {
index afd26bf06649a06690bf7e29a67592c00151a5b9..c8f09da1f84df425dacdd5a29a55cb4479d4ad37 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/spi/spi.h>
 #include <linux/etherdevice.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include "p54spi.h"
 #include "p54spi_eeprom.h"
index b3c4fbd80d8d42cc4af9f98758b871cf68b87b54..743a6c68b29d023cf9e5be018a46390d32b50a55 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/usb.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
@@ -35,6 +36,7 @@ MODULE_FIRMWARE("isl3887usb");
 static struct usb_device_id p54u_table[] __devinitdata = {
        /* Version 1 devices (pci chip + net2280) */
        {USB_DEVICE(0x0506, 0x0a11)},   /* 3COM 3CRWE254G72 */
+       {USB_DEVICE(0x06b9, 0x0120)},   /* Thomson SpeedTouch 120g */
        {USB_DEVICE(0x0707, 0xee06)},   /* SMC 2862W-G */
        {USB_DEVICE(0x07aa, 0x001c)},   /* Corega CG-WLUSB2GT */
        {USB_DEVICE(0x083a, 0x4501)},   /* Accton 802.11g WN4501 USB */
index f7f5c793514b2516e1f0b8d0c21362b543314bb6..a45818ebfdfb250b991d14983de249b3c2ee82bb 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 
 #include <asm/uaccess.h>
index a3ba3539db027df101ce154d986ff1645be71fee..689d59a13d5b295b0db107807ee9ef22a2131af0 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
index 872b64783e780e8bf2e1570348114195457b94d8..ac99eaaeabcee9831afdf5928271b6cc431e7d28 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/gfp.h>
 
 #include <linux/pci.h>
 #include <linux/delay.h>
index 69d2f882fd065e18af75ac62ca88fec3e776ab39..adb289723a967e5fe474332e1c256b7aa94649ad 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
index 87a1734663dac15fb91b5ce599e20970cf3a1d8a..0b27e50fe0d5420d2d0273801bdecec4f4d7c61f 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/wireless.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 
 /*
  *  Function definitions
index 1187e6112a641ee1de6cbc6c8ac80d1cee4a40d9..d66933d70fb9cac31c0ce007e05de592dcabca99 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include "prismcompat.h"
 #include "islpci_dev.h"
index 84c530aa52f9d42f11f3f62f816c8fdd95767b43..11865ea21875331c53b6b2850a0f01f8c3ab5f5c 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/proc_fs.h>
 #include <linux/ptrace.h>
 #include <linux/seq_file.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/init.h>
index 2887047069f217824c9d21cec142167ae1f42fbc..1de5b22d3efe8402a514d769ebd893c1a5d3549a 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/if_arp.h>
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <net/iw_handler.h>
 #include <net/cfg80211.h>
 #include <linux/usb/usbnet.h>
index c22b04042d5cacc8f4813f2445fa908045227e57..5f5204b8289178941f579ea81319230ced397e77 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/eeprom_93cx6.h>
+#include <linux/slab.h>
 
 #include "rt2x00.h"
 #include "rt2x00pci.h"
index 52bbcf1bd17c4f51d1114ffb9213518908c730f6..2a73f593aab0cb82ef4bdaa1e949b82cd7e7d4a2 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/eeprom_93cx6.h>
+#include <linux/slab.h>
 
 #include "rt2x00.h"
 #include "rt2x00pci.h"
index 9b04964deced458e85a8c814580db05052838fb3..8ebb705fe106f6c6403bcc953c6e04d18a9403dd 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "rt2x00.h"
@@ -1642,6 +1643,11 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
        char *tx_power;
        unsigned int i;
 
+       /*
+        * Disable powersaving as default.
+        */
+       rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+
        /*
         * Initialize all hw fields.
         */
index 18d4d8e4ae6ba587734574b2095cc435a7fd5e49..c015ce9fdd09925da8e46dff2495c9d69e24d7a8 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "rt2x00.h"
 #if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE)
@@ -812,9 +813,9 @@ static void rt2800_config_channel_rt3x(struct rt2x00_dev *rt2x00dev,
        rt2800_rfcsr_write(rt2x00dev, 24,
                              rt2x00dev->calibration[conf_is_ht40(conf)]);
 
-       rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
+       rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
        rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
-       rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
+       rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
 }
 
 static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
index 28a1c46ec4eb28194e315a3a3c22baacc059b762..9569fb4e5bc5625b5586b13294b6435fbb83e398 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/module.h>
 #include <linux/poll.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 
 #include "rt2x00.h"
index dd5ab8fe232180dfc0a44c19330d649780a171ae..eda73ba735a6e388ed8d9f68d22668af84ead912 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "rt2x00.h"
 #include "rt2x00lib.h"
index 047123b766fce5576bd6f1ff3d297ec87ef6767f..cf3f1c0c43822fe70d0390bfd4ff060c306c07c3 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include "rt2x00.h"
 #include "rt2x00pci.h"
index 5b6b789cad3d6a4f0bd88ad0747e53aabcaf4774..a0bd36fc4d2e928227478f7b7f266978ccb4813b 100644 (file)
@@ -24,6 +24,7 @@
        Abstract: rt2x00 queue specific routines.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/dma-mapping.h>
index 111c0ff5c6c79f500fb20a9c868261dc36e64e04..fc98063de71dab47d265e0b7c3f5084b68a6728d 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include "rt2x00.h"
 #include "rt2x00soc.h"
index 0a751e73aa0f6ecb341b59a314b8d14e9179ac98..f9a7f8b1741134e57e840ea01baa0bb4ace149b8 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/bug.h>
 
index 17747274217243792f462cf9e6c0009cd674f44f..432e75f960b72d409cb3f925fb3249312eff6071 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/eeprom_93cx6.h>
 
index 290d70bc5d221a74bd353ad4a5b8feb554959a7d..bb58d797fb72910afdd0598450d3323732bcd8ce 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "rt2x00.h"
index 2b928ecf47bdb9815289bf35819bd4fbe4cc42b9..2131a442831aa678746bf359d03e46a1745c9f06 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/eeprom_93cx6.h>
index 0fb850e0c6569ca991ba03b59e2fec76626bfa4e..1d30792973f5ef78dfaad45ea439f23c159618c2 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/init.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/eeprom_93cx6.h>
index beff084040b569499efae9dc637a15bb25be3c34..91891f9280706266b2ab8e6f8d283e587d833c70 100644 (file)
@@ -1,6 +1,7 @@
 #include "wl1251_acx.h"
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/crc7.h>
 
 #include "wl1251.h"
index 28a808674080952b73e1615fefcba75d784ef406..d5ac79aeaa735cecdca705f6e556b774807c69c6 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include "wl1251_reg.h"
 #include "wl1251_boot.h"
index 0320b478bb3f0dfde1fc6cfbee04859fe9b01a35..a37b30cef4894c6da466989be64546de3f38af94 100644 (file)
@@ -1,6 +1,7 @@
 #include "wl1251_cmd.h"
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/crc7.h>
 
 #include "wl1251.h"
index 0ccba57fb9fb9548eaceaf267481af256f9928d3..5e4465ac08fadbbb435db0ad890edc4d610e2ae6 100644 (file)
@@ -24,6 +24,7 @@
 #include "wl1251_debugfs.h"
 
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 
 #include "wl1251.h"
 #include "wl1251_acx.h"
@@ -466,7 +467,8 @@ out:
 
 void wl1251_debugfs_reset(struct wl1251 *wl)
 {
-       memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
+       if (wl->stats.fw_stats != NULL)
+               memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
        wl->stats.retry_count = 0;
        wl->stats.excessive_retries = 0;
 }
index 5aad56ea71536fa1dbc5875d601f7bd76eaae961..b538bdd7b320f41e8abdf2516d755179d780f94e 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "wl1251_init.h"
 #include "wl12xx_80211.h"
index 24ae6a360ac8f6e09ca719e6f48bfede224df683..1c8226eee40938aafc13cbb89e1797305c8e5df9 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/crc32.h>
 #include <linux/etherdevice.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include "wl1251.h"
 #include "wl12xx_80211.h"
index b56732226cc09943638b976b0e4c95114ad7b15a..6f229e0990f4efc45d3a54facaad939d994cbf3c 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/skbuff.h>
+#include <linux/gfp.h>
 #include <net/mac80211.h>
 
 #include "wl1251.h"
index 9cc8c323830fdf8a34f5bf49cd7c43206fd523ea..3bfb59bd4635413422c3031625c5fb89c090ab0d 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/irq.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/crc7.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/wl12xx.h>
index 60f10dce48000f7a54dbaa7bd7b91ce10a9af636..308782421fce5afb777b22caa755e2c395e6fc9f 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/platform_device.h>
 #include <linux/crc7.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 
 #include "wl1271.h"
 #include "wl12xx_80211.h"
index 2be76ee42bb9b2a4aeda9a40a5ac46153fa97fe0..0243562630657098d5b3f05802500f5d151c8704 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include "wl1271_acx.h"
 #include "wl1271_reg.h"
index 36a64e06f2907c3b088de1cd6b351717b123c896..e7832f3318eba7e38629e3f43adce326c6a6f411 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/crc7.h>
 #include <linux/spi/spi.h>
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 
 #include "wl1271.h"
 #include "wl1271_reg.h"
index 8d7588ca68fd0c14adc8c6508d1ab5456b674cf9..3f7ff8d0cf5acc3f2c48e7eb820bc034aff6bb05 100644 (file)
@@ -24,6 +24,7 @@
 #include "wl1271_debugfs.h"
 
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 
 #include "wl1271.h"
 #include "wl1271_acx.h"
index 86c30a86a456cd5952f2b28c5ee65baaf9763fe7..d189e8fe05a645a268f4a315b5b0798b44ca04af 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "wl1271_init.h"
 #include "wl12xx_80211.h"
index 2a864b24291da705e47a38bf5874a7dbaf657f39..65a1aeba2419116f793a5cfba18ffae7b44839d7 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/vmalloc.h>
 #include <linux/spi/wl12xx.h>
 #include <linux/inetdevice.h>
+#include <linux/slab.h>
 
 #include "wl1271.h"
 #include "wl12xx_80211.h"
index 6730f5b96e76a7e2baa2ba6ec7dd0c0726828149..c723d9c7e1310c4eb7f263f4405786832b6ef80b 100644 (file)
@@ -21,6 +21,8 @@
  *
  */
 
+#include <linux/gfp.h>
+
 #include "wl1271.h"
 #include "wl1271_acx.h"
 #include "wl1271_reg.h"
index 67a82934f36eca4e8344fcfecb6e43442de625f9..053c84aceb4900263ddcd40b188467bfd4e73ce7 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/platform_device.h>
 #include <linux/crc7.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 
 #include "wl1271.h"
 #include "wl12xx_80211.h"
index 3919102e942e012509659e2038b6b09c118252a9..5c1c4f565fd8be475f3665316a1a6b931bd31497 100644 (file)
@@ -22,6 +22,7 @@
  */
 #include "wl1271_testmode.h"
 
+#include <linux/slab.h>
 #include <net/genetlink.h>
 
 #include "wl1271.h"
index 6917286edcae555df02297b793ac6f42b6d91692..9d12778746452161990e55363487b312dc449be8 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/module.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
index 7ca95c414fa83d9e6b19e7fccb1b4ee43c7965a6..b2af3c549bb39e21010051f55a3eaa21df00a30a 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 
 #include "zd_def.h"
 #include "zd_chip.h"
index 00e09e26c826e444dfb9eec223b653012917f8c4..16fa289ad77b20367aeff3cd9f1327eb66b25f0c 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/jiffies.h>
 #include <net/ieee80211_radiotap.h>
index 439799b84876b9f597d0ec8004f2fae39f9a67a4..9e74eb1b67d508ac6e16a9462899eb5744ae7229 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include "zd_rf.h"
 #include "zd_usb.h"
index 442fc1117326bbaefdb11975c7166d8cf8387987..d91ad1a612afd23ef64a0045cc41e70ce99537f8 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/firmware.h>
 #include <linux/device.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/usb.h>
 #include <linux/workqueue.h>
index a869b45d3d37b2f38a986c4dfb0146d10be4416d..d504e2b6025705ded7ee1ac4524791818d8c5ec5 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/udp.h>
 #include <linux/moduleparam.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <net/ip.h>
 
 #include <xen/xen.h>
index 1a74594224b1b8303c74b4247b444cf251e58119..1e783ccc306ebe7866de609f2df0c4ff5a277ca3 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
index 389ba9df71206a12f933b3b5931499c8a6b3337e..fdba9cb3a599e65b77522008930f98226722f4c4 100644 (file)
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
+#include <linux/gfp.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
@@ -33,6 +33,7 @@
 #include <linux/skbuff.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/pgtable.h>
index 7d4107f5eeb020d830a2e387dd275fdd47164b36..ede5b2436f2271f31743cd1efa285b281bf1a6c2 100644 (file)
@@ -90,7 +90,6 @@ static int gx_fix;
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
index def49d2ec69ac8c29695ddfced8aec23e8b4cc4d..dbfef8d70f2dfdf7660496c473308b5302f1b1d9 100644 (file)
@@ -88,6 +88,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
index 81c753a617ab93ab793b724428c9c0c97646da84..9548cbb5012a69305b799d6fc68664f072fc3bd5 100644 (file)
@@ -102,6 +102,7 @@ static struct zorro_device_id zorro8390_zorro_tbl[] __devinitdata = {
     { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, },
     { 0 }
 };
+MODULE_DEVICE_TABLE(zorro, zorro8390_zorro_tbl);
 
 static struct zorro_driver zorro8390_driver = {
     .name      = "zorro8390",
index f5f75844954cf829641774ec940307fd8e71b635..b764ac22d523276a59c4055b914cba90f7e13d64 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/setup.h>
 #include <asm/system.h>
 #include <asm/page.h>
index cb96888d142785c4f9ea82f19e1de26ffcd448c7..b5ad9740d8b21a6eb6b3e3f3bd1586e8a5645426 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/proc_fs.h>
 
 struct device_node *allnodes;
index 406757a9d7ea62056680808392acd02e2889cda9..dee4fb56b094106381dc891d94bdc47341480131 100644 (file)
@@ -376,8 +376,11 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
                if (!np->type)
                        np->type = "<NULL>";
        }
-       while (tag == OF_DT_BEGIN_NODE) {
-               mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
+       while (tag == OF_DT_BEGIN_NODE || tag == OF_DT_NOP) {
+               if (tag == OF_DT_NOP)
+                       *p += 4;
+               else
+                       mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
                tag = be32_to_cpup((__be32 *)(*p));
        }
        if (tag != OF_DT_END_NODE) {
index 24c3606217f86a5db00bbf36547ba90d0489e2b2..a1b31a4abae4479e647e3e1a5eacd314139fbad1 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/errno.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/slab.h>
 #include <linux/of_gpio.h>
 #include <asm/prom.h>
 
index 18ecae4a4375d461957b04ee8171f1e5e1434b8c..b4748337223b43d28aa7fb11d7eb788ec29d6da4 100644 (file)
@@ -69,7 +69,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
                }
 
                phy = get_phy_device(mdio, be32_to_cpup(addr));
-               if (!phy) {
+               if (!phy || IS_ERR(phy)) {
                        dev_err(&mdio->dev, "error probing PHY at address %i\n",
                                *addr);
                        continue;
index c9e2ae90f19508db8f74f91440636689d50321d8..a9352b2c7ac430d4e4aafac3d65a1b46005ea505 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/fs.h>
 #include <linux/oprofile.h>
 #include <linux/sched.h>
+#include <linux/gfp.h>
 
 #include "oprofile_stats.h"
 #include "event_buffer.h"
index 166b67ea622f11563a33c539b78c5dafc7c2503f..219f79e2210a3fcd561b94456c4960a0a1fbacd9 100644 (file)
 
 #define OP_BUFFER_FLAGS        0
 
-/*
- * Read and write access is using spin locking. Thus, writing to the
- * buffer by NMI handler (x86) could occur also during critical
- * sections when reading the buffer. To avoid this, there are 2
- * buffers for independent read and write access. Read access is in
- * process context only, write access only in the NMI handler. If the
- * read buffer runs empty, both buffers are swapped atomically. There
- * is potentially a small window during swapping where the buffers are
- * disabled and samples could be lost.
- *
- * Using 2 buffers is a little bit overhead, but the solution is clear
- * and does not require changes in the ring buffer implementation. It
- * can be changed to a single buffer solution when the ring buffer
- * access is implemented as non-locking atomic code.
- */
-static struct ring_buffer *op_ring_buffer_read;
-static struct ring_buffer *op_ring_buffer_write;
+static struct ring_buffer *op_ring_buffer;
 DEFINE_PER_CPU(struct oprofile_cpu_buffer, op_cpu_buffer);
 
 static void wq_sync_buffer(struct work_struct *work);
@@ -68,12 +52,9 @@ void oprofile_cpu_buffer_inc_smpl_lost(void)
 
 void free_cpu_buffers(void)
 {
-       if (op_ring_buffer_read)
-               ring_buffer_free(op_ring_buffer_read);
-       op_ring_buffer_read = NULL;
-       if (op_ring_buffer_write)
-               ring_buffer_free(op_ring_buffer_write);
-       op_ring_buffer_write = NULL;
+       if (op_ring_buffer)
+               ring_buffer_free(op_ring_buffer);
+       op_ring_buffer = NULL;
 }
 
 #define RB_EVENT_HDR_SIZE 4
@@ -86,11 +67,8 @@ int alloc_cpu_buffers(void)
        unsigned long byte_size = buffer_size * (sizeof(struct op_sample) +
                                                 RB_EVENT_HDR_SIZE);
 
-       op_ring_buffer_read = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS);
-       if (!op_ring_buffer_read)
-               goto fail;
-       op_ring_buffer_write = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS);
-       if (!op_ring_buffer_write)
+       op_ring_buffer = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS);
+       if (!op_ring_buffer)
                goto fail;
 
        for_each_possible_cpu(i) {
@@ -162,16 +140,11 @@ struct op_sample
 *op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size)
 {
        entry->event = ring_buffer_lock_reserve
-               (op_ring_buffer_write, sizeof(struct op_sample) +
+               (op_ring_buffer, sizeof(struct op_sample) +
                 size * sizeof(entry->sample->data[0]));
-       if (entry->event)
-               entry->sample = ring_buffer_event_data(entry->event);
-       else
-               entry->sample = NULL;
-
-       if (!entry->sample)
+       if (!entry->event)
                return NULL;
-
+       entry->sample = ring_buffer_event_data(entry->event);
        entry->size = size;
        entry->data = entry->sample->data;
 
@@ -180,25 +153,16 @@ struct op_sample
 
 int op_cpu_buffer_write_commit(struct op_entry *entry)
 {
-       return ring_buffer_unlock_commit(op_ring_buffer_write, entry->event);
+       return ring_buffer_unlock_commit(op_ring_buffer, entry->event);
 }
 
 struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu)
 {
        struct ring_buffer_event *e;
-       e = ring_buffer_consume(op_ring_buffer_read, cpu, NULL);
-       if (e)
-               goto event;
-       if (ring_buffer_swap_cpu(op_ring_buffer_read,
-                                op_ring_buffer_write,
-                                cpu))
+       e = ring_buffer_consume(op_ring_buffer, cpu, NULL, NULL);
+       if (!e)
                return NULL;
-       e = ring_buffer_consume(op_ring_buffer_read, cpu, NULL);
-       if (e)
-               goto event;
-       return NULL;
 
-event:
        entry->event = e;
        entry->sample = ring_buffer_event_data(e);
        entry->size = (ring_buffer_event_length(e) - sizeof(struct op_sample))
@@ -209,8 +173,7 @@ event:
 
 unsigned long op_cpu_buffer_entries(int cpu)
 {
-       return ring_buffer_entries_cpu(op_ring_buffer_read, cpu)
-               + ring_buffer_entries_cpu(op_ring_buffer_write, cpu);
+       return ring_buffer_entries_cpu(op_ring_buffer, cpu);
 }
 
 static int
@@ -356,8 +319,16 @@ void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
 
 void oprofile_add_sample(struct pt_regs * const regs, unsigned long event)
 {
-       int is_kernel = !user_mode(regs);
-       unsigned long pc = profile_pc(regs);
+       int is_kernel;
+       unsigned long pc;
+
+       if (likely(regs)) {
+               is_kernel = !user_mode(regs);
+               pc = profile_pc(regs);
+       } else {
+               is_kernel = 0;    /* This value will not be used */
+               pc = ESCAPE_CODE; /* as this causes an early return. */
+       }
 
        __oprofile_add_ext_sample(pc, regs, event, is_kernel);
 }
index dc8a0428260dd3d5c141982d0da9dcdaceca70f7..b336cd9ee7a114c54d6b7b85d48cacc6f3ed1a6d 100644 (file)
@@ -253,22 +253,26 @@ static int __init oprofile_init(void)
        int err;
 
        err = oprofile_arch_init(&oprofile_ops);
-
        if (err < 0 || timer) {
                printk(KERN_INFO "oprofile: using timer interrupt.\n");
-               oprofile_timer_init(&oprofile_ops);
+               err = oprofile_timer_init(&oprofile_ops);
+               if (err)
+                       goto out_arch;
        }
-
        err = oprofilefs_register();
        if (err)
-               oprofile_arch_exit();
+               goto out_arch;
+       return 0;
 
+out_arch:
+       oprofile_arch_exit();
        return err;
 }
 
 
 static void __exit oprofile_exit(void)
 {
+       oprofile_timer_exit();
        oprofilefs_unregister();
        oprofile_arch_exit();
 }
index cb92f5c98c1abc2f4207b94ce205b6c6848ee3cd..47e12cb4ee8ba7464e4b0c7ef955be71b1caa201 100644 (file)
@@ -34,7 +34,8 @@ struct super_block;
 struct dentry;
 
 void oprofile_create_files(struct super_block *sb, struct dentry *root);
-void oprofile_timer_init(struct oprofile_operations *ops);
+int oprofile_timer_init(struct oprofile_operations *ops);
+void oprofile_timer_exit(void);
 
 int oprofile_set_backtrace(unsigned long depth);
 int oprofile_set_timeout(unsigned long time);
index 333f915568c796683af2b49e51227e54914d97b2..dc0ae4d14dffe25ab067f337907b77815121cfd3 100644 (file)
 #include <linux/oprofile.h>
 #include <linux/profile.h>
 #include <linux/init.h>
+#include <linux/cpu.h>
+#include <linux/hrtimer.h>
+#include <asm/irq_regs.h>
 #include <asm/ptrace.h>
 
 #include "oprof.h"
 
-static int timer_notify(struct pt_regs *regs)
+static DEFINE_PER_CPU(struct hrtimer, oprofile_hrtimer);
+
+static enum hrtimer_restart oprofile_hrtimer_notify(struct hrtimer *hrtimer)
+{
+       oprofile_add_sample(get_irq_regs(), 0);
+       hrtimer_forward_now(hrtimer, ns_to_ktime(TICK_NSEC));
+       return HRTIMER_RESTART;
+}
+
+static void __oprofile_hrtimer_start(void *unused)
+{
+       struct hrtimer *hrtimer = &__get_cpu_var(oprofile_hrtimer);
+
+       hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       hrtimer->function = oprofile_hrtimer_notify;
+
+       hrtimer_start(hrtimer, ns_to_ktime(TICK_NSEC),
+                     HRTIMER_MODE_REL_PINNED);
+}
+
+static int oprofile_hrtimer_start(void)
 {
-       oprofile_add_sample(regs, 0);
+       on_each_cpu(__oprofile_hrtimer_start, NULL, 1);
        return 0;
 }
 
-static int timer_start(void)
+static void __oprofile_hrtimer_stop(int cpu)
 {
-       return register_timer_hook(timer_notify);
+       struct hrtimer *hrtimer = &per_cpu(oprofile_hrtimer, cpu);
+
+       hrtimer_cancel(hrtimer);
 }
 
+static void oprofile_hrtimer_stop(void)
+{
+       int cpu;
+
+       for_each_online_cpu(cpu)
+               __oprofile_hrtimer_stop(cpu);
+}
 
-static void timer_stop(void)
+static int __cpuinit oprofile_cpu_notify(struct notifier_block *self,
+                                        unsigned long action, void *hcpu)
 {
-       unregister_timer_hook(timer_notify);
+       long cpu = (long) hcpu;
+
+       switch (action) {
+       case CPU_ONLINE:
+       case CPU_ONLINE_FROZEN:
+               smp_call_function_single(cpu, __oprofile_hrtimer_start,
+                                        NULL, 1);
+               break;
+       case CPU_DEAD:
+       case CPU_DEAD_FROZEN:
+               __oprofile_hrtimer_stop(cpu);
+               break;
+       }
+       return NOTIFY_OK;
 }
 
+static struct notifier_block __refdata oprofile_cpu_notifier = {
+       .notifier_call = oprofile_cpu_notify,
+};
 
-void __init oprofile_timer_init(struct oprofile_operations *ops)
+int __init oprofile_timer_init(struct oprofile_operations *ops)
 {
+       int rc;
+
+       rc = register_hotcpu_notifier(&oprofile_cpu_notifier);
+       if (rc)
+               return rc;
        ops->create_files = NULL;
        ops->setup = NULL;
        ops->shutdown = NULL;
-       ops->start = timer_start;
-       ops->stop = timer_stop;
+       ops->start = oprofile_hrtimer_start;
+       ops->stop = oprofile_hrtimer_stop;
        ops->cpu_type = "timer";
+       return 0;
+}
+
+void __exit oprofile_timer_exit(void)
+{
+       unregister_hotcpu_notifier(&oprofile_cpu_notifier);
 }
index 9ca21098b146c73e54e0facbf101e657e21ddaa0..6a1ab2512a53625aea4f54ae842bef2c38e77649 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/types.h>
 #include <asm/io.h>
 #include <asm/led.h>
index 356b8357bcccefc0dba8e2fa3e91fe53766c6878..f78f6f1aef47409f6066ea68560690c87dd386e7 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/pci.h>
+#include <linux/gfp.h>
 
 #include <asm/uaccess.h>
 
index c4e1f3c3c2fadd9cc1c4bf6f5e6561e803b3002d..20a1bce1a03163e4a9cb9b983a7bd8e00b5bb517 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/types.h>
 
 #include <asm/hardware.h>
index 3c8f06c3a5a07acc4c1f041fee7c495a2386c53e..5bed17f68ef4d164bdef53a22c6c0c65c6e83e8c 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/parport.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 
 #include <asm/current.h>
index 6938d2e9f18f8171d41adcaa0e33e1e487334305..2c5ac2bf5c565ecd03041b4b9117f8742fb877bf 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/interrupt.h>
 #include <linux/errno.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index 6d58bf895b1ac8690d786ad390e6b7c282ce5f62..d3d7809af8bf5287653ebe4b3e968489eba2c4cd 100644 (file)
 #include <linux/module.h>
 #include <linux/parport.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/stddef.h>
 #include <linux/types.h>
index c3bb84ac931ee577645aa13db06c8cdb9778c783..40e208d130f5b8ccf5a6e95be316f8af7e35440a 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/parport.h>
index 0f6550719bcf179d9fc493407b5d2a3dc38f447a..d763bc9e44c1c1a0e98d7f69b490afdc0721004e 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/parport.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 static const struct {
index 3d102dd87c9f84937e92eb29ac9dd1bb311c19ee..0b51857fbaf74842433d1eddef7b51cb54209ec3 100644 (file)
@@ -48,6 +48,7 @@ obj-$(CONFIG_PPC) += setup-bus.o
 obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
 obj-$(CONFIG_X86_VISWS) += setup-irq.o
 obj-$(CONFIG_MN10300) += setup-bus.o
+obj-$(CONFIG_MICROBLAZE) += setup-bus.o
 
 #
 # ACPI Related PCI FW Functions
index db23200c487426d6fd9d9b04e53e518b88ebd50f..2f646fe1260f3831b13036cdfd5b26cb56078c8e 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/wait.h>
 
index 26301cb25e7f7cc682bd0f5ce102466a7810088b..628ea20a884190afbbffff2f80e0faf5cbaade1b 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/ioport.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #include "pci.h"
 
index 83aae47475940b383fe89c5fd3cf30c7c7cb3ec4..33ead97f0c4b24e2e030ae913bef26cdf435d533 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/interrupt.h>
 #include <linux/tboot.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 
 #define PREFIX "DMAR: "
 
index 3c76fc67cf0e62f8598877881ce40efb0c7a12ae..45fcc1e96df9ac08718696e7ea8a8f487f33072f 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/pci_hotplug.h>
 #include <linux/acpi.h>
 #include <linux/pci-acpi.h>
+#include <linux/slab.h>
 
 #define MY_NAME        "acpi_pcihp"
 
index b5dad9f374537a92012fbd4dc274b0b076458fcb..cb23aa2ebf96b1c768b6c2edae033984c2959fac 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/pci_hotplug.h>
 #include <linux/pci-acpi.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include "../pci.h"
 #include "acpiphp.h"
index aa5df485f8cf8e8b029e23b99f0f7780f67f4e58..6ecbfb27db9d1c95fa00d2c2e6bcf0a9395dcfff 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <acpi/acpi_bus.h>
index e6089bdb6e5bddbc2b08e09c9419d26056e543e7..56215322930ad143c5d0d3adba42823d70f77c12 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/workqueue.h>
index 0a894efd4b9b34da6ddcaacd84c62cafd2a859d2..5317e4d7d96eab58ac6c24a450022ae82a5c13e5 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include "../pci.h"
 
 struct legacy_slot {
index 728b119f71ad4dbaadfe65ce51ce1e7b1271bf99..6d2eea93298fbbcf31afb03cba64b262b228e313 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/kobject.h>
 #include <linux/sysfs.h>
 #include <linux/pagemap.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
index b09b083011d69ad43e743490bad963266f6af36b..1f4000a5a108fa8d9f57383ffc03f9313c9fc2c0 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/acpi.h>
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
+#include <linux/slab.h>
 #include "pciehp.h"
 
 #define PCIEHP_DETECT_PCIE     (0)
index 920f820edf8798dd4c75103d7969eb4061a8d8a5..3588ea61b0dd244df58ac3fdc92adc61cdc512be 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include "pciehp.h"
index 9a7f247e8ac155e164158da9fe13fe8b8a640b2c..8f58148be044ae3a53e1b7b0419f222698a76558 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/workqueue.h>
 #include "../pci.h"
index 40b48f569b1e3daf9c6de0330f4f4f9f2fab4317..0cd42047d89b07fd965fcc757b49fa699b154dd8 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/time.h>
+#include <linux/slab.h>
 
 #include "../pci.h"
 #include "pciehp.h"
@@ -832,9 +833,8 @@ static inline void dbg_ctrl(struct controller *ctrl)
        for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
                if (!pci_resource_len(pdev, i))
                        continue;
-               ctrl_info(ctrl, "  PCI resource [%d]     : 0x%llx@0x%llx\n",
-                         i, (unsigned long long)pci_resource_len(pdev, i),
-                         (unsigned long long)pci_resource_start(pdev, i));
+               ctrl_info(ctrl, "  PCI resource [%d]     : %pR\n",
+                         i, &pdev->resource[i]);
        }
        ctrl_info(ctrl, "Slot Capabilities      : 0x%08x\n", ctrl->slot_cap);
        ctrl_info(ctrl, "  Physical Slot Number : %d\n", PSN(ctrl));
index 4e3e0382c16e2a954c55aaa42e8ebb44bc7493b1..083034710fa6cc7c144ccf0d875e4b77e1fb805f 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/string.h>
+#include <linux/vmalloc.h>
 
 #include <asm/pci-bridge.h>
 #include <linux/mutex.h>
@@ -430,6 +431,8 @@ int dlpar_remove_slot(char *drc_name)
                        rc = dlpar_remove_pci_slot(drc_name, dn);
                        break;
        }
+       vm_unmap_aliases();
+
        printk(KERN_INFO "%s: slot %s removed\n", DLPAR_MODULE_NAME, drc_name);
 exit:
        mutex_unlock(&rpadlpar_mutex);
index dcaae725fd791185278805bf2b5af343f2ccb290..ef7411c660b99f0352548fb989fb6f5fa7dc158e 100644 (file)
@@ -27,9 +27,9 @@
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
-#include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/init.h>
+#include <linux/vmalloc.h>
 #include <asm/eeh.h>       /* for eeh_add_device() */
 #include <asm/rtas.h>          /* rtas_call */
 #include <asm/pci-bridge.h>    /* for pci_controller */
@@ -419,6 +419,8 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
                return -EINVAL;
 
        pcibios_remove_pci_devices(slot->bus);
+       vm_unmap_aliases();
+
        slot->state = NOT_CONFIGURED;
        return 0;
 }
index 8aebe1e9d3d6ae21c664f998a4192194547b7afe..72d507b6a2aa8d446d06fcbbcfc3aa68799434f5 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/mutex.h>
 
index a5062297f4886e255c6c9f006b1bc729460f84c6..a7bd5048396ed61ba1d379b713215c39725e0bd0 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/workqueue.h>
 #include "shpchp.h"
index 3bba0c0888ff180100d1d8ee1c2e58cbcf5dda73..3387fbfb0c54bed289e5a9ddfeac1f5bb36f653b 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/workqueue.h>
 #include "../pci.h"
index 737a1c44b07af9a8ed81ed6e2191fce7934603fd..98abf8b912943f12b6cbcdfe90e4779f3650294e 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
-#include <linux/gfp.h>
 #include <linux/htirq.h>
 
 /* Global ht irq lock.
index 417312528ddff29ab4ead4fd5bc7d89e9a718121..371dc564e2e46c744ac48dc9fd08c361dee0c34b 100644 (file)
@@ -3626,14 +3626,15 @@ static void intel_iommu_detach_device(struct iommu_domain *domain,
        domain_remove_one_dev_info(dmar_domain, pdev);
 }
 
-static int intel_iommu_map_range(struct iommu_domain *domain,
-                                unsigned long iova, phys_addr_t hpa,
-                                size_t size, int iommu_prot)
+static int intel_iommu_map(struct iommu_domain *domain,
+                          unsigned long iova, phys_addr_t hpa,
+                          int gfp_order, int iommu_prot)
 {
        struct dmar_domain *dmar_domain = domain->priv;
        u64 max_addr;
        int addr_width;
        int prot = 0;
+       size_t size;
        int ret;
 
        if (iommu_prot & IOMMU_READ)
@@ -3643,6 +3644,7 @@ static int intel_iommu_map_range(struct iommu_domain *domain,
        if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
                prot |= DMA_PTE_SNP;
 
+       size     = PAGE_SIZE << gfp_order;
        max_addr = iova + size;
        if (dmar_domain->max_addr < max_addr) {
                int min_agaw;
@@ -3669,19 +3671,19 @@ static int intel_iommu_map_range(struct iommu_domain *domain,
        return ret;
 }
 
-static void intel_iommu_unmap_range(struct iommu_domain *domain,
-                                   unsigned long iova, size_t size)
+static int intel_iommu_unmap(struct iommu_domain *domain,
+                            unsigned long iova, int gfp_order)
 {
        struct dmar_domain *dmar_domain = domain->priv;
-
-       if (!size)
-               return;
+       size_t size = PAGE_SIZE << gfp_order;
 
        dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT,
                            (iova + size - 1) >> VTD_PAGE_SHIFT);
 
        if (dmar_domain->max_addr == iova + size)
                dmar_domain->max_addr = iova;
+
+       return gfp_order;
 }
 
 static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
@@ -3714,8 +3716,8 @@ static struct iommu_ops intel_iommu_ops = {
        .domain_destroy = intel_iommu_domain_destroy,
        .attach_dev     = intel_iommu_attach_device,
        .detach_dev     = intel_iommu_detach_device,
-       .map            = intel_iommu_map_range,
-       .unmap          = intel_iommu_unmap_range,
+       .map            = intel_iommu_map,
+       .unmap          = intel_iommu_unmap,
        .iova_to_phys   = intel_iommu_iova_to_phys,
        .domain_has_cap = intel_iommu_domain_has_cap,
 };
index 95b849130ad41189ea2540272ffc84f5407a5bc6..6ee98a56946fff4a887b80f39c281ac495eb479b 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/interrupt.h>
 #include <linux/dmar.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/jiffies.h>
 #include <linux/hpet.h>
 #include <linux/pci.h>
index 3e0d7b5dd1b904e0e02425f1ea005915cafb2610..203508b227b7ca383498a485947dbd482da98b7d 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/pci.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #include <acpi/acpi_bus.h>
 
 struct ioapic {
@@ -31,9 +32,9 @@ static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent)
        acpi_status status;
        unsigned long long gsb;
        struct ioapic *ioapic;
-       u64 addr;
        int ret;
        char *type;
+       struct resource *res;
 
        handle = DEVICE_ACPI_HANDLE(&dev->dev);
        if (!handle)
@@ -69,13 +70,12 @@ static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent)
        if (pci_request_region(dev, 0, type))
                goto exit_disable;
 
-       addr = pci_resource_start(dev, 0);
-       if (acpi_register_ioapic(ioapic->handle, addr, ioapic->gsi_base))
+       res = &dev->resource[0];
+       if (acpi_register_ioapic(ioapic->handle, res->start, ioapic->gsi_base))
                goto exit_release;
 
        pci_set_drvdata(dev, ioapic);
-       dev_info(&dev->dev, "%s at %#llx, GSI %u\n", type, addr,
-                ioapic->gsi_base);
+       dev_info(&dev->dev, "%s at %pR, GSI %u\n", type, res, ioapic->gsi_base);
        return 0;
 
 exit_release:
index 3e5ab2bf6a5c05f7f87374b6f3a2955a1c32aa51..ce6a3666b3d9878f70be6fb65f3e1272fdf6b6b2 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/string.h>
 #include <linux/delay.h>
index f9cf3173b23dcc9e8bea22d1ff6679523bcb0944..77b68eaf021e43152c4bbd257bd190a4a210473c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/smp.h>
 #include <linux/errno.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include "pci.h"
 #include "msi.h"
index de296452c957b7fb7ecb352ed03b7926913c98a9..fad93983bfed09a2780822b8a8c36bad18a32828 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/mm.h>
 #include <linux/capability.h>
 #include <linux/pci-aspm.h>
+#include <linux/slab.h>
 #include "pci.h"
 
 static int sysfs_initialized;  /* = 0 */
@@ -655,8 +656,8 @@ void pci_create_legacy_files(struct pci_bus *b)
                goto legacy_io_err;
 
        /* Allocated above after the legacy_io struct */
-       sysfs_bin_attr_init(b->legacy_mem);
        b->legacy_mem = b->legacy_io + 1;
+       sysfs_bin_attr_init(b->legacy_mem);
        b->legacy_mem->attr.name = "legacy_mem";
        b->legacy_mem->size = 1024*1024;
        b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
index cb1dd5f4988c72d533cabefa9b6b540761c294d6..37499127c801e5db16927377981e6a721bf0bd0d 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pm.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
@@ -678,7 +679,7 @@ static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state)
  */
 int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state)
 {
-       return state > PCI_D0 ?
+       return state >= PCI_D0 ?
                        pci_platform_power_transition(dev, state) : -EINVAL;
 }
 EXPORT_SYMBOL_GPL(__pci_complete_power_transition);
@@ -715,10 +716,6 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
                 */
                return 0;
 
-       /* Check if we're already there */
-       if (dev->current_state == state)
-               return 0;
-
        __pci_start_power_transition(dev, state);
 
        /* This device is quirked not to be put into D3, so
@@ -2576,18 +2573,17 @@ EXPORT_SYMBOL_GPL(pci_reset_function);
  */
 int pcix_get_max_mmrbc(struct pci_dev *dev)
 {
-       int err, cap;
+       int cap;
        u32 stat;
 
        cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
        if (!cap)
                return -EINVAL;
 
-       err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat);
-       if (err)
+       if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat))
                return -EINVAL;
 
-       return (stat & PCI_X_STATUS_MAX_READ) >> 12;
+       return 512 << ((stat & PCI_X_STATUS_MAX_READ) >> 21);
 }
 EXPORT_SYMBOL(pcix_get_max_mmrbc);
 
@@ -2600,18 +2596,17 @@ EXPORT_SYMBOL(pcix_get_max_mmrbc);
  */
 int pcix_get_mmrbc(struct pci_dev *dev)
 {
-       int ret, cap;
-       u32 cmd;
+       int cap;
+       u16 cmd;
 
        cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
        if (!cap)
                return -EINVAL;
 
-       ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd);
-       if (!ret)
-               ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2);
+       if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd))
+               return -EINVAL;
 
-       return ret;
+       return 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2);
 }
 EXPORT_SYMBOL(pcix_get_mmrbc);
 
@@ -2626,28 +2621,27 @@ EXPORT_SYMBOL(pcix_get_mmrbc);
  */
 int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc)
 {
-       int cap, err = -EINVAL;
-       u32 stat, cmd, v, o;
+       int cap;
+       u32 stat, v, o;
+       u16 cmd;
 
        if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc))
-               goto out;
+               return -EINVAL;
 
        v = ffs(mmrbc) - 10;
 
        cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
        if (!cap)
-               goto out;
+               return -EINVAL;
 
-       err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat);
-       if (err)
-               goto out;
+       if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat))
+               return -EINVAL;
 
        if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21)
                return -E2BIG;
 
-       err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd);
-       if (err)
-               goto out;
+       if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd))
+               return -EINVAL;
 
        o = (cmd & PCI_X_CMD_MAX_READ) >> 2;
        if (o != v) {
@@ -2657,10 +2651,10 @@ int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc)
 
                cmd &= ~PCI_X_CMD_MAX_READ;
                cmd |= v << 2;
-               err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd);
+               if (pci_write_config_word(dev, cap + PCI_X_CMD, cmd))
+                       return -EIO;
        }
-out:
-       return err;
+       return 0;
 }
 EXPORT_SYMBOL(pcix_set_mmrbc);
 
@@ -3023,7 +3017,6 @@ EXPORT_SYMBOL(pcim_pin_device);
 EXPORT_SYMBOL(pci_disable_device);
 EXPORT_SYMBOL(pci_find_capability);
 EXPORT_SYMBOL(pci_bus_find_capability);
-EXPORT_SYMBOL(pci_register_set_vga_state);
 EXPORT_SYMBOL(pci_release_regions);
 EXPORT_SYMBOL(pci_request_regions);
 EXPORT_SYMBOL(pci_request_regions_exclusive);
index 223052b735634c697739ca37396d10154c93c72c..f8f425b8731ddb91f8663069da23495bf75befcb 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/uaccess.h>
 #include <linux/stddef.h>
index 21f215f4daa30cc090424ee25f4b24bb90d27115..7a711ee314b7f6a6c3da38b4b47082c859e8dfa2 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/pcieport_if.h>
+#include <linux/slab.h>
 
 #include "aerdrv.h"
 #include "../../pci.h"
@@ -243,11 +244,17 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
 
        /* Assert Secondary Bus Reset */
        pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &p2p_ctrl);
-       p2p_ctrl |= PCI_CB_BRIDGE_CTL_CB_RESET;
+       p2p_ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
        pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl);
 
+       /*
+        * we should send hot reset message for 2ms to allow it time to
+        * propogate to all downstream ports
+        */
+       msleep(2);
+
        /* De-assert Secondary Bus Reset */
-       p2p_ctrl &= ~PCI_CB_BRIDGE_CTL_CB_RESET;
+       p2p_ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
        pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl);
 
        /*
index c843a799814d28fde6e8a4832edf986ccde977f0..aceb04b67b60f55979258256e84e93209faf3f24 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/pm.h>
 #include <linux/suspend.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include "aerdrv.h"
 
 static int forceload;
index 7b3cbff547ee9021ab1e680abf3c07ebf22b4b5a..aac285a16b62bec0f84690c5241c4ee82185e383 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/pci.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/device.h>
index 127e8f169d9c2409baa283ca48582e56cbde31fc..3debed25e46bb63f4e70e4a58b0d9abff3fd33be 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/errno.h>
 #include <linux/pm.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/pcieport_if.h>
 #include <linux/aer.h>
 #include <linux/dmi.h>
index 2a943090a3b7838b3a8fcb86a9caa89dfe611133..c82548afcd5cbc4781b1fbf0784c0012475689bb 100644 (file)
@@ -312,7 +312,7 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
                dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
        } else {
                dev_printk(KERN_DEBUG, &dev->dev,
-                        "  bridge window [io  %04lx - %04lx] reg reading\n",
+                        "  bridge window [io  %#06lx-%#06lx] (disabled)\n",
                                 base, limit);
        }
 }
@@ -336,7 +336,7 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
                dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
        } else {
                dev_printk(KERN_DEBUG, &dev->dev,
-                       "  bridge window [mem 0x%08lx - 0x%08lx] reg reading\n",
+                       "  bridge window [mem %#010lx-%#010lx] (disabled)\n",
                                         base, limit + 0xfffff);
        }
 }
@@ -387,7 +387,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
                dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
        } else {
                dev_printk(KERN_DEBUG, &dev->dev,
-                    "  bridge window [mem 0x%08lx - %08lx pref] reg reading\n",
+                    "  bridge window [mem %#010lx-%#010lx pref] (disabled)\n",
                                         base, limit + 0xfffff);
        }
 }
@@ -673,16 +673,20 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
        int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
        u32 buses, i, j = 0;
        u16 bctl;
+       u8 primary, secondary, subordinate;
        int broken = 0;
 
        pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
+       primary = buses & 0xFF;
+       secondary = (buses >> 8) & 0xFF;
+       subordinate = (buses >> 16) & 0xFF;
 
-       dev_dbg(&dev->dev, "scanning behind bridge, config %06x, pass %d\n",
-               buses & 0xffffff, pass);
+       dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n",
+               secondary, subordinate, pass);
 
        /* Check if setup is sensible at all */
        if (!pass &&
-           ((buses & 0xff) != bus->number || ((buses >> 8) & 0xff) <= bus->number)) {
+           (primary != bus->number || secondary <= bus->number)) {
                dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n");
                broken = 1;
        }
@@ -693,15 +697,15 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
        pci_write_config_word(dev, PCI_BRIDGE_CONTROL,
                              bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT);
 
-       if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus && !broken) {
-               unsigned int cmax, busnr;
+       if ((secondary || subordinate) && !pcibios_assign_all_busses() &&
+           !is_cardbus && !broken) {
+               unsigned int cmax;
                /*
                 * Bus already configured by firmware, process it in the first
                 * pass and just note the configuration.
                 */
                if (pass)
                        goto out;
-               busnr = (buses >> 8) & 0xFF;
 
                /*
                 * If we already got to this bus through a different bridge,
@@ -710,13 +714,13 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
                 * However, we continue to descend down the hierarchy and
                 * scan remaining child buses.
                 */
-               child = pci_find_bus(pci_domain_nr(bus), busnr);
+               child = pci_find_bus(pci_domain_nr(bus), secondary);
                if (!child) {
-                       child = pci_add_new_bus(bus, dev, busnr);
+                       child = pci_add_new_bus(bus, dev, secondary);
                        if (!child)
                                goto out;
-                       child->primary = buses & 0xFF;
-                       child->subordinate = (buses >> 16) & 0xFF;
+                       child->primary = primary;
+                       child->subordinate = subordinate;
                        child->bridge_ctl = bctl;
                }
 
index 593bb844b8db68258a41647f709f1d5d6807640d..449e890267a2bae74de8a2b6b0bedf30023b7de0 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
index 81d19d5683ace216b2edd8728c0bde78f3fccf31..27c0e6eb7136030b8c419e91e2c3dae595322a0c 100644 (file)
@@ -368,8 +368,9 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region,
                bus_region.end = res->end;
                pcibios_bus_to_resource(dev, res, &bus_region);
 
-               pci_claim_resource(dev, nr);
-               dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name);
+               if (pci_claim_resource(dev, nr) == 0)
+                       dev_info(&dev->dev, "quirk: %pR claimed by %s\n",
+                                res, name);
        }
 }      
 
@@ -1977,11 +1978,25 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
        /*
         * Disable PCI Bus Parking and PCI Master read caching on CX700
         * which causes unspecified timing errors with a VT6212L on the PCI
-        * bus leading to USB2.0 packet loss. The defaults are that these
-        * features are turned off but some BIOSes turn them on.
+        * bus leading to USB2.0 packet loss.
+        *
+        * This quirk is only enabled if a second (on the external PCI bus)
+        * VT6212L is found -- the CX700 core itself also contains a USB
+        * host controller with the same PCI ID as the VT6212L.
         */
 
+       /* Count VT6212L instances */
+       struct pci_dev *p = pci_get_device(PCI_VENDOR_ID_VIA,
+               PCI_DEVICE_ID_VIA_8235_USB_2, NULL);
        uint8_t b;
+
+       /* p should contain the first (internal) VT6212L -- see if we have
+          an external one by searching again */
+       p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, p);
+       if (!p)
+               return;
+       pci_dev_put(p);
+
        if (pci_read_config_byte(dev, 0x76, &b) == 0) {
                if (b & 0x40) {
                        /* Turn off PCI Bus Parking */
@@ -2008,7 +2023,7 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
                }
        }
 }
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching);
 
 /*
  * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the
@@ -2108,6 +2123,10 @@ static void __devinit quirk_disable_msi(struct pci_dev *dev)
        }
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9602, quirk_disable_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASUSTEK, 0x9602, quirk_disable_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AI, 0x9602, quirk_disable_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi);
 
 /* Go through the list of Hypertransport capabilities and
  * return 1 if a HT MSI capability is found and enabled */
index 4a471dc4f4b9c6167a11de5d8041df65aa371fc1..20d03f7722890807b5a128a2032878180794435d 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include "pci.h"
index 4fe36d2e104930cc99cc7014b27614277d75c9f8..19b111383f62fe63c9859dfd509de2cda3801d9e 100644 (file)
@@ -838,65 +838,11 @@ static void pci_bus_dump_resources(struct pci_bus *bus)
        }
 }
 
-static int __init pci_bus_get_depth(struct pci_bus *bus)
-{
-       int depth = 0;
-       struct pci_dev *dev;
-
-       list_for_each_entry(dev, &bus->devices, bus_list) {
-               int ret;
-               struct pci_bus *b = dev->subordinate;
-               if (!b)
-                       continue;
-
-               ret = pci_bus_get_depth(b);
-               if (ret + 1 > depth)
-                       depth = ret + 1;
-       }
-
-       return depth;
-}
-static int __init pci_get_max_depth(void)
-{
-       int depth = 0;
-       struct pci_bus *bus;
-
-       list_for_each_entry(bus, &pci_root_buses, node) {
-               int ret;
-
-               ret = pci_bus_get_depth(bus);
-               if (ret > depth)
-                       depth = ret;
-       }
-
-       return depth;
-}
-
-/*
- * first try will not touch pci bridge res
- * second  and later try will clear small leaf bridge res
- * will stop till to the max  deepth if can not find good one
- */
 void __init
 pci_assign_unassigned_resources(void)
 {
        struct pci_bus *bus;
-       int tried_times = 0;
-       enum release_type rel_type = leaf_only;
-       struct resource_list_x head, *list;
-       unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
-                                 IORESOURCE_PREFETCH;
-       unsigned long failed_type;
-       int max_depth = pci_get_max_depth();
-       int pci_try_num;
 
-       head.next = NULL;
-
-       pci_try_num = max_depth + 1;
-       printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n",
-                max_depth, pci_try_num);
-
-again:
        /* Depth first, calculate sizes and alignments of all
           subordinate buses. */
        list_for_each_entry(bus, &pci_root_buses, node) {
@@ -904,65 +850,9 @@ again:
        }
        /* Depth last, allocate resources and update the hardware. */
        list_for_each_entry(bus, &pci_root_buses, node) {
-               __pci_bus_assign_resources(bus, &head);
-       }
-       tried_times++;
-
-       /* any device complain? */
-       if (!head.next)
-               goto enable_and_dump;
-       failed_type = 0;
-       for (list = head.next; list;) {
-               failed_type |= list->flags;
-               list = list->next;
-       }
-       /*
-        * io port are tight, don't try extra
-        * or if reach the limit, don't want to try more
-        */
-       failed_type &= type_mask;
-       if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) {
-               free_failed_list(&head);
-               goto enable_and_dump;
-       }
-
-       printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
-                        tried_times + 1);
-
-       /* third times and later will not check if it is leaf */
-       if ((tried_times + 1) > 2)
-               rel_type = whole_subtree;
-
-       /*
-        * Try to release leaf bridge's resources that doesn't fit resource of
-        * child device under that bridge
-        */
-       for (list = head.next; list;) {
-               bus = list->dev->bus;
-               pci_bus_release_bridge_resources(bus, list->flags & type_mask,
-                                                 rel_type);
-               list = list->next;
-       }
-       /* restore size and flags */
-       for (list = head.next; list;) {
-               struct resource *res = list->res;
-
-               res->start = list->start;
-               res->end = list->end;
-               res->flags = list->flags;
-               if (list->dev->subordinate)
-                       res->flags = 0;
-
-               list = list->next;
-       }
-       free_failed_list(&head);
-
-       goto again;
-
-enable_and_dump:
-       /* Depth last, update the hardware. */
-       list_for_each_entry(bus, &pci_root_buses, node)
+               pci_bus_assign_resources(bus);
                pci_enable_bridges(bus);
+       }
 
        /* dump the resource on buses */
        list_for_each_entry(bus, &pci_root_buses, node) {
index 7d678bb15ffb30daed8bebf18d1ef5642a30a13b..17bed18d24ad10eb021e7d3148f8456ff5fe2277 100644 (file)
@@ -93,8 +93,7 @@ void pci_update_resource(struct pci_dev *dev, int resno)
 int pci_claim_resource(struct pci_dev *dev, int resource)
 {
        struct resource *res = &dev->resource[resource];
-       struct resource *root;
-       int err;
+       struct resource *root, *conflict;
 
        root = pci_find_parent_resource(dev, res);
        if (!root) {
@@ -103,12 +102,15 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
                return -EINVAL;
        }
 
-       err = request_resource(root, res);
-       if (err)
+       conflict = request_resource_conflict(root, res);
+       if (conflict) {
                dev_err(&dev->dev,
-                       "address space collision: %pR already in use\n", res);
+                       "address space collision: %pR conflicts with %s %pR\n",
+                       res, conflict->name, conflict);
+               return -EBUSY;
+       }
 
-       return err;
+       return 0;
 }
 EXPORT_SYMBOL(pci_claim_resource);
 
index f75a44d37fbed588ffda8a8742904eca4386b1cf..659eaa0fc48facf81dad9c0b5c430498e01398e3 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/kobject.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/err.h>
 #include "pci.h"
index 5d228071ec69b938fb860ef51470c3adc3ea8025..fb33fa42d249847d1c900a5c374b6859f3cd8dde 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #include <pcmcia/ss.h>
 
@@ -361,7 +362,6 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
        struct at91_cf_socket   *cf = platform_get_drvdata(pdev);
        struct at91_cf_data     *board = cf->board;
 
-       pcmcia_socket_dev_suspend(&pdev->dev);
        if (device_may_wakeup(&pdev->dev)) {
                enable_irq_wake(board->det_pin);
                if (board->irq_pin)
@@ -381,7 +381,6 @@ static int at91_cf_resume(struct platform_device *pdev)
                        disable_irq_wake(board->irq_pin);
        }
 
-       pcmcia_socket_dev_resume(&pdev->dev);
        return 0;
 }
 
index 171c8a654887a65dcb91663e1173d48242923653..88c4c4098789e1e3e3b08dc3847412c570ebfc35 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -510,17 +511,6 @@ static int au1x00_drv_pcmcia_probe(struct platform_device *dev)
        return ret;
 }
 
-static int au1x00_drv_pcmcia_suspend(struct platform_device *dev,
-                                    pm_message_t state)
-{
-       return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int au1x00_drv_pcmcia_resume(struct platform_device *dev)
-{
-       return pcmcia_socket_dev_resume(&dev->dev);
-}
-
 static struct platform_driver au1x00_pcmcia_driver = {
        .driver = {
                .name           = "au1x00-pcmcia",
@@ -528,8 +518,6 @@ static struct platform_driver au1x00_pcmcia_driver = {
        },
        .probe          = au1x00_drv_pcmcia_probe,
        .remove         = au1x00_drv_pcmcia_remove,
-       .suspend        = au1x00_drv_pcmcia_suspend,
-       .resume         = au1x00_drv_pcmcia_resume,
 };
 
 
index bc88a3b19bb349761be651054e070f1ff701d409..693577e0fefc3c52a037bd9af6e63567f67a43c8 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/ioport.h>
 #include <linux/timer.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/gpio.h>
index 2482ce7ac6dcb3f9845eeebe664ab30defeb76b8..9e84d039de41f8d4cf1bedf0ba5902244f25ea49 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/platform_device.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
@@ -300,16 +301,6 @@ static int __devexit bfin_cf_remove(struct platform_device *pdev)
        return 0;
 }
 
-static int bfin_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
-{
-       return pcmcia_socket_dev_suspend(&pdev->dev);
-}
-
-static int bfin_cf_resume(struct platform_device *pdev)
-{
-       return pcmcia_socket_dev_resume(&pdev->dev);
-}
-
 static struct platform_driver bfin_cf_driver = {
        .driver = {
                   .name = (char *)driver_name,
@@ -317,8 +308,6 @@ static struct platform_driver bfin_cf_driver = {
                   },
        .probe = bfin_cf_probe,
        .remove = __devexit_p(bfin_cf_remove),
-       .suspend = bfin_cf_suspend,
-       .resume = bfin_cf_resume,
 };
 
 static int __init bfin_cf_init(void)
index f230f6543bffef6554b20289c445f3730d880d54..854959cada3ae3b302dcfcdb8d6650d14b6f3fd5 100644 (file)
@@ -1484,6 +1484,11 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
        if (!s)
                return -EINVAL;
 
+       if (s->functions) {
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
        /* We do not want to validate the CIS cache... */
        mutex_lock(&s->ops_mutex);
        destroy_cis_cache(s);
@@ -1639,7 +1644,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
                count = 0;
        else {
                struct pcmcia_socket *s;
-               unsigned int chains;
+               unsigned int chains = 1;
 
                if (off + count > size)
                        count = size - off;
@@ -1648,7 +1653,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
 
                if (!(s->state & SOCKET_PRESENT))
                        return -ENODEV;
-               if (pccard_validate_cis(s, &chains))
+               if (!s->functions && pccard_validate_cis(s, &chains))
                        return -EIO;
                if (!chains)
                        return -ENODATA;
index e679e708db630e3c8a93a7f6d87ded908a2c397e..c3383750e33397371f72b46dc1dcc8c0ec51784d 100644 (file)
@@ -76,65 +76,6 @@ DECLARE_RWSEM(pcmcia_socket_list_rwsem);
 EXPORT_SYMBOL(pcmcia_socket_list_rwsem);
 
 
-/*
- * Low-level PCMCIA socket drivers need to register with the PCCard
- * core using pcmcia_register_socket.
- *
- * socket drivers are expected to use the following callbacks in their
- * .drv struct:
- *  - pcmcia_socket_dev_suspend
- *  - pcmcia_socket_dev_resume
- * 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);
-
-static void pcmcia_socket_dev_run(struct device *dev,
-                                 int (*cb)(struct pcmcia_socket *))
-{
-       struct pcmcia_socket *socket;
-
-       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);
-               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);
-
-void pcmcia_socket_dev_early_resume(struct device *dev)
-{
-       pcmcia_socket_dev_run(dev, socket_early_resume);
-}
-EXPORT_SYMBOL(pcmcia_socket_dev_early_resume);
-
-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);
-
-
 struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt)
 {
        struct device *dev = get_device(&skt->dev);
@@ -578,12 +519,18 @@ static int socket_early_resume(struct pcmcia_socket *skt)
 
 static int socket_late_resume(struct pcmcia_socket *skt)
 {
+       int ret;
+
        mutex_lock(&skt->ops_mutex);
        skt->state &= ~SOCKET_SUSPEND;
        mutex_unlock(&skt->ops_mutex);
 
-       if (!(skt->state & SOCKET_PRESENT))
-               return socket_insert(skt);
+       if (!(skt->state & SOCKET_PRESENT)) {
+               ret = socket_insert(skt);
+               if (ret == -ENODEV)
+                       ret = 0;
+               return ret;
+       }
 
        if (skt->resume_status) {
                socket_shutdown(skt);
@@ -724,20 +671,22 @@ static int pccardd(void *__skt)
                                socket_remove(skt);
                        if (sysfs_events & PCMCIA_UEVENT_INSERT)
                                socket_insert(skt);
-                       if ((sysfs_events & PCMCIA_UEVENT_RESUME) &&
-                               !(skt->state & SOCKET_CARDBUS)) {
-                               ret = socket_resume(skt);
-                               if (!ret && skt->callback)
-                                       skt->callback->resume(skt);
-                       }
                        if ((sysfs_events & PCMCIA_UEVENT_SUSPEND) &&
                                !(skt->state & SOCKET_CARDBUS)) {
                                if (skt->callback)
                                        ret = skt->callback->suspend(skt);
                                else
                                        ret = 0;
-                               if (!ret)
+                               if (!ret) {
                                        socket_suspend(skt);
+                                       msleep(100);
+                               }
+                       }
+                       if ((sysfs_events & PCMCIA_UEVENT_RESUME) &&
+                               !(skt->state & SOCKET_CARDBUS)) {
+                               ret = socket_resume(skt);
+                               if (!ret && skt->callback)
+                                       skt->callback->resume(skt);
                        }
                        if ((sysfs_events & PCMCIA_UEVENT_REQUERY) &&
                                !(skt->state & SOCKET_CARDBUS)) {
@@ -919,11 +868,66 @@ static void pcmcia_release_socket_class(struct class *data)
 }
 
 
+#ifdef CONFIG_PM
+
+static int __pcmcia_pm_op(struct device *dev,
+                         int (*callback) (struct pcmcia_socket *skt))
+{
+       struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
+       int ret;
+
+       mutex_lock(&s->skt_mutex);
+       ret = callback(s);
+       mutex_unlock(&s->skt_mutex);
+
+       return ret;
+}
+
+static int pcmcia_socket_dev_suspend_noirq(struct device *dev)
+{
+       return __pcmcia_pm_op(dev, socket_suspend);
+}
+
+static int pcmcia_socket_dev_resume_noirq(struct device *dev)
+{
+       return __pcmcia_pm_op(dev, socket_early_resume);
+}
+
+static int pcmcia_socket_dev_resume(struct device *dev)
+{
+       return __pcmcia_pm_op(dev, socket_late_resume);
+}
+
+static const struct dev_pm_ops pcmcia_socket_pm_ops = {
+       /* dev_resume may be called with IRQs enabled */
+       SET_SYSTEM_SLEEP_PM_OPS(NULL,
+                               pcmcia_socket_dev_resume)
+
+       /* late suspend must be called with IRQs disabled */
+       .suspend_noirq = pcmcia_socket_dev_suspend_noirq,
+       .freeze_noirq = pcmcia_socket_dev_suspend_noirq,
+       .poweroff_noirq = pcmcia_socket_dev_suspend_noirq,
+
+       /* early resume must be called with IRQs disabled */
+       .resume_noirq = pcmcia_socket_dev_resume_noirq,
+       .thaw_noirq = pcmcia_socket_dev_resume_noirq,
+       .restore_noirq = pcmcia_socket_dev_resume_noirq,
+};
+
+#define PCMCIA_SOCKET_CLASS_PM_OPS (&pcmcia_socket_pm_ops)
+
+#else /* CONFIG_PM */
+
+#define PCMCIA_SOCKET_CLASS_PM_OPS NULL
+
+#endif /* CONFIG_PM */
+
 struct class pcmcia_socket_class = {
        .name = "pcmcia_socket",
        .dev_uevent = pcmcia_socket_uevent,
        .dev_release = pcmcia_release_socket,
        .class_release = pcmcia_release_socket_class,
+       .pm = PCMCIA_SOCKET_CLASS_PM_OPS,
 };
 EXPORT_SYMBOL(pcmcia_socket_class);
 
index 9254ab0b29b1b1262fdc1fdb9b1c705041128ae7..0f4cc3f00028ec8d96f4df730c7f2b6fa31f7428 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/pm.h>
 #include <linux/platform_device.h>
 #include <linux/resource.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 
 #include <pcmcia/cs_types.h>
@@ -145,7 +146,6 @@ static irqreturn_t db1200_pcmcia_cdirq(int irq, void *data)
 static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
 {
        int ret;
-       unsigned long flags;
 
        if (sock->stschg_irq != -1) {
                ret = request_irq(sock->stschg_irq, db1000_pcmcia_stschgirq,
@@ -161,8 +161,6 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
         * active one disabled.
         */
        if (sock->board_type == BOARD_TYPE_DB1200) {
-               local_irq_save(flags);
-
                ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq,
                                  IRQF_DISABLED, "pcmcia_insert", sock);
                if (ret)
@@ -172,17 +170,14 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
                                  IRQF_DISABLED, "pcmcia_eject", sock);
                if (ret) {
                        free_irq(sock->insert_irq, sock);
-                       local_irq_restore(flags);
                        goto out1;
                }
 
-               /* disable the currently active one */
+               /* enable the currently silent one */
                if (db1200_card_inserted(sock))
-                       disable_irq_nosync(sock->insert_irq);
+                       enable_irq(sock->eject_irq);
                else
-                       disable_irq_nosync(sock->eject_irq);
-
-               local_irq_restore(flags);
+                       enable_irq(sock->insert_irq);
        } else {
                /* all other (older) Db1x00 boards use a GPIO to show
                 * card detection status:  use both-edge triggers.
@@ -558,37 +553,10 @@ static int __devexit db1x_pcmcia_socket_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
-static int db1x_pcmcia_suspend(struct device *dev)
-{
-       return pcmcia_socket_dev_suspend(dev);
-}
-
-static int db1x_pcmcia_resume(struct device *dev)
-{
-       return pcmcia_socket_dev_resume(dev);
-}
-
-static struct dev_pm_ops db1x_pcmcia_pmops = {
-       .resume         = db1x_pcmcia_resume,
-       .suspend        = db1x_pcmcia_suspend,
-       .thaw           = db1x_pcmcia_resume,
-       .freeze         = db1x_pcmcia_suspend,
-};
-
-#define DB1XXX_SS_PMOPS &db1x_pcmcia_pmops
-
-#else
-
-#define DB1XXX_SS_PMOPS NULL
-
-#endif
-
 static struct platform_driver db1x_pcmcia_socket_driver = {
        .driver = {
                .name   = "db1xxx_pcmcia",
                .owner  = THIS_MODULE,
-               .pm     = DB1XXX_SS_PMOPS
        },
        .probe          = db1x_pcmcia_socket_probe,
        .remove         = __devexit_p(db1x_pcmcia_socket_remove),
index ad93ebd7b2a2f8d3e5cdd65b07bff388d49e3db2..041eee43fd8d67b03a690abe0341039949e43cfc 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/firmware.h>
 #include <linux/kref.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
@@ -334,7 +335,6 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
 
                mutex_lock(&s->ops_mutex);
                list_del(&p_dev->socket_device_list);
-               p_dev->_removed = 1;
                mutex_unlock(&s->ops_mutex);
 
                dev_dbg(&p_dev->dev, "unregistering device\n");
@@ -509,8 +509,12 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
        p_dev->device_no = (s->device_count++);
        mutex_unlock(&s->ops_mutex);
 
-       /* max of 2 devices per card */
-       if (p_dev->device_no >= 2)
+       /* max of 2 PFC devices */
+       if ((p_dev->device_no >= 2) && (function == 0))
+               goto err_free;
+
+       /* max of 4 devices overall */
+       if (p_dev->device_no >= 4)
                goto err_free;
 
        p_dev->socket = s;
@@ -649,14 +653,7 @@ static int pcmcia_requery_callback(struct device *dev, void * _data)
 
 static void pcmcia_requery(struct pcmcia_socket *s)
 {
-       int present, has_pfc;
-
-       mutex_lock(&s->ops_mutex);
-       present = s->pcmcia_state.present;
-       mutex_unlock(&s->ops_mutex);
-
-       if (!present)
-               return;
+       int has_pfc;
 
        if (s->functions == 0) {
                pcmcia_card_add(s);
@@ -682,12 +679,10 @@ static void pcmcia_requery(struct pcmcia_socket *s)
                        new_funcs = mfc.nfn;
                else
                        new_funcs = 1;
-               if (old_funcs > new_funcs) {
+               if (old_funcs != new_funcs) {
+                       /* we need to re-start */
                        pcmcia_card_remove(s, NULL);
                        pcmcia_card_add(s);
-               } else if (new_funcs > old_funcs) {
-                       s->functions = new_funcs;
-                       pcmcia_device_add(s, 1);
                }
        }
 
@@ -723,6 +718,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
        struct pcmcia_socket *s = dev->socket;
        const struct firmware *fw;
        int ret = -ENOMEM;
+       cistpl_longlink_mfc_t mfc;
+       int old_funcs, new_funcs = 1;
 
        if (!filename)
                return -EINVAL;
@@ -745,6 +742,14 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
                        goto release;
                }
 
+               /* we need to re-start if the number of functions changed */
+               old_funcs = s->functions;
+               if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC,
+                                       &mfc))
+                       new_funcs = mfc.nfn;
+
+               if (old_funcs != new_funcs)
+                       ret = -EBUSY;
 
                /* update information */
                pcmcia_device_query(dev);
@@ -815,11 +820,12 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
        }
 
        if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) {
-               if (dev->device_no != did->device_no)
-                       return 0;
+               dev_dbg(&dev->dev, "this is a pseudo-multi-function device\n");
                mutex_lock(&dev->socket->ops_mutex);
                dev->socket->pcmcia_state.has_pfc = 1;
                mutex_unlock(&dev->socket->ops_mutex);
+               if (dev->device_no != did->device_no)
+                       return 0;
        }
 
        if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) {
@@ -830,7 +836,7 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
 
                /* if this is a pseudo-multi-function device,
                 * we need explicit matches */
-               if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO)
+               if (dev->socket->pcmcia_state.has_pfc)
                        return 0;
                if (dev->device_no)
                        return 0;
@@ -853,10 +859,8 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
        if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
                dev_dbg(&dev->dev, "device needs a fake CIS\n");
                if (!dev->socket->fake_cis)
-                       pcmcia_load_firmware(dev, did->cisfile);
-
-               if (!dev->socket->fake_cis)
-                       return 0;
+                       if (pcmcia_load_firmware(dev, did->cisfile))
+                               return 0;
        }
 
        if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) {
@@ -1249,9 +1253,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
 
        switch (event) {
        case CS_EVENT_CARD_REMOVAL:
-               mutex_lock(&s->ops_mutex);
-               s->pcmcia_state.present = 0;
-               mutex_unlock(&s->ops_mutex);
+               atomic_set(&skt->present, 0);
                pcmcia_card_remove(skt, NULL);
                handle_event(skt, event);
                mutex_lock(&s->ops_mutex);
@@ -1260,9 +1262,9 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
                break;
 
        case CS_EVENT_CARD_INSERTION:
+               atomic_set(&skt->present, 1);
                mutex_lock(&s->ops_mutex);
                s->pcmcia_state.has_pfc = 0;
-               s->pcmcia_state.present = 1;
                destroy_cis_cache(s); /* to be on the safe side... */
                mutex_unlock(&s->ops_mutex);
                pcmcia_card_add(skt);
@@ -1281,6 +1283,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
                        destroy_cis_cache(skt);
                        kfree(skt->fake_cis);
                        skt->fake_cis = NULL;
+                       s->functions = 0;
                        mutex_unlock(&s->ops_mutex);
                        /* now, add the new card */
                        ds_event(skt, CS_EVENT_CARD_INSERTION,
@@ -1302,7 +1305,13 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
     return 0;
 } /* ds_event */
 
-
+/*
+ * NOTE: This is racy. There's no guarantee the card will still be
+ * physically present, even if the call to this function returns
+ * non-NULL. Furthermore, the device driver most likely is unbound
+ * almost immediately, so the timeframe where pcmcia_dev_present
+ * returns NULL is probably really really small.
+ */
 struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev)
 {
        struct pcmcia_device *p_dev;
@@ -1312,22 +1321,9 @@ struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev)
        if (!p_dev)
                return NULL;
 
-       mutex_lock(&p_dev->socket->ops_mutex);
-       if (!p_dev->socket->pcmcia_state.present)
-               goto out;
-
-       if (p_dev->socket->pcmcia_state.dead)
-               goto out;
+       if (atomic_read(&p_dev->socket->present) != 0)
+               ret = p_dev;
 
-       if (p_dev->_removed)
-               goto out;
-
-       if (p_dev->suspended)
-               goto out;
-
-       ret = p_dev;
- out:
-       mutex_unlock(&p_dev->socket->ops_mutex);
        pcmcia_put_dev(p_dev);
        return ret;
 }
@@ -1377,6 +1373,8 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev,
                return ret;
        }
 
+       atomic_set(&socket->present, 0);
+
        return 0;
 }
 
@@ -1388,10 +1386,6 @@ static void pcmcia_bus_remove_socket(struct device *dev,
        if (!socket)
                return;
 
-       mutex_lock(&socket->ops_mutex);
-       socket->pcmcia_state.dead = 1;
-       mutex_unlock(&socket->ops_mutex);
-
        pccard_register_pcmcia(socket, NULL);
 
        /* unregister any unbound devices */
index 89cfddca089a7fea87e2e92dcdcb91aaf14adcae..2e59fe947d28095c15fb96327499e07edd8b32ea 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/of_platform.h>
+#include <linux/slab.h>
 
 #include <pcmcia/ss.h>
 
index a04f21c8170f38257c2c46545500c42e0c95bcb8..3003bb3dfcc0d08912897b2192e732ea26cccbf3 100644 (file)
@@ -39,27 +39,11 @@ static struct pci_device_id i82092aa_pci_ids[] = {
 };
 MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids);
 
-#ifdef CONFIG_PM
-static int i82092aa_socket_suspend (struct pci_dev *dev, pm_message_t state)
-{
-       return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int i82092aa_socket_resume (struct pci_dev *dev)
-{
-       return pcmcia_socket_dev_resume(&dev->dev);
-}
-#endif
-
 static struct pci_driver i82092aa_pci_driver = {
        .name           = "i82092aa",
        .id_table       = i82092aa_pci_ids,
        .probe          = i82092aa_pci_probe,
        .remove         = __devexit_p(i82092aa_pci_remove),
-#ifdef CONFIG_PM
-       .suspend        = i82092aa_socket_suspend,
-       .resume         = i82092aa_socket_resume,
-#endif
 };
 
 
@@ -133,6 +117,7 @@ static int __devinit i82092aa_pci_probe(struct pci_dev *dev, const struct pci_de
                sockets[i].socket.map_size = 0x1000;
                sockets[i].socket.irq_mask = 0;
                sockets[i].socket.pci_irq  = dev->irq;
+               sockets[i].socket.cb_dev  = dev;
                sockets[i].socket.owner = THIS_MODULE;
 
                sockets[i].number = i;
index c13fd9360511b89fe3b52f37477bb86a6dab5f1a..9e2a15628de57af889115628a3c9e4aaca7e4a60 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/timer.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/workqueue.h>
@@ -1223,16 +1222,7 @@ static int pcic_init(struct pcmcia_socket *s)
        return 0;
 }
 
-static int i82365_drv_pcmcia_suspend(struct platform_device *dev,
-                                    pm_message_t state)
-{
-       return pcmcia_socket_dev_suspend(&dev->dev);
-}
 
-static int i82365_drv_pcmcia_resume(struct platform_device *dev)
-{
-       return pcmcia_socket_dev_resume(&dev->dev);
-}
 static struct pccard_operations pcic_operations = {
        .init                   = pcic_init,
        .get_status             = pcic_get_status,
@@ -1248,8 +1238,6 @@ static struct platform_driver i82365_driver = {
                .name = "i82365",
                .owner          = THIS_MODULE,
        },
-       .suspend        = i82365_drv_pcmcia_suspend,
-       .resume         = i82365_drv_pcmcia_resume,
 };
 
 static struct platform_device *i82365_device;
index 849ef1b5d687c7683244cb32d89cd29663144dde..3f84d7a2dc84fad3ee64d020268712df618c82f4 100644 (file)
@@ -95,6 +95,7 @@
 #define I365_CSC_DETECT        0x08
 #define I365_CSC_ANY   0x0F
 #define I365_CSC_GPI   0x10
+#define I365_CSC_IRQ_MASK      0xF0
 
 /* Flags for I365_ADDRWIN */
 #define I365_ENA_IO(map)       (0x40 << (map))
index 0ece2cd4a85ea9640bd408fe0dc55ebe65a5692e..7e16ed8eb0a4e0b9ee3b425636fc2d52f0dd5ee1 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/timer.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/workqueue.h>
@@ -685,16 +684,7 @@ static struct pccard_operations pcc_operations = {
        .set_mem_map            = pcc_set_mem_map,
 };
 
-static int cfc_drv_pcmcia_suspend(struct platform_device *dev,
-                                    pm_message_t state)
-{
-       return pcmcia_socket_dev_suspend(&dev->dev);
-}
 
-static int cfc_drv_pcmcia_resume(struct platform_device *dev)
-{
-       return pcmcia_socket_dev_resume(&dev->dev);
-}
 /*====================================================================*/
 
 static struct platform_driver pcc_driver = {
@@ -702,8 +692,6 @@ static struct platform_driver pcc_driver = {
                .name           = "cfc",
                .owner          = THIS_MODULE,
        },
-       .suspend        = cfc_drv_pcmcia_suspend,
-       .resume         = cfc_drv_pcmcia_resume,
 };
 
 static struct platform_device pcc_device = {
index 72844c5a6d05fb53999ded835e5bf56f22ba6a21..6c5c3f910d71435ff542c71eab7e6a0285abfc42 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/timer.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/workqueue.h>
@@ -663,16 +662,6 @@ static struct pccard_operations pcc_operations = {
        .set_mem_map            = pcc_set_mem_map,
 };
 
-static int pcc_drv_pcmcia_suspend(struct platform_device *dev,
-                                    pm_message_t state)
-{
-       return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int pcc_drv_pcmcia_resume(struct platform_device *dev)
-{
-       return pcmcia_socket_dev_resume(&dev->dev);
-}
 /*====================================================================*/
 
 static struct platform_driver pcc_driver = {
@@ -680,8 +669,6 @@ static struct platform_driver pcc_driver = {
                .name           = "pcc",
                .owner          = THIS_MODULE,
        },
-       .suspend        = pcc_drv_pcmcia_suspend,
-       .resume         = pcc_drv_pcmcia_resume,
 };
 
 static struct platform_device pcc_device = {
index 61c2159181288e5442381696b1eb60e2eaed8994..41cc954a5ffee1dd2a87bd4374bd69f22ddb4f9e 100644 (file)
@@ -42,7 +42,6 @@
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
@@ -1288,21 +1287,6 @@ static int m8xx_remove(struct of_device *ofdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
-static int m8xx_suspend(struct platform_device *pdev, pm_message_t state)
-{
-       return pcmcia_socket_dev_suspend(&pdev->dev);
-}
-
-static int m8xx_resume(struct platform_device *pdev)
-{
-       return pcmcia_socket_dev_resume(&pdev->dev);
-}
-#else
-#define m8xx_suspend NULL
-#define m8xx_resume NULL
-#endif
-
 static const struct of_device_id m8xx_pcmcia_match[] = {
        {
         .type = "pcmcia",
@@ -1318,8 +1302,6 @@ static struct of_platform_driver m8xx_pcmcia_driver = {
        .match_table = m8xx_pcmcia_match,
        .probe = m8xx_probe,
        .remove = m8xx_remove,
-       .suspend = m8xx_suspend,
-       .resume = m8xx_resume,
 };
 
 static int __init m8xx_init(void)
index 3ef991552398095ddc9de8b7f2505be88108437f..a7cfc7964c7c6453d3e9de3e1c6e7d214d8f611f 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #include <pcmcia/ss.h>
 
@@ -330,24 +331,12 @@ static int __exit omap_cf_remove(struct platform_device *pdev)
        return 0;
 }
 
-static int omap_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
-{
-       return pcmcia_socket_dev_suspend(&pdev->dev);
-}
-
-static int omap_cf_resume(struct platform_device *pdev)
-{
-       return pcmcia_socket_dev_resume(&pdev->dev);
-}
-
 static struct platform_driver omap_cf_driver = {
        .driver = {
                .name   = (char *) driver_name,
                .owner  = THIS_MODULE,
        },
        .remove         = __exit_p(omap_cf_remove),
-       .suspend        = omap_cf_suspend,
-       .resume         = omap_cf_resume,
 };
 
 static int __init omap_cf_init(void)
index 13a7132cf6885577bbb096e24e87dd32d3fee754..7631faa0caddf5e953123bc451915bd8fbde3a71 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/proc_fs.h>
 #include <linux/poll.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/smp_lock.h>
 #include <linux/workqueue.h>
@@ -710,7 +711,7 @@ static int ds_open(struct inode *inode, struct file *file)
            warning_printed = 1;
     }
 
-    if (s->pcmcia_state.present)
+    if (atomic_read(&s->present))
        queue_event(user, CS_EVENT_CARD_INSERTION);
 out:
     unlock_kernel();
@@ -769,9 +770,6 @@ static ssize_t ds_read(struct file *file, char __user *buf,
        return -EIO;
 
     s = user->socket;
-    if (s->pcmcia_state.dead)
-       return -EIO;
-
     ret = wait_event_interruptible(s->queue, !queue_empty(user));
     if (ret == 0)
        ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
@@ -837,8 +835,6 @@ static int ds_ioctl(struct inode *inode, struct file *file,
        return -EIO;
 
     s = user->socket;
-    if (s->pcmcia_state.dead)
-       return -EIO;
 
     size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
     if (size > sizeof(ds_ioctl_arg_t))
index b2df04199a2197b353ab074cd3a682f65cb7dfa7..7c3d03bb4f304eac0b22fb1ae99db20026133d44 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/pci.h>
 #include <linux/device.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
@@ -256,6 +257,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
 {
        struct pcmcia_socket *s;
        config_t *c;
+       int ret;
 
        s = p_dev->socket;
 
@@ -264,13 +266,13 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
 
        if (!(s->state & SOCKET_PRESENT)) {
                dev_dbg(&s->dev, "No card present\n");
-               mutex_unlock(&s->ops_mutex);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto unlock;
        }
        if (!(c->state & CONFIG_LOCKED)) {
                dev_dbg(&s->dev, "Configuration isnt't locked\n");
-               mutex_unlock(&s->ops_mutex);
-               return -EACCES;
+               ret = -EACCES;
+               goto unlock;
        }
 
        if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
@@ -286,7 +288,8 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
 
        if (mod->Attributes & CONF_VCC_CHANGE_VALID) {
                dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto unlock;
        }
 
        /* We only allow changing Vpp1 and Vpp2 to the same value */
@@ -294,21 +297,21 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
            (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
                if (mod->Vpp1 != mod->Vpp2) {
                        dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n");
-                       mutex_unlock(&s->ops_mutex);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto unlock;
                }
                s->socket.Vpp = mod->Vpp1;
                if (s->ops->set_socket(s, &s->socket)) {
-                       mutex_unlock(&s->ops_mutex);
                        dev_printk(KERN_WARNING, &s->dev,
                                   "Unable to set VPP\n");
-                       return -EIO;
+                       ret = -EIO;
+                       goto unlock;
                }
        } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
                   (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
                dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
-               mutex_unlock(&s->ops_mutex);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto unlock;
        }
 
        if (mod->Attributes & CONF_IO_CHANGE_WIDTH) {
@@ -332,9 +335,11 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
                        s->ops->set_io_map(s, &io_on);
                }
        }
+       ret = 0;
+unlock:
        mutex_unlock(&s->ops_mutex);
 
-       return 0;
+       return ret;
 } /* modify_configuration */
 EXPORT_SYMBOL(pcmcia_modify_configuration);
 
@@ -750,20 +755,12 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
        else
                printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n");
 
-#ifdef CONFIG_PCMCIA_PROBE
-
-#ifdef IRQ_NOAUTOEN
-       /* if the underlying IRQ infrastructure allows for it, only allocate
-        * the IRQ, but do not enable it
-        */
-       if (!(req->Handler))
-               type |= IRQ_NOAUTOEN;
-#endif /* IRQ_NOAUTOEN */
-
-       if (s->irq.AssignedIRQ != 0) {
-               /* If the interrupt is already assigned, it must be the same */
+       /* If the interrupt is already assigned, it must be the same */
+       if (s->irq.AssignedIRQ != 0)
                irq = s->irq.AssignedIRQ;
-       } else {
+
+#ifdef CONFIG_PCMCIA_PROBE
+       if (!irq) {
                int try;
                u32 mask = s->irq_mask;
                void *data = p_dev; /* something unique to this device */
index 7c204910a77742980cf7cdbb448110f65f763611..b61a13663a0a79babf86a0d86722b76d8c02ad40 100644 (file)
@@ -9,18 +9,19 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/device.h>
+#include <linux/io.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
 
 #include <asm/system.h>
-#include <asm/io.h>
 
 #include "pd6729.h"
 #include "i82365.h"
@@ -222,9 +223,9 @@ static irqreturn_t pd6729_interrupt(int irq, void *dev)
                                                ? SS_READY : 0;
                        }
 
-                       if (events) {
+                       if (events)
                                pcmcia_parse_events(&socket[i].socket, events);
-                       }
+
                        active |= events;
                }
 
@@ -256,9 +257,8 @@ static int pd6729_get_status(struct pcmcia_socket *sock, u_int *value)
        status = indirect_read(socket, I365_STATUS);
        *value = 0;
 
-       if ((status & I365_CS_DETECT) == I365_CS_DETECT) {
+       if ((status & I365_CS_DETECT) == I365_CS_DETECT)
                *value |= SS_DETECT;
-       }
 
        /*
         * IO cards have a different meaning of bits 0,1
@@ -308,7 +308,7 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
        socket->card_irq = state->io_irq;
 
        reg = 0;
-       /* The reset bit has "inverse" logic */
+       /* The reset bit has "inverse" logic */
        if (!(state->flags & SS_RESET))
                reg |= I365_PC_RESET;
        if (state->flags & SS_IOCARD)
@@ -380,7 +380,7 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
                indirect_write(socket, I365_POWER, reg);
 
        if (irq_mode == 1) {
-                /* all interrupts are to be done as PCI interrupts */
+               /* all interrupts are to be done as PCI interrupts */
                data = PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ;
        } else
                data = 0;
@@ -391,9 +391,9 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
        /* Enable specific interrupt events */
 
        reg = 0x00;
-       if (state->csc_mask & SS_DETECT) {
+       if (state->csc_mask & SS_DETECT)
                reg |= I365_CSC_DETECT;
-       }
+
        if (state->flags & SS_IOCARD) {
                if (state->csc_mask & SS_STSCHG)
                        reg |= I365_CSC_STSCHG;
@@ -450,9 +450,12 @@ static int pd6729_set_io_map(struct pcmcia_socket *sock,
 
        ioctl = indirect_read(socket, I365_IOCTL) & ~I365_IOCTL_MASK(map);
 
-       if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
-       if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
-       if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
+       if (io->flags & MAP_0WS)
+               ioctl |= I365_IOCTL_0WS(map);
+       if (io->flags & MAP_16BIT)
+               ioctl |= I365_IOCTL_16BIT(map);
+       if (io->flags & MAP_AUTOSZ)
+               ioctl |= I365_IOCTL_IOCS16(map);
 
        indirect_write(socket, I365_IOCTL, ioctl);
 
@@ -497,7 +500,7 @@ static int pd6729_set_mem_map(struct pcmcia_socket *sock,
 
        /* write the stop address */
 
-       i= (mem->res->end >> 12) & 0x0fff;
+       i = (mem->res->end >> 12) & 0x0fff;
        switch (to_cycles(mem->speed)) {
        case 0:
                break;
@@ -563,7 +566,7 @@ static int pd6729_init(struct pcmcia_socket *sock)
 
 /* the pccard structure and its functions */
 static struct pccard_operations pd6729_operations = {
-       .init                   = pd6729_init,
+       .init                   = pd6729_init,
        .get_status             = pd6729_get_status,
        .set_socket             = pd6729_set_socket,
        .set_io_map             = pd6729_set_io_map,
@@ -578,8 +581,13 @@ static irqreturn_t pd6729_test(int irq, void *dev)
 
 static int pd6729_check_irq(int irq)
 {
-       if (request_irq(irq, pd6729_test, IRQF_PROBE_SHARED, "x", pd6729_test)
-               != 0) return -1;
+       int ret;
+
+       ret = request_irq(irq, pd6729_test, IRQF_PROBE_SHARED, "x",
+                         pd6729_test);
+       if (ret)
+               return -1;
+
        free_irq(irq, pd6729_test);
        return 0;
 }
@@ -591,7 +599,7 @@ static u_int __devinit pd6729_isa_scan(void)
 
        if (irq_mode == 1) {
                printk(KERN_INFO "pd6729: PCI card interrupts, "
-                                               "PCI status changes\n");
+                      "PCI status changes\n");
                return 0;
        }
 
@@ -607,9 +615,10 @@ static u_int __devinit pd6729_isa_scan(void)
                if (mask & (1<<i))
                        printk("%s%d", ((mask & ((1<<i)-1)) ? "," : ""), i);
 
-       if (mask == 0) printk("none!");
-
-       printk("  polling status changes.\n");
+       if (mask == 0)
+               printk("none!");
+       else
+               printk("  polling status changes.\n");
 
        return mask;
 }
@@ -624,11 +633,16 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
 
        socket = kzalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS,
                         GFP_KERNEL);
-       if (!socket)
+       if (!socket) {
+               dev_warn(&dev->dev, "failed to kzalloc socket.\n");
                return -ENOMEM;
+       }
 
-       if ((ret = pci_enable_device(dev)))
+       ret = pci_enable_device(dev);
+       if (ret) {
+               dev_warn(&dev->dev, "failed to enable pci_device.\n");
                goto err_out_free_mem;
+       }
 
        if (!pci_resource_start(dev, 0)) {
                dev_warn(&dev->dev, "refusing to load the driver as the "
@@ -639,7 +653,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
        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
         * have had PCI_COMMAND_MEMORY enabled, yet the device needs it.
         */
@@ -671,6 +685,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
                socket[i].socket.map_size = 0x1000;
                socket[i].socket.irq_mask = mask;
                socket[i].socket.pci_irq  = dev->irq;
+               socket[i].socket.cb_dev = dev;
                socket[i].socket.owner = THIS_MODULE;
 
                socket[i].number = i;
@@ -684,8 +699,9 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
        pci_set_drvdata(dev, socket);
        if (irq_mode == 1) {
                /* Register the interrupt handler */
-               if ((ret = request_irq(dev->irq, pd6729_interrupt, IRQF_SHARED,
-                                                       "pd6729", socket))) {
+               ret = request_irq(dev->irq, pd6729_interrupt, IRQF_SHARED,
+                                 "pd6729", socket);
+               if (ret) {
                        dev_err(&dev->dev, "Failed to register irq %d\n",
                                dev->irq);
                        goto err_out_free_res;
@@ -749,18 +765,6 @@ static void __devexit pd6729_pci_remove(struct pci_dev *dev)
        kfree(socket);
 }
 
-#ifdef CONFIG_PM
-static int pd6729_socket_suspend(struct pci_dev *dev, pm_message_t state)
-{
-       return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int pd6729_socket_resume(struct pci_dev *dev)
-{
-       return pcmcia_socket_dev_resume(&dev->dev);
-}
-#endif
-
 static struct pci_device_id pd6729_pci_ids[] = {
        {
                .vendor         = PCI_VENDOR_ID_CIRRUS,
@@ -777,10 +781,6 @@ static struct pci_driver pd6729_pci_driver = {
        .id_table       = pd6729_pci_ids,
        .probe          = pd6729_pci_probe,
        .remove         = __devexit_p(pd6729_pci_remove),
-#ifdef CONFIG_PM
-       .suspend        = pd6729_socket_suspend,
-       .resume         = pd6729_socket_resume,
-#endif
 };
 
 static int pd6729_module_init(void)
index 76e640bccde848c258799b2d4b245e73a17e37bb..df4532e91b1a0da9627a7fc5916c2438a5829af1 100644 (file)
@@ -17,6 +17,7 @@
   ======================================================================*/
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 #include <linux/ioport.h>
@@ -325,19 +326,13 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
        return 0;
 }
 
-static int pxa2xx_drv_pcmcia_suspend(struct device *dev)
-{
-       return pcmcia_socket_dev_suspend(dev);
-}
-
 static int pxa2xx_drv_pcmcia_resume(struct device *dev)
 {
        pxa2xx_configure_sockets(dev);
-       return pcmcia_socket_dev_resume(dev);
+       return 0;
 }
 
 static const struct dev_pm_ops pxa2xx_drv_pcmcia_pm_ops = {
-       .suspend        = pxa2xx_drv_pcmcia_suspend,
        .resume         = pxa2xx_drv_pcmcia_resume,
 };
 
index 452c83b512c47eb8413ae55ffebf1a74251eca84..ffa5f3cae57b4ba543a5664e372281dff36ad000 100644 (file)
@@ -12,6 +12,7 @@
  * (C) 1999            David A. Hinds
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 
index 4663b3fa9f9616a66db5214fc6f5ef16c1b37dc0..a6eb7b59ba9f805c68c13aacda0b7d886a6a9803 100644 (file)
@@ -214,7 +214,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
                return;
        }
        for (i = base, most = 0; i < base+num; i += 8) {
-               res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
+               res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
                if (!res)
                        continue;
                hole = inb(i);
@@ -231,9 +231,14 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
 
        bad = any = 0;
        for (i = base; i < base+num; i += 8) {
-               res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
-               if (!res)
+               res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
+               if (!res) {
+                       if (!any)
+                               printk(" excluding");
+                       if (!bad)
+                               bad = any = i;
                        continue;
+               }
                for (j = 0; j < 8; j++)
                        if (inb(i+j) != most)
                                break;
@@ -253,6 +258,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
        }
        if (bad) {
                if ((num > 16) && (bad == base) && (i == base+num)) {
+                       sub_interval(&s_data->io_db, bad, i-bad);
                        printk(" nothing: probe failed.\n");
                        return;
                } else {
@@ -596,19 +602,17 @@ struct pcmcia_align_data {
        struct resource_map     *map;
 };
 
-static resource_size_t
-pcmcia_common_align(void *align_data, const struct resource *res,
-                       resource_size_t size, resource_size_t align)
+static resource_size_t pcmcia_common_align(struct pcmcia_align_data *align_data,
+                                       resource_size_t start)
 {
-       struct pcmcia_align_data *data = align_data;
-       resource_size_t start;
+       resource_size_t ret;
        /*
         * Ensure that we have the correct start address
         */
-       start = (res->start & ~data->mask) + data->offset;
-       if (start < res->start)
-               start += data->mask + 1;
-       return start;
+       ret = (start & ~align_data->mask) + align_data->offset;
+       if (ret < start)
+               ret += align_data->mask + 1;
+       return ret;
 }
 
 static resource_size_t
@@ -619,29 +623,28 @@ pcmcia_align(void *align_data, const struct resource *res,
        struct resource_map *m;
        resource_size_t start;
 
-       start = pcmcia_common_align(data, res, size, align);
+       start = pcmcia_common_align(data, res->start);
 
        for (m = data->map->next; m != data->map; m = m->next) {
-               unsigned long start = m->base;
-               unsigned long end = m->base + m->num - 1;
+               unsigned long map_start = m->base;
+               unsigned long map_end = m->base + m->num - 1;
 
                /*
                 * If the lower resources are not available, try aligning
                 * to this entry of the resource database to see if it'll
                 * fit here.
                 */
-               if (res->start < start) {
-                       start = pcmcia_common_align(data, res, size, align);
-               }
+               if (start < map_start)
+                       start = pcmcia_common_align(data, map_start);
 
                /*
                 * If we're above the area which was passed in, there's
                 * no point proceeding.
                 */
-               if (res->start >= res->end)
+               if (start >= res->end)
                        break;
 
-               if ((res->start + size - 1) <= end)
+               if ((start + size - 1) <= map_end)
                        break;
        }
 
@@ -807,9 +810,18 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
 static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
 {
        struct socket_data *data = s->resource_data;
-       unsigned long size = end - start + 1;
+       unsigned long size;
        int ret = 0;
 
+#if defined(CONFIG_X86)
+       /* on x86, avoid anything < 0x100 for it is often used for
+        * legacy platform devices */
+       if (start < 0x100)
+               start = 0x100;
+#endif
+
+       size = end - start + 1;
+
        if (end < start)
                return -EINVAL;
 
@@ -867,10 +879,8 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
                        if (res == &ioport_resource)
                                continue;
                        dev_printk(KERN_INFO, &s->cb_dev->dev,
-                                  "pcmcia: parent PCI bridge I/O "
-                                  "window: 0x%llx - 0x%llx\n",
-                                  (unsigned long long)res->start,
-                                  (unsigned long long)res->end);
+                                  "pcmcia: parent PCI bridge window: %pR\n",
+                                  res);
                        if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
                                done |= IORESOURCE_IO;
 
@@ -880,10 +890,8 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
                        if (res == &iomem_resource)
                                continue;
                        dev_printk(KERN_INFO, &s->cb_dev->dev,
-                                  "pcmcia: parent PCI bridge Memory "
-                                  "window: 0x%llx - 0x%llx\n",
-                                  (unsigned long long)res->start,
-                                  (unsigned long long)res->end);
+                                  "pcmcia: parent PCI bridge window: %pR\n",
+                                  res);
                        if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
                                done |= IORESOURCE_MEM;
                }
index 8db86b90c200e089a59dc5ea0fd17e721e490411..edbd8c472628fd8312334803ba21b2c7175d5236 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 
 #include <pcmcia/cs_types.h>
@@ -95,17 +96,6 @@ static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
        return 0;
 }
 
-static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev,
-                                    pm_message_t state)
-{
-       return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int sa11x0_drv_pcmcia_resume(struct platform_device *dev)
-{
-       return pcmcia_socket_dev_resume(&dev->dev);
-}
-
 static struct platform_driver sa11x0_pcmcia_driver = {
        .driver = {
                .name           = "sa11x0-pcmcia",
@@ -113,8 +103,6 @@ static struct platform_driver sa11x0_pcmcia_driver = {
        },
        .probe          = sa11x0_drv_pcmcia_probe,
        .remove         = sa11x0_drv_pcmcia_remove,
-       .suspend        = sa11x0_drv_pcmcia_suspend,
-       .resume         = sa11x0_drv_pcmcia_resume,
 };
 
 /* sa11x0_pcmcia_init()
index db79ca61cf964ec7ba51b71b2d41f7d97dd8e62b..59866905ea37e5f2150221506cf9bac73b2eaa6d 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <pcmcia/ss.h>
 
@@ -213,16 +214,6 @@ static int __devexit pcmcia_remove(struct sa1111_dev *dev)
        return 0;
 }
 
-static int pcmcia_suspend(struct sa1111_dev *dev, pm_message_t state)
-{
-       return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int pcmcia_resume(struct sa1111_dev *dev)
-{
-       return pcmcia_socket_dev_resume(&dev->dev);
-}
-
 static struct sa1111_driver pcmcia_driver = {
        .drv = {
                .name   = "sa1111-pcmcia",
@@ -230,8 +221,6 @@ static struct sa1111_driver pcmcia_driver = {
        .devid          = SA1111_DEVID_PCMCIA,
        .probe          = pcmcia_probe,
        .remove         = __devexit_p(pcmcia_remove),
-       .suspend        = pcmcia_suspend,
-       .resume         = pcmcia_resume,
 };
 
 static int __init sa1111_drv_pcmcia_init(void)
index fc9a6527019b033d21a3d234cc09b2d0c29b792d..fa28d8911b00ade20122e4c2ebe9042835eaea60 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
index 08278016e58dde68a2d8526d6b3cf0d6e9c1a9ef..80e36bc407dac811ab1b6e9e54c1b8bc36f79e77 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/string.h>
 #include <linux/major.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/timer.h>
index 12c49ee135e1edb36ce47a17d06f3be9ee2fe822..56004a1b5bbaefa4683a584a57fbf86d46525ed1 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
@@ -348,16 +347,6 @@ static int __init get_tcic_id(void)
     return id;
 }
 
-static int tcic_drv_pcmcia_suspend(struct platform_device *dev,
-                                    pm_message_t state)
-{
-       return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int tcic_drv_pcmcia_resume(struct platform_device *dev)
-{
-       return pcmcia_socket_dev_resume(&dev->dev);
-}
 /*====================================================================*/
 
 static struct platform_driver tcic_driver = {
@@ -365,8 +354,6 @@ static struct platform_driver tcic_driver = {
                .name = "tcic-pcmcia",
                .owner          = THIS_MODULE,
        },
-       .suspend        = tcic_drv_pcmcia_suspend,
-       .resume         = tcic_drv_pcmcia_resume,
 };
 
 static struct platform_device tcic_device = {
index aaa70227bfb05ee4df811a00fc11df5670d8d50c..9ffa97d0b16c3655469deb0f4895694034ff3182 100644 (file)
@@ -296,7 +296,7 @@ static int ti_init(struct yenta_socket *socket)
        u8 new, reg = exca_readb(socket, I365_INTCTL);
 
        new = reg & ~I365_INTR_ENA;
-       if (socket->cb_irq)
+       if (socket->dev->irq)
                new |= I365_INTR_ENA;
        if (new != reg)
                exca_writeb(socket, I365_INTCTL, new);
@@ -316,14 +316,47 @@ static int ti_override(struct yenta_socket *socket)
        return 0;
 }
 
+static void ti113x_use_isa_irq(struct yenta_socket *socket)
+{
+       int isa_irq = -1;
+       u8 intctl;
+       u32 isa_irq_mask = 0;
+
+       if (!isa_probe)
+               return;
+
+       /* get a free isa int */
+       isa_irq_mask = yenta_probe_irq(socket, isa_interrupts);
+       if (!isa_irq_mask)
+               return; /* no useable isa irq found */
+
+       /* choose highest available */
+       for (; isa_irq_mask; isa_irq++)
+               isa_irq_mask >>= 1;
+       socket->cb_irq = isa_irq;
+
+       exca_writeb(socket, I365_CSCINT, (isa_irq << 4));
+
+       intctl = exca_readb(socket, I365_INTCTL);
+       intctl &= ~(I365_INTR_ENA | I365_IRQ_MASK);     /* CSC Enable */
+       exca_writeb(socket, I365_INTCTL, intctl);
+
+       dev_info(&socket->dev->dev,
+               "Yenta TI113x: using isa irq %d for CardBus\n", isa_irq);
+}
+
+
 static int ti113x_override(struct yenta_socket *socket)
 {
        u8 cardctl;
 
        cardctl = config_readb(socket, TI113X_CARD_CONTROL);
        cardctl &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC);
-       if (socket->cb_irq)
+       if (socket->dev->irq)
                cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ;
+       else
+               ti113x_use_isa_irq(socket);
+
        config_writeb(socket, TI113X_CARD_CONTROL, cardctl);
 
        return ti_override(socket);
index c9fcbdc164eabcd812d12e808b310417795603f7..86e4a1a3c6426d4524a79effd9310fa48c7bc2e3 100644 (file)
@@ -105,6 +105,7 @@ typedef struct vrc4171_socket {
        char name[24];
        int csc_irq;
        int io_irq;
+       spinlock_t lock;
 } vrc4171_socket_t;
 
 static vrc4171_socket_t vrc4171_sockets[CARD_MAX_SLOTS];
@@ -327,7 +328,7 @@ static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
        slot = sock->sock;
        socket = &vrc4171_sockets[slot];
 
-       spin_lock_irq(&sock->lock);
+       spin_lock_irq(&socket->lock);
 
        voltage = set_Vcc_value(state->Vcc);
        exca_write_byte(slot, CARD_VOLTAGE_SELECT, voltage);
@@ -370,7 +371,7 @@ static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
                cscint |= I365_CSC_DETECT;
         exca_write_byte(slot, I365_CSCINT, cscint);
 
-       spin_unlock_irq(&sock->lock);
+       spin_unlock_irq(&socket->lock);
 
        return 0;
 }
@@ -704,24 +705,11 @@ static int __devinit vrc4171_card_setup(char *options)
 
 __setup("vrc4171_card=", vrc4171_card_setup);
 
-static int vrc4171_card_suspend(struct platform_device *dev,
-                                    pm_message_t state)
-{
-       return pcmcia_socket_dev_suspend(&dev->dev);
-}
-
-static int vrc4171_card_resume(struct platform_device *dev)
-{
-       return pcmcia_socket_dev_resume(&dev->dev);
-}
-
 static struct platform_driver vrc4171_card_driver = {
        .driver = {
                .name           = vrc4171_card_name,
                .owner          = THIS_MODULE,
        },
-       .suspend        = vrc4171_card_suspend,
-       .resume         = vrc4171_card_resume,
 };
 
 static int __devinit vrc4171_card_init(void)
index f9009d34254b7c2a3edcc0fb1f3161d83eeb8c14..201ccfa1e97b59a383e2fe05fd12082e3c63f6d5 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/resource.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 
 #include <pcmcia/cs_types.h>
index 967c766f53ba63a0c8939ce236862ae86971204c..83ace277426ca5592cebc5a461b877b90c9c7a6e 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
@@ -42,6 +43,18 @@ module_param_string(o2_speedup, o2_speedup, sizeof(o2_speedup), 0444);
 MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' "
        "or 'default' (uses recommended behaviour for the detected bridge)");
 
+/*
+ * Only probe "regular" interrupts, don't
+ * touch dangerous spots like the mouse irq,
+ * because there are mice that apparently
+ * get really confused if they get fondled
+ * too intimately.
+ *
+ * Default to 11, 10, 9, 7, 6, 5, 4, 3.
+ */
+static u32 isa_interrupts = 0x0ef8;
+
+
 #define debug(x, s, args...) dev_dbg(&s->dev->dev, x, ##args)
 
 /* Don't ask.. */
@@ -54,6 +67,8 @@ MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' "
  */
 #ifdef CONFIG_YENTA_TI
 static int yenta_probe_cb_irq(struct yenta_socket *socket);
+static unsigned int yenta_probe_irq(struct yenta_socket *socket,
+                               u32 isa_irq_mask);
 #endif
 
 
@@ -329,8 +344,8 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
                /* ISA interrupt control? */
                intr = exca_readb(socket, I365_INTCTL);
                intr = (intr & ~0xf);
-               if (!socket->cb_irq) {
-                       intr |= state->io_irq;
+               if (!socket->dev->irq) {
+                       intr |= socket->cb_irq ? socket->cb_irq : state->io_irq;
                        bridge |= CB_BRIDGE_INTR;
                }
                exca_writeb(socket, I365_INTCTL, intr);
@@ -340,7 +355,7 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
                reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA);
                reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
                reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
-               if (state->io_irq != socket->cb_irq) {
+               if (state->io_irq != socket->dev->irq) {
                        reg |= state->io_irq;
                        bridge |= CB_BRIDGE_INTR;
                }
@@ -356,7 +371,9 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
                        exca_writeb(socket, I365_POWER, reg);
 
                /* CSC interrupt: no ISA irq for CSC */
-               reg = I365_CSC_DETECT;
+               reg = exca_readb(socket, I365_CSCINT);
+               reg &= I365_CSC_IRQ_MASK;
+               reg |= I365_CSC_DETECT;
                if (state->flags & SS_IOCARD) {
                        if (state->csc_mask & SS_STSCHG)
                                reg |= I365_CSC_STSCHG;
@@ -896,22 +913,12 @@ static struct cardbus_type cardbus_type[] = {
 };
 
 
-/*
- * Only probe "regular" interrupts, don't
- * touch dangerous spots like the mouse irq,
- * because there are mice that apparently
- * get really confused if they get fondled
- * too intimately.
- *
- * Default to 11, 10, 9, 7, 6, 5, 4, 3.
- */
-static u32 isa_interrupts = 0x0ef8;
-
 static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask)
 {
        int i;
        unsigned long val;
        u32 mask;
+       u8 reg;
 
        /*
         * Probe for usable interrupts using the force
@@ -919,6 +926,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
         */
        cb_writel(socket, CB_SOCKET_EVENT, -1);
        cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
+       reg = exca_readb(socket, I365_CSCINT);
        exca_writeb(socket, I365_CSCINT, 0);
        val = probe_irq_on() & isa_irq_mask;
        for (i = 1; i < 16; i++) {
@@ -930,7 +938,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
                cb_writel(socket, CB_SOCKET_EVENT, -1);
        }
        cb_writel(socket, CB_SOCKET_MASK, 0);
-       exca_writeb(socket, I365_CSCINT, 0);
+       exca_writeb(socket, I365_CSCINT, reg);
 
        mask = probe_irq_mask(val) & 0xffff;
 
@@ -967,6 +975,8 @@ static irqreturn_t yenta_probe_handler(int irq, void *dev_id)
 /* probes the PCI interrupt, use only on override functions */
 static int yenta_probe_cb_irq(struct yenta_socket *socket)
 {
+       u8 reg;
+
        if (!socket->cb_irq)
                return -1;
 
@@ -979,7 +989,8 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
        }
 
        /* generate interrupt, wait */
-       exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG);
+       reg = exca_readb(socket, I365_CSCINT);
+       exca_writeb(socket, I365_CSCINT, reg | I365_CSC_STSCHG);
        cb_writel(socket, CB_SOCKET_EVENT, -1);
        cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
        cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS);
@@ -988,7 +999,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
 
        /* disable interrupts */
        cb_writel(socket, CB_SOCKET_MASK, 0);
-       exca_writeb(socket, I365_CSCINT, 0);
+       exca_writeb(socket, I365_CSCINT, reg);
        cb_writel(socket, CB_SOCKET_EVENT, -1);
        exca_readb(socket, I365_CSC);
 
@@ -1280,12 +1291,9 @@ static int yenta_dev_suspend_noirq(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
        struct yenta_socket *socket = pci_get_drvdata(pdev);
-       int ret;
-
-       ret = pcmcia_socket_dev_suspend(dev);
 
        if (!socket)
-               return ret;
+               return 0;
 
        if (socket->type && socket->type->save_state)
                socket->type->save_state(socket);
@@ -1302,7 +1310,7 @@ static int yenta_dev_suspend_noirq(struct device *dev)
         */
        /* pci_set_power_state(dev, 3); */
 
-       return ret;
+       return 0;
 }
 
 static int yenta_dev_resume_noirq(struct device *dev)
@@ -1326,26 +1334,16 @@ static int yenta_dev_resume_noirq(struct device *dev)
        if (socket->type && socket->type->restore_state)
                socket->type->restore_state(socket);
 
-       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 const 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)
index e631dbeafd798ff87d9d7a0eee27953c6d5aa446..6c3320d7505533804881a56fb349534b4eea0e4c 100644 (file)
@@ -385,6 +385,17 @@ config EEEPC_LAPTOP
 
          If you have an Eee PC laptop, say Y or M here.
 
+config EEEPC_WMI
+       tristate "Eee PC WMI Hotkey Driver (EXPERIMENTAL)"
+       depends on ACPI_WMI
+       depends on INPUT
+       depends on EXPERIMENTAL
+       select INPUT_SPARSEKMAP
+       ---help---
+         Say Y here if you want to support WMI-based hotkeys on Eee PC laptops.
+
+         To compile this driver as a module, choose M here: the module will
+         be called eeepc-wmi.
 
 config ACPI_WMI
        tristate "WMI"
index 9cd9fa0a27e640389cd22a0872cbbdf48933adf5..a906490e3530a91f44b41b571af0b9737d85feae 100644 (file)
@@ -4,6 +4,7 @@
 #
 obj-$(CONFIG_ASUS_LAPTOP)      += asus-laptop.o
 obj-$(CONFIG_EEEPC_LAPTOP)     += eeepc-laptop.o
+obj-$(CONFIG_EEEPC_WMI)                += eeepc-wmi.o
 obj-$(CONFIG_MSI_LAPTOP)       += msi-laptop.o
 obj-$(CONFIG_ACPI_CMPC)                += classmate-laptop.o
 obj-$(CONFIG_COMPAL_LAPTOP)    += compal-laptop.o
index 226b3e93498c45d8f63fc2f67544950a512b20cd..1ea6c434d3304756cedc826616e117aaa70c1050 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/rfkill.h>
 #include <linux/workqueue.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 
 #include <acpi/acpi_drivers.h>
 
@@ -922,9 +923,13 @@ static struct backlight_ops acer_bl_ops = {
 
 static int __devinit acer_backlight_init(struct device *dev)
 {
+       struct backlight_properties props;
        struct backlight_device *bd;
 
-       bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = max_brightness;
+       bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops,
+                                      &props);
        if (IS_ERR(bd)) {
                printk(ACER_ERR "Could not register Acer backlight device\n");
                acer_backlight_device = NULL;
@@ -935,7 +940,6 @@ static int __devinit acer_backlight_init(struct device *dev)
 
        bd->props.power = FB_BLANK_UNBLANK;
        bd->props.brightness = read_brightness(bd);
-       bd->props.max_brightness = max_brightness;
        backlight_update_status(bd);
        return 0;
 }
index 791fcf321506af6df46e243e061539a47c88cdad..efe8f63889065dff18aa9ae7d7d4ffb10d6d9279 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
 #include <linux/rfkill.h>
+#include <linux/slab.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
 
@@ -78,15 +79,15 @@ static uint wapf = 1;
 module_param(wapf, uint, 0644);
 MODULE_PARM_DESC(wapf, "WAPF value");
 
-static uint wlan_status = 1;
-static uint bluetooth_status = 1;
+static int wlan_status = 1;
+static int bluetooth_status = 1;
 
-module_param(wlan_status, uint, 0644);
+module_param(wlan_status, int, 0644);
 MODULE_PARM_DESC(wlan_status, "Set the wireless status on boot "
                 "(0 = disabled, 1 = enabled, -1 = don't do anything). "
                 "default is 1");
 
-module_param(bluetooth_status, uint, 0644);
+module_param(bluetooth_status, int, 0644);
 MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot "
                 "(0 = disabled, 1 = enabled, -1 = don't do anything). "
                 "default is 1");
@@ -139,7 +140,7 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot "
 
 /* Backlight */
 static acpi_handle lcd_switch_handle;
-static const char *lcd_switch_paths[] = {
+static char *lcd_switch_paths[] = {
   "\\_SB.PCI0.SBRG.EC0._Q10",  /* All new models */
   "\\_SB.PCI0.ISA.EC0._Q10",   /* A1x */
   "\\_SB.PCI0.PX40.ECD0._Q10", /* L3C */
@@ -153,7 +154,7 @@ static const char *lcd_switch_paths[] = {
 #define METHOD_SWITCH_DISPLAY  "SDSP"
 
 static acpi_handle display_get_handle;
-static const char *display_get_paths[] = {
+static char *display_get_paths[] = {
   /* A6B, A6K A6R A7D F3JM L4R M6R A3G M6A M6V VX-1 V6J V6V W3Z */
   "\\_SB.PCI0.P0P1.VGA.GETD",
   /* A3E A4K, A4D A4L A6J A7J A8J Z71V M9V S5A M5A z33A W1Jc W2V G1 */
@@ -639,12 +640,16 @@ static int asus_backlight_init(struct asus_laptop *asus)
 {
        struct backlight_device *bd;
        struct device *dev = &asus->platform_device->dev;
+       struct backlight_properties props;
 
        if (!acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_GET, NULL) &&
            !acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_SET, NULL) &&
            lcd_switch_handle) {
+               memset(&props, 0, sizeof(struct backlight_properties));
+               props.max_brightness = 15;
+
                bd = backlight_device_register(ASUS_LAPTOP_FILE, dev,
-                                              asus, &asusbl_ops);
+                                              asus, &asusbl_ops, &props);
                if (IS_ERR(bd)) {
                        pr_err("Could not register asus backlight device\n");
                        asus->backlight_device = NULL;
@@ -653,7 +658,6 @@ static int asus_backlight_init(struct asus_laptop *asus)
 
                asus->backlight_device = bd;
 
-               bd->props.max_brightness = 15;
                bd->props.power = FB_BLANK_UNBLANK;
                bd->props.brightness = asus_read_brightness(bd);
                backlight_update_status(bd);
index 1381430e110565f012f4c98bb7927b01874fd026..92fd30c9379ce3eb2f6ab6bf4b6b7dbfb7dc5b9f 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
@@ -1481,6 +1482,7 @@ static void asus_acpi_exit(void)
 
 static int __init asus_acpi_init(void)
 {
+       struct backlight_properties props;
        int result;
 
        result = acpi_bus_register_driver(&asus_hotk_driver);
@@ -1507,15 +1509,17 @@ static int __init asus_acpi_init(void)
                return -ENODEV;
        }
 
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 15;
        asus_backlight_device = backlight_device_register("asus", NULL, NULL,
-                                                         &asus_backlight_data);
+                                                         &asus_backlight_data,
+                                                         &props);
        if (IS_ERR(asus_backlight_device)) {
                printk(KERN_ERR "Could not register asus backlight device\n");
                asus_backlight_device = NULL;
                asus_acpi_exit();
                return -ENODEV;
        }
-       asus_backlight_device->props.max_brightness = 15;
 
        return 0;
 }
index 035a7dd65a3fdf87d08305b9f0d663446240d4cd..7f9e5ddc949841ba3c80d15aa75d94a60e9385c0 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <acpi/acpi_drivers.h>
 #include <linux/backlight.h>
@@ -455,18 +456,22 @@ static int cmpc_bl_update_status(struct backlight_device *bd)
                return -1;
 }
 
-static struct backlight_ops cmpc_bl_ops = {
+static const struct backlight_ops cmpc_bl_ops = {
        .get_brightness = cmpc_bl_get_brightness,
        .update_status = cmpc_bl_update_status
 };
 
 static int cmpc_bl_add(struct acpi_device *acpi)
 {
+       struct backlight_properties props;
        struct backlight_device *bd;
 
-       bd = backlight_device_register("cmpc_bl", &acpi->dev,
-                                      acpi->handle, &cmpc_bl_ops);
-       bd->props.max_brightness = 7;
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 7;
+       bd = backlight_device_register("cmpc_bl", &acpi->dev, acpi->handle,
+                                      &cmpc_bl_ops, &props);
+       if (IS_ERR(bd))
+               return PTR_ERR(bd);
        dev_set_drvdata(&acpi->dev, bd);
        return 0;
 }
index 2740b40aad9b318bbaf289357c197b6294323bf8..71ff1545a93e0a87e3c0ea80953e909c7f901424 100644 (file)
@@ -291,12 +291,15 @@ static int __init compal_init(void)
        /* Register backlight stuff */
 
        if (!acpi_video_backlight_support()) {
-               compalbl_device = backlight_device_register("compal-laptop", NULL, NULL,
-                                                           &compalbl_ops);
+               struct backlight_properties props;
+               memset(&props, 0, sizeof(struct backlight_properties));
+               props.max_brightness = COMPAL_LCD_LEVEL_MAX - 1;
+               compalbl_device = backlight_device_register("compal-laptop",
+                                                           NULL, NULL,
+                                                           &compalbl_ops,
+                                                           &props);
                if (IS_ERR(compalbl_device))
                        return PTR_ERR(compalbl_device);
-
-               compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1;
        }
 
        ret = platform_driver_register(&compal_driver);
index ef614979afe97de3f5c3e90eb4c37214374ac6e8..661e3ac4d5b112edfa417b154ae6a60e104c2ffa 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/acpi.h>
 #include <linux/mm.h>
 #include <linux/i8042.h>
+#include <linux/slab.h>
 #include "../../firmware/dcdbas.h"
 
 #define BRIGHTNESS_TOKEN 0x7d
@@ -559,10 +560,14 @@ static int __init dell_init(void)
        release_buffer();
 
        if (max_intensity) {
-               dell_backlight_device = backlight_device_register(
-                       "dell_backlight",
-                       &platform_device->dev, NULL,
-                       &dell_ops);
+               struct backlight_properties props;
+               memset(&props, 0, sizeof(struct backlight_properties));
+               props.max_brightness = max_intensity;
+               dell_backlight_device = backlight_device_register("dell_backlight",
+                                                                 &platform_device->dev,
+                                                                 NULL,
+                                                                 &dell_ops,
+                                                                 &props);
 
                if (IS_ERR(dell_backlight_device)) {
                        ret = PTR_ERR(dell_backlight_device);
@@ -570,7 +575,6 @@ static int __init dell_init(void)
                        goto fail_backlight;
                }
 
-               dell_backlight_device->props.max_brightness = max_intensity;
                dell_backlight_device->props.brightness =
                        dell_get_intensity(dell_backlight_device);
                backlight_update_status(dell_backlight_device);
index bed764e3ea2a03f5892194d8e992bc4ccf9987c1..66f53c3c35e8bf3fef464b2c8fae431167bca464 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/input.h>
 #include <acpi/acpi_drivers.h>
@@ -216,6 +217,7 @@ static void dell_wmi_notify(u32 value, void *context)
                if (dell_new_hk_type && (buffer_entry[1] != 0x10)) {
                        printk(KERN_INFO "dell-wmi: Received unknown WMI event"
                                         " (0x%x)\n", buffer_entry[1]);
+                       kfree(obj);
                        return;
                }
 
@@ -233,7 +235,7 @@ static void dell_wmi_notify(u32 value, void *context)
                            key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) {
                        /* Don't report brightness notifications that will also
                         * come via ACPI */
-                       return;
+                       ;
                } else {
                        input_report_key(dell_wmi_input_dev, key->keycode, 1);
                        input_sync(dell_wmi_input_dev);
index 9a844caa3756717e9dd355d1309b6bf6c46cfb4d..0306174ba8758ed69a44c57c8e7dcef0a1c7802f 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/fb.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/slab.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
 #include <linux/uaccess.h>
@@ -168,7 +169,6 @@ struct eeepc_laptop {
        struct backlight_device *backlight_device;
 
        struct input_dev *inputdev;
-       struct key_entry *keymap;
 
        struct rfkill *wlan_rfkill;
        struct rfkill *bluetooth_rfkill;
@@ -1131,18 +1131,20 @@ static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
 
 static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
 {
+       struct backlight_properties props;
        struct backlight_device *bd;
 
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 15;
        bd = backlight_device_register(EEEPC_LAPTOP_FILE,
-                                      &eeepc->platform_device->dev,
-                                      eeepc, &eeepcbl_ops);
+                                      &eeepc->platform_device->dev, eeepc,
+                                      &eeepcbl_ops, &props);
        if (IS_ERR(bd)) {
                pr_err("Could not register eeepc backlight device\n");
                eeepc->backlight_device = NULL;
                return PTR_ERR(bd);
        }
        eeepc->backlight_device = bd;
-       bd->props.max_brightness = 15;
        bd->props.brightness = read_brightness(bd);
        bd->props.power = FB_BLANK_UNBLANK;
        backlight_update_status(bd);
@@ -1201,8 +1203,8 @@ static int eeepc_input_init(struct eeepc_laptop *eeepc)
 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
 {
        if (eeepc->inputdev) {
+               sparse_keymap_free(eeepc->inputdev);
                input_unregister_device(eeepc->inputdev);
-               kfree(eeepc->keymap);
        }
 }
 
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
new file mode 100644 (file)
index 0000000..b227eb4
--- /dev/null
@@ -0,0 +1,413 @@
+/*
+ * Eee PC WMI hotkey driver
+ *
+ * Copyright(C) 2010 Intel Corporation.
+ *
+ * Portions based on wistron_btns.c:
+ * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
+ * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
+ * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
+ *
+ *  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 pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#define        EEEPC_WMI_FILE  "eeepc-wmi"
+
+MODULE_AUTHOR("Yong Wang <yong.y.wang@intel.com>");
+MODULE_DESCRIPTION("Eee PC WMI Hotkey Driver");
+MODULE_LICENSE("GPL");
+
+#define EEEPC_WMI_EVENT_GUID   "ABBC0F72-8EA1-11D1-00A0-C90629100000"
+#define EEEPC_WMI_MGMT_GUID    "97845ED0-4E6D-11DE-8A39-0800200C9A66"
+
+MODULE_ALIAS("wmi:"EEEPC_WMI_EVENT_GUID);
+MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
+
+#define NOTIFY_BRNUP_MIN       0x11
+#define NOTIFY_BRNUP_MAX       0x1f
+#define NOTIFY_BRNDOWN_MIN     0x20
+#define NOTIFY_BRNDOWN_MAX     0x2e
+
+#define EEEPC_WMI_METHODID_DEVS        0x53564544
+#define EEEPC_WMI_METHODID_DSTS        0x53544344
+
+#define EEEPC_WMI_DEVID_BACKLIGHT      0x00050012
+
+static const struct key_entry eeepc_wmi_keymap[] = {
+       /* Sleep already handled via generic ACPI code */
+       { KE_KEY, 0x5d, { KEY_WLAN } },
+       { KE_KEY, 0x32, { KEY_MUTE } },
+       { KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
+       { KE_KEY, 0x30, { KEY_VOLUMEUP } },
+       { KE_IGNORE, NOTIFY_BRNDOWN_MIN, { KEY_BRIGHTNESSDOWN } },
+       { KE_IGNORE, NOTIFY_BRNUP_MIN, { KEY_BRIGHTNESSUP } },
+       { KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } },
+       { KE_END, 0},
+};
+
+struct bios_args {
+       u32     dev_id;
+       u32     ctrl_param;
+};
+
+struct eeepc_wmi {
+       struct input_dev *inputdev;
+       struct backlight_device *backlight_device;
+};
+
+static struct platform_device *platform_device;
+
+static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc)
+{
+       int err;
+
+       eeepc->inputdev = input_allocate_device();
+       if (!eeepc->inputdev)
+               return -ENOMEM;
+
+       eeepc->inputdev->name = "Eee PC WMI hotkeys";
+       eeepc->inputdev->phys = EEEPC_WMI_FILE "/input0";
+       eeepc->inputdev->id.bustype = BUS_HOST;
+       eeepc->inputdev->dev.parent = &platform_device->dev;
+
+       err = sparse_keymap_setup(eeepc->inputdev, eeepc_wmi_keymap, NULL);
+       if (err)
+               goto err_free_dev;
+
+       err = input_register_device(eeepc->inputdev);
+       if (err)
+               goto err_free_keymap;
+
+       return 0;
+
+err_free_keymap:
+       sparse_keymap_free(eeepc->inputdev);
+err_free_dev:
+       input_free_device(eeepc->inputdev);
+       return err;
+}
+
+static void eeepc_wmi_input_exit(struct eeepc_wmi *eeepc)
+{
+       if (eeepc->inputdev) {
+               sparse_keymap_free(eeepc->inputdev);
+               input_unregister_device(eeepc->inputdev);
+       }
+
+       eeepc->inputdev = NULL;
+}
+
+static acpi_status eeepc_wmi_get_devstate(u32 dev_id, u32 *ctrl_param)
+{
+       struct acpi_buffer input = { (acpi_size)sizeof(u32), &dev_id };
+       struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+       union acpi_object *obj;
+       acpi_status status;
+       u32 tmp;
+
+       status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
+                       1, EEEPC_WMI_METHODID_DSTS, &input, &output);
+
+       if (ACPI_FAILURE(status))
+               return status;
+
+       obj = (union acpi_object *)output.pointer;
+       if (obj && obj->type == ACPI_TYPE_INTEGER)
+               tmp = (u32)obj->integer.value;
+       else
+               tmp = 0;
+
+       if (ctrl_param)
+               *ctrl_param = tmp;
+
+       kfree(obj);
+
+       return status;
+
+}
+
+static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param)
+{
+       struct bios_args args = {
+               .dev_id = dev_id,
+               .ctrl_param = ctrl_param,
+       };
+       struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
+       acpi_status status;
+
+       status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
+                       1, EEEPC_WMI_METHODID_DEVS, &input, NULL);
+
+       return status;
+}
+
+static int read_brightness(struct backlight_device *bd)
+{
+       static u32 ctrl_param;
+       acpi_status status;
+
+       status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT, &ctrl_param);
+
+       if (ACPI_FAILURE(status))
+               return -1;
+       else
+               return ctrl_param & 0xFF;
+}
+
+static int update_bl_status(struct backlight_device *bd)
+{
+
+       static u32 ctrl_param;
+       acpi_status status;
+
+       ctrl_param = bd->props.brightness;
+
+       status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT, ctrl_param);
+
+       if (ACPI_FAILURE(status))
+               return -1;
+       else
+               return 0;
+}
+
+static const struct backlight_ops eeepc_wmi_bl_ops = {
+       .get_brightness = read_brightness,
+       .update_status = update_bl_status,
+};
+
+static int eeepc_wmi_backlight_notify(struct eeepc_wmi *eeepc, int code)
+{
+       struct backlight_device *bd = eeepc->backlight_device;
+       int old = bd->props.brightness;
+       int new;
+
+       if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
+               new = code - NOTIFY_BRNUP_MIN + 1;
+       else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
+               new = code - NOTIFY_BRNDOWN_MIN;
+
+       bd->props.brightness = new;
+       backlight_update_status(bd);
+       backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
+
+       return old;
+}
+
+static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
+{
+       struct backlight_device *bd;
+       struct backlight_properties props;
+
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 15;
+       bd = backlight_device_register(EEEPC_WMI_FILE,
+                                      &platform_device->dev, eeepc,
+                                      &eeepc_wmi_bl_ops, &props);
+       if (IS_ERR(bd)) {
+               pr_err("Could not register backlight device\n");
+               return PTR_ERR(bd);
+       }
+
+       eeepc->backlight_device = bd;
+
+       bd->props.brightness = read_brightness(bd);
+       bd->props.power = FB_BLANK_UNBLANK;
+       backlight_update_status(bd);
+
+       return 0;
+}
+
+static void eeepc_wmi_backlight_exit(struct eeepc_wmi *eeepc)
+{
+       if (eeepc->backlight_device)
+               backlight_device_unregister(eeepc->backlight_device);
+
+       eeepc->backlight_device = NULL;
+}
+
+static void eeepc_wmi_notify(u32 value, void *context)
+{
+       struct eeepc_wmi *eeepc = context;
+       struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+       union acpi_object *obj;
+       acpi_status status;
+       int code;
+       int orig_code;
+
+       status = wmi_get_event_data(value, &response);
+       if (status != AE_OK) {
+               pr_err("bad event status 0x%x\n", status);
+               return;
+       }
+
+       obj = (union acpi_object *)response.pointer;
+
+       if (obj && obj->type == ACPI_TYPE_INTEGER) {
+               code = obj->integer.value;
+               orig_code = code;
+
+               if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
+                       code = NOTIFY_BRNUP_MIN;
+               else if (code >= NOTIFY_BRNDOWN_MIN &&
+                        code <= NOTIFY_BRNDOWN_MAX)
+                       code = NOTIFY_BRNDOWN_MIN;
+
+               if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) {
+                       if (!acpi_video_backlight_support())
+                               eeepc_wmi_backlight_notify(eeepc, orig_code);
+               }
+
+               if (!sparse_keymap_report_event(eeepc->inputdev,
+                                               code, 1, true))
+                       pr_info("Unknown key %x pressed\n", code);
+       }
+
+       kfree(obj);
+}
+
+static int __devinit eeepc_wmi_platform_probe(struct platform_device *device)
+{
+       struct eeepc_wmi *eeepc;
+       int err;
+       acpi_status status;
+
+       eeepc = platform_get_drvdata(device);
+
+       err = eeepc_wmi_input_init(eeepc);
+       if (err)
+               goto error_input;
+
+       if (!acpi_video_backlight_support()) {
+               err = eeepc_wmi_backlight_init(eeepc);
+               if (err)
+                       goto error_backlight;
+       } else
+               pr_info("Backlight controlled by ACPI video driver\n");
+
+       status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID,
+                                       eeepc_wmi_notify, eeepc);
+       if (ACPI_FAILURE(status)) {
+               pr_err("Unable to register notify handler - %d\n",
+                       status);
+               err = -ENODEV;
+               goto error_wmi;
+       }
+
+       return 0;
+
+error_wmi:
+       eeepc_wmi_backlight_exit(eeepc);
+error_backlight:
+       eeepc_wmi_input_exit(eeepc);
+error_input:
+       return err;
+}
+
+static int __devexit eeepc_wmi_platform_remove(struct platform_device *device)
+{
+       struct eeepc_wmi *eeepc;
+
+       eeepc = platform_get_drvdata(device);
+       wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
+       eeepc_wmi_backlight_exit(eeepc);
+       eeepc_wmi_input_exit(eeepc);
+
+       return 0;
+}
+
+static struct platform_driver platform_driver = {
+       .driver = {
+               .name = EEEPC_WMI_FILE,
+               .owner = THIS_MODULE,
+       },
+       .probe = eeepc_wmi_platform_probe,
+       .remove = __devexit_p(eeepc_wmi_platform_remove),
+};
+
+static int __init eeepc_wmi_init(void)
+{
+       struct eeepc_wmi *eeepc;
+       int err;
+
+       if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID) ||
+           !wmi_has_guid(EEEPC_WMI_MGMT_GUID)) {
+               pr_warning("No known WMI GUID found\n");
+               return -ENODEV;
+       }
+
+       eeepc = kzalloc(sizeof(struct eeepc_wmi), GFP_KERNEL);
+       if (!eeepc)
+               return -ENOMEM;
+
+       platform_device = platform_device_alloc(EEEPC_WMI_FILE, -1);
+       if (!platform_device) {
+               pr_warning("Unable to allocate platform device\n");
+               err = -ENOMEM;
+               goto fail_platform;
+       }
+
+       err = platform_device_add(platform_device);
+       if (err) {
+               pr_warning("Unable to add platform device\n");
+               goto put_dev;
+       }
+
+       platform_set_drvdata(platform_device, eeepc);
+
+       err = platform_driver_register(&platform_driver);
+       if (err) {
+               pr_warning("Unable to register platform driver\n");
+               goto del_dev;
+       }
+
+       return 0;
+
+del_dev:
+       platform_device_del(platform_device);
+put_dev:
+       platform_device_put(platform_device);
+fail_platform:
+       kfree(eeepc);
+
+       return err;
+}
+
+static void __exit eeepc_wmi_exit(void)
+{
+       struct eeepc_wmi *eeepc;
+
+       eeepc = platform_get_drvdata(platform_device);
+       platform_driver_unregister(&platform_driver);
+       platform_device_unregister(platform_device);
+       kfree(eeepc);
+}
+
+module_init(eeepc_wmi_init);
+module_exit(eeepc_wmi_exit);
index 5f3320d468f61bd6aa37d7606e86570508910b81..47b4fd75aa344966b3933af9ca7b09acf7eee613 100644 (file)
@@ -66,6 +66,7 @@
 #include <linux/kfifo.h>
 #include <linux/video_output.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
 #include <linux/leds.h>
 #endif
@@ -1126,16 +1127,20 @@ static int __init fujitsu_init(void)
        /* Register backlight stuff */
 
        if (!acpi_video_backlight_support()) {
-               fujitsu->bl_device =
-                       backlight_device_register("fujitsu-laptop", NULL, NULL,
-                                                 &fujitsubl_ops);
+               struct backlight_properties props;
+
+               memset(&props, 0, sizeof(struct backlight_properties));
+               max_brightness = fujitsu->max_brightness;
+               props.max_brightness = max_brightness - 1;
+               fujitsu->bl_device = backlight_device_register("fujitsu-laptop",
+                                                              NULL, NULL,
+                                                              &fujitsubl_ops,
+                                                              &props);
                if (IS_ERR(fujitsu->bl_device)) {
                        ret = PTR_ERR(fujitsu->bl_device);
                        fujitsu->bl_device = NULL;
                        goto fail_sysfs_group;
                }
-               max_brightness = fujitsu->max_brightness;
-               fujitsu->bl_device->props.max_brightness = max_brightness - 1;
                fujitsu->bl_device->props.brightness = fujitsu->brightness_level;
        }
 
index 56086363becc21fba3dfcd1f8f31397881d5d76d..51c07a05a7bca4056b548ecdbb7b06afaf3cfad3 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/input.h>
 #include <acpi/acpi_drivers.h>
index f0a90a6bf396a39b8ea3f8133a79798db2a66e2b..2f795ce2b939216274a32a3d740152dbaba09108 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/pm.h>
@@ -396,6 +397,7 @@ static int intel_menlow_add_one_attribute(char *name, int mode, void *show,
        if (!attr)
                return -ENOMEM;
 
+       sysfs_attr_init(&attr->attr.attr); /* That is consistent naming :D */
        attr->attr.attr.name = name;
        attr->attr.attr.mode = mode;
        attr->attr.show = show;
index c2b05da4289a7dadd8f79f1add1b507610f5c77f..996223a7c009b01f080d0130e7c5e701872fa511 100644 (file)
@@ -683,11 +683,14 @@ static int __init msi_init(void)
                printk(KERN_INFO "MSI: Brightness ignored, must be controlled "
                       "by ACPI video driver\n");
        } else {
+               struct backlight_properties props;
+               memset(&props, 0, sizeof(struct backlight_properties));
+               props.max_brightness = MSI_LCD_LEVEL_MAX - 1;
                msibl_device = backlight_device_register("msi-laptop-bl", NULL,
-                                                        NULL, &msibl_ops);
+                                                        NULL, &msibl_ops,
+                                                        &props);
                if (IS_ERR(msibl_device))
                        return PTR_ERR(msibl_device);
-               msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1;
        }
 
        ret = platform_driver_register(&msipf_driver);
index f5f70d4c6913bf373af4a052e6618c3077bee85d..d1736009636fadcd3f8bf7ad63f125b798cbe37a 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/input/sparse-keymap.h>
 #include <linux/acpi.h>
 #include <linux/backlight.h>
+#include <linux/slab.h>
 
 MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
 MODULE_DESCRIPTION("MSI laptop WMI hotkeys driver");
@@ -138,7 +139,7 @@ static int bl_set_status(struct backlight_device *bd)
        return msi_wmi_set_block(0, backlight_map[bright]);
 }
 
-static struct backlight_ops msi_backlight_ops = {
+static const struct backlight_ops msi_backlight_ops = {
        .get_brightness = bl_get,
        .update_status  = bl_set_status,
 };
@@ -249,12 +250,17 @@ static int __init msi_wmi_init(void)
                goto err_uninstall_notifier;
 
        if (!acpi_video_backlight_support()) {
-               backlight = backlight_device_register(DRV_NAME,
-                               NULL, NULL, &msi_backlight_ops);
-               if (IS_ERR(backlight))
+               struct backlight_properties props;
+               memset(&props, 0, sizeof(struct backlight_properties));
+               props.max_brightness = ARRAY_SIZE(backlight_map) - 1;
+               backlight = backlight_device_register(DRV_NAME, NULL, NULL,
+                                                     &msi_backlight_ops,
+                                                     &props);
+               if (IS_ERR(backlight)) {
+                       err = PTR_ERR(backlight);
                        goto err_free_input;
+               }
 
-               backlight->props.max_brightness = ARRAY_SIZE(backlight_map) - 1;
                err = bl_get(NULL);
                if (err < 0)
                        goto err_free_backlight;
index c9fc479fc290ee5bb5266cd25f6a23397e7bf1da..2fb9a32926f86f5258e685847f1eac0c8aa75e59 100644 (file)
 #include <linux/ctype.h>
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 #include <linux/input.h>
@@ -352,7 +353,7 @@ static int bl_set_status(struct backlight_device *bd)
        return acpi_pcc_write_sset(pcc, SINF_DC_CUR_BRIGHT, bright);
 }
 
-static struct backlight_ops pcc_backlight_ops = {
+static const struct backlight_ops pcc_backlight_ops = {
        .get_brightness = bl_get,
        .update_status  = bl_set_status,
 };
@@ -600,6 +601,7 @@ static int acpi_pcc_hotkey_resume(struct acpi_device *device)
 
 static int acpi_pcc_hotkey_add(struct acpi_device *device)
 {
+       struct backlight_properties props;
        struct pcc_acpi *pcc;
        int num_sifr, result;
 
@@ -637,24 +639,25 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
        if (result) {
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
                                  "Error installing keyinput handler\n"));
-               goto out_sinf;
+               goto out_hotkey;
        }
 
-       /* initialize backlight */
-       pcc->backlight = backlight_device_register("panasonic", NULL, pcc,
-                                                  &pcc_backlight_ops);
-       if (IS_ERR(pcc->backlight))
-               goto out_input;
-
        if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) {
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
                                 "Couldn't retrieve BIOS data\n"));
-               goto out_backlight;
+               goto out_input;
+       }
+       /* initialize backlight */
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = pcc->sinf[SINF_AC_MAX_BRIGHT];
+       pcc->backlight = backlight_device_register("panasonic", NULL, pcc,
+                                                  &pcc_backlight_ops, &props);
+       if (IS_ERR(pcc->backlight)) {
+               result = PTR_ERR(pcc->backlight);
+               goto out_sinf;
        }
 
        /* read the initial brightness setting from the hardware */
-       pcc->backlight->props.max_brightness =
-                                       pcc->sinf[SINF_AC_MAX_BRIGHT];
        pcc->backlight->props.brightness = pcc->sinf[SINF_AC_CUR_BRIGHT];
 
        /* read the initial sticky key mode from the hardware */
@@ -669,12 +672,12 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
 
 out_backlight:
        backlight_device_unregister(pcc->backlight);
+out_sinf:
+       kfree(pcc->sinf);
 out_input:
        input_unregister_device(pcc->input_dev);
        /* no need to input_free_device() since core input API refcount and
         * free()s the device */
-out_sinf:
-       kfree(pcc->sinf);
 out_hotkey:
        kfree(pcc);
 
index 5a3d8514c66dafbd57c4d1900151626a55550ae5..1387c5f9c24d926aef958528cc031a5478475e1f 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/kfifo.h>
 #include <linux/workqueue.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
 #include <asm/uaccess.h>
@@ -1291,9 +1292,13 @@ static int sony_nc_add(struct acpi_device *device)
                       "controlled by ACPI video driver\n");
        } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
                                                &handle))) {
+                                                       struct backlight_properties props;
+               memset(&props, 0, sizeof(struct backlight_properties));
+               props.max_brightness = SONY_MAX_BRIGHTNESS - 1;
                sony_backlight_device = backlight_device_register("sony", NULL,
                                                                  NULL,
-                                                                 &sony_backlight_ops);
+                                                                 &sony_backlight_ops,
+                                                                 &props);
 
                if (IS_ERR(sony_backlight_device)) {
                        printk(KERN_WARNING DRV_PFX "unable to register backlight device\n");
@@ -1302,8 +1307,6 @@ static int sony_nc_add(struct acpi_device *device)
                        sony_backlight_device->props.brightness =
                            sony_backlight_get_brightness
                            (sony_backlight_device);
-                       sony_backlight_device->props.max_brightness =
-                           SONY_MAX_BRIGHTNESS - 1;
                }
 
        }
index dd33b51c34869b098ee43ce9e63e36b89c3d4a22..1fe0f1feff71607e9397dac7aed322af871b9424 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <acpi/acpi.h>
index c64e3528889bd9fdd91cddd6b0e7fd2e4130c4ea..63290b33c8796e203113309536ed8716a42ef1f7 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <linux/nvram.h>
 #include <linux/proc_fs.h>
@@ -6170,6 +6171,7 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
 
 static int __init brightness_init(struct ibm_init_struct *iibm)
 {
+       struct backlight_properties props;
        int b;
        unsigned long quirks;
 
@@ -6259,9 +6261,12 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
                printk(TPACPI_INFO
                       "detected a 16-level brightness capable ThinkPad\n");
 
-       ibm_backlight_device = backlight_device_register(
-                                       TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL,
-                                       &ibm_backlight_data);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = (tp_features.bright_16levels) ? 15 : 7;
+       ibm_backlight_device = backlight_device_register(TPACPI_BACKLIGHT_DEV_NAME,
+                                                        NULL, NULL,
+                                                        &ibm_backlight_data,
+                                                        &props);
        if (IS_ERR(ibm_backlight_device)) {
                int rc = PTR_ERR(ibm_backlight_device);
                ibm_backlight_device = NULL;
@@ -6280,8 +6285,6 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
                        "or not on your ThinkPad\n", TPACPI_MAIL);
        }
 
-       ibm_backlight_device->props.max_brightness =
-                               (tp_features.bright_16levels)? 15 : 7;
        ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
        backlight_update_status(ibm_backlight_device);
 
index 4d6516fded7eeaea8f5f98ebf19254cd17363d7b..ff4b476f1950856f101959c7c1ccc6caa2e89b4a 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/acpi.h>
 #include <linux/input.h>
 
index 789240d1b577b9c1fc43f861c4ee884ca5e22d16..37aa1479855136c10f2384edc814da5eda6dc6c9 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/platform_device.h>
 #include <linux/rfkill.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
@@ -924,6 +925,7 @@ static int __init toshiba_acpi_init(void)
        u32 hci_result;
        bool bt_present;
        int ret = 0;
+       struct backlight_properties props;
 
        if (acpi_disabled)
                return -ENODEV;
@@ -974,10 +976,12 @@ static int __init toshiba_acpi_init(void)
                }
        }
 
+       props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
        toshiba_backlight_device = backlight_device_register("toshiba",
-                                               &toshiba_acpi.p_dev->dev,
-                                               NULL,
-                                               &toshiba_backlight_data);
+                                                            &toshiba_acpi.p_dev->dev,
+                                                            NULL,
+                                                            &toshiba_backlight_data,
+                                                            &props);
         if (IS_ERR(toshiba_backlight_device)) {
                ret = PTR_ERR(toshiba_backlight_device);
 
@@ -986,7 +990,6 @@ static int __init toshiba_acpi_init(void)
                toshiba_acpi_exit();
                return ret;
        }
-        toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
 
        /* Register rfkill switch for Bluetooth */
        if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) {
index 09e9918c69c145820f92e19fc2fc76947c7321bc..39ec5b6c2e3a804518bdad78257bb766812e3274 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/device.h>
 #include <linux/list.h>
 #include <linux/acpi.h>
+#include <linux/slab.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
index e851160e14f06e6d98179f19716ac04b51e7a598..918d5f044865b3dc513a5f3ad877b458592aa243 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/isapnp.h>
index 00fd3577b98575abb218972a4e35d1d62f6366c2..0a15664eef1c65f2c9670f24ab03af0a604122c6 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/pnp.h>
-#include <linux/slab.h>
 #include <linux/bitmap.h>
 #include <linux/mutex.h>
 #include "base.h"
index 5314bf630bc4c7fe1b227e4eb0e39b6cf618e79b..f7ff628b7d9437a096d534ff6d829ce2c7cca49f 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/acpi.h>
 #include <linux/pnp.h>
+#include <linux/slab.h>
 #include <linux/mod_devicetable.h>
 #include <acpi/acpi_bus.h>
 
index 54514aa35b093f27d11604d4bca986e5b6c53e5c..100e4d9372f1fa24c30d280efa4c105bc96da6f8 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/acpi.h>
 #include <linux/pci.h>
 #include <linux/pnp.h>
+#include <linux/slab.h>
 #include "../base.h"
 #include "pnpacpi.h"
 
@@ -279,6 +280,7 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
        struct acpi_resource_address64 addr, *p = &addr;
        acpi_status status;
        int window;
+       u64 len;
 
        status = acpi_resource_to_address64(res, p);
        if (!ACPI_SUCCESS(status)) {
@@ -287,20 +289,19 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
                return;
        }
 
+       /* Windows apparently computes length rather than using _LEN */
+       len = p->maximum - p->minimum + 1;
        window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
 
        if (p->resource_type == ACPI_MEMORY_RANGE)
-               pnpacpi_parse_allocated_memresource(dev,
-                       p->minimum, p->address_length,
+               pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
                        p->info.mem.write_protect, window);
        else if (p->resource_type == ACPI_IO_RANGE)
-               pnpacpi_parse_allocated_ioresource(dev,
-                       p->minimum, p->address_length,
+               pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
                        p->granularity == 0xfff ? ACPI_DECODE_10 :
                                ACPI_DECODE_16, window);
        else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
-               pnpacpi_parse_allocated_busresource(dev, p->minimum,
-                                                   p->address_length);
+               pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
 }
 
 static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev,
@@ -308,21 +309,21 @@ static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev,
 {
        struct acpi_resource_extended_address64 *p = &res->data.ext_address64;
        int window;
+       u64 len;
 
+       /* Windows apparently computes length rather than using _LEN */
+       len = p->maximum - p->minimum + 1;
        window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
 
        if (p->resource_type == ACPI_MEMORY_RANGE)
-               pnpacpi_parse_allocated_memresource(dev,
-                       p->minimum, p->address_length,
+               pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
                        p->info.mem.write_protect, window);
        else if (p->resource_type == ACPI_IO_RANGE)
-               pnpacpi_parse_allocated_ioresource(dev,
-                       p->minimum, p->address_length,
+               pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
                        p->granularity == 0xfff ? ACPI_DECODE_10 :
                                ACPI_DECODE_16, window);
        else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
-               pnpacpi_parse_allocated_busresource(dev, p->minimum,
-                                                   p->address_length);
+               pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
 }
 
 static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
index fc83783c3a96b16cf4a67a584b48bf23e447110b..8591f6ab1b3562f6642e0adb20afb198d2087def 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/pnp.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/completion.h>
 #include <linux/spinlock.h>
index a5135ebe5f077da279f8688ae259d4f0817a0cc9..cb1f47bfee96685637d81ca51c3f9415092fe7e3 100644 (file)
@@ -5,7 +5,6 @@
 #include <linux/ctype.h>
 #include <linux/pnp.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 
 #ifdef CONFIG_PCI
 #include <linux/pci.h>
index 5b277dbaacde5df589b227ac754056fe86757428..e3446ab8b563743d462756fb7237225a8a492f79 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
@@ -210,6 +211,8 @@ int pnp_check_port(struct pnp_dev *dev, struct resource *res)
                        if (tres->flags & IORESOURCE_IO) {
                                if (cannot_compare(tres->flags))
                                        continue;
+                               if (tres->flags & IORESOURCE_WINDOW)
+                                       continue;
                                tport = &tres->start;
                                tend = &tres->end;
                                if (ranged_conflict(port, end, tport, tend))
@@ -270,6 +273,8 @@ int pnp_check_mem(struct pnp_dev *dev, struct resource *res)
                        if (tres->flags & IORESOURCE_MEM) {
                                if (cannot_compare(tres->flags))
                                        continue;
+                               if (tres->flags & IORESOURCE_WINDOW)
+                                       continue;
                                taddr = &tres->start;
                                tend = &tres->end;
                                if (ranged_conflict(addr, end, taddr, tend))
index bece33ed873cbc425accae82fb7ed7bdadb08615..3ec9c6a8896b5ea9c22c0da72705b51ab79ca6fc 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/power_supply.h>
 #include <linux/idr.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 #define DRIVER_VERSION                 "1.1.0"
index a2e71f7b27fb6d68a26029086e88e2b830744400..d2c793cf676582516ef97af4bb4deae08750c728 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/device.h>
index 6f1dba5a519dfa4c458e66a784aafadf8fee2460..3bf8d1f622e31319144a8077420d683231ed1195 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/jiffies.h>
 #include <linux/workqueue.h>
 #include <linux/pm.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
 
index da14f374cb60893c2fa9962f73664186386cc078..99c89976a902b1166cded15540f12aa53de0721e 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/idr.h>
 #include <linux/power_supply.h>
+#include <linux/slab.h>
 
 #define DS2782_REG_RARC                0x06    /* Remaining active relative capacity */
 
index 87b98bf27ae1f66311927a9a641b8f4b2332f6a1..f3e22c9fe20a538581a70fc0d0134bf78a5a1b33 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/power_supply.h>
 #include <linux/max17040_battery.h>
+#include <linux/slab.h>
 
 #define MAX17040_VCELL_MSB     0x02
 #define MAX17040_VCELL_LSB     0x03
index a1b4410544d7fea415097183e84f0296dafa1d3b..8e5aec26086681c03908a91cfd3e3ea4a314e9f5 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
index ea3fdfaca90dd70cd31815d4fdc23901414f0b4c..066f994e6fe5ac4b74dda65ba658450b283cbe9f 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/device.h>
index 9c87ad564803b96f0b915b75edaf2ae48fd7bfaf..023d24993b871de656da8a631b8f73fc827acbfc 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/power_supply.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
+#include <linux/slab.h>
 
 static struct pmu_battery_dev {
        struct power_supply bat;
index 2dece40c544f2098dae9b94ae110f31c8f50be31..031a554837f78d2958b2c3368268c27466251837 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/kernel.h>
 #include <linux/power_supply.h>
+#include <linux/slab.h>
 
 #include "power_supply.h"
 
index ff05e61897682343e0fa6f5c892fcd050e67be41..5b6e352ac7c1e935fc7cfce0f5683028a541f94f 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/ctype.h>
 #include <linux/power_supply.h>
+#include <linux/slab.h>
 
 #include "power_supply.h"
 
index bf4f387a80098a33c1ed1186473d994e70271e7a..0fd130d80f5d914826029c9f8bb370d44718472f 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/auxadc.h>
index f85e80b1b400c917963010d679dd394c0326b7d7..875c4d0f776b90570058eef2e41328488f3f0b51 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/auxadc.h>
index 23eed356a854c880fc3d26854fe90f15105c0f21..94c70650aafc90275fd24d74b798d6d66f91263c 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 
 static DEFINE_MUTEX(bat_lock);
 static struct work_struct bat_work;
index 2d414e23d390174c7b49942a7723dbfda8cb800e..1aa02db3ff4e50f592455cb50cb7f9d0f5c8797a 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/idr.h>
 #include <linux/fs.h>
 #include <linux/pps_kernel.h>
+#include <linux/slab.h>
 
 /*
  * Global variables
index fe96793e3f080e155abfae2ef804b211f3c0e166..8000985d0e8c80f3df68802b9210736a25f499f2 100644 (file)
@@ -18,6 +18,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
index e4ad5ba5d0a3da7b4014c003f7582d9146323a44..d9fb729535a1691b976d475c5b089bab6fa60cfe 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
index 95a689befc84b5887ea0e629f85579006c4cf15c..a409fa050a1a910e0074ce0098e76e0868988b52 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/notifier.h>
 #include <linux/ioctl.h>
 #include <linux/fb.h>
+#include <linux/slab.h>
 
 #include <asm/firmware.h>
 #include <asm/ps3av.h>
index c7bbe30010f70b3dc69542eb99fe14488cd31f45..2b4e40d311902c3a05061aa99e4d4fd65b38a167 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/suspend.h>
@@ -1038,6 +1039,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
                        goto overflow_err;
 
                regulator->dev = dev;
+               sysfs_attr_init(&regulator->dev_attr.attr);
                regulator->dev_attr.attr.name = kstrdup(buf, GFP_KERNEL);
                if (regulator->dev_attr.attr.name == NULL)
                        goto attr_name_err;
index d11f7622430bfa4a00d6ade280f1ad70edb7e93b..2fe9d99c9f23107366ab8d485831bd65bce0663f 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/regulator/fixed.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 struct fixed_voltage_data {
        struct regulator_desc desc;
index f5532ed79272c08976723687684f461f49b5b281..671a7d1f1f0e33e5f9f0fd4e016b742a870da3a4 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/lp3971.h>
+#include <linux/slab.h>
 
 struct lp3971 {
        struct device *dev;
@@ -45,7 +46,7 @@ static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val);
        LP3971_BUCK2 -> 4
        LP3971_BUCK3 -> 6
 */
-#define BUCK_VOL_CHANGE_SHIFT(x) (((1 << x) & ~0x01) << 1)
+#define BUCK_VOL_CHANGE_SHIFT(x) (((!!x) << 2) | (x & ~0x01))
 #define BUCK_VOL_CHANGE_FLAG_GO 0x01
 #define BUCK_VOL_CHANGE_FLAG_TARGET 0x02
 #define BUCK_VOL_CHANGE_FLAG_MASK 0x03
@@ -187,7 +188,8 @@ static int lp3971_ldo_set_voltage(struct regulator_dev *dev,
                return -EINVAL;
 
        return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo),
-               LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo), val);
+                       LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo),
+                       val << LDO_VOL_CONTR_SHIFT(ldo));
 }
 
 static struct regulator_ops lp3971_ldo_ops = {
@@ -439,6 +441,10 @@ static int __devinit setup_regulators(struct lp3971 *lp3971,
        lp3971->num_regulators = pdata->num_regulators;
        lp3971->rdev = kcalloc(pdata->num_regulators,
                                sizeof(struct regulator_dev *), GFP_KERNEL);
+       if (!lp3971->rdev) {
+               err = -ENOMEM;
+               goto err_nomem;
+       }
 
        /* Instantiate the regulators */
        for (i = 0; i < pdata->num_regulators; i++) {
@@ -461,6 +467,7 @@ error:
                regulator_unregister(lp3971->rdev[i]);
        kfree(lp3971->rdev);
        lp3971->rdev = NULL;
+err_nomem:
        return err;
 }
 
index a49fc952c9a98bd7495b59957b60a139e91b0f45..b3c1afc16889434f47c9fd74e387da39bb255737 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
+#include <linux/slab.h>
 #include <linux/regulator/max1586.h>
 
 #define MAX1586_V3_MAX_VSEL 31
@@ -243,8 +244,8 @@ static int __devexit max1586_pmic_remove(struct i2c_client *client)
        for (i = 0; i <= MAX1586_V6; i++)
                if (rdev[i])
                        regulator_unregister(rdev[i]);
-       kfree(rdev);
        i2c_set_clientdata(client, NULL);
+       kfree(rdev);
 
        return 0;
 }
index 3ebdf698c648f6cb588a0637cbcd15ab6782f3e3..bfc4c5ffdc966f3ab03081259faf52adce239906 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
+#include <linux/slab.h>
 #include <linux/regulator/max8649.h>
 
 #define MAX8649_DCDC_VMIN      750000          /* uV */
@@ -356,6 +357,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
        dev_info(info->dev, "Max8649 regulator device is detected.\n");
        return 0;
 out:
+       i2c_set_clientdata(client, NULL);
        kfree(info);
        return ret;
 }
@@ -367,9 +369,9 @@ static int __devexit max8649_regulator_remove(struct i2c_client *client)
        if (info) {
                if (info->regulator)
                        regulator_unregister(info->regulator);
+               i2c_set_clientdata(client, NULL);
                kfree(info);
        }
-       i2c_set_clientdata(client, NULL);
 
        return 0;
 }
index f12f1bb62138f95851ae7da9289a1b89d159924c..3790b21879ff2f8d2c5b8000fe216f1f0770a436 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
+#include <linux/slab.h>
 #include <linux/regulator/max8660.h>
 
 #define MAX8660_DCDC_MIN_UV     725000
@@ -470,8 +471,8 @@ static int __devexit max8660_remove(struct i2c_client *client)
        for (i = 0; i < MAX8660_V_END; i++)
                if (rdev[i])
                        regulator_unregister(rdev[i]);
-       kfree(rdev);
        i2c_set_clientdata(client, NULL);
+       kfree(rdev);
 
        return 0;
 }
index 67873f08ed40cccd89b52a764058affb0cb4e2b2..552cad85ae5a2418ce7aec4430e3f111cb78c5c0 100644 (file)
@@ -109,7 +109,7 @@ static int max8925_is_enabled(struct regulator_dev *rdev)
        struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
        int ret;
 
-       ret = max8925_reg_read(info->i2c, info->vol_reg);
+       ret = max8925_reg_read(info->i2c, info->enable_reg);
        if (ret < 0)
                return ret;
 
@@ -230,7 +230,7 @@ static struct max8925_regulator_info max8925_regulator_info[] = {
        MAX8925_LDO(20, 750, 3900, 50),
 };
 
-static inline struct max8925_regulator_info *find_regulator_info(int id)
+static struct max8925_regulator_info * __devinit find_regulator_info(int id)
 {
        struct max8925_regulator_info *ri;
        int i;
@@ -247,7 +247,7 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev)
 {
        struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
        struct max8925_platform_data *pdata = chip->dev->platform_data;
-       struct max8925_regulator_info *ri = NULL;
+       struct max8925_regulator_info *ri;
        struct regulator_dev *rdev;
 
        ri = find_regulator_info(pdev->id);
@@ -274,7 +274,9 @@ static int __devexit max8925_regulator_remove(struct platform_device *pdev)
 {
        struct regulator_dev *rdev = platform_get_drvdata(pdev);
 
+       platform_set_drvdata(pdev, NULL);
        regulator_unregister(rdev);
+
        return 0;
 }
 
index f7b81845a196223f5fdf5051115fa9ecd2a69d7f..ad036dd8da136852bd1490eff9c36807a1bfef0a 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/regulator/driver.h>
 #include <linux/platform_device.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/err.h>
 
@@ -617,9 +618,12 @@ static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
                dev_get_platdata(&pdev->dev);
        int i;
 
+       platform_set_drvdata(pdev, NULL);
+
        for (i = 0; i < pdata->num_regulators; i++)
                regulator_unregister(priv->regulators[i]);
 
+       kfree(priv);
        return 0;
 }
 
index 1f183543bdbd68fa2570cba036438d274f721837..8e2f2098b00562fd2e9608494569f28f9b85a83f 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 /* Register definitions */
 #define        TPS65023_REG_VERSION            0
index c2a9539acd723377c8f82f91a97448bdde14e742..74841abcc9cc5d037e5837eebe1bd4971719986a 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 /* Register definitions */
 #define        TPS6507X_REG_PPATH1                             0X01
index 44917da4ac97a3853420ca99856c1c436c15e985..9d5ba93575975f22e8d00a620613cc1848ffb8fe 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/userspace-consumer.h>
+#include <linux/slab.h>
 
 struct userspace_consumer_data {
        const char *name;
index d96cecaac73d7aeb5b1e2f0dc9f599764148a078..69e550f57638cbde4ebde30990318cb21816ad0a 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 
 struct virtual_consumer_data {
        struct mutex lock;
index 6e18e56d850ba7159312938baf59d6f50ecc3fa3..dbfaf5945e48a683c20cd87ff185dfc816b789e7 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/regulator.h>
index ca0f6b6c384b34ef327f09d77cc5be44148d4a65..6c446cd6ad546839aa455d2302fff558921ea3c3 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/regulator.h>
index d2406c1519a195a16437561bd3e2fadde4859f9b..e686cdb61b97cd8a54ab7fbecb1312a41e333595 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/regulator.h>
index 95454a4637b7ef771c426d0540df313afe5fe087..5a1dc8a24d355bcdf5e9e741c0a9acab6e7ced5c 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm8994/core.h>
 #include <linux/mfd/wm8994/registers.h>
index 40845c7e93221c7a13a236619ab8225e9638e9ca..565562ba6ac9dacc7d8aa4842c7ddedb29de074d 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/rtc.h>
 #include <linux/kdev_t.h>
 #include <linux/idr.h>
+#include <linux/slab.h>
 
 #include "rtc-core.h"
 
index 8825695777df281777a3d61e7179b0afa9d61f55..b2752b6e7a2f903da45d39a7c275248b174988a1 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/rtc.h>
 #include <linux/io.h>
 
index 78a018b5c941c5acf51184a46189e9aedbfdff80..f677e0710ca1160957940b51d403885fd71d603e 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/rtc.h>
 #include <linux/interrupt.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 
 #include <mach/board.h>
 #include <mach/at91_rtt.h>
index b11485b9f21ca1c3c90f7bc96cfffb32c66e0b8c..72b2bcc2c22413b1a63e465e355ea65084ec7b8e 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <asm/blackfin.h>
 
index 280fe48ada0bfa629556a9da28d232d7f3462064..128270ce355d08f0689b8e0961d39bb565923bf5 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
+#include <linux/slab.h>
 
 MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
 MODULE_DESCRIPTION("TI BQ4802 RTC driver");
index 44c4399ee7144fc2e8cffca50d8a96426b05a8fb..316f484999b55fb861667b5c6950654959ab7b75 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/pm.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 /*
  * Registers in the COH 901 331
index 4aedc705518c773a40739aa5292d06f2f7e193db..45cd8c9f5a39acd4e135b46908aee500da306415 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/rtc.h>
 #include <linux/platform_device.h>
 #include <linux/bcd.h>
+#include <linux/slab.h>
 
 #define DRV_VERSION "0.2"
 
index 4fcb16bbff4ab801ca0fe31b03d61e1ef0d5e108..bf430f9091ed0ba3b10b66dfeab207ca4cda3287 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/bcd.h>
 #include <linux/ds1286.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #define DRV_VERSION            "1.0"
 
index 9630e7d3314e59d19dd9e94be9f917cab7307f16..7836c9cec5578a559170e1c356284f795f6be409 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/bcd.h>
+#include <linux/slab.h>
 #include <linux/rtc.h>
 #include <linux/workqueue.h>
 
index 5317bbcbc7a0c7cb3f60e16e6bafac483327a666..61945734ad003c379fde6424c708942b1afbbf8a 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/rtc.h>
 #include <linux/bcd.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 #define DS1374_REG_TOD0                0x00 /* Time of Day */
 #define DS1374_REG_TOD1                0x01
index cdb705057091f1cb8bbbca35f42be3154e86d07a..26a86d235051ff283115c34324ae2605a860a42f 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/rtc.h>
 #include <linux/spi/spi.h>
 #include <linux/bcd.h>
+#include <linux/slab.h>
 
 #define DS1390_REG_100THS              0x00
 #define DS1390_REG_SECONDS             0x01
index 4166b84cb514f6ff68d918d4e0ebf3fbd0c97bc5..06b8566c4532ebefe541d5a0bc164d29642cb2f0 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/bcd.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/rtc.h>
index ed1ef7c9cc069fc2d2634429827f66c783734aa6..244f9994bcbbade98fa1615dc243acdfadf39be8 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/bcd.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
 #include <linux/interrupt.h>
index cad9ceb89bafea483c0cdbf0de70742bde2bb220..2b4b0bc42d6f7a0768ff63f73524d928029023fa 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/bcd.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
 #include <linux/rtc.h>
index 91bde976bc0fb79031f18faf5756069f04c38ac6..11ae64dcbf3c7b1a365853ae16cb095cbb38ea9f 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/rtc.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 
 #define EP93XX_RTC_DATA                        0x000
 #define EP93XX_RTC_MATCH               0x004
index 812c667550837ea6f12adaedcfbff41f32d2a30e..ff6fce61ea41afff5e0d9d6bd8bd480c6f8d37d4 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/i2c.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
+#include <linux/slab.h>
 
 #define FM3130_RTC_CONTROL     (0x0)
 #define FM3130_CAL_CONTROL     (0x1)
index 8cb5b8959e5b2c2befd63f59323e89f7657324ab..7410875e5838957d0763a079f967c78c72a0751c 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/module.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/bcd.h>
 #include <linux/io.h>
index ede43b8468596e3ac0037d9b25e4b251d1466036..365ff3ac23486fe2e08eae2fddb03720e6c8ba94 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/rtc.h>
 #include <linux/rtc/m48t59.h>
 #include <linux/bcd.h>
+#include <linux/slab.h>
 
 #ifndef NO_IRQ
 #define NO_IRQ (-1)
index acdbb1760187af5da1cb122aba25f0b1e3a8aaf3..174036dda78652ce106afc23d12699f1d310000b 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/rtc.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/max8925.h>
index d60c81b7b693c9c26afa236cf85abafd1b6e2ec2..675bfb51536722bbea5d703146a9972bb4be5d30 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/rtc.h>
 
 #define DRIVER_NAME "mc13783-rtc"
@@ -319,35 +320,38 @@ static int __devinit mc13783_rtc_probe(struct platform_device *pdev)
 {
        int ret;
        struct mc13783_rtc *priv;
+       struct mc13783 *mc13783;
        int rtcrst_pending;
 
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
-       priv->mc13783 = dev_get_drvdata(pdev->dev.parent);
+       mc13783 = dev_get_drvdata(pdev->dev.parent);
+       priv->mc13783 = mc13783;
+
        platform_set_drvdata(pdev, priv);
 
-       mc13783_lock(priv->mc13783);
+       mc13783_lock(mc13783);
 
-       ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_RTCRST,
+       ret = mc13783_irq_request(mc13783, MC13783_IRQ_RTCRST,
                        mc13783_rtc_reset_handler, DRIVER_NAME, priv);
        if (ret)
                goto err_reset_irq_request;
 
-       ret = mc13783_irq_status(priv->mc13783, MC13783_IRQ_RTCRST,
+       ret = mc13783_irq_status(mc13783, MC13783_IRQ_RTCRST,
                        NULL, &rtcrst_pending);
        if (ret)
                goto err_reset_irq_status;
 
        priv->valid = !rtcrst_pending;
 
-       ret = mc13783_irq_request_nounmask(priv->mc13783, MC13783_IRQ_1HZ,
+       ret = mc13783_irq_request_nounmask(mc13783, MC13783_IRQ_1HZ,
                        mc13783_rtc_update_handler, DRIVER_NAME, priv);
        if (ret)
                goto err_update_irq_request;
 
-       ret = mc13783_irq_request_nounmask(priv->mc13783, MC13783_IRQ_TODA,
+       ret = mc13783_irq_request_nounmask(mc13783, MC13783_IRQ_TODA,
                        mc13783_rtc_alarm_handler, DRIVER_NAME, priv);
        if (ret)
                goto err_alarm_irq_request;
@@ -357,22 +361,22 @@ static int __devinit mc13783_rtc_probe(struct platform_device *pdev)
        if (IS_ERR(priv->rtc)) {
                ret = PTR_ERR(priv->rtc);
 
-               mc13783_irq_free(priv->mc13783, MC13783_IRQ_TODA, priv);
+               mc13783_irq_free(mc13783, MC13783_IRQ_TODA, priv);
 err_alarm_irq_request:
 
-               mc13783_irq_free(priv->mc13783, MC13783_IRQ_1HZ, priv);
+               mc13783_irq_free(mc13783, MC13783_IRQ_1HZ, priv);
 err_update_irq_request:
 
 err_reset_irq_status:
 
-               mc13783_irq_free(priv->mc13783, MC13783_IRQ_RTCRST, priv);
+               mc13783_irq_free(mc13783, MC13783_IRQ_RTCRST, priv);
 err_reset_irq_request:
 
                platform_set_drvdata(pdev, NULL);
                kfree(priv);
        }
 
-       mc13783_unlock(priv->mc13783);
+       mc13783_unlock(mc13783);
 
        return ret;
 }
index 4313ca03a96d8da6b3ee4f80c8c53f83ba8306fd..f0dbf9cb8f9c42f30e51b6db7dba823d887c6f61 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 struct mpc5121_rtc_regs {
        u8 set_time;            /* RTC + 0x00 */
index 5f5968a4892584ae2f2a3d8ae4e61bdfb280397c..b2fff0ca49f8c734e9337244c56511470cf7c0db 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 
 
 enum {
index dc052ce6e63a8af6525cd067d0748927298c0c41..bcca4729855402f68b4b1601120779a5b35df742 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 
 #define RTC_TIME_REG_OFFS      0
index 8710f9415d98ce35a42757b6974065d80c784f2c..d71fe61db1d655427e3d10b40113482ee2063a4e 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/io.h>
 #include <linux/rtc.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
@@ -383,21 +384,26 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
        struct rtc_device *rtc;
        struct rtc_plat_data *pdata = NULL;
        u32 reg;
-       int ret, rate;
+       unsigned long rate;
+       int ret;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res)
                return -ENODEV;
 
-       pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
                return -ENOMEM;
 
-       pdata->ioaddr = ioremap(res->start, resource_size(res));
+       if (!devm_request_mem_region(&pdev->dev, res->start,
+                                    resource_size(res), pdev->name))
+               return -EBUSY;
+
+       pdata->ioaddr = devm_ioremap(&pdev->dev, res->start,
+                                    resource_size(res));
 
        clk = clk_get(&pdev->dev, "ckil");
        if (IS_ERR(clk)) {
-               iounmap(pdata->ioaddr);
                ret = PTR_ERR(clk);
                goto exit_free_pdata;
        }
@@ -412,8 +418,7 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
        else if (rate == 38400)
                reg = RTC_INPUT_CLK_38400HZ;
        else {
-               dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n",
-                       clk_get_rate(clk));
+               dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate);
                ret = -EINVAL;
                goto exit_free_pdata;
        }
@@ -449,8 +454,8 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
        pdata->irq = platform_get_irq(pdev, 0);
 
        if (pdata->irq >= 0 &&
-           request_irq(pdata->irq, mxc_rtc_interrupt, IRQF_SHARED,
-                       pdev->name, pdev) < 0) {
+           devm_request_irq(&pdev->dev, pdata->irq, mxc_rtc_interrupt,
+                            IRQF_SHARED, pdev->name, pdev) < 0) {
                dev_warn(&pdev->dev, "interrupt not available.\n");
                pdata->irq = -1;
        }
@@ -458,10 +463,10 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
        return 0;
 
 exit_put_clk:
+       clk_disable(pdata->clk);
        clk_put(pdata->clk);
 
 exit_free_pdata:
-       kfree(pdata);
 
        return ret;
 }
@@ -472,12 +477,8 @@ static int __exit mxc_rtc_remove(struct platform_device *pdev)
 
        rtc_device_unregister(pdata->rtc);
 
-       if (pdata->irq >= 0)
-               free_irq(pdata->irq, pdev);
-
        clk_disable(pdata->clk);
        clk_put(pdata->clk);
-       kfree(pdata);
        platform_set_drvdata(pdev, NULL);
 
        return 0;
index bf59c9c586b2d1d38076d629c09f84bf747146a6..a351bd5d81765d785d9b3b41972961446615d12b 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/rtc.h>
 #include <linux/delay.h>
 #include <linux/io.h>
index a99c28992d21658a25663e5e01c7110116ea5bdb..25c0b3fd44f1ba901f96b0b8582a6941335640b4 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/mfd/ezx-pcap.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 
 struct pcap_rtc {
index 2ceb365533b2a3d8d0701753a4e54716dccefb81..71bab0ef54436bd19be3882f95df4f62dbbd96a4 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/rtc.h>
 #include <linux/spi/spi.h>
 
index 854c3cb365a1919d0c6a92dad726f2a648ed4a5e..16edf94ab42f2826f20024ef3a57778f8e15a0c6 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
index 65f346b2fbaebfcf73b58759e6622d6e9ababefd..1af42b4a6f59c07146c83b4001709a921f161225 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/i2c.h>
 #include <linux/bcd.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 
 #define DRV_VERSION "0.4.3"
 
index 457231bb1029748ca4c1be64d1689577ae4ad00d..bbdb2f02798a13187c91475696fa9f84594f8f47 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/amba/bus.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #define RTC_DR         (0)
 #define RTC_MR         (4)
index c256aacfa9542232c121bd6a91a95456a16406c6..3587d9922f2895832059f1ea1163e715750dd19a 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/bcd.h>
 #include <linux/delay.h>
 #include <linux/version.h>
+#include <linux/slab.h>
 
 /*
  * Register definitions
index e6351b743da644cd78dd34b0cfd73b667e885cfe..e9c6fa035989ad328f094f58396cfea79c28ae3d 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 
index e1313feb060f0bde073b18b05050d763a405a2ae..a95f733bb15aa5aa1c8cc6af6ad49e33292b196a 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 
 
 enum {
index 2099037cb3eab5921be8497205e74e4f2ba84127..368d0e63cf836a3f054a56adcc7f86f12fcc278a 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/rtc.h>
 #include <linux/workqueue.h>
 #include <linux/spi/spi.h>
index 2f2c68d476daa924028e167be775859d35ce21b4..90cf0a6ff23e3cce363958cb0c3e81cde08c14af 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/i2c.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
+#include <linux/slab.h>
 
 #define DRV_VERSION "0.6"
 
index b1a29bcfdf1339b06ec6b4ff190dcaa2cbf04d21..b65c82f792d9cd6f86614304db1f4c9d99077c6b 100644 (file)
@@ -20,6 +20,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/bcd.h>
 #include <linux/i2c.h>
index e0d7b9991505564c412e4771f8061154c5adc449..4969b6059c896e3fafe9ee9d8bf591fdc87f03b0 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/bcd.h>
 #include <linux/clk.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <asm/uaccess.h>
index e95cc6f8d61e28c035fed8d0648fd92463ed595e..5efbd5990ff8dee1ea6431540405082303fd3119 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/io.h>
 #include <linux/log2.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 #include <asm/rtc.h>
 
 #define DRV_NAME       "sh-rtc"
index 67700831b5c991e948e7b03b48e9ea75777b5938..875ba099e7a554ffcd35d71e3b4ae83cc6db82eb 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/bcd.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
 #include <linux/interrupt.h>
index d7ce1a5c857dfa92925c6f568b46e1ee3432ef7d..7e7d0c806f2db8eaea1da72cbf3e3052649a7f1b 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 
 #include <mach/platform.h>
 #include <mach/stmp3xxx.h>
index 9ee81d8aa7c02ecd88c637776b82d14978e063ef..20bfc64a15c82f1a06d9b6e42594ea84c9d9c2f0 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 #include <asm/txx9/tx4939.h>
 
 struct tx4939rtc_plat_data {
index bed4cab07043674615ab7fef5d3093e67577af44..f71c3ce180369225938f8ba21a6960e605f9d251 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/rtc-v3020.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include <linux/io.h>
 
index 000c7e481e594ab8216b5c5d05098af188a9d876..b16cfe57a484b8590ab78e855963dc8840bd6d46 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/time.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 #include <linux/bcd.h>
 #include <linux/interrupt.h>
 #include <linux/ioctl.h>
index bbea90baf98ffe32f26b466869a547253822e715..fa2339cb1681f43fb19e337ad037f75d908b8d89 100644 (file)
@@ -37,6 +37,9 @@
  */
 #define DASD_CHANQ_MAX_SIZE 4
 
+#define DASD_SLEEPON_START_TAG (void *) 1
+#define DASD_SLEEPON_END_TAG   (void *) 2
+
 /*
  * SECTION: exported variables of dasd.c
  */
@@ -1472,7 +1475,10 @@ void dasd_add_request_tail(struct dasd_ccw_req *cqr)
  */
 static void dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data)
 {
-       wake_up((wait_queue_head_t *) data);
+       spin_lock_irq(get_ccwdev_lock(cqr->startdev->cdev));
+       cqr->callback_data = DASD_SLEEPON_END_TAG;
+       spin_unlock_irq(get_ccwdev_lock(cqr->startdev->cdev));
+       wake_up(&generic_waitq);
 }
 
 static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr)
@@ -1482,10 +1488,7 @@ static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr)
 
        device = cqr->startdev;
        spin_lock_irq(get_ccwdev_lock(device->cdev));
-       rc = ((cqr->status == DASD_CQR_DONE ||
-              cqr->status == DASD_CQR_NEED_ERP ||
-              cqr->status == DASD_CQR_TERMINATED) &&
-             list_empty(&cqr->devlist));
+       rc = (cqr->callback_data == DASD_SLEEPON_END_TAG);
        spin_unlock_irq(get_ccwdev_lock(device->cdev));
        return rc;
 }
@@ -1573,7 +1576,7 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
                        wait_event(generic_waitq, !(device->stopped));
 
                cqr->callback = dasd_wakeup_cb;
-               cqr->callback_data = (void *) &generic_waitq;
+               cqr->callback_data = DASD_SLEEPON_START_TAG;
                dasd_add_request_tail(cqr);
                if (interruptible) {
                        rc = wait_event_interruptible(
@@ -1652,7 +1655,7 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
        }
 
        cqr->callback = dasd_wakeup_cb;
-       cqr->callback_data = (void *) &generic_waitq;
+       cqr->callback_data = DASD_SLEEPON_START_TAG;
        cqr->status = DASD_CQR_QUEUED;
        list_add(&cqr->devlist, &device->ccw_queue);
 
@@ -1899,7 +1902,8 @@ restart:
                /*  Process requests that may be recovered */
                if (cqr->status == DASD_CQR_NEED_ERP) {
                        erp_fn = base->discipline->erp_action(cqr);
-                       erp_fn(cqr);
+                       if (IS_ERR(erp_fn(cqr)))
+                               continue;
                        goto restart;
                }
 
index 51224f76b980eaf15908897b7a30fb19cca0ecfe..6632649dd6aa4ce1d052cd6dc428ec96be8577f3 100644 (file)
@@ -10,7 +10,6 @@
 #define KMSG_COMPONENT "dasd-eckd"
 
 #include <linux/timer.h>
-#include <linux/slab.h>
 #include <asm/idals.h>
 
 #define PRINTK_HEADER "dasd_erp(3990): "
@@ -2287,7 +2286,8 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
 
        if (cqr->cpmode == 1) {
                cplength = 0;
-               datasize = sizeof(struct tcw) + sizeof(struct tsb);
+               /* TCW needs to be 64 byte aligned, so leave enough room */
+               datasize = 64 + sizeof(struct tcw) + sizeof(struct tsb);
        } else {
                cplength = 2;
                datasize = 0;
@@ -2309,15 +2309,15 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
                                      cqr->retries);
                        dasd_block_set_timer(device->block, (HZ << 3));
                 }
-               return cqr;
+               return erp;
        }
 
        ccw = cqr->cpaddr;
        if (cqr->cpmode == 1) {
                /* make a shallow copy of the original tcw but set new tsb */
                erp->cpmode = 1;
-               erp->cpaddr = erp->data;
-               tcw = erp->data;
+               erp->cpaddr = PTR_ALIGN(erp->data, 64);
+               tcw = erp->cpaddr;
                tsb = (struct tsb *) &tcw[1];
                *tcw = *((struct tcw *)cqr->cpaddr);
                tcw->tsb = (long)tsb;
@@ -2372,6 +2372,9 @@ dasd_3990_erp_additional_erp(struct dasd_ccw_req * cqr)
        /* add erp and initialize with default TIC */
        erp = dasd_3990_erp_add_erp(cqr);
 
+       if (IS_ERR(erp))
+               return erp;
+
        /* inspect sense, determine specific ERP if possible */
        if (erp != cqr) {
 
@@ -2711,6 +2714,8 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
        if (erp == NULL) {
                /* no matching erp found - set up erp */
                erp = dasd_3990_erp_additional_erp(cqr);
+               if (IS_ERR(erp))
+                       return erp;
        } else {
                /* matching erp found - set all leading erp's to DONE */
                erp = dasd_3990_erp_handle_match_erp(cqr, erp);
index 148b1dd240704e8d472b6ba83f5c435d40fb0fb3..8c4814258e93c9fe58e3711be1051a49b0af0269 100644 (file)
@@ -8,6 +8,7 @@
 #define KMSG_COMPONENT "dasd-eckd"
 
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <asm/ebcdic.h>
 #include "dasd_int.h"
 #include "dasd_eckd.h"
index 8e23919c870484a02159411f99f92c17c20a6a22..eff9c812c5c2befa559e1281fd2a1cb152451659 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <asm/debug.h>
 #include <asm/uaccess.h>
index 01f4e7a34aa8b2aa8570bd16c4078b53c9f415cf..0cb2331168551ef4f290adb65683d8ee1902b30a 100644 (file)
@@ -3155,11 +3155,11 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
 
        tsb = NULL;
        sense = NULL;
-       if (irb->scsw.tm.tcw)
+       if (irb->scsw.tm.tcw && (irb->scsw.tm.fcxs == 0x01))
                tsb = tcw_get_tsb(
                        (struct tcw *)(unsigned long)irb->scsw.tm.tcw);
 
-       if (tsb && (irb->scsw.tm.fcxs == 0x01)) {
+       if (tsb) {
                len += sprintf(page + len, KERN_ERR PRINTK_HEADER
                               " tsb->length %d\n", tsb->length);
                len += sprintf(page + len, KERN_ERR PRINTK_HEADER
index 1f3e967aaba8f650d4618a2e57ed3c9c72cbde84..dd88803e4899c415e1cba6e0fe402f3b79a77664 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mutex.h>
 #include <linux/smp_lock.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
index 3479f8158a1b3206039dc55551503eb138a0b104..1557214944f718fda7b239a88de50b10e97973fd 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/fs.h>
 #include <linux/blkpg.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include <asm/compat.h>
 #include <asm/ccwdev.h>
 #include <asm/cmb.h>
index f13a0bdd148cae363315ef7d6f1ad895554e0568..2eb02559280927594f7a10efbfe19ead060be9aa 100644 (file)
@@ -14,6 +14,7 @@
 #define KMSG_COMPONENT "dasd"
 
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/seq_file.h>
 #include <linux/vmalloc.h>
index 118de392af63895b98b42afc0123911f054168f5..c881a14fa5dd7796c2f07a08120e3891254a66df 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/ctype.h>  /* isdigit, isxdigit */
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/blkpg.h>
 #include <linux/hdreg.h>  /* HDIO_GETGEO */
@@ -41,6 +40,7 @@
 #include <linux/bio.h>
 #include <linux/suspend.h>
 #include <linux/platform_device.h>
+#include <linux/gfp.h>
 #include <asm/uaccess.h>
 
 #define XPRAM_NAME     "xpram"
index 6bca81aea3966e0da735d72fb9c3829566efa2bd..bb07577e8fd4409331aeef22562edec3c838a468 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/reboot.h>
 
index 31c59b0d6df0c1509a191ece52a77c3ba4f6e0ae..0eabcca3c92d45f47e2001a046c996ac077df7fd 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/smp_lock.h>
 
index cee4d4e4242907bb7a917070b0e3ac7b706cb794..cb6bffe7141a948feb3f8f370f360eb941861991 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/sysrq.h>
 
 #include <linux/consolemap.h>
index 33e96484d54fd1bf5d28aeb369751eed9dbef539..2ed3f82e5c30e1e5ead0f0a159a83174c70d2079 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/poll.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <net/iucv/iucv.h>
 #include <asm/uaccess.h>
 #include <asm/ebcdic.h>
index 668a0579b26b8b7767d2fbc912c220d02d3a874b..98a49dfda1de0d425b8f6b3157c1e0c131d3a8a5 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/poll.h>
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/ebcdic.h>
 #include <asm/io.h>
index 740fe405c3959f199ca9d393d9d912443653101b..7ad30e72f868de1e45ef7e4bdd81cfa8a4701ca4 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/device.h>
 #include <linux/stat.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/kmod.h>
 #include <linux/err.h>
@@ -84,6 +85,7 @@ static int proc_handler_callhome(struct ctl_table *ctl, int write,
                rc = copy_from_user(buf, buffer, sizeof(buf));
                if (rc != 0)
                        return -EFAULT;
+               buf[sizeof(buf) - 1] = '\0';
                if (strict_strtoul(buf, 0, &val) != 0)
                        return -EINVAL;
                if (val != 0 && val != 1)
index b3beab610da445334be1818b4f8ae05e81e941ba..4b60ede07f0e0f9738d22c70d53c3393eff1b37e 100644 (file)
@@ -308,6 +308,13 @@ struct assign_storage_sccb {
        u16 rn;
 } __packed;
 
+int arch_get_memory_phys_device(unsigned long start_pfn)
+{
+       if (!rzm)
+               return 0;
+       return PFN_PHYS(start_pfn) >> ilog2(rzm);
+}
+
 static unsigned long long rn2addr(u16 rn)
 {
        return (unsigned long long) (rn - 1) * rzm;
index ad698d30cb3b5db6dbfb52e147fa1f60592c07b9..ecf45c54f8c469c84da45049e006225593283a90 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/termios.h>
 #include <linux/err.h>
 #include <linux/reboot.h>
+#include <linux/gfp.h>
 
 #include "sclp.h"
 #include "sclp_rw.h"
index 434ba04b1309529e0e0959eea440a074085a5535..8258d590505f1444e9a4a4ed8cab036fe400b72e 100644 (file)
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
-#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/gfp.h>
 #include <asm/uaccess.h>
 
 #include "ctrlchar.h"
index 3796ffdb847995c89ff74acf9bb5078f28a7eff5..5d706e6c946fb37ea87d78dddfef45a628bb00d0 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/reboot.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include "sclp.h"
index cb70fa1cf5398fb5d8ff5cd58b5c0a24f45baec6..c17f35b6136ace01d56cd643ed0bffdaae8e7b86 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/bio.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 #define TAPE_DBF_AREA  tape_34xx_dbf
 
index 9821c58866137710bfa2e52aaa5bd6a2045831ae..fc993acf99b656a273475588be808c2894c72884 100644 (file)
@@ -12,6 +12,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/bio.h>
 #include <asm/ebcdic.h>
index b2864e3edb6da8a80cb70ff99b2812918c7cfefb..55343df61edde6a583328d1a7faa0c2515491670 100644 (file)
@@ -11,6 +11,8 @@
 #define KMSG_COMPONENT "tape"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/slab.h>
+
 #include "tape_class.h"
 
 MODULE_AUTHOR("Stefan Bader <shbader@de.ibm.com>");
index 81b094e480e66f0f9d7823a0afeb0a2067d340b1..29c2d73d719db55ab963660efdbfe6b9db55c030 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/spinlock.h>  // for locks
 #include <linux/vmalloc.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 
 #include <asm/types.h>      // for variable types
 
index 921dcda77676b1e94f6e857c695a8d36737c9c5c..5bb59d36a6d496431d8375168d7d723acccf1679 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/compat.h>
 #include <asm/cpcmd.h>
 #include <asm/debug.h>
index 7dfa5412d5a8bc9d5c0b6ddcacffc6fe6d958981..e40a1b89286667d02329800f64c03d2fa35cfdda 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
index cc56fc708baeced52b18918fcf659e016e31b5b1..1de672f21037bd70f57e06b4abcd43a89b65a864 100644 (file)
@@ -12,6 +12,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/cdev.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
index c974058e48d2a4da6976755d48d371e87b15fe90..e13508c98b1a754c38509f5cb89ce06eb2044e44 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include <linux/suspend.h>
 #include <linux/watchdog.h>
 
index 3438658b66b76fb7f7aaf261310fe3512fa1cc70..7217966f7d318eb2757c95ac35db0d471f3198bf 100644 (file)
@@ -13,6 +13,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/miscdevice.h>
 #include <linux/debugfs.h>
 #include <asm/asm-offsets.h>
@@ -141,33 +142,6 @@ static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count)
        return memcpy_hsa(dest, src, count, TO_KERNEL);
 }
 
-static int memcpy_real(void *dest, unsigned long src, size_t count)
-{
-       unsigned long flags;
-       int rc = -EFAULT;
-       register unsigned long _dest asm("2") = (unsigned long) dest;
-       register unsigned long _len1 asm("3") = (unsigned long) count;
-       register unsigned long _src  asm("4") = src;
-       register unsigned long _len2 asm("5") = (unsigned long) count;
-
-       if (count == 0)
-               return 0;
-       flags = __raw_local_irq_stnsm(0xf8UL); /* switch to real mode */
-       asm volatile (
-               "0:     mvcle   %1,%2,0x0\n"
-               "1:     jo      0b\n"
-               "       lhi     %0,0x0\n"
-               "2:\n"
-               EX_TABLE(1b,2b)
-               : "+d" (rc), "+d" (_dest), "+d" (_src), "+d" (_len1),
-                 "+d" (_len2), "=m" (*((long*)dest))
-               : "m" (*((long*)src))
-               : "cc", "memory");
-       __raw_local_irq_ssm(flags);
-
-       return rc;
-}
-
 static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
 {
        static char buf[4096];
@@ -175,7 +149,7 @@ static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
 
        while (offs < count) {
                size = min(sizeof(buf), count - offs);
-               if (memcpy_real(buf, src + offs, size))
+               if (memcpy_real(buf, (void *) src + offs, size))
                        return -EFAULT;
                if (copy_to_user(dest + offs, buf, size))
                        return -EFAULT;
@@ -663,12 +637,8 @@ static int __init zcore_reipl_init(void)
        if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE)
                rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE);
        else
-               rc = memcpy_real(ipl_block, ipib_info.ipib, PAGE_SIZE);
-       if (rc) {
-               free_page((unsigned long) ipl_block);
-               return rc;
-       }
-       if (csum_partial(ipl_block, ipl_block->hdr.len, 0) !=
+               rc = memcpy_real(ipl_block, (void *) ipib_info.ipib, PAGE_SIZE);
+       if (rc || csum_partial(ipl_block, ipl_block->hdr.len, 0) !=
            ipib_info.checksum) {
                TRACE("Checksum does not match\n");
                free_page((unsigned long) ipl_block);
index 7eab9ab9f40650902c1405a98551e43362c9c21b..13cb60162e429675a2f0233e903f48ccea9d89ed 100644 (file)
@@ -14,7 +14,6 @@
 
 #include <linux/init.h>
 #include <linux/vmalloc.h>
-#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/ctype.h>
index c268a2e5b7c332901c7225e30afe7872cfbd7bbd..1d16189f2f2dbd60b17f29e5400a11cf8da5477e 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/wait.h>
 #include <linux/mutex.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <asm/chpid.h>
 #include <asm/sclp.h>
 #include <asm/crw.h>
index 4038f5b4f144e565bae3a5aac6201bce651b41bb..ce7cb87479fe3b8aed786eeea182549da7352b35 100644 (file)
@@ -29,6 +29,7 @@
 #include "chsc.h"
 
 static void *sei_page;
+static DEFINE_SPINLOCK(sda_lock);
 
 /**
  * chsc_error_from_response() - convert a chsc response to an error
@@ -832,11 +833,10 @@ void __init chsc_free_sei_area(void)
        kfree(sei_page);
 }
 
-int __init
-chsc_enable_facility(int operation_code)
+int chsc_enable_facility(int operation_code)
 {
        int ret;
-       struct {
+       static struct {
                struct chsc_header request;
                u8 reserved1:4;
                u8 format:4;
@@ -849,33 +849,32 @@ chsc_enable_facility(int operation_code)
                u32 reserved5:4;
                u32 format2:4;
                u32 reserved6:24;
-       } __attribute__ ((packed)) *sda_area;
+       } __attribute__ ((packed, aligned(4096))) sda_area;
 
-       sda_area = (void *)get_zeroed_page(GFP_KERNEL|GFP_DMA);
-       if (!sda_area)
-               return -ENOMEM;
-       sda_area->request.length = 0x0400;
-       sda_area->request.code = 0x0031;
-       sda_area->operation_code = operation_code;
+       spin_lock(&sda_lock);
+       memset(&sda_area, 0, sizeof(sda_area));
+       sda_area.request.length = 0x0400;
+       sda_area.request.code = 0x0031;
+       sda_area.operation_code = operation_code;
 
-       ret = chsc(sda_area);
+       ret = chsc(&sda_area);
        if (ret > 0) {
                ret = (ret == 3) ? -ENODEV : -EBUSY;
                goto out;
        }
 
-       switch (sda_area->response.code) {
+       switch (sda_area.response.code) {
        case 0x0101:
                ret = -EOPNOTSUPP;
                break;
        default:
-               ret = chsc_error_from_response(sda_area->response.code);
+               ret = chsc_error_from_response(sda_area.response.code);
        }
        if (ret != 0)
                CIO_CRW_EVENT(2, "chsc: sda (oc=%x) failed (rc=%04x)\n",
-                             operation_code, sda_area->response.code);
+                             operation_code, sda_area.response.code);
  out:
-       free_page((unsigned long)sda_area);
+       spin_unlock(&sda_lock);
        return ret;
 }
 
index 852612f5dba0607d81b29c8ae5ecd8c7ca44053d..3b6f4adc50948d078f88e314350f55a208434a6f 100644 (file)
@@ -7,6 +7,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/uaccess.h>
@@ -123,7 +124,7 @@ static int chsc_subchannel_prepare(struct subchannel *sch)
         * since we don't have a way to clear the subchannel and
         * cannot disable it with a request running.
         */
-       cc = stsch(sch->schid, &schib);
+       cc = stsch_err(sch->schid, &schib);
        if (!cc && scsw_stctl(&schib.scsw))
                return -EAGAIN;
        return 0;
index f736cdcf08ad79ee5522b5143888933292c63ef7..5feea1a371e193ac7154f96eefc0f41f1159b2bb 100644 (file)
@@ -361,7 +361,7 @@ int cio_commit_config(struct subchannel *sch)
        struct schib schib;
        int ccode, retry, ret = 0;
 
-       if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib))
+       if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib))
                return -ENODEV;
 
        for (retry = 0; retry < 5; retry++) {
@@ -372,7 +372,7 @@ int cio_commit_config(struct subchannel *sch)
                        return ccode;
                switch (ccode) {
                case 0: /* successful */
-                       if (stsch(sch->schid, &schib) ||
+                       if (stsch_err(sch->schid, &schib) ||
                            !css_sch_is_valid(&schib))
                                return -ENODEV;
                        if (cio_check_config(sch, &schib)) {
@@ -404,7 +404,7 @@ int cio_update_schib(struct subchannel *sch)
 {
        struct schib schib;
 
-       if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib))
+       if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib))
                return -ENODEV;
 
        memcpy(&sch->schib, &schib, sizeof(schib));
@@ -771,7 +771,7 @@ cio_get_console_sch_no(void)
        if (console_irq != -1) {
                /* VM provided us with the irq number of the console. */
                schid.sch_no = console_irq;
-               if (stsch(schid, &console_subchannel.schib) != 0 ||
+               if (stsch_err(schid, &console_subchannel.schib) != 0 ||
                    (console_subchannel.schib.pmcw.st != SUBCHANNEL_TYPE_IO) ||
                    !console_subchannel.schib.pmcw.dnv)
                        return -1;
@@ -863,10 +863,10 @@ __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
        cc = 0;
        for (retry=0;retry<3;retry++) {
                schib->pmcw.ena = 0;
-               cc = msch(schid, schib);
+               cc = msch_err(schid, schib);
                if (cc)
                        return (cc==3?-ENODEV:-EBUSY);
-               if (stsch(schid, schib) || !css_sch_is_valid(schib))
+               if (stsch_err(schid, schib) || !css_sch_is_valid(schib))
                        return -ENODEV;
                if (!schib->pmcw.ena)
                        return 0;
@@ -913,7 +913,7 @@ static int stsch_reset(struct subchannel_id schid, struct schib *addr)
 
        pgm_check_occured = 0;
        s390_base_pgm_handler_fn = cio_reset_pgm_check_handler;
-       rc = stsch(schid, addr);
+       rc = stsch_err(schid, addr);
        s390_base_pgm_handler_fn = NULL;
 
        /* The program check handler could have changed pgm_check_occured. */
@@ -950,7 +950,7 @@ static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data)
                        /* No default clear strategy */
                        break;
                }
-               stsch(schid, &schib);
+               stsch_err(schid, &schib);
                __disable_subchannel_easy(schid, &schib);
        }
 out:
@@ -1086,7 +1086,7 @@ int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo)
        schid = *(struct subchannel_id *)&S390_lowcore.subchannel_id;
        if (!schid.one)
                return -ENODEV;
-       if (stsch(schid, &schib))
+       if (stsch_err(schid, &schib))
                return -ENODEV;
        if (schib.pmcw.st != SUBCHANNEL_TYPE_IO)
                return -ENODEV;
index 2769da54f2b96ebf9f26f86ff76c049ff71c5e82..511649115bd7e0163d3283db97161ab179e8dbf4 100644 (file)
@@ -870,15 +870,10 @@ static int __init css_bus_init(void)
 
        /* Try to enable MSS. */
        ret = chsc_enable_facility(CHSC_SDA_OC_MSS);
-       switch (ret) {
-       case 0: /* Success. */
-               max_ssid = __MAX_SSID;
-               break;
-       case -ENOMEM:
-               goto out;
-       default:
+       if (ret)
                max_ssid = 0;
-       }
+       else /* Success. */
+               max_ssid = __MAX_SSID;
 
        ret = slow_subchannel_init();
        if (ret)
@@ -1048,6 +1043,11 @@ static int __init channel_subsystem_init_sync(void)
 }
 subsys_initcall_sync(channel_subsystem_init_sync);
 
+void channel_subsystem_reinit(void)
+{
+       chsc_enable_facility(CHSC_SDA_OC_MSS);
+}
+
 #ifdef CONFIG_PROC_FS
 static ssize_t cio_settle_write(struct file *file, const char __user *buf,
                                size_t count, loff_t *ppos)
index c56ab94612f9c47697246eaff1daed49a4558028..c9b852647f018fcba3c6e6ce682f2698d3374a11 100644 (file)
@@ -45,7 +45,7 @@ static void ccw_timeout_log(struct ccw_device *cdev)
        sch = to_subchannel(cdev->dev.parent);
        private = to_io_private(sch);
        orb = &private->orb;
-       cc = stsch(sch->schid, &schib);
+       cc = stsch_err(sch->schid, &schib);
 
        printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, "
               "device information:\n", get_clock());
index 4f8f7431177867f3657c54c18fdce2e1127ce0d4..88be7b9ea6e10a6129d867f1abcc8890097f6bf1 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/timer.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <asm/atomic.h>
 #include <asm/debug.h>
 #include <asm/qdio.h>
index 9942c1031b25332ba133ff4916907c395e4c0b7b..ce5f8910ff83a376e0d2df6fd3d4cd895662aa8c 100644 (file)
@@ -7,6 +7,7 @@
  *           Jan Glauber <jang@linux.vnet.ibm.com>
  */
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <asm/atomic.h>
 #include <asm/debug.h>
 #include <asm/qdio.h>
index 20836eff88c574c4094e9b5b8f392972b4e0c516..91c6028d7b74016157bba24247da45cf5aac141d 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 #include <linux/notifier.h>
 #include <linux/kthread.h>
 #include <linux/mutex.h>
index ba50fe02e572a40957780eebf825581e46c7c1c6..304caf549973268496d076298def900a38be061d 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/seq_file.h>
 #include <linux/compat.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include <asm/atomic.h>
 #include <asm/uaccess.h>
 #include <linux/hw_random.h>
index c6fb0aa895074ad417c3c6949fd2a4b6b424f9d3..9c409efa1ecf49dd0170b433fba563f7edc653b8 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/err.h>
 #include <asm/atomic.h>
index e78df3671caf46ea42715fccab429954e1dfd0f5..09e934b295a0210e67c5649cebfea9597d0a1c6f 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/err.h>
 #include <asm/atomic.h>
index 142f72a2ca5a75ec7ea1bf4d2d3fa2a2219dad1f..9dec5c77cff46869def7d4f70a05b183f9da95f7 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/err.h>
 #include <asm/atomic.h>
 #include <asm/uaccess.h>
index 68f3e6204db87079d5c1f49e700a1309026d3624..510fab4577d430f56f303a39b2601439943701b2 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/atomic.h>
 #include <asm/uaccess.h>
 
index b2fc4fd63f7f09b1be3ee84ac90d12287e6ec99e..4e298bc8949d36c84a1fb5cdecbe67360369a7b0 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/err.h>
 #include <linux/virtio.h>
 #include <linux/virtio_config.h>
+#include <linux/slab.h>
 #include <linux/virtio_console.h>
 #include <linux/interrupt.h>
 #include <linux/virtio_ring.h>
index 1ca58f15347048b775beb879012faf3e383a6f1b..d962fd741a2327cc68c33fea9d36bd4437057104 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/sysctl.h>
 #include <linux/module.h>
index 738ad26c74a737c1f6c9b5a8ceb6d853f7e86719..2b24550e865e672e9ef6761b667beba2231b235e 100644 (file)
@@ -14,6 +14,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 #include "ctcm_main.h"
 
 /*
index cae48cbc5e965b9f970728f0d8656a267636e276..e5dea67f902e81b3569eb6829f2926e14bab3622 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "fsm.h"
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 
 MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)");
index f6cc46dc0501644ca5eef0f82646b4876056bd37..9b19ea13b4d8593302620a60da62bf8c653abdef 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/igmp.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 #include <net/ip.h>
 
index 3bd4206f347090fa793e1d67da31c1f22f3c1693..3ba738b2e27117eb4c932143fffedce377919df1 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/tcp.h>
 #include <linux/mii.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 #include <asm/ebcdic.h>
 #include <asm/io.h>
index 6f1e3036bafd00f1c6c7772a0f861a50c468ed96..6a801dc3bf8eb6546ccb3bc6960ca8b6c632ac4c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/etherdevice.h>
 #include <linux/mii.h>
 #include <linux/ip.h>
index b3b6e872d8066e640e6f9d7bea456625fae83760..fc6ca1da8b983b568d49271f4ec2914d72b76a1f 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/ipv6.h>
 #include <linux/inetdevice.h>
 #include <linux/igmp.h>
+#include <linux/slab.h>
 
 #include <net/ip.h>
 #include <net/arp.h>
index 3f08b11274aeede53cffa6822738ebd4f5ed1396..25b3e7aae44f336ce9d354f8a99c37cfced240f6 100644 (file)
@@ -8,6 +8,8 @@
  *              Frank Blaschka <frank.blaschka@de.ibm.com>
  */
 
+#include <linux/slab.h>
+
 #include "qeth_l3.h"
 
 #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
index ecef1edee701013420d64fb99e2677e8a42e18df..70491274da16a7cf74120eaf79b416d12789c618 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <net/iucv/iucv.h>
 #include <asm/cpcmd.h>
 #include <asm/ebcdic.h>
index 91579dc6a2b059ae6959eae39d5cbca06ecaa0b2..137688790207248c5153d08ea880bcbec8d287a6 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/list.h>
 #include <linux/kobject.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
 #include <net/iucv/iucv.h>
index 66d6c01fcf3e32ed9e720ad4a3f58733f6c4798b..1e6183a86ce5f4f7ccd91cfdd0566ee85ff70db3 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <linux/miscdevice.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "zfcp_ext.h"
 #include "zfcp_fc.h"
 #include "zfcp_reqlist.h"
index 0eb6eefd2c1a0c457e7d19cdbe536af1f72fd941..25d9e0ae9c5726abbc76b3c8a24b79f63e2f954f 100644 (file)
@@ -10,6 +10,7 @@
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/miscdevice.h>
 #include <asm/compat.h>
index 7a149fd85f6de3801e334df219809262742a987d..075852f6968c478d5920c9b5230470bf3e1c73d6 100644 (file)
@@ -10,6 +10,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <asm/debug.h>
 #include "zfcp_dbf.h"
 #include "zfcp_ext.h"
index 5219670f0c99f015d61a5a8dea757c7c7c5061b5..2a1cbb74b99b624cb7bec855b16caba61dd7cf0f 100644 (file)
@@ -10,6 +10,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <scsi/fc/fc_els.h>
 #include <scsi/libfc.h>
 #include "zfcp_ext.h"
index 6538742b421a1737ae84d766a34990ebfa484277..b3b1d2f79398695685617671e67199119414d05e 100644 (file)
@@ -10,6 +10,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/blktrace_api.h>
+#include <linux/slab.h>
 #include <scsi/fc/fc_els.h>
 #include "zfcp_ext.h"
 #include "zfcp_fc.h"
@@ -2104,7 +2105,8 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)
        blktrc.inb_usage = req->qdio_req.qdio_inb_usage;
        blktrc.outb_usage = req->qdio_req.qdio_outb_usage;
 
-       if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) {
+       if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA &&
+           !(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
                blktrc.flags |= ZFCP_BLK_LAT_VALID;
                blktrc.channel_lat = lat_in->channel_lat * ticks;
                blktrc.fabric_lat = lat_in->fabric_lat * ticks;
@@ -2156,9 +2158,8 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
        fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
        zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt);
 
-       zfcp_fsf_req_trace(req, scpnt);
-
 skip_fsfstatus:
+       zfcp_fsf_req_trace(req, scpnt);
        zfcp_dbf_scsi_result(req->adapter->dbf, scpnt, req);
 
        scpnt->host_scribble = NULL;
index 6479273a30940bd93743d6d66192fa03080b40ce..dbfa312a7f50bb19e66812c310f22cd02fa4439b 100644 (file)
@@ -9,6 +9,7 @@
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/slab.h>
 #include "zfcp_ext.h"
 #include "zfcp_qdio.h"
 
index c3c4178888afbc2a344c708add3d936f8256b59e..174b6d57d5769c23735ae137bdce73849031253f 100644 (file)
@@ -10,6 +10,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <scsi/fc/fc_fcp.h>
 #include <asm/atomic.h>
 #include "zfcp_ext.h"
index a43035d4bd70d6b4bca8947b9060de52c8d374e5..f5f60698dc4c96c0d69ff09db3dc0221a11c92c3 100644 (file)
@@ -9,6 +9,7 @@
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/slab.h>
 #include "zfcp_ext.h"
 
 #define ZFCP_DEV_ATTR(_feat, _name, _mode, _show, _store) \
index 28d86f9df83c64717d3d173283cc5c5679c8a539..b4951eb0358e4046ca64bc38a7c9d2f2cd41dd4a 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/kmod.h>
 #include <linux/reboot.h>
 #include <linux/of.h>
+#include <linux/slab.h>
 #include <linux/of_device.h>
 #include <asm/oplib.h>
 
index 4431578d8c451fb7f11d60703221efe6548c5cd7..3e59189f4137292f3eab85a11fe9a1db268649be 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/ioport.h>              /* request_region */
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
index aa2b60a868baf0314b85591e3a7bb7fad837fd61..c6e2eff19409c6cd3cdf6c4bcbe75bd77cccc3fc 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/miscdevice.h>
 #include <linux/kmod.h>
 #include <linux/reboot.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
index 41083472ff4f46298ce3c8f97484d38df6acb788..19f255b97c868aa14bab6dd4e057961e09f47e27 100644 (file)
@@ -7,7 +7,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
-#include <linux/slab.h>
 #include <linux/fcntl.h>
 #include <linux/poll.h>
 #include <linux/init.h>
index 869a30b49edc93620b38848b369395dbae37bf13..4942050dc5b6f0ea795d62e992368669ab1f6f6a 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
-#include <linux/slab.h>
 #include <linux/fcntl.h>
 #include <linux/poll.h>
 #include <linux/init.h>
index 84d3bbaa95e7868f8cb3d2aa20e3844c721e79c6..e9788f55ab1348050edff7025bf79fe0664cf11f 100644 (file)
@@ -91,6 +91,7 @@
 #include <linux/time.h>
 #include <linux/mutex.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
index 4d314d740de443f34e28c100f88932c580f42c24..54c5ffb1eaa14168b60daffce5918cb11ee24e41 100644 (file)
@@ -65,6 +65,7 @@
 #include <linux/time.h>
 #include <linux/mutex.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
index f65a1e92340c91b24841751c6d44f44657540da2..5faf903ca8c8257f879c9c07f7b77dbb242fa496 100644 (file)
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/time.h>
 #include <linux/mutex.h>
index 9f4a911a6d8c31af416dae58f29b47491bd38bf7..80dc3ac12cdef2b422cfc36778bad44c3fec0139 100644 (file)
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
index 1ddcf4031d4cf6b21dac5bb95e06ae7117eb577a..fc0b4b81d5522ddaff339d3dc6187ce72a4c7d9a 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/spinlock.h>
 #include <linux/jiffies.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <scsi/scsicam.h>
 
 #include <asm/dma.h>
index 9191d1ea6451a5e1cbbdac3d1ec34e5ba640888a..75f2336807cbdba97fa52a01b7d860b7796c8175 100644 (file)
@@ -1,9 +1,15 @@
 menu "SCSI device support"
 
+config SCSI_MOD
+       tristate
+       default y if SCSI=n || SCSI=y
+       default m if SCSI=m
+
 config RAID_ATTRS
        tristate "RAID Transport Class"
        default n
        depends on BLOCK
+       depends on SCSI_MOD
        ---help---
          Provides RAID
 
index 1cdf09a4779a560532e7dc2edafc4dc4f91e2170..8647256ad66df3540e0fee4c264c202ef9bc0eca 100644 (file)
@@ -97,6 +97,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mca.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
index a8bbdc2273b84d8d110cf93e4b6462b1da2f97c8..afdbb9addf18aec48ba703152ce24e258de74129 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mca.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index ff5716d5f044d2fdd3521cc264a5a738d37c74a2..dbbc601948e5328e4c9a0bbfeb18ee8ac7f7fd91 100644 (file)
@@ -69,7 +69,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/dma-mapping.h>
 
 #include <asm/io.h>
index 4b38c4750f77ab2f27af3a4ea9088d25e34cd64f..d8fe5b76fee030b549f1dc7577b1d9a8a963cf06 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/types.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
index 6970ce82c4ac37a7ca03d1c456596e92fcb81922..c35fc55f1c96b321ea5a6bd9f1665540eb8f93d4 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/types.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
index e3519fa5a3ba628e8fbb61a0846a3a1951efa42b..11ae6be8aeaf81ee466609eff419961d82c76d19 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <asm/amigahw.h>
 #include <asm/amigaints.h>
 #include <scsi/scsi_host.h>
index f70d9f8e79e5a871be73376296c33bfed3dcaa69..04057ab72a8bf2131f315d6a8ddf3bda5ab6e4d5 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
-#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/completion.h>
index b6a3c5c187b6ec2707505150da52610e9794ad9d..622c21c68e65f8be4b36b9169319bdfe66dfacf6 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
-#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/completion.h>
index 22626abdb630ac2e4e696213dfcc6e6e8c9b3e8f..7f87979da22d31b9702b2f8fc06fd489df7fe19e 100644 (file)
@@ -4724,6 +4724,10 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
        BUG_ON((unsigned long)asc_dvc->overrun_buf & 7);
        asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf,
                                        ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
+       if (dma_mapping_error(board->dev, asc_dvc->overrun_dma)) {
+               warn_code = -ENOMEM;
+               goto err_dma_map;
+       }
        phy_addr = cpu_to_le32(asc_dvc->overrun_dma);
        AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
                                 (uchar *)&phy_addr, 1);
@@ -4739,14 +4743,23 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
        AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
        if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
                asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
-               return warn_code;
+               warn_code = UW_ERR;
+               goto err_mcode_start;
        }
        if (AscStartChip(iop_base) != 1) {
                asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
-               return warn_code;
+               warn_code = UW_ERR;
+               goto err_mcode_start;
        }
 
        return warn_code;
+
+err_mcode_start:
+       dma_unmap_single(board->dev, asc_dvc->overrun_dma,
+                        ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
+err_dma_map:
+       asc_dvc->overrun_dma = 0;
+       return warn_code;
 }
 
 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
@@ -4781,12 +4794,14 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
        if (err) {
                printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
                       fwname, err);
+               asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
                return err;
        }
        if (fw->size < 4) {
                printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
                       fw->size, fwname);
                release_firmware(fw);
+               asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
                return -EINVAL;
        }
        chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
@@ -4800,6 +4815,8 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
        }
        release_firmware(fw);
        warn_code |= AscInitMicroCodeVar(asc_dvc);
+       if (!asc_dvc->overrun_dma)
+               return warn_code;
        asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
        AscEnableInterrupt(iop_base);
        return warn_code;
@@ -5110,12 +5127,14 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
        if (err) {
                printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
                       fwname, err);
+               asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
                return err;
        }
        if (fw->size < 4) {
                printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
                       fw->size, fwname);
                release_firmware(fw);
+               asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
                return -EINVAL;
        }
        chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
@@ -5624,12 +5643,14 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
        if (err) {
                printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
                       fwname, err);
+               asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
                return err;
        }
        if (fw->size < 4) {
                printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
                       fw->size, fwname);
                release_firmware(fw);
+               asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
                return -EINVAL;
        }
        chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
@@ -6124,12 +6145,14 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
        if (err) {
                printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
                       fwname, err);
+               asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
                return err;
        }
        if (fw->size < 4) {
                printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
                       fw->size, fwname);
                release_firmware(fw);
+               asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
                return -EINVAL;
        }
        chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
@@ -7970,9 +7993,10 @@ static int advansys_reset(struct scsi_cmnd *scp)
                status = AscInitAsc1000Driver(asc_dvc);
 
                /* Refer to ASC_IERR_* definitions for meaning of 'err_code'. */
-               if (asc_dvc->err_code) {
+               if (asc_dvc->err_code || !asc_dvc->overrun_dma) {
                        scmd_printk(KERN_INFO, scp, "SCSI bus reset error: "
-                                   "0x%x\n", asc_dvc->err_code);
+                                   "0x%x, status: 0x%x\n", asc_dvc->err_code,
+                                   status);
                        ret = FAILED;
                } else if (status) {
                        scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: "
@@ -12303,7 +12327,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
                asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL);
                if (!asc_dvc_varp->overrun_buf) {
                        ret = -ENOMEM;
-                       goto err_free_wide_mem;
+                       goto err_free_irq;
                }
                warn_code = AscInitAsc1000Driver(asc_dvc_varp);
 
@@ -12312,30 +12336,36 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
                                        "warn 0x%x, error 0x%x\n",
                                        asc_dvc_varp->init_state, warn_code,
                                        asc_dvc_varp->err_code);
-                       if (asc_dvc_varp->err_code) {
+                       if (!asc_dvc_varp->overrun_dma) {
                                ret = -ENODEV;
-                               kfree(asc_dvc_varp->overrun_buf);
+                               goto err_free_mem;
                        }
                }
        } else {
-               if (advansys_wide_init_chip(shost))
+               if (advansys_wide_init_chip(shost)) {
                        ret = -ENODEV;
+                       goto err_free_mem;
+               }
        }
 
-       if (ret)
-               goto err_free_wide_mem;
-
        ASC_DBG_PRT_SCSI_HOST(2, shost);
 
        ret = scsi_add_host(shost, boardp->dev);
        if (ret)
-               goto err_free_wide_mem;
+               goto err_free_mem;
 
        scsi_scan_host(shost);
        return 0;
 
- err_free_wide_mem:
-       advansys_wide_free_mem(boardp);
+ err_free_mem:
+       if (ASC_NARROW_BOARD(boardp)) {
+               if (asc_dvc_varp->overrun_dma)
+                       dma_unmap_single(boardp->dev, asc_dvc_varp->overrun_dma,
+                                        ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
+               kfree(asc_dvc_varp->overrun_buf);
+       } else
+               advansys_wide_free_mem(boardp);
+ err_free_irq:
        free_irq(boardp->irq, shost);
  err_free_dma:
 #ifdef CONFIG_ISA
index 1e5478abd90ee8ae6c2371ff7f043d6f4f9122bf..8eab8587ff21b6c35bb31129fd62a30d8ddc9f06 100644 (file)
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <scsi/scsicam.h>
 
 #include "scsi.h"
index 80594947c6f6c1a97117be2bedde8fa9b83c75a8..2a8cf137f609f695748328ca677d5289794a7bd4 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/blkdev.h>
 #include <linux/mca.h>
 #include <linux/mca-legacy.h>
+#include <linux/slab.h>
 
 #include <asm/dma.h>
 #include <asm/system.h>
index 538135783aab017b0c2ba0ea782801912b0b93a1..0107a4cc33319bfef8c8e22cb5dbde9e9a700fe8 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/device.h>
 #include <linux/eisa.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <asm/dma.h>
 #include <asm/system.h>
index 1222a7ac698ad0c0f16637d6f4d4c31fea7c43f5..4c41332a354bc46dfd60a1bf27f686d7075d8cd0 100644 (file)
@@ -53,6 +53,7 @@ static struct scsi_transport_template *ahd_linux_transport_template = NULL;
 #include <linux/blkdev.h>              /* For block_size() */
 #include <linux/delay.h>       /* For ssleep/msleep */
 #include <linux/device.h>
+#include <linux/slab.h>
 
 /*
  * Bucket size for counting good commands in between bad ones.
index 8cb05dc8e6a1f265aeaf22c3b85df6e0eacadae1..5e42dac23505f7b2dd27168eea34b03a0577a4f6 100644 (file)
@@ -129,6 +129,7 @@ static struct scsi_transport_template *ahc_linux_transport_template = NULL;
 #include <linux/mm.h>          /* For fetching system memory size */
 #include <linux/blkdev.h>              /* For block_size() */
 #include <linux/delay.h>       /* For ssleep/msleep */
+#include <linux/slab.h>
 
 
 /*
index eb9dc3195fdfdbe7918b7d3ce0a3547e53e55ce4..81b736c76fffab7bf40be168ff1ae3fb2388faad 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/firmware.h>
index 996f7224f90e2d32e39d9a109b5da16a814237e1..24ac2315c5c7f2becb398500382699a38e63fff0 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi_host.h>
 
index ca55013b6ae588cd699dde7739faf1f8dcbc3025..c43698b1cb6449af1de81bb3059ffba83354bd6a 100644 (file)
@@ -24,6 +24,7 @@
  *
  */
 
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 
 #include "aic94xx.h"
index 8630a75b2872730132e28a1b8d11350eeb37456e..edb43fda9f36f34d5834f3f516fc9227aea67af6 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 
 #include "aic94xx.h"
index 8f98e33155e9dbd9e8c391544a08ef5bd306c5ec..d01dcc62b39a413f9e793dc6183c3614cb0bce91 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/firmware.h>
index 78eb86fc627666f3a5c2ceaa13205ada76149b4f..0add73bdf2a4f6f98d34379c9999b91313026a03 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/spinlock.h>
+#include <linux/gfp.h>
 #include "aic94xx.h"
 #include "aic94xx_sas.h"
 #include "aic94xx_hwi.h"
index 47d5d19f8c9221bb3e288fdf779f7cc8994dadf5..ffbe2192da3c4bc42ac32e0bd8233db84eb1926f 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/timer.h>
 #include <linux/pci.h>
 #include <linux/aer.h>
+#include <linux/slab.h>
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/system.h>
index 4240b05aef6d191f8c7f5782ac2c51b07a403de3..158ebc3644d83f2188a1e0007950799db4246652 100644 (file)
@@ -651,6 +651,7 @@ static inline void NCR5380_print_phase(struct Scsi_Host *instance)
  * interrupt or bottom half.
  */
 
+#include <linux/gfp.h>
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 
index b137e561f5bc715951145592d5569bae80e19893..ab5bdda6903e3f6f650fa63c203ab6401bcd71a4 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/pci.h>
 #include <linux/blkdev.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 #include <asm/io.h>
 
index 67098578fba480f423d1007288c8be5df5f2eb6b..cda6642c7368806e2492fc9402f0c67382a6ce62 100644 (file)
@@ -32,18 +32,11 @@ void be_mcc_notify(struct beiscsi_hba *phba)
 unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
 {
        unsigned int tag = 0;
-       unsigned int num = 0;
 
-mcc_tag_rdy:
        if (phba->ctrl.mcc_tag_available) {
                tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
                phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
                phba->ctrl.mcc_numtag[tag] = 0;
-       } else {
-               udelay(100);
-               num++;
-               if (num < mcc_timeout)
-                       goto mcc_tag_rdy;
        }
        if (tag) {
                phba->ctrl.mcc_tag_available--;
index 29a3aaf35f9ff2573c9f39b5f12460766fe91baf..c3928cb8b04208c5dcddd915014c24e2ac3e4b51 100644 (file)
@@ -482,7 +482,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
        tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep);
        if (!tag) {
                SE_DEBUG(DBG_LVL_1,
-                        "mgmt_invalidate_connection Failed for cid=%d \n",
+                        "mgmt_open_connection Failed for cid=%d \n",
                         beiscsi_ep->ep_cid);
        } else {
                wait_event_interruptible(phba->ctrl.mcc_wait[tag],
@@ -701,7 +701,7 @@ void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
        if (!tag) {
                SE_DEBUG(DBG_LVL_1,
                         "mgmt_invalidate_connection Failed for cid=%d \n",
-                        beiscsi_ep->ep_cid);
+                         beiscsi_ep->ep_cid);
        } else {
                wait_event_interruptible(phba->ctrl.mcc_wait[tag],
                                         phba->ctrl.mcc_numtag[tag]);
index 7c22616ab141795a70e070e074ab4855e59df0cc..dd5b105f8f47a73ab45e3c73e43a2f9f9353b52a 100644 (file)
@@ -19,6 +19,7 @@
  */
 #include <linux/reboot.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/blkdev.h>
 #include <linux/pci.h>
@@ -58,6 +59,123 @@ static int beiscsi_slave_configure(struct scsi_device *sdev)
        return 0;
 }
 
+static int beiscsi_eh_abort(struct scsi_cmnd *sc)
+{
+       struct iscsi_cls_session *cls_session;
+       struct iscsi_task *aborted_task = (struct iscsi_task *)sc->SCp.ptr;
+       struct beiscsi_io_task *aborted_io_task;
+       struct iscsi_conn *conn;
+       struct beiscsi_conn *beiscsi_conn;
+       struct beiscsi_hba *phba;
+       struct iscsi_session *session;
+       struct invalidate_command_table *inv_tbl;
+       unsigned int cid, tag, num_invalidate;
+
+       cls_session = starget_to_session(scsi_target(sc->device));
+       session = cls_session->dd_data;
+
+       spin_lock_bh(&session->lock);
+       if (!aborted_task || !aborted_task->sc) {
+               /* we raced */
+               spin_unlock_bh(&session->lock);
+               return SUCCESS;
+       }
+
+       aborted_io_task = aborted_task->dd_data;
+       if (!aborted_io_task->scsi_cmnd) {
+               /* raced or invalid command */
+               spin_unlock_bh(&session->lock);
+               return SUCCESS;
+       }
+       spin_unlock_bh(&session->lock);
+       conn = aborted_task->conn;
+       beiscsi_conn = conn->dd_data;
+       phba = beiscsi_conn->phba;
+
+       /* invalidate iocb */
+       cid = beiscsi_conn->beiscsi_conn_cid;
+       inv_tbl = phba->inv_tbl;
+       memset(inv_tbl, 0x0, sizeof(*inv_tbl));
+       inv_tbl->cid = cid;
+       inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index;
+       num_invalidate = 1;
+       tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
+       if (!tag) {
+               shost_printk(KERN_WARNING, phba->shost,
+                            "mgmt_invalidate_icds could not be"
+                            " submitted\n");
+               return FAILED;
+       } else {
+               wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+                                        phba->ctrl.mcc_numtag[tag]);
+               free_mcc_tag(&phba->ctrl, tag);
+       }
+
+       return iscsi_eh_abort(sc);
+}
+
+static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
+{
+       struct iscsi_task *abrt_task;
+       struct beiscsi_io_task *abrt_io_task;
+       struct iscsi_conn *conn;
+       struct beiscsi_conn *beiscsi_conn;
+       struct beiscsi_hba *phba;
+       struct iscsi_session *session;
+       struct iscsi_cls_session *cls_session;
+       struct invalidate_command_table *inv_tbl;
+       unsigned int cid, tag, i, num_invalidate;
+       int rc = FAILED;
+
+       /* invalidate iocbs */
+       cls_session = starget_to_session(scsi_target(sc->device));
+       session = cls_session->dd_data;
+       spin_lock_bh(&session->lock);
+       if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN)
+               goto unlock;
+
+       conn = session->leadconn;
+       beiscsi_conn = conn->dd_data;
+       phba = beiscsi_conn->phba;
+       cid = beiscsi_conn->beiscsi_conn_cid;
+       inv_tbl = phba->inv_tbl;
+       memset(inv_tbl, 0x0, sizeof(*inv_tbl) * BE2_CMDS_PER_CXN);
+       num_invalidate = 0;
+       for (i = 0; i < conn->session->cmds_max; i++) {
+               abrt_task = conn->session->cmds[i];
+               abrt_io_task = abrt_task->dd_data;
+               if (!abrt_task->sc || abrt_task->state == ISCSI_TASK_FREE)
+                       continue;
+
+               if (abrt_task->sc->device->lun != abrt_task->sc->device->lun)
+                       continue;
+
+               inv_tbl->cid = cid;
+               inv_tbl->icd = abrt_io_task->psgl_handle->sgl_index;
+               num_invalidate++;
+               inv_tbl++;
+       }
+       spin_unlock_bh(&session->lock);
+       inv_tbl = phba->inv_tbl;
+
+       tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
+       if (!tag) {
+               shost_printk(KERN_WARNING, phba->shost,
+                            "mgmt_invalidate_icds could not be"
+                            " submitted\n");
+               return FAILED;
+       } else {
+               wait_event_interruptible(phba->ctrl.mcc_wait[tag],
+                                        phba->ctrl.mcc_numtag[tag]);
+               free_mcc_tag(&phba->ctrl, tag);
+       }
+
+       return iscsi_eh_device_reset(sc);
+unlock:
+       spin_unlock_bh(&session->lock);
+       return rc;
+}
+
 /*------------------- PCI Driver operations and data ----------------- */
 static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
        { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
@@ -74,12 +192,12 @@ static struct scsi_host_template beiscsi_sht = {
        .name = "ServerEngines 10Gbe open-iscsi Initiator Driver",
        .proc_name = DRV_NAME,
        .queuecommand = iscsi_queuecommand,
-       .eh_abort_handler = iscsi_eh_abort,
        .change_queue_depth = iscsi_change_queue_depth,
        .slave_configure = beiscsi_slave_configure,
        .target_alloc = iscsi_target_alloc,
-       .eh_device_reset_handler = iscsi_eh_device_reset,
-       .eh_target_reset_handler = iscsi_eh_target_reset,
+       .eh_abort_handler = beiscsi_eh_abort,
+       .eh_device_reset_handler = beiscsi_eh_device_reset,
+       .eh_target_reset_handler = iscsi_eh_session_reset,
        .sg_tablesize = BEISCSI_SGLIST_ELEMENTS,
        .can_queue = BE2_IO_DEPTH,
        .this_id = -1,
@@ -242,7 +360,7 @@ static void beiscsi_get_params(struct beiscsi_hba *phba)
                                    + BE2_TMFS
                                    + BE2_NOPOUT_REQ));
        phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count;
-       phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count;;
+       phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count * 2;
        phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count;;
        phba->params.num_sge_per_io = BE2_SGE;
        phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ;
@@ -946,14 +1064,18 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
        case HWH_TYPE_IO:
        case HWH_TYPE_IO_RD:
                if ((task->hdr->opcode & ISCSI_OPCODE_MASK) ==
-                   ISCSI_OP_NOOP_OUT) {
+                    ISCSI_OP_NOOP_OUT)
                        be_complete_nopin_resp(beiscsi_conn, task, psol);
-               else
+               else
                        be_complete_io(beiscsi_conn, task, psol);
                break;
 
        case HWH_TYPE_LOGOUT:
-               be_complete_logout(beiscsi_conn, task, psol);
+               if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
+                       be_complete_logout(beiscsi_conn, task, psol);
+               else
+                       be_complete_tmf(beiscsi_conn, task, psol);
+
                break;
 
        case HWH_TYPE_LOGIN:
@@ -962,10 +1084,6 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
                         "- Solicited path \n");
                break;
 
-       case HWH_TYPE_TMF:
-               be_complete_tmf(beiscsi_conn, task, psol);
-               break;
-
        case HWH_TYPE_NOP:
                be_complete_nopin_resp(beiscsi_conn, task, psol);
                break;
@@ -2052,7 +2170,7 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
        num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) /
                      ((sizeof(struct iscsi_wrb) *
                        phba->params.wrbs_per_cxn));
-       for (index = 0; index < phba->params.cxns_per_ctrl; index += 2) {
+       for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) {
                pwrb_context = &phwi_ctrlr->wrb_context[index];
                if (num_cxn_wrb) {
                        for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
@@ -3073,14 +3191,18 @@ static unsigned char hwi_enable_intr(struct beiscsi_hba *phba)
                reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
                SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr);
                iowrite32(reg, addr);
-               for (i = 0; i <= phba->num_cpus; i++) {
-                       eq = &phwi_context->be_eq[i].q;
+               if (!phba->msix_enabled) {
+                       eq = &phwi_context->be_eq[0].q;
                        SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
                        hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
+               } else {
+                       for (i = 0; i <= phba->num_cpus; i++) {
+                               eq = &phwi_context->be_eq[i].q;
+                               SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
+                               hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
+                       }
                }
-       } else
-               shost_printk(KERN_WARNING, phba->shost,
-                            "In hwi_enable_intr, Not Enabled \n");
+       }
        return true;
 }
 
@@ -3476,19 +3598,13 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
 
 static int beiscsi_mtask(struct iscsi_task *task)
 {
-       struct beiscsi_io_task *aborted_io_task, *io_task = task->dd_data;
+       struct beiscsi_io_task *io_task = task->dd_data;
        struct iscsi_conn *conn = task->conn;
        struct beiscsi_conn *beiscsi_conn = conn->dd_data;
        struct beiscsi_hba *phba = beiscsi_conn->phba;
-       struct iscsi_session *session;
        struct iscsi_wrb *pwrb = NULL;
-       struct hwi_controller *phwi_ctrlr;
-       struct hwi_wrb_context *pwrb_context;
-       struct wrb_handle *pwrb_handle;
        unsigned int doorbell = 0;
-       unsigned int i, cid;
-       struct iscsi_task *aborted_task;
-       unsigned int tag;
+       unsigned int cid;
 
        cid = beiscsi_conn->beiscsi_conn_cid;
        pwrb = io_task->pwrb_handle->pwrb;
@@ -3499,6 +3615,7 @@ static int beiscsi_mtask(struct iscsi_task *task)
                      io_task->pwrb_handle->wrb_index);
        AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb,
                      io_task->psgl_handle->sgl_index);
+
        switch (task->hdr->opcode & ISCSI_OPCODE_MASK) {
        case ISCSI_OP_LOGIN:
                AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
@@ -3523,33 +3640,6 @@ static int beiscsi_mtask(struct iscsi_task *task)
                hwi_write_buffer(pwrb, task);
                break;
        case ISCSI_OP_SCSI_TMFUNC:
-               session = conn->session;
-               i = ((struct iscsi_tm *)task->hdr)->rtt;
-               phwi_ctrlr = phba->phwi_ctrlr;
-               pwrb_context = &phwi_ctrlr->wrb_context[cid -
-                                           phba->fw_config.iscsi_cid_start];
-               pwrb_handle = pwrb_context->pwrb_handle_basestd[be32_to_cpu(i)
-                                                               >> 16];
-               aborted_task = pwrb_handle->pio_handle;
-                if (!aborted_task)
-                       return 0;
-
-               aborted_io_task = aborted_task->dd_data;
-               if (!aborted_io_task->scsi_cmnd)
-                       return 0;
-
-               tag = mgmt_invalidate_icds(phba,
-                                    aborted_io_task->psgl_handle->sgl_index,
-                                    cid);
-               if (!tag) {
-                       shost_printk(KERN_WARNING, phba->shost,
-                                    "mgmt_invalidate_icds could not be"
-                                    " submitted\n");
-               } else {
-                       wait_event_interruptible(phba->ctrl.mcc_wait[tag],
-                                                phba->ctrl.mcc_numtag[tag]);
-                       free_mcc_tag(&phba->ctrl, tag);
-               }
                AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
                              INI_TMF_CMD);
                AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
@@ -3558,7 +3648,7 @@ static int beiscsi_mtask(struct iscsi_task *task)
        case ISCSI_OP_LOGOUT:
                AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
                AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
-                               HWH_TYPE_LOGOUT);
+                             HWH_TYPE_LOGOUT);
                hwi_write_buffer(pwrb, task);
                break;
 
@@ -3584,17 +3674,12 @@ static int beiscsi_mtask(struct iscsi_task *task)
 
 static int beiscsi_task_xmit(struct iscsi_task *task)
 {
-       struct iscsi_conn *conn = task->conn;
        struct beiscsi_io_task *io_task = task->dd_data;
        struct scsi_cmnd *sc = task->sc;
-       struct beiscsi_conn *beiscsi_conn = conn->dd_data;
        struct scatterlist *sg;
        int num_sg;
        unsigned int  writedir = 0, xferlen = 0;
 
-       SE_DEBUG(DBG_LVL_4, "\n cid=%d In beiscsi_task_xmit task=%p conn=%p \t"
-                "beiscsi_conn=%p \n", beiscsi_conn->beiscsi_conn_cid,
-                task, conn, beiscsi_conn);
        if (!sc)
                return beiscsi_mtask(task);
 
@@ -3699,7 +3784,6 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
                        " Failed in beiscsi_hba_alloc \n");
                goto disable_pci;
        }
-       SE_DEBUG(DBG_LVL_8, " phba = %p \n", phba);
 
        switch (pcidev->device) {
        case BE_DEVICE_ID1:
index c53a80ab796c1f84a789c7bb9c1e059568378647..87ec21280a37424c81a0c5815dcfcebc62bda80f 100644 (file)
@@ -257,6 +257,11 @@ struct hba_parameters {
        unsigned int num_sge;
 };
 
+struct invalidate_command_table {
+       unsigned short icd;
+       unsigned short cid;
+} __packed;
+
 struct beiscsi_hba {
        struct hba_parameters params;
        struct hwi_controller *phwi_ctrlr;
@@ -329,6 +334,8 @@ struct beiscsi_hba {
        struct work_struct work_cqs;    /* The work being queued */
        struct be_ctrl_info ctrl;
        unsigned int generation;
+       struct invalidate_command_table inv_tbl[128];
+
 };
 
 struct beiscsi_session {
@@ -491,8 +498,6 @@ struct hwi_async_entry {
        struct list_head data_busy_list;
 };
 
-#define BE_MIN_ASYNC_ENTRIES 128
-
 struct hwi_async_pdu_context {
        struct {
                struct be_bus_address pa_base;
@@ -533,7 +538,7 @@ struct hwi_async_pdu_context {
         * This is a varying size list! Do not add anything
         * after this entry!!
         */
-       struct hwi_async_entry async_entry[BE_MIN_ASYNC_ENTRIES];
+       struct hwi_async_entry async_entry[BE2_MAX_SESSIONS * 2];
 };
 
 #define PDUCQE_CODE_MASK       0x0000003F
index 317bcd042ced234d0df2ec0db9b0d3cb063a550d..e641922f20bc5eb58a4ce0adb879b55e55cad13d 100644 (file)
@@ -145,14 +145,15 @@ unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
 }
 
 unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
-                                  unsigned int icd, unsigned int cid)
+                               struct invalidate_command_table *inv_tbl,
+                               unsigned int num_invalidate, unsigned int cid)
 {
        struct be_dma_mem nonemb_cmd;
        struct be_ctrl_info *ctrl = &phba->ctrl;
        struct be_mcc_wrb *wrb;
        struct be_sge *sge;
        struct invalidate_commands_params_in *req;
-       unsigned int tag = 0;
+       unsigned int i, tag = 0;
 
        spin_lock(&ctrl->mbox_lock);
        tag = alloc_mcc_tag(phba);
@@ -168,6 +169,7 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
                SE_DEBUG(DBG_LVL_1,
                         "Failed to allocate memory for"
                         "mgmt_invalidate_icds \n");
+               spin_unlock(&ctrl->mbox_lock);
                return -1;
        }
        nonemb_cmd.size = sizeof(struct invalidate_commands_params_in);
@@ -183,9 +185,12 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
                        sizeof(*req));
        req->ref_handle = 0;
        req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
-       req->icd_count = 0;
-       req->table[req->icd_count].icd = icd;
-       req->table[req->icd_count].cid = cid;
+       for (i = 0; i < num_invalidate; i++) {
+               req->table[i].icd = inv_tbl->icd;
+               req->table[i].cid = inv_tbl->cid;
+               req->icd_count++;
+               inv_tbl++;
+       }
        sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
        sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
        sge->len = cpu_to_le32(nonemb_cmd.size);
index ecead6a5aa56f4e1597b69adc2003396a4e0eb0e..3d316b82feb1455906801cdebd40d04574d58571 100644 (file)
@@ -94,7 +94,8 @@ unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
                                     unsigned short cid,
                                     unsigned int upload_flag);
 unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
-                                  unsigned int icd, unsigned int cid);
+                               struct invalidate_command_table *inv_tbl,
+                               unsigned int num_invalidate, unsigned int cid);
 
 struct iscsi_invalidate_connection_params_in {
        struct be_cmd_req_hdr hdr;
@@ -116,11 +117,6 @@ union iscsi_invalidate_connection_params {
        struct iscsi_invalidate_connection_params_out response;
 } __packed;
 
-struct invalidate_command_table {
-       unsigned short icd;
-       unsigned short cid;
-} __packed;
-
 struct invalidate_commands_params_in {
        struct be_cmd_req_hdr hdr;
        unsigned int ref_handle;
index 1d6009490d1cadd059213a7945ac232067200eaa..17e06cae71b2f545028926a19069176e6324974b 100644 (file)
@@ -2,14 +2,14 @@ obj-$(CONFIG_SCSI_BFA_FC) := bfa.o
 
 bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o
 
-bfa-y += bfa_core.o bfa_ioc.o bfa_iocfc.o bfa_fcxp.o bfa_lps.o
-bfa-y += bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o 
+bfa-y += bfa_core.o bfa_ioc.o bfa_ioc_ct.o bfa_ioc_cb.o bfa_iocfc.o bfa_fcxp.o
+bfa-y += bfa_lps.o bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o
 bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o
 bfa-y += bfa_itnim.o bfa_fcpim.o bfa_tskim.o bfa_log.o bfa_log_module.o
 bfa-y += bfa_csdebug.o bfa_sm.o plog.o
 
-bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o 
+bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o
 bfa-y += bfa_fcs_uf.o bfa_fcs_lport.o fab.o fdmi.o ms.o ns.o scn.o loop.o
 bfa-y += lport_api.o n2n.o rport.o rport_api.o rport_ftrs.o vport.o
 
-ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna
+ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna -DBFA_PERF_BUILD
index 44e2d1155c51a20ef88febe563941c58aa1716ad..0c08e185a7666606729f10d9856d54be2ed503b9 100644 (file)
@@ -384,6 +384,15 @@ bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen)
        return bfa_ioc_debug_fwsave(&bfa->ioc, trcdata, trclen);
 }
 
+/**
+ * Clear the saved firmware trace information of an IOC.
+ */
+void
+bfa_debug_fwsave_clear(struct bfa_s *bfa)
+{
+       bfa_ioc_debug_fwsave_clear(&bfa->ioc);
+}
+
 /**
  *             Fetch firmware trace data.
  *
@@ -399,4 +408,14 @@ bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen)
 {
        return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen);
 }
+
+/**
+ * Reset hw semaphore & usage cnt regs and initialize.
+ */
+void
+bfa_chip_reset(struct bfa_s *bfa)
+{
+       bfa_ioc_ownership_reset(&bfa->ioc);
+       bfa_ioc_pll_init(&bfa->ioc);
+}
 #endif
index aef648b55dfc3d706e0347cb53f7647696942d8f..c589488db0c1751088df25cdab5a52549d274df3 100644 (file)
 #include <cs/bfa_plog.h>
 #include <aen/bfa_aen_port.h>
 
-BFA_TRC_FILE(HAL, PPORT);
-BFA_MODULE(pport);
-
-#define bfa_pport_callback(__pport, __event) do {                      \
-       if ((__pport)->bfa->fcs) {      \
-               (__pport)->event_cbfn((__pport)->event_cbarg, (__event));      \
-       } else {                                                        \
-               (__pport)->hcb_event = (__event);      \
-               bfa_cb_queue((__pport)->bfa, &(__pport)->hcb_qe,        \
-               __bfa_cb_port_event, (__pport));      \
-       }                                                               \
-} while (0)
+BFA_TRC_FILE(HAL, FCPORT);
+BFA_MODULE(fcport);
 
 /*
  * The port is considered disabled if corresponding physical port or IOC are
  * disabled explicitly
  */
 #define BFA_PORT_IS_DISABLED(bfa) \
-       ((bfa_pport_is_disabled(bfa) == BFA_TRUE) || \
+       ((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \
        (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
 
 /*
  * forward declarations
  */
-static bfa_boolean_t bfa_pport_send_enable(struct bfa_pport_s *port);
-static bfa_boolean_t bfa_pport_send_disable(struct bfa_pport_s *port);
-static void     bfa_pport_update_linkinfo(struct bfa_pport_s *pport);
-static void     bfa_pport_reset_linkinfo(struct bfa_pport_s *pport);
-static void     bfa_pport_set_wwns(struct bfa_pport_s *port);
-static void     __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete);
-static void     __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete);
-static void     __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete);
-static void     bfa_port_stats_timeout(void *cbarg);
-static void     bfa_port_stats_clr_timeout(void *cbarg);
+static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport);
+static bfa_boolean_t bfa_fcport_send_disable(struct bfa_fcport_s *fcport);
+static void     bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport);
+static void     bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport);
+static void     bfa_fcport_set_wwns(struct bfa_fcport_s *fcport);
+static void     __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete);
+static void     bfa_fcport_callback(struct bfa_fcport_s *fcport,
+                               enum bfa_pport_linkstate event);
+static void     bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln,
+                               enum bfa_pport_linkstate event);
+static void     __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete);
+static void     bfa_fcport_stats_get_timeout(void *cbarg);
+static void     bfa_fcport_stats_clr_timeout(void *cbarg);
 
 /**
  *  bfa_pport_private
@@ -65,111 +58,114 @@ static void     bfa_port_stats_clr_timeout(void *cbarg);
 /**
  * BFA port state machine events
  */
-enum bfa_pport_sm_event {
-       BFA_PPORT_SM_START = 1, /*  start port state machine */
-       BFA_PPORT_SM_STOP = 2,  /*  stop port state machine */
-       BFA_PPORT_SM_ENABLE = 3,        /*  enable port */
-       BFA_PPORT_SM_DISABLE = 4,       /*  disable port state machine */
-       BFA_PPORT_SM_FWRSP = 5, /*  firmware enable/disable rsp */
-       BFA_PPORT_SM_LINKUP = 6,        /*  firmware linkup event */
-       BFA_PPORT_SM_LINKDOWN = 7,      /*  firmware linkup down */
-       BFA_PPORT_SM_QRESUME = 8,       /*  CQ space available */
-       BFA_PPORT_SM_HWFAIL = 9,        /*  IOC h/w failure */
+enum bfa_fcport_sm_event {
+       BFA_FCPORT_SM_START = 1,        /*  start port state machine */
+       BFA_FCPORT_SM_STOP = 2, /*  stop port state machine */
+       BFA_FCPORT_SM_ENABLE = 3,       /*  enable port */
+       BFA_FCPORT_SM_DISABLE = 4,      /*  disable port state machine */
+       BFA_FCPORT_SM_FWRSP = 5,        /*  firmware enable/disable rsp */
+       BFA_FCPORT_SM_LINKUP = 6,       /*  firmware linkup event */
+       BFA_FCPORT_SM_LINKDOWN = 7,     /*  firmware linkup down */
+       BFA_FCPORT_SM_QRESUME = 8,      /*  CQ space available */
+       BFA_FCPORT_SM_HWFAIL = 9,       /*  IOC h/w failure */
 };
 
-static void     bfa_pport_sm_uninit(struct bfa_pport_s *pport,
-                                   enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport,
-                                           enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_enabling(struct bfa_pport_s *pport,
-                                     enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_linkdown(struct bfa_pport_s *pport,
-                                     enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_linkup(struct bfa_pport_s *pport,
-                                   enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_disabling(struct bfa_pport_s *pport,
-                                      enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport,
-                                            enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_disabled(struct bfa_pport_s *pport,
-                                     enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_stopped(struct bfa_pport_s *pport,
-                                    enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_iocdown(struct bfa_pport_s *pport,
-                                    enum bfa_pport_sm_event event);
-static void     bfa_pport_sm_iocfail(struct bfa_pport_s *pport,
-                                    enum bfa_pport_sm_event event);
+/**
+ * BFA port link notification state machine events
+ */
+
+enum bfa_fcport_ln_sm_event {
+       BFA_FCPORT_LN_SM_LINKUP         = 1,    /*  linkup event */
+       BFA_FCPORT_LN_SM_LINKDOWN       = 2,    /*  linkdown event */
+       BFA_FCPORT_LN_SM_NOTIFICATION   = 3     /*  done notification */
+};
+
+static void     bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
+                                       enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
+                                               enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
+                                               enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
+                                               enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
+                                               enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
+                                               enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
+                                               enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
+                                               enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
+                                        enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
+                                        enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
+                                        enum bfa_fcport_sm_event event);
+
+static void     bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
+                                        enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
+                                        enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
+                                        enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
+                                        enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
+                                        enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
+                                        enum bfa_fcport_ln_sm_event event);
+static void     bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
+                                        enum bfa_fcport_ln_sm_event event);
 
 static struct bfa_sm_table_s hal_pport_sm_table[] = {
-       {BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT},
-       {BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
-       {BFA_SM(bfa_pport_sm_enabling), BFA_PPORT_ST_ENABLING},
-       {BFA_SM(bfa_pport_sm_linkdown), BFA_PPORT_ST_LINKDOWN},
-       {BFA_SM(bfa_pport_sm_linkup), BFA_PPORT_ST_LINKUP},
-       {BFA_SM(bfa_pport_sm_disabling_qwait),
-        BFA_PPORT_ST_DISABLING_QWAIT},
-       {BFA_SM(bfa_pport_sm_disabling), BFA_PPORT_ST_DISABLING},
-       {BFA_SM(bfa_pport_sm_disabled), BFA_PPORT_ST_DISABLED},
-       {BFA_SM(bfa_pport_sm_stopped), BFA_PPORT_ST_STOPPED},
-       {BFA_SM(bfa_pport_sm_iocdown), BFA_PPORT_ST_IOCDOWN},
-       {BFA_SM(bfa_pport_sm_iocfail), BFA_PPORT_ST_IOCDOWN},
+       {BFA_SM(bfa_fcport_sm_uninit), BFA_PPORT_ST_UNINIT},
+       {BFA_SM(bfa_fcport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
+       {BFA_SM(bfa_fcport_sm_enabling), BFA_PPORT_ST_ENABLING},
+       {BFA_SM(bfa_fcport_sm_linkdown), BFA_PPORT_ST_LINKDOWN},
+       {BFA_SM(bfa_fcport_sm_linkup), BFA_PPORT_ST_LINKUP},
+       {BFA_SM(bfa_fcport_sm_disabling_qwait), BFA_PPORT_ST_DISABLING_QWAIT},
+       {BFA_SM(bfa_fcport_sm_disabling), BFA_PPORT_ST_DISABLING},
+       {BFA_SM(bfa_fcport_sm_disabled), BFA_PPORT_ST_DISABLED},
+       {BFA_SM(bfa_fcport_sm_stopped), BFA_PPORT_ST_STOPPED},
+       {BFA_SM(bfa_fcport_sm_iocdown), BFA_PPORT_ST_IOCDOWN},
+       {BFA_SM(bfa_fcport_sm_iocfail), BFA_PPORT_ST_IOCDOWN},
 };
 
 static void
-bfa_pport_aen_post(struct bfa_pport_s *pport, enum bfa_port_aen_event event)
+bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event)
 {
        union bfa_aen_data_u aen_data;
-       struct bfa_log_mod_s *logmod = pport->bfa->logm;
-       wwn_t           pwwn = pport->pwwn;
+       struct bfa_log_mod_s *logmod = fcport->bfa->logm;
+       wwn_t           pwwn = fcport->pwwn;
        char            pwwn_ptr[BFA_STRING_32];
-       struct bfa_ioc_attr_s ioc_attr;
 
+       memset(&aen_data, 0, sizeof(aen_data));
        wwn2str(pwwn_ptr, pwwn);
-       switch (event) {
-       case BFA_PORT_AEN_ONLINE:
-               bfa_log(logmod, BFA_AEN_PORT_ONLINE, pwwn_ptr);
-               break;
-       case BFA_PORT_AEN_OFFLINE:
-               bfa_log(logmod, BFA_AEN_PORT_OFFLINE, pwwn_ptr);
-               break;
-       case BFA_PORT_AEN_ENABLE:
-               bfa_log(logmod, BFA_AEN_PORT_ENABLE, pwwn_ptr);
-               break;
-       case BFA_PORT_AEN_DISABLE:
-               bfa_log(logmod, BFA_AEN_PORT_DISABLE, pwwn_ptr);
-               break;
-       case BFA_PORT_AEN_DISCONNECT:
-               bfa_log(logmod, BFA_AEN_PORT_DISCONNECT, pwwn_ptr);
-               break;
-       case BFA_PORT_AEN_QOS_NEG:
-               bfa_log(logmod, BFA_AEN_PORT_QOS_NEG, pwwn_ptr);
-               break;
-       default:
-               break;
-       }
+       bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event), pwwn_ptr);
 
-       bfa_ioc_get_attr(&pport->bfa->ioc, &ioc_attr);
-       aen_data.port.ioc_type = ioc_attr.ioc_type;
+       aen_data.port.ioc_type = bfa_get_type(fcport->bfa);
        aen_data.port.pwwn = pwwn;
 }
 
 static void
-bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
+                       enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_START:
+       case BFA_FCPORT_SM_START:
                /**
                 * Start event after IOC is configured and BFA is started.
                 */
-               if (bfa_pport_send_enable(pport))
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+               if (bfa_fcport_send_enable(fcport))
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
                else
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
                break;
 
-       case BFA_PPORT_SM_ENABLE:
+       case BFA_FCPORT_SM_ENABLE:
                /**
                 * Port is persistently configured to be in enabled state. Do
                 * not change state. Port enabling is done when START event is
@@ -177,389 +173,412 @@ bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
                 */
                break;
 
-       case BFA_PPORT_SM_DISABLE:
+       case BFA_FCPORT_SM_DISABLE:
                /**
                 * If a port is persistently configured to be disabled, the
                 * first event will a port disable request.
                 */
-               bfa_sm_set_state(pport, bfa_pport_sm_disabled);
+               bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
                break;
 
-       case BFA_PPORT_SM_HWFAIL:
-               bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+       case BFA_FCPORT_SM_HWFAIL:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
                break;
 
        default:
-               bfa_sm_fault(pport->bfa, event);
+               bfa_sm_fault(fcport->bfa, event);
        }
 }
 
 static void
-bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport,
-                           enum bfa_pport_sm_event event)
+bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
+                           enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_QRESUME:
-               bfa_sm_set_state(pport, bfa_pport_sm_enabling);
-               bfa_pport_send_enable(pport);
+       case BFA_FCPORT_SM_QRESUME:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
+               bfa_fcport_send_enable(fcport);
                break;
 
-       case BFA_PPORT_SM_STOP:
-               bfa_reqq_wcancel(&pport->reqq_wait);
-               bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+       case BFA_FCPORT_SM_STOP:
+               bfa_reqq_wcancel(&fcport->reqq_wait);
+               bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
                break;
 
-       case BFA_PPORT_SM_ENABLE:
+       case BFA_FCPORT_SM_ENABLE:
                /**
                 * Already enable is in progress.
                 */
                break;
 
-       case BFA_PPORT_SM_DISABLE:
+       case BFA_FCPORT_SM_DISABLE:
                /**
                 * Just send disable request to firmware when room becomes
                 * available in request queue.
                 */
-               bfa_sm_set_state(pport, bfa_pport_sm_disabled);
-               bfa_reqq_wcancel(&pport->reqq_wait);
-               bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+               bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
+               bfa_reqq_wcancel(&fcport->reqq_wait);
+               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                             BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
-               bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
+               bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
                break;
 
-       case BFA_PPORT_SM_LINKUP:
-       case BFA_PPORT_SM_LINKDOWN:
+       case BFA_FCPORT_SM_LINKUP:
+       case BFA_FCPORT_SM_LINKDOWN:
                /**
                 * Possible to get link events when doing back-to-back
                 * enable/disables.
                 */
                break;
 
-       case BFA_PPORT_SM_HWFAIL:
-               bfa_reqq_wcancel(&pport->reqq_wait);
-               bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+       case BFA_FCPORT_SM_HWFAIL:
+               bfa_reqq_wcancel(&fcport->reqq_wait);
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
                break;
 
        default:
-               bfa_sm_fault(pport->bfa, event);
+               bfa_sm_fault(fcport->bfa, event);
        }
 }
 
 static void
-bfa_pport_sm_enabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
+               enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_FWRSP:
-       case BFA_PPORT_SM_LINKDOWN:
-               bfa_sm_set_state(pport, bfa_pport_sm_linkdown);
+       case BFA_FCPORT_SM_FWRSP:
+       case BFA_FCPORT_SM_LINKDOWN:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
                break;
 
-       case BFA_PPORT_SM_LINKUP:
-               bfa_pport_update_linkinfo(pport);
-               bfa_sm_set_state(pport, bfa_pport_sm_linkup);
+       case BFA_FCPORT_SM_LINKUP:
+               bfa_fcport_update_linkinfo(fcport);
+               bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
 
-               bfa_assert(pport->event_cbfn);
-               bfa_pport_callback(pport, BFA_PPORT_LINKUP);
+               bfa_assert(fcport->event_cbfn);
+               bfa_fcport_callback(fcport, BFA_PPORT_LINKUP);
                break;
 
-       case BFA_PPORT_SM_ENABLE:
+       case BFA_FCPORT_SM_ENABLE:
                /**
                 * Already being enabled.
                 */
                break;
 
-       case BFA_PPORT_SM_DISABLE:
-               if (bfa_pport_send_disable(pport))
-                       bfa_sm_set_state(pport, bfa_pport_sm_disabling);
+       case BFA_FCPORT_SM_DISABLE:
+               if (bfa_fcport_send_disable(fcport))
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
                else
-                       bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
 
-               bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                             BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
-               bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
+               bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
                break;
 
-       case BFA_PPORT_SM_STOP:
-               bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+       case BFA_FCPORT_SM_STOP:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
                break;
 
-       case BFA_PPORT_SM_HWFAIL:
-               bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+       case BFA_FCPORT_SM_HWFAIL:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
                break;
 
        default:
-               bfa_sm_fault(pport->bfa, event);
+               bfa_sm_fault(fcport->bfa, event);
        }
 }
 
 static void
-bfa_pport_sm_linkdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
+                       enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_LINKUP:
-               bfa_pport_update_linkinfo(pport);
-               bfa_sm_set_state(pport, bfa_pport_sm_linkup);
-               bfa_assert(pport->event_cbfn);
-               bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+       case BFA_FCPORT_SM_LINKUP:
+               bfa_fcport_update_linkinfo(fcport);
+               bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
+               bfa_assert(fcport->event_cbfn);
+               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                             BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup");
-               bfa_pport_callback(pport, BFA_PPORT_LINKUP);
-               bfa_pport_aen_post(pport, BFA_PORT_AEN_ONLINE);
+
+               if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
+
+                       bfa_trc(fcport->bfa, pevent->link_state.fcf.fipenabled);
+                       bfa_trc(fcport->bfa, pevent->link_state.fcf.fipfailed);
+
+                       if (pevent->link_state.fcf.fipfailed)
+                               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
+                                       BFA_PL_EID_FIP_FCF_DISC, 0,
+                                       "FIP FCF Discovery Failed");
+                       else
+                               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
+                                       BFA_PL_EID_FIP_FCF_DISC, 0,
+                                       "FIP FCF Discovered");
+               }
+
+               bfa_fcport_callback(fcport, BFA_PPORT_LINKUP);
+               bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE);
                /**
                 * If QoS is enabled and it is not online,
                 * Send a separate event.
                 */
-               if ((pport->cfg.qos_enabled)
-                   && (bfa_os_ntohl(pport->qos_attr.state) != BFA_QOS_ONLINE))
-                       bfa_pport_aen_post(pport, BFA_PORT_AEN_QOS_NEG);
+               if ((fcport->cfg.qos_enabled)
+                   && (bfa_os_ntohl(fcport->qos_attr.state) != BFA_QOS_ONLINE))
+                       bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG);
 
                break;
 
-       case BFA_PPORT_SM_LINKDOWN:
+       case BFA_FCPORT_SM_LINKDOWN:
                /**
                 * Possible to get link down event.
                 */
                break;
 
-       case BFA_PPORT_SM_ENABLE:
+       case BFA_FCPORT_SM_ENABLE:
                /**
                 * Already enabled.
                 */
                break;
 
-       case BFA_PPORT_SM_DISABLE:
-               if (bfa_pport_send_disable(pport))
-                       bfa_sm_set_state(pport, bfa_pport_sm_disabling);
+       case BFA_FCPORT_SM_DISABLE:
+               if (bfa_fcport_send_disable(fcport))
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
                else
-                       bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
 
-               bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                             BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
-               bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
+               bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
                break;
 
-       case BFA_PPORT_SM_STOP:
-               bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+       case BFA_FCPORT_SM_STOP:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
                break;
 
-       case BFA_PPORT_SM_HWFAIL:
-               bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+       case BFA_FCPORT_SM_HWFAIL:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
                break;
 
        default:
-               bfa_sm_fault(pport->bfa, event);
+               bfa_sm_fault(fcport->bfa, event);
        }
 }
 
 static void
-bfa_pport_sm_linkup(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
+                       enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_ENABLE:
+       case BFA_FCPORT_SM_ENABLE:
                /**
                 * Already enabled.
                 */
                break;
 
-       case BFA_PPORT_SM_DISABLE:
-               if (bfa_pport_send_disable(pport))
-                       bfa_sm_set_state(pport, bfa_pport_sm_disabling);
+       case BFA_FCPORT_SM_DISABLE:
+               if (bfa_fcport_send_disable(fcport))
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
                else
-                       bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
 
-               bfa_pport_reset_linkinfo(pport);
-               bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
-               bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+               bfa_fcport_reset_linkinfo(fcport);
+               bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
+               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                             BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
-               bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
-               bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
+               bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
+               bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
                break;
 
-       case BFA_PPORT_SM_LINKDOWN:
-               bfa_sm_set_state(pport, bfa_pport_sm_linkdown);
-               bfa_pport_reset_linkinfo(pport);
-               bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
-               bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+       case BFA_FCPORT_SM_LINKDOWN:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
+               bfa_fcport_reset_linkinfo(fcport);
+               bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
+               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                             BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
-               if (BFA_PORT_IS_DISABLED(pport->bfa))
-                       bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
+               if (BFA_PORT_IS_DISABLED(fcport->bfa))
+                       bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
                else
-                       bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
+                       bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
                break;
 
-       case BFA_PPORT_SM_STOP:
-               bfa_sm_set_state(pport, bfa_pport_sm_stopped);
-               bfa_pport_reset_linkinfo(pport);
-               if (BFA_PORT_IS_DISABLED(pport->bfa))
-                       bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
+       case BFA_FCPORT_SM_STOP:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
+               bfa_fcport_reset_linkinfo(fcport);
+               if (BFA_PORT_IS_DISABLED(fcport->bfa))
+                       bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
                else
-                       bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
+                       bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
                break;
 
-       case BFA_PPORT_SM_HWFAIL:
-               bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
-               bfa_pport_reset_linkinfo(pport);
-               bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
-               if (BFA_PORT_IS_DISABLED(pport->bfa))
-                       bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
+       case BFA_FCPORT_SM_HWFAIL:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
+               bfa_fcport_reset_linkinfo(fcport);
+               bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
+               if (BFA_PORT_IS_DISABLED(fcport->bfa))
+                       bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
                else
-                       bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
+                       bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
                break;
 
        default:
-               bfa_sm_fault(pport->bfa, event);
+               bfa_sm_fault(fcport->bfa, event);
        }
 }
 
 static void
-bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport,
-                            enum bfa_pport_sm_event event)
+bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
+                            enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_QRESUME:
-               bfa_sm_set_state(pport, bfa_pport_sm_disabling);
-               bfa_pport_send_disable(pport);
+       case BFA_FCPORT_SM_QRESUME:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
+               bfa_fcport_send_disable(fcport);
                break;
 
-       case BFA_PPORT_SM_STOP:
-               bfa_sm_set_state(pport, bfa_pport_sm_stopped);
-               bfa_reqq_wcancel(&pport->reqq_wait);
+       case BFA_FCPORT_SM_STOP:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
+               bfa_reqq_wcancel(&fcport->reqq_wait);
                break;
 
-       case BFA_PPORT_SM_DISABLE:
+       case BFA_FCPORT_SM_DISABLE:
                /**
                 * Already being disabled.
                 */
                break;
 
-       case BFA_PPORT_SM_LINKUP:
-       case BFA_PPORT_SM_LINKDOWN:
+       case BFA_FCPORT_SM_LINKUP:
+       case BFA_FCPORT_SM_LINKDOWN:
                /**
                 * Possible to get link events when doing back-to-back
                 * enable/disables.
                 */
                break;
 
-       case BFA_PPORT_SM_HWFAIL:
-               bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
-               bfa_reqq_wcancel(&pport->reqq_wait);
+       case BFA_FCPORT_SM_HWFAIL:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
+               bfa_reqq_wcancel(&fcport->reqq_wait);
                break;
 
        default:
-               bfa_sm_fault(pport->bfa, event);
+               bfa_sm_fault(fcport->bfa, event);
        }
 }
 
 static void
-bfa_pport_sm_disabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
+                       enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_FWRSP:
-               bfa_sm_set_state(pport, bfa_pport_sm_disabled);
+       case BFA_FCPORT_SM_FWRSP:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
                break;
 
-       case BFA_PPORT_SM_DISABLE:
+       case BFA_FCPORT_SM_DISABLE:
                /**
                 * Already being disabled.
                 */
                break;
 
-       case BFA_PPORT_SM_ENABLE:
-               if (bfa_pport_send_enable(pport))
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+       case BFA_FCPORT_SM_ENABLE:
+               if (bfa_fcport_send_enable(fcport))
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
                else
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
 
-               bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                             BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
-               bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE);
+               bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
                break;
 
-       case BFA_PPORT_SM_STOP:
-               bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+       case BFA_FCPORT_SM_STOP:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
                break;
 
-       case BFA_PPORT_SM_LINKUP:
-       case BFA_PPORT_SM_LINKDOWN:
+       case BFA_FCPORT_SM_LINKUP:
+       case BFA_FCPORT_SM_LINKDOWN:
                /**
                 * Possible to get link events when doing back-to-back
                 * enable/disables.
                 */
                break;
 
-       case BFA_PPORT_SM_HWFAIL:
-               bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
+       case BFA_FCPORT_SM_HWFAIL:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
                break;
 
        default:
-               bfa_sm_fault(pport->bfa, event);
+               bfa_sm_fault(fcport->bfa, event);
        }
 }
 
 static void
-bfa_pport_sm_disabled(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
+                       enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_START:
+       case BFA_FCPORT_SM_START:
                /**
                 * Ignore start event for a port that is disabled.
                 */
                break;
 
-       case BFA_PPORT_SM_STOP:
-               bfa_sm_set_state(pport, bfa_pport_sm_stopped);
+       case BFA_FCPORT_SM_STOP:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
                break;
 
-       case BFA_PPORT_SM_ENABLE:
-               if (bfa_pport_send_enable(pport))
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+       case BFA_FCPORT_SM_ENABLE:
+               if (bfa_fcport_send_enable(fcport))
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
                else
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
 
-               bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
+               bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                             BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
-               bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE);
+               bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
                break;
 
-       case BFA_PPORT_SM_DISABLE:
+       case BFA_FCPORT_SM_DISABLE:
                /**
                 * Already disabled.
                 */
                break;
 
-       case BFA_PPORT_SM_HWFAIL:
-               bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
+       case BFA_FCPORT_SM_HWFAIL:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
                break;
 
        default:
-               bfa_sm_fault(pport->bfa, event);
+               bfa_sm_fault(fcport->bfa, event);
        }
 }
 
 static void
-bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
+                       enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_START:
-               if (bfa_pport_send_enable(pport))
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+       case BFA_FCPORT_SM_START:
+               if (bfa_fcport_send_enable(fcport))
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
                else
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
                break;
 
        default:
@@ -574,16 +593,17 @@ bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
  * Port is enabled. IOC is down/failed.
  */
 static void
-bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
+                       enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_START:
-               if (bfa_pport_send_enable(pport))
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling);
+       case BFA_FCPORT_SM_START:
+               if (bfa_fcport_send_enable(fcport))
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
                else
-                       bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
+                       bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
                break;
 
        default:
@@ -598,17 +618,18 @@ bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
  * Port is disabled. IOC is down/failed.
  */
 static void
-bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
+bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
+                       enum bfa_fcport_sm_event event)
 {
-       bfa_trc(pport->bfa, event);
+       bfa_trc(fcport->bfa, event);
 
        switch (event) {
-       case BFA_PPORT_SM_START:
-               bfa_sm_set_state(pport, bfa_pport_sm_disabled);
+       case BFA_FCPORT_SM_START:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
                break;
 
-       case BFA_PPORT_SM_ENABLE:
-               bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
+       case BFA_FCPORT_SM_ENABLE:
+               bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
                break;
 
        default:
@@ -619,41 +640,226 @@ bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
        }
 }
 
+/**
+ * Link state is down
+ */
+static void
+bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
+               enum bfa_fcport_ln_sm_event event)
+{
+       bfa_trc(ln->fcport->bfa, event);
+
+       switch (event) {
+       case BFA_FCPORT_LN_SM_LINKUP:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
+               bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP);
+               break;
+
+       default:
+               bfa_sm_fault(ln->fcport->bfa, event);
+       }
+}
+
+/**
+ * Link state is waiting for down notification
+ */
+static void
+bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
+               enum bfa_fcport_ln_sm_event event)
+{
+       bfa_trc(ln->fcport->bfa, event);
+
+       switch (event) {
+       case BFA_FCPORT_LN_SM_LINKUP:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
+               break;
+
+       case BFA_FCPORT_LN_SM_NOTIFICATION:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
+               break;
+
+       default:
+               bfa_sm_fault(ln->fcport->bfa, event);
+       }
+}
+
+/**
+ * Link state is waiting for down notification and there is a pending up
+ */
+static void
+bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
+               enum bfa_fcport_ln_sm_event event)
+{
+       bfa_trc(ln->fcport->bfa, event);
+
+       switch (event) {
+       case BFA_FCPORT_LN_SM_LINKDOWN:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
+               break;
+
+       case BFA_FCPORT_LN_SM_NOTIFICATION:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
+               bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP);
+               break;
+
+       default:
+               bfa_sm_fault(ln->fcport->bfa, event);
+       }
+}
+
+/**
+ * Link state is up
+ */
+static void
+bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
+               enum bfa_fcport_ln_sm_event event)
+{
+       bfa_trc(ln->fcport->bfa, event);
+
+       switch (event) {
+       case BFA_FCPORT_LN_SM_LINKDOWN:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
+               bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
+               break;
 
+       default:
+               bfa_sm_fault(ln->fcport->bfa, event);
+       }
+}
+
+/**
+ * Link state is waiting for up notification
+ */
+static void
+bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
+               enum bfa_fcport_ln_sm_event event)
+{
+       bfa_trc(ln->fcport->bfa, event);
+
+       switch (event) {
+       case BFA_FCPORT_LN_SM_LINKDOWN:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
+               break;
+
+       case BFA_FCPORT_LN_SM_NOTIFICATION:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_up);
+               break;
+
+       default:
+               bfa_sm_fault(ln->fcport->bfa, event);
+       }
+}
+
+/**
+ * Link state is waiting for up notification and there is a pending down
+ */
+static void
+bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
+               enum bfa_fcport_ln_sm_event event)
+{
+       bfa_trc(ln->fcport->bfa, event);
+
+       switch (event) {
+       case BFA_FCPORT_LN_SM_LINKUP:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_up_nf);
+               break;
+
+       case BFA_FCPORT_LN_SM_NOTIFICATION:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
+               bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
+               break;
+
+       default:
+               bfa_sm_fault(ln->fcport->bfa, event);
+       }
+}
+
+/**
+ * Link state is waiting for up notification and there are pending down and up
+ */
+static void
+bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
+                       enum bfa_fcport_ln_sm_event event)
+{
+       bfa_trc(ln->fcport->bfa, event);
+
+       switch (event) {
+       case BFA_FCPORT_LN_SM_LINKDOWN:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
+               break;
+
+       case BFA_FCPORT_LN_SM_NOTIFICATION:
+               bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
+               bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
+               break;
+
+       default:
+               bfa_sm_fault(ln->fcport->bfa, event);
+       }
+}
 
 /**
  *  bfa_pport_private
  */
 
 static void
-__bfa_cb_port_event(void *cbarg, bfa_boolean_t complete)
+__bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete)
 {
-       struct bfa_pport_s *pport = cbarg;
+       struct bfa_fcport_ln_s *ln = cbarg;
 
        if (complete)
-               pport->event_cbfn(pport->event_cbarg, pport->hcb_event);
+               ln->fcport->event_cbfn(ln->fcport->event_cbarg, ln->ln_event);
+       else
+               bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION);
 }
 
-#define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \
+static void
+bfa_fcport_callback(struct bfa_fcport_s *fcport, enum bfa_pport_linkstate event)
+{
+       if (fcport->bfa->fcs) {
+               fcport->event_cbfn(fcport->event_cbarg, event);
+               return;
+       }
+
+       switch (event) {
+       case BFA_PPORT_LINKUP:
+               bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP);
+               break;
+       case BFA_PPORT_LINKDOWN:
+               bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN);
+               break;
+       default:
+               bfa_assert(0);
+       }
+}
+
+static void
+bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_pport_linkstate event)
+{
+       ln->ln_event = event;
+       bfa_cb_queue(ln->fcport->bfa, &ln->ln_qe, __bfa_cb_fcport_event, ln);
+}
+
+#define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \
                                                        BFA_CACHELINE_SZ))
 
 static void
-bfa_pport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
+bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
                  u32 *dm_len)
 {
-       *dm_len += PPORT_STATS_DMA_SZ;
+       *dm_len += FCPORT_STATS_DMA_SZ;
 }
 
 static void
-bfa_pport_qresume(void *cbarg)
+bfa_fcport_qresume(void *cbarg)
 {
-       struct bfa_pport_s *port = cbarg;
+       struct bfa_fcport_s *fcport = cbarg;
 
-       bfa_sm_send_event(port, BFA_PPORT_SM_QRESUME);
+       bfa_sm_send_event(fcport, BFA_FCPORT_SM_QRESUME);
 }
 
 static void
-bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo)
+bfa_fcport_mem_claim(struct bfa_fcport_s *fcport, struct bfa_meminfo_s *meminfo)
 {
        u8        *dm_kva;
        u64        dm_pa;
@@ -661,12 +867,12 @@ bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo)
        dm_kva = bfa_meminfo_dma_virt(meminfo);
        dm_pa = bfa_meminfo_dma_phys(meminfo);
 
-       pport->stats_kva = dm_kva;
-       pport->stats_pa = dm_pa;
-       pport->stats = (union bfa_pport_stats_u *)dm_kva;
+       fcport->stats_kva = dm_kva;
+       fcport->stats_pa = dm_pa;
+       fcport->stats = (union bfa_fcport_stats_u *)dm_kva;
 
-       dm_kva += PPORT_STATS_DMA_SZ;
-       dm_pa += PPORT_STATS_DMA_SZ;
+       dm_kva += FCPORT_STATS_DMA_SZ;
+       dm_pa += FCPORT_STATS_DMA_SZ;
 
        bfa_meminfo_dma_virt(meminfo) = dm_kva;
        bfa_meminfo_dma_phys(meminfo) = dm_pa;
@@ -676,18 +882,21 @@ bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo)
  * Memory initialization.
  */
 static void
-bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
+bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
                 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
-       struct bfa_pport_cfg_s *port_cfg = &pport->cfg;
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+       struct bfa_pport_cfg_s *port_cfg = &fcport->cfg;
+       struct bfa_fcport_ln_s *ln = &fcport->ln;
 
-       bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s));
-       pport->bfa = bfa;
+       bfa_os_memset(fcport, 0, sizeof(struct bfa_fcport_s));
+       fcport->bfa = bfa;
+       ln->fcport = fcport;
 
-       bfa_pport_mem_claim(pport, meminfo);
+       bfa_fcport_mem_claim(fcport, meminfo);
 
-       bfa_sm_set_state(pport, bfa_pport_sm_uninit);
+       bfa_sm_set_state(fcport, bfa_fcport_sm_uninit);
+       bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
 
        /**
         * initialize and set default configuration
@@ -699,30 +908,30 @@ bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
 
        port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS;
 
-       bfa_reqq_winit(&pport->reqq_wait, bfa_pport_qresume, pport);
+       bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport);
 }
 
 static void
-bfa_pport_initdone(struct bfa_s *bfa)
+bfa_fcport_initdone(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        /**
         * Initialize port attributes from IOC hardware data.
         */
-       bfa_pport_set_wwns(pport);
-       if (pport->cfg.maxfrsize == 0)
-               pport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
-       pport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
-       pport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
+       bfa_fcport_set_wwns(fcport);
+       if (fcport->cfg.maxfrsize == 0)
+               fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
+       fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
+       fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
 
-       bfa_assert(pport->cfg.maxfrsize);
-       bfa_assert(pport->cfg.rx_bbcredit);
-       bfa_assert(pport->speed_sup);
+       bfa_assert(fcport->cfg.maxfrsize);
+       bfa_assert(fcport->cfg.rx_bbcredit);
+       bfa_assert(fcport->speed_sup);
 }
 
 static void
-bfa_pport_detach(struct bfa_s *bfa)
+bfa_fcport_detach(struct bfa_s *bfa)
 {
 }
 
@@ -730,95 +939,97 @@ bfa_pport_detach(struct bfa_s *bfa)
  * Called when IOC is ready.
  */
 static void
-bfa_pport_start(struct bfa_s *bfa)
+bfa_fcport_start(struct bfa_s *bfa)
 {
-       bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_START);
+       bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START);
 }
 
 /**
  * Called before IOC is stopped.
  */
 static void
-bfa_pport_stop(struct bfa_s *bfa)
+bfa_fcport_stop(struct bfa_s *bfa)
 {
-       bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_STOP);
+       bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_STOP);
 }
 
 /**
  * Called when IOC failure is detected.
  */
 static void
-bfa_pport_iocdisable(struct bfa_s *bfa)
+bfa_fcport_iocdisable(struct bfa_s *bfa)
 {
-       bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_HWFAIL);
+       bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_HWFAIL);
 }
 
 static void
-bfa_pport_update_linkinfo(struct bfa_pport_s *pport)
+bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
 {
-       struct bfi_pport_event_s *pevent = pport->event_arg.i2hmsg.event;
+       struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
 
-       pport->speed = pevent->link_state.speed;
-       pport->topology = pevent->link_state.topology;
+       fcport->speed = pevent->link_state.speed;
+       fcport->topology = pevent->link_state.topology;
 
-       if (pport->topology == BFA_PPORT_TOPOLOGY_LOOP)
-               pport->myalpa = pevent->link_state.tl.loop_info.myalpa;
+       if (fcport->topology == BFA_PPORT_TOPOLOGY_LOOP)
+               fcport->myalpa =
+                       pevent->link_state.tl.loop_info.myalpa;
 
        /*
         * QoS Details
         */
-       bfa_os_assign(pport->qos_attr, pevent->link_state.qos_attr);
-       bfa_os_assign(pport->qos_vc_attr, pevent->link_state.qos_vc_attr);
+       bfa_os_assign(fcport->qos_attr, pevent->link_state.qos_attr);
+       bfa_os_assign(fcport->qos_vc_attr, pevent->link_state.qos_vc_attr);
 
-       bfa_trc(pport->bfa, pport->speed);
-       bfa_trc(pport->bfa, pport->topology);
+       bfa_trc(fcport->bfa, fcport->speed);
+       bfa_trc(fcport->bfa, fcport->topology);
 }
 
 static void
-bfa_pport_reset_linkinfo(struct bfa_pport_s *pport)
+bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport)
 {
-       pport->speed = BFA_PPORT_SPEED_UNKNOWN;
-       pport->topology = BFA_PPORT_TOPOLOGY_NONE;
+       fcport->speed = BFA_PPORT_SPEED_UNKNOWN;
+       fcport->topology = BFA_PPORT_TOPOLOGY_NONE;
 }
 
 /**
  * Send port enable message to firmware.
  */
 static          bfa_boolean_t
-bfa_pport_send_enable(struct bfa_pport_s *port)
+bfa_fcport_send_enable(struct bfa_fcport_s *fcport)
 {
-       struct bfi_pport_enable_req_s *m;
+       struct bfi_fcport_enable_req_s *m;
 
        /**
         * Increment message tag before queue check, so that responses to old
         * requests are discarded.
         */
-       port->msgtag++;
+       fcport->msgtag++;
 
        /**
         * check for room in queue to send request now
         */
-       m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+       m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
        if (!m) {
-               bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait);
+               bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
+                                                       &fcport->reqq_wait);
                return BFA_FALSE;
        }
 
-       bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_ENABLE_REQ,
-                   bfa_lpuid(port->bfa));
-       m->nwwn = port->nwwn;
-       m->pwwn = port->pwwn;
-       m->port_cfg = port->cfg;
-       m->msgtag = port->msgtag;
-       m->port_cfg.maxfrsize = bfa_os_htons(port->cfg.maxfrsize);
-       bfa_dma_be_addr_set(m->stats_dma_addr, port->stats_pa);
-       bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_lo);
-       bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_hi);
+       bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ,
+                               bfa_lpuid(fcport->bfa));
+       m->nwwn = fcport->nwwn;
+       m->pwwn = fcport->pwwn;
+       m->port_cfg = fcport->cfg;
+       m->msgtag = fcport->msgtag;
+       m->port_cfg.maxfrsize = bfa_os_htons(fcport->cfg.maxfrsize);
+       bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa);
+       bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo);
+       bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi);
 
        /**
         * queue I/O message to firmware
         */
-       bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
+       bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
        return BFA_TRUE;
 }
 
@@ -826,74 +1037,226 @@ bfa_pport_send_enable(struct bfa_pport_s *port)
  * Send port disable message to firmware.
  */
 static          bfa_boolean_t
-bfa_pport_send_disable(struct bfa_pport_s *port)
+bfa_fcport_send_disable(struct bfa_fcport_s *fcport)
 {
-       bfi_pport_disable_req_t *m;
+       struct bfi_fcport_req_s *m;
 
        /**
         * Increment message tag before queue check, so that responses to old
         * requests are discarded.
         */
-       port->msgtag++;
+       fcport->msgtag++;
 
        /**
         * check for room in queue to send request now
         */
-       m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+       m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
        if (!m) {
-               bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait);
+               bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
+                                                       &fcport->reqq_wait);
                return BFA_FALSE;
        }
 
-       bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_DISABLE_REQ,
-                   bfa_lpuid(port->bfa));
-       m->msgtag = port->msgtag;
+       bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ,
+                       bfa_lpuid(fcport->bfa));
+       m->msgtag = fcport->msgtag;
 
        /**
         * queue I/O message to firmware
         */
-       bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
+       bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
 
        return BFA_TRUE;
 }
 
 static void
-bfa_pport_set_wwns(struct bfa_pport_s *port)
+bfa_fcport_set_wwns(struct bfa_fcport_s *fcport)
 {
-       port->pwwn = bfa_ioc_get_pwwn(&port->bfa->ioc);
-       port->nwwn = bfa_ioc_get_nwwn(&port->bfa->ioc);
+       fcport->pwwn = bfa_ioc_get_pwwn(&fcport->bfa->ioc);
+       fcport->nwwn = bfa_ioc_get_nwwn(&fcport->bfa->ioc);
 
-       bfa_trc(port->bfa, port->pwwn);
-       bfa_trc(port->bfa, port->nwwn);
+       bfa_trc(fcport->bfa, fcport->pwwn);
+       bfa_trc(fcport->bfa, fcport->nwwn);
 }
 
 static void
-bfa_port_send_txcredit(void *port_cbarg)
+bfa_fcport_send_txcredit(void *port_cbarg)
 {
 
-       struct bfa_pport_s *port = port_cbarg;
-       struct bfi_pport_set_svc_params_req_s *m;
+       struct bfa_fcport_s *fcport = port_cbarg;
+       struct bfi_fcport_set_svc_params_req_s *m;
 
        /**
         * check for room in queue to send request now
         */
-       m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+       m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
        if (!m) {
-               bfa_trc(port->bfa, port->cfg.tx_bbcredit);
+               bfa_trc(fcport->bfa, fcport->cfg.tx_bbcredit);
                return;
        }
 
-       bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_SET_SVC_PARAMS_REQ,
-                   bfa_lpuid(port->bfa));
-       m->tx_bbcredit = bfa_os_htons((u16) port->cfg.tx_bbcredit);
+       bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ,
+                       bfa_lpuid(fcport->bfa));
+       m->tx_bbcredit = bfa_os_htons((u16) fcport->cfg.tx_bbcredit);
 
        /**
         * queue I/O message to firmware
         */
-       bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
+       bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
 }
 
+static void
+bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d,
+       struct bfa_qos_stats_s *s)
+{
+       u32     *dip = (u32 *) d;
+       u32     *sip = (u32 *) s;
+       int             i;
+
+       /* Now swap the 32 bit fields */
+       for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i)
+               dip[i] = bfa_os_ntohl(sip[i]);
+}
 
+static void
+bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d,
+       struct bfa_fcoe_stats_s *s)
+{
+       u32     *dip = (u32 *) d;
+       u32     *sip = (u32 *) s;
+       int             i;
+
+       for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32));
+               i = i + 2) {
+#ifdef __BIGENDIAN
+               dip[i] = bfa_os_ntohl(sip[i]);
+               dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
+#else
+               dip[i] = bfa_os_ntohl(sip[i + 1]);
+               dip[i + 1] = bfa_os_ntohl(sip[i]);
+#endif
+       }
+}
+
+static void
+__bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
+{
+       struct bfa_fcport_s *fcport = cbarg;
+
+       if (complete) {
+               if (fcport->stats_status == BFA_STATUS_OK) {
+
+                       /* Swap FC QoS or FCoE stats */
+                       if (bfa_ioc_get_fcmode(&fcport->bfa->ioc))
+                               bfa_fcport_qos_stats_swap(
+                                       &fcport->stats_ret->fcqos,
+                                       &fcport->stats->fcqos);
+                       else
+                               bfa_fcport_fcoe_stats_swap(
+                                       &fcport->stats_ret->fcoe,
+                                       &fcport->stats->fcoe);
+               }
+               fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
+       } else {
+               fcport->stats_busy = BFA_FALSE;
+               fcport->stats_status = BFA_STATUS_OK;
+       }
+}
+
+static void
+bfa_fcport_stats_get_timeout(void *cbarg)
+{
+       struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
+
+       bfa_trc(fcport->bfa, fcport->stats_qfull);
+
+       if (fcport->stats_qfull) {
+               bfa_reqq_wcancel(&fcport->stats_reqq_wait);
+               fcport->stats_qfull = BFA_FALSE;
+       }
+
+       fcport->stats_status = BFA_STATUS_ETIMER;
+       bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats_get,
+               fcport);
+}
+
+static void
+bfa_fcport_send_stats_get(void *cbarg)
+{
+       struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
+       struct bfi_fcport_req_s *msg;
+
+       msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
+
+       if (!msg) {
+               fcport->stats_qfull = BFA_TRUE;
+               bfa_reqq_winit(&fcport->stats_reqq_wait,
+                               bfa_fcport_send_stats_get, fcport);
+               bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
+                               &fcport->stats_reqq_wait);
+               return;
+       }
+       fcport->stats_qfull = BFA_FALSE;
+
+       bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
+       bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ,
+               bfa_lpuid(fcport->bfa));
+       bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
+}
+
+static void
+__bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
+{
+       struct bfa_fcport_s *fcport = cbarg;
+
+       if (complete) {
+               fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
+       } else {
+               fcport->stats_busy = BFA_FALSE;
+               fcport->stats_status = BFA_STATUS_OK;
+       }
+}
+
+static void
+bfa_fcport_stats_clr_timeout(void *cbarg)
+{
+       struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
+
+       bfa_trc(fcport->bfa, fcport->stats_qfull);
+
+       if (fcport->stats_qfull) {
+               bfa_reqq_wcancel(&fcport->stats_reqq_wait);
+               fcport->stats_qfull = BFA_FALSE;
+       }
+
+       fcport->stats_status = BFA_STATUS_ETIMER;
+       bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
+                       __bfa_cb_fcport_stats_clr, fcport);
+}
+
+static void
+bfa_fcport_send_stats_clear(void *cbarg)
+{
+       struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
+       struct bfi_fcport_req_s *msg;
+
+       msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
+
+       if (!msg) {
+               fcport->stats_qfull = BFA_TRUE;
+               bfa_reqq_winit(&fcport->stats_reqq_wait,
+                               bfa_fcport_send_stats_clear, fcport);
+               bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
+                               &fcport->stats_reqq_wait);
+               return;
+       }
+       fcport->stats_qfull = BFA_FALSE;
+
+       bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
+       bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ,
+                       bfa_lpuid(fcport->bfa));
+       bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
+}
 
 /**
  *  bfa_pport_public
@@ -903,32 +1266,32 @@ bfa_port_send_txcredit(void *port_cbarg)
  * Firmware message handler.
  */
 void
-bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
+bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
-       union bfi_pport_i2h_msg_u i2hmsg;
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+       union bfi_fcport_i2h_msg_u i2hmsg;
 
        i2hmsg.msg = msg;
-       pport->event_arg.i2hmsg = i2hmsg;
+       fcport->event_arg.i2hmsg = i2hmsg;
 
        switch (msg->mhdr.msg_id) {
-       case BFI_PPORT_I2H_ENABLE_RSP:
-               if (pport->msgtag == i2hmsg.enable_rsp->msgtag)
-                       bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP);
+       case BFI_FCPORT_I2H_ENABLE_RSP:
+               if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
+                       bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
                break;
 
-       case BFI_PPORT_I2H_DISABLE_RSP:
-               if (pport->msgtag == i2hmsg.enable_rsp->msgtag)
-                       bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP);
+       case BFI_FCPORT_I2H_DISABLE_RSP:
+               if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
+                       bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
                break;
 
-       case BFI_PPORT_I2H_EVENT:
+       case BFI_FCPORT_I2H_EVENT:
                switch (i2hmsg.event->link_state.linkstate) {
                case BFA_PPORT_LINKUP:
-                       bfa_sm_send_event(pport, BFA_PPORT_SM_LINKUP);
+                       bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP);
                        break;
                case BFA_PPORT_LINKDOWN:
-                       bfa_sm_send_event(pport, BFA_PPORT_SM_LINKDOWN);
+                       bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN);
                        break;
                case BFA_PPORT_TRUNK_LINKDOWN:
                        /** todo: event notification */
@@ -936,42 +1299,40 @@ bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
                }
                break;
 
-       case BFI_PPORT_I2H_GET_STATS_RSP:
-       case BFI_PPORT_I2H_GET_QOS_STATS_RSP:
+       case BFI_FCPORT_I2H_STATS_GET_RSP:
                /*
                 * check for timer pop before processing the rsp
                 */
-               if (pport->stats_busy == BFA_FALSE
-                   || pport->stats_status == BFA_STATUS_ETIMER)
+               if (fcport->stats_busy == BFA_FALSE ||
+                       fcport->stats_status == BFA_STATUS_ETIMER)
                        break;
 
-               bfa_timer_stop(&pport->timer);
-               pport->stats_status = i2hmsg.getstats_rsp->status;
-               bfa_cb_queue(pport->bfa, &pport->hcb_qe, __bfa_cb_port_stats,
-                            pport);
+               bfa_timer_stop(&fcport->timer);
+               fcport->stats_status = i2hmsg.pstatsget_rsp->status;
+               bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
+                               __bfa_cb_fcport_stats_get, fcport);
                break;
-       case BFI_PPORT_I2H_CLEAR_STATS_RSP:
-       case BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP:
+
+       case BFI_FCPORT_I2H_STATS_CLEAR_RSP:
                /*
                 * check for timer pop before processing the rsp
                 */
-               if (pport->stats_busy == BFA_FALSE
-                   || pport->stats_status == BFA_STATUS_ETIMER)
+               if (fcport->stats_busy == BFA_FALSE ||
+                       fcport->stats_status == BFA_STATUS_ETIMER)
                        break;
 
-               bfa_timer_stop(&pport->timer);
-               pport->stats_status = BFA_STATUS_OK;
-               bfa_cb_queue(pport->bfa, &pport->hcb_qe,
-                            __bfa_cb_port_stats_clr, pport);
+               bfa_timer_stop(&fcport->timer);
+               fcport->stats_status = BFA_STATUS_OK;
+               bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
+                               __bfa_cb_fcport_stats_clr, fcport);
                break;
 
        default:
                bfa_assert(0);
+       break;
        }
 }
 
-
-
 /**
  *  bfa_pport_api
  */
@@ -980,35 +1341,35 @@ bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
  * Registered callback for port events.
  */
 void
-bfa_pport_event_register(struct bfa_s *bfa,
+bfa_fcport_event_register(struct bfa_s *bfa,
                         void (*cbfn) (void *cbarg, bfa_pport_event_t event),
                         void *cbarg)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       pport->event_cbfn = cbfn;
-       pport->event_cbarg = cbarg;
+       fcport->event_cbfn = cbfn;
+       fcport->event_cbarg = cbarg;
 }
 
 bfa_status_t
-bfa_pport_enable(struct bfa_s *bfa)
+bfa_fcport_enable(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       if (pport->diag_busy)
+       if (fcport->diag_busy)
                return BFA_STATUS_DIAG_BUSY;
        else if (bfa_sm_cmp_state
-                (BFA_PORT_MOD(bfa), bfa_pport_sm_disabling_qwait))
+                (BFA_FCPORT_MOD(bfa), bfa_fcport_sm_disabling_qwait))
                return BFA_STATUS_DEVBUSY;
 
-       bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_ENABLE);
+       bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_ENABLE);
        return BFA_STATUS_OK;
 }
 
 bfa_status_t
-bfa_pport_disable(struct bfa_s *bfa)
+bfa_fcport_disable(struct bfa_s *bfa)
 {
-       bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_DISABLE);
+       bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE);
        return BFA_STATUS_OK;
 }
 
@@ -1016,18 +1377,18 @@ bfa_pport_disable(struct bfa_s *bfa)
  * Configure port speed.
  */
 bfa_status_t
-bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
+bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, speed);
 
-       if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > pport->speed_sup)) {
-               bfa_trc(bfa, pport->speed_sup);
+       if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > fcport->speed_sup)) {
+               bfa_trc(bfa, fcport->speed_sup);
                return BFA_STATUS_UNSUPP_SPEED;
        }
 
-       pport->cfg.speed = speed;
+       fcport->cfg.speed = speed;
 
        return BFA_STATUS_OK;
 }
@@ -1036,23 +1397,23 @@ bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
  * Get current speed.
  */
 enum bfa_pport_speed
-bfa_pport_get_speed(struct bfa_s *bfa)
+bfa_fcport_get_speed(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       return port->speed;
+       return fcport->speed;
 }
 
 /**
  * Configure port topology.
  */
 bfa_status_t
-bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
+bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, topology);
-       bfa_trc(bfa, pport->cfg.topology);
+       bfa_trc(bfa, fcport->cfg.topology);
 
        switch (topology) {
        case BFA_PPORT_TOPOLOGY_P2P:
@@ -1064,7 +1425,7 @@ bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
                return BFA_STATUS_EINVAL;
        }
 
-       pport->cfg.topology = topology;
+       fcport->cfg.topology = topology;
        return BFA_STATUS_OK;
 }
 
@@ -1072,64 +1433,64 @@ bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
  * Get current topology.
  */
 enum bfa_pport_topology
-bfa_pport_get_topology(struct bfa_s *bfa)
+bfa_fcport_get_topology(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       return port->topology;
+       return fcport->topology;
 }
 
 bfa_status_t
-bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
+bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, alpa);
-       bfa_trc(bfa, pport->cfg.cfg_hardalpa);
-       bfa_trc(bfa, pport->cfg.hardalpa);
+       bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
+       bfa_trc(bfa, fcport->cfg.hardalpa);
 
-       pport->cfg.cfg_hardalpa = BFA_TRUE;
-       pport->cfg.hardalpa = alpa;
+       fcport->cfg.cfg_hardalpa = BFA_TRUE;
+       fcport->cfg.hardalpa = alpa;
 
        return BFA_STATUS_OK;
 }
 
 bfa_status_t
-bfa_pport_clr_hardalpa(struct bfa_s *bfa)
+bfa_fcport_clr_hardalpa(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       bfa_trc(bfa, pport->cfg.cfg_hardalpa);
-       bfa_trc(bfa, pport->cfg.hardalpa);
+       bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
+       bfa_trc(bfa, fcport->cfg.hardalpa);
 
-       pport->cfg.cfg_hardalpa = BFA_FALSE;
+       fcport->cfg.cfg_hardalpa = BFA_FALSE;
        return BFA_STATUS_OK;
 }
 
 bfa_boolean_t
-bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
+bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       *alpa = port->cfg.hardalpa;
-       return port->cfg.cfg_hardalpa;
+       *alpa = fcport->cfg.hardalpa;
+       return fcport->cfg.cfg_hardalpa;
 }
 
 u8
-bfa_pport_get_myalpa(struct bfa_s *bfa)
+bfa_fcport_get_myalpa(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       return port->myalpa;
+       return fcport->myalpa;
 }
 
 bfa_status_t
-bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
+bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, maxfrsize);
-       bfa_trc(bfa, pport->cfg.maxfrsize);
+       bfa_trc(bfa, fcport->cfg.maxfrsize);
 
        /*
         * with in range
@@ -1143,41 +1504,41 @@ bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
        if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1)))
                return BFA_STATUS_INVLD_DFSZ;
 
-       pport->cfg.maxfrsize = maxfrsize;
+       fcport->cfg.maxfrsize = maxfrsize;
        return BFA_STATUS_OK;
 }
 
 u16
-bfa_pport_get_maxfrsize(struct bfa_s *bfa)
+bfa_fcport_get_maxfrsize(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       return port->cfg.maxfrsize;
+       return fcport->cfg.maxfrsize;
 }
 
 u32
-bfa_pport_mypid(struct bfa_s *bfa)
+bfa_fcport_mypid(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       return port->mypid;
+       return fcport->mypid;
 }
 
 u8
-bfa_pport_get_rx_bbcredit(struct bfa_s *bfa)
+bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       return port->cfg.rx_bbcredit;
+       return fcport->cfg.rx_bbcredit;
 }
 
 void
-bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
+bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       port->cfg.tx_bbcredit = (u8) tx_bbcredit;
-       bfa_port_send_txcredit(port);
+       fcport->cfg.tx_bbcredit = (u8) tx_bbcredit;
+       bfa_fcport_send_txcredit(fcport);
 }
 
 /**
@@ -1185,302 +1546,192 @@ bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
  */
 
 wwn_t
-bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
+bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
        if (node)
-               return pport->nwwn;
+               return fcport->nwwn;
        else
-               return pport->pwwn;
+               return fcport->pwwn;
 }
 
 void
-bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
+bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s));
 
-       attr->nwwn = pport->nwwn;
-       attr->pwwn = pport->pwwn;
+       attr->nwwn = fcport->nwwn;
+       attr->pwwn = fcport->pwwn;
 
-       bfa_os_memcpy(&attr->pport_cfg, &pport->cfg,
+       bfa_os_memcpy(&attr->pport_cfg, &fcport->cfg,
                      sizeof(struct bfa_pport_cfg_s));
        /*
         * speed attributes
         */
-       attr->pport_cfg.speed = pport->cfg.speed;
-       attr->speed_supported = pport->speed_sup;
-       attr->speed = pport->speed;
+       attr->pport_cfg.speed = fcport->cfg.speed;
+       attr->speed_supported = fcport->speed_sup;
+       attr->speed = fcport->speed;
        attr->cos_supported = FC_CLASS_3;
 
        /*
         * topology attributes
         */
-       attr->pport_cfg.topology = pport->cfg.topology;
-       attr->topology = pport->topology;
+       attr->pport_cfg.topology = fcport->cfg.topology;
+       attr->topology = fcport->topology;
 
        /*
         * beacon attributes
         */
-       attr->beacon = pport->beacon;
-       attr->link_e2e_beacon = pport->link_e2e_beacon;
-       attr->plog_enabled = bfa_plog_get_setting(pport->bfa->plog);
+       attr->beacon = fcport->beacon;
+       attr->link_e2e_beacon = fcport->link_e2e_beacon;
+       attr->plog_enabled = bfa_plog_get_setting(fcport->bfa->plog);
 
        attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa);
        attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa);
-       attr->port_state = bfa_sm_to_state(hal_pport_sm_table, pport->sm);
-       if (bfa_ioc_is_disabled(&pport->bfa->ioc))
+       attr->port_state = bfa_sm_to_state(hal_pport_sm_table, fcport->sm);
+       if (bfa_ioc_is_disabled(&fcport->bfa->ioc))
                attr->port_state = BFA_PPORT_ST_IOCDIS;
-       else if (bfa_ioc_fw_mismatch(&pport->bfa->ioc))
+       else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc))
                attr->port_state = BFA_PPORT_ST_FWMISMATCH;
 }
 
-static void
-bfa_port_stats_query(void *cbarg)
-{
-       struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
-       bfi_pport_get_stats_req_t *msg;
-
-       msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
-
-       if (!msg) {
-               port->stats_qfull = BFA_TRUE;
-               bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_query,
-                              port);
-               bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
-               return;
-       }
-       port->stats_qfull = BFA_FALSE;
-
-       bfa_os_memset(msg, 0, sizeof(bfi_pport_get_stats_req_t));
-       bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_GET_STATS_REQ,
-                   bfa_lpuid(port->bfa));
-       bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
-
-       return;
-}
-
-static void
-bfa_port_stats_clear(void *cbarg)
-{
-       struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
-       bfi_pport_clear_stats_req_t *msg;
-
-       msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+#define BFA_FCPORT_STATS_TOV   1000
 
-       if (!msg) {
-               port->stats_qfull = BFA_TRUE;
-               bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_clear,
-                              port);
-               bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
-               return;
-       }
-       port->stats_qfull = BFA_FALSE;
-
-       bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_stats_req_t));
-       bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_STATS_REQ,
-                   bfa_lpuid(port->bfa));
-       bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
-       return;
-}
-
-static void
-bfa_port_qos_stats_clear(void *cbarg)
+/**
+ * Fetch port attributes (FCQoS or FCoE).
+ */
+bfa_status_t
+bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
+                   bfa_cb_pport_t cbfn, void *cbarg)
 {
-       struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
-       bfi_pport_clear_qos_stats_req_t *msg;
-
-       msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       if (!msg) {
-               port->stats_qfull = BFA_TRUE;
-               bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_qos_stats_clear,
-                              port);
-               bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
-               return;
+       if (fcport->stats_busy) {
+               bfa_trc(bfa, fcport->stats_busy);
+               return BFA_STATUS_DEVBUSY;
        }
-       port->stats_qfull = BFA_FALSE;
 
-       bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_qos_stats_req_t));
-       bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ,
-                   bfa_lpuid(port->bfa));
-       bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
-       return;
-}
-
-static void
-bfa_pport_stats_swap(union bfa_pport_stats_u *d, union bfa_pport_stats_u *s)
-{
-       u32       *dip = (u32 *) d;
-       u32       *sip = (u32 *) s;
-       int             i;
+       fcport->stats_busy  = BFA_TRUE;
+       fcport->stats_ret   = stats;
+       fcport->stats_cbfn  = cbfn;
+       fcport->stats_cbarg = cbarg;
 
-       /*
-        * Do 64 bit fields swap first
-        */
-       for (i = 0;
-            i <
-            ((sizeof(union bfa_pport_stats_u) -
-              sizeof(struct bfa_qos_stats_s)) / sizeof(u32)); i = i + 2) {
-#ifdef __BIGENDIAN
-               dip[i] = bfa_os_ntohl(sip[i]);
-               dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
-#else
-               dip[i] = bfa_os_ntohl(sip[i + 1]);
-               dip[i + 1] = bfa_os_ntohl(sip[i]);
-#endif
-       }
+       bfa_fcport_send_stats_get(fcport);
 
-       /*
-        * Now swap the 32 bit fields
-        */
-       for (; i < (sizeof(union bfa_pport_stats_u) / sizeof(u32)); ++i)
-               dip[i] = bfa_os_ntohl(sip[i]);
+       bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_get_timeout,
+               fcport, BFA_FCPORT_STATS_TOV);
+       return BFA_STATUS_OK;
 }
 
-static void
-__bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete)
+/**
+ * Reset port statistics (FCQoS or FCoE).
+ */
+bfa_status_t
+bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
 {
-       struct bfa_pport_s *port = cbarg;
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       if (complete) {
-               port->stats_cbfn(port->stats_cbarg, port->stats_status);
-       } else {
-               port->stats_busy = BFA_FALSE;
-               port->stats_status = BFA_STATUS_OK;
+       if (fcport->stats_busy) {
+               bfa_trc(bfa, fcport->stats_busy);
+               return BFA_STATUS_DEVBUSY;
        }
-}
-
-static void
-bfa_port_stats_clr_timeout(void *cbarg)
-{
-       struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
 
-       bfa_trc(port->bfa, port->stats_qfull);
+       fcport->stats_busy = BFA_TRUE;
+       fcport->stats_cbfn = cbfn;
+       fcport->stats_cbarg = cbarg;
 
-       if (port->stats_qfull) {
-               bfa_reqq_wcancel(&port->stats_reqq_wait);
-               port->stats_qfull = BFA_FALSE;
-       }
+       bfa_fcport_send_stats_clear(fcport);
 
-       port->stats_status = BFA_STATUS_ETIMER;
-       bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats_clr, port);
+       bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_clr_timeout,
+                       fcport, BFA_FCPORT_STATS_TOV);
+       return BFA_STATUS_OK;
 }
 
-static void
-__bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete)
+/**
+ * Fetch FCQoS port statistics
+ */
+bfa_status_t
+bfa_fcport_get_qos_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
+       bfa_cb_pport_t cbfn, void *cbarg)
 {
-       struct bfa_pport_s *port = cbarg;
+       /* Meaningful only for FC mode */
+       bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
 
-       if (complete) {
-               if (port->stats_status == BFA_STATUS_OK)
-                       bfa_pport_stats_swap(port->stats_ret, port->stats);
-               port->stats_cbfn(port->stats_cbarg, port->stats_status);
-       } else {
-               port->stats_busy = BFA_FALSE;
-               port->stats_status = BFA_STATUS_OK;
-       }
+       return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
 }
 
-static void
-bfa_port_stats_timeout(void *cbarg)
+/**
+ * Reset FCoE port statistics
+ */
+bfa_status_t
+bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
 {
-       struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
-
-       bfa_trc(port->bfa, port->stats_qfull);
+       /* Meaningful only for FC mode */
+       bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
 
-       if (port->stats_qfull) {
-               bfa_reqq_wcancel(&port->stats_reqq_wait);
-               port->stats_qfull = BFA_FALSE;
-       }
-
-       port->stats_status = BFA_STATUS_ETIMER;
-       bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats, port);
+       return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
 }
 
-#define BFA_PORT_STATS_TOV     1000
-
 /**
- * Fetch port attributes.
+ * Fetch FCQoS port statistics
  */
 bfa_status_t
-bfa_pport_get_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats,
-                   bfa_cb_pport_t cbfn, void *cbarg)
+bfa_fcport_get_fcoe_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
+       bfa_cb_pport_t cbfn, void *cbarg)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
-
-       if (port->stats_busy) {
-               bfa_trc(bfa, port->stats_busy);
-               return BFA_STATUS_DEVBUSY;
-       }
-
-       port->stats_busy = BFA_TRUE;
-       port->stats_ret = stats;
-       port->stats_cbfn = cbfn;
-       port->stats_cbarg = cbarg;
-
-       bfa_port_stats_query(port);
+       /* Meaningful only for FCoE mode */
+       bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
 
-       bfa_timer_start(bfa, &port->timer, bfa_port_stats_timeout, port,
-                       BFA_PORT_STATS_TOV);
-       return BFA_STATUS_OK;
+       return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
 }
 
+/**
+ * Reset FCoE port statistics
+ */
 bfa_status_t
-bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
+bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
-
-       if (port->stats_busy) {
-               bfa_trc(bfa, port->stats_busy);
-               return BFA_STATUS_DEVBUSY;
-       }
-
-       port->stats_busy = BFA_TRUE;
-       port->stats_cbfn = cbfn;
-       port->stats_cbarg = cbarg;
-
-       bfa_port_stats_clear(port);
+       /* Meaningful only for FCoE mode */
+       bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
 
-       bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
-                       BFA_PORT_STATS_TOV);
-       return BFA_STATUS_OK;
+       return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
 }
 
 bfa_status_t
-bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap)
+bfa_fcport_trunk_enable(struct bfa_s *bfa, u8 bitmap)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, bitmap);
-       bfa_trc(bfa, pport->cfg.trunked);
-       bfa_trc(bfa, pport->cfg.trunk_ports);
+       bfa_trc(bfa, fcport->cfg.trunked);
+       bfa_trc(bfa, fcport->cfg.trunk_ports);
 
        if (!bitmap || (bitmap & (bitmap - 1)))
                return BFA_STATUS_EINVAL;
 
-       pport->cfg.trunked = BFA_TRUE;
-       pport->cfg.trunk_ports = bitmap;
+       fcport->cfg.trunked = BFA_TRUE;
+       fcport->cfg.trunk_ports = bitmap;
 
        return BFA_STATUS_OK;
 }
 
 void
-bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
+bfa_fcport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       qos_attr->state = bfa_os_ntohl(pport->qos_attr.state);
-       qos_attr->total_bb_cr = bfa_os_ntohl(pport->qos_attr.total_bb_cr);
+       qos_attr->state = bfa_os_ntohl(fcport->qos_attr.state);
+       qos_attr->total_bb_cr = bfa_os_ntohl(fcport->qos_attr.total_bb_cr);
 }
 
 void
-bfa_pport_qos_get_vc_attr(struct bfa_s *bfa,
+bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
                          struct bfa_qos_vc_attr_s *qos_vc_attr)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
-       struct bfa_qos_vc_attr_s *bfa_vc_attr = &pport->qos_vc_attr;
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+       struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr;
        u32        i = 0;
 
        qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count);
@@ -1502,120 +1753,90 @@ bfa_pport_qos_get_vc_attr(struct bfa_s *bfa,
        }
 }
 
-/**
- * Fetch QoS Stats.
- */
-bfa_status_t
-bfa_pport_get_qos_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats,
-                       bfa_cb_pport_t cbfn, void *cbarg)
-{
-       /*
-        * QoS stats is embedded in port stats
-        */
-       return bfa_pport_get_stats(bfa, stats, cbfn, cbarg);
-}
-
-bfa_status_t
-bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
-{
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
-
-       if (port->stats_busy) {
-               bfa_trc(bfa, port->stats_busy);
-               return BFA_STATUS_DEVBUSY;
-       }
-
-       port->stats_busy = BFA_TRUE;
-       port->stats_cbfn = cbfn;
-       port->stats_cbarg = cbarg;
-
-       bfa_port_qos_stats_clear(port);
-
-       bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
-                       BFA_PORT_STATS_TOV);
-       return BFA_STATUS_OK;
-}
-
 /**
  * Fetch port attributes.
  */
 bfa_status_t
-bfa_pport_trunk_disable(struct bfa_s *bfa)
+bfa_fcport_trunk_disable(struct bfa_s *bfa)
 {
        return BFA_STATUS_OK;
 }
 
 bfa_boolean_t
-bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap)
+bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       *bitmap = port->cfg.trunk_ports;
-       return port->cfg.trunked;
+       *bitmap = fcport->cfg.trunk_ports;
+       return fcport->cfg.trunked;
 }
 
 bfa_boolean_t
-bfa_pport_is_disabled(struct bfa_s *bfa)
+bfa_fcport_is_disabled(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       return bfa_sm_to_state(hal_pport_sm_table, port->sm) ==
+       return bfa_sm_to_state(hal_pport_sm_table, fcport->sm) ==
                BFA_PPORT_ST_DISABLED;
 
 }
 
 bfa_boolean_t
-bfa_pport_is_ratelim(struct bfa_s *bfa)
+bfa_fcport_is_ratelim(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       return pport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
+       return fcport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
 
 }
 
 void
-bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
+bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+       enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa);
 
        bfa_trc(bfa, on_off);
-       bfa_trc(bfa, pport->cfg.qos_enabled);
+       bfa_trc(bfa, fcport->cfg.qos_enabled);
+
+       bfa_trc(bfa, ioc_type);
 
-       pport->cfg.qos_enabled = on_off;
+       if (ioc_type == BFA_IOC_TYPE_FC)
+               fcport->cfg.qos_enabled = on_off;
 }
 
 void
-bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
+bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, on_off);
-       bfa_trc(bfa, pport->cfg.ratelimit);
+       bfa_trc(bfa, fcport->cfg.ratelimit);
 
-       pport->cfg.ratelimit = on_off;
-       if (pport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN)
-               pport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS;
+       fcport->cfg.ratelimit = on_off;
+       if (fcport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN)
+               fcport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS;
 }
 
 /**
  * Configure default minimum ratelim speed
  */
 bfa_status_t
-bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
+bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, speed);
 
        /*
         * Auto and speeds greater than the supported speed, are invalid
         */
-       if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > pport->speed_sup)) {
-               bfa_trc(bfa, pport->speed_sup);
+       if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > fcport->speed_sup)) {
+               bfa_trc(bfa, fcport->speed_sup);
                return BFA_STATUS_UNSUPP_SPEED;
        }
 
-       pport->cfg.trl_def_speed = speed;
+       fcport->cfg.trl_def_speed = speed;
 
        return BFA_STATUS_OK;
 }
@@ -1624,45 +1845,45 @@ bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
  * Get default minimum ratelim speed
  */
 enum bfa_pport_speed
-bfa_pport_get_ratelim_speed(struct bfa_s *bfa)
+bfa_fcport_get_ratelim_speed(struct bfa_s *bfa)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       bfa_trc(bfa, pport->cfg.trl_def_speed);
-       return pport->cfg.trl_def_speed;
+       bfa_trc(bfa, fcport->cfg.trl_def_speed);
+       return fcport->cfg.trl_def_speed;
 
 }
 
 void
-bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status)
+bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, status);
-       bfa_trc(bfa, pport->diag_busy);
+       bfa_trc(bfa, fcport->diag_busy);
 
-       pport->diag_busy = status;
+       fcport->diag_busy = status;
 }
 
 void
-bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
+bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
                 bfa_boolean_t link_e2e_beacon)
 {
-       struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        bfa_trc(bfa, beacon);
        bfa_trc(bfa, link_e2e_beacon);
-       bfa_trc(bfa, pport->beacon);
-       bfa_trc(bfa, pport->link_e2e_beacon);
+       bfa_trc(bfa, fcport->beacon);
+       bfa_trc(bfa, fcport->link_e2e_beacon);
 
-       pport->beacon = beacon;
-       pport->link_e2e_beacon = link_e2e_beacon;
+       fcport->beacon = beacon;
+       fcport->link_e2e_beacon = link_e2e_beacon;
 }
 
 bfa_boolean_t
-bfa_pport_is_linkup(struct bfa_s *bfa)
+bfa_fcport_is_linkup(struct bfa_s *bfa)
 {
-       return bfa_sm_cmp_state(BFA_PORT_MOD(bfa), bfa_pport_sm_linkup);
+       return bfa_sm_cmp_state(BFA_FCPORT_MOD(bfa), bfa_fcport_sm_linkup);
 }
 
 
index 7cb39a306ea98bf38bc3d18a44a0ac55537f42d4..3516172c597c9f43633df2459bdfdd472589c72a 100644 (file)
@@ -36,6 +36,7 @@
  * FCS sub-modules
  */
 struct bfa_fcs_mod_s {
+       void            (*attach) (struct bfa_fcs_s *fcs);
        void            (*modinit) (struct bfa_fcs_s *fcs);
        void            (*modexit) (struct bfa_fcs_s *fcs);
 };
@@ -43,12 +44,10 @@ struct bfa_fcs_mod_s {
 #define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit }
 
 static struct bfa_fcs_mod_s fcs_modules[] = {
-       BFA_FCS_MODULE(bfa_fcs_pport),
-       BFA_FCS_MODULE(bfa_fcs_uf),
-       BFA_FCS_MODULE(bfa_fcs_fabric),
-       BFA_FCS_MODULE(bfa_fcs_vport),
-       BFA_FCS_MODULE(bfa_fcs_rport),
-       BFA_FCS_MODULE(bfa_fcs_fcpim),
+       { bfa_fcs_pport_attach, NULL, NULL },
+       { bfa_fcs_uf_attach, NULL, NULL },
+       { bfa_fcs_fabric_attach, bfa_fcs_fabric_modinit,
+        bfa_fcs_fabric_modexit },
 };
 
 /**
@@ -71,16 +70,10 @@ bfa_fcs_exit_comp(void *fcs_cbarg)
  */
 
 /**
- *             FCS instance initialization.
- *
- *     param[in]               fcs             FCS instance
- *     param[in]               bfa             BFA instance
- *     param[in]               bfad            BFA driver instance
- *
- *     return None
+ * fcs attach -- called once to initialize data structures at driver attach time
  */
 void
-bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
+bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
                        bfa_boolean_t min_cfg)
 {
        int             i;
@@ -95,7 +88,24 @@ bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
 
        for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
                mod = &fcs_modules[i];
-               mod->modinit(fcs);
+               if (mod->attach)
+                       mod->attach(fcs);
+       }
+}
+
+/**
+ * fcs initialization, called once after bfa initialization is complete
+ */
+void
+bfa_fcs_init(struct bfa_fcs_s *fcs)
+{
+       int             i;
+       struct bfa_fcs_mod_s  *mod;
+
+       for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
+               mod = &fcs_modules[i];
+               if (mod->modinit)
+                       mod->modinit(fcs);
        }
 }
 
@@ -126,6 +136,23 @@ bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
        bfa_fcs_fabric_psymb_init(&fcs->fabric);
 }
 
+/**
+ *      @brief
+ *              FCS FDMI Driver Parameter Initialization
+ *
+ *      @param[in]              fcs             FCS instance
+ *      @param[in]              fdmi_enable     TRUE/FALSE
+ *
+ *      @return None
+ */
+void
+bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable)
+{
+
+       fcs->fdmi_enabled = fdmi_enable;
+
+}
+
 /**
  *             FCS instance cleanup and exit.
  *
@@ -143,10 +170,12 @@ bfa_fcs_exit(struct bfa_fcs_s *fcs)
        nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]);
 
        for (i = 0; i < nmods; i++) {
-               bfa_wc_up(&fcs->wc);
 
                mod = &fcs_modules[i];
-               mod->modexit(fcs);
+               if (mod->modexit) {
+                       bfa_wc_up(&fcs->wc);
+                       mod->modexit(fcs);
+               }
        }
 
        bfa_wc_wait(&fcs->wc);
index c7ab257f10a76d4284cdf1640089ecda6cf87cce..7c1251c682d8e4ecb1cafaf7af421010ea796446 100644 (file)
@@ -114,7 +114,7 @@ bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -136,7 +136,7 @@ bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port, enum bfa_fcs_port_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -176,7 +176,7 @@ bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -214,7 +214,7 @@ bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -234,7 +234,7 @@ bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -263,30 +263,8 @@ bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port,
 
        bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
 
-       switch (event) {
-       case BFA_LPORT_AEN_ONLINE:
-               bfa_log(logmod, BFA_AEN_LPORT_ONLINE, lpwwn_ptr,
-                       role_str[role / 2]);
-               break;
-       case BFA_LPORT_AEN_OFFLINE:
-               bfa_log(logmod, BFA_AEN_LPORT_OFFLINE, lpwwn_ptr,
-                       role_str[role / 2]);
-               break;
-       case BFA_LPORT_AEN_NEW:
-               bfa_log(logmod, BFA_AEN_LPORT_NEW, lpwwn_ptr,
-                       role_str[role / 2]);
-               break;
-       case BFA_LPORT_AEN_DELETE:
-               bfa_log(logmod, BFA_AEN_LPORT_DELETE, lpwwn_ptr,
-                       role_str[role / 2]);
-               break;
-       case BFA_LPORT_AEN_DISCONNECT:
-               bfa_log(logmod, BFA_AEN_LPORT_DISCONNECT, lpwwn_ptr,
-                       role_str[role / 2]);
-               break;
-       default:
-               break;
-       }
+       bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr,
+               role_str[role/2]);
 
        aen_data.lport.vf_id = port->fabric->vf_id;
        aen_data.lport.roles = role;
@@ -873,36 +851,46 @@ bfa_fcs_port_is_online(struct bfa_fcs_port_s *port)
 }
 
 /**
- * Logical port initialization of base or virtual port.
- * Called by fabric for base port or by vport for virtual ports.
+ * Attach time initialization of logical ports.
  */
 void
-bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
-                  u16 vf_id, struct bfa_port_cfg_s *port_cfg,
-                  struct bfa_fcs_vport_s *vport)
+bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
+               uint16_t vf_id, struct bfa_fcs_vport_s *vport)
 {
        lport->fcs = fcs;
        lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
-       bfa_os_assign(lport->port_cfg, *port_cfg);
        lport->vport = vport;
        lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) :
                         bfa_lps_get_tag(lport->fabric->lps);
 
        INIT_LIST_HEAD(&lport->rport_q);
        lport->num_rports = 0;
+}
+
+/**
+ * Logical port initialization of base or virtual port.
+ * Called by fabric for base port or by vport for virtual ports.
+ */
 
-       lport->bfad_port =
-               bfa_fcb_port_new(fcs->bfad, lport, lport->port_cfg.roles,
+void
+bfa_fcs_lport_init(struct bfa_fcs_port_s *lport,
+               struct bfa_port_cfg_s *port_cfg)
+{
+       struct bfa_fcs_vport_s *vport = lport->vport;
+
+       bfa_os_assign(lport->port_cfg, *port_cfg);
+
+       lport->bfad_port = bfa_fcb_port_new(lport->fcs->bfad, lport,
+                               lport->port_cfg.roles,
                                lport->fabric->vf_drv,
                                vport ? vport->vport_drv : NULL);
+
        bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW);
 
        bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit);
        bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
 }
 
-
-
 /**
  *  fcs_lport_api
  */
@@ -921,13 +909,20 @@ bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port,
        if (port->fabric) {
                port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric);
                port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric);
+               port_attr->authfail =
+                               bfa_fcs_fabric_is_auth_failed(port->fabric);
                port_attr->fabric_name = bfa_fcs_port_get_fabric_name(port);
                memcpy(port_attr->fabric_ip_addr,
                       bfa_fcs_port_get_fabric_ipaddr(port),
                       BFA_FCS_FABRIC_IPADDR_SZ);
 
-               if (port->vport != NULL)
+               if (port->vport != NULL) {
                        port_attr->port_type = BFA_PPORT_TYPE_VPORT;
+                       port_attr->fpma_mac =
+                               bfa_lps_get_lp_mac(port->vport->lps);
+               } else
+                       port_attr->fpma_mac =
+                               bfa_lps_get_lp_mac(port->fabric->lps);
 
        } else {
                port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN;
index 9c4b24e62de1427ff4ed38afd7d27ee8eda153f9..3c27788cd527f6b0e639f14e12351d22988cc22e 100644 (file)
@@ -55,14 +55,7 @@ bfa_fcs_pport_event_handler(void *cbarg, bfa_pport_event_t event)
 }
 
 void
-bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs)
+bfa_fcs_pport_attach(struct bfa_fcs_s *fcs)
 {
-       bfa_pport_event_register(fcs->bfa, bfa_fcs_pport_event_handler,
-                                    fcs);
-}
-
-void
-bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs)
-{
-       bfa_fcs_modexit_comp(fcs);
+       bfa_fcport_event_register(fcs->bfa, bfa_fcs_pport_event_handler, fcs);
 }
index ad01db6444b2031e98e86c898776ae70e2d65bde..3d57d48bbae4ee0123f3603a7b1ff4a297112e75 100644 (file)
@@ -93,13 +93,7 @@ bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
 }
 
 void
-bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs)
+bfa_fcs_uf_attach(struct bfa_fcs_s *fcs)
 {
        bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs);
 }
-
-void
-bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs)
-{
-       bfa_fcs_modexit_comp(fcs);
-}
index ede1438619e2d0394cb755731d75b0fddb101e1f..871a4e28575c9781b8504d5a59e771e5d9dd31ec 100644 (file)
@@ -52,6 +52,18 @@ bfa_hwcb_reginit(struct bfa_s *bfa)
        }
 }
 
+void
+bfa_hwcb_reqq_ack(struct bfa_s *bfa, int reqq)
+{
+}
+
+static void
+bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq)
+{
+       bfa_reg_write(bfa->iocfc.bfa_regs.intr_status,
+               __HFN_INT_CPE_Q0 << CPE_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), reqq));
+}
+
 void
 bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq)
 {
@@ -136,6 +148,7 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
 void
 bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
 {
+       bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix;
        bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
 }
 
index 51ae5740e6e99be8c50c6c9eb44960943651de99..76ceb9a4bf2fab7eb062525538db3aa5786de7cc 100644 (file)
@@ -84,6 +84,15 @@ bfa_hwct_reginit(struct bfa_s *bfa)
        }
 }
 
+void
+bfa_hwct_reqq_ack(struct bfa_s *bfa, int reqq)
+{
+       u32 r32;
+
+       r32 = bfa_reg_read(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]);
+       bfa_reg_write(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq], r32);
+}
+
 void
 bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq)
 {
index b36540e4ed76c35df1cc3e524a7516c1bdc7bfad..0eba3f930d5b8fb5c9906921454b3bbff95f449b 100644 (file)
@@ -15,7 +15,7 @@
  * General Public License for more details.
  */
 #include <bfa.h>
-#include <bfi/bfi_cbreg.h>
+#include <bfi/bfi_ctreg.h>
 #include <bfa_port_priv.h>
 #include <bfa_intr_priv.h>
 #include <cs/bfa_debug.h>
@@ -34,6 +34,26 @@ bfa_msix_lpu(struct bfa_s *bfa)
        bfa_ioc_mbox_isr(&bfa->ioc);
 }
 
+static void
+bfa_reqq_resume(struct bfa_s *bfa, int qid)
+{
+       struct list_head *waitq, *qe, *qen;
+       struct bfa_reqq_wait_s *wqe;
+
+       waitq = bfa_reqq(bfa, qid);
+       list_for_each_safe(qe, qen, waitq) {
+               /**
+                * Callback only as long as there is room in request queue
+                */
+               if (bfa_reqq_full(bfa, qid))
+                       break;
+
+               list_del(qe);
+               wqe = (struct bfa_reqq_wait_s *) qe;
+               wqe->qresume(wqe->cbarg);
+       }
+}
+
 void
 bfa_msix_all(struct bfa_s *bfa, int vec)
 {
@@ -96,7 +116,8 @@ bfa_isr_enable(struct bfa_s *bfa)
 
        bfa_msix_install(bfa);
        intr_unmask = (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
-                      __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS);
+                      __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS |
+                      __HFN_INT_LL_HALT);
 
        if (pci_func == 0)
                intr_unmask |= (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 |
@@ -127,23 +148,18 @@ bfa_isr_disable(struct bfa_s *bfa)
 void
 bfa_msix_reqq(struct bfa_s *bfa, int qid)
 {
-       struct list_head                *waitq, *qe, *qen;
-       struct bfa_reqq_wait_s  *wqe;
+       struct list_head *waitq;
 
        qid &= (BFI_IOC_MAX_CQS - 1);
 
-       waitq = bfa_reqq(bfa, qid);
-       list_for_each_safe(qe, qen, waitq) {
-               /**
-                * Callback only as long as there is room in request queue
-                */
-               if (bfa_reqq_full(bfa, qid))
-                       break;
+       bfa->iocfc.hwif.hw_reqq_ack(bfa, qid);
 
-               list_del(qe);
-               wqe = (struct bfa_reqq_wait_s *) qe;
-               wqe->qresume(wqe->cbarg);
-       }
+       /**
+        * Resume any pending requests in the corresponding reqq.
+        */
+       waitq = bfa_reqq(bfa, qid);
+       if (!list_empty(waitq))
+               bfa_reqq_resume(bfa, qid);
 }
 
 void
@@ -157,26 +173,27 @@ bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m)
 }
 
 void
-bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid)
+bfa_msix_rspq(struct bfa_s *bfa, int qid)
 {
-       struct bfi_msg_s      *m;
-       u32        pi, ci;
+       struct bfi_msg_s *m;
+       u32 pi, ci;
+       struct list_head *waitq;
 
-       bfa_trc_fp(bfa, rsp_qid);
+       bfa_trc_fp(bfa, qid);
 
-       rsp_qid &= (BFI_IOC_MAX_CQS - 1);
+       qid &= (BFI_IOC_MAX_CQS - 1);
 
-       bfa->iocfc.hwif.hw_rspq_ack(bfa, rsp_qid);
+       bfa->iocfc.hwif.hw_rspq_ack(bfa, qid);
 
-       ci = bfa_rspq_ci(bfa, rsp_qid);
-       pi = bfa_rspq_pi(bfa, rsp_qid);
+       ci = bfa_rspq_ci(bfa, qid);
+       pi = bfa_rspq_pi(bfa, qid);
 
        bfa_trc_fp(bfa, ci);
        bfa_trc_fp(bfa, pi);
 
        if (bfa->rme_process) {
                while (ci != pi) {
-                       m = bfa_rspq_elem(bfa, rsp_qid, ci);
+                       m = bfa_rspq_elem(bfa, qid, ci);
                        bfa_assert_fp(m->mhdr.msg_class < BFI_MC_MAX);
 
                        bfa_isrs[m->mhdr.msg_class] (bfa, m);
@@ -188,25 +205,59 @@ bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid)
        /**
         * update CI
         */
-       bfa_rspq_ci(bfa, rsp_qid) = pi;
-       bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[rsp_qid], pi);
+       bfa_rspq_ci(bfa, qid) = pi;
+       bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[qid], pi);
        bfa_os_mmiowb();
+
+       /**
+        * Resume any pending requests in the corresponding reqq.
+        */
+       waitq = bfa_reqq(bfa, qid);
+       if (!list_empty(waitq))
+               bfa_reqq_resume(bfa, qid);
 }
 
 void
 bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
 {
-       u32 intr;
+       u32 intr, curr_value;
 
        intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status);
 
        if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1))
                bfa_msix_lpu(bfa);
 
-       if (intr & (__HFN_INT_ERR_EMC |
-                   __HFN_INT_ERR_LPU0 | __HFN_INT_ERR_LPU1 |
-                   __HFN_INT_ERR_PSS))
+       intr &= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
+               __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT);
+
+       if (intr) {
+               if (intr & __HFN_INT_LL_HALT) {
+                       /**
+                        * If LL_HALT bit is set then FW Init Halt LL Port
+                        * Register needs to be cleared as well so Interrupt
+                        * Status Register will be cleared.
+                        */
+                       curr_value = bfa_reg_read(bfa->ioc.ioc_regs.ll_halt);
+                       curr_value &= ~__FW_INIT_HALT_P;
+                       bfa_reg_write(bfa->ioc.ioc_regs.ll_halt, curr_value);
+               }
+
+               if (intr & __HFN_INT_ERR_PSS) {
+                       /**
+                        * ERR_PSS bit needs to be cleared as well in case
+                        * interrups are shared so driver's interrupt handler is
+                        * still called eventhough it is already masked out.
+                        */
+                       curr_value = bfa_reg_read(
+                               bfa->ioc.ioc_regs.pss_err_status_reg);
+                       curr_value &= __PSS_ERR_STATUS_SET;
+                       bfa_reg_write(bfa->ioc.ioc_regs.pss_err_status_reg,
+                               curr_value);
+               }
+
+               bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, intr);
                bfa_msix_errint(bfa, intr);
+       }
 }
 
 void
index 397d7e9eade5b2be44f443a859ece2fe33c9eab5..e038bc9769f63dc51317909b613fc3bd6791b316 100644 (file)
@@ -18,7 +18,7 @@
 #include <bfa.h>
 #include <bfa_ioc.h>
 #include <bfa_fwimg_priv.h>
-#include <bfa_trcmod_priv.h>
+#include <cna/bfa_cna_trcmod.h>
 #include <cs/bfa_debug.h>
 #include <bfi/bfi_ioc.h>
 #include <bfi/bfi_ctreg.h>
 #include <log/bfa_log_hal.h>
 #include <defs/bfa_defs_pci.h>
 
-BFA_TRC_FILE(HAL, IOC);
+BFA_TRC_FILE(CNA, IOC);
 
 /**
  * IOC local definitions
  */
 #define BFA_IOC_TOV            2000    /* msecs */
-#define BFA_IOC_HB_TOV         1000    /* msecs */
-#define BFA_IOC_HB_FAIL_MAX    4
-#define BFA_IOC_HWINIT_MAX     2
+#define BFA_IOC_HWSEM_TOV       500     /* msecs */
+#define BFA_IOC_HB_TOV          500     /* msecs */
+#define BFA_IOC_HWINIT_MAX      2
 #define BFA_IOC_FWIMG_MINSZ     (16 * 1024)
-#define BFA_IOC_TOV_RECOVER    (BFA_IOC_HB_FAIL_MAX * BFA_IOC_HB_TOV \
-                               + BFA_IOC_TOV)
+#define BFA_IOC_TOV_RECOVER      BFA_IOC_HB_TOV
 
 #define bfa_ioc_timer_start(__ioc)                                     \
        bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer,        \
@@ -51,12 +50,25 @@ BFA_TRC_FILE(HAL, IOC);
         (sizeof(struct bfa_trc_mod_s) -                        \
          BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
 #define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
-#define bfa_ioc_stats(_ioc, _stats)    ((_ioc)->stats._stats++)
 
-#define BFA_FLASH_CHUNK_NO(off)         (off / BFI_FLASH_CHUNK_SZ_WORDS)
-#define BFA_FLASH_OFFSET_IN_CHUNK(off)  (off % BFI_FLASH_CHUNK_SZ_WORDS)
-#define BFA_FLASH_CHUNK_ADDR(chunkno)   (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
-bfa_boolean_t   bfa_auto_recover = BFA_FALSE;
+/**
+ * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details.
+ */
+
+#define bfa_ioc_firmware_lock(__ioc)                    \
+                       ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc))
+#define bfa_ioc_firmware_unlock(__ioc)                  \
+                       ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc))
+#define bfa_ioc_fwimg_get_chunk(__ioc, __off)           \
+                       ((__ioc)->ioc_hwif->ioc_fwimg_get_chunk(__ioc, __off))
+#define bfa_ioc_fwimg_get_size(__ioc)                   \
+                       ((__ioc)->ioc_hwif->ioc_fwimg_get_size(__ioc))
+#define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc))
+#define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc))
+#define bfa_ioc_notify_hbfail(__ioc)                    \
+                       ((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc))
+
+bfa_boolean_t   bfa_auto_recover = BFA_TRUE;
 
 /*
  * forward declarations
@@ -64,7 +76,6 @@ bfa_boolean_t   bfa_auto_recover = BFA_FALSE;
 static void     bfa_ioc_aen_post(struct bfa_ioc_s *bfa,
                                 enum bfa_ioc_aen_event event);
 static void     bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
-static void     bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
 static void     bfa_ioc_timeout(void *ioc);
@@ -77,8 +88,6 @@ static void     bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force);
 static void     bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_recover(struct bfa_ioc_s *ioc);
-static bfa_boolean_t bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc);
-static void     bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
 static void     bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
 
@@ -508,14 +517,19 @@ bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
        bfa_trc(ioc, event);
 
        switch (event) {
-       case IOC_E_HWERROR:
        case IOC_E_FWRSP_DISABLE:
+               bfa_ioc_timer_stop(ioc);
+               bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
+               break;
+
+       case IOC_E_HWERROR:
                bfa_ioc_timer_stop(ioc);
                /*
                 * !!! fall through !!!
                 */
 
        case IOC_E_TIMEOUT:
+               bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL);
                bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
                break;
 
@@ -608,15 +622,12 @@ bfa_ioc_sm_hbfail_entry(struct bfa_ioc_s *ioc)
         * Mark IOC as failed in hardware and stop firmware.
         */
        bfa_ioc_lpu_stop(ioc);
-       bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_HBFAIL);
+       bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL);
 
-       if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
-               bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
-               /*
-                * Wait for halt to take effect
-                */
-               bfa_reg_read(ioc->ioc_regs.ll_halt);
-       }
+       /**
+        * Notify other functions on HB failure.
+        */
+       bfa_ioc_notify_hbfail(ioc);
 
        /**
         * Notify driver and common modules registered for notification.
@@ -672,6 +683,12 @@ bfa_ioc_sm_hbfail(struct bfa_ioc_s *ioc, enum ioc_event event)
                 */
                break;
 
+       case IOC_E_HWERROR:
+               /*
+                * HB failure notification, ignore.
+                */
+               break;
+
        default:
                bfa_sm_fault(ioc, event);
        }
@@ -700,7 +717,7 @@ bfa_ioc_disable_comp(struct bfa_ioc_s *ioc)
        }
 }
 
-static void
+void
 bfa_ioc_sem_timeout(void *ioc_arg)
 {
        struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg;
@@ -708,26 +725,32 @@ bfa_ioc_sem_timeout(void *ioc_arg)
        bfa_ioc_hw_sem_get(ioc);
 }
 
-static void
-bfa_ioc_usage_sem_get(struct bfa_ioc_s *ioc)
+bfa_boolean_t
+bfa_ioc_sem_get(bfa_os_addr_t sem_reg)
 {
-       u32        r32;
-       int             cnt = 0;
-#define BFA_SEM_SPINCNT        1000
+       u32 r32;
+       int cnt = 0;
+#define BFA_SEM_SPINCNT 3000
 
-       do {
-               r32 = bfa_reg_read(ioc->ioc_regs.ioc_usage_sem_reg);
+       r32 = bfa_reg_read(sem_reg);
+
+       while (r32 && (cnt < BFA_SEM_SPINCNT)) {
                cnt++;
-               if (cnt > BFA_SEM_SPINCNT)
-                       break;
-       } while (r32 != 0);
+               bfa_os_udelay(2);
+               r32 = bfa_reg_read(sem_reg);
+       }
+
+       if (r32 == 0)
+               return BFA_TRUE;
+
        bfa_assert(cnt < BFA_SEM_SPINCNT);
+       return BFA_FALSE;
 }
 
-static void
-bfa_ioc_usage_sem_release(struct bfa_ioc_s *ioc)
+void
+bfa_ioc_sem_release(bfa_os_addr_t sem_reg)
 {
-       bfa_reg_write(ioc->ioc_regs.ioc_usage_sem_reg, 1);
+       bfa_reg_write(sem_reg, 1);
 }
 
 static void
@@ -737,7 +760,7 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
 
        /**
         * First read to the semaphore register will return 0, subsequent reads
-        * will return 1. Semaphore is released by writing 0 to the register
+        * will return 1. Semaphore is released by writing 1 to the register
         */
        r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
        if (r32 == 0) {
@@ -746,10 +769,10 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
        }
 
        bfa_timer_begin(ioc->timer_mod, &ioc->sem_timer, bfa_ioc_sem_timeout,
-                       ioc, BFA_IOC_TOV);
+                       ioc, BFA_IOC_HWSEM_TOV);
 }
 
-static void
+void
 bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc)
 {
        bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1);
@@ -828,7 +851,7 @@ bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc)
 /**
  * Get driver and firmware versions.
  */
-static void
+void
 bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
 {
        u32        pgnum, pgoff;
@@ -847,24 +870,10 @@ bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
        }
 }
 
-static u32 *
-bfa_ioc_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
-{
-       if (ioc->ctdev)
-               return bfi_image_ct_get_chunk(off);
-       return bfi_image_cb_get_chunk(off);
-}
-
-static          u32
-bfa_ioc_fwimg_get_size(struct bfa_ioc_s *ioc)
-{
-return (ioc->ctdev) ? bfi_image_ct_size : bfi_image_cb_size;
-}
-
 /**
  * Returns TRUE if same.
  */
-static          bfa_boolean_t
+bfa_boolean_t
 bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
 {
        struct bfi_ioc_image_hdr_s *drv_fwhdr;
@@ -920,95 +929,6 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc)
        return bfa_ioc_fwver_cmp(ioc, &fwhdr);
 }
 
-/**
- * Return true if firmware of current driver matches the running firmware.
- */
-static          bfa_boolean_t
-bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc)
-{
-       enum bfi_ioc_state ioc_fwstate;
-       u32        usecnt;
-       struct bfi_ioc_image_hdr_s fwhdr;
-
-       /**
-        * Firmware match check is relevant only for CNA.
-        */
-       if (!ioc->cna)
-               return BFA_TRUE;
-
-       /**
-        * If bios boot (flash based) -- do not increment usage count
-        */
-       if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
-               return BFA_TRUE;
-
-       bfa_ioc_usage_sem_get(ioc);
-       usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
-
-       /**
-        * If usage count is 0, always return TRUE.
-        */
-       if (usecnt == 0) {
-               bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
-               bfa_ioc_usage_sem_release(ioc);
-               bfa_trc(ioc, usecnt);
-               return BFA_TRUE;
-       }
-
-       ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
-       bfa_trc(ioc, ioc_fwstate);
-
-       /**
-        * Use count cannot be non-zero and chip in uninitialized state.
-        */
-       bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
-
-       /**
-        * Check if another driver with a different firmware is active
-        */
-       bfa_ioc_fwver_get(ioc, &fwhdr);
-       if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
-               bfa_ioc_usage_sem_release(ioc);
-               bfa_trc(ioc, usecnt);
-               return BFA_FALSE;
-       }
-
-       /**
-        * Same firmware version. Increment the reference count.
-        */
-       usecnt++;
-       bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
-       bfa_ioc_usage_sem_release(ioc);
-       bfa_trc(ioc, usecnt);
-       return BFA_TRUE;
-}
-
-static void
-bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc)
-{
-       u32        usecnt;
-
-       /**
-        * Firmware lock is relevant only for CNA.
-        * If bios boot (flash based) -- do not decrement usage count
-        */
-       if (!ioc->cna || (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ))
-               return;
-
-       /**
-        * decrement usage count
-        */
-       bfa_ioc_usage_sem_get(ioc);
-       usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
-       bfa_assert(usecnt > 0);
-
-       usecnt--;
-       bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
-       bfa_trc(ioc, usecnt);
-
-       bfa_ioc_usage_sem_release(ioc);
-}
-
 /**
  * Conditionally flush any pending message from firmware at start.
  */
@@ -1152,33 +1072,27 @@ bfa_ioc_send_getattr(struct bfa_ioc_s *ioc)
 static void
 bfa_ioc_hb_check(void *cbarg)
 {
-       struct bfa_ioc_s *ioc = cbarg;
-       u32        hb_count;
+       struct bfa_ioc_s  *ioc = cbarg;
+       u32     hb_count;
 
        hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
        if (ioc->hb_count == hb_count) {
-               ioc->hb_fail++;
-       } else {
-               ioc->hb_count = hb_count;
-               ioc->hb_fail = 0;
-       }
-
-       if (ioc->hb_fail >= BFA_IOC_HB_FAIL_MAX) {
-               bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE, hb_count);
-               ioc->hb_fail = 0;
+               bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE,
+                       hb_count);
                bfa_ioc_recover(ioc);
                return;
+       } else {
+               ioc->hb_count = hb_count;
        }
 
        bfa_ioc_mbox_poll(ioc);
-       bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
-                       BFA_IOC_HB_TOV);
+       bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check,
+                       ioc, BFA_IOC_HB_TOV);
 }
 
 static void
 bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
 {
-       ioc->hb_fail = 0;
        ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
        bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
                        BFA_IOC_HB_TOV);
@@ -1190,112 +1104,6 @@ bfa_ioc_hb_stop(struct bfa_ioc_s *ioc)
        bfa_timer_stop(&ioc->ioc_timer);
 }
 
-/**
- * Host to LPU mailbox message addresses
- */
-static struct {
-       u32        hfn_mbox, lpu_mbox, hfn_pgn;
-} iocreg_fnreg[] = {
-       {
-       HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0}, {
-       HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1}, {
-       HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2}, {
-       HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3}
-};
-
-/**
- * Host <-> LPU mailbox command/status registers - port 0
- */
-static struct {
-       u32        hfn, lpu;
-} iocreg_mbcmd_p0[] = {
-       {
-       HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT}, {
-       HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT}, {
-       HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT}, {
-       HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT}
-};
-
-/**
- * Host <-> LPU mailbox command/status registers - port 1
- */
-static struct {
-       u32        hfn, lpu;
-} iocreg_mbcmd_p1[] = {
-       {
-       HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT}, {
-       HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT}, {
-       HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT}, {
-       HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT}
-};
-
-/**
- * Shared IRQ handling in INTX mode
- */
-static struct {
-       u32        isr, msk;
-} iocreg_shirq_next[] = {
-       {
-       HOSTFN1_INT_STATUS, HOSTFN1_INT_MSK}, {
-       HOSTFN2_INT_STATUS, HOSTFN2_INT_MSK}, {
-       HOSTFN3_INT_STATUS, HOSTFN3_INT_MSK}, {
-HOSTFN0_INT_STATUS, HOSTFN0_INT_MSK},};
-
-static void
-bfa_ioc_reg_init(struct bfa_ioc_s *ioc)
-{
-       bfa_os_addr_t   rb;
-       int             pcifn = bfa_ioc_pcifn(ioc);
-
-       rb = bfa_ioc_bar0(ioc);
-
-       ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
-       ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
-       ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
-
-       if (ioc->port_id == 0) {
-               ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
-               ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
-               ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
-               ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
-               ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
-       } else {
-               ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
-               ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
-               ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
-               ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
-               ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
-       }
-
-       /**
-        * Shared IRQ handling in INTX mode
-        */
-       ioc->ioc_regs.shirq_isr_next = rb + iocreg_shirq_next[pcifn].isr;
-       ioc->ioc_regs.shirq_msk_next = rb + iocreg_shirq_next[pcifn].msk;
-
-       /*
-        * PSS control registers
-        */
-       ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
-       ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
-       ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
-
-       /*
-        * IOC semaphore registers and serialization
-        */
-       ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
-       ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
-       ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
-
-       /**
-        * sram memory access
-        */
-       ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
-       ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
-       if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT)
-               ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
-}
-
 /**
  *      Initiate a full firmware download.
  */
@@ -1321,9 +1129,6 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
        if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
                boot_type = BFI_BOOT_TYPE_FLASH;
        fwimg = bfa_ioc_fwimg_get_chunk(ioc, chunkno);
-       fwimg[BFI_BOOT_TYPE_OFF / sizeof(u32)] = bfa_os_swap32(boot_type);
-       fwimg[BFI_BOOT_PARAM_OFF / sizeof(u32)] =
-               bfa_os_swap32(boot_param);
 
        pgnum = bfa_ioc_smem_pgnum(ioc, loff);
        pgoff = bfa_ioc_smem_pgoff(ioc, loff);
@@ -1332,17 +1137,17 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
 
        for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) {
 
-               if (BFA_FLASH_CHUNK_NO(i) != chunkno) {
-                       chunkno = BFA_FLASH_CHUNK_NO(i);
+               if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
+                       chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
                        fwimg = bfa_ioc_fwimg_get_chunk(ioc,
-                                       BFA_FLASH_CHUNK_ADDR(chunkno));
+                                       BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
                }
 
                /**
                 * write smem
                 */
                bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
-                             fwimg[BFA_FLASH_OFFSET_IN_CHUNK(i)]);
+                             fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]);
 
                loff += sizeof(u32);
 
@@ -1358,6 +1163,14 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
 
        bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
                      bfa_ioc_smem_pgnum(ioc, 0));
+
+       /*
+        * Set boot type and boot param at the end.
+        */
+       bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_TYPE_OFF,
+                       bfa_os_swap32(boot_type));
+       bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_PARAM_OFF,
+                       bfa_os_swap32(boot_param));
 }
 
 static void
@@ -1439,168 +1252,10 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc)
                bfa_q_deq(&mod->cmd_q, &cmd);
 }
 
-/**
- * Initialize IOC to port mapping.
- */
-
-#define FNC_PERS_FN_SHIFT(__fn)        ((__fn) * 8)
-static void
-bfa_ioc_map_port(struct bfa_ioc_s *ioc)
-{
-       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
-       u32        r32;
-
-       /**
-        * For crossbow, port id is same as pci function.
-        */
-       if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT) {
-               ioc->port_id = bfa_ioc_pcifn(ioc);
-               return;
-       }
-
-       /**
-        * For catapult, base port id on personality register and IOC type
-        */
-       r32 = bfa_reg_read(rb + FNC_PERS_REG);
-       r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
-       ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
-
-       bfa_trc(ioc, bfa_ioc_pcifn(ioc));
-       bfa_trc(ioc, ioc->port_id);
-}
-
-
-
 /**
  *  bfa_ioc_public
  */
 
-/**
-* Set interrupt mode for a function: INTX or MSIX
- */
-void
-bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
-{
-       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
-       u32        r32, mode;
-
-       r32 = bfa_reg_read(rb + FNC_PERS_REG);
-       bfa_trc(ioc, r32);
-
-       mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
-               __F0_INTX_STATUS;
-
-       /**
-        * If already in desired mode, do not change anything
-        */
-       if (!msix && mode)
-               return;
-
-       if (msix)
-               mode = __F0_INTX_STATUS_MSIX;
-       else
-               mode = __F0_INTX_STATUS_INTA;
-
-       r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
-       r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
-       bfa_trc(ioc, r32);
-
-       bfa_reg_write(rb + FNC_PERS_REG, r32);
-}
-
-bfa_status_t
-bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
-{
-       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
-       u32        pll_sclk, pll_fclk, r32;
-
-       if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
-               pll_sclk =
-                       __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
-                       __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) |
-                       __APP_PLL_312_JITLMT0_1(3U) |
-                       __APP_PLL_312_CNTLMT0_1(1U);
-               pll_fclk =
-                       __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
-                       __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) |
-                       __APP_PLL_425_JITLMT0_1(3U) |
-                       __APP_PLL_425_CNTLMT0_1(1U);
-
-               /**
-                *      For catapult, choose operational mode FC/FCoE
-                */
-               if (ioc->fcmode) {
-                       bfa_reg_write((rb + OP_MODE), 0);
-                       bfa_reg_write((rb + ETH_MAC_SER_REG),
-                                     __APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2
-                                     | __APP_EMS_CHANNEL_SEL);
-               } else {
-                       ioc->pllinit = BFA_TRUE;
-                       bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
-                       bfa_reg_write((rb + ETH_MAC_SER_REG),
-                                     __APP_EMS_REFCKBUFEN1);
-               }
-       } else {
-               pll_sclk =
-                       __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
-                       __APP_PLL_312_P0_1(3U) | __APP_PLL_312_JITLMT0_1(3U) |
-                       __APP_PLL_312_CNTLMT0_1(3U);
-               pll_fclk =
-                       __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
-                       __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
-                       __APP_PLL_425_JITLMT0_1(3U) |
-                       __APP_PLL_425_CNTLMT0_1(3U);
-       }
-
-       bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
-       bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
-
-       bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
-
-       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
-                     __APP_PLL_312_LOGIC_SOFT_RESET);
-       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
-                     __APP_PLL_312_BYPASS | __APP_PLL_312_LOGIC_SOFT_RESET);
-       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
-                     __APP_PLL_425_LOGIC_SOFT_RESET);
-       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
-                     __APP_PLL_425_BYPASS | __APP_PLL_425_LOGIC_SOFT_RESET);
-       bfa_os_udelay(2);
-       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
-                     __APP_PLL_312_LOGIC_SOFT_RESET);
-       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
-                     __APP_PLL_425_LOGIC_SOFT_RESET);
-
-       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
-                     pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET);
-       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
-                     pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET);
-
-       /**
-        * Wait for PLLs to lock.
-        */
-       bfa_os_udelay(2000);
-       bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
-
-       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
-       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
-
-       if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
-               bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
-               bfa_os_udelay(1000);
-               r32 = bfa_reg_read((rb + MBIST_STAT_REG));
-               bfa_trc(ioc, r32);
-       }
-
-       return BFA_STATUS_OK;
-}
-
 /**
  * Interface used by diag module to do firmware boot with memory test
  * as the entry vector.
@@ -1642,7 +1297,7 @@ bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param)
 void
 bfa_ioc_auto_recover(bfa_boolean_t auto_recover)
 {
-       bfa_auto_recover = BFA_FALSE;
+       bfa_auto_recover = auto_recover;
 }
 
 
@@ -1764,6 +1419,14 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
        ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT);
        ioc->cna = ioc->ctdev && !ioc->fcmode;
 
+       /**
+        * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c
+        */
+       if (ioc->ctdev)
+               bfa_ioc_set_ct_hwif(ioc);
+       else
+               bfa_ioc_set_cb_hwif(ioc);
+
        bfa_ioc_map_port(ioc);
        bfa_ioc_reg_init(ioc);
 }
@@ -1830,7 +1493,6 @@ return (auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
 void
 bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave)
 {
-       bfa_assert(ioc->auto_recover);
        ioc->dbg_fwsave = dbg_fwsave;
        ioc->dbg_fwsave_len = bfa_ioc_debug_trcsz(ioc->auto_recover);
 }
@@ -1973,7 +1635,7 @@ bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
         ((__sm) == BFI_IOC_INITING) ||         \
         ((__sm) == BFI_IOC_HWINIT) ||          \
         ((__sm) == BFI_IOC_DISABLED) ||        \
-        ((__sm) == BFI_IOC_HBFAIL) ||          \
+        ((__sm) == BFI_IOC_FAIL) ||            \
         ((__sm) == BFI_IOC_CFG_DISABLED))
 
 /**
@@ -2017,46 +1679,28 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
                         struct bfa_adapter_attr_s *ad_attr)
 {
        struct bfi_ioc_attr_s *ioc_attr;
-       char            model[BFA_ADAPTER_MODEL_NAME_LEN];
 
        ioc_attr = ioc->attr;
-       bfa_os_memcpy((void *)&ad_attr->serial_num,
-                     (void *)ioc_attr->brcd_serialnum,
-                     BFA_ADAPTER_SERIAL_NUM_LEN);
-
-       bfa_os_memcpy(&ad_attr->fw_ver, ioc_attr->fw_version, BFA_VERSION_LEN);
-       bfa_os_memcpy(&ad_attr->optrom_ver, ioc_attr->optrom_version,
-                     BFA_VERSION_LEN);
-       bfa_os_memcpy(&ad_attr->manufacturer, BFA_MFG_NAME,
-                     BFA_ADAPTER_MFG_NAME_LEN);
+
+       bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num);
+       bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver);
+       bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver);
+       bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer);
        bfa_os_memcpy(&ad_attr->vpd, &ioc_attr->vpd,
                      sizeof(struct bfa_mfg_vpd_s));
 
-       ad_attr->nports = BFI_ADAPTER_GETP(NPORTS, ioc_attr->adapter_prop);
-       ad_attr->max_speed = BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
+       ad_attr->nports = bfa_ioc_get_nports(ioc);
+       ad_attr->max_speed = bfa_ioc_speed_sup(ioc);
 
-       /**
-        * model name
-        */
-       if (BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop) == 10) {
-               strcpy(model, "BR-10?0");
-               model[5] = '0' + ad_attr->nports;
-       } else {
-               strcpy(model, "Brocade-??5");
-               model[8] =
-                       '0' + BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
-               model[9] = '0' + ad_attr->nports;
-       }
+       bfa_ioc_get_adapter_model(ioc, ad_attr->model);
+       /* For now, model descr uses same model string */
+       bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr);
 
        if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
                ad_attr->prototype = 1;
        else
                ad_attr->prototype = 0;
 
-       bfa_os_memcpy(&ad_attr->model, model, BFA_ADAPTER_MODEL_NAME_LEN);
-       bfa_os_memcpy(&ad_attr->model_descr, &ad_attr->model,
-                     BFA_ADAPTER_MODEL_NAME_LEN);
-
        ad_attr->pwwn = bfa_ioc_get_pwwn(ioc);
        ad_attr->mac = bfa_ioc_get_mac(ioc);
 
@@ -2064,41 +1708,122 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
        ad_attr->pcie_lanes = ioc_attr->pcie_lanes;
        ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig;
        ad_attr->asic_rev = ioc_attr->asic_rev;
-       ad_attr->hw_ver[0] = 'R';
-       ad_attr->hw_ver[1] = 'e';
-       ad_attr->hw_ver[2] = 'v';
-       ad_attr->hw_ver[3] = '-';
-       ad_attr->hw_ver[4] = ioc_attr->asic_rev;
-       ad_attr->hw_ver[5] = '\0';
+
+       bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver);
 
        ad_attr->cna_capable = ioc->cna;
 }
 
+enum bfa_ioc_type_e
+bfa_ioc_get_type(struct bfa_ioc_s *ioc)
+{
+       if (!ioc->ctdev || ioc->fcmode)
+               return BFA_IOC_TYPE_FC;
+       else if (ioc->ioc_mc == BFI_MC_IOCFC)
+               return BFA_IOC_TYPE_FCoE;
+       else if (ioc->ioc_mc == BFI_MC_LL)
+               return BFA_IOC_TYPE_LL;
+       else {
+               bfa_assert(ioc->ioc_mc == BFI_MC_LL);
+               return BFA_IOC_TYPE_LL;
+       }
+}
+
+void
+bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num)
+{
+       bfa_os_memset((void *)serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN);
+       bfa_os_memcpy((void *)serial_num,
+                       (void *)ioc->attr->brcd_serialnum,
+                       BFA_ADAPTER_SERIAL_NUM_LEN);
+}
+
+void
+bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver)
+{
+       bfa_os_memset((void *)fw_ver, 0, BFA_VERSION_LEN);
+       bfa_os_memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN);
+}
+
+void
+bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev)
+{
+       bfa_assert(chip_rev);
+
+       bfa_os_memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN);
+
+       chip_rev[0] = 'R';
+       chip_rev[1] = 'e';
+       chip_rev[2] = 'v';
+       chip_rev[3] = '-';
+       chip_rev[4] = ioc->attr->asic_rev;
+       chip_rev[5] = '\0';
+}
+
+void
+bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver)
+{
+       bfa_os_memset((void *)optrom_ver, 0, BFA_VERSION_LEN);
+       bfa_os_memcpy(optrom_ver, ioc->attr->optrom_version,
+               BFA_VERSION_LEN);
+}
+
+void
+bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer)
+{
+       bfa_os_memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN);
+       bfa_os_memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
+}
+
+void
+bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model)
+{
+       struct bfi_ioc_attr_s   *ioc_attr;
+       u8              nports;
+       u8              max_speed;
+
+       bfa_assert(model);
+       bfa_os_memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
+
+       ioc_attr = ioc->attr;
+
+       nports = bfa_ioc_get_nports(ioc);
+       max_speed = bfa_ioc_speed_sup(ioc);
+
+       /**
+        * model name
+        */
+       if (max_speed == 10) {
+               strcpy(model, "BR-10?0");
+               model[5] = '0' + nports;
+       } else {
+               strcpy(model, "Brocade-??5");
+               model[8] = '0' + max_speed;
+               model[9] = '0' + nports;
+       }
+}
+
+enum bfa_ioc_state
+bfa_ioc_get_state(struct bfa_ioc_s *ioc)
+{
+       return bfa_sm_to_state(ioc_sm_table, ioc->fsm);
+}
+
 void
 bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
 {
        bfa_os_memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s));
 
-       ioc_attr->state = bfa_sm_to_state(ioc_sm_table, ioc->fsm);
+       ioc_attr->state = bfa_ioc_get_state(ioc);
        ioc_attr->port_id = ioc->port_id;
 
-       if (!ioc->ctdev)
-               ioc_attr->ioc_type = BFA_IOC_TYPE_FC;
-       else if (ioc->ioc_mc == BFI_MC_IOCFC)
-               ioc_attr->ioc_type = BFA_IOC_TYPE_FCoE;
-       else if (ioc->ioc_mc == BFI_MC_LL)
-               ioc_attr->ioc_type = BFA_IOC_TYPE_LL;
+       ioc_attr->ioc_type = bfa_ioc_get_type(ioc);
 
        bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
 
        ioc_attr->pci_attr.device_id = ioc->pcidev.device_id;
        ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func;
-       ioc_attr->pci_attr.chip_rev[0] = 'R';
-       ioc_attr->pci_attr.chip_rev[1] = 'e';
-       ioc_attr->pci_attr.chip_rev[2] = 'v';
-       ioc_attr->pci_attr.chip_rev[3] = '-';
-       ioc_attr->pci_attr.chip_rev[4] = ioc_attr->adapter_attr.asic_rev;
-       ioc_attr->pci_attr.chip_rev[5] = '\0';
+       bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
 }
 
 /**
@@ -2194,29 +1919,6 @@ bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc)
        return ioc->fcmode || (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT);
 }
 
-/**
- * Return true if interrupt should be claimed.
- */
-bfa_boolean_t
-bfa_ioc_intx_claim(struct bfa_ioc_s *ioc)
-{
-       u32        isr, msk;
-
-       /**
-        * Always claim if not catapult.
-        */
-       if (!ioc->ctdev)
-               return BFA_TRUE;
-
-       /**
-        * FALSE if next device is claiming interrupt.
-        * TRUE if next device is not interrupting or not present.
-        */
-       msk = bfa_reg_read(ioc->ioc_regs.shirq_msk_next);
-       isr = bfa_reg_read(ioc->ioc_regs.shirq_isr_next);
-       return !(isr & ~msk);
-}
-
 /**
  * Send AEN notification
  */
@@ -2226,32 +1928,14 @@ bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
        union bfa_aen_data_u aen_data;
        struct bfa_log_mod_s *logmod = ioc->logm;
        s32         inst_num = 0;
-       struct bfa_ioc_attr_s ioc_attr;
+       enum bfa_ioc_type_e ioc_type;
 
-       switch (event) {
-       case BFA_IOC_AEN_HBGOOD:
-               bfa_log(logmod, BFA_AEN_IOC_HBGOOD, inst_num);
-               break;
-       case BFA_IOC_AEN_HBFAIL:
-               bfa_log(logmod, BFA_AEN_IOC_HBFAIL, inst_num);
-               break;
-       case BFA_IOC_AEN_ENABLE:
-               bfa_log(logmod, BFA_AEN_IOC_ENABLE, inst_num);
-               break;
-       case BFA_IOC_AEN_DISABLE:
-               bfa_log(logmod, BFA_AEN_IOC_DISABLE, inst_num);
-               break;
-       case BFA_IOC_AEN_FWMISMATCH:
-               bfa_log(logmod, BFA_AEN_IOC_FWMISMATCH, inst_num);
-               break;
-       default:
-               break;
-       }
+       bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, event), inst_num);
 
        memset(&aen_data.ioc.pwwn, 0, sizeof(aen_data.ioc.pwwn));
        memset(&aen_data.ioc.mac, 0, sizeof(aen_data.ioc.mac));
-       bfa_ioc_get_attr(ioc, &ioc_attr);
-       switch (ioc_attr.ioc_type) {
+       ioc_type = bfa_ioc_get_type(ioc);
+       switch (ioc_type) {
        case BFA_IOC_TYPE_FC:
                aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc);
                break;
@@ -2263,10 +1947,10 @@ bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
                aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
                break;
        default:
-               bfa_assert(ioc_attr.ioc_type == BFA_IOC_TYPE_FC);
+               bfa_assert(ioc_type == BFA_IOC_TYPE_FC);
                break;
        }
-       aen_data.ioc.ioc_type = ioc_attr.ioc_type;
+       aen_data.ioc.ioc_type = ioc_type;
 }
 
 /**
@@ -2289,6 +1973,15 @@ bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
        return BFA_STATUS_OK;
 }
 
+/**
+ * Clear saved firmware trace
+ */
+void
+bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc)
+{
+       ioc->dbg_fwsave_once = BFA_TRUE;
+}
+
 /**
  * Retrieve saved firmware trace from a prior IOC failure.
  */
@@ -2304,6 +1997,13 @@ bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
 
        pgnum = bfa_ioc_smem_pgnum(ioc, loff);
        loff = bfa_ioc_smem_pgoff(ioc, loff);
+
+       /*
+        *  Hold semaphore to serialize pll init and fwtrc.
+        */
+       if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg))
+               return BFA_STATUS_FAILED;
+
        bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
 
        tlen = *trclen;
@@ -2329,6 +2029,12 @@ bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
        }
        bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
                      bfa_ioc_smem_pgnum(ioc, 0));
+
+       /*
+        *  release semaphore.
+        */
+       bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+
        bfa_trc(ioc, pgnum);
 
        *trclen = tlen * sizeof(u32);
index 7c30f05ab137c44804ebf38dc26fb03d58501028..d0804406ea1a318c115e1f5ccb6983a9dca58c71 100644 (file)
@@ -74,15 +74,18 @@ struct bfa_ioc_regs_s {
        bfa_os_addr_t   lpu_mbox_cmd;
        bfa_os_addr_t   lpu_mbox;
        bfa_os_addr_t   pss_ctl_reg;
+       bfa_os_addr_t   pss_err_status_reg;
        bfa_os_addr_t   app_pll_fast_ctl_reg;
        bfa_os_addr_t   app_pll_slow_ctl_reg;
        bfa_os_addr_t   ioc_sem_reg;
        bfa_os_addr_t   ioc_usage_sem_reg;
+       bfa_os_addr_t   ioc_init_sem_reg;
        bfa_os_addr_t   ioc_usage_reg;
        bfa_os_addr_t   host_page_num_fn;
        bfa_os_addr_t   heartbeat;
        bfa_os_addr_t   ioc_fwstate;
        bfa_os_addr_t   ll_halt;
+       bfa_os_addr_t   err_set;
        bfa_os_addr_t   shirq_isr_next;
        bfa_os_addr_t   shirq_msk_next;
        bfa_os_addr_t   smem_page_start;
@@ -154,7 +157,6 @@ struct bfa_ioc_s {
        struct bfa_timer_s      ioc_timer;
        struct bfa_timer_s      sem_timer;
        u32             hb_count;
-       u32             hb_fail;
        u32             retry_count;
        struct list_head                hb_notify_q;
        void                    *dbg_fwsave;
@@ -177,6 +179,22 @@ struct bfa_ioc_s {
        struct bfi_ioc_attr_s   *attr;
        struct bfa_ioc_cbfn_s   *cbfn;
        struct bfa_ioc_mbox_mod_s mbox_mod;
+       struct bfa_ioc_hwif_s   *ioc_hwif;
+};
+
+struct bfa_ioc_hwif_s {
+       bfa_status_t    (*ioc_pll_init) (struct bfa_ioc_s *ioc);
+       bfa_boolean_t   (*ioc_firmware_lock)    (struct bfa_ioc_s *ioc);
+       void            (*ioc_firmware_unlock)  (struct bfa_ioc_s *ioc);
+       u32 *           (*ioc_fwimg_get_chunk)  (struct bfa_ioc_s *ioc,
+                                               u32 off);
+       u32             (*ioc_fwimg_get_size)   (struct bfa_ioc_s *ioc);
+       void            (*ioc_reg_init) (struct bfa_ioc_s *ioc);
+       void            (*ioc_map_port) (struct bfa_ioc_s *ioc);
+       void            (*ioc_isr_mode_set)     (struct bfa_ioc_s *ioc,
+                                               bfa_boolean_t msix);
+       void            (*ioc_notify_hbfail)    (struct bfa_ioc_s *ioc);
+       void            (*ioc_ownership_reset)  (struct bfa_ioc_s *ioc);
 };
 
 #define bfa_ioc_pcifn(__ioc)           ((__ioc)->pcidev.pci_func)
@@ -191,6 +209,15 @@ struct bfa_ioc_s {
 #define bfa_ioc_rx_bbcredit(__ioc)     ((__ioc)->attr->rx_bbcredit)
 #define bfa_ioc_speed_sup(__ioc)       \
        BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop)
+#define bfa_ioc_get_nports(__ioc)       \
+       BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop)
+
+#define bfa_ioc_stats(_ioc, _stats)     ((_ioc)->stats._stats++)
+#define BFA_IOC_FWIMG_MINSZ     (16 * 1024)
+
+#define BFA_IOC_FLASH_CHUNK_NO(off)             (off / BFI_FLASH_CHUNK_SZ_WORDS)
+#define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off)      (off % BFI_FLASH_CHUNK_SZ_WORDS)
+#define BFA_IOC_FLASH_CHUNK_ADDR(chunkno)  (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
 
 /**
  * IOC mailbox interface
@@ -207,6 +234,14 @@ void bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
 /**
  * IOC interfaces
  */
+#define bfa_ioc_pll_init(__ioc) ((__ioc)->ioc_hwif->ioc_pll_init(__ioc))
+#define bfa_ioc_isr_mode_set(__ioc, __msix)                     \
+                       ((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix))
+#define bfa_ioc_ownership_reset(__ioc)                          \
+                       ((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc))
+
+void bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc);
+void bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc);
 void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa,
                struct bfa_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod,
                struct bfa_trc_mod_s *trcmod,
@@ -223,13 +258,21 @@ bfa_boolean_t bfa_ioc_intx_claim(struct bfa_ioc_s *ioc);
 void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param);
 void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg);
 void bfa_ioc_error_isr(struct bfa_ioc_s *ioc);
-void bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t intx);
-bfa_status_t bfa_ioc_pll_init(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc);
 void bfa_ioc_cfg_complete(struct bfa_ioc_s *ioc);
+enum bfa_ioc_type_e bfa_ioc_get_type(struct bfa_ioc_s *ioc);
+void bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num);
+void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver);
+void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver);
+void bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model);
+void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc,
+       char *manufacturer);
+void bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev);
+enum bfa_ioc_state bfa_ioc_get_state(struct bfa_ioc_s *ioc);
+
 void bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr);
 void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
                struct bfa_adapter_attr_s *ad_attr);
@@ -237,6 +280,7 @@ int bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover);
 void bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave);
 bfa_status_t bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata,
                int *trclen);
+void bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc);
 bfa_status_t bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata,
                                 int *trclen);
 u32 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr);
@@ -245,6 +289,13 @@ void bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc);
 void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
        struct bfa_ioc_hbfail_notify_s *notify);
+bfa_boolean_t bfa_ioc_sem_get(bfa_os_addr_t sem_reg);
+void bfa_ioc_sem_release(bfa_os_addr_t sem_reg);
+void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
+void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc,
+                       struct bfi_ioc_image_hdr_s *fwhdr);
+bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
+                       struct bfi_ioc_image_hdr_s *fwhdr);
 
 /*
  * bfa mfg wwn API functions
diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c
new file mode 100644 (file)
index 0000000..3ce8531
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux driver for Brocade Fibre Channel Host Bus Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) 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.
+ */
+
+#include <bfa.h>
+#include <bfa_ioc.h>
+#include <bfa_fwimg_priv.h>
+#include <cna/bfa_cna_trcmod.h>
+#include <cs/bfa_debug.h>
+#include <bfi/bfi_ioc.h>
+#include <bfi/bfi_cbreg.h>
+#include <log/bfa_log_hal.h>
+#include <defs/bfa_defs_pci.h>
+
+BFA_TRC_FILE(CNA, IOC_CB);
+
+/*
+ * forward declarations
+ */
+static bfa_status_t bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc);
+static bfa_boolean_t bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc);
+static u32  *bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off);
+static u32 bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
+static void bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc);
+
+struct bfa_ioc_hwif_s hwif_cb = {
+       bfa_ioc_cb_pll_init,
+       bfa_ioc_cb_firmware_lock,
+       bfa_ioc_cb_firmware_unlock,
+       bfa_ioc_cb_fwimg_get_chunk,
+       bfa_ioc_cb_fwimg_get_size,
+       bfa_ioc_cb_reg_init,
+       bfa_ioc_cb_map_port,
+       bfa_ioc_cb_isr_mode_set,
+       bfa_ioc_cb_notify_hbfail,
+       bfa_ioc_cb_ownership_reset,
+};
+
+/**
+ * Called from bfa_ioc_attach() to map asic specific calls.
+ */
+void
+bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc)
+{
+       ioc->ioc_hwif = &hwif_cb;
+}
+
+static u32 *
+bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
+{
+       return bfi_image_cb_get_chunk(off);
+}
+
+static u32
+bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc)
+{
+       return bfi_image_cb_size;
+}
+
+/**
+ * Return true if firmware of current driver matches the running firmware.
+ */
+static bfa_boolean_t
+bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc)
+{
+       return BFA_TRUE;
+}
+
+static void
+bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc)
+{
+}
+
+/**
+ * Notify other functions on HB failure.
+ */
+static void
+bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc)
+{
+       bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET);
+       bfa_reg_read(ioc->ioc_regs.err_set);
+}
+
+/**
+ * Host to LPU mailbox message addresses
+ */
+static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
+       { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
+       { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers
+ */
+static struct { u32 hfn, lpu; } iocreg_mbcmd[] = {
+       { HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT },
+       { HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT }
+};
+
+static void
+bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc)
+{
+       bfa_os_addr_t   rb;
+       int             pcifn = bfa_ioc_pcifn(ioc);
+
+       rb = bfa_ioc_bar0(ioc);
+
+       ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
+       ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
+       ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
+
+       if (ioc->port_id == 0) {
+               ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
+               ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
+       } else {
+               ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
+               ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
+       }
+
+       /**
+        * Host <-> LPU mailbox command/status registers
+        */
+       ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd[pcifn].hfn;
+       ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd[pcifn].lpu;
+
+       /*
+        * PSS control registers
+        */
+       ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
+       ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
+       ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_400_CTL_REG);
+       ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_212_CTL_REG);
+
+       /*
+        * IOC semaphore registers and serialization
+        */
+       ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
+       ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
+
+       /**
+        * sram memory access
+        */
+       ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
+       ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
+
+       /*
+        * err set reg : for notification of hb failure
+        */
+       ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
+}
+
+/**
+ * Initialize IOC to port mapping.
+ */
+static void
+bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc)
+{
+       /**
+        * For crossbow, port id is same as pci function.
+        */
+       ioc->port_id = bfa_ioc_pcifn(ioc);
+       bfa_trc(ioc, ioc->port_id);
+}
+
+/**
+ * Set interrupt mode for a function: INTX or MSIX
+ */
+static void
+bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
+{
+}
+
+static bfa_status_t
+bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc)
+{
+       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
+       u32     pll_sclk, pll_fclk;
+
+       /*
+        *  Hold semaphore so that nobody can access the chip during init.
+        */
+       bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
+
+       pll_sclk = __APP_PLL_212_ENABLE | __APP_PLL_212_LRESETN |
+                       __APP_PLL_212_P0_1(3U) |
+                       __APP_PLL_212_JITLMT0_1(3U) |
+                       __APP_PLL_212_CNTLMT0_1(3U);
+       pll_fclk = __APP_PLL_400_ENABLE | __APP_PLL_400_LRESETN |
+                       __APP_PLL_400_RSEL200500 | __APP_PLL_400_P0_1(3U) |
+                       __APP_PLL_400_JITLMT0_1(3U) |
+                       __APP_PLL_400_CNTLMT0_1(3U);
+
+       bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
+       bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
+
+       bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+
+       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+                       __APP_PLL_212_LOGIC_SOFT_RESET);
+       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+                       __APP_PLL_212_BYPASS |
+                       __APP_PLL_212_LOGIC_SOFT_RESET);
+       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+                       __APP_PLL_400_LOGIC_SOFT_RESET);
+       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+                       __APP_PLL_400_BYPASS |
+                       __APP_PLL_400_LOGIC_SOFT_RESET);
+       bfa_os_udelay(2);
+       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+                       __APP_PLL_212_LOGIC_SOFT_RESET);
+       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+                       __APP_PLL_400_LOGIC_SOFT_RESET);
+
+       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
+                       pll_sclk | __APP_PLL_212_LOGIC_SOFT_RESET);
+       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
+                       pll_fclk | __APP_PLL_400_LOGIC_SOFT_RESET);
+
+       /**
+        * Wait for PLLs to lock.
+        */
+       bfa_os_udelay(2000);
+       bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+
+       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
+       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
+
+       /*
+        *  release semaphore.
+        */
+       bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+
+       return BFA_STATUS_OK;
+}
+
+/**
+ * Cleanup hw semaphore and usecnt registers
+ */
+static void
+bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc)
+{
+
+       /*
+        * Read the hw sem reg to make sure that it is locked
+        * before we clear it. If it is not locked, writing 1
+        * will lock it instead of clearing it.
+        */
+       bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
+       bfa_ioc_hw_sem_release(ioc);
+}
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c
new file mode 100644 (file)
index 0000000..20b58ad
--- /dev/null
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux driver for Brocade Fibre Channel Host Bus Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) 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.
+ */
+
+#include <bfa.h>
+#include <bfa_ioc.h>
+#include <bfa_fwimg_priv.h>
+#include <cna/bfa_cna_trcmod.h>
+#include <cs/bfa_debug.h>
+#include <bfi/bfi_ioc.h>
+#include <bfi/bfi_ctreg.h>
+#include <log/bfa_log_hal.h>
+#include <defs/bfa_defs_pci.h>
+
+BFA_TRC_FILE(CNA, IOC_CT);
+
+/*
+ * forward declarations
+ */
+static bfa_status_t bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc);
+static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc);
+static u32* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc,
+                                       u32 off);
+static u32 bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
+static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc);
+
+struct bfa_ioc_hwif_s hwif_ct = {
+       bfa_ioc_ct_pll_init,
+       bfa_ioc_ct_firmware_lock,
+       bfa_ioc_ct_firmware_unlock,
+       bfa_ioc_ct_fwimg_get_chunk,
+       bfa_ioc_ct_fwimg_get_size,
+       bfa_ioc_ct_reg_init,
+       bfa_ioc_ct_map_port,
+       bfa_ioc_ct_isr_mode_set,
+       bfa_ioc_ct_notify_hbfail,
+       bfa_ioc_ct_ownership_reset,
+};
+
+/**
+ * Called from bfa_ioc_attach() to map asic specific calls.
+ */
+void
+bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc)
+{
+       ioc->ioc_hwif = &hwif_ct;
+}
+
+static u32*
+bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
+{
+       return bfi_image_ct_get_chunk(off);
+}
+
+static u32
+bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc)
+{
+       return bfi_image_ct_size;
+}
+
+/**
+ * Return true if firmware of current driver matches the running firmware.
+ */
+static bfa_boolean_t
+bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
+{
+       enum bfi_ioc_state ioc_fwstate;
+       u32 usecnt;
+       struct bfi_ioc_image_hdr_s fwhdr;
+
+       /**
+        * Firmware match check is relevant only for CNA.
+        */
+       if (!ioc->cna)
+               return BFA_TRUE;
+
+       /**
+        * If bios boot (flash based) -- do not increment usage count
+        */
+       if (bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+               return BFA_TRUE;
+
+       bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+       usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
+
+       /**
+        * If usage count is 0, always return TRUE.
+        */
+       if (usecnt == 0) {
+               bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
+               bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+               bfa_trc(ioc, usecnt);
+               return BFA_TRUE;
+       }
+
+       ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
+       bfa_trc(ioc, ioc_fwstate);
+
+       /**
+        * Use count cannot be non-zero and chip in uninitialized state.
+        */
+       bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
+
+       /**
+        * Check if another driver with a different firmware is active
+        */
+       bfa_ioc_fwver_get(ioc, &fwhdr);
+       if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
+               bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+               bfa_trc(ioc, usecnt);
+               return BFA_FALSE;
+       }
+
+       /**
+        * Same firmware version. Increment the reference count.
+        */
+       usecnt++;
+       bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
+       bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+       bfa_trc(ioc, usecnt);
+       return BFA_TRUE;
+}
+
+static void
+bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
+{
+       u32 usecnt;
+
+       /**
+        * Firmware lock is relevant only for CNA.
+        * If bios boot (flash based) -- do not decrement usage count
+        */
+       if (!ioc->cna || bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+               return;
+
+       /**
+        * decrement usage count
+        */
+       bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+       usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
+       bfa_assert(usecnt > 0);
+
+       usecnt--;
+       bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
+       bfa_trc(ioc, usecnt);
+
+       bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+}
+
+/**
+ * Notify other functions on HB failure.
+ */
+static void
+bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc)
+{
+       if (ioc->cna) {
+               bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
+               /* Wait for halt to take effect */
+               bfa_reg_read(ioc->ioc_regs.ll_halt);
+       } else {
+               bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET);
+               bfa_reg_read(ioc->ioc_regs.err_set);
+       }
+}
+
+/**
+ * Host to LPU mailbox message addresses
+ */
+static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
+       { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
+       { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
+       { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 },
+       { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 }
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers - port 0
+ */
+static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = {
+       { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT },
+       { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT },
+       { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT },
+       { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT }
+};
+
+/**
+ * Host <-> LPU mailbox command/status registers - port 1
+ */
+static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = {
+       { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT },
+       { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT },
+       { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT },
+       { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT }
+};
+
+static void
+bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
+{
+       bfa_os_addr_t   rb;
+       int             pcifn = bfa_ioc_pcifn(ioc);
+
+       rb = bfa_ioc_bar0(ioc);
+
+       ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
+       ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
+       ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
+
+       if (ioc->port_id == 0) {
+               ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
+               ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
+               ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
+               ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
+               ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
+       } else {
+               ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
+               ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
+               ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
+               ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
+               ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
+       }
+
+       /*
+        * PSS control registers
+        */
+       ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
+       ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
+       ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
+       ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
+
+       /*
+        * IOC semaphore registers and serialization
+        */
+       ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
+       ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
+       ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
+       ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
+
+       /**
+        * sram memory access
+        */
+       ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
+       ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
+
+       /*
+        * err set reg : for notification of hb failure in fcmode
+        */
+       ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
+}
+
+/**
+ * Initialize IOC to port mapping.
+ */
+
+#define FNC_PERS_FN_SHIFT(__fn)        ((__fn) * 8)
+static void
+bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc)
+{
+       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
+       u32     r32;
+
+       /**
+        * For catapult, base port id on personality register and IOC type
+        */
+       r32 = bfa_reg_read(rb + FNC_PERS_REG);
+       r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
+       ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
+
+       bfa_trc(ioc, bfa_ioc_pcifn(ioc));
+       bfa_trc(ioc, ioc->port_id);
+}
+
+/**
+ * Set interrupt mode for a function: INTX or MSIX
+ */
+static void
+bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
+{
+       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
+       u32     r32, mode;
+
+       r32 = bfa_reg_read(rb + FNC_PERS_REG);
+       bfa_trc(ioc, r32);
+
+       mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
+               __F0_INTX_STATUS;
+
+       /**
+        * If already in desired mode, do not change anything
+        */
+       if (!msix && mode)
+               return;
+
+       if (msix)
+               mode = __F0_INTX_STATUS_MSIX;
+       else
+               mode = __F0_INTX_STATUS_INTA;
+
+       r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
+       r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
+       bfa_trc(ioc, r32);
+
+       bfa_reg_write(rb + FNC_PERS_REG, r32);
+}
+
+static bfa_status_t
+bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc)
+{
+       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
+       u32     pll_sclk, pll_fclk, r32;
+
+       /*
+        *  Hold semaphore so that nobody can access the chip during init.
+        */
+       bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
+
+       pll_sclk = __APP_PLL_312_LRESETN | __APP_PLL_312_ENARST |
+               __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(3U) |
+               __APP_PLL_312_JITLMT0_1(3U) |
+               __APP_PLL_312_CNTLMT0_1(1U);
+       pll_fclk = __APP_PLL_425_LRESETN | __APP_PLL_425_ENARST |
+               __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
+               __APP_PLL_425_JITLMT0_1(3U) |
+               __APP_PLL_425_CNTLMT0_1(1U);
+
+       /**
+        *      For catapult, choose operational mode FC/FCoE
+        */
+       if (ioc->fcmode) {
+               bfa_reg_write((rb + OP_MODE), 0);
+               bfa_reg_write((rb + ETH_MAC_SER_REG),
+                               __APP_EMS_CMLCKSEL |
+                               __APP_EMS_REFCKBUFEN2 |
+                               __APP_EMS_CHANNEL_SEL);
+       } else {
+               ioc->pllinit = BFA_TRUE;
+               bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
+               bfa_reg_write((rb + ETH_MAC_SER_REG),
+                                __APP_EMS_REFCKBUFEN1);
+       }
+
+       bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
+       bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
+
+       bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
+
+       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
+               __APP_PLL_312_LOGIC_SOFT_RESET);
+       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
+               __APP_PLL_425_LOGIC_SOFT_RESET);
+       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
+               __APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE);
+       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
+               __APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE);
+
+       /**
+        * Wait for PLLs to lock.
+        */
+       bfa_reg_read(rb + HOSTFN0_INT_MSK);
+       bfa_os_udelay(2000);
+       bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
+       bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
+
+       bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
+               __APP_PLL_312_ENABLE);
+       bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
+               __APP_PLL_425_ENABLE);
+
+       bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
+       bfa_os_udelay(1000);
+       r32 = bfa_reg_read((rb + MBIST_STAT_REG));
+       bfa_trc(ioc, r32);
+       /*
+        *  release semaphore.
+        */
+       bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
+
+       return BFA_STATUS_OK;
+}
+
+/**
+ * Cleanup hw semaphore and usecnt registers
+ */
+static void
+bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
+{
+
+       if (ioc->cna) {
+               bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+               bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 0);
+               bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
+       }
+
+       /*
+        * Read the hw sem reg to make sure that it is locked
+        * before we clear it. If it is not locked, writing 1
+        * will lock it instead of clearing it.
+        */
+       bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
+       bfa_ioc_hw_sem_release(ioc);
+}
index d7ab792a9e549f18809b145c012f8600f497d0cd..a76de2669bfcf760196e7fd13360590c2f60d940 100644 (file)
@@ -172,6 +172,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
         */
        if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) {
                iocfc->hwif.hw_reginit = bfa_hwct_reginit;
+               iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack;
                iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack;
                iocfc->hwif.hw_msix_init = bfa_hwct_msix_init;
                iocfc->hwif.hw_msix_install = bfa_hwct_msix_install;
@@ -180,6 +181,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
                iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;
        } else {
                iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
+               iocfc->hwif.hw_reqq_ack = bfa_hwcb_reqq_ack;
                iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
                iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
                iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install;
@@ -336,8 +338,10 @@ bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete)
                        bfa_cb_init(bfa->bfad, BFA_STATUS_OK);
                else
                        bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED);
-       } else
-               bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
+       } else {
+               if (bfa->iocfc.cfgdone)
+                       bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
+       }
 }
 
 static void
@@ -619,8 +623,6 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
 
        bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod,
                bfa->trcmod, bfa->aen, bfa->logm);
-       bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC);
-       bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
 
        /**
         * Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode.
@@ -628,6 +630,9 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
        if (0)
                bfa_ioc_set_fcmode(&bfa->ioc);
 
+       bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC);
+       bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
+
        bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev);
        bfa_iocfc_mem_claim(bfa, cfg, meminfo);
        bfa_timer_init(&bfa->timer_mod);
@@ -654,7 +659,6 @@ bfa_iocfc_init(struct bfa_s *bfa)
 {
        bfa->iocfc.action = BFA_IOCFC_ACT_INIT;
        bfa_ioc_enable(&bfa->ioc);
-       bfa_msix_install(bfa);
 }
 
 /**
@@ -797,6 +801,11 @@ bfa_iocfc_get_stats(struct bfa_s *bfa, struct bfa_iocfc_stats_s *stats,
                return BFA_STATUS_DEVBUSY;
        }
 
+       if (!bfa_iocfc_is_operational(bfa)) {
+               bfa_trc(bfa, 0);
+               return BFA_STATUS_IOC_NON_OP;
+       }
+
        iocfc->stats_busy = BFA_TRUE;
        iocfc->stats_ret = stats;
        iocfc->stats_cbfn = cbfn;
@@ -817,6 +826,11 @@ bfa_iocfc_clear_stats(struct bfa_s *bfa, bfa_cb_ioc_t cbfn, void *cbarg)
                return BFA_STATUS_DEVBUSY;
        }
 
+       if (!bfa_iocfc_is_operational(bfa)) {
+               bfa_trc(bfa, 0);
+               return BFA_STATUS_IOC_NON_OP;
+       }
+
        iocfc->stats_busy = BFA_TRUE;
        iocfc->stats_cbfn = cbfn;
        iocfc->stats_cbarg = cbarg;
index ce9a830a420749957d31f56983a64f2d6ffe2b51..fbb4bdc9d600af9da34114602151781856dc3ce1 100644 (file)
@@ -54,6 +54,7 @@ struct bfa_msix_s {
  */
 struct bfa_hwif_s {
        void (*hw_reginit)(struct bfa_s *bfa);
+       void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq);
        void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq);
        void (*hw_msix_init)(struct bfa_s *bfa, int nvecs);
        void (*hw_msix_install)(struct bfa_s *bfa);
@@ -143,6 +144,7 @@ void bfa_msix_rspq(struct bfa_s *bfa, int vec);
 void bfa_msix_lpu_err(struct bfa_s *bfa, int vec);
 
 void bfa_hwcb_reginit(struct bfa_s *bfa);
+void bfa_hwcb_reqq_ack(struct bfa_s *bfa, int rspq);
 void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq);
 void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs);
 void bfa_hwcb_msix_install(struct bfa_s *bfa);
@@ -151,6 +153,7 @@ void bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix);
 void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap,
                        u32 *nvecs, u32 *maxvec);
 void bfa_hwct_reginit(struct bfa_s *bfa);
+void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq);
 void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq);
 void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs);
 void bfa_hwct_msix_install(struct bfa_s *bfa);
index f81d359b7089de06133afdbbffd6c5aa84e29e60..5b107abe46e5cce516667f5b760f7acf81cdabcd 100644 (file)
@@ -149,7 +149,7 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -194,7 +194,7 @@ bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -259,7 +259,7 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -317,7 +317,7 @@ bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -377,7 +377,7 @@ bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -419,7 +419,7 @@ bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -467,7 +467,7 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -516,7 +516,7 @@ bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -544,7 +544,7 @@ bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -577,7 +577,7 @@ bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
@@ -605,7 +605,7 @@ bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ioim->bfa, event);
        }
 }
 
index eabf7d38bd0942ac2dc8d0a145ce8b8ea1a081c1..a914ff2551357c5dd2f3d9e999b531bf42cea144 100644 (file)
@@ -144,7 +144,7 @@ bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -175,7 +175,7 @@ bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -212,7 +212,7 @@ bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -247,7 +247,7 @@ bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -275,7 +275,7 @@ bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -317,7 +317,7 @@ bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -348,7 +348,7 @@ bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -385,7 +385,7 @@ bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -413,7 +413,7 @@ bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -442,7 +442,7 @@ bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -470,7 +470,7 @@ bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -502,7 +502,7 @@ bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -538,7 +538,7 @@ bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -559,7 +559,7 @@ bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
@@ -583,7 +583,7 @@ bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->bfa, event);
        }
 }
 
index 9844b45412b6d416408e5c55c0d22f4004589a42..ad06f6189092b59833a3d0de039c5195d1badd55 100644 (file)
@@ -18,6 +18,7 @@
 #include <bfa.h>
 #include <bfi/bfi_lps.h>
 #include <cs/bfa_debug.h>
+#include <defs/bfa_defs_pci.h>
 
 BFA_TRC_FILE(HAL, LPS);
 BFA_MODULE(lps);
@@ -25,6 +26,12 @@ BFA_MODULE(lps);
 #define BFA_LPS_MIN_LPORTS     (1)
 #define BFA_LPS_MAX_LPORTS     (256)
 
+/*
+ * Maximum Vports supported per physical port or vf.
+ */
+#define BFA_LPS_MAX_VPORTS_SUPP_CB  255
+#define BFA_LPS_MAX_VPORTS_SUPP_CT  190
+
 /**
  * forward declarations
  */
@@ -49,7 +56,7 @@ static void bfa_lps_send_login(struct bfa_lps_s *lps);
 static void bfa_lps_send_logout(struct bfa_lps_s *lps);
 static void bfa_lps_login_comp(struct bfa_lps_s *lps);
 static void bfa_lps_logout_comp(struct bfa_lps_s *lps);
-
+static void bfa_lps_cvl_event(struct bfa_lps_s *lps);
 
 /**
  *  lps_pvt BFA LPS private functions
@@ -62,6 +69,7 @@ enum bfa_lps_event {
        BFA_LPS_SM_RESUME       = 4,    /* space present in reqq queue  */
        BFA_LPS_SM_DELETE       = 5,    /* lps delete from user         */
        BFA_LPS_SM_OFFLINE      = 6,    /* Link is offline              */
+       BFA_LPS_SM_RX_CVL       = 7,    /* Rx clear virtual link        */
 };
 
 static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event);
@@ -91,6 +99,12 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
                        bfa_sm_set_state(lps, bfa_lps_sm_login);
                        bfa_lps_send_login(lps);
                }
+               if (lps->fdisc)
+                       bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                       BFA_PL_EID_LOGIN, 0, "FDISC Request");
+               else
+                       bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                       BFA_PL_EID_LOGIN, 0, "FLOGI Request");
                break;
 
        case BFA_LPS_SM_LOGOUT:
@@ -101,6 +115,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
                bfa_lps_free(lps);
                break;
 
+       case BFA_LPS_SM_RX_CVL:
        case BFA_LPS_SM_OFFLINE:
                break;
 
@@ -112,7 +127,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(lps->bfa, event);
        }
 }
 
@@ -127,10 +142,25 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
 
        switch (event) {
        case BFA_LPS_SM_FWRSP:
-               if (lps->status == BFA_STATUS_OK)
+               if (lps->status == BFA_STATUS_OK) {
                        bfa_sm_set_state(lps, bfa_lps_sm_online);
-               else
+                       if (lps->fdisc)
+                               bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                               BFA_PL_EID_LOGIN, 0, "FDISC Accept");
+                       else
+                               bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                               BFA_PL_EID_LOGIN, 0, "FLOGI Accept");
+               } else {
                        bfa_sm_set_state(lps, bfa_lps_sm_init);
+                       if (lps->fdisc)
+                               bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                               BFA_PL_EID_LOGIN, 0,
+                               "FDISC Fail (RJT or timeout)");
+                       else
+                               bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                               BFA_PL_EID_LOGIN, 0,
+                               "FLOGI Fail (RJT or timeout)");
+               }
                bfa_lps_login_comp(lps);
                break;
 
@@ -139,7 +169,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(lps->bfa, event);
        }
 }
 
@@ -162,8 +192,16 @@ bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event)
                bfa_reqq_wcancel(&lps->wqe);
                break;
 
+       case BFA_LPS_SM_RX_CVL:
+               /*
+                * Login was not even sent out; so when getting out
+                * of this state, it will appear like a login retry
+                * after Clear virtual link
+                */
+               break;
+
        default:
-               bfa_assert(0);
+               bfa_sm_fault(lps->bfa, event);
        }
 }
 
@@ -185,6 +223,17 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
                        bfa_sm_set_state(lps, bfa_lps_sm_logout);
                        bfa_lps_send_logout(lps);
                }
+               bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                       BFA_PL_EID_LOGO, 0, "Logout");
+               break;
+
+       case BFA_LPS_SM_RX_CVL:
+               bfa_sm_set_state(lps, bfa_lps_sm_init);
+
+               /* Let the vport module know about this event */
+               bfa_lps_cvl_event(lps);
+               bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                       BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
                break;
 
        case BFA_LPS_SM_OFFLINE:
@@ -193,7 +242,7 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(lps->bfa, event);
        }
 }
 
@@ -217,7 +266,7 @@ bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(lps->bfa, event);
        }
 }
 
@@ -242,7 +291,7 @@ bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(lps->bfa, event);
        }
 }
 
@@ -395,6 +444,20 @@ bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp)
        bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
 }
 
+/**
+ * Firmware received a Clear virtual link request (for FCoE)
+ */
+static void
+bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl)
+{
+       struct bfa_lps_mod_s    *mod = BFA_LPS_MOD(bfa);
+       struct bfa_lps_s        *lps;
+
+       lps = BFA_LPS_FROM_TAG(mod, cvl->lp_tag);
+
+       bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL);
+}
+
 /**
  * Space is available in request queue, resume queueing request to firmware.
  */
@@ -531,7 +594,48 @@ bfa_lps_logout_comp(struct bfa_lps_s *lps)
                bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg);
 }
 
+/**
+ * Clear virtual link completion handler for non-fcs
+ */
+static void
+bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete)
+{
+       struct bfa_lps_s *lps   = arg;
+
+       if (!complete)
+               return;
+
+       /* Clear virtual link to base port will result in link down */
+       if (lps->fdisc)
+               bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
+}
+
+/**
+ * Received Clear virtual link event --direct call for fcs,
+ * queue for others
+ */
+static void
+bfa_lps_cvl_event(struct bfa_lps_s *lps)
+{
+       if (!lps->bfa->fcs) {
+               bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb,
+                               lps);
+               return;
+       }
+
+       /* Clear virtual link to base port will result in link down */
+       if (lps->fdisc)
+               bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
+}
 
+u32
+bfa_lps_get_max_vport(struct bfa_s *bfa)
+{
+       if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT)
+               return BFA_LPS_MAX_VPORTS_SUPP_CT;
+       else
+               return BFA_LPS_MAX_VPORTS_SUPP_CB;
+}
 
 /**
  *  lps_public BFA LPS public functions
@@ -752,6 +856,14 @@ bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps)
        return lps->lsrjt_expl;
 }
 
+/**
+ * Return fpma/spma MAC for lport
+ */
+struct mac_s
+bfa_lps_get_lp_mac(struct bfa_lps_s *lps)
+{
+       return lps->lp_mac;
+}
 
 /**
  * LPS firmware message class handler.
@@ -773,6 +885,10 @@ bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
                bfa_lps_logout_rsp(bfa, msg.logout_rsp);
                break;
 
+       case BFI_LPS_H2I_CVL_EVENT:
+               bfa_lps_rx_cvl_event(bfa, msg.cvl_event);
+               break;
+
        default:
                bfa_trc(bfa, m->mhdr.msg_id);
                bfa_assert(0);
index 32eda8e1ec6510714f1acf39d937d81ea1b1d18b..a7fcc80c177e16680890c8161ecdf8b725eff73a 100644 (file)
@@ -24,7 +24,7 @@
  */
 struct bfa_module_s *hal_mods[] = {
        &hal_mod_sgpg,
-       &hal_mod_pport,
+       &hal_mod_fcport,
        &hal_mod_fcxp,
        &hal_mod_lps,
        &hal_mod_uf,
@@ -45,7 +45,7 @@ bfa_isr_func_t  bfa_isrs[BFI_MC_MAX] = {
        bfa_isr_unhandled,      /* BFI_MC_DIAG */
        bfa_isr_unhandled,      /* BFI_MC_FLASH */
        bfa_isr_unhandled,      /* BFI_MC_CEE */
-       bfa_pport_isr,          /* BFI_MC_PORT */
+       bfa_fcport_isr,         /* BFI_MC_FCPORT */
        bfa_isr_unhandled,      /* BFI_MC_IOCFC */
        bfa_isr_unhandled,      /* BFI_MC_LL */
        bfa_uf_isr,             /* BFI_MC_UF */
index 96f70534593c04f740368e6d2ee0286caebbe0af..f554c2fad6a99dd3acc30eb11478c35260aeda01 100644 (file)
@@ -29,7 +29,7 @@
 
 
 struct bfa_modules_s {
-       struct bfa_pport_s      pport;  /*  physical port module        */
+       struct bfa_fcport_s     fcport; /*  fc port module      */
        struct bfa_fcxp_mod_s fcxp_mod; /*  fcxp module         */
        struct bfa_lps_mod_s lps_mod;   /*  fcxp module         */
        struct bfa_uf_mod_s uf_mod;     /*  unsolicited frame module    */
index 51f698a06b6da42683c4f397de1017342bcfe0c4..40e256ec67ff675e2d35a498cd08b76d6ebb4af4 100644 (file)
 #include "bfa_intr_priv.h"
 
 /**
- * BFA physical port data structure
+ * Link notification data structure
  */
-struct bfa_pport_s {
+struct bfa_fcport_ln_s {
+       struct bfa_fcport_s     *fcport;
+       bfa_sm_t                sm;
+       struct bfa_cb_qe_s      ln_qe;  /*  BFA callback queue elem for ln */
+       enum bfa_pport_linkstate ln_event; /*  ln event for callback */
+};
+
+/**
+ * BFA FC port data structure
+ */
+struct bfa_fcport_s {
        struct bfa_s            *bfa;   /*  parent BFA instance */
        bfa_sm_t                sm;     /*  port state machine */
        wwn_t                   nwwn;   /*  node wwn of physical port */
@@ -36,6 +46,8 @@ struct bfa_pport_s {
        enum bfa_pport_topology topology;       /*  current topology */
        u8                      myalpa; /*  my ALPA in LOOP topology */
        u8                      rsvd[3];
+       u32             mypid:24;
+       u32             rsvd_b:8;
        struct bfa_pport_cfg_s  cfg;    /*  current port configuration */
        struct bfa_qos_attr_s  qos_attr;   /* QoS Attributes */
        struct bfa_qos_vc_attr_s qos_vc_attr;  /*  VC info from ELP */
@@ -49,42 +61,31 @@ struct bfa_pport_s {
        void                    (*event_cbfn) (void *cbarg,
                                                bfa_pport_event_t event);
        union {
-               union bfi_pport_i2h_msg_u i2hmsg;
+               union bfi_fcport_i2h_msg_u i2hmsg;
        } event_arg;
        void                    *bfad;  /*  BFA driver handle */
+       struct bfa_fcport_ln_s   ln; /* Link Notification */
        struct bfa_cb_qe_s              hcb_qe; /*  BFA callback queue elem */
-       enum bfa_pport_linkstate        hcb_event;
-                                       /*  link event for callback */
+       struct bfa_timer_s      timer;  /*  timer */
        u32             msgtag; /*  fimrware msg tag for reply */
        u8                      *stats_kva;
        u64             stats_pa;
-       union bfa_pport_stats_u *stats; /*  pport stats */
-       u32             mypid:24;
-       u32             rsvd_b:8;
-       struct bfa_timer_s      timer;  /*  timer */
-       union bfa_pport_stats_u         *stats_ret;
-                                       /*  driver stats location */
-       bfa_status_t            stats_status;
-                                       /*  stats/statsclr status */
-       bfa_boolean_t           stats_busy;
-                                       /*  outstanding stats/statsclr */
-       bfa_boolean_t           stats_qfull;
-       bfa_boolean_t           diag_busy;
-                                       /*  diag busy status */
-       bfa_boolean_t           beacon;
-                                       /*  port beacon status */
-       bfa_boolean_t           link_e2e_beacon;
-                                       /*  link beacon status */
-       bfa_cb_pport_t          stats_cbfn;
-                                       /*  driver callback function */
-       void                    *stats_cbarg;
-                                       /* *!< user callback arg */
+       union bfa_fcport_stats_u *stats;
+       union bfa_fcport_stats_u *stats_ret; /*  driver stats location */
+       bfa_status_t            stats_status; /*  stats/statsclr status */
+       bfa_boolean_t           stats_busy; /*  outstanding stats/statsclr */
+       bfa_boolean_t           stats_qfull;
+       bfa_cb_pport_t          stats_cbfn; /*  driver callback function */
+       void                    *stats_cbarg; /* *!< user callback arg */
+       bfa_boolean_t           diag_busy; /*  diag busy status */
+       bfa_boolean_t           beacon; /*  port beacon status */
+       bfa_boolean_t           link_e2e_beacon; /*  link beacon status */
 };
 
-#define BFA_PORT_MOD(__bfa)    (&(__bfa)->modules.pport)
+#define BFA_FCPORT_MOD(__bfa)  (&(__bfa)->modules.fcport)
 
 /*
  * public functions
  */
-void   bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
+void   bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
 #endif /* __BFA_PORT_PRIV_H__ */
index 0747a6b26f7b0423a06e84e13e1394c59c515db0..be80fc7e1b0e7137961eace2386840a7973e2c31 100644 (file)
@@ -101,7 +101,7 @@ extern bfa_boolean_t bfa_auto_recover;
 extern struct bfa_module_s hal_mod_flash;
 extern struct bfa_module_s hal_mod_fcdiag;
 extern struct bfa_module_s hal_mod_sgpg;
-extern struct bfa_module_s hal_mod_pport;
+extern struct bfa_module_s hal_mod_fcport;
 extern struct bfa_module_s hal_mod_fcxp;
 extern struct bfa_module_s hal_mod_lps;
 extern struct bfa_module_s hal_mod_uf;
index 3e1990a74258387dd24cf1968a5fad7c74fe8a45..7c509fa244e48262b3384921013a34ccee5651dd 100644 (file)
@@ -114,7 +114,7 @@ bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_un_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -146,7 +146,7 @@ bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_cr_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -183,7 +183,7 @@ bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_fwc_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -224,7 +224,7 @@ bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_fwc_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -296,7 +296,7 @@ bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_on_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -329,7 +329,7 @@ bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_fwd_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -359,7 +359,7 @@ bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_fwd_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -394,7 +394,7 @@ bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_off_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -421,7 +421,7 @@ bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -446,7 +446,7 @@ bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -477,7 +477,7 @@ bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
 
        default:
                bfa_stats(rp, sm_delp_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -512,7 +512,7 @@ bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
 
        default:
                bfa_stats(rp, sm_offp_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
@@ -550,7 +550,7 @@ bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
        default:
                bfa_stats(rp, sm_iocd_unexp);
-               bfa_assert(0);
+               bfa_sm_fault(rp->bfa, event);
        }
 }
 
index b3562dce7e9f48c1a2029aaf611a9344465fc626..a7a82610db85622ddc018e7d9f0d63fc890b6320 100644 (file)
  * !!! needed between trace utility and driver version
  */
 enum {
-       BFA_TRC_HAL_IOC         = 1,
-       BFA_TRC_HAL_INTR        = 2,
-       BFA_TRC_HAL_FCXP        = 3,
-       BFA_TRC_HAL_UF          = 4,
-       BFA_TRC_HAL_DIAG        = 5,
-       BFA_TRC_HAL_RPORT       = 6,
-       BFA_TRC_HAL_FCPIM       = 7,
-       BFA_TRC_HAL_IOIM        = 8,
-       BFA_TRC_HAL_TSKIM       = 9,
-       BFA_TRC_HAL_ITNIM       = 10,
-       BFA_TRC_HAL_PPORT       = 11,
-       BFA_TRC_HAL_SGPG        = 12,
-       BFA_TRC_HAL_FLASH       = 13,
-       BFA_TRC_HAL_DEBUG       = 14,
-       BFA_TRC_HAL_WWN         = 15,
-       BFA_TRC_HAL_FLASH_RAW   = 16,
-       BFA_TRC_HAL_SBOOT       = 17,
-       BFA_TRC_HAL_SBOOT_IO    = 18,
-       BFA_TRC_HAL_SBOOT_INTR  = 19,
-       BFA_TRC_HAL_SBTEST      = 20,
-       BFA_TRC_HAL_IPFC        = 21,
-       BFA_TRC_HAL_IOCFC       = 22,
-       BFA_TRC_HAL_FCPTM       = 23,
-       BFA_TRC_HAL_IOTM        = 24,
-       BFA_TRC_HAL_TSKTM       = 25,
-       BFA_TRC_HAL_TIN         = 26,
-       BFA_TRC_HAL_LPS         = 27,
-       BFA_TRC_HAL_FCDIAG      = 28,
-       BFA_TRC_HAL_PBIND       = 29,
-       BFA_TRC_HAL_IOCFC_CT    = 30,
-       BFA_TRC_HAL_IOCFC_CB    = 31,
-       BFA_TRC_HAL_IOCFC_Q     = 32,
+       BFA_TRC_HAL_INTR        = 1,
+       BFA_TRC_HAL_FCXP        = 2,
+       BFA_TRC_HAL_UF          = 3,
+       BFA_TRC_HAL_RPORT       = 4,
+       BFA_TRC_HAL_FCPIM       = 5,
+       BFA_TRC_HAL_IOIM        = 6,
+       BFA_TRC_HAL_TSKIM       = 7,
+       BFA_TRC_HAL_ITNIM       = 8,
+       BFA_TRC_HAL_FCPORT      = 9,
+       BFA_TRC_HAL_SGPG        = 10,
+       BFA_TRC_HAL_FLASH       = 11,
+       BFA_TRC_HAL_DEBUG       = 12,
+       BFA_TRC_HAL_WWN         = 13,
+       BFA_TRC_HAL_FLASH_RAW   = 14,
+       BFA_TRC_HAL_SBOOT       = 15,
+       BFA_TRC_HAL_SBOOT_IO    = 16,
+       BFA_TRC_HAL_SBOOT_INTR  = 17,
+       BFA_TRC_HAL_SBTEST      = 18,
+       BFA_TRC_HAL_IPFC        = 19,
+       BFA_TRC_HAL_IOCFC       = 20,
+       BFA_TRC_HAL_FCPTM       = 21,
+       BFA_TRC_HAL_IOTM        = 22,
+       BFA_TRC_HAL_TSKTM       = 23,
+       BFA_TRC_HAL_TIN         = 24,
+       BFA_TRC_HAL_LPS         = 25,
+       BFA_TRC_HAL_FCDIAG      = 26,
+       BFA_TRC_HAL_PBIND       = 27,
+       BFA_TRC_HAL_IOCFC_CT    = 28,
+       BFA_TRC_HAL_IOCFC_CB    = 29,
+       BFA_TRC_HAL_IOCFC_Q     = 30,
 };
 
 #endif /* __BFA_TRCMOD_PRIV_H__ */
index ff7a4dc0bf3c35cedc806d8a30397914222b2bb8..ad9aaaedd3f1ba28f79804fe5041108f56c2a6a8 100644 (file)
@@ -110,7 +110,7 @@ bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(tskim->bfa, event);
        }
 }
 
@@ -146,7 +146,7 @@ bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(tskim->bfa, event);
        }
 }
 
@@ -178,7 +178,7 @@ bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(tskim->bfa, event);
        }
 }
 
@@ -207,7 +207,7 @@ bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(tskim->bfa, event);
        }
 }
 
@@ -242,7 +242,7 @@ bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(tskim->bfa, event);
        }
 }
 
@@ -277,7 +277,7 @@ bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(tskim->bfa, event);
        }
 }
 
@@ -303,7 +303,7 @@ bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(tskim->bfa, event);
        }
 }
 
index b52b773d49d9de6f64439899310cd16211a3b4d9..13f5feb308c2304bb2559d33332670fe2f28b73f 100644 (file)
@@ -19,7 +19,9 @@
  *  bfad.c Linux driver PCI interface module.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/kthread.h>
 #include "bfad_drv.h"
 #include "bfad_im.h"
 #include "bfad_tm.h"
@@ -53,6 +55,7 @@ static int      log_level = BFA_LOG_WARNING;
 static int      ioc_auto_recover = BFA_TRUE;
 static int      ipfc_enable = BFA_FALSE;
 static int      ipfc_mtu = -1;
+static int     fdmi_enable = BFA_TRUE;
 int            bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
 int            bfa_linkup_delay = -1;
 
@@ -74,6 +77,7 @@ module_param(log_level, int, S_IRUGO | S_IWUSR);
 module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
 module_param(ipfc_enable, int, S_IRUGO | S_IWUSR);
 module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR);
+module_param(fdmi_enable, int, S_IRUGO | S_IWUSR);
 module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR);
 
 /*
@@ -95,6 +99,8 @@ bfad_fc4_probe(struct bfad_s *bfad)
 
        if (ipfc_enable)
                bfad_ipfc_probe(bfad);
+
+       bfad->bfad_flags |= BFAD_FC4_PROBE_DONE;
 ext:
        return rc;
 }
@@ -106,6 +112,7 @@ bfad_fc4_probe_undo(struct bfad_s *bfad)
        bfad_tm_probe_undo(bfad);
        if (ipfc_enable)
                bfad_ipfc_probe_undo(bfad);
+       bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
 }
 
 static void
@@ -173,9 +180,19 @@ bfa_cb_init(void *drv, bfa_status_t init_status)
 {
        struct bfad_s  *bfad = drv;
 
-       if (init_status == BFA_STATUS_OK)
+       if (init_status == BFA_STATUS_OK) {
                bfad->bfad_flags |= BFAD_HAL_INIT_DONE;
 
+               /* If BFAD_HAL_INIT_FAIL flag is set:
+                * Wake up the kernel thread to start
+                * the bfad operations after HAL init done
+                */
+               if ((bfad->bfad_flags & BFAD_HAL_INIT_FAIL)) {
+                       bfad->bfad_flags &= ~BFAD_HAL_INIT_FAIL;
+                       wake_up_process(bfad->bfad_tsk);
+               }
+       }
+
        complete(&bfad->comp);
 }
 
@@ -648,7 +665,7 @@ bfad_fcs_port_cfg(struct bfad_s *bfad)
 
        sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no);
        memcpy(port_cfg.sym_name.symname, symname, strlen(symname));
-       bfa_pport_get_attr(&bfad->bfa, &attr);
+       bfa_fcport_get_attr(&bfad->bfa, &attr);
        port_cfg.nwwn = attr.nwwn;
        port_cfg.pwwn = attr.pwwn;
 
@@ -661,7 +678,6 @@ bfad_drv_init(struct bfad_s *bfad)
        bfa_status_t    rc;
        unsigned long   flags;
        struct bfa_fcs_driver_info_s driver_info;
-       int             i;
 
        bfad->cfg_data.rport_del_timeout = rport_del_timeout;
        bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth;
@@ -681,12 +697,7 @@ bfad_drv_init(struct bfad_s *bfad)
        bfa_init_log(&bfad->bfa, bfad->logmod);
        bfa_init_trc(&bfad->bfa, bfad->trcmod);
        bfa_init_aen(&bfad->bfa, bfad->aen);
-       INIT_LIST_HEAD(&bfad->file_q);
-       INIT_LIST_HEAD(&bfad->file_free_q);
-       for (i = 0; i < BFAD_AEN_MAX_APPS; i++) {
-               bfa_q_qe_init(&bfad->file_buf[i].qe);
-               list_add_tail(&bfad->file_buf[i].qe, &bfad->file_free_q);
-       }
+       memset(bfad->file_map, 0, sizeof(bfad->file_map));
        bfa_init_plog(&bfad->bfa, &bfad->plog_buf);
        bfa_plog_init(&bfad->plog_buf);
        bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
@@ -746,8 +757,16 @@ bfad_drv_init(struct bfad_s *bfad)
        bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod);
        bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod);
        bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen);
-       bfa_fcs_init(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
+       bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
+
+       /* Do FCS init only when HAL init is done */
+       if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
+               bfa_fcs_init(&bfad->bfa_fcs);
+               bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
+       }
+
        bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info);
+       bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
        bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
@@ -763,12 +782,21 @@ out_hal_mem_alloc_failure:
 void
 bfad_drv_uninit(struct bfad_s *bfad)
 {
+       unsigned long   flags;
+
+       spin_lock_irqsave(&bfad->bfad_lock, flags);
+       init_completion(&bfad->comp);
+       bfa_stop(&bfad->bfa);
+       spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+       wait_for_completion(&bfad->comp);
+
        del_timer_sync(&bfad->hal_tmo);
        bfa_isr_disable(&bfad->bfa);
        bfa_detach(&bfad->bfa);
        bfad_remove_intr(bfad);
-       bfa_assert(list_empty(&bfad->file_q));
        bfad_hal_mem_release(bfad);
+
+       bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE;
 }
 
 void
@@ -859,6 +887,86 @@ bfad_drv_log_level_set(struct bfad_s *bfad)
                bfa_log_set_level_all(&bfad->log_data, log_level);
 }
 
+bfa_status_t
+bfad_start_ops(struct bfad_s *bfad)
+{
+       int retval;
+
+       /* PPORT FCS config */
+       bfad_fcs_port_cfg(bfad);
+
+       retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
+       if (retval != BFA_STATUS_OK)
+               goto out_cfg_pport_failure;
+
+       /* BFAD level FC4 (IM/TM/IPFC) specific resource allocation */
+       retval = bfad_fc4_probe(bfad);
+       if (retval != BFA_STATUS_OK) {
+               printk(KERN_WARNING "bfad_fc4_probe failed\n");
+               goto out_fc4_probe_failure;
+       }
+
+       bfad_drv_start(bfad);
+
+       /*
+        * If bfa_linkup_delay is set to -1 default; try to retrive the
+        * value using the bfad_os_get_linkup_delay(); else use the
+        * passed in module param value as the bfa_linkup_delay.
+        */
+       if (bfa_linkup_delay < 0) {
+
+               bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
+               bfad_os_rport_online_wait(bfad);
+               bfa_linkup_delay = -1;
+
+       } else {
+               bfad_os_rport_online_wait(bfad);
+       }
+
+       bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
+
+       return BFA_STATUS_OK;
+
+out_fc4_probe_failure:
+       bfad_fc4_probe_undo(bfad);
+       bfad_uncfg_pport(bfad);
+out_cfg_pport_failure:
+       return BFA_STATUS_FAILED;
+}
+
+int
+bfad_worker (void *ptr)
+{
+       struct bfad_s *bfad;
+       unsigned long   flags;
+
+       bfad = (struct bfad_s *)ptr;
+
+       while (!kthread_should_stop()) {
+
+               /* Check if the FCS init is done from bfad_drv_init;
+                * if not done do FCS init and set the flag.
+                */
+               if (!(bfad->bfad_flags & BFAD_FCS_INIT_DONE)) {
+                       spin_lock_irqsave(&bfad->bfad_lock, flags);
+                       bfa_fcs_init(&bfad->bfa_fcs);
+                       bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
+                       spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+               }
+
+               /* Start the bfad operations after HAL init done */
+               bfad_start_ops(bfad);
+
+               spin_lock_irqsave(&bfad->bfad_lock, flags);
+               bfad->bfad_tsk = NULL;
+               spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+               break;
+       }
+
+       return 0;
+}
+
  /*
   *  PCI_entry PCI driver entries * {
   */
@@ -871,7 +979,6 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
 {
        struct bfad_s  *bfad;
        int             error = -ENODEV, retval;
-       char            buf[16];
 
        /*
         * For single port cards - only claim function 0
@@ -902,8 +1009,7 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
        bfa_trc(bfad, bfad_inst);
 
        bfad->logmod = &bfad->log_data;
-       sprintf(buf, "%d", bfad_inst);
-       bfa_log_init(bfad->logmod, buf, bfa_os_printf);
+       bfa_log_init(bfad->logmod, (char *)pci_name(pdev), bfa_os_printf);
 
        bfad_drv_log_level_set(bfad);
 
@@ -933,57 +1039,39 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
        bfad->ref_count = 0;
        bfad->pport.bfad = bfad;
 
+       bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s",
+                                       "bfad_worker");
+       if (IS_ERR(bfad->bfad_tsk)) {
+               printk(KERN_INFO "bfad[%d]: Kernel thread"
+                       " creation failed!\n",
+                       bfad->inst_no);
+               goto out_kthread_create_failure;
+       }
+
        retval = bfad_drv_init(bfad);
        if (retval != BFA_STATUS_OK)
                goto out_drv_init_failure;
        if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
+               bfad->bfad_flags |= BFAD_HAL_INIT_FAIL;
                printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no);
                goto ok;
        }
 
-       /*
-        * PPORT FCS config
-        */
-       bfad_fcs_port_cfg(bfad);
-
-       retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
+       retval = bfad_start_ops(bfad);
        if (retval != BFA_STATUS_OK)
-               goto out_cfg_pport_failure;
-
-       /*
-        * BFAD level FC4 (IM/TM/IPFC) specific resource allocation
-        */
-       retval = bfad_fc4_probe(bfad);
-       if (retval != BFA_STATUS_OK) {
-               printk(KERN_WARNING "bfad_fc4_probe failed\n");
-               goto out_fc4_probe_failure;
-       }
+               goto out_start_ops_failure;
 
-       bfad_drv_start(bfad);
-
-       /*
-        * If bfa_linkup_delay is set to -1 default; try to retrive the
-        * value using the bfad_os_get_linkup_delay(); else use the
-        * passed in module param value as the bfa_linkup_delay.
-        */
-       if (bfa_linkup_delay < 0) {
-               bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
-               bfad_os_rport_online_wait(bfad);
-               bfa_linkup_delay = -1;
-       } else {
-               bfad_os_rport_online_wait(bfad);
-       }
+       kthread_stop(bfad->bfad_tsk);
+       bfad->bfad_tsk = NULL;
 
-       bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
 ok:
        return 0;
 
-out_fc4_probe_failure:
-       bfad_fc4_probe_undo(bfad);
-       bfad_uncfg_pport(bfad);
-out_cfg_pport_failure:
+out_start_ops_failure:
        bfad_drv_uninit(bfad);
 out_drv_init_failure:
+       kthread_stop(bfad->bfad_tsk);
+out_kthread_create_failure:
        mutex_lock(&bfad_mutex);
        bfad_inst--;
        list_del(&bfad->list_entry);
@@ -1008,6 +1096,11 @@ bfad_pci_remove(struct pci_dev *pdev)
 
        bfa_trc(bfad, bfad->inst_no);
 
+       spin_lock_irqsave(&bfad->bfad_lock, flags);
+       if (bfad->bfad_tsk != NULL)
+               kthread_stop(bfad->bfad_tsk);
+       spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
        if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE)
            && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
 
@@ -1024,13 +1117,25 @@ bfad_pci_remove(struct pci_dev *pdev)
                goto remove_sysfs;
        }
 
-       if (bfad->bfad_flags & BFAD_HAL_START_DONE)
+       if (bfad->bfad_flags & BFAD_HAL_START_DONE) {
                bfad_drv_stop(bfad);
+       } else if (bfad->bfad_flags & BFAD_DRV_INIT_DONE) {
+               /* Invoking bfa_stop() before bfa_detach
+                * when HAL and DRV init are success
+                * but HAL start did not occur.
+                */
+               spin_lock_irqsave(&bfad->bfad_lock, flags);
+               init_completion(&bfad->comp);
+               bfa_stop(&bfad->bfa);
+               spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+               wait_for_completion(&bfad->comp);
+       }
 
        bfad_remove_intr(bfad);
-
        del_timer_sync(&bfad->hal_tmo);
-       bfad_fc4_probe_undo(bfad);
+
+       if (bfad->bfad_flags & BFAD_FC4_PROBE_DONE)
+               bfad_fc4_probe_undo(bfad);
 
        if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE)
                bfad_uncfg_pport(bfad);
index 9129ae3040ff3d85a2a0a98d6db9b4cfbcaecc78..6a2efdd5ef24b5b4ce3d675a3e10d708e695348e 100644 (file)
@@ -19,6 +19,7 @@
  *  bfa_attr.c Linux driver configuration interface module.
  */
 
+#include <linux/slab.h>
 #include "bfad_drv.h"
 #include "bfad_im.h"
 #include "bfad_trcmod.h"
@@ -141,7 +142,7 @@ bfad_im_get_host_port_type(struct Scsi_Host *shost)
        struct bfad_s         *bfad = im_port->bfad;
        struct bfa_pport_attr_s attr;
 
-       bfa_pport_get_attr(&bfad->bfa, &attr);
+       bfa_fcport_get_attr(&bfad->bfa, &attr);
 
        switch (attr.port_type) {
        case BFA_PPORT_TYPE_NPORT:
@@ -173,7 +174,7 @@ bfad_im_get_host_port_state(struct Scsi_Host *shost)
        struct bfad_s         *bfad = im_port->bfad;
        struct bfa_pport_attr_s attr;
 
-       bfa_pport_get_attr(&bfad->bfa, &attr);
+       bfa_fcport_get_attr(&bfad->bfa, &attr);
 
        switch (attr.port_state) {
        case BFA_PPORT_ST_LINKDOWN:
@@ -229,8 +230,10 @@ bfad_im_get_host_speed(struct Scsi_Host *shost)
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
        struct bfa_pport_attr_s attr;
+       unsigned long   flags;
 
-       bfa_pport_get_attr(&bfad->bfa, &attr);
+       spin_lock_irqsave(shost->host_lock, flags);
+       bfa_fcport_get_attr(&bfad->bfa, &attr);
        switch (attr.speed) {
        case BFA_PPORT_SPEED_8GBPS:
                fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
@@ -248,6 +251,7 @@ bfad_im_get_host_speed(struct Scsi_Host *shost)
                fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
                break;
        }
+       spin_unlock_irqrestore(shost->host_lock, flags);
 }
 
 /**
@@ -285,7 +289,7 @@ bfad_im_get_stats(struct Scsi_Host *shost)
        init_completion(&fcomp.comp);
        spin_lock_irqsave(&bfad->bfad_lock, flags);
        memset(hstats, 0, sizeof(struct fc_host_statistics));
-       rc = bfa_pport_get_stats(&bfad->bfa,
+       rc =  bfa_port_get_stats(BFA_FCPORT(&bfad->bfa),
                                     (union bfa_pport_stats_u *) hstats,
                                     bfad_hcb_comp, &fcomp);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -312,7 +316,8 @@ bfad_im_reset_stats(struct Scsi_Host *shost)
 
        init_completion(&fcomp.comp);
        spin_lock_irqsave(&bfad->bfad_lock, flags);
-       rc = bfa_pport_clear_stats(&bfad->bfa, bfad_hcb_comp, &fcomp);
+       rc = bfa_port_clear_stats(BFA_FCPORT(&bfad->bfa), bfad_hcb_comp,
+               &fcomp);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
        if (rc != BFA_STATUS_OK)
@@ -421,12 +426,10 @@ bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr,
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
-       struct bfa_ioc_attr_s  ioc_attr;
+       char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
 
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
-       return snprintf(buf, PAGE_SIZE, "%s\n",
-                       ioc_attr.adapter_attr.serial_num);
+       bfa_get_adapter_serial_num(&bfad->bfa, serial_num);
+       return snprintf(buf, PAGE_SIZE, "%s\n", serial_num);
 }
 
 static ssize_t
@@ -437,11 +440,10 @@ bfad_im_model_show(struct device *dev, struct device_attribute *attr,
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
-       struct bfa_ioc_attr_s  ioc_attr;
+       char model[BFA_ADAPTER_MODEL_NAME_LEN];
 
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
-       return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.model);
+       bfa_get_adapter_model(&bfad->bfa, model);
+       return snprintf(buf, PAGE_SIZE, "%s\n", model);
 }
 
 static ssize_t
@@ -452,12 +454,10 @@ bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr,
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
-       struct bfa_ioc_attr_s  ioc_attr;
+       char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN];
 
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
-       return snprintf(buf, PAGE_SIZE, "%s\n",
-                       ioc_attr.adapter_attr.model_descr);
+       bfa_get_adapter_model(&bfad->bfa, model_descr);
+       return snprintf(buf, PAGE_SIZE, "%s\n", model_descr);
 }
 
 static ssize_t
@@ -482,14 +482,13 @@ bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr,
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
-       struct bfa_ioc_attr_s  ioc_attr;
-
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
+       char model[BFA_ADAPTER_MODEL_NAME_LEN];
+       char fw_ver[BFA_VERSION_LEN];
 
+       bfa_get_adapter_model(&bfad->bfa, model);
+       bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
        return snprintf(buf, PAGE_SIZE, "Brocade %s FV%s DV%s\n",
-                       ioc_attr.adapter_attr.model,
-                       ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION);
+               model, fw_ver, BFAD_DRIVER_VERSION);
 }
 
 static ssize_t
@@ -500,11 +499,10 @@ bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr,
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
-       struct bfa_ioc_attr_s  ioc_attr;
+       char hw_ver[BFA_VERSION_LEN];
 
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
-       return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.hw_ver);
+       bfa_get_pci_chip_rev(&bfad->bfa, hw_ver);
+       return snprintf(buf, PAGE_SIZE, "%s\n", hw_ver);
 }
 
 static ssize_t
@@ -522,12 +520,10 @@ bfad_im_optionrom_version_show(struct device *dev,
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
-       struct bfa_ioc_attr_s  ioc_attr;
+       char optrom_ver[BFA_VERSION_LEN];
 
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
-       return snprintf(buf, PAGE_SIZE, "%s\n",
-                       ioc_attr.adapter_attr.optrom_ver);
+       bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver);
+       return snprintf(buf, PAGE_SIZE, "%s\n", optrom_ver);
 }
 
 static ssize_t
@@ -538,11 +534,10 @@ bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr,
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
-       struct bfa_ioc_attr_s  ioc_attr;
+       char fw_ver[BFA_VERSION_LEN];
 
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
-       return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.fw_ver);
+       bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
+       return snprintf(buf, PAGE_SIZE, "%s\n", fw_ver);
 }
 
 static ssize_t
@@ -553,11 +548,9 @@ bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr,
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
        struct bfad_s         *bfad = im_port->bfad;
-       struct bfa_ioc_attr_s  ioc_attr;
 
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
-       return snprintf(buf, PAGE_SIZE, "%d\n", ioc_attr.adapter_attr.nports);
+       return snprintf(buf, PAGE_SIZE, "%d\n",
+               bfa_get_nports(&bfad->bfa));
 }
 
 static ssize_t
index 4d3312da6a819a353ae30b1d712a8c99f7ff527b..bf0102076508f3636f5ff35c64a470ee1bb36a9b 100644 (file)
@@ -17,9 +17,6 @@
 
 #ifndef __BFAD_ATTR_H__
 #define __BFAD_ATTR_H__
-/**
- *  bfad_attr.h VMware driver configuration interface module.
- */
 
 /**
  *  FC_transport_template FC transport template
@@ -52,12 +49,6 @@ bfad_im_get_starget_port_name(struct scsi_target *starget);
 void
 bfad_im_get_host_port_id(struct Scsi_Host *shost);
 
-/**
- * FC transport template entry, issue a LIP.
- */
-int
-bfad_im_issue_fc_host_lip(struct Scsi_Host *shost);
-
 struct Scsi_Host*
 bfad_os_starget_to_shost(struct scsi_target *starget);
 
index 172c81e25c1c8b46c7bb1110c68332b3db9d8987..107848cd3b6df2f40eaad3643fce95a11e8f54be 100644 (file)
@@ -46,7 +46,7 @@
 #ifdef BFA_DRIVER_VERSION
 #define BFAD_DRIVER_VERSION    BFA_DRIVER_VERSION
 #else
-#define BFAD_DRIVER_VERSION    "2.0.0.0"
+#define BFAD_DRIVER_VERSION    "2.1.2.1"
 #endif
 
 
@@ -62,7 +62,9 @@
 #define BFAD_HAL_START_DONE                    0x00000010
 #define BFAD_PORT_ONLINE                       0x00000020
 #define BFAD_RPORT_ONLINE                      0x00000040
-
+#define BFAD_FCS_INIT_DONE                      0x00000080
+#define BFAD_HAL_INIT_FAIL                      0x00000100
+#define BFAD_FC4_PROBE_DONE                     0x00000200
 #define BFAD_PORT_DELETE                       0x00000001
 
 /*
@@ -137,12 +139,16 @@ struct bfad_cfg_param_s {
        u32        binding_method;
 };
 
-#define BFAD_AEN_MAX_APPS 8
-struct bfad_aen_file_s {
-       struct list_head  qe;
-       struct bfad_s *bfad;
-       s32 ri;
-       s32 app_id;
+union bfad_tmp_buf {
+       /* From struct bfa_adapter_attr_s */
+       char            manufacturer[BFA_ADAPTER_MFG_NAME_LEN];
+       char            serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
+       char            model[BFA_ADAPTER_MODEL_NAME_LEN];
+       char            fw_ver[BFA_VERSION_LEN];
+       char            optrom_ver[BFA_VERSION_LEN];
+
+       /* From struct bfa_ioc_pci_attr_s */
+       u8         chip_rev[BFA_IOC_CHIP_REV_LEN];  /*  chip revision */
 };
 
 /*
@@ -168,6 +174,7 @@ struct bfad_s {
        u32        inst_no;     /* BFAD instance number */
        u32        bfad_flags;
        spinlock_t      bfad_lock;
+       struct task_struct *bfad_tsk;
        struct bfad_cfg_param_s cfg_data;
        struct bfad_msix_s msix_tab[MAX_MSIX_ENTRY];
        int             nvec;
@@ -183,18 +190,12 @@ struct bfad_s {
        struct bfa_log_mod_s  *logmod;
        struct bfa_aen_s      *aen;
        struct bfa_aen_s       aen_buf;
-       struct bfad_aen_file_s file_buf[BFAD_AEN_MAX_APPS];
-       struct list_head         file_q;
-       struct list_head         file_free_q;
+       void            *file_map[BFA_AEN_MAX_APP];
        struct bfa_plog_s      plog_buf;
        int             ref_count;
        bfa_boolean_t   ipfc_enabled;
+       union bfad_tmp_buf tmp_buf;
        struct fc_host_statistics link_stats;
-
-       struct kobject *bfa_kobj;
-       struct kobject *ioc_kobj;
-       struct kobject *pport_kobj;
-       struct kobject *lport_kobj;
 };
 
 /*
@@ -258,6 +259,7 @@ bfa_status_t    bfad_vf_create(struct bfad_s *bfad, u16 vf_id,
                               struct bfa_port_cfg_s *port_cfg);
 bfa_status_t    bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role);
 bfa_status_t    bfad_drv_init(struct bfad_s *bfad);
+bfa_status_t   bfad_start_ops(struct bfad_s *bfad);
 void            bfad_drv_start(struct bfad_s *bfad);
 void            bfad_uncfg_pport(struct bfad_s *bfad);
 void            bfad_drv_stop(struct bfad_s *bfad);
@@ -279,6 +281,7 @@ void                bfad_drv_uninit(struct bfad_s *bfad);
 void           bfad_drv_log_level_set(struct bfad_s *bfad);
 bfa_status_t   bfad_fc4_module_init(void);
 void           bfad_fc4_module_exit(void);
+int            bfad_worker (void *ptr);
 
 void bfad_pci_remove(struct pci_dev *pdev);
 int bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid);
index f788c2a0ab07a6d5ab9ac39397557b5dc21fc758..78f42aa57369572785d83e803a2a9db45a0b66a0 100644 (file)
@@ -19,6 +19,7 @@
  *  bfad_im.c Linux driver IM module.
  */
 
+#include <linux/slab.h>
 #include "bfad_drv.h"
 #include "bfad_im.h"
 #include "bfad_trcmod.h"
@@ -43,11 +44,11 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio,
        struct bfad_s         *bfad = drv;
        struct bfad_itnim_data_s *itnim_data;
        struct bfad_itnim_s *itnim;
+       u8         host_status = DID_OK;
 
        switch (io_status) {
        case BFI_IOIM_STS_OK:
                bfa_trc(bfad, scsi_status);
-               cmnd->result = ScsiResult(DID_OK, scsi_status);
                scsi_set_resid(cmnd, 0);
 
                if (sns_len > 0) {
@@ -56,8 +57,18 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio,
                                sns_len = SCSI_SENSE_BUFFERSIZE;
                        memcpy(cmnd->sense_buffer, sns_info, sns_len);
                }
-               if (residue > 0)
+               if (residue > 0) {
+                       bfa_trc(bfad, residue);
                        scsi_set_resid(cmnd, residue);
+                       if (!sns_len && (scsi_status == SAM_STAT_GOOD) &&
+                               (scsi_bufflen(cmnd) - residue) <
+                                       cmnd->underflow) {
+                               bfa_trc(bfad, 0);
+                               host_status = DID_ERROR;
+                       }
+               }
+               cmnd->result = ScsiResult(host_status, scsi_status);
+
                break;
 
        case BFI_IOIM_STS_ABORTED:
@@ -167,17 +178,15 @@ bfad_im_info(struct Scsi_Host *shost)
        static char     bfa_buf[256];
        struct bfad_im_port_s *im_port =
                        (struct bfad_im_port_s *) shost->hostdata[0];
-       struct bfa_ioc_attr_s  ioc_attr;
        struct bfad_s         *bfad = im_port->bfad;
+       char model[BFA_ADAPTER_MODEL_NAME_LEN];
 
-       memset(&ioc_attr, 0, sizeof(ioc_attr));
-       bfa_get_attr(&bfad->bfa, &ioc_attr);
+       bfa_get_adapter_model(&bfad->bfa, model);
 
        memset(bfa_buf, 0, sizeof(bfa_buf));
        snprintf(bfa_buf, sizeof(bfa_buf),
-                "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s",
-                ioc_attr.adapter_attr.model, bfad->pci_name,
-                BFAD_DRIVER_VERSION);
+               "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s",
+               model, bfad->pci_name, BFAD_DRIVER_VERSION);
        return bfa_buf;
 }
 
@@ -500,16 +509,6 @@ void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim)
        itnim->state = ITNIM_STATE_TIMEOUT;
 }
 
-/**
- * Path TOV processing begin notification -- dummy for linux
- */
-void
-bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim)
-{
-}
-
-
-
 /**
  * Allocate a Scsi_Host for a port.
  */
@@ -931,10 +930,9 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port)
        struct Scsi_Host *host = im_port->shost;
        struct bfad_s         *bfad = im_port->bfad;
        struct bfad_port_s    *port = im_port->port;
-       union attr {
-               struct bfa_pport_attr_s pattr;
-               struct bfa_ioc_attr_s  ioc_attr;
-       } attr;
+       struct bfa_pport_attr_s pattr;
+       char model[BFA_ADAPTER_MODEL_NAME_LEN];
+       char fw_ver[BFA_VERSION_LEN];
 
        fc_host_node_name(host) =
                bfa_os_htonll((bfa_fcs_port_get_nwwn(port->fcs_port)));
@@ -954,20 +952,18 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port)
        /* For fibre channel services type 0x20 */
        fc_host_supported_fc4s(host)[7] = 1;
 
-       memset(&attr.ioc_attr, 0, sizeof(attr.ioc_attr));
-       bfa_get_attr(&bfad->bfa, &attr.ioc_attr);
+       bfa_get_adapter_model(&bfad->bfa, model);
+       bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
        sprintf(fc_host_symbolic_name(host), "Brocade %s FV%s DV%s",
-               attr.ioc_attr.adapter_attr.model,
-               attr.ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION);
+               model, fw_ver, BFAD_DRIVER_VERSION);
 
        fc_host_supported_speeds(host) = 0;
        fc_host_supported_speeds(host) |=
                FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT |
                FC_PORTSPEED_1GBIT;
 
-       memset(&attr.pattr, 0, sizeof(attr.pattr));
-       bfa_pport_get_attr(&bfad->bfa, &attr.pattr);
-       fc_host_maxframe_size(host) = attr.pattr.pport_cfg.maxfrsize;
+       bfa_fcport_get_attr(&bfad->bfa, &pattr);
+       fc_host_maxframe_size(host) = pattr.pport_cfg.maxfrsize;
 }
 
 static void
index 189a5b29e21ad1e086bf690152041a44d16b32e3..85ab2da21321b3124349ca989b8c53539d50dc1f 100644 (file)
@@ -23,7 +23,6 @@
 
 #define FCPI_NAME " fcpim"
 
-void bfad_flags_set(struct bfad_s *bfad, u32 flags);
 bfa_status_t bfad_im_module_init(void);
 void bfad_im_module_exit(void);
 bfa_status_t bfad_im_probe(struct bfad_s *bfad);
@@ -126,7 +125,6 @@ bfa_status_t bfad_os_thread_workq(struct bfad_s *bfad);
 void bfad_os_destroy_workq(struct bfad_im_s *im);
 void bfad_os_itnim_process(struct bfad_itnim_s *itnim_drv);
 void bfad_os_fc_host_init(struct bfad_im_port_s *im_port);
-void bfad_os_init_work(struct bfad_im_port_s *im_port);
 void bfad_os_scsi_host_free(struct bfad_s *bfad,
                                 struct bfad_im_port_s *im_port);
 void bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim,
@@ -136,9 +134,6 @@ struct bfad_itnim_s *bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id);
 int bfad_os_scsi_add_host(struct Scsi_Host *shost,
                struct bfad_im_port_s *im_port, struct bfad_s *bfad);
 
-/*
- * scsi_host_template entries
- */
 void bfad_im_itnim_unmap(struct bfad_im_port_s  *im_port,
                         struct bfad_itnim_s *itnim);
 
index 7de8832f6feefd6e1f41f837e78be9232e3f2c05..2b7dbecbebcaddf2ddd1873e55f6c64adaaee662 100644 (file)
@@ -23,8 +23,10 @@ BFA_TRC_FILE(LDRV, INTR);
 /**
  *  bfa_isr BFA driver interrupt functions
  */
-static int msix_disable;
-module_param(msix_disable, int, S_IRUGO | S_IWUSR);
+static int msix_disable_cb;
+static int msix_disable_ct;
+module_param(msix_disable_cb, int, S_IRUGO | S_IWUSR);
+module_param(msix_disable_ct, int, S_IRUGO | S_IWUSR);
 /**
  * Line based interrupt handler.
  */
@@ -141,6 +143,7 @@ bfad_setup_intr(struct bfad_s *bfad)
        int error = 0;
        u32 mask = 0, i, num_bit = 0, max_bit = 0;
        struct msix_entry msix_entries[MAX_MSIX_ENTRY];
+       struct pci_dev *pdev = bfad->pcidev;
 
        /* Call BFA to get the msix map for this PCI function.  */
        bfa_msix_getvecs(&bfad->bfa, &mask, &num_bit, &max_bit);
@@ -148,7 +151,9 @@ bfad_setup_intr(struct bfad_s *bfad)
        /* Set up the msix entry table */
        bfad_init_msix_entry(bfad, msix_entries, mask, max_bit);
 
-       if (!msix_disable) {
+       if ((pdev->device == BFA_PCI_DEVICE_ID_CT && !msix_disable_ct) ||
+           (pdev->device != BFA_PCI_DEVICE_ID_CT && !msix_disable_cb)) {
+
                error = pci_enable_msix(bfad->pcidev, msix_entries, bfad->nvec);
                if (error) {
                        /*
index a4b5dd449573c38a490381a8143d703bededde39..8166e9745ec07a21f7b43abb451a02809c620d78 100644 (file)
@@ -37,7 +37,7 @@ BFA_TRC_FILE(FCS, FABRIC);
 #define BFA_FCS_FABRIC_CLEANUP_DELAY   (10000) /* Milliseconds */
 
 #define bfa_fcs_fabric_set_opertype(__fabric) do {             \
-       if (bfa_pport_get_topology((__fabric)->fcs->bfa)       \
+       if (bfa_fcport_get_topology((__fabric)->fcs->bfa)       \
                                == BFA_PPORT_TOPOLOGY_P2P)     \
                (__fabric)->oper_type = BFA_PPORT_TYPE_NPORT;  \
        else                                                   \
@@ -136,8 +136,7 @@ bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
        case BFA_FCS_FABRIC_SM_CREATE:
                bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
                bfa_fcs_fabric_init(fabric);
-               bfa_fcs_lport_init(&fabric->bport, fabric->fcs, FC_VF_ID_NULL,
-                                  &fabric->bport.port_cfg, NULL);
+               bfa_fcs_lport_init(&fabric->bport, &fabric->bport.port_cfg);
                break;
 
        case BFA_FCS_FABRIC_SM_LINK_UP:
@@ -161,7 +160,7 @@ bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
 
        switch (event) {
        case BFA_FCS_FABRIC_SM_START:
-               if (bfa_pport_is_linkup(fabric->fcs->bfa)) {
+               if (bfa_fcport_is_linkup(fabric->fcs->bfa)) {
                        bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
                        bfa_fcs_fabric_login(fabric);
                } else
@@ -225,7 +224,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
        switch (event) {
        case BFA_FCS_FABRIC_SM_CONT_OP:
 
-               bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
+               bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
                fabric->fab_type = BFA_FCS_FABRIC_SWITCHED;
 
                if (fabric->auth_reqd && fabric->is_auth) {
@@ -252,7 +251,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
 
        case BFA_FCS_FABRIC_SM_NO_FABRIC:
                fabric->fab_type = BFA_FCS_FABRIC_N2N;
-               bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
+               bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
                bfa_fcs_fabric_notify_online(fabric);
                bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric);
                break;
@@ -419,7 +418,7 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
 
        case BFA_FCS_FABRIC_SM_NO_FABRIC:
                bfa_trc(fabric->fcs, fabric->bb_credit);
-               bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
+               bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
                break;
 
        default:
@@ -563,17 +562,15 @@ void
 bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
 {
        struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg;
-       struct bfa_adapter_attr_s adapter_attr;
+       char            model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
        struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
 
-       bfa_os_memset((void *)&adapter_attr, 0,
-                     sizeof(struct bfa_adapter_attr_s));
-       bfa_ioc_get_adapter_attr(&fabric->fcs->bfa->ioc, &adapter_attr);
+       bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
 
        /*
         * Model name/number
         */
-       strncpy((char *)&port_cfg->sym_name, adapter_attr.model,
+       strncpy((char *)&port_cfg->sym_name, model,
                BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
        strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
                sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
@@ -719,10 +716,10 @@ bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
        struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg;
        u8         alpa = 0;
 
-       if (bfa_pport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP)
-               alpa = bfa_pport_get_myalpa(bfa);
+       if (bfa_fcport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP)
+               alpa = bfa_fcport_get_myalpa(bfa);
 
-       bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_pport_get_maxfrsize(bfa),
+       bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa),
                      pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd);
 
        fabric->stats.flogi_sent++;
@@ -814,10 +811,10 @@ bfa_fcs_fabric_delete_comp(void *cbarg)
  */
 
 /**
- *   Module initialization
+ *   Attach time initialization
  */
 void
-bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
+bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs)
 {
        struct bfa_fcs_fabric_s *fabric;
 
@@ -841,7 +838,13 @@ bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
        bfa_wc_up(&fabric->wc); /* For the base port */
 
        bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
-       bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CREATE);
+       bfa_fcs_lport_attach(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, NULL);
+}
+
+void
+bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
+{
+       bfa_sm_send_event(&fcs->fabric, BFA_FCS_FABRIC_SM_CREATE);
        bfa_trc(fcs, 0);
 }
 
@@ -890,6 +893,12 @@ bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric)
        return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback);
 }
 
+bfa_boolean_t
+bfa_fcs_fabric_is_auth_failed(struct bfa_fcs_fabric_s *fabric)
+{
+       return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_auth_failed);
+}
+
 enum bfa_pport_type
 bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric)
 {
@@ -1165,8 +1174,8 @@ bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
        reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
                                    bfa_os_hton3b(FC_FABRIC_PORT),
                                    n2n_port->reply_oxid, pcfg->pwwn,
-                                   pcfg->nwwn, bfa_pport_get_maxfrsize(bfa),
-                                   bfa_pport_get_rx_bbcredit(bfa));
+                                   pcfg->nwwn, bfa_fcport_get_maxfrsize(bfa),
+                                   bfa_fcport_get_rx_bbcredit(bfa));
 
        bfa_fcxp_send(fcxp, NULL, fabric->vf_id, bfa_lps_get_tag(fabric->lps),
                        BFA_FALSE, FC_CLASS_3, reqlen, &fchs,
@@ -1224,14 +1233,8 @@ bfa_fcs_fabric_aen_post(struct bfa_fcs_port_s *port,
        wwn2str(pwwn_ptr, pwwn);
        wwn2str(fwwn_ptr, fwwn);
 
-       switch (event) {
-       case BFA_PORT_AEN_FABRIC_NAME_CHANGE:
-               bfa_log(logmod, BFA_AEN_PORT_FABRIC_NAME_CHANGE, pwwn_ptr,
-                       fwwn_ptr);
-               break;
-       default:
-               break;
-       }
+       bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event),
+               pwwn_ptr, fwwn_ptr);
 
        aen_data.port.pwwn = pwwn;
        aen_data.port.fwwn = fwwn;
index 8fa7f270ef7b85c9a938a4051c90fb343efd10a8..981d98d542b90ece26acd3dcf5a634f4bedc699a 100644 (file)
@@ -72,6 +72,9 @@ fc_rpsc_operspeed_to_bfa_speed(enum fc_rpsc_op_speed_s speed)
        case RPSC_OP_SPEED_8G:
                return BFA_PPORT_SPEED_8GBPS;
 
+       case RPSC_OP_SPEED_10G:
+               return BFA_PPORT_SPEED_10GBPS;
+
        default:
                return BFA_PPORT_SPEED_UNKNOWN;
        }
@@ -97,6 +100,9 @@ fc_bfa_speed_to_rpsc_operspeed(enum bfa_pport_speed op_speed)
        case BFA_PPORT_SPEED_8GBPS:
                return RPSC_OP_SPEED_8G;
 
+       case BFA_PPORT_SPEED_10GBPS:
+               return RPSC_OP_SPEED_10G;
+
        default:
                return RPSC_OP_SPEED_NOT_EST;
        }
index 1f3c06efaa9ea42d7a7325e8fd8b2bec678928f7..8ae4a2cfa85b94bbafdf41277aadd34322a40cde 100644 (file)
@@ -126,7 +126,7 @@ bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->fcs, event);
        }
 
 }
@@ -161,7 +161,7 @@ bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->fcs, event);
        }
 }
 
@@ -205,7 +205,7 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->fcs, event);
        }
 }
 
@@ -240,7 +240,7 @@ bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->fcs, event);
        }
 }
 
@@ -270,7 +270,7 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->fcs, event);
        }
 }
 
@@ -298,7 +298,7 @@ bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->fcs, event);
        }
 }
 
@@ -321,7 +321,7 @@ bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->fcs, event);
        }
 }
 
@@ -354,7 +354,7 @@ bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(itnim->fcs, event);
        }
 }
 
@@ -385,19 +385,8 @@ bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
        wwn2str(lpwwn_ptr, lpwwn);
        wwn2str(rpwwn_ptr, rpwwn);
 
-       switch (event) {
-       case BFA_ITNIM_AEN_ONLINE:
-               bfa_log(logmod, BFA_AEN_ITNIM_ONLINE, rpwwn_ptr, lpwwn_ptr);
-               break;
-       case BFA_ITNIM_AEN_OFFLINE:
-               bfa_log(logmod, BFA_AEN_ITNIM_OFFLINE, rpwwn_ptr, lpwwn_ptr);
-               break;
-       case BFA_ITNIM_AEN_DISCONNECT:
-               bfa_log(logmod, BFA_AEN_ITNIM_DISCONNECT, rpwwn_ptr, lpwwn_ptr);
-               break;
-       default:
-               break;
-       }
+       bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_ITNIM, event),
+               rpwwn_ptr, lpwwn_ptr);
 
        aen_data.itnim.vf_id = rport->port->fabric->vf_id;
        aen_data.itnim.ppwwn =
@@ -689,7 +678,6 @@ bfa_cb_itnim_tov_begin(void *cb_arg)
        struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg;
 
        bfa_trc(itnim->fcs, itnim->rport->pwwn);
-       bfa_fcb_itnim_tov_begin(itnim->itnim_drv);
 }
 
 /**
@@ -822,22 +810,3 @@ void
 bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim)
 {
 }
-
-/**
- *   Module initialization
- */
-void
-bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs)
-{
-}
-
-/**
- *   Module cleanup
- */
-void
-bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs)
-{
-       bfa_fcs_modexit_comp(fcs);
-}
-
-
index eee960820f86c967cb5fd4fa9673bd03c0fe0b26..244c3f00c50c8b65c0ffc51c1af69beba73bdd7c 100644 (file)
@@ -29,6 +29,7 @@
 /*
 * fcs friend functions: only between fcs modules
  */
+void           bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs);
 void            bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs);
 void            bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs);
 void            bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs);
@@ -46,6 +47,7 @@ void            bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric,
                        struct fchs_s *fchs, u16 len);
 u16        bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric);
 bfa_boolean_t   bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric);
+bfa_boolean_t  bfa_fcs_fabric_is_auth_failed(struct bfa_fcs_fabric_s *fabric);
 enum bfa_pport_type bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric);
 void           bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric);
 void bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric);
index 61e9e2687de3c5e734d0df523a02f91e54928ff9..11e6e7bce9f63664134bfa9dab231c5dbfec00ab 100644 (file)
@@ -34,11 +34,6 @@ void bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim);
 void bfa_fcs_itnim_pause(struct bfa_fcs_itnim_s *itnim);
 void bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim);
 
-/*
- * Modudle init/cleanup routines.
- */
-void bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs);
 void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, struct fchs_s *fchs,
                        u16 len);
 #endif /* __FCS_FCPIM_H__ */
index ae744ba356714bda035c7c1fdce9cd3bd6828c47..a6508c8ab184c9260c93c1706e052d684a27f74d 100644 (file)
@@ -84,9 +84,10 @@ void bfa_fcs_port_uf_recv(struct bfa_fcs_port_s *lport, struct fchs_s *fchs,
  * Following routines will be called by Fabric to indicate port
  * online/offline to vport.
  */
-void bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
-                       u16 vf_id, struct bfa_port_cfg_s *port_cfg,
-                       struct bfa_fcs_vport_s *vport);
+void bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
+                       uint16_t vf_id, struct bfa_fcs_vport_s *vport);
+void bfa_fcs_lport_init(struct bfa_fcs_port_s *lport,
+                       struct bfa_port_cfg_s *port_cfg);
 void bfa_fcs_port_online(struct bfa_fcs_port_s *port);
 void bfa_fcs_port_offline(struct bfa_fcs_port_s *port);
 void bfa_fcs_port_delete(struct bfa_fcs_port_s *port);
index abb65191dd27de55a0b962499e2ac7af75397245..408c06a7d164cb1879ee188b8f03836db7c4df67 100644 (file)
@@ -26,7 +26,6 @@
 /*
  * fcs friend functions: only between fcs modules
  */
-void bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs);
+void bfa_fcs_pport_attach(struct bfa_fcs_s *fcs);
 
 #endif /* __FCS_PPORT_H__ */
index f601e9d742360eb2ad002306a306cc3788c59879..9c8d1d2923807b759549f2eaffc0a2858ad9f7b4 100644 (file)
@@ -24,9 +24,6 @@
 
 #include <fcs/bfa_fcs_rport.h>
 
-void bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs);
-
 void bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs,
                        u16 len);
 void bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport);
index 96f1bdcb31ed35da8f8c5394d19206e5430f1111..f591072214febc7c64707c2347f4ef89fa77dc2a 100644 (file)
@@ -26,7 +26,6 @@
 /*
  * fcs friend functions: only between fcs modules
  */
-void bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs);
+void bfa_fcs_uf_attach(struct bfa_fcs_s *fcs);
 
 #endif /* __FCS_UF_H__ */
index 9e80b6a97b7f6c28fcd06a21fc7d7d0901120c49..13c32ebf946ca54ba7226e1304c093699e9d2586 100644 (file)
 #include <fcs/bfa_fcs_vport.h>
 #include <defs/bfa_defs_pci.h>
 
-/*
- * Modudle init/cleanup routines.
- */
-
-void bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs);
-void bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs);
-
 void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport);
 void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport);
 void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport);
 void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport);
-u32 bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs);
 
 #endif /* __FCS_VPORT_H__ */
 
index df2a1e54e16bb3e2d28aff9826258a957951bc22..8f17076d1a8786589d4a92dfbfbc86da2a42a2ba 100644 (file)
@@ -116,6 +116,9 @@ static void     bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi,
                        enum port_fdmi_event event);
 static void     bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi,
                        enum port_fdmi_event event);
+static void    bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s *fdmi,
+                       enum port_fdmi_event event);
+
 /**
  *             Start in offline state - awaiting MS to send start.
  */
@@ -155,7 +158,7 @@ bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -180,7 +183,7 @@ bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -227,7 +230,7 @@ bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -255,7 +258,7 @@ bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -283,7 +286,7 @@ bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -328,7 +331,7 @@ bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -356,7 +359,7 @@ bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -384,7 +387,7 @@ bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -428,7 +431,7 @@ bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -456,7 +459,7 @@ bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
@@ -475,10 +478,24 @@ bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(port->fcs, event);
        }
 }
 
+/**
+ *  FDMI is disabled state.
+ */
+static void
+bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s *fdmi,
+                               enum port_fdmi_event event)
+{
+       struct bfa_fcs_port_s *port = fdmi->ms->port;
+
+       bfa_trc(port->fcs, port->port_cfg.pwwn);
+       bfa_trc(port->fcs, event);
+
+       /* No op State. It can only be enabled at Driver Init. */
+}
 
 /**
 *   RHBA : Register HBA Attributes.
@@ -1097,36 +1114,23 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
 {
        struct bfa_fcs_port_s *port = fdmi->ms->port;
        struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
-       struct bfa_adapter_attr_s adapter_attr;
 
        bfa_os_memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
-       bfa_os_memset(&adapter_attr, 0, sizeof(struct bfa_adapter_attr_s));
-
-       bfa_ioc_get_adapter_attr(&port->fcs->bfa->ioc, &adapter_attr);
-
-       strncpy(hba_attr->manufacturer, adapter_attr.manufacturer,
-               sizeof(adapter_attr.manufacturer));
-
-       strncpy(hba_attr->serial_num, adapter_attr.serial_num,
-               sizeof(adapter_attr.serial_num));
 
-       strncpy(hba_attr->model, adapter_attr.model, sizeof(hba_attr->model));
-
-       strncpy(hba_attr->model_desc, adapter_attr.model_descr,
-               sizeof(hba_attr->model_desc));
-
-       strncpy(hba_attr->hw_version, adapter_attr.hw_ver,
-               sizeof(hba_attr->hw_version));
+       bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc,
+               hba_attr->manufacturer);
+       bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc,
+                                               hba_attr->serial_num);
+       bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, hba_attr->model);
+       bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, hba_attr->model_desc);
+       bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc, hba_attr->hw_version);
+       bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc,
+               hba_attr->option_rom_ver);
+       bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc, hba_attr->fw_version);
 
        strncpy(hba_attr->driver_version, (char *)driver_info->version,
                sizeof(hba_attr->driver_version));
 
-       strncpy(hba_attr->option_rom_ver, adapter_attr.optrom_ver,
-               sizeof(hba_attr->option_rom_ver));
-
-       strncpy(hba_attr->fw_version, adapter_attr.fw_ver,
-               sizeof(hba_attr->fw_version));
-
        strncpy(hba_attr->os_name, driver_info->host_os_name,
                sizeof(hba_attr->os_name));
 
@@ -1158,7 +1162,7 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
        /*
         * get pport attributes from hal
         */
-       bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
+       bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
 
        /*
         * get FC4 type Bitmask
@@ -1201,7 +1205,10 @@ bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s *ms)
        struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
 
        fdmi->ms = ms;
-       bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
+       if (ms->port->fcs->fdmi_enabled)
+               bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
+       else
+               bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_disabled);
 }
 
 void
index d9cbc2a783d49a73eba6bebe902dc03043d9ca40..6abbab005db6d7855fa4fe1a9b502a5d9b489114 100644 (file)
 #define __BFA_AEN_H__
 
 #include "defs/bfa_defs_aen.h"
+#include "defs/bfa_defs_status.h"
+#include "cs/bfa_debug.h"
 
-#define BFA_AEN_MAX_ENTRY   512
+#define BFA_AEN_MAX_ENTRY      512
 
-extern s32 bfa_aen_max_cfg_entry;
+extern int bfa_aen_max_cfg_entry;
 struct bfa_aen_s {
        void            *bfad;
-       s32             max_entry;
-       s32             write_index;
-       s32             read_index;
-       u32     bfad_num;
-       u32     seq_num;
+       int             max_entry;
+       int             write_index;
+       int             read_index;
+       int             bfad_num;
+       int             seq_num;
        void            (*aen_cb_notify)(void *bfad);
        void            (*gettimeofday)(struct bfa_timeval_s *tv);
-       struct bfa_trc_mod_s    *trcmod;
-       struct bfa_aen_entry_s  list[BFA_AEN_MAX_ENTRY]; /* Must be the last */
+       struct bfa_trc_mod_s *trcmod;
+       int             app_ri[BFA_AEN_MAX_APP]; /* For multiclient support */
+       struct bfa_aen_entry_s list[BFA_AEN_MAX_ENTRY]; /* Must be the last */
 };
 
 
@@ -45,48 +48,49 @@ bfa_aen_set_max_cfg_entry(int max_entry)
        bfa_aen_max_cfg_entry = max_entry;
 }
 
-static inline s32
+static inline int
 bfa_aen_get_max_cfg_entry(void)
 {
        return bfa_aen_max_cfg_entry;
 }
 
-static inline s32
+static inline int
 bfa_aen_get_meminfo(void)
 {
        return sizeof(struct bfa_aen_entry_s) * bfa_aen_get_max_cfg_entry();
 }
 
-static inline s32
+static inline int
 bfa_aen_get_wi(struct bfa_aen_s *aen)
 {
        return aen->write_index;
 }
 
-static inline s32
+static inline int
 bfa_aen_get_ri(struct bfa_aen_s *aen)
 {
        return aen->read_index;
 }
 
-static inline s32
-bfa_aen_fetch_count(struct bfa_aen_s *aen, s32 read_index)
+static inline int
+bfa_aen_fetch_count(struct bfa_aen_s *aen, enum bfa_aen_app  app_id)
 {
-       return ((aen->write_index + aen->max_entry) - read_index)
+       bfa_assert((app_id < BFA_AEN_MAX_APP) && (app_id >= bfa_aen_app_bcu));
+       return ((aen->write_index + aen->max_entry) - aen->app_ri[app_id])
                % aen->max_entry;
 }
 
-s32 bfa_aen_init(struct bfa_aen_s *aen, struct bfa_trc_mod_s *trcmod,
-               void *bfad, u32 inst_id, void (*aen_cb_notify)(void *),
+int bfa_aen_init(struct bfa_aen_s *aen, struct bfa_trc_mod_s *trcmod,
+               void *bfad, int bfad_num, void (*aen_cb_notify)(void *),
                void (*gettimeofday)(struct bfa_timeval_s *));
 
-s32 bfa_aen_post(struct bfa_aen_s *aen, enum bfa_aen_category aen_category,
+void bfa_aen_post(struct bfa_aen_s *aen, enum bfa_aen_category aen_category,
                     int aen_type, union bfa_aen_data_u *aen_data);
 
-s32 bfa_aen_fetch(struct bfa_aen_s *aen, struct bfa_aen_entry_s *aen_entry,
-                     s32 entry_space, s32 rii, s32 *ri_arr,
-                     s32 ri_arr_cnt);
+bfa_status_t bfa_aen_fetch(struct bfa_aen_s *aen,
+                       struct bfa_aen_entry_s *aen_entry,
+                       int entry_req, enum bfa_aen_app app_id, int *entry_ret);
 
-s32 bfa_aen_get_inst(struct bfa_aen_s *aen);
+int bfa_aen_get_inst(struct bfa_aen_s *aen);
 
 #endif /* __BFA_AEN_H__ */
index d4bc0d9fa42cb831ee5e0db994bd22ab6bdd2b4b..1f5966cfbd166eccbbbd1a708021c277c6bb8b4e 100644 (file)
@@ -106,6 +106,26 @@ struct bfa_sge_s {
        bfa_ioc_fetch_stats(&(__bfa)->ioc, __ioc_stats)
 #define bfa_ioc_clear_stats(__bfa)     \
        bfa_ioc_clr_stats(&(__bfa)->ioc)
+#define bfa_get_nports(__bfa)   \
+       bfa_ioc_get_nports(&(__bfa)->ioc)
+#define bfa_get_adapter_manufacturer(__bfa, __manufacturer) \
+       bfa_ioc_get_adapter_manufacturer(&(__bfa)->ioc, __manufacturer)
+#define bfa_get_adapter_model(__bfa, __model)   \
+       bfa_ioc_get_adapter_model(&(__bfa)->ioc, __model)
+#define bfa_get_adapter_serial_num(__bfa, __serial_num) \
+       bfa_ioc_get_adapter_serial_num(&(__bfa)->ioc, __serial_num)
+#define bfa_get_adapter_fw_ver(__bfa, __fw_ver) \
+       bfa_ioc_get_adapter_fw_ver(&(__bfa)->ioc, __fw_ver)
+#define bfa_get_adapter_optrom_ver(__bfa, __optrom_ver) \
+       bfa_ioc_get_adapter_optrom_ver(&(__bfa)->ioc, __optrom_ver)
+#define bfa_get_pci_chip_rev(__bfa, __chip_rev) \
+       bfa_ioc_get_pci_chip_rev(&(__bfa)->ioc, __chip_rev)
+#define bfa_get_ioc_state(__bfa)    \
+       bfa_ioc_get_state(&(__bfa)->ioc)
+#define bfa_get_type(__bfa) \
+       bfa_ioc_get_type(&(__bfa)->ioc)
+#define bfa_get_mac(__bfa)  \
+       bfa_ioc_get_mac(&(__bfa)->ioc)
 
 /*
  * bfa API functions
@@ -161,6 +181,7 @@ bfa_status_t bfa_iocfc_israttr_set(struct bfa_s *bfa,
 void bfa_iocfc_enable(struct bfa_s *bfa);
 void bfa_iocfc_disable(struct bfa_s *bfa);
 void bfa_ioc_auto_recover(bfa_boolean_t auto_recover);
+void bfa_chip_reset(struct bfa_s *bfa);
 void bfa_cb_ioc_disable(void *bfad);
 void bfa_timer_tick(struct bfa_s *bfa);
 #define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout)        \
@@ -171,6 +192,7 @@ void bfa_timer_tick(struct bfa_s *bfa);
  */
 bfa_status_t bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen);
 bfa_status_t bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen);
+void bfa_debug_fwsave_clear(struct bfa_s *bfa);
 
 #include "bfa_priv.h"
 
index 268d956bad89cf4d0cfda4533781c735beb50e44..1349b99a3c6dff233e3f602e0254b5542f74e5e7 100644 (file)
@@ -26,6 +26,7 @@ struct bfa_fcxp_s;
 #include <defs/bfa_defs_pport.h>
 #include <defs/bfa_defs_rport.h>
 #include <defs/bfa_defs_qos.h>
+#include <defs/bfa_defs_fcport.h>
 #include <cs/bfa_sm.h>
 #include <bfa.h>
 
@@ -35,7 +36,7 @@ struct bfa_fcxp_s;
 struct bfa_rport_info_s {
        u16        max_frmsz;   /*  max rcv pdu size               */
        u32        pid:24,              /*  remote port ID                 */
-                       lp_tag:8;
+                       lp_tag:8;       /*  tag                     */
        u32        local_pid:24,        /*  local port ID                   */
                        cisc:8;         /*  CIRO supported                  */
        u8         fc_class;    /*  supported FC classes. enum fc_cos */
@@ -54,7 +55,7 @@ struct bfa_rport_s {
        void                  *rport_drv; /*  fcs/driver rport object */
        u16              fw_handle; /*  firmware rport handle */
        u16              rport_tag; /*  BFA rport tag */
-       struct bfa_rport_info_s rport_info; /*  rport info from *fcs/driver */
+       struct bfa_rport_info_s rport_info; /*  rport info from fcs/driver */
        struct bfa_reqq_wait_s reqq_wait; /*  to wait for room in reqq */
        struct bfa_cb_qe_s    hcb_qe;    /*  BFA callback qelem */
        struct bfa_rport_hal_stats_s stats; /*  BFA rport statistics  */
@@ -101,7 +102,7 @@ struct bfa_uf_buf_s {
 struct bfa_uf_s {
        struct list_head        qe;             /*  queue element         */
        struct bfa_s    *bfa;           /*  bfa instance          */
-       u16        uf_tag;              /*  identifying tag f/w messages */
+       u16        uf_tag;              /*  identifying tag fw msgs     */
        u16        vf_id;
        u16        src_rport_handle;
        u16        rsvd;
@@ -127,7 +128,7 @@ struct bfa_lps_s {
        u8              reqq;           /*  lport request queue */
        u8              alpa;           /*  ALPA for loop topologies    */
        u32     lp_pid;         /*  lport port ID               */
-       bfa_boolean_t   fdisc;          /*  send FDISC instead of FLOGI*/
+       bfa_boolean_t   fdisc;          /*  send FDISC instead of FLOGI  */
        bfa_boolean_t   auth_en;        /*  enable authentication       */
        bfa_boolean_t   auth_req;       /*  authentication required     */
        bfa_boolean_t   npiv_en;        /*  NPIV is allowed by peer     */
@@ -151,60 +152,69 @@ struct bfa_lps_s {
        bfa_eproto_status_t     ext_status;
 };
 
+#define BFA_FCPORT(_bfa)        (&((_bfa)->modules.port))
+
 /*
  * bfa pport API functions
  */
-bfa_status_t bfa_pport_enable(struct bfa_s *bfa);
-bfa_status_t bfa_pport_disable(struct bfa_s *bfa);
-bfa_status_t bfa_pport_cfg_speed(struct bfa_s *bfa,
+bfa_status_t bfa_fcport_enable(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_disable(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_cfg_speed(struct bfa_s *bfa,
                        enum bfa_pport_speed speed);
-enum bfa_pport_speed bfa_pport_get_speed(struct bfa_s *bfa);
-bfa_status_t bfa_pport_cfg_topology(struct bfa_s *bfa,
+enum bfa_pport_speed bfa_fcport_get_speed(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_cfg_topology(struct bfa_s *bfa,
                        enum bfa_pport_topology topo);
-enum bfa_pport_topology bfa_pport_get_topology(struct bfa_s *bfa);
-bfa_status_t bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa);
-bfa_boolean_t bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa);
-u8 bfa_pport_get_myalpa(struct bfa_s *bfa);
-bfa_status_t bfa_pport_clr_hardalpa(struct bfa_s *bfa);
-bfa_status_t bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxsize);
-u16 bfa_pport_get_maxfrsize(struct bfa_s *bfa);
-u32 bfa_pport_mypid(struct bfa_s *bfa);
-u8 bfa_pport_get_rx_bbcredit(struct bfa_s *bfa);
-bfa_status_t bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap);
-bfa_status_t bfa_pport_trunk_disable(struct bfa_s *bfa);
-bfa_boolean_t bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap);
-void bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr);
-wwn_t bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node);
-bfa_status_t bfa_pport_get_stats(struct bfa_s *bfa,
-                       union bfa_pport_stats_u *stats,
-                       bfa_cb_pport_t cbfn, void *cbarg);
-bfa_status_t bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
-                       void *cbarg);
-void bfa_pport_event_register(struct bfa_s *bfa,
+enum bfa_pport_topology bfa_fcport_get_topology(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa);
+bfa_boolean_t bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa);
+u8 bfa_fcport_get_myalpa(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_clr_hardalpa(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxsize);
+u16 bfa_fcport_get_maxfrsize(struct bfa_s *bfa);
+u32 bfa_fcport_mypid(struct bfa_s *bfa);
+u8 bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_trunk_enable(struct bfa_s *bfa, u8 bitmap);
+bfa_status_t bfa_fcport_trunk_disable(struct bfa_s *bfa);
+bfa_boolean_t bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap);
+void bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr);
+wwn_t bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node);
+void bfa_fcport_event_register(struct bfa_s *bfa,
                        void (*event_cbfn) (void *cbarg,
                        bfa_pport_event_t event), void *event_cbarg);
-bfa_boolean_t bfa_pport_is_disabled(struct bfa_s *bfa);
-void bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off);
-void bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off);
-bfa_status_t bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa,
+bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa);
+void bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off);
+void bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off);
+bfa_status_t bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa,
                        enum bfa_pport_speed speed);
-enum bfa_pport_speed bfa_pport_get_ratelim_speed(struct bfa_s *bfa);
+enum bfa_pport_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa);
 
-void bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit);
-void bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status);
-void bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
+void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit);
+void bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status);
+void bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
                        bfa_boolean_t link_e2e_beacon);
 void bfa_cb_pport_event(void *cbarg, bfa_pport_event_t event);
-void bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr);
-void bfa_pport_qos_get_vc_attr(struct bfa_s *bfa,
+void bfa_fcport_qos_get_attr(struct bfa_s *bfa,
+                       struct bfa_qos_attr_s *qos_attr);
+void bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
                        struct bfa_qos_vc_attr_s *qos_vc_attr);
-bfa_status_t bfa_pport_get_qos_stats(struct bfa_s *bfa,
-                       union bfa_pport_stats_u *stats,
+bfa_status_t bfa_fcport_get_qos_stats(struct bfa_s *bfa,
+                       union bfa_fcport_stats_u *stats,
                        bfa_cb_pport_t cbfn, void *cbarg);
-bfa_status_t bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
+bfa_status_t bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
                        void *cbarg);
-bfa_boolean_t     bfa_pport_is_ratelim(struct bfa_s *bfa);
-bfa_boolean_t  bfa_pport_is_linkup(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_get_fcoe_stats(struct bfa_s *bfa,
+                       union bfa_fcport_stats_u *stats,
+                       bfa_cb_pport_t cbfn, void *cbarg);
+bfa_status_t bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
+                       void *cbarg);
+
+bfa_boolean_t     bfa_fcport_is_ratelim(struct bfa_s *bfa);
+bfa_boolean_t  bfa_fcport_is_linkup(struct bfa_s *bfa);
+bfa_status_t bfa_fcport_get_stats(struct bfa_s *bfa,
+               union bfa_fcport_stats_u *stats,
+               bfa_cb_pport_t cbfn, void *cbarg);
+bfa_status_t bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
+               void *cbarg);
 
 /*
  * bfa rport API functions
@@ -293,6 +303,7 @@ void bfa_uf_free(struct bfa_uf_s *uf);
  * bfa lport service api
  */
 
+u32    bfa_lps_get_max_vport(struct bfa_s *bfa);
 struct bfa_lps_s *bfa_lps_alloc(struct bfa_s *bfa);
 void bfa_lps_delete(struct bfa_lps_s *lps);
 void bfa_lps_discard(struct bfa_lps_s *lps);
@@ -315,10 +326,12 @@ wwn_t bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps);
 wwn_t bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps);
 u8 bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps);
 u8 bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps);
+mac_t bfa_lps_get_lp_mac(struct bfa_lps_s *lps);
 void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status);
 void bfa_cb_lps_flogo_comp(void *bfad, void *uarg);
 void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status);
 void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg);
+void bfa_cb_lps_cvl_event(void *bfad, void *uarg);
 
 #endif /* __BFA_SVC_H__ */
 
index e407103fa5657d69b65e768d1ad94ac2f243758a..f71087448222404f199304d8e66517e3aa52b8ff 100644 (file)
@@ -41,7 +41,7 @@ struct bfa_timer_mod_s {
        struct list_head timer_q;
 };
 
-#define BFA_TIMER_FREQ 500 /**< specified in millisecs */
+#define BFA_TIMER_FREQ 200 /**< specified in millisecs */
 
 void bfa_timer_beat(struct bfa_timer_mod_s *mod);
 void bfa_timer_init(struct bfa_timer_mod_s *mod);
index 7042c18e542da7565ac6ffcae9ed8ada0a6ab24e..a550e80cabd20d455bc42644895649d22e51488e 100644 (file)
@@ -143,8 +143,8 @@ enum bfi_mclass {
        BFI_MC_IOC              = 1,    /*  IO Controller (IOC)     */
        BFI_MC_DIAG             = 2,    /*  Diagnostic Msgs                 */
        BFI_MC_FLASH            = 3,    /*  Flash message class     */
-       BFI_MC_CEE              = 4,
-       BFI_MC_FC_PORT          = 5,    /*  FC port                         */
+       BFI_MC_CEE              = 4,    /*  CEE                     */
+       BFI_MC_FCPORT           = 5,    /*  FC port                         */
        BFI_MC_IOCFC            = 6,    /*  FC - IO Controller (IOC)        */
        BFI_MC_LL               = 7,    /*  Link Layer                      */
        BFI_MC_UF               = 8,    /*  Unsolicited frame receive       */
index b3bb52b565b1ea96ad89d16b1bc56beba963713a..a51ee61ddb19d2b7bd59b72f250c12fbde3ead75 100644 (file)
 #define __PSS_LMEM_INIT_EN               0x00000100
 #define __PSS_LPU1_RESET                 0x00000002
 #define __PSS_LPU0_RESET                 0x00000001
-
+#define PSS_ERR_STATUS_REG              0x00018810
+#define __PSS_LMEM1_CORR_ERR            0x00000800
+#define __PSS_LMEM0_CORR_ERR             0x00000400
+#define __PSS_LMEM1_UNCORR_ERR           0x00000200
+#define __PSS_LMEM0_UNCORR_ERR           0x00000100
+#define __PSS_BAL_PERR                   0x00000080
+#define __PSS_DIP_IF_ERR                 0x00000040
+#define __PSS_IOH_IF_ERR                 0x00000020
+#define __PSS_TDS_IF_ERR                 0x00000010
+#define __PSS_RDS_IF_ERR                 0x00000008
+#define __PSS_SGM_IF_ERR                 0x00000004
+#define __PSS_LPU1_RAM_ERR               0x00000002
+#define __PSS_LPU0_RAM_ERR               0x00000001
+#define ERR_SET_REG                     0x00018818
+#define __PSS_ERR_STATUS_SET            0x00000fff
 
 /*
  * These definitions are either in error/missing in spec. Its auto-generated
index d3caa58c0a0a5db788ce40e0e996abd810fc8016..57a8497105af6c21c31a8d9dac97c61a5328ed85 100644 (file)
@@ -430,6 +430,31 @@ enum {
 #define __PSS_LMEM_INIT_EN               0x00000100
 #define __PSS_LPU1_RESET                 0x00000002
 #define __PSS_LPU0_RESET                 0x00000001
+#define PSS_ERR_STATUS_REG               0x00018810
+#define __PSS_LPU1_TCM_READ_ERR          0x00200000
+#define __PSS_LPU0_TCM_READ_ERR          0x00100000
+#define __PSS_LMEM5_CORR_ERR             0x00080000
+#define __PSS_LMEM4_CORR_ERR             0x00040000
+#define __PSS_LMEM3_CORR_ERR             0x00020000
+#define __PSS_LMEM2_CORR_ERR             0x00010000
+#define __PSS_LMEM1_CORR_ERR             0x00008000
+#define __PSS_LMEM0_CORR_ERR             0x00004000
+#define __PSS_LMEM5_UNCORR_ERR           0x00002000
+#define __PSS_LMEM4_UNCORR_ERR           0x00001000
+#define __PSS_LMEM3_UNCORR_ERR           0x00000800
+#define __PSS_LMEM2_UNCORR_ERR           0x00000400
+#define __PSS_LMEM1_UNCORR_ERR           0x00000200
+#define __PSS_LMEM0_UNCORR_ERR           0x00000100
+#define __PSS_BAL_PERR                   0x00000080
+#define __PSS_DIP_IF_ERR                 0x00000040
+#define __PSS_IOH_IF_ERR                 0x00000020
+#define __PSS_TDS_IF_ERR                 0x00000010
+#define __PSS_RDS_IF_ERR                 0x00000008
+#define __PSS_SGM_IF_ERR                 0x00000004
+#define __PSS_LPU1_RAM_ERR               0x00000002
+#define __PSS_LPU0_RAM_ERR               0x00000001
+#define ERR_SET_REG                     0x00018818
+#define __PSS_ERR_STATUS_SET            0x003fffff
 #define HQM_QSET0_RXQ_DRBL_P0            0x00038000
 #define __RXQ0_ADD_VECTORS_P             0x80000000
 #define __RXQ0_STOP_P                    0x40000000
@@ -589,6 +614,7 @@ enum {
 #define __HFN_INT_MBOX_LPU1                0x00200000U
 #define __HFN_INT_MBOX1_LPU0               0x00400000U
 #define __HFN_INT_MBOX1_LPU1               0x00800000U
+#define __HFN_INT_LL_HALT                 0x01000000U
 #define __HFN_INT_CPE_MASK                 0x000000ffU
 #define __HFN_INT_RME_MASK                 0x0000ff00U
 
index 96ef05670659dcb6dd9472b1fe7a9f918f11cb9c..a0158aac002405a0be2d8a4450263d497ca762c6 100644 (file)
@@ -123,7 +123,7 @@ enum bfi_ioc_state {
        BFI_IOC_DISABLING        = 5,   /*  IOC is being disabled           */
        BFI_IOC_DISABLED         = 6,   /*  IOC is disabled                 */
        BFI_IOC_CFG_DISABLED = 7,       /*  IOC is being disabled;transient */
-       BFI_IOC_HBFAIL       = 8,       /*  IOC heart-beat failure          */
+       BFI_IOC_FAIL       = 8,         /*  IOC heart-beat failure          */
        BFI_IOC_MEMTEST      = 9,       /*  IOC is doing memtest            */
 };
 
index c59d47badb4ba42d722d583f5d6caf12a71a7258..7ed31bbb8696fda7f7b7b529a14b8041343f3220 100644 (file)
@@ -30,6 +30,7 @@ enum bfi_lps_h2i_msgs {
 enum bfi_lps_i2h_msgs {
        BFI_LPS_H2I_LOGIN_RSP   = BFA_I2HM(1),
        BFI_LPS_H2I_LOGOUT_RSP  = BFA_I2HM(2),
+       BFI_LPS_H2I_CVL_EVENT   = BFA_I2HM(3),
 };
 
 struct bfi_lps_login_req_s {
@@ -77,6 +78,12 @@ struct bfi_lps_logout_rsp_s {
        u8              rsvd[2];
 };
 
+struct bfi_lps_cvl_event_s {
+       struct bfi_mhdr_s  mh;      /* common msg header      */
+       u8              lp_tag;
+       u8              rsvd[3];
+};
+
 union bfi_lps_h2i_msg_u {
        struct bfi_mhdr_s               *msg;
        struct bfi_lps_login_req_s      *login_req;
@@ -87,6 +94,7 @@ union bfi_lps_i2h_msg_u {
        struct bfi_msg_s                *msg;
        struct bfi_lps_login_rsp_s      *login_rsp;
        struct bfi_lps_logout_rsp_s     *logout_rsp;
+       struct bfi_lps_cvl_event_s      *cvl_event;
 };
 
 #pragma pack()
index c96d246851af2486eb97b6fc3770beb137753da1..50dcf45c7470ce3b222f9a156344638fd16d2fbf 100644 (file)
 
 #pragma pack(1)
 
-enum bfi_pport_h2i {
-       BFI_PPORT_H2I_ENABLE_REQ                = (1),
-       BFI_PPORT_H2I_DISABLE_REQ               = (2),
-       BFI_PPORT_H2I_GET_STATS_REQ             = (3),
-       BFI_PPORT_H2I_CLEAR_STATS_REQ   = (4),
-       BFI_PPORT_H2I_SET_SVC_PARAMS_REQ        = (5),
-       BFI_PPORT_H2I_ENABLE_RX_VF_TAG_REQ      = (6),
-       BFI_PPORT_H2I_ENABLE_TX_VF_TAG_REQ      = (7),
-       BFI_PPORT_H2I_GET_QOS_STATS_REQ         = (8),
-       BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ       = (9),
+enum bfi_fcport_h2i {
+       BFI_FCPORT_H2I_ENABLE_REQ               = (1),
+       BFI_FCPORT_H2I_DISABLE_REQ              = (2),
+       BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ       = (3),
+       BFI_FCPORT_H2I_STATS_GET_REQ            = (4),
+       BFI_FCPORT_H2I_STATS_CLEAR_REQ          = (5),
 };
 
-enum bfi_pport_i2h {
-       BFI_PPORT_I2H_ENABLE_RSP                = BFA_I2HM(1),
-       BFI_PPORT_I2H_DISABLE_RSP               = BFA_I2HM(2),
-       BFI_PPORT_I2H_GET_STATS_RSP             = BFA_I2HM(3),
-       BFI_PPORT_I2H_CLEAR_STATS_RSP   = BFA_I2HM(4),
-       BFI_PPORT_I2H_SET_SVC_PARAMS_RSP        = BFA_I2HM(5),
-       BFI_PPORT_I2H_ENABLE_RX_VF_TAG_RSP      = BFA_I2HM(6),
-       BFI_PPORT_I2H_ENABLE_TX_VF_TAG_RSP      = BFA_I2HM(7),
-       BFI_PPORT_I2H_EVENT                     = BFA_I2HM(8),
-       BFI_PPORT_I2H_GET_QOS_STATS_RSP         = BFA_I2HM(9),
-       BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP       = BFA_I2HM(10),
+enum bfi_fcport_i2h {
+       BFI_FCPORT_I2H_ENABLE_RSP               = BFA_I2HM(1),
+       BFI_FCPORT_I2H_DISABLE_RSP              = BFA_I2HM(2),
+       BFI_FCPORT_I2H_SET_SVC_PARAMS_RSP       = BFA_I2HM(3),
+       BFI_FCPORT_I2H_STATS_GET_RSP            = BFA_I2HM(4),
+       BFI_FCPORT_I2H_STATS_CLEAR_RSP          = BFA_I2HM(5),
+       BFI_FCPORT_I2H_EVENT                    = BFA_I2HM(6),
 };
 
 /**
  * Generic REQ type
  */
-struct bfi_pport_generic_req_s {
+struct bfi_fcport_req_s {
        struct bfi_mhdr_s  mh;          /*  msg header                      */
-       u32        msgtag;              /*  msgtag for reply                */
+       u32        msgtag;      /*  msgtag for reply                */
 };
 
 /**
  * Generic RSP type
  */
-struct bfi_pport_generic_rsp_s {
+struct bfi_fcport_rsp_s {
        struct bfi_mhdr_s  mh;          /*  common msg header               */
-       u8         status;              /*  port enable status              */
-       u8         rsvd[3];
-       u32        msgtag;              /*  msgtag for reply                */
+       u8                 status;      /*  port enable status              */
+       u8                 rsvd[3];
+       u32        msgtag;      /*  msgtag for reply                */
 };
 
 /**
- * BFI_PPORT_H2I_ENABLE_REQ
+ * BFI_FCPORT_H2I_ENABLE_REQ
  */
-struct bfi_pport_enable_req_s {
+struct bfi_fcport_enable_req_s {
        struct bfi_mhdr_s  mh;          /*  msg header                      */
-       u32        rsvd1;
-       wwn_t           nwwn;           /*  node wwn of physical port       */
-       wwn_t           pwwn;           /*  port wwn of physical port       */
-       struct bfa_pport_cfg_s port_cfg;        /*  port configuration      */
-       union bfi_addr_u  stats_dma_addr;       /*  DMA address for stats  */
-       u32        msgtag;              /*  msgtag for reply                */
-       u32        rsvd2;
+       u32        rsvd1;
+       wwn_t              nwwn;        /*  node wwn of physical port       */
+       wwn_t              pwwn;        /*  port wwn of physical port       */
+       struct bfa_pport_cfg_s port_cfg; /*  port configuration     */
+       union bfi_addr_u   stats_dma_addr; /*  DMA address for stats        */
+       u32        msgtag;      /*  msgtag for reply                */
+       u32        rsvd2;
 };
 
 /**
- * BFI_PPORT_I2H_ENABLE_RSP
+ * BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ
  */
-#define bfi_pport_enable_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_DISABLE_REQ
- */
-#define bfi_pport_disable_req_t struct bfi_pport_generic_req_s
-
-/**
- * BFI_PPORT_I2H_DISABLE_RSP
- */
-#define bfi_pport_disable_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_GET_STATS_REQ
- */
-#define bfi_pport_get_stats_req_t struct bfi_pport_generic_req_s
-
-/**
- * BFI_PPORT_I2H_GET_STATS_RSP
- */
-#define bfi_pport_get_stats_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_CLEAR_STATS_REQ
- */
-#define bfi_pport_clear_stats_req_t struct bfi_pport_generic_req_s
-
-/**
- * BFI_PPORT_I2H_CLEAR_STATS_RSP
- */
-#define bfi_pport_clear_stats_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_GET_QOS_STATS_REQ
- */
-#define bfi_pport_get_qos_stats_req_t struct bfi_pport_generic_req_s
-
-/**
- * BFI_PPORT_H2I_GET_QOS_STATS_RSP
- */
-#define bfi_pport_get_qos_stats_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ
- */
-#define bfi_pport_clear_qos_stats_req_t struct bfi_pport_generic_req_s
-
-/**
- * BFI_PPORT_H2I_CLEAR_QOS_STATS_RSP
- */
-#define bfi_pport_clear_qos_stats_rsp_t struct bfi_pport_generic_rsp_s
-
-/**
- * BFI_PPORT_H2I_SET_SVC_PARAMS_REQ
- */
-struct bfi_pport_set_svc_params_req_s {
+struct bfi_fcport_set_svc_params_req_s {
        struct bfi_mhdr_s  mh;          /*  msg header */
-       u16        tx_bbcredit; /*  Tx credits */
-       u16        rsvd;
+       u16        tx_bbcredit; /*  Tx credits */
+       u16        rsvd;
 };
 
 /**
- * BFI_PPORT_I2H_SET_SVC_PARAMS_RSP
- */
-
-/**
- * BFI_PPORT_I2H_EVENT
+ * BFI_FCPORT_I2H_EVENT
  */
-struct bfi_pport_event_s {
+struct bfi_fcport_event_s {
        struct bfi_mhdr_s       mh;     /*  common msg header */
        struct bfa_pport_link_s link_state;
 };
 
-union bfi_pport_h2i_msg_u {
+/**
+ * fcport H2I message
+ */
+union bfi_fcport_h2i_msg_u {
        struct bfi_mhdr_s                       *mhdr;
-       struct bfi_pport_enable_req_s           *penable;
-       struct bfi_pport_generic_req_s          *pdisable;
-       struct bfi_pport_generic_req_s          *pgetstats;
-       struct bfi_pport_generic_req_s          *pclearstats;
-       struct bfi_pport_set_svc_params_req_s   *psetsvcparams;
-       struct bfi_pport_get_qos_stats_req_s    *pgetqosstats;
-       struct bfi_pport_generic_req_s          *pclearqosstats;
+       struct bfi_fcport_enable_req_s          *penable;
+       struct bfi_fcport_req_s                 *pdisable;
+       struct bfi_fcport_set_svc_params_req_s  *psetsvcparams;
+       struct bfi_fcport_req_s                 *pstatsget;
+       struct bfi_fcport_req_s                 *pstatsclear;
 };
 
-union bfi_pport_i2h_msg_u {
+/**
+ * fcport I2H message
+ */
+union bfi_fcport_i2h_msg_u {
        struct bfi_msg_s                        *msg;
-       struct bfi_pport_generic_rsp_s          *enable_rsp;
-       struct bfi_pport_disable_rsp_s          *disable_rsp;
-       struct bfi_pport_generic_rsp_s          *getstats_rsp;
-       struct bfi_pport_clear_stats_rsp_s      *clearstats_rsp;
-       struct bfi_pport_set_svc_params_rsp_s   *setsvcparasm_rsp;
-       struct bfi_pport_get_qos_stats_rsp_s    *getqosstats_rsp;
-       struct bfi_pport_clear_qos_stats_rsp_s  *clearqosstats_rsp;
-       struct bfi_pport_event_s                *event;
+       struct bfi_fcport_rsp_s                 *penable_rsp;
+       struct bfi_fcport_rsp_s                 *pdisable_rsp;
+       struct bfi_fcport_rsp_s                 *psetsvcparams_rsp;
+       struct bfi_fcport_rsp_s                 *pstatsget_rsp;
+       struct bfi_fcport_rsp_s                 *pstatsclear_rsp;
+       struct bfi_fcport_event_s               *event;
 };
 
 #pragma pack()
 
 #endif /* __BFI_PPORT_H__ */
-
index 43ba7064e81a5c01b7205fc37454ffb7cf475a1d..a75a1f3be315d4c471f7edde4d35d97a9898fd79 100644 (file)
 enum {
        BFA_TRC_CNA_CEE         = 1,
        BFA_TRC_CNA_PORT        = 2,
+       BFA_TRC_CNA_IOC     = 3,
+       BFA_TRC_CNA_DIAG    = 4,
+       BFA_TRC_CNA_IOC_CB  = 5,
+       BFA_TRC_CNA_IOC_CT  = 6,
 };
 
 #endif /* __BFA_CNA_TRCMOD_H__ */
index 761cbe22130a7194c728824c754c535fb407f77c..bc334e0a93faace2336300013946637590ba0885 100644 (file)
@@ -157,7 +157,7 @@ typedef void (*bfa_log_cb_t)(struct bfa_log_mod_s *log_mod, u32 msg_id,
 
 
 struct bfa_log_mod_s {
-       char            instance_info[16];      /*  instance info */
+       char            instance_info[BFA_STRING_32];   /*  instance info */
        int             log_level[BFA_LOG_MODULE_ID_MAX + 1];
                                                /*  log level for modules */
        bfa_log_cb_t    cbfn;                   /*  callback function */
index 670f86e5fc6ea3338a19976c3650b93ce153855b..f5bef63b5877bbca905a886d9c08cb3f5a982fe8 100644 (file)
@@ -80,7 +80,8 @@ enum bfa_plog_mid {
        BFA_PL_MID_HAL_FCXP     = 4,
        BFA_PL_MID_HAL_UF       = 5,
        BFA_PL_MID_FCS          = 6,
-       BFA_PL_MID_MAX          = 7
+       BFA_PL_MID_LPS          = 7,
+       BFA_PL_MID_MAX          = 8
 };
 
 #define BFA_PL_MID_STRLEN    8
@@ -118,7 +119,11 @@ enum bfa_plog_eid {
        BFA_PL_EID_RSCN                 = 17,
        BFA_PL_EID_DEBUG                = 18,
        BFA_PL_EID_MISC                 = 19,
-       BFA_PL_EID_MAX                  = 20
+       BFA_PL_EID_FIP_FCF_DISC         = 20,
+       BFA_PL_EID_FIP_FCF_CVL          = 21,
+       BFA_PL_EID_LOGIN                = 22,
+       BFA_PL_EID_LOGO                 = 23,
+       BFA_PL_EID_MAX                  = 24
 };
 
 #define BFA_PL_ENAME_STRLEN            8
index b0a92baf6657251d2c6013a4b1102249e6808d4d..11fba9082f05fb0e5e2eeebe45c8637364f90fe9 100644 (file)
 #define __BFA_SM_H__
 
 typedef void (*bfa_sm_t)(void *sm, int event);
+/**
+ * oc - object class eg. bfa_ioc
+ * st - state, eg. reset
+ * otype - object type, eg. struct bfa_ioc_s
+ * etype - object type, eg. enum ioc_event
+ */
+#define bfa_sm_state_decl(oc, st, otype, etype)         \
+       static void oc ## _sm_ ## st(otype * fsm, etype event)
 
 #define bfa_sm_set_state(_sm, _state)  ((_sm)->sm = (bfa_sm_t)(_state))
 #define bfa_sm_send_event(_sm, _event) ((_sm)->sm((_sm), (_event)))
index 4c81a613db3d6a6ede8b8a70cc3837cbe2722099..35244698fcdc07fafc5b2ba04a145a4f123d37cc 100644 (file)
 #include <defs/bfa_defs_audit.h>
 #include <defs/bfa_defs_ethport.h>
 
+#define BFA_AEN_MAX_APP         5
+
+enum bfa_aen_app {
+       bfa_aen_app_bcu = 0,    /* No thread for bcu */
+       bfa_aen_app_hcm = 1,
+       bfa_aen_app_cim = 2,
+       bfa_aen_app_snia = 3,
+       bfa_aen_app_test = 4,   /* To be removed after unit test */
+};
+
 enum bfa_aen_category {
        BFA_AEN_CAT_ADAPTER     = 1,
        BFA_AEN_CAT_PORT        = 2,
index dd19c83aba5831c9b612d33fef4d6456f65df5e2..45df3282091130752abcd265f82c2801f95d0a59 100644 (file)
@@ -23,6 +23,7 @@
 #define PRIVATE_KEY                    19009
 #define KEY_LEN                                32399
 #define BFA_AUTH_SECRET_STRING_LEN     256
+#define BFA_AUTH_FAIL_NO_PASSWORD      0xFE
 #define BFA_AUTH_FAIL_TIMEOUT          0xFF
 
 /**
@@ -41,6 +42,27 @@ enum bfa_auth_status {
        BFA_AUTH_STATUS_UNKNOWN = 9,    /*  authentication status unknown */
 };
 
+enum bfa_auth_rej_code {
+       BFA_AUTH_RJT_CODE_AUTH_FAILURE   = 1, /* auth failure */
+       BFA_AUTH_RJT_CODE_LOGICAL_ERR    = 2, /* logical error */
+};
+
+/**
+ * Authentication reject codes
+ */
+enum bfa_auth_rej_code_exp {
+       BFA_AUTH_MECH_NOT_USABLE        = 1, /* auth. mechanism not usable */
+       BFA_AUTH_DH_GROUP_NOT_USABLE    = 2, /* DH Group not usable */
+       BFA_AUTH_HASH_FUNC_NOT_USABLE   = 3, /* hash Function not usable */
+       BFA_AUTH_AUTH_XACT_STARTED      = 4, /* auth xact started */
+       BFA_AUTH_AUTH_FAILED            = 5, /* auth failed */
+       BFA_AUTH_INCORRECT_PLD          = 6, /* incorrect payload */
+       BFA_AUTH_INCORRECT_PROTO_MSG    = 7, /* incorrect proto msg */
+       BFA_AUTH_RESTART_AUTH_PROTO     = 8, /* restart auth protocol */
+       BFA_AUTH_AUTH_CONCAT_NOT_SUPP   = 9, /* auth concat not supported */
+       BFA_AUTH_PROTO_VER_NOT_SUPP     = 10,/* proto version not supported */
+};
+
 struct auth_proto_stats_s {
        u32        auth_rjts;
        u32        auth_negs;
index 520a22f52dd18a6fcae2a42145cd0e975f7d1bd7..b0ac9ac15c5d6b7ce37b240a68d4d7dafc1073a7 100644 (file)
 
 #define BFA_CEE_LLDP_MAX_STRING_LEN (128)
 
-
-/* FIXME: this is coming from the protocol spec. Can the host & apps share the
-   protocol .h files ?
- */
 #define BFA_CEE_LLDP_SYS_CAP_OTHER       0x0001
 #define BFA_CEE_LLDP_SYS_CAP_REPEATER    0x0002
 #define BFA_CEE_LLDP_SYS_CAP_MAC_BRIDGE  0x0004
@@ -94,9 +90,10 @@ struct bfa_cee_dcbx_cfg_s {
 /* CEE status */
 /* Making this to tri-state for the benefit of port list command */
 enum bfa_cee_status_e {
-    CEE_PHY_DOWN = 0,
-    CEE_PHY_UP = 1,
-    CEE_UP = 2,
+       CEE_UP = 0,
+       CEE_PHY_UP = 1,
+       CEE_LOOPBACK = 2,
+       CEE_PHY_DOWN = 3,
 };
 
 /* CEE Query */
@@ -107,7 +104,8 @@ struct bfa_cee_attr_s {
        struct bfa_cee_dcbx_cfg_s dcbx_remote;
        mac_t src_mac;
        u8 link_speed;
-       u8 filler[3];
+       u8 nw_priority;
+       u8 filler[2];
 };
 
 
index 57049805762babcb461dc9fca8a740f418e1a8b8..50382dd2ab417eaab85459398ad482036ad6f8e5 100644 (file)
@@ -21,6 +21,7 @@
 /**
  * Driver statistics
  */
+struct bfa_driver_stats_s {
        u16    tm_io_abort;
     u16    tm_io_abort_comp;
     u16    tm_lun_reset;
@@ -34,7 +35,7 @@
     u64    output_req;
     u64    input_words;
     u64    output_words;
-} bfa_driver_stats_t;
+};
 
 
 #endif /* __BFA_DEFS_DRIVER_H__ */
index 79f9b3e146f7112cf0a9fe38a8486f7c238e4fa7..b4fa0923aa8943813ab4edc2db287034b8bc4684 100644 (file)
@@ -19,6 +19,7 @@
 #define __BFA_DEFS_ETHPORT_H__
 
 #include <defs/bfa_defs_status.h>
+#include <defs/bfa_defs_port.h>
 #include <protocol/types.h>
 #include <cna/pstats/phyport_defs.h>
 #include <cna/pstats/ethport_defs.h>
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h b/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h
new file mode 100644 (file)
index 0000000..a07ef4a
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ *  bfa_defs_fcport.h
+ *
+ * Linux driver for Brocade Fibre Channel Host Bus Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) 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.
+ */
+#ifndef __BFA_DEFS_FCPORT_H__
+#define __BFA_DEFS_FCPORT_H__
+
+#include <defs/bfa_defs_types.h>
+#include <protocol/types.h>
+
+#pragma pack(1)
+
+/**
+ * FCoE statistics
+ */
+struct bfa_fcoe_stats_s {
+       u64     secs_reset;     /*  Seconds since stats reset        */
+       u64     cee_linkups;    /*  CEE link up              */
+       u64     cee_linkdns;    /*  CEE link down                    */
+       u64     fip_linkups;    /*  FIP link up              */
+       u64     fip_linkdns;    /*  FIP link down                    */
+       u64     fip_fails;      /*  FIP failures                     */
+       u64     mac_invalids;   /*  Invalid mac assignments          */
+       u64     vlan_req;       /*  Vlan requests                    */
+       u64     vlan_notify;    /*  Vlan notifications               */
+       u64     vlan_err;       /*  Vlan notification errors         */
+       u64     vlan_timeouts;  /*  Vlan request timeouts            */
+       u64     vlan_invalids;  /*  Vlan invalids                    */
+       u64     disc_req;       /*  Discovery requests               */
+       u64     disc_rsp;       /*  Discovery responses      */
+       u64     disc_err;       /*  Discovery error frames           */
+       u64     disc_unsol;     /*  Discovery unsolicited            */
+       u64     disc_timeouts;  /*  Discovery timeouts               */
+       u64     disc_fcf_unavail; /*  Discovery FCF not avail        */
+       u64     linksvc_unsupp; /*  FIP link service req unsupp.    */
+       u64     linksvc_err;    /*  FIP link service req errors     */
+       u64     logo_req;       /*  FIP logo                         */
+       u64     clrvlink_req;   /*  Clear virtual link requests     */
+       u64     op_unsupp;      /*  FIP operation unsupp.            */
+       u64     untagged;       /*  FIP untagged frames      */
+       u64     txf_ucast;      /*  Tx FCoE unicast frames           */
+       u64     txf_ucast_vlan; /*  Tx FCoE unicast vlan frames     */
+       u64     txf_ucast_octets; /*  Tx FCoE unicast octets         */
+       u64     txf_mcast;      /*  Tx FCoE mutlicast frames         */
+       u64     txf_mcast_vlan; /*  Tx FCoE mutlicast vlan frames   */
+       u64     txf_mcast_octets; /*  Tx FCoE multicast octets       */
+       u64     txf_bcast;      /*  Tx FCoE broadcast frames         */
+       u64     txf_bcast_vlan; /*  Tx FCoE broadcast vlan frames   */
+       u64     txf_bcast_octets; /*  Tx FCoE broadcast octets       */
+       u64     txf_timeout;    /*  Tx timeouts              */
+       u64     txf_parity_errors; /*  Transmit parity err           */
+       u64     txf_fid_parity_errors; /*  Transmit FID parity err  */
+       u64     tx_pause;       /*  Tx pause frames                  */
+       u64     tx_zero_pause;  /*  Tx zero pause frames             */
+       u64     tx_first_pause; /*  Tx first pause frames            */
+       u64     rx_pause;       /*  Rx pause frames                  */
+       u64     rx_zero_pause;  /*  Rx zero pause frames             */
+       u64     rx_first_pause; /*  Rx first pause frames            */
+       u64     rxf_ucast_octets; /*  Rx unicast octets      */
+       u64     rxf_ucast;      /*  Rx unicast frames                */
+       u64     rxf_ucast_vlan; /*  Rx unicast vlan frames           */
+       u64     rxf_mcast_octets; /*  Rx multicast octets            */
+       u64     rxf_mcast;      /*  Rx multicast frames      */
+       u64     rxf_mcast_vlan; /*  Rx multicast vlan frames         */
+       u64     rxf_bcast_octets; /*  Rx broadcast octests           */
+       u64     rxf_bcast;      /*  Rx broadcast frames      */
+       u64     rxf_bcast_vlan; /*  Rx broadcast vlan frames         */
+};
+
+/**
+ * QoS or FCoE stats (fcport stats excluding physical FC port stats)
+ */
+union bfa_fcport_stats_u {
+       struct bfa_qos_stats_s  fcqos;
+       struct bfa_fcoe_stats_s fcoe;
+};
+
+#pragma pack()
+
+#endif  /* __BFA_DEFS_FCPORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h b/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h
deleted file mode 100644 (file)
index 9ccf53b..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- *
- * Linux driver for Brocade Fibre Channel Host Bus Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) 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.
- */
-
-#ifndef __BFA_DEFS_IM_COMMON_H__
-#define __BFA_DEFS_IM_COMMON_H__
-
-#define        BFA_ADAPTER_NAME_LEN    256
-#define BFA_ADAPTER_GUID_LEN    256
-#define RESERVED_VLAN_NAME      L"PORT VLAN"
-#define PASSTHRU_VLAN_NAME      L"PASSTHRU VLAN"
-
-       u64     tx_pkt_cnt;
-       u64     rx_pkt_cnt;
-       u32     duration;
-       u8              status;
-} bfa_im_stats_t, *pbfa_im_stats_t;
-
-#endif /* __BFA_DEFS_IM_COMMON_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h b/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h
deleted file mode 100644 (file)
index a486a7e..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- *
- * Linux driver for Brocade Fibre Channel Host Bus Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) 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.
- */
-
-#ifndef __BFA_DEFS_IM_TEAM_H__
-#define __BFA_DEFS_IM_TEAM_H__
-
-#include <protocol/types.h>
-
-#define        BFA_TEAM_MAX_PORTS      8
-#define        BFA_TEAM_NAME_LEN       256
-#define BFA_MAX_NUM_TEAMS      16
-#define BFA_TEAM_INVALID_DELAY -1
-
-       BFA_LACP_RATE_SLOW = 1,
-       BFA_LACP_RATE_FAST
-} bfa_im_lacp_rate_t;
-
-       BFA_TEAM_MODE_FAIL_OVER = 1,
-       BFA_TEAM_MODE_FAIL_BACK,
-       BFA_TEAM_MODE_LACP,
-       BFA_TEAM_MODE_NONE
-} bfa_im_team_mode_t;
-
-       BFA_XMIT_POLICY_L2 = 1,
-       BFA_XMIT_POLICY_L3_L4
-} bfa_im_xmit_policy_t;
-
-       bfa_im_team_mode_t     team_mode;
-       bfa_im_lacp_rate_t     lacp_rate;
-       bfa_im_xmit_policy_t   xmit_policy;
-       int               delay;
-       wchar_t           primary[BFA_ADAPTER_NAME_LEN];
-       wchar_t           preferred_primary[BFA_ADAPTER_NAME_LEN];
-       mac_t             mac;
-       u16               num_ports;
-       u16          num_vlans;
-       u16 vlan_list[BFA_MAX_VLANS_PER_PORT];
-       wchar_t  team_guid_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_GUID_LEN];
-       wchar_t  ioc_name_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_NAME_LEN];
-} bfa_im_team_attr_t;
-
-       wchar_t                      team_name[BFA_TEAM_NAME_LEN];
-       bfa_im_xmit_policy_t     xmit_policy;
-       int                      delay;
-       wchar_t                  primary[BFA_ADAPTER_NAME_LEN];
-       wchar_t                  preferred_primary[BFA_ADAPTER_NAME_LEN];
-} bfa_im_team_edit_t, *pbfa_im_team_edit_t;
-
-       wchar_t                                 team_name[BFA_TEAM_NAME_LEN];
-       bfa_im_team_mode_t      team_mode;
-       mac_t                   mac;
-} bfa_im_team_info_t;
-
-       bfa_im_team_info_t              team_info[BFA_MAX_NUM_TEAMS];
-       u16                             num_teams;
-} bfa_im_team_list_t, *pbfa_im_team_list_t;
-
-#endif /* __BFA_DEFS_IM_TEAM_H__ */
index b1d532da3a9d4258254cc91dc6aaebbdeb01d9ec..8d8e6a96653706f67cdf3fec0b14cef38bdcedb0 100644 (file)
@@ -126,6 +126,7 @@ struct bfa_ioc_attr_s {
        struct bfa_ioc_driver_attr_s    driver_attr;    /*  driver attr    */
        struct bfa_ioc_pci_attr_s       pci_attr;
        u8                              port_id;        /*  port number    */
+       u8                              rsvd[7];        /*!< 64bit align    */
 };
 
 /**
@@ -143,8 +144,8 @@ enum bfa_ioc_aen_event {
  * BFA IOC level event data, now just a place holder
  */
 struct bfa_ioc_aen_data_s {
-       enum bfa_ioc_type_e ioc_type;
        wwn_t   pwwn;
+       s16 ioc_type;
        mac_t   mac;
 };
 
index d76bcbd9820f99a22a060c6401291e721d16a40c..c290fb13d2d124921aa4f2c5c106d5ecc4d68e2e 100644 (file)
@@ -26,6 +26,8 @@
 
 #define BFA_IOCFC_INTR_DELAY   1125
 #define BFA_IOCFC_INTR_LATENCY 225
+#define BFA_IOCFCOE_INTR_DELAY  25
+#define BFA_IOCFCOE_INTR_LATENCY 5
 
 /**
  * Interrupt coalescing configuration.
@@ -50,7 +52,7 @@ struct bfa_iocfc_fwcfg_s {
        u16        num_fcxp_reqs;       /*  unassisted FC exchanges     */
        u16        num_uf_bufs; /*  unsolicited recv buffers    */
        u8              num_cqs;
-       u8              rsvd;
+       u8              rsvd[5];
 };
 
 struct bfa_iocfc_drvcfg_s {
@@ -224,18 +226,24 @@ struct bfa_fw_port_physm_stats_s {
 
 
 struct bfa_fw_fip_stats_s {
+    u32    vlan_req;           /*  vlan discovery requests             */
+    u32    vlan_notify;        /*  vlan notifications                  */
+    u32    vlan_err;           /*  vlan response error                 */
+    u32    vlan_timeouts;      /*  vlan disvoery timeouts              */
+    u32    vlan_invalids;      /*  invalid vlan in discovery advert.   */
     u32    disc_req;           /*  Discovery solicit requests          */
     u32    disc_rsp;           /*  Discovery solicit response          */
     u32    disc_err;           /*  Discovery advt. parse errors        */
     u32    disc_unsol;         /*  Discovery unsolicited               */
     u32    disc_timeouts;      /*  Discovery timeouts                  */
+    u32    disc_fcf_unavail;   /*  Discovery FCF Not Avail.            */
     u32    linksvc_unsupp;     /*  Unsupported link service req        */
     u32    linksvc_err;        /*  Parse error in link service req     */
     u32    logo_req;           /*  Number of FIP logos received        */
     u32    clrvlink_req;       /*  Clear virtual link req              */
     u32    op_unsupp;          /*  Unsupported FIP operation           */
     u32    untagged;           /*  Untagged frames (ignored)           */
-    u32    rsvd;
+    u32           invalid_version;    /*!< Invalid FIP version           */
 };
 
 
index 7359f82aacfc242a71aef08fec865cce8c8f60ba..0952a139c47cfff33408670f819bde9b117069c7 100644 (file)
@@ -59,8 +59,8 @@ enum bfa_lport_aen_event {
  */
 struct bfa_lport_aen_data_s {
        u16        vf_id;       /*  vf_id of this logical port */
-       u16        rsvd;
-       enum bfa_port_role roles;       /*  Logical port mode,IM/TM/IP etc */
+       s16         roles;  /*  Logical port mode,IM/TM/IP etc */
+       u32        rsvd;
        wwn_t           ppwwn;  /*  WWN of its physical port */
        wwn_t           lpwwn;  /*  WWN of this logical port */
 };
index 13fd4ab6aae2310436b755aebfe1432bbba6e27d..c5bd9c36ad4d972d877e9a18acf2dd77750fe312 100644 (file)
 /**
  * Manufacturing block version
  */
-#define BFA_MFG_VERSION                                1
+#define BFA_MFG_VERSION                                2
+
+/**
+ * Manufacturing block encrypted version
+ */
+#define BFA_MFG_ENC_VER                                2
+
+/**
+ * Manufacturing block version 1 length
+ */
+#define BFA_MFG_VER1_LEN                       128
+
+/**
+ * Manufacturing block header length
+ */
+#define BFA_MFG_HDR_LEN                                4
+
+/**
+ * Checksum size
+ */
+#define BFA_MFG_CHKSUM_SIZE                    16
+
+/**
+ * Manufacturing block encrypted version
+ */
+#define BFA_MFG_ENC_VER                                2
+
+/**
+ * Manufacturing block version 1 length
+ */
+#define BFA_MFG_VER1_LEN                       128
+
+/**
+ * Manufacturing block header length
+ */
+#define BFA_MFG_HDR_LEN                                4
+
+/**
+ * Checksum size
+ */
+#define BFA_MFG_CHKSUM_SIZE                    16
 
 /**
  * Manufacturing block format
 #define BFA_MFG_SERIALNUM_SIZE                 11
 #define BFA_MFG_PARTNUM_SIZE                   14
 #define BFA_MFG_SUPPLIER_ID_SIZE               10
-#define BFA_MFG_SUPPLIER_PARTNUM_SIZE  20
-#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE        20
-#define BFA_MFG_SUPPLIER_REVISION_SIZE 4
+#define BFA_MFG_SUPPLIER_PARTNUM_SIZE          20
+#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE                20
+#define BFA_MFG_SUPPLIER_REVISION_SIZE         4
 #define STRSZ(_n)      (((_n) + 4) & ~3)
 
+/**
+ * Manufacturing card type
+ */
+enum {
+       BFA_MFG_TYPE_CB_MAX  = 825,      /*  Crossbow card type max     */
+       BFA_MFG_TYPE_FC8P2   = 825,      /*  8G 2port FC card           */
+       BFA_MFG_TYPE_FC8P1   = 815,      /*  8G 1port FC card           */
+       BFA_MFG_TYPE_FC4P2   = 425,      /*  4G 2port FC card           */
+       BFA_MFG_TYPE_FC4P1   = 415,      /*  4G 1port FC card           */
+       BFA_MFG_TYPE_CNA10P2 = 1020,     /*  10G 2port CNA card */
+       BFA_MFG_TYPE_CNA10P1 = 1010,     /*  10G 1port CNA card */
+};
+
+#pragma pack(1)
+
+/**
+ * Card type to port number conversion
+ */
+#define bfa_mfg_type2port_num(card_type) (((card_type) / 10) % 10)
+
+
+/**
+ * All numerical fields are in big-endian format.
+ */
+struct bfa_mfg_block_s {
+};
+
 /**
  * VPD data length
  */
-#define BFA_MFG_VPD_LEN     256
+#define BFA_MFG_VPD_LEN                512
+
+#define BFA_MFG_VPD_PCI_HDR_OFF                137
+#define BFA_MFG_VPD_PCI_VER_MASK       0x07    /*  version mask 3 bits */
+#define BFA_MFG_VPD_PCI_VDR_MASK       0xf8    /*  vendor mask 5 bits */
+
+/**
+ * VPD vendor tag
+ */
+enum {
+       BFA_MFG_VPD_UNKNOWN     = 0,     /*  vendor unknown             */
+       BFA_MFG_VPD_IBM         = 1,     /*  vendor IBM                 */
+       BFA_MFG_VPD_HP          = 2,     /*  vendor HP                  */
+       BFA_MFG_VPD_DELL        = 3,     /*  vendor DELL                */
+       BFA_MFG_VPD_PCI_IBM     = 0x08,  /*  PCI VPD IBM                */
+       BFA_MFG_VPD_PCI_HP      = 0x10,  /*  PCI VPD HP                 */
+       BFA_MFG_VPD_PCI_DELL    = 0x20,  /*  PCI VPD DELL               */
+       BFA_MFG_VPD_PCI_BRCD    = 0xf8,  /*  PCI VPD Brocade            */
+};
 
 /**
  * All numerical fields are in big-endian format.
  */
 struct bfa_mfg_vpd_s {
-    u8     version;    /*  vpd data version */
-    u8     vpd_sig[3]; /*  characters 'V', 'P', 'D' */
-    u8     chksum;     /*  u8 checksum */
-    u8     vendor;     /*  vendor */
-    u8     len;        /*  vpd data length excluding header */
-    u8     rsv;
-    u8     data[BFA_MFG_VPD_LEN];  /*  vpd data */
+       u8              version;        /*  vpd data version */
+       u8              vpd_sig[3];     /*  characters 'V', 'P', 'D' */
+       u8              chksum;         /*  u8 checksum */
+       u8              vendor;         /*  vendor */
+       u8      len;            /*  vpd data length excluding header */
+       u8      rsv;
+       u8              data[BFA_MFG_VPD_LEN];  /*  vpd data */
 };
 
-#pragma pack(1)
+#pragma pack()
 
 #endif /* __BFA_DEFS_MFG_H__ */
index de0696c81bc4cb4267d3a41e9032d4036e7273fb..501bc9739d9d7a99083a32a9547bc2953a4558bc 100644 (file)
@@ -185,6 +185,8 @@ struct bfa_port_attr_s {
        wwn_t           fabric_name; /*  attached switch's nwwn */
        u8              fabric_ip_addr[BFA_FCS_FABRIC_IPADDR_SZ]; /*  attached
                                                        * fabric's ip addr */
+       struct mac_s    fpma_mac;       /*  Lport's FPMA Mac address */
+       u16     authfail;               /*  auth failed state */
 };
 
 /**
@@ -232,14 +234,15 @@ enum bfa_port_aen_sfp_pom {
 };
 
 struct bfa_port_aen_data_s {
-       enum bfa_ioc_type_e ioc_type;
-       wwn_t           pwwn;         /*  WWN of the physical port */
-       wwn_t           fwwn;         /*  WWN of the fabric port */
-       mac_t           mac;          /*  MAC addres of the ethernet port,
-                                      * applicable to CNA port only */
-       int             phy_port_num; /*! For SFP related events */
-       enum bfa_port_aen_sfp_pom level; /*  Only transitions will
-                                         * be informed */
+       wwn_t           pwwn;         /*  WWN of the physical port */
+       wwn_t           fwwn;         /*  WWN of the fabric port */
+       s32         phy_port_num; /*! For SFP related events */
+       s16         ioc_type;
+       s16         level;        /*  Only transitions will
+                                       * be informed */
+       struct mac_s    mac;          /*  MAC address of the ethernet port,
+                                       * applicable to CNA port only */
+       s16         rsvd;
 };
 
 #endif /* __BFA_DEFS_PORT_H__ */
index bf320412ee24bd859cd3f8eaf07260d158c6fe9a..26e5cc78095d900eef42ea8d3419135ec503b138 100644 (file)
@@ -232,7 +232,7 @@ struct bfa_pport_attr_s {
        u32             pid;            /*  port ID */
        enum bfa_pport_type     port_type;      /*  current topology */
        u32             loopback;       /*  external loopback */
-       u32             rsvd1;
+       u32             authfail;       /* auth fail state */
        u32             rsvd2;          /*  padding for 64 bit */
 };
 
@@ -240,73 +240,79 @@ struct bfa_pport_attr_s {
  *             FC Port statistics.
  */
 struct bfa_pport_fc_stats_s {
-       u64        secs_reset;  /*  seconds since stats is reset */
-       u64        tx_frames;   /*  transmitted frames */
-       u64        tx_words;    /*  transmitted words */
-       u64        rx_frames;   /*  received frames */
-       u64        rx_words;    /*  received words */
-       u64        lip_count;   /*  LIPs seen */
-       u64        nos_count;   /*  NOS count */
-       u64        error_frames;        /*  errored frames (sent?) */
-       u64        dropped_frames;      /*  dropped frames */
-       u64        link_failures;       /*  link failure count */
-       u64        loss_of_syncs;       /*  loss of sync count */
-       u64        loss_of_signals;/*  loss of signal count */
-       u64        primseq_errs;        /*  primitive sequence protocol */
-       u64        bad_os_count;        /*  invalid ordered set */
-       u64        err_enc_out; /*  Encoding error outside frame */
-       u64        invalid_crcs;        /*  frames received with invalid CRC*/
-       u64     undersized_frm; /*  undersized frames */
-       u64     oversized_frm;  /*  oversized frames */
-       u64     bad_eof_frm;    /*  frames with bad EOF */
-       struct bfa_qos_stats_s  qos_stats;      /*  QoS statistics */
+       u64    secs_reset; /* Seconds since stats is reset     */
+       u64    tx_frames;  /* Tx frames                */
+       u64    tx_words;   /* Tx words                 */
+       u64    tx_lip;     /* TX LIP               */
+       u64    tx_nos;     /* Tx NOS               */
+       u64    tx_ols;     /* Tx OLS               */
+       u64    tx_lr;      /* Tx LR                */
+       u64    tx_lrr;     /* Tx LRR               */
+       u64    rx_frames;  /* Rx frames                */
+       u64    rx_words;   /* Rx words                 */
+       u64    lip_count;  /* Rx LIP                   */
+       u64    nos_count;  /* Rx NOS               */
+       u64    ols_count;  /* Rx OLS               */
+       u64    lr_count;   /* Rx LR                */
+       u64    lrr_count;  /* Rx LRR               */
+       u64    invalid_crcs;   /* Rx CRC err frames            */
+       u64    invalid_crc_gd_eof; /* Rx CRC err good EOF frames   */
+       u64    undersized_frm; /* Rx undersized frames         */
+       u64    oversized_frm;  /* Rx oversized frames          */
+       u64    bad_eof_frm;    /* Rx frames with bad EOF       */
+       u64    error_frames;   /* Errored frames           */
+       u64    dropped_frames; /* Dropped frames           */
+       u64    link_failures;  /* Link Failure (LF) count          */
+       u64    loss_of_syncs;  /* Loss of sync count           */
+       u64    loss_of_signals;/* Loss of signal count         */
+       u64    primseq_errs;   /* Primitive sequence protocol err. */
+       u64    bad_os_count;   /* Invalid ordered sets         */
+       u64    err_enc_out;    /* Encoding err nonframe_8b10b      */
+       u64    err_enc;    /* Encoding err frame_8b10b         */
 };
 
 /**
  *             Eth Port statistics.
  */
 struct bfa_pport_eth_stats_s {
-       u64     secs_reset;     /*  seconds since stats is reset */
-       u64     frame_64;      /*  both rx and tx counter */
-       u64     frame_65_127;      /* both rx and tx counter */
-       u64     frame_128_255;     /* both rx and tx counter */
-       u64     frame_256_511;     /* both rx and tx counter */
-       u64     frame_512_1023;    /* both rx and tx counter */
-       u64     frame_1024_1518;   /* both rx and tx counter */
-       u64     frame_1519_1522;   /* both rx and tx counter */
-
-       u64     tx_bytes;
-       u64     tx_packets;
-       u64     tx_mcast_packets;
-       u64     tx_bcast_packets;
-       u64     tx_control_frame;
-       u64     tx_drop;
-       u64     tx_jabber;
-       u64     tx_fcs_error;
-       u64     tx_fragments;
-
-       u64     rx_bytes;
-       u64     rx_packets;
-       u64     rx_mcast_packets;
-       u64     rx_bcast_packets;
-       u64     rx_control_frames;
-       u64     rx_unknown_opcode;
-       u64     rx_drop;
-       u64     rx_jabber;
-       u64     rx_fcs_error;
-       u64     rx_alignment_error;
-       u64     rx_frame_length_error;
-       u64     rx_code_error;
-       u64     rx_fragments;
-
-       u64     rx_pause; /* BPC */
-       u64     rx_zero_pause; /*  BPC Pause cancellation */
-       u64     tx_pause;      /* BPC */
-       u64     tx_zero_pause; /*  BPC Pause cancellation */
-       u64     rx_fcoe_pause; /* BPC */
-       u64     rx_fcoe_zero_pause; /*  BPC Pause cancellation */
-       u64     tx_fcoe_pause;      /* BPC */
-       u64     tx_fcoe_zero_pause; /*  BPC Pause cancellation */
+       u64    secs_reset;   /* Seconds since stats is reset   */
+       u64    frame_64;     /* Frames 64 bytes            */
+       u64    frame_65_127;     /* Frames 65-127 bytes        */
+       u64    frame_128_255;    /* Frames 128-255 bytes       */
+       u64    frame_256_511;    /* Frames 256-511 bytes       */
+       u64    frame_512_1023;   /* Frames 512-1023 bytes          */
+       u64    frame_1024_1518;  /* Frames 1024-1518 bytes         */
+       u64    frame_1519_1522;  /* Frames 1519-1522 bytes         */
+       u64    tx_bytes;     /* Tx bytes               */
+       u64    tx_packets;   /* Tx packets             */
+       u64    tx_mcast_packets; /* Tx multicast packets       */
+       u64    tx_bcast_packets; /* Tx broadcast packets       */
+       u64    tx_control_frame; /* Tx control frame           */
+       u64    tx_drop;      /* Tx drops               */
+       u64    tx_jabber;    /* Tx jabber              */
+       u64    tx_fcs_error;     /* Tx FCS error           */
+       u64    tx_fragments;     /* Tx fragments           */
+       u64    rx_bytes;     /* Rx bytes               */
+       u64    rx_packets;   /* Rx packets             */
+       u64    rx_mcast_packets; /* Rx multicast packets       */
+       u64    rx_bcast_packets; /* Rx broadcast packets       */
+       u64    rx_control_frames; /* Rx control frames         */
+       u64    rx_unknown_opcode; /* Rx unknown opcode         */
+       u64    rx_drop;      /* Rx drops               */
+       u64    rx_jabber;    /* Rx jabber              */
+       u64    rx_fcs_error;     /* Rx FCS errors              */
+       u64    rx_alignment_error; /* Rx alignment errors          */
+       u64    rx_frame_length_error; /* Rx frame len errors       */
+       u64    rx_code_error;    /* Rx code errors             */
+       u64    rx_fragments;     /* Rx fragments           */
+       u64    rx_pause;     /* Rx pause               */
+       u64    rx_zero_pause;    /* Rx zero pause              */
+       u64    tx_pause;     /* Tx pause               */
+       u64    tx_zero_pause;    /* Tx zero pause              */
+       u64    rx_fcoe_pause;    /* Rx fcoe pause              */
+       u64    rx_fcoe_zero_pause; /* Rx FCoE zero pause       */
+       u64    tx_fcoe_pause;    /* Tx FCoE pause              */
+       u64    tx_fcoe_zero_pause; /* Tx FCoE zero pause       */
 };
 
 /**
@@ -333,8 +339,7 @@ struct bfa_pport_fcpmap_s {
 };
 
 /**
- *              Port RNID info.
- */
+ *              Port RNI        */
 struct bfa_pport_rnid_s {
        wwn_t             wwn;
        u32          unittype;
@@ -347,6 +352,23 @@ struct bfa_pport_rnid_s {
        u16          topologydiscoveryflags;
 };
 
+struct bfa_fcport_fcf_s {
+       wwn_t           name;           /* FCF name                 */
+       wwn_t           fabric_name;    /* Fabric Name              */
+       u8              fipenabled;     /* FIP enabled or not       */
+       u8              fipfailed;      /* FIP failed or not        */
+       u8              resv[2];
+       u8              pri;            /* FCF priority             */
+       u8              version;        /* FIP version used         */
+       u8              available;      /* Available  for  login    */
+       u8              fka_disabled;   /* FKA is disabled          */
+       u8              maxsz_verified; /* FCoE max size verified   */
+       u8              fc_map[3];      /* FC map                   */
+       u16             vlan;           /* FCoE vlan tag/priority   */
+       u32             fka_adv_per;    /* FIP  ka advert. period   */
+       struct mac_s    mac;            /* FCF mac                  */
+};
+
 /**
  *             Link state information
  */
@@ -378,6 +400,7 @@ struct bfa_pport_link_s {
                        struct fc_alpabm_s     alpabm;     /*  alpa bitmap */
                } loop_info;
        } tl;
+       struct bfa_fcport_fcf_s fcf;    /*!< FCF information (for FCoE) */
 };
 
 #endif /* __BFA_DEFS_PPORT_H__ */
index cdceaeb9f4b822e2d34ac31af76e6c48158c816b..4374494bd5661b5aa0048216a2005007fd0b0410 100644 (file)
@@ -180,8 +180,8 @@ enum bfa_status {
        BFA_STATUS_IM_ADAPT_ALREADY_IN_TEAM = 114, /*  Given adapter is part
                                                    * of another team */
        BFA_STATUS_IM_ADAPT_HAS_VLANS = 115, /*  Adapter has VLANs configured.
-                                             * Delete all VLANs before
-                                             * creating team */
+                                             * Delete all VLANs to become
+                                             * part of the team */
        BFA_STATUS_IM_PVID_MISMATCH = 116, /*  Mismatching PVIDs configured
                                            * for adapters */
        BFA_STATUS_IM_LINK_SPEED_MISMATCH = 117, /*  Mismatching link speeds
@@ -213,7 +213,7 @@ enum bfa_status {
                                             * loaded */
        BFA_STATUS_CARD_TYPE_MISMATCH = 131, /*  Card type mismatch */
        BFA_STATUS_BAD_ASICBLK = 132, /*  Bad ASIC block */
-       BFA_STATUS_NO_DRIVER = 133, /*  Storage/Ethernet driver not loaded */
+       BFA_STATUS_NO_DRIVER = 133, /*  Brocade adapter/driver not installed or loaded */
        BFA_STATUS_INVALID_MAC = 134, /*  Invalid mac address */
        BFA_STATUS_IM_NO_VLAN = 135, /*  No VLANs configured on the adapter */
        BFA_STATUS_IM_ETH_LB_FAILED = 136, /*  Ethernet loopback test failed */
@@ -228,8 +228,7 @@ enum bfa_status {
        BFA_STATUS_IM_GET_INETCFG_FAILED = 142, /*  Acquiring Network Subsytem
                                                 * handle Failed. Please try
                                                 * after some time */
-       BFA_STATUS_IM_NOT_BOUND = 143, /*  Brocade 10G Ethernet Service is not
-                                       * Enabled on this port */
+       BFA_STATUS_IM_NOT_BOUND = 143, /*  IM driver is not active */
        BFA_STATUS_INSUFFICIENT_PERMS = 144, /*  User doesn't have sufficient
                                              * permissions to execute the BCU
                                              * application */
@@ -242,6 +241,14 @@ enum bfa_status {
                                          * failed */
        BFA_STATUS_IM_UNBIND_FAILED = 149, /* ! < IM Driver unbind operation
                                            * failed */
+       BFA_STATUS_IM_PORT_IN_TEAM = 150, /*  Port is already part of the
+                                          * team */
+       BFA_STATUS_IM_VLAN_NOT_FOUND = 151, /*  VLAN ID doesn't exists */
+       BFA_STATUS_IM_TEAM_NOT_FOUND = 152, /*  Teaming configuration doesn't
+                                            * exists */
+       BFA_STATUS_IM_TEAM_CFG_NOT_ALLOWED = 153, /*  Given settings are not
+                                               * allowed for the current
+                                               * Teaming mode */
        BFA_STATUS_MAX_VAL              /*  Unknown error code */
 };
 #define bfa_status_t enum bfa_status
index a6c70aee0aa36d9731b13b7ba7f06c7ee23f7d5c..52585d3dd8917e725d483ee11b78e0475c8c606c 100644 (file)
@@ -70,7 +70,6 @@ void            bfa_fcb_itnim_online(struct bfad_itnim_s *itnim_drv);
  */
 void            bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv);
 
-void            bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim_drv);
 void            bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim_drv);
 
 #endif /* __BFAD_FCB_FCPIM_H__ */
index 627669c65546deebebe77ba2a71acae083d26cf3..f2fd35fdee28805cd71be4070792061a22d06e6c 100644 (file)
@@ -49,6 +49,7 @@ struct bfa_fcs_s {
        struct bfa_trc_mod_s  *trcmod;  /*  tracing module */
        struct bfa_aen_s      *aen;     /*  aen component */
        bfa_boolean_t   vf_enabled;     /*  VF mode is enabled */
+       bfa_boolean_t   fdmi_enabled;   /*!< FDMI is enabled */
        bfa_boolean_t min_cfg;          /* min cfg enabled/disabled */
        u16        port_vfid;   /*  port default VF ID */
        struct bfa_fcs_driver_info_s driver_info;
@@ -60,10 +61,12 @@ struct bfa_fcs_s {
 /*
  * bfa fcs API functions
  */
-void bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
+void bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
                        bfa_boolean_t min_cfg);
+void bfa_fcs_init(struct bfa_fcs_s *fcs);
 void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
                        struct bfa_fcs_driver_info_s *driver_info);
+void bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable);
 void bfa_fcs_exit(struct bfa_fcs_s *fcs);
 void bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod);
 void bfa_fcs_log_init(struct bfa_fcs_s *fcs, struct bfa_log_mod_s *logmod);
index 967ceb0eb074881d4f6877597a70f040d68fb632..ceaefd3060f4553a4c05c6707a8ad7aa4001a166 100644 (file)
@@ -34,14 +34,6 @@ struct bfa_fcs_s;
 struct bfa_fcs_fabric_s;
 
 /*
-* @todo : need to move to a global config file.
- * Maximum Vports supported per physical port or vf.
- */
-#define BFA_FCS_MAX_VPORTS_SUPP_CB  255
-#define BFA_FCS_MAX_VPORTS_SUPP_CT  191
-
-/*
-* @todo : need to move to a global config file.
  * Maximum Rports supported per port (physical/logical).
  */
 #define BFA_FCS_MAX_RPORTS_SUPP  256   /* @todo : tentative value */
index 0412aea2ec307c0f1a1fc8b6eb56141ba03b6aa2..5f8f5e30b9e829315a56be5107515efd4c5c888f 100644 (file)
        (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 3)
 #define BFA_LOG_HAL_SM_ASSERT \
        (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 4)
+#define BFA_LOG_HAL_DRIVER_ERROR \
+       (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 5)
+#define BFA_LOG_HAL_DRIVER_CONFIG_ERROR \
+       (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 6)
+#define BFA_LOG_HAL_MBOX_ERROR \
+       (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 7)
 #endif
index 317c0547ee1672a312893472f66279fe175bad5b..bd451db4c30a9929e7e6abc44b6bcc4da56227ab 100644 (file)
                (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 10)
 #define BFA_LOG_LINUX_SCSI_ABORT_COMP \
                (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 11)
+#define BFA_LOG_LINUX_DRIVER_CONFIG_ERROR \
+               (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 12)
+#define BFA_LOG_LINUX_BNA_STATE_MACHINE \
+               (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 13)
+#define BFA_LOG_LINUX_IOC_ERROR \
+       (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 14)
+#define BFA_LOG_LINUX_RESOURCE_ALLOC_ERROR \
+       (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 15)
+#define BFA_LOG_LINUX_RING_BUFFER_ERROR \
+       (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 16)
+#define BFA_LOG_LINUX_DRIVER_ERROR \
+       (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 17)
+#define BFA_LOG_LINUX_DRIVER_DIAG \
+       (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 18)
+#define BFA_LOG_LINUX_DRIVER_AEN \
+       (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 19)
 #endif
index 14969eecf6a9e8491420ee406d28dc080d047d12..8d1038035a7682652c1139066ee8abfff7aa7124 100644 (file)
@@ -50,6 +50,11 @@ struct fchs_s {
 
        u32        ro;          /* relative offset */
 };
+
+#define FC_SOF_LEN      4
+#define FC_EOF_LEN      4
+#define FC_CRC_LEN      4
+
 /*
  * Fibre Channel BB_E Header Structure
  */
diff --git a/drivers/scsi/bfa/include/protocol/pcifw.h b/drivers/scsi/bfa/include/protocol/pcifw.h
deleted file mode 100644 (file)
index 6830dc3..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- *
- * Linux driver for Brocade Fibre Channel Host Bus Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) 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.
- */
-
-/**
- *  pcifw.h PCI FW related headers
- */
-
-#ifndef __PCIFW_H__
-#define __PCIFW_H__
-
-#pragma pack(1)
-
-struct pnp_hdr_s{
-  u32  signature;      /* "$PnP" */
-  u8   rev;            /* Struct revision */
-  u8   len;            /* Header structure len in multiples
-                                * of 16 bytes */
-  u16  off;            /* Offset to next header 00 if none */
-  u8   rsvd;           /* Reserved byte */
-  u8   cksum;          /* 8-bit checksum for this header */
-  u32  pnp_dev_id;     /* PnP Device Id */
-  u16  mfstr;          /* Pointer to manufacturer string */
-  u16  prstr;          /* Pointer to product string */
-  u8   devtype[3];     /* Device Type Code */
-  u8   devind;         /* Device Indicator */
-  u16  bcventr;        /* Bootstrap entry vector */
-  u16  rsvd2;          /* Reserved */
-  u16  sriv;           /* Static resource information vector */
-};
-
-struct pci_3_0_ds_s{
- u32   sig;            /* Signature "PCIR" */
- u16   vendid;         /* Vendor ID */
- u16   devid;          /* Device ID */
- u16   devlistoff;     /* Device List Offset */
- u16   len;            /* PCI Data Structure Length */
- u8    rev;            /* PCI Data Structure Revision */
- u8    clcode[3];      /* Class Code */
- u16   imglen;         /* Code image length in multiples of
-                                * 512 bytes */
- u16   coderev;        /* Revision level of code/data */
- u8    codetype;       /* Code type 0x00 - BIOS */
- u8    indr;           /* Last image indicator */
- u16   mrtimglen;      /* Max Run Time Image Length */
- u16   cuoff;          /* Config Utility Code Header Offset */
- u16   dmtfclp;        /* DMTF CLP entry point offset */
-};
-
-struct pci_optrom_hdr_s{
- u16   sig;            /* Signature 0x55AA */
- u8    len;            /* Option ROM length in units of 512 bytes */
- u8    inivec[3];      /* Initialization vector */
- u8    rsvd[16];       /* Reserved field */
- u16   verptr;         /* Pointer to version string - private */
- u16   pcids;          /* Pointer to PCI data structure */
- u16   pnphdr;         /* Pointer to PnP expansion header */
-};
-
-#pragma pack()
-
-#endif
index f7c7f4f3c6408923d5e38b8e05e61343caf7bbb5..f6342efb6a904d1f4e43bdecc21c098878f5a43b 100644 (file)
@@ -162,7 +162,7 @@ bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port, u8 alpa)
        len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
                             bfa_fcs_port_get_fcid(port), 0,
                             port->port_cfg.pwwn, port->port_cfg.nwwn,
-                                bfa_pport_get_maxfrsize(port->fcs->bfa));
+                                bfa_fcport_get_maxfrsize(port->fcs->bfa));
 
        bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
                          FC_CLASS_3, len, &fchs,
index 1e06792cd4c2cea68f4ec1a56a5497fe6e93eed4..d3907d184e2b0c92ea2cdd3101e6224d2d011b77 100644 (file)
@@ -156,7 +156,7 @@ bfa_fcs_port_get_rport_max_speed(struct bfa_fcs_port_s *port)
        /*
         * Get Physical port's current speed
         */
-       bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
+       bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
        pport_speed = pport_attr.speed;
        bfa_trc(fcs, pport_speed);
 
@@ -235,7 +235,8 @@ bfa_fcs_port_get_info(struct bfa_fcs_port_s *port,
                port_info->port_wwn = bfa_fcs_port_get_pwwn(port);
                port_info->node_wwn = bfa_fcs_port_get_nwwn(port);
 
-               port_info->max_vports_supp = bfa_fcs_vport_get_max(port->fcs);
+               port_info->max_vports_supp =
+                       bfa_lps_get_max_vport(port->fcs->bfa);
                port_info->num_vports_inuse =
                        bfa_fcs_fabric_vport_count(port->fabric);
                port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP;
index c96b3ca007aec0aede127cc8d88ae4c0decb9680..5e8c8dee6c97dc946d716eb57a0bee1d4d6436e5 100644 (file)
@@ -118,7 +118,7 @@ bfa_fcs_port_ms_sm_offline(struct bfa_fcs_port_ms_s *ms,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ms->port->fcs, event);
        }
 }
 
@@ -141,7 +141,7 @@ bfa_fcs_port_ms_sm_plogi_sending(struct bfa_fcs_port_ms_s *ms,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ms->port->fcs, event);
        }
 }
 
@@ -190,7 +190,7 @@ bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ms->port->fcs, event);
        }
 }
 
@@ -216,7 +216,7 @@ bfa_fcs_port_ms_sm_plogi_retry(struct bfa_fcs_port_ms_s *ms,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ms->port->fcs, event);
        }
 }
 
@@ -230,10 +230,6 @@ bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms,
        switch (event) {
        case MSSM_EVENT_PORT_OFFLINE:
                bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
-               /*
-                * now invoke MS related sub-modules
-                */
-               bfa_fcs_port_fdmi_offline(ms);
                break;
 
        case MSSM_EVENT_PORT_FABRIC_RSCN:
@@ -243,7 +239,7 @@ bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ms->port->fcs, event);
        }
 }
 
@@ -266,7 +262,7 @@ bfa_fcs_port_ms_sm_gmal_sending(struct bfa_fcs_port_ms_s *ms,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ms->port->fcs, event);
        }
 }
 
@@ -304,7 +300,7 @@ bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ms->port->fcs, event);
        }
 }
 
@@ -330,7 +326,7 @@ bfa_fcs_port_ms_sm_gmal_retry(struct bfa_fcs_port_ms_s *ms,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ms->port->fcs, event);
        }
 }
 
@@ -466,7 +462,7 @@ bfa_fcs_port_ms_sm_gfn_sending(struct bfa_fcs_port_ms_s *ms,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ms->port->fcs, event);
        }
 }
 
@@ -502,7 +498,7 @@ bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ms->port->fcs, event);
        }
 }
 
@@ -528,7 +524,7 @@ bfa_fcs_port_ms_sm_gfn_retry(struct bfa_fcs_port_ms_s *ms,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ms->port->fcs, event);
        }
 }
 
@@ -637,7 +633,7 @@ bfa_fcs_port_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
                             bfa_os_hton3b(FC_MGMT_SERVER),
                             bfa_fcs_port_get_fcid(port), 0,
                             port->port_cfg.pwwn, port->port_cfg.nwwn,
-                            bfa_pport_get_maxfrsize(port->fcs->bfa));
+                            bfa_fcport_get_maxfrsize(port->fcs->bfa));
 
        bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
                      FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_plogi_response,
@@ -735,6 +731,7 @@ bfa_fcs_port_ms_offline(struct bfa_fcs_port_s *port)
 
        ms->port = port;
        bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE);
+       bfa_fcs_port_fdmi_offline(ms);
 }
 
 void
index 2f8b880060bbfd619306181194f777588e92a4cc..d20dd7e15742ca08f42739bb73209599217616b3 100644 (file)
@@ -164,7 +164,7 @@ bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 
@@ -187,7 +187,7 @@ bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 
@@ -221,7 +221,7 @@ bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 
@@ -247,7 +247,7 @@ bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 
@@ -270,7 +270,7 @@ bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 
@@ -304,7 +304,7 @@ bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 
@@ -330,7 +330,7 @@ bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 
@@ -353,7 +353,7 @@ bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 
@@ -390,7 +390,7 @@ bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 
@@ -413,7 +413,7 @@ bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 
@@ -436,7 +436,7 @@ bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 
@@ -494,7 +494,7 @@ bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 
@@ -517,7 +517,7 @@ bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 static void
@@ -539,7 +539,7 @@ bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 
@@ -575,7 +575,7 @@ bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 
@@ -598,7 +598,7 @@ bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 
@@ -626,7 +626,7 @@ bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s *ns,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(ns->port->fcs, event);
        }
 }
 
@@ -660,7 +660,7 @@ bfa_fcs_port_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
                             bfa_os_hton3b(FC_NAME_SERVER),
                             bfa_fcs_port_get_fcid(port), 0,
                             port->port_cfg.pwwn, port->port_cfg.nwwn,
-                            bfa_pport_get_maxfrsize(port->fcs->bfa));
+                            bfa_fcport_get_maxfrsize(port->fcs->bfa));
 
        bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
                      FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_plogi_response,
index 9cf58bb138dc4a502555c54114c194f213b589f0..7b096f2e38369065f609442796e177c198312ed2 100644 (file)
@@ -19,6 +19,7 @@
  *  rport.c Remote port implementation.
  */
 
+#include <linux/slab.h>
 #include <bfa.h>
 #include <bfa_svc.h>
 #include "fcbuild.h"
@@ -224,7 +225,7 @@ bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -276,7 +277,7 @@ bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -332,7 +333,7 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -406,7 +407,7 @@ bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -481,7 +482,7 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -534,7 +535,7 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -589,7 +590,7 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -646,7 +647,7 @@ bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -704,7 +705,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -754,7 +755,7 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -816,7 +817,7 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -846,7 +847,7 @@ bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -869,7 +870,7 @@ bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -905,7 +906,7 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -925,10 +926,17 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
        case RPSM_EVENT_HCB_OFFLINE:
        case RPSM_EVENT_ADDRESS_CHANGE:
                if (bfa_fcs_port_is_online(rport->port)) {
-                       bfa_sm_set_state(rport,
-                                        bfa_fcs_rport_sm_nsdisc_sending);
-                       rport->ns_retries = 0;
-                       bfa_fcs_rport_send_gidpn(rport, NULL);
+                       if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
+                               bfa_sm_set_state(rport,
+                                       bfa_fcs_rport_sm_nsdisc_sending);
+                               rport->ns_retries = 0;
+                               bfa_fcs_rport_send_gidpn(rport, NULL);
+                       } else {
+                               bfa_sm_set_state(rport,
+                                       bfa_fcs_rport_sm_plogi_sending);
+                               rport->plogi_retries = 0;
+                               bfa_fcs_rport_send_plogi(rport, NULL);
+                       }
                } else {
                        rport->pid = 0;
                        bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
@@ -951,7 +959,7 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -1011,7 +1019,7 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -1038,7 +1046,7 @@ bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -1073,7 +1081,7 @@ bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -1132,7 +1140,7 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -1188,7 +1196,7 @@ bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -1249,7 +1257,7 @@ bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -1334,7 +1342,7 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -1366,7 +1374,7 @@ bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
        len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
                             bfa_fcs_port_get_fcid(port), 0,
                             port->port_cfg.pwwn, port->port_cfg.nwwn,
-                            bfa_pport_get_maxfrsize(port->fcs->bfa));
+                            bfa_fcport_get_maxfrsize(port->fcs->bfa));
 
        bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
                      FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response,
@@ -1478,7 +1486,7 @@ bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
        len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
                                 bfa_fcs_port_get_fcid(port), rport->reply_oxid,
                                 port->port_cfg.pwwn, port->port_cfg.nwwn,
-                                bfa_pport_get_maxfrsize(port->fcs->bfa));
+                                bfa_fcport_get_maxfrsize(port->fcs->bfa));
 
        bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
                      FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
@@ -1813,7 +1821,7 @@ bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport,
        /*
         * get curent speed from pport attributes from BFA
         */
-       bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
+       bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
 
        speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
 
@@ -2032,13 +2040,10 @@ bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport,
 
        switch (event) {
        case BFA_RPORT_AEN_ONLINE:
-               bfa_log(logmod, BFA_AEN_RPORT_ONLINE, rpwwn_ptr, lpwwn_ptr);
-               break;
        case BFA_RPORT_AEN_OFFLINE:
-               bfa_log(logmod, BFA_AEN_RPORT_OFFLINE, rpwwn_ptr, lpwwn_ptr);
-               break;
        case BFA_RPORT_AEN_DISCONNECT:
-               bfa_log(logmod, BFA_AEN_RPORT_DISCONNECT, rpwwn_ptr, lpwwn_ptr);
+               bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, event),
+                       rpwwn_ptr, lpwwn_ptr);
                break;
        case BFA_RPORT_AEN_QOS_PRIO:
                aen_data.rport.priv.qos = data->priv.qos;
@@ -2164,7 +2169,7 @@ bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
                bfa_trc(port->fcs, port->fabric->bb_credit);
 
                port->fabric->bb_credit = bfa_os_ntohs(plogi->csp.bbcred);
-               bfa_pport_set_tx_bbcredit(port->fcs->bfa,
+               bfa_fcport_set_tx_bbcredit(port->fcs->bfa,
                                          port->fabric->bb_credit);
        }
 
@@ -2574,23 +2579,6 @@ bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
                      FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
 }
 
-/**
- *   Module initialization
- */
-void
-bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs)
-{
-}
-
-/**
- *   Module cleanup
- */
-void
-bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs)
-{
-       bfa_fcs_modexit_comp(fcs);
-}
-
 /**
  * Return state of rport.
  */
index 3dae1774181efe4a54340a5c9c842d3f1a4798c6..a441f41d2a6446db401eaf09d73fa55cc7ae8c5a 100644 (file)
@@ -102,7 +102,7 @@ bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
        rport_attr->qos_attr = qos_attr;
 
        rport_attr->trl_enforced = BFA_FALSE;
-       if (bfa_pport_is_ratelim(port->fcs->bfa)) {
+       if (bfa_fcport_is_ratelim(port->fcs->bfa)) {
                if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN) ||
                        (rport->rpf.rpsc_speed <
                        bfa_fcs_port_get_rport_max_speed(port)))
index e1932c885ac28f5fc5740f5469503629b6765ff4..ae7bba67ae2a16ba3538032d8ef40ffc7945e3e4 100644 (file)
@@ -91,7 +91,7 @@ bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -114,7 +114,7 @@ bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -160,7 +160,7 @@ bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -186,7 +186,7 @@ bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -206,7 +206,7 @@ bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 
@@ -229,7 +229,7 @@ bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(rport->fcs, event);
        }
 }
 /**
index bd4771ff62c831bc961c8f4ff5142dece8118471..8fe09ba88a919ebc868200d310f72b1f6c51ee35 100644 (file)
@@ -90,7 +90,7 @@ bfa_fcs_port_scn_sm_offline(struct bfa_fcs_port_scn_s *scn,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(scn->port->fcs, event);
        }
 }
 
@@ -109,7 +109,7 @@ bfa_fcs_port_scn_sm_sending_scr(struct bfa_fcs_port_scn_s *scn,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(scn->port->fcs, event);
        }
 }
 
@@ -137,7 +137,7 @@ bfa_fcs_port_scn_sm_scr(struct bfa_fcs_port_scn_s *scn,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(scn->port->fcs, event);
        }
 }
 
@@ -157,7 +157,7 @@ bfa_fcs_port_scn_sm_scr_retry(struct bfa_fcs_port_scn_s *scn,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(scn->port->fcs, event);
        }
 }
 
@@ -171,7 +171,7 @@ bfa_fcs_port_scn_sm_online(struct bfa_fcs_port_scn_s *scn,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(scn->port->fcs, event);
        }
 }
 
index e90f1e38c32d5d2e1f76a618a398a606987482f9..27cd619a227a7a191acda944c8917fa7f000d257 100644 (file)
@@ -122,7 +122,7 @@ bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(__vport_fcs(vport), event);
        }
 }
 
@@ -165,7 +165,7 @@ bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(__vport_fcs(vport), event);
        }
 }
 
@@ -202,7 +202,7 @@ bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(__vport_fcs(vport), event);
        }
 }
 
@@ -249,7 +249,7 @@ bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(__vport_fcs(vport), event);
        }
 }
 
@@ -283,7 +283,7 @@ bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(__vport_fcs(vport), event);
        }
 }
 
@@ -310,7 +310,7 @@ bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(__vport_fcs(vport), event);
        }
 }
 
@@ -339,7 +339,7 @@ bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(__vport_fcs(vport), event);
        }
 }
 
@@ -387,7 +387,7 @@ bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(__vport_fcs(vport), event);
        }
 }
 
@@ -419,7 +419,7 @@ bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
                break;
 
        default:
-               bfa_assert(0);
+               bfa_sm_fault(__vport_fcs(vport), event);
        }
 }
 
@@ -447,22 +447,8 @@ bfa_fcs_vport_aen_post(bfa_fcs_lport_t *port, enum bfa_lport_aen_event event)
 
        bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
 
-       switch (event) {
-       case BFA_LPORT_AEN_NPIV_DUP_WWN:
-               bfa_log(logmod, BFA_AEN_LPORT_NPIV_DUP_WWN, lpwwn_ptr,
-                       role_str[role / 2]);
-               break;
-       case BFA_LPORT_AEN_NPIV_FABRIC_MAX:
-               bfa_log(logmod, BFA_AEN_LPORT_NPIV_FABRIC_MAX, lpwwn_ptr,
-                       role_str[role / 2]);
-               break;
-       case BFA_LPORT_AEN_NPIV_UNKNOWN:
-               bfa_log(logmod, BFA_AEN_LPORT_NPIV_UNKNOWN, lpwwn_ptr,
-                       role_str[role / 2]);
-               break;
-       default:
-               break;
-       }
+       bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr,
+                       role_str[role/2]);
 
        aen_data.lport.vf_id = port->fabric->vf_id;
        aen_data.lport.roles = role;
@@ -478,7 +464,7 @@ static void
 bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport)
 {
        bfa_lps_fdisc(vport->lps, vport,
-                     bfa_pport_get_maxfrsize(__vport_bfa(vport)),
+                     bfa_fcport_get_maxfrsize(__vport_bfa(vport)),
                      __vport_pwwn(vport), __vport_nwwn(vport));
        vport->vport_stats.fdisc_sent++;
 }
@@ -616,38 +602,6 @@ bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport)
        bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP);
 }
 
-/**
- *   Module initialization
- */
-void
-bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs)
-{
-}
-
-/**
- *   Module cleanup
- */
-void
-bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs)
-{
-       bfa_fcs_modexit_comp(fcs);
-}
-
-u32
-bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs)
-{
-       struct bfa_ioc_attr_s ioc_attr;
-
-       bfa_get_attr(fcs->bfa, &ioc_attr);
-
-       if (ioc_attr.pci_attr.device_id == BFA_PCI_DEVICE_ID_CT)
-               return BFA_FCS_MAX_VPORTS_SUPP_CT;
-       else
-               return BFA_FCS_MAX_VPORTS_SUPP_CB;
-}
-
-
-
 /**
  *  fcs_vport_api Virtual port API
  */
@@ -684,7 +638,7 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
                return BFA_STATUS_VPORT_EXISTS;
 
        if (bfa_fcs_fabric_vport_count(&fcs->fabric) ==
-           bfa_fcs_vport_get_max(fcs))
+               bfa_lps_get_max_vport(fcs->bfa))
                return BFA_STATUS_VPORT_MAX;
 
        vport->lps = bfa_lps_alloc(fcs->bfa);
@@ -694,7 +648,8 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
        vport->vport_drv = vport_drv;
        bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
 
-       bfa_fcs_lport_init(&vport->lport, fcs, vf_id, vport_cfg, vport);
+       bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport);
+       bfa_fcs_lport_init(&vport->lport, vport_cfg);
 
        bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE);
 
@@ -888,4 +843,15 @@ bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg)
        bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
 }
 
+/**
+ * Received clear virtual link
+ */
+void
+bfa_cb_lps_cvl_event(void *bfad, void *uarg)
+{
+       struct bfa_fcs_vport_s *vport = uarg;
 
+       /* Send an Offline followed by an ONLINE */
+       bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
+       bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
+}
index 6cf9dc37d78b4883e59ee40cf6f19aaea80636da..6b624e767d3ba1611c4cddecb4e735517f46ddac 100644 (file)
@@ -362,6 +362,7 @@ struct bnx2i_hba {
        u32 num_ccell;
 
        int ofld_conns_active;
+       wait_queue_head_t eh_wait;
 
        int max_active_conns;
        struct iscsi_cid_queue cid_que;
@@ -381,6 +382,7 @@ struct bnx2i_hba {
        spinlock_t lock;        /* protects hba structure access */
        struct mutex net_dev_lock;/* sync net device access */
 
+       int hba_shutdown_tmo;
        /*
         * PCI related info.
         */
index 1af578dec276da2b2254cf85451d9c4c235503f0..18352ff821018b588f2094277564957ae46a2b9c 100644 (file)
@@ -11,6 +11,7 @@
  * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
  */
 
+#include <linux/gfp.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/libiscsi.h>
 #include "bnx2i.h"
index 6d8172e781cff03c976223e49c7e8fc30812b6b5..5d9296c599f641a984ecb79a71b35cdfc80a14a0 100644 (file)
@@ -177,11 +177,22 @@ void bnx2i_stop(void *handle)
        struct bnx2i_hba *hba = handle;
 
        /* check if cleanup happened in GOING_DOWN context */
-       clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
        if (!test_and_clear_bit(ADAPTER_STATE_GOING_DOWN,
                                &hba->adapter_state))
                iscsi_host_for_each_session(hba->shost,
                                            bnx2i_drop_session);
+
+       /* Wait for all endpoints to be torn down, Chip will be reset once
+        *  control returns to network driver. So it is required to cleanup and
+        * release all connection resources before returning from this routine.
+        */
+       wait_event_interruptible_timeout(hba->eh_wait,
+                                        (hba->ofld_conns_active == 0),
+                                        hba->hba_shutdown_tmo);
+       /* This flag should be cleared last so that ep_disconnect() gracefully
+        * cleans up connection context
+        */
+       clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
 }
 
 /**
index 1c4d1215769dc72704edc6d6dc8f85fd677086c8..fa68ab34b9985588f0ad6af4910b587d2625790f 100644 (file)
@@ -12,6 +12,7 @@
  * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
  */
 
+#include <linux/slab.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/libiscsi.h>
 #include "bnx2i.h"
@@ -819,6 +820,11 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic)
 
        spin_lock_init(&hba->lock);
        mutex_init(&hba->net_dev_lock);
+       init_waitqueue_head(&hba->eh_wait);
+       if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type))
+               hba->hba_shutdown_tmo = 240 * HZ;
+       else    /* 5706/5708/5709 */
+               hba->hba_shutdown_tmo = 30 * HZ;
 
        if (iscsi_host_add(shost, &hba->pcidev->dev))
                goto free_dump_mem;
@@ -1657,8 +1663,8 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
                 */
                hba = bnx2i_check_route(dst_addr);
 
-       if (!hba) {
-               rc = -ENOMEM;
+       if (!hba || test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state)) {
+               rc = -EINVAL;
                goto check_busy;
        }
 
@@ -1803,7 +1809,7 @@ static int bnx2i_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
                                               (bnx2i_ep->state ==
                                                EP_STATE_CONNECT_COMPL)),
                                              msecs_to_jiffies(timeout_ms));
-       if (!rc || (bnx2i_ep->state == EP_STATE_OFLD_FAILED))
+       if (bnx2i_ep->state == EP_STATE_OFLD_FAILED)
                rc = -1;
 
        if (rc > 0)
@@ -1956,6 +1962,8 @@ return_bnx2i_ep:
 
        if (!hba->ofld_conns_active)
                bnx2i_unreg_dev_all();
+
+       wake_up_interruptible(&hba->eh_wait);
 }
 
 
@@ -1989,7 +1997,7 @@ static struct scsi_host_template bnx2i_host_template = {
        .queuecommand           = iscsi_queuecommand,
        .eh_abort_handler       = iscsi_eh_abort,
        .eh_device_reset_handler = iscsi_eh_device_reset,
-       .eh_target_reset_handler = iscsi_eh_target_reset,
+       .eh_target_reset_handler = iscsi_eh_recover_target,
        .change_queue_depth     = iscsi_change_queue_depth,
        .can_queue              = 1024,
        .max_sectors            = 127,
index 5799cb5cba6b5643e4128cab450aa49d1f0f754c..d40ea2f5be106374a71d037b17eb7c91263b5e88 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <asm/bvme6000hw.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
index fe11c1d4b31d58a5cab85c92be0e8e824330f9ae..4799d439120358395519b7c3def4dc0ff9575362 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/mutex.h>
 #include <linux/idr.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index 344fd53b9954c263ef1189ee489e40d54cd5055a..b58d9134ac1b53cdd3f13defbdd79a03e142f956 100644 (file)
@@ -10,6 +10,7 @@
  * Written by: Karen Xie (kxie@chelsio.com)
  */
 
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/scatterlist.h>
 
index 87dd56b422bfb4ed07c783765d94c32e38173529..6761b329124decf34f89f0b86710ba542cbbdea7 100644 (file)
@@ -13,6 +13,7 @@
 #ifndef __CXGB3I_ULP2_DDP_H__
 #define __CXGB3I_ULP2_DDP_H__
 
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 /**
index 412853c653721bc9afbb7e95241be07dcb76a7cf..7b686abaae6459cfffabe331e053cd798b7226e1 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/inet.h>
+#include <linux/slab.h>
 #include <linux/crypto.h>
 #include <linux/if_vlan.h>
 #include <net/dst.h>
@@ -915,7 +916,7 @@ static struct scsi_host_template cxgb3i_host_template = {
        .cmd_per_lun            = ISCSI_DEF_CMD_PER_LUN,
        .eh_abort_handler       = iscsi_eh_abort,
        .eh_device_reset_handler = iscsi_eh_device_reset,
-       .eh_target_reset_handler = iscsi_eh_target_reset,
+       .eh_target_reset_handler = iscsi_eh_recover_target,
        .target_alloc           = iscsi_target_alloc,
        .use_clustering         = DISABLE_CLUSTERING,
        .this_id                = -1,
index 3e08c430ff2997c25d2727d013f02f71aff0cb1c..a175be9c496f479c0687bf15a126a13fb0b13941 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/if_vlan.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 
 #include "cxgb3_defs.h"
index 9c38539557fc9fc356f383a91b8ebe121cd37bb7..dc5e3e77a351c5ec421f36a0be9f681427acbb3f 100644 (file)
@@ -12,6 +12,7 @@
  * Written by: Karen Xie (kxie@chelsio.com)
  */
 
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/crypto.h>
 #include <scsi/scsi_cmnd.h>
index 6c59c02c1ed9959e487e54258a1dd5f966742976..bd977be7544e37355c35b2addf55d02ef9747039 100644 (file)
@@ -57,6 +57,7 @@
 #include <linux/pci.h>
 #include <linux/list.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 #include <scsi/scsi.h>
index e19a1a55270c03b443e47cfbba7b15bd65cfe7fd..6fae3d285ae79d5680f3d1e5d4cad02f5b47d3b6 100644 (file)
@@ -21,6 +21,7 @@
  *               Mike Anderson <andmike@linux.vnet.ibm.com>
  */
 
+#include <linux/slab.h>
 #include <scsi/scsi_dh.h>
 #include "../scsi_priv.h"
 
index bc9e94f5915e1227a14262b907f14858711c134b..1a970a76b1b959cc3906dd0579159b22eb1eaadc 100644 (file)
@@ -19,6 +19,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
  */
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_dh.h>
index 61966750bd60a8dd124e3ba36d40a31b27df531e..e8a0bc3efd491a91d212233e46c3b29f94498967 100644 (file)
@@ -20,6 +20,7 @@
  * along with this program; see the file COPYING.  If not, write to
  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  */
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_dh.h>
@@ -272,7 +273,7 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
        int len = 0;
 
        rq = blk_get_request(sdev->request_queue,
-                       (cmd == MODE_SELECT) ? WRITE : READ, GFP_NOIO);
+                       (cmd != INQUIRY) ? WRITE : READ, GFP_NOIO);
        if (!rq) {
                sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed");
                return NULL;
@@ -286,14 +287,17 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
                len = sizeof(short_trespass);
                rq->cmd_flags |= REQ_RW;
                rq->cmd[1] = 0x10;
+               rq->cmd[4] = len;
                break;
        case MODE_SELECT_10:
                len = sizeof(long_trespass);
                rq->cmd_flags |= REQ_RW;
                rq->cmd[1] = 0x10;
+               rq->cmd[8] = len;
                break;
        case INQUIRY:
                len = CLARIION_BUFFER_SIZE;
+               rq->cmd[4] = len;
                memset(buffer, 0, len);
                break;
        default:
@@ -301,7 +305,6 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
                break;
        }
 
-       rq->cmd[4] = len;
        rq->cmd_type = REQ_TYPE_BLOCK_PC;
        rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
                         REQ_FAILFAST_DRIVER;
index 857fdd6032b25a8df5efee8e70740ea135ae07be..e3916641e627883418d18b4eeb94bcbe1ddec018 100644 (file)
@@ -21,6 +21,7 @@
  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_eh.h>
index 1a660191a90547039ae7b5815e3ad8620a8b79d3..5b683e4295420a2e3e67dd3f298cebbec9c3273d 100644 (file)
@@ -23,6 +23,7 @@
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_dh.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 #define RDAC_NAME "rdac"
 #define RDAC_RETRY_COUNT 5
index 496764349c4143ce5ac50c8bfd3fb1854144986c..0435d044c9da1fa12dfc03455e79629126c9593b 100644 (file)
@@ -188,7 +188,8 @@ MODULE_DEVICE_TABLE(pci,dptids);
 static int adpt_detect(struct scsi_host_template* sht)
 {
        struct pci_dev *pDev = NULL;
-       adpt_hba* pHba;
+       adpt_hba *pHba;
+       adpt_hba *next;
 
        PINFO("Detecting Adaptec I2O RAID controllers...\n");
 
@@ -206,7 +207,8 @@ static int adpt_detect(struct scsi_host_template* sht)
        }
 
        /* In INIT state, Activate IOPs */
-       for (pHba = hba_chain; pHba; pHba = pHba->next) {
+       for (pHba = hba_chain; pHba; pHba = next) {
+               next = pHba->next;
                // Activate does get status , init outbound, and get hrt
                if (adpt_i2o_activate_hba(pHba) < 0) {
                        adpt_i2o_delete_hba(pHba);
@@ -243,7 +245,8 @@ rebuild_sys_tab:
        PDEBUG("HBA's in OPERATIONAL state\n");
 
        printk("dpti: If you have a lot of devices this could take a few minutes.\n");
-       for (pHba = hba_chain; pHba; pHba = pHba->next) {
+       for (pHba = hba_chain; pHba; pHba = next) {
+               next = pHba->next;
                printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
                if (adpt_i2o_lct_get(pHba) < 0){
                        adpt_i2o_delete_hba(pHba);
@@ -263,7 +266,8 @@ rebuild_sys_tab:
                adpt_sysfs_class = NULL;
        }
 
-       for (pHba = hba_chain; pHba; pHba = pHba->next) {
+       for (pHba = hba_chain; pHba; pHba = next) {
+               next = pHba->next;
                if (adpt_scsi_host_alloc(pHba, sht) < 0){
                        adpt_i2o_delete_hba(pHba);
                        continue;
@@ -1229,11 +1233,10 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
                }
        }
        pci_dev_put(pHba->pDev);
-       kfree(pHba);
-
        if (adpt_sysfs_class)
                device_destroy(adpt_sysfs_class,
                                MKDEV(DPTI_I2O_MAJOR, pHba->unit));
+       kfree(pHba);
 
        if(hba_count <= 0){
                unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);   
index 3c5abf7cd762d0fa3229e37fc14914e86d64de89..d1c31378f6da9823b67e895ae7143578cfa110ee 100644 (file)
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 #include <asm/dma.h>
 #include <asm/io.h>
index 152dd15db276c42af82ccc39bde3ed0d9d346cb3..60886c19065e290a4475822d183aa92c8dc4de0c 100644 (file)
@@ -50,7 +50,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/in.h>
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
index 2f47ae7cce91a21069d4335b603bc26aa6320613..f01b9b44e8aa8a6ab387a969e7b7701400a4d1cf 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
 #include <linux/crc32.h>
+#include <linux/slab.h>
 #include <linux/cpu.h>
 #include <linux/fs.h>
 #include <linux/sysfs.h>
index 511cb6b371eec6429b92cd7a9bfd7c626a1d0357..3440da48d1698d3b2fde2796d1df1ea333edd3a9 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/if_vlan.h>
 #include <linux/errno.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include <net/rtnetlink.h>
 
 #include <scsi/fc/fc_els.h>
index 85bd54c77b50b950947157d4521370ce2dec36b3..2ad95aa8f58536a664a4c7d2114c4505d27355fe 100644 (file)
@@ -88,6 +88,7 @@
 #include <linux/delay.h>
 #include <linux/mca.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <scsi/scsicam.h>
 #include <linux/mca-legacy.h>
 
index 32eef66114c74a40cb01ab6b8351ccc1af38e997..e296bcc57d5c8920a2b90cf9a0858cac91e60d07 100644 (file)
 #include <linux/stat.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <scsi/scsicam.h>
 
 #include <asm/system.h>
index 54f8d0e5407f4ba179344bedb06e68d1f260bd87..5259888fbfb19fe95137dfdbe9f543e0c56e7cec 100644 (file)
@@ -17,6 +17,7 @@
  */
 #include <linux/errno.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
index 507e26c1c29f05c29727509ba3aaf8e363da5306..97b212570bcc67f2431d86b17740e1051812f031 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/mempool.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/pci.h>
index 65a39b0f6dc24a6430d4434bb59312d594a5ead5..3cc47c6e1ada8d4e38309cc496bfca641d090102 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
index 566770645086612f9371b6be1f3e83f0d34d0e0a..db710148d1568ba8d3b7e12b726954c767a8c09e 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/if_ether.h>
+#include <linux/slab.h>
 #include "vnic_resource.h"
 #include "vnic_devcmd.h"
 #include "vnic_dev.h"
index bedd0d285630287ffc1b5d5cc379437cd3da4734..fd2068f5ae1675478d6ee2edd325633581a79f7c 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include "vnic_dev.h"
 #include "vnic_rq.h"
 
index 1f9ea790d1301c6d604fa60b4d5350e40b00c7b2..a414135460dba770e318ffa72746a6972fdcc3de 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include "vnic_dev.h"
 #include "vnic_wq.h"
 
index ba3c94c9c25f22cb00bbf2dd64db394e85c51944..35a4b3073ec3fa992a406162b9bf3dac038bff97 100644 (file)
 #include <linux/dma-mapping.h>
 #include <linux/list.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 
 #ifdef GDTH_RTC
 #include <linux/mc146818rtc.h>
index ffb2b21992bae81dc7424b130489141aed80eb8a..0572b9bf4bd6e79c8b7650a4ef970039744a58cf 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include <linux/completion.h>
+#include <linux/slab.h>
 
 int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length,   
                    int inout)
index 5d1bf7e3d245988649b75ac4ae352579a31cc087..48f406850c6507f1532f5a9d843d1eb4ed78ebe9 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/types.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
index 09dbcb847b73c307ecb835e6463735f00ce9139c..6660fa92ffa149a3419ca3c87f7744453e3706fb 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/blkdev.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/kthread.h>
 #include <linux/string.h>
 #include <linux/mm.h>
index 03697ba942510243de25b4f4d093605ac3c16366..183d3a43c28041c54a3904e512a8d6eba9a77cbe 100644 (file)
@@ -43,6 +43,7 @@
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
 #include <linux/cciss_ioctl.h>
 #include <linux/string.h>
 #include <linux/bitmap.h>
@@ -52,7 +53,7 @@
 #include "hpsa.h"
 
 /* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */
-#define HPSA_DRIVER_VERSION "2.0.1-3"
+#define HPSA_DRIVER_VERSION "2.0.2-1"
 #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
 
 /* How long to wait (in milliseconds) for board to go into simple mode */
@@ -134,6 +135,8 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
 static void hpsa_scan_start(struct Scsi_Host *);
 static int hpsa_scan_finished(struct Scsi_Host *sh,
        unsigned long elapsed_time);
+static int hpsa_change_queue_depth(struct scsi_device *sdev,
+       int qdepth, int reason);
 
 static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd);
 static int hpsa_slave_alloc(struct scsi_device *sdev);
@@ -182,8 +185,8 @@ static struct scsi_host_template hpsa_driver_template = {
        .queuecommand           = hpsa_scsi_queue_command,
        .scan_start             = hpsa_scan_start,
        .scan_finished          = hpsa_scan_finished,
+       .change_queue_depth     = hpsa_change_queue_depth,
        .this_id                = -1,
-       .sg_tablesize           = MAXSGENTRIES,
        .use_clustering         = ENABLE_CLUSTERING,
        .eh_device_reset_handler = hpsa_eh_device_reset_handler,
        .ioctl                  = hpsa_ioctl,
@@ -208,133 +211,6 @@ static inline struct ctlr_info *shost_to_hba(struct Scsi_Host *sh)
        return (struct ctlr_info *) *priv;
 }
 
-static struct task_struct *hpsa_scan_thread;
-static DEFINE_MUTEX(hpsa_scan_mutex);
-static LIST_HEAD(hpsa_scan_q);
-static int hpsa_scan_func(void *data);
-
-/**
- * add_to_scan_list() - add controller to rescan queue
- * @h:               Pointer to the controller.
- *
- * Adds the controller to the rescan queue if not already on the queue.
- *
- * returns 1 if added to the queue, 0 if skipped (could be on the
- * queue already, or the controller could be initializing or shutting
- * down).
- **/
-static int add_to_scan_list(struct ctlr_info *h)
-{
-       struct ctlr_info *test_h;
-       int found = 0;
-       int ret = 0;
-
-       if (h->busy_initializing)
-               return 0;
-
-       /*
-        * If we don't get the lock, it means the driver is unloading
-        * and there's no point in scheduling a new scan.
-        */
-       if (!mutex_trylock(&h->busy_shutting_down))
-               return 0;
-
-       mutex_lock(&hpsa_scan_mutex);
-       list_for_each_entry(test_h, &hpsa_scan_q, scan_list) {
-               if (test_h == h) {
-                       found = 1;
-                       break;
-               }
-       }
-       if (!found && !h->busy_scanning) {
-               INIT_COMPLETION(h->scan_wait);
-               list_add_tail(&h->scan_list, &hpsa_scan_q);
-               ret = 1;
-       }
-       mutex_unlock(&hpsa_scan_mutex);
-       mutex_unlock(&h->busy_shutting_down);
-
-       return ret;
-}
-
-/**
- * remove_from_scan_list() - remove controller from rescan queue
- * @h:                    Pointer to the controller.
- *
- * Removes the controller from the rescan queue if present. Blocks if
- * the controller is currently conducting a rescan.  The controller
- * can be in one of three states:
- * 1. Doesn't need a scan
- * 2. On the scan list, but not scanning yet (we remove it)
- * 3. Busy scanning (and not on the list). In this case we want to wait for
- *    the scan to complete to make sure the scanning thread for this
- *    controller is completely idle.
- **/
-static void remove_from_scan_list(struct ctlr_info *h)
-{
-       struct ctlr_info *test_h, *tmp_h;
-
-       mutex_lock(&hpsa_scan_mutex);
-       list_for_each_entry_safe(test_h, tmp_h, &hpsa_scan_q, scan_list) {
-               if (test_h == h) { /* state 2. */
-                       list_del(&h->scan_list);
-                       complete_all(&h->scan_wait);
-                       mutex_unlock(&hpsa_scan_mutex);
-                       return;
-               }
-       }
-       if (h->busy_scanning) { /* state 3. */
-               mutex_unlock(&hpsa_scan_mutex);
-               wait_for_completion(&h->scan_wait);
-       } else { /* state 1, nothing to do. */
-               mutex_unlock(&hpsa_scan_mutex);
-       }
-}
-
-/* hpsa_scan_func() - kernel thread used to rescan controllers
- * @data:       Ignored.
- *
- * A kernel thread used scan for drive topology changes on
- * controllers. The thread processes only one controller at a time
- * using a queue.  Controllers are added to the queue using
- * add_to_scan_list() and removed from the queue either after done
- * processing or using remove_from_scan_list().
- *
- * returns 0.
- **/
-static int hpsa_scan_func(__attribute__((unused)) void *data)
-{
-       struct ctlr_info *h;
-       int host_no;
-
-       while (1) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule();
-               if (kthread_should_stop())
-                       break;
-
-               while (1) {
-                       mutex_lock(&hpsa_scan_mutex);
-                       if (list_empty(&hpsa_scan_q)) {
-                               mutex_unlock(&hpsa_scan_mutex);
-                               break;
-                       }
-                       h = list_entry(hpsa_scan_q.next, struct ctlr_info,
-                                       scan_list);
-                       list_del(&h->scan_list);
-                       h->busy_scanning = 1;
-                       mutex_unlock(&hpsa_scan_mutex);
-                       host_no = h->scsi_host ?  h->scsi_host->host_no : -1;
-                       hpsa_scan_start(h->scsi_host);
-                       complete_all(&h->scan_wait);
-                       mutex_lock(&hpsa_scan_mutex);
-                       h->busy_scanning = 0;
-                       mutex_unlock(&hpsa_scan_mutex);
-               }
-       }
-       return 0;
-}
-
 static int check_for_unit_attention(struct ctlr_info *h,
        struct CommandList *c)
 {
@@ -352,21 +228,8 @@ static int check_for_unit_attention(struct ctlr_info *h,
                break;
        case REPORT_LUNS_CHANGED:
                dev_warn(&h->pdev->dev, "hpsa%d: report LUN data "
-                       "changed\n", h->ctlr);
+                       "changed, action required\n", h->ctlr);
        /*
-        * Here, we could call add_to_scan_list and wake up the scan thread,
-        * except that it's quite likely that we will get more than one
-        * REPORT_LUNS_CHANGED condition in quick succession, which means
-        * that those which occur after the first one will likely happen
-        * *during* the hpsa_scan_thread's rescan.  And the rescan code is not
-        * robust enough to restart in the middle, undoing what it has already
-        * done, and it's not clear that it's even possible to do this, since
-        * part of what it does is notify the SCSI mid layer, which starts
-        * doing it's own i/o to read partition tables and so on, and the
-        * driver doesn't have visibility to know what might need undoing.
-        * In any event, if possible, it is horribly complicated to get right
-        * so we just don't do it for now.
-        *
         * Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012.
         */
                break;
@@ -393,10 +256,7 @@ static ssize_t host_store_rescan(struct device *dev,
        struct ctlr_info *h;
        struct Scsi_Host *shost = class_to_shost(dev);
        h = shost_to_hba(shost);
-       if (add_to_scan_list(h)) {
-               wake_up_process(hpsa_scan_thread);
-               wait_for_completion_interruptible(&h->scan_wait);
-       }
+       hpsa_scan_start(h->scsi_host);
        return count;
 }
 
@@ -983,6 +843,76 @@ static void hpsa_scsi_setup(struct ctlr_info *h)
        spin_lock_init(&h->devlock);
 }
 
+static void hpsa_free_sg_chain_blocks(struct ctlr_info *h)
+{
+       int i;
+
+       if (!h->cmd_sg_list)
+               return;
+       for (i = 0; i < h->nr_cmds; i++) {
+               kfree(h->cmd_sg_list[i]);
+               h->cmd_sg_list[i] = NULL;
+       }
+       kfree(h->cmd_sg_list);
+       h->cmd_sg_list = NULL;
+}
+
+static int hpsa_allocate_sg_chain_blocks(struct ctlr_info *h)
+{
+       int i;
+
+       if (h->chainsize <= 0)
+               return 0;
+
+       h->cmd_sg_list = kzalloc(sizeof(*h->cmd_sg_list) * h->nr_cmds,
+                               GFP_KERNEL);
+       if (!h->cmd_sg_list)
+               return -ENOMEM;
+       for (i = 0; i < h->nr_cmds; i++) {
+               h->cmd_sg_list[i] = kmalloc(sizeof(*h->cmd_sg_list[i]) *
+                                               h->chainsize, GFP_KERNEL);
+               if (!h->cmd_sg_list[i])
+                       goto clean;
+       }
+       return 0;
+
+clean:
+       hpsa_free_sg_chain_blocks(h);
+       return -ENOMEM;
+}
+
+static void hpsa_map_sg_chain_block(struct ctlr_info *h,
+       struct CommandList *c)
+{
+       struct SGDescriptor *chain_sg, *chain_block;
+       u64 temp64;
+
+       chain_sg = &c->SG[h->max_cmd_sg_entries - 1];
+       chain_block = h->cmd_sg_list[c->cmdindex];
+       chain_sg->Ext = HPSA_SG_CHAIN;
+       chain_sg->Len = sizeof(*chain_sg) *
+               (c->Header.SGTotal - h->max_cmd_sg_entries);
+       temp64 = pci_map_single(h->pdev, chain_block, chain_sg->Len,
+                               PCI_DMA_TODEVICE);
+       chain_sg->Addr.lower = (u32) (temp64 & 0x0FFFFFFFFULL);
+       chain_sg->Addr.upper = (u32) ((temp64 >> 32) & 0x0FFFFFFFFULL);
+}
+
+static void hpsa_unmap_sg_chain_block(struct ctlr_info *h,
+       struct CommandList *c)
+{
+       struct SGDescriptor *chain_sg;
+       union u64bit temp64;
+
+       if (c->Header.SGTotal <= h->max_cmd_sg_entries)
+               return;
+
+       chain_sg = &c->SG[h->max_cmd_sg_entries - 1];
+       temp64.val32.lower = chain_sg->Addr.lower;
+       temp64.val32.upper = chain_sg->Addr.upper;
+       pci_unmap_single(h->pdev, temp64.val, chain_sg->Len, PCI_DMA_TODEVICE);
+}
+
 static void complete_scsi_command(struct CommandList *cp,
        int timeout, u32 tag)
 {
@@ -999,10 +929,12 @@ static void complete_scsi_command(struct CommandList *cp,
        h = cp->h;
 
        scsi_dma_unmap(cmd); /* undo the DMA mappings */
+       if (cp->Header.SGTotal > h->max_cmd_sg_entries)
+               hpsa_unmap_sg_chain_block(h, cp);
 
        cmd->result = (DID_OK << 16);           /* host byte */
        cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
-       cmd->result |= (ei->ScsiStatus << 1);
+       cmd->result |= ei->ScsiStatus;
 
        /* copy the sense data whether we need to or not. */
        memcpy(cmd->sense_buffer, ei->SenseInfo,
@@ -1203,6 +1135,7 @@ static int hpsa_scsi_detect(struct ctlr_info *h)
        sh->max_id = HPSA_MAX_LUN;
        sh->can_queue = h->nr_cmds;
        sh->cmd_per_lun = h->nr_cmds;
+       sh->sg_tablesize = h->maxsgentries;
        h->scsi_host = sh;
        sh->hostdata[0] = (unsigned long) h;
        sh->irq = h->intr[PERF_MODE_INT];
@@ -1382,7 +1315,7 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr)
 
        if (c == NULL) {                        /* trouble... */
                dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n");
-               return -1;
+               return -ENOMEM;
        }
 
        fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0, scsi3addr, TYPE_MSG);
@@ -1904,16 +1837,17 @@ out:
  * dma mapping  and fills in the scatter gather entries of the
  * hpsa command, cp.
  */
-static int hpsa_scatter_gather(struct pci_dev *pdev,
+static int hpsa_scatter_gather(struct ctlr_info *h,
                struct CommandList *cp,
                struct scsi_cmnd *cmd)
 {
        unsigned int len;
        struct scatterlist *sg;
        u64 addr64;
-       int use_sg, i;
+       int use_sg, i, sg_index, chained;
+       struct SGDescriptor *curr_sg;
 
-       BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES);
+       BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);
 
        use_sg = scsi_dma_map(cmd);
        if (use_sg < 0)
@@ -1922,15 +1856,33 @@ static int hpsa_scatter_gather(struct pci_dev *pdev,
        if (!use_sg)
                goto sglist_finished;
 
+       curr_sg = cp->SG;
+       chained = 0;
+       sg_index = 0;
        scsi_for_each_sg(cmd, sg, use_sg, i) {
+               if (i == h->max_cmd_sg_entries - 1 &&
+                       use_sg > h->max_cmd_sg_entries) {
+                       chained = 1;
+                       curr_sg = h->cmd_sg_list[cp->cmdindex];
+                       sg_index = 0;
+               }
                addr64 = (u64) sg_dma_address(sg);
                len  = sg_dma_len(sg);
-               cp->SG[i].Addr.lower =
-                       (u32) (addr64 & (u64) 0x00000000FFFFFFFF);
-               cp->SG[i].Addr.upper =
-                       (u32) ((addr64 >> 32) & (u64) 0x00000000FFFFFFFF);
-               cp->SG[i].Len = len;
-               cp->SG[i].Ext = 0;  /* we are not chaining */
+               curr_sg->Addr.lower = (u32) (addr64 & 0x0FFFFFFFFULL);
+               curr_sg->Addr.upper = (u32) ((addr64 >> 32) & 0x0FFFFFFFFULL);
+               curr_sg->Len = len;
+               curr_sg->Ext = 0;  /* we are not chaining */
+               curr_sg++;
+       }
+
+       if (use_sg + chained > h->maxSG)
+               h->maxSG = use_sg + chained;
+
+       if (chained) {
+               cp->Header.SGList = h->max_cmd_sg_entries;
+               cp->Header.SGTotal = (u16) (use_sg + 1);
+               hpsa_map_sg_chain_block(h, cp);
+               return 0;
        }
 
 sglist_finished:
@@ -2026,7 +1978,7 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
                break;
        }
 
-       if (hpsa_scatter_gather(h->pdev, c, cmd) < 0) { /* Fill SG list */
+       if (hpsa_scatter_gather(h, c, cmd) < 0) { /* Fill SG list */
                cmd_free(h, c);
                return SCSI_MLQUEUE_HOST_BUSY;
        }
@@ -2077,6 +2029,23 @@ static int hpsa_scan_finished(struct Scsi_Host *sh,
        return finished;
 }
 
+static int hpsa_change_queue_depth(struct scsi_device *sdev,
+       int qdepth, int reason)
+{
+       struct ctlr_info *h = sdev_to_hba(sdev);
+
+       if (reason != SCSI_QDEPTH_DEFAULT)
+               return -ENOTSUPP;
+
+       if (qdepth < 1)
+               qdepth = 1;
+       else
+               if (qdepth > h->nr_cmds)
+                       qdepth = h->nr_cmds;
+       scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+       return sdev->queue_depth;
+}
+
 static void hpsa_unregister_scsi(struct ctlr_info *h)
 {
        /* we are being forcibly unloaded, and may not refuse. */
@@ -2961,7 +2930,7 @@ static irqreturn_t do_hpsa_intr(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-/* Send a message CDB to the firmwart. */
+/* Send a message CDB to the firmware. */
 static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode,
                                                unsigned char type)
 {
@@ -3296,7 +3265,7 @@ default_int_mode:
        h->intr[PERF_MODE_INT] = pdev->irq;
 }
 
-static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
+static int __devinit hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
 {
        ushort subsystem_vendor_id, subsystem_device_id, command;
        u32 board_id, scratchpad = 0;
@@ -3405,6 +3374,23 @@ static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
 
        h->board_id = board_id;
        h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
+       h->maxsgentries = readl(&(h->cfgtable->MaxScatterGatherElements));
+
+       /*
+        * Limit in-command s/g elements to 32 save dma'able memory.
+        * Howvever spec says if 0, use 31
+        */
+
+       h->max_cmd_sg_entries = 31;
+       if (h->maxsgentries > 512) {
+               h->max_cmd_sg_entries = 32;
+               h->chainsize = h->maxsgentries - h->max_cmd_sg_entries + 1;
+               h->maxsgentries--; /* save one for chain pointer */
+       } else {
+               h->maxsgentries = 31; /* default to traditional values */
+               h->chainsize = 0;
+       }
+
        h->product_name = products[prod_index].product_name;
        h->access = *(products[prod_index].access);
        /* Allow room for some ioctls */
@@ -3532,8 +3518,6 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
        h->busy_initializing = 1;
        INIT_HLIST_HEAD(&h->cmpQ);
        INIT_HLIST_HEAD(&h->reqQ);
-       mutex_init(&h->busy_shutting_down);
-       init_completion(&h->scan_wait);
        rc = hpsa_pci_init(h, pdev);
        if (rc != 0)
                goto clean1;
@@ -3587,6 +3571,8 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
                rc = -ENOMEM;
                goto clean4;
        }
+       if (hpsa_allocate_sg_chain_blocks(h))
+               goto clean4;
        spin_lock_init(&h->lock);
        spin_lock_init(&h->scan_lock);
        init_waitqueue_head(&h->scan_wait_queue);
@@ -3609,6 +3595,7 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
        return 1;
 
 clean4:
+       hpsa_free_sg_chain_blocks(h);
        kfree(h->cmd_pool_bits);
        if (h->cmd_pool)
                pci_free_consistent(h->pdev,
@@ -3681,11 +3668,10 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
                return;
        }
        h = pci_get_drvdata(pdev);
-       mutex_lock(&h->busy_shutting_down);
-       remove_from_scan_list(h);
        hpsa_unregister_scsi(h);        /* unhook from SCSI subsystem */
        hpsa_shutdown(pdev);
        iounmap(h->vaddr);
+       hpsa_free_sg_chain_blocks(h);
        pci_free_consistent(h->pdev,
                h->nr_cmds * sizeof(struct CommandList),
                h->cmd_pool, h->cmd_pool_dhandle);
@@ -3703,7 +3689,6 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
         */
        pci_release_regions(pdev);
        pci_set_drvdata(pdev, NULL);
-       mutex_unlock(&h->busy_shutting_down);
        kfree(h);
 }
 
@@ -3857,23 +3842,12 @@ clean_up:
  */
 static int __init hpsa_init(void)
 {
-       int err;
-       /* Start the scan thread */
-       hpsa_scan_thread = kthread_run(hpsa_scan_func, NULL, "hpsa_scan");
-       if (IS_ERR(hpsa_scan_thread)) {
-               err = PTR_ERR(hpsa_scan_thread);
-               return -ENODEV;
-       }
-       err = pci_register_driver(&hpsa_pci_driver);
-       if (err)
-               kthread_stop(hpsa_scan_thread);
-       return err;
+       return pci_register_driver(&hpsa_pci_driver);
 }
 
 static void __exit hpsa_cleanup(void)
 {
        pci_unregister_driver(&hpsa_pci_driver);
-       kthread_stop(hpsa_scan_thread);
 }
 
 module_init(hpsa_init);
index a0502b3ac17eb297eec8957ad38b9e57fe592d95..1bb5233b09a0e5eb7ee5365488da09ada6252630 100644 (file)
@@ -83,6 +83,10 @@ struct ctlr_info {
        unsigned int maxQsinceinit;
        unsigned int maxSG;
        spinlock_t lock;
+       int maxsgentries;
+       u8 max_cmd_sg_entries;
+       int chainsize;
+       struct SGDescriptor **cmd_sg_list;
 
        /* pointers to command and error info pool */
        struct CommandList      *cmd_pool;
@@ -97,9 +101,6 @@ struct ctlr_info {
        int                     scan_finished;
        spinlock_t              scan_lock;
        wait_queue_head_t       scan_wait_queue;
-       struct mutex            busy_shutting_down;
-       struct list_head        scan_list;
-       struct completion       scan_wait;
 
        struct Scsi_Host *scsi_host;
        spinlock_t devlock; /* to protect hba[ctlr]->dev[];  */
index 3e0abdf7668921005fd42bc58a26b2cc083a75ca..56fb9827681e7d3884ae97c52fbc5cd8673f8180 100644 (file)
@@ -23,7 +23,8 @@
 
 /* general boundary defintions */
 #define SENSEINFOBYTES          32 /* may vary between hbas */
-#define MAXSGENTRIES            31
+#define MAXSGENTRIES            32
+#define HPSA_SG_CHAIN          0x80000000
 #define MAXREPLYQS              256
 
 /* Command Status value */
@@ -305,20 +306,23 @@ struct CommandList {
        int                        cmd_type;
        long                       cmdindex;
        struct hlist_node list;
-       struct CommandList *prev;
-       struct CommandList *next;
        struct request *rq;
        struct completion *waiting;
-       int      retry_count;
        void   *scsi_cmd;
 
 /* on 64 bit architectures, to get this to be 32-byte-aligned
- * it so happens we need no padding, on 32 bit systems,
- * we need 8 bytes of padding.   This does that.
+ * it so happens we need PAD_64 bytes of padding, on 32 bit systems,
+ * we need PAD_32 bytes of padding (see below).   This does that.
+ * If it happens that 64 bit and 32 bit systems need different
+ * padding, PAD_32 and PAD_64 can be set independently, and.
+ * the code below will do the right thing.
  */
-#define COMMANDLIST_PAD ((8 - sizeof(long))/4 * 8)
+#define IS_32_BIT ((8 - sizeof(long))/4)
+#define IS_64_BIT (!IS_32_BIT)
+#define PAD_32 (4)
+#define PAD_64 (4)
+#define COMMANDLIST_PAD (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64)
        u8 pad[COMMANDLIST_PAD];
-
 };
 
 /* Configuration Table Structure */
index 4f0556571f80d933aa1fdc6f0b9ed34a493e2790..645f7cdf21abb377731690c393434b0c202c1507 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/timer.h>
 #include <linux/spinlock.h>
+#include <linux/gfp.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/div64.h>
index 732f6d35b4a8e4aebf9af1c7ef07bb593edf9a3f..c2eea711a5ceea72103b8ac4bbeff90519c2747e 100644 (file)
@@ -28,7 +28,9 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/pm.h>
 #include <linux/stringify.h>
 #include <asm/firmware.h>
 #include <asm/irq.h>
@@ -4735,6 +4737,27 @@ static int ibmvfc_remove(struct vio_dev *vdev)
        return 0;
 }
 
+/**
+ * ibmvfc_resume - Resume from suspend
+ * @dev:       device struct
+ *
+ * We may have lost an interrupt across suspend/resume, so kick the
+ * interrupt handler
+ *
+ */
+static int ibmvfc_resume(struct device *dev)
+{
+       unsigned long flags;
+       struct ibmvfc_host *vhost = dev_get_drvdata(dev);
+       struct vio_dev *vdev = to_vio_dev(dev);
+
+       spin_lock_irqsave(vhost->host->host_lock, flags);
+       vio_disable_interrupts(vdev);
+       tasklet_schedule(&vhost->tasklet);
+       spin_unlock_irqrestore(vhost->host->host_lock, flags);
+       return 0;
+}
+
 /**
  * ibmvfc_get_desired_dma - Calculate DMA resources needed by the driver
  * @vdev:      vio device struct
@@ -4755,6 +4778,10 @@ static struct vio_device_id ibmvfc_device_table[] __devinitdata = {
 };
 MODULE_DEVICE_TABLE(vio, ibmvfc_device_table);
 
+static struct dev_pm_ops ibmvfc_pm_ops = {
+       .resume = ibmvfc_resume
+};
+
 static struct vio_driver ibmvfc_driver = {
        .id_table = ibmvfc_device_table,
        .probe = ibmvfc_probe,
@@ -4763,6 +4790,7 @@ static struct vio_driver ibmvfc_driver = {
        .driver = {
                .name = IBMVFC_NAME,
                .owner = THIS_MODULE,
+               .pm = &ibmvfc_pm_ops,
        }
 };
 
index e3a18e0ef276511e33061eb86b8cfb5f8f763241..88bad0e81bdda3b5195396b9e2e6d0d7dc4f26e2 100644 (file)
@@ -70,7 +70,9 @@
 #include <linux/moduleparam.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/pm.h>
 #include <asm/firmware.h>
 #include <asm/vio.h>
 #include <scsi/scsi.h>
@@ -321,16 +323,6 @@ static void set_srp_direction(struct scsi_cmnd *cmd,
                srp_cmd->buf_fmt = fmt;
 }
 
-static void unmap_sg_list(int num_entries,
-               struct device *dev,
-               struct srp_direct_buf *md)
-{
-       int i;
-
-       for (i = 0; i < num_entries; ++i)
-               dma_unmap_single(dev, md[i].va, md[i].len, DMA_BIDIRECTIONAL);
-}
-
 /**
  * unmap_cmd_data: - Unmap data pointed in srp_cmd based on the format
  * @cmd:       srp_cmd whose additional_data member will be unmapped
@@ -348,24 +340,9 @@ static void unmap_cmd_data(struct srp_cmd *cmd,
 
        if (out_fmt == SRP_NO_DATA_DESC && in_fmt == SRP_NO_DATA_DESC)
                return;
-       else if (out_fmt == SRP_DATA_DESC_DIRECT ||
-                in_fmt == SRP_DATA_DESC_DIRECT) {
-               struct srp_direct_buf *data =
-                       (struct srp_direct_buf *) cmd->add_data;
-               dma_unmap_single(dev, data->va, data->len, DMA_BIDIRECTIONAL);
-       } else {
-               struct srp_indirect_buf *indirect =
-                       (struct srp_indirect_buf *) cmd->add_data;
-               int num_mapped = indirect->table_desc.len /
-                       sizeof(struct srp_direct_buf);
-
-               if (num_mapped <= MAX_INDIRECT_BUFS) {
-                       unmap_sg_list(num_mapped, dev, &indirect->desc_list[0]);
-                       return;
-               }
 
-               unmap_sg_list(num_mapped, dev, evt_struct->ext_list);
-       }
+       if (evt_struct->cmnd)
+               scsi_dma_unmap(evt_struct->cmnd);
 }
 
 static int map_sg_list(struct scsi_cmnd *cmd, int nseg,
@@ -1990,6 +1967,19 @@ static int ibmvscsi_remove(struct vio_dev *vdev)
        return 0;
 }
 
+/**
+ * ibmvscsi_resume: Resume from suspend
+ * @dev:       device struct
+ *
+ * We may have lost an interrupt across suspend/resume, so kick the
+ * interrupt handler
+ */
+static int ibmvscsi_resume(struct device *dev)
+{
+       struct ibmvscsi_host_data *hostdata = dev_get_drvdata(dev);
+       return ibmvscsi_ops->resume(hostdata);
+}
+
 /**
  * ibmvscsi_device_table: Used by vio.c to match devices in the device tree we 
  * support.
@@ -2000,6 +1990,10 @@ static struct vio_device_id ibmvscsi_device_table[] __devinitdata = {
 };
 MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table);
 
+static struct dev_pm_ops ibmvscsi_pm_ops = {
+       .resume = ibmvscsi_resume
+};
+
 static struct vio_driver ibmvscsi_driver = {
        .id_table = ibmvscsi_device_table,
        .probe = ibmvscsi_probe,
@@ -2008,6 +2002,7 @@ static struct vio_driver ibmvscsi_driver = {
        .driver = {
                .name = "ibmvscsi",
                .owner = THIS_MODULE,
+               .pm = &ibmvscsi_pm_ops,
        }
 };
 
index 76425303def0c0265b89db3ea656132cf7b756c8..9cb7c6a773e1a1f7a7550c67b9fa49213bacf6a1 100644 (file)
@@ -120,6 +120,7 @@ struct ibmvscsi_ops {
                                  struct ibmvscsi_host_data *hostdata);
        int (*send_crq)(struct ibmvscsi_host_data *hostdata,
                       u64 word1, u64 word2);
+       int (*resume) (struct ibmvscsi_host_data *hostdata);
 };
 
 extern struct ibmvscsi_ops iseriesvscsi_ops;
index d5eaf972710978a9b24464c4e20fadbdac5babae..e2056d517e99d07fdf4b2bd3f4771643b5e9bfa1 100644 (file)
@@ -23,6 +23,7 @@
  */
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport_srp.h>
index 0775fdee5fa80cc4f9609167c8fc2e1769596d30..f4776451a7546fa015dbbe3452870858e5a28a8c 100644 (file)
@@ -158,10 +158,16 @@ static int iseriesvscsi_send_crq(struct ibmvscsi_host_data *hostdata,
                                             0);
 }
 
+static int iseriesvscsi_resume(struct ibmvscsi_host_data *hostdata)
+{
+       return 0;
+}
+
 struct ibmvscsi_ops iseriesvscsi_ops = {
        .init_crq_queue = iseriesvscsi_init_crq_queue,
        .release_crq_queue = iseriesvscsi_release_crq_queue,
        .reset_crq_queue = iseriesvscsi_reset_crq_queue,
        .reenable_crq_queue = iseriesvscsi_reenable_crq_queue,
        .send_crq = iseriesvscsi_send_crq,
+       .resume = iseriesvscsi_resume,
 };
index 462a8574dad96ffa6020c9aa27886c545b8a7988..a864ccc0a342867d387c949e3e11b44ff071f95f 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/iommu.h>
 #include <asm/hvcall.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 #include <linux/interrupt.h>
 #include "ibmvscsi.h"
 
@@ -334,10 +335,23 @@ static int rpavscsi_reenable_crq_queue(struct crq_queue *queue,
        return rc;
 }
 
+/**
+ * rpavscsi_resume: - resume after suspend
+ * @hostdata:  ibmvscsi_host_data of host
+ *
+ */
+static int rpavscsi_resume(struct ibmvscsi_host_data *hostdata)
+{
+       vio_disable_interrupts(to_vio_dev(hostdata->dev));
+       tasklet_schedule(&hostdata->srp_task);
+       return 0;
+}
+
 struct ibmvscsi_ops rpavscsi_ops = {
        .init_crq_queue = rpavscsi_init_crq_queue,
        .release_crq_queue = rpavscsi_release_crq_queue,
        .reset_crq_queue = rpavscsi_reset_crq_queue,
        .reenable_crq_queue = rpavscsi_reenable_crq_queue,
        .send_crq = rpavscsi_send_crq,
+       .resume = rpavscsi_resume,
 };
index c2a9a13d788f2bb6f68e7c921b71270a5dc6d20b..4734ab0b3ff6ab9297352d532bf5aeb530757fe8 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/parport.h>
 #include <linux/workqueue.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 #include <scsi/scsi.h>
index 032f0d0e6cb454695dffaec23b4ddfc0a9fa279f..520461b9bc09036449f1ff2ccd58a09f538ed84f 100644 (file)
@@ -59,6 +59,7 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
@@ -72,6 +73,8 @@
 #include <linux/moduleparam.h>
 #include <linux/libata.h>
 #include <linux/hdreg.h>
+#include <linux/reboot.h>
+#include <linux/stringify.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/processor.h>
@@ -91,8 +94,8 @@ static unsigned int ipr_max_speed = 1;
 static int ipr_testmode = 0;
 static unsigned int ipr_fastfail = 0;
 static unsigned int ipr_transop_timeout = 0;
-static unsigned int ipr_enable_cache = 1;
 static unsigned int ipr_debug = 0;
+static unsigned int ipr_max_devs = IPR_DEFAULT_SIS64_DEVS;
 static unsigned int ipr_dual_ioa_raid = 1;
 static DEFINE_SPINLOCK(ipr_driver_lock);
 
@@ -104,13 +107,20 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
                {
                        .set_interrupt_mask_reg = 0x0022C,
                        .clr_interrupt_mask_reg = 0x00230,
+                       .clr_interrupt_mask_reg32 = 0x00230,
                        .sense_interrupt_mask_reg = 0x0022C,
+                       .sense_interrupt_mask_reg32 = 0x0022C,
                        .clr_interrupt_reg = 0x00228,
+                       .clr_interrupt_reg32 = 0x00228,
                        .sense_interrupt_reg = 0x00224,
+                       .sense_interrupt_reg32 = 0x00224,
                        .ioarrin_reg = 0x00404,
                        .sense_uproc_interrupt_reg = 0x00214,
+                       .sense_uproc_interrupt_reg32 = 0x00214,
                        .set_uproc_interrupt_reg = 0x00214,
-                       .clr_uproc_interrupt_reg = 0x00218
+                       .set_uproc_interrupt_reg32 = 0x00214,
+                       .clr_uproc_interrupt_reg = 0x00218,
+                       .clr_uproc_interrupt_reg32 = 0x00218
                }
        },
        { /* Snipe and Scamp */
@@ -119,25 +129,59 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
                {
                        .set_interrupt_mask_reg = 0x00288,
                        .clr_interrupt_mask_reg = 0x0028C,
+                       .clr_interrupt_mask_reg32 = 0x0028C,
                        .sense_interrupt_mask_reg = 0x00288,
+                       .sense_interrupt_mask_reg32 = 0x00288,
                        .clr_interrupt_reg = 0x00284,
+                       .clr_interrupt_reg32 = 0x00284,
                        .sense_interrupt_reg = 0x00280,
+                       .sense_interrupt_reg32 = 0x00280,
                        .ioarrin_reg = 0x00504,
                        .sense_uproc_interrupt_reg = 0x00290,
+                       .sense_uproc_interrupt_reg32 = 0x00290,
                        .set_uproc_interrupt_reg = 0x00290,
-                       .clr_uproc_interrupt_reg = 0x00294
+                       .set_uproc_interrupt_reg32 = 0x00290,
+                       .clr_uproc_interrupt_reg = 0x00294,
+                       .clr_uproc_interrupt_reg32 = 0x00294
+               }
+       },
+       { /* CRoC */
+               .mailbox = 0x00040,
+               .cache_line_size = 0x20,
+               {
+                       .set_interrupt_mask_reg = 0x00010,
+                       .clr_interrupt_mask_reg = 0x00018,
+                       .clr_interrupt_mask_reg32 = 0x0001C,
+                       .sense_interrupt_mask_reg = 0x00010,
+                       .sense_interrupt_mask_reg32 = 0x00014,
+                       .clr_interrupt_reg = 0x00008,
+                       .clr_interrupt_reg32 = 0x0000C,
+                       .sense_interrupt_reg = 0x00000,
+                       .sense_interrupt_reg32 = 0x00004,
+                       .ioarrin_reg = 0x00070,
+                       .sense_uproc_interrupt_reg = 0x00020,
+                       .sense_uproc_interrupt_reg32 = 0x00024,
+                       .set_uproc_interrupt_reg = 0x00020,
+                       .set_uproc_interrupt_reg32 = 0x00024,
+                       .clr_uproc_interrupt_reg = 0x00028,
+                       .clr_uproc_interrupt_reg32 = 0x0002C,
+                       .init_feedback_reg = 0x0005C,
+                       .dump_addr_reg = 0x00064,
+                       .dump_data_reg = 0x00068
                }
        },
 };
 
 static const struct ipr_chip_t ipr_chip[] = {
-       { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, &ipr_chip_cfg[0] },
-       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, &ipr_chip_cfg[0] },
-       { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] },
-       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] },
-       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, &ipr_chip_cfg[0] },
-       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, &ipr_chip_cfg[1] },
-       { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, &ipr_chip_cfg[1] }
+       { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] },
+       { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, IPR_SIS32, &ipr_chip_cfg[0] },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] },
+       { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, IPR_USE_MSI, IPR_SIS64, &ipr_chip_cfg[2] },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, IPR_USE_MSI, IPR_SIS64, &ipr_chip_cfg[2] }
 };
 
 static int ipr_max_bus_speeds [] = {
@@ -156,12 +200,13 @@ module_param_named(fastfail, ipr_fastfail, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(fastfail, "Reduce timeouts and retries");
 module_param_named(transop_timeout, ipr_transop_timeout, int, 0);
 MODULE_PARM_DESC(transop_timeout, "Time in seconds to wait for adapter to come operational (default: 300)");
-module_param_named(enable_cache, ipr_enable_cache, int, 0);
-MODULE_PARM_DESC(enable_cache, "Enable adapter's non-volatile write cache (default: 1)");
 module_param_named(debug, ipr_debug, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)");
 module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0);
 MODULE_PARM_DESC(dual_ioa_raid, "Enable dual adapter RAID support. Set to 1 to enable. (default: 1)");
+module_param_named(max_devs, ipr_max_devs, int, 0);
+MODULE_PARM_DESC(max_devs, "Specify the maximum number of physical devices. "
+                "[Default=" __stringify(IPR_DEFAULT_SIS64_DEVS) "]");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(IPR_DRIVER_VERSION);
 
@@ -180,6 +225,20 @@ struct ipr_error_table_t ipr_error_table[] = {
        "FFFE: Soft device bus error recovered by the IOA"},
        {0x01088100, 0, IPR_DEFAULT_LOG_LEVEL,
        "4101: Soft device bus fabric error"},
+       {0x01100100, 0, IPR_DEFAULT_LOG_LEVEL,
+       "FFFC: Logical block guard error recovered by the device"},
+       {0x01100300, 0, IPR_DEFAULT_LOG_LEVEL,
+       "FFFC: Logical block reference tag error recovered by the device"},
+       {0x01108300, 0, IPR_DEFAULT_LOG_LEVEL,
+       "4171: Recovered scatter list tag / sequence number error"},
+       {0x01109000, 0, IPR_DEFAULT_LOG_LEVEL,
+       "FF3D: Recovered logical block CRC error on IOA to Host transfer"},
+       {0x01109200, 0, IPR_DEFAULT_LOG_LEVEL,
+       "4171: Recovered logical block sequence number error on IOA to Host transfer"},
+       {0x0110A000, 0, IPR_DEFAULT_LOG_LEVEL,
+       "FFFD: Recovered logical block reference tag error detected by the IOA"},
+       {0x0110A100, 0, IPR_DEFAULT_LOG_LEVEL,
+       "FFFD: Logical block guard error recovered by the IOA"},
        {0x01170600, 0, IPR_DEFAULT_LOG_LEVEL,
        "FFF9: Device sector reassign successful"},
        {0x01170900, 0, IPR_DEFAULT_LOG_LEVEL,
@@ -236,12 +295,28 @@ struct ipr_error_table_t ipr_error_table[] = {
        "3120: SCSI bus is not operational"},
        {0x04088100, 0, IPR_DEFAULT_LOG_LEVEL,
        "4100: Hard device bus fabric error"},
+       {0x04100100, 0, IPR_DEFAULT_LOG_LEVEL,
+       "310C: Logical block guard error detected by the device"},
+       {0x04100300, 0, IPR_DEFAULT_LOG_LEVEL,
+       "310C: Logical block reference tag error detected by the device"},
+       {0x04108300, 1, IPR_DEFAULT_LOG_LEVEL,
+       "4170: Scatter list tag / sequence number error"},
+       {0x04109000, 1, IPR_DEFAULT_LOG_LEVEL,
+       "8150: Logical block CRC error on IOA to Host transfer"},
+       {0x04109200, 1, IPR_DEFAULT_LOG_LEVEL,
+       "4170: Logical block sequence number error on IOA to Host transfer"},
+       {0x0410A000, 0, IPR_DEFAULT_LOG_LEVEL,
+       "310D: Logical block reference tag error detected by the IOA"},
+       {0x0410A100, 0, IPR_DEFAULT_LOG_LEVEL,
+       "310D: Logical block guard error detected by the IOA"},
        {0x04118000, 0, IPR_DEFAULT_LOG_LEVEL,
        "9000: IOA reserved area data check"},
        {0x04118100, 0, IPR_DEFAULT_LOG_LEVEL,
        "9001: IOA reserved area invalid data pattern"},
        {0x04118200, 0, IPR_DEFAULT_LOG_LEVEL,
        "9002: IOA reserved area LRC error"},
+       {0x04118300, 1, IPR_DEFAULT_LOG_LEVEL,
+       "Hardware Error, IOA metadata access error"},
        {0x04320000, 0, IPR_DEFAULT_LOG_LEVEL,
        "102E: Out of alternate sectors for disk storage"},
        {0x04330000, 1, IPR_DEFAULT_LOG_LEVEL,
@@ -306,6 +381,8 @@ struct ipr_error_table_t ipr_error_table[] = {
        "Illegal request, commands not allowed to this device"},
        {0x05258100, 0, 0,
        "Illegal request, command not allowed to a secondary adapter"},
+       {0x05258200, 0, 0,
+       "Illegal request, command not allowed to a non-optimized resource"},
        {0x05260000, 0, 0,
        "Illegal request, invalid field in parameter list"},
        {0x05260100, 0, 0,
@@ -468,7 +545,10 @@ static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd,
        trace_entry->time = jiffies;
        trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0];
        trace_entry->type = type;
-       trace_entry->ata_op_code = ipr_cmd->ioarcb.add_data.u.regs.command;
+       if (ipr_cmd->ioa_cfg->sis64)
+               trace_entry->ata_op_code = ipr_cmd->i.ata_ioadl.regs.command;
+       else
+               trace_entry->ata_op_code = ipr_cmd->ioarcb.u.add_data.u.regs.command;
        trace_entry->cmd_index = ipr_cmd->cmd_index & 0xff;
        trace_entry->res_handle = ipr_cmd->ioarcb.res_handle;
        trace_entry->u.add_data = add_data;
@@ -488,16 +568,23 @@ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd)
 {
        struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
        struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
-       dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr);
+       dma_addr_t dma_addr = ipr_cmd->dma_addr;
 
        memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt));
-       ioarcb->write_data_transfer_length = 0;
+       ioarcb->data_transfer_length = 0;
        ioarcb->read_data_transfer_length = 0;
-       ioarcb->write_ioadl_len = 0;
+       ioarcb->ioadl_len = 0;
        ioarcb->read_ioadl_len = 0;
-       ioarcb->write_ioadl_addr =
-               cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl));
-       ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+
+       if (ipr_cmd->ioa_cfg->sis64)
+               ioarcb->u.sis64_addr_data.data_ioadl_addr =
+                       cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64));
+       else {
+               ioarcb->write_ioadl_addr =
+                       cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl));
+               ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+       }
+
        ioasa->ioasc = 0;
        ioasa->residual_data_len = 0;
        ioasa->u.gata.status = 0;
@@ -562,10 +649,15 @@ static void ipr_mask_and_clear_interrupts(struct ipr_ioa_cfg *ioa_cfg,
        ioa_cfg->allow_interrupts = 0;
 
        /* Set interrupt mask to stop all new interrupts */
-       writel(~0, ioa_cfg->regs.set_interrupt_mask_reg);
+       if (ioa_cfg->sis64)
+               writeq(~0, ioa_cfg->regs.set_interrupt_mask_reg);
+       else
+               writel(~0, ioa_cfg->regs.set_interrupt_mask_reg);
 
        /* Clear any pending interrupts */
-       writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg);
+       if (ioa_cfg->sis64)
+               writel(~0, ioa_cfg->regs.clr_interrupt_reg);
+       writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg32);
        int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
 }
 
@@ -692,6 +784,35 @@ static void ipr_fail_all_ops(struct ipr_ioa_cfg *ioa_cfg)
        LEAVE;
 }
 
+/**
+ * ipr_send_command -  Send driver initiated requests.
+ * @ipr_cmd:           ipr command struct
+ *
+ * This function sends a command to the adapter using the correct write call.
+ * In the case of sis64, calculate the ioarcb size required. Then or in the
+ * appropriate bits.
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_send_command(struct ipr_cmnd *ipr_cmd)
+{
+       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+       dma_addr_t send_dma_addr = ipr_cmd->dma_addr;
+
+       if (ioa_cfg->sis64) {
+               /* The default size is 256 bytes */
+               send_dma_addr |= 0x1;
+
+               /* If the number of ioadls * size of ioadl > 128 bytes,
+                  then use a 512 byte ioarcb */
+               if (ipr_cmd->dma_use_sg * sizeof(struct ipr_ioadl64_desc) > 128 )
+                       send_dma_addr |= 0x4;
+               writeq(send_dma_addr, ioa_cfg->regs.ioarrin_reg);
+       } else
+               writel(send_dma_addr, ioa_cfg->regs.ioarrin_reg);
+}
+
 /**
  * ipr_do_req -  Send driver initiated requests.
  * @ipr_cmd:           ipr command struct
@@ -724,8 +845,8 @@ static void ipr_do_req(struct ipr_cmnd *ipr_cmd,
        ipr_trc_hook(ipr_cmd, IPR_TRACE_START, 0);
 
        mb();
-       writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr),
-              ioa_cfg->regs.ioarrin_reg);
+
+       ipr_send_command(ipr_cmd);
 }
 
 /**
@@ -746,6 +867,51 @@ static void ipr_internal_cmd_done(struct ipr_cmnd *ipr_cmd)
                complete(&ipr_cmd->completion);
 }
 
+/**
+ * ipr_init_ioadl - initialize the ioadl for the correct SIS type
+ * @ipr_cmd:   ipr command struct
+ * @dma_addr:  dma address
+ * @len:       transfer length
+ * @flags:     ioadl flag value
+ *
+ * This function initializes an ioadl in the case where there is only a single
+ * descriptor.
+ *
+ * Return value:
+ *     nothing
+ **/
+static void ipr_init_ioadl(struct ipr_cmnd *ipr_cmd, dma_addr_t dma_addr,
+                          u32 len, int flags)
+{
+       struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl;
+       struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64;
+
+       ipr_cmd->dma_use_sg = 1;
+
+       if (ipr_cmd->ioa_cfg->sis64) {
+               ioadl64->flags = cpu_to_be32(flags);
+               ioadl64->data_len = cpu_to_be32(len);
+               ioadl64->address = cpu_to_be64(dma_addr);
+
+               ipr_cmd->ioarcb.ioadl_len =
+                       cpu_to_be32(sizeof(struct ipr_ioadl64_desc));
+               ipr_cmd->ioarcb.data_transfer_length = cpu_to_be32(len);
+       } else {
+               ioadl->flags_and_data_len = cpu_to_be32(flags | len);
+               ioadl->address = cpu_to_be32(dma_addr);
+
+               if (flags == IPR_IOADL_FLAGS_READ_LAST) {
+                       ipr_cmd->ioarcb.read_ioadl_len =
+                               cpu_to_be32(sizeof(struct ipr_ioadl_desc));
+                       ipr_cmd->ioarcb.read_data_transfer_length = cpu_to_be32(len);
+               } else {
+                       ipr_cmd->ioarcb.ioadl_len =
+                               cpu_to_be32(sizeof(struct ipr_ioadl_desc));
+                       ipr_cmd->ioarcb.data_transfer_length = cpu_to_be32(len);
+               }
+       }
+}
+
 /**
  * ipr_send_blocking_cmd - Send command and sleep on its completion.
  * @ipr_cmd:   ipr command struct
@@ -803,11 +969,8 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type,
                ioarcb->cmd_pkt.cdb[7] = (sizeof(hostrcb->hcam) >> 8) & 0xff;
                ioarcb->cmd_pkt.cdb[8] = sizeof(hostrcb->hcam) & 0xff;
 
-               ioarcb->read_data_transfer_length = cpu_to_be32(sizeof(hostrcb->hcam));
-               ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
-               ipr_cmd->ioadl[0].flags_and_data_len =
-                       cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | sizeof(hostrcb->hcam));
-               ipr_cmd->ioadl[0].address = cpu_to_be32(hostrcb->hostrcb_dma);
+               ipr_init_ioadl(ipr_cmd, hostrcb->hostrcb_dma,
+                              sizeof(hostrcb->hcam), IPR_IOADL_FLAGS_READ_LAST);
 
                if (type == IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE)
                        ipr_cmd->done = ipr_process_ccn;
@@ -817,22 +980,54 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type,
                ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_IOA_RES_ADDR);
 
                mb();
-               writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr),
-                      ioa_cfg->regs.ioarrin_reg);
+
+               ipr_send_command(ipr_cmd);
        } else {
                list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q);
        }
 }
 
+/**
+ * ipr_update_ata_class - Update the ata class in the resource entry
+ * @res:       resource entry struct
+ * @proto:     cfgte device bus protocol value
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_update_ata_class(struct ipr_resource_entry *res, unsigned int proto)
+{
+       switch(proto) {
+       case IPR_PROTO_SATA:
+       case IPR_PROTO_SAS_STP:
+               res->ata_class = ATA_DEV_ATA;
+               break;
+       case IPR_PROTO_SATA_ATAPI:
+       case IPR_PROTO_SAS_STP_ATAPI:
+               res->ata_class = ATA_DEV_ATAPI;
+               break;
+       default:
+               res->ata_class = ATA_DEV_UNKNOWN;
+               break;
+       };
+}
+
 /**
  * ipr_init_res_entry - Initialize a resource entry struct.
  * @res:       resource entry struct
+ * @cfgtew:    config table entry wrapper struct
  *
  * Return value:
  *     none
  **/
-static void ipr_init_res_entry(struct ipr_resource_entry *res)
+static void ipr_init_res_entry(struct ipr_resource_entry *res,
+                              struct ipr_config_table_entry_wrapper *cfgtew)
 {
+       int found = 0;
+       unsigned int proto;
+       struct ipr_ioa_cfg *ioa_cfg = res->ioa_cfg;
+       struct ipr_resource_entry *gscsi_res = NULL;
+
        res->needs_sync_complete = 0;
        res->in_erp = 0;
        res->add_to_ml = 0;
@@ -840,6 +1035,205 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res)
        res->resetting_device = 0;
        res->sdev = NULL;
        res->sata_port = NULL;
+
+       if (ioa_cfg->sis64) {
+               proto = cfgtew->u.cfgte64->proto;
+               res->res_flags = cfgtew->u.cfgte64->res_flags;
+               res->qmodel = IPR_QUEUEING_MODEL64(res);
+               res->type = cfgtew->u.cfgte64->res_type & 0x0f;
+
+               memcpy(res->res_path, &cfgtew->u.cfgte64->res_path,
+                       sizeof(res->res_path));
+
+               res->bus = 0;
+               res->lun = scsilun_to_int(&res->dev_lun);
+
+               if (res->type == IPR_RES_TYPE_GENERIC_SCSI) {
+                       list_for_each_entry(gscsi_res, &ioa_cfg->used_res_q, queue) {
+                               if (gscsi_res->dev_id == cfgtew->u.cfgte64->dev_id) {
+                                       found = 1;
+                                       res->target = gscsi_res->target;
+                                       break;
+                               }
+                       }
+                       if (!found) {
+                               res->target = find_first_zero_bit(ioa_cfg->target_ids,
+                                                                 ioa_cfg->max_devs_supported);
+                               set_bit(res->target, ioa_cfg->target_ids);
+                       }
+
+                       memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun,
+                               sizeof(res->dev_lun.scsi_lun));
+               } else if (res->type == IPR_RES_TYPE_IOAFP) {
+                       res->bus = IPR_IOAFP_VIRTUAL_BUS;
+                       res->target = 0;
+               } else if (res->type == IPR_RES_TYPE_ARRAY) {
+                       res->bus = IPR_ARRAY_VIRTUAL_BUS;
+                       res->target = find_first_zero_bit(ioa_cfg->array_ids,
+                                                         ioa_cfg->max_devs_supported);
+                       set_bit(res->target, ioa_cfg->array_ids);
+               } else if (res->type == IPR_RES_TYPE_VOLUME_SET) {
+                       res->bus = IPR_VSET_VIRTUAL_BUS;
+                       res->target = find_first_zero_bit(ioa_cfg->vset_ids,
+                                                         ioa_cfg->max_devs_supported);
+                       set_bit(res->target, ioa_cfg->vset_ids);
+               } else {
+                       res->target = find_first_zero_bit(ioa_cfg->target_ids,
+                                                         ioa_cfg->max_devs_supported);
+                       set_bit(res->target, ioa_cfg->target_ids);
+               }
+       } else {
+               proto = cfgtew->u.cfgte->proto;
+               res->qmodel = IPR_QUEUEING_MODEL(res);
+               res->flags = cfgtew->u.cfgte->flags;
+               if (res->flags & IPR_IS_IOA_RESOURCE)
+                       res->type = IPR_RES_TYPE_IOAFP;
+               else
+                       res->type = cfgtew->u.cfgte->rsvd_subtype & 0x0f;
+
+               res->bus = cfgtew->u.cfgte->res_addr.bus;
+               res->target = cfgtew->u.cfgte->res_addr.target;
+               res->lun = cfgtew->u.cfgte->res_addr.lun;
+       }
+
+       ipr_update_ata_class(res, proto);
+}
+
+/**
+ * ipr_is_same_device - Determine if two devices are the same.
+ * @res:       resource entry struct
+ * @cfgtew:    config table entry wrapper struct
+ *
+ * Return value:
+ *     1 if the devices are the same / 0 otherwise
+ **/
+static int ipr_is_same_device(struct ipr_resource_entry *res,
+                             struct ipr_config_table_entry_wrapper *cfgtew)
+{
+       if (res->ioa_cfg->sis64) {
+               if (!memcmp(&res->dev_id, &cfgtew->u.cfgte64->dev_id,
+                                       sizeof(cfgtew->u.cfgte64->dev_id)) &&
+                       !memcmp(&res->lun, &cfgtew->u.cfgte64->lun,
+                                       sizeof(cfgtew->u.cfgte64->lun))) {
+                       return 1;
+               }
+       } else {
+               if (res->bus == cfgtew->u.cfgte->res_addr.bus &&
+                   res->target == cfgtew->u.cfgte->res_addr.target &&
+                   res->lun == cfgtew->u.cfgte->res_addr.lun)
+                       return 1;
+       }
+
+       return 0;
+}
+
+/**
+ * ipr_format_resource_path - Format the resource path for printing.
+ * @res_path:  resource path
+ * @buf:       buffer
+ *
+ * Return value:
+ *     pointer to buffer
+ **/
+static char *ipr_format_resource_path(u8 *res_path, char *buffer)
+{
+       int i;
+
+       sprintf(buffer, "%02X", res_path[0]);
+       for (i=1; res_path[i] != 0xff; i++)
+               sprintf(buffer, "%s-%02X", buffer, res_path[i]);
+
+       return buffer;
+}
+
+/**
+ * ipr_update_res_entry - Update the resource entry.
+ * @res:       resource entry struct
+ * @cfgtew:    config table entry wrapper struct
+ *
+ * Return value:
+ *      none
+ **/
+static void ipr_update_res_entry(struct ipr_resource_entry *res,
+                                struct ipr_config_table_entry_wrapper *cfgtew)
+{
+       char buffer[IPR_MAX_RES_PATH_LENGTH];
+       unsigned int proto;
+       int new_path = 0;
+
+       if (res->ioa_cfg->sis64) {
+               res->flags = cfgtew->u.cfgte64->flags;
+               res->res_flags = cfgtew->u.cfgte64->res_flags;
+               res->type = cfgtew->u.cfgte64->res_type & 0x0f;
+
+               memcpy(&res->std_inq_data, &cfgtew->u.cfgte64->std_inq_data,
+                       sizeof(struct ipr_std_inq_data));
+
+               res->qmodel = IPR_QUEUEING_MODEL64(res);
+               proto = cfgtew->u.cfgte64->proto;
+               res->res_handle = cfgtew->u.cfgte64->res_handle;
+               res->dev_id = cfgtew->u.cfgte64->dev_id;
+
+               memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun,
+                       sizeof(res->dev_lun.scsi_lun));
+
+               if (memcmp(res->res_path, &cfgtew->u.cfgte64->res_path,
+                                       sizeof(res->res_path))) {
+                       memcpy(res->res_path, &cfgtew->u.cfgte64->res_path,
+                               sizeof(res->res_path));
+                       new_path = 1;
+               }
+
+               if (res->sdev && new_path)
+                       sdev_printk(KERN_INFO, res->sdev, "Resource path: %s\n",
+                                   ipr_format_resource_path(&res->res_path[0], &buffer[0]));
+       } else {
+               res->flags = cfgtew->u.cfgte->flags;
+               if (res->flags & IPR_IS_IOA_RESOURCE)
+                       res->type = IPR_RES_TYPE_IOAFP;
+               else
+                       res->type = cfgtew->u.cfgte->rsvd_subtype & 0x0f;
+
+               memcpy(&res->std_inq_data, &cfgtew->u.cfgte->std_inq_data,
+                       sizeof(struct ipr_std_inq_data));
+
+               res->qmodel = IPR_QUEUEING_MODEL(res);
+               proto = cfgtew->u.cfgte->proto;
+               res->res_handle = cfgtew->u.cfgte->res_handle;
+       }
+
+       ipr_update_ata_class(res, proto);
+}
+
+/**
+ * ipr_clear_res_target - Clear the bit in the bit map representing the target
+ *                       for the resource.
+ * @res:       resource entry struct
+ * @cfgtew:    config table entry wrapper struct
+ *
+ * Return value:
+ *      none
+ **/
+static void ipr_clear_res_target(struct ipr_resource_entry *res)
+{
+       struct ipr_resource_entry *gscsi_res = NULL;
+       struct ipr_ioa_cfg *ioa_cfg = res->ioa_cfg;
+
+       if (!ioa_cfg->sis64)
+               return;
+
+       if (res->bus == IPR_ARRAY_VIRTUAL_BUS)
+               clear_bit(res->target, ioa_cfg->array_ids);
+       else if (res->bus == IPR_VSET_VIRTUAL_BUS)
+               clear_bit(res->target, ioa_cfg->vset_ids);
+       else if (res->bus == 0 && res->type == IPR_RES_TYPE_GENERIC_SCSI) {
+               list_for_each_entry(gscsi_res, &ioa_cfg->used_res_q, queue)
+                       if (gscsi_res->dev_id == res->dev_id && gscsi_res != res)
+                               return;
+               clear_bit(res->target, ioa_cfg->target_ids);
+
+       } else if (res->bus == 0)
+               clear_bit(res->target, ioa_cfg->target_ids);
 }
 
 /**
@@ -851,17 +1245,24 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res)
  *     none
  **/
 static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg,
-                             struct ipr_hostrcb *hostrcb)
+                                    struct ipr_hostrcb *hostrcb)
 {
        struct ipr_resource_entry *res = NULL;
-       struct ipr_config_table_entry *cfgte;
+       struct ipr_config_table_entry_wrapper cfgtew;
+       __be32 cc_res_handle;
+
        u32 is_ndn = 1;
 
-       cfgte = &hostrcb->hcam.u.ccn.cfgte;
+       if (ioa_cfg->sis64) {
+               cfgtew.u.cfgte64 = &hostrcb->hcam.u.ccn.u.cfgte64;
+               cc_res_handle = cfgtew.u.cfgte64->res_handle;
+       } else {
+               cfgtew.u.cfgte = &hostrcb->hcam.u.ccn.u.cfgte;
+               cc_res_handle = cfgtew.u.cfgte->res_handle;
+       }
 
        list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
-               if (!memcmp(&res->cfgte.res_addr, &cfgte->res_addr,
-                           sizeof(cfgte->res_addr))) {
+               if (res->res_handle == cc_res_handle) {
                        is_ndn = 0;
                        break;
                }
@@ -879,20 +1280,22 @@ static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg,
                                 struct ipr_resource_entry, queue);
 
                list_del(&res->queue);
-               ipr_init_res_entry(res);
+               ipr_init_res_entry(res, &cfgtew);
                list_add_tail(&res->queue, &ioa_cfg->used_res_q);
        }
 
-       memcpy(&res->cfgte, cfgte, sizeof(struct ipr_config_table_entry));
+       ipr_update_res_entry(res, &cfgtew);
 
        if (hostrcb->hcam.notify_type == IPR_HOST_RCB_NOTIF_TYPE_REM_ENTRY) {
                if (res->sdev) {
                        res->del_from_ml = 1;
-                       res->cfgte.res_handle = IPR_INVALID_RES_HANDLE;
+                       res->res_handle = IPR_INVALID_RES_HANDLE;
                        if (ioa_cfg->allow_ml_add_del)
                                schedule_work(&ioa_cfg->work_q);
-               } else
+               } else {
+                       ipr_clear_res_target(res);
                        list_move_tail(&res->queue, &ioa_cfg->free_res_q);
+               }
        } else if (!res->sdev) {
                res->add_to_ml = 1;
                if (ioa_cfg->allow_ml_add_del)
@@ -1044,8 +1447,12 @@ static void ipr_log_ext_vpd(struct ipr_ext_vpd *vpd)
 static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg,
                                         struct ipr_hostrcb *hostrcb)
 {
-       struct ipr_hostrcb_type_12_error *error =
-               &hostrcb->hcam.u.error.u.type_12_error;
+       struct ipr_hostrcb_type_12_error *error;
+
+       if (ioa_cfg->sis64)
+               error = &hostrcb->hcam.u.error64.u.type_12_error;
+       else
+               error = &hostrcb->hcam.u.error.u.type_12_error;
 
        ipr_err("-----Current Configuration-----\n");
        ipr_err("Cache Directory Card Information:\n");
@@ -1137,6 +1544,48 @@ static void ipr_log_enhanced_config_error(struct ipr_ioa_cfg *ioa_cfg,
        }
 }
 
+/**
+ * ipr_log_sis64_config_error - Log a device error.
+ * @ioa_cfg:   ioa config struct
+ * @hostrcb:   hostrcb struct
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_log_sis64_config_error(struct ipr_ioa_cfg *ioa_cfg,
+                                      struct ipr_hostrcb *hostrcb)
+{
+       int errors_logged, i;
+       struct ipr_hostrcb64_device_data_entry_enhanced *dev_entry;
+       struct ipr_hostrcb_type_23_error *error;
+       char buffer[IPR_MAX_RES_PATH_LENGTH];
+
+       error = &hostrcb->hcam.u.error64.u.type_23_error;
+       errors_logged = be32_to_cpu(error->errors_logged);
+
+       ipr_err("Device Errors Detected/Logged: %d/%d\n",
+               be32_to_cpu(error->errors_detected), errors_logged);
+
+       dev_entry = error->dev;
+
+       for (i = 0; i < errors_logged; i++, dev_entry++) {
+               ipr_err_separator;
+
+               ipr_err("Device %d : %s", i + 1,
+                        ipr_format_resource_path(&dev_entry->res_path[0], &buffer[0]));
+               ipr_log_ext_vpd(&dev_entry->vpd);
+
+               ipr_err("-----New Device Information-----\n");
+               ipr_log_ext_vpd(&dev_entry->new_vpd);
+
+               ipr_err("Cache Directory Card Information:\n");
+               ipr_log_ext_vpd(&dev_entry->ioa_last_with_dev_vpd);
+
+               ipr_err("Adapter Card Information:\n");
+               ipr_log_ext_vpd(&dev_entry->cfc_last_with_dev_vpd);
+       }
+}
+
 /**
  * ipr_log_config_error - Log a configuration error.
  * @ioa_cfg:   ioa config struct
@@ -1331,7 +1780,11 @@ static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg,
 {
        struct ipr_hostrcb_type_17_error *error;
 
-       error = &hostrcb->hcam.u.error.u.type_17_error;
+       if (ioa_cfg->sis64)
+               error = &hostrcb->hcam.u.error64.u.type_17_error;
+       else
+               error = &hostrcb->hcam.u.error.u.type_17_error;
+
        error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
        strim(error->failure_reason);
 
@@ -1438,6 +1891,42 @@ static void ipr_log_fabric_path(struct ipr_hostrcb *hostrcb,
                fabric->ioa_port, fabric->cascaded_expander, fabric->phy);
 }
 
+/**
+ * ipr_log64_fabric_path - Log a fabric path error
+ * @hostrcb:   hostrcb struct
+ * @fabric:            fabric descriptor
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_log64_fabric_path(struct ipr_hostrcb *hostrcb,
+                                 struct ipr_hostrcb64_fabric_desc *fabric)
+{
+       int i, j;
+       u8 path_state = fabric->path_state;
+       u8 active = path_state & IPR_PATH_ACTIVE_MASK;
+       u8 state = path_state & IPR_PATH_STATE_MASK;
+       char buffer[IPR_MAX_RES_PATH_LENGTH];
+
+       for (i = 0; i < ARRAY_SIZE(path_active_desc); i++) {
+               if (path_active_desc[i].active != active)
+                       continue;
+
+               for (j = 0; j < ARRAY_SIZE(path_state_desc); j++) {
+                       if (path_state_desc[j].state != state)
+                               continue;
+
+                       ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s\n",
+                                    path_active_desc[i].desc, path_state_desc[j].desc,
+                                    ipr_format_resource_path(&fabric->res_path[0], &buffer[0]));
+                       return;
+               }
+       }
+
+       ipr_err("Path state=%02X Resource Path=%s\n", path_state,
+               ipr_format_resource_path(&fabric->res_path[0], &buffer[0]));
+}
+
 static const struct {
        u8 type;
        char *desc;
@@ -1546,6 +2035,49 @@ static void ipr_log_path_elem(struct ipr_hostrcb *hostrcb,
                     be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
 }
 
+/**
+ * ipr_log64_path_elem - Log a fabric path element.
+ * @hostrcb:   hostrcb struct
+ * @cfg:               fabric path element struct
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_log64_path_elem(struct ipr_hostrcb *hostrcb,
+                               struct ipr_hostrcb64_config_element *cfg)
+{
+       int i, j;
+       u8 desc_id = cfg->descriptor_id & IPR_DESCRIPTOR_MASK;
+       u8 type = cfg->type_status & IPR_PATH_CFG_TYPE_MASK;
+       u8 status = cfg->type_status & IPR_PATH_CFG_STATUS_MASK;
+       char buffer[IPR_MAX_RES_PATH_LENGTH];
+
+       if (type == IPR_PATH_CFG_NOT_EXIST || desc_id != IPR_DESCRIPTOR_SIS64)
+               return;
+
+       for (i = 0; i < ARRAY_SIZE(path_type_desc); i++) {
+               if (path_type_desc[i].type != type)
+                       continue;
+
+               for (j = 0; j < ARRAY_SIZE(path_status_desc); j++) {
+                       if (path_status_desc[j].status != status)
+                               continue;
+
+                       ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s, Link rate=%s, WWN=%08X%08X\n",
+                                    path_status_desc[j].desc, path_type_desc[i].desc,
+                                    ipr_format_resource_path(&cfg->res_path[0], &buffer[0]),
+                                    link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
+                                    be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
+                       return;
+               }
+       }
+       ipr_hcam_err(hostrcb, "Path element=%02X: Resource Path=%s, Link rate=%s "
+                    "WWN=%08X%08X\n", cfg->type_status,
+                    ipr_format_resource_path(&cfg->res_path[0], &buffer[0]),
+                    link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
+                    be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
+}
+
 /**
  * ipr_log_fabric_error - Log a fabric error.
  * @ioa_cfg:   ioa config struct
@@ -1583,6 +2115,96 @@ static void ipr_log_fabric_error(struct ipr_ioa_cfg *ioa_cfg,
        ipr_log_hex_data(ioa_cfg, (u32 *)fabric, add_len);
 }
 
+/**
+ * ipr_log_sis64_array_error - Log a sis64 array error.
+ * @ioa_cfg:   ioa config struct
+ * @hostrcb:   hostrcb struct
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_log_sis64_array_error(struct ipr_ioa_cfg *ioa_cfg,
+                                     struct ipr_hostrcb *hostrcb)
+{
+       int i, num_entries;
+       struct ipr_hostrcb_type_24_error *error;
+       struct ipr_hostrcb64_array_data_entry *array_entry;
+       char buffer[IPR_MAX_RES_PATH_LENGTH];
+       const u8 zero_sn[IPR_SERIAL_NUM_LEN] = { [0 ... IPR_SERIAL_NUM_LEN-1] = '0' };
+
+       error = &hostrcb->hcam.u.error64.u.type_24_error;
+
+       ipr_err_separator;
+
+       ipr_err("RAID %s Array Configuration: %s\n",
+               error->protection_level,
+               ipr_format_resource_path(&error->last_res_path[0], &buffer[0]));
+
+       ipr_err_separator;
+
+       array_entry = error->array_member;
+       num_entries = min_t(u32, be32_to_cpu(error->num_entries),
+                           sizeof(error->array_member));
+
+       for (i = 0; i < num_entries; i++, array_entry++) {
+
+               if (!memcmp(array_entry->vpd.vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN))
+                       continue;
+
+               if (error->exposed_mode_adn == i)
+                       ipr_err("Exposed Array Member %d:\n", i);
+               else
+                       ipr_err("Array Member %d:\n", i);
+
+               ipr_err("Array Member %d:\n", i);
+               ipr_log_ext_vpd(&array_entry->vpd);
+               ipr_err("Current Location: %s",
+                        ipr_format_resource_path(&array_entry->res_path[0], &buffer[0]));
+               ipr_err("Expected Location: %s",
+                        ipr_format_resource_path(&array_entry->expected_res_path[0], &buffer[0]));
+
+               ipr_err_separator;
+       }
+}
+
+/**
+ * ipr_log_sis64_fabric_error - Log a sis64 fabric error.
+ * @ioa_cfg:   ioa config struct
+ * @hostrcb:   hostrcb struct
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_log_sis64_fabric_error(struct ipr_ioa_cfg *ioa_cfg,
+                                      struct ipr_hostrcb *hostrcb)
+{
+       struct ipr_hostrcb_type_30_error *error;
+       struct ipr_hostrcb64_fabric_desc *fabric;
+       struct ipr_hostrcb64_config_element *cfg;
+       int i, add_len;
+
+       error = &hostrcb->hcam.u.error64.u.type_30_error;
+
+       error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
+       ipr_hcam_err(hostrcb, "%s\n", error->failure_reason);
+
+       add_len = be32_to_cpu(hostrcb->hcam.length) -
+               (offsetof(struct ipr_hostrcb64_error, u) +
+                offsetof(struct ipr_hostrcb_type_30_error, desc));
+
+       for (i = 0, fabric = error->desc; i < error->num_entries; i++) {
+               ipr_log64_fabric_path(hostrcb, fabric);
+               for_each_fabric_cfg(fabric, cfg)
+                       ipr_log64_path_elem(hostrcb, cfg);
+
+               add_len -= be16_to_cpu(fabric->length);
+               fabric = (struct ipr_hostrcb64_fabric_desc *)
+                       ((unsigned long)fabric + be16_to_cpu(fabric->length));
+       }
+
+       ipr_log_hex_data(ioa_cfg, (u32 *)fabric, add_len);
+}
+
 /**
  * ipr_log_generic_error - Log an adapter error.
  * @ioa_cfg:   ioa config struct
@@ -1642,13 +2264,16 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg,
        if (hostrcb->hcam.notifications_lost == IPR_HOST_RCB_NOTIFICATIONS_LOST)
                dev_err(&ioa_cfg->pdev->dev, "Error notifications lost\n");
 
-       ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc);
+       if (ioa_cfg->sis64)
+               ioasc = be32_to_cpu(hostrcb->hcam.u.error64.fd_ioasc);
+       else
+               ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc);
 
-       if (ioasc == IPR_IOASC_BUS_WAS_RESET ||
-           ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER) {
+       if (!ioa_cfg->sis64 && (ioasc == IPR_IOASC_BUS_WAS_RESET ||
+           ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER)) {
                /* Tell the midlayer we had a bus reset so it will handle the UA properly */
                scsi_report_bus_reset(ioa_cfg->host,
-                                     hostrcb->hcam.u.error.failing_dev_res_addr.bus);
+                                     hostrcb->hcam.u.error.fd_res_addr.bus);
        }
 
        error_index = ipr_get_error(ioasc);
@@ -1696,6 +2321,16 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg,
        case IPR_HOST_RCB_OVERLAY_ID_20:
                ipr_log_fabric_error(ioa_cfg, hostrcb);
                break;
+       case IPR_HOST_RCB_OVERLAY_ID_23:
+               ipr_log_sis64_config_error(ioa_cfg, hostrcb);
+               break;
+       case IPR_HOST_RCB_OVERLAY_ID_24:
+       case IPR_HOST_RCB_OVERLAY_ID_26:
+               ipr_log_sis64_array_error(ioa_cfg, hostrcb);
+               break;
+       case IPR_HOST_RCB_OVERLAY_ID_30:
+               ipr_log_sis64_fabric_error(ioa_cfg, hostrcb);
+               break;
        case IPR_HOST_RCB_OVERLAY_ID_1:
        case IPR_HOST_RCB_OVERLAY_ID_DEFAULT:
        default:
@@ -1720,7 +2355,12 @@ static void ipr_process_error(struct ipr_cmnd *ipr_cmd)
        struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
        struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb;
        u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
-       u32 fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc);
+       u32 fd_ioasc;
+
+       if (ioa_cfg->sis64)
+               fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error64.fd_ioasc);
+       else
+               fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc);
 
        list_del(&hostrcb->queue);
        list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
@@ -1845,12 +2485,14 @@ static const struct ipr_ses_table_entry *
 ipr_find_ses_entry(struct ipr_resource_entry *res)
 {
        int i, j, matches;
+       struct ipr_std_inq_vpids *vpids;
        const struct ipr_ses_table_entry *ste = ipr_ses_table;
 
        for (i = 0; i < ARRAY_SIZE(ipr_ses_table); i++, ste++) {
                for (j = 0, matches = 0; j < IPR_PROD_ID_LEN; j++) {
                        if (ste->compare_product_id_byte[j] == 'X') {
-                               if (res->cfgte.std_inq_data.vpids.product_id[j] == ste->product_id[j])
+                               vpids = &res->std_inq_data.vpids;
+                               if (vpids->product_id[j] == ste->product_id[j])
                                        matches++;
                                else
                                        break;
@@ -1885,10 +2527,10 @@ static u32 ipr_get_max_scsi_speed(struct ipr_ioa_cfg *ioa_cfg, u8 bus, u8 bus_wi
 
        /* Loop through each config table entry in the config table buffer */
        list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
-               if (!(IPR_IS_SES_DEVICE(res->cfgte.std_inq_data)))
+               if (!(IPR_IS_SES_DEVICE(res->std_inq_data)))
                        continue;
 
-               if (bus != res->cfgte.res_addr.bus)
+               if (bus != res->bus)
                        continue;
 
                if (!(ste = ipr_find_ses_entry(res)))
@@ -1933,6 +2575,31 @@ static int ipr_wait_iodbg_ack(struct ipr_ioa_cfg *ioa_cfg, int max_delay)
        return -EIO;
 }
 
+/**
+ * ipr_get_sis64_dump_data_section - Dump IOA memory
+ * @ioa_cfg:                   ioa config struct
+ * @start_addr:                        adapter address to dump
+ * @dest:                      destination kernel buffer
+ * @length_in_words:           length to dump in 4 byte words
+ *
+ * Return value:
+ *     0 on success
+ **/
+static int ipr_get_sis64_dump_data_section(struct ipr_ioa_cfg *ioa_cfg,
+                                          u32 start_addr,
+                                          __be32 *dest, u32 length_in_words)
+{
+       int i;
+
+       for (i = 0; i < length_in_words; i++) {
+               writel(start_addr+(i*4), ioa_cfg->regs.dump_addr_reg);
+               *dest = cpu_to_be32(readl(ioa_cfg->regs.dump_data_reg));
+               dest++;
+       }
+
+       return 0;
+}
+
 /**
  * ipr_get_ldump_data_section - Dump IOA memory
  * @ioa_cfg:                   ioa config struct
@@ -1950,9 +2617,13 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg,
        volatile u32 temp_pcii_reg;
        int i, delay = 0;
 
+       if (ioa_cfg->sis64)
+               return ipr_get_sis64_dump_data_section(ioa_cfg, start_addr,
+                                                      dest, length_in_words);
+
        /* Write IOA interrupt reg starting LDUMP state  */
        writel((IPR_UPROCI_RESET_ALERT | IPR_UPROCI_IO_DEBUG_ALERT),
-              ioa_cfg->regs.set_uproc_interrupt_reg);
+              ioa_cfg->regs.set_uproc_interrupt_reg32);
 
        /* Wait for IO debug acknowledge */
        if (ipr_wait_iodbg_ack(ioa_cfg,
@@ -1971,7 +2642,7 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg,
 
        /* Signal address valid - clear IOA Reset alert */
        writel(IPR_UPROCI_RESET_ALERT,
-              ioa_cfg->regs.clr_uproc_interrupt_reg);
+              ioa_cfg->regs.clr_uproc_interrupt_reg32);
 
        for (i = 0; i < length_in_words; i++) {
                /* Wait for IO debug acknowledge */
@@ -1996,10 +2667,10 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg,
 
        /* Signal end of block transfer. Set reset alert then clear IO debug ack */
        writel(IPR_UPROCI_RESET_ALERT,
-              ioa_cfg->regs.set_uproc_interrupt_reg);
+              ioa_cfg->regs.set_uproc_interrupt_reg32);
 
        writel(IPR_UPROCI_IO_DEBUG_ALERT,
-              ioa_cfg->regs.clr_uproc_interrupt_reg);
+              ioa_cfg->regs.clr_uproc_interrupt_reg32);
 
        /* Signal dump data received - Clear IO debug Ack */
        writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE,
@@ -2008,7 +2679,7 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg,
        /* Wait for IOA to signal LDUMP exit - IOA reset alert will be cleared */
        while (delay < IPR_LDUMP_MAX_SHORT_ACK_DELAY_IN_USEC) {
                temp_pcii_reg =
-                   readl(ioa_cfg->regs.sense_uproc_interrupt_reg);
+                   readl(ioa_cfg->regs.sense_uproc_interrupt_reg32);
 
                if (!(temp_pcii_reg & IPR_UPROCI_RESET_ALERT))
                        return 0;
@@ -2207,6 +2878,7 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
        u32 num_entries, start_off, end_off;
        u32 bytes_to_copy, bytes_copied, rc;
        struct ipr_sdt *sdt;
+       int valid = 1;
        int i;
 
        ENTER;
@@ -2220,7 +2892,7 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
 
        start_addr = readl(ioa_cfg->ioa_mailbox);
 
-       if (!ipr_sdt_is_fmt2(start_addr)) {
+       if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(start_addr)) {
                dev_err(&ioa_cfg->pdev->dev,
                        "Invalid dump table format: %lx\n", start_addr);
                spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@@ -2249,7 +2921,6 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
 
        /* IOA Dump entry */
        ipr_init_dump_entry_hdr(&ioa_dump->hdr);
-       ioa_dump->format = IPR_SDT_FMT2;
        ioa_dump->hdr.len = 0;
        ioa_dump->hdr.data_type = IPR_DUMP_DATA_TYPE_BINARY;
        ioa_dump->hdr.id = IPR_DUMP_IOA_DUMP_ID;
@@ -2264,7 +2935,8 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
                                        sizeof(struct ipr_sdt) / sizeof(__be32));
 
        /* Smart Dump table is ready to use and the first entry is valid */
-       if (rc || (be32_to_cpu(sdt->hdr.state) != IPR_FMT2_SDT_READY_TO_USE)) {
+       if (rc || ((be32_to_cpu(sdt->hdr.state) != IPR_FMT3_SDT_READY_TO_USE) &&
+           (be32_to_cpu(sdt->hdr.state) != IPR_FMT2_SDT_READY_TO_USE))) {
                dev_err(&ioa_cfg->pdev->dev,
                        "Dump of IOA failed. Dump table not valid: %d, %X.\n",
                        rc, be32_to_cpu(sdt->hdr.state));
@@ -2288,12 +2960,19 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
                }
 
                if (sdt->entry[i].flags & IPR_SDT_VALID_ENTRY) {
-                       sdt_word = be32_to_cpu(sdt->entry[i].bar_str_offset);
-                       start_off = sdt_word & IPR_FMT2_MBX_ADDR_MASK;
-                       end_off = be32_to_cpu(sdt->entry[i].end_offset);
-
-                       if (ipr_sdt_is_fmt2(sdt_word) && sdt_word) {
-                               bytes_to_copy = end_off - start_off;
+                       sdt_word = be32_to_cpu(sdt->entry[i].start_token);
+                       if (ioa_cfg->sis64)
+                               bytes_to_copy = be32_to_cpu(sdt->entry[i].end_token);
+                       else {
+                               start_off = sdt_word & IPR_FMT2_MBX_ADDR_MASK;
+                               end_off = be32_to_cpu(sdt->entry[i].end_token);
+
+                               if (ipr_sdt_is_fmt2(sdt_word) && sdt_word)
+                                       bytes_to_copy = end_off - start_off;
+                               else
+                                       valid = 0;
+                       }
+                       if (valid) {
                                if (bytes_to_copy > IPR_MAX_IOA_DUMP_SIZE) {
                                        sdt->entry[i].flags &= ~IPR_SDT_VALID_ENTRY;
                                        continue;
@@ -2422,9 +3101,9 @@ restart:
 
        list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
                if (res->add_to_ml) {
-                       bus = res->cfgte.res_addr.bus;
-                       target = res->cfgte.res_addr.target;
-                       lun = res->cfgte.res_addr.lun;
+                       bus = res->bus;
+                       target = res->target;
+                       lun = res->lun;
                        res->add_to_ml = 0;
                        spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
                        scsi_add_device(ioa_cfg->host, bus, target, lun);
@@ -2478,105 +3157,6 @@ static struct bin_attribute ipr_trace_attr = {
 };
 #endif
 
-static const struct {
-       enum ipr_cache_state state;
-       char *name;
-} cache_state [] = {
-       { CACHE_NONE, "none" },
-       { CACHE_DISABLED, "disabled" },
-       { CACHE_ENABLED, "enabled" }
-};
-
-/**
- * ipr_show_write_caching - Show the write caching attribute
- * @dev:       device struct
- * @buf:       buffer
- *
- * Return value:
- *     number of bytes printed to buffer
- **/
-static ssize_t ipr_show_write_caching(struct device *dev,
-                                     struct device_attribute *attr, char *buf)
-{
-       struct Scsi_Host *shost = class_to_shost(dev);
-       struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata;
-       unsigned long lock_flags = 0;
-       int i, len = 0;
-
-       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
-       for (i = 0; i < ARRAY_SIZE(cache_state); i++) {
-               if (cache_state[i].state == ioa_cfg->cache_state) {
-                       len = snprintf(buf, PAGE_SIZE, "%s\n", cache_state[i].name);
-                       break;
-               }
-       }
-       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-       return len;
-}
-
-
-/**
- * ipr_store_write_caching - Enable/disable adapter write cache
- * @dev:       device struct
- * @buf:       buffer
- * @count:     buffer size
- *
- * This function will enable/disable adapter write cache.
- *
- * Return value:
- *     count on success / other on failure
- **/
-static ssize_t ipr_store_write_caching(struct device *dev,
-                                      struct device_attribute *attr,
-                                      const char *buf, size_t count)
-{
-       struct Scsi_Host *shost = class_to_shost(dev);
-       struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata;
-       unsigned long lock_flags = 0;
-       enum ipr_cache_state new_state = CACHE_INVALID;
-       int i;
-
-       if (!capable(CAP_SYS_ADMIN))
-               return -EACCES;
-       if (ioa_cfg->cache_state == CACHE_NONE)
-               return -EINVAL;
-
-       for (i = 0; i < ARRAY_SIZE(cache_state); i++) {
-               if (!strncmp(cache_state[i].name, buf, strlen(cache_state[i].name))) {
-                       new_state = cache_state[i].state;
-                       break;
-               }
-       }
-
-       if (new_state != CACHE_DISABLED && new_state != CACHE_ENABLED)
-               return -EINVAL;
-
-       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
-       if (ioa_cfg->cache_state == new_state) {
-               spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-               return count;
-       }
-
-       ioa_cfg->cache_state = new_state;
-       dev_info(&ioa_cfg->pdev->dev, "%s adapter write cache.\n",
-                new_state == CACHE_ENABLED ? "Enabling" : "Disabling");
-       if (!ioa_cfg->in_reset_reload)
-               ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL);
-       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-       wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
-
-       return count;
-}
-
-static struct device_attribute ipr_ioa_cache_attr = {
-       .attr = {
-               .name =         "write_cache",
-               .mode =         S_IRUGO | S_IWUSR,
-       },
-       .show = ipr_show_write_caching,
-       .store = ipr_store_write_caching
-};
-
 /**
  * ipr_show_fw_version - Show the firmware version
  * @dev:       class device struct
@@ -2975,6 +3555,37 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
        return result;
 }
 
+/**
+ * ipr_build_ucode_ioadl64 - Build a microcode download IOADL
+ * @ipr_cmd:           ipr command struct
+ * @sglist:            scatter/gather list
+ *
+ * Builds a microcode download IOA data list (IOADL).
+ *
+ **/
+static void ipr_build_ucode_ioadl64(struct ipr_cmnd *ipr_cmd,
+                                   struct ipr_sglist *sglist)
+{
+       struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
+       struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64;
+       struct scatterlist *scatterlist = sglist->scatterlist;
+       int i;
+
+       ipr_cmd->dma_use_sg = sglist->num_dma_sg;
+       ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
+       ioarcb->data_transfer_length = cpu_to_be32(sglist->buffer_len);
+
+       ioarcb->ioadl_len =
+               cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg);
+       for (i = 0; i < ipr_cmd->dma_use_sg; i++) {
+               ioadl64[i].flags = cpu_to_be32(IPR_IOADL_FLAGS_WRITE);
+               ioadl64[i].data_len = cpu_to_be32(sg_dma_len(&scatterlist[i]));
+               ioadl64[i].address = cpu_to_be64(sg_dma_address(&scatterlist[i]));
+       }
+
+       ioadl64[i-1].flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
+}
+
 /**
  * ipr_build_ucode_ioadl - Build a microcode download IOADL
  * @ipr_cmd:   ipr command struct
@@ -2987,14 +3598,15 @@ static void ipr_build_ucode_ioadl(struct ipr_cmnd *ipr_cmd,
                                  struct ipr_sglist *sglist)
 {
        struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
-       struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+       struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl;
        struct scatterlist *scatterlist = sglist->scatterlist;
        int i;
 
        ipr_cmd->dma_use_sg = sglist->num_dma_sg;
        ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
-       ioarcb->write_data_transfer_length = cpu_to_be32(sglist->buffer_len);
-       ioarcb->write_ioadl_len =
+       ioarcb->data_transfer_length = cpu_to_be32(sglist->buffer_len);
+
+       ioarcb->ioadl_len =
                cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
 
        for (i = 0; i < ipr_cmd->dma_use_sg; i++) {
@@ -3146,7 +3758,6 @@ static struct device_attribute *ipr_ioa_attrs[] = {
        &ipr_ioa_state_attr,
        &ipr_ioa_reset_attr,
        &ipr_update_fw_attr,
-       &ipr_ioa_cache_attr,
        NULL,
 };
 
@@ -3450,7 +4061,7 @@ static ssize_t ipr_show_adapter_handle(struct device *dev, struct device_attribu
        spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
        res = (struct ipr_resource_entry *)sdev->hostdata;
        if (res)
-               len = snprintf(buf, PAGE_SIZE, "%08X\n", res->cfgte.res_handle);
+               len = snprintf(buf, PAGE_SIZE, "%08X\n", res->res_handle);
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
        return len;
 }
@@ -3463,8 +4074,43 @@ static struct device_attribute ipr_adapter_handle_attr = {
        .show = ipr_show_adapter_handle
 };
 
+/**
+ * ipr_show_resource_path - Show the resource path for this device.
+ * @dev:       device struct
+ * @buf:       buffer
+ *
+ * Return value:
+ *     number of bytes printed to buffer
+ **/
+static ssize_t ipr_show_resource_path(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct scsi_device *sdev = to_scsi_device(dev);
+       struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
+       struct ipr_resource_entry *res;
+       unsigned long lock_flags = 0;
+       ssize_t len = -ENXIO;
+       char buffer[IPR_MAX_RES_PATH_LENGTH];
+
+       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+       res = (struct ipr_resource_entry *)sdev->hostdata;
+       if (res)
+               len = snprintf(buf, PAGE_SIZE, "%s\n",
+                              ipr_format_resource_path(&res->res_path[0], &buffer[0]));
+       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+       return len;
+}
+
+static struct device_attribute ipr_resource_path_attr = {
+       .attr = {
+               .name =         "resource_path",
+               .mode =         S_IRUSR,
+       },
+       .show = ipr_show_resource_path
+};
+
 static struct device_attribute *ipr_dev_attrs[] = {
        &ipr_adapter_handle_attr,
+       &ipr_resource_path_attr,
        NULL,
 };
 
@@ -3517,9 +4163,9 @@ static struct ipr_resource_entry *ipr_find_starget(struct scsi_target *starget)
        struct ipr_resource_entry *res;
 
        list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
-               if ((res->cfgte.res_addr.bus == starget->channel) &&
-                   (res->cfgte.res_addr.target == starget->id) &&
-                   (res->cfgte.res_addr.lun == 0)) {
+               if ((res->bus == starget->channel) &&
+                   (res->target == starget->id) &&
+                   (res->lun == 0)) {
                        return res;
                }
        }
@@ -3589,6 +4235,17 @@ static int ipr_target_alloc(struct scsi_target *starget)
 static void ipr_target_destroy(struct scsi_target *starget)
 {
        struct ipr_sata_port *sata_port = starget->hostdata;
+       struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+       struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata;
+
+       if (ioa_cfg->sis64) {
+               if (starget->channel == IPR_ARRAY_VIRTUAL_BUS)
+                       clear_bit(starget->id, ioa_cfg->array_ids);
+               else if (starget->channel == IPR_VSET_VIRTUAL_BUS)
+                       clear_bit(starget->id, ioa_cfg->vset_ids);
+               else if (starget->channel == 0)
+                       clear_bit(starget->id, ioa_cfg->target_ids);
+       }
 
        if (sata_port) {
                starget->hostdata = NULL;
@@ -3610,9 +4267,9 @@ static struct ipr_resource_entry *ipr_find_sdev(struct scsi_device *sdev)
        struct ipr_resource_entry *res;
 
        list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
-               if ((res->cfgte.res_addr.bus == sdev->channel) &&
-                   (res->cfgte.res_addr.target == sdev->id) &&
-                   (res->cfgte.res_addr.lun == sdev->lun))
+               if ((res->bus == sdev->channel) &&
+                   (res->target == sdev->id) &&
+                   (res->lun == sdev->lun))
                        return res;
        }
 
@@ -3661,6 +4318,7 @@ static int ipr_slave_configure(struct scsi_device *sdev)
        struct ipr_resource_entry *res;
        struct ata_port *ap = NULL;
        unsigned long lock_flags = 0;
+       char buffer[IPR_MAX_RES_PATH_LENGTH];
 
        spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
        res = sdev->hostdata;
@@ -3687,6 +4345,9 @@ static int ipr_slave_configure(struct scsi_device *sdev)
                        ata_sas_slave_configure(sdev, ap);
                } else
                        scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
+               if (ioa_cfg->sis64)
+                       sdev_printk(KERN_INFO, sdev, "Resource path: %s\n",
+                                   ipr_format_resource_path(&res->res_path[0], &buffer[0]));
                return 0;
        }
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@@ -3828,14 +4489,19 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg,
        ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
        ioarcb = &ipr_cmd->ioarcb;
        cmd_pkt = &ioarcb->cmd_pkt;
-       regs = &ioarcb->add_data.u.regs;
 
-       ioarcb->res_handle = res->cfgte.res_handle;
+       if (ipr_cmd->ioa_cfg->sis64) {
+               regs = &ipr_cmd->i.ata_ioadl.regs;
+               ioarcb->add_cmd_parms_offset = cpu_to_be16(sizeof(*ioarcb));
+       } else
+               regs = &ioarcb->u.add_data.u.regs;
+
+       ioarcb->res_handle = res->res_handle;
        cmd_pkt->request_type = IPR_RQTYPE_IOACMD;
        cmd_pkt->cdb[0] = IPR_RESET_DEVICE;
        if (ipr_is_gata(res)) {
                cmd_pkt->cdb[2] = IPR_ATA_PHY_RESET;
-               ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(regs->flags));
+               ioarcb->add_cmd_parms_len = cpu_to_be16(sizeof(regs->flags));
                regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION;
        }
 
@@ -3880,19 +4546,7 @@ static int ipr_sata_reset(struct ata_link *link, unsigned int *classes,
        res = sata_port->res;
        if (res) {
                rc = ipr_device_reset(ioa_cfg, res);
-               switch(res->cfgte.proto) {
-               case IPR_PROTO_SATA:
-               case IPR_PROTO_SAS_STP:
-                       *classes = ATA_DEV_ATA;
-                       break;
-               case IPR_PROTO_SATA_ATAPI:
-               case IPR_PROTO_SAS_STP_ATAPI:
-                       *classes = ATA_DEV_ATAPI;
-                       break;
-               default:
-                       *classes = ATA_DEV_UNKNOWN;
-                       break;
-               };
+               *classes = res->ata_class;
        }
 
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@@ -3937,7 +4591,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
                return FAILED;
 
        list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
-               if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) {
+               if (ipr_cmd->ioarcb.res_handle == res->res_handle) {
                        if (ipr_cmd->scsi_cmd)
                                ipr_cmd->done = ipr_scsi_eh_done;
                        if (ipr_cmd->qc)
@@ -3959,7 +4613,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
                spin_lock_irq(scsi_cmd->device->host->host_lock);
 
                list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
-                       if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) {
+                       if (ipr_cmd->ioarcb.res_handle == res->res_handle) {
                                rc = -EIO;
                                break;
                        }
@@ -3998,13 +4652,13 @@ static void ipr_bus_reset_done(struct ipr_cmnd *ipr_cmd)
        struct ipr_resource_entry *res;
 
        ENTER;
-       list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
-               if (!memcmp(&res->cfgte.res_handle, &ipr_cmd->ioarcb.res_handle,
-                           sizeof(res->cfgte.res_handle))) {
-                       scsi_report_bus_reset(ioa_cfg->host, res->cfgte.res_addr.bus);
-                       break;
+       if (!ioa_cfg->sis64)
+               list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
+                       if (res->res_handle == ipr_cmd->ioarcb.res_handle) {
+                               scsi_report_bus_reset(ioa_cfg->host, res->bus);
+                               break;
+                       }
                }
-       }
 
        /*
         * If abort has not completed, indicate the reset has, else call the
@@ -4102,7 +4756,7 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd)
                return SUCCESS;
 
        ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
-       ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle;
+       ipr_cmd->ioarcb.res_handle = res->res_handle;
        cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt;
        cmd_pkt->request_type = IPR_RQTYPE_IOACMD;
        cmd_pkt->cdb[0] = IPR_CANCEL_ALL_REQUESTS;
@@ -4239,11 +4893,29 @@ static irqreturn_t ipr_isr(int irq, void *devp)
                return IRQ_NONE;
        }
 
-       int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
-       int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+       int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32);
+       int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg;
 
-       /* If an interrupt on the adapter did not occur, ignore it */
+       /* If an interrupt on the adapter did not occur, ignore it.
+        * Or in the case of SIS 64, check for a stage change interrupt.
+        */
        if (unlikely((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0)) {
+               if (ioa_cfg->sis64) {
+                       int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
+                       int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+                       if (int_reg & IPR_PCII_IPL_STAGE_CHANGE) {
+
+                               /* clear stage change */
+                               writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg);
+                               int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+                               list_del(&ioa_cfg->reset_cmd->queue);
+                               del_timer(&ioa_cfg->reset_cmd->timer);
+                               ipr_reset_ioa_job(ioa_cfg->reset_cmd);
+                               spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+                               return IRQ_HANDLED;
+                       }
+               }
+
                spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
                return IRQ_NONE;
        }
@@ -4286,8 +4958,8 @@ static irqreturn_t ipr_isr(int irq, void *devp)
                if (ipr_cmd != NULL) {
                        /* Clear the PCI interrupt */
                        do {
-                               writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg);
-                               int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+                               writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32);
+                               int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg;
                        } while (int_reg & IPR_PCII_HRRQ_UPDATED &&
                                        num_hrrq++ < IPR_MAX_HRRQ_RETRIES);
 
@@ -4308,6 +4980,53 @@ static irqreturn_t ipr_isr(int irq, void *devp)
        return rc;
 }
 
+/**
+ * ipr_build_ioadl64 - Build a scatter/gather list and map the buffer
+ * @ioa_cfg:   ioa config struct
+ * @ipr_cmd:   ipr command struct
+ *
+ * Return value:
+ *     0 on success / -1 on failure
+ **/
+static int ipr_build_ioadl64(struct ipr_ioa_cfg *ioa_cfg,
+                            struct ipr_cmnd *ipr_cmd)
+{
+       int i, nseg;
+       struct scatterlist *sg;
+       u32 length;
+       u32 ioadl_flags = 0;
+       struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
+       struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
+       struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64;
+
+       length = scsi_bufflen(scsi_cmd);
+       if (!length)
+               return 0;
+
+       nseg = scsi_dma_map(scsi_cmd);
+       if (nseg < 0) {
+               dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n");
+               return -1;
+       }
+
+       ipr_cmd->dma_use_sg = nseg;
+
+       if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) {
+               ioadl_flags = IPR_IOADL_FLAGS_WRITE;
+               ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
+       } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE)
+               ioadl_flags = IPR_IOADL_FLAGS_READ;
+
+       scsi_for_each_sg(scsi_cmd, sg, ipr_cmd->dma_use_sg, i) {
+               ioadl64[i].flags = cpu_to_be32(ioadl_flags);
+               ioadl64[i].data_len = cpu_to_be32(sg_dma_len(sg));
+               ioadl64[i].address = cpu_to_be64(sg_dma_address(sg));
+       }
+
+       ioadl64[i-1].flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
+       return 0;
+}
+
 /**
  * ipr_build_ioadl - Build a scatter/gather list and map the buffer
  * @ioa_cfg:   ioa config struct
@@ -4325,7 +5044,7 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
        u32 ioadl_flags = 0;
        struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
        struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
-       struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+       struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl;
 
        length = scsi_bufflen(scsi_cmd);
        if (!length)
@@ -4342,8 +5061,8 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
        if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) {
                ioadl_flags = IPR_IOADL_FLAGS_WRITE;
                ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
-               ioarcb->write_data_transfer_length = cpu_to_be32(length);
-               ioarcb->write_ioadl_len =
+               ioarcb->data_transfer_length = cpu_to_be32(length);
+               ioarcb->ioadl_len =
                        cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
        } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) {
                ioadl_flags = IPR_IOADL_FLAGS_READ;
@@ -4352,11 +5071,10 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
                        cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
        }
 
-       if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->add_data.u.ioadl)) {
-               ioadl = ioarcb->add_data.u.ioadl;
-               ioarcb->write_ioadl_addr =
-                       cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) +
-                                   offsetof(struct ipr_ioarcb, add_data));
+       if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->u.add_data.u.ioadl)) {
+               ioadl = ioarcb->u.add_data.u.ioadl;
+               ioarcb->write_ioadl_addr = cpu_to_be32((ipr_cmd->dma_addr) +
+                                   offsetof(struct ipr_ioarcb, u.add_data));
                ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
        }
 
@@ -4446,18 +5164,24 @@ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd)
 {
        struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
        struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
-       dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr);
+       dma_addr_t dma_addr = ipr_cmd->dma_addr;
 
        memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt));
-       ioarcb->write_data_transfer_length = 0;
+       ioarcb->data_transfer_length = 0;
        ioarcb->read_data_transfer_length = 0;
-       ioarcb->write_ioadl_len = 0;
+       ioarcb->ioadl_len = 0;
        ioarcb->read_ioadl_len = 0;
        ioasa->ioasc = 0;
        ioasa->residual_data_len = 0;
-       ioarcb->write_ioadl_addr =
-               cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl));
-       ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+
+       if (ipr_cmd->ioa_cfg->sis64)
+               ioarcb->u.sis64_addr_data.data_ioadl_addr =
+                       cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64));
+       else {
+               ioarcb->write_ioadl_addr =
+                       cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl));
+               ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+       }
 }
 
 /**
@@ -4489,15 +5213,8 @@ static void ipr_erp_request_sense(struct ipr_cmnd *ipr_cmd)
        cmd_pkt->flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;
        cmd_pkt->timeout = cpu_to_be16(IPR_REQUEST_SENSE_TIMEOUT / HZ);
 
-       ipr_cmd->ioadl[0].flags_and_data_len =
-               cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | SCSI_SENSE_BUFFERSIZE);
-       ipr_cmd->ioadl[0].address =
-               cpu_to_be32(ipr_cmd->sense_buffer_dma);
-
-       ipr_cmd->ioarcb.read_ioadl_len =
-               cpu_to_be32(sizeof(struct ipr_ioadl_desc));
-       ipr_cmd->ioarcb.read_data_transfer_length =
-               cpu_to_be32(SCSI_SENSE_BUFFERSIZE);
+       ipr_init_ioadl(ipr_cmd, ipr_cmd->sense_buffer_dma,
+                      SCSI_SENSE_BUFFERSIZE, IPR_IOADL_FLAGS_READ_LAST);
 
        ipr_do_req(ipr_cmd, ipr_erp_done, ipr_timeout,
                   IPR_REQUEST_SENSE_TIMEOUT * 2);
@@ -4893,9 +5610,9 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
 
        memcpy(ioarcb->cmd_pkt.cdb, scsi_cmd->cmnd, scsi_cmd->cmd_len);
        ipr_cmd->scsi_cmd = scsi_cmd;
-       ioarcb->res_handle = res->cfgte.res_handle;
+       ioarcb->res_handle = res->res_handle;
        ipr_cmd->done = ipr_scsi_done;
-       ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr));
+       ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res));
 
        if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) {
                if (scsi_cmd->underflow == 0)
@@ -4916,13 +5633,16 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
            (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE))
                ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
 
-       if (likely(rc == 0))
-               rc = ipr_build_ioadl(ioa_cfg, ipr_cmd);
+       if (likely(rc == 0)) {
+               if (ioa_cfg->sis64)
+                       rc = ipr_build_ioadl64(ioa_cfg, ipr_cmd);
+               else
+                       rc = ipr_build_ioadl(ioa_cfg, ipr_cmd);
+       }
 
        if (likely(rc == 0)) {
                mb();
-               writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr),
-                      ioa_cfg->regs.ioarrin_reg);
+               ipr_send_command(ipr_cmd);
        } else {
                 list_move_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
                 return SCSI_MLQUEUE_HOST_BUSY;
@@ -5035,20 +5755,9 @@ static void ipr_ata_phy_reset(struct ata_port *ap)
                goto out_unlock;
        }
 
-       switch(res->cfgte.proto) {
-       case IPR_PROTO_SATA:
-       case IPR_PROTO_SAS_STP:
-               ap->link.device[0].class = ATA_DEV_ATA;
-               break;
-       case IPR_PROTO_SATA_ATAPI:
-       case IPR_PROTO_SAS_STP_ATAPI:
-               ap->link.device[0].class = ATA_DEV_ATAPI;
-               break;
-       default:
-               ap->link.device[0].class = ATA_DEV_UNKNOWN;
+       ap->link.device[0].class = res->ata_class;
+       if (ap->link.device[0].class == ATA_DEV_UNKNOWN)
                ata_port_disable(ap);
-               break;
-       };
 
 out_unlock:
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
@@ -5134,8 +5843,7 @@ static void ipr_sata_done(struct ipr_cmnd *ipr_cmd)
        ipr_dump_ioasa(ioa_cfg, ipr_cmd, res);
 
        if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET)
-               scsi_report_device_reset(ioa_cfg->host, res->cfgte.res_addr.bus,
-                                        res->cfgte.res_addr.target);
+               scsi_report_device_reset(ioa_cfg->host, res->bus, res->target);
 
        if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR)
                qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status);
@@ -5145,6 +5853,52 @@ static void ipr_sata_done(struct ipr_cmnd *ipr_cmd)
        ata_qc_complete(qc);
 }
 
+/**
+ * ipr_build_ata_ioadl64 - Build an ATA scatter/gather list
+ * @ipr_cmd:   ipr command struct
+ * @qc:                ATA queued command
+ *
+ **/
+static void ipr_build_ata_ioadl64(struct ipr_cmnd *ipr_cmd,
+                                 struct ata_queued_cmd *qc)
+{
+       u32 ioadl_flags = 0;
+       struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
+       struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64;
+       struct ipr_ioadl64_desc *last_ioadl64 = NULL;
+       int len = qc->nbytes;
+       struct scatterlist *sg;
+       unsigned int si;
+       dma_addr_t dma_addr = ipr_cmd->dma_addr;
+
+       if (len == 0)
+               return;
+
+       if (qc->dma_dir == DMA_TO_DEVICE) {
+               ioadl_flags = IPR_IOADL_FLAGS_WRITE;
+               ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
+       } else if (qc->dma_dir == DMA_FROM_DEVICE)
+               ioadl_flags = IPR_IOADL_FLAGS_READ;
+
+       ioarcb->data_transfer_length = cpu_to_be32(len);
+       ioarcb->ioadl_len =
+               cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg);
+       ioarcb->u.sis64_addr_data.data_ioadl_addr =
+               cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ata_ioadl));
+
+       for_each_sg(qc->sg, sg, qc->n_elem, si) {
+               ioadl64->flags = cpu_to_be32(ioadl_flags);
+               ioadl64->data_len = cpu_to_be32(sg_dma_len(sg));
+               ioadl64->address = cpu_to_be64(sg_dma_address(sg));
+
+               last_ioadl64 = ioadl64;
+               ioadl64++;
+       }
+
+       if (likely(last_ioadl64))
+               last_ioadl64->flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
+}
+
 /**
  * ipr_build_ata_ioadl - Build an ATA scatter/gather list
  * @ipr_cmd:   ipr command struct
@@ -5156,7 +5910,7 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
 {
        u32 ioadl_flags = 0;
        struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
-       struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+       struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl;
        struct ipr_ioadl_desc *last_ioadl = NULL;
        int len = qc->nbytes;
        struct scatterlist *sg;
@@ -5168,8 +5922,8 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
        if (qc->dma_dir == DMA_TO_DEVICE) {
                ioadl_flags = IPR_IOADL_FLAGS_WRITE;
                ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
-               ioarcb->write_data_transfer_length = cpu_to_be32(len);
-               ioarcb->write_ioadl_len =
+               ioarcb->data_transfer_length = cpu_to_be32(len);
+               ioarcb->ioadl_len =
                        cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
        } else if (qc->dma_dir == DMA_FROM_DEVICE) {
                ioadl_flags = IPR_IOADL_FLAGS_READ;
@@ -5212,25 +5966,34 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc)
 
        ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
        ioarcb = &ipr_cmd->ioarcb;
-       regs = &ioarcb->add_data.u.regs;
 
-       memset(&ioarcb->add_data, 0, sizeof(ioarcb->add_data));
-       ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(ioarcb->add_data.u.regs));
+       if (ioa_cfg->sis64) {
+               regs = &ipr_cmd->i.ata_ioadl.regs;
+               ioarcb->add_cmd_parms_offset = cpu_to_be16(sizeof(*ioarcb));
+       } else
+               regs = &ioarcb->u.add_data.u.regs;
+
+       memset(regs, 0, sizeof(*regs));
+       ioarcb->add_cmd_parms_len = cpu_to_be16(sizeof(*regs));
 
        list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
        ipr_cmd->qc = qc;
        ipr_cmd->done = ipr_sata_done;
-       ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle;
+       ipr_cmd->ioarcb.res_handle = res->res_handle;
        ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU;
        ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC;
        ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;
        ipr_cmd->dma_use_sg = qc->n_elem;
 
-       ipr_build_ata_ioadl(ipr_cmd, qc);
+       if (ioa_cfg->sis64)
+               ipr_build_ata_ioadl64(ipr_cmd, qc);
+       else
+               ipr_build_ata_ioadl(ipr_cmd, qc);
+
        regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION;
        ipr_copy_sata_tf(regs, &qc->tf);
        memcpy(ioarcb->cmd_pkt.cdb, qc->cdb, IPR_MAX_CDB_LEN);
-       ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr));
+       ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res));
 
        switch (qc->tf.protocol) {
        case ATA_PROT_NODATA:
@@ -5257,8 +6020,9 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc)
        }
 
        mb();
-       writel(be32_to_cpu(ioarcb->ioarcb_host_pci_addr),
-              ioa_cfg->regs.ioarrin_reg);
+
+       ipr_send_command(ipr_cmd);
+
        return 0;
 }
 
@@ -5459,7 +6223,7 @@ static void ipr_set_sup_dev_dflt(struct ipr_supported_device *supported_dev,
  * ipr_set_supported_devs - Send Set Supported Devices for a device
  * @ipr_cmd:   ipr command struct
  *
- * This function send a Set Supported Devices to the adapter
+ * This function sends a Set Supported Devices to the adapter
  *
  * Return value:
  *     IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
@@ -5468,7 +6232,6 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd)
 {
        struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
        struct ipr_supported_device *supp_dev = &ioa_cfg->vpd_cbs->supp_dev;
-       struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
        struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
        struct ipr_resource_entry *res = ipr_cmd->u.res;
 
@@ -5479,64 +6242,34 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd)
                        continue;
 
                ipr_cmd->u.res = res;
-               ipr_set_sup_dev_dflt(supp_dev, &res->cfgte.std_inq_data.vpids);
+               ipr_set_sup_dev_dflt(supp_dev, &res->std_inq_data.vpids);
 
                ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
                ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
                ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
 
                ioarcb->cmd_pkt.cdb[0] = IPR_SET_SUPPORTED_DEVICES;
+               ioarcb->cmd_pkt.cdb[1] = IPR_SET_ALL_SUPPORTED_DEVICES;
                ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_supported_device) >> 8) & 0xff;
                ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_supported_device) & 0xff;
 
-               ioadl->flags_and_data_len = cpu_to_be32(IPR_IOADL_FLAGS_WRITE_LAST |
-                                                       sizeof(struct ipr_supported_device));
-               ioadl->address = cpu_to_be32(ioa_cfg->vpd_cbs_dma +
-                                            offsetof(struct ipr_misc_cbs, supp_dev));
-               ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
-               ioarcb->write_data_transfer_length =
-                       cpu_to_be32(sizeof(struct ipr_supported_device));
+               ipr_init_ioadl(ipr_cmd,
+                              ioa_cfg->vpd_cbs_dma +
+                                offsetof(struct ipr_misc_cbs, supp_dev),
+                              sizeof(struct ipr_supported_device),
+                              IPR_IOADL_FLAGS_WRITE_LAST);
 
                ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout,
                           IPR_SET_SUP_DEVICE_TIMEOUT);
 
-               ipr_cmd->job_step = ipr_set_supported_devs;
+               if (!ioa_cfg->sis64)
+                       ipr_cmd->job_step = ipr_set_supported_devs;
                return IPR_RC_JOB_RETURN;
        }
 
        return IPR_RC_JOB_CONTINUE;
 }
 
-/**
- * ipr_setup_write_cache - Disable write cache if needed
- * @ipr_cmd:   ipr command struct
- *
- * This function sets up adapters write cache to desired setting
- *
- * Return value:
- *     IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
- **/
-static int ipr_setup_write_cache(struct ipr_cmnd *ipr_cmd)
-{
-       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
-
-       ipr_cmd->job_step = ipr_set_supported_devs;
-       ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next,
-                                   struct ipr_resource_entry, queue);
-
-       if (ioa_cfg->cache_state != CACHE_DISABLED)
-               return IPR_RC_JOB_CONTINUE;
-
-       ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
-       ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
-       ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN;
-       ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL;
-
-       ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
-
-       return IPR_RC_JOB_RETURN;
-}
-
 /**
  * ipr_get_mode_page - Locate specified mode page
  * @mode_pages:        mode page buffer
@@ -5695,10 +6428,9 @@ static void ipr_modify_ioafp_mode_page_28(struct ipr_ioa_cfg *ioa_cfg,
  *     none
  **/
 static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd,
-                                 __be32 res_handle, u8 parm, u32 dma_addr,
-                                 u8 xfer_len)
+                                 __be32 res_handle, u8 parm,
+                                 dma_addr_t dma_addr, u8 xfer_len)
 {
-       struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
        struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
 
        ioarcb->res_handle = res_handle;
@@ -5708,11 +6440,7 @@ static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd,
        ioarcb->cmd_pkt.cdb[1] = parm;
        ioarcb->cmd_pkt.cdb[4] = xfer_len;
 
-       ioadl->flags_and_data_len =
-               cpu_to_be32(IPR_IOADL_FLAGS_WRITE_LAST | xfer_len);
-       ioadl->address = cpu_to_be32(dma_addr);
-       ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
-       ioarcb->write_data_transfer_length = cpu_to_be32(xfer_len);
+       ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_WRITE_LAST);
 }
 
 /**
@@ -5742,7 +6470,9 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd)
                              ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages),
                              length);
 
-       ipr_cmd->job_step = ipr_setup_write_cache;
+       ipr_cmd->job_step = ipr_set_supported_devs;
+       ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next,
+                                   struct ipr_resource_entry, queue);
        ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
 
        LEAVE;
@@ -5762,9 +6492,8 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd)
  **/
 static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd,
                                 __be32 res_handle,
-                                u8 parm, u32 dma_addr, u8 xfer_len)
+                                u8 parm, dma_addr_t dma_addr, u8 xfer_len)
 {
-       struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
        struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
 
        ioarcb->res_handle = res_handle;
@@ -5773,11 +6502,7 @@ static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd,
        ioarcb->cmd_pkt.cdb[4] = xfer_len;
        ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB;
 
-       ioadl->flags_and_data_len =
-               cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | xfer_len);
-       ioadl->address = cpu_to_be32(dma_addr);
-       ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
-       ioarcb->read_data_transfer_length = cpu_to_be32(xfer_len);
+       ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_READ_LAST);
 }
 
 /**
@@ -5815,10 +6540,13 @@ static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd)
  **/
 static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd)
 {
+       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
        u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
 
        if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) {
-               ipr_cmd->job_step = ipr_setup_write_cache;
+               ipr_cmd->job_step = ipr_set_supported_devs;
+               ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next,
+                                           struct ipr_resource_entry, queue);
                return IPR_RC_JOB_CONTINUE;
        }
 
@@ -5958,24 +6686,36 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd)
 {
        struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
        struct ipr_resource_entry *res, *temp;
-       struct ipr_config_table_entry *cfgte;
-       int found, i;
+       struct ipr_config_table_entry_wrapper cfgtew;
+       int entries, found, flag, i;
        LIST_HEAD(old_res);
 
        ENTER;
-       if (ioa_cfg->cfg_table->hdr.flags & IPR_UCODE_DOWNLOAD_REQ)
+       if (ioa_cfg->sis64)
+               flag = ioa_cfg->u.cfg_table64->hdr64.flags;
+       else
+               flag = ioa_cfg->u.cfg_table->hdr.flags;
+
+       if (flag & IPR_UCODE_DOWNLOAD_REQ)
                dev_err(&ioa_cfg->pdev->dev, "Microcode download required\n");
 
        list_for_each_entry_safe(res, temp, &ioa_cfg->used_res_q, queue)
                list_move_tail(&res->queue, &old_res);
 
-       for (i = 0; i < ioa_cfg->cfg_table->hdr.num_entries; i++) {
-               cfgte = &ioa_cfg->cfg_table->dev[i];
+       if (ioa_cfg->sis64)
+               entries = ioa_cfg->u.cfg_table64->hdr64.num_entries;
+       else
+               entries = ioa_cfg->u.cfg_table->hdr.num_entries;
+
+       for (i = 0; i < entries; i++) {
+               if (ioa_cfg->sis64)
+                       cfgtew.u.cfgte64 = &ioa_cfg->u.cfg_table64->dev[i];
+               else
+                       cfgtew.u.cfgte = &ioa_cfg->u.cfg_table->dev[i];
                found = 0;
 
                list_for_each_entry_safe(res, temp, &old_res, queue) {
-                       if (!memcmp(&res->cfgte.res_addr,
-                                   &cfgte->res_addr, sizeof(cfgte->res_addr))) {
+                       if (ipr_is_same_device(res, &cfgtew)) {
                                list_move_tail(&res->queue, &ioa_cfg->used_res_q);
                                found = 1;
                                break;
@@ -5992,24 +6732,27 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd)
                        res = list_entry(ioa_cfg->free_res_q.next,
                                         struct ipr_resource_entry, queue);
                        list_move_tail(&res->queue, &ioa_cfg->used_res_q);
-                       ipr_init_res_entry(res);
+                       ipr_init_res_entry(res, &cfgtew);
                        res->add_to_ml = 1;
                }
 
                if (found)
-                       memcpy(&res->cfgte, cfgte, sizeof(struct ipr_config_table_entry));
+                       ipr_update_res_entry(res, &cfgtew);
        }
 
        list_for_each_entry_safe(res, temp, &old_res, queue) {
                if (res->sdev) {
                        res->del_from_ml = 1;
-                       res->cfgte.res_handle = IPR_INVALID_RES_HANDLE;
+                       res->res_handle = IPR_INVALID_RES_HANDLE;
                        list_move_tail(&res->queue, &ioa_cfg->used_res_q);
-               } else {
-                       list_move_tail(&res->queue, &ioa_cfg->free_res_q);
                }
        }
 
+       list_for_each_entry_safe(res, temp, &old_res, queue) {
+               ipr_clear_res_target(res);
+               list_move_tail(&res->queue, &ioa_cfg->free_res_q);
+       }
+
        if (ioa_cfg->dual_raid && ipr_dual_ioa_raid)
                ipr_cmd->job_step = ipr_ioafp_mode_sense_page24;
        else
@@ -6033,7 +6776,6 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd)
 {
        struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
        struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
-       struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
        struct ipr_inquiry_page3 *ucode_vpd = &ioa_cfg->vpd_cbs->page3_data;
        struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap;
 
@@ -6047,16 +6789,11 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd)
        ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
 
        ioarcb->cmd_pkt.cdb[0] = IPR_QUERY_IOA_CONFIG;
-       ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_config_table) >> 8) & 0xff;
-       ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_config_table) & 0xff;
-
-       ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
-       ioarcb->read_data_transfer_length =
-               cpu_to_be32(sizeof(struct ipr_config_table));
+       ioarcb->cmd_pkt.cdb[7] = (ioa_cfg->cfg_table_size >> 8) & 0xff;
+       ioarcb->cmd_pkt.cdb[8] = ioa_cfg->cfg_table_size & 0xff;
 
-       ioadl->address = cpu_to_be32(ioa_cfg->cfg_table_dma);
-       ioadl->flags_and_data_len =
-               cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | sizeof(struct ipr_config_table));
+       ipr_init_ioadl(ipr_cmd, ioa_cfg->cfg_table_dma, ioa_cfg->cfg_table_size,
+                      IPR_IOADL_FLAGS_READ_LAST);
 
        ipr_cmd->job_step = ipr_init_res_table;
 
@@ -6076,10 +6813,9 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd)
  *     none
  **/
 static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page,
-                             u32 dma_addr, u8 xfer_len)
+                             dma_addr_t dma_addr, u8 xfer_len)
 {
        struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
-       struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
 
        ENTER;
        ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB;
@@ -6090,12 +6826,7 @@ static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page,
        ioarcb->cmd_pkt.cdb[2] = page;
        ioarcb->cmd_pkt.cdb[4] = xfer_len;
 
-       ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
-       ioarcb->read_data_transfer_length = cpu_to_be32(xfer_len);
-
-       ioadl->address = cpu_to_be32(dma_addr);
-       ioadl->flags_and_data_len =
-               cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | xfer_len);
+       ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_READ_LAST);
 
        ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
        LEAVE;
@@ -6166,13 +6897,9 @@ static int ipr_ioafp_cap_inquiry(struct ipr_cmnd *ipr_cmd)
 static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd)
 {
        struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
-       struct ipr_inquiry_page0 *page0 = &ioa_cfg->vpd_cbs->page0_data;
 
        ENTER;
 
-       if (!ipr_inquiry_page_supported(page0, 1))
-               ioa_cfg->cache_state = CACHE_NONE;
-
        ipr_cmd->job_step = ipr_ioafp_cap_inquiry;
 
        ipr_ioafp_inquiry(ipr_cmd, 1, 3,
@@ -6240,7 +6967,7 @@ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd)
 }
 
 /**
- * ipr_ioafp_indentify_hrrq - Send Identify Host RRQ.
+ * ipr_ioafp_identify_hrrq - Send Identify Host RRQ.
  * @ipr_cmd:   ipr command struct
  *
  * This function send an Identify Host Request Response Queue
@@ -6249,7 +6976,7 @@ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd)
  * Return value:
  *     IPR_RC_JOB_RETURN
  **/
-static int ipr_ioafp_indentify_hrrq(struct ipr_cmnd *ipr_cmd)
+static int ipr_ioafp_identify_hrrq(struct ipr_cmnd *ipr_cmd)
 {
        struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
        struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
@@ -6261,19 +6988,32 @@ static int ipr_ioafp_indentify_hrrq(struct ipr_cmnd *ipr_cmd)
        ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
 
        ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
+       if (ioa_cfg->sis64)
+               ioarcb->cmd_pkt.cdb[1] = 0x1;
        ioarcb->cmd_pkt.cdb[2] =
-               ((u32) ioa_cfg->host_rrq_dma >> 24) & 0xff;
+               ((u64) ioa_cfg->host_rrq_dma >> 24) & 0xff;
        ioarcb->cmd_pkt.cdb[3] =
-               ((u32) ioa_cfg->host_rrq_dma >> 16) & 0xff;
+               ((u64) ioa_cfg->host_rrq_dma >> 16) & 0xff;
        ioarcb->cmd_pkt.cdb[4] =
-               ((u32) ioa_cfg->host_rrq_dma >> 8) & 0xff;
+               ((u64) ioa_cfg->host_rrq_dma >> 8) & 0xff;
        ioarcb->cmd_pkt.cdb[5] =
-               ((u32) ioa_cfg->host_rrq_dma) & 0xff;
+               ((u64) ioa_cfg->host_rrq_dma) & 0xff;
        ioarcb->cmd_pkt.cdb[7] =
                ((sizeof(u32) * IPR_NUM_CMD_BLKS) >> 8) & 0xff;
        ioarcb->cmd_pkt.cdb[8] =
                (sizeof(u32) * IPR_NUM_CMD_BLKS) & 0xff;
 
+       if (ioa_cfg->sis64) {
+               ioarcb->cmd_pkt.cdb[10] =
+                       ((u64) ioa_cfg->host_rrq_dma >> 56) & 0xff;
+               ioarcb->cmd_pkt.cdb[11] =
+                       ((u64) ioa_cfg->host_rrq_dma >> 48) & 0xff;
+               ioarcb->cmd_pkt.cdb[12] =
+                       ((u64) ioa_cfg->host_rrq_dma >> 40) & 0xff;
+               ioarcb->cmd_pkt.cdb[13] =
+                       ((u64) ioa_cfg->host_rrq_dma >> 32) & 0xff;
+       }
+
        ipr_cmd->job_step = ipr_ioafp_std_inquiry;
 
        ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
@@ -6354,7 +7094,58 @@ static void ipr_init_ioa_mem(struct ipr_ioa_cfg *ioa_cfg)
        ioa_cfg->toggle_bit = 1;
 
        /* Zero out config table */
-       memset(ioa_cfg->cfg_table, 0, sizeof(struct ipr_config_table));
+       memset(ioa_cfg->u.cfg_table, 0, ioa_cfg->cfg_table_size);
+}
+
+/**
+ * ipr_reset_next_stage - Process IPL stage change based on feedback register.
+ * @ipr_cmd:   ipr command struct
+ *
+ * Return value:
+ *     IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
+ **/
+static int ipr_reset_next_stage(struct ipr_cmnd *ipr_cmd)
+{
+       unsigned long stage, stage_time;
+       u32 feedback;
+       volatile u32 int_reg;
+       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+       u64 maskval = 0;
+
+       feedback = readl(ioa_cfg->regs.init_feedback_reg);
+       stage = feedback & IPR_IPL_INIT_STAGE_MASK;
+       stage_time = feedback & IPR_IPL_INIT_STAGE_TIME_MASK;
+
+       ipr_dbg("IPL stage = 0x%lx, IPL stage time = %ld\n", stage, stage_time);
+
+       /* sanity check the stage_time value */
+       if (stage_time < IPR_IPL_INIT_MIN_STAGE_TIME)
+               stage_time = IPR_IPL_INIT_MIN_STAGE_TIME;
+       else if (stage_time > IPR_LONG_OPERATIONAL_TIMEOUT)
+               stage_time = IPR_LONG_OPERATIONAL_TIMEOUT;
+
+       if (stage == IPR_IPL_INIT_STAGE_UNKNOWN) {
+               writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.set_interrupt_mask_reg);
+               int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
+               stage_time = ioa_cfg->transop_timeout;
+               ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
+       } else if (stage == IPR_IPL_INIT_STAGE_TRANSOP) {
+               ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
+               maskval = IPR_PCII_IPL_STAGE_CHANGE;
+               maskval = (maskval << 32) | IPR_PCII_IOA_TRANS_TO_OPER;
+               writeq(maskval, ioa_cfg->regs.set_interrupt_mask_reg);
+               int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
+               return IPR_RC_JOB_CONTINUE;
+       }
+
+       ipr_cmd->timer.data = (unsigned long) ipr_cmd;
+       ipr_cmd->timer.expires = jiffies + stage_time * HZ;
+       ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout;
+       ipr_cmd->done = ipr_reset_ioa_job;
+       add_timer(&ipr_cmd->timer);
+       list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
+
+       return IPR_RC_JOB_RETURN;
 }
 
 /**
@@ -6373,7 +7164,7 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd)
        volatile u32 int_reg;
 
        ENTER;
-       ipr_cmd->job_step = ipr_ioafp_indentify_hrrq;
+       ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
        ipr_init_ioa_mem(ioa_cfg);
 
        ioa_cfg->allow_interrupts = 1;
@@ -6381,19 +7172,27 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd)
 
        if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) {
                writel((IPR_PCII_ERROR_INTERRUPTS | IPR_PCII_HRRQ_UPDATED),
-                      ioa_cfg->regs.clr_interrupt_mask_reg);
+                      ioa_cfg->regs.clr_interrupt_mask_reg32);
                int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
                return IPR_RC_JOB_CONTINUE;
        }
 
        /* Enable destructive diagnostics on IOA */
-       writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg);
+       writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg32);
+
+       writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg32);
+       if (ioa_cfg->sis64)
+               writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_mask_reg);
 
-       writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg);
        int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
 
        dev_info(&ioa_cfg->pdev->dev, "Initializing IOA.\n");
 
+       if (ioa_cfg->sis64) {
+               ipr_cmd->job_step = ipr_reset_next_stage;
+               return IPR_RC_JOB_CONTINUE;
+       }
+
        ipr_cmd->timer.data = (unsigned long) ipr_cmd;
        ipr_cmd->timer.expires = jiffies + (ioa_cfg->transop_timeout * HZ);
        ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout;
@@ -6463,7 +7262,7 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg)
 
        mailbox = readl(ioa_cfg->ioa_mailbox);
 
-       if (!ipr_sdt_is_fmt2(mailbox)) {
+       if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(mailbox)) {
                ipr_unit_check_no_data(ioa_cfg);
                return;
        }
@@ -6472,15 +7271,20 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg)
        rc = ipr_get_ldump_data_section(ioa_cfg, mailbox, (__be32 *) &sdt,
                                        (sizeof(struct ipr_uc_sdt)) / sizeof(__be32));
 
-       if (rc || (be32_to_cpu(sdt.hdr.state) != IPR_FMT2_SDT_READY_TO_USE) ||
-           !(sdt.entry[0].flags & IPR_SDT_VALID_ENTRY)) {
+       if (rc || !(sdt.entry[0].flags & IPR_SDT_VALID_ENTRY) ||
+           ((be32_to_cpu(sdt.hdr.state) != IPR_FMT3_SDT_READY_TO_USE) &&
+           (be32_to_cpu(sdt.hdr.state) != IPR_FMT2_SDT_READY_TO_USE))) {
                ipr_unit_check_no_data(ioa_cfg);
                return;
        }
 
        /* Find length of the first sdt entry (UC buffer) */
-       length = (be32_to_cpu(sdt.entry[0].end_offset) -
-                 be32_to_cpu(sdt.entry[0].bar_str_offset)) & IPR_FMT2_MBX_ADDR_MASK;
+       if (be32_to_cpu(sdt.hdr.state) == IPR_FMT3_SDT_READY_TO_USE)
+               length = be32_to_cpu(sdt.entry[0].end_token);
+       else
+               length = (be32_to_cpu(sdt.entry[0].end_token) -
+                         be32_to_cpu(sdt.entry[0].start_token)) &
+                         IPR_FMT2_MBX_ADDR_MASK;
 
        hostrcb = list_entry(ioa_cfg->hostrcb_free_q.next,
                             struct ipr_hostrcb, queue);
@@ -6488,13 +7292,13 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg)
        memset(&hostrcb->hcam, 0, sizeof(hostrcb->hcam));
 
        rc = ipr_get_ldump_data_section(ioa_cfg,
-                                       be32_to_cpu(sdt.entry[0].bar_str_offset),
+                                       be32_to_cpu(sdt.entry[0].start_token),
                                        (__be32 *)&hostrcb->hcam,
                                        min(length, (int)sizeof(hostrcb->hcam)) / sizeof(__be32));
 
        if (!rc) {
                ipr_handle_log_data(ioa_cfg, hostrcb);
-               ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc);
+               ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc);
                if (ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED &&
                    ioa_cfg->sdt_state == GET_DUMP)
                        ioa_cfg->sdt_state = WAIT_FOR_DUMP;
@@ -6722,7 +7526,7 @@ static int ipr_reset_alert(struct ipr_cmnd *ipr_cmd)
 
        if ((rc == PCIBIOS_SUCCESSFUL) && (cmd_reg & PCI_COMMAND_MEMORY)) {
                ipr_mask_and_clear_interrupts(ioa_cfg, ~0);
-               writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg);
+               writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg32);
                ipr_cmd->job_step = ipr_reset_wait_to_start_bist;
        } else {
                ipr_cmd->job_step = ioa_cfg->reset;
@@ -6785,7 +7589,10 @@ static int ipr_reset_ucode_download(struct ipr_cmnd *ipr_cmd)
        ipr_cmd->ioarcb.cmd_pkt.cdb[7] = (sglist->buffer_len & 0x00ff00) >> 8;
        ipr_cmd->ioarcb.cmd_pkt.cdb[8] = sglist->buffer_len & 0x0000ff;
 
-       ipr_build_ucode_ioadl(ipr_cmd, sglist);
+       if (ioa_cfg->sis64)
+               ipr_build_ucode_ioadl64(ipr_cmd, sglist);
+       else
+               ipr_build_ucode_ioadl(ipr_cmd, sglist);
        ipr_cmd->job_step = ipr_reset_ucode_download_done;
 
        ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout,
@@ -7154,8 +7961,8 @@ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg)
        ipr_free_cmd_blks(ioa_cfg);
        pci_free_consistent(ioa_cfg->pdev, sizeof(u32) * IPR_NUM_CMD_BLKS,
                            ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma);
-       pci_free_consistent(ioa_cfg->pdev, sizeof(struct ipr_config_table),
-                           ioa_cfg->cfg_table,
+       pci_free_consistent(ioa_cfg->pdev, ioa_cfg->cfg_table_size,
+                           ioa_cfg->u.cfg_table,
                            ioa_cfg->cfg_table_dma);
 
        for (i = 0; i < IPR_NUM_HCAMS; i++) {
@@ -7209,7 +8016,7 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
        int i;
 
        ioa_cfg->ipr_cmd_pool = pci_pool_create (IPR_NAME, ioa_cfg->pdev,
-                                                sizeof(struct ipr_cmnd), 8, 0);
+                                                sizeof(struct ipr_cmnd), 16, 0);
 
        if (!ioa_cfg->ipr_cmd_pool)
                return -ENOMEM;
@@ -7227,13 +8034,25 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
                ioa_cfg->ipr_cmnd_list_dma[i] = dma_addr;
 
                ioarcb = &ipr_cmd->ioarcb;
-               ioarcb->ioarcb_host_pci_addr = cpu_to_be32(dma_addr);
+               ipr_cmd->dma_addr = dma_addr;
+               if (ioa_cfg->sis64)
+                       ioarcb->a.ioarcb_host_pci_addr64 = cpu_to_be64(dma_addr);
+               else
+                       ioarcb->a.ioarcb_host_pci_addr = cpu_to_be32(dma_addr);
+
                ioarcb->host_response_handle = cpu_to_be32(i << 2);
-               ioarcb->write_ioadl_addr =
-                       cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl));
-               ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
-               ioarcb->ioasa_host_pci_addr =
-                       cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa));
+               if (ioa_cfg->sis64) {
+                       ioarcb->u.sis64_addr_data.data_ioadl_addr =
+                               cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64));
+                       ioarcb->u.sis64_addr_data.ioasa_host_pci_addr =
+                               cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, ioasa));
+               } else {
+                       ioarcb->write_ioadl_addr =
+                               cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl));
+                       ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+                       ioarcb->ioasa_host_pci_addr =
+                               cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa));
+               }
                ioarcb->ioasa_len = cpu_to_be16(sizeof(struct ipr_ioasa));
                ipr_cmd->cmd_index = i;
                ipr_cmd->ioa_cfg = ioa_cfg;
@@ -7260,13 +8079,24 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
 
        ENTER;
        ioa_cfg->res_entries = kzalloc(sizeof(struct ipr_resource_entry) *
-                                      IPR_MAX_PHYSICAL_DEVS, GFP_KERNEL);
+                                      ioa_cfg->max_devs_supported, GFP_KERNEL);
 
        if (!ioa_cfg->res_entries)
                goto out;
 
-       for (i = 0; i < IPR_MAX_PHYSICAL_DEVS; i++)
+       if (ioa_cfg->sis64) {
+               ioa_cfg->target_ids = kzalloc(sizeof(unsigned long) *
+                                             BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
+               ioa_cfg->array_ids = kzalloc(sizeof(unsigned long) *
+                                            BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
+               ioa_cfg->vset_ids = kzalloc(sizeof(unsigned long) *
+                                           BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL);
+       }
+
+       for (i = 0; i < ioa_cfg->max_devs_supported; i++) {
                list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q);
+               ioa_cfg->res_entries[i].ioa_cfg = ioa_cfg;
+       }
 
        ioa_cfg->vpd_cbs = pci_alloc_consistent(ioa_cfg->pdev,
                                                sizeof(struct ipr_misc_cbs),
@@ -7285,11 +8115,11 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
        if (!ioa_cfg->host_rrq)
                goto out_ipr_free_cmd_blocks;
 
-       ioa_cfg->cfg_table = pci_alloc_consistent(ioa_cfg->pdev,
-                                                 sizeof(struct ipr_config_table),
-                                                 &ioa_cfg->cfg_table_dma);
+       ioa_cfg->u.cfg_table = pci_alloc_consistent(ioa_cfg->pdev,
+                                                   ioa_cfg->cfg_table_size,
+                                                   &ioa_cfg->cfg_table_dma);
 
-       if (!ioa_cfg->cfg_table)
+       if (!ioa_cfg->u.cfg_table)
                goto out_free_host_rrq;
 
        for (i = 0; i < IPR_NUM_HCAMS; i++) {
@@ -7323,8 +8153,9 @@ out_free_hostrcb_dma:
                                    ioa_cfg->hostrcb[i],
                                    ioa_cfg->hostrcb_dma[i]);
        }
-       pci_free_consistent(pdev, sizeof(struct ipr_config_table),
-                           ioa_cfg->cfg_table, ioa_cfg->cfg_table_dma);
+       pci_free_consistent(pdev, ioa_cfg->cfg_table_size,
+                           ioa_cfg->u.cfg_table,
+                           ioa_cfg->cfg_table_dma);
 out_free_host_rrq:
        pci_free_consistent(pdev, sizeof(u32) * IPR_NUM_CMD_BLKS,
                            ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma);
@@ -7399,15 +8230,21 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
        init_waitqueue_head(&ioa_cfg->reset_wait_q);
        init_waitqueue_head(&ioa_cfg->msi_wait_q);
        ioa_cfg->sdt_state = INACTIVE;
-       if (ipr_enable_cache)
-               ioa_cfg->cache_state = CACHE_ENABLED;
-       else
-               ioa_cfg->cache_state = CACHE_DISABLED;
 
        ipr_initialize_bus_attr(ioa_cfg);
+       ioa_cfg->max_devs_supported = ipr_max_devs;
 
-       host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS;
-       host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET;
+       if (ioa_cfg->sis64) {
+               host->max_id = IPR_MAX_SIS64_TARGETS_PER_BUS;
+               host->max_lun = IPR_MAX_SIS64_LUNS_PER_TARGET;
+               if (ipr_max_devs > IPR_MAX_SIS64_DEVS)
+                       ioa_cfg->max_devs_supported = IPR_MAX_SIS64_DEVS;
+       } else {
+               host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS;
+               host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET;
+               if (ipr_max_devs > IPR_MAX_PHYSICAL_DEVS)
+                       ioa_cfg->max_devs_supported = IPR_MAX_PHYSICAL_DEVS;
+       }
        host->max_channel = IPR_MAX_BUS_TO_SCAN;
        host->unique_id = host->host_no;
        host->max_cmd_len = IPR_MAX_CDB_LEN;
@@ -7419,13 +8256,26 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
 
        t->set_interrupt_mask_reg = base + p->set_interrupt_mask_reg;
        t->clr_interrupt_mask_reg = base + p->clr_interrupt_mask_reg;
+       t->clr_interrupt_mask_reg32 = base + p->clr_interrupt_mask_reg32;
        t->sense_interrupt_mask_reg = base + p->sense_interrupt_mask_reg;
+       t->sense_interrupt_mask_reg32 = base + p->sense_interrupt_mask_reg32;
        t->clr_interrupt_reg = base + p->clr_interrupt_reg;
+       t->clr_interrupt_reg32 = base + p->clr_interrupt_reg32;
        t->sense_interrupt_reg = base + p->sense_interrupt_reg;
+       t->sense_interrupt_reg32 = base + p->sense_interrupt_reg32;
        t->ioarrin_reg = base + p->ioarrin_reg;
        t->sense_uproc_interrupt_reg = base + p->sense_uproc_interrupt_reg;
+       t->sense_uproc_interrupt_reg32 = base + p->sense_uproc_interrupt_reg32;
        t->set_uproc_interrupt_reg = base + p->set_uproc_interrupt_reg;
+       t->set_uproc_interrupt_reg32 = base + p->set_uproc_interrupt_reg32;
        t->clr_uproc_interrupt_reg = base + p->clr_uproc_interrupt_reg;
+       t->clr_uproc_interrupt_reg32 = base + p->clr_uproc_interrupt_reg32;
+
+       if (ioa_cfg->sis64) {
+               t->init_feedback_reg = base + p->init_feedback_reg;
+               t->dump_addr_reg = base + p->dump_addr_reg;
+               t->dump_data_reg = base + p->dump_data_reg;
+       }
 }
 
 /**
@@ -7497,7 +8347,7 @@ static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg,
        init_waitqueue_head(&ioa_cfg->msi_wait_q);
        ioa_cfg->msi_received = 0;
        ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
-       writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg);
+       writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg32);
        int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
 
@@ -7508,7 +8358,7 @@ static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg,
        } else if (ipr_debug)
                dev_info(&pdev->dev, "IRQ assigned: %d\n", pdev->irq);
 
-       writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg);
+       writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg32);
        int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
        wait_event_timeout(ioa_cfg->msi_wait_q, ioa_cfg->msi_received, HZ);
        ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
@@ -7578,6 +8428,8 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
                goto out_scsi_host_put;
        }
 
+       /* set SIS 32 or SIS 64 */
+       ioa_cfg->sis64 = ioa_cfg->ipr_chip->sis_type == IPR_SIS64 ? 1 : 0;
        ioa_cfg->chip_cfg = ioa_cfg->ipr_chip->cfg;
 
        if (ipr_transop_timeout)
@@ -7615,7 +8467,16 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
 
        pci_set_master(pdev);
 
-       rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+       if (ioa_cfg->sis64) {
+               rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+               if (rc < 0) {
+                       dev_dbg(&pdev->dev, "Failed to set 64 bit PCI DMA mask\n");
+                       rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+               }
+
+       } else
+               rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+
        if (rc < 0) {
                dev_err(&pdev->dev, "Failed to set PCI DMA mask\n");
                goto cleanup_nomem;
@@ -7657,6 +8518,15 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
        if ((rc = ipr_set_pcix_cmd_reg(ioa_cfg)))
                goto cleanup_nomem;
 
+       if (ioa_cfg->sis64)
+               ioa_cfg->cfg_table_size = (sizeof(struct ipr_config_table_hdr64)
+                               + ((sizeof(struct ipr_config_table_entry64)
+                               * ioa_cfg->max_devs_supported)));
+       else
+               ioa_cfg->cfg_table_size = (sizeof(struct ipr_config_table_hdr)
+                               + ((sizeof(struct ipr_config_table_entry)
+                               * ioa_cfg->max_devs_supported)));
+
        rc = ipr_alloc_mem(ioa_cfg);
        if (rc < 0) {
                dev_err(&pdev->dev,
@@ -7668,9 +8538,9 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
         * If HRRQ updated interrupt is not masked, or reset alert is set,
         * the card is in an unknown state and needs a hard reset
         */
-       mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
-       interrupts = readl(ioa_cfg->regs.sense_interrupt_reg);
-       uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg);
+       mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg32);
+       interrupts = readl(ioa_cfg->regs.sense_interrupt_reg32);
+       uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg32);
        if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT))
                ioa_cfg->needs_hard_reset = 1;
        if (interrupts & IPR_PCII_ERROR_INTERRUPTS)
@@ -7957,9 +8827,6 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
        { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
              PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574E, 0, 0,
              IPR_USE_LONG_TRANSOP_TIMEOUT },
-       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
-             PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0,
-             IPR_USE_LONG_TRANSOP_TIMEOUT },
        { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
              PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B3, 0, 0, 0 },
        { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
@@ -7975,9 +8842,22 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
        { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP,
                PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0,
                IPR_USE_LONG_TRANSOP_TIMEOUT },
-       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SCAMP_E,
-               PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0,
-               IPR_USE_LONG_TRANSOP_TIMEOUT },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
+               PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B5, 0, 0, 0 },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
+               PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0, 0 },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
+               PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B2, 0, 0, 0 },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
+               PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B4, 0, 0, 0 },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
+               PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B1, 0, 0, 0 },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
+               PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57C6, 0, 0, 0 },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
+               PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0, 0 },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
+               PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57CE, 0, 0, 0 },
        { }
 };
 MODULE_DEVICE_TABLE(pci, ipr_pci_table);
@@ -7996,6 +8876,61 @@ static struct pci_driver ipr_driver = {
        .err_handler = &ipr_err_handler,
 };
 
+/**
+ * ipr_halt_done - Shutdown prepare completion
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_halt_done(struct ipr_cmnd *ipr_cmd)
+{
+       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+
+       list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
+}
+
+/**
+ * ipr_halt - Issue shutdown prepare to all adapters
+ *
+ * Return value:
+ *     NOTIFY_OK on success / NOTIFY_DONE on failure
+ **/
+static int ipr_halt(struct notifier_block *nb, ulong event, void *buf)
+{
+       struct ipr_cmnd *ipr_cmd;
+       struct ipr_ioa_cfg *ioa_cfg;
+       unsigned long flags = 0;
+
+       if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
+               return NOTIFY_DONE;
+
+       spin_lock(&ipr_driver_lock);
+
+       list_for_each_entry(ioa_cfg, &ipr_ioa_head, queue) {
+               spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
+               if (!ioa_cfg->allow_cmds) {
+                       spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
+                       continue;
+               }
+
+               ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
+               ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
+               ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
+               ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN;
+               ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL;
+
+               ipr_do_req(ipr_cmd, ipr_halt_done, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT);
+               spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
+       }
+       spin_unlock(&ipr_driver_lock);
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block ipr_notifier = {
+       ipr_halt, NULL, 0
+};
+
 /**
  * ipr_init - Module entry point
  *
@@ -8007,6 +8942,7 @@ static int __init ipr_init(void)
        ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n",
                 IPR_DRIVER_VERSION, IPR_DRIVER_DATE);
 
+       register_reboot_notifier(&ipr_notifier);
        return pci_register_driver(&ipr_driver);
 }
 
@@ -8020,6 +8956,7 @@ static int __init ipr_init(void)
  **/
 static void __exit ipr_exit(void)
 {
+       unregister_reboot_notifier(&ipr_notifier);
        pci_unregister_driver(&ipr_driver);
 }
 
index 19bbcf39f0c9fb759af60b670782e3c48dc12e01..4c267b5e0b96c97c505149d1193891914c15f217 100644 (file)
@@ -37,8 +37,8 @@
 /*
  * Literals
  */
-#define IPR_DRIVER_VERSION "2.4.3"
-#define IPR_DRIVER_DATE "(June 10, 2009)"
+#define IPR_DRIVER_VERSION "2.5.0"
+#define IPR_DRIVER_DATE "(February 11, 2010)"
 
 /*
  * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@@ -55,7 +55,9 @@
 #define IPR_NUM_BASE_CMD_BLKS                          100
 
 #define PCI_DEVICE_ID_IBM_OBSIDIAN_E   0x0339
-#define PCI_DEVICE_ID_IBM_SCAMP_E              0x034A
+
+#define PCI_DEVICE_ID_IBM_CROC_FPGA_E2          0x033D
+#define PCI_DEVICE_ID_IBM_CROC_ASIC_E2          0x034A
 
 #define IPR_SUBS_DEV_ID_2780   0x0264
 #define IPR_SUBS_DEV_ID_5702   0x0266
 #define IPR_SUBS_DEV_ID_572A   0x02C1
 #define IPR_SUBS_DEV_ID_572B   0x02C2
 #define IPR_SUBS_DEV_ID_572F   0x02C3
-#define IPR_SUBS_DEV_ID_574D   0x030B
 #define IPR_SUBS_DEV_ID_574E   0x030A
 #define IPR_SUBS_DEV_ID_575B   0x030D
 #define IPR_SUBS_DEV_ID_575C   0x0338
-#define IPR_SUBS_DEV_ID_575D   0x033E
 #define IPR_SUBS_DEV_ID_57B3   0x033A
 #define IPR_SUBS_DEV_ID_57B7   0x0360
 #define IPR_SUBS_DEV_ID_57B8   0x02C2
 
+#define IPR_SUBS_DEV_ID_57B4    0x033B
+#define IPR_SUBS_DEV_ID_57B2    0x035F
+#define IPR_SUBS_DEV_ID_57C6    0x0357
+
+#define IPR_SUBS_DEV_ID_57B5    0x033C
+#define IPR_SUBS_DEV_ID_57CE    0x035E
+#define IPR_SUBS_DEV_ID_57B1    0x0355
+
+#define IPR_SUBS_DEV_ID_574D    0x0356
+#define IPR_SUBS_DEV_ID_575D    0x035D
+
 #define IPR_NAME                               "ipr"
 
 /*
 #define IPR_NUM_LOG_HCAMS                              2
 #define IPR_NUM_CFG_CHG_HCAMS                          2
 #define IPR_NUM_HCAMS  (IPR_NUM_LOG_HCAMS + IPR_NUM_CFG_CHG_HCAMS)
+
+#define IPR_MAX_SIS64_TARGETS_PER_BUS                  1024
+#define IPR_MAX_SIS64_LUNS_PER_TARGET                  0xffffffff
+
 #define IPR_MAX_NUM_TARGETS_PER_BUS                    256
 #define IPR_MAX_NUM_LUNS_PER_TARGET                    256
 #define IPR_MAX_NUM_VSET_LUNS_PER_TARGET       8
 
 /* We need resources for HCAMS, IOA reset, IOA bringdown, and ERP */
 #define IPR_NUM_INTERNAL_CMD_BLKS      (IPR_NUM_HCAMS + \
-                                     ((IPR_NUM_RESET_RELOAD_RETRIES + 1) * 2) + 3)
+                                     ((IPR_NUM_RESET_RELOAD_RETRIES + 1) * 2) + 4)
 
 #define IPR_MAX_COMMANDS               IPR_NUM_BASE_CMD_BLKS
 #define IPR_NUM_CMD_BLKS               (IPR_NUM_BASE_CMD_BLKS + \
                                                IPR_NUM_INTERNAL_CMD_BLKS)
 
 #define IPR_MAX_PHYSICAL_DEVS                          192
+#define IPR_DEFAULT_SIS64_DEVS                         1024
+#define IPR_MAX_SIS64_DEVS                             4096
 
 #define IPR_MAX_SGLIST                                 64
 #define IPR_IOA_MAX_SECTORS                            32767
 #define        IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE      0x01
 #define        IPR_HCAM_CDB_OP_CODE_LOG_DATA           0x02
 #define IPR_SET_SUPPORTED_DEVICES                      0xFB
+#define IPR_SET_ALL_SUPPORTED_DEVICES                  0x80
 #define IPR_IOA_SHUTDOWN                               0xF7
 #define        IPR_WR_BUF_DOWNLOAD_AND_SAVE                    0x05
 
 #define IPR_SDT_FMT2_BAR5_SEL                          0x5
 #define IPR_SDT_FMT2_EXP_ROM_SEL                       0x8
 #define IPR_FMT2_SDT_READY_TO_USE                      0xC4D4E3F2
+#define IPR_FMT3_SDT_READY_TO_USE                      0xC4D4E3F3
 #define IPR_DOORBELL                                   0x82800000
 #define IPR_RUNTIME_RESET                              0x40000000
 
+#define IPR_IPL_INIT_MIN_STAGE_TIME                    5
+#define IPR_IPL_INIT_STAGE_UNKNOWN                     0x0
+#define IPR_IPL_INIT_STAGE_TRANSOP                     0xB0000000
+#define IPR_IPL_INIT_STAGE_MASK                                0xff000000
+#define IPR_IPL_INIT_STAGE_TIME_MASK                   0x0000ffff
+#define IPR_PCII_IPL_STAGE_CHANGE                      (0x80000000 >> 0)
+
 #define IPR_PCII_IOA_TRANS_TO_OPER                     (0x80000000 >> 0)
 #define IPR_PCII_IOARCB_XFER_FAILED                    (0x80000000 >> 3)
 #define IPR_PCII_IOA_UNIT_CHECKED                      (0x80000000 >> 4)
@@ -318,27 +344,27 @@ struct ipr_std_inq_data {
        u8 serial_num[IPR_SERIAL_NUM_LEN];
 }__attribute__ ((packed));
 
+#define IPR_RES_TYPE_AF_DASD           0x00
+#define IPR_RES_TYPE_GENERIC_SCSI      0x01
+#define IPR_RES_TYPE_VOLUME_SET                0x02
+#define IPR_RES_TYPE_REMOTE_AF_DASD    0x03
+#define IPR_RES_TYPE_GENERIC_ATA       0x04
+#define IPR_RES_TYPE_ARRAY             0x05
+#define IPR_RES_TYPE_IOAFP             0xff
+
 struct ipr_config_table_entry {
        u8 proto;
 #define IPR_PROTO_SATA                 0x02
 #define IPR_PROTO_SATA_ATAPI           0x03
 #define IPR_PROTO_SAS_STP              0x06
-#define IPR_PROTO_SAS_STP_ATAPI        0x07
+#define IPR_PROTO_SAS_STP_ATAPI                0x07
        u8 array_id;
        u8 flags;
-#define IPR_IS_IOA_RESOURCE    0x80
-#define IPR_IS_ARRAY_MEMBER 0x20
-#define IPR_IS_HOT_SPARE       0x10
-
+#define IPR_IS_IOA_RESOURCE            0x80
        u8 rsvd_subtype;
-#define IPR_RES_SUBTYPE(res) (((res)->cfgte.rsvd_subtype) & 0x0f)
-#define IPR_SUBTYPE_AF_DASD                    0
-#define IPR_SUBTYPE_GENERIC_SCSI       1
-#define IPR_SUBTYPE_VOLUME_SET         2
-#define IPR_SUBTYPE_GENERIC_ATA        4
-
-#define IPR_QUEUEING_MODEL(res)        ((((res)->cfgte.flags) & 0x70) >> 4)
-#define IPR_QUEUE_FROZEN_MODEL 0
+
+#define IPR_QUEUEING_MODEL(res)        ((((res)->flags) & 0x70) >> 4)
+#define IPR_QUEUE_FROZEN_MODEL         0
 #define IPR_QUEUE_NACA_MODEL           1
 
        struct ipr_res_addr res_addr;
@@ -347,6 +373,28 @@ struct ipr_config_table_entry {
        struct ipr_std_inq_data std_inq_data;
 }__attribute__ ((packed, aligned (4)));
 
+struct ipr_config_table_entry64 {
+       u8 res_type;
+       u8 proto;
+       u8 vset_num;
+       u8 array_id;
+       __be16 flags;
+       __be16 res_flags;
+#define IPR_QUEUEING_MODEL64(res) ((((res)->res_flags) & 0x7000) >> 12)
+       __be32 res_handle;
+       u8 dev_id_type;
+       u8 reserved[3];
+       __be64 dev_id;
+       __be64 lun;
+       __be64 lun_wwn[2];
+#define IPR_MAX_RES_PATH_LENGTH                24
+       __be64 res_path;
+       struct ipr_std_inq_data std_inq_data;
+       u8 reserved2[4];
+       __be64 reserved3[2]; // description text
+       u8 reserved4[8];
+}__attribute__ ((packed, aligned (8)));
+
 struct ipr_config_table_hdr {
        u8 num_entries;
        u8 flags;
@@ -354,13 +402,35 @@ struct ipr_config_table_hdr {
        __be16 reserved;
 }__attribute__((packed, aligned (4)));
 
+struct ipr_config_table_hdr64 {
+       __be16 num_entries;
+       __be16 reserved;
+       u8 flags;
+       u8 reserved2[11];
+}__attribute__((packed, aligned (4)));
+
 struct ipr_config_table {
        struct ipr_config_table_hdr hdr;
-       struct ipr_config_table_entry dev[IPR_MAX_PHYSICAL_DEVS];
+       struct ipr_config_table_entry dev[0];
 }__attribute__((packed, aligned (4)));
 
+struct ipr_config_table64 {
+       struct ipr_config_table_hdr64 hdr64;
+       struct ipr_config_table_entry64 dev[0];
+}__attribute__((packed, aligned (8)));
+
+struct ipr_config_table_entry_wrapper {
+       union {
+               struct ipr_config_table_entry *cfgte;
+               struct ipr_config_table_entry64 *cfgte64;
+       } u;
+};
+
 struct ipr_hostrcb_cfg_ch_not {
-       struct ipr_config_table_entry cfgte;
+       union {
+               struct ipr_config_table_entry cfgte;
+               struct ipr_config_table_entry64 cfgte64;
+       } u;
        u8 reserved[936];
 }__attribute__((packed, aligned (4)));
 
@@ -381,7 +451,7 @@ struct ipr_cmd_pkt {
 #define IPR_RQTYPE_HCAM                        0x02
 #define IPR_RQTYPE_ATA_PASSTHRU        0x04
 
-       u8 luntar_luntrn;
+       u8 reserved2;
 
        u8 flags_hi;
 #define IPR_FLAGS_HI_WRITE_NOT_READ            0x80
@@ -403,7 +473,7 @@ struct ipr_cmd_pkt {
        __be16 timeout;
 }__attribute__ ((packed, aligned(4)));
 
-struct ipr_ioarcb_ata_regs {
+struct ipr_ioarcb_ata_regs {   /* 22 bytes */
        u8 flags;
 #define IPR_ATA_FLAG_PACKET_CMD                        0x80
 #define IPR_ATA_FLAG_XFER_TYPE_DMA                     0x40
@@ -442,28 +512,49 @@ struct ipr_ioadl_desc {
        __be32 address;
 }__attribute__((packed, aligned (8)));
 
+struct ipr_ioadl64_desc {
+       __be32 flags;
+       __be32 data_len;
+       __be64 address;
+}__attribute__((packed, aligned (16)));
+
+struct ipr_ata64_ioadl {
+       struct ipr_ioarcb_ata_regs regs;
+       u16 reserved[5];
+       struct ipr_ioadl64_desc ioadl64[IPR_NUM_IOADL_ENTRIES];
+}__attribute__((packed, aligned (16)));
+
 struct ipr_ioarcb_add_data {
        union {
                struct ipr_ioarcb_ata_regs regs;
                struct ipr_ioadl_desc ioadl[5];
                __be32 add_cmd_parms[10];
-       }u;
-}__attribute__ ((packed, aligned(4)));
+       } u;
+}__attribute__ ((packed, aligned (4)));
+
+struct ipr_ioarcb_sis64_add_addr_ecb {
+       __be64 ioasa_host_pci_addr;
+       __be64 data_ioadl_addr;
+       __be64 reserved;
+       __be32 ext_control_buf[4];
+}__attribute__((packed, aligned (8)));
 
 /* IOA Request Control Block    128 bytes  */
 struct ipr_ioarcb {
-       __be32 ioarcb_host_pci_addr;
-       __be32 reserved;
+       union {
+               __be32 ioarcb_host_pci_addr;
+               __be64 ioarcb_host_pci_addr64;
+       } a;
        __be32 res_handle;
        __be32 host_response_handle;
        __be32 reserved1;
        __be32 reserved2;
        __be32 reserved3;
 
-       __be32 write_data_transfer_length;
+       __be32 data_transfer_length;
        __be32 read_data_transfer_length;
        __be32 write_ioadl_addr;
-       __be32 write_ioadl_len;
+       __be32 ioadl_len;
        __be32 read_ioadl_addr;
        __be32 read_ioadl_len;
 
@@ -473,8 +564,14 @@ struct ipr_ioarcb {
 
        struct ipr_cmd_pkt cmd_pkt;
 
-       __be32 add_cmd_parms_len;
-       struct ipr_ioarcb_add_data add_data;
+       __be16 add_cmd_parms_offset;
+       __be16 add_cmd_parms_len;
+
+       union {
+               struct ipr_ioarcb_add_data add_data;
+               struct ipr_ioarcb_sis64_add_addr_ecb sis64_addr_data;
+       } u;
+
 }__attribute__((packed, aligned (4)));
 
 struct ipr_ioasa_vset {
@@ -676,12 +773,29 @@ struct ipr_hostrcb_device_data_entry_enhanced {
        struct ipr_ext_vpd cfc_last_with_dev_vpd;
 }__attribute__((packed, aligned (4)));
 
+struct ipr_hostrcb64_device_data_entry_enhanced {
+       struct ipr_ext_vpd vpd;
+       u8 ccin[4];
+       u8 res_path[8];
+       struct ipr_ext_vpd new_vpd;
+       u8 new_ccin[4];
+       struct ipr_ext_vpd ioa_last_with_dev_vpd;
+       struct ipr_ext_vpd cfc_last_with_dev_vpd;
+}__attribute__((packed, aligned (4)));
+
 struct ipr_hostrcb_array_data_entry {
        struct ipr_vpd vpd;
        struct ipr_res_addr expected_dev_res_addr;
        struct ipr_res_addr dev_res_addr;
 }__attribute__((packed, aligned (4)));
 
+struct ipr_hostrcb64_array_data_entry {
+       struct ipr_ext_vpd vpd;
+       u8 ccin[4];
+       u8 expected_res_path[8];
+       u8 res_path[8];
+}__attribute__((packed, aligned (4)));
+
 struct ipr_hostrcb_array_data_entry_enhanced {
        struct ipr_ext_vpd vpd;
        u8 ccin[4];
@@ -733,6 +847,14 @@ struct ipr_hostrcb_type_13_error {
        struct ipr_hostrcb_device_data_entry_enhanced dev[3];
 }__attribute__((packed, aligned (4)));
 
+struct ipr_hostrcb_type_23_error {
+       struct ipr_ext_vpd ioa_vpd;
+       struct ipr_ext_vpd cfc_vpd;
+       __be32 errors_detected;
+       __be32 errors_logged;
+       struct ipr_hostrcb64_device_data_entry_enhanced dev[3];
+}__attribute__((packed, aligned (4)));
+
 struct ipr_hostrcb_type_04_error {
        struct ipr_vpd ioa_vpd;
        struct ipr_vpd cfc_vpd;
@@ -760,6 +882,22 @@ struct ipr_hostrcb_type_14_error {
        struct ipr_hostrcb_array_data_entry_enhanced array_member[18];
 }__attribute__((packed, aligned (4)));
 
+struct ipr_hostrcb_type_24_error {
+       struct ipr_ext_vpd ioa_vpd;
+       struct ipr_ext_vpd cfc_vpd;
+       u8 reserved[2];
+       u8 exposed_mode_adn;
+#define IPR_INVALID_ARRAY_DEV_NUM              0xff
+       u8 array_id;
+       u8 last_res_path[8];
+       u8 protection_level[8];
+       struct ipr_ext_vpd array_vpd;
+       u8 description[16];
+       u8 reserved2[3];
+       u8 num_entries;
+       struct ipr_hostrcb64_array_data_entry array_member[32];
+}__attribute__((packed, aligned (4)));
+
 struct ipr_hostrcb_type_07_error {
        u8 failure_reason[64];
        struct ipr_vpd vpd;
@@ -797,6 +935,22 @@ struct ipr_hostrcb_config_element {
        __be32 wwid[2];
 }__attribute__((packed, aligned (4)));
 
+struct ipr_hostrcb64_config_element {
+       __be16 length;
+       u8 descriptor_id;
+#define IPR_DESCRIPTOR_MASK            0xC0
+#define IPR_DESCRIPTOR_SIS64           0x00
+
+       u8 reserved;
+       u8 type_status;
+
+       u8 reserved2[2];
+       u8 link_rate;
+
+       u8 res_path[8];
+       __be32 wwid[2];
+}__attribute__((packed, aligned (8)));
+
 struct ipr_hostrcb_fabric_desc {
        __be16 length;
        u8 ioa_port;
@@ -818,6 +972,20 @@ struct ipr_hostrcb_fabric_desc {
        struct ipr_hostrcb_config_element elem[1];
 }__attribute__((packed, aligned (4)));
 
+struct ipr_hostrcb64_fabric_desc {
+       __be16 length;
+       u8 descriptor_id;
+
+       u8 reserved;
+       u8 path_state;
+
+       u8 reserved2[2];
+       u8 res_path[8];
+       u8 reserved3[6];
+       __be16 num_entries;
+       struct ipr_hostrcb64_config_element elem[1];
+}__attribute__((packed, aligned (8)));
+
 #define for_each_fabric_cfg(fabric, cfg) \
                for (cfg = (fabric)->elem; \
                        cfg < ((fabric)->elem + be16_to_cpu((fabric)->num_entries)); \
@@ -830,10 +998,17 @@ struct ipr_hostrcb_type_20_error {
        struct ipr_hostrcb_fabric_desc desc[1];
 }__attribute__((packed, aligned (4)));
 
+struct ipr_hostrcb_type_30_error {
+       u8 failure_reason[64];
+       u8 reserved[3];
+       u8 num_entries;
+       struct ipr_hostrcb64_fabric_desc desc[1];
+}__attribute__((packed, aligned (4)));
+
 struct ipr_hostrcb_error {
-       __be32 failing_dev_ioasc;
-       struct ipr_res_addr failing_dev_res_addr;
-       __be32 failing_dev_res_handle;
+       __be32 fd_ioasc;
+       struct ipr_res_addr fd_res_addr;
+       __be32 fd_res_handle;
        __be32 prc;
        union {
                struct ipr_hostrcb_type_ff_error type_ff_error;
@@ -850,6 +1025,26 @@ struct ipr_hostrcb_error {
        } u;
 }__attribute__((packed, aligned (4)));
 
+struct ipr_hostrcb64_error {
+       __be32 fd_ioasc;
+       __be32 ioa_fw_level;
+       __be32 fd_res_handle;
+       __be32 prc;
+       __be64 fd_dev_id;
+       __be64 fd_lun;
+       u8 fd_res_path[8];
+       __be64 time_stamp;
+       u8 reserved[2];
+       union {
+               struct ipr_hostrcb_type_ff_error type_ff_error;
+               struct ipr_hostrcb_type_12_error type_12_error;
+               struct ipr_hostrcb_type_17_error type_17_error;
+               struct ipr_hostrcb_type_23_error type_23_error;
+               struct ipr_hostrcb_type_24_error type_24_error;
+               struct ipr_hostrcb_type_30_error type_30_error;
+       } u;
+}__attribute__((packed, aligned (8)));
+
 struct ipr_hostrcb_raw {
        __be32 data[sizeof(struct ipr_hostrcb_error)/sizeof(__be32)];
 }__attribute__((packed, aligned (4)));
@@ -887,7 +1082,11 @@ struct ipr_hcam {
 #define IPR_HOST_RCB_OVERLAY_ID_16                             0x16
 #define IPR_HOST_RCB_OVERLAY_ID_17                             0x17
 #define IPR_HOST_RCB_OVERLAY_ID_20                             0x20
-#define IPR_HOST_RCB_OVERLAY_ID_DEFAULT                        0xFF
+#define IPR_HOST_RCB_OVERLAY_ID_23                             0x23
+#define IPR_HOST_RCB_OVERLAY_ID_24                             0x24
+#define IPR_HOST_RCB_OVERLAY_ID_26                             0x26
+#define IPR_HOST_RCB_OVERLAY_ID_30                             0x30
+#define IPR_HOST_RCB_OVERLAY_ID_DEFAULT                                0xFF
 
        u8 reserved1[3];
        __be32 ilid;
@@ -897,6 +1096,7 @@ struct ipr_hcam {
 
        union {
                struct ipr_hostrcb_error error;
+               struct ipr_hostrcb64_error error64;
                struct ipr_hostrcb_cfg_ch_not ccn;
                struct ipr_hostrcb_raw raw;
        } u;
@@ -907,14 +1107,14 @@ struct ipr_hostrcb {
        dma_addr_t hostrcb_dma;
        struct list_head queue;
        struct ipr_ioa_cfg *ioa_cfg;
+       char rp_buffer[IPR_MAX_RES_PATH_LENGTH];
 };
 
 /* IPR smart dump table structures */
 struct ipr_sdt_entry {
-       __be32 bar_str_offset;
-       __be32 end_offset;
-       u8 entry_byte;
-       u8 reserved[3];
+       __be32 start_token;
+       __be32 end_token;
+       u8 reserved[4];
 
        u8 flags;
 #define IPR_SDT_ENDIAN         0x80
@@ -960,28 +1160,48 @@ struct ipr_sata_port {
 };
 
 struct ipr_resource_entry {
-       struct ipr_config_table_entry cfgte;
        u8 needs_sync_complete:1;
        u8 in_erp:1;
        u8 add_to_ml:1;
        u8 del_from_ml:1;
        u8 resetting_device:1;
 
+       u32 bus;                /* AKA channel */
+       u32 target;             /* AKA id */
+       u32 lun;
+#define IPR_ARRAY_VIRTUAL_BUS                  0x1
+#define IPR_VSET_VIRTUAL_BUS                   0x2
+#define IPR_IOAFP_VIRTUAL_BUS                  0x3
+
+#define IPR_GET_RES_PHYS_LOC(res) \
+       (((res)->bus << 24) | ((res)->target << 8) | (res)->lun)
+
+       u8 ata_class;
+
+       u8 flags;
+       __be16 res_flags;
+
+       __be32 type;
+
+       u8 qmodel;
+       struct ipr_std_inq_data std_inq_data;
+
+       __be32 res_handle;
+       __be64 dev_id;
+       struct scsi_lun dev_lun;
+       u8 res_path[8];
+
+       struct ipr_ioa_cfg *ioa_cfg;
        struct scsi_device *sdev;
        struct ipr_sata_port *sata_port;
        struct list_head queue;
-};
+}; /* struct ipr_resource_entry */
 
 struct ipr_resource_hdr {
        u16 num_entries;
        u16 reserved;
 };
 
-struct ipr_resource_table {
-       struct ipr_resource_hdr hdr;
-       struct ipr_resource_entry dev[IPR_MAX_PHYSICAL_DEVS];
-};
-
 struct ipr_misc_cbs {
        struct ipr_ioa_vpd ioa_vpd;
        struct ipr_inquiry_page0 page0_data;
@@ -994,27 +1214,51 @@ struct ipr_misc_cbs {
 struct ipr_interrupt_offsets {
        unsigned long set_interrupt_mask_reg;
        unsigned long clr_interrupt_mask_reg;
+       unsigned long clr_interrupt_mask_reg32;
        unsigned long sense_interrupt_mask_reg;
+       unsigned long sense_interrupt_mask_reg32;
        unsigned long clr_interrupt_reg;
+       unsigned long clr_interrupt_reg32;
 
        unsigned long sense_interrupt_reg;
+       unsigned long sense_interrupt_reg32;
        unsigned long ioarrin_reg;
        unsigned long sense_uproc_interrupt_reg;
+       unsigned long sense_uproc_interrupt_reg32;
        unsigned long set_uproc_interrupt_reg;
+       unsigned long set_uproc_interrupt_reg32;
        unsigned long clr_uproc_interrupt_reg;
+       unsigned long clr_uproc_interrupt_reg32;
+
+       unsigned long init_feedback_reg;
+
+       unsigned long dump_addr_reg;
+       unsigned long dump_data_reg;
 };
 
 struct ipr_interrupts {
        void __iomem *set_interrupt_mask_reg;
        void __iomem *clr_interrupt_mask_reg;
+       void __iomem *clr_interrupt_mask_reg32;
        void __iomem *sense_interrupt_mask_reg;
+       void __iomem *sense_interrupt_mask_reg32;
        void __iomem *clr_interrupt_reg;
+       void __iomem *clr_interrupt_reg32;
 
        void __iomem *sense_interrupt_reg;
+       void __iomem *sense_interrupt_reg32;
        void __iomem *ioarrin_reg;
        void __iomem *sense_uproc_interrupt_reg;
+       void __iomem *sense_uproc_interrupt_reg32;
        void __iomem *set_uproc_interrupt_reg;
+       void __iomem *set_uproc_interrupt_reg32;
        void __iomem *clr_uproc_interrupt_reg;
+       void __iomem *clr_uproc_interrupt_reg32;
+
+       void __iomem *init_feedback_reg;
+
+       void __iomem *dump_addr_reg;
+       void __iomem *dump_data_reg;
 };
 
 struct ipr_chip_cfg_t {
@@ -1029,6 +1273,9 @@ struct ipr_chip_t {
        u16 intr_type;
 #define IPR_USE_LSI                    0x00
 #define IPR_USE_MSI                    0x01
+       u16 sis_type;
+#define IPR_SIS32                      0x00
+#define IPR_SIS64                      0x01
        const struct ipr_chip_cfg_t *cfg;
 };
 
@@ -1073,13 +1320,6 @@ enum ipr_sdt_state {
        DUMP_OBTAINED
 };
 
-enum ipr_cache_state {
-       CACHE_NONE,
-       CACHE_DISABLED,
-       CACHE_ENABLED,
-       CACHE_INVALID
-};
-
 /* Per-controller data */
 struct ipr_ioa_cfg {
        char eye_catcher[8];
@@ -1099,10 +1339,17 @@ struct ipr_ioa_cfg {
        u8 dual_raid:1;
        u8 needs_warm_reset:1;
        u8 msi_received:1;
+       u8 sis64:1;
 
        u8 revid;
 
-       enum ipr_cache_state cache_state;
+       /*
+        * Bitmaps for SIS64 generated target values
+        */
+       unsigned long *target_ids;
+       unsigned long *array_ids;
+       unsigned long *vset_ids;
+
        u16 type; /* CCIN of the card */
 
        u8 log_level;
@@ -1133,8 +1380,13 @@ struct ipr_ioa_cfg {
 
        char cfg_table_start[8];
 #define IPR_CFG_TBL_START              "cfg"
-       struct ipr_config_table *cfg_table;
+       union {
+               struct ipr_config_table *cfg_table;
+               struct ipr_config_table64 *cfg_table64;
+       } u;
        dma_addr_t cfg_table_dma;
+       u32 cfg_table_size;
+       u32 max_devs_supported;
 
        char resource_table_label[8];
 #define IPR_RES_TABLE_LABEL            "res_tbl"
@@ -1202,13 +1454,17 @@ struct ipr_ioa_cfg {
        char ipr_cmd_label[8];
 #define IPR_CMD_LABEL          "ipr_cmd"
        struct ipr_cmnd *ipr_cmnd_list[IPR_NUM_CMD_BLKS];
-       u32 ipr_cmnd_list_dma[IPR_NUM_CMD_BLKS];
-};
+       dma_addr_t ipr_cmnd_list_dma[IPR_NUM_CMD_BLKS];
+}; /* struct ipr_ioa_cfg */
 
 struct ipr_cmnd {
        struct ipr_ioarcb ioarcb;
+       union {
+               struct ipr_ioadl_desc ioadl[IPR_NUM_IOADL_ENTRIES];
+               struct ipr_ioadl64_desc ioadl64[IPR_NUM_IOADL_ENTRIES];
+               struct ipr_ata64_ioadl ata_ioadl;
+       } i;
        struct ipr_ioasa ioasa;
-       struct ipr_ioadl_desc ioadl[IPR_NUM_IOADL_ENTRIES];
        struct list_head queue;
        struct scsi_cmnd *scsi_cmd;
        struct ata_queued_cmd *qc;
@@ -1221,7 +1477,7 @@ struct ipr_cmnd {
        u8 sense_buffer[SCSI_SENSE_BUFFERSIZE];
        dma_addr_t sense_buffer_dma;
        unsigned short dma_use_sg;
-       dma_addr_t dma_handle;
+       dma_addr_t dma_addr;
        struct ipr_cmnd *sibling;
        union {
                enum ipr_shutdown_type shutdown_type;
@@ -1314,8 +1570,6 @@ struct ipr_ioa_dump {
        u32 next_page_index;
        u32 page_offset;
        u32 format;
-#define IPR_SDT_FMT2           2
-#define IPR_SDT_UNKNOWN                3
 }__attribute__((packed, aligned (4)));
 
 struct ipr_dump {
@@ -1377,6 +1631,13 @@ struct ipr_ucode_image_header {
 #define ipr_info(...) printk(KERN_INFO IPR_NAME ": "__VA_ARGS__)
 #define ipr_dbg(...) IPR_DBG_CMD(printk(KERN_INFO IPR_NAME ": "__VA_ARGS__))
 
+#define ipr_res_printk(level, ioa_cfg, bus, target, lun, fmt, ...) \
+       printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, (ioa_cfg)->host->host_no, \
+               bus, target, lun, ##__VA_ARGS__)
+
+#define ipr_res_err(ioa_cfg, res, fmt, ...) \
+       ipr_res_printk(KERN_ERR, ioa_cfg, (res)->bus, (res)->target, (res)->lun, fmt, ##__VA_ARGS__)
+
 #define ipr_ra_printk(level, ioa_cfg, ra, fmt, ...) \
        printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, (ioa_cfg)->host->host_no, \
                (ra).bus, (ra).target, (ra).lun, ##__VA_ARGS__)
@@ -1384,9 +1645,6 @@ struct ipr_ucode_image_header {
 #define ipr_ra_err(ioa_cfg, ra, fmt, ...) \
        ipr_ra_printk(KERN_ERR, ioa_cfg, ra, fmt, ##__VA_ARGS__)
 
-#define ipr_res_err(ioa_cfg, res, fmt, ...) \
-       ipr_ra_err(ioa_cfg, (res)->cfgte.res_addr, fmt, ##__VA_ARGS__)
-
 #define ipr_phys_res_err(ioa_cfg, res, fmt, ...)                       \
 {                                                                      \
        if ((res).bus >= IPR_MAX_NUM_BUSES) {                           \
@@ -1399,14 +1657,21 @@ struct ipr_ucode_image_header {
 }
 
 #define ipr_hcam_err(hostrcb, fmt, ...)                                        \
-{                                                                                                      \
-       if (ipr_is_device(&(hostrcb)->hcam.u.error.failing_dev_res_addr)) {             \
-               ipr_ra_err((hostrcb)->ioa_cfg,                                                  \
-                               (hostrcb)->hcam.u.error.failing_dev_res_addr,                   \
-                               fmt, ##__VA_ARGS__);                                                    \
-       } else {                                                                                        \
-               dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, ##__VA_ARGS__);            \
-       }                                                                                               \
+{                                                                      \
+       if (ipr_is_device(hostrcb)) {                                   \
+               if ((hostrcb)->ioa_cfg->sis64) {                        \
+                       printk(KERN_ERR IPR_NAME ": %s: " fmt,          \
+                               ipr_format_resource_path(&hostrcb->hcam.u.error64.fd_res_path[0], \
+                                       &hostrcb->rp_buffer[0]),        \
+                               __VA_ARGS__);                           \
+               } else {                                                \
+                       ipr_ra_err((hostrcb)->ioa_cfg,                  \
+                               (hostrcb)->hcam.u.error.fd_res_addr,    \
+                               fmt, __VA_ARGS__);                      \
+               }                                                       \
+       } else {                                                        \
+               dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, __VA_ARGS__); \
+       }                                                               \
 }
 
 #define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\
@@ -1432,7 +1697,7 @@ ipr_err("----------------------------------------------------------\n")
  **/
 static inline int ipr_is_ioa_resource(struct ipr_resource_entry *res)
 {
-       return (res->cfgte.flags & IPR_IS_IOA_RESOURCE) ? 1 : 0;
+       return res->type == IPR_RES_TYPE_IOAFP;
 }
 
 /**
@@ -1444,12 +1709,8 @@ static inline int ipr_is_ioa_resource(struct ipr_resource_entry *res)
  **/
 static inline int ipr_is_af_dasd_device(struct ipr_resource_entry *res)
 {
-       if (IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data) &&
-           !ipr_is_ioa_resource(res) &&
-           IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_AF_DASD)
-               return 1;
-       else
-               return 0;
+       return res->type == IPR_RES_TYPE_AF_DASD ||
+               res->type == IPR_RES_TYPE_REMOTE_AF_DASD;
 }
 
 /**
@@ -1461,12 +1722,7 @@ static inline int ipr_is_af_dasd_device(struct ipr_resource_entry *res)
  **/
 static inline int ipr_is_vset_device(struct ipr_resource_entry *res)
 {
-       if (IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data) &&
-           !ipr_is_ioa_resource(res) &&
-           IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_VOLUME_SET)
-               return 1;
-       else
-               return 0;
+       return res->type == IPR_RES_TYPE_VOLUME_SET;
 }
 
 /**
@@ -1478,11 +1734,7 @@ static inline int ipr_is_vset_device(struct ipr_resource_entry *res)
  **/
 static inline int ipr_is_gscsi(struct ipr_resource_entry *res)
 {
-       if (!ipr_is_ioa_resource(res) &&
-           IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_GENERIC_SCSI)
-               return 1;
-       else
-               return 0;
+       return res->type == IPR_RES_TYPE_GENERIC_SCSI;
 }
 
 /**
@@ -1495,7 +1747,7 @@ static inline int ipr_is_gscsi(struct ipr_resource_entry *res)
 static inline int ipr_is_scsi_disk(struct ipr_resource_entry *res)
 {
        if (ipr_is_af_dasd_device(res) ||
-           (ipr_is_gscsi(res) && IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data)))
+           (ipr_is_gscsi(res) && IPR_IS_DASD_DEVICE(res->std_inq_data)))
                return 1;
        else
                return 0;
@@ -1510,11 +1762,7 @@ static inline int ipr_is_scsi_disk(struct ipr_resource_entry *res)
  **/
 static inline int ipr_is_gata(struct ipr_resource_entry *res)
 {
-       if (!ipr_is_ioa_resource(res) &&
-           IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_GENERIC_ATA)
-               return 1;
-       else
-               return 0;
+       return res->type == IPR_RES_TYPE_GENERIC_ATA;
 }
 
 /**
@@ -1526,24 +1774,35 @@ static inline int ipr_is_gata(struct ipr_resource_entry *res)
  **/
 static inline int ipr_is_naca_model(struct ipr_resource_entry *res)
 {
-       if (ipr_is_gscsi(res) && IPR_QUEUEING_MODEL(res) == IPR_QUEUE_NACA_MODEL)
+       if (ipr_is_gscsi(res) && res->qmodel == IPR_QUEUE_NACA_MODEL)
                return 1;
        return 0;
 }
 
 /**
- * ipr_is_device - Determine if resource address is that of a device
- * @res_addr:  resource address struct
+ * ipr_is_device - Determine if the hostrcb structure is related to a device
+ * @hostrcb:   host resource control blocks struct
  *
  * Return value:
  *     1 if AF / 0 if not AF
  **/
-static inline int ipr_is_device(struct ipr_res_addr *res_addr)
+static inline int ipr_is_device(struct ipr_hostrcb *hostrcb)
 {
-       if ((res_addr->bus < IPR_MAX_NUM_BUSES) &&
-           (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1)))
-               return 1;
-
+       struct ipr_res_addr *res_addr;
+       u8 *res_path;
+
+       if (hostrcb->ioa_cfg->sis64) {
+               res_path = &hostrcb->hcam.u.error64.fd_res_path[0];
+               if ((res_path[0] == 0x00 || res_path[0] == 0x80 ||
+                   res_path[0] == 0x81) && res_path[2] != 0xFF)
+                       return 1;
+       } else {
+               res_addr = &hostrcb->hcam.u.error.fd_res_addr;
+
+               if ((res_addr->bus < IPR_MAX_NUM_BUSES) &&
+                   (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1)))
+                       return 1;
+       }
        return 0;
 }
 
index 8a89ba9005881b9bd07a5e46d85346161cc7d9a4..02143af7c1af6234a27d416b6e5e8a3df370c057 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <linux/types.h>
 #include <linux/inet.h>
+#include <linux/slab.h>
 #include <linux/file.h>
 #include <linux/blkdev.h>
 #include <linux/crypto.h>
@@ -598,7 +599,7 @@ static void iscsi_sw_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
        set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
        write_unlock_bh(&tcp_sw_conn->sock->sk->sk_callback_lock);
 
-       if (sock->sk->sk_sleep && waitqueue_active(sock->sk->sk_sleep)) {
+       if (sock->sk->sk_sleep) {
                sock->sk->sk_err = EIO;
                wake_up_interruptible(sock->sk->sk_sleep);
        }
@@ -874,7 +875,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = {
        .cmd_per_lun            = ISCSI_DEF_CMD_PER_LUN,
        .eh_abort_handler       = iscsi_eh_abort,
        .eh_device_reset_handler= iscsi_eh_device_reset,
-       .eh_target_reset_handler= iscsi_eh_target_reset,
+       .eh_target_reset_handler = iscsi_eh_recover_target,
        .use_clustering         = DISABLE_CLUSTERING,
        .slave_alloc            = iscsi_sw_tcp_slave_alloc,
        .slave_configure        = iscsi_sw_tcp_slave_configure,
index b2d481dd37505f43f25d9c0cc79659e900bb25ca..08e26d4e3731c4d35dd010317b4d642947dbbc51 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/init.h>
index b3d31315ac32daea6321968eedca52cb921ade3a..23880f8fe7e4fccb985997d782fce852b916ed54 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/blkdev.h>
 #include <linux/ioport.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
index 9b0a5192a965d94552396d9ccac680892c795921..1087a7f18e845d9b1bafd8b7ba26b34581645f27 100644 (file)
@@ -33,6 +33,7 @@
  */
 
 #include <linux/timer.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <asm/unaligned.h>
 
index 7f4364770e4a5b90050e28fbc5cbe8fb634e8e88..e5df0d4db67ed7190e5d6a5c6d4e178cd039bc42 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include <linux/timer.h>
-#include <linux/gfp.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 
 #include <scsi/fc/fc_fc2.h>
index 774e7ac837a593ba69d2bf6be41f7a660a129a60..17396c708b0807aaf57f36fda331c6045f1a4411 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/scatterlist.h>
 #include <linux/err.h>
 #include <linux/crc32.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi.h>
index 6da01c6169641ee882df5f56359b474485abef30..981329a17c488384491ee1bc31169586635ba85c 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 #include <linux/crc32.h>
+#include <linux/gfp.h>
 
 #include <scsi/fc_frame.h>
 
index 7ec8ce75007c06ba4bcbe02b3dd81071818c394e..d126ecfff70484ea49908f1cde4e8d007a64bbb8 100644 (file)
@@ -88,6 +88,7 @@
  */
 
 #include <linux/timer.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 #include <scsi/fc/fc_gs.h>
index 97923bb07765e60cc43c121666c0e9b19a4734fb..b37d0ff28b352c380f5359bfe0e1b6e72faf7cfd 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/rcupdate.h>
 #include <linux/timer.h>
 #include <linux/workqueue.h>
index 703eb6a88790280c788b9fb88ce331d15ff282e1..633e09036357828b87e1df84dacec85beda24492 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/kfifo.h>
 #include <linux/delay.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include <net/tcp.h>
 #include <scsi/scsi_cmnd.h>
@@ -470,12 +471,12 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
 
        WARN_ON(hdrlength >= 256);
        hdr->hlength = hdrlength & 0xFF;
+       hdr->cmdsn = task->cmdsn = cpu_to_be32(session->cmdsn);
 
        if (session->tt->init_task && session->tt->init_task(task))
                return -EIO;
 
        task->state = ISCSI_TASK_RUNNING;
-       hdr->cmdsn = task->cmdsn = cpu_to_be32(session->cmdsn);
        session->cmdsn++;
 
        conn->scsicmd_pdus_cnt++;
@@ -2338,7 +2339,7 @@ EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout);
  * This function will wait for a relogin, session termination from
  * userspace, or a recovery/replacement timeout.
  */
-static int iscsi_eh_session_reset(struct scsi_cmnd *sc)
+int iscsi_eh_session_reset(struct scsi_cmnd *sc)
 {
        struct iscsi_cls_session *cls_session;
        struct iscsi_session *session;
@@ -2389,6 +2390,7 @@ failed:
        mutex_unlock(&session->eh_mutex);
        return SUCCESS;
 }
+EXPORT_SYMBOL_GPL(iscsi_eh_session_reset);
 
 static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr)
 {
@@ -2403,8 +2405,7 @@ static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr)
  * iscsi_eh_target_reset - reset target
  * @sc: scsi command
  *
- * This will attempt to send a warm target reset. If that fails
- * then we will drop the session and attempt ERL0 recovery.
+ * This will attempt to send a warm target reset.
  */
 int iscsi_eh_target_reset(struct scsi_cmnd *sc)
 {
@@ -2476,12 +2477,27 @@ done:
        ISCSI_DBG_EH(session, "tgt %s reset result = %s\n", session->targetname,
                     rc == SUCCESS ? "SUCCESS" : "FAILED");
        mutex_unlock(&session->eh_mutex);
+       return rc;
+}
+EXPORT_SYMBOL_GPL(iscsi_eh_target_reset);
+
+/**
+ * iscsi_eh_recover_target - reset target and possibly the session
+ * @sc: scsi command
+ *
+ * This will attempt to send a warm target reset. If that fails,
+ * we will escalate to ERL0 session recovery.
+ */
+int iscsi_eh_recover_target(struct scsi_cmnd *sc)
+{
+       int rc;
 
+       rc = iscsi_eh_target_reset(sc);
        if (rc == FAILED)
                rc = iscsi_eh_session_reset(sc);
        return rc;
 }
-EXPORT_SYMBOL_GPL(iscsi_eh_target_reset);
+EXPORT_SYMBOL_GPL(iscsi_eh_recover_target);
 
 /*
  * Pre-allocate a pool of @max items of @item_size. By default, the pool
@@ -3072,14 +3088,15 @@ static void iscsi_start_session_recovery(struct iscsi_session *session,
                session->state = ISCSI_STATE_TERMINATE;
        else if (conn->stop_stage != STOP_CONN_RECOVER)
                session->state = ISCSI_STATE_IN_RECOVERY;
+
+       old_stop_stage = conn->stop_stage;
+       conn->stop_stage = flag;
        spin_unlock_bh(&session->lock);
 
        del_timer_sync(&conn->transport_timer);
        iscsi_suspend_tx(conn);
 
        spin_lock_bh(&session->lock);
-       old_stop_stage = conn->stop_stage;
-       conn->stop_stage = flag;
        conn->c_stage = ISCSI_CONN_STOPPED;
        spin_unlock_bh(&session->lock);
 
index 4ad87fd74ddd926be593e684ca3d9c0f37bb9917..5c92620292fba3b6e35076f366db1b338228c9a4 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/inet.h>
+#include <linux/slab.h>
 #include <linux/file.h>
 #include <linux/blkdev.h>
 #include <linux/crypto.h>
index e15501170698a19957d22f92c6fbc2e3e89ac0c6..88f7446725764b42a4d1eb7c54153605ea5dc9b8 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 #include <scsi/sas_ata.h>
 #include "sas_internal.h"
@@ -394,11 +395,15 @@ int sas_ata_init_host_and_port(struct domain_device *found_dev,
 void sas_ata_task_abort(struct sas_task *task)
 {
        struct ata_queued_cmd *qc = task->uldd_task;
+       struct request_queue *q = qc->scsicmd->device->request_queue;
        struct completion *waiting;
+       unsigned long flags;
 
        /* Bounce SCSI-initiated commands to the SCSI EH */
        if (qc->scsicmd) {
+               spin_lock_irqsave(q->queue_lock, flags);
                blk_abort_request(qc->scsicmd->request);
+               spin_unlock_irqrestore(q->queue_lock, flags);
                scsi_schedule_eh(qc->scsicmd->device->host);
                return;
        }
index facc5bfcf7db673ae9f994a6e2c5deb1507bcd9a..f5831930df9bd31e540516b792673f8fd7ce5ab5 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_eh.h>
 #include "sas_internal.h"
index 33cf988c8c8a2cd25548ce5be0f67d97ee58e997..c65af02dcfe832f59ff2a8f5ff05b4c18b8d7323 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/scatterlist.h>
 #include <linux/blkdev.h>
+#include <linux/slab.h>
 
 #include "sas_internal.h"
 
index 1bc3b75679947ac1d8bcca33d132835cf16854f8..04ad8dd1a74cf8267982e29a551efd1503a5ef1c 100644 (file)
@@ -10,6 +10,7 @@
  */
 #include <linux/scatterlist.h>
 #include <linux/blkdev.h>
+#include <linux/slab.h>
 
 #include "sas_internal.h"
 
index 9cd5abe9e714e3f243ffddce6cda0500f3257f92..2dc55343f671f6c7b4fa681278233c85c3db314e 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/spinlock.h>
index 14b13196b22d0ab57619a51e1c4753d525a6144a..822835055cef3cc3c0fe9e9d9c6cbd2d7a17c4d4 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/err.h>
 #include <linux/blkdev.h>
 #include <linux/freezer.h>
+#include <linux/gfp.h>
 #include <linux/scatterlist.h>
 #include <linux/libata.h>
 
@@ -1029,6 +1030,8 @@ int __sas_task_abort(struct sas_task *task)
 void sas_task_abort(struct sas_task *task)
 {
        struct scsi_cmnd *sc = task->uldd_task;
+       struct request_queue *q = sc->device->request_queue;
+       unsigned long flags;
 
        /* Escape for libsas internal commands */
        if (!sc) {
@@ -1043,7 +1046,9 @@ void sas_task_abort(struct sas_task *task)
                return;
        }
 
+       spin_lock_irqsave(q->queue_lock, flags);
        blk_abort_request(sc->request);
+       spin_unlock_irqrestore(q->queue_lock, flags);
        scsi_schedule_eh(sc->device->host);
 }
 
index 22775165bf6ad79371b72db2055ee5e93a465d23..ff6a28ce9b6900f647145120830cb7de96b439b7 100644 (file)
@@ -19,6 +19,7 @@
  * 02110-1301 USA
  */
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/kfifo.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
index 84b696463a585a684cc5055572a7953bb03da5f8..565e16dd74fc47778babc6b752f49ce405809018 100644 (file)
@@ -37,6 +37,9 @@ struct lpfc_sli2_slim;
                                           the NameServer  before giving up. */
 #define LPFC_CMD_PER_LUN       3       /* max outstanding cmds per lun */
 #define LPFC_DEFAULT_SG_SEG_CNT 64     /* sg element count per scsi cmnd */
+#define LPFC_DEFAULT_MENLO_SG_SEG_CNT 128      /* sg element count per scsi
+               cmnd for menlo needs nearly twice as for firmware
+               downloads using bsg */
 #define LPFC_DEFAULT_PROT_SG_SEG_CNT 4096 /* sg protection elements count */
 #define LPFC_MAX_SG_SEG_CNT    4096    /* sg element count per scsi cmnd */
 #define LPFC_MAX_PROT_SG_SEG_CNT 4096  /* prot sg element count per scsi cmd*/
@@ -509,7 +512,6 @@ struct lpfc_hba {
        int (*lpfc_hba_down_link)
                (struct lpfc_hba *);
 
-
        /* SLI4 specific HBA data structure */
        struct lpfc_sli4_hba sli4_hba;
 
@@ -623,6 +625,9 @@ struct lpfc_hba {
        uint32_t cfg_log_verbose;
        uint32_t cfg_aer_support;
        uint32_t cfg_suppress_link_up;
+#define LPFC_INITIALIZE_LINK              0    /* do normal init_link mbox */
+#define LPFC_DELAY_INIT_LINK              1    /* layered driver hold off */
+#define LPFC_DELAY_INIT_LINK_INDEFINITELY 2    /* wait, manual intervention */
 
        lpfc_vpd_t vpd;         /* vital product data */
 
@@ -804,6 +809,9 @@ struct lpfc_hba {
        struct list_head ct_ev_waiters;
        struct unsol_rcv_ct_ctx ct_ctx[64];
        uint32_t ctx_idx;
+
+       uint8_t menlo_flag;     /* menlo generic flags */
+#define HBA_MENLO_SUPPORT      0x1 /* HBA supports menlo commands */
 };
 
 static inline struct Scsi_Host *
index c992e8328f9e4a5fe6bd6bc428c89a819034e7c0..1849e33e68f91ef5facd2bfa23bc6037d952450b 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/aer.h>
+#include <linux/gfp.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
@@ -1939,7 +1940,9 @@ static DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO,
 #            0x2  = never bring up link
 # Default value is 0.
 */
-LPFC_ATTR_R(suppress_link_up, 0, 0, 2, "Suppress Link Up at initialization");
+LPFC_ATTR_R(suppress_link_up, LPFC_INITIALIZE_LINK, LPFC_INITIALIZE_LINK,
+               LPFC_DELAY_INIT_LINK_INDEFINITELY,
+               "Suppress Link Up at initialization");
 
 /*
 # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
@@ -1966,8 +1969,7 @@ lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr,
 {
        struct Scsi_Host  *shost = class_to_shost(dev);
        struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
-       int val = 0;
-       val = vport->cfg_devloss_tmo;
+
        return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo);
 }
 
index f3f1bf1a0a719e24c93962f1d2fc4e5e98fb340b..d62b3e46792656e378bc768615faf5d089ada1f6 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/mempool.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 
 #include <scsi/scsi.h>
@@ -83,15 +84,28 @@ struct lpfc_bsg_mbox {
        struct fc_bsg_job *set_job;
 };
 
+#define MENLO_DID 0x0000FC0E
+
+struct lpfc_bsg_menlo {
+       struct lpfc_iocbq *cmdiocbq;
+       struct lpfc_iocbq *rspiocbq;
+       struct lpfc_dmabuf *bmp;
+
+       /* job waiting for this iocb to finish */
+       struct fc_bsg_job *set_job;
+};
+
 #define TYPE_EVT       1
 #define TYPE_IOCB      2
 #define TYPE_MBOX      3
+#define TYPE_MENLO     4
 struct bsg_job_data {
        uint32_t type;
        union {
                struct lpfc_bsg_event *evt;
                struct lpfc_bsg_iocb iocb;
                struct lpfc_bsg_mbox mbox;
+               struct lpfc_bsg_menlo menlo;
        } context_un;
 };
 
@@ -419,7 +433,7 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
        dd_data = cmdiocbq->context1;
        /* normal completion and timeout crossed paths, already done */
        if (!dd_data) {
-               spin_unlock_irqrestore(&phba->hbalock, flags);
+               spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
                return;
        }
 
@@ -1182,7 +1196,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
        dd_data = cmdiocbq->context1;
        /* normal completion and timeout crossed paths, already done */
        if (!dd_data) {
-               spin_unlock_irqrestore(&phba->hbalock, flags);
+               spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
                return;
        }
 
@@ -2456,6 +2470,18 @@ static int lpfc_bsg_check_cmd_access(struct lpfc_hba *phba,
        case MBX_PORT_IOV_CONTROL:
                break;
        case MBX_SET_VARIABLE:
+               lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+                       "1226 mbox: set_variable 0x%x, 0x%x\n",
+                       mb->un.varWords[0],
+                       mb->un.varWords[1]);
+               if ((mb->un.varWords[0] == SETVAR_MLOMNT)
+                       && (mb->un.varWords[1] == 1)) {
+                       phba->wait_4_mlo_maint_flg = 1;
+               } else if (mb->un.varWords[0] == SETVAR_MLORST) {
+                       phba->link_flag &= ~LS_LOOPBACK_MODE;
+                       phba->fc_topology = TOPOLOGY_PT_PT;
+               }
+               break;
        case MBX_RUN_BIU_DIAG64:
        case MBX_READ_EVENT_LOG:
        case MBX_READ_SPARM64:
@@ -2637,6 +2663,297 @@ job_error:
        return rc;
 }
 
+/**
+ * lpfc_bsg_menlo_cmd_cmp - lpfc_menlo_cmd completion handler
+ * @phba: Pointer to HBA context object.
+ * @cmdiocbq: Pointer to command iocb.
+ * @rspiocbq: Pointer to response iocb.
+ *
+ * This function is the completion handler for iocbs issued using
+ * lpfc_menlo_cmd function. This function is called by the
+ * ring event handler function without any lock held. This function
+ * can be called from both worker thread context and interrupt
+ * context. This function also can be called from another thread which
+ * cleans up the SLI layer objects.
+ * This function copies the contents of the response iocb to the
+ * response iocb memory object provided by the caller of
+ * lpfc_sli_issue_iocb_wait and then wakes up the thread which
+ * sleeps for the iocb completion.
+ **/
+static void
+lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
+                       struct lpfc_iocbq *cmdiocbq,
+                       struct lpfc_iocbq *rspiocbq)
+{
+       struct bsg_job_data *dd_data;
+       struct fc_bsg_job *job;
+       IOCB_t *rsp;
+       struct lpfc_dmabuf *bmp;
+       struct lpfc_bsg_menlo *menlo;
+       unsigned long flags;
+       struct menlo_response *menlo_resp;
+       int rc = 0;
+
+       spin_lock_irqsave(&phba->ct_ev_lock, flags);
+       dd_data = cmdiocbq->context1;
+       if (!dd_data) {
+               spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+               return;
+       }
+
+       menlo = &dd_data->context_un.menlo;
+       job = menlo->set_job;
+       job->dd_data = NULL; /* so timeout handler does not reply */
+
+       spin_lock_irqsave(&phba->hbalock, flags);
+       cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
+       if (cmdiocbq->context2 && rspiocbq)
+               memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
+                      &rspiocbq->iocb, sizeof(IOCB_t));
+       spin_unlock_irqrestore(&phba->hbalock, flags);
+
+       bmp = menlo->bmp;
+       rspiocbq = menlo->rspiocbq;
+       rsp = &rspiocbq->iocb;
+
+       pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
+                    job->request_payload.sg_cnt, DMA_TO_DEVICE);
+       pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
+                    job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+
+       /* always return the xri, this would be used in the case
+        * of a menlo download to allow the data to be sent as a continuation
+        * of the exchange.
+        */
+       menlo_resp = (struct menlo_response *)
+               job->reply->reply_data.vendor_reply.vendor_rsp;
+       menlo_resp->xri = rsp->ulpContext;
+       if (rsp->ulpStatus) {
+               if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
+                       switch (rsp->un.ulpWord[4] & 0xff) {
+                       case IOERR_SEQUENCE_TIMEOUT:
+                               rc = -ETIMEDOUT;
+                               break;
+                       case IOERR_INVALID_RPI:
+                               rc = -EFAULT;
+                               break;
+                       default:
+                               rc = -EACCES;
+                               break;
+                       }
+               } else
+                       rc = -EACCES;
+       } else
+               job->reply->reply_payload_rcv_len =
+                       rsp->un.genreq64.bdl.bdeSize;
+
+       lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
+       lpfc_sli_release_iocbq(phba, rspiocbq);
+       lpfc_sli_release_iocbq(phba, cmdiocbq);
+       kfree(bmp);
+       kfree(dd_data);
+       /* make error code available to userspace */
+       job->reply->result = rc;
+       /* complete the job back to userspace */
+       job->job_done(job);
+       spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+       return;
+}
+
+/**
+ * lpfc_menlo_cmd - send an ioctl for menlo hardware
+ * @job: fc_bsg_job to handle
+ *
+ * This function issues a gen request 64 CR ioctl for all menlo cmd requests,
+ * all the command completions will return the xri for the command.
+ * For menlo data requests a gen request 64 CX is used to continue the exchange
+ * supplied in the menlo request header xri field.
+ **/
+static int
+lpfc_menlo_cmd(struct fc_bsg_job *job)
+{
+       struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+       struct lpfc_hba *phba = vport->phba;
+       struct lpfc_iocbq *cmdiocbq, *rspiocbq;
+       IOCB_t *cmd, *rsp;
+       int rc = 0;
+       struct menlo_command *menlo_cmd;
+       struct menlo_response *menlo_resp;
+       struct lpfc_dmabuf *bmp = NULL;
+       int request_nseg;
+       int reply_nseg;
+       struct scatterlist *sgel = NULL;
+       int numbde;
+       dma_addr_t busaddr;
+       struct bsg_job_data *dd_data;
+       struct ulp_bde64 *bpl = NULL;
+
+       /* in case no data is returned return just the return code */
+       job->reply->reply_payload_rcv_len = 0;
+
+       if (job->request_len <
+           sizeof(struct fc_bsg_request) +
+               sizeof(struct menlo_command)) {
+               lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+                               "2784 Received MENLO_CMD request below "
+                               "minimum size\n");
+               rc = -ERANGE;
+               goto no_dd_data;
+       }
+
+       if (job->reply_len <
+           sizeof(struct fc_bsg_request) + sizeof(struct menlo_response)) {
+               lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+                               "2785 Received MENLO_CMD reply below "
+                               "minimum size\n");
+               rc = -ERANGE;
+               goto no_dd_data;
+       }
+
+       if (!(phba->menlo_flag & HBA_MENLO_SUPPORT)) {
+               lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+                               "2786 Adapter does not support menlo "
+                               "commands\n");
+               rc = -EPERM;
+               goto no_dd_data;
+       }
+
+       menlo_cmd = (struct menlo_command *)
+               job->request->rqst_data.h_vendor.vendor_cmd;
+
+       menlo_resp = (struct menlo_response *)
+               job->reply->reply_data.vendor_reply.vendor_rsp;
+
+       /* allocate our bsg tracking structure */
+       dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
+       if (!dd_data) {
+               lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+                               "2787 Failed allocation of dd_data\n");
+               rc = -ENOMEM;
+               goto no_dd_data;
+       }
+
+       bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+       if (!bmp) {
+               rc = -ENOMEM;
+               goto free_dd;
+       }
+
+       cmdiocbq = lpfc_sli_get_iocbq(phba);
+       if (!cmdiocbq) {
+               rc = -ENOMEM;
+               goto free_bmp;
+       }
+
+       rspiocbq = lpfc_sli_get_iocbq(phba);
+       if (!rspiocbq) {
+               rc = -ENOMEM;
+               goto free_cmdiocbq;
+       }
+
+       rsp = &rspiocbq->iocb;
+
+       bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys);
+       if (!bmp->virt) {
+               rc = -ENOMEM;
+               goto free_rspiocbq;
+       }
+
+       INIT_LIST_HEAD(&bmp->list);
+       bpl = (struct ulp_bde64 *) bmp->virt;
+       request_nseg = pci_map_sg(phba->pcidev, job->request_payload.sg_list,
+                                 job->request_payload.sg_cnt, DMA_TO_DEVICE);
+       for_each_sg(job->request_payload.sg_list, sgel, request_nseg, numbde) {
+               busaddr = sg_dma_address(sgel);
+               bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+               bpl->tus.f.bdeSize = sg_dma_len(sgel);
+               bpl->tus.w = cpu_to_le32(bpl->tus.w);
+               bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr));
+               bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr));
+               bpl++;
+       }
+
+       reply_nseg = pci_map_sg(phba->pcidev, job->reply_payload.sg_list,
+                               job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+       for_each_sg(job->reply_payload.sg_list, sgel, reply_nseg, numbde) {
+               busaddr = sg_dma_address(sgel);
+               bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I;
+               bpl->tus.f.bdeSize = sg_dma_len(sgel);
+               bpl->tus.w = cpu_to_le32(bpl->tus.w);
+               bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr));
+               bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr));
+               bpl++;
+       }
+
+       cmd = &cmdiocbq->iocb;
+       cmd->un.genreq64.bdl.ulpIoTag32 = 0;
+       cmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
+       cmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
+       cmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
+       cmd->un.genreq64.bdl.bdeSize =
+           (request_nseg + reply_nseg) * sizeof(struct ulp_bde64);
+       cmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
+       cmd->un.genreq64.w5.hcsw.Dfctl = 0;
+       cmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CMD;
+       cmd->un.genreq64.w5.hcsw.Type = MENLO_TRANSPORT_TYPE; /* 0xfe */
+       cmd->ulpBdeCount = 1;
+       cmd->ulpClass = CLASS3;
+       cmd->ulpOwner = OWN_CHIP;
+       cmd->ulpLe = 1; /* Limited Edition */
+       cmdiocbq->iocb_flag |= LPFC_IO_LIBDFC;
+       cmdiocbq->vport = phba->pport;
+       /* We want the firmware to timeout before we do */
+       cmd->ulpTimeout = MENLO_TIMEOUT - 5;
+       cmdiocbq->context3 = bmp;
+       cmdiocbq->context2 = rspiocbq;
+       cmdiocbq->iocb_cmpl = lpfc_bsg_menlo_cmd_cmp;
+       cmdiocbq->context1 = dd_data;
+       cmdiocbq->context2 = rspiocbq;
+       if (menlo_cmd->cmd == LPFC_BSG_VENDOR_MENLO_CMD) {
+               cmd->ulpCommand = CMD_GEN_REQUEST64_CR;
+               cmd->ulpPU = MENLO_PU; /* 3 */
+               cmd->un.ulpWord[4] = MENLO_DID; /* 0x0000FC0E */
+               cmd->ulpContext = MENLO_CONTEXT; /* 0 */
+       } else {
+               cmd->ulpCommand = CMD_GEN_REQUEST64_CX;
+               cmd->ulpPU = 1;
+               cmd->un.ulpWord[4] = 0;
+               cmd->ulpContext = menlo_cmd->xri;
+       }
+
+       dd_data->type = TYPE_MENLO;
+       dd_data->context_un.menlo.cmdiocbq = cmdiocbq;
+       dd_data->context_un.menlo.rspiocbq = rspiocbq;
+       dd_data->context_un.menlo.set_job = job;
+       dd_data->context_un.menlo.bmp = bmp;
+
+       rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq,
+               MENLO_TIMEOUT - 5);
+       if (rc == IOCB_SUCCESS)
+               return 0; /* done for now */
+
+       /* iocb failed so cleanup */
+       pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
+                    job->request_payload.sg_cnt, DMA_TO_DEVICE);
+       pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
+                    job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+
+       lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
+
+free_rspiocbq:
+       lpfc_sli_release_iocbq(phba, rspiocbq);
+free_cmdiocbq:
+       lpfc_sli_release_iocbq(phba, cmdiocbq);
+free_bmp:
+       kfree(bmp);
+free_dd:
+       kfree(dd_data);
+no_dd_data:
+       /* make error code available to userspace */
+       job->reply->result = rc;
+       job->dd_data = NULL;
+       return rc;
+}
 /**
  * lpfc_bsg_hst_vendor - process a vendor-specific fc_bsg_job
  * @job: fc_bsg_job to handle
@@ -2669,6 +2986,10 @@ lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
        case LPFC_BSG_VENDOR_MBOX:
                rc = lpfc_bsg_mbox_cmd(job);
                break;
+       case LPFC_BSG_VENDOR_MENLO_CMD:
+       case LPFC_BSG_VENDOR_MENLO_DATA:
+               rc = lpfc_menlo_cmd(job);
+               break;
        default:
                rc = -EINVAL;
                job->reply->reply_payload_rcv_len = 0;
@@ -2728,6 +3049,7 @@ lpfc_bsg_timeout(struct fc_bsg_job *job)
        struct lpfc_bsg_event *evt;
        struct lpfc_bsg_iocb *iocb;
        struct lpfc_bsg_mbox *mbox;
+       struct lpfc_bsg_menlo *menlo;
        struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
        struct bsg_job_data *dd_data;
        unsigned long flags;
@@ -2775,6 +3097,17 @@ lpfc_bsg_timeout(struct fc_bsg_job *job)
                spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
                job->job_done(job);
                break;
+       case TYPE_MENLO:
+               menlo = &dd_data->context_un.menlo;
+               cmdiocb = menlo->cmdiocbq;
+               /* hint to completion handler that the job timed out */
+               job->reply->result = -EAGAIN;
+               spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+               /* this will call our completion handler */
+               spin_lock_irq(&phba->hbalock);
+               lpfc_sli_issue_abort_iotag(phba, pring, cmdiocb);
+               spin_unlock_irq(&phba->hbalock);
+               break;
        default:
                spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
                break;
index 6c8f87e39b9817da4abc3533ac8628db416f9aac..5bc630819b9e86555b177c38e978e07c7b08e8bb 100644 (file)
@@ -31,6 +31,8 @@
 #define LPFC_BSG_VENDOR_DIAG_TEST      5
 #define LPFC_BSG_VENDOR_GET_MGMT_REV   6
 #define LPFC_BSG_VENDOR_MBOX           7
+#define LPFC_BSG_VENDOR_MENLO_CMD      8
+#define LPFC_BSG_VENDOR_MENLO_DATA     9
 
 struct set_ct_event {
        uint32_t command;
@@ -96,3 +98,13 @@ struct dfc_mbox_req {
        uint8_t mbOffset;
 };
 
+/* Used for menlo command or menlo data. The xri is only used for menlo data */
+struct menlo_command {
+       uint32_t cmd;
+       uint32_t xri;
+};
+
+struct menlo_response {
+       uint32_t xri; /* return the xri of the iocb exchange */
+};
+
index 6f0fb51eb4616899538e7e3927d8876e4431d412..5087c4211b439d72f36bbc65d7c93461fd67c712 100644 (file)
@@ -63,6 +63,7 @@ void lpfc_linkdown_port(struct lpfc_vport *);
 void lpfc_port_link_failure(struct lpfc_vport *);
 void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_init_vpi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *);
 void lpfc_retry_pport_discovery(struct lpfc_hba *);
 
 void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -221,6 +222,10 @@ void lpfc_unregister_fcf_rescan(struct lpfc_hba *);
 void lpfc_unregister_unused_fcf(struct lpfc_hba *);
 int lpfc_sli4_redisc_fcf_table(struct lpfc_hba *);
 void lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *);
+void lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *);
+uint16_t lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *);
+int lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *, uint16_t);
+void lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *, uint16_t);
 
 int lpfc_mem_alloc(struct lpfc_hba *, int align);
 void lpfc_mem_free(struct lpfc_hba *);
@@ -385,7 +390,7 @@ void lpfc_parse_fcoe_conf(struct lpfc_hba *, uint8_t *, uint32_t);
 int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int);
 void lpfc_start_fdiscs(struct lpfc_hba *phba);
 struct lpfc_vport *lpfc_find_vport_by_vpid(struct lpfc_hba *, uint16_t);
-
+struct lpfc_sglq *__lpfc_get_active_sglq(struct lpfc_hba *, uint16_t);
 #define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code)
 #define HBA_EVENT_RSCN                   5
 #define HBA_EVENT_LINK_UP                2
index c7e921973f66adedf93bb087f229b4e3fc2485ea..463b74902ac4b2b32368e2b99227321515e1d314 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/blkdev.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/utsname.h>
 
 #include <scsi/scsi.h>
index 391584183d81fc7102453bd73a5f7faf1a5e1798..a80d938fafc90ae1530f9c2b8573a4ed39e61242 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/idr.h>
 #include <linux/interrupt.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/ctype.h>
index 2a40a6eabf4d3a55708d5ceb93494f07a9daaef7..5fbdb22c1899a82be318ff127b28d93ffa1f8285 100644 (file)
@@ -21,6 +21,7 @@
 /* See Fibre Channel protocol T11 FC-LS for details */
 #include <linux/blkdev.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 
 #include <scsi/scsi.h>
@@ -771,6 +772,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        struct lpfc_nodelist *ndlp = cmdiocb->context1;
        struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp;
        struct serv_parm *sp;
+       uint16_t fcf_index;
        int rc;
 
        /* Check to see if link went down during discovery */
@@ -788,6 +790,54 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                vport->port_state);
 
        if (irsp->ulpStatus) {
+               /*
+                * In case of FIP mode, perform round robin FCF failover
+                * due to new FCF discovery
+                */
+               if ((phba->hba_flag & HBA_FIP_SUPPORT) &&
+                   (phba->fcf.fcf_flag & FCF_DISCOVERY)) {
+                       lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS,
+                                       "2611 FLOGI failed on registered "
+                                       "FCF record fcf_index:%d, trying "
+                                       "to perform round robin failover\n",
+                                       phba->fcf.current_rec.fcf_indx);
+                       fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba);
+                       if (fcf_index == LPFC_FCOE_FCF_NEXT_NONE) {
+                               /*
+                                * Exhausted the eligible FCF record list,
+                                * fail through to retry FLOGI on current
+                                * FCF record.
+                                */
+                               lpfc_printf_log(phba, KERN_WARNING,
+                                               LOG_FIP | LOG_ELS,
+                                               "2760 FLOGI exhausted FCF "
+                                               "round robin failover list, "
+                                               "retry FLOGI on the current "
+                                               "registered FCF index:%d\n",
+                                               phba->fcf.current_rec.fcf_indx);
+                               spin_lock_irq(&phba->hbalock);
+                               phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
+                               spin_unlock_irq(&phba->hbalock);
+                       } else {
+                               rc = lpfc_sli4_fcf_rr_read_fcf_rec(phba,
+                                                                  fcf_index);
+                               if (rc) {
+                                       lpfc_printf_log(phba, KERN_WARNING,
+                                                       LOG_FIP | LOG_ELS,
+                                                       "2761 FLOGI round "
+                                                       "robin FCF failover "
+                                                       "read FCF failed "
+                                                       "rc:x%x, fcf_index:"
+                                                       "%d\n", rc,
+                                               phba->fcf.current_rec.fcf_indx);
+                                       spin_lock_irq(&phba->hbalock);
+                                       phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
+                                       spin_unlock_irq(&phba->hbalock);
+                               } else
+                                       goto out;
+                       }
+               }
+
                /* Check for retry */
                if (lpfc_els_retry(phba, cmdiocb, rspiocb))
                        goto out;
@@ -806,9 +856,8 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                }
 
                /* FLOGI failure */
-               lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
-                                "0100 FLOGI failure Data: x%x x%x "
-                                "x%x\n",
+               lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+                                "0100 FLOGI failure Status:x%x/x%x TMO:x%x\n",
                                 irsp->ulpStatus, irsp->un.ulpWord[4],
                                 irsp->ulpTimeout);
                goto flogifail;
@@ -842,8 +891,18 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                else
                        rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp);
 
-               if (!rc)
+               if (!rc) {
+                       /* Mark the FCF discovery process done */
+                       lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP | LOG_ELS,
+                                        "2769 FLOGI successful on FCF record: "
+                                        "current_fcf_index:x%x, terminate FCF "
+                                        "round robin failover process\n",
+                                        phba->fcf.current_rec.fcf_indx);
+                       spin_lock_irq(&phba->hbalock);
+                       phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
+                       spin_unlock_irq(&phba->hbalock);
                        goto out;
+               }
        }
 
 flogifail:
@@ -1409,6 +1468,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        goto out;
                }
                /* PLOGI failed */
+               lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+                                "2753 PLOGI failure DID:%06X Status:x%x/x%x\n",
+                                ndlp->nlp_DID, irsp->ulpStatus,
+                                irsp->un.ulpWord[4]);
                /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
                if (lpfc_error_lost_link(irsp))
                        rc = NLP_STE_FREED_NODE;
@@ -1577,6 +1640,10 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        goto out;
                }
                /* PRLI failed */
+               lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+                                "2754 PRLI failure DID:%06X Status:x%x/x%x\n",
+                                ndlp->nlp_DID, irsp->ulpStatus,
+                                irsp->un.ulpWord[4]);
                /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
                if (lpfc_error_lost_link(irsp))
                        goto out;
@@ -1860,6 +1927,10 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        goto out;
                }
                /* ADISC failed */
+               lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+                                "2755 ADISC failure DID:%06X Status:x%x/x%x\n",
+                                ndlp->nlp_DID, irsp->ulpStatus,
+                                irsp->un.ulpWord[4]);
                /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
                if (!lpfc_error_lost_link(irsp))
                        lpfc_disc_state_machine(vport, ndlp, cmdiocb,
@@ -2009,6 +2080,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        /* ELS command is being retried */
                        goto out;
                /* LOGO failed */
+               lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+                                "2756 LOGO failure DID:%06X Status:x%x/x%x\n",
+                                ndlp->nlp_DID, irsp->ulpStatus,
+                                irsp->un.ulpWord[4]);
                /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
                if (lpfc_error_lost_link(irsp))
                        goto out;
@@ -5989,7 +6064,12 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
                        if (phba->sli_rev < LPFC_SLI_REV4)
                                lpfc_issue_fabric_reglogin(vport);
                        else {
-                               lpfc_start_fdiscs(phba);
+                               /*
+                                * If the physical port is instantiated using
+                                * FDISC, do not start vport discovery.
+                                */
+                               if (vport->port_state != LPFC_FDISC)
+                                       lpfc_start_fdiscs(phba);
                                lpfc_do_scr_ns_plogi(phba, vport);
                        }
                } else
@@ -6055,21 +6135,18 @@ mbox_err_exit:
 }
 
 /**
- * lpfc_retry_pport_discovery - Start timer to retry FLOGI.
+ * lpfc_cancel_all_vport_retry_delay_timer - Cancel all vport retry delay timer
  * @phba: pointer to lpfc hba data structure.
  *
- * This routine abort all pending discovery commands and
- * start a timer to retry FLOGI for the physical port
- * discovery.
+ * This routine cancels the retry delay timers to all the vports.
  **/
 void
-lpfc_retry_pport_discovery(struct lpfc_hba *phba)
+lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *phba)
 {
        struct lpfc_vport **vports;
        struct lpfc_nodelist *ndlp;
-       struct Scsi_Host  *shost;
-       int i;
        uint32_t link_state;
+       int i;
 
        /* Treat this failure as linkdown for all vports */
        link_state = phba->link_state;
@@ -6087,13 +6164,30 @@ lpfc_retry_pport_discovery(struct lpfc_hba *phba)
                }
                lpfc_destroy_vport_work_array(phba, vports);
        }
+}
+
+/**
+ * lpfc_retry_pport_discovery - Start timer to retry FLOGI.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine abort all pending discovery commands and
+ * start a timer to retry FLOGI for the physical port
+ * discovery.
+ **/
+void
+lpfc_retry_pport_discovery(struct lpfc_hba *phba)
+{
+       struct lpfc_nodelist *ndlp;
+       struct Scsi_Host  *shost;
+
+       /* Cancel the all vports retry delay retry timers */
+       lpfc_cancel_all_vport_retry_delay_timer(phba);
 
        /* If fabric require FLOGI, then re-instantiate physical login */
        ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
        if (!ndlp)
                return;
 
-
        shost = lpfc_shost_from_vport(phba->pport);
        mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
        spin_lock_irq(shost->host_lock);
@@ -6219,7 +6313,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                lpfc_mbx_unreg_vpi(vport);
                spin_lock_irq(shost->host_lock);
                vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
-               vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
+               if (phba->sli_rev == LPFC_SLI_REV4)
+                       vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
                spin_unlock_irq(shost->host_lock);
        }
 
@@ -6797,21 +6892,27 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
        struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;
        unsigned long iflag = 0;
 
-       spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, iflag);
+       spin_lock_irqsave(&phba->hbalock, iflag);
+       spin_lock(&phba->sli4_hba.abts_sgl_list_lock);
        list_for_each_entry_safe(sglq_entry, sglq_next,
                        &phba->sli4_hba.lpfc_abts_els_sgl_list, list) {
                if (sglq_entry->sli4_xritag == xri) {
                        list_del(&sglq_entry->list);
-                       spin_unlock_irqrestore(
-                                       &phba->sli4_hba.abts_sgl_list_lock,
-                                        iflag);
-                       spin_lock_irqsave(&phba->hbalock, iflag);
-
                        list_add_tail(&sglq_entry->list,
                                &phba->sli4_hba.lpfc_sgl_list);
+                       sglq_entry->state = SGL_FREED;
+                       spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
                        spin_unlock_irqrestore(&phba->hbalock, iflag);
                        return;
                }
        }
-       spin_unlock_irqrestore(&phba->sli4_hba.abts_sgl_list_lock, iflag);
+       spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
+       sglq_entry = __lpfc_get_active_sglq(phba, xri);
+       if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) {
+               spin_unlock_irqrestore(&phba->hbalock, iflag);
+               return;
+       }
+       sglq_entry->state = SGL_XRI_ABORTED;
+       spin_unlock_irqrestore(&phba->hbalock, iflag);
+       return;
 }
index 2359d0bfb734f0cd352ca8c68560a07757a8c47c..e1466eec56b703ce1d8fda03d85d29b2be1d31cd 100644 (file)
@@ -20,6 +20,7 @@
  *******************************************************************/
 
 #include <linux/blkdev.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/kthread.h>
 #include <linux/interrupt.h>
@@ -1481,8 +1482,6 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
 int
 lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf)
 {
-       LPFC_MBOXQ_t *mbox;
-       int rc;
        /*
         * If the Link is up and no FCoE events while in the
         * FCF discovery, no need to restart FCF discovery.
@@ -1491,86 +1490,70 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf)
                (phba->fcoe_eventtag == phba->fcoe_eventtag_at_fcf_scan))
                return 0;
 
+       lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                       "2768 Pending link or FCF event during current "
+                       "handling of the previous event: link_state:x%x, "
+                       "evt_tag_at_scan:x%x, evt_tag_current:x%x\n",
+                       phba->link_state, phba->fcoe_eventtag_at_fcf_scan,
+                       phba->fcoe_eventtag);
+
        spin_lock_irq(&phba->hbalock);
        phba->fcf.fcf_flag &= ~FCF_AVAILABLE;
        spin_unlock_irq(&phba->hbalock);
 
-       if (phba->link_state >= LPFC_LINK_UP)
-               lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
-       else {
+       if (phba->link_state >= LPFC_LINK_UP) {
+               lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+                               "2780 Restart FCF table scan due to "
+                               "pending FCF event:evt_tag_at_scan:x%x, "
+                               "evt_tag_current:x%x\n",
+                               phba->fcoe_eventtag_at_fcf_scan,
+                               phba->fcoe_eventtag);
+               lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
+       } else {
                /*
                 * Do not continue FCF discovery and clear FCF_DISC_INPROGRESS
                 * flag
                 */
                spin_lock_irq(&phba->hbalock);
                phba->hba_flag &= ~FCF_DISC_INPROGRESS;
-               phba->fcf.fcf_flag &= ~FCF_REDISC_FOV;
+               phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | FCF_DISCOVERY);
                spin_unlock_irq(&phba->hbalock);
        }
 
+       /* Unregister the currently registered FCF if required */
        if (unreg_fcf) {
                spin_lock_irq(&phba->hbalock);
                phba->fcf.fcf_flag &= ~FCF_REGISTERED;
                spin_unlock_irq(&phba->hbalock);
-               mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-               if (!mbox) {
-                       lpfc_printf_log(phba, KERN_ERR,
-                               LOG_DISCOVERY|LOG_MBOX,
-                               "2610 UNREG_FCFI mbox allocation failed\n");
-                       return 1;
-               }
-               lpfc_unreg_fcfi(mbox, phba->fcf.fcfi);
-               mbox->vport = phba->pport;
-               mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl;
-               rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
-               if (rc == MBX_NOT_FINISHED) {
-                       lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
-                               "2611 UNREG_FCFI issue mbox failed\n");
-                       mempool_free(mbox, phba->mbox_mem_pool);
-               }
+               lpfc_sli4_unregister_fcf(phba);
        }
-
        return 1;
 }
 
 /**
- * lpfc_mbx_cmpl_read_fcf_record - Completion handler for read_fcf mbox.
+ * lpfc_sli4_fcf_rec_mbox_parse - parse non-embedded fcf record mailbox command
  * @phba: pointer to lpfc hba data structure.
  * @mboxq: pointer to mailbox object.
+ * @next_fcf_index: pointer to holder of next fcf index.
  *
- * This function iterate through all the fcf records available in
- * HBA and choose the optimal FCF record for discovery. After finding
- * the FCF for discovery it register the FCF record and kick start
- * discovery.
- * If FCF_IN_USE flag is set in currently used FCF, the routine try to
- * use a FCF record which match fabric name and mac address of the
- * currently used FCF record.
- * If the driver support only one FCF, it will try to use the FCF record
- * used by BOOT_BIOS.
+ * This routine parses the non-embedded fcf mailbox command by performing the
+ * necessarily error checking, non-embedded read FCF record mailbox command
+ * SGE parsing, and endianness swapping.
+ *
+ * Returns the pointer to the new FCF record in the non-embedded mailbox
+ * command DMA memory if successfully, other NULL.
  */
-void
-lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+static struct fcf_record *
+lpfc_sli4_fcf_rec_mbox_parse(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq,
+                            uint16_t *next_fcf_index)
 {
        void *virt_addr;
        dma_addr_t phys_addr;
-       uint8_t *bytep;
        struct lpfc_mbx_sge sge;
        struct lpfc_mbx_read_fcf_tbl *read_fcf;
        uint32_t shdr_status, shdr_add_status;
        union lpfc_sli4_cfg_shdr *shdr;
        struct fcf_record *new_fcf_record;
-       uint32_t boot_flag, addr_mode;
-       uint32_t next_fcf_index;
-       struct lpfc_fcf_rec *fcf_rec = NULL;
-       unsigned long iflags;
-       uint16_t vlan_id;
-       int rc;
-
-       /* If there is pending FCoE event restart FCF table scan */
-       if (lpfc_check_pending_fcoe_event(phba, 0)) {
-               lpfc_sli4_mbox_cmd_free(phba, mboxq);
-               return;
-       }
 
        /* Get the first SGE entry from the non-embedded DMA memory. This
         * routine only uses a single SGE.
@@ -1581,59 +1564,183 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
                lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
                                "2524 Failed to get the non-embedded SGE "
                                "virtual address\n");
-               goto out;
+               return NULL;
        }
        virt_addr = mboxq->sge_array->addr[0];
 
        shdr = (union lpfc_sli4_cfg_shdr *)virt_addr;
        shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
-       shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
-                                &shdr->response);
-       /*
-        * The FCF Record was read and there is no reason for the driver
-        * to maintain the FCF record data or memory. Instead, just need
-        * to book keeping the FCFIs can be used.
-        */
+       shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
        if (shdr_status || shdr_add_status) {
-               if (shdr_status == STATUS_FCF_TABLE_EMPTY) {
-                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+               if (shdr_status == STATUS_FCF_TABLE_EMPTY)
+                       lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
                                        "2726 READ_FCF_RECORD Indicates empty "
                                        "FCF table.\n");
-               } else {
-                       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+               else
+                       lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
                                        "2521 READ_FCF_RECORD mailbox failed "
-                                       "with status x%x add_status x%x, mbx\n",
-                                       shdr_status, shdr_add_status);
-               }
-               goto out;
+                                       "with status x%x add_status x%x, "
+                                       "mbx\n", shdr_status, shdr_add_status);
+               return NULL;
        }
-       /* Interpreting the returned information of FCF records */
+
+       /* Interpreting the returned information of the FCF record */
        read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr;
        lpfc_sli_pcimem_bcopy(read_fcf, read_fcf,
                              sizeof(struct lpfc_mbx_read_fcf_tbl));
-       next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf);
-
+       *next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf);
        new_fcf_record = (struct fcf_record *)(virt_addr +
                          sizeof(struct lpfc_mbx_read_fcf_tbl));
        lpfc_sli_pcimem_bcopy(new_fcf_record, new_fcf_record,
                              sizeof(struct fcf_record));
-       bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr);
 
+       return new_fcf_record;
+}
+
+/**
+ * lpfc_sli4_log_fcf_record_info - Log the information of a fcf record
+ * @phba: pointer to lpfc hba data structure.
+ * @fcf_record: pointer to the fcf record.
+ * @vlan_id: the lowest vlan identifier associated to this fcf record.
+ * @next_fcf_index: the index to the next fcf record in hba's fcf table.
+ *
+ * This routine logs the detailed FCF record if the LOG_FIP loggin is
+ * enabled.
+ **/
+static void
+lpfc_sli4_log_fcf_record_info(struct lpfc_hba *phba,
+                             struct fcf_record *fcf_record,
+                             uint16_t vlan_id,
+                             uint16_t next_fcf_index)
+{
+       lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                       "2764 READ_FCF_RECORD:\n"
+                       "\tFCF_Index     : x%x\n"
+                       "\tFCF_Avail     : x%x\n"
+                       "\tFCF_Valid     : x%x\n"
+                       "\tFIP_Priority  : x%x\n"
+                       "\tMAC_Provider  : x%x\n"
+                       "\tLowest VLANID : x%x\n"
+                       "\tFCF_MAC Addr  : x%x:%x:%x:%x:%x:%x\n"
+                       "\tFabric_Name   : x%x:%x:%x:%x:%x:%x:%x:%x\n"
+                       "\tSwitch_Name   : x%x:%x:%x:%x:%x:%x:%x:%x\n"
+                       "\tNext_FCF_Index: x%x\n",
+                       bf_get(lpfc_fcf_record_fcf_index, fcf_record),
+                       bf_get(lpfc_fcf_record_fcf_avail, fcf_record),
+                       bf_get(lpfc_fcf_record_fcf_valid, fcf_record),
+                       fcf_record->fip_priority,
+                       bf_get(lpfc_fcf_record_mac_addr_prov, fcf_record),
+                       vlan_id,
+                       bf_get(lpfc_fcf_record_mac_0, fcf_record),
+                       bf_get(lpfc_fcf_record_mac_1, fcf_record),
+                       bf_get(lpfc_fcf_record_mac_2, fcf_record),
+                       bf_get(lpfc_fcf_record_mac_3, fcf_record),
+                       bf_get(lpfc_fcf_record_mac_4, fcf_record),
+                       bf_get(lpfc_fcf_record_mac_5, fcf_record),
+                       bf_get(lpfc_fcf_record_fab_name_0, fcf_record),
+                       bf_get(lpfc_fcf_record_fab_name_1, fcf_record),
+                       bf_get(lpfc_fcf_record_fab_name_2, fcf_record),
+                       bf_get(lpfc_fcf_record_fab_name_3, fcf_record),
+                       bf_get(lpfc_fcf_record_fab_name_4, fcf_record),
+                       bf_get(lpfc_fcf_record_fab_name_5, fcf_record),
+                       bf_get(lpfc_fcf_record_fab_name_6, fcf_record),
+                       bf_get(lpfc_fcf_record_fab_name_7, fcf_record),
+                       bf_get(lpfc_fcf_record_switch_name_0, fcf_record),
+                       bf_get(lpfc_fcf_record_switch_name_1, fcf_record),
+                       bf_get(lpfc_fcf_record_switch_name_2, fcf_record),
+                       bf_get(lpfc_fcf_record_switch_name_3, fcf_record),
+                       bf_get(lpfc_fcf_record_switch_name_4, fcf_record),
+                       bf_get(lpfc_fcf_record_switch_name_5, fcf_record),
+                       bf_get(lpfc_fcf_record_switch_name_6, fcf_record),
+                       bf_get(lpfc_fcf_record_switch_name_7, fcf_record),
+                       next_fcf_index);
+}
+
+/**
+ * lpfc_mbx_cmpl_fcf_scan_read_fcf_rec - fcf scan read_fcf mbox cmpl handler.
+ * @phba: pointer to lpfc hba data structure.
+ * @mboxq: pointer to mailbox object.
+ *
+ * This function iterates through all the fcf records available in
+ * HBA and chooses the optimal FCF record for discovery. After finding
+ * the FCF for discovery it registers the FCF record and kicks start
+ * discovery.
+ * If FCF_IN_USE flag is set in currently used FCF, the routine tries to
+ * use an FCF record which matches fabric name and mac address of the
+ * currently used FCF record.
+ * If the driver supports only one FCF, it will try to use the FCF record
+ * used by BOOT_BIOS.
+ */
+void
+lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+{
+       struct fcf_record *new_fcf_record;
+       uint32_t boot_flag, addr_mode;
+       uint16_t fcf_index, next_fcf_index;
+       struct lpfc_fcf_rec *fcf_rec = NULL;
+       uint16_t vlan_id;
+       int rc;
+
+       /* If there is pending FCoE event restart FCF table scan */
+       if (lpfc_check_pending_fcoe_event(phba, 0)) {
+               lpfc_sli4_mbox_cmd_free(phba, mboxq);
+               return;
+       }
+
+       /* Parse the FCF record from the non-embedded mailbox command */
+       new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq,
+                                                     &next_fcf_index);
+       if (!new_fcf_record) {
+               lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
+                               "2765 Mailbox command READ_FCF_RECORD "
+                               "failed to retrieve a FCF record.\n");
+               /* Let next new FCF event trigger fast failover */
+               spin_lock_irq(&phba->hbalock);
+               phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+               spin_unlock_irq(&phba->hbalock);
+               lpfc_sli4_mbox_cmd_free(phba, mboxq);
+               return;
+       }
+
+       /* Check the FCF record against the connection list */
        rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag,
                                      &addr_mode, &vlan_id);
+
+       /* Log the FCF record information if turned on */
+       lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id,
+                                     next_fcf_index);
+
        /*
         * If the fcf record does not match with connect list entries
-        * read the next entry.
+        * read the next entry; otherwise, this is an eligible FCF
+        * record for round robin FCF failover.
         */
-       if (!rc)
+       if (!rc) {
+               lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
+                               "2781 FCF record fcf_index:x%x failed FCF "
+                               "connection list check, fcf_avail:x%x, "
+                               "fcf_valid:x%x\n",
+                               bf_get(lpfc_fcf_record_fcf_index,
+                                      new_fcf_record),
+                               bf_get(lpfc_fcf_record_fcf_avail,
+                                      new_fcf_record),
+                               bf_get(lpfc_fcf_record_fcf_valid,
+                                      new_fcf_record));
                goto read_next_fcf;
+       } else {
+               fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record);
+               rc = lpfc_sli4_fcf_rr_index_set(phba, fcf_index);
+               if (rc)
+                       goto read_next_fcf;
+       }
+
        /*
         * If this is not the first FCF discovery of the HBA, use last
         * FCF record for the discovery. The condition that a rescan
         * matches the in-use FCF record: fabric name, switch name, mac
         * address, and vlan_id.
         */
-       spin_lock_irqsave(&phba->hbalock, iflags);
+       spin_lock_irq(&phba->hbalock);
        if (phba->fcf.fcf_flag & FCF_IN_USE) {
                if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name,
                                        new_fcf_record) &&
@@ -1649,8 +1756,9 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
                                __lpfc_sli4_stop_fcf_redisc_wait_timer(phba);
                        else if (phba->fcf.fcf_flag & FCF_REDISC_FOV)
                                /* If in fast failover, mark it's completed */
-                               phba->fcf.fcf_flag &= ~FCF_REDISC_FOV;
-                       spin_unlock_irqrestore(&phba->hbalock, iflags);
+                               phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV |
+                                                       FCF_DISCOVERY);
+                       spin_unlock_irq(&phba->hbalock);
                        goto out;
                }
                /*
@@ -1661,7 +1769,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
                 * next candidate.
                 */
                if (!(phba->fcf.fcf_flag & FCF_REDISC_FOV)) {
-                       spin_unlock_irqrestore(&phba->hbalock, iflags);
+                       spin_unlock_irq(&phba->hbalock);
                        goto read_next_fcf;
                }
        }
@@ -1669,14 +1777,9 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
         * Update on failover FCF record only if it's in FCF fast-failover
         * period; otherwise, update on current FCF record.
         */
-       if (phba->fcf.fcf_flag & FCF_REDISC_FOV) {
-               /* Fast FCF failover only to the same fabric name */
-               if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name,
-                                       new_fcf_record))
-                       fcf_rec = &phba->fcf.failover_rec;
-               else
-                       goto read_next_fcf;
-       } else
+       if (phba->fcf.fcf_flag & FCF_REDISC_FOV)
+               fcf_rec = &phba->fcf.failover_rec;
+       else
                fcf_rec = &phba->fcf.current_rec;
 
        if (phba->fcf.fcf_flag & FCF_AVAILABLE) {
@@ -1689,7 +1792,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
                        /* Choose this FCF record */
                        __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record,
                                        addr_mode, vlan_id, BOOT_ENABLE);
-                       spin_unlock_irqrestore(&phba->hbalock, iflags);
+                       spin_unlock_irq(&phba->hbalock);
                        goto read_next_fcf;
                }
                /*
@@ -1698,20 +1801,19 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
                 * the next FCF record.
                 */
                if (!boot_flag && (fcf_rec->flag & BOOT_ENABLE)) {
-                       spin_unlock_irqrestore(&phba->hbalock, iflags);
+                       spin_unlock_irq(&phba->hbalock);
                        goto read_next_fcf;
                }
                /*
                 * If the new hba FCF record has lower priority value
                 * than the driver FCF record, use the new record.
                 */
-               if (lpfc_fab_name_match(fcf_rec->fabric_name, new_fcf_record) &&
-                   (new_fcf_record->fip_priority < fcf_rec->priority)) {
+               if (new_fcf_record->fip_priority < fcf_rec->priority) {
                        /* Choose this FCF record */
                        __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record,
                                        addr_mode, vlan_id, 0);
                }
-               spin_unlock_irqrestore(&phba->hbalock, iflags);
+               spin_unlock_irq(&phba->hbalock);
                goto read_next_fcf;
        }
        /*
@@ -1724,7 +1826,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
                                         BOOT_ENABLE : 0));
                phba->fcf.fcf_flag |= FCF_AVAILABLE;
        }
-       spin_unlock_irqrestore(&phba->hbalock, iflags);
+       spin_unlock_irq(&phba->hbalock);
        goto read_next_fcf;
 
 read_next_fcf:
@@ -1740,9 +1842,22 @@ read_next_fcf:
                         * FCF scan inprogress, and do nothing
                         */
                        if (!(phba->fcf.failover_rec.flag & RECORD_VALID)) {
-                               spin_lock_irqsave(&phba->hbalock, iflags);
+                               lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
+                                              "2782 No suitable FCF record "
+                                              "found during this round of "
+                                              "post FCF rediscovery scan: "
+                                              "fcf_evt_tag:x%x, fcf_index: "
+                                              "x%x\n",
+                                              phba->fcoe_eventtag_at_fcf_scan,
+                                              bf_get(lpfc_fcf_record_fcf_index,
+                                                     new_fcf_record));
+                               /*
+                                * Let next new FCF event trigger fast
+                                * failover
+                                */
+                               spin_lock_irq(&phba->hbalock);
                                phba->hba_flag &= ~FCF_DISC_INPROGRESS;
-                               spin_unlock_irqrestore(&phba->hbalock, iflags);
+                               spin_unlock_irq(&phba->hbalock);
                                return;
                        }
                        /*
@@ -1754,16 +1869,23 @@ read_next_fcf:
                         * record.
                         */
 
-                       /* unregister the current in-use FCF record */
+                       /* Unregister the current in-use FCF record */
                        lpfc_unregister_fcf(phba);
-                       /* replace in-use record with the new record */
+
+                       /* Replace in-use record with the new record */
                        memcpy(&phba->fcf.current_rec,
                               &phba->fcf.failover_rec,
                               sizeof(struct lpfc_fcf_rec));
                        /* mark the FCF fast failover completed */
-                       spin_lock_irqsave(&phba->hbalock, iflags);
+                       spin_lock_irq(&phba->hbalock);
                        phba->fcf.fcf_flag &= ~FCF_REDISC_FOV;
-                       spin_unlock_irqrestore(&phba->hbalock, iflags);
+                       spin_unlock_irq(&phba->hbalock);
+                       /*
+                        * Set up the initial registered FCF index for FLOGI
+                        * round robin FCF failover.
+                        */
+                       phba->fcf.fcf_rr_init_indx =
+                                       phba->fcf.failover_rec.fcf_indx;
                        /* Register to the new FCF record */
                        lpfc_register_fcf(phba);
                } else {
@@ -1776,13 +1898,25 @@ read_next_fcf:
                                return;
                        /*
                         * Otherwise, initial scan or post linkdown rescan,
-                        * register with the best fit FCF record found so
-                        * far through the scanning process.
+                        * register with the best FCF record found so far
+                        * through the FCF scanning process.
+                        */
+
+                       /* mark the initial FCF discovery completed */
+                       spin_lock_irq(&phba->hbalock);
+                       phba->fcf.fcf_flag &= ~FCF_INIT_DISC;
+                       spin_unlock_irq(&phba->hbalock);
+                       /*
+                        * Set up the initial registered FCF index for FLOGI
+                        * round robin FCF failover
                         */
+                       phba->fcf.fcf_rr_init_indx =
+                                       phba->fcf.current_rec.fcf_indx;
+                       /* Register to the new FCF record */
                        lpfc_register_fcf(phba);
                }
        } else
-               lpfc_sli4_read_fcf_record(phba, next_fcf_index);
+               lpfc_sli4_fcf_scan_read_fcf_rec(phba, next_fcf_index);
        return;
 
 out:
@@ -1792,6 +1926,141 @@ out:
        return;
 }
 
+/**
+ * lpfc_mbx_cmpl_fcf_rr_read_fcf_rec - fcf round robin read_fcf mbox cmpl hdler
+ * @phba: pointer to lpfc hba data structure.
+ * @mboxq: pointer to mailbox object.
+ *
+ * This is the callback function for FLOGI failure round robin FCF failover
+ * read FCF record mailbox command from the eligible FCF record bmask for
+ * performing the failover. If the FCF read back is not valid/available, it
+ * fails through to retrying FLOGI to the currently registered FCF again.
+ * Otherwise, if the FCF read back is valid and available, it will set the
+ * newly read FCF record to the failover FCF record, unregister currently
+ * registered FCF record, copy the failover FCF record to the current
+ * FCF record, and then register the current FCF record before proceeding
+ * to trying FLOGI on the new failover FCF.
+ */
+void
+lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+{
+       struct fcf_record *new_fcf_record;
+       uint32_t boot_flag, addr_mode;
+       uint16_t next_fcf_index;
+       uint16_t current_fcf_index;
+       uint16_t vlan_id;
+
+       /* If link state is not up, stop the round robin failover process */
+       if (phba->link_state < LPFC_LINK_UP) {
+               spin_lock_irq(&phba->hbalock);
+               phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
+               spin_unlock_irq(&phba->hbalock);
+               lpfc_sli4_mbox_cmd_free(phba, mboxq);
+               return;
+       }
+
+       /* Parse the FCF record from the non-embedded mailbox command */
+       new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq,
+                                                     &next_fcf_index);
+       if (!new_fcf_record) {
+               lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
+                               "2766 Mailbox command READ_FCF_RECORD "
+                               "failed to retrieve a FCF record.\n");
+               goto out;
+       }
+
+       /* Get the needed parameters from FCF record */
+       lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag,
+                                &addr_mode, &vlan_id);
+
+       /* Log the FCF record information if turned on */
+       lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id,
+                                     next_fcf_index);
+
+       /* Upload new FCF record to the failover FCF record */
+       spin_lock_irq(&phba->hbalock);
+       __lpfc_update_fcf_record(phba, &phba->fcf.failover_rec,
+                                new_fcf_record, addr_mode, vlan_id,
+                                (boot_flag ? BOOT_ENABLE : 0));
+       spin_unlock_irq(&phba->hbalock);
+
+       current_fcf_index = phba->fcf.current_rec.fcf_indx;
+
+       /* Unregister the current in-use FCF record */
+       lpfc_unregister_fcf(phba);
+
+       /* Replace in-use record with the new record */
+       memcpy(&phba->fcf.current_rec, &phba->fcf.failover_rec,
+              sizeof(struct lpfc_fcf_rec));
+
+       lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                       "2783 FLOGI round robin FCF failover from FCF "
+                       "(index:x%x) to FCF (index:x%x).\n",
+                       current_fcf_index,
+                       bf_get(lpfc_fcf_record_fcf_index, new_fcf_record));
+
+out:
+       lpfc_sli4_mbox_cmd_free(phba, mboxq);
+       lpfc_register_fcf(phba);
+}
+
+/**
+ * lpfc_mbx_cmpl_read_fcf_rec - read fcf completion handler.
+ * @phba: pointer to lpfc hba data structure.
+ * @mboxq: pointer to mailbox object.
+ *
+ * This is the callback function of read FCF record mailbox command for
+ * updating the eligible FCF bmask for FLOGI failure round robin FCF
+ * failover when a new FCF event happened. If the FCF read back is
+ * valid/available and it passes the connection list check, it updates
+ * the bmask for the eligible FCF record for round robin failover.
+ */
+void
+lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+{
+       struct fcf_record *new_fcf_record;
+       uint32_t boot_flag, addr_mode;
+       uint16_t fcf_index, next_fcf_index;
+       uint16_t vlan_id;
+       int rc;
+
+       /* If link state is not up, no need to proceed */
+       if (phba->link_state < LPFC_LINK_UP)
+               goto out;
+
+       /* If FCF discovery period is over, no need to proceed */
+       if (phba->fcf.fcf_flag & FCF_DISCOVERY)
+               goto out;
+
+       /* Parse the FCF record from the non-embedded mailbox command */
+       new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq,
+                                                     &next_fcf_index);
+       if (!new_fcf_record) {
+               lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                               "2767 Mailbox command READ_FCF_RECORD "
+                               "failed to retrieve a FCF record.\n");
+               goto out;
+       }
+
+       /* Check the connection list for eligibility */
+       rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag,
+                                     &addr_mode, &vlan_id);
+
+       /* Log the FCF record information if turned on */
+       lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id,
+                                     next_fcf_index);
+
+       if (!rc)
+               goto out;
+
+       /* Update the eligible FCF record index bmask */
+       fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record);
+       rc = lpfc_sli4_fcf_rr_index_set(phba, fcf_index);
+
+out:
+       lpfc_sli4_mbox_cmd_free(phba, mboxq);
+}
+
 /**
  * lpfc_init_vpi_cmpl - Completion handler for init_vpi mbox command.
  * @phba: pointer to lpfc hba data structure.
@@ -2024,8 +2293,6 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
        int rc;
        struct fcf_record *fcf_record;
 
-       sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-
        spin_lock_irq(&phba->hbalock);
        switch (la->UlnkSpeed) {
        case LA_1GHZ_LINK:
@@ -2117,18 +2384,24 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
        spin_unlock_irq(&phba->hbalock);
 
        lpfc_linkup(phba);
-       if (sparam_mbox) {
-               lpfc_read_sparam(phba, sparam_mbox, 0);
-               sparam_mbox->vport = vport;
-               sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;
-               rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT);
-               if (rc == MBX_NOT_FINISHED) {
-                       mp = (struct lpfc_dmabuf *) sparam_mbox->context1;
-                       lpfc_mbuf_free(phba, mp->virt, mp->phys);
-                       kfree(mp);
-                       mempool_free(sparam_mbox, phba->mbox_mem_pool);
-                       goto out;
-               }
+       sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+       if (!sparam_mbox)
+               goto out;
+
+       rc = lpfc_read_sparam(phba, sparam_mbox, 0);
+       if (rc) {
+               mempool_free(sparam_mbox, phba->mbox_mem_pool);
+               goto out;
+       }
+       sparam_mbox->vport = vport;
+       sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;
+       rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT);
+       if (rc == MBX_NOT_FINISHED) {
+               mp = (struct lpfc_dmabuf *) sparam_mbox->context1;
+               lpfc_mbuf_free(phba, mp->virt, mp->phys);
+               kfree(mp);
+               mempool_free(sparam_mbox, phba->mbox_mem_pool);
+               goto out;
        }
 
        if (!(phba->hba_flag & HBA_FCOE_SUPPORT)) {
@@ -2186,10 +2459,20 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
                        spin_unlock_irq(&phba->hbalock);
                        return;
                }
+               /* This is the initial FCF discovery scan */
+               phba->fcf.fcf_flag |= FCF_INIT_DISC;
                spin_unlock_irq(&phba->hbalock);
-               rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
-               if (rc)
+               lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+                               "2778 Start FCF table scan at linkup\n");
+
+               rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba,
+                                                    LPFC_FCOE_FCF_GET_FIRST);
+               if (rc) {
+                       spin_lock_irq(&phba->hbalock);
+                       phba->fcf.fcf_flag &= ~FCF_INIT_DISC;
+                       spin_unlock_irq(&phba->hbalock);
                        goto out;
+               }
        }
 
        return;
@@ -3379,8 +3662,12 @@ lpfc_unreg_hba_rpis(struct lpfc_hba *phba)
                shost = lpfc_shost_from_vport(vports[i]);
                spin_lock_irq(shost->host_lock);
                list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) {
-                       if (ndlp->nlp_flag & NLP_RPI_VALID)
+                       if (ndlp->nlp_flag & NLP_RPI_VALID) {
+                               /* The mempool_alloc might sleep */
+                               spin_unlock_irq(shost->host_lock);
                                lpfc_unreg_rpi(vports[i], ndlp);
+                               spin_lock_irq(shost->host_lock);
+                       }
                }
                spin_unlock_irq(shost->host_lock);
        }
@@ -4756,6 +5043,7 @@ lpfc_unregister_fcf_rescan(struct lpfc_hba *phba)
                return;
        /* Reset HBA FCF states after successful unregister FCF */
        phba->fcf.fcf_flag = 0;
+       phba->fcf.current_rec.flag = 0;
 
        /*
         * If driver is not unloading, check if there is any other
@@ -4765,13 +5053,21 @@ lpfc_unregister_fcf_rescan(struct lpfc_hba *phba)
            (phba->link_state < LPFC_LINK_UP))
                return;
 
-       rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
+       /* This is considered as the initial FCF discovery scan */
+       spin_lock_irq(&phba->hbalock);
+       phba->fcf.fcf_flag |= FCF_INIT_DISC;
+       spin_unlock_irq(&phba->hbalock);
+       rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
 
-       if (rc)
+       if (rc) {
+               spin_lock_irq(&phba->hbalock);
+               phba->fcf.fcf_flag &= ~FCF_INIT_DISC;
+               spin_unlock_irq(&phba->hbalock);
                lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
                                "2553 lpfc_unregister_unused_fcf failed "
                                "to read FCF record HBA state x%x\n",
                                phba->pport->port_state);
+       }
 }
 
 /**
index d29ac7c317d9d7324b13807f2329615320c2d37f..774663e8e1fe0ff39caf1171de5c29b5ec6d3697 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/spinlock.h>
 #include <linux/ctype.h>
 #include <linux/aer.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
@@ -350,7 +351,12 @@ lpfc_config_port_post(struct lpfc_hba *phba)
        mb = &pmb->u.mb;
 
        /* Get login parameters for NID.  */
-       lpfc_read_sparam(phba, pmb, 0);
+       rc = lpfc_read_sparam(phba, pmb, 0);
+       if (rc) {
+               mempool_free(pmb, phba->mbox_mem_pool);
+               return -ENOMEM;
+       }
+
        pmb->vport = vport;
        if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) {
                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -359,7 +365,7 @@ lpfc_config_port_post(struct lpfc_hba *phba)
                                mb->mbxCommand, mb->mbxStatus);
                phba->link_state = LPFC_HBA_ERROR;
                mp = (struct lpfc_dmabuf *) pmb->context1;
-               mempool_free( pmb, phba->mbox_mem_pool);
+               mempool_free(pmb, phba->mbox_mem_pool);
                lpfc_mbuf_free(phba, mp->virt, mp->phys);
                kfree(mp);
                return -EIO;
@@ -544,7 +550,7 @@ lpfc_config_port_post(struct lpfc_hba *phba)
                        mempool_free(pmb, phba->mbox_mem_pool);
                        return -EIO;
                }
-       } else if (phba->cfg_suppress_link_up == 0) {
+       } else if (phba->cfg_suppress_link_up == LPFC_INITIALIZE_LINK) {
                lpfc_init_link(phba, pmb, phba->cfg_topology,
                        phba->cfg_link_speed);
                pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
@@ -571,6 +577,11 @@ lpfc_config_port_post(struct lpfc_hba *phba)
        }
        /* MBOX buffer will be freed in mbox compl */
        pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+       if (!pmb) {
+               phba->link_state = LPFC_HBA_ERROR;
+               return -ENOMEM;
+       }
+
        lpfc_config_async(phba, pmb, LPFC_ELS_RING);
        pmb->mbox_cmpl = lpfc_config_async_cmpl;
        pmb->vport = phba->pport;
@@ -588,6 +599,11 @@ lpfc_config_port_post(struct lpfc_hba *phba)
 
        /* Get Option rom version */
        pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+       if (!pmb) {
+               phba->link_state = LPFC_HBA_ERROR;
+               return -ENOMEM;
+       }
+
        lpfc_dump_wakeup_param(phba, pmb);
        pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl;
        pmb->vport = phba->pport;
@@ -652,7 +668,7 @@ lpfc_hba_init_link(struct lpfc_hba *phba)
                        mempool_free(pmb, phba->mbox_mem_pool);
                return -EIO;
        }
-       phba->cfg_suppress_link_up = 0;
+       phba->cfg_suppress_link_up = LPFC_INITIALIZE_LINK;
 
        return 0;
 }
@@ -807,6 +823,8 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba)
        LIST_HEAD(aborts);
        int ret;
        unsigned long iflag = 0;
+       struct lpfc_sglq *sglq_entry = NULL;
+
        ret = lpfc_hba_down_post_s3(phba);
        if (ret)
                return ret;
@@ -822,6 +840,10 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba)
         * list.
         */
        spin_lock(&phba->sli4_hba.abts_sgl_list_lock);
+       list_for_each_entry(sglq_entry,
+               &phba->sli4_hba.lpfc_abts_els_sgl_list, list)
+               sglq_entry->state = SGL_FREED;
+
        list_splice_init(&phba->sli4_hba.lpfc_abts_els_sgl_list,
                        &phba->sli4_hba.lpfc_sgl_list);
        spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
@@ -2178,8 +2200,10 @@ lpfc_stop_vport_timers(struct lpfc_vport *vport)
 void
 __lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba)
 {
-       /* Clear pending FCF rediscovery wait timer */
-       phba->fcf.fcf_flag &= ~FCF_REDISC_PEND;
+       /* Clear pending FCF rediscovery wait and failover in progress flags */
+       phba->fcf.fcf_flag &= ~(FCF_REDISC_PEND |
+                               FCF_DEAD_DISC |
+                               FCF_ACVL_DISC);
        /* Now, try to stop the timer */
        del_timer(&phba->fcf.redisc_wait);
 }
@@ -2576,6 +2600,14 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
        init_timer(&vport->els_tmofunc);
        vport->els_tmofunc.function = lpfc_els_timeout;
        vport->els_tmofunc.data = (unsigned long)vport;
+       if (phba->pcidev->device == PCI_DEVICE_ID_HORNET) {
+               phba->menlo_flag |= HBA_MENLO_SUPPORT;
+               /* check for menlo minimum sg count */
+               if (phba->cfg_sg_seg_cnt < LPFC_DEFAULT_MENLO_SG_SEG_CNT) {
+                       phba->cfg_sg_seg_cnt = LPFC_DEFAULT_MENLO_SG_SEG_CNT;
+                       shost->sg_tablesize = phba->cfg_sg_seg_cnt;
+               }
+       }
 
        error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev);
        if (error)
@@ -2912,6 +2944,9 @@ lpfc_sli4_fcf_redisc_wait_tmo(unsigned long ptr)
        /* FCF rediscovery event to worker thread */
        phba->fcf.fcf_flag |= FCF_REDISC_EVT;
        spin_unlock_irq(&phba->hbalock);
+       lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                       "2776 FCF rediscover wait timer expired, post "
+                       "a worker thread event for FCF table scan\n");
        /* wake up worker thread */
        lpfc_worker_wake_up(phba);
 }
@@ -3182,6 +3217,68 @@ out_free_pmb:
        mempool_free(pmb, phba->mbox_mem_pool);
 }
 
+/**
+ * lpfc_sli4_perform_vport_cvl - Perform clear virtual link on a vport
+ * @vport: pointer to vport data structure.
+ *
+ * This routine is to perform Clear Virtual Link (CVL) on a vport in
+ * response to a CVL event.
+ *
+ * Return the pointer to the ndlp with the vport if successful, otherwise
+ * return NULL.
+ **/
+static struct lpfc_nodelist *
+lpfc_sli4_perform_vport_cvl(struct lpfc_vport *vport)
+{
+       struct lpfc_nodelist *ndlp;
+       struct Scsi_Host *shost;
+       struct lpfc_hba *phba;
+
+       if (!vport)
+               return NULL;
+       ndlp = lpfc_findnode_did(vport, Fabric_DID);
+       if (!ndlp)
+               return NULL;
+       phba = vport->phba;
+       if (!phba)
+               return NULL;
+       if (phba->pport->port_state <= LPFC_FLOGI)
+               return NULL;
+       /* If virtual link is not yet instantiated ignore CVL */
+       if (vport->port_state <= LPFC_FDISC)
+               return NULL;
+       shost = lpfc_shost_from_vport(vport);
+       if (!shost)
+               return NULL;
+       lpfc_linkdown_port(vport);
+       lpfc_cleanup_pending_mbox(vport);
+       spin_lock_irq(shost->host_lock);
+       vport->fc_flag |= FC_VPORT_CVL_RCVD;
+       spin_unlock_irq(shost->host_lock);
+
+       return ndlp;
+}
+
+/**
+ * lpfc_sli4_perform_all_vport_cvl - Perform clear virtual link on all vports
+ * @vport: pointer to lpfc hba data structure.
+ *
+ * This routine is to perform Clear Virtual Link (CVL) on all vports in
+ * response to a FCF dead event.
+ **/
+static void
+lpfc_sli4_perform_all_vport_cvl(struct lpfc_hba *phba)
+{
+       struct lpfc_vport **vports;
+       int i;
+
+       vports = lpfc_create_vport_work_array(phba);
+       if (vports)
+               for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++)
+                       lpfc_sli4_perform_vport_cvl(vports[i]);
+       lpfc_destroy_vport_work_array(phba, vports);
+}
+
 /**
  * lpfc_sli4_async_fcoe_evt - Process the asynchronous fcoe event
  * @phba: pointer to lpfc hba data structure.
@@ -3198,7 +3295,6 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
        struct lpfc_vport *vport;
        struct lpfc_nodelist *ndlp;
        struct Scsi_Host  *shost;
-       uint32_t link_state;
        int active_vlink_present;
        struct lpfc_vport **vports;
        int i;
@@ -3208,10 +3304,11 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
        switch (event_type) {
        case LPFC_FCOE_EVENT_TYPE_NEW_FCF:
        case LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD:
-               lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
-                       "2546 New FCF found index 0x%x tag 0x%x\n",
-                       acqe_fcoe->index,
-                       acqe_fcoe->event_tag);
+               lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
+                       "2546 New FCF found/FCF parameter modified event: "
+                       "evt_tag:x%x, fcf_index:x%x\n",
+                       acqe_fcoe->event_tag, acqe_fcoe->index);
+
                spin_lock_irq(&phba->hbalock);
                if ((phba->fcf.fcf_flag & FCF_SCAN_DONE) ||
                    (phba->hba_flag & FCF_DISC_INPROGRESS)) {
@@ -3222,6 +3319,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                        spin_unlock_irq(&phba->hbalock);
                        break;
                }
+
                if (phba->fcf.fcf_flag & FCF_REDISC_EVT) {
                        /*
                         * If fast FCF failover rescan event is pending,
@@ -3232,12 +3330,33 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                }
                spin_unlock_irq(&phba->hbalock);
 
-               /* Read the FCF table and re-discover SAN. */
-               rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
+               if ((phba->fcf.fcf_flag & FCF_DISCOVERY) &&
+                   !(phba->fcf.fcf_flag & FCF_REDISC_FOV)) {
+                       /*
+                        * During period of FCF discovery, read the FCF
+                        * table record indexed by the event to update
+                        * FCF round robin failover eligible FCF bmask.
+                        */
+                       lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
+                                       LOG_DISCOVERY,
+                                       "2779 Read new FCF record with "
+                                       "fcf_index:x%x for updating FCF "
+                                       "round robin failover bmask\n",
+                                       acqe_fcoe->index);
+                       rc = lpfc_sli4_read_fcf_rec(phba, acqe_fcoe->index);
+               }
+
+               /* Otherwise, scan the entire FCF table and re-discover SAN */
+               lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+                               "2770 Start FCF table scan due to new FCF "
+                               "event: evt_tag:x%x, fcf_index:x%x\n",
+                               acqe_fcoe->event_tag, acqe_fcoe->index);
+               rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba,
+                                                    LPFC_FCOE_FCF_GET_FIRST);
                if (rc)
-                       lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
-                                       "2547 Read FCF record failed 0x%x\n",
-                                       rc);
+                       lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
+                                       "2547 Issue FCF scan read FCF mailbox "
+                                       "command failed 0x%x\n", rc);
                break;
 
        case LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL:
@@ -3248,47 +3367,63 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                break;
 
        case LPFC_FCOE_EVENT_TYPE_FCF_DEAD:
-               lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
+               lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
                        "2549 FCF disconnected from network index 0x%x"
                        " tag 0x%x\n", acqe_fcoe->index,
                        acqe_fcoe->event_tag);
                /* If the event is not for currently used fcf do nothing */
                if (phba->fcf.current_rec.fcf_indx != acqe_fcoe->index)
                        break;
-               /*
-                * Currently, driver support only one FCF - so treat this as
-                * a link down, but save the link state because we don't want
-                * it to be changed to Link Down unless it is already down.
+               /* We request port to rediscover the entire FCF table for
+                * a fast recovery from case that the current FCF record
+                * is no longer valid if we are not in the middle of FCF
+                * failover process already.
                 */
-               link_state = phba->link_state;
-               lpfc_linkdown(phba);
-               phba->link_state = link_state;
-               /* Unregister FCF if no devices connected to it */
-               lpfc_unregister_unused_fcf(phba);
+               spin_lock_irq(&phba->hbalock);
+               if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
+                       spin_unlock_irq(&phba->hbalock);
+                       /* Update FLOGI FCF failover eligible FCF bmask */
+                       lpfc_sli4_fcf_rr_index_clear(phba, acqe_fcoe->index);
+                       break;
+               }
+               /* Mark the fast failover process in progress */
+               phba->fcf.fcf_flag |= FCF_DEAD_DISC;
+               spin_unlock_irq(&phba->hbalock);
+               lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+                               "2771 Start FCF fast failover process due to "
+                               "FCF DEAD event: evt_tag:x%x, fcf_index:x%x "
+                               "\n", acqe_fcoe->event_tag, acqe_fcoe->index);
+               rc = lpfc_sli4_redisc_fcf_table(phba);
+               if (rc) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
+                                       LOG_DISCOVERY,
+                                       "2772 Issue FCF rediscover mabilbox "
+                                       "command failed, fail through to FCF "
+                                       "dead event\n");
+                       spin_lock_irq(&phba->hbalock);
+                       phba->fcf.fcf_flag &= ~FCF_DEAD_DISC;
+                       spin_unlock_irq(&phba->hbalock);
+                       /*
+                        * Last resort will fail over by treating this
+                        * as a link down to FCF registration.
+                        */
+                       lpfc_sli4_fcf_dead_failthrough(phba);
+               } else
+                       /* Handling fast FCF failover to a DEAD FCF event
+                        * is considered equalivant to receiving CVL to all
+                        * vports.
+                        */
+                       lpfc_sli4_perform_all_vport_cvl(phba);
                break;
        case LPFC_FCOE_EVENT_TYPE_CVL:
-               lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
+               lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
                        "2718 Clear Virtual Link Received for VPI 0x%x"
                        " tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag);
                vport = lpfc_find_vport_by_vpid(phba,
                                acqe_fcoe->index - phba->vpi_base);
-               if (!vport)
-                       break;
-               ndlp = lpfc_findnode_did(vport, Fabric_DID);
+               ndlp = lpfc_sli4_perform_vport_cvl(vport);
                if (!ndlp)
                        break;
-               shost = lpfc_shost_from_vport(vport);
-               if (phba->pport->port_state <= LPFC_FLOGI)
-                       break;
-               /* If virtual link is not yet instantiated ignore CVL */
-               if (vport->port_state <= LPFC_FDISC)
-                       break;
-
-               lpfc_linkdown_port(vport);
-               lpfc_cleanup_pending_mbox(vport);
-               spin_lock_irq(shost->host_lock);
-               vport->fc_flag |= FC_VPORT_CVL_RCVD;
-               spin_unlock_irq(shost->host_lock);
                active_vlink_present = 0;
 
                vports = lpfc_create_vport_work_array(phba);
@@ -3311,6 +3446,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                         * re-instantiate the Vlink using FDISC.
                         */
                        mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
+                       shost = lpfc_shost_from_vport(vport);
                        spin_lock_irq(shost->host_lock);
                        ndlp->nlp_flag |= NLP_DELAY_TMO;
                        spin_unlock_irq(shost->host_lock);
@@ -3321,15 +3457,38 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                         * Otherwise, we request port to rediscover
                         * the entire FCF table for a fast recovery
                         * from possible case that the current FCF
-                        * is no longer valid.
+                        * is no longer valid if we are not already
+                        * in the FCF failover process.
                         */
+                       spin_lock_irq(&phba->hbalock);
+                       if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
+                               spin_unlock_irq(&phba->hbalock);
+                               break;
+                       }
+                       /* Mark the fast failover process in progress */
+                       phba->fcf.fcf_flag |= FCF_ACVL_DISC;
+                       spin_unlock_irq(&phba->hbalock);
+                       lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
+                                       LOG_DISCOVERY,
+                                       "2773 Start FCF fast failover due "
+                                       "to CVL event: evt_tag:x%x\n",
+                                       acqe_fcoe->event_tag);
                        rc = lpfc_sli4_redisc_fcf_table(phba);
-                       if (rc)
+                       if (rc) {
+                               lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
+                                               LOG_DISCOVERY,
+                                               "2774 Issue FCF rediscover "
+                                               "mabilbox command failed, "
+                                               "through to CVL event\n");
+                               spin_lock_irq(&phba->hbalock);
+                               phba->fcf.fcf_flag &= ~FCF_ACVL_DISC;
+                               spin_unlock_irq(&phba->hbalock);
                                /*
                                 * Last resort will be re-try on the
                                 * the current registered FCF entry.
                                 */
                                lpfc_retry_pport_discovery(phba);
+                       }
                }
                break;
        default:
@@ -3426,11 +3585,14 @@ void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *phba)
        spin_unlock_irq(&phba->hbalock);
 
        /* Scan FCF table from the first entry to re-discover SAN */
-       rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
+       lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+                       "2777 Start FCF table scan after FCF "
+                       "rediscovery quiescent period over\n");
+       rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
        if (rc)
-               lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
-                               "2747 Post FCF rediscovery read FCF record "
-                               "failed 0x%x\n", rc);
+               lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
+                               "2747 Issue FCF scan read FCF mailbox "
+                               "command failed 0x%x\n", rc);
 }
 
 /**
@@ -3722,6 +3884,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
        int rc, i, hbq_count, buf_size, dma_buf_size, max_buf_size;
        uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0};
        struct lpfc_mqe *mqe;
+       int longs;
 
        /* Before proceed, wait for POST done and device ready */
        rc = lpfc_sli4_post_status_check(phba);
@@ -3898,13 +4061,24 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
                goto out_free_active_sgl;
        }
 
+       /* Allocate eligible FCF bmask memory for FCF round robin failover */
+       longs = (LPFC_SLI4_FCF_TBL_INDX_MAX + BITS_PER_LONG - 1)/BITS_PER_LONG;
+       phba->fcf.fcf_rr_bmask = kzalloc(longs * sizeof(unsigned long),
+                                        GFP_KERNEL);
+       if (!phba->fcf.fcf_rr_bmask) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                               "2759 Failed allocate memory for FCF round "
+                               "robin failover bmask\n");
+               goto out_remove_rpi_hdrs;
+       }
+
        phba->sli4_hba.fcp_eq_hdl = kzalloc((sizeof(struct lpfc_fcp_eq_hdl) *
                                    phba->cfg_fcp_eq_count), GFP_KERNEL);
        if (!phba->sli4_hba.fcp_eq_hdl) {
                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
                                "2572 Failed allocate memory for fast-path "
                                "per-EQ handle array\n");
-               goto out_remove_rpi_hdrs;
+               goto out_free_fcf_rr_bmask;
        }
 
        phba->sli4_hba.msix_entries = kzalloc((sizeof(struct msix_entry) *
@@ -3957,6 +4131,8 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
 
 out_free_fcp_eq_hdl:
        kfree(phba->sli4_hba.fcp_eq_hdl);
+out_free_fcf_rr_bmask:
+       kfree(phba->fcf.fcf_rr_bmask);
 out_remove_rpi_hdrs:
        lpfc_sli4_remove_rpi_hdrs(phba);
 out_free_active_sgl:
@@ -4002,6 +4178,9 @@ lpfc_sli4_driver_resource_unset(struct lpfc_hba *phba)
        lpfc_sli4_remove_rpi_hdrs(phba);
        lpfc_sli4_remove_rpis(phba);
 
+       /* Free eligible FCF index bmask */
+       kfree(phba->fcf.fcf_rr_bmask);
+
        /* Free the ELS sgl list */
        lpfc_free_active_sgl(phba);
        lpfc_free_sgl_list(phba);
@@ -4397,6 +4576,7 @@ lpfc_init_sgl_list(struct lpfc_hba *phba)
 
                /* The list order is used by later block SGL registraton */
                spin_lock_irq(&phba->hbalock);
+               sglq_entry->state = SGL_FREED;
                list_add_tail(&sglq_entry->list, &phba->sli4_hba.lpfc_sgl_list);
                phba->sli4_hba.lpfc_els_sgl_array[i] = sglq_entry;
                phba->sli4_hba.total_sglq_bufs++;
index 954ba57970a3ab294ef8db13d99ff798b6ca346c..bb59e927312674b4ff6fea061ca6549120290507 100644 (file)
@@ -35,6 +35,7 @@
 #define LOG_VPORT      0x00004000      /* NPIV events */
 #define LOF_SECURITY   0x00008000      /* Security events */
 #define LOG_EVENT      0x00010000      /* CT,TEMP,DUMP, logging */
+#define LOG_FIP                0x00020000      /* FIP events */
 #define LOG_ALL_MSG    0xffffffff      /* LOG all messages */
 
 #define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \
index 6c4dce1a30ca70dded02523804b133cc169c40af..72e6adb0643e09e50357706549a5a658703ee447 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/blkdev.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 
 #include <scsi/scsi_device.h>
@@ -1748,7 +1749,7 @@ lpfc_sli4_mbox_opcode_get(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
 }
 
 /**
- * lpfc_sli4_mbx_read_fcf_record - Allocate and construct read fcf mbox cmd
+ * lpfc_sli4_mbx_read_fcf_rec - Allocate and construct read fcf mbox cmd
  * @phba: pointer to lpfc hba data structure.
  * @fcf_index: index to fcf table.
  *
@@ -1759,9 +1760,9 @@ lpfc_sli4_mbox_opcode_get(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
  * NULL.
  **/
 int
-lpfc_sli4_mbx_read_fcf_record(struct lpfc_hba *phba,
-                             struct lpfcMboxq *mboxq,
-                             uint16_t fcf_index)
+lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *phba,
+                          struct lpfcMboxq *mboxq,
+                          uint16_t fcf_index)
 {
        void *virt_addr;
        dma_addr_t phys_addr;
index a1b6db6016da0aee42bf9753833012d26bad85e9..8f879e477e9d3a666f7cc490072cda2b29deaba0 100644 (file)
@@ -20,6 +20,7 @@
  *******************************************************************/
 
 #include <linux/mempool.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 
index d20ae6b3b3cf77552ad7061d8e311b34dd3f85b9..e331204a4d56a38c62398d76ffc76dd6f32be16e 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/blkdev.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 
 #include <scsi/scsi.h>
index 483fb74bc5922697f4077635f04121bbaa38d293..dccdb822328c2233ff72c89393acb663f53fc568 100644 (file)
@@ -19,6 +19,7 @@
  * included with this package.                                     *
  *******************************************************************/
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <asm/unaligned.h>
@@ -620,23 +621,40 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba,
        uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri);
        struct lpfc_scsi_buf *psb, *next_psb;
        unsigned long iflag = 0;
+       struct lpfc_iocbq *iocbq;
+       int i;
 
-       spin_lock_irqsave(&phba->sli4_hba.abts_scsi_buf_list_lock, iflag);
+       spin_lock_irqsave(&phba->hbalock, iflag);
+       spin_lock(&phba->sli4_hba.abts_scsi_buf_list_lock);
        list_for_each_entry_safe(psb, next_psb,
                &phba->sli4_hba.lpfc_abts_scsi_buf_list, list) {
                if (psb->cur_iocbq.sli4_xritag == xri) {
                        list_del(&psb->list);
                        psb->exch_busy = 0;
                        psb->status = IOSTAT_SUCCESS;
-                       spin_unlock_irqrestore(
-                               &phba->sli4_hba.abts_scsi_buf_list_lock,
-                               iflag);
+                       spin_unlock(
+                               &phba->sli4_hba.abts_scsi_buf_list_lock);
+                       spin_unlock_irqrestore(&phba->hbalock, iflag);
                        lpfc_release_scsi_buf_s4(phba, psb);
                        return;
                }
        }
-       spin_unlock_irqrestore(&phba->sli4_hba.abts_scsi_buf_list_lock,
-                               iflag);
+       spin_unlock(&phba->sli4_hba.abts_scsi_buf_list_lock);
+       for (i = 1; i <= phba->sli.last_iotag; i++) {
+               iocbq = phba->sli.iocbq_lookup[i];
+
+               if (!(iocbq->iocb_flag &  LPFC_IO_FCP) ||
+                       (iocbq->iocb_flag & LPFC_IO_LIBDFC))
+                       continue;
+               if (iocbq->sli4_xritag != xri)
+                       continue;
+               psb = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq);
+               psb->exch_busy = 0;
+               spin_unlock_irqrestore(&phba->hbalock, iflag);
+               return;
+
+       }
+       spin_unlock_irqrestore(&phba->hbalock, iflag);
 }
 
 /**
@@ -1006,6 +1024,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
        struct scatterlist *sgel = NULL;
        struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd;
        struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl;
+       struct lpfc_iocbq *iocbq = &lpfc_cmd->cur_iocbq;
        IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
        struct ulp_bde64 *data_bde = iocb_cmd->unsli3.fcp_ext.dbde;
        dma_addr_t physaddr;
@@ -1056,6 +1075,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
                        physaddr = sg_dma_address(sgel);
                        if (phba->sli_rev == 3 &&
                            !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) &&
+                           !(iocbq->iocb_flag & DSS_SECURITY_OP) &&
                            nseg <= LPFC_EXT_DATA_BDE_COUNT) {
                                data_bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
                                data_bde->tus.f.bdeSize = sg_dma_len(sgel);
@@ -1082,7 +1102,8 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
         * explicitly reinitialized since all iocb memory resources are reused.
         */
        if (phba->sli_rev == 3 &&
-           !(phba->sli3_options & LPFC_SLI3_BG_ENABLED)) {
+           !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) &&
+           !(iocbq->iocb_flag & DSS_SECURITY_OP)) {
                if (num_bde > LPFC_EXT_DATA_BDE_COUNT) {
                        /*
                         * The extended IOCB format can only fit 3 BDE or a BPL.
@@ -1107,6 +1128,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
        } else {
                iocb_cmd->un.fcpi64.bdl.bdeSize =
                        ((num_bde + 2) * sizeof(struct ulp_bde64));
+               iocb_cmd->unsli3.fcp_ext.ebde_count = (num_bde + 1);
        }
        fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd));
 
@@ -2079,8 +2101,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
 
        if (resp_info & RSP_LEN_VALID) {
                rsplen = be32_to_cpu(fcprsp->rspRspLen);
-               if ((rsplen != 0 && rsplen != 4 && rsplen != 8) ||
-                   (fcprsp->rspInfo3 != RSP_NO_FAILURE)) {
+               if (rsplen != 0 && rsplen != 4 && rsplen != 8) {
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
                                 "2719 Invalid response length: "
                                 "tgt x%x lun x%x cmnd x%x rsplen x%x\n",
@@ -2090,6 +2111,17 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
                        host_status = DID_ERROR;
                        goto out;
                }
+               if (fcprsp->rspInfo3 != RSP_NO_FAILURE) {
+                       lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+                                "2757 Protocol failure detected during "
+                                "processing of FCP I/O op: "
+                                "tgt x%x lun x%x cmnd x%x rspInfo3 x%x\n",
+                                cmnd->device->id,
+                                cmnd->device->lun, cmnd->cmnd[0],
+                                fcprsp->rspInfo3);
+                       host_status = DID_ERROR;
+                       goto out;
+               }
        }
 
        if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) {
index 35e3b96d4e079d2ae519dae5bb891fb955e9bcd6..049fb9a17b3f2c7ae730253709c65187289f418e 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -494,7 +495,7 @@ __lpfc_clear_active_sglq(struct lpfc_hba *phba, uint16_t xritag)
  *
  * Returns sglq ponter = success, NULL = Failure.
  **/
-static struct lpfc_sglq *
+struct lpfc_sglq *
 __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag)
 {
        uint16_t adj_xri;
@@ -526,6 +527,7 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba)
                return NULL;
        adj_xri = sglq->sli4_xritag - phba->sli4_hba.max_cfg_param.xri_base;
        phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq;
+       sglq->state = SGL_ALLOCATED;
        return sglq;
 }
 
@@ -580,15 +582,18 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
        else
                sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag);
        if (sglq)  {
-               if (iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) {
+               if ((iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) &&
+                       (sglq->state != SGL_XRI_ABORTED)) {
                        spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock,
                                        iflag);
                        list_add(&sglq->list,
                                &phba->sli4_hba.lpfc_abts_els_sgl_list);
                        spin_unlock_irqrestore(
                                &phba->sli4_hba.abts_sgl_list_lock, iflag);
-               } else
+               } else {
+                       sglq->state = SGL_FREED;
                        list_add(&sglq->list, &phba->sli4_hba.lpfc_sgl_list);
+               }
        }
 
 
@@ -2258,41 +2263,56 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                                        spin_unlock_irqrestore(&phba->hbalock,
                                                               iflag);
                                }
-                               if ((phba->sli_rev == LPFC_SLI_REV4) &&
-                                   (saveq->iocb_flag & LPFC_EXCHANGE_BUSY)) {
-                                       /* Set cmdiocb flag for the exchange
-                                        * busy so sgl (xri) will not be
-                                        * released until the abort xri is
-                                        * received from hba, clear the
-                                        * LPFC_DRIVER_ABORTED bit in case
-                                        * it was driver initiated abort.
-                                        */
-                                       spin_lock_irqsave(&phba->hbalock,
-                                                         iflag);
-                                       cmdiocbp->iocb_flag &=
-                                               ~LPFC_DRIVER_ABORTED;
-                                       cmdiocbp->iocb_flag |=
-                                               LPFC_EXCHANGE_BUSY;
-                                       spin_unlock_irqrestore(&phba->hbalock,
-                                                              iflag);
-                                       cmdiocbp->iocb.ulpStatus =
-                                               IOSTAT_LOCAL_REJECT;
-                                       cmdiocbp->iocb.un.ulpWord[4] =
-                                               IOERR_ABORT_REQUESTED;
-                                       /*
-                                        * For SLI4, irsiocb contains NO_XRI
-                                        * in sli_xritag, it shall not affect
-                                        * releasing sgl (xri) process.
-                                        */
-                                       saveq->iocb.ulpStatus =
-                                               IOSTAT_LOCAL_REJECT;
-                                       saveq->iocb.un.ulpWord[4] =
-                                               IOERR_SLI_ABORTED;
-                                       spin_lock_irqsave(&phba->hbalock,
-                                                         iflag);
-                                       saveq->iocb_flag |= LPFC_DELAY_MEM_FREE;
-                                       spin_unlock_irqrestore(&phba->hbalock,
-                                                              iflag);
+                               if (phba->sli_rev == LPFC_SLI_REV4) {
+                                       if (saveq->iocb_flag &
+                                           LPFC_EXCHANGE_BUSY) {
+                                               /* Set cmdiocb flag for the
+                                                * exchange busy so sgl (xri)
+                                                * will not be released until
+                                                * the abort xri is received
+                                                * from hba.
+                                                */
+                                               spin_lock_irqsave(
+                                                       &phba->hbalock, iflag);
+                                               cmdiocbp->iocb_flag |=
+                                                       LPFC_EXCHANGE_BUSY;
+                                               spin_unlock_irqrestore(
+                                                       &phba->hbalock, iflag);
+                                       }
+                                       if (cmdiocbp->iocb_flag &
+                                           LPFC_DRIVER_ABORTED) {
+                                               /*
+                                                * Clear LPFC_DRIVER_ABORTED
+                                                * bit in case it was driver
+                                                * initiated abort.
+                                                */
+                                               spin_lock_irqsave(
+                                                       &phba->hbalock, iflag);
+                                               cmdiocbp->iocb_flag &=
+                                                       ~LPFC_DRIVER_ABORTED;
+                                               spin_unlock_irqrestore(
+                                                       &phba->hbalock, iflag);
+                                               cmdiocbp->iocb.ulpStatus =
+                                                       IOSTAT_LOCAL_REJECT;
+                                               cmdiocbp->iocb.un.ulpWord[4] =
+                                                       IOERR_ABORT_REQUESTED;
+                                               /*
+                                                * For SLI4, irsiocb contains
+                                                * NO_XRI in sli_xritag, it
+                                                * shall not affect releasing
+                                                * sgl (xri) process.
+                                                */
+                                               saveq->iocb.ulpStatus =
+                                                       IOSTAT_LOCAL_REJECT;
+                                               saveq->iocb.un.ulpWord[4] =
+                                                       IOERR_SLI_ABORTED;
+                                               spin_lock_irqsave(
+                                                       &phba->hbalock, iflag);
+                                               saveq->iocb_flag |=
+                                                       LPFC_DELAY_MEM_FREE;
+                                               spin_unlock_irqrestore(
+                                                       &phba->hbalock, iflag);
+                                       }
                                }
                        }
                        (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq);
@@ -2515,14 +2535,16 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
 
                        cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
                                                         &rspiocbq);
-                       if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
-                                       spin_unlock_irqrestore(&phba->hbalock,
-                                                              iflag);
-                                       (cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
-                                                             &rspiocbq);
-                                       spin_lock_irqsave(&phba->hbalock,
-                                                         iflag);
-                               }
+                       if (unlikely(!cmdiocbq))
+                               break;
+                       if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED)
+                               cmdiocbq->iocb_flag &= ~LPFC_DRIVER_ABORTED;
+                       if (cmdiocbq->iocb_cmpl) {
+                               spin_unlock_irqrestore(&phba->hbalock, iflag);
+                               (cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
+                                                     &rspiocbq);
+                               spin_lock_irqsave(&phba->hbalock, iflag);
+                       }
                        break;
                case LPFC_UNSOL_IOCB:
                        spin_unlock_irqrestore(&phba->hbalock, iflag);
@@ -3091,6 +3113,12 @@ lpfc_sli_brdready_s3(struct lpfc_hba *phba, uint32_t mask)
 
        /* Check to see if any errors occurred during init */
        if ((status & HS_FFERM) || (i >= 20)) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                               "2751 Adapter failed to restart, "
+                               "status reg x%x, FW Data: A8 x%x AC x%x\n",
+                               status,
+                               readl(phba->MBslimaddr + 0xa8),
+                               readl(phba->MBslimaddr + 0xac));
                phba->link_state = LPFC_HBA_ERROR;
                retval = 1;
        }
@@ -3278,6 +3306,9 @@ lpfc_sli_brdkill(struct lpfc_hba *phba)
        if (retval != MBX_SUCCESS) {
                if (retval != MBX_BUSY)
                        mempool_free(pmb, phba->mbox_mem_pool);
+               lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+                               "2752 KILL_BOARD command failed retval %d\n",
+                               retval);
                spin_lock_irq(&phba->hbalock);
                phba->link_flag &= ~LS_IGNORE_ERATT;
                spin_unlock_irq(&phba->hbalock);
@@ -4035,7 +4066,7 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba)
 
 lpfc_sli_hba_setup_error:
        phba->link_state = LPFC_HBA_ERROR;
-       lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+       lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
                        "0445 Firmware initialization failed\n");
        return rc;
 }
@@ -4388,7 +4419,13 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
        spin_unlock_irq(&phba->hbalock);
 
        /* Read the port's service parameters. */
-       lpfc_read_sparam(phba, mboxq, vport->vpi);
+       rc = lpfc_read_sparam(phba, mboxq, vport->vpi);
+       if (rc) {
+               phba->link_state = LPFC_HBA_ERROR;
+               rc = -ENOMEM;
+               goto out_free_vpd;
+       }
+
        mboxq->vport = vport;
        rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
        mp = (struct lpfc_dmabuf *) mboxq->context1;
@@ -4483,6 +4520,10 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
        /* Post receive buffers to the device */
        lpfc_sli4_rb_setup(phba);
 
+       /* Reset HBA FCF states after HBA reset */
+       phba->fcf.fcf_flag = 0;
+       phba->fcf.current_rec.flag = 0;
+
        /* Start the ELS watchdog timer */
        mod_timer(&vport->els_tmofunc,
                  jiffies + HZ * (phba->fc_ratov * 2));
@@ -7436,6 +7477,7 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
 {
        wait_queue_head_t *pdone_q;
        unsigned long iflags;
+       struct lpfc_scsi_buf *lpfc_cmd;
 
        spin_lock_irqsave(&phba->hbalock, iflags);
        cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
@@ -7443,6 +7485,14 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
                memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
                       &rspiocbq->iocb, sizeof(IOCB_t));
 
+       /* Set the exchange busy flag for task management commands */
+       if ((cmdiocbq->iocb_flag & LPFC_IO_FCP) &&
+               !(cmdiocbq->iocb_flag & LPFC_IO_LIBDFC)) {
+               lpfc_cmd = container_of(cmdiocbq, struct lpfc_scsi_buf,
+                       cur_iocbq);
+               lpfc_cmd->exch_busy = rspiocbq->iocb_flag & LPFC_EXCHANGE_BUSY;
+       }
+
        pdone_q = cmdiocbq->context_un.wait_queue;
        if (pdone_q)
                wake_up(pdone_q);
@@ -9061,6 +9111,12 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba,
        /* Fake the irspiocb and copy necessary response information */
        lpfc_sli4_iocb_param_transfer(phba, &irspiocbq, cmdiocbq, wcqe);
 
+       if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED) {
+               spin_lock_irqsave(&phba->hbalock, iflags);
+               cmdiocbq->iocb_flag &= ~LPFC_DRIVER_ABORTED;
+               spin_unlock_irqrestore(&phba->hbalock, iflags);
+       }
+
        /* Pass the cmd_iocb and the rsp state to the upper layer */
        (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, &irspiocbq);
 }
@@ -11941,15 +11997,19 @@ lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *phba,
 }
 
 /**
- * lpfc_sli4_read_fcf_record - Read the driver's default FCF Record.
+ * lpfc_sli4_fcf_scan_read_fcf_rec - Read hba fcf record for fcf scan.
  * @phba: pointer to lpfc hba data structure.
  * @fcf_index: FCF table entry offset.
  *
- * This routine is invoked to read up to @fcf_num of FCF record from the
- * device starting with the given @fcf_index.
+ * This routine is invoked to scan the entire FCF table by reading FCF
+ * record and processing it one at a time starting from the @fcf_index
+ * for initial FCF discovery or fast FCF failover rediscovery.
+ *
+ * Return 0 if the mailbox command is submitted sucessfully, none 0
+ * otherwise.
  **/
 int
-lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index)
+lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
 {
        int rc = 0, error;
        LPFC_MBOXQ_t *mboxq;
@@ -11961,17 +12021,17 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index)
                                "2000 Failed to allocate mbox for "
                                "READ_FCF cmd\n");
                error = -ENOMEM;
-               goto fail_fcfscan;
+               goto fail_fcf_scan;
        }
        /* Construct the read FCF record mailbox command */
-       rc = lpfc_sli4_mbx_read_fcf_record(phba, mboxq, fcf_index);
+       rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index);
        if (rc) {
                error = -EINVAL;
-               goto fail_fcfscan;
+               goto fail_fcf_scan;
        }
        /* Issue the mailbox command asynchronously */
        mboxq->vport = phba->pport;
-       mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_record;
+       mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_scan_read_fcf_rec;
        rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
        if (rc == MBX_NOT_FINISHED)
                error = -EIO;
@@ -11979,9 +12039,13 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index)
                spin_lock_irq(&phba->hbalock);
                phba->hba_flag |= FCF_DISC_INPROGRESS;
                spin_unlock_irq(&phba->hbalock);
+               /* Reset FCF round robin index bmask for new scan */
+               if (fcf_index == LPFC_FCOE_FCF_GET_FIRST)
+                       memset(phba->fcf.fcf_rr_bmask, 0,
+                              sizeof(*phba->fcf.fcf_rr_bmask));
                error = 0;
        }
-fail_fcfscan:
+fail_fcf_scan:
        if (error) {
                if (mboxq)
                        lpfc_sli4_mbox_cmd_free(phba, mboxq);
@@ -11993,6 +12057,181 @@ fail_fcfscan:
        return error;
 }
 
+/**
+ * lpfc_sli4_fcf_rr_read_fcf_rec - Read hba fcf record for round robin fcf.
+ * @phba: pointer to lpfc hba data structure.
+ * @fcf_index: FCF table entry offset.
+ *
+ * This routine is invoked to read an FCF record indicated by @fcf_index
+ * and to use it for FLOGI round robin FCF failover.
+ *
+ * Return 0 if the mailbox command is submitted sucessfully, none 0
+ * otherwise.
+ **/
+int
+lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
+{
+       int rc = 0, error;
+       LPFC_MBOXQ_t *mboxq;
+
+       mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+       if (!mboxq) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_INIT,
+                               "2763 Failed to allocate mbox for "
+                               "READ_FCF cmd\n");
+               error = -ENOMEM;
+               goto fail_fcf_read;
+       }
+       /* Construct the read FCF record mailbox command */
+       rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index);
+       if (rc) {
+               error = -EINVAL;
+               goto fail_fcf_read;
+       }
+       /* Issue the mailbox command asynchronously */
+       mboxq->vport = phba->pport;
+       mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_rr_read_fcf_rec;
+       rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
+       if (rc == MBX_NOT_FINISHED)
+               error = -EIO;
+       else
+               error = 0;
+
+fail_fcf_read:
+       if (error && mboxq)
+               lpfc_sli4_mbox_cmd_free(phba, mboxq);
+       return error;
+}
+
+/**
+ * lpfc_sli4_read_fcf_rec - Read hba fcf record for update eligible fcf bmask.
+ * @phba: pointer to lpfc hba data structure.
+ * @fcf_index: FCF table entry offset.
+ *
+ * This routine is invoked to read an FCF record indicated by @fcf_index to
+ * determine whether it's eligible for FLOGI round robin failover list.
+ *
+ * Return 0 if the mailbox command is submitted sucessfully, none 0
+ * otherwise.
+ **/
+int
+lpfc_sli4_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
+{
+       int rc = 0, error;
+       LPFC_MBOXQ_t *mboxq;
+
+       mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+       if (!mboxq) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_INIT,
+                               "2758 Failed to allocate mbox for "
+                               "READ_FCF cmd\n");
+                               error = -ENOMEM;
+                               goto fail_fcf_read;
+       }
+       /* Construct the read FCF record mailbox command */
+       rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index);
+       if (rc) {
+               error = -EINVAL;
+               goto fail_fcf_read;
+       }
+       /* Issue the mailbox command asynchronously */
+       mboxq->vport = phba->pport;
+       mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_rec;
+       rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
+       if (rc == MBX_NOT_FINISHED)
+               error = -EIO;
+       else
+               error = 0;
+
+fail_fcf_read:
+       if (error && mboxq)
+               lpfc_sli4_mbox_cmd_free(phba, mboxq);
+       return error;
+}
+
+/**
+ * lpfc_sli4_fcf_rr_next_index_get - Get next eligible fcf record index
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is to get the next eligible FCF record index in a round
+ * robin fashion. If the next eligible FCF record index equals to the
+ * initial round robin FCF record index, LPFC_FCOE_FCF_NEXT_NONE (0xFFFF)
+ * shall be returned, otherwise, the next eligible FCF record's index
+ * shall be returned.
+ **/
+uint16_t
+lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *phba)
+{
+       uint16_t next_fcf_index;
+
+       /* Search from the currently registered FCF index */
+       next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask,
+                                      LPFC_SLI4_FCF_TBL_INDX_MAX,
+                                      phba->fcf.current_rec.fcf_indx);
+       /* Wrap around condition on phba->fcf.fcf_rr_bmask */
+       if (next_fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX)
+               next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask,
+                                              LPFC_SLI4_FCF_TBL_INDX_MAX, 0);
+       /* Round robin failover stop condition */
+       if (next_fcf_index == phba->fcf.fcf_rr_init_indx)
+               return LPFC_FCOE_FCF_NEXT_NONE;
+
+       return next_fcf_index;
+}
+
+/**
+ * lpfc_sli4_fcf_rr_index_set - Set bmask with eligible fcf record index
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine sets the FCF record index in to the eligible bmask for
+ * round robin failover search. It checks to make sure that the index
+ * does not go beyond the range of the driver allocated bmask dimension
+ * before setting the bit.
+ *
+ * Returns 0 if the index bit successfully set, otherwise, it returns
+ * -EINVAL.
+ **/
+int
+lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *phba, uint16_t fcf_index)
+{
+       if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
+                               "2610 HBA FCF index reached driver's "
+                               "book keeping dimension: fcf_index:%d, "
+                               "driver_bmask_max:%d\n",
+                               fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX);
+               return -EINVAL;
+       }
+       /* Set the eligible FCF record index bmask */
+       set_bit(fcf_index, phba->fcf.fcf_rr_bmask);
+
+       return 0;
+}
+
+/**
+ * lpfc_sli4_fcf_rr_index_set - Clear bmask from eligible fcf record index
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine clears the FCF record index from the eligible bmask for
+ * round robin failover search. It checks to make sure that the index
+ * does not go beyond the range of the driver allocated bmask dimension
+ * before clearing the bit.
+ **/
+void
+lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *phba, uint16_t fcf_index)
+{
+       if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
+                               "2762 HBA FCF index goes beyond driver's "
+                               "book keeping dimension: fcf_index:%d, "
+                               "driver_bmask_max:%d\n",
+                               fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX);
+               return;
+       }
+       /* Clear the eligible FCF record index bmask */
+       clear_bit(fcf_index, phba->fcf.fcf_rr_bmask);
+}
+
 /**
  * lpfc_mbx_cmpl_redisc_fcf_table - completion routine for rediscover FCF table
  * @phba: pointer to lpfc hba data structure.
@@ -12014,21 +12253,40 @@ lpfc_mbx_cmpl_redisc_fcf_table(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
        shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
                             &redisc_fcf->header.cfg_shdr.response);
        if (shdr_status || shdr_add_status) {
-               lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+               lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
                                "2746 Requesting for FCF rediscovery failed "
                                "status x%x add_status x%x\n",
                                shdr_status, shdr_add_status);
-               /*
-                * Request failed, last resort to re-try current
-                * registered FCF entry
-                */
-               lpfc_retry_pport_discovery(phba);
-       } else
+               if (phba->fcf.fcf_flag & FCF_ACVL_DISC) {
+                       spin_lock_irq(&phba->hbalock);
+                       phba->fcf.fcf_flag &= ~FCF_ACVL_DISC;
+                       spin_unlock_irq(&phba->hbalock);
+                       /*
+                        * CVL event triggered FCF rediscover request failed,
+                        * last resort to re-try current registered FCF entry.
+                        */
+                       lpfc_retry_pport_discovery(phba);
+               } else {
+                       spin_lock_irq(&phba->hbalock);
+                       phba->fcf.fcf_flag &= ~FCF_DEAD_DISC;
+                       spin_unlock_irq(&phba->hbalock);
+                       /*
+                        * DEAD FCF event triggered FCF rediscover request
+                        * failed, last resort to fail over as a link down
+                        * to FCF registration.
+                        */
+                       lpfc_sli4_fcf_dead_failthrough(phba);
+               }
+       } else {
+               lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                               "2775 Start FCF rediscovery quiescent period "
+                               "wait timer before scaning FCF table\n");
                /*
                 * Start FCF rediscovery wait timer for pending FCF
                 * before rescan FCF record table.
                 */
                lpfc_fcf_redisc_wait_start_timer(phba);
+       }
 
        mempool_free(mbox, phba->mbox_mem_pool);
 }
@@ -12047,6 +12305,9 @@ lpfc_sli4_redisc_fcf_table(struct lpfc_hba *phba)
        struct lpfc_mbx_redisc_fcf_tbl *redisc_fcf;
        int rc, length;
 
+       /* Cancel retry delay timers to all vports before FCF rediscover */
+       lpfc_cancel_all_vport_retry_delay_timer(phba);
+
        mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
        if (!mbox) {
                lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
@@ -12077,6 +12338,31 @@ lpfc_sli4_redisc_fcf_table(struct lpfc_hba *phba)
        return 0;
 }
 
+/**
+ * lpfc_sli4_fcf_dead_failthrough - Failthrough routine to fcf dead event
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This function is the failover routine as a last resort to the FCF DEAD
+ * event when driver failed to perform fast FCF failover.
+ **/
+void
+lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *phba)
+{
+       uint32_t link_state;
+
+       /*
+        * Last resort as FCF DEAD event failover will treat this as
+        * a link down, but save the link state because we don't want
+        * it to be changed to Link Down unless it is already down.
+        */
+       link_state = phba->link_state;
+       lpfc_linkdown(phba);
+       phba->link_state = link_state;
+
+       /* Unregister FCF if no devices connected to it */
+       lpfc_unregister_unused_fcf(phba);
+}
+
 /**
  * lpfc_sli_read_link_ste - Read region 23 to decide if link is disabled.
  * @phba: pointer to lpfc hba data structure.
index dfcf5437d1f53ce9f91001f1fbd1e9f66e4944a0..b4a639c47616b94dd51a3790d2e72f47d9cf0d5a 100644 (file)
@@ -62,6 +62,7 @@ struct lpfc_iocbq {
 #define LPFC_DELAY_MEM_FREE    0x20    /* Defer free'ing of FC data */
 #define LPFC_EXCHANGE_BUSY     0x40    /* SLI4 hba reported XB in response */
 #define LPFC_USE_FCPWQIDX      0x80    /* Submit to specified FCPWQ index */
+#define DSS_SECURITY_OP                0x100   /* security IO */
 
 #define LPFC_FIP_ELS_ID_MASK   0xc000  /* ELS_ID range 0-3, non-shifted mask */
 #define LPFC_FIP_ELS_ID_SHIFT  14
index 86308836600f29df3afb2da145c3f877b552498c..4a35e7b9bc5b2bd0e36b947cfc77168921c721f6 100644 (file)
@@ -153,15 +153,27 @@ struct lpfc_fcf {
 #define FCF_REGISTERED 0x02 /* FCF registered with FW */
 #define FCF_SCAN_DONE  0x04 /* FCF table scan done */
 #define FCF_IN_USE     0x08 /* Atleast one discovery completed */
-#define FCF_REDISC_PEND        0x10 /* FCF rediscovery pending */
-#define FCF_REDISC_EVT 0x20 /* FCF rediscovery event to worker thread */
-#define FCF_REDISC_FOV 0x40 /* Post FCF rediscovery fast failover */
+#define FCF_INIT_DISC  0x10 /* Initial FCF discovery */
+#define FCF_DEAD_DISC  0x20 /* FCF DEAD fast FCF failover discovery */
+#define FCF_ACVL_DISC  0x40 /* All CVL fast FCF failover discovery */
+#define FCF_DISCOVERY  (FCF_INIT_DISC | FCF_DEAD_DISC | FCF_ACVL_DISC)
+#define FCF_REDISC_PEND        0x80 /* FCF rediscovery pending */
+#define FCF_REDISC_EVT 0x100 /* FCF rediscovery event to worker thread */
+#define FCF_REDISC_FOV 0x200 /* Post FCF rediscovery fast failover */
        uint32_t addr_mode;
+       uint16_t fcf_rr_init_indx;
        struct lpfc_fcf_rec current_rec;
        struct lpfc_fcf_rec failover_rec;
        struct timer_list redisc_wait;
+       unsigned long *fcf_rr_bmask; /* Eligible FCF indexes for RR failover */
 };
 
+/*
+ * Maximum FCF table index, it is for driver internal book keeping, it
+ * just needs to be no less than the supported HBA's FCF table size.
+ */
+#define LPFC_SLI4_FCF_TBL_INDX_MAX     32
+
 #define LPFC_REGION23_SIGNATURE "RG23"
 #define LPFC_REGION23_VERSION  1
 #define LPFC_REGION23_LAST_REC  0xff
@@ -431,11 +443,18 @@ enum lpfc_sge_type {
        SCSI_BUFF_TYPE
 };
 
+enum lpfc_sgl_state {
+       SGL_FREED,
+       SGL_ALLOCATED,
+       SGL_XRI_ABORTED
+};
+
 struct lpfc_sglq {
        /* lpfc_sglqs are used in double linked lists */
        struct list_head list;
        struct list_head clist;
        enum lpfc_sge_type buff_type; /* is this a scsi sgl */
+       enum lpfc_sgl_state state;
        uint16_t iotag;         /* pre-assigned IO tag */
        uint16_t sli4_xritag;   /* pre-assigned XRI, (OXID) tag. */
        struct sli4_sge *sgl;   /* pre-assigned SGL */
@@ -463,8 +482,8 @@ void lpfc_sli4_mbox_cmd_free(struct lpfc_hba *, struct lpfcMboxq *);
 void lpfc_sli4_mbx_sge_set(struct lpfcMboxq *, uint32_t, dma_addr_t, uint32_t);
 void lpfc_sli4_mbx_sge_get(struct lpfcMboxq *, uint32_t,
                           struct lpfc_mbx_sge *);
-int lpfc_sli4_mbx_read_fcf_record(struct lpfc_hba *, struct lpfcMboxq *,
-                                 uint16_t);
+int lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *, struct lpfcMboxq *,
+                              uint16_t);
 
 void lpfc_sli4_hba_reset(struct lpfc_hba *);
 struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *, uint32_t,
@@ -523,8 +542,13 @@ int lpfc_sli4_init_vpi(struct lpfc_hba *, uint16_t);
 uint32_t lpfc_sli4_cq_release(struct lpfc_queue *, bool);
 uint32_t lpfc_sli4_eq_release(struct lpfc_queue *, bool);
 void lpfc_sli4_fcfi_unreg(struct lpfc_hba *, uint16_t);
-int lpfc_sli4_read_fcf_record(struct lpfc_hba *, uint16_t);
-void lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *, LPFC_MBOXQ_t *);
+int lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *, uint16_t);
+int lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *, uint16_t);
+int lpfc_sli4_read_fcf_rec(struct lpfc_hba *, uint16_t);
+void lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *);
+int lpfc_sli4_unregister_fcf(struct lpfc_hba *);
 int lpfc_sli4_post_status_check(struct lpfc_hba *);
 uint8_t lpfc_sli4_mbox_opcode_get(struct lpfc_hba *, struct lpfcMboxq *);
 
index ac276aa46fba58489a893bdb66845caea6b6fa7e..013deec5dae8a786acc35d982f9cc106ba3a407e 100644 (file)
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.3.9"
+#define LPFC_DRIVER_VERSION "8.3.10"
 #define LPFC_DRIVER_NAME               "lpfc"
 #define LPFC_SP_DRIVER_HANDLER_NAME    "lpfc:sp"
 #define LPFC_FP_DRIVER_HANDLER_NAME    "lpfc:fp"
index dc86e873102a1763a445e285b9d671d7411058a8..ffd575c379f34b9b046415f4c11737e10677b6e4 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/interrupt.h>
 #include <linux/kthread.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 
 #include <scsi/scsi.h>
@@ -123,7 +124,12 @@ lpfc_vport_sparm(struct lpfc_hba *phba, struct lpfc_vport *vport)
        }
        mb = &pmb->u.mb;
 
-       lpfc_read_sparam(phba, pmb, vport->vpi);
+       rc = lpfc_read_sparam(phba, pmb, vport->vpi);
+       if (rc) {
+               mempool_free(pmb, phba->mbox_mem_pool);
+               return -ENOMEM;
+       }
+
        /*
         * Grab buffer pointer and clear context1 so we can use
         * lpfc_sli_issue_box_wait
index 4a90eaf7cb63ac5a7e8f874ca9868f596924567a..3893337e3dd3ff05155f7dd99cf5db356adde3f0 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/nubus.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 #include <asm/dma.h>
index 49eb0612d5af03f10e8b2ad591ed0bbf25943557..4bf7edca9e69a249fa29642650640250053dde56 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include <scsi/scsicam.h>
 
 #include "scsi.h"
index 7f977967b884892c5626a0e09c75756a7127d625..a7810a106b37aed653e5183c192e60d1758d30bb 100644 (file)
@@ -70,6 +70,7 @@
  * For history of changes, see Documentation/ChangeLog.megaraid
  */
 
+#include <linux/slab.h>
 #include "megaraid_mbox.h"
 
 static int megaraid_init(void);
index f680561d2c6f6101bac31fb4ad5ef7dcf2ded20c..36e0b7d05c1dbc13cc6252094f02b68fbabc02c4 100644 (file)
@@ -15,6 +15,7 @@
  * Common management module
  */
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include "megaraid_mm.h"
 
index 409648f5845f06c6ff3d0c435164efc060e561ba..99e4478c3f3ed4efc8d018ee2cc5f3b98d941514 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/delay.h>
 #include <linux/smp_lock.h>
 #include <linux/uio.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/fs.h>
 #include <linux/compat.h>
index 11aa917629acda4924a7db48e2f7e5bd5254347f..a1c97e88068ae961ce3605ecfe1143f2c80af7b3 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/delay.h>
 #include <linux/types.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
index 411c27d7f787f1bed4d85f7fd956d8f211709698..cf44b355bc972797cff74ea6b88e56c0d210ddcf 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/workqueue.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include "mpt2sas_base.h"
 
index c7ec3f17478220e5637750a52fc5621a38390443..be171ed682e08c2fe165bcee16fa627cac33f702 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/raid_class.h>
+#include <linux/slab.h>
 
 #include "mpt2sas_base.h"
 
index 789f9ee7f00157fa10ec3f292725c9b1ee666d7c..bd7ca2b49f81516989469f84971e726a9227d5bb 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/workqueue.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index b5fbfd6ce870af0294bb909fa3ea42455bf8a8ae..39f554f5f26114b1e5a7f401036974d9119cc697 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <asm/mvme16xhw.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
index aa2270af1bac55c2d926c14ff955ac5d85cc15ad..885858bcc403b56e906a30bc5883d21d2b4e761c 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <scsi/libsas.h>
 #include <scsi/scsi_tcq.h>
index a2d569828308f341bb8261b7ff824f118ee74cad..d013a2aa2fd54aac8e6d251f4aa2267ebe669922 100644 (file)
@@ -98,6 +98,7 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
index 2c98a6ee973bc442d8ce40a924be3c456aa9ac6f..4c1e545452009c957baed7fa590018d93b4a3bfe 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/ioport.h>
index 24223473f573c9b9e3ffd51714e015a68f8fa0cb..ee4b6914667f9cb2a55c9f20f493bfb971357a9d 100644 (file)
@@ -39,6 +39,8 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
+
 #include <scsi/osd_initiator.h>
 #include <scsi/osd_sec.h>
 #include <scsi/osd_attributes.h>
@@ -1433,6 +1435,10 @@ int osd_finalize_request(struct osd_request *or,
        cdbh->command_specific_options |= or->attributes_mode;
        if (or->attributes_mode == OSD_CDB_GET_ATTR_PAGE_SET_ONE) {
                ret = _osd_req_finalize_attr_page(or);
+               if (ret) {
+                       OSD_DEBUG("_osd_req_finalize_attr_page failed\n");
+                       return ret;
+               }
        } else {
                /* TODO: I think that for the GET_ATTR command these 2 should
                 * be reversed to keep them in execution order (for embeded
index 0a90702b3d710101904b73defb89a9a8d5580c67..ffdd9fdb9995bcd158ae293e353fbaf99a19171f 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/idr.h>
 #include <linux/major.h>
 #include <linux/file.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_driver.h>
index acb835837eec6213cae3f70679406570a5eba557..b219118f8bd6abccc03d6cc9e3c9f4500c7c9de3 100644 (file)
@@ -38,6 +38,7 @@ static const char * osst_version = "0.99.4";
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/errno.h>
index c2341af587a3111e1920678400f75be246afb017..02124645487215aa7b02d7da572d66798aa5f0e6 100644 (file)
@@ -1717,6 +1717,7 @@ static int nsp_cs_config(struct pcmcia_device *link)
        cfg_mem->data = data;
 
        ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem);
+       if (ret)
                goto cs_failed;
 
        if (link->conf.Attributes & CONF_ENABLE_IRQ) {
index 14b13acae6dde617a416d85a4c05185dbb61b0a3..45bc197bc22f2a45c46f5176cabefddc69e077f2 100644 (file)
@@ -38,6 +38,7 @@
  *
  */
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include "pm8001_sas.h"
 #include "pm8001_ctl.h"
 
index 7985ae45d68867487cad097777cdbbc0f11918fe..909c00ec044f35e0904b19ce9c900917f02a03a8 100644 (file)
@@ -37,6 +37,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  *
  */
+ #include <linux/slab.h>
  #include "pm8001_sas.h"
  #include "pm8001_hwi.h"
  #include "pm8001_chips.h"
index f80c1da8f6ca340b187ae08fc3a09e3341fe99b7..f8c86b28f03f8155c70c9303c9f57de9543acff9 100644 (file)
@@ -38,6 +38,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include "pm8001_sas.h"
 #include "pm8001_chips.h"
 
index 3b2c98fba834323e000d77eeae2fb3d7b3b2f3a9..bff4f5139b9cb87dceedeb7074a479047f1b686e 100644 (file)
@@ -38,6 +38,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include "pm8001_sas.h"
 
 /**
index 9b1c1433c26bd1b538833397bd8e38d5f619a6da..53aefffbaead2027c09d2da7925fe3c0afecb607 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/hdreg.h>
 #include <linux/version.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <asm/irq.h>
 #include <asm/processor.h>
 #include <linux/libata.h>
index 8aa0bd987e29e95d2f18578e8d64c9900e59062e..7bc2d796e4037712dd1113fe1e94d81f09782b85 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/blkdev.h>
 #include <linux/parport.h>
index db90caf43f42d06eccd70516c857aea39fe4e437..92ffbb5104980dc98bde7d839dce1cd6548d385d 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/cdrom.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index 49ac4148493b9746a31cfdc50dcbe8a6d705f618..b8166ecfd0e35f17894a077679d5f5d2a29701cf 100644 (file)
 * General Public License for more details.
 *
 ******************************************************************************/
-#define QLA1280_VERSION      "3.27"
+#define QLA1280_VERSION      "3.27.1"
 /*****************************************************************************
     Revision History:
+    Rev  3.27.1, February 8, 2010, Michael Reed
+       - Retain firmware image for error recovery.
     Rev  3.27, February 10, 2009, Michael Reed
        - General code cleanup.
        - Improve error recovery.
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
-#include <linux/slab.h>
 #include <linux/pci_ids.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -538,9 +539,9 @@ __setup("qla1280=", qla1280_setup);
 /*****************************************/
 
 struct qla_boards {
-       unsigned char name[9];  /* Board ID String */
+       char *name;             /* Board ID String */
        int numPorts;           /* Number of SCSI ports */
-       char *fwname;           /* firmware name        */
+       int fw_index;           /* index into qla1280_fw_tbl for firmware */
 };
 
 /* NOTE: the last argument in each entry is used to index ql1280_board_tbl */
@@ -561,15 +562,30 @@ static struct pci_device_id qla1280_pci_tbl[] = {
 };
 MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl);
 
+DEFINE_MUTEX(qla1280_firmware_mutex);
+
+struct qla_fw {
+       char *fwname;
+       const struct firmware *fw;
+};
+
+#define QL_NUM_FW_IMAGES 3
+
+struct qla_fw qla1280_fw_tbl[QL_NUM_FW_IMAGES] = {
+       {"qlogic/1040.bin",  NULL},     /* image 0 */
+       {"qlogic/1280.bin",  NULL},     /* image 1 */
+       {"qlogic/12160.bin", NULL},     /* image 2 */
+};
+
+/* NOTE: Order of boards in this table must match order in qla1280_pci_tbl */
 static struct qla_boards ql1280_board_tbl[] = {
-       /* Name ,  Number of ports, FW details */
-       {"QLA12160",    2, "qlogic/12160.bin"},
-       {"QLA1040",     1, "qlogic/1040.bin"},
-       {"QLA1080",     1, "qlogic/1280.bin"},
-       {"QLA1240",     2, "qlogic/1280.bin"},
-       {"QLA1280",     2, "qlogic/1280.bin"},
-       {"QLA10160",    1, "qlogic/12160.bin"},
-       {"        ",    0, "   "},
+       {.name = "QLA12160", .numPorts = 2, .fw_index = 2},
+       {.name = "QLA1040" , .numPorts = 1, .fw_index = 0},
+       {.name = "QLA1080" , .numPorts = 1, .fw_index = 1},
+       {.name = "QLA1240" , .numPorts = 2, .fw_index = 1},
+       {.name = "QLA1280" , .numPorts = 2, .fw_index = 1},
+       {.name = "QLA10160", .numPorts = 1, .fw_index = 2},
+       {.name = "        ", .numPorts = 0, .fw_index = -1},
 };
 
 static int qla1280_verbose = 1;
@@ -1511,6 +1527,63 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha)
        return status;
 }
 
+/*
+ * qla1280_request_firmware
+ *      Acquire firmware for chip.  Retain in memory
+ *      for error recovery.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ *
+ * Returns:
+ *      Pointer to firmware image or an error code
+ *      cast to pointer via ERR_PTR().
+ */
+static const struct firmware *
+qla1280_request_firmware(struct scsi_qla_host *ha)
+{
+       const struct firmware *fw;
+       int err;
+       int index;
+       char *fwname;
+
+       spin_unlock_irq(ha->host->host_lock);
+       mutex_lock(&qla1280_firmware_mutex);
+
+       index = ql1280_board_tbl[ha->devnum].fw_index;
+       fw = qla1280_fw_tbl[index].fw;
+       if (fw)
+               goto out;
+
+       fwname = qla1280_fw_tbl[index].fwname;
+       err = request_firmware(&fw, fwname, &ha->pdev->dev);
+
+       if (err) {
+               printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+                      fwname, err);
+               fw = ERR_PTR(err);
+               goto unlock;
+       }
+       if ((fw->size % 2) || (fw->size < 6)) {
+               printk(KERN_ERR "Invalid firmware length %zu in image \"%s\"\n",
+                      fw->size, fwname);
+               release_firmware(fw);
+               fw = ERR_PTR(-EINVAL);
+               goto unlock;
+       }
+
+       qla1280_fw_tbl[index].fw = fw;
+
+ out:
+       ha->fwver1 = fw->data[0];
+       ha->fwver2 = fw->data[1];
+       ha->fwver3 = fw->data[2];
+ unlock:
+       mutex_unlock(&qla1280_firmware_mutex);
+       spin_lock_irq(ha->host->host_lock);
+       return fw;
+}
+
 /*
  * Chip diagnostics
  *      Test chip for proper operation.
@@ -1634,30 +1707,18 @@ qla1280_chip_diag(struct scsi_qla_host *ha)
 static int
 qla1280_load_firmware_pio(struct scsi_qla_host *ha)
 {
+       /* enter with host_lock acquired */
+
        const struct firmware *fw;
        const __le16 *fw_data;
        uint16_t risc_address, risc_code_size;
        uint16_t mb[MAILBOX_REGISTER_COUNT], i;
-       int err;
+       int err = 0;
+
+       fw = qla1280_request_firmware(ha);
+       if (IS_ERR(fw))
+               return PTR_ERR(fw);
 
-       spin_unlock_irq(ha->host->host_lock);
-       err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
-                              &ha->pdev->dev);
-       spin_lock_irq(ha->host->host_lock);
-       if (err) {
-               printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
-                      ql1280_board_tbl[ha->devnum].fwname, err);
-               return err;
-       }
-       if ((fw->size % 2) || (fw->size < 6)) {
-               printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
-                      fw->size, ql1280_board_tbl[ha->devnum].fwname);
-               err = -EINVAL;
-               goto out;
-       }
-       ha->fwver1 = fw->data[0];
-       ha->fwver2 = fw->data[1];
-       ha->fwver3 = fw->data[2];
        fw_data = (const __le16 *)&fw->data[0];
        ha->fwstart = __le16_to_cpu(fw_data[2]);
 
@@ -1675,11 +1736,10 @@ qla1280_load_firmware_pio(struct scsi_qla_host *ha)
                if (err) {
                        printk(KERN_ERR "scsi(%li): Failed to load firmware\n",
                                        ha->host_no);
-                       goto out;
+                       break;
                }
        }
-out:
-       release_firmware(fw);
+
        return err;
 }
 
@@ -1687,6 +1747,7 @@ out:
 static int
 qla1280_load_firmware_dma(struct scsi_qla_host *ha)
 {
+       /* enter with host_lock acquired */
        const struct firmware *fw;
        const __le16 *fw_data;
        uint16_t risc_address, risc_code_size;
@@ -1701,24 +1762,10 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
                return -ENOMEM;
 #endif
 
-       spin_unlock_irq(ha->host->host_lock);
-       err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
-                              &ha->pdev->dev);
-       spin_lock_irq(ha->host->host_lock);
-       if (err) {
-               printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
-                      ql1280_board_tbl[ha->devnum].fwname, err);
-               return err;
-       }
-       if ((fw->size % 2) || (fw->size < 6)) {
-               printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
-                      fw->size, ql1280_board_tbl[ha->devnum].fwname);
-               err = -EINVAL;
-               goto out;
-       }
-       ha->fwver1 = fw->data[0];
-       ha->fwver2 = fw->data[1];
-       ha->fwver3 = fw->data[2];
+       fw = qla1280_request_firmware(ha);
+       if (IS_ERR(fw))
+               return PTR_ERR(fw);
+
        fw_data = (const __le16 *)&fw->data[0];
        ha->fwstart = __le16_to_cpu(fw_data[2]);
 
@@ -1803,7 +1850,6 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
 #if DUMP_IT_BACK
        pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf);
 #endif
-       release_firmware(fw);
        return err;
 }
 
@@ -1842,6 +1888,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha)
 static int
 qla1280_load_firmware(struct scsi_qla_host *ha)
 {
+       /* enter with host_lock taken */
        int err;
 
        err = qla1280_chip_diag(ha);
@@ -4420,7 +4467,16 @@ qla1280_init(void)
 static void __exit
 qla1280_exit(void)
 {
+       int i;
+
        pci_unregister_driver(&qla1280_pci_driver);
+       /* release any allocated firmware images */
+       for (i = 0; i < QL_NUM_FW_IMAGES; i++) {
+               if (qla1280_fw_tbl[i].fw) {
+                       release_firmware(qla1280_fw_tbl[i].fw);
+                       qla1280_fw_tbl[i].fw = NULL;
+               }
+       }
 }
 
 module_init(qla1280_init);
index 90d1e062ec4f13461bc428d41c17f4e03e007932..1c7ef55966fb528db0dfc9422434cbd78ba528f8 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/kthread.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 
 static int qla24xx_vport_disable(struct fc_vport *, bool);
@@ -1274,7 +1275,11 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr,
        int rval = QLA_FUNCTION_FAILED;
        uint16_t state[5];
 
-       if (!vha->hw->flags.eeh_busy)
+       if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
+               test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
+               DEBUG2_3_11(printk("%s(%ld): isp reset in progress.\n",
+                       __func__, vha->host_no));
+       else if (!vha->hw->flags.eeh_busy)
                rval = qla2x00_get_firmware_state(vha, state);
        if (rval != QLA_SUCCESS)
                memset(state, -1, sizeof(state));
@@ -2388,6 +2393,7 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
        return 0;
 
 done:
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
        if (bsg_job->request->msgcode == FC_BSG_HST_CT)
                kfree(sp->fcport);
        kfree(sp->ctx);
index cebf4f1bb7d9686248a8abb6f787e75c2658ac00..42c5587cc50cd0e8cfdc24edb6e6c038d04cdf0a 100644 (file)
@@ -1592,10 +1592,22 @@ struct nvram_81xx {
 
        /* Offset 384. */
        uint8_t reserved_21[16];
-       uint16_t reserved_22[8];
+       uint16_t reserved_22[3];
+
+       /*
+        * BIT 0 = Extended BB credits for LR
+        * BIT 1 = Virtual Fabric Enable
+        * BIT 2 = Enhanced Features Unused
+        * BIT 3-7 = Enhanced Features Reserved
+        */
+       /* Enhanced Features */
+       uint8_t enhanced_features;
+
+       uint8_t reserved_23;
+       uint16_t reserved_24[4];
 
        /* Offset 416. */
-       uint16_t reserved_23[32];
+       uint16_t reserved_25[32];
 
        /* Offset 480. */
        uint8_t model_name[16];
@@ -1603,7 +1615,7 @@ struct nvram_81xx {
        /* Offset 496. */
        uint16_t feature_mask_l;
        uint16_t feature_mask_h;
-       uint16_t reserved_24[2];
+       uint16_t reserved_26[2];
 
        uint16_t subsystem_vendor_id;
        uint16_t subsystem_device_id;
index a67b2bafb88242201a047da0e47dc8880d9a6312..4229bb483c5e02421d5746c8070a42450392ddec 100644 (file)
@@ -8,6 +8,7 @@
 #include "qla_gbl.h"
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include "qla_devtbl.h"
index ab90329ff2e4877ce57ccd15e1a7ee28ab5acd9f..db539b0c3dae71cbe8b86609b44409c6c7f3f56b 100644 (file)
@@ -7,6 +7,7 @@
 #include "qla_def.h"
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi_bsg_fc.h>
 
@@ -620,11 +621,10 @@ skip_rio:
                 *           vp_idx does not match
                 *       Event is not global, vp_idx does not match
                 */
-               if ((mb[1] == 0xffff && (mb[3] & 0xff) != 0xff)
-                       || (mb[1] != 0xffff)) {
-                       if (vha->vp_idx != (mb[3] & 0xff))
-                               break;
-               }
+               if (IS_QLA2XXX_MIDTYPE(ha) &&
+                   ((mb[1] == 0xffff && (mb[3] & 0xff) != 0xff) ||
+                       (mb[1] != 0xffff)) && vha->vp_idx != (mb[3] & 0xff))
+                       break;
 
                /* Global event -- port logout or port unavailable. */
                if (mb[1] == 0xffff && mb[2] == 0x7) {
@@ -2272,30 +2272,28 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
 
        /* If possible, enable MSI-X. */
        if (!IS_QLA2432(ha) && !IS_QLA2532(ha) &&
-           !IS_QLA8432(ha) && !IS_QLA8001(ha))
-               goto skip_msix;
+               !IS_QLA8432(ha) && !IS_QLA8001(ha))
+               goto skip_msi;
+
+       if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
+               (ha->pdev->subsystem_device == 0x7040 ||
+               ha->pdev->subsystem_device == 0x7041 ||
+               ha->pdev->subsystem_device == 0x1705)) {
+               DEBUG2(qla_printk(KERN_WARNING, ha,
+                       "MSI-X: Unsupported ISP2432 SSVID/SSDID (0x%X,0x%X).\n",
+                       ha->pdev->subsystem_vendor,
+                       ha->pdev->subsystem_device));
+               goto skip_msi;
+       }
 
        if (IS_QLA2432(ha) && (ha->pdev->revision < QLA_MSIX_CHIP_REV_24XX ||
                !QLA_MSIX_FW_MODE_1(ha->fw_attributes))) {
                DEBUG2(qla_printk(KERN_WARNING, ha,
                "MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n",
                        ha->pdev->revision, ha->fw_attributes));
-
                goto skip_msix;
        }
 
-       if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
-           (ha->pdev->subsystem_device == 0x7040 ||
-               ha->pdev->subsystem_device == 0x7041 ||
-               ha->pdev->subsystem_device == 0x1705)) {
-               DEBUG2(qla_printk(KERN_WARNING, ha,
-                   "MSI-X: Unsupported ISP2432 SSVID/SSDID (0x%X, 0x%X).\n",
-                   ha->pdev->subsystem_vendor,
-                   ha->pdev->subsystem_device));
-
-               goto skip_msi;
-       }
-
        ret = qla24xx_enable_msix(ha, rsp);
        if (!ret) {
                DEBUG2(qla_printk(KERN_INFO, ha,
index 6e53bdbb1da8ffe3a3fb240a9867efd08fbf3efd..42eb7ffd5942ed2e9a4243a01ece11e85bceeb0f 100644 (file)
@@ -7,6 +7,7 @@
 #include "qla_def.h"
 
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 
 /*
@@ -339,6 +340,7 @@ qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr,
        return rval;
 }
 
+#define        EXTENDED_BB_CREDITS     BIT_0
 /*
  * qla2x00_execute_fw
  *     Start adapter firmware.
@@ -371,7 +373,12 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
                mcp->mb[1] = MSW(risc_addr);
                mcp->mb[2] = LSW(risc_addr);
                mcp->mb[3] = 0;
-               mcp->mb[4] = 0;
+               if (IS_QLA81XX(ha)) {
+                       struct nvram_81xx *nv = ha->nvram;
+                       mcp->mb[4] = (nv->enhanced_features &
+                           EXTENDED_BB_CREDITS);
+               } else
+                       mcp->mb[4] = 0;
                mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
                mcp->in_mb |= MBX_1;
        } else {
index ff17dee286131f3c6ba49a9f5c1626bb93189b3a..8220e7b9799bb4cc7dd819bd28dc59c11f082a96 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/moduleparam.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 
 #include <scsi/scsi_tcq.h>
index 46720b23028f72850989cdef77b3a13cd477479f..48c37e38ed0172b137b99a0effaabc9049375a9b 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kthread.h>
 #include <linux/mutex.h>
 #include <linux/kobject.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsicam.h>
@@ -1676,9 +1677,11 @@ skip_pio:
 
        /* Determine queue resources */
        ha->max_req_queues = ha->max_rsp_queues = 1;
-       if ((ql2xmaxqueues <= 1 || ql2xmultique_tag < 1) &&
+       if ((ql2xmaxqueues <= 1 && !ql2xmultique_tag) ||
+               (ql2xmaxqueues > 1 && ql2xmultique_tag) ||
                (!IS_QLA25XX(ha) && !IS_QLA81XX(ha)))
                goto mqiobase_exit;
+
        ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3),
                        pci_resource_len(ha->pdev, 3));
        if (ha->mqiobase) {
index 371dc895972ae349ffb878eff28b62b5015e8366..8b3de4e54c28bfb5ebdd6b5901e62e37101fe36f 100644 (file)
@@ -7,6 +7,7 @@
 #include "qla_def.h"
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <asm/uaccess.h>
 
index 8d2fc2fa7a6be830f5bedad880cf5e85c9891c05..109068df933fe794275c2f01426524416cc8f403 100644 (file)
@@ -7,9 +7,9 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.03.02-k1"
+#define QLA2XXX_VERSION      "8.03.02-k2"
 
 #define QLA_DRIVER_MAJOR_VER   8
 #define QLA_DRIVER_MINOR_VER   3
 #define QLA_DRIVER_PATCH_VER   2
-#define QLA_DRIVER_BETA_VER    1
+#define QLA_DRIVER_BETA_VER    2
index 09d6d4b76f39536512b3578142b26a1a0f27bcf8..caeb7d10ae0450b1cb8227f7f8c9fbc50b3f3664 100644 (file)
@@ -467,7 +467,7 @@ int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
        if (conn_err_detail)
                *conn_err_detail = mbox_sts[5];
        if (tcp_source_port_num)
-               *tcp_source_port_num = (uint16_t) mbox_sts[6] >> 16;
+               *tcp_source_port_num = (uint16_t) (mbox_sts[6] >> 16);
        if (connection_id)
                *connection_id = (uint16_t) mbox_sts[6] & 0x00FF;
        status = QLA_SUCCESS;
index 83c8b5e4fc8b45856a37f2a58fb5727a4a740fa7..2ccad36bee9f0843a6807ede4cd44b5fd62dc48f 100644 (file)
@@ -5,6 +5,7 @@
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsicam.h>
index 1b8217076b0e6e18d2ff0ee5f16963ecc0ac8f86..aa406497eebcf912cd296dd1554fdc9120611aa2 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/delay.h>
 #include <linux/types.h>
 #include <linux/string.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/blkdev.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
index bd88349b852684d3d31f87d614f2c50947b86fe3..2c146b44d95fc7e14a5705f2934142770f65f79b 100644 (file)
@@ -63,6 +63,7 @@ static int raid_match(struct attribute_container *cont, struct device *dev)
         * emulated RAID devices, so start with SCSI */
        struct raid_internal *i = ac_to_raid_internal(cont);
 
+#if defined(CONFIG_SCSI) || defined(CONFIG_SCSI_MODULE)
        if (scsi_is_sdev_device(dev)) {
                struct scsi_device *sdev = to_scsi_device(dev);
 
@@ -71,6 +72,7 @@ static int raid_match(struct attribute_container *cont, struct device *dev)
 
                return i->f->is_raid(dev);
        }
+#endif
        /* FIXME: look at other subsystems too */
        return 0;
 }
index 0b575c8710075e48c183547ac0dfd42eda6adb1e..3a5bfd10b2cbd4d419b2a84cb57deeed13c6ad32 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/genhd.h>
@@ -956,7 +957,8 @@ static int resp_start_stop(struct scsi_cmnd * scp,
 static sector_t get_sdebug_capacity(void)
 {
        if (scsi_debug_virtual_gb > 0)
-               return 2048 * 1024 * (sector_t)scsi_debug_virtual_gb;
+               return (sector_t)scsi_debug_virtual_gb *
+                       (1073741824 / scsi_debug_sector_size);
        else
                return sdebug_store_sectors;
 }
index 37af178b2d1743b0b3d3da54f8a6880faaa602ce..43fad4c09beb6714ec2712fbc1ba8d39af607845 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/moduleparam.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_devinfo.h>
index 08ed506e6059db96cd09c02588ea306800a54cb0..7ad53fa42766ad597df9b5e0c0739676211c90bc 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/gfp.h>
 #include <linux/timer.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
@@ -301,7 +302,20 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
                if (scmd->device->allow_restart &&
                    (sshdr.asc == 0x04) && (sshdr.ascq == 0x02))
                        return FAILED;
-               return SUCCESS;
+
+               if (blk_barrier_rq(scmd->request))
+                       /*
+                        * barrier requests should always retry on UA
+                        * otherwise block will get a spurious error
+                        */
+                       return NEEDS_RETRY;
+               else
+                       /*
+                        * for normal (non barrier) commands, pass the
+                        * UA upwards for a determination in the
+                        * completion functions
+                        */
+                       return SUCCESS;
 
                /* these three are not supported */
        case COPY_ABORTED:
index 0fd6ae6911ad822eb035fd3c7fb020bd1e7799f8..d53e6503c6d5bd052df0f98c7047a5edcae29e6c 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/jiffies.h>
 #include <linux/security.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/netlink.h>
 
index 77fbddb507fdcb65b5d4fc940e6780ae756f6da9..c99da926fdac02e1d5a43faa9a9436f4d55a8f0b 100644 (file)
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/errno.h>
 #include <linux/blkdev.h>
 #include <linux/seq_file.h>
 #include <linux/mutex.h>
+#include <linux/gfp.h>
 #include <asm/uaccess.h>
 
 #include <scsi/scsi.h>
index 4bc8b77a2ef3ae55d71606310213f3007f2c1a56..38518b0880739a5d2dded941e5b6cfbdb85c131d 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/kthread.h>
 #include <linux/spinlock.h>
 #include <linux/async.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index 19ec9e2d3f391c1189e57b178173bd446ed14b20..429c9b73e3e4de02254ac71af588f334a21e877b 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/device.h>
index 0e9533f7aabc4bcd38befa28c1727db45cd41a1e..a87e21c35ef269ecae82f68e49ee235dd3d0eced 100644 (file)
@@ -20,6 +20,7 @@
  * 02110-1301 USA
  */
 #include <linux/miscdevice.h>
+#include <linux/gfp.h>
 #include <linux/file.h>
 #include <linux/smp_lock.h>
 #include <net/tcp.h>
index 10303272ba4573082f942a4ec8e9cd7e4d0a9e95..66241dd525ae7fac133197064a0eaa86e5e0e624 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/hash.h>
 #include <linux/module.h>
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
index 79660ee3e2113affe5735c4c97786f5142b1f10c..6cfffc88022a317490a91e34704b3d3bbbddffd8 100644 (file)
@@ -27,6 +27,7 @@
  */
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
@@ -1232,6 +1233,15 @@ store_fc_vport_delete(struct device *dev, struct device_attribute *attr,
 {
        struct fc_vport *vport = transport_class_to_vport(dev);
        struct Scsi_Host *shost = vport_to_shost(vport);
+       unsigned long flags;
+
+       spin_lock_irqsave(shost->host_lock, flags);
+       if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) {
+               spin_unlock_irqrestore(shost->host_lock, flags);
+               return -EBUSY;
+       }
+       vport->flags |= FC_VPORT_DELETING;
+       spin_unlock_irqrestore(shost->host_lock, flags);
 
        fc_queue_work(shost, &vport->vport_delete_work);
        return count;
@@ -1821,6 +1831,9 @@ store_fc_host_vport_delete(struct device *dev, struct device_attribute *attr,
        list_for_each_entry(vport, &fc_host->vports, peers) {
                if ((vport->channel == 0) &&
                    (vport->port_name == wwpn) && (vport->node_name == wwnn)) {
+                       if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING))
+                               break;
+                       vport->flags |= FC_VPORT_DELETING;
                        match = 1;
                        break;
                }
@@ -3370,18 +3383,6 @@ fc_vport_terminate(struct fc_vport *vport)
        unsigned long flags;
        int stat;
 
-       spin_lock_irqsave(shost->host_lock, flags);
-       if (vport->flags & FC_VPORT_CREATING) {
-               spin_unlock_irqrestore(shost->host_lock, flags);
-               return -EBUSY;
-       }
-       if (vport->flags & (FC_VPORT_DEL)) {
-               spin_unlock_irqrestore(shost->host_lock, flags);
-               return -EALREADY;
-       }
-       vport->flags |= FC_VPORT_DELETING;
-       spin_unlock_irqrestore(shost->host_lock, flags);
-
        if (i->f->vport_delete)
                stat = i->f->vport_delete(vport);
        else
@@ -3852,7 +3853,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
                if (rport && (rport->port_state != FC_PORTSTATE_ONLINE)) {
                        req->errors = -ENXIO;
                        spin_unlock_irq(q->queue_lock);
-                       blk_end_request(req, -ENXIO, blk_rq_bytes(req));
+                       blk_end_request_all(req, -ENXIO);
                        spin_lock_irq(q->queue_lock);
                        continue;
                }
@@ -3862,7 +3863,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
                ret = fc_req_to_bsgjob(shost, rport, req);
                if (ret) {
                        req->errors = ret;
-                       blk_end_request(req, ret, blk_rq_bytes(req));
+                       blk_end_request_all(req, ret);
                        spin_lock_irq(q->queue_lock);
                        continue;
                }
index ea3892e7e0f76a46ef219c12e97b23e13abe326e..1e6d4793542c30943602fbc13a2abcbae82080b2 100644 (file)
@@ -22,6 +22,7 @@
  */
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <net/tcp.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
index c25bd9a34e02f4fa2b106694d0e93a8fa28b1e3b..8a172d4f4564670c57450d06f484af6be0052827 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/blkdev.h>
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 #include "scsi_priv.h"
 #include <scsi/scsi_device.h>
index 3f21bc65e8c66e6cbbb65d6a376de096a3cdfbee..6803b1e26eccd63986dda5198bcc9cc2abe36f38 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/genhd.h>
 #include <linux/kernel.h>
index 83881dfb33c055646b42cc1341f21caebee9f42f..de6c60320f6ffb70f1b9d00a1677f1f36caabba0 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/mutex.h>
 #include <linux/string_helpers.h>
 #include <linux/async.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 
@@ -1039,6 +1040,7 @@ static void sd_prepare_flush(struct request_queue *q, struct request *rq)
 {
        rq->cmd_type = REQ_TYPE_BLOCK_PC;
        rq->timeout = SD_TIMEOUT;
+       rq->retries = SD_MAX_RETRIES;
        rq->cmd[0] = SYNCHRONIZE_CACHE;
        rq->cmd_len = 10;
 }
@@ -1948,7 +1950,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
 {
        struct request_queue *q = sdkp->disk->queue;
        unsigned int sector_sz = sdkp->device->sector_size;
-       const int vpd_len = 32;
+       const int vpd_len = 64;
        unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL);
 
        if (!buffer ||
@@ -1998,7 +2000,7 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)
 {
        unsigned char *buffer;
        u16 rot;
-       const int vpd_len = 32;
+       const int vpd_len = 64;
 
        buffer = kmalloc(vpd_len, GFP_KERNEL);
 
@@ -2185,7 +2187,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
        blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
 
        gd->driverfs_dev = &sdp->sdev_gendev;
-       gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS;
+       gd->flags = GENHD_FL_EXT_DEVT;
        if (sdp->removable)
                gd->flags |= GENHD_FL_REMOVABLE;
 
index 0d9d6f7567f5a60352b5462fd48c056c279a191e..7f5a6a86f820fbae8baee63e7de722b480c96462 100644 (file)
@@ -21,6 +21,7 @@
 **-----------------------------------------------------------------------------
 */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/enclosure.h>
index c996d98636f340704b82c0fab8d445c1591823ff..dee1c96288d4420e2461c68c4d18ac253d46c6f7 100644 (file)
@@ -38,6 +38,7 @@ static int sg_version_num = 30534;    /* 2 digits for each component */
 #include <linux/errno.h>
 #include <linux/mtio.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 #include <linux/fcntl.h>
 #include <linux/init.h>
 #include <linux/poll.h>
index 6dc8b846c1127ee75273817ba830ee6490d2ee72..8ac6ce792b696763e54a4a88c6eb6b3120492a31 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <linux/blkdev.h>
 #include <linux/device.h>
index 56cf0bb4ed1f998af1d460d6ffa1725aa2014523..9acc2b2a36019f30fe2150feb55db56c3ae6730f 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/mm.h>
 #include <linux/blkdev.h>
index d6f340f48a3bcecebbf57aef61d5b0e8cd67d3b5..0a90abc7f140215fcc5aa50301ea927cd5564e8f 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 #include <scsi/scsi.h>
index 291236e6e4351f6ef3517832b0e5ce901b7b26e3..cbb38c5197fad67299f32a36792ab1fc5cdeec3e 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/blkpg.h>
 #include <linux/cdrom.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
index 4ad3e017213f868ed85af9a7032912194836abea..92cc2efb25d70e00d33e3b1a555f6b8505348a10 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/string.h>
 #include <linux/bcd.h>
 #include <linux/blkdev.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index f67d1a159aad9173982bacce034b88f7d7cb6732..3ea1a713ef250fcc35a64b10c71a65ac73ea6e42 100644 (file)
@@ -27,6 +27,7 @@ static const char *verstr = "20081215";
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/mtio.h>
 #include <linux/cdrom.h>
index fd7b15be7640fa8d5b89c616f76a849606704445..9c73dbda3bbb8d3137e8adaed717b61d83cf6551 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/pci.h>
 #include <linux/blkdev.h>
index 75da6e58ce550ecd03031cb05ee4d8a8b9290ba1..b5838d547c68aabdb62b4b6af7a57f5c823d94f7 100644 (file)
@@ -645,6 +645,7 @@ __inline__ void NCR5380_print_phase(struct Scsi_Host *instance) { };
  * interrupt or bottom half.
  */
 
+#include <linux/gfp.h>
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 
index 34a99620e5bd35ca2d7ed411ed42004d59788240..0621037f027129970748ac77ad918ef0dd6d1442 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/types.h>
 #include <linux/delay.h>
 #include <linux/module.h>
index 3d73aad4bc8201196946e2a1e2c19e4e98157327..fc23d273fb1a6c17d37a648e6fd05c1cbaccbf75 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/gfp.h>
 
 #include <asm/irq.h>
 #include <asm/io.h>
index 9a4273445c0d0537e61fe1f0dd732bc572779815..27866b0adfebd4901dbb1a38a4ebc752ecfd3d70 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 #include <scsi/scsi.h>
index 26e8e0e6b8ddeedd3b3c40b5d87a717ec84a5288..5d9fdeeb2315cdd5e9958bf24ea56cd3669fca47 100644 (file)
 #include <linux/init.h>
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <asm/dma.h>
 #include <asm/irq.h>
 
index e4ac5829b637b2c99e0cc7fdc37b7ba875bc1056..26894459c37fe375076464330ef7809345b57408 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/pci.h>
 
index 2f6e9d8eaf71b18bba107769b4dd38a2070b0587..333580bf37c5a7d6cbccf6587d55ad7a2b3b3b2b 100644 (file)
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/ioport.h>
 #include <linux/proc_fs.h>
@@ -1588,7 +1587,7 @@ static int wd7000_host_reset(struct scsi_cmnd *SCpnt)
 {
        Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
 
-       spin_unlock_irq(SCpnt->device->host->host_lock);
+       spin_lock_irq(SCpnt->device->host->host_lock);
 
        if (wd7000_adapter_reset(host) < 0) {
                spin_unlock_irq(SCpnt->device->host->host_lock);
index 64d40a2d4d4d5699167d04d12cecea1c6574b7e0..e17764d7147624045fefb50ea95c477a9b04a8a1 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/zorro.h>
+#include <linux/slab.h>
 
 #include <asm/amigahw.h>
 #include <asm/amigaints.h>
@@ -68,6 +69,7 @@ static struct zorro_device_id zorro7xx_zorro_tbl[] __devinitdata = {
        },
        { 0 }
 };
+MODULE_DEVICE_TABLE(zorro, zorro7xx_zorro_tbl);
 
 static int __devinit zorro7xx_init_one(struct zorro_dev *z,
                                       const struct zorro_device_id *ent)
index ae0251ef6f4ef76b087f119901a46f6d8c5c8b7b..78ed24bb6a35d4eb09f9a4f90939f5b4f7151d20 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/pm.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index c3db16b7afa12f6b43e94fe5437bde3ca7aeea4a..2b1ea3d4c4f41e4b444c0541ce9285703f5f28fc 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/serial_8250.h>
 #include <linux/nmi.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index 33149d982e82a3e6329e811d9a8e2440f0a86858..d8c0ffbfa6e39b53bafaef22f2d090e2739613e9 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/module.h>
 #include <linux/serial_core.h>
 #include <linux/signal.h>
-#include <linux/slab.h>
 #include <linux/types.h>
 
 #include <asm/hardware.h>
index 0e1410f2c03394362f25a07b6ce27981dff38ab2..c13438c930129a0b4e736fd67630a1ef9338345b 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/delay.h>
 #include <linux/dio.h>
 #include <linux/console.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 
 #include "8250.h"
index 24485cc62ff8255a6f56a38f95a6de83eb113600..4822cb50cd0f0176f4bd1c1370297c67ef5591a3 100644 (file)
@@ -348,6 +348,8 @@ static const struct pnp_device_id pnp_dev_table[] = {
        {       "FUJ02E6",              0       },
        /* Fujitsu Wacom 2FGT Tablet PC device */
        {       "FUJ02E7",              0       },
+       /* Fujitsu Wacom 1FGT Tablet PC device */
+       {       "FUJ02E9",              0       },
        /*
         * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in
         * disguise)
index e4b3c2c88bb65098bd806219ac32f682cb3b2c90..b09a638d051fde98c37e52a58eb2cb9a25756663 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/serial.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
index ce6c35333ff7b9faaf65acfc087ace884f150c60..743ebf5f16da8942bc6c7d23508cc69cfd9eb229 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/serial.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/sizes.h>
index fcf273e3f48c5faee2741e316d7de927d3ac204e..96f7e7484feebf4269c631862f9a01b227eac0f6 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/module.h>
 #include <linux/ioport.h>
+#include <linux/gfp.h>
 #include <linux/io.h>
 #include <linux/init.h>
 #include <linux/console.h>
index 7c72888fbf94e20ca3c7982edeec7cffffc31c06..c88f8ad3ff821d16fef218c5021adede8c9c6cf1 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/sysrq.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
index 1b94c56ec23914a0c7a44acd04ebe61594f39273..3fc1d66e32c651cbcca46808a4aa1fac7ba9ca85 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <linux/module.h>
 #include <linux/tty.h>
+#include <linux/gfp.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/serial.h>
index a9802e76b5fabbd91f44adedb16708fda49f289b..814ac006393fabac29f97d0f3cb129fe125f1ee3 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/tty.h>
 #include <linux/ioport.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/serial.h>
 #include <linux/console.h>
@@ -61,7 +62,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,
        void __iomem *pram;
        unsigned long offset;
        struct resource res;
-       unsigned long len;
+       resource_size_t len;
 
        /* Don't remap parameter RAM if it has already been initialized
         * during console setup.
@@ -74,7 +75,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,
        if (of_address_to_resource(np, 1, &res))
                return NULL;
 
-       len = 1 + res.end - res.start;
+       len = resource_size(&res);
        pram = ioremap(res.start, len);
        if (!pram)
                return NULL;
index e579d7a1807ab4728bed3d94520f5c8e1e499ae4..eacb588a93459911e2d3d5be0a7af7f171dc24ec 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/rational.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 #define  MX2_UCR3_RXDMUXSEL     (1<<2)  /* RXD Muxed Input Select, on mx2/mx3 */
 #define  UCR3_INVT      (1<<1)  /* Inverted Infrared transmission */
 #define  UCR3_BPEN      (1<<0)  /* Preset registers enable */
-#define  UCR4_CTSTL_32   (32<<10) /* CTS trigger level (32 chars) */
+#define  UCR4_CTSTL_SHF  10      /* CTS trigger level shift */
+#define  UCR4_CTSTL_MASK 0x3F    /* CTS trigger is 6 bits wide */
 #define  UCR4_INVR      (1<<9)  /* Inverted infrared reception */
 #define  UCR4_ENIRI     (1<<8)  /* Serial infrared interrupt enable */
 #define  UCR4_WKEN      (1<<7)  /* Wake interrupt enable */
@@ -590,6 +592,9 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
        return 0;
 }
 
+/* half the RX buffer size */
+#define CTSTL 16
+
 static int imx_startup(struct uart_port *port)
 {
        struct imx_port *sport = (struct imx_port *)port;
@@ -606,6 +611,10 @@ static int imx_startup(struct uart_port *port)
        if (USE_IRDA(sport))
                temp |= UCR4_IRSC;
 
+       /* set the trigger level for CTS */
+       temp &= ~(UCR4_CTSTL_MASK<<  UCR4_CTSTL_SHF);
+       temp |= CTSTL<<  UCR4_CTSTL_SHF;
+
        writel(temp & ~UCR4_DREN, sport->port.membase + UCR4);
 
        if (USE_IRDA(sport)) {
index 23ba6b40b3ac4ac9d62f12c0ff2b55c5cd403a5c..f164ba4eba02292806cd04ece8864f7efb2f3570 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/pci.h>
 #include <linux/serial_core.h>
 #include <linux/ioc3.h>
+#include <linux/slab.h>
 
 /*
  * Interesting things about the ioc3
index 836d9ab4f729669ac11f941a3b3e246b367fdcb3..8ad28fc64926a88e2d5399439f3852d3818f243f 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/pci.h>
 #include <linux/ioc4.h>
 #include <linux/serial_core.h>
+#include <linux/slab.h>
 
 /*
  * interesting things about the ioc4
index 12cb5e446a4f07580219360cdb6c61415d218df1..eaf545014119cda24fe4a115e5b3c3a7ffe9b9e4 100644 (file)
@@ -26,6 +26,7 @@
  ***********************************************************************/
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include "jsm.h"
 
index 5673ca9dfdc884fce7150428207cff30b5941677..7a4a914ecff0b0b96186a61812528d2750d05f1a 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/serial_reg.h>
 #include <linux/delay.h>       /* For udelay */
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include "jsm.h"
 
index 3c30c56aa2e16eb4c24907545d1d423d39b10c08..3351c3bd59e4089f11bc3081df0c91443ab01a7e 100644 (file)
@@ -41,6 +41,7 @@
 #define MAX_MAX3100 4
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/serial_core.h>
 #include <linux/serial.h>
index 7bb5fee639e36e7859e7c3b8d4207471b9c40d5b..b5aaef965f24e904e179a4a579fa4bcafbf92809 100644 (file)
@@ -263,6 +263,7 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios,
        }
 
        spin_lock_irqsave(&port->lock, flags);
+       uart_update_timeout(port, termios->c_cflag, baud);
        writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
        writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
        writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR);
@@ -379,6 +380,7 @@ static irqreturn_t mcf_interrupt(int irq, void *data)
 static void mcf_config_port(struct uart_port *port, int flags)
 {
        port->type = PORT_MCF;
+       port->fifosize = MCFUART_TXFIFOSIZE;
 
        /* Clear mask, so no surprise interrupts. */
        writeb(0, port->membase + MCFUART_UIMR);
@@ -424,7 +426,7 @@ static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser)
 /*
  *     Define the basic serial functions we support.
  */
-static struct uart_ops mcf_uart_ops = {
+static const struct uart_ops mcf_uart_ops = {
        .tx_empty       = mcf_tx_empty,
        .get_mctrl      = mcf_get_mctrl,
        .set_mctrl      = mcf_set_mctrl,
@@ -443,7 +445,7 @@ static struct uart_ops mcf_uart_ops = {
        .verify_port    = mcf_verify_port,
 };
 
-static struct mcf_uart mcf_ports[3];
+static struct mcf_uart mcf_ports[4];
 
 #define        MCF_MAXPORTS    ARRAY_SIZE(mcf_ports)
 
index 3119fddaedb5708ec80346dfb239323365292608..02469c31bf0b6939f37e96e03ac7e1af98a45a14 100644 (file)
  * kind, whether express or implied.
  */
 
-/* Platform device Usage :
- *
- * Since PSCs can have multiple function, the correct driver for each one
- * is selected by calling mpc52xx_match_psc_function(...). The function
- * handled by this driver is "uart".
- *
- * The driver init all necessary registers to place the PSC in uart mode without
- * DCD. However, the pin multiplexing aren't changed and should be set either
- * by the bootloader or in the platform init code.
- *
- * The idx field must be equal to the PSC index (e.g. 0 for PSC1, 1 for PSC2,
- * and so on). So the PSC1 is mapped to /dev/ttyPSC0, PSC2 to /dev/ttyPSC1 and
- * so on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly
- * fpr the console code : without this 1:1 mapping, at early boot time, when we
- * are parsing the kernel args console=ttyPSC?, we wouldn't know which PSC it
- * will be mapped to.
- */
-
-/* OF Platform device Usage :
- *
- * This driver is only used for PSCs configured in uart mode.  The device
- * tree will have a node for each PSC with "mpc52xx-psc-uart" in the compatible
- * list.
- *
- * By default, PSC devices are enumerated in the order they are found.  However
- * a particular PSC number can be forces by adding 'device_no = <port#>'
- * to the device node.
- *
- * The driver init all necessary registers to place the PSC in uart mode without
- * DCD. However, the pin multiplexing aren't changed and should be set either
- * by the bootloader or in the platform init code.
- */
-
 #undef DEBUG
 
 #include <linux/device.h>
@@ -1500,7 +1467,7 @@ mpc52xx_uart_init(void)
        /*
         * Map the PSC FIFO Controller and init if on MPC512x.
         */
-       if (psc_ops->fifoc_init) {
+       if (psc_ops && psc_ops->fifoc_init) {
                ret = psc_ops->fifoc_init();
                if (ret)
                        return ret;
index b5496c28e60be5b486d90a587b9a5746f5f25a04..55e113a0be0332631f500e36ca560441db63092d 100644 (file)
@@ -70,6 +70,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/mv643xx.h>
 #include <linux/platform_device.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index 7571aaa138b0ce1884b82826dff428efcbc2be30..9711e06a8374c73561524fc79369b20e4c33825b 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/init.h>
 #include <linux/serial.h>
 #include <linux/console.h>
-#include <linux/slab.h>
 #include <linux/delay.h> /* for udelay */
 #include <linux/device.h>
 #include <asm/io.h>
index cdf172eda2e3792a61abc155d1c63b7c0396b92c..4abfebdb0fccdb5ca4131c2c9bbe3c3cf0288eee 100644 (file)
@@ -11,6 +11,7 @@
  */
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 #include <linux/of_platform.h>
index f020de1cdd5035155bbb4f3c95ba847e81b1c52b..700e10833bf98965280491ba49771b1ad7c3d618 100644 (file)
@@ -54,7 +54,6 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/console.h>
-#include <linux/slab.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
 #include <linux/bitops.h>
@@ -753,8 +752,10 @@ static void pmz_break_ctl(struct uart_port *port, int break_state)
                uap->curregs[R5] = new_reg;
 
                /* NOTE: Not subject to 'transmitter active' rule. */
-               if (ZS_IS_ASLEEP(uap))
+               if (ZS_IS_ASLEEP(uap)) {
+                       spin_unlock_irqrestore(&port->lock, flags);
                        return;
+               }
                write_zsreg(uap, R5, uap->curregs[R5]);
        }
 
index 56ee082157aaf121c755fd3a42ef4005e9667f14..1102a39b44f5497c4daf4512123ba49fbeb9cf54 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/serial_core.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 struct uart_pxa_port {
        struct uart_port        port;
index e91db4b380120fb1eae857179c1d42006b545bb1..8cfa5b12ea7a743ab5bd13b43cfe28bd5d72db2c 100644 (file)
@@ -105,6 +105,10 @@ struct serial_cfg_mem {
  * manfid 0x0160, 0x0104
  * This card appears to have a 14.7456MHz clock.
  */
+/* Generic Modem: MD55x (GPRS/EDGE) have
+ * Elan VPU16551 UART with 14.7456MHz oscillator
+ * manfid 0x015D, 0x4C45
+ */
 static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
 {
        port->uartclk = 14745600;
@@ -195,6 +199,11 @@ static const struct serial_quirk quirks[] = {
                .prodid = 0x0104,
                .multi  = -1,
                .setup  = quirk_setup_brainboxes_0104,
+       }, {
+               .manfid = 0x015D,
+               .prodid = 0x4C45,
+               .multi  = -1,
+               .setup  = quirk_setup_brainboxes_0104,
        }, {
                .manfid = MANFID_IBM,
                .prodid = ~0,
@@ -745,6 +754,7 @@ static struct pcmcia_device_id serial_ids[] = {
        PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29),
        PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719),
        PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4),
+       PCMCIA_PFC_DEVICE_PROD_ID12(1, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e),
        PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
        PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c),
        PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
index 2e71bbc04dac4d49054ca682f8b6976ce82dba86..b1962025b1aa7f79a381a58bd1d2ce56909ab180 100644 (file)
@@ -650,6 +650,7 @@ static struct console ks8695_console = {
 
 static int __init ks8695_console_init(void)
 {
+       add_preferred_console(SERIAL_KS8695_DEVNAME, 0, NULL);
        register_console(&ks8695_console);
        return 0;
 }
index 980f39449ee5635ccb7b4f681151892e92a493b0..8eb094c1f61b2c2ab17cb68e420f16ad42428823 100644 (file)
@@ -50,7 +50,7 @@
 #include <linux/list.h>
 #include <linux/dmaengine.h>
 #include <linux/scatterlist.h>
-#include <linux/timer.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_SUPERH
 #include <asm/sh_bios.h>
@@ -780,10 +780,6 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
        if ((ssr_status & SCxSR_BRK(port)) && err_enabled)
                ret = sci_br_interrupt(irq, ptr);
 
-       WARN_ONCE(ret == IRQ_NONE,
-                 "%s: %d IRQ %d, status %x, control %x\n", __func__,
-                 irq, port->line, ssr_status, scr_status);
-
        return ret;
 }
 
index fad67d33b0bdddf5a04cfb103842c83ac0a72d35..f70c49f915fa11c7878747f58973bebc899f5542 100644 (file)
@@ -31,7 +31,9 @@
 # define SCSCR_INIT(port) (port->mapbase == SCIF2) ? 0xF3 : 0xF0
 #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \
       defined(CONFIG_CPU_SUBTYPE_SH7721) || \
-      defined(CONFIG_ARCH_SHMOBILE)
+      defined(CONFIG_ARCH_SH7367) || \
+      defined(CONFIG_ARCH_SH7377) || \
+      defined(CONFIG_ARCH_SH7372)
 # define SCSCR_INIT(port)  0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */
 # define PORT_PTCR        0xA405011EUL
 # define PORT_PVCR        0xA4050122UL
@@ -94,7 +96,9 @@
 # define SCSCR_INIT(port)       0x0038  /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
 #elif defined(CONFIG_CPU_SUBTYPE_SH7724)
 # define SCIF_ORER              0x0001  /* overrun error bit */
-# define SCSCR_INIT(port)       0x0038  /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+# define SCSCR_INIT(port) ((port)->type == PORT_SCIFA ? \
+       0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ : \
+       0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ )
 #elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
 # define SCSPTR2 0xffe80020 /* 16 bit SCIF */
 # define SCIF_ORER 0x0001   /* overrun error bit */
     defined(CONFIG_CPU_SUBTYPE_SH7786)  || \
     defined(CONFIG_CPU_SUBTYPE_SHX3)
 #define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */
+#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define SCI_CTRL_FLAGS_REIE ((port)->type == PORT_SCIFA ? 0 : 8)
 #else
 #define SCI_CTRL_FLAGS_REIE 0
 #endif
 #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
     defined(CONFIG_CPU_SUBTYPE_SH7720) || \
     defined(CONFIG_CPU_SUBTYPE_SH7721) || \
-    defined(CONFIG_ARCH_SHMOBILE)
+    defined(CONFIG_ARCH_SH7367) || \
+    defined(CONFIG_ARCH_SH7377) || \
+    defined(CONFIG_ARCH_SH7372)
 # define SCIF_ORER    0x0200
 # define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER)
 # define SCIF_RFDC_MASK 0x007f
 #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
     defined(CONFIG_CPU_SUBTYPE_SH7720) || \
     defined(CONFIG_CPU_SUBTYPE_SH7721) || \
-    defined(CONFIG_ARCH_SHMOBILE)
+    defined(CONFIG_ARCH_SH7367) || \
+    defined(CONFIG_ARCH_SH7377) || \
+    defined(CONFIG_ARCH_SH7372)
 # define SCxSR_RDxF_CLEAR(port)         (sci_in(port, SCxSR) & 0xfffc)
 # define SCxSR_ERROR_CLEAR(port) (sci_in(port, SCxSR) & 0xfd73)
 # define SCxSR_TDxE_CLEAR(port)         (sci_in(port, SCxSR) & 0xffdf)
     SCI_OUT(sci_size, sci_offset, value);                              \
   }
 
-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_ARCH_SHMOBILE)
+#if defined(CONFIG_CPU_SH3) || \
+    defined(CONFIG_ARCH_SH7367) || \
+    defined(CONFIG_ARCH_SH7377) || \
+    defined(CONFIG_ARCH_SH7372)
 #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
 #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
                                sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \
 #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
       defined(CONFIG_CPU_SUBTYPE_SH7720) || \
       defined(CONFIG_CPU_SUBTYPE_SH7721) || \
-      defined(CONFIG_ARCH_SHMOBILE)
+      defined(CONFIG_ARCH_SH7367) || \
+      defined(CONFIG_ARCH_SH7377) || \
+      defined(CONFIG_ARCH_SH7372)
 #define SCIF_FNS(name, scif_offset, scif_size) \
   CPU_SCIF_FNS(name, scif_offset, scif_size)
 #else
 #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
     defined(CONFIG_CPU_SUBTYPE_SH7720) || \
     defined(CONFIG_CPU_SUBTYPE_SH7721) || \
-    defined(CONFIG_ARCH_SHMOBILE)
+    defined(CONFIG_ARCH_SH7367) || \
+    defined(CONFIG_ARCH_SH7377) || \
+    defined(CONFIG_ARCH_SH7372)
 
 SCIF_FNS(SCSMR,  0x00, 16)
 SCIF_FNS(SCBRR,  0x04,  8)
@@ -589,7 +606,9 @@ static inline int sci_rxd_in(struct uart_port *port)
 #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
       defined(CONFIG_CPU_SUBTYPE_SH7720) || \
       defined(CONFIG_CPU_SUBTYPE_SH7721) || \
-      defined(CONFIG_ARCH_SHMOBILE)
+      defined(CONFIG_ARCH_SH7367) || \
+      defined(CONFIG_ARCH_SH7377) || \
+      defined(CONFIG_ARCH_SH7372)
 #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1)
 #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
       defined(CONFIG_CPU_SUBTYPE_SH7724)
index d514e28d07557b7516de0ecd7478d1cb9401f619..d2e0321049e2e1e3952244f35300da0bc887aff2 100644 (file)
@@ -474,7 +474,7 @@ static void sunsab_stop_rx(struct uart_port *port)
 {
        struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
 
-       up->interrupt_mask0 |= SAB82532_ISR0_TCD;
+       up->interrupt_mask0 |= SAB82532_IMR0_TCD;
        writeb(up->interrupt_mask1, &up->regs->w.imr0);
 }
 
index 170d3d68c8f04d38fb67f8d3b84c9c977f57f7a1..01f7731e59b89feed0745b89d5ab4282699b2164 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/serial.h>
 #include <linux/sysrq.h>
 #include <linux/console.h>
+#include <linux/slab.h>
 #ifdef CONFIG_SERIO
 #include <linux/serio.h>
 #endif
@@ -1453,8 +1454,10 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
        if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) {
                err = sunsu_kbd_ms_init(up);
                if (err) {
+                       of_iounmap(&op->resource[0],
+                                  up->port.membase, up->reg_size);
                        kfree(up);
-                       goto out_unmap;
+                       return err;
                }
                dev_set_drvdata(&op->dev, up);
 
index 7bf10264a6ac7fd7310106440b6b7f1cd65a442d..786ba85c170ba622d638a010fc27b1c1213142a3 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/ioport.h>
+#include <linux/slab.h>
 
 #include "timbuart.h"
 
index ab2ab3c818342d4cb9fd67e402523a26bd696a2f..f0a6c61b17f722ef1a6cd7c0ac4da53a823b82b9 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <asm/io.h>
-#if defined(CONFIG_OF)
+#if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE))
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
@@ -581,7 +581,7 @@ static struct platform_driver ulite_platform_driver = {
 /* ---------------------------------------------------------------------
  * OF bus bindings
  */
-#if defined(CONFIG_OF)
+#if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE))
 static int __devinit
 ulite_of_probe(struct of_device *op, const struct of_device_id *match)
 {
@@ -631,11 +631,11 @@ static inline void __exit ulite_of_unregister(void)
 {
        of_unregister_platform_driver(&ulite_of_driver);
 }
-#else /* CONFIG_OF */
-/* CONFIG_OF not enabled; do nothing helpers */
+#else /* CONFIG_OF && (CONFIG_PPC32 || CONFIG_MICROBLAZE) */
+/* Appropriate config not enabled; do nothing helpers */
 static inline int __init ulite_of_register(void) { return 0; }
 static inline void __exit ulite_of_unregister(void) { }
-#endif /* CONFIG_OF */
+#endif /* CONFIG_OF && (CONFIG_PPC32 || CONFIG_MICROBLAZE) */
 
 /* ---------------------------------------------------------------------
  * Module setup/teardown
index 465f2fae1025ebeef99a7c7a657a14de23858341..074904912f642caa23a89af5a8b7e838501e9fd5 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/module.h>
 #include <linux/serial.h>
+#include <linux/slab.h>
 #include <linux/serial_core.h>
 #include <linux/io.h>
 #include <linux/of_platform.h>
index c2750391fd34402efb405e24cd5b0e3d1b4a43c3..94ad6bd86a00c02754d6c3ac2666cc347a2816c7 100644 (file)
@@ -2,7 +2,7 @@
  * Shared interrupt handling code for IPR and INTC2 types of IRQs.
  *
  * Copyright (C) 2007, 2008 Magnus Damm
- * Copyright (C) 2009 Paul Mundt
+ * Copyright (C) 2009, 2010 Paul Mundt
  *
  * Based on intc2.c and ipr.c
  *
 #include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/sh_intc.h>
 #include <linux/sysdev.h>
 #include <linux/list.h>
 #include <linux/topology.h>
 #include <linux/bitmap.h>
+#include <linux/cpumask.h>
 
 #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
        ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
@@ -234,6 +236,10 @@ static inline void _intc_enable(unsigned int irq, unsigned long handle)
        unsigned int cpu;
 
        for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) {
+#ifdef CONFIG_SMP
+               if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity))
+                       continue;
+#endif
                addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu);
                intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\
                                                    [_INTC_FN(handle)], irq);
@@ -253,6 +259,10 @@ static void intc_disable(unsigned int irq)
        unsigned int cpu;
 
        for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) {
+#ifdef CONFIG_SMP
+               if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity))
+                       continue;
+#endif
                addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu);
                intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\
                                                     [_INTC_FN(handle)], irq);
@@ -301,6 +311,23 @@ static int intc_set_wake(unsigned int irq, unsigned int on)
        return 0; /* allow wakeup, but setup hardware in intc_suspend() */
 }
 
+#ifdef CONFIG_SMP
+/*
+ * This is held with the irq desc lock held, so we don't require any
+ * additional locking here at the intc desc level. The affinity mask is
+ * later tested in the enable/disable paths.
+ */
+static int intc_set_affinity(unsigned int irq, const struct cpumask *cpumask)
+{
+       if (!cpumask_intersects(cpumask, cpu_online_mask))
+               return -1;
+
+       cpumask_copy(irq_to_desc(irq)->affinity, cpumask);
+
+       return 0;
+}
+#endif
+
 static void intc_mask_ack(unsigned int irq)
 {
        struct intc_desc_int *d = get_intc_desc(irq);
@@ -847,6 +874,9 @@ void __init register_intc_controller(struct intc_desc *desc)
        d->chip.shutdown = intc_disable;
        d->chip.set_type = intc_set_sense;
        d->chip.set_wake = intc_set_wake;
+#ifdef CONFIG_SMP
+       d->chip.set_affinity = intc_set_affinity;
+#endif
 
        if (hw->ack_regs) {
                for (i = 0; i < hw->nr_ack_regs; i++)
index 66802a4390ccff59bd51025dbb62800e6fd92336..b3b33fa26acda7bb99483341980f47bed9e6a213 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/ioc3.h>
 #include <linux/rwsem.h>
+#include <linux/slab.h>
 
 #define IOC3_PCI_SIZE 0x100000
 
index 9aeb6811310001619baa9ffffbc4d4de2274ffcc..e9aeee16d922aba598f731e3cbd61b48e6d5b63c 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/pl022.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 /*
  * This macro is used to define some register default values.
index d21c24eaf0a95537baae7f22e783bff8658aa816..c4e04428992de8302b3b3e2a512927bdb159643b 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <mach/board.h>
index ba8ac4f599d3966179eb1ce3847dd5a268a96d2a..3c9ade69643f6526128114afbf892aae6958e28a 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
index 225ab60b02c466e8f0b9802b4f8c9a263bf5207c..95afb6b77395f3c60b4c8a18bafe2b4146369229 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
+#include <linux/slab.h>
 
 #include <mach/spi.h>
 #include <mach/edma.h>
index 8ed38f1d6c18d36daab177affb9fb1e015cd2c07..d256cb00604c55db5cc2ce25233b8d8e189c69be 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/highmem.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <linux/spi/dw_spi.h>
 #include <linux/spi/spi.h>
index e35b45ac5174f54c44cd3fe02d09127b1db50a32..db35bd9c1b24bf89f15c308de5915ce7fd04d97e 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/clk.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/spi/dw_spi.h>
 #include <linux/spi/spi.h>
 
index 1f0735f9cc76ab0232aa282f19f071b89be827ce..1f52755dc87824e9764b354557c86dfd901dc4a3 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/spi/dw_spi.h>
 #include <linux/spi/spi.h>
 
index 04747868d6c4d4605ec679f21306b650b4475657..77d4cc88edea137251be529ded2a53dc11a8aa61 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/spi/spi.h>
 #include <linux/fsl_devices.h>
+#include <linux/slab.h>
 
 #include <asm/mpc52xx.h>
 #include <asm/mpc52xx_psc.h>
index 6eab46537a0ae3a6bb1d52d9a9662fc24c60da18..cd68f1ce5cc3ffa78dcd7d6ad49bc49396dee834 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/of_spi.h>
 #include <linux/io.h>
 #include <linux/of_gpio.h>
+#include <linux/slab.h>
 #include <asm/time.h>
 #include <asm/mpc52xx.h>
 
index 715c518b1b68f78d820145a13e652f22d4d51dea..e0de0d0eedeaf26909075194abce7267b61dcddd 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <linux/spi/spi.h>
 
@@ -203,6 +204,7 @@ static inline void mcspi_write_chconf0(const struct spi_device *spi, u32 val)
 
        cs->chconf0 = val;
        mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, val);
+       mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0);
 }
 
 static void omap2_mcspi_set_dma_req(const struct spi_device *spi,
@@ -531,7 +533,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
                                        goto out;
                                }
 #ifdef VERBOSE
-                               dev_dbg(&spi->dev, "write-%d %04x\n",
+                               dev_dbg(&spi->dev, "write-%d %08x\n",
                                                word_len, *tx);
 #endif
                                __raw_writel(*tx++, tx_reg);
@@ -549,7 +551,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
                                        mcspi_write_chconf0(spi, l);
                                *rx++ = __raw_readl(rx_reg);
 #ifdef VERBOSE
-                               dev_dbg(&spi->dev, "read-%d %04x\n",
+                               dev_dbg(&spi->dev, "read-%d %08x\n",
                                                word_len, *(rx - 1));
 #endif
                        }
@@ -578,6 +580,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
        struct spi_master *spi_cntrl;
        u32 l = 0, div = 0;
        u8 word_len = spi->bits_per_word;
+       u32 speed_hz = spi->max_speed_hz;
 
        mcspi = spi_master_get_devdata(spi->master);
        spi_cntrl = mcspi->master;
@@ -587,9 +590,12 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
 
        cs->word_len = word_len;
 
-       if (spi->max_speed_hz) {
+       if (t && t->speed_hz)
+               speed_hz = t->speed_hz;
+
+       if (speed_hz) {
                while (div <= 15 && (OMAP2_MCSPI_MAX_FREQ / (1 << div))
-                                       > spi->max_speed_hz)
+                                       > speed_hz)
                        div++;
        } else
                div = 15;
@@ -751,11 +757,13 @@ static void omap2_mcspi_cleanup(struct spi_device *spi)
        mcspi = spi_master_get_devdata(spi->master);
        mcspi_dma = &mcspi->dma_channels[spi->chip_select];
 
-       /* Unlink controller state from context save list */
-       cs = spi->controller_state;
-       list_del(&cs->node);
+       if (spi->controller_state) {
+               /* Unlink controller state from context save list */
+               cs = spi->controller_state;
+               list_del(&cs->node);
 
-       kfree(spi->controller_state);
+               kfree(spi->controller_state);
+       }
 
        if (mcspi_dma->dma_rx_channel != -1) {
                omap_free_dma(mcspi_dma->dma_rx_channel);
index 5355d90d1bee10fc08a2a3728d1836f6d1a82696..24668b30a52d4a88a6bec93499e82c35886f7f31 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include <linux/spi/spi.h>
 
index 6c3a8557db2761871764983cde3f9ac7fa3adceb..160d3266205f864f4e49cc951171c7329a373500 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/interrupt.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
index c2f707e5ce74accbc44a4c3766a25ea2fde93272..36828358a4d8602a1fdbbc56f5aeb588e3467d1a 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index b76f2468a84a10d6afa8f6a583b1e9bb44c79bc3..b3a1f9259b62539d6f2b3bd4c2a501f93c337cee 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/cache.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/mod_devicetable.h>
 #include <linux/spi/spi.h>
 
@@ -40,7 +41,7 @@ static void spidev_release(struct device *dev)
                spi->master->cleanup(spi);
 
        spi_master_put(spi->master);
-       kfree(dev);
+       kfree(spi);
 }
 
 static ssize_t
@@ -256,6 +257,7 @@ int spi_add_device(struct spi_device *spi)
 {
        static DEFINE_MUTEX(spi_add_lock);
        struct device *dev = spi->master->dev.parent;
+       struct device *d;
        int status;
 
        /* Chipselects are numbered 0..max; validate. */
@@ -277,10 +279,11 @@ int spi_add_device(struct spi_device *spi)
         */
        mutex_lock(&spi_add_lock);
 
-       if (bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev))
-                       != NULL) {
+       d = bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev));
+       if (d != NULL) {
                dev_err(dev, "chipselect %d already in use\n",
                                spi->chip_select);
+               put_device(d);
                status = -EBUSY;
                goto done;
        }
index 1d41058bbab2a4227dc663f388e3e026e1ce84b3..10a6dc3d37ac835568083698b1165ea027893739 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
index f1db395dd88981ca4bf7f2e8777c8e9f2c6cceee..5265330a528fb2a367f164465fefb0b496e25c31 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
index 0ddbbe45e83442f77f2334e7e84a87d5d77ac810..7972e90774738d87d75b835be0a8555d63b78c58 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
 #include <linux/types.h>
index 4f0cc9d457e04b6c115d08a72014e83ff4e5bd58..14d052316502cfcf7334cbb57cf5181e02c2c3be 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/gpio.h>
 #include <linux/of_gpio.h>
 #include <linux/of_spi.h>
+#include <linux/slab.h>
 
 #include <sysdev/fsl_soc.h>
 #include <asm/cpm.h>
index b319f9bf9b9b902012ef33998d6e14f95d196ec7..dff63be0d0a8c7b23205d9374c209e3914805bfb 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
index 6d8d4026a07a6569e0ba2812a0ce705dc94c5b67..7cb5ff37f6e2662254eb66a321b1be2acb2c604b 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/wait.h>
 #include <linux/of_platform.h>
index 1fabede9e06184e49564456f74587c7c648fbdc6..151a95e40653e8908e362968212abd182aeaa5ae 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
index bf9540f5fb98de7ad1f7c523a96548382984848d..a3938958147c887ecbf803c6c806d668735b62de 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/device.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/tle62x0.h>
index ed34a8d419c7545b1a3912d9737e48c100852fb2..748d33a76d290286c6435ff3d11965c2e023525d 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <linux/of_platform.h>
 #include <linux/of_device.h>
index 172f90407b93aa1159fc2618e90e16ea1beb70fb..5ba92a2719a46e28453fbc913ba460080bb02b7c 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/ssb/ssb_driver_gige.h>
 #include <linux/pci.h>
 #include <linux/pci_regs.h>
+#include <linux/slab.h>
 
 
 /*
index f1dcd7969a5caabfcd292603933f113943fe4062..0e8d352246144766112b88db85fb2085f6e1361c 100644 (file)
@@ -246,20 +246,12 @@ static struct pci_controller ssb_pcicore_controller = {
        .pci_ops        = &ssb_pcicore_pciops,
        .io_resource    = &ssb_pcicore_io_resource,
        .mem_resource   = &ssb_pcicore_mem_resource,
-       .mem_offset     = 0x24000000,
 };
 
-static u32 ssb_pcicore_pcibus_iobase = 0x100;
-static u32 ssb_pcicore_pcibus_membase = SSB_PCI_DMA;
-
 /* This function is called when doing a pci_enable_device().
  * We must first check if the device is a device on the PCI-core bridge. */
 int ssb_pcicore_plat_dev_init(struct pci_dev *d)
 {
-       struct resource *res;
-       int pos, size;
-       u32 *base;
-
        if (d->bus->ops != &ssb_pcicore_pciops) {
                /* This is not a device on the PCI-core bridge. */
                return -ENODEV;
@@ -268,27 +260,6 @@ int ssb_pcicore_plat_dev_init(struct pci_dev *d)
        ssb_printk(KERN_INFO "PCI: Fixing up device %s\n",
                   pci_name(d));
 
-       /* Fix up resource bases */
-       for (pos = 0; pos < 6; pos++) {
-               res = &d->resource[pos];
-               if (res->flags & IORESOURCE_IO)
-                       base = &ssb_pcicore_pcibus_iobase;
-               else
-                       base = &ssb_pcicore_pcibus_membase;
-               res->flags |= IORESOURCE_PCI_FIXED;
-               if (res->end) {
-                       size = res->end - res->start + 1;
-                       if (*base & (size - 1))
-                               *base = (*base + size) & ~(size - 1);
-                       res->start = *base;
-                       res->end = res->start + size - 1;
-                       *base += size;
-                       pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
-               }
-               /* Fix up PCI bridge BAR0 only */
-               if (d->bus->number == 0 && PCI_SLOT(d->devfn) == 0)
-                       break;
-       }
        /* Fix up interrupt lines */
        d->irq = ssb_mips_irq(extpci_core->dev) + 2;
        pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
index 03dfd27c4bfba8cb78df400a12589be531879f6b..80ff7d9e60ded74e35c78dc1064cfd950af1eea3 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/pci.h>
 #include <linux/mmc/sdio_func.h>
+#include <linux/slab.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
index 9e50896233aa969e5fa145bcf630dd0ba9055363..a8dbb06623c96f17e61ad996df9647ab699a6740 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_regs.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 
index 26737a010c6d03080f345955ecfa97c30cc8fa27..6536a041d90dd671966bf478a474aefe2ec926ef 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/ssb/ssb.h>
 
 
index d0e6762fec50c6316193eae92a1b787320cbb276..f2f920fef10df9f2d0f5845fcf7ff70875c12350 100644 (file)
@@ -14,6 +14,7 @@
 #include "ssb_private.h"
 
 #include <linux/ctype.h>
+#include <linux/slab.h>
 
 
 static const struct ssb_sprom *fallback_sprom;
index e7f44215b5f383834b865b0791737f55e5838991..2f61500186f275b034e99e4e84edb31e75e4455f 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/slab.h>
 #include "main.h"
 #include "device.h"
 #include "send.h"
index deb41f5beda6d9c08abb45a5641df4dfbbe93bc8..2e9bb891a5dece8f93eb88c1e03a8416b0ad01ef 100644 (file)
@@ -109,6 +109,7 @@ extern int bat_debug_type(int type);
 #include <linux/kthread.h>     /* kernel threads */
 #include <linux/pkt_sched.h>   /* schedule types */
 #include <linux/workqueue.h>   /* workqueue */
+#include <linux/slab.h>
 #include <net/sock.h>          /* struct sock */
 #include <linux/jiffies.h>
 #include "types.h"
index c9b35d9f799121774e3abe64a6c6789c60d0d39c..0e2307f3cb96f6892f18d6df6df7d817acc73041 100644 (file)
@@ -26,6 +26,7 @@
 #include "translation-table.h"
 #include "types.h"
 #include "hash.h"
+#include <linux/slab.h>
 #include <linux/ethtool.h>
 #include <linux/etherdevice.h>
 
index 10f488f0e5ee732f49f6ad319ad046aa5e637a4a..2d54993ffb12c414eb8bca65ac8fec43f2fb5ddb 100644 (file)
@@ -81,6 +81,7 @@ I/O port base address can be found in the output of 'lspci -v'.
 #include "../comedidev.h"
 
 #include <linux/ioport.h>
+#include <linux/slab.h>
 
 #define _8255_SIZE 4
 
index 8db5ab63e36313714d1bb62676c7ab7a431283be..6625fdc8e9036348c84659dc7803dd1fdf52967b 100644 (file)
@@ -50,7 +50,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
@@ -58,6 +57,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour
 #include <linux/timex.h>
 #include <linux/timer.h>
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include "../../comedidev.h"
 #include <asm/io.h>
 #if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300)
index 9934a3cf25489cdf27330ab8c5e513da0b5bcabd..944f20ae5a6a311edc62bfc5f3e1b8ca0896cff6 100644 (file)
@@ -66,6 +66,7 @@ Configuration options:
 #include "../pci_ids.h"
 
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/interrupt.h>
 
 #include "amcc_s5933.h"
index 204f30ef6e9602b8d2b27cac5729bd74f1bfb007..92bcc205dd4bc84a200709ddd95b04f1e30efdae 100644 (file)
@@ -206,6 +206,7 @@ order they appear in the channel list.
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #include "../comedidev.h"
 
index b41e5e5963aa5f3caeeecfb8be0981e40d28060d..c54cca8b2565b05069f70a05d3796132c5a42bb3 100644 (file)
@@ -104,6 +104,7 @@ Caveats:
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #include "../comedidev.h"
 
index bc375e73abc105cdc6a3523d2c7e1c7583f13046..5632991760af52f61c6e6e61ecba5e76d2d2ffda 100644 (file)
@@ -32,6 +32,7 @@ Status: experimental
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 #include <linux/delay.h>
 #include <linux/pci.h>
index d7260cc86985665d5c41fcb92c70db15c229777b..41311d99473b89937a2c4964fb009e58114502cb 100644 (file)
@@ -90,6 +90,7 @@ Configuration Options:
 #include "../comedilib.h"
 #include "../comedidev.h"
 #include <linux/string.h>
+#include <linux/slab.h>
 
 /* The maxiumum number of channels per subdevice. */
 #define MAX_CHANS 256
index f12ef1cd6f53b3c8eb3447901b36b687ec2436da..9164ce158dcde3bf1477512ae73f42fab32aba1e 100644 (file)
@@ -43,6 +43,7 @@ Command support does not exist, but could be added for this board.
 
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include "das08.h"
 
index 10a87e6a809516ce80a9f0afd7d800b648bd390e..f2aadda9b2414dbe34c622f2f9b5448618273c32 100644 (file)
@@ -79,6 +79,7 @@ Computer boards manuals also available from their website www.measurementcomputi
 */
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <asm/dma.h>
 #include "../comedidev.h"
index 6ea59cc6b2bb5554fe08523e4ea266de9dadbed0..3c3e0455c7c412077f2066b71881edada32fd5f0 100644 (file)
@@ -101,6 +101,7 @@ TODO:
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 
 #include <linux/ioport.h>
index 99ca294b1ec560539961eae28d759d4ccab7f60a..e548763cf2f3ca1fcdab7bdf5f8199d2b683487a 100644 (file)
@@ -58,6 +58,7 @@ Notes:
 
 #include "../comedidev.h"
 
+#include <linux/gfp.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <asm/dma.h>
index fe5b4953f7ec617af8805df12b6fda0327759716..d330b1886846f866103ba746d2fb93653619258b 100644 (file)
@@ -46,6 +46,7 @@ Devices: [JR3] PCI force sensor board (jr3_pci)
 #include <linux/ctype.h>
 #include <linux/firmware.h>
 #include <linux/jiffies.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include "comedi_pci.h"
 #include "jr3_pci.h"
index c223f76031f6aa6eed91e04adec2a1af7cc0ff4d..9a4fffe5655ffb19fcb901a3e44607a13997d3b6 100644 (file)
@@ -52,6 +52,7 @@ except maybe the 6514.
 #define DEBUG 1
 #define DEBUG_FLAGS
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 
 #include "mite.h"
index 1e792d592f7343056af1637283442b740cf6daa3..68221bfba5dd64bf37051e1f142d67b5aefff304 100644 (file)
@@ -42,6 +42,7 @@ Commands are not supported.
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 
 #include "mite.h"
index dd75dfb34309f793e52a6f0528a8180417c4892b..9bff34cf06d1a709199c5e41cecf05710a4f6ea5 100644 (file)
@@ -65,6 +65,7 @@ TRIG_WAKE_EOS
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 
 #include <linux/ioport.h>
index c9b0395a61037c37e7c7c4fe79f3c54fee02c237..7ea64538e0556482f187f8b19b07bdd9ced246f8 100644 (file)
@@ -42,6 +42,7 @@ IRQ is assigned but not used.
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 
 #include <linux/ioport.h>
index 9017be3a92f15939e3fcd2c9123dbe2171101496..ddc312b5d20da3eef4519556071370c5de092cfb 100644 (file)
@@ -41,6 +41,7 @@ the PCMCIA interface.
 #undef LABPC_DEBUG
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 
 #include <linux/ioport.h>
index 3c88caaa9dabc2d72dcaf879be5d05bb3fb86cae..558e525fed37db604286071dd6cbf546ffe32c09 100644 (file)
@@ -77,6 +77,7 @@ NI manuals:
 /* #define LABPC_DEBUG    enable debugging messages */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 
 #include <linux/delay.h>
index 0b963bb3328bdcaff6efdbc3fae2baf6ea15876d..8ad1055a5cc1a66192c1405a3f70e9d8224baa10 100644 (file)
@@ -64,6 +64,7 @@ NI manuals:
 #include "../comedidev.h"
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "8253.h"
 #include "8255.h"
index d4634c4f02dc2ec7cd14e86c2a3de9056d3859a3..1ddc19c705a6b186f9aab5fb59f8be06bdee1a8a 100644 (file)
@@ -108,6 +108,7 @@ Options for ACL-8113, ISO-813:
 */
 
 #include <linux/interrupt.h>
+#include <linux/gfp.h>
 #include "../comedidev.h"
 
 #include <linux/delay.h>
index 9820759ec54f9da66f6c0ecb9d3cf5d0dfc32766..71c2a3aa379e419e477b3973e90db17b95b8f501 100644 (file)
@@ -36,6 +36,7 @@ Configuration Options:
 
 #include <linux/ioport.h>
 #include <linux/mc146818rtc.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <asm/dma.h>
 
index c9d75385755d471f703a6677e3f7ea6e8ebcdf00..9d6aa393ef13b83785efff2bee825662714c64fd 100644 (file)
@@ -102,6 +102,7 @@ A word or two about DMA. Driver support DMA operations at two ways:
 
 #include <linux/ioport.h>
 #include <linux/mc146818rtc.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <asm/dma.h>
 
index 6ca4105610c182b4e159aaf3d66a012f15ce1c7b..025a52e8981d1868d68497359b4a165d96bfc24a 100644 (file)
@@ -77,6 +77,7 @@ Configuration Options:
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 #include "pcm_common.h"
 #include <linux/pci.h>         /* for PCI devices */
index c1ae20ffb37957f77048bd021a944c5f17255f6c..5af4c8448a3a6ab1a670c2a72ce350bbd0dfac51 100644 (file)
@@ -76,6 +76,7 @@ Configuration Options:
 */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "../comedidev.h"
 #include "pcm_common.h"
 
index dd2b903727942ddd0dbd122b7b038dba4491f5ba..0792617ebc3557c327d5c05f36389c6af1d1ae7d 100644 (file)
@@ -36,6 +36,7 @@ Status: in development
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <asm/termios.h>
 #include <asm/ioctls.h>
index 75a9a62e1a7040f8d07afb570b547ee841401434..be1d83df0de51bd9448ed18de1daca41c6cc2e54 100644 (file)
@@ -44,6 +44,7 @@ Devices: [Fastwel] UNIOxx-5 (unioxx5),
 
 #include "../comedidev.h"
 #include <linux/ioport.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME "unioxx5"
 #define UNIOXX5_SIZE 0x10
index 6552ef6d82978f11b99e89a8028c7b5d6557399e..288fef4fcbcc345788cc46e87c5cdd1de00b66cb 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <asm/io.h>
 
 #include "../comedi.h"
index 19293d1f998da37ffd8ca42a65004d824ec86db3..8bf4471ce6c14c01912a4089b5857625b486b6fc 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 
 /* functions specific to kcomedilib */
 
index 01819d34201aec7b66cca833af6f1dc975e4f899..c438c489aa92fc9344e8a9defd9c633f1bda6b54 100644 (file)
@@ -23,6 +23,7 @@
  **********************************************************************/
 
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include "crystalhd_hw.h"
 
index 3eac70aa213c85231db2e0418fdfe40161228ece..54bad652c0c5022c195c6ca22c9881d8a778cc10 100644 (file)
@@ -16,6 +16,7 @@
 ***************************************************************************/
 
 #include <linux/version.h>
+#include <linux/slab.h>
 
 #include "crystalhd_lnx.h"
 
index 587dcc47786517bb77da2754121eb3f772f314be..73593b078b339fb3cf276941ee2fd3c870da8521 100644 (file)
@@ -24,6 +24,8 @@
  * along with this driver.  If not, see <http://www.gnu.org/licenses/>.
  **********************************************************************/
 
+#include <linux/slab.h>
+
 #include "crystalhd_misc.h"
 #include "crystalhd_lnx.h"
 
index e0eef12759e46eb9fc93c725957bd22ef7770be5..061add30ba8aa3c79569cb3b857fb257b3b9ef36 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/vmalloc.h>
 #include <linux/dma-mapping.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include <asm/delay.h>
 #include <sound/core.h>
index ddddf651266baa461915fb6c02b023b6dff57a7e..11c56bdb0ceb0ba6be38d48b130116c1d1c7b4c2 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/file.h>
 #include <linux/fcntl.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
index 46c7f78bb972ed2f4785a102d3402b8944565fcf..e76451c309f1f1b37eadb9a263b921c302e3a688 100644 (file)
@@ -21,6 +21,8 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
+
 #include "cx25821-video.h"
 
 static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
index 67f689de4daada8a8d110c9377ce65e62f6efc60..9e9b8c3c931157f2d78039a429bfe39f1c79653e 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include "cx25821.h"
 #include "cx25821-sram.h"
 #include "cx25821-video.h"
index c8905e0ac509563abfdfb851981e9632ec399db9..cc51618cffa9b419c0deb46631f8293e97df285b 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/syscalls.h>
 #include <linux/file.h>
 #include <linux/fcntl.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
index 3d7dd3f66541d9d3d91a050cdd5a3892d4eeaafa..6d48a1e26d1bf872668245f2919d731139598795 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/syscalls.h>
 #include <linux/file.h>
 #include <linux/fcntl.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
index dc7c603625c7ea28055c4149452b8f74f4d7bec8..81bd71fd816ee69a56d928b9122dc50fa34fa129 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <mach/board.h>
index 6a7d46cf11eb18e6cd856ee16f9b53f1f339ad48..c276f2f7583ac239c028ddf62918a760e784f0b7 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/spinlock.h>
 #include <linux/videodev2.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 #include <media/v4l2-dev.h>
 #include <media/msm_camera.h>
 #include <mach/camera.h>
index 62fd24d632d5cef6ef36d5ddc757862bf7be07aa..198656ac3de530ba68f39afd08b9bfa3be2fb22f 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/android_pmem.h>
+#include <linux/slab.h>
 #include <mach/msm_adsp.h>
 #include <linux/delay.h>
 #include <linux/wait.h>
index 03de6ec2eb44178d985f4c918f0acaae882f59fc..e61fdba6283867ac56cda2a2c21c557418378936 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2008-2009 QUALCOMM Incorporated.
  */
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/interrupt.h>
 #include <mach/irqs.h>
index 4f938f9dfc4709bc9960ac084de65703a5e4b084..e6f2d5124611d2202c608ed8b160d76274711cf6 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/i2c.h>
 #include <linux/uaccess.h>
index 70119d5e0ab3230a8e11eb4cc9d129133fa31f3c..791bd6c406154e5d82c1e9cc914b90938099d204 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/delay.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
index 88229f2663b56409007a5586dd85042b990dc70c..8fd7727ba234ee6636205f08e02a4a7f3080d051 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/delay.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
index 841792e2624b23bda21cb28fc21bd5843d752cf2..1459903a339d40d9fbb1d8b1d6669811da08b38b 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/i2c.h>
 #include <linux/uaccess.h>
index c801172aa9eecf024f9d38fe08f0f2037b7042c3..eb54724b1d3a59bb465291efc58174feec919f57 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/gpio_event.h>
 #include <linux/interrupt.h>
index e60e2c0db9c04d349411376e074a0e3c29fb58e8..97a511d11f49f168f2c973f68ef604b00e620f3d 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/input.h>
 #include <linux/gpio_event.h>
index 0638ec43601a9058b05ae7eb7b2f5de7fd7a261e..ca29e5eb070a37e79765d33dd7334b73c0ec76cf 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/hrtimer.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 enum {
        DEBOUNCE_UNSTABLE     = BIT(0), /* Got irq, while debouncing */
index 796de4faf85929d2dcd43cc7b718463ee53c7a78..b377ee1f5a5f7e1537154478127623bd1eaec10b 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/gpio_event.h>
 #include <linux/hrtimer.h>
index 503ba212dc9647bfa86bd8ae0a44b3a6b8c50938..6edfdd4ef80419e3fb8ff2e5805f8020876111d8 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/android_pmem.h>
 #include <linux/mempolicy.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
index 9069535fcaf18ba213086066dddf7dde9a46b764..f1e9d81674e85be3ef31118f1dddc73ebfe8be49 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/kthread.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/wait.h>
 
index e55a0db53a93f39bb8b1e20d280da85e8766e11e..8197765aae1e8d8b173ff120473e3f9eda421385 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/list.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 
 #include "adsp.h"
index ad2390f32a4f59bf903abac35d385886e3313844..a373f3522384aba567ba33213aad568ee55d8a5a 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/kthread.h>
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <linux/delay.h>
 
index cd818a526f836b122287e3faf4da5a9ec583f216..07b79d5836e5e984ac834f77695b7ee7596c80ce 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/kthread.h>
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <linux/delay.h>
 
index 4b43e183f9e863568bf9b17696417033f4c49946..ad989ee87690a13dd53ed8f05f2c65c6bd868d2d 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 #include <asm/atomic.h>
 #include <asm/ioctls.h>
index 3d950a245895f92a24964db9ae8aa6b2211e29d9..6ae48e72d1459cdb938a062bed40a9ed5b05c6a3 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kthread.h>
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <linux/delay.h>
 
index 7ed6e261d6c97ab0cb13e4c05961b04a75f840d9..530e1f35eed35946a799800ec28386a691b0ef4a 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kthread.h>
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <linux/delay.h>
 
index df87ca337b9476e313bdaf358dad5c432983d615..fe7809dd440100901f81b3d3077364303e9b3636 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/wakelock.h>
+#include <linux/gfp.h>
 
 #include <linux/msm_audio.h>
 
index f0f50e36805a3b38ec4f2ec0b5278ee1ae2ab4c4..effa96f34fdceddfe020fce8b656b4e4faa6d23e 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <asm/ioctls.h>
 #include <mach/msm_adsp.h>
index 1ad8b82c257019ab7836a9f0aadd0b3d9604ec3f..427ae6c0bea8730dd53c97fc80ea2321f2bf63bb 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <linux/kthread.h>
 #include <linux/wait.h>
 
index 69911a7bc87ac74fa122320ccb502c43a5c2350b..8744a6e499cbf530ec4e9f0e859db0c39a6ba1e8 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/err.h>
 #include <linux/sched.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
 #include <linux/platform_device.h>
index cd3910bcc4ed7491375e161b664f390e9df5f2a0..e9c28eddce3128117300a4fbf8c1fda54ffad57c 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/poll.h>
 #include <linux/platform_device.h>
 #include <linux/msm_rpcrouter.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
index 2597bbbc6f5e9da65fd14fa579320cc94b6a8566..1b152abb27830daecd2a3a2bc1ac63809a1e10b2 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/wakelock.h>
+#include <linux/slab.h>
 
 #include <linux/msm_rpcrouter.h>
 #include <linux/uaccess.h>
index 4de6bc9175954899b314c2ec14fa4bed8805c257..d2ca116a1c256beafc955db859175d984f62a740 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/module.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #ifdef CONFIG_HAS_EARLYSUSPEND
 #include <linux/earlysuspend.h>
 #endif
index c74234c66895eeaadfda57fe3267ecc2aac29631..db382ef90217727f9c0012528a7c223f8c5c83d4 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/types.h>
 #include <linux/mm.h>  /* PAGE_ALIGN() */
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/page.h>
 
index a67c622869d253c21d61d8694e6b535b9cc80351..7ac2c6d8e9a33b343122959d6ff2b2a25a5c69c8 100644 (file)
@@ -57,19 +57,8 @@ MA 02111-1307 USA
 
 extern void printques(int);
 
-#ifdef MODULE
 #include <linux/module.h>
 #include <linux/interrupt.h>
-
-
-MODULE_LICENSE("GPL");
-
-#endif
-
-#ifndef CONFIG_PCI
-#error  "DT3155 :  Kernel PCI support not enabled (DT3155 drive requires PCI)"
-#endif
-
 #include <linux/pci.h>
 #include <linux/types.h>
 #include <linux/poll.h>
@@ -84,6 +73,9 @@ MODULE_LICENSE("GPL");
 #include "dt3155_io.h"
 #include "allocator.h"
 
+
+MODULE_LICENSE("GPL");
+
 /* Error variable.  Zero means no error. */
 int dt3155_errno = 0;
 
@@ -472,9 +464,9 @@ static void dt3155_init_isr(int minor)
   /* 50/60 Hz should be set before this point but let's make sure it is */
   /* right anyway */
 
-  ReadI2C(dt3155_lbase[ minor ], CONFIG, &i2c_csr2.reg);
+  ReadI2C(dt3155_lbase[ minor ], CSR2, &i2c_csr2.reg);
   i2c_csr2.fld.HZ50 = FORMAT50HZ;
-  WriteI2C(dt3155_lbase[ minor ], CONFIG, i2c_config.reg);
+  WriteI2C(dt3155_lbase[ minor ], CSR2, i2c_csr2.reg);
 
   /* enable busmaster chip, clear flags */
 
index fd7f93d6c33df19b7ff9fa0cb7c772e74df73ddb..09d7d9b8272dce495075598658e125ab84d14601 100644 (file)
@@ -45,7 +45,7 @@ Purpose: Buffer management routines, and other routines for the ISR
 */
 
 #include <asm/system.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/types.h>
 
index 3ca253672ba1f5bd7bcbb3fb5aa319b18690caf4..e4d095b0b52a7a2fa3031a2a063ee3ddad67515d 100644 (file)
@@ -66,7 +66,6 @@
 
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/timer.h>
index a292b1edc41435886ceecc013db7754d67fe6f01..16fa13d4821f56694ef861c4e47e07e0ba71f978 100644 (file)
@@ -65,7 +65,6 @@
 
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/timer.h>
@@ -226,7 +225,7 @@ void ConfigMACRegs2(struct et131x_adapter *etdev)
        }
 
        /* Enable TXMAC */
-       ctl |= 0x05;    /* TX mac enable, FC disable */
+       ctl |= 0x09;    /* TX mac enable, FC disable */
        writel(ctl, &etdev->regs->txmac.ctl);
 
        /* Ready to start the RXDMA/TXDMA engine */
index 4a55fbfbd59dbd73ba08c1a19a102c857bfae27a..34cd5d1b586ac854fdcda316e5f5bbcf40d1c953 100644 (file)
@@ -66,7 +66,6 @@
 
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/timer.h>
index 41019e390af5cd2c426a00f20160d3a5e03157f7..c64bb2c6d0d69d6c9f6ed605d6e80b9aa0518a61 100644 (file)
@@ -65,7 +65,6 @@
 
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/timer.h>
index 5ad7e5a6f6313041c9955b929503b37e38c2608f..1dd5fa5b888b231461fb1b44b8efb3a1f734a457 100644 (file)
@@ -68,7 +68,6 @@
 
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/timer.h>
index 8b6e0b7ec5688a9e4a2527e49c965962d50c358d..cb7f6775ce0a72c23f1fd319f2eaacf2f0917255 100644 (file)
@@ -66,7 +66,6 @@
 
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/timer.h>
index 40f8954dde478b526039b3729ad9267b9d16ce6f..ab047f2ff72cd10e1a3a17e34803f4e8f04b1893 100644 (file)
@@ -65,7 +65,6 @@
 
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/timer.h>
index d42ba1696999af76b9e677dd6b93f73239d4f7fb..372a7c6791ca29a0af3e496d1a6312199e49db4e 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/firmware.h>
 #include <linux/mutex.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 #include <linux/videodev2.h>
 #include <media/tuner.h>
index a8bb264e0074edca23e0e8f77940c0524344cb6f..ee622ff1707e063482ee1611b16b6b2605988415 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/device.h>
 #include <linux/i2c.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 
 #include "go7007-priv.h"
index 3af79242313e5cdfb6281b46d08e0a0ef9a3a346..723c1a64d87f3007f5f7da252e160d7cd0453f66 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/unistd.h>
 #include <linux/time.h>
index dc89502ea1b7ddce759040df0dc9d7a9b77658bb..93f26048e3b4570ba1b1a5c467740bc82883be7d 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/usb.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-i2c-drv.h>
index 1de2dfb16d3f7c1b30c0633b9cd403d282b0cdd0..7547a8f77345a00fc3c261ed0624eb3a31b95306 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/usb.h>
 #include <dvb-usb.h>
index 03c4dfc138a1e08fe5faa31603bc929d84a983fc..deac938d850535b367cf35d0f5a3c195b5faa96c 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/i2c.h>
 #include <linux/mutex.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <asm/system.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
index d196e16fe72b679023b04efd615b5e233ed53818..5c12b4d384595013bbd7667c7d5f0b70a035f837 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 
 #include "wis-i2c.h"
 
index 0f2b4a0ceccfd566610ba940843e4bfde3203956..73f2283a88034f0b285d3499b05e22b2c57188e5 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 
 #include "wis-i2c.h"
 
index c723e4aa7147bfa338dce705ba18a3516e5fde0b..b1013291190f162f6668af96c8593c81b57cb7e9 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
+#include <linux/slab.h>
 #include <media/tuner.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
index 1983839f554d0aa2c7e450f79b1d83bcc36fbd27..315268d130dd61311873a36bd3ae373ed75f3539 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 
 #include "wis-i2c.h"
 
index f97e2be3c0b51d49f2b262980d7942d5204f0f00..3ac6f785c4ad6c4796de320952980e2606a4c0dd 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 
 #include "wis-i2c.h"
 
index d46eb145484f1f24a5d70322baa1732fd5c01022..e69e9ee704ace1017e5c9648e466149a3211f619 100644 (file)
@@ -20,6 +20,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include "osd.h"
 #include "logging.h"
 #include "VmbusPrivate.h"
index ef38467ed4e20d51ce71033265717d1ebc3023dd..5f92c2102ab4ca854e73a9c3e0a61eb0fbf5948c 100644 (file)
@@ -20,6 +20,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include "osd.h"
 #include "logging.h"
index 43c2e685501554ae6d12664ea03cf12fbba3de09..e0ea9cf90f0312044a91474110b5d5571bd0e5f5 100644 (file)
@@ -22,6 +22,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include "osd.h"
 #include "logging.h"
index 51149e69f3e84032b05fd76dbd11aed89f2922d8..3a1112d29aeb731962939b85bc70c571c83b1376 100644 (file)
@@ -21,6 +21,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include "osd.h"
 #include "logging.h"
@@ -305,9 +306,9 @@ void HvCleanup(void)
        DPRINT_ENTER(VMBUS);
 
        if (gHvContext.SignalEventBuffer) {
+               kfree(gHvContext.SignalEventBuffer);
                gHvContext.SignalEventBuffer = NULL;
                gHvContext.SignalEventParam = NULL;
-               kfree(gHvContext.SignalEventBuffer);
        }
 
        if (gHvContext.HypercallPage) {
index 1c717f9a554ef36cc1dd43725f54989b99db5b9f..e4bf8229750469d4e20ca92a90767a6743cfb002 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include "osd.h"
 #include "logging.h"
 #include "NetVsc.h"
index 1ab7fa97d3735bb608f395f02a5734c522c85c69..6704f64c93f0bf329733f7b35502a045b715cb97 100644 (file)
@@ -20,6 +20,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 #include "osd.h"
 #include "logging.h"
@@ -750,6 +751,7 @@ static int RndisFilterOpenDevice(struct rndis_device *Device)
 
        ret = RndisFilterSetPacketFilter(Device,
                                         NDIS_PACKET_TYPE_BROADCAST |
+                                        NDIS_PACKET_TYPE_ALL_MULTICAST |
                                         NDIS_PACKET_TYPE_DIRECTED);
        if (ret == 0)
                Device->State = RNDIS_DEV_DATAINITIALIZED;
index 38ea1407f222d8308ad42f5098f1f9a4ce9711eb..e426a23ca537e12d60b4c913612b92dedc258bd0 100644 (file)
@@ -20,6 +20,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include "osd.h"
index 3d0a240ed664c30590bcfaf5c4a237485e7dd532..2f84bf7c0a9f8d59bf6edc127d806d69e4615d84 100644 (file)
@@ -21,6 +21,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include "osd.h"
 #include "logging.h"
 #include "VersionInfo.h"
index abeac12c093d4900a06bf75162808a7cd58c603f..8f1fda3256ad2492119808b5a5f2bd87916a76fc 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/major.h>
 #include <linux/delay.h>
 #include <linux/hdreg.h>
+#include <linux/slab.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_eh.h>
index 1af3dcbafd6554507c7da8f01618cf6ead2271f8..ab27d9a4446d1caf612203480bf81769cb722f95 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/in.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 #include <net/route.h>
 #include <net/sock.h>
@@ -402,8 +403,7 @@ static int netvsc_probe(struct device *device)
        if (!net_drv_obj->Base.OnDeviceAdd)
                return -1;
 
-       net = alloc_netdev(sizeof(struct net_device_context), "seth%d",
-                          ether_setup);
+       net = alloc_etherdev(sizeof(struct net_device_context));
        if (!net)
                return -1;
 
index 3a4793a0fd050996d83c2de8e07d5e1183dfd4c4..9aea31067295b29b62aa9243c94c560d4de0fb35 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/time.h>
 #include <linux/io.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include "osd.h"
 
 struct osd_callback_struct {
index 3988f4bec1cef29b830e3d9b43dbc2992aee0415..8a58272b8039af95322c341dede29465d4b649e1 100644 (file)
@@ -19,6 +19,7 @@
  *   Hank Janssen  <hjanssen@microsoft.com>
  */
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/blkdev.h>
index 2c906195b9c8b5a65d825386c0017c856e0a4700..3397ef08e0aaa87c25152b48c840a4b2d015949b 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/sysctl.h>
 #include <linux/pci.h>
 #include <linux/dmi.h>
+#include <linux/slab.h>
 #include "VersionInfo.h"
 #include "osd.h"
 #include "logging.h"
index 33d16b6f7b50089eca6c915d0caa3f6d8deae37a..db2dd537ffb0dcb57ce478c69efcf7e444515e3f 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/sysfs.h>
 #include <linux/rtc.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
index f008837e5a147f44d3508bc738e07f8c5af5bba5..82e43588e8a5c35d692c7ff130247e5a96bcc460 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 
 #include <linux/sysfs.h>
 #include <linux/list.h>
@@ -617,7 +618,7 @@ static int lis3l02dq_thresh_handler_th(struct iio_dev *dev_info,
 static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s)
 {
        struct iio_work_cont *wc
-               = container_of(work_s, struct iio_work_cont, ws_nocheck);
+               = container_of(work_s, struct iio_work_cont, ws);
        struct lis3l02dq_state *st = wc->st;
        u8 t;
 
index a6b7c72a86f48c8925cc7e4642e74c2b027ca124..a4d97ea0df3d8adc73b0e5c6f515c2b5cfbf5c49 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/spi/spi.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -492,6 +493,9 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
        struct lis3l02dq_state *state = indio_dev->dev_data;
 
        state->trig = iio_allocate_trigger();
+       if (!state->trig)
+               return -ENOMEM;
+
        state->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
        if (!state->trig->name) {
                ret = -ENOMEM;
index cedcaa2b3d1f2d5d81d4bac4a59878aeb8be4662..1c229869a22defb8a4ba582ad9182f70cece1115 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/gpio.h>
 #include <linux/fs.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
 #include <linux/sysfs.h>
index d5ea237793a6b88c917ba297a97a83b81ffec18a..40cbab2a659223e4ea0ba50b7b01950e055e93e4 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/gpio.h>
 #include <linux/fs.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
 #include <linux/sysfs.h>
index 9703881cb3f8b0e0116bcb2ad6cd94c00c2e72c7..773f1d1d9c6ee490312f7138c9e96a870eb48ca2 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/i2c.h>
 #include <linux/rtc.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -556,6 +557,7 @@ error_put_reg:
        if (!IS_ERR(st->reg))
                regulator_put(st->reg);
 error_free_st:
+       i2c_set_clientdata(client, NULL);
        kfree(st);
 
 error_ret:
@@ -573,6 +575,7 @@ static int max1363_remove(struct i2c_client *client)
                regulator_disable(st->reg);
                regulator_put(st->reg);
        }
+       i2c_set_clientdata(client, NULL);
        kfree(st);
 
        return 0;
index a953eac6fd62e8b7e32a620f9233b5823a7e5ab7..f94fe2d38a977e712daad3c2477e6156846a44a2 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/gpio.h>
 #include <linux/workqueue.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
index b456dfc8fe27b008387bce803db0df9cd9aaa0c6..1d77082c8531862db21b72ffece6a90417b43209 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/cdev.h>
+#include <linux/slab.h>
 #include "iio.h"
 #include "trigger_consumer.h"
 
@@ -536,6 +537,7 @@ static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
        sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
 }
 
+/* Return a negative errno on failure */
 int iio_get_new_idr_val(struct idr *this_idr)
 {
        int ret;
@@ -659,7 +661,7 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
        for (i = 0; i < dev_info->num_interrupt_lines; i++) {
                dev_info->event_interfaces[i].owner = dev_info->driver_module;
                ret = iio_get_new_idr_val(&iio_event_idr);
-               if (ret)
+               if (ret < 0)
                        goto error_free_setup_ev_ints;
                else
                        dev_info->event_interfaces[i].id = ret;
index ebe5cccb4034ce5711f6b0a765f4986abefb05bf..e53e214bfeb0eb59ee4663b57f3b9cb97522fdf9 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/cdev.h>
 #include <linux/idr.h>
+#include <linux/slab.h>
 
 #include "iio.h"
 #include "ring_generic.h"
index 693ebc48597cf1d7b4495c837a98e20de620109b..35ec80ba444fc09c266c6e1a93b2ecce34e84a50 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 
 #include "iio.h"
 #include "trigger.h"
index 78b9432c81057bcf8b019bf9835c32d2e5d875b2..8770a00e365225239b98e0f46e4868a02e1957fa 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/pm.h>
 #include <linux/hwmon.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include "../iio.h"
 #include "tsl2563.h"
@@ -681,6 +682,7 @@ static int __devinit tsl2563_probe(struct i2c_client *client,
 fail2:
        iio_device_unregister(chip->indio_dev);
 fail1:
+       i2c_set_clientdata(client, NULL);
        kfree(chip);
        return err;
 }
@@ -691,6 +693,7 @@ static int tsl2563_remove(struct i2c_client *client)
 
        iio_device_unregister(chip->indio_dev);
 
+       i2c_set_clientdata(client, NULL);
        kfree(chip);
        return 0;
 }
index 6f7f4d5a93f3ef83aea226fa2ca6bb51d2383ead..cf22c091668cfaaf402853a81334d26032f22929 100644 (file)
@@ -7,6 +7,7 @@
  * the Free Software Foundation.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/device.h>
@@ -292,7 +293,7 @@ again:
                return -EAGAIN;
        memcpy(data, last_written_p_copy, ring->buf.bpd);
 
-       if (unlikely(ring->last_written_p >= last_written_p_copy))
+       if (unlikely(ring->last_written_p != last_written_p_copy))
                goto again;
 
        iio_unmark_sw_rb_in_use(&ring->buf);
index 539e4169a02e8bc32b21c56c2f47b8fb5735e7cf..0c3bad3187f50648046072617876e4648bb8dd7b 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include "../iio.h"
 #include "../trigger.h"
index e310dc0098559c424d5100d03401109d2976d21c..4295bbc7b50d0f55646eea055974aa555c79c150 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/rtc.h>
 #include "../iio.h"
 #include "../trigger.h"
index fd4890de8dbcd3cf6837099d29d5fa608ec5d40c..ca092247f363602bdbf62c227223f42928ac27ee 100644 (file)
@@ -11,6 +11,8 @@
 
 #include "driver.h"
 
+#include <linux/slab.h>
+
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 0392a4bc8cc8cf96ce253d61c7072fcbe8ee8496..258555417bc7aeaa02a53f80222721d77a870e2d 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "audio.h"
index decbaa971b68f7ebbefe47520632e5451b1e29e4..bb8c9da5803ff24de76f610256238d037a3ae958 100644 (file)
@@ -10,6 +10,9 @@
  */
 
 #include "driver.h"
+
+#include <linux/slab.h>
+
 #include "dumprequest.h"
 
 
index 6ef4455d87d8754b1ae6d1f3f7046316f80517a9..32b6ca75cadbcf89f3c02527c7b6f2c823846faa 100644 (file)
@@ -12,6 +12,7 @@
 #include "driver.h"
 
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 #include <sound/core.h>
 #include <sound/rawmidi.h>
index dd98121eb80bb582bf515b8e4a9b740bd6f5a545..fbe4b083eac5bdb9ddd19f9c8a9eca48a6748193 100644 (file)
@@ -11,6 +11,8 @@
 
 #include "driver.h"
 
+#include <linux/slab.h>
+
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
index 3431f5cd28525d527157f50ab2516a3fd7e277e1..fbcd6e150aaff741a2868be754d6c584a36bacb8 100644 (file)
@@ -11,6 +11,8 @@
 
 #include "driver.h"
 
+#include <linux/slab.h>
+
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 685c529950eb56541683a2439b9dfd1a71702354..4983f2b51cf2df1e7cb5f9df5b539de4eecb7158 100644 (file)
@@ -11,6 +11,8 @@
 
 #include "driver.h"
 
+#include <linux/slab.h>
+
 #include "audio.h"
 #include "capture.h"
 #include "control.h"
index 58fef82c247d991a30db7c6b653bc6b107db9efe..28eb89983f36be2ab088ccdf17fa2345a000a080 100644 (file)
@@ -11,6 +11,8 @@
 
 #include "driver.h"
 
+#include <linux/slab.h>
+
 #include "audio.h"
 #include "control.h"
 #include "variax.h"
index e936717d1f4bb2aefbaeb36c4edde83bbee4ff03..3875a722d12b76629bea142dd3c80ea58eb7b922 100644 (file)
@@ -46,7 +46,6 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/errno.h>
index 3085e38a6f9904c974e0814b6bbeb268808dbbd2..00a555b83354e773f4f366368b6a82e4c6d6f866 100644 (file)
@@ -153,6 +153,14 @@ int cvmx_helper_board_get_mii_address(int ipd_port)
                 * through switch.
                 */
                return -1;
+
+       case CVMX_BOARD_TYPE_CUST_WSX16:
+               if (ipd_port >= 0 && ipd_port <= 3)
+                       return ipd_port;
+               else if (ipd_port >= 16 && ipd_port <= 19)
+                       return ipd_port - 16 + 4;
+               else
+                       return -1;
        }
 
        /* Some unknown board. Somebody forgot to update this function... */
index 00cc91df6b46a2448d2da9040fa3ba196644b2a2..635bb86cdcff38297e7d9a2201f3b35544977c20 100644 (file)
@@ -26,6 +26,7 @@
 **********************************************************************/
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 
 #include <asm/octeon/octeon.h>
 
index 4a2161f70c7f734646f131013f5d8914296970a9..e50a17d807072c150f082daf655b3a459fb9b1cf 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/phy.h>
+#include <linux/slab.h>
 
 #include <net/dst.h>
 
index 8c47b1a686271f041fc4701ba83ced08ba7098e6..84be4b2cd692f77976bb33eeb66dedca717d49ec 100644 (file)
@@ -23,6 +23,7 @@
 /*     Platform dependent.                                              */
 /*                                                                      */
 /************************************************************************/
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/if_arp.h>
 #include <linux/uaccess.h>
index 5e6a12037b12e10af4e285b93fc86b26ff532310..0ce65b5b9456dad4e795e134358b3dfc128eb4ba 100644 (file)
@@ -38,6 +38,7 @@
 
 #include "linux/netlink.h"
 #include "linux/rtnetlink.h"
+#include "linux/slab.h"
 
 #include <net/iw_handler.h>
 
index 330d1b95cb889435670aa31d361a5204dbb242be..7e66c2d72a6913c6dbac5fe23d98d0458a479188 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/uaccess.h>
 #include <linux/wireless.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 
 #include "zdcompat.h"
index 47cbce1346a9384ea820ccf58d53dac061cbf342..b0037568e870127bb4d556887a65840ed47431f9 100644 (file)
@@ -27,6 +27,7 @@
 #include "usbdrv.h"
 
 #include <linux/netlink.h>
+#include <linux/slab.h>
 #include <net/iw_handler.h>
 
 /* Memory management */
index a2f5cb1f529884dc1d995bfddbeb458af8d39f7a..5ecf38e355a8e02c77da3ea851336b1e3be382c0 100644 (file)
@@ -28,6 +28,7 @@
 #include "usbdrv.h"
 
 #include <linux/netlink.h>
+#include <linux/gfp.h>
 #include <net/iw_handler.h>
 
 
index 6b336ede8867eaf989986eb869cb5b83de8ed19b..93459cadc472f75dee6c3ff52f4409ba992e6d8e 100644 (file)
@@ -28,6 +28,7 @@
 #include "usbdrv.h"
 
 #include <linux/netlink.h>
+#include <linux/slab.h>
 #include <net/iw_handler.h>
 
 extern void zfLnxInitUsbTxQ(zdev_t *dev);
index 53d2a45d55f9672deddb79aa25dc61cda1eef57d..a74f7eea56e466e159f29700c716cede9a00e471 100644 (file)
@@ -26,6 +26,7 @@
 #include "usbdrv.h"
 
 #include <linux/netlink.h>
+#include <linux/slab.h>
 #include <net/iw_handler.h>
 
 extern void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo);
index 4cd9b7f5a8871fcba539183869cf8e47120c5652..bb89d85a4c7ce3e20fbeecdad6c5ffe3f0156b3f 100644 (file)
@@ -29,6 +29,7 @@
 #endif
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "usbdrv.h"
index 9095158fb1b3a1a908c55a1bc5b7f3ff0773681a..f940a34c1a0c3d712ba0808bd1d139a0e2869cab 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/ioctl.h>
 #include <linux/io.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include "poch.h"
 
index 5d04bf5b021a8c24b9534339ec194bc3f5659e05..eed0e5545a557d1904fecaaf0e66ed5a7c39713e 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/mutex.h>
 #include <linux/string.h>
 #include <linux/in.h>
+#include <linux/slab.h>
 
 #include "netfs.h"
 
index aacd25bfb0cb8e00fc554f30316890cc7ada47e0..79819f07bfb93c5bb4f053692555c7b8545bea74 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/fs.h>
 #include <linux/jhash.h>
 #include <linux/namei.h>
+#include <linux/slab.h>
 #include <linux/pagemap.h>
 
 #include "netfs.h"
index 22fef18cae90565ee9b4e7659905260586b865f8..6710114cd425962f8caa7cae425bc050aec2c909 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/backing-dev.h>
 #include <linux/fs.h>
 #include <linux/fsnotify.h>
-#include <linux/slab.h>
 #include <linux/mempool.h>
 
 #include "netfs.h"
index af7f262e68c2040e86440d845055a08c6d2f8b46..4a86f0b1ea888fcadbfebaa5ac5fe303b5bc6322 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/kthread.h>
 #include <linux/pagemap.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/swap.h>
 #include <linux/syscalls.h>
 #include <linux/vmalloc.h>
index 3bad888ced13bb669e122e26daa7f71030c75f29..cdc4dd50d638a51abc240c780989b4433856b27c 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/ktime.h>
 #include <linux/fs_struct.h>
index 5e422e254ee8931e561cce301bfc2654ce958bba..ee5eb12b9285a8579bfdbef821cf80548a4e5ad7 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/device.h>
 #include <linux/genhd.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 #include <linux/lzo.h>
 #include <linux/string.h>
 #include <linux/swap.h>
index 6af430419070046c8277f75ae3c8b24ef1ff9acc..e665d862281ccd25997fff341903ce063dbe5324 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "rt_config.h"
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 /* Following information will be show when you run 'modinfo' */
 /* *** If you have a solution for the bug in current version of driver, please mail to me. */
index b5c78aecf5e3a18d20b3cdc750158fbdf327c3e8..fd9a2072139b668670f3a69fa4d323c0a2d3e18a 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/firmware.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "rt_config.h"
 
 unsigned long RTDebugLevel = RT_DEBUG_ERROR;
index 1873a79bb03308cbbf94812e20fb2218fd8b285c..740db0c1ac01c28adc17eb146161f6fce5b69bb8 100644 (file)
@@ -63,6 +63,7 @@ struct usb_device_id rtusb_usb_id[] = {
        {USB_DEVICE(0x07D1, 0x3C11)},   /* D-Link */
        {USB_DEVICE(0x14B2, 0x3C07)},   /* AL */
        {USB_DEVICE(0x050D, 0x8053)},   /* Belkin */
+       {USB_DEVICE(0x050D, 0x825B)},   /* Belkin */
        {USB_DEVICE(0x14B2, 0x3C23)},   /* Airlink */
        {USB_DEVICE(0x14B2, 0x3C27)},   /* Airlink */
        {USB_DEVICE(0x07AA, 0x002F)},   /* Corega */
index c2f472ee6eb6f20cd936ac031d024cba162555df..be2d17f60c35e8a1f873c971cc578b4d84cd908d 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/random.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include <asm/uaccess.h>
 
index bd5e77bf716213df8c27900c9c1f6d00a2a63ea3..c5b80f9c32c0638b29c4c0785d82a37ee35db575 100644 (file)
@@ -31,6 +31,7 @@
 ******************************************************************************/
 #include <linux/wireless.h>
 #include <linux/kmod.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 
 #include "ieee80211.h"
index b1757acabedcd331e706d785b344a7f518da6756..55d12e3271de685b0230eeed253fa71e8cf95ff0 100644 (file)
@@ -30,6 +30,7 @@
 #undef RX_DONT_PASS_UL
 #undef DUMMY_RX
 
+#include <linux/slab.h>
 #include <linux/syscalls.h>
 #include <linux/eeprom_93cx6.h>
 
index ea96c49569304fbac8a1b4c6a882b841baec6f59..d1d7b0866755522db2970bf4e7cc92b303cb8fee 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/random.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include <asm/uaccess.h>
 #ifdef ENABLE_DOT11D
index a3302d5e01ab55d88b8c0e84844cb8343494ad1d..de57967b9681d71c72ae630b0d3e3b0364aac79c 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/wireless.h>
 #include <linux/version.h>
 #include <linux/kmod.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 
 #include "ieee80211.h"
index e2cbfd3aa00f11d564f73137253b9a0a03c61765..e8699616fad44a0fd0fa1446af942e4aeb755151 100644 (file)
@@ -1,5 +1,6 @@
 #include "ieee80211.h"
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include "rtl819x_TS.h"
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
index 886105db8b7c3bd97790da9b2f5531b350824cc3..bb7e1ef28d3b20c5eb4acb04b09bc959a69e8bb0 100644 (file)
@@ -47,6 +47,7 @@
 
 //#define CONFIG_RTL8192_IO_MAP
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include "r8192E_hw.h"
 #include "r8192E.h"
index 9d8cb0e575d3def3b6ebbf0c3c99ba3ed461c207..84a4e23b60b3fa6518c4ff25f174707bfb9f16c1 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/random.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include <asm/uaccess.h>
 #include "dot11d.h"
index 122f8004904b1a4484fa4bd8e166001913ec65f3..727cc552c5eef4e93d65b226ade2bbd8836125e6 100644 (file)
@@ -31,6 +31,7 @@
 ******************************************************************************/
 #include <linux/wireless.h>
 #include <linux/kmod.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 
 #include "ieee80211.h"
index 60cf1f8781ce41f35ce27cba4cda0bb76d713915..38468c53967506a2a7f2b306613084dba9785406 100644 (file)
@@ -1,5 +1,6 @@
 #include "ieee80211.h"
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include "rtl819x_TS.h"
 
 void TsSetupTimeOut(unsigned long data)
index 7d0305cc21062320969ed6426d3f0adb9ecb752f..04d9b85f3d4cb8f372f141109e5af5545fdaefef 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #undef LOOP_TEST
 #undef DUMP_RX
@@ -112,14 +113,17 @@ u32 rt_global_debug_component = \
 
 static const struct usb_device_id rtl8192_usb_id_tbl[] = {
        /* Realtek */
+       {USB_DEVICE(0x0bda, 0x8171)},
        {USB_DEVICE(0x0bda, 0x8192)},
        {USB_DEVICE(0x0bda, 0x8709)},
        /* Corega */
        {USB_DEVICE(0x07aa, 0x0043)},
        /* Belkin */
        {USB_DEVICE(0x050d, 0x805E)},
+       {USB_DEVICE(0x050d, 0x815F)}, /* Belkin F5D8053 v6 */
        /* Sitecom */
        {USB_DEVICE(0x0df6, 0x0031)},
+       {USB_DEVICE(0x0df6, 0x004b)},   /* WL-349 */
        /* EnGenius */
        {USB_DEVICE(0x1740, 0x9201)},
        /* Dlink */
index 27d925712cddfca52b7d92eccfc4b0c7f2499c33..d54e3a77423ff2f79b70c47f312e7b4af7066341 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/random.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include <asm/uaccess.h>
 #ifdef ENABLE_DOT11D
index c0b2c02b0ac458fbcf56ec727f252f74c876bce5..750e94e17114dfd65f5530b79310abca3d633910 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/wireless.h>
 #include <linux/version.h>
 #include <linux/kmod.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 
 #include "ieee80211.h"
index d1275e887f0cdcd198903db17bd0c22b4c4f7ef2..451120ff2130e62f6fd3a155614721eb493f2756 100644 (file)
@@ -1,5 +1,6 @@
 #include "ieee80211.h"
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include "rtl819x_TS.h"
 
 void TsSetupTimeOut(unsigned long data)
index f1e085ba1cf1639c7b9f7761feaf04bf320dc470..68ebb02567714ef22095e02d87f7acad7addd352 100644 (file)
@@ -70,6 +70,7 @@ double __extendsfdf2(float a) {return a;}
 #include "r8192U_dm.h"
 //#include "r8192xU_phyreg.h"
 #include <linux/usb.h>
+#include <linux/slab.h>
 // FIXME: check if 2.6.7 is ok
 
 #ifdef CONFIG_RTL8192_PM
index dd7ea4c075dbb319d5148c25fad0601592858d82..eb44b60e1eb542d735cb0cbabbff1e55109008c9 100644 (file)
@@ -394,6 +394,7 @@ MODULE_DEVICE_TABLE(dmi, samsung_dmi_table);
 
 static int __init samsung_init(void)
 {
+       struct backlight_properties props;
        struct sabi_retval sretval;
        const char *testStr = "SECLINUX";
        void __iomem *memcheck;
@@ -486,12 +487,14 @@ static int __init samsung_init(void)
                goto error_no_platform;
 
        /* create a backlight device to talk to this one */
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = MAX_BRIGHT;
        backlight_device = backlight_device_register("samsung", &sdev->dev,
-                                                    NULL, &backlight_ops);
+                                                    NULL, &backlight_ops,
+                                                    &props);
        if (IS_ERR(backlight_device))
                goto error_no_backlight;
 
-       backlight_device->props.max_brightness = MAX_BRIGHT;
        backlight_device->props.brightness = read_brightness();
        backlight_device->props.power = FB_BLANK_UNBLANK;
        backlight_update_status(backlight_device);
index 265de7949a78758e8c83cd9381b5681785f762c7..88880734921a8a8a1dd8ea7a50354bf255e41bab 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <asm/ioctl.h>
 #include <linux/ioport.h>
 #include <asm/io.h>
index 9c82a1a81ccc8ba06a0bfe9cb90791e158eb5e59..8d7261c052eb4d9337feab41b3fb436b1fc17b76 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/fb.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/console.h>
 #include <linux/screen_info.h>
index 698aade79d40a3eb921415d0e4befef4b9a3217c..c976c6b4d28a6165c74d702b5c124eb6f19280f7 100644 (file)
@@ -107,6 +107,7 @@ static const char StripVersion[] = "1.3A-STUART.CHESHIRE";
 #include <linux/serialP.h>
 #include <linux/rcupdate.h>
 #include <linux/compat.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 #include <net/net_namespace.h>
 
index 8f6223c8303a6f9a390fa6158e6268eac738de9f..a78ade0dc6874fa78cfa2e6072f27751f2c19dfd 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/mm.h>
 #include <linux/fb.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include "udlfb.h"
 
index 173b018c56d8c6011ba73d98b542564649cff5fc..3f95605427a7447c92ebd2e2b95d7600adafa20e 100644 (file)
@@ -17,6 +17,8 @@
  * USA.
  */
 
+#include <linux/slab.h>
+
 #include "usbip_common.h"
 #include "stub.h"
 
index ba1678fa6311b33b736bfad74fe5cdd02b1f944e..6665cefe573b539a2c4046bc2280594500f8d2a6 100644 (file)
@@ -17,6 +17,7 @@
  * USA.
  */
 
+#include <linux/slab.h>
 
 #include "usbip_common.h"
 #include "stub.h"
index 815fb7cc3b2362d45c2af9e0def402d9a24ff195..bc2674086673b058d769744baae59b93bdd24b4a 100644 (file)
@@ -17,6 +17,8 @@
  * USA.
  */
 
+#include <linux/slab.h>
+
 #include "usbip_common.h"
 #include "stub.h"
 #include "../../usb/core/hcd.h"
index e2ab4f3fdac236e2464b43a9e84c51756361e068..d7136e2c86faa16a1e64638047dc0109dca0d533 100644 (file)
@@ -17,6 +17,8 @@
  * USA.
  */
 
+#include <linux/slab.h>
+
 #include "usbip_common.h"
 #include "stub.h"
 
index 7a45da8f9565e3731538095531402ad5833d87d6..e3fa4216c1cdaf0552f1e8f45c9e826bbf35f622 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/tcp.h>
 #include <linux/in.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include "usbip_common.h"
 
 /* version information */
index 6da1021e8a65edd1d9baad721ae3d50bc58f78da..a2566f1075d557014e4bcd443fb02ed36202dc72 100644 (file)
@@ -117,6 +117,9 @@ void usbip_stop_eh(struct usbip_device *ud)
 {
        struct usbip_task *eh = &ud->eh;
 
+       if (eh->thread == current)
+               return; /* do not wait for myself */
+
        wait_for_completion(&eh->thread_done);
        usbip_dbg_eh("usbip_eh has finished\n");
 }
index ef4371358dbe9fe0a4bb0e837fe4acecf05a9e16..0b1766122d389f42fb086f839d03a0cbf27f3ce7 100644 (file)
@@ -17,6 +17,7 @@
  * USA.
  */
 
+#include <linux/slab.h>
 
 #include "usbip_common.h"
 #include "vhci.h"
index 7636d86c23881589346167506f098e055aa4cafa..8147d7202b2dc092e8986891baaf463e6e3f1bf3 100644 (file)
@@ -17,6 +17,8 @@
  * USA.
  */
 
+#include <linux/slab.h>
+
 #include "usbip_common.h"
 #include "vhci.h"
 
index 7a00eb44b7954846506fed6355232f740a3b1dd6..b71b4c2fbd86e20bd1706ee16aeca23f1f53b59d 100644 (file)
@@ -17,6 +17,8 @@
  * USA.
  */
 
+#include <linux/slab.h>
+
 #include "usbip_common.h"
 #include "vhci.h"
 
index 2795ff2411e030e5f9a1291f5457c1a071b72c04..b159ea58adf7a72db94aa1b02b857ede17b7fb03 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/time.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
index faf652edb70ff89e89c413c373af157760cea7d8..783051f59f191d3ff8fa4fdcced2c459d93418f0 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/time.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -2454,9 +2455,10 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        dev_info(&pdev->dev, "VME Write and flush and error check is %s\n",
                err_chk ? "enabled" : "disabled");
 
-       if (tsi148_crcsr_init(tsi148_bridge, pdev))
+       if (tsi148_crcsr_init(tsi148_bridge, pdev)) {
                dev_err(&pdev->dev, "CR/CSR configuration failed.\n");
                goto err_crcsr;
+       }
 
        retval = vme_register_bridge(tsi148_bridge);
        if (retval != 0) {
index c60c80fb241d506b079de6b3240fbacdd2f79d87..1ab9a985dfb94fb51cbbc8c122cca4c422fc63b0 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/pagemap.h>
 #include <linux/pci.h>
 #include <linux/semaphore.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/syscalls.h>
 #include <linux/types.h>
index d6d84ebeeec0a3d0fc3cd3cf2a02ad573d966854..934283a19ca5c9c75dc0497ab2b42f1d50f812d0 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/syscalls.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 
 #include "vme.h"
 #include "vme_bridge.h"
index 1d643653a7ed85f25ab52bc7b4c13200525ef71e..e40a2e990f4f6e389da82b567026ba00871da29f 100644 (file)
@@ -84,6 +84,7 @@
 #include "iowpa.h"
 #include <linux/delay.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 //#define      DEBUG
 /*---------------------  Static Definitions -------------------------*/
index f5608ad9ed00e0871148fb6b365b22e307cce6f0..1b93547ff5bcd2a37793a5d5074621e9bc09ebe0 100644 (file)
@@ -2,6 +2,7 @@
 #include "wb35reg_f.h"
 
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 extern void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency);
 
index 4d41f6c3563c75052140fb88752ddb9e45025346..d7b57e62db08caff270ba800c0605ce4daed3a2c 100644 (file)
@@ -9,6 +9,7 @@
 //
 //============================================================================
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 #include "core.h"
 #include "sysdef.h"
index 5869ef473fcd2e2e7644c683ab6bda9b721e8ed6..bda7a913edf84ec06908ab08423057203222e065 100644 (file)
@@ -9,6 +9,7 @@
 //
 //============================================================================
 #include <linux/usb.h>
+#include <linux/gfp.h>
 
 #include "wb35tx_f.h"
 #include "mds_f.h"
index 811a8daa660ec5913e53558d1b8a858b53c3a986..9da42e66085e0039a007be1e5f8b03bc25e01fed 100644 (file)
@@ -67,7 +67,6 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/timer.h>
index fa082d90fcade4820f710a094f7a91e83588d982..1db73ebcae28798407b9e02eb65a6ca2cc27c409 100644 (file)
@@ -65,6 +65,7 @@
 #include <wl_version.h>
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 // #include <linux/sched.h>
index 01e4bec9fd5be1118bef73e2a68c2ec7bd4bed01..6751b4bad2e43560c60f92939f6a3c5ac8fcf3fb 100644 (file)
@@ -71,7 +71,6 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 //#include <linux/timer.h>
index ee610c76457e99235575a91532c0a688353377ad..727ea8a483af313d7bd3b855db44ca0f6e6b23f2 100644 (file)
@@ -65,6 +65,7 @@
 
 #include <linux/if_arp.h>
 #include <linux/ioport.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <asm/uaccess.h>
 
index c2e95f166828f42ddeb9f9bc23ff26f0d17d1018..e1e7bf1bf27c6eb058e4468f07bf9aadbe073bf9 100644 (file)
@@ -55,7 +55,6 @@
 #include <linux/sched.h>
 #include <linux/types.h>
 #include <linux/skbuff.h>
-#include <linux/slab.h>
 #include <linux/wireless.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
index ecbb15b297ae99ff687a3aacff5f69f68285bc63..80c2d3b672bb9e47c471c3c8fb8760ac0af42727 100644 (file)
@@ -50,7 +50,6 @@
 
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/kernel.h>
 
index 2fa1dfa23783e16924c1e476f0597809b8de5f3c..83f1d6cd7991f8fc0ccee7b4ce9cca6ff1014553 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
index 4be54cea6ad7bd8c029f9e9735aee19832f53170..d383ea85c9bc0053721489a6bac416c355365f18 100644 (file)
@@ -48,6 +48,7 @@
 /*================================================================*/
 /* System Includes */
 #include <linux/ihex.h>
+#include <linux/slab.h>
 
 /*================================================================*/
 /* Local Constants */
index ad163da72ae466d1a5de12cefdb73e29fe2c67a5..4d1cdfc3542098054518aa12b10aa0a10afe5c44 100644 (file)
@@ -63,7 +63,6 @@
 #include <linux/wait.h>
 #include <linux/sched.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/wireless.h>
 #include <linux/netdevice.h>
 #include <linux/delay.h>
index 98a5d58c3f55065d8b415ee090ff11214fb1e4bc..0b0ec9c59a5dc1be9c9e053e5d61f06bf654b315 100644 (file)
@@ -54,7 +54,6 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/wireless.h>
 #include <linux/netdevice.h>
 #include <linux/io.h>
index e5bd4470a570a4d45fcd7ef97d6a93c0a90aa601..a8aaf6ac2ae2275e2071dc53c174d0543db64dd8 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/tc.h>
 #include <linux/types.h>
index 5066de5cfc0c5b3f2b9bc7709e09a1bb801b8bbc..13c72c629329c02a687cc127009764122010e30f 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/kdev_t.h>
 #include <linux/idr.h>
 #include <linux/thermal.h>
@@ -505,6 +506,7 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
        tz->temp_input.attr.attr.name = tz->temp_input.name;
        tz->temp_input.attr.attr.mode = 0444;
        tz->temp_input.attr.show = temp_input_show;
+       sysfs_attr_init(&tz->temp_input.attr.attr);
        result = device_create_file(hwmon->device, &tz->temp_input.attr);
        if (result)
                goto unregister_hwmon_device;
@@ -517,6 +519,7 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
                        tz->temp_crit.attr.attr.name = tz->temp_crit.name;
                        tz->temp_crit.attr.attr.mode = 0444;
                        tz->temp_crit.attr.show = temp_crit_show;
+                       sysfs_attr_init(&tz->temp_crit.attr.attr);
                        result = device_create_file(hwmon->device,
                                                    &tz->temp_crit.attr);
                        if (result)
@@ -725,6 +728,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
                goto release_idr;
 
        sprintf(dev->attr_name, "cdev%d_trip_point", dev->id);
+       sysfs_attr_init(&dev->attr.attr);
        dev->attr.attr.name = dev->attr_name;
        dev->attr.attr.mode = 0444;
        dev->attr.show = thermal_cooling_device_trip_point_show;
index 4de382acd8f26ecc64d74dfcdaf5deba7d7d87cd..bff1afbde5a4b0ad01d0314b1661d43c972c3d84 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/idr.h>
 #include <linux/sched.h>
index b7830e9a3baabf1373ab8c62fcdc8602d0faf0aa..72b22d44e8b90b9645f08a612656c9042dbb629c 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/io.h>
 #include <linux/uaccess.h>
 #include <linux/uio_driver.h>
+#include <linux/slab.h>
 
 #define PCI_VENDOR_ID_AEC 0xaecb
 #define PCI_DEVICE_ID_AEC_VITCLTC 0x6250
index 28034c812914e024b5494fecb818f1a3ddfa315d..371f87f8bc229f7cdcabca5d7cee7944a6b3cf7f 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/uio_driver.h>
 
 #include <asm/io.h>
index afbf0bd55cc9ea3f6b3c3475ec85c7d39ee0d31a..5a18e9f7b8362787dbf60c0dc09fe48c23d627be 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/uio_driver.h>
 
 #define PCI_VENDOR_ID_HILSCHER         0x15CF
index 313da35984afece38a4614e427431d5ab4be6772..85c9884a67fdd1497ae99fde326cc8def67838a9 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/uio_driver.h>
 #include <linux/spinlock.h>
 
index d494ce9288c37e9b59c34962c66b291f7185a313..7d3e469b99045be5ad1ff6e0dfecc4dd1870d50e 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/platform_device.h>
 #include <linux/uio_driver.h>
 #include <linux/stringify.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME "uio_pdrv"
 
index 1ef3b8fc50b33063ed3fa988dd7b7ea9740bde08..61e569df2bba60cabc46a6e85d5f33007fd58a6c 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/stringify.h>
 #include <linux/pm_runtime.h>
+#include <linux/slab.h>
 
 #define DRIVER_NAME "uio_pdrv_genirq"
 
index a6d1b2bc47f3379f1930c9a610df7cb85706b8c3..3d461cd73e6b5bf9487a5e6662dbbc3da538a338 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/pci.h>
 #include <linux/uio_driver.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 /* ID's for SERCOS III PCI card (PLX 9030) */
 #define SERCOS_SUB_VENDOR_ID  0x1971
index 3e862401a638e15141460190208270a03aa0a756..1e9ba4bdffeff65e501751569eb41c5d8944966c 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/firmware.h>
-#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index c5395246886d060b11c4ba2e12867c5784d2e211..25f01b536f67c3551b0452d9e7f1b2edcf3ca35c 100644 (file)
@@ -66,6 +66,7 @@
 #include <linux/kthread.h>
 #include <linux/mutex.h>
 #include <linux/freezer.h>
+#include <linux/slab.h>
 
 #include <asm/unaligned.h>
 
index 029ee4a8a1f33b4b3bf4d28dd4a46723b9fdc72a..b6d49234e5217a9fd0779944469790cef5f479d0 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/c67x00.h>
 
index 85dfe29656618dfd17fe3f32b1b436e56dea38c0..f6b3c253f3fa92db1afe24be7cbcbf99684558d3 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 #include "c67x00.h"
 #include "c67x00-hcd.h"
index 975d556b47874e5148b1520ff5bb5cc6a8c072bc..5e1a253b08a016581672b124a8e1c5cbb49e74b8 100644 (file)
@@ -1441,7 +1441,7 @@ static int acm_resume(struct usb_interface *intf)
                        wb = acm->delayed_wb;
                        acm->delayed_wb = NULL;
                        spin_unlock_irq(&acm->write_lock);
-                       acm_start_wb(acm, acm->delayed_wb);
+                       acm_start_wb(acm, wb);
                } else {
                        spin_unlock_irq(&acm->write_lock);
                }
@@ -1542,6 +1542,9 @@ static const struct usb_device_id acm_ids[] = {
        { USB_DEVICE(0x1bbb, 0x0003), /* Alcatel OT-I650 */
        .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
        },
+       { USB_DEVICE(0x1576, 0x03b1), /* Maretron USB100 */
+       .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
+       },
 
        /* Nokia S60 phones expose two ACM channels. The first is
         * a modem and is picked up by the standard AT-command
index 18aafcb08fc8be08536a4ff3caf75859bc003116..189141ca4e0513c8775a70f8c125777ff410fbbc 100644 (file)
@@ -52,7 +52,8 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
 #define WDM_READ               4
 #define WDM_INT_STALL          5
 #define WDM_POLL_RUNNING       6
-
+#define WDM_RESPONDING         7
+#define WDM_SUSPENDING         8
 
 #define WDM_MAX                        16
 
@@ -87,9 +88,7 @@ struct wdm_device {
        int                     count;
        dma_addr_t              shandle;
        dma_addr_t              ihandle;
-       struct mutex            wlock;
-       struct mutex            rlock;
-       struct mutex            plock;
+       struct mutex            lock;
        wait_queue_head_t       wait;
        struct work_struct      rxwork;
        int                     werr;
@@ -117,21 +116,22 @@ static void wdm_in_callback(struct urb *urb)
        int status = urb->status;
 
        spin_lock(&desc->iuspin);
+       clear_bit(WDM_RESPONDING, &desc->flags);
 
        if (status) {
                switch (status) {
                case -ENOENT:
                        dev_dbg(&desc->intf->dev,
                                "nonzero urb status received: -ENOENT");
-                       break;
+                       goto skip_error;
                case -ECONNRESET:
                        dev_dbg(&desc->intf->dev,
                                "nonzero urb status received: -ECONNRESET");
-                       break;
+                       goto skip_error;
                case -ESHUTDOWN:
                        dev_dbg(&desc->intf->dev,
                                "nonzero urb status received: -ESHUTDOWN");
-                       break;
+                       goto skip_error;
                case -EPIPE:
                        dev_err(&desc->intf->dev,
                                "nonzero urb status received: -EPIPE\n");
@@ -147,6 +147,7 @@ static void wdm_in_callback(struct urb *urb)
        desc->reslength = urb->actual_length;
        memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength);
        desc->length += desc->reslength;
+skip_error:
        wake_up(&desc->wait);
 
        set_bit(WDM_READ, &desc->flags);
@@ -229,13 +230,16 @@ static void wdm_int_callback(struct urb *urb)
        desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
        spin_lock(&desc->iuspin);
        clear_bit(WDM_READ, &desc->flags);
-       if (!test_bit(WDM_DISCONNECTING, &desc->flags)) {
+       set_bit(WDM_RESPONDING, &desc->flags);
+       if (!test_bit(WDM_DISCONNECTING, &desc->flags)
+               && !test_bit(WDM_SUSPENDING, &desc->flags)) {
                rv = usb_submit_urb(desc->response, GFP_ATOMIC);
                dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d",
                        __func__, rv);
        }
        spin_unlock(&desc->iuspin);
        if (rv < 0) {
+               clear_bit(WDM_RESPONDING, &desc->flags);
                if (rv == -EPERM)
                        return;
                if (rv == -ENOMEM) {
@@ -305,14 +309,38 @@ static ssize_t wdm_write
        if (we < 0)
                return -EIO;
 
-       r = mutex_lock_interruptible(&desc->wlock); /* concurrent writes */
+       desc->outbuf = buf = kmalloc(count, GFP_KERNEL);
+       if (!buf) {
+               rv = -ENOMEM;
+               goto outnl;
+       }
+
+       r = copy_from_user(buf, buffer, count);
+       if (r > 0) {
+               kfree(buf);
+               rv = -EFAULT;
+               goto outnl;
+       }
+
+       /* concurrent writes and disconnect */
+       r = mutex_lock_interruptible(&desc->lock);
        rv = -ERESTARTSYS;
-       if (r)
+       if (r) {
+               kfree(buf);
                goto outnl;
+       }
+
+       if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
+               kfree(buf);
+               rv = -ENODEV;
+               goto outnp;
+       }
 
        r = usb_autopm_get_interface(desc->intf);
-       if (r < 0)
+       if (r < 0) {
+               kfree(buf);
                goto outnp;
+       }
 
        if (!file->f_flags && O_NONBLOCK)
                r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE,
@@ -320,24 +348,8 @@ static ssize_t wdm_write
        else
                if (test_bit(WDM_IN_USE, &desc->flags))
                        r = -EAGAIN;
-       if (r < 0)
-               goto out;
-
-       if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
-               rv = -ENODEV;
-               goto out;
-       }
-
-       desc->outbuf = buf = kmalloc(count, GFP_KERNEL);
-       if (!buf) {
-               rv = -ENOMEM;
-               goto out;
-       }
-
-       r = copy_from_user(buf, buffer, count);
-       if (r > 0) {
+       if (r < 0) {
                kfree(buf);
-               rv = -EFAULT;
                goto out;
        }
 
@@ -374,7 +386,7 @@ static ssize_t wdm_write
 out:
        usb_autopm_put_interface(desc->intf);
 outnp:
-       mutex_unlock(&desc->wlock);
+       mutex_unlock(&desc->lock);
 outnl:
        return rv < 0 ? rv : count;
 }
@@ -387,7 +399,7 @@ static ssize_t wdm_read
        struct wdm_device *desc = file->private_data;
 
 
-       rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */
+       rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */
        if (rv < 0)
                return -ERESTARTSYS;
 
@@ -424,11 +436,8 @@ retry:
                spin_lock_irq(&desc->iuspin);
 
                if (desc->rerr) { /* read completed, error happened */
-                       int t = desc->rerr;
                        desc->rerr = 0;
                        spin_unlock_irq(&desc->iuspin);
-                       dev_err(&desc->intf->dev,
-                               "reading had resulted in %d\n", t);
                        rv = -EIO;
                        goto err;
                }
@@ -465,9 +474,7 @@ retry:
        rv = cntr;
 
 err:
-       mutex_unlock(&desc->rlock);
-       if (rv < 0 && rv != -EAGAIN)
-               dev_err(&desc->intf->dev, "wdm_read: exit error\n");
+       mutex_unlock(&desc->lock);
        return rv;
 }
 
@@ -533,7 +540,7 @@ static int wdm_open(struct inode *inode, struct file *file)
        }
        intf->needs_remote_wakeup = 1;
 
-       mutex_lock(&desc->plock);
+       mutex_lock(&desc->lock);
        if (!desc->count++) {
                rv = usb_submit_urb(desc->validity, GFP_KERNEL);
                if (rv < 0) {
@@ -544,7 +551,7 @@ static int wdm_open(struct inode *inode, struct file *file)
        } else {
                rv = 0;
        }
-       mutex_unlock(&desc->plock);
+       mutex_unlock(&desc->lock);
        usb_autopm_put_interface(desc->intf);
 out:
        mutex_unlock(&wdm_mutex);
@@ -556,9 +563,9 @@ static int wdm_release(struct inode *inode, struct file *file)
        struct wdm_device *desc = file->private_data;
 
        mutex_lock(&wdm_mutex);
-       mutex_lock(&desc->plock);
+       mutex_lock(&desc->lock);
        desc->count--;
-       mutex_unlock(&desc->plock);
+       mutex_unlock(&desc->lock);
 
        if (!desc->count) {
                dev_dbg(&desc->intf->dev, "wdm_release: cleanup");
@@ -655,9 +662,7 @@ next_desc:
        desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL);
        if (!desc)
                goto out;
-       mutex_init(&desc->wlock);
-       mutex_init(&desc->rlock);
-       mutex_init(&desc->plock);
+       mutex_init(&desc->lock);
        spin_lock_init(&desc->iuspin);
        init_waitqueue_head(&desc->wait);
        desc->wMaxCommand = maxcom;
@@ -771,14 +776,17 @@ static void wdm_disconnect(struct usb_interface *intf)
        /* to terminate pending flushes */
        clear_bit(WDM_IN_USE, &desc->flags);
        spin_unlock_irqrestore(&desc->iuspin, flags);
-       cancel_work_sync(&desc->rxwork);
+       mutex_lock(&desc->lock);
        kill_urbs(desc);
+       cancel_work_sync(&desc->rxwork);
+       mutex_unlock(&desc->lock);
        wake_up_all(&desc->wait);
        if (!desc->count)
                cleanup(desc);
        mutex_unlock(&wdm_mutex);
 }
 
+#ifdef CONFIG_PM
 static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
 {
        struct wdm_device *desc = usb_get_intfdata(intf);
@@ -786,22 +794,30 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
 
        dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor);
 
-       mutex_lock(&desc->plock);
-#ifdef CONFIG_PM
+       /* if this is an autosuspend the caller does the locking */
+       if (!(message.event & PM_EVENT_AUTO))
+               mutex_lock(&desc->lock);
+       spin_lock_irq(&desc->iuspin);
+
        if ((message.event & PM_EVENT_AUTO) &&
-                       test_bit(WDM_IN_USE, &desc->flags)) {
+                       (test_bit(WDM_IN_USE, &desc->flags)
+                       || test_bit(WDM_RESPONDING, &desc->flags))) {
+               spin_unlock_irq(&desc->iuspin);
                rv = -EBUSY;
        } else {
-#endif
-               cancel_work_sync(&desc->rxwork);
+
+               set_bit(WDM_SUSPENDING, &desc->flags);
+               spin_unlock_irq(&desc->iuspin);
+               /* callback submits work - order is essential */
                kill_urbs(desc);
-#ifdef CONFIG_PM
+               cancel_work_sync(&desc->rxwork);
        }
-#endif
-       mutex_unlock(&desc->plock);
+       if (!(message.event & PM_EVENT_AUTO))
+               mutex_unlock(&desc->lock);
 
        return rv;
 }
+#endif
 
 static int recover_from_urb_loss(struct wdm_device *desc)
 {
@@ -815,23 +831,27 @@ static int recover_from_urb_loss(struct wdm_device *desc)
        }
        return rv;
 }
+
+#ifdef CONFIG_PM
 static int wdm_resume(struct usb_interface *intf)
 {
        struct wdm_device *desc = usb_get_intfdata(intf);
        int rv;
 
        dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor);
-       mutex_lock(&desc->plock);
+
+       clear_bit(WDM_SUSPENDING, &desc->flags);
        rv = recover_from_urb_loss(desc);
-       mutex_unlock(&desc->plock);
+
        return rv;
 }
+#endif
 
 static int wdm_pre_reset(struct usb_interface *intf)
 {
        struct wdm_device *desc = usb_get_intfdata(intf);
 
-       mutex_lock(&desc->plock);
+       mutex_lock(&desc->lock);
        return 0;
 }
 
@@ -841,7 +861,7 @@ static int wdm_post_reset(struct usb_interface *intf)
        int rv;
 
        rv = recover_from_urb_loss(desc);
-       mutex_unlock(&desc->plock);
+       mutex_unlock(&desc->lock);
        return 0;
 }
 
@@ -849,9 +869,11 @@ static struct usb_driver wdm_driver = {
        .name =         "cdc_wdm",
        .probe =        wdm_probe,
        .disconnect =   wdm_disconnect,
+#ifdef CONFIG_PM
        .suspend =      wdm_suspend,
        .resume =       wdm_resume,
        .reset_resume = wdm_resume,
+#endif
        .pre_reset =    wdm_pre_reset,
        .post_reset =   wdm_post_reset,
        .id_table =     wdm_ids,
index 8588c0937a89ea948dd8d839af7902e815e7d02e..3e7c1b800ebb03e8668ac6a506cc137d26bcf41a 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/fs.h>
 #include <linux/uaccess.h>
 #include <linux/kref.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/usb.h>
 #include <linux/usb/tmc.h>
index 97a819c23ef365a8d52dd63c13d7c94891d5f54d..7e594449600e004c7f6ba14fa2dce39ebee25d20 100644 (file)
@@ -109,7 +109,7 @@ config USB_SUSPEND
 config USB_OTG
        bool
        depends on USB && EXPERIMENTAL
-       select USB_SUSPEND
+       depends on USB_SUSPEND
        default n
 
 
index d41811bfef2a35acc1eb52127cb3649c42efc87c..19bc03a9fecf3d8bbaba0bafafaf9f49d472e6b2 100644 (file)
@@ -50,7 +50,7 @@
 
 #include <linux/fs.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/poll.h>
 #include <linux/usb.h>
 #include <linux/smp_lock.h>
index e909ff7b9094051c1ea1812d1252718d96ba23cc..3466fdc5bb11e7cdc42871982c5e85cde38ae0bc 100644 (file)
@@ -1207,6 +1207,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                        free_async(as);
                        return -ENOMEM;
                }
+               /* Isochronous input data may end up being discontiguous
+                * if some of the packets are short.  Clear the buffer so
+                * that the gaps don't leak kernel data to userspace.
+                */
+               if (is_in && uurb->type == USBDEVFS_URB_TYPE_ISO)
+                       memset(as->urb->transfer_buffer, 0,
+                                       uurb->buffer_length);
        }
        as->urb->dev = ps->dev;
        as->urb->pipe = (uurb->type << 30) |
@@ -1345,10 +1352,14 @@ static int processcompl(struct async *as, void __user * __user *arg)
        void __user *addr = as->userurb;
        unsigned int i;
 
-       if (as->userbuffer && urb->actual_length)
-               if (copy_to_user(as->userbuffer, urb->transfer_buffer,
-                                urb->actual_length))
+       if (as->userbuffer && urb->actual_length) {
+               if (urb->number_of_packets > 0)         /* Isochronous */
+                       i = urb->transfer_buffer_length;
+               else                                    /* Non-Isoc */
+                       i = urb->actual_length;
+               if (copy_to_user(as->userbuffer, urb->transfer_buffer, i))
                        goto err_out;
+       }
        if (put_user(as->status, &userurb->status))
                goto err_out;
        if (put_user(urb->actual_length, &userurb->actual_length))
index f3c233806fa3415a5489842f3ccbf4030da55f8f..2f3dc4cdf79bc12d2bc2cafbfa3ec7ecc43292ee 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/quirks.h>
 #include <linux/pm_runtime.h>
@@ -300,7 +301,7 @@ static int usb_probe_interface(struct device *dev)
 
        intf->condition = USB_INTERFACE_BINDING;
 
-       /* Bound interfaces are initially active.  They are
+       /* Probed interfaces are initially active.  They are
         * runtime-PM-enabled only if the driver has autosuspend support.
         * They are sensitive to their children's power states.
         */
@@ -436,11 +437,11 @@ int usb_driver_claim_interface(struct usb_driver *driver,
 
        iface->condition = USB_INTERFACE_BOUND;
 
-       /* Bound interfaces are initially active.  They are
+       /* Claimed interfaces are initially inactive (suspended).  They are
         * runtime-PM-enabled only if the driver has autosuspend support.
         * They are sensitive to their children's power states.
         */
-       pm_runtime_set_active(dev);
+       pm_runtime_set_suspended(dev);
        pm_suspend_ignore_children(dev, false);
        if (driver->supports_autosuspend)
                pm_runtime_enable(dev);
@@ -1169,7 +1170,7 @@ done:
 static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
 {
        int                     status = 0;
-       int                     i = 0;
+       int                     i = 0, n = 0;
        struct usb_interface    *intf;
 
        if (udev->state == USB_STATE_NOTATTACHED ||
@@ -1178,7 +1179,8 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
 
        /* Suspend all the interfaces and then udev itself */
        if (udev->actconfig) {
-               for (; i < udev->actconfig->desc.bNumInterfaces; i++) {
+               n = udev->actconfig->desc.bNumInterfaces;
+               for (i = n - 1; i >= 0; --i) {
                        intf = udev->actconfig->interface[i];
                        status = usb_suspend_interface(udev, intf, msg);
                        if (status != 0)
@@ -1191,7 +1193,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
        /* If the suspend failed, resume interfaces that did get suspended */
        if (status != 0) {
                msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME);
-               while (--i >= 0) {
+               while (++i < n) {
                        intf = udev->actconfig->interface[i];
                        usb_resume_interface(udev, intf, msg, 0);
                }
@@ -1262,13 +1264,47 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg)
        return status;
 }
 
+static void choose_wakeup(struct usb_device *udev, pm_message_t msg)
+{
+       int                     w, i;
+       struct usb_interface    *intf;
+
+       /* Remote wakeup is needed only when we actually go to sleep.
+        * For things like FREEZE and QUIESCE, if the device is already
+        * autosuspended then its current wakeup setting is okay.
+        */
+       if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_QUIESCE) {
+               if (udev->state != USB_STATE_SUSPENDED)
+                       udev->do_remote_wakeup = 0;
+               return;
+       }
+
+       /* If remote wakeup is permitted, see whether any interface drivers
+        * actually want it.
+        */
+       w = 0;
+       if (device_may_wakeup(&udev->dev) && udev->actconfig) {
+               for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
+                       intf = udev->actconfig->interface[i];
+                       w |= intf->needs_remote_wakeup;
+               }
+       }
+
+       /* If the device is autosuspended with the wrong wakeup setting,
+        * autoresume now so the setting can be changed.
+        */
+       if (udev->state == USB_STATE_SUSPENDED && w != udev->do_remote_wakeup)
+               pm_runtime_resume(&udev->dev);
+       udev->do_remote_wakeup = w;
+}
+
 /* The device lock is held by the PM core */
 int usb_suspend(struct device *dev, pm_message_t msg)
 {
        struct usb_device       *udev = to_usb_device(dev);
 
        do_unbind_rebind(udev, DO_UNBIND);
-       udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
+       choose_wakeup(udev, msg);
        return usb_suspend_both(udev, msg);
 }
 
index d26b9ea981f92f322c5c402f38e53d7c075e7e52..4f84a41ee7a85a39bbe939be6e96bc3ba48c2445 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/idr.h>
 #include <linux/usb.h>
 #include "usb.h"
index c3536f151f029674bfd49d33a093a30069ce8904..f06f5dbc8cdc22fbedfa463c05b18672cbb99516 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/rwsem.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/usb.h>
 
index bdf87a8414a1af4f9278257c31e67415f78ff497..2c95153c0f24bcbbebeb1d02948afb1a439610cb 100644 (file)
@@ -120,7 +120,7 @@ int usb_choose_configuration(struct usb_device *udev)
                 * than a vendor-specific driver. */
                else if (udev->descriptor.bDeviceClass !=
                                                USB_CLASS_VENDOR_SPEC &&
-                               (!desc || desc->bInterfaceClass !=
+                               (desc && desc->bInterfaceClass !=
                                                USB_CLASS_VENDOR_SPEC)) {
                        best = c;
                        break;
index 97b40ce133f0a8b7165a742d885dd91656843bc1..111a01a747fcc940c94d86357ffcb8efdb4f2d71 100644 (file)
@@ -380,6 +380,7 @@ static int usbfs_rmdir(struct inode *dir, struct dentry *dentry)
        mutex_lock(&inode->i_mutex);
        dentry_unhash(dentry);
        if (usbfs_empty(dentry)) {
+               dont_mount(dentry);
                drop_nlink(dentry->d_inode);
                drop_nlink(dentry->d_inode);
                dput(dentry);
@@ -515,13 +516,13 @@ static int fs_create_by_name (const char *name, mode_t mode,
        *dentry = NULL;
        mutex_lock(&parent->d_inode->i_mutex);
        *dentry = lookup_one_len(name, parent, strlen(name));
-       if (!IS_ERR(dentry)) {
+       if (!IS_ERR(*dentry)) {
                if ((mode & S_IFMT) == S_IFDIR)
                        error = usbfs_mkdir (parent->d_inode, *dentry, mode);
                else 
                        error = usbfs_create (parent->d_inode, *dentry, mode);
        } else
-               error = PTR_ERR(dentry);
+               error = PTR_ERR(*dentry);
        mutex_unlock(&parent->d_inode->i_mutex);
 
        return error;
index 27080561a1c2386567160b7aec7394028e1a60b3..45a32dadb40664388169a67d1443cdd6e7cf086c 100644 (file)
@@ -453,6 +453,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
                        if (urb->interval > (1 << 15))
                                return -EINVAL;
                        max = 1 << 15;
+                       break;
                case USB_SPEED_WIRELESS:
                        if (urb->interval > 16)
                                return -EINVAL;
index 1297e9b16a5101bb941dbfeda831b3c2c3be350d..0561430f2edea25da4ea10a508b2896eed6396c8 100644 (file)
@@ -718,7 +718,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
 EXPORT_SYMBOL_GPL(__usb_get_extra_descriptor);
 
 /**
- * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
+ * usb_alloc_coherent - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
  * @dev: device the buffer will be used with
  * @size: requested buffer size
  * @mem_flags: affect whether allocation may block
@@ -737,30 +737,30 @@ EXPORT_SYMBOL_GPL(__usb_get_extra_descriptor);
  * architectures where CPU caches are not DMA-coherent.  On systems without
  * bus-snooping caches, these buffers are uncached.
  *
- * When the buffer is no longer used, free it with usb_buffer_free().
+ * When the buffer is no longer used, free it with usb_free_coherent().
  */
-void *usb_buffer_alloc(struct usb_device *dev, size_t size, gfp_t mem_flags,
-                      dma_addr_t *dma)
+void *usb_alloc_coherent(struct usb_device *dev, size_t size, gfp_t mem_flags,
+                        dma_addr_t *dma)
 {
        if (!dev || !dev->bus)
                return NULL;
        return hcd_buffer_alloc(dev->bus, size, mem_flags, dma);
 }
-EXPORT_SYMBOL_GPL(usb_buffer_alloc);
+EXPORT_SYMBOL_GPL(usb_alloc_coherent);
 
 /**
- * usb_buffer_free - free memory allocated with usb_buffer_alloc()
+ * usb_free_coherent - free memory allocated with usb_alloc_coherent()
  * @dev: device the buffer was used with
  * @size: requested buffer size
  * @addr: CPU address of buffer
  * @dma: DMA address of buffer
  *
  * This reclaims an I/O buffer, letting it be reused.  The memory must have
- * been allocated using usb_buffer_alloc(), and the parameters must match
+ * been allocated using usb_alloc_coherent(), and the parameters must match
  * those provided in that allocation request.
  */
-void usb_buffer_free(struct usb_device *dev, size_t size, void *addr,
-                    dma_addr_t dma)
+void usb_free_coherent(struct usb_device *dev, size_t size, void *addr,
+                      dma_addr_t dma)
 {
        if (!dev || !dev->bus)
                return;
@@ -768,7 +768,7 @@ void usb_buffer_free(struct usb_device *dev, size_t size, void *addr,
                return;
        hcd_buffer_free(dev->bus, size, addr, dma);
 }
-EXPORT_SYMBOL_GPL(usb_buffer_free);
+EXPORT_SYMBOL_GPL(usb_free_coherent);
 
 /**
  * usb_buffer_map - create DMA mapping(s) for an urb
index 7460cd797f454fd13f23dc157e6845a788dbe505..11a3e0fa433181363c1eb76c259e0b120a2f03b1 100644 (file)
@@ -747,7 +747,7 @@ config USB_MASS_STORAGE
          which may be used with composite framework.
 
          Say "y" to link the driver statically, or "m" to build
-         a dynamically linked module called "g_file_storage".  If unsure,
+         a dynamically linked module called "g_mass_storage".  If unsure,
          consider File-backed Storage Gadget.
 
 config USB_G_SERIAL
index 12ac9cd32a07562ec665f04636b75a263f68d9a8..df1bae9b048e4585f13f4b06ff720c497e667c54 100644 (file)
@@ -1370,6 +1370,12 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
 {
        struct at91_udc         *udc = _udc;
        u32                     rescans = 5;
+       int                     disable_clock = 0;
+
+       if (!udc->clocked) {
+               clk_on(udc);
+               disable_clock = 1;
+       }
 
        while (rescans--) {
                u32 status;
@@ -1458,6 +1464,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
                }
        }
 
+       if (disable_clock)
+               clk_off(udc);
+
        return IRQ_HANDLED;
 }
 
index f79bdfe4bed9f9e694146a38970c11d32fd1719f..75a256f3d45be57ee2791692672e4a9e57071d5b 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/list.h>
index c7cb87a6fee22a4519a0f720fcf3f3451eb22920..699695128e33de185f743afa8f26ed51f38f9295 100644 (file)
@@ -62,6 +62,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 
index e1191b9a316a6b3751c90c23e263849e5a5d6c51..47e8e722682c6c638de6b938485ac83849a3cedc 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/string.h>
index 65a5f94cbc0435153dfe76fda74bc5e4ff3481a5..3568de210f7977f75ead536e25e56c90f67c2c86 100644 (file)
@@ -266,7 +266,7 @@ struct usb_ep * __init usb_ep_autoconfig (
                }
 
 #ifdef CONFIG_BLACKFIN
-       } else if (gadget_is_musbhsfc(gadget) || gadget_is_musbhdrc(gadget)) {
+       } else if (gadget_is_musbhdrc(gadget)) {
                if ((USB_ENDPOINT_XFER_BULK == type) ||
                    (USB_ENDPOINT_XFER_ISOC == type)) {
                        if (USB_DIR_IN & desc->bEndpointAddress)
index e49c7325dce2e8c4eeef62f38b8217febd8b079e..400e1ebe6976678f4f991b3d3c9112a112278d79 100644 (file)
@@ -14,6 +14,7 @@
 
 /* #define VERBOSE_DEBUG */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 
index f1e3aad76c3766fec509b898d7e50ac0fdb9ee23..43bf44514c417d0431b52604569bef796871248b 100644 (file)
@@ -9,6 +9,7 @@
  * Licensed under the GPL-2 or later.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <asm/atomic.h>
index 2fff530efc19f163eb466cf2d577cfdc525a5ac1..4e595324c614f6c8578055f8c577ad7a818b3e99 100644 (file)
@@ -21,6 +21,7 @@
 
 /* #define VERBOSE_DEBUG */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/etherdevice.h>
index d4f0db58a8ad11238ee9ded4995f4f5780b863ab..38226e9a371d2d39dcb932a64144372545e75542 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/device.h>
 #include <linux/etherdevice.h>
 #include <linux/crc32.h>
+#include <linux/slab.h>
 
 #include "u_ether.h"
 
index 6cb29d3df575b3757abb639de812d0cd42eb8daf..e91d1b16d9bed4901037fba7fbcc0c4af548db32 100644 (file)
@@ -21,6 +21,7 @@
 
 /* #define VERBOSE_DEBUG */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 
index 5a3cdd08f1d05c7d589399670fa2ac4eec7eb4a7..f4911c09022e92c2c16cc1b294045a56a0aca231 100644 (file)
@@ -2910,7 +2910,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
 }
 
 
-static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+static int __init fsg_bind(struct usb_configuration *c, struct usb_function *f)
 {
        struct fsg_dev          *fsg = fsg_from_func(f);
        struct usb_gadget       *gadget = c->cdev->gadget;
@@ -2954,7 +2954,6 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
 autoconf_fail:
        ERROR(fsg, "unable to autoconfigure all endpoints\n");
        rc = -ENOTSUPP;
-       fsg_unbind(c, f);
        return rc;
 }
 
index b4a3ba654ea53def501a4b7b6befdf83ba78bad1..8f8c64371475c28565e15406894080cf5f10cd07 100644 (file)
@@ -23,6 +23,7 @@
 
 /* #define VERBOSE_DEBUG */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 
index d2de10b9dc4b0520d5151bb4a2d40c897893ad0f..3c6e1a058745c739e40cdd825882993a5671661f 100644 (file)
@@ -20,6 +20,7 @@
  * 02110-1301 USA
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 
index a30e60c7f129dc19ec732b51d9b7465ff7e71317..56b022150f227d8dbfd7ca939d80e376d0916e1c 100644 (file)
@@ -24,6 +24,7 @@
 
 /* #define VERBOSE_DEBUG */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/etherdevice.h>
index db0aa93606ef90b4615e4acb5d908ba79944f5ce..490b00b01a7d68774263c4d84c89b7775eb4acad 100644 (file)
@@ -10,6 +10,7 @@
  * either version 2 of that License or (at your option) any later version.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 
index 09cba273d2dbda8c7fd346745410c9717fc87df2..6d3cc443d914010d6ee7fafac601f3980e04ccf8 100644 (file)
@@ -21,6 +21,7 @@
 
 /* #define VERBOSE_DEBUG */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 
index a9c98fdb626d75e855eb1515cef19dfb8100e299..8675ca415329ce535ab97e44251884c19c83ed33 100644 (file)
@@ -19,6 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/etherdevice.h>
index 1edbc12fff18fdc172cd44627fc8e7d397f0b46c..e511fec9f26d8d5f529d3a6a7ba7ae5a648aa24e 100644 (file)
 #define        gadget_is_r8a66597(g)   0
 #endif
 
+#ifdef CONFIG_USB_S3C_HSOTG
+#define gadget_is_s3c_hsotg(g)    (!strcmp("s3c-hsotg", (g)->name))
+#else
+#define gadget_is_s3c_hsotg(g)    0
+#endif
+
 
 /**
  * usb_gadget_controller_number - support bcdDevice id convention
@@ -192,6 +198,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
                return 0x24;
        else if (gadget_is_r8a66597(gadget))
                return 0x25;
+       else if (gadget_is_s3c_hsotg(gadget))
+               return 0x26;
        return -ENOENT;
 }
 
index 04f6224b7e06b1b65972609f37a8cf7228b43174..2b56ce62185297de5d954fbc04719de818e9dfa6 100644 (file)
@@ -21,6 +21,7 @@
 /* #define VERBOSE_DEBUG */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/utsname.h>
 #include <linux/device.h>
 
index e8edc640381e5bdbd8275b3a580da2ea78a966ab..1088d08c7ed8fac07146bd8d6fbde9d59a1897ca 100644 (file)
@@ -1768,7 +1768,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
         * usb_gadget_driver_{register,unregister}() must change.
         */
        if (the_controller) {
-               WARNING(dev, "ignoring %s\n", pci_name(pdev));
+               pr_warning("ignoring %s\n", pci_name(pdev));
                return -EBUSY;
        }
        if (!pdev->irq) {
index 01ee0b9bc9575e7e8902fd67a66bea7ae4234fff..e743122fcd93e0f74ec23f8b1f0efa050d9a5f10 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
index 6cd3d54f56409d9255da3620e624f500b75511ed..fded3fca793b5850add32e2cb9798740cf6e02f3 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include "lh7a40x_udc.h"
 
index a8c8543d1b08962666af3415ad4c8ce5c552b3c1..166bf71fd3482252e00fde5455fc529e8f22337b 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
index 76496f5d272c59cebd3856aa8cce245d5c4352f3..a930d7fd7e7a5425fff7bd6c77044acaf0dc2355 100644 (file)
@@ -211,8 +211,6 @@ static int __init cdc_do_config(struct usb_configuration *c)
        ret = fsg_add(c->cdev, c, fsg_common);
        if (ret < 0)
                return ret;
-       if (ret < 0)
-               return ret;
 
        return 0;
 }
index 05b892c3d686ccf0492dc87dc34fefc794e2084e..85b0d8921eae4fbfe14c86c1ac7bf1f9ffae3705 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include <asm/byteorder.h>
 #include <mach/hardware.h>
index 8b45145b913618ea302bf062e905a67ed87baaf2..888d8f166c0b1c9d4ddcac3fbf364935041458be 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
index 48267bc0b2e00c151bf05e8ed6caa2662e1de9a5..5c0d06c79a81f1f5e5198aa1576e5e2d29d369f7 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/netdevice.h>
 
index f742c8e7397ccf06a0759f88a0769723287522cd..1f73b485732d1b74028064e37193ce6f56021718 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/seq_file.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
@@ -2144,6 +2145,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
        u32 epctrl;
        u32 mps;
        int dir_in;
+       int ret = 0;
 
        dev_dbg(hsotg->dev,
                "%s: ep %s: a 0x%02x, attr 0x%02x, mps 0x%04x, intr %d\n",
@@ -2195,7 +2197,8 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
        switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
        case USB_ENDPOINT_XFER_ISOC:
                dev_err(hsotg->dev, "no current ISOC support\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out;
 
        case USB_ENDPOINT_XFER_BULK:
                epctrl |= S3C_DxEPCTL_EPType_Bulk;
@@ -2234,8 +2237,9 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
        /* enable the endpoint interrupt */
        s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1);
 
+out:
        spin_unlock_irqrestore(&hs_ep->lock, flags);
-       return 0;
+       return ret;
 }
 
 static int s3c_hsotg_ep_disable(struct usb_ep *ep)
index 35e0930f5bbb7c4927bceb6523af63e5562a59b8..7a86d2c9109c6bae8341e4d659792a9315d1a19f 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/delay.h>
 #include <linux/ctype.h>
index 84ca195c2d10f8a2b71346bdd031ba18a15e1571..07f4178ad1788ef10363fba7899fae05ff14a036 100644 (file)
@@ -23,6 +23,7 @@
 /* #define VERBOSE_DEBUG */
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/device.h>
 #include <linux/ctype.h>
 #include <linux/etherdevice.h>
index adf8260c3a6aeff9f295e4ad5bf45cdfcb23233c..16bdf77f582a02526f2b60750e26dbfb2e425228 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
+#include <linux/slab.h>
 
 #include "u_serial.h"
 
index fac81ee193dd0100d71bcf344f4badb0d341a153..807280d069f96e815ea11c1eddddb29cbe6692fd 100644 (file)
@@ -50,6 +50,7 @@
 /* #define VERBOSE_DEBUG */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/utsname.h>
 #include <linux/device.h>
 
index 4e0c67f1f51ba1dbc5e4efb964936b01c4afe037..b6315aa47f7a91592b2ec613c965f86a49c61f5b 100644 (file)
@@ -12,7 +12,7 @@ fhci-objs := fhci-hcd.o fhci-hub.o fhci-q.o fhci-mem.o \
 ifeq ($(CONFIG_FHCI_DEBUG),y)
 fhci-objs += fhci-dbg.o
 endif
-xhci-objs := xhci-hcd.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o
+xhci-hcd-objs := xhci.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o
 
 obj-$(CONFIG_USB_WHCI_HCD)     += whci/
 
@@ -25,7 +25,7 @@ obj-$(CONFIG_USB_ISP1362_HCD) += isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)     += ohci-hcd.o
 obj-$(CONFIG_USB_UHCI_HCD)     += uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)     += fhci.o
-obj-$(CONFIG_USB_XHCI_HCD)     += xhci.o
+obj-$(CONFIG_USB_XHCI_HCD)     += xhci-hcd.o
 obj-$(CONFIG_USB_SL811_HCD)    += sl811-hcd.o
 obj-$(CONFIG_USB_SL811_CS)     += sl811_cs.o
 obj-$(CONFIG_USB_U132_HCD)     += u132-hcd.o
index d8d6d3461d3270de5fb71188c598557b465116f2..13ead00aecd503280dc2e29852c5fc1e17fe8c73 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -35,6 +34,7 @@
 #include <linux/moduleparam.h>
 #include <linux/dma-mapping.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 
 #include "../core/hcd.h"
 
@@ -543,6 +543,7 @@ static int ehci_init(struct usb_hcd *hcd)
         */
        ehci->periodic_size = DEFAULT_I_TDPS;
        INIT_LIST_HEAD(&ehci->cached_itd_list);
+       INIT_LIST_HEAD(&ehci->cached_sitd_list);
        if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0)
                return retval;
 
@@ -995,7 +996,7 @@ rescan:
        /* endpoints can be iso streams.  for now, we don't
         * accelerate iso completions ... so spin a while.
         */
-       if (qh->hw->hw_info1 == 0) {
+       if (qh->hw == NULL) {
                ehci_vdbg (ehci, "iso delay\n");
                goto idle_timeout;
        }
index 19372673bf09aadffc955c2ca531b8133b219149..c7178bcde67a99da38c2e08b1b2a8bb4481a7a14 100644 (file)
@@ -801,7 +801,7 @@ static int ehci_hub_control (
                         * this bit; seems too long to spin routinely...
                         */
                        retval = handshake(ehci, status_reg,
-                                       PORT_RESET, 0, 750);
+                                       PORT_RESET, 0, 1000);
                        if (retval != 0) {
                                ehci_err (ehci, "port %d reset error %d\n",
                                        wIndex + 1, retval);
index aeda96e0af67bd6eb43b3b607e2c7a3817da8c5d..1f3f01eacaf09cecb88af40187910465cb49b0f3 100644 (file)
@@ -136,7 +136,7 @@ static inline void qh_put (struct ehci_qh *qh)
 
 static void ehci_mem_cleanup (struct ehci_hcd *ehci)
 {
-       free_cached_itd_list(ehci);
+       free_cached_lists(ehci);
        if (ehci->async)
                qh_put (ehci->async);
        ehci->async = NULL;
index 23cd917088b41fa73a74abad13f66fba82a9df85..ead59f42e69b10e75be28c14a2186573d0723fdd 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/usb/otg.h>
+#include <linux/slab.h>
 
 #include <mach/mxc_ehci.h>
 
index f0282d6bb7aa63e42484b5868b31d96553c9fb7d..40a8583350353883719112b33c739a382d424a17 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/clk.h>
 #include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 #include <plat/usb.h>
 
 /*
@@ -628,11 +629,13 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
                }
                snprintf(supply, sizeof(supply), "hsusb%d", i);
                omap->regulator[i] = regulator_get(omap->dev, supply);
-               if (IS_ERR(omap->regulator[i]))
+               if (IS_ERR(omap->regulator[i])) {
+                       omap->regulator[i] = NULL;
                        dev_dbg(&pdev->dev,
                        "failed to get ehci port%d regulator\n", i);
-               else
+               } else {
                        regulator_enable(omap->regulator[i]);
+               }
        }
 
        ret = omap_start_ehc(omap, hcd);
index 39340ae00ac488bcd6a0a3f1ed5ac71931dbe63e..805ec633a652643c6952cd4e7b2595f2c9b10815 100644 (file)
@@ -510,7 +510,7 @@ static int disable_periodic (struct ehci_hcd *ehci)
        ehci_writel(ehci, cmd, &ehci->regs->command);
        /* posted write ... */
 
-       free_cached_itd_list(ehci);
+       free_cached_lists(ehci);
 
        ehci->next_uframe = -1;
        return 0;
@@ -1123,8 +1123,8 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb)
                                        urb->interval);
                }
 
-       /* if dev->ep [epnum] is a QH, info1.maxpacket is nonzero */
-       } else if (unlikely (stream->hw_info1 != 0)) {
+       /* if dev->ep [epnum] is a QH, hw is set */
+       } else if (unlikely (stream->hw != NULL)) {
                ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n",
                        urb->dev->devpath, epnum,
                        usb_pipein(urb->pipe) ? "in" : "out");
@@ -1565,13 +1565,27 @@ itd_patch(
 static inline void
 itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd)
 {
-       /* always prepend ITD/SITD ... only QH tree is order-sensitive */
-       itd->itd_next = ehci->pshadow [frame];
-       itd->hw_next = ehci->periodic [frame];
-       ehci->pshadow [frame].itd = itd;
+       union ehci_shadow       *prev = &ehci->pshadow[frame];
+       __hc32                  *hw_p = &ehci->periodic[frame];
+       union ehci_shadow       here = *prev;
+       __hc32                  type = 0;
+
+       /* skip any iso nodes which might belong to previous microframes */
+       while (here.ptr) {
+               type = Q_NEXT_TYPE(ehci, *hw_p);
+               if (type == cpu_to_hc32(ehci, Q_TYPE_QH))
+                       break;
+               prev = periodic_next_shadow(ehci, prev, type);
+               hw_p = shadow_next_periodic(ehci, &here, type);
+               here = *prev;
+       }
+
+       itd->itd_next = here;
+       itd->hw_next = *hw_p;
+       prev->itd = itd;
        itd->frame = frame;
        wmb ();
-       ehci->periodic[frame] = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
+       *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
 }
 
 /* fit urb's itds into the selected schedule slot; activate as needed */
@@ -2125,13 +2139,27 @@ sitd_complete (
                        (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
        }
        iso_stream_put (ehci, stream);
-       /* OK to recycle this SITD now that its completion callback ran. */
+
 done:
        sitd->urb = NULL;
-       sitd->stream = NULL;
-       list_move(&sitd->sitd_list, &stream->free_list);
-       iso_stream_put(ehci, stream);
-
+       if (ehci->clock_frame != sitd->frame) {
+               /* OK to recycle this SITD now. */
+               sitd->stream = NULL;
+               list_move(&sitd->sitd_list, &stream->free_list);
+               iso_stream_put(ehci, stream);
+       } else {
+               /* HW might remember this SITD, so we can't recycle it yet.
+                * Move it to a safe place until a new frame starts.
+                */
+               list_move(&sitd->sitd_list, &ehci->cached_sitd_list);
+               if (stream->refcount == 2) {
+                       /* If iso_stream_put() were called here, stream
+                        * would be freed.  Instead, just prevent reuse.
+                        */
+                       stream->ep->hcpriv = NULL;
+                       stream->ep = NULL;
+               }
+       }
        return retval;
 }
 
@@ -2197,9 +2225,10 @@ done:
 
 /*-------------------------------------------------------------------------*/
 
-static void free_cached_itd_list(struct ehci_hcd *ehci)
+static void free_cached_lists(struct ehci_hcd *ehci)
 {
        struct ehci_itd *itd, *n;
+       struct ehci_sitd *sitd, *sn;
 
        list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) {
                struct ehci_iso_stream  *stream = itd->stream;
@@ -2207,6 +2236,13 @@ static void free_cached_itd_list(struct ehci_hcd *ehci)
                list_move(&itd->itd_list, &stream->free_list);
                iso_stream_put(ehci, stream);
        }
+
+       list_for_each_entry_safe(sitd, sn, &ehci->cached_sitd_list, sitd_list) {
+               struct ehci_iso_stream  *stream = sitd->stream;
+               sitd->stream = NULL;
+               list_move(&sitd->sitd_list, &stream->free_list);
+               iso_stream_put(ehci, stream);
+       }
 }
 
 /*-------------------------------------------------------------------------*/
@@ -2233,7 +2269,7 @@ scan_periodic (struct ehci_hcd *ehci)
                clock_frame = -1;
        }
        if (ehci->clock_frame != clock_frame) {
-               free_cached_itd_list(ehci);
+               free_cached_lists(ehci);
                ehci->clock_frame = clock_frame;
        }
        clock %= mod;
@@ -2400,7 +2436,7 @@ restart:
                        clock = now;
                        clock_frame = clock >> 3;
                        if (ehci->clock_frame != clock_frame) {
-                               free_cached_itd_list(ehci);
+                               free_cached_lists(ehci);
                                ehci->clock_frame = clock_frame;
                        }
                } else {
index 2d85e21ff282e9199be521fe630588cf8b3e01fb..556c0b48f3abd73278206e5c1581eb3d32b73850 100644 (file)
@@ -87,8 +87,9 @@ struct ehci_hcd {                     /* one per controller */
        int                     next_uframe;    /* scan periodic, start here */
        unsigned                periodic_sched; /* periodic activity count */
 
-       /* list of itds completed while clock_frame was still active */
+       /* list of itds & sitds completed while clock_frame was still active */
        struct list_head        cached_itd_list;
+       struct list_head        cached_sitd_list;
        unsigned                clock_frame;
 
        /* per root hub port */
@@ -195,7 +196,7 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action)
        clear_bit (action, &ehci->actions);
 }
 
-static void free_cached_itd_list(struct ehci_hcd *ehci);
+static void free_cached_lists(struct ehci_hcd *ehci);
 
 /*-------------------------------------------------------------------------*/
 
@@ -394,9 +395,8 @@ struct ehci_iso_sched {
  * acts like a qh would, if EHCI had them for ISO.
  */
 struct ehci_iso_stream {
-       /* first two fields match QH, but info1 == 0 */
-       __hc32                  hw_next;
-       __hc32                  hw_info1;
+       /* first field matches ehci_hq, but is NULL */
+       struct ehci_qh_hw       *hw;
 
        u32                     refcount;
        u8                      bEndpointAddress;
index 5dcfb3de9945788798b5fae2ce91a67706458e4d..15379c636143e86fa5d684b5af5dc21f662f0ba5 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/usb.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
+#include <linux/slab.h>
 #include <asm/qe.h>
 #include <asm/fsl_gtm.h>
 #include "../core/hcd.h"
index 2c0736c9971242d3f7ec6a54d28f7ed72152d741..5591bfb499d19d2b8ccbe829b957452996651078 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/usb.h>
 #include "../core/hcd.h"
index b0a1446ba292542eecd682aaa6f2f3afd5f7ef07..f73c92359beb34579676a32b8a6cca72ecea3f59 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/usb.h>
 #include "../core/hcd.h"
index e1232890c78bb9f9f4d931589dc14adeb363f2ba..57013479d7f7c6d911a480b4a4652a8b5cfa9c20 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/io.h>
 #include <linux/usb.h>
index 88b03214622b96683f3c0f6d9b5db73e8d98f2d5..35742f8c7cdaf714d0562a9a1a5e3ae7a2f5d06e 100644 (file)
@@ -55,6 +55,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/workqueue.h>
 #include <linux/wait.h>
index 213e270e1c2983ae4b430af95451519398efe1fb..8a12f297645fae9dfb08c191f0635ebe7d0b1b02 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "../core/hcd.h"
index a2b305477afef25b1a37c0e03a7cfeff42e6acf6..92de71dc7729f88fcd33b5b9a85cfc682ed21f8a 100644 (file)
@@ -62,6 +62,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/isp116x.h>
 #include <linux/platform_device.h>
index 68b83ab70719aa8b76f79d7b766625cc991cbe4c..944291e10f972f23f218bd5dd23bc03ef776f54d 100644 (file)
@@ -331,6 +331,8 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
         */
        if (at91_suspend_entering_slow_clock()) {
                ohci_usb_reset (ohci);
+               /* flush the writes */
+               (void) ohci_readl (ohci, &ohci->regs->control);
                at91_stop_clock();
        }
 
index 4aa08d36d07797c5cefaded275af7e5d2c2b896f..d22fb4d577b775b9b2144796d4d57453bb98cda4 100644 (file)
@@ -23,7 +23,7 @@
 #error "This file is DA8xx bus glue.  Define CONFIG_ARCH_DAVINCI_DA8XX."
 #endif
 
-#define CFGCHIP2       DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP2_REG)
+#define CFGCHIP2       DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)
 
 static struct clk *usb11_clk;
 static struct clk *usb20_clk;
index 32bbce9718f0626b98cc37e09b14faa51a5cc16f..65cac8cc8921254718d835860a9ad2871d13b823 100644 (file)
@@ -697,7 +697,7 @@ static int ohci_hub_control (
        u16             wLength
 ) {
        struct ohci_hcd *ohci = hcd_to_ohci (hcd);
-       int             ports = hcd_to_bus (hcd)->root_hub->maxchild;
+       int             ports = ohci->num_ports;
        u32             temp;
        int             retval = 0;
 
index 35288bcae0dbc10ccc04fe380e36ba8026f1220a..83094d067e0f40bdf18370210e90cbd4d7b24ef8 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/irq.h>
+#include <linux/slab.h>
 
 static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv)
 {
index 50f57f468836da478f87c19e353dfb811f112b93..e62b30b3e4296e5e8fe157128b2206f1f5d25c52 100644 (file)
@@ -660,13 +660,13 @@ static struct ehci_qh *oxu_qh_alloc(struct oxu_hcd *oxu)
                if (qh->dummy == NULL) {
                        oxu_dbg(oxu, "no dummy td\n");
                        oxu->qh_used[i] = 0;
-
-                       return NULL;
+                       qh = NULL;
+                       goto unlock;
                }
 
                oxu->qh_used[i] = 1;
        }
-
+unlock:
        spin_unlock(&oxu->mem_lock);
 
        return qh;
index bee558aed42778ce153b5a1db9c4c55376575431..d478ffad59b4db18eb1b5c0eb0654e4882b94efe 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/io.h>
 #include <linux/mm.h>
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <asm/cacheflush.h>
 
 #include "../core/hcd.h"
@@ -418,7 +419,7 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb)
 
 /* this function must be called with interrupt disabled */
 static void free_usb_address(struct r8a66597 *r8a66597,
-                            struct r8a66597_device *dev)
+                            struct r8a66597_device *dev, int reset)
 {
        int port;
 
@@ -430,7 +431,13 @@ static void free_usb_address(struct r8a66597 *r8a66597,
        dev->state = USB_STATE_DEFAULT;
        r8a66597->address_map &= ~(1 << dev->address);
        dev->address = 0;
-       dev_set_drvdata(&dev->udev->dev, NULL);
+       /*
+        * Only when resetting USB, it is necessary to erase drvdata. When
+        * a usb device with usb hub is disconnect, "dev->udev" is already
+        * freed on usb_desconnect(). So we cannot access the data.
+        */
+       if (reset)
+               dev_set_drvdata(&dev->udev->dev, NULL);
        list_del(&dev->device_list);
        kfree(dev);
 
@@ -1069,7 +1076,7 @@ static void r8a66597_usb_disconnect(struct r8a66597 *r8a66597, int port)
        struct r8a66597_device *dev = r8a66597->root_hub[port].dev;
 
        disable_r8a66597_pipe_all(r8a66597, dev);
-       free_usb_address(r8a66597, dev);
+       free_usb_address(r8a66597, dev, 0);
 
        start_root_hub_sampling(r8a66597, port, 0);
 }
@@ -2085,7 +2092,7 @@ static void update_usb_address_map(struct r8a66597 *r8a66597,
                                spin_lock_irqsave(&r8a66597->lock, flags);
                                dev = get_r8a66597_device(r8a66597, addr);
                                disable_r8a66597_pipe_all(r8a66597, dev);
-                               free_usb_address(r8a66597, dev);
+                               free_usb_address(r8a66597, dev, 0);
                                put_child_connect_map(r8a66597, addr);
                                spin_unlock_irqrestore(&r8a66597->lock, flags);
                        }
@@ -2228,7 +2235,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                        rh->port |= (1 << USB_PORT_FEAT_RESET);
 
                        disable_r8a66597_pipe_all(r8a66597, dev);
-                       free_usb_address(r8a66597, dev);
+                       free_usb_address(r8a66597, dev, 1);
 
                        r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT,
                                      get_dvstctr_reg(port));
index e11cc3aa4b82f2bd968d89e187f3a2c1ed53d40b..3b867a8af7b2d15df00d0dbf6f595e00b2f32b24 100644 (file)
@@ -720,10 +720,10 @@ retry:
                /* port status seems weird until after reset, so
                 * force the reset and make khubd clean up later.
                 */
-               if (sl811->stat_insrmv & 1)
-                       sl811->port1 |= 1 << USB_PORT_FEAT_CONNECTION;
-               else
+               if (irqstat & SL11H_INTMASK_RD)
                        sl811->port1 &= ~(1 << USB_PORT_FEAT_CONNECTION);
+               else
+                       sl811->port1 |= 1 << USB_PORT_FEAT_CONNECTION;
 
                sl811->port1 |= 1 << USB_PORT_FEAT_C_CONNECTION;
 
index e52b954dda471d1a492e5be2a10ff2b5a19d8bdf..98cf0b26b9684b2da11b7aa2c0628196479cc2a1 100644 (file)
@@ -9,6 +9,7 @@
  * (C) Copyright 1999-2001 Johannes Erdfelt
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/debugfs.h>
 #include <linux/smp_lock.h>
index 562eba108816cb689bda3eee2b9b2125150c77fe..773249306031bd6a45ef7a49a22b9b7366e0a613 100644 (file)
@@ -16,6 +16,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/dma-mapping.h>
 #include <linux/uwb/umc.h>
 #include <linux/usb.h>
index 8c1c610c9513222aa494e86e6977799c57cbc991..c5305b599ca052a1acc27e68386942e306f7c6e1 100644 (file)
@@ -15,6 +15,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
index 34a783cb0133914b6806c9bcd322852f362a0888..f7582e8e2169216c64e0f75ff6e67e037579f885 100644 (file)
@@ -16,6 +16,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/dma-mapping.h>
 #include <linux/uwb/umc.h>
 
index 0db3fb2dc03ae500f545b8356485c6b460c12859..33c5580b4d25f78c93b9abe7625edcf083f4011e 100644 (file)
@@ -16,6 +16,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/dma-mapping.h>
 #include <linux/uwb/umc.h>
 #include <linux/usb.h>
index 7d4204db0f61c7ce18bb9e897700b22335094139..141d049beb3ee973df29af238728909d8353c27c 100644 (file)
@@ -17,6 +17,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <linux/uwb/umc.h>
 #include <linux/usb.h>
 
index 49f7d72f8b1b0e5e936077024b3f9720d15178e0..d64f5724bfc4b850c75b57c505d307e90eaeba44 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/usb.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/dmapool.h>
 
 #include "xhci.h"
@@ -566,8 +567,13 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
                        if (interval < 3)
                                interval = 3;
                        if ((1 << interval) != 8*ep->desc.bInterval)
-                               dev_warn(&udev->dev, "ep %#x - rounding interval to %d microframes\n",
-                                               ep->desc.bEndpointAddress, 1 << interval);
+                               dev_warn(&udev->dev,
+                                               "ep %#x - rounding interval"
+                                               " to %d microframes, "
+                                               "ep desc says %d microframes\n",
+                                               ep->desc.bEndpointAddress,
+                                               1 << interval,
+                                               8*ep->desc.bInterval);
                }
                break;
        default:
@@ -576,6 +582,19 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
        return EP_INTERVAL(interval);
 }
 
+/* The "Mult" field in the endpoint context is only set for SuperSpeed devices.
+ * High speed endpoint descriptors can define "the number of additional
+ * transaction opportunities per microframe", but that goes in the Max Burst
+ * endpoint context field.
+ */
+static inline u32 xhci_get_endpoint_mult(struct usb_device *udev,
+               struct usb_host_endpoint *ep)
+{
+       if (udev->speed != USB_SPEED_SUPER || !ep->ss_ep_comp)
+               return 0;
+       return ep->ss_ep_comp->desc.bmAttributes;
+}
+
 static inline u32 xhci_get_endpoint_type(struct usb_device *udev,
                struct usb_host_endpoint *ep)
 {
@@ -606,6 +625,36 @@ static inline u32 xhci_get_endpoint_type(struct usb_device *udev,
        return type;
 }
 
+/* Return the maximum endpoint service interval time (ESIT) payload.
+ * Basically, this is the maxpacket size, multiplied by the burst size
+ * and mult size.
+ */
+static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci,
+               struct usb_device *udev,
+               struct usb_host_endpoint *ep)
+{
+       int max_burst;
+       int max_packet;
+
+       /* Only applies for interrupt or isochronous endpoints */
+       if (usb_endpoint_xfer_control(&ep->desc) ||
+                       usb_endpoint_xfer_bulk(&ep->desc))
+               return 0;
+
+       if (udev->speed == USB_SPEED_SUPER) {
+               if (ep->ss_ep_comp)
+                       return ep->ss_ep_comp->desc.wBytesPerInterval;
+               xhci_warn(xhci, "WARN no SS endpoint companion descriptor.\n");
+               /* Assume no bursts, no multiple opportunities to send. */
+               return ep->desc.wMaxPacketSize;
+       }
+
+       max_packet = ep->desc.wMaxPacketSize & 0x3ff;
+       max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11;
+       /* A 0 in max burst means 1 transfer per ESIT */
+       return max_packet * (max_burst + 1);
+}
+
 int xhci_endpoint_init(struct xhci_hcd *xhci,
                struct xhci_virt_device *virt_dev,
                struct usb_device *udev,
@@ -617,6 +666,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
        struct xhci_ring *ep_ring;
        unsigned int max_packet;
        unsigned int max_burst;
+       u32 max_esit_payload;
 
        ep_index = xhci_get_endpoint_index(&ep->desc);
        ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
@@ -638,6 +688,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
        ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state;
 
        ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep);
+       ep_ctx->ep_info |= EP_MULT(xhci_get_endpoint_mult(udev, ep));
 
        /* FIXME dig Mult and streams info out of ep companion desc */
 
@@ -683,6 +734,26 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
        default:
                BUG();
        }
+       max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep);
+       ep_ctx->tx_info = MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload);
+
+       /*
+        * XXX no idea how to calculate the average TRB buffer length for bulk
+        * endpoints, as the driver gives us no clue how big each scatter gather
+        * list entry (or buffer) is going to be.
+        *
+        * For isochronous and interrupt endpoints, we set it to the max
+        * available, until we have new API in the USB core to allow drivers to
+        * declare how much bandwidth they actually need.
+        *
+        * Normally, it would be calculated by taking the total of the buffer
+        * lengths in the TD and then dividing by the number of TRBs in a TD,
+        * including link TRBs, No-op TRBs, and Event data TRBs.  Since we don't
+        * use Event Data TRBs, and we don't chain in a link TRB on short
+        * transfers, we're basically dividing by 1.
+        */
+       ep_ctx->tx_info |= AVG_TRB_LENGTH_FOR_EP(max_esit_payload);
+
        /* FIXME Debug endpoint context */
        return 0;
 }
index 6ba841bca4a28f24db9a76f6808f87e08c599194..85d7e8f2085e70481cb0cdcf4207f15efa1ba886 100644 (file)
@@ -65,6 +65,7 @@
  */
 
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include "xhci.h"
 
 /*
similarity index 99%
rename from drivers/usb/host/xhci-hcd.c
rename to drivers/usb/host/xhci.c
index 4cb69e0af83442230fc13448a3e31f5b144ebe86..7e4277273908fc6cb31cc596e2e45482b7021ebd 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 
 #include "xhci.h"
 
@@ -1173,6 +1174,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
                cmd_completion = &virt_dev->cmd_completion;
                cmd_status = &virt_dev->cmd_status;
        }
+       init_completion(cmd_completion);
 
        if (!ctx_change)
                ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma,
index e5eb09b2f38ed690451995f5899fd75136bdcea7..ea389e9a4931992bb96fba25c14b57e2cea50873 100644 (file)
@@ -609,6 +609,10 @@ struct xhci_ep_ctx {
 #define MAX_PACKET_MASK                (0xffff << 16)
 #define MAX_PACKET_DECODED(p)  (((p) >> 16) & 0xffff)
 
+/* tx_info bitmasks */
+#define AVG_TRB_LENGTH_FOR_EP(p)       ((p) & 0xffff)
+#define MAX_ESIT_PAYLOAD_FOR_EP(p)     (((p) & 0xffff) << 16)
+
 
 /**
  * struct xhci_input_control_context
index 4d2952f1fb1370f86b7c13630ee7a096769f94e5..094f91cbc5780b78ab9f3eb67c1d87c1583b9cd8 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/backlight.h>
 #include <linux/timer.h>
@@ -202,6 +203,7 @@ static void appledisplay_work(struct work_struct *work)
 static int appledisplay_probe(struct usb_interface *iface,
        const struct usb_device_id *id)
 {
+       struct backlight_properties props;
        struct appledisplay *pdata;
        struct usb_device *udev = interface_to_usbdev(iface);
        struct usb_host_interface *iface_desc;
@@ -279,16 +281,16 @@ static int appledisplay_probe(struct usb_interface *iface,
        /* Register backlight device */
        snprintf(bl_name, sizeof(bl_name), "appledisplay%d",
                atomic_inc_return(&count_displays) - 1);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 0xff;
        pdata->bd = backlight_device_register(bl_name, NULL, pdata,
-                                               &appledisplay_bl_data);
+                                             &appledisplay_bl_data, &props);
        if (IS_ERR(pdata->bd)) {
                dev_err(&iface->dev, "Backlight registration failed\n");
                retval = PTR_ERR(pdata->bd);
                goto error;
        }
 
-       pdata->bd->props.max_brightness = 0xff;
-
        /* Try to get brightness */
        brightness = appledisplay_bl_get_brightness(pdata->bd);
 
index 1547d8cac5fb96fcae8f87b0085a63c277eb1320..2f43c57743c9c905b26e8e06dc517df6b5bb7c26 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #define DRIVER_AUTHOR          "Oliver Bock (bock@tfh-berlin.de)"
index b9cbbbda824558f20802d18b28ae9151ce59a3d3..1d7251bc1b5f5f395376ccf01f829c097d5ec82f 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/usb.h>
 
index 06e990adc6cdd50e77657beeb5a690d7684ed224..fe1d44319d0a1eb2d373c14c6fccbfdfedd505c9 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/firmware.h>
 #include <linux/errno.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 static const struct usb_device_id id_table[] = {
        {USB_DEVICE(0x05ac, 0x8300)},
index b624320df903da090c8380f59d06593d8c648302..b271b0557a1f9fb0db8ea382898fcbe5e18e09c8 100644 (file)
@@ -58,7 +58,6 @@
 #include <linux/string.h>
 #include <linux/kd.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/vt_kern.h>
 #include <linux/selection.h>
 #include <linux/spinlock.h>
index 0ab990744830c4fc321eca69fa485c59997670ba..cb8a3d91f9706d14fbf6ee4a710c404047ea7ece 100644 (file)
@@ -41,7 +41,6 @@
 #include <linux/errno.h>
 #include <linux/poll.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 
 #include "sisusb.h"
index 5da28eaee314c0e0ecdba8bed88f925e71a123ed..d77aba46ae85675e58afb532078458b74b7b29a7 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/usb.h>
 
index a9555cb901a1df27274d415255563242d74c178a..de8ef945b536d07a277c56bff506798bd90620e3 100644 (file)
@@ -49,6 +49,7 @@ struct usb_sevsegdev {
        u16 textlength;
 
        u8 shadow_power; /* for PM */
+       u8 has_interface_pm;
 };
 
 /* sysfs_streq can't replace this completely
@@ -68,12 +69,16 @@ static void update_display_powered(struct usb_sevsegdev *mydev)
 {
        int rc;
 
-       if (!mydev->shadow_power && mydev->powered) {
+       if (mydev->powered && !mydev->has_interface_pm) {
                rc = usb_autopm_get_interface(mydev->intf);
                if (rc < 0)
                        return;
+               mydev->has_interface_pm = 1;
        }
 
+       if (mydev->shadow_power != 1)
+               return;
+
        rc = usb_control_msg(mydev->udev,
                        usb_sndctrlpipe(mydev->udev, 0),
                        0x12,
@@ -86,8 +91,10 @@ static void update_display_powered(struct usb_sevsegdev *mydev)
        if (rc < 0)
                dev_dbg(&mydev->udev->dev, "power retval = %d\n", rc);
 
-       if (mydev->shadow_power && !mydev->powered)
+       if (!mydev->powered && mydev->has_interface_pm) {
                usb_autopm_put_interface(mydev->intf);
+               mydev->has_interface_pm = 0;
+       }
 }
 
 static void update_display_mode(struct usb_sevsegdev *mydev)
@@ -351,6 +358,10 @@ static int sevseg_probe(struct usb_interface *interface,
        mydev->intf = interface;
        usb_set_intfdata(interface, mydev);
 
+       /* PM */
+       mydev->shadow_power = 1; /* currently active */
+       mydev->has_interface_pm = 0; /* have not issued autopm_get */
+
        /*set defaults */
        mydev->textmode = 0x02; /* ascii mode */
        mydev->mode_msb = 0x06; /* 6 characters */
index f56fed53f2dd202b8f6cc551488e3590f006af7a..796e2f68f7494fad857349e9ffc82ac4f9303984 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/delay.h>
 #include <linux/completion.h>
 #include <linux/kref.h>
+#include <linux/slab.h>
 
 /*
  * Version Information
index 6dd44bc1f5ff4cb98791691a077d344960894690..ddf7f9a1b3362c37178ac2cccc9f81f828d7bfcd 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/mm.h>
 #include <linux/smp_lock.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 
index e0c2db3b767b7cb91539e1ed1fe8f386beebc268..e4af18b93c7d85b7bc512872d7cb46f88bd07882 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 #include <linux/notifier.h>
 #include <linux/mutex.h>
 
index ac8b0d5ce7f852c663dca9af9fbb8dc389348591..1becdc3837e6ce5f897d5b6a2e4b0f4dcdd12c3b 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/fs.h>
 #include <asm/uaccess.h>
index 31c11888ec6a9e3bed63f56628761a98e193789d..4d0be130f49b5282af7b70654b94ead4e0cf2e9b 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/mutex.h>
 #include <linux/debugfs.h>
index b4c783c284bacaff36fb5eb2e0f5c601ae079d8a..07fe490b44d81e1b804c12adaf990880c907777e 100644 (file)
@@ -42,7 +42,7 @@ config USB_MUSB_SOC
        default y if (BF52x && !BF522 && !BF523)
 
 comment "DaVinci 35x and 644x USB support"
-       depends on USB_MUSB_HDRC && ARCH_DAVINCI
+       depends on USB_MUSB_HDRC && ARCH_DAVINCI_DMx
 
 comment "OMAP 243x high speed USB support"
        depends on USB_MUSB_HDRC && ARCH_OMAP2430
index 85710ccc188754ad5bc52678fe9d2071b67ee188..3a485dabebbb33c6fa242099874b8108568e71f9 100644 (file)
@@ -6,7 +6,7 @@ musb_hdrc-objs := musb_core.o
 
 obj-$(CONFIG_USB_MUSB_HDRC)    += musb_hdrc.o
 
-ifeq ($(CONFIG_ARCH_DAVINCI),y)
+ifeq ($(CONFIG_ARCH_DAVINCI_DMx),y)
        musb_hdrc-objs  += davinci.o
 endif
 
index bcee1339d4fdfdbb0a53c7a96ddbdeceda360b85..ec8d324237f6814e2e8947b06ef00ea92b67bf5e 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/gpio.h>
@@ -173,13 +172,7 @@ static irqreturn_t blackfin_interrupt(int irq, void *__hci)
 
        spin_unlock_irqrestore(&musb->lock, flags);
 
-       /* REVISIT we sometimes get spurious IRQs on g_ep0
-        * not clear why... fall in BF54x too.
-        */
-       if (retval != IRQ_HANDLED)
-               DBG(5, "spurious?\n");
-
-       return IRQ_HANDLED;
+       return retval;
 }
 
 static void musb_conn_timer_handler(unsigned long _musb)
index 3c69a76ec392fdd8574bd061e1e113df341175ad..59dc3d351b60269f3c3872b859c0b39d7fcbe449 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 
 #include "musb_core.h"
index a883f9dd3f8aea7da8f894b54ccdf694eb47b1b9..ce2e16fee0df9dc644c1c14d52fa78c038f34b2e 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/delay.h>
@@ -445,6 +444,8 @@ int __init musb_platform_init(struct musb *musb)
        return 0;
 
 fail:
+       clk_disable(musb->clock);
+
        usb_nop_xceiv_unregister();
        return -ENODEV;
 }
index b4bbf8f2c2381bb0f4de4d0042b85b2260a843d0..705cc4ad8737361400f106cc206e4e6cbc629384 100644 (file)
@@ -379,7 +379,6 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
                                u8 devctl, u8 power)
 {
        irqreturn_t handled = IRQ_NONE;
-       void __iomem *mbase = musb->mregs;
 
        DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl,
                int_usb);
@@ -394,6 +393,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
 
                if (devctl & MUSB_DEVCTL_HM) {
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
+                       void __iomem *mbase = musb->mregs;
+
                        switch (musb->xceiv->state) {
                        case OTG_STATE_A_SUSPEND:
                                /* remote wakeup?  later, GetPortStatus
@@ -471,6 +472,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
        /* see manual for the order of the tests */
        if (int_usb & MUSB_INTR_SESSREQ) {
+               void __iomem *mbase = musb->mregs;
+
                DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb));
 
                /* IRQ arrives from ID pin sense or (later, if VBUS power
@@ -519,6 +522,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
                case OTG_STATE_A_WAIT_BCON:
                case OTG_STATE_A_WAIT_VRISE:
                        if (musb->vbuserr_retry) {
+                               void __iomem *mbase = musb->mregs;
+
                                musb->vbuserr_retry--;
                                ignore = 1;
                                devctl |= MUSB_DEVCTL_SESSION;
@@ -622,6 +627,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
 
        if (int_usb & MUSB_INTR_CONNECT) {
                struct usb_hcd *hcd = musb_to_hcd(musb);
+               void __iomem *mbase = musb->mregs;
 
                handled = IRQ_HANDLED;
                musb->is_active = 1;
@@ -959,10 +965,8 @@ static void musb_shutdown(struct platform_device *pdev)
        spin_lock_irqsave(&musb->lock, flags);
        musb_platform_disable(musb);
        musb_generic_disable(musb);
-       if (musb->clock) {
+       if (musb->clock)
                clk_put(musb->clock);
-               musb->clock = NULL;
-       }
        spin_unlock_irqrestore(&musb->lock, flags);
 
        /* FIXME power down */
@@ -1847,15 +1851,6 @@ static void musb_free(struct musb *musb)
        put_device(musb->xceiv->dev);
 #endif
 
-       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
-       musb_platform_exit(musb);
-       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
-
-       if (musb->clock) {
-               clk_disable(musb->clock);
-               clk_put(musb->clock);
-       }
-
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
        usb_put_hcd(musb_to_hcd(musb));
 #else
@@ -1883,8 +1878,10 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
         */
        if (!plat) {
                dev_dbg(dev, "no platform_data?\n");
-               return -ENODEV;
+               status = -ENODEV;
+               goto fail0;
        }
+
        switch (plat->mode) {
        case MUSB_HOST:
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
@@ -1906,13 +1903,16 @@ bad_config:
 #endif
        default:
                dev_err(dev, "incompatible Kconfig role setting\n");
-               return -EINVAL;
+               status = -EINVAL;
+               goto fail0;
        }
 
        /* allocate */
        musb = allocate_instance(dev, plat->config, ctrl);
-       if (!musb)
-               return -ENOMEM;
+       if (!musb) {
+               status = -ENOMEM;
+               goto fail0;
+       }
 
        spin_lock_init(&musb->lock);
        musb->board_mode = plat->mode;
@@ -1930,7 +1930,7 @@ bad_config:
                if (IS_ERR(musb->clock)) {
                        status = PTR_ERR(musb->clock);
                        musb->clock = NULL;
-                       goto fail;
+                       goto fail1;
                }
        }
 
@@ -1949,12 +1949,12 @@ bad_config:
         */
        musb->isr = generic_interrupt;
        status = musb_platform_init(musb);
-
        if (status < 0)
-               goto fail;
+               goto fail2;
+
        if (!musb->isr) {
                status = -ENODEV;
-               goto fail2;
+               goto fail3;
        }
 
 #ifndef CONFIG_MUSB_PIO_ONLY
@@ -1980,7 +1980,7 @@ bad_config:
                        ? MUSB_CONTROLLER_MHDRC
                        : MUSB_CONTROLLER_HDRC, musb);
        if (status < 0)
-               goto fail2;
+               goto fail3;
 
 #ifdef CONFIG_USB_MUSB_OTG
        setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb);
@@ -1993,7 +1993,7 @@ bad_config:
        if (request_irq(nIrq, musb->isr, 0, dev_name(dev), musb)) {
                dev_err(dev, "request_irq %d failed!\n", nIrq);
                status = -ENODEV;
-               goto fail2;
+               goto fail3;
        }
        musb->nIrq = nIrq;
 /* FIXME this handles wakeup irqs wrong */
@@ -2007,7 +2007,6 @@ bad_config:
        /* host side needs more setup */
        if (is_host_enabled(musb)) {
                struct usb_hcd  *hcd = musb_to_hcd(musb);
-               u8 busctl;
 
                otg_set_host(musb->xceiv, &hcd->self);
 
@@ -2018,9 +2017,9 @@ bad_config:
 
                /* program PHY to use external vBus if required */
                if (plat->extvbus) {
-                       busctl = musb_readb(musb->mregs, MUSB_ULPI_BUSCONTROL);
+                       u8 busctl = musb_read_ulpi_buscontrol(musb->mregs);
                        busctl |= MUSB_ULPI_USE_EXTVBUS;
-                       musb_writeb(musb->mregs, MUSB_ULPI_BUSCONTROL, busctl);
+                       musb_write_ulpi_buscontrol(musb->mregs, busctl);
                }
        }
 
@@ -2034,8 +2033,6 @@ bad_config:
                musb->xceiv->state = OTG_STATE_A_IDLE;
 
                status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
-               if (status)
-                       goto fail;
 
                DBG(1, "%s mode, status %d, devctl %02x %c\n",
                        "HOST", status,
@@ -2050,8 +2047,6 @@ bad_config:
                musb->xceiv->state = OTG_STATE_B_IDLE;
 
                status = musb_gadget_setup(musb);
-               if (status)
-                       goto fail;
 
                DBG(1, "%s mode, status %d, dev%02x\n",
                        is_otg_enabled(musb) ? "OTG" : "PERIPHERAL",
@@ -2059,12 +2054,14 @@ bad_config:
                        musb_readb(musb->mregs, MUSB_DEVCTL));
 
        }
+       if (status < 0)
+               goto fail3;
 
 #ifdef CONFIG_SYSFS
        status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group);
-#endif
        if (status)
-               goto fail2;
+               goto fail4;
+#endif
 
        dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",
                        ({char *s;
@@ -2080,17 +2077,29 @@ bad_config:
 
        return 0;
 
-fail2:
+fail4:
+       if (!is_otg_enabled(musb) && is_host_enabled(musb))
+               usb_remove_hcd(musb_to_hcd(musb));
+       else
+               musb_gadget_cleanup(musb);
+
+fail3:
+       if (musb->irq_wake)
+               device_init_wakeup(dev, 0);
        musb_platform_exit(musb);
-fail:
-       dev_err(musb->controller,
-               "musb_init_controller failed with status %d\n", status);
 
+fail2:
        if (musb->clock)
                clk_put(musb->clock);
-       device_init_wakeup(dev, 0);
+
+fail1:
+       dev_err(musb->controller,
+               "musb_init_controller failed with status %d\n", status);
+
        musb_free(musb);
 
+fail0:
+
        return status;
 
 }
@@ -2127,7 +2136,6 @@ static int __init musb_probe(struct platform_device *pdev)
        /* clobbered by use_dma=n */
        orig_dma_mask = dev->dma_mask;
 #endif
-
        status = musb_init_controller(dev, irq, base);
        if (status < 0)
                iounmap(base);
@@ -2150,6 +2158,10 @@ static int __exit musb_remove(struct platform_device *pdev)
        if (musb->board_mode == MUSB_HOST)
                usb_remove_hcd(musb_to_hcd(musb));
 #endif
+       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+       musb_platform_exit(musb);
+       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+
        musb_free(musb);
        iounmap(ctrl_base);
        device_init_wakeup(&pdev->dev, 0);
@@ -2171,6 +2183,7 @@ void musb_save_context(struct musb *musb)
        if (is_host_enabled(musb)) {
                musb_context.frame = musb_readw(musb_base, MUSB_FRAME);
                musb_context.testmode = musb_readb(musb_base, MUSB_TESTMODE);
+               musb_context.busctl = musb_read_ulpi_buscontrol(musb->mregs);
        }
        musb_context.power = musb_readb(musb_base, MUSB_POWER);
        musb_context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE);
@@ -2242,6 +2255,7 @@ void musb_restore_context(struct musb *musb)
        if (is_host_enabled(musb)) {
                musb_writew(musb_base, MUSB_FRAME, musb_context.frame);
                musb_writeb(musb_base, MUSB_TESTMODE, musb_context.testmode);
+               musb_write_ulpi_buscontrol(musb->mregs, musb_context.busctl);
        }
        musb_writeb(musb_base, MUSB_POWER, musb_context.power);
        musb_writew(musb_base, MUSB_INTRTXE, musb_context.intrtxe);
index d849fb81c131cb6cae9bcb3f9d7ce58020219c46..ac17b004909b5c16d91f416ff5afc830c3799478 100644 (file)
@@ -469,7 +469,7 @@ struct musb_csr_regs {
 
 struct musb_context_registers {
 
-#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430)
+#ifdef CONFIG_PM
        u32 otg_sysconfig, otg_forcestandby;
 #endif
        u8 power;
@@ -478,12 +478,12 @@ struct musb_context_registers {
        u16 frame;
        u8 index, testmode;
 
-       u8 devctl, misc;
+       u8 devctl, busctl, misc;
 
        struct musb_csr_regs index_regs[MUSB_C_NUM_EPS];
 };
 
-#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430)
+#ifdef CONFIG_PM
 extern void musb_platform_save_context(struct musb *musb,
                struct musb_context_registers *musb_context);
 extern void musb_platform_restore_context(struct musb *musb,
index a9f288cd70ed2817ce36fceb4a006888e79e5233..6fca870e957ed3b5061f19deec76a9472d6d5211 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/moduleparam.h>
 #include <linux/stat.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include "musb_core.h"
 
index 3421cf9858b5100ee3eddd2093af35aaf1dc7f25..877d20b1dff973fd6975f258bb0b18267df1f5f5 100644 (file)
@@ -1689,7 +1689,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
                                dma->desired_mode = 1;
                        if (rx_count < hw_ep->max_packet_sz_rx) {
                                length = rx_count;
-                               dma->bDesiredMode = 0;
+                               dma->desired_mode = 0;
                        } else {
                                length = urb->transfer_buffer_length;
                        }
@@ -2042,6 +2042,7 @@ static int musb_urb_enqueue(
                 * odd, rare, error prone, but legal.
                 */
                kfree(qh);
+               qh = NULL;
                ret = 0;
        } else
                ret = musb_schedule(musb, qh,
index 8d8062b10e2ff5749394bb9f64099fdbab2adfdb..fa55aacc385d3541b6fa162e4ee00000c96cd7a2 100644 (file)
@@ -326,6 +326,11 @@ static inline void  musb_write_rxfifoadd(void __iomem *mbase, u16 c_off)
        musb_writew(mbase, MUSB_RXFIFOADD, c_off);
 }
 
+static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val)
+{
+       musb_writeb(mbase, MUSB_ULPI_BUSCONTROL, val);
+}
+
 static inline u8 musb_read_txfifosz(void __iomem *mbase)
 {
        return musb_readb(mbase, MUSB_TXFIFOSZ);
@@ -346,6 +351,11 @@ static inline u16  musb_read_rxfifoadd(void __iomem *mbase)
        return musb_readw(mbase, MUSB_RXFIFOADD);
 }
 
+static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase)
+{
+       return musb_readb(mbase, MUSB_ULPI_BUSCONTROL);
+}
+
 static inline u8 musb_read_configdata(void __iomem *mbase)
 {
        musb_writeb(mbase, MUSB_INDEX, 0);
@@ -510,20 +520,33 @@ static inline void  musb_write_rxfifoadd(void __iomem *mbase, u16 c_off)
 {
 }
 
+static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val)
+{
+}
+
 static inline u8 musb_read_txfifosz(void __iomem *mbase)
 {
+       return 0;
 }
 
 static inline u16 musb_read_txfifoadd(void __iomem *mbase)
 {
+       return 0;
 }
 
 static inline u8 musb_read_rxfifosz(void __iomem *mbase)
 {
+       return 0;
 }
 
 static inline u16  musb_read_rxfifoadd(void __iomem *mbase)
 {
+       return 0;
+}
+
+static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase)
+{
+       return 0;
 }
 
 static inline u8 musb_read_configdata(void __iomem *mbase)
@@ -577,22 +600,27 @@ static inline void  musb_write_txhubport(void __iomem *mbase, u8 epnum,
 
 static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum)
 {
+       return 0;
 }
 
 static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum)
 {
+       return 0;
 }
 
 static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum)
 {
+       return 0;
 }
 
 static inline u8  musb_read_txfunaddr(void __iomem *mbase, u8 epnum)
 {
+       return 0;
 }
 
 static inline u8  musb_read_txhubaddr(void __iomem *mbase, u8 epnum)
 {
+       return 0;
 }
 
 static inline void  musb_read_txhubport(void __iomem *mbase, u8 epnum)
index bfe5fe4ebfeeb87b49e6f762aa670d0aed4da8aa..7775e1c0a215fd81b780bf54ba024845868f0fda 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/time.h>
index 2fa7d5c00f313eadf7c83c061a9b0774c74279fa..1008044a3bbc38efc580ae72211fd7a33b29d4d3 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include "musb_core.h"
 #include "musbhsdma.h"
 
index 3fe16867b5a87f0338f861f1b37901eb3ad15a7f..82592633502fd226b152e518be4cbdcb8259f6b8 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/clk.h>
@@ -332,8 +331,5 @@ int musb_platform_exit(struct musb *musb)
 
        musb_platform_suspend(musb);
 
-       clk_put(musb->clock);
-       musb->clock = NULL;
-
        return 0;
 }
index ab776a8d98cad99897a7c01f0a02cc78ba1b4dc2..60d3938cafcf3c08f74050923b9aa41ac1c76ebc 100644 (file)
@@ -29,6 +29,19 @@ static void tusb_source_power(struct musb *musb, int is_on);
 #define TUSB_REV_MAJOR(reg_val)                ((reg_val >> 4) & 0xf)
 #define TUSB_REV_MINOR(reg_val)                (reg_val & 0xf)
 
+#ifdef CONFIG_PM
+/* REVISIT: These should be only needed if somebody implements off idle */
+void musb_platform_save_context(struct musb *musb,
+                       struct musb_context_registers *musb_context)
+{
+}
+
+void musb_platform_restore_context(struct musb *musb,
+                       struct musb_context_registers *musb_context)
+{
+}
+#endif
+
 /*
  * Checks the revision. We need to use the DMA register as 3.0 does not
  * have correct versions for TUSB_PRCM_REV or TUSB_INT_CTRL_REV.
index 1c868096bd6fb2697adff17fe018d5ec4400b11a..c061a88f2b0f96199656f725382209ade44680f9 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/usb.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <plat/dma.h>
 #include <plat/mux.h>
 
@@ -38,7 +39,7 @@ struct tusb_omap_dma_ch {
 
        struct tusb_omap_dma    *tusb_dma;
 
-       void __iomem            *dma_addr;
+       dma_addr_t              dma_addr;
 
        u32                     len;
        u16                     packet_sz;
@@ -125,6 +126,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
        struct tusb_omap_dma_ch *chdat = to_chdat(channel);
        struct tusb_omap_dma    *tusb_dma = chdat->tusb_dma;
        struct musb             *musb = chdat->musb;
+       struct device           *dev = musb->controller;
        struct musb_hw_ep       *hw_ep = chdat->hw_ep;
        void __iomem            *ep_conf = hw_ep->conf;
        void __iomem            *mbase = musb->mregs;
@@ -172,13 +174,15 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
                DBG(3, "Using PIO for remaining %lu bytes\n", pio);
                buf = phys_to_virt((u32)chdat->dma_addr) + chdat->transfer_len;
                if (chdat->tx) {
-                       dma_cache_maint(phys_to_virt((u32)chdat->dma_addr),
-                                       chdat->transfer_len, DMA_TO_DEVICE);
+                       dma_unmap_single(dev, chdat->dma_addr,
+                                               chdat->transfer_len,
+                                               DMA_TO_DEVICE);
                        musb_write_fifo(hw_ep, pio, buf);
                } else {
+                       dma_unmap_single(dev, chdat->dma_addr,
+                                               chdat->transfer_len,
+                                               DMA_FROM_DEVICE);
                        musb_read_fifo(hw_ep, pio, buf);
-                       dma_cache_maint(phys_to_virt((u32)chdat->dma_addr),
-                                       chdat->transfer_len, DMA_FROM_DEVICE);
                }
                channel->actual_len += pio;
        }
@@ -223,6 +227,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
        struct tusb_omap_dma_ch         *chdat = to_chdat(channel);
        struct tusb_omap_dma            *tusb_dma = chdat->tusb_dma;
        struct musb                     *musb = chdat->musb;
+       struct device                   *dev = musb->controller;
        struct musb_hw_ep               *hw_ep = chdat->hw_ep;
        void __iomem                    *mbase = musb->mregs;
        void __iomem                    *ep_conf = hw_ep->conf;
@@ -298,14 +303,16 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
        chdat->packet_sz = packet_sz;
        chdat->len = len;
        channel->actual_len = 0;
-       chdat->dma_addr = (void __iomem *)dma_addr;
+       chdat->dma_addr = dma_addr;
        channel->status = MUSB_DMA_STATUS_BUSY;
 
        /* Since we're recycling dma areas, we need to clean or invalidate */
        if (chdat->tx)
-               dma_cache_maint(phys_to_virt(dma_addr), len, DMA_TO_DEVICE);
+               dma_map_single(dev, phys_to_virt(dma_addr), len,
+                               DMA_TO_DEVICE);
        else
-               dma_cache_maint(phys_to_virt(dma_addr), len, DMA_FROM_DEVICE);
+               dma_map_single(dev, phys_to_virt(dma_addr), len,
+                               DMA_FROM_DEVICE);
 
        /* Use 16-bit transfer if dma_addr is not 32-bit aligned */
        if ((dma_addr & 0x3) == 0) {
index 1c26c94513e9e5bd14299d1ae046125a6d1cce07..221c44444ec677a5679d15a86b2dd9fd0a5e72be 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/usb.h>
 #include <linux/workqueue.h>
index af456b48985f06f3ebe09ae43363f47f7d0bfec7..e70014ab0976ae0ea737c8faa210544c233d4dcd 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/usb/otg.h>
+#include <linux/slab.h>
 
 struct nop_usb_xceiv {
        struct otg_transceiver  otg;
index 3e4e9f434d78d31f6f6699c0e507a1e6e09e91a7..223cdf46ccb78cad3b7aa4d0e2b0da72b93db72b 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/err.h>
 #include <linux/notifier.h>
+#include <linux/slab.h>
 
 /* Register defines */
 
index 896527456b7e4fee4632672b47c9822d39d33da6..9010225e0d063a6be854000a43efea8f6faebcf3 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/ulpi.h>
index c78b255e3f831ee7cd086c6053f7728915062783..a0ecb42cb33a13cf5b7518bc5b2344f6d71e192f 100644 (file)
@@ -474,14 +474,14 @@ config USB_SERIAL_OTI6858
 
 config USB_SERIAL_QCAUX
        tristate "USB Qualcomm Auxiliary Serial Port Driver"
-       ---help---
+       help
          Say Y here if you want to use the auxiliary serial ports provided
          by many modems based on Qualcomm chipsets.  These ports often use
          a proprietary protocol called DM and cannot be used for AT- or
          PPP-based communication.
 
          To compile this driver as a module, choose M here: the
-         module will be called moto_modem.  If unsure, choose N.
+         module will be called qcaux.  If unsure, choose N.
 
 config USB_SERIAL_QUALCOMM
        tristate "USB Qualcomm Serial modem"
index 365db1097bfdbdca5761fff631a8b37b6f280c10..4fd7af98b1aeb267c63328646708f93924a10bb2 100644 (file)
@@ -43,6 +43,7 @@
  */
 
 #include <linux/tty.h>
+#include <linux/slab.h>
 #include <linux/tty_flip.h>
 #include <linux/circ_buf.h>
 #include <linux/usb.h>
index 547c9448c28c345fd2f90966e3410b8e7949f2d3..9b66bf19f751061ce998bde586908275dda40a99 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/ioctl.h>
 #include <linux/tty.h>
+#include <linux/slab.h>
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/usb.h>
index ba555c528cc6cc8c5b88356140cd0a4e288d1ed1..7f547dc3a5903fd25e0837441115007320ae122d 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
index 9f4fed1968b52ae64e9c58f0132fd5571efde772..7e8e398184145f3d36e14a4632c9984378c44469 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/tty.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include <linux/serial.h>
index b22ac3258523af80e46a63fd0660117e51232553..f347da2ef00a04c6c8a875e54657c1eb5c87edb4 100644 (file)
@@ -181,6 +181,7 @@ static int usb_console_setup(struct console *co, char *options)
        /* The console is special in terms of closing the device so
         * indicate this port is now acting as a system console. */
        port->console = 1;
+       port->port.console = 1;
 
        mutex_unlock(&serial->disc_mutex);
        return retval;
index 507382b0a9ed1d377330344c62024fbd8e661d9d..ec9b0449ccf6658bbd013ef3a18989a34f1afcf2 100644 (file)
@@ -313,11 +313,6 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
                return -EPROTO;
        }
 
-       /* Single data value */
-       result = usb_control_msg(serial->dev,
-                       usb_sndctrlpipe(serial->dev, 0),
-                       request, REQTYPE_HOST_TO_DEVICE, data[0],
-                       0, NULL, 0, 300);
        return 0;
 }
 
index 6af0dfa5f5ac22e31a0fc9d70c8996ba33cbe53a..1d7c4fac02e8e14db7bc0f12017194be8041226c 100644 (file)
@@ -91,7 +91,7 @@ struct ftdi_private {
        unsigned long tx_outstanding_bytes;
        unsigned long tx_outstanding_urbs;
        unsigned short max_packet_size;
-       struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() */
+       struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() and change_speed() */
 };
 
 /* struct ftdi_sio_quirk is used by devices requiring special attention. */
@@ -658,6 +658,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
        { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) },
        { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) },
+       { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) },
@@ -1272,8 +1273,8 @@ check_and_exit:
             (priv->flags & ASYNC_SPD_MASK)) ||
            (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) &&
             (old_priv.custom_divisor != priv->custom_divisor))) {
-               mutex_unlock(&priv->cfg_lock);
                change_speed(tty, port);
+               mutex_unlock(&priv->cfg_lock);
        }
        else
                mutex_unlock(&priv->cfg_lock);
@@ -2264,9 +2265,11 @@ static void ftdi_set_termios(struct tty_struct *tty,
                clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
        } else {
                /* set the baudrate determined before */
+               mutex_lock(&priv->cfg_lock);
                if (change_speed(tty, port))
                        dev_err(&port->dev, "%s urb failed to set baudrate\n",
                                __func__);
+               mutex_unlock(&priv->cfg_lock);
                /* Ensure RTS and DTR are raised when baudrate changed from 0 */
                if (!old_termios || (old_termios->c_cflag & CBAUD) == B0)
                        set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
index 0727e198503e5b402af505b2e5ef286937f325b5..75482cbc39989fb51059f9de69781c82717eef92 100644 (file)
 #define CONTEC_VID             0x06CE  /* Vendor ID */
 #define CONTEC_COM1USBH_PID    0x8311  /* COM-1(USB)H */
 
+/*
+ * Contec products (http://www.contec.com)
+ * Submitted by Daniel Sangorrin
+ */
+#define CONTEC_VID             0x06CE  /* Vendor ID */
+#define CONTEC_COM1USBH_PID    0x8311  /* COM-1(USB)H */
+
 /*
  * Definitions for B&B Electronics products.
  */
index 89fac36684c56d83caa67e9426c723e3cfb00009..f804acb138ec508f85fe63481b9b6622e084ace1 100644 (file)
@@ -130,7 +130,7 @@ int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port
        spin_unlock_irqrestore(&port->lock, flags);
 
        /* if we have a bulk endpoint, start reading from it */
-       if (serial->num_bulk_in) {
+       if (port->bulk_in_size) {
                /* Start reading from the device */
                usb_fill_bulk_urb(port->read_urb, serial->dev,
                                   usb_rcvbulkpipe(serial->dev,
@@ -159,10 +159,10 @@ static void generic_cleanup(struct usb_serial_port *port)
        dbg("%s - port %d", __func__, port->number);
 
        if (serial->dev) {
-               /* shutdown any bulk reads that might be going on */
-               if (serial->num_bulk_out)
+               /* shutdown any bulk transfers that might be going on */
+               if (port->bulk_out_size)
                        usb_kill_urb(port->write_urb);
-               if (serial->num_bulk_in)
+               if (port->bulk_in_size)
                        usb_kill_urb(port->read_urb);
        }
 }
@@ -333,15 +333,15 @@ int usb_serial_generic_write(struct tty_struct *tty,
 
        dbg("%s - port %d", __func__, port->number);
 
+       /* only do something if we have a bulk out endpoint */
+       if (!port->bulk_out_size)
+               return -ENODEV;
+
        if (count == 0) {
                dbg("%s - write request of 0 bytes", __func__);
                return 0;
        }
 
-       /* only do something if we have a bulk out endpoint */
-       if (!serial->num_bulk_out)
-               return 0;
-
        if (serial->type->max_in_flight_urbs)
                return usb_serial_multi_urb_write(tty, port,
                                                  buf, count);
@@ -364,14 +364,19 @@ int usb_serial_generic_write_room(struct tty_struct *tty)
        int room = 0;
 
        dbg("%s - port %d", __func__, port->number);
+
+       if (!port->bulk_out_size)
+               return 0;
+
        spin_lock_irqsave(&port->lock, flags);
        if (serial->type->max_in_flight_urbs) {
                if (port->urbs_in_flight < serial->type->max_in_flight_urbs)
                        room = port->bulk_out_size *
                                (serial->type->max_in_flight_urbs -
                                 port->urbs_in_flight);
-       } else if (serial->num_bulk_out)
+       } else {
                room = kfifo_avail(&port->write_fifo);
+       }
        spin_unlock_irqrestore(&port->lock, flags);
 
        dbg("%s - returns %d", __func__, room);
@@ -382,15 +387,18 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
 {
        struct usb_serial_port *port = tty->driver_data;
        struct usb_serial *serial = port->serial;
-       int chars = 0;
        unsigned long flags;
+       int chars;
 
        dbg("%s - port %d", __func__, port->number);
 
+       if (!port->bulk_out_size)
+               return 0;
+
        spin_lock_irqsave(&port->lock, flags);
        if (serial->type->max_in_flight_urbs)
                chars = port->tx_bytes_flight;
-       else if (serial->num_bulk_out)
+       else
                chars = kfifo_len(&port->write_fifo);
        spin_unlock_irqrestore(&port->lock, flags);
 
@@ -415,11 +423,13 @@ void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port,
                           ((serial->type->read_bulk_callback) ?
                             serial->type->read_bulk_callback :
                             usb_serial_generic_read_bulk_callback), port);
+
        result = usb_submit_urb(urb, mem_flags);
-       if (result)
+       if (result && result != -EPERM) {
                dev_err(&port->dev,
                        "%s - failed resubmitting read urb, error %d\n",
                                                        __func__, result);
+       }
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_resubmit_read_urb);
 
@@ -498,23 +508,18 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb)
                if (port->urbs_in_flight < 0)
                        port->urbs_in_flight = 0;
                spin_unlock_irqrestore(&port->lock, flags);
-
-               if (status) {
-                       dbg("%s - nonzero multi-urb write bulk status "
-                               "received: %d", __func__, status);
-                       return;
-               }
        } else {
                port->write_urb_busy = 0;
 
-               if (status) {
-                       dbg("%s - nonzero multi-urb write bulk status "
-                               "received: %d", __func__, status);
+               if (status)
                        kfifo_reset_out(&port->write_fifo);
-               else
+               else
                        usb_serial_generic_write_start(port);
        }
 
+       if (status)
+               dbg("%s - non-zero urb status: %d", __func__, status);
+
        usb_serial_port_softint(port);
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
index 04a6cbbed2c0f1de6837d9b3d611a3f543e18e97..a6b207c84917425db5f4c9ea1a1da075a6798002 100644 (file)
@@ -12,6 +12,7 @@
  *     flags as the navman is rx only so cannot echo.
  */
 
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/tty.h>
index 701452ae91979a23129d24d656a5e4a2df7b8946..ed01f3b2de8c037675667cedabf19040fa81c876 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
+#include <linux/slab.h>
 #include <linux/tty_flip.h>
 #include <linux/serial.h>
 #include <linux/module.h>
index 847b805d63a3b7444b554462efb4c78dc4581fba..84d0edad8e4f91aad7078c1a98c1809cd69da463 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/errno.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/usb.h>
@@ -288,7 +289,9 @@ static int  option_resume(struct usb_serial *serial);
 
 #define QUALCOMM_VENDOR_ID                     0x05C6
 
-#define MAXON_VENDOR_ID                                0x16d8
+#define CMOTECH_VENDOR_ID                      0x16d8
+#define CMOTECH_PRODUCT_6008                   0x6008
+#define CMOTECH_PRODUCT_6280                   0x6280
 
 #define TELIT_VENDOR_ID                                0x1bc7
 #define TELIT_PRODUCT_UC864E                   0x1003
@@ -302,6 +305,11 @@ static int  option_resume(struct usb_serial *serial);
 #define ZTE_PRODUCT_CDMA_TECH                  0xfffe
 #define ZTE_PRODUCT_AC8710                     0xfff1
 #define ZTE_PRODUCT_AC2726                     0xfff5
+#define ZTE_PRODUCT_AC8710T                    0xffff
+
+/* ZTE PRODUCTS -- alternate vendor ID */
+#define ZTE_VENDOR_ID2                         0x1d6b
+#define ZTE_PRODUCT_MF_330                     0x0002
 
 #define BENQ_VENDOR_ID                         0x04a5
 #define BENQ_PRODUCT_H10                       0x4068
@@ -309,6 +317,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 DLINK_PRODUCT_DWM_652_U5A              0xce1e
 
 #define QISDA_VENDOR_ID                                0x1da5
 #define QISDA_PRODUCT_H21_4512                 0x4512
@@ -332,6 +341,24 @@ static int  option_resume(struct usb_serial *serial);
 #define ALCATEL_VENDOR_ID                      0x1bbb
 #define ALCATEL_PRODUCT_X060S                  0x0000
 
+#define PIRELLI_VENDOR_ID                      0x1266
+#define PIRELLI_PRODUCT_C100_1                 0x1002
+#define PIRELLI_PRODUCT_C100_2                 0x1003
+#define PIRELLI_PRODUCT_1004                   0x1004
+#define PIRELLI_PRODUCT_1005                   0x1005
+#define PIRELLI_PRODUCT_1006                   0x1006
+#define PIRELLI_PRODUCT_1007                   0x1007
+#define PIRELLI_PRODUCT_1008                   0x1008
+#define PIRELLI_PRODUCT_1009                   0x1009
+#define PIRELLI_PRODUCT_100A                   0x100a
+#define PIRELLI_PRODUCT_100B                   0x100b
+#define PIRELLI_PRODUCT_100C                   0x100c
+#define PIRELLI_PRODUCT_100D                   0x100d
+#define PIRELLI_PRODUCT_100E                   0x100e
+#define PIRELLI_PRODUCT_100F                   0x100f
+#define PIRELLI_PRODUCT_1011                   0x1011
+#define PIRELLI_PRODUCT_1012                   0x1012
+
 /* Airplus products */
 #define AIRPLUS_VENDOR_ID                      0x1011
 #define AIRPLUS_PRODUCT_MCD650                 0x3198
@@ -351,6 +378,8 @@ static int  option_resume(struct usb_serial *serial);
 #define HAIER_VENDOR_ID                                0x201e
 #define HAIER_PRODUCT_CE100                    0x2009
 
+#define CINTERION_VENDOR_ID                    0x0681
+
 /* some devices interfaces need special handling due to a number of reasons */
 enum option_blacklist_reason {
                OPTION_BLACKLIST_NONE = 0,
@@ -547,7 +576,8 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
-       { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) },
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
@@ -656,9 +686,12 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) },
+       { USB_DEVICE(ZTE_VENDOR_ID2, ZTE_PRODUCT_MF_330) },
        { 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(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5A) },
        { 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) },
@@ -666,7 +699,6 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) },
        { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */
        { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
-       { USB_DEVICE(ALINK_VENDOR_ID, 0xce16) },
        { 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) },
@@ -675,6 +707,25 @@ static const struct usb_device_id option_ids[] = {
          .driver_info = (kernel_ulong_t)&four_g_w14_blacklist
        },
        { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) },
+       /* Pirelli  */
+       { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1)},
+       { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_2)},
+       { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1004)},
+       { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1005)},
+       { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1006)},
+       { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1007)},
+       { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1008)},
+       { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1009)},
+       { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100A)},
+       { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100B) },
+       { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100C) },
+       { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100D) },
+       { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100E) },
+       { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) },
+       { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)},
+       { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)},
+
+       { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) },
        { } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
@@ -798,12 +849,19 @@ static int option_probe(struct usb_serial *serial,
                        const struct usb_device_id *id)
 {
        struct option_intf_private *data;
+
        /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */
        if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID &&
                serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 &&
                serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8)
                return -ENODEV;
 
+       /* Bandrich modem and AT command interface is 0xff */
+       if ((serial->dev->descriptor.idVendor == BANDRICH_VENDOR_ID ||
+               serial->dev->descriptor.idVendor == PIRELLI_VENDOR_ID) &&
+               serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff)
+               return -ENODEV;
+
        data = serial->private = kzalloc(sizeof(struct option_intf_private), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
index 73d5f346d3e07659ad585f89f1c3b93b97d6aba9..c28b1607eacc961973e2eb054742765eeacfcfdd 100644 (file)
@@ -59,6 +59,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) },
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) },
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) },
+       { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) },
        { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
        { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
        { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
@@ -97,6 +98,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
        { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
        { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
+       { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
        { }                                     /* Terminating entry */
 };
 
index d640dc951568dc705c3d7c2ae22ea7321d9afe11..23c09b38b9ec124240c40366f8166bc907a40f7b 100644 (file)
@@ -20,6 +20,7 @@
 #define PL2303_PRODUCT_ID_ALDIGA       0x0611
 #define PL2303_PRODUCT_ID_MMX          0x0612
 #define PL2303_PRODUCT_ID_GPRS         0x0609
+#define PL2303_PRODUCT_ID_HCR331       0x331a
 
 #define ATEN_VENDOR_ID         0x0557
 #define ATEN_VENDOR_ID2                0x0547
 /* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */
 #define SANWA_VENDOR_ID                0x11ad
 #define SANWA_PRODUCT_ID       0x0001
+
+/* ADLINK ND-6530 RS232,RS485 and RS422 adapter */
+#define ADLINK_VENDOR_ID        0x0b63
+#define ADLINK_ND6530_PRODUCT_ID       0x6530
index 0b93620617138d11ff467c242c609ca78e1efffb..7e3bea23600b91ecccbc2fa3e284ca50cd9ce8d2 100644 (file)
 #define CMOTECH_PRODUCT_CDU550                 0x5553
 #define CMOTECH_PRODUCT_CDX650                 0x6512
 
+/* LG devices */
+#define LG_VENDOR_ID                           0x1004
+#define LG_PRODUCT_VX4400_6000                 0x6000 /* VX4400/VX6000/Rumor */
+
+/* Sanyo devices */
+#define SANYO_VENDOR_ID                                0x0474
+#define SANYO_PRODUCT_KATANA_LX                        0x0754 /* SCP-3800 (Katana LX) */
+
 static struct usb_device_id id_table[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5740, 0xff, 0x00, 0x00) },
        { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5750, 0xff, 0x00, 0x00) },
@@ -51,6 +59,8 @@ static struct usb_device_id id_table[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM175_ALLTEL, 0xff, 0x00, 0x00) },
        { USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU550, 0xff, 0xff, 0x00) },
        { USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDX650, 0xff, 0xff, 0x00) },
+       { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) },
+       { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) },
        { },
 };
 MODULE_DEVICE_TABLE(usb, id_table);
index 310ff6ec65678d1c38da316cfdb4fe8a06936c52..53a2d5a935a24505bead07eaeec3da5a01566ed8 100644 (file)
@@ -47,6 +47,35 @@ static const struct usb_device_id id_table[] = {
        {USB_DEVICE(0x05c6, 0x9221)},   /* Generic Gobi QDL device */
        {USB_DEVICE(0x05c6, 0x9231)},   /* Generic Gobi QDL device */
        {USB_DEVICE(0x1f45, 0x0001)},   /* Unknown Gobi QDL device */
+       {USB_DEVICE(0x413c, 0x8185)},   /* Dell Gobi 2000 QDL device (N0218, VU936) */
+       {USB_DEVICE(0x413c, 0x8186)},   /* Dell Gobi 2000 Modem device (N0218, VU936) */
+       {USB_DEVICE(0x05c6, 0x9224)},   /* Sony Gobi 2000 QDL device (N0279, VU730) */
+       {USB_DEVICE(0x05c6, 0x9225)},   /* Sony Gobi 2000 Modem device (N0279, VU730) */
+       {USB_DEVICE(0x05c6, 0x9244)},   /* Samsung Gobi 2000 QDL device (VL176) */
+       {USB_DEVICE(0x05c6, 0x9245)},   /* Samsung Gobi 2000 Modem device (VL176) */
+       {USB_DEVICE(0x03f0, 0x241d)},   /* HP Gobi 2000 QDL device (VP412) */
+       {USB_DEVICE(0x03f0, 0x251d)},   /* HP Gobi 2000 Modem device (VP412) */
+       {USB_DEVICE(0x05c6, 0x9214)},   /* Acer Gobi 2000 QDL device (VP413) */
+       {USB_DEVICE(0x05c6, 0x9215)},   /* Acer Gobi 2000 Modem device (VP413) */
+       {USB_DEVICE(0x05c6, 0x9264)},   /* Asus Gobi 2000 QDL device (VR305) */
+       {USB_DEVICE(0x05c6, 0x9265)},   /* Asus Gobi 2000 Modem device (VR305) */
+       {USB_DEVICE(0x05c6, 0x9234)},   /* Top Global Gobi 2000 QDL device (VR306) */
+       {USB_DEVICE(0x05c6, 0x9235)},   /* Top Global Gobi 2000 Modem device (VR306) */
+       {USB_DEVICE(0x05c6, 0x9274)},   /* iRex Technologies Gobi 2000 QDL device (VR307) */
+       {USB_DEVICE(0x05c6, 0x9275)},   /* iRex Technologies Gobi 2000 Modem device (VR307) */
+       {USB_DEVICE(0x1199, 0x9000)},   /* Sierra Wireless Gobi 2000 QDL device (VT773) */
+       {USB_DEVICE(0x1199, 0x9001)},   /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+       {USB_DEVICE(0x1199, 0x9002)},   /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+       {USB_DEVICE(0x1199, 0x9003)},   /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+       {USB_DEVICE(0x1199, 0x9004)},   /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+       {USB_DEVICE(0x1199, 0x9005)},   /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+       {USB_DEVICE(0x1199, 0x9006)},   /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+       {USB_DEVICE(0x1199, 0x9007)},   /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+       {USB_DEVICE(0x1199, 0x9008)},   /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+       {USB_DEVICE(0x1199, 0x9009)},   /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+       {USB_DEVICE(0x1199, 0x900a)},   /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+       {USB_DEVICE(0x16d8, 0x8001)},   /* CMDTech Gobi 2000 QDL device (VU922) */
+       {USB_DEVICE(0x16d8, 0x8002)},   /* CMDTech Gobi 2000 Modem device (VU922) */
        { }                             /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, id_table);
index 4b463cd140ef6436b392a8a5255c6c6cf5d523b5..43a0cadd5782361e0f4753c1ce586c184c7a0bb9 100644 (file)
@@ -64,8 +64,8 @@
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
index 34e6f894cba9c422769c4607d49d2fd8081b7747..ef0bdb08d7887b17c7a6a17bc933be7aa0680175 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/jiffies.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
+#include <linux/slab.h>
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/usb.h>
@@ -229,6 +230,7 @@ static const struct sierra_iface_info direct_ip_interface_blacklist = {
 static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
        { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */
+       { USB_DEVICE(0x03F0, 0x211D) }, /* HP ev2210 a.k.a MC5725 */
        { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */
 
        { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
index ee190cc1757ce84dd0b78114fb9ca190b1c7e9e1..d9457bd4fe10a925423b9f3f1d3b5670e5ac5822 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/tty.h>
+#include <linux/slab.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
 #include <linux/module.h>
index 0afe5c71c17e6e4c687c3b2f5ac816857146087f..e1bfda33f5b9a16131d5866f665941e36ddf2230 100644 (file)
@@ -172,7 +172,7 @@ static unsigned int product_5052_count;
 /* the array dimension is the number of default entries plus */
 /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
 /* null entry */
-static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_3410[13+TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
        { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -180,6 +180,9 @@ static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) },
        { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) },
        { USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234MU_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBA_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBAOLD_PRODUCT_ID) },
        { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
        { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
        { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
@@ -192,7 +195,7 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
 };
 
-static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_combined[17+2*TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
        { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -200,6 +203,9 @@ static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1]
        { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) },
        { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) },
        { USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234MU_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBA_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBAOLD_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
@@ -287,6 +293,8 @@ MODULE_FIRMWARE("ti_5052.fw");
 MODULE_FIRMWARE("mts_cdma.fw");
 MODULE_FIRMWARE("mts_gsm.fw");
 MODULE_FIRMWARE("mts_edge.fw");
+MODULE_FIRMWARE("mts_mt9234mu.fw");
+MODULE_FIRMWARE("mts_mt9234zba.fw");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes");
@@ -1687,6 +1695,7 @@ static int ti_download_firmware(struct ti_device *tdev)
        const struct firmware *fw_p;
        char buf[32];
 
+       dbg("%s\n", __func__);
        /* try ID specific firmware first, then try generic firmware */
        sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor,
            dev->descriptor.idProduct);
@@ -1703,7 +1712,15 @@ static int ti_download_firmware(struct ti_device *tdev)
                        case MTS_EDGE_PRODUCT_ID:
                                strcpy(buf, "mts_edge.fw");
                                break;
-                       }
+                       case MTS_MT9234MU_PRODUCT_ID:
+                               strcpy(buf, "mts_mt9234mu.fw");
+                               break;
+                       case MTS_MT9234ZBA_PRODUCT_ID:
+                               strcpy(buf, "mts_mt9234zba.fw");
+                               break;
+                       case MTS_MT9234ZBAOLD_PRODUCT_ID:
+                               strcpy(buf, "mts_mt9234zba.fw");
+                               break;                  }
                }
                if (buf[0] == '\0') {
                        if (tdev->td_is_3410)
@@ -1718,7 +1735,7 @@ static int ti_download_firmware(struct ti_device *tdev)
                return -ENOENT;
        }
        if (fw_p->size > TI_FIRMWARE_BUF_SIZE) {
-               dev_err(&dev->dev, "%s - firmware too large\n", __func__);
+               dev_err(&dev->dev, "%s - firmware too large %zu\n", __func__, fw_p->size);
                return -ENOENT;
        }
 
@@ -1730,6 +1747,7 @@ static int ti_download_firmware(struct ti_device *tdev)
                status = ti_do_download(dev, pipe, buffer, fw_p->size);
                kfree(buffer);
        } else {
+               dbg("%s ENOMEM\n", __func__);
                status = -ENOMEM;
        }
        release_firmware(fw_p);
index f323c6025858f6e831dd77e953d173b942d8c2ae..2aac1953993b1c9508283a8ecfef303c9fa26f1e 100644 (file)
@@ -45,6 +45,9 @@
 #define MTS_CDMA_PRODUCT_ID            0xF110
 #define MTS_GSM_PRODUCT_ID             0xF111
 #define MTS_EDGE_PRODUCT_ID            0xF112
+#define MTS_MT9234MU_PRODUCT_ID                0xF114
+#define MTS_MT9234ZBA_PRODUCT_ID       0xF115
+#define MTS_MT9234ZBAOLD_PRODUCT_ID    0x0319
 
 /* Commands */
 #define TI_GET_VERSION                 0x01
index 252cc2d993b2992b7bbb7480f76c3760800322f3..28026b47344a2bee655a776f5cd5b72a79dede08 100644 (file)
@@ -8,6 +8,7 @@
  *     2 as published by the Free Software Foundation.
  */
 
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/tty.h>
index 67edc65acb8efc69e8a214fd032aa4da7c6eebaf..42d0eaed4a0133282678792d9d74bd7ebc4045a7 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index 7953d93a7739bd6ac5d89902a7f257e3c8d3c37d..ba1b789068802c138549e96542fa18a7dac8952d 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index 773a5cd38c5aa7773f5b7f1837351a8945b3f084..89460181d122759ba00ff064b49b2ff3c8b28268 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 #include "usb.h"
 #include "transport.h"
index 4cc035562cc2e0669e588d4a376ad9bf1c25b032..d8d98cfecadad457ddde6393730af86f097d39d4 100644 (file)
@@ -43,7 +43,6 @@
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 
index 4395c4100ec2096313933d029e8b25191eefe6c9..57fc2f532cabe985b9b10fdd57c7042b6d0fd4be 100644 (file)
@@ -3,6 +3,7 @@
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 #include "usb.h"
 #include "transport.h"
index 468038126e5eb00ba5180585a8923575103be9d0..f253edec3bb827c29a0d90173fd7cafa18173b00 100644 (file)
@@ -44,8 +44,8 @@
  */
 
 #include <linux/sched.h>
+#include <linux/gfp.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 
 #include <linux/usb/quirks.h>
 
index 98b549b1cab25f0799c8846aaa43edc98e4c8cc7..ccf1dbbb87efd60e930a4d9a4fdfc62a80759fae 100644 (file)
@@ -374,6 +374,15 @@ UNUSUAL_DEV(  0x04ce, 0x0002, 0x0074, 0x0074,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_INQUIRY),
 
+/* Reported by Ondrej Zary <linux@rainbow-software.org>
+ * The device reports one sector more and breaks when that sector is accessed
+ */
+UNUSUAL_DEV(  0x04ce, 0x0002, 0x026c, 0x026c,
+               "ScanLogic",
+               "SL11R-IDE",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_CAPACITY),
+
 /* Reported by Kriston Fincher <kriston@airmail.net>
  * Patch submitted by Sean Millichamp <sean@bruenor.org>
  * This is to support the Panasonic PalmCam PV-SD4090
@@ -1380,20 +1389,6 @@ UNUSUAL_DEV(  0x0f19, 0x0105, 0x0100, 0x0100,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_IGNORE_RESIDUE ),
 
-/* Jeremy Katz <katzj@redhat.com>:
- * The Blackberry Pearl can run in two modes; a usb-storage only mode
- * and a mode that allows access via mass storage and to its database.
- * The berry_charge module will set the device to dual mode and thus we
- * should ignore its native mode if that module is built
- */
-#ifdef CONFIG_USB_BERRY_CHARGE
-UNUSUAL_DEV(  0x0fca, 0x0006, 0x0001, 0x0001,
-               "RIM",
-               "Blackberry Pearl",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_IGNORE_DEVICE ),
-#endif
-
 /* Reported by Michael Stattmann <michael@stattmann.com> */
 UNUSUAL_DEV(  0x0fce, 0xd008, 0x0000, 0x0000,
                "Sony Ericsson",
index 51a8e0d5789d0da9654e13dca6e6ab53290d51cc..c0c5665e60a917de8ca6680164bfd598b0d4f83c 100644 (file)
@@ -92,6 +92,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/uwb.h>
 #include <linux/usb/wusb.h>
index 9579cf4c38bf6717c56e3677938e6afb19f022b9..827c87f10cc5a80c06f84afd38d7d66b7249f0d6 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/module.h>
 #include <linux/err.h>
 #include <linux/uwb.h>
+#include <linux/slab.h>
 #include <linux/usb/wusb.h>
 #include <linux/scatterlist.h>
 
index 1c918286159cd683f71916c891ba9cd7d6f5753e..7ec24e46b34bef5269b220b71b8382eaa9140c16 100644 (file)
@@ -88,6 +88,7 @@
 
 #include <linux/jiffies.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include "wusbhc.h"
 
@@ -437,7 +438,7 @@ static void __wusbhc_keep_alive(struct wusbhc *wusbhc)
        old_keep_alives = ie->hdr.bLength - sizeof(ie->hdr);
        keep_alives = 0;
        for (cnt = 0;
-            keep_alives <= WUIE_ELT_MAX && cnt < wusbhc->ports_max;
+            keep_alives < WUIE_ELT_MAX && cnt < wusbhc->ports_max;
             cnt++) {
                unsigned tt = msecs_to_jiffies(wusbhc->trust_timeout);
 
index 2d827397e30b2dbddd121342a8899d9e028b0867..0a57ff0a0b0c6df4b802f5ff5316ceb77ae7a2a1 100644 (file)
@@ -37,6 +37,7 @@
  *  - add timers that autoremove intervalled IEs?
  */
 #include <linux/usb/wusb.h>
+#include <linux/slab.h>
 #include "wusbhc.h"
 
 /* Initialize the MMCIEs handling mechanism */
index 9fe4246cecb98d5bb5fa2cb77ca23bd3bae90c9e..a68ad7aa0b592948e0c5168435b609d174231ea1 100644 (file)
@@ -69,6 +69,7 @@
  *
  * wusbhc_rh_start_port_reset() ??? unimplemented
  */
+#include <linux/slab.h>
 #include "wusbhc.h"
 
 /*
index edcd2d7560378f1681f8c2ec74dc042a4e0815f6..b60799b811c144e5513e9e201f2f6fb38b5a709b 100644 (file)
@@ -23,6 +23,7 @@
  * FIXME: docs
  */
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/usb/ch9.h>
 #include <linux/random.h>
 #include "wusbhc.h"
index 9d04722415bb5bbf8f14bc63e903f165720635dd..59a748a0e5dae07cbaa1ae5107654b9666712156 100644 (file)
@@ -22,6 +22,7 @@
  *
  * FIXME: docs
  */
+#include <linux/slab.h>
 #include "wusbhc.h"
 #include "wa-hc.h"
 
index 17d2626038be6ab1ef085c820f88eb8d4ff14647..f67f7f1e6df9502680868d2bfa5e0493df0cf36d 100644 (file)
@@ -51,6 +51,7 @@
  */
 #include <linux/workqueue.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 
 #include "wa-hc.h"
 #include "wusbhc.h"
index 7369655f69cdc9722f0aa281e3803748e13fa2dc..c7b1d8108de94338ea610f1286134a74fe13f593 100644 (file)
@@ -60,6 +60,7 @@
 #include <linux/init.h>
 #include <asm/atomic.h>
 #include <linux/bitmap.h>
+#include <linux/slab.h>
 
 #include "wusbhc.h"
 #include "wa-hc.h"
index 489b47833e2c54ff7f1b225c35f1a51283ef2494..112ef7e26f6bf69af4f32c78d4255b68af2e554a 100644 (file)
@@ -81,6 +81,7 @@
  */
 #include <linux/init.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/hash.h>
 
 #include "wa-hc.h"
index ad21b1d7218cb327be2e4d4ab22d861f8f023130..973321327c44b897ae3ae14eb95f2d33b784732f 100644 (file)
@@ -23,6 +23,7 @@
  * FIXME: docs
  */
 
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/device.h>
index c13cec7dcbc5ee6cdfa6a6ee0ff29280de910ce3..436e4f7110cbddc41cda3d4677fdb2eca6c0ab17 100644 (file)
@@ -16,6 +16,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/uwb.h>
 
 #include "uwb-internal.h"
index 36bc3158006f5e21012e0d79af888ff27605c99b..dcdd59bfcd09cff5e7cc0d9235af3850dad287e5 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/kdev_t.h>
+#include <linux/slab.h>
 
 #include "uwb-internal.h"
 
index 2840d7bf9e67eff12c9b743c04eb01c0120763cd..520673109a7ea7a63627cc3f697ea419b6d355f6 100644 (file)
@@ -18,6 +18,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <linux/uwb.h>
 
 #include "uwb-internal.h"
index 4f5ca99a04b9de20c513b015e84e7b6d0ad972e3..a8d83e25e3b66e21bb3ac48f2548b9334dbaf8ee 100644 (file)
@@ -20,6 +20,7 @@
  */
 #include <linux/kthread.h>
 #include <linux/freezer.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include "uwb-internal.h"
 
index 328fcc2b60990af30a56eb35896b0a3db322bae8..a2eaa3c33b0b2b90a870bf775aeb274213eacc47 100644 (file)
@@ -40,6 +40,7 @@
  *   uwb_est_get_size()
  */
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 
 #include "uwb-internal.h"
 
index e7eeb63fab23a11632a1b94176def00e28bc9d27..2babcd4fbfc13b6bebd4238444925eca6f99e401 100644 (file)
@@ -53,6 +53,7 @@
  */
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/wusb.h>
 #include <linux/usb/wusb-wa.h>
@@ -891,7 +892,7 @@ static int hwarc_post_reset(struct usb_interface *iface)
 }
 
 /** USB device ID's that we handle */
-static struct usb_device_id hwarc_id_table[] = {
+static const struct usb_device_id hwarc_id_table[] = {
        /* D-Link DUB-1210 */
        { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3d02, 0xe0, 0x01, 0x02),
          .driver_info = WUSB_QUIRK_WHCI_CMD_EVT },
index 694d0daf88aba1594bcc0d259e01fc4e89e6f137..6ec14f5fcde47f951fd8b1092f82deb0940fdeeb 100644 (file)
@@ -28,6 +28,7 @@
  */
 #include <linux/delay.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <linux/uwb.h>
 #include "i1480-dfu.h"
 
index 0bb665a0c02454e41745d55a129c35bb65f40b84..ba8664328afa965ab63d5b2ee305a517fa0ed9a2 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/uwb.h>
 #include <linux/usb/wusb.h>
@@ -120,8 +121,7 @@ int i1480_usb_write(struct i1480 *i1480, u32 memory_address,
                result = usb_control_msg(
                        i1480_usb->usb_dev, usb_sndctrlpipe(i1480_usb->usb_dev, 0),
                        0xf0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-                       cpu_to_le16(memory_address & 0xffff),
-                       cpu_to_le16((memory_address >> 16) & 0xffff),
+                       memory_address, (memory_address >> 16),
                        i1480->cmd_buf, buffer_size, 100 /* FIXME: arbitrary */);
                if (result < 0)
                        break;
@@ -166,8 +166,7 @@ int i1480_usb_read(struct i1480 *i1480, u32 addr, size_t size)
                result = usb_control_msg(
                        i1480_usb->usb_dev, usb_rcvctrlpipe(i1480_usb->usb_dev, 0),
                        0xf0, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-                       cpu_to_le16(itr_addr & 0xffff),
-                       cpu_to_le16((itr_addr >> 16) & 0xffff),
+                       itr_addr, (itr_addr >> 16),
                        i1480->cmd_buf + itr, itr_size,
                        100 /* FIXME: arbitrary */);
                if (result < 0) {
@@ -413,6 +412,10 @@ error:
        return result;
 }
 
+MODULE_FIRMWARE("i1480-pre-phy-0.0.bin");
+MODULE_FIRMWARE("i1480-usb-0.0.bin");
+MODULE_FIRMWARE("i1480-phy-0.0.bin");
+
 #define i1480_USB_DEV(v, p)                            \
 {                                                      \
        .match_flags = USB_DEVICE_ID_MATCH_DEVICE       \
@@ -430,7 +433,7 @@ error:
 
 
 /** USB device ID's that we handle */
-static struct usb_device_id i1480_usb_id_table[] = {
+static const struct usb_device_id i1480_usb_id_table[] = {
        i1480_USB_DEV(0x8086, 0xdf3b),
        i1480_USB_DEV(0x15a9, 0x0005),
        i1480_USB_DEV(0x07d1, 0x3802),
index f272dfe54d491ed75dc0a0a8d0b3e3450f6f7e32..def778cf221690846df58dafe75794aaded7184a 100644 (file)
@@ -55,6 +55,7 @@
  *                          is being removed.
  *         i1480u_rm()
  */
+#include <linux/gfp.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 
index b236e6969942f29b4031095e000e2ed4d6d287b0..f98f6ce8b9e7372f0605ab06aaea752fc0f81f8b 100644 (file)
@@ -39,6 +39,7 @@
  *     i1480u_set_config():
  */
 
+#include <linux/slab.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 
index 25a2758beb61d2d078d51de5847e30d92dd42c82..d4e51e108aa4aa52d5dc015430575f9920bba535 100644 (file)
@@ -64,6 +64,7 @@
  *
  */
 
+#include <linux/gfp.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include "i1480u-wlp.h"
index 3db3449dbda46962171f71acdf3ebca250a4d860..3c117a3645642e142c9e251910233f12e8ea9c6a 100644 (file)
@@ -54,6 +54,7 @@
  *          the times the MTU will be smaller than one page...
  */
 
+#include <linux/slab.h>
 #include "i1480u-wlp.h"
 
 enum {
index ab976686175be5694589192636d69d685979b90c..30acec740425e48ea48c1e11d32028bbd837d710 100644 (file)
@@ -24,6 +24,7 @@
  * FIXME: docs
  */
 
+#include <linux/slab.h>
 #include "uwb-internal.h"
 
 /**
index 1097e81b56d01029f9ec8aac68fdb262c9874ed9..90113bafefca8dafbd4aa210fc2ef81887238cae 100644 (file)
@@ -23,6 +23,7 @@
  * FIXME: docs
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/kdev_t.h>
index 9611ef3b787a39c3de7b295c39d99a7e376a2afe..b0091c771b9a2d3c8d29fd782000df41cc777c31 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/kdev_t.h>
 #include <linux/etherdevice.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 #include "uwb-internal.h"
 
index 78510a1f410d793350d5b3a1efe55247bf0f8029..697e56a5bcdd0c7e4233774ce2670b70ae8a9373 100644 (file)
@@ -83,6 +83,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 
 #include "uwb-internal.h"
index 7f0512e43d9dea10c5005e298ac0902c32ae0c70..27849292b552aab93c7ac3be1eae6650607a1d1a 100644 (file)
@@ -30,6 +30,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 
 #include "uwb-internal.h"
index 6b76f4bb4cc7dc5a25da658c0cc2d006ba3662f0..78c892233cf1d9acb2eac33e87b5e41f8a3bb79e 100644 (file)
@@ -17,6 +17,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/uwb.h>
+#include <linux/slab.h>
 #include <linux/random.h>
 
 #include "uwb-internal.h"
index 2d270748f32be0fdf4eda5e12f36a1031fe6a5e3..76a1a1ed7d3ec1e5831ca1d8024367e676cac266 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include "uwb-internal.h"
 
 
index 1fc7d8270bb83054198f141fd8b6ec6911411b52..43ea9982e68776a37c80f33ff19e2624fbec546d 100644 (file)
@@ -6,6 +6,7 @@
  * This file is released under the GNU GPL v2.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/uwb/umc.h>
 
 static void umc_device_release(struct device *dev)
index 6210fe1fd1bbfb64b9015a03da8dbb37a5a2b753..001c8b4020a84c7073f2fc99489bf9047571e086 100644 (file)
@@ -69,6 +69,7 @@
  * Handler functions are called normally uwbd_evt_handle_*().
  */
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/freezer.h>
 
index 01950c62dc8dd4ca58e1e4e0700f5e9b51771dc7..73495583c4444bba046779115b56c905e2c0c424 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/sched.h>
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/uwb.h>
 #include <linux/uwb/whci.h>
index 2e2784627ad66cf8502361fa59c2ad029e138d82..b221142446a29d5690d332628389cd763856fa32 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <linux/uwb/whci.h>
 #include <linux/uwb/umc.h>
 
index 69e020039718aed4711849b0b9fee3c80dfea866..086fc0cf94019f657757af6ba959b39afeb07d64 100644 (file)
@@ -53,6 +53,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <linux/wlp.h>
 #include "wlp-internal.h"
 
index aa42fcee4c4f8e052a2e25b24d1c8aaa75a3ac9a..3a8e033dce21c7a88d68f77e224b43b2423c9c17 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include <linux/wlp.h>
+#include <linux/slab.h>
 
 #include "wlp-internal.h"
 
@@ -259,6 +260,63 @@ out:
 }
 
 
+static ssize_t wlp_get_attribute(struct wlp *wlp, u16 type_code,
+       struct wlp_attr_hdr *attr_hdr, void *value, ssize_t value_len,
+       ssize_t buflen)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       ssize_t attr_len = sizeof(*attr_hdr) + value_len;
+       if (buflen < 0)
+               return -EINVAL;
+       if (buflen < attr_len) {
+               dev_err(dev, "WLP: Not enough space in buffer to parse"
+                       " attribute field. Need %d, received %zu\n",
+                       (int)attr_len, buflen);
+               return -EIO;
+       }
+       if (wlp_check_attr_hdr(wlp, attr_hdr, type_code, value_len) < 0) {
+               dev_err(dev, "WLP: Header verification failed. \n");
+               return -EINVAL;
+       }
+       memcpy(value, (void *)attr_hdr + sizeof(*attr_hdr), value_len);
+       return attr_len;
+}
+
+static ssize_t wlp_vget_attribute(struct wlp *wlp, u16 type_code,
+       struct wlp_attr_hdr *attr_hdr, void *value, ssize_t max_value_len,
+       ssize_t buflen)
+{
+       struct device *dev = &wlp->rc->uwb_dev.dev;
+       size_t len;
+       if (buflen < 0)
+               return -EINVAL;
+       if (buflen < sizeof(*attr_hdr)) {
+               dev_err(dev, "WLP: Not enough space in buffer to parse"
+                       " header.\n");
+               return -EIO;
+       }
+       if (le16_to_cpu(attr_hdr->type) != type_code) {
+               dev_err(dev, "WLP: Unexpected attribute type. Got %u, "
+                       "expected %u.\n", le16_to_cpu(attr_hdr->type),
+                       type_code);
+               return -EINVAL;
+       }
+       len = le16_to_cpu(attr_hdr->length);
+       if (len > max_value_len) {
+               dev_err(dev, "WLP: Attribute larger than maximum "
+                       "allowed. Received %zu, max is %d.\n", len,
+                       (int)max_value_len);
+               return -EFBIG;
+       }
+       if (buflen < sizeof(*attr_hdr) + len) {
+               dev_err(dev, "WLP: Not enough space in buffer to parse "
+                       "variable data.\n");
+               return -EIO;
+       }
+       memcpy(value, (void *)attr_hdr + sizeof(*attr_hdr), len);
+       return sizeof(*attr_hdr) + len;
+}
+
 /**
  * Get value of attribute from fixed size attribute field.
  *
@@ -274,22 +332,8 @@ out:
 ssize_t wlp_get_##name(struct wlp *wlp, struct wlp_attr_##name *attr,  \
                      type *value, ssize_t buflen)                      \
 {                                                                      \
-       struct device *dev = &wlp->rc->uwb_dev.dev;                     \
-       if (buflen < 0)                                                 \
-               return -EINVAL;                                         \
-       if (buflen < sizeof(*attr)) {                                   \
-               dev_err(dev, "WLP: Not enough space in buffer to parse" \
-                       " attribute field. Need %d, received %zu\n",    \
-                       (int)sizeof(*attr), buflen);                    \
-               return -EIO;                                            \
-       }                                                               \
-       if (wlp_check_attr_hdr(wlp, &attr->hdr, type_code,              \
-                              sizeof(attr->name)) < 0) {               \
-               dev_err(dev, "WLP: Header verification failed. \n");    \
-               return -EINVAL;                                         \
-       }                                                               \
-       *value = attr->name;                                            \
-       return sizeof(*attr);                                           \
+       return wlp_get_attribute(wlp, (type_code), &attr->hdr,          \
+                                value, sizeof(*value), buflen);        \
 }
 
 #define wlp_get_sparse(type, type_code, name) \
@@ -313,35 +357,8 @@ static ssize_t wlp_get_##name(struct wlp *wlp,                             \
                              struct wlp_attr_##name *attr,             \
                              type_val *value, ssize_t buflen)          \
 {                                                                      \
-       struct device *dev = &wlp->rc->uwb_dev.dev;                     \
-       size_t len;                                                     \
-       if (buflen < 0)                                                 \
-               return -EINVAL;                                         \
-       if (buflen < sizeof(*attr)) {                                   \
-               dev_err(dev, "WLP: Not enough space in buffer to parse" \
-                       " header.\n");                                  \
-               return -EIO;                                            \
-       }                                                               \
-       if (le16_to_cpu(attr->hdr.type) != type_code) {                 \
-               dev_err(dev, "WLP: Unexpected attribute type. Got %u, " \
-                       "expected %u.\n", le16_to_cpu(attr->hdr.type),  \
-                       type_code);                                     \
-               return -EINVAL;                                         \
-       }                                                               \
-       len = le16_to_cpu(attr->hdr.length);                            \
-       if (len > max) {                                                \
-               dev_err(dev, "WLP: Attribute larger than maximum "      \
-                       "allowed. Received %zu, max is %d.\n", len,     \
-                       (int)max);                                      \
-               return -EFBIG;                                          \
-       }                                                               \
-       if (buflen < sizeof(*attr) + len) {                             \
-               dev_err(dev, "WLP: Not enough space in buffer to parse "\
-                       "variable data.\n");                            \
-               return -EIO;                                            \
-       }                                                               \
-       memcpy(value, (void *) attr + sizeof(*attr), len);              \
-       return sizeof(*attr) + len;                                     \
+       return wlp_vget_attribute(wlp, (type_code), &attr->hdr,         \
+                             value, (max), buflen);                    \
 }
 
 wlp_get(u8, WLP_ATTR_WLP_VER, version)
index 7350ed6909f888fb9a974737da561d45586275de..05dde44b35929ebcf1db8c1ba8fe70456a42ade8 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <linux/wlp.h>
 
 #include "wlp-internal.h"
index 13db739c4e397621487b88abbcd7b2c07c93f332..7f6a630bf26c47e4f2a5f13a5478d81f5cdcf346 100644 (file)
@@ -22,6 +22,7 @@
  * FIXME: docs
  */
 #include <linux/wlp.h>
+#include <linux/slab.h>
 
 #include "wlp-internal.h"
 
index 5913c7a5d922ec7749a866bbc276132b6384ef94..90accdd54c07e14877e5018d2491b15b77cfd9e5 100644 (file)
@@ -45,6 +45,7 @@
  */
 #include <linux/etherdevice.h> /* for is_valid_ether_addr */
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/wlp.h>
 
 #include "wlp-internal.h"
index ad37da2b6cb5bba78ac91664d93088f7ec2fb59c..9777583218ff9fa4abaa7be5896de223b92f77ab 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/workqueue.h>
 #include <linux/rcupdate.h>
 #include <linux/file.h>
+#include <linux/slab.h>
 
 #include <linux/net.h>
 #include <linux/if_packet.h>
@@ -125,7 +126,7 @@ static void handle_tx(struct vhost_net *net)
        mutex_lock(&vq->mutex);
        vhost_disable_notify(vq);
 
-       if (wmem < sock->sk->sk_sndbuf * 2)
+       if (wmem < sock->sk->sk_sndbuf / 2)
                tx_poll_stop(net);
        hdr_size = vq->hdr_size;
 
@@ -508,12 +509,12 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
        /* Verify that ring has been setup correctly. */
        if (!vhost_vq_access_ok(vq)) {
                r = -EFAULT;
-               goto err;
+               goto err_vq;
        }
        sock = get_socket(fd);
        if (IS_ERR(sock)) {
                r = PTR_ERR(sock);
-               goto err;
+               goto err_vq;
        }
 
        /* start polling new socket */
@@ -524,12 +525,14 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
        vhost_net_disable_vq(n, vq);
        rcu_assign_pointer(vq->private_data, sock);
        vhost_net_enable_vq(n, vq);
-       mutex_unlock(&vq->mutex);
 done:
        if (oldsock) {
                vhost_net_flush_vq(n, index);
                fput(oldsock->file);
        }
+
+err_vq:
+       mutex_unlock(&vq->mutex);
 err:
        mutex_unlock(&n->dev.mutex);
        return r;
index 7cd55e07879455abe95e04fa06656623b415c9a9..49fa953aaf6e354be77e47ff708f8677cc58026b 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/poll.h>
 #include <linux/file.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 
 #include <linux/net.h>
 #include <linux/if_packet.h>
@@ -235,6 +236,10 @@ static int vq_memory_access_ok(void __user *log_base, struct vhost_memory *mem,
                               int log_all)
 {
        int i;
+
+        if (!mem)
+                return 0;
+
        for (i = 0; i < mem->nregions; ++i) {
                struct vhost_memory_region *m = mem->regions + i;
                unsigned long a = m->userspace_addr;
@@ -476,8 +481,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
                if (r < 0)
                        break;
                eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd);
-               if (IS_ERR(eventfp))
-                       return PTR_ERR(eventfp);
+               if (IS_ERR(eventfp)) {
+                       r = PTR_ERR(eventfp);
+                       break;
+               }
                if (eventfp != vq->kick) {
                        pollstop = filep = vq->kick;
                        pollstart = vq->kick = eventfp;
@@ -489,8 +496,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
                if (r < 0)
                        break;
                eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd);
-               if (IS_ERR(eventfp))
-                       return PTR_ERR(eventfp);
+               if (IS_ERR(eventfp)) {
+                       r = PTR_ERR(eventfp);
+                       break;
+               }
                if (eventfp != vq->call) {
                        filep = vq->call;
                        ctx = vq->call_ctx;
@@ -505,8 +514,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
                if (r < 0)
                        break;
                eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd);
-               if (IS_ERR(eventfp))
-                       return PTR_ERR(eventfp);
+               if (IS_ERR(eventfp)) {
+                       r = PTR_ERR(eventfp);
+                       break;
+               }
                if (eventfp != vq->error) {
                        filep = vq->error;
                        vq->error = eventfp;
@@ -1024,7 +1035,12 @@ int vhost_add_used(struct vhost_virtqueue *vq, unsigned int head, int len)
 /* This actually signals the guest, using eventfd. */
 void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq)
 {
-       __u16 flags = 0;
+       __u16 flags;
+       /* Flush out used index updates. This is paired
+        * with the barrier that the Guest executes when enabling
+        * interrupts. */
+       smp_mb();
+
        if (get_user(flags, &vq->avail->flags)) {
                vq_err(vq, "Failed to get flags");
                return;
index 2110556f76b3fde28f5edc6a6adc49a2ddd9efd4..75a39eab70c38e291363473074ff8373dcf30135 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index dabe804ba575ecdd714873795ee7c081d474cc28..6e16244f3ed1f4d27c6d5c6baa1c0a1042cfe00c 100644 (file)
@@ -914,7 +914,7 @@ config FB_XVR2500
 
 config FB_XVR1000
        bool "Sun XVR-1000 support"
-       depends on SPARC64
+       depends on (FB = y) && SPARC64
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
@@ -1881,7 +1881,7 @@ config FB_W100
 
 config FB_SH_MOBILE_LCDC
        tristate "SuperH Mobile LCDC framebuffer support"
-       depends on FB && SUPERH && HAVE_CLK
+       depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
        select FB_SYS_FILLRECT
        select FB_SYS_COPYAREA
        select FB_SYS_IMAGEBLIT
index 43d7d506736154bee53d3a67fa99fce943a935c0..82acb8dc4aa144dab7888e567238a1ce332e49c8 100644 (file)
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/fb.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
index a21efcd10b78792bd75132d19e72cbd56b55e2bf..afe21e6eb5443cc8e8056e6f630fbd1c89caf991 100644 (file)
@@ -65,16 +65,16 @@ static void clcdfb_disable(struct clcd_fb *fb)
        if (fb->board->disable)
                fb->board->disable(fb);
 
-       val = readl(fb->regs + CLCD_CNTL);
+       val = readl(fb->regs + fb->off_cntl);
        if (val & CNTL_LCDPWR) {
                val &= ~CNTL_LCDPWR;
-               writel(val, fb->regs + CLCD_CNTL);
+               writel(val, fb->regs + fb->off_cntl);
 
                clcdfb_sleep(20);
        }
        if (val & CNTL_LCDEN) {
                val &= ~CNTL_LCDEN;
-               writel(val, fb->regs + CLCD_CNTL);
+               writel(val, fb->regs + fb->off_cntl);
        }
 
        /*
@@ -94,7 +94,7 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
         * Bring up by first enabling..
         */
        cntl |= CNTL_LCDEN;
-       writel(cntl, fb->regs + CLCD_CNTL);
+       writel(cntl, fb->regs + fb->off_cntl);
 
        clcdfb_sleep(20);
 
@@ -102,7 +102,7 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
         * and now apply power.
         */
        cntl |= CNTL_LCDPWR;
-       writel(cntl, fb->regs + CLCD_CNTL);
+       writel(cntl, fb->regs + fb->off_cntl);
 
        /*
         * finally, enable the interface.
@@ -233,7 +233,7 @@ static int clcdfb_set_par(struct fb_info *info)
                readl(fb->regs + CLCD_TIM0), readl(fb->regs + CLCD_TIM1),
                readl(fb->regs + CLCD_TIM2), readl(fb->regs + CLCD_TIM3),
                readl(fb->regs + CLCD_UBAS), readl(fb->regs + CLCD_LBAS),
-               readl(fb->regs + CLCD_IENB), readl(fb->regs + CLCD_CNTL));
+               readl(fb->regs + fb->off_ienb), readl(fb->regs + fb->off_cntl));
 #endif
 
        return 0;
@@ -345,6 +345,23 @@ static int clcdfb_register(struct clcd_fb *fb)
 {
        int ret;
 
+       /*
+        * ARM PL111 always has IENB at 0x1c; it's only PL110
+        * which is reversed on some platforms.
+        */
+       if (amba_manf(fb->dev) == 0x41 && amba_part(fb->dev) == 0x111) {
+               fb->off_ienb = CLCD_PL111_IENB;
+               fb->off_cntl = CLCD_PL111_CNTL;
+       } else {
+#ifdef CONFIG_ARCH_VERSATILE
+               fb->off_ienb = CLCD_PL111_IENB;
+               fb->off_cntl = CLCD_PL111_CNTL;
+#else
+               fb->off_ienb = CLCD_PL110_IENB;
+               fb->off_cntl = CLCD_PL110_CNTL;
+#endif
+       }
+
        fb->clk = clk_get(&fb->dev->dev, NULL);
        if (IS_ERR(fb->clk)) {
                ret = PTR_ERR(fb->clk);
@@ -416,7 +433,7 @@ static int clcdfb_register(struct clcd_fb *fb)
        /*
         * Ensure interrupts are disabled.
         */
-       writel(0, fb->regs + CLCD_IENB);
+       writel(0, fb->regs + fb->off_ienb);
 
        fb_set_var(&fb->fb, &fb->fb.var);
 
index 82bedd7f778967ee879258d27bc9183111107036..e5d6b56d4447e274d0db3f8eedf68cda99bfb53e 100644 (file)
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-
+#include <linux/platform_device.h>
 #include <linux/uaccess.h>
+
 #include <asm/system.h>
 #include <asm/irq.h>
 #include <asm/amigahw.h>
@@ -1136,7 +1136,7 @@ static int amifb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg
         * Interface to the low level console driver
         */
 
-static void amifb_deinit(void);
+static void amifb_deinit(struct platform_device *pdev);
 
        /*
         * Internal routines
@@ -2247,7 +2247,7 @@ static inline void chipfree(void)
         * Initialisation
         */
 
-static int __init amifb_init(void)
+static int __init amifb_probe(struct platform_device *pdev)
 {
        int tag, i, err = 0;
        u_long chipptr;
@@ -2262,16 +2262,6 @@ static int __init amifb_init(void)
        }
        amifb_setup(option);
 #endif
-       if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_VIDEO))
-               return -ENODEV;
-
-       /*
-        * We request all registers starting from bplpt[0]
-        */
-       if (!request_mem_region(CUSTOM_PHYSADDR+0xe0, 0x120,
-                               "amifb [Denise/Lisa]"))
-               return -EBUSY;
-
        custom.dmacon = DMAF_ALL | DMAF_MASTER;
 
        switch (amiga_chipset) {
@@ -2378,6 +2368,7 @@ default_chipset:
        fb_info.fbops = &amifb_ops;
        fb_info.par = &currentpar;
        fb_info.flags = FBINFO_DEFAULT;
+       fb_info.device = &pdev->dev;
 
        if (!fb_find_mode(&fb_info.var, &fb_info, mode_option, ami_modedb,
                          NUM_TOTAL_MODES, &ami_modedb[defmode], 4)) {
@@ -2452,18 +2443,18 @@ default_chipset:
        return 0;
 
 amifb_error:
-       amifb_deinit();
+       amifb_deinit(pdev);
        return err;
 }
 
-static void amifb_deinit(void)
+static void amifb_deinit(struct platform_device *pdev)
 {
        if (fb_info.cmap.len)
                fb_dealloc_cmap(&fb_info.cmap);
+       fb_dealloc_cmap(&fb_info.cmap);
        chipfree();
        if (videomemory)
                iounmap((void*)videomemory);
-       release_mem_region(CUSTOM_PHYSADDR+0xe0, 0x120);
        custom.dmacon = DMAF_ALL | DMAF_MASTER;
 }
 
@@ -3795,14 +3786,35 @@ static void ami_rebuild_copper(void)
        }
 }
 
-static void __exit amifb_exit(void)
+static int __exit amifb_remove(struct platform_device *pdev)
 {
        unregister_framebuffer(&fb_info);
-       amifb_deinit();
+       amifb_deinit(pdev);
        amifb_video_off();
+       return 0;
+}
+
+static struct platform_driver amifb_driver = {
+       .remove = __exit_p(amifb_remove),
+       .driver   = {
+               .name   = "amiga-video",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init amifb_init(void)
+{
+       return platform_driver_probe(&amifb_driver, amifb_probe);
 }
 
 module_init(amifb_init);
+
+static void __exit amifb_exit(void)
+{
+       platform_driver_unregister(&amifb_driver);
+}
+
 module_exit(amifb_exit);
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:amiga-video");
index 01554d6965281435c9a4a8e1876a68e551d3a0cd..8d406fb689c132330dcaa4972a60cd271f3b348d 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index e70bc225fe315d39288d20d6d34011647571fe6c..8cdf88e20b4b649136439aef85af97be7baf2d91 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index b7687c55fe16b6d04efed50a5059dd1b100672ec..f3aada20fa02ad5e51264b1f347dd50e6120e85e 100644 (file)
@@ -52,7 +52,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
index 3d886c6902f9fe463064ac7d2d39818e36944339..8dce25126330f48639607e97398267a131c7d959 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/backlight.h>
+#include <linux/gfp.h>
 
 #include <mach/board.h>
 #include <mach/cpu.h>
@@ -117,6 +118,7 @@ static struct backlight_ops atmel_lcdc_bl_ops = {
 
 static void init_backlight(struct atmel_lcdfb_info *sinfo)
 {
+       struct backlight_properties props;
        struct backlight_device *bl;
 
        sinfo->bl_power = FB_BLANK_UNBLANK;
@@ -124,8 +126,10 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo)
        if (sinfo->backlight)
                return;
 
-       bl = backlight_device_register("backlight", &sinfo->pdev->dev,
-                       sinfo, &atmel_lcdc_bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 0xff;
+       bl = backlight_device_register("backlight", &sinfo->pdev->dev, sinfo,
+                                      &atmel_lcdc_bl_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&sinfo->pdev->dev, "error %ld on backlight register\n",
                                PTR_ERR(bl));
@@ -135,7 +139,6 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo)
 
        bl->props.power = FB_BLANK_UNBLANK;
        bl->props.fb_blank = FB_BLANK_UNBLANK;
-       bl->props.max_brightness = 0xff;
        bl->props.brightness = atmel_bl_get_brightness(bl);
 }
 
index 9ee67d6da7101f1d3b0f714553792f60015b4c02..34a0851bcbfa1f7a8d119e4e340062315a3ed5f0 100644 (file)
@@ -52,7 +52,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
@@ -1802,6 +1801,7 @@ static void aty128_bl_set_power(struct fb_info *info, int power)
 
 static void aty128_bl_init(struct aty128fb_par *par)
 {
+       struct backlight_properties props;
        struct fb_info *info = pci_get_drvdata(par->pdev);
        struct backlight_device *bd;
        char name[12];
@@ -1817,7 +1817,10 @@ static void aty128_bl_init(struct aty128fb_par *par)
 
        snprintf(name, sizeof(name), "aty128bl%d", info->node);
 
-       bd = backlight_device_register(name, info->dev, par, &aty128_bl_data);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+       bd = backlight_device_register(name, info->dev, par, &aty128_bl_data,
+                                      &props);
        if (IS_ERR(bd)) {
                info->bl_dev = NULL;
                printk(KERN_WARNING "aty128: Backlight registration failed\n");
@@ -1829,7 +1832,6 @@ static void aty128_bl_init(struct aty128fb_par *par)
                 63 * FB_BACKLIGHT_MAX / MAX_LEVEL,
                219 * FB_BACKLIGHT_MAX / MAX_LEVEL);
 
-       bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
        bd->props.brightness = bd->props.max_brightness;
        bd->props.power = FB_BLANK_UNBLANK;
        backlight_update_status(bd);
index e45ab8db2ddc6f7f46d98ff09504dcc8c45ff2e6..29d72851f85bd1d01aa50448b1cc9f1e34f5924f 100644 (file)
@@ -2232,6 +2232,7 @@ static struct backlight_ops aty_bl_data = {
 
 static void aty_bl_init(struct atyfb_par *par)
 {
+       struct backlight_properties props;
        struct fb_info *info = pci_get_drvdata(par->pdev);
        struct backlight_device *bd;
        char name[12];
@@ -2243,7 +2244,10 @@ static void aty_bl_init(struct atyfb_par *par)
 
        snprintf(name, sizeof(name), "atybl%d", info->node);
 
-       bd = backlight_device_register(name, info->dev, par, &aty_bl_data);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+       bd = backlight_device_register(name, info->dev, par, &aty_bl_data,
+                                      &props);
        if (IS_ERR(bd)) {
                info->bl_dev = NULL;
                printk(KERN_WARNING "aty: Backlight registration failed\n");
@@ -2255,7 +2259,6 @@ static void aty_bl_init(struct atyfb_par *par)
                            0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL,
                            0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL);
 
-       bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
        bd->props.brightness = bd->props.max_brightness;
        bd->props.power = FB_BLANK_UNBLANK;
        backlight_update_status(bd);
index 04c710804bb04e93e67cd1b81fe7b811d5c87bce..2ba8b3c421a1e03af15524c4e49d233ebcec8149 100644 (file)
@@ -2,7 +2,6 @@
  *  ATI Mach64 CT/VT/GT/LT Cursor Support
  */
 
-#include <linux/slab.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/string.h>
index fa1198c4ccc5d0041072b5ca95913134e3531ee3..256966e9667db3bfa776e71c51a694c3239c3432 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "radeonfb.h"
 #include <linux/backlight.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 #include <asm/backlight.h>
@@ -134,6 +135,7 @@ static struct backlight_ops radeon_bl_data = {
 
 void radeonfb_bl_init(struct radeonfb_info *rinfo)
 {
+       struct backlight_properties props;
        struct backlight_device *bd;
        struct radeon_bl_privdata *pdata;
        char name[12];
@@ -155,7 +157,10 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo)
 
        snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node);
 
-       bd = backlight_device_register(name, rinfo->info->dev, pdata, &radeon_bl_data);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+       bd = backlight_device_register(name, rinfo->info->dev, pdata,
+                                      &radeon_bl_data, &props);
        if (IS_ERR(bd)) {
                rinfo->info->bl_dev = NULL;
                printk("radeonfb: Backlight registration failed\n");
@@ -185,7 +190,6 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo)
                 63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL,
                217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL);
 
-       bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
        bd->props.brightness = bd->props.max_brightness;
        bd->props.power = FB_BLANK_UNBLANK;
        backlight_update_status(bd);
index b4d4b88afc093d752f8ffce2ccbc14109e234eea..9261c918fde87cc61712b993f93aae2f4dd28c84 100644 (file)
@@ -1,4 +1,7 @@
 #include "radeonfb.h"
+
+#include <linux/slab.h>
+
 #include "../edid.h"
 
 static struct fb_var_screeninfo radeonfb_default_var = {
index a699aab638205c01b0765610cd9846a5468a8944..40f61320ce1665b156b04761b739b8c4bbc96862 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/ctype.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/mach-au1x00/au1000.h>
 
index 0d96f1d2d4c5bd0d3d490becbc84a0c012d7e443..e77e8e4280fb4005854f68c5450031d4764b040b 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/interrupt.h>
 #include <linux/ctype.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <asm/mach-au1x00/au1000.h>
 #include "au1200fb.h"
index b8f705cca438b43d641168188a2eaf55f8aec75e..68d2518fadaa67fc56af119fde89fd7dd49648a3 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/i2c.h>
 #include <linux/backlight.h>
 #include <linux/mfd/88pm860x.h>
+#include <linux/slab.h>
 
 #define MAX_BRIGHTNESS         (0xFF)
 #define MIN_BRIGHTNESS         (0)
@@ -187,6 +188,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
        struct pm860x_backlight_data *data;
        struct backlight_device *bl;
        struct resource *res;
+       struct backlight_properties props;
        unsigned char value;
        char name[MFD_NAME_SIZE];
        int ret;
@@ -223,14 +225,15 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = MAX_BRIGHTNESS;
        bl = backlight_device_register(name, &pdev->dev, data,
-                                       &pm860x_backlight_ops);
+                                       &pm860x_backlight_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
                kfree(data);
                return PTR_ERR(bl);
        }
-       bl->props.max_brightness = MAX_BRIGHTNESS;
        bl->props.brightness = MAX_BRIGHTNESS;
 
        platform_set_drvdata(pdev, bl);
index 0c77fc61021261176c5bc498f89f001d901b8379..c025c84601b01d805d98bf5336806b6ae8273062 100644 (file)
@@ -31,6 +31,13 @@ config LCD_CORGI
          Say y here to support the LCD panels usually found on SHARP
          corgi (C7x0) and spitz (Cxx00) models.
 
+config LCD_L4F00242T03
+       tristate "Epson L4F00242T03 LCD"
+       depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO
+       help
+         SPI driver for Epson L4F00242T03. This provides basic support
+         for init and powering the LCD up/down through a sysfs interface.
+
 config LCD_LMS283GF05
        tristate "Samsung LMS283GF05 LCD"
        depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO
index 6c704d41462d03c1fed49fe34a167b93380034ff..09d1f14d6257ac1ceedb9a8988c8017d24f6e265 100644 (file)
@@ -3,6 +3,7 @@
 obj-$(CONFIG_LCD_CLASS_DEVICE)     += lcd.o
 obj-$(CONFIG_LCD_CORGI)                   += corgi_lcd.o
 obj-$(CONFIG_LCD_HP700)                   += jornada720_lcd.o
+obj-$(CONFIG_LCD_L4F00242T03)     += l4f00242t03.o
 obj-$(CONFIG_LCD_LMS283GF05)      += lms283gf05.o
 obj-$(CONFIG_LCD_LTV350QV)        += ltv350qv.o
 obj-$(CONFIG_LCD_ILI9320)         += ili9320.o
index 86d95c228adb7289ec294f454b44e9575516d1f7..9f436e014f85b3e809198f37e42d8b57cc387fe1 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/fb.h>
 #include <linux/backlight.h>
 #include <linux/mfd/adp5520.h>
+#include <linux/slab.h>
 
 struct adp5520_bl {
        struct device *master;
@@ -278,6 +279,7 @@ static const struct attribute_group adp5520_bl_attr_group = {
 
 static int __devinit adp5520_bl_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct backlight_device *bl;
        struct adp5520_bl *data;
        int ret = 0;
@@ -300,17 +302,17 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
 
        mutex_init(&data->lock);
 
-       bl = backlight_device_register(pdev->name, data->master,
-                       data, &adp5520_bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = ADP5020_MAX_BRIGHTNESS;
+       bl = backlight_device_register(pdev->name, data->master, data,
+                                      &adp5520_bl_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
                kfree(data);
                return PTR_ERR(bl);
        }
 
-       bl->props.max_brightness =
-               bl->props.brightness = ADP5020_MAX_BRIGHTNESS;
-
+       bl->props.brightness = ADP5020_MAX_BRIGHTNESS;
        if (data->pdata->en_ambl_sens)
                ret = sysfs_create_group(&bl->dev.kobj,
                        &adp5520_bl_attr_group);
index d769b0bab21abfc5b41105f430210532a7bd948e..7f4a7c30a98b1f3a09fd020c4c5906f386a1015c 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/backlight.h>
 #include <linux/fb.h>
+#include <linux/gfp.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -56,7 +57,7 @@ static int adx_backlight_get_brightness(struct backlight_device *bldev)
        return brightness & 0xff;
 }
 
-static int adx_backlight_check_fb(struct fb_info *fb)
+static int adx_backlight_check_fb(struct backlight_device *bldev, struct fb_info *fb)
 {
        return 1;
 }
@@ -70,6 +71,7 @@ static const struct backlight_ops adx_backlight_ops = {
 
 static int __devinit adx_backlight_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct backlight_device *bldev;
        struct resource *res;
        struct adxbl *bl;
@@ -101,14 +103,15 @@ static int __devinit adx_backlight_probe(struct platform_device *pdev)
                goto out;
        }
 
-       bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, bl,
-                       &adx_backlight_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 0xff;
+       bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev,
+                                         bl, &adx_backlight_ops, &props);
        if (!bldev) {
                ret = -ENOMEM;
                goto out;
        }
 
-       bldev->props.max_brightness = 0xff;
        bldev->props.brightness = 0xff;
        bldev->props.power = FB_BLANK_UNBLANK;
 
index f625ffc69ad3139cef6ba88688ac1e76878ff1e4..e6a66dab088c10a697f438625651d6d17f2aed4c 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/backlight.h>
 #include <linux/atmel_pwm.h>
 #include <linux/atmel-pwm-bl.h>
+#include <linux/slab.h>
 
 struct atmel_pwm_bl {
        const struct atmel_pwm_bl_platform_data *pdata;
@@ -120,6 +121,7 @@ static const struct backlight_ops atmel_pwm_bl_ops = {
 
 static int atmel_pwm_bl_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        const struct atmel_pwm_bl_platform_data *pdata;
        struct backlight_device *bldev;
        struct atmel_pwm_bl *pwmbl;
@@ -165,8 +167,10 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
                        goto err_free_gpio;
        }
 
-       bldev = backlight_device_register("atmel-pwm-bl",
-                       &pdev->dev, pwmbl, &atmel_pwm_bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min;
+       bldev = backlight_device_register("atmel-pwm-bl", &pdev->dev, pwmbl,
+                                         &atmel_pwm_bl_ops, &props);
        if (IS_ERR(bldev)) {
                retval = PTR_ERR(bldev);
                goto err_free_gpio;
@@ -178,7 +182,6 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
 
        /* Power up the backlight by default at middle intesity. */
        bldev->props.power = FB_BLANK_UNBLANK;
-       bldev->props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min;
        bldev->props.brightness = bldev->props.max_brightness / 2;
 
        retval = atmel_pwm_bl_init_pwm(pwmbl);
index 18829cf68b1b97ca111af2d390820a3576ad68c1..e207810bba3cfe9e0042f02bc447ad5b01564ff0 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/ctype.h>
 #include <linux/err.h>
 #include <linux/fb.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 #include <asm/backlight.h>
@@ -38,7 +39,7 @@ static int fb_notifier_callback(struct notifier_block *self,
        mutex_lock(&bd->ops_lock);
        if (bd->ops)
                if (!bd->ops->check_fb ||
-                   bd->ops->check_fb(evdata->info)) {
+                   bd->ops->check_fb(bd, evdata->info)) {
                        bd->props.fb_blank = *(int *)evdata->data;
                        if (bd->props.fb_blank == FB_BLANK_UNBLANK)
                                bd->props.state &= ~BL_CORE_FBBLANK;
@@ -269,7 +270,8 @@ EXPORT_SYMBOL(backlight_force_update);
  * ERR_PTR() or a pointer to the newly allocated device.
  */
 struct backlight_device *backlight_device_register(const char *name,
-               struct device *parent, void *devdata, const struct backlight_ops *ops)
+       struct device *parent, void *devdata, const struct backlight_ops *ops,
+       const struct backlight_properties *props)
 {
        struct backlight_device *new_bd;
        int rc;
@@ -289,6 +291,11 @@ struct backlight_device *backlight_device_register(const char *name,
        dev_set_name(&new_bd->dev, name);
        dev_set_drvdata(&new_bd->dev, devdata);
 
+       /* Set default properties */
+       if (props)
+               memcpy(&new_bd->props, props,
+                      sizeof(struct backlight_properties));
+
        rc = device_register(&new_bd->dev);
        if (rc) {
                kfree(new_bd);
index b4bcf8043797d18ced2ab1618ee9ef57853e6399..1e71c35083bb4ca8505031efeee5db036a2a2c51 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/lcd.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/corgi_lcd.h>
+#include <linux/slab.h>
 #include <asm/mach/sharpsl_param.h>
 
 #define POWER_IS_ON(pwr)       ((pwr) <= FB_BLANK_NORMAL)
@@ -533,6 +534,7 @@ err_free_backlight_on:
 
 static int __devinit corgi_lcd_probe(struct spi_device *spi)
 {
+       struct backlight_properties props;
        struct corgi_lcd_platform_data *pdata = spi->dev.platform_data;
        struct corgi_lcd *lcd;
        int ret = 0;
@@ -559,13 +561,14 @@ static int __devinit corgi_lcd_probe(struct spi_device *spi)
        lcd->power = FB_BLANK_POWERDOWN;
        lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA;
 
-       lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev,
-                                       lcd, &corgi_bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = pdata->max_intensity;
+       lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, lcd,
+                                               &corgi_bl_ops, &props);
        if (IS_ERR(lcd->bl_dev)) {
                ret = PTR_ERR(lcd->bl_dev);
                goto err_unregister_lcd;
        }
-       lcd->bl_dev->props.max_brightness = pdata->max_intensity;
        lcd->bl_dev->props.brightness = pdata->default_intensity;
        lcd->bl_dev->props.power = FB_BLANK_UNBLANK;
 
index da86db4374a05a350084b2f06834d489e773f4ba..a4f4546f0be08555f8a2d793b6b94beaae91186f 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/backlight.h>
 #include <linux/lcd.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 /* The LVDS- and panel power controls sits on the
  * GPIO port of the ISA bridge.
@@ -170,6 +171,7 @@ static struct lcd_ops cr_lcd_ops = {
 
 static int cr_backlight_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct backlight_device *bdp;
        struct lcd_device *ldp;
        struct cr_panel *crp;
@@ -190,8 +192,9 @@ static int cr_backlight_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       bdp = backlight_device_register("cr-backlight",
-                                       &pdev->dev, NULL, &cr_backlight_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       bdp = backlight_device_register("cr-backlight", &pdev->dev, NULL,
+                                       &cr_backlight_ops, &props);
        if (IS_ERR(bdp)) {
                pci_dev_put(lpc_dev);
                return PTR_ERR(bdp);
@@ -220,9 +223,7 @@ static int cr_backlight_probe(struct platform_device *pdev)
        crp->cr_lcd_device = ldp;
        crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK;
        crp->cr_backlight_device->props.brightness = 0;
-       crp->cr_backlight_device->props.max_brightness = 0;
        cr_backlight_set_intensity(crp->cr_backlight_device);
-
        cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_UNBLANK);
 
        platform_set_drvdata(pdev, crp);
index 74cdc640173de5879af656d46cfaafa4ec8ad6bf..87659ed79bd7aa3eae7cc1fafd6e12e8cad79e25 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/fb.h>
 #include <linux/backlight.h>
 #include <linux/mfd/da903x.h>
+#include <linux/slab.h>
 
 #define DA9030_WLED_CONTROL    0x25
 #define DA9030_WLED_CP_EN      (1 << 6)
@@ -105,6 +106,7 @@ static int da903x_backlight_probe(struct platform_device *pdev)
        struct da9034_backlight_pdata *pdata = pdev->dev.platform_data;
        struct da903x_backlight_data *data;
        struct backlight_device *bl;
+       struct backlight_properties props;
        int max_brightness;
 
        data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -134,15 +136,15 @@ static int da903x_backlight_probe(struct platform_device *pdev)
                da903x_write(data->da903x_dev, DA9034_WLED_CONTROL2,
                                DA9034_WLED_ISET(pdata->output_current));
 
-       bl = backlight_device_register(pdev->name, data->da903x_dev,
-                       data, &da903x_backlight_ops);
+       props.max_brightness = max_brightness;
+       bl = backlight_device_register(pdev->name, data->da903x_dev, data,
+                                      &da903x_backlight_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
                kfree(data);
                return PTR_ERR(bl);
        }
 
-       bl->props.max_brightness = max_brightness;
        bl->props.brightness = max_brightness;
 
        platform_set_drvdata(pdev, bl);
index e6d348e63596455f06d4a3443e82ea4f982a91e6..312ca619735d4dcafa4a0bb70294be13fe5081db 100644 (file)
@@ -78,6 +78,7 @@ static const struct backlight_ops genericbl_ops = {
 
 static int genericbl_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct generic_bl_info *machinfo = pdev->dev.platform_data;
        const char *name = "generic-bl";
        struct backlight_device *bd;
@@ -89,14 +90,15 @@ static int genericbl_probe(struct platform_device *pdev)
        if (machinfo->name)
                name = machinfo->name;
 
-       bd = backlight_device_register (name,
-               &pdev->dev, NULL, &genericbl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = machinfo->max_intensity;
+       bd = backlight_device_register(name, &pdev->dev, NULL, &genericbl_ops,
+                                      &props);
        if (IS_ERR (bd))
                return PTR_ERR (bd);
 
        platform_set_drvdata(pdev, bd);
 
-       bd->props.max_brightness = machinfo->max_intensity;
        bd->props.power = FB_BLANK_UNBLANK;
        bd->props.brightness = machinfo->default_intensity;
        backlight_update_status(bd);
index f7cc528d5be79a066347e43b3271c0d376e5275c..267d23f8d645fc889d7f5faace0d951e93ae41c0 100644 (file)
@@ -105,16 +105,18 @@ static const struct backlight_ops hp680bl_ops = {
 
 static int __devinit hp680bl_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct backlight_device *bd;
 
-       bd = backlight_device_register ("hp680-bl", &pdev->dev, NULL,
-                   &hp680bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = HP680_MAX_INTENSITY;
+       bd = backlight_device_register("hp680-bl", &pdev->dev, NULL,
+                                      &hp680bl_ops, &props);
        if (IS_ERR(bd))
                return PTR_ERR(bd);
 
        platform_set_drvdata(pdev, bd);
 
-       bd->props.max_brightness = HP680_MAX_INTENSITY;
        bd->props.brightness = HP680_DEFAULT_INTENSITY;
        hp680bl_send_intensity(bd);
 
index ba89b41b639cde4517fa8bb64237441ee8fa9e5e..5118a9f029aba5a872c231239d9f86c52738b73c 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/lcd.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <linux/spi/spi.h>
 
index db9071fc56654add5b279b31845c75e34e7726cc..2f177b3a4885c1658685712703d266184b5b35ed 100644 (file)
@@ -101,10 +101,14 @@ static const struct backlight_ops jornada_bl_ops = {
 
 static int jornada_bl_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        int ret;
        struct backlight_device *bd;
 
-       bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = BL_MAX_BRIGHT;
+       bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL,
+                                      &jornada_bl_ops, &props);
 
        if (IS_ERR(bd)) {
                ret = PTR_ERR(bd);
@@ -117,7 +121,6 @@ static int jornada_bl_probe(struct platform_device *pdev)
        /* note. make sure max brightness is set otherwise
           you will get seemingly non-related errors when
           trying to change brightness */
-       bd->props.max_brightness = BL_MAX_BRIGHT;
        jornada_bl_update_status(bd);
 
        platform_set_drvdata(pdev, bd);
index 939e7b830cf3f5afabaf104e694d465e63759bd5..f439a863228755d22621f57b4ecb384327ab3966 100644 (file)
@@ -141,20 +141,24 @@ static const struct backlight_ops kb3886bl_ops = {
 
 static int kb3886bl_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct kb3886bl_machinfo *machinfo = pdev->dev.platform_data;
 
        bl_machinfo = machinfo;
        if (!machinfo->limit_mask)
                machinfo->limit_mask = -1;
 
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = machinfo->max_intensity;
        kb3886_backlight_device = backlight_device_register("kb3886-bl",
-               &pdev->dev, NULL, &kb3886bl_ops);
+                                                           &pdev->dev, NULL,
+                                                           &kb3886bl_ops,
+                                                           &props);
        if (IS_ERR(kb3886_backlight_device))
                return PTR_ERR(kb3886_backlight_device);
 
        platform_set_drvdata(pdev, kb3886_backlight_device);
 
-       kb3886_backlight_device->props.max_brightness = machinfo->max_intensity;
        kb3886_backlight_device->props.power = FB_BLANK_UNBLANK;
        kb3886_backlight_device->props.brightness = machinfo->default_intensity;
        backlight_update_status(kb3886_backlight_device);
diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c
new file mode 100644 (file)
index 0000000..bcdb12c
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * l4f00242t03.c -- support for Epson L4F00242T03 LCD
+ *
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ *     Inspired by Marek Vasut work in l4f00242t03.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/lcd.h>
+#include <linux/slab.h>
+#include <linux/regulator/consumer.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/l4f00242t03.h>
+
+struct l4f00242t03_priv {
+       struct spi_device       *spi;
+       struct lcd_device       *ld;
+       int lcd_on:1;
+       struct regulator *io_reg;
+       struct regulator *core_reg;
+};
+
+
+static void l4f00242t03_reset(unsigned int gpio)
+{
+       pr_debug("l4f00242t03_reset.\n");
+       gpio_set_value(gpio, 1);
+       mdelay(100);
+       gpio_set_value(gpio, 0);
+       mdelay(10);     /* tRES >= 100us */
+       gpio_set_value(gpio, 1);
+       mdelay(20);
+}
+
+#define param(x) ((x) | 0x100)
+
+static void l4f00242t03_lcd_init(struct spi_device *spi)
+{
+       struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
+       struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
+       const u16 cmd[] = { 0x36, param(0), 0x3A, param(0x60) };
+
+       dev_dbg(&spi->dev, "initializing LCD\n");
+
+       if (priv->io_reg) {
+               regulator_set_voltage(priv->io_reg, 1800000, 1800000);
+               regulator_enable(priv->io_reg);
+       }
+
+       if (priv->core_reg) {
+               regulator_set_voltage(priv->core_reg, 2800000, 2800000);
+               regulator_enable(priv->core_reg);
+       }
+
+       gpio_set_value(pdata->data_enable_gpio, 1);
+       msleep(60);
+       spi_write(spi, (const u8 *)cmd, ARRAY_SIZE(cmd) * sizeof(u16));
+}
+
+static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power)
+{
+       struct l4f00242t03_priv *priv = lcd_get_data(ld);
+       struct spi_device *spi = priv->spi;
+
+       const u16 slpout = 0x11;
+       const u16 dison = 0x29;
+
+       const u16 slpin = 0x10;
+       const u16 disoff = 0x28;
+
+       if (power) {
+               if (priv->lcd_on)
+                       return 0;
+
+               dev_dbg(&spi->dev, "turning on LCD\n");
+
+               spi_write(spi, (const u8 *)&slpout, sizeof(u16));
+               msleep(60);
+               spi_write(spi, (const u8 *)&dison, sizeof(u16));
+
+               priv->lcd_on = 1;
+       } else {
+               if (!priv->lcd_on)
+                       return 0;
+
+               dev_dbg(&spi->dev, "turning off LCD\n");
+
+               spi_write(spi, (const u8 *)&disoff, sizeof(u16));
+               msleep(60);
+               spi_write(spi, (const u8 *)&slpin, sizeof(u16));
+
+               priv->lcd_on = 0;
+       }
+
+       return 0;
+}
+
+static struct lcd_ops l4f_ops = {
+       .set_power      = l4f00242t03_lcd_power_set,
+       .get_power      = NULL,
+};
+
+static int __devinit l4f00242t03_probe(struct spi_device *spi)
+{
+       struct l4f00242t03_priv *priv;
+       struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
+       int ret;
+
+       if (pdata == NULL) {
+               dev_err(&spi->dev, "Uninitialized platform data.\n");
+               return -EINVAL;
+       }
+
+       priv = kzalloc(sizeof(struct l4f00242t03_priv), GFP_KERNEL);
+
+       if (priv == NULL) {
+               dev_err(&spi->dev, "No memory for this device.\n");
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       dev_set_drvdata(&spi->dev, priv);
+       spi->bits_per_word = 9;
+       spi_setup(spi);
+
+       priv->spi = spi;
+
+       ret = gpio_request(pdata->reset_gpio, "lcd l4f00242t03 reset");
+       if (ret) {
+               dev_err(&spi->dev,
+                       "Unable to get the lcd l4f00242t03 reset gpio.\n");
+               return ret;
+       }
+
+       ret = gpio_direction_output(pdata->reset_gpio, 1);
+       if (ret)
+               goto err2;
+
+       ret = gpio_request(pdata->data_enable_gpio,
+                               "lcd l4f00242t03 data enable");
+       if (ret) {
+               dev_err(&spi->dev,
+                       "Unable to get the lcd l4f00242t03 data en gpio.\n");
+               return ret;
+       }
+
+       ret = gpio_direction_output(pdata->data_enable_gpio, 0);
+       if (ret)
+               goto err3;
+
+       if (pdata->io_supply) {
+               priv->io_reg = regulator_get(NULL, pdata->io_supply);
+
+               if (IS_ERR(priv->io_reg)) {
+                       pr_err("%s: Unable to get the IO regulator\n",
+                                                               __func__);
+                       goto err3;
+               }
+       }
+
+       if (pdata->core_supply) {
+               priv->core_reg = regulator_get(NULL, pdata->core_supply);
+
+               if (IS_ERR(priv->core_reg)) {
+                       pr_err("%s: Unable to get the core regulator\n",
+                                                               __func__);
+                       goto err4;
+               }
+       }
+
+       priv->ld = lcd_device_register("l4f00242t03",
+                                       &spi->dev, priv, &l4f_ops);
+       if (IS_ERR(priv->ld)) {
+               ret = PTR_ERR(priv->ld);
+               goto err5;
+       }
+
+       /* Init the LCD */
+       l4f00242t03_reset(pdata->reset_gpio);
+       l4f00242t03_lcd_init(spi);
+       l4f00242t03_lcd_power_set(priv->ld, 1);
+
+       dev_info(&spi->dev, "Epson l4f00242t03 lcd probed.\n");
+
+       return 0;
+
+err5:
+       if (priv->core_reg)
+               regulator_put(priv->core_reg);
+err4:
+       if (priv->io_reg)
+               regulator_put(priv->io_reg);
+err3:
+       gpio_free(pdata->data_enable_gpio);
+err2:
+       gpio_free(pdata->reset_gpio);
+err:
+       kfree(priv);
+
+       return ret;
+}
+
+static int __devexit l4f00242t03_remove(struct spi_device *spi)
+{
+       struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
+       struct l4f00242t03_pdata *pdata = priv->spi->dev.platform_data;
+
+       l4f00242t03_lcd_power_set(priv->ld, 0);
+       lcd_device_unregister(priv->ld);
+
+       gpio_free(pdata->data_enable_gpio);
+       gpio_free(pdata->reset_gpio);
+
+       if (priv->io_reg)
+               regulator_put(priv->core_reg);
+       if (priv->core_reg)
+               regulator_put(priv->io_reg);
+
+       kfree(priv);
+
+       return 0;
+}
+
+static struct spi_driver l4f00242t03_driver = {
+       .driver = {
+               .name   = "l4f00242t03",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = l4f00242t03_probe,
+       .remove         = __devexit_p(l4f00242t03_remove),
+};
+
+static __init int l4f00242t03_init(void)
+{
+       return spi_register_driver(&l4f00242t03_driver);
+}
+
+static __exit void l4f00242t03_exit(void)
+{
+       spi_unregister_driver(&l4f00242t03_driver);
+}
+
+module_init(l4f00242t03_init);
+module_exit(l4f00242t03_exit);
+
+MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>");
+MODULE_DESCRIPTION("EPSON L4F00242T03 LCD");
+MODULE_LICENSE("GPL v2");
index 9b3be74cee5a7f2e9f000bf4b64f9cec8c7a2715..71a11cadffc48134b3ab164cb798f7278be6f802 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/ctype.h>
 #include <linux/err.h>
 #include <linux/fb.h>
+#include <linux/slab.h>
 
 #if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
                           defined(CONFIG_LCD_CLASS_DEVICE_MODULE))
index 447b542a20ca61f208e539af84dc75489567edfb..abc43a0eb97dd054f7c526b47fa014e61e458dc0 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/lcd.h>
 
index 00a9591b00030f8a3bf744ec124cc163ff061ad9..7571bc26071e7039f5b9c064604e5077cdf4bf79 100644 (file)
@@ -167,6 +167,7 @@ static int locomolcd_resume(struct locomo_dev *dev)
 
 static int locomolcd_probe(struct locomo_dev *ldev)
 {
+       struct backlight_properties props;
        unsigned long flags;
 
        local_irq_save(flags);
@@ -182,13 +183,16 @@ static int locomolcd_probe(struct locomo_dev *ldev)
 
        local_irq_restore(flags);
 
-       locomolcd_bl_device = backlight_device_register("locomo-bl", &ldev->dev, NULL, &locomobl_data);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 4;
+       locomolcd_bl_device = backlight_device_register("locomo-bl",
+                                                       &ldev->dev, NULL,
+                                                       &locomobl_data, &props);
 
        if (IS_ERR (locomolcd_bl_device))
                return PTR_ERR (locomolcd_bl_device);
 
        /* Set up frontlight so that screen is readable */
-       locomolcd_bl_device->props.max_brightness = 4,
        locomolcd_bl_device->props.brightness = 2;
        locomolcd_set_intensity(locomolcd_bl_device);
 
index 4631ca8fa4a4a33dcc39eb3801dfbc5ee21de121..8010aaeb5adb4437620bd51c63604897198bd0e1 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/lcd.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/spi/spi.h>
 
 #include "ltv350qv.h"
index c267069a52a3e926361c627be32b267c8b62754c..b5accc957ad37e50d5644f68749bb37d44667acf 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/i2c.h>
 #include <linux/backlight.h>
 #include <linux/mfd/max8925.h>
+#include <linux/slab.h>
 
 #define MAX_BRIGHTNESS         (0xff)
 #define MIN_BRIGHTNESS         (0)
@@ -104,6 +105,7 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
        struct max8925_backlight_pdata *pdata = NULL;
        struct max8925_backlight_data *data;
        struct backlight_device *bl;
+       struct backlight_properties props;
        struct resource *res;
        char name[MAX8925_NAME_SIZE];
        unsigned char value;
@@ -133,14 +135,15 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
        data->chip = chip;
        data->current_brightness = 0;
 
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = MAX_BRIGHTNESS;
        bl = backlight_device_register(name, &pdev->dev, data,
-                                       &max8925_backlight_ops);
+                                       &max8925_backlight_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
                kfree(data);
                return PTR_ERR(bl);
        }
-       bl->props.max_brightness = MAX_BRIGHTNESS;
        bl->props.brightness = MAX_BRIGHTNESS;
 
        platform_set_drvdata(pdev, bl);
index 2e78b0784bdc8b1dae7083fbee8f052302a30227..1b5d3fe6bbbccd3093cfb2772d4ee9deae42bcea 100644 (file)
@@ -137,6 +137,51 @@ static int mbp_dmi_match(const struct dmi_system_id *id)
 }
 
 static const struct dmi_system_id __initdata mbp_device_table[] = {
+       {
+               .callback       = mbp_dmi_match,
+               .ident          = "MacBook 1,1",
+               .matches        = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"),
+               },
+               .driver_data    = (void *)&intel_chipset_data,
+       },
+       {
+               .callback       = mbp_dmi_match,
+               .ident          = "MacBook 2,1",
+               .matches        = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"),
+               },
+               .driver_data    = (void *)&intel_chipset_data,
+       },
+       {
+               .callback       = mbp_dmi_match,
+               .ident          = "MacBook 3,1",
+               .matches        = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBook3,1"),
+               },
+               .driver_data    = (void *)&intel_chipset_data,
+       },
+       {
+               .callback       = mbp_dmi_match,
+               .ident          = "MacBook 4,1",
+               .matches        = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,1"),
+               },
+               .driver_data    = (void *)&intel_chipset_data,
+       },
+       {
+               .callback       = mbp_dmi_match,
+               .ident          = "MacBook 4,2",
+               .matches        = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,2"),
+               },
+               .driver_data    = (void *)&intel_chipset_data,
+       },
        {
                .callback       = mbp_dmi_match,
                .ident          = "MacBookPro 3,1",
@@ -250,6 +295,7 @@ static const struct dmi_system_id __initdata mbp_device_table[] = {
 
 static int __init mbp_init(void)
 {
+       struct backlight_properties props;
        if (!dmi_check_system(mbp_device_table))
                return -ENODEV;
 
@@ -257,14 +303,17 @@ static int __init mbp_init(void)
                                                "Macbook Pro backlight"))
                return -ENXIO;
 
-       mbp_backlight_device = backlight_device_register("mbp_backlight",
-                                       NULL, NULL, &driver_data->backlight_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 15;
+       mbp_backlight_device = backlight_device_register("mbp_backlight", NULL,
+                                                        NULL,
+                                                        &driver_data->backlight_ops,
+                                                        &props);
        if (IS_ERR(mbp_backlight_device)) {
                release_region(driver_data->iostart, driver_data->iolen);
                return PTR_ERR(mbp_backlight_device);
        }
 
-       mbp_backlight_device->props.max_brightness = 15;
        mbp_backlight_device->props.brightness =
                driver_data->backlight_ops.get_brightness(mbp_backlight_device);
        backlight_update_status(mbp_backlight_device);
index a3a7f893817516aacbfa0da8e4aecf727c671932..d3bc56296c8d98007321a1cce4945c7bdd7e0259 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/fb.h>
 #include <linux/backlight.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
 #include <plat/board.h>
@@ -132,6 +133,7 @@ static const struct backlight_ops omapbl_ops = {
 
 static int omapbl_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct backlight_device *dev;
        struct omap_backlight *bl;
        struct omap_backlight_config *pdata = pdev->dev.platform_data;
@@ -143,7 +145,10 @@ static int omapbl_probe(struct platform_device *pdev)
        if (unlikely(!bl))
                return -ENOMEM;
 
-       dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = OMAPBL_MAX_INTENSITY;
+       dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops,
+                                       &props);
        if (IS_ERR(dev)) {
                kfree(bl);
                return PTR_ERR(dev);
@@ -160,7 +165,6 @@ static int omapbl_probe(struct platform_device *pdev)
        omap_cfg_reg(PWL);      /* Conflicts with UART3 */
 
        dev->props.fb_blank = FB_BLANK_UNBLANK;
-       dev->props.max_brightness = OMAPBL_MAX_INTENSITY;
        dev->props.brightness = pdata->default_intensity;
        omapbl_update_status(dev);
 
index 738694d23889069805a752f1be14ba9b3d102ece..302330acf6284e0b22e7dc77a6ea055603aa5358 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/fb.h>
 #include <linux/backlight.h>
 #include <linux/lcd.h>
+#include <linux/slab.h>
 
 #include <video/platform_lcd.h>
 
index 075786e05034cc5defba6606a32e13b2e18f8de6..809278c90738945b8546bad7faeb7676f842114f 100644 (file)
@@ -61,8 +61,10 @@ static const struct backlight_ops progearbl_ops = {
 
 static int progearbl_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        u8 temp;
        struct backlight_device *progear_backlight_device;
+       int ret;
 
        pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL);
        if (!pmu_dev) {
@@ -73,28 +75,37 @@ static int progearbl_probe(struct platform_device *pdev)
        sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
        if (!sb_dev) {
                printk("ALI 1533 SB not found.\n");
-               pci_dev_put(pmu_dev);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto put_pmu;
        }
 
        /*     Set SB_MPS1 to enable brightness control. */
        pci_read_config_byte(sb_dev, SB_MPS1, &temp);
        pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20);
 
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
        progear_backlight_device = backlight_device_register("progear-bl",
                                                             &pdev->dev, NULL,
-                                                            &progearbl_ops);
-       if (IS_ERR(progear_backlight_device))
-               return PTR_ERR(progear_backlight_device);
+                                                            &progearbl_ops,
+                                                            &props);
+       if (IS_ERR(progear_backlight_device)) {
+               ret = PTR_ERR(progear_backlight_device);
+               goto put_sb;
+       }
 
        platform_set_drvdata(pdev, progear_backlight_device);
 
        progear_backlight_device->props.power = FB_BLANK_UNBLANK;
        progear_backlight_device->props.brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
-       progear_backlight_device->props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
        progearbl_set_intensity(progear_backlight_device);
 
        return 0;
+put_sb:
+       pci_dev_put(sb_dev);
+put_pmu:
+       pci_dev_put(pmu_dev);
+       return ret;
 }
 
 static int progearbl_remove(struct platform_device *pdev)
index 9d2ec2a1cce8fff721d40680277d45ac5bc1bb55..550443518891d41345234f4aa72929798b1f68a8 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/err.h>
 #include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
+#include <linux/slab.h>
 
 struct pwm_bl_data {
        struct pwm_device       *pwm;
@@ -65,6 +66,7 @@ static const struct backlight_ops pwm_backlight_ops = {
 
 static int pwm_backlight_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
        struct backlight_device *bl;
        struct pwm_bl_data *pb;
@@ -100,15 +102,16 @@ static int pwm_backlight_probe(struct platform_device *pdev)
        } else
                dev_dbg(&pdev->dev, "got pwm for backlight\n");
 
-       bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev,
-                       pb, &pwm_backlight_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = data->max_brightness;
+       bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
+                                      &pwm_backlight_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
                ret = PTR_ERR(bl);
                goto err_bl;
        }
 
-       bl->props.max_brightness = data->max_brightness;
        bl->props.brightness = data->dft_brightness;
        backlight_update_status(bl);
 
index 4a3d46e08016cc9ff49100f51574d67850249db2..1997e12a105783d0b3d40a4310cebcdacc826906 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/spi/tdo24m.h>
 #include <linux/fb.h>
 #include <linux/lcd.h>
+#include <linux/slab.h>
 
 #define POWER_IS_ON(pwr)       ((pwr) <= FB_BLANK_NORMAL)
 
index e14ce4d469f57f1ed6525ba53113bcbd6bca6913..e03e60bbfd855f01301ab14d71b1fc9d94453bcc 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/gpio.h>
 #include <linux/fb.h>
 #include <linux/backlight.h>
+#include <linux/slab.h>
 
 #include <asm/mach/sharpsl_param.h>
 
@@ -80,6 +81,7 @@ static const struct backlight_ops bl_ops = {
 static int __devinit tosa_bl_probe(struct i2c_client *client,
                const struct i2c_device_id *id)
 {
+       struct backlight_properties props;
        struct tosa_bl_data *data = kzalloc(sizeof(struct tosa_bl_data), GFP_KERNEL);
        int ret = 0;
        if (!data)
@@ -99,15 +101,16 @@ static int __devinit tosa_bl_probe(struct i2c_client *client,
        i2c_set_clientdata(client, data);
        data->i2c = client;
 
-       data->bl = backlight_device_register("tosa-bl", &client->dev,
-                       data, &bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 512 - 1;
+       data->bl = backlight_device_register("tosa-bl", &client->dev, data,
+                                            &bl_ops, &props);
        if (IS_ERR(data->bl)) {
                ret = PTR_ERR(data->bl);
                goto err_reg;
        }
 
        data->bl->props.brightness = 69;
-       data->bl->props.max_brightness = 512 - 1;
        data->bl->props.power = FB_BLANK_UNBLANK;
 
        backlight_update_status(data->bl);
index fa32b94a45466c0d4c5f024e7ea95bfb4920d434..772f6015219a91764a78a481071b2830824e4272 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/device.h>
 #include <linux/spi/spi.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/lcd.h>
index e32add37a203453558c80a6c195276cb402094c6..08fd87f3aecce368219ed7cb08dfdaa0aebafef6 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/fb.h>
 #include <linux/backlight.h>
+#include <linux/slab.h>
 
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/pdata.h>
@@ -125,6 +126,7 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
        struct wm831x_backlight_pdata *pdata;
        struct wm831x_backlight_data *data;
        struct backlight_device *bl;
+       struct backlight_properties props;
        int ret, i, max_isel, isink_reg, dcdc_cfg;
 
        /* We need platform data */
@@ -191,15 +193,15 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
        data->current_brightness = 0;
        data->isink_reg = isink_reg;
 
-       bl = backlight_device_register("wm831x", &pdev->dev,
-                       data, &wm831x_backlight_ops);
+       props.max_brightness = max_isel;
+       bl = backlight_device_register("wm831x", &pdev->dev, data,
+                                      &wm831x_backlight_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
                kfree(data);
                return PTR_ERR(bl);
        }
 
-       bl->props.max_brightness = max_isel;
        bl->props.brightness = max_isel;
 
        platform_set_drvdata(pdev, bl);
index 814312a7452fc389a9c9c0314654bb6174a9b2f4..23b2a8c0dbfcbdee211e253a5df9fd7b19aad80a 100644 (file)
@@ -433,7 +433,7 @@ static int bl_get_brightness(struct backlight_device *bd)
        return 0;
 }
 
-static struct backlight_ops bfin_lq043fb_bl_ops = {
+static const struct backlight_ops bfin_lq043fb_bl_ops = {
        .get_brightness = bl_get_brightness,
 };
 
@@ -501,6 +501,7 @@ static irqreturn_t bfin_bf54x_irq_error(int irq, void *dev_id)
 
 static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct bfin_bf54xfb_info *info;
        struct fb_info *fbinfo;
        int ret;
@@ -645,10 +646,16 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
                goto out8;
        }
 #ifndef NO_BL_SUPPORT
-       bl_dev =
-           backlight_device_register("bf54x-bl", NULL, NULL,
-                                     &bfin_lq043fb_bl_ops);
-       bl_dev->props.max_brightness = 255;
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 255;
+       bl_dev = backlight_device_register("bf54x-bl", NULL, NULL,
+                                          &bfin_lq043fb_bl_ops, &props);
+       if (IS_ERR(bl_dev)) {
+               printk(KERN_ERR DRIVER_NAME
+                       ": unable to register backlight.\n");
+               ret = -EINVAL;
+               goto out9;
+       }
 
        lcd_dev = lcd_device_register(DRIVER_NAME, &pdev->dev, NULL, &bfin_lcd_ops);
        lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n");
@@ -656,6 +663,8 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
 
        return 0;
 
+out9:
+       unregister_framebuffer(fbinfo);
 out8:
        free_irq(info->irq, info);
 out7:
index 03872365a36d4b38e5b793c7c4aefb8890bf2ab4..2baac7cc14255ea3b7401f442951f42580a0d7a3 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/fb.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
index 5653d083a9837c6de9c1e7ba9da613faacb8c489..c2ec3dcd4e918023886376b3103b21928c8b1e27 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/gfp.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/types.h>
@@ -352,7 +353,7 @@ static int bl_get_brightness(struct backlight_device *bd)
        return 0;
 }
 
-static struct backlight_ops bfin_lq043fb_bl_ops = {
+static const struct backlight_ops bfin_lq043fb_bl_ops = {
        .get_brightness = bl_get_brightness,
 };
 
@@ -419,6 +420,7 @@ static irqreturn_t bfin_t350mcqb_irq_error(int irq, void *dev_id)
 
 static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct bfin_t350mcqbfb_info *info;
        struct fb_info *fbinfo;
        int ret;
@@ -486,9 +488,9 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
        fbinfo->fbops = &bfin_t350mcqb_fb_ops;
        fbinfo->flags = FBINFO_FLAG_DEFAULT;
 
-       info->fb_buffer =
-           dma_alloc_coherent(NULL, fbinfo->fix.smem_len, &info->dma_handle,
-                              GFP_KERNEL);
+       info->fb_buffer = dma_alloc_coherent(NULL, fbinfo->fix.smem_len +
+                               ACTIVE_VIDEO_MEM_OFFSET,
+                               &info->dma_handle, GFP_KERNEL);
 
        if (NULL == info->fb_buffer) {
                printk(KERN_ERR DRIVER_NAME
@@ -540,10 +542,16 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
                goto out8;
        }
 #ifndef NO_BL_SUPPORT
-       bl_dev =
-           backlight_device_register("bf52x-bl", NULL, NULL,
-                                     &bfin_lq043fb_bl_ops);
-       bl_dev->props.max_brightness = 255;
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 255;
+       bl_dev = backlight_device_register("bf52x-bl", NULL, NULL,
+                                          &bfin_lq043fb_bl_ops, &props);
+       if (IS_ERR(bl_dev)) {
+               printk(KERN_ERR DRIVER_NAME
+                       ": unable to register backlight.\n");
+               ret = -EINVAL;
+               goto out9;
+       }
 
        lcd_dev = lcd_device_register(DRIVER_NAME, NULL, &bfin_lcd_ops);
        lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n");
@@ -551,6 +559,8 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
 
        return 0;
 
+out9:
+       unregister_framebuffer(fbinfo);
 out8:
        free_irq(info->irq, info);
 out7:
@@ -558,8 +568,8 @@ out7:
 out6:
        fb_dealloc_cmap(&fbinfo->cmap);
 out4:
-       dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
-                         info->dma_handle);
+       dma_free_coherent(NULL, fbinfo->fix.smem_len + ACTIVE_VIDEO_MEM_OFFSET,
+                        info->fb_buffer, info->dma_handle);
 out3:
        framebuffer_release(fbinfo);
 out2:
@@ -582,8 +592,9 @@ static int __devexit bfin_t350mcqb_remove(struct platform_device *pdev)
        free_irq(info->irq, info);
 
        if (info->fb_buffer != NULL)
-               dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
-                                 info->dma_handle);
+               dma_free_coherent(NULL, fbinfo->fix.smem_len +
+                       ACTIVE_VIDEO_MEM_OFFSET, info->fb_buffer,
+                       info->dma_handle);
 
        fb_dealloc_cmap(&fbinfo->cmap);
 
index b0b147cb4cb3aae5a0090e38145f8b48d1b0e25b..43320925c4cea48b980a905fa0d5766cadcad335 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
index 0c02f8ec4bf3dafe14965025a3a1121e19ab4dfd..d8345fcc4fe33f95edb460e410cf09b8f4e87bf5 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/fb.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include "carminefb.h"
 #include "carminefb_regs.h"
index 79e5f40e6486687c8e43062c6aaece0c1dc2a071..bb5a96b1645dc4a46600ee38f387e6d4267f3618 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/fb.h>
-#include <linux/slab.h>
 #include <asm/types.h>
 #include <asm/io.h>
 #include "fb_draw.h"
index fe45a3b8d0e060141e8a7cef3d7702fff15a44fa..77a040af20a7860626b9bae5696b88fce42a0c20 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
index b2319fa7286f8c77d8649ff4892f02ace8fb45e0..30eedf79322c4dcff534da06fe7938a5753d112c 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
index 0d47c6030e3d084011d697bf7aefe34d6f02021f..6d0fcb43696ec10bed2b44a020ee46e787b238e4 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
index 57b9d276497ed07e485311f38e95c6ef86af870e..d637e1f53172ac8180fcfec902cbe580dbca3072 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index 4c2bf923418c34bea4254318faeafb2d84190255..6df7c54db0a3470b1150d1eb8f5089967628eb73 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/init.h>
@@ -300,6 +299,7 @@ static const struct zorro_device_id cirrusfb_zorro_table[] = {
        },
        { 0 }
 };
+MODULE_DEVICE_TABLE(zorro, cirrusfb_zorro_table);
 
 static const struct {
        zorro_id id2;
index 6b7c8fbc5495cf6429a9206e4ebb92a1ec85caee..af88651b0735d9f270c9f11baebdc8786802802a 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/fb.h>
 #include <linux/vt_kern.h>
index bdf913ecf001de64916ede55b21c9b318743ee04..d135671d996184be2907dc43897222987c22d442 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/fb.h>
 #include <linux/vt_kern.h>
index a6819b9d1770cccd2690e9ee4c95f52736c27d42..126110f8454ff5b305a83e0af55de6a8176fd1d6 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/fb.h>
 #include <linux/vt_kern.h>
index 00884e013f0f2713591bad338b978ac37713b5cf..db6528f2d3f29506cd33c55b48ee5ece6fef4a37 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/fb.h>
 #include <linux/vt_kern.h>
index d9b5d6eb68a73c4e9129a84679532dc191cf4693..93a3e7381b5062d4e4c3596129f2c30d3b5671e8 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/fb.h>
 #include <linux/vt_kern.h>
index dd3eaaad44417781a6cef9a1537ca055812d3d65..0b67866cae10334200e1570d421cc5f74d56c7ea 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/console.h>
 #include <linux/string.h>
 #include <linux/kd.h>
-#include <linux/slab.h>
 #include <linux/vt_kern.h>
 #include <linux/vt_buffer.h>
 #include <linux/selection.h>
index 369a5b3ac6493b578425a7435ad45b4c2bc3759b..8d244ba0f6019689293bb7929a60ed065de6fdca 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/clk.h>
 #include <linux/cpufreq.h>
 #include <linux/console.h>
+#include <linux/slab.h>
 #include <video/da8xx-fb.h>
 
 #define DRIVER_NAME "da8xx_lcdc"
index 80abbf323b99befaa77bd0588463cb01ad1fe578..f6a09ab0dac6dad6184f783a9fe89e9dc04934b6 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/idr.h>
 #include <linux/err.h>
 #include <linux/kdev_t.h>
+#include <linux/slab.h>
 
 static ssize_t display_show_name(struct device *dev,
                                struct device_attribute *attr, char *buf)
index 606da043f4b479cd46c31f1778a7a1272dc4d872..ec56d2544c734aea151fd49ad97b88092b7beb5e 100644 (file)
@@ -2,7 +2,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
index 581d2dbf675a0061722db955a66d3fa402166db8..ecf405562f5ce7cff5c4a2549409162b87d680cb 100644 (file)
@@ -49,6 +49,7 @@ enum {
        M_MBP_2,        /* MacBook Pro 2nd gen */
        M_MBP_SR,       /* MacBook Pro (Santa Rosa) */
        M_MBP_4,        /* MacBook Pro, 4th gen */
+       M_MBP_5_1,    /* MacBook Pro, 5,1th gen */
        M_UNKNOWN       /* placeholder */
 };
 
@@ -70,6 +71,7 @@ static struct efifb_dmi_info {
        [M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */
        [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 },
        [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 },
+       [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900 },
        [M_UNKNOWN] = { NULL, 0, 0, 0, 0 }
 };
 
@@ -106,6 +108,7 @@ static struct dmi_system_id __initdata dmi_system_table[] = {
        EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR),
        EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR),
        EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4),
+       EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1),
        {},
 };
 
index 27aab4a0619851b0d38301f2d3ecba0a761c24db..0c99de0562ca7ccfd4a144d0b348c76b58073256 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/fb.h>
 
index 6d755bb3a2bcf0ee832476504a0329b2c4b9e445..db9713b49ce9a8a7ebd160fa87a0d9ee68d4b58d 100644 (file)
@@ -48,7 +48,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/init.h>
index 0cf96eb8a60f610b3fc26f0bc827453eb1c201fc..4a874c8d039c2867246d6e58c749b9d6f8170dbf 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/device.h>
 #include <linux/fb.h>
 #include <linux/i2c-algo-bit.h>
+#include <linux/slab.h>
 
 #include "edid.h"
 
index 44ce908a478b5f4d4ef116e6e92c93172e44b760..6113c47e095aaa0e94805c42622c47a344ff4dce 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index 0847c5e72cbd73ff2fcf53afe59c1d729810e2d9..7293eaccd81bd4b5846c187f848cb30ccb32d735 100644 (file)
@@ -13,6 +13,7 @@
  *
  */
 #include <linux/fb.h>
+#include <linux/slab.h>
 
 #define FB_CVT_CELLSIZE               8
 #define FB_CVT_GTF_C                 40
index 9ae9cd32bd065b1142d63c9975ad51fd1a1972e5..563a98b88e9bf17ce32edeaf4268fbfcee48681c 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/fb.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <video/edid.h>
 #ifdef CONFIG_PPC_OF
 #include <asm/prom.h>
index d4a2c11d980975be84131abd3a94670a1e2f7c98..81aa3129c17d75cbf67daf7d8226abb630c9d22a 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/fb.h>
 #include <linux/console.h>
 #include <linux/module.h>
index 9dbb9646081f670a92c6c29733184a25c4ef107e..a42fabab69dfe5d43b96cd63902625b219845f46 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
index 6c91c61cdb63824f1482e08407b8390ee8e59414..1b0feb8e7244b7bf6fbc1d606673ac03d8bf7656 100644 (file)
@@ -219,6 +219,7 @@ static struct zorro_device_id fm2fb_devices[] __devinitdata = {
        { ZORRO_PROD_HELFRICH_RAINBOW_II },
        { 0 }
 };
+MODULE_DEVICE_TABLE(zorro, fm2fb_devices);
 
 static struct zorro_driver fm2fb_driver = {
        .name           = "fm2fb",
index 4637bcbe03a4bcd462a86c52c34338e26f003e46..994358a4f30298d9684148db609a8c15723de82c 100644 (file)
@@ -1536,6 +1536,7 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev,
                goto error;
        }
 
+       sysfs_attr_init(&machine_data->dev_attr.attr);
        machine_data->dev_attr.attr.name = "monitor";
        machine_data->dev_attr.attr.mode = S_IRUGO|S_IWUSR;
        machine_data->dev_attr.show = show_monitor;
index b7655c05da53ad25a2bd6099992f503eff0e2d92..d662317d85e30fb01782b29f0bb681d327b766df 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index 5643a35c1746681ae1f464fe39036b5d42334b0f..7d8c55d7fd28a42c5d73a7f9e5f226bd9362a799 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
index f20eff8c4a816e1b9751ef1110f868e788f2e6a0..c6b554f72c6d255b61e1925e32f6effb9f300978 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/init.h>
index b3e639d1e12cbf67addef7eaa7455b8684b47b43..76e7dac6f25901843da1717d6fb55a3c721a8e16 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/console.h>
index cc781c00f75d04a11a9b371db177dca3ea64b06d..e4c4d89b786034c33aaf687b9616feddd3c76bbd 100644 (file)
@@ -365,6 +365,8 @@ enum fp_registers {
        FP_CRC, /* 0x458 */
 };
 
+#define FP_PT2_HSP                     (1 << 22)
+#define FP_PT2_VSP                     (1 << 23)
 #define FP_PT2_SCRC                    (1 << 27)       /* shfclk free */
 
 #define FP_PM_P                                (1 << 24)       /* panel power ctl */
index 889cbe39e5800a27346cdc7377e6662d915bd459..1a18da86d3fa3cbde2b899831ec136a178527340 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/string.h>
 #include <linux/console.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/suspend.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
index 0e5d8c7c3ebae2ad81a62bd693c857e10771f01a..bc35a95e59d417ef85df900e26824f5de67eaa35 100644 (file)
@@ -274,7 +274,15 @@ static void lx_graphics_enable(struct fb_info *info)
                u32 msrlo, msrhi;
 
                write_fp(par, FP_PT1, 0);
-               write_fp(par, FP_PT2, FP_PT2_SCRC);
+               temp = FP_PT2_SCRC;
+
+               if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
+                       temp |= FP_PT2_HSP;
+
+               if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
+                       temp |= FP_PT2_VSP;
+
+               write_fp(par, FP_PT2, temp);
                write_fp(par, FP_DFC, FP_DFC_BC);
 
                msrlo = MSR_LX_MSR_PADSEL_TFT_SEL_LOW;
index f9d77adf035d92a027ef29a2d376eb2e237b23a9..c77bcc6ab463c2ce1cfd17abdb813d490c4376bd 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index db9b785b56eb929d3baceba900a3f79921c54e57..8bbf251f83d9800ffef5dbe6efccc02105f5b065 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/init.h>
index bf78779199c6ff48fd253993d451b15ee8d74637..393f3f3d3dfe4149957c524d1cd56de8011c42e0 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
index b8ebff1e8493e2290b21530ad5086b5d55172089..c8e280f1bb0bf78181570a8d9b36956d55683ae6 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
index 9dd55e5324a13d9653b0b77a0a77ca1e8f9be751..cd2c728a809bd0f8338e7b0b6ac844197893779d 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/fb.h>
 #include "i810.h"
index 15d50b9906ced3eb1d76da6e1bc45844d9165f99..efb2c10656b0a89aa88d23276d47926805bbb4b2 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index 81627466804e1f7ceeba08f63bf7517562ac3ef4..38065cf94ac4cf5dbaf195233871712af4607ab6 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/ioport.h>
index e145e2d16fe37414d40e7c1ce4df3831b3752ddc..1db55f128490213ebfc35a6ad6ed87176af670fb 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
index f3728ab262f8a7d7c9c63b5d93940e5c7f4e37b7..403b14445a7830c7c29744acb8e92d6c9eb3ab2f 100644 (file)
@@ -13,6 +13,7 @@
 #include "matroxfb_base.h"
 #include "matroxfb_maven.h"
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/i2c-algo-bit.h>
 
 /* MGA-TVO I2C for G200, G400 */
index 7064fb4427b6f44b2c45fd26860e31a2e6ccdefc..052dd9f0b7607978fd50a22c8502f5134d903dbe 100644 (file)
 #include "matroxfb_g450.h"
 #include <linux/matroxfb.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 
 #ifdef CONFIG_PPC_PMAC
index 78414baa5a54f185da5d43f2b9deaa7c70e66e0d..d7112c39614b0006736c8b9ea76f91e07a748683 100644 (file)
@@ -15,6 +15,7 @@
 #include "matroxfb_misc.h"
 #include "matroxfb_DAC1064.h"
 #include <linux/matroxfb.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 
 /* **************************************************** */
index 91af9159111ffb58c83fb3f572c0c8a48417934c..1e3e8f19783e30f408ca82a480b92832ee437423 100644 (file)
@@ -17,6 +17,7 @@
 #include "matroxfb_DAC1064.h"
 #include <linux/i2c.h>
 #include <linux/matroxfb.h>
+#include <linux/slab.h>
 #include <asm/div64.h>
 
 #define MGATVO_B       1
index 7854c7a37dc58430e3751ebedbce9c6286cf6280..5cf52d3c8e75065bddeed87299c7aef7ddd82e87 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
index 049256052b1aff2548ab48ea37b5c07543c62eb7..fe92eed6da70c01bb1a96b07c23f87561d5dac18 100644 (file)
@@ -4,7 +4,7 @@
  * Fujitsu Carmine/Coral-P(A)/Lime framebuffer driver acceleration support
  *
  * (C) 2007 Alexander Shishkin <virtuoso@slind.org>
- * (C) 2009 Valentin Sitdikov <valentin.sitdikov@siemens.com>
+ * (C) 2009 Valentin Sitdikov <v.sitdikov@gmail.com>
  * (C) 2009 Siemens AG
  *
  * This program is free software; you can redistribute it and/or modify
@@ -16,7 +16,9 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #if defined(CONFIG_OF)
 #include <linux/of_platform.h>
 #endif
@@ -329,3 +331,5 @@ void mb862xxfb_init_accel(struct fb_info *info, int xres)
        info->fix.accel = 0xff; /*FIXME: add right define */
 }
 EXPORT_SYMBOL(mb862xxfb_init_accel);
+
+MODULE_LICENSE("GPL v2");
index 15b8b3c4330ec3b3aca5813a985ef87101dcb295..ecad96524570882b143827c9cfc10aa29c0b9a97 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 
 #define BIG_BUFFER_SIZE        (1024)
 
index 661bfd20d1943e805dd6aa2865d4c2f361a38eb1..9b3d6e4584cca075387682eaf18ba3b76038a03b 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index b895aae41630b3d1b6dd90b54038986bf350b331..0a4dbdc1693a4462bddb82cdf5e0b9ab5ec4bed2 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/fb.h>
 #include <linux/kernel.h>
 
index 474421fe79a646dfa98d04ad28c72930061575a5..c1ff271017a93c06e2d2594c4ea2de9d541e3264 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/spinlock.h>
 #include <linux/clk.h>
 #include <linux/io.h>
index ebbae87885b69f1ff5e09ba46363970e82fc25f2..d2a091cebe2c31f42edabb2524d7053acc5956e3 100644 (file)
@@ -15,6 +15,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
index c9e9349451cbbbaa097ff71b08148c14cc4570ae..f239f4a25e014d5f93b6099c7024a85f5de4f88e 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 #include <mach/msm_fb.h>
 
 static DECLARE_WAIT_QUEUE_HEAD(nt35399_vsync_wait);
index 71048e78f7f01810404dc687a51f94f6d5696fdc..f9bc932ac46b32809ff3ff4d9b13fe8a4d459b5d 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <mach/msm_fb.h>
 
 
index 6c519e2fa2b7a1bece0557f23e082c22f673f621..19c01c6208e880d4090dd845c358f96d3e2c6be9 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/clk.h>
 #include <linux/file.h>
 #include <linux/major.h>
+#include <linux/slab.h>
 
 #include <mach/msm_iomap.h>
 #include <mach/msm_fb.h>
index 49101dda45ee5906b8abb1fcd1e3cf23eff1ec98..debe5933fd2e6c0d3c3e272242e093632f2732cf 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/module.h>
 #include <linux/fb.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 
 #include <linux/freezer.h>
index 443e3c85a9a0a677c12c2840899b55c209b261be..2fb552a6f32cf52910e551f989dbdbf6c0d30c74 100644 (file)
@@ -94,6 +94,7 @@ static struct backlight_ops nvidia_bl_ops = {
 
 void nvidia_bl_init(struct nvidia_par *par)
 {
+       struct backlight_properties props;
        struct fb_info *info = pci_get_drvdata(par->pci_dev);
        struct backlight_device *bd;
        char name[12];
@@ -109,7 +110,10 @@ void nvidia_bl_init(struct nvidia_par *par)
 
        snprintf(name, sizeof(name), "nvidiabl%d", info->node);
 
-       bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+       bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops,
+                                      &props);
        if (IS_ERR(bd)) {
                info->bl_dev = NULL;
                printk(KERN_WARNING "nvidia: Backlight registration failed\n");
@@ -121,7 +125,6 @@ void nvidia_bl_init(struct nvidia_par *par)
                0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL,
                0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL);
 
-       bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
        bd->props.brightness = bd->props.max_brightness;
        bd->props.power = FB_BLANK_UNBLANK;
        backlight_update_status(bd);
index 6aaddb4f678897383b187cf45decea12166c13e9..d7994a1732459d831775374d61f135ecaf5e06c5 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/fb.h>
 
index 73afd7eb9977b4b34d22254aa3f57bb6199a3426..3bc13df4b120fd12c9d888a40de7bef5f7ed3372 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/fb.h>
 
index eef2bb298d9f08b4c831a4cce8a78ec7ab5ff965..2f2e162134fabe193add5d945cfc69a725aa6f03 100644 (file)
@@ -50,6 +50,7 @@
 #include <video/vga.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include "nv_type.h"
 #include "nv_local.h"
 #include "nv_proto.h"
index b043ac83c41265b884bbe07e2510519be4ba91dd..61f8b8f919b07417a78c29be1592abbb690217d7 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index e192b058a6888002ddecbcfed4413ec85269da58..529483467abf0254fbe6da582c938e57c8494e8a 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <plat/sram.h>
 #include <plat/board.h>
index abe1c76a3257249cf7e6eaca2cc2965dd145d079..64dcc7439c991f704d7920897a715941bfba4c7e 100644 (file)
@@ -20,6 +20,7 @@
  */
 #include <linux/device.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/spi/spi.h>
 
index 9557f963662e2fb42b1a40a0119fc38b495d7f94..43ab7d8b66b2bf9e32d2e687747a8e6427daa6d5 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/vmalloc.h>
 #include <linux/clk.h>
+#include <linux/gfp.h>
 
 #include <mach/lcdc.h>
 #include <plat/dma.h>
index 8ce60e1b220a23f366a9eb886a0460efe634a4b5..e264efd0278f24cf2fa9650e4002d25a0c7160c2 100644 (file)
@@ -26,6 +26,7 @@
  */
 #include <linux/platform_device.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 
 #include <plat/dma.h>
index c59e4baed8b2b7d780a67c24bd45ce50c25b4de7..300eff5de1b4830490e6a5f36d48adf8b63a5b1e 100644 (file)
@@ -116,6 +116,24 @@ static int generic_panel_resume(struct omap_dss_device *dssdev)
        return 0;
 }
 
+static void generic_panel_set_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
+{
+       dpi_set_timings(dssdev, timings);
+}
+
+static void generic_panel_get_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
+{
+       *timings = dssdev->panel.timings;
+}
+
+static int generic_panel_check_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
+{
+       return dpi_check_timings(dssdev, timings);
+}
+
 static struct omap_dss_driver generic_driver = {
        .probe          = generic_panel_probe,
        .remove         = generic_panel_remove,
@@ -125,6 +143,10 @@ static struct omap_dss_driver generic_driver = {
        .suspend        = generic_panel_suspend,
        .resume         = generic_panel_resume,
 
+       .set_timings    = generic_panel_set_timings,
+       .get_timings    = generic_panel_get_timings,
+       .check_timings  = generic_panel_check_timings,
+
        .driver         = {
                .name   = "generic_panel",
                .owner  = THIS_MODULE,
index fcd6a61a91ebf73d519385c9c1c3a2247a30da62..4f3988a4108215eba3a0e504a5aef2b3e6ba3d97 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/gpio.h>
 #include <linux/completion.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 #include <plat/display.h>
 
@@ -486,6 +487,7 @@ static struct attribute_group taal_attr_group = {
 
 static int taal_probe(struct omap_dss_device *dssdev)
 {
+       struct backlight_properties props;
        struct taal_data *td;
        struct backlight_device *bldev;
        int r;
@@ -520,11 +522,16 @@ static int taal_probe(struct omap_dss_device *dssdev)
 
        /* if no platform set_backlight() defined, presume DSI backlight
         * control */
+       memset(&props, 0, sizeof(struct backlight_properties));
        if (!dssdev->set_backlight)
                td->use_dsi_bl = true;
 
+       if (td->use_dsi_bl)
+               props.max_brightness = 255;
+       else
+               props.max_brightness = 127;
        bldev = backlight_device_register("taal", &dssdev->dev, dssdev,
-                       &taal_bl_ops);
+                                         &taal_bl_ops, &props);
        if (IS_ERR(bldev)) {
                r = PTR_ERR(bldev);
                goto err2;
@@ -534,13 +541,10 @@ static int taal_probe(struct omap_dss_device *dssdev)
 
        bldev->props.fb_blank = FB_BLANK_UNBLANK;
        bldev->props.power = FB_BLANK_UNBLANK;
-       if (td->use_dsi_bl) {
-               bldev->props.max_brightness = 255;
+       if (td->use_dsi_bl)
                bldev->props.brightness = 255;
-       } else {
-               bldev->props.max_brightness = 127;
+       else
                bldev->props.brightness = 127;
-       }
 
        taal_bl_update_status(bldev);
 
index d578feee3550b53a29c70c26eeb6851e9ada1ce5..e866e76b13d02bfc746656c33d1167d94d7d84fb 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/gpio.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <plat/display.h>
 
index 8254a4232a536d3c844214e165bd67507d94c943..54344184dd733ceae5df78e9cff33ffa51c7629f 100644 (file)
@@ -590,6 +590,9 @@ int dss_init(bool skip_init)
                }
        }
 
+       dss.dsi_clk_source = DSS_SRC_DSS1_ALWON_FCLK;
+       dss.dispc_clk_source = DSS_SRC_DSS1_ALWON_FCLK;
+
        dss_save_context();
 
        rev = dss_read_reg(DSS_REVISION);
index 9acef00c47eaad1c4727c1721c01ccb10c85684d..0820986d4a68b986fb66e303bc22e8fd997a540c 100644 (file)
@@ -23,6 +23,7 @@
 #define DSS_SUBSYS_NAME "MANAGER"
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
index aed3f31943478d6c8c52d6a43b1c87963d5bd1ce..82336583adeffa7333975ba71d3796a604e1981b 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/kobject.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <plat/display.h>
 #include <plat/cpu.h>
index 4a76917b7cc8dcd6e0aa6787477ce37168dcfd78..4b4506da96da360ad706f0fbc59716dd8013cd8d 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/module.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/fb.h>
 #include <linux/dma-mapping.h>
 #include <linux/vmalloc.h>
index 55a4de5e5d10df6cc45c7dd6c9ef68c97636cd40..3b1237ad85ed384a3adba6dfe07451d2a732ed11 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/bootmem.h>
 #include <linux/completion.h>
@@ -511,13 +512,14 @@ static u32 omap_vram_sdram_size __initdata;
 static u32 omap_vram_def_sdram_size __initdata;
 static u32 omap_vram_def_sdram_start __initdata;
 
-static void __init omap_vram_early_vram(char **p)
+static int __init omap_vram_early_vram(char *p)
 {
-       omap_vram_def_sdram_size = memparse(*p, p);
-       if (**p == ',')
-               omap_vram_def_sdram_start = simple_strtoul((*p) + 1, p, 16);
+       omap_vram_def_sdram_size = memparse(p, &p);
+       if (*p == ',')
+               omap_vram_def_sdram_start = simple_strtoul(p + 1, &p, 16);
+       return 0;
 }
-__early_param("vram=", omap_vram_early_vram);
+early_param("vram", omap_vram_early_vram);
 
 /*
  * Called from map_io. We need to call to this early enough so that we
index 5137aa016b833589b3ed2855daba5e076a2183d6..0d6f2cda93696fa96322d77a15f122d81555311a 100644 (file)
@@ -23,6 +23,7 @@
  */
 #include <linux/module.h>
 #include <linux/video_output.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/ctype.h>
 
index 7fa4ab01b0d36281536875ed1d28e68606d78984..81440f2b90919c2e9904343c24528fe989472270 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
index 0a366d86f08ea8faf50918128266431e9f4abd21..8a204e7a5b5b655a95897ba533c12b032434f16b 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index 6515ec11c16ba250f55f6cbe6a10b6a74f7effca..838424817de2307e0af1c92358ebaf412d5b7c92 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
index 4db6b48a87155b1f7316ad6f5145d37922edec8f..b2252fea2858c732533af9063c889931ab27c895 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index 2aa09bce3944bdb2b0b9fb73fbf878d5fb31aff7..5ec4f2d439c949efd03f8b6d6024ac77cea81e83 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/tty.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
@@ -29,6 +28,7 @@
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
+#include <linux/gfp.h>
 #include <asm/uaccess.h>
 #include <mach/gpio.h>
 
index 75285d3f393cba74c77eb35017e98b229d639769..c91a7f70f7b086f56882ba07f97ba38e314adfd6 100644 (file)
@@ -668,7 +668,7 @@ static int __init pxa168fb_probe(struct platform_device *pdev)
        /*
         * Map LCD controller registers.
         */
-       fbi->reg_base = ioremap_nocache(res->start, res->end - res->start);
+       fbi->reg_base = ioremap_nocache(res->start, resource_size(res));
        if (fbi->reg_base == NULL) {
                ret = -ENOMEM;
                goto failed;
index de40a626dc76b0effe165e84d258e816ccabf409..fc32c323a38115c6e7430767d607dfc06e920545 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
index d94c57ffbdb1661b4c7b3476ce406275388980ca..618f36bec10d10ed5ece287e19e02909506e11a3 100644 (file)
@@ -338,6 +338,7 @@ static struct backlight_ops riva_bl_ops = {
 
 static void riva_bl_init(struct riva_par *par)
 {
+       struct backlight_properties props;
        struct fb_info *info = pci_get_drvdata(par->pdev);
        struct backlight_device *bd;
        char name[12];
@@ -353,7 +354,10 @@ static void riva_bl_init(struct riva_par *par)
 
        snprintf(name, sizeof(name), "rivabl%d", info->node);
 
-       bd = backlight_device_register(name, info->dev, par, &riva_bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+       bd = backlight_device_register(name, info->dev, par, &riva_bl_ops,
+                                      &props);
        if (IS_ERR(bd)) {
                info->bl_dev = NULL;
                printk(KERN_WARNING "riva: Backlight registration failed\n");
@@ -365,7 +369,6 @@ static void riva_bl_init(struct riva_par *par)
                MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL,
                FB_BACKLIGHT_MAX);
 
-       bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
        bd->props.brightness = bd->props.max_brightness;
        bd->props.power = FB_BLANK_UNBLANK;
        backlight_update_status(bd);
index 7b63429f1a7cc17bc2e1da3190473241d1ca9249..a6247fc081ab9fb80671b6fd34b611d0484586d5 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/fb.h>
 #include <linux/spinlock_types.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
index 53cb722c45a02f37e23403e2b0874d110c8e25c5..9682ecc60e12f4f4719ff0ef082948a74fe9d102 100644 (file)
@@ -16,8 +16,8 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <linux/init.h>
-#include <linux/gfp.h>
 #include <linux/clk.h>
 #include <linux/fb.h>
 #include <linux/io.h>
index c3fad34309eda24e32f5be510d6385f873d7f643..d4471b4c037476e82a8ade24acac32164fc6727e 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/tty.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/svga.h>
index 574b29e9f8f2dff6782a27d997001f861f750609..ed371c868b3ac6d7ab0c171689415092d55dc9b7 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/pci.h>
 #include <linux/fb.h>
 
index 9f6d6e61f0cc73a91f6ce93c959b61b090f38464..bea38fce2470298f4bf27345ab72b0007abb260b 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/sh7760fb.h>
 
index bbd1dbf4026a32439bf5ef7b96b037974c5c6416..e8c769944812e90a81b7d0cf8bdbe5d3f5525fc8 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/interrupt.h>
 #include <linux/vmalloc.h>
 #include <linux/ioctl.h>
+#include <linux/slab.h>
 #include <video/sh_mobile_lcdc.h>
 #include <asm/atomic.h>
 
@@ -694,6 +695,7 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
         * 1) Enable Runtime PM
         * 2) Force Runtime PM Resume since hardware is accessed from probe()
         */
+       priv->dev = &pdev->dev;
        pm_runtime_enable(priv->dev);
        pm_runtime_resume(priv->dev);
        return 0;
@@ -956,25 +958,24 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
 
        if (!pdev->dev.platform_data) {
                dev_err(&pdev->dev, "no platform data defined\n");
-               error = -EINVAL;
-               goto err0;
+               return -EINVAL;
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        i = platform_get_irq(pdev, 0);
        if (!res || i < 0) {
                dev_err(&pdev->dev, "cannot get platform resources\n");
-               error = -ENOENT;
-               goto err0;
+               return -ENOENT;
        }
 
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv) {
                dev_err(&pdev->dev, "cannot allocate device data\n");
-               error = -ENOMEM;
-               goto err0;
+               return -ENOMEM;
        }
 
+       platform_set_drvdata(pdev, priv);
+
        error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED,
                            dev_name(&pdev->dev), priv);
        if (error) {
@@ -983,8 +984,6 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
        }
 
        priv->irq = i;
-       priv->dev = &pdev->dev;
-       platform_set_drvdata(pdev, priv);
        pdata = pdev->dev.platform_data;
 
        j = 0;
@@ -1098,9 +1097,9 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
                info = ch->info;
 
                if (info->fbdefio) {
-                       priv->ch->sglist = vmalloc(sizeof(struct scatterlist) *
+                       ch->sglist = vmalloc(sizeof(struct scatterlist) *
                                        info->fix.smem_len >> PAGE_SHIFT);
-                       if (!priv->ch->sglist) {
+                       if (!ch->sglist) {
                                dev_err(&pdev->dev, "cannot allocate sglist\n");
                                goto err1;
                        }
@@ -1125,9 +1124,9 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
        }
 
        return 0;
- err1:
+err1:
        sh_mobile_lcdc_remove(pdev);
- err0:
+
        return error;
 }
 
@@ -1138,7 +1137,7 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
        int i;
 
        for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
-               if (priv->ch[i].info->dev)
+               if (priv->ch[i].info && priv->ch[i].info->dev)
                        unregister_framebuffer(priv->ch[i].info);
 
        sh_mobile_lcdc_stop(priv);
@@ -1161,7 +1160,8 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
        if (priv->dot_clk)
                clk_put(priv->dot_clk);
 
-       pm_runtime_disable(priv->dev);
+       if (priv->dev)
+               pm_runtime_disable(priv->dev);
 
        if (priv->base)
                iounmap(priv->base);
index 79840f11fecbba5467388cd1987be73401343044..dee64c3b1e678f06c1878d769c3652457cbb4441 100644 (file)
@@ -86,7 +86,6 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <asm/io.h>
 #include <linux/uaccess.h>
 #include <video/sstfb.h>
index a8248c0b9192d4425411971006c785f47d0ff43c..23e69e834a18de9b3e97056f5b6aebc85bea008f 100644 (file)
@@ -5,7 +5,6 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/of_device.h>
index b1dde09e70156d31c8cfcd7a5345b241155875d7..5848436c19da294040fd3e5a9e652809b89b702b 100644 (file)
@@ -5,7 +5,6 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/fb.h>
 #include <linux/pci.h>
 #include <linux/init.h>
index 4cd50497264d3c65d092e1ca9c4fd55d2a7d0e22..b9c2b948d34d515b4cdccaa6c70d5ab1da29e063 100644 (file)
@@ -5,7 +5,6 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/fb.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -242,11 +241,27 @@ static int __devinit e3d_set_fbinfo(struct e3d_info *ep)
 static int __devinit e3d_pci_register(struct pci_dev *pdev,
                                      const struct pci_device_id *ent)
 {
+       struct device_node *of_node;
+       const char *device_type;
        struct fb_info *info;
        struct e3d_info *ep;
        unsigned int line_length;
        int err;
 
+       of_node = pci_device_to_OF_node(pdev);
+       if (!of_node) {
+               printk(KERN_ERR "e3d: Cannot find OF node of %s\n",
+                      pci_name(pdev));
+               return -ENODEV;
+       }
+
+       device_type = of_get_property(of_node, "device_type", NULL);
+       if (!device_type) {
+               printk(KERN_INFO "e3d: Ignoring secondary output device "
+                      "at %s\n", pci_name(pdev));
+               return -ENODEV;
+       }
+
        err = pci_enable_device(pdev);
        if (err < 0) {
                printk(KERN_ERR "e3d: Cannot enable PCI device %s\n",
@@ -265,13 +280,7 @@ static int __devinit e3d_pci_register(struct pci_dev *pdev,
        ep->info = info;
        ep->pdev = pdev;
        spin_lock_init(&ep->lock);
-       ep->of_node = pci_device_to_OF_node(pdev);
-       if (!ep->of_node) {
-               printk(KERN_ERR "e3d: Cannot find OF node of %s\n",
-                      pci_name(pdev));
-               err = -ENODEV;
-               goto err_release_fb;
-       }
+       ep->of_node = of_node;
 
        /* Read the PCI base register of the frame buffer, which we
         * need in order to interpret the RAMDAC_VID_*FB* values in
index 9c7106701572409a967e563585209f1e9cb5198c..fdb45674e2f628b906e3997cf22eebe7c38f6711 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/string.h>
 #include <linux/fb.h>
 #include <linux/svga.h>
-#include <linux/slab.h>
 #include <asm/types.h>
 #include <asm/io.h>
 
index a352d5f46bbf08be1badbe0b23313fc07d8f4090..844a32fd38ed9640b5197e6e963a3f960e6f11b8 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/fb.h>
-#include <linux/slab.h>
 #include <asm/types.h>
 #include <asm/io.h>
 #include "fb_draw.h"
index 45b883598bf02739083c19ba32106fe527dda081..c0c2b18fcdcff6229bdd7afaffa2cbd36c30a891 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
index a86046ff60ad527f7f10cf16a0451df33abc45a2..1b3b1c718e80d4cd775b359464a73321ac70a3b6 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/selection.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/tc.h>
 
index 03a9c35e9f552a951ff9ed6798536633d515e020..c6c77562839d9663cef133f9b23e0d1607a5d2c8 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include <linux/delay.h>
 #include <video/vga.h>
index 54fbb2995a5f3007d2ed5fbceea54738e9314904..7b8839ebf3c402ced009123ac6260c97a51a922a 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/fb.h>
 #include <linux/io.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <video/edid.h>
 #include <video/uvesafb.h>
 #ifdef CONFIG_X86
index c18f1884b550b923d797e6b1d8b1eb768edb266a..931a567f9aff4219cf015f7855189725313b810b 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/fb.h>
 #include <linux/pci.h>
index ef4128c8e57af0a31833908b00be09732c8a4fd7..0cadf7aee27e3e9e3b6181655e6401ef034393d3 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/ioport.h>
@@ -226,7 +225,7 @@ static int __init vesafb_setup(char *options)
        return 0;
 }
 
-static int __devinit vesafb_probe(struct platform_device *dev)
+static int __init vesafb_probe(struct platform_device *dev)
 {
        struct fb_info *info;
        int i, err;
@@ -477,7 +476,6 @@ err:
 }
 
 static struct platform_driver vesafb_driver = {
-       .probe  = vesafb_probe,
        .driver = {
                .name   = "vesafb",
        },
@@ -493,20 +491,21 @@ static int __init vesafb_init(void)
        /* ignore error return of fb_get_options */
        fb_get_options("vesafb", &option);
        vesafb_setup(option);
-       ret = platform_driver_register(&vesafb_driver);
 
-       if (!ret) {
-               vesafb_device = platform_device_alloc("vesafb", 0);
+       vesafb_device = platform_device_alloc("vesafb", 0);
+       if (!vesafb_device)
+               return -ENOMEM;
 
-               if (vesafb_device)
-                       ret = platform_device_add(vesafb_device);
-               else
-                       ret = -ENOMEM;
+       ret = platform_device_add(vesafb_device);
+       if (!ret) {
+               ret = platform_driver_probe(&vesafb_driver, vesafb_probe);
+               if (ret)
+                       platform_device_del(vesafb_device);
+       }
 
-               if (ret) {
-                       platform_device_put(vesafb_device);
-                       platform_driver_unregister(&vesafb_driver);
-               }
+       if (ret) {
+               platform_device_put(vesafb_device);
+               vesafb_device = NULL;
        }
 
        return ret;
index b8ab995fbda75f92248e62f6508deefb917ca034..9b5532b4de35fe9f622b37a7d1fbe14815ba5049 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index 76d8dae5b1bb44d6ab7e7dc67ed0c3cf60c95b7c..bf638a47a5b3957da6e02c429d5f27d442476b19 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/ioport.h>
index ce7783b63f6a6c39881da9e7f6b81647f039256d..777b38a06d40b2390a0cc8778ba5212546ff74f5 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/module.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/stat.h>
 #define _MASTER_FILE
 
index 65ccd215d4969672fa218ee0d44c6a39705779ab..d31dc96f838a29576d1c11a0cbd6857d266475ac 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/tty.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/svga.h>
index 5d223959778a7898b6abc2ae5822f17635952e04..31b0e17ed090f4316dc39fed9c99e73ba2455893 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
 #include <asm/io.h>
index 603598f4dbb1a5ddc969478d42a41912d1bfe1fe..fa97d3e7c21ab2e9c7ae0098971f6b3530845a60 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/errno.h>
 #include <linux/fb.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 
index ed7c8d0ddccb47394b2cff3dd6608a826a8d0a7c..3fcb83f03881e58f94c27004e05ebdd82eca8e93 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/of_platform.h>
 #include <linux/io.h>
 #include <linux/xilinxfb.h>
+#include <linux/slab.h>
 #include <asm/dcr.h>
 
 #define DRIVER_NAME            "xilinxfb"
index 369f2eebbad14d5a2999712549894260f4e407e4..bfec7c29486df963c16c2f3a1f292242eedc09eb 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 struct virtio_balloon
 {
@@ -102,7 +103,8 @@ static void fill_balloon(struct virtio_balloon *vb, size_t num)
        num = min(num, ARRAY_SIZE(vb->pfns));
 
        for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) {
-               struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY);
+               struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY |
+                                       __GFP_NOMEMALLOC | __GFP_NOWARN);
                if (!page) {
                        if (printk_ratelimit())
                                dev_printk(KERN_INFO, &vb->vdev->dev,
index 625447f645d935d59cc23ee5813357ae044ae8ce..24747aef1952880ca686a1b8d9506acb1e174f55 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/list.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/virtio.h>
 #include <linux/virtio_config.h>
index 0db906b3c95d71bd985fa97b2fc62c52a7244104..0f90634bcb85d170e64ce6e2addee12f5fb37f82 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/virtio_ring.h>
 #include <linux/virtio_config.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 
 /* virtio guest is communicating with a virtual "device" that actually runs on
  * a host processor.  Memory barriers are used to control SMP effects. */
index 9554ad5f9af799641e6eda438f136886704a061a..f2d9e667972da120d3c39ab87965566fe5c13506 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <linux/vlynq.h>
 
index 37f08c85060877508a85ed58cdf0e2a7974fb67b..6b85e7fefa43c52a5636b8a9ec41fb8c30503418 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/ds1wm.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 
index 59ad6e95af8f0b0dded05413115c45bee2d2276b..02bf7bf7160bcbb79e2d94b36e4fa32022ff3be0 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/mod_devicetable.h>
 #include <linux/usb.h>
+#include <linux/slab.h>
 
 #include "../w1_int.h"
 #include "../w1.h"
index 492670358cbf1ad7e00a1ac59617e69dc0109e2f..a3b6a74c67a729b93949a1e06c89c40cf252c1a1 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 
index 22977d30f89e58660b99ee62f406a3a3c7eefd76..3a7e9ff8a7462cd38df8d12cff80ff44ac5d2739 100644 (file)
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/sched.h>
 
 #include <asm/irq.h>
 #include <mach/hardware.h>
index 6f8866d6a905fd746256bb6bb3b0b90e6f308834..fcbe742188a50e93b15105e6ccfa77d7a53663a6 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/w1-gpio.h>
 
 #include "../w1.h"
index 1394471488228d2f747475256a3236103a7973f4..d2bf32118a987c91e334b01591336291ebf1c192 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/device.h>
 #include <linux/types.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #ifdef CONFIG_W1_SLAVE_DS2433_CRC
 #include <linux/crc16.h>
 
index 59f708efe25f061b0573358d028d317622fe41a7..6e153343e117fe4b0a5b56ad615ff1b9d780e17b 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
 #include <linux/idr.h>
+#include <linux/gfp.h>
 
 #include "../w1.h"
 #include "../w1_int.h"
index 1ed3d554e3728a1f7b6fb51501b1df52d26f514d..17726a05a0a62849bcf09918b622b45fbd761351 100644 (file)
@@ -115,9 +115,8 @@ static struct w1_therm_family_converter w1_therm_families[] = {
 
 static inline int w1_DS18B20_convert_temp(u8 rom[9])
 {
-       int t = ((s16)rom[1] << 8) | rom[0];
-       t = t*1000/16;
-       return t;
+       s16 t = le16_to_cpup((__le16 *)rom);
+       return t*1000/16;
 }
 
 static inline int w1_DS18S20_convert_temp(u8 rom[9])
index 4a46ed58ece938621ea3dc3c016efff9f053379f..b50be3f1073d0fc92af534cc61dc757408e57a5b 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/list.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 #include "w1.h"
 #include "w1_log.h"
index 45c126fea31dcdad608a666964d316214386e1fb..7e667bc77ef2d02649fbe32cd69b4ab94e06e9f6 100644 (file)
@@ -19,6 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/netlink.h>
 #include <linux/connector.h>
index bdcdbd53da894b826d1abb3690fbc87b6be15f75..b87ba23442d26e2118a5437cadc57272358dd042 100644 (file)
@@ -55,11 +55,6 @@ config SOFT_WATCHDOG
          To compile this driver as a module, choose M here: the
          module will be called softdog.
 
-config MAX63XX_WATCHDOG
-       tristate "Max63xx watchdog"
-       help
-         Support for memory mapped max63{69,70,71,72,73,74} watchdog timer.
-
 config WM831X_WATCHDOG
        tristate "WM831x watchdog"
        depends on MFD_WM831X
@@ -180,7 +175,7 @@ config SA1100_WATCHDOG
 
 config MPCORE_WATCHDOG
        tristate "MPcore watchdog"
-       depends on ARM_MPCORE_PLATFORM && LOCAL_TIMERS
+       depends on HAVE_ARM_TWD
        help
          Watchdog timer embedded into the MPcore system.
 
@@ -199,10 +194,10 @@ config EP93XX_WATCHDOG
 
 config OMAP_WATCHDOG
        tristate "OMAP Watchdog"
-       depends on ARCH_OMAP16XX || ARCH_OMAP2 || ARCH_OMAP3
+       depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
        help
-         Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog.  Say 'Y'
-         here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog timer.
+         Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog.  Say 'Y'
+         here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer.
 
 config PNX4008_WATCHDOG
        tristate "PNX4008 Watchdog"
@@ -305,6 +300,12 @@ config TS72XX_WATCHDOG
          To compile this driver as a module, choose M here: the
          module will be called ts72xx_wdt.
 
+config MAX63XX_WATCHDOG
+       tristate "Max63xx watchdog"
+       depends on ARM && HAS_IOMEM
+       help
+         Support for memory mapped max63{69,70,71,72,73,74} watchdog timer.
+
 # AVR32 Architecture
 
 config AT32AP700X_WDT
index a5ca7a6ee133a3fbd0524c5063fe3b0f5faf52b5..af6e6b16475afeb831f16df00e846f160f452647 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <linux/io.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
index 6873376f986c1ea69dd93b085a64aafd7ba7b90c..1cddf92cb9a604f8afd43312af0b46ef4d145bd8 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 
 #define TIMEOUT_MIN            1
 #define TIMEOUT_MAX            2
index 8b724aad6825929b334375075eda02deab687084..801ead1914999c435b36fba4624329758936aadf 100644 (file)
@@ -44,7 +44,7 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT;
 
 #ifdef CONFIG_FSL_BOOKE
 #define WDTP(x)                ((((x)&0x3)<<30)|(((x)&0x3c)<<15))
-#define WDTP_MASK      (WDTP(0))
+#define WDTP_MASK      (WDTP(0x3f))
 #else
 #define WDTP(x)                (TCR_WP(x))
 #define WDTP_MASK      (TCR_WP_MASK)
@@ -121,7 +121,7 @@ static ssize_t booke_wdt_write(struct file *file, const char __user *buf,
        return count;
 }
 
-static const struct watchdog_info ident = {
+static struct watchdog_info ident = {
        .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
        .identity = "PowerPC Book-E Watchdog",
 };
index 37ea052d4dee95d2483a8ffca20fcb5e81cf963e..ba2efce4b40ef795ee7f7fd6e3ca469d3f0f5a43 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/io.h>
 #include <linux/of.h>
index 56162c87f5d8b4bb4eb881f3cd23d434b507c5e7..596ba604e78d11cdc1e451d80281c69de1825e32 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/io.h>
 #include <linux/device.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 #define MODULE_NAME "DAVINCI-WDT: "
 
index 88ed54e50f74d3768b75fb05485393da4042aa62..59359c9a5e01aafaaa43cba6c8a3fd1ca4842e1c 100644 (file)
@@ -244,7 +244,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
 module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout,
        "Watchdog timeout in seconds. (1<=timeout<=3600, default="
-                               __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
+                               __MODULE_STRING(WDT_TIMEOUT) ")");
 
 MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>,"
                "Alessandro Zummo <a.zummo@towertech.it>");
index 70c2c24660d0e4f2250b2bb06d5ec06717dcbe1d..809e7167a6243fa2b1aeb37c6678be21faf3b01c 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/efi.h>
 #include <linux/string.h>
 #include <linux/bootmem.h>
-#include <linux/slab.h>
 #include <asm/desc.h>
 #include <asm/cacheflush.h>
 
@@ -443,7 +442,7 @@ static void hpwdt_ping(void)
 static int hpwdt_change_timer(int new_margin)
 {
        /* Arbitrary, can't find the card's limits */
-       if (new_margin < 30 || new_margin > 600) {
+       if (new_margin < 5 || new_margin > 600) {
                printk(KERN_WARNING
                        "hpwdt: New value passed in is invalid: %d seconds.\n",
                        new_margin);
index 44bc6aa46edf421e744979fa7e053232e3561b9d..8da8860353748a6fcae9c72cc9e0fd2b1b4deb3c 100644 (file)
@@ -115,8 +115,37 @@ enum iTCO_chipsets {
        TCO_3420,       /* 3420 */
        TCO_3450,       /* 3450 */
        TCO_EP80579,    /* EP80579 */
-       TCO_CPTD,       /* CPT Desktop */
-       TCO_CPTM,       /* CPT Mobile */
+       TCO_CPT1,       /* Cougar Point */
+       TCO_CPT2,       /* Cougar Point Desktop */
+       TCO_CPT3,       /* Cougar Point Mobile */
+       TCO_CPT4,       /* Cougar Point */
+       TCO_CPT5,       /* Cougar Point */
+       TCO_CPT6,       /* Cougar Point */
+       TCO_CPT7,       /* Cougar Point */
+       TCO_CPT8,       /* Cougar Point */
+       TCO_CPT9,       /* Cougar Point */
+       TCO_CPT10,      /* Cougar Point */
+       TCO_CPT11,      /* Cougar Point */
+       TCO_CPT12,      /* Cougar Point */
+       TCO_CPT13,      /* Cougar Point */
+       TCO_CPT14,      /* Cougar Point */
+       TCO_CPT15,      /* Cougar Point */
+       TCO_CPT16,      /* Cougar Point */
+       TCO_CPT17,      /* Cougar Point */
+       TCO_CPT18,      /* Cougar Point */
+       TCO_CPT19,      /* Cougar Point */
+       TCO_CPT20,      /* Cougar Point */
+       TCO_CPT21,      /* Cougar Point */
+       TCO_CPT22,      /* Cougar Point */
+       TCO_CPT23,      /* Cougar Point */
+       TCO_CPT24,      /* Cougar Point */
+       TCO_CPT25,      /* Cougar Point */
+       TCO_CPT26,      /* Cougar Point */
+       TCO_CPT27,      /* Cougar Point */
+       TCO_CPT28,      /* Cougar Point */
+       TCO_CPT29,      /* Cougar Point */
+       TCO_CPT30,      /* Cougar Point */
+       TCO_CPT31,      /* Cougar Point */
 };
 
 static struct {
@@ -173,8 +202,37 @@ static struct {
        {"3420", 2},
        {"3450", 2},
        {"EP80579", 2},
-       {"CPT Desktop", 2},
-       {"CPT Mobile", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
+       {"Cougar Point", 2},
        {NULL, 0}
 };
 
@@ -259,8 +317,37 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = {
        { ITCO_PCI_DEVICE(0x3b14,                               TCO_3420)},
        { ITCO_PCI_DEVICE(0x3b16,                               TCO_3450)},
        { ITCO_PCI_DEVICE(0x5031,                               TCO_EP80579)},
-       { ITCO_PCI_DEVICE(0x1c42,                               TCO_CPTD)},
-       { ITCO_PCI_DEVICE(0x1c43,                               TCO_CPTM)},
+       { ITCO_PCI_DEVICE(0x1c41,                               TCO_CPT1)},
+       { ITCO_PCI_DEVICE(0x1c42,                               TCO_CPT2)},
+       { ITCO_PCI_DEVICE(0x1c43,                               TCO_CPT3)},
+       { ITCO_PCI_DEVICE(0x1c44,                               TCO_CPT4)},
+       { ITCO_PCI_DEVICE(0x1c45,                               TCO_CPT5)},
+       { ITCO_PCI_DEVICE(0x1c46,                               TCO_CPT6)},
+       { ITCO_PCI_DEVICE(0x1c47,                               TCO_CPT7)},
+       { ITCO_PCI_DEVICE(0x1c48,                               TCO_CPT8)},
+       { ITCO_PCI_DEVICE(0x1c49,                               TCO_CPT9)},
+       { ITCO_PCI_DEVICE(0x1c4a,                               TCO_CPT10)},
+       { ITCO_PCI_DEVICE(0x1c4b,                               TCO_CPT11)},
+       { ITCO_PCI_DEVICE(0x1c4c,                               TCO_CPT12)},
+       { ITCO_PCI_DEVICE(0x1c4d,                               TCO_CPT13)},
+       { ITCO_PCI_DEVICE(0x1c4e,                               TCO_CPT14)},
+       { ITCO_PCI_DEVICE(0x1c4f,                               TCO_CPT15)},
+       { ITCO_PCI_DEVICE(0x1c50,                               TCO_CPT16)},
+       { ITCO_PCI_DEVICE(0x1c51,                               TCO_CPT17)},
+       { ITCO_PCI_DEVICE(0x1c52,                               TCO_CPT18)},
+       { ITCO_PCI_DEVICE(0x1c53,                               TCO_CPT19)},
+       { ITCO_PCI_DEVICE(0x1c54,                               TCO_CPT20)},
+       { ITCO_PCI_DEVICE(0x1c55,                               TCO_CPT21)},
+       { ITCO_PCI_DEVICE(0x1c56,                               TCO_CPT22)},
+       { ITCO_PCI_DEVICE(0x1c57,                               TCO_CPT23)},
+       { ITCO_PCI_DEVICE(0x1c58,                               TCO_CPT24)},
+       { ITCO_PCI_DEVICE(0x1c59,                               TCO_CPT25)},
+       { ITCO_PCI_DEVICE(0x1c5a,                               TCO_CPT26)},
+       { ITCO_PCI_DEVICE(0x1c5b,                               TCO_CPT27)},
+       { ITCO_PCI_DEVICE(0x1c5c,                               TCO_CPT28)},
+       { ITCO_PCI_DEVICE(0x1c5d,                               TCO_CPT29)},
+       { ITCO_PCI_DEVICE(0x1c5e,                               TCO_CPT30)},
+       { ITCO_PCI_DEVICE(0x1c5f,                               TCO_CPT31)},
        { 0, },                 /* End of list */
 };
 MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
index 89fcefcc8510da969bfb13a99677e4f73faf7463..195e0f798e769d4fda32ea7e164b3fd818c41d69 100644 (file)
@@ -12,7 +12,6 @@
 
 #include <linux/fs.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/timer.h>
index 6eb91d75760466e83e983ad3875973f4cf8c3264..3053ff05ca410b7d4fba52cadd7d86071d3c4896 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 
 #define DEFAULT_HEARTBEAT 60
 #define MAX_HEARTBEAT     60
@@ -153,9 +154,14 @@ static void max63xx_wdt_enable(struct max63xx_timeout *entry)
 
 static void max63xx_wdt_disable(void)
 {
+       u8 val;
+
        spin_lock(&io_lock);
 
-       __raw_writeb(3, wdt_base);
+       val = __raw_readb(wdt_base);
+       val &= ~MAX6369_WDSET;
+       val |= 3;
+       __raw_writeb(val, wdt_base);
 
        spin_unlock(&io_lock);
 
index b0646dac924e9510e304037933c6d62cb6f599c4..b8ec7aca3c8ea4696c96a5cb2d6f000905577ab9 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <linux/io.h>
 
-#include <asm/hardware/arm_twd.h>
+#include <asm/smp_twd.h>
 
 struct mpcore_wdt {
        unsigned long   timer_alive;
@@ -43,7 +45,7 @@ struct mpcore_wdt {
 };
 
 static struct platform_device *mpcore_wdt_dev;
-extern unsigned int mpcore_timer_rate;
+static DEFINE_SPINLOCK(wdt_lock);
 
 #define TIMER_MARGIN   60
 static int mpcore_margin = TIMER_MARGIN;
@@ -93,13 +95,15 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
  */
 static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt)
 {
-       unsigned int count;
+       unsigned long count;
 
+       spin_lock(&wdt_lock);
        /* Assume prescale is set to 256 */
-       count = (mpcore_timer_rate / 256) * mpcore_margin;
+       count =  __raw_readl(wdt->base + TWD_WDOG_COUNTER);
+       count = (0xFFFFFFFFU - count) * (HZ / 5);
+       count = (count / 256) * mpcore_margin;
 
        /* Reload the counter */
-       spin_lock(&wdt_lock);
        writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
        wdt->perturb = wdt->perturb ? 0 : 1;
        spin_unlock(&wdt_lock);
@@ -118,7 +122,6 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt)
 {
        dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n");
 
-       spin_lock(&wdt_lock);
        /* This loads the count register but does NOT start the count yet */
        mpcore_wdt_keepalive(wdt);
 
@@ -129,7 +132,6 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt)
                /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */
                writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL);
        }
-       spin_unlock(&wdt_lock);
 }
 
 static int mpcore_wdt_set_heartbeat(int t)
@@ -359,7 +361,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
        mpcore_wdt_miscdev.parent = &dev->dev;
        ret = misc_register(&mpcore_wdt_miscdev);
        if (ret) {
-               dev_printk(KERN_ERR, _dev,
+               dev_printk(KERN_ERR, wdt->dev,
                        "cannot register miscdev on minor=%d (err=%d)\n",
                                                        WATCHDOG_MINOR, ret);
                goto err_misc;
@@ -368,13 +370,13 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
        ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED,
                                                        "mpcore_wdt", wdt);
        if (ret) {
-               dev_printk(KERN_ERR, _dev,
+               dev_printk(KERN_ERR, wdt->dev,
                        "cannot register IRQ%d for watchdog\n", wdt->irq);
                goto err_irq;
        }
 
        mpcore_wdt_stop(wdt);
-       platform_set_drvdata(&dev->dev, wdt);
+       platform_set_drvdata(dev, wdt);
        mpcore_wdt_dev = dev;
 
        return 0;
index adefe3a9d510e8e48f6936f4c1db7f73827c428d..6cee33d4b1612cba6ff4ea1b96cfae5691689c36 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/types.h>
 #include <linux/watchdog.h>
index c6aaf2845741379a69235ccc069cc8589600cbf0..76b58abf445182d6708e39f7801c77c062004769 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/bitops.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <mach/hardware.h>
 #include <plat/prcm.h>
 
index 435ec2aed4fe49b8eb956d94301648de350d84e2..2d22e996e9963cedaf656aa1c82867894d14c906 100644 (file)
@@ -52,7 +52,7 @@ static struct {
        struct timer_list timer;        /* The timer that pings the watchdog */
 } pikawdt_private;
 
-static const struct watchdog_info ident = {
+static struct watchdog_info ident = {
        .identity       = DRV_NAME,
        .options        = WDIOF_CARDRESET |
                          WDIOF_SETTIMEOUT |
index c7a9479934af87558e45bf16a036803060ede2f2..bf5b97c546eb4d699edbbd0fa3aa3f22727c7570 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/spinlock.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <mach/hardware.h>
 
 #define MODULE_NAME "PNX4008-WDT: "
index ae57bf9e1b03c49bb2b0e175ed7d1e4c5a6422f2..ea7f803f624862f973a024737d9e49ef039202a0 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/of_device.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 
 
 /* RIO uses the NatSemi Super I/O power management logical device
index 8760a26ab2a3996fd7b48b4615d7d68f85055b1d..e4cebef55177f62e3067e0b2a7195f76ee03d725 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/cpufreq.h>
+#include <linux/slab.h>
 
 #include <mach/map.h>
 
index c8eadd47817585cdd492f8b9c4b3a944ff2b2880..88c83aa5730318b512d86a7a048dc60a9758de46 100644 (file)
@@ -67,8 +67,8 @@ static DEFINE_SPINLOCK(sbwd_lock);
 void sbwdog_set(char __iomem *wdog, unsigned long t)
 {
        spin_lock(&sbwd_lock);
-       __raw_writeb(0, wdog - 0x10);
-       __raw_writeq(t & 0x7fffffUL, wdog);
+       __raw_writeb(0, wdog);
+       __raw_writeq(t & 0x7fffffUL, wdog - 0x10);
        spin_unlock(&sbwd_lock);
 }
 
index 8d44c9b6fb5b75dbfaed1ad674b6665204c9bae2..c7d67e9a74659bc004abd8ba64b39426003cf788 100644 (file)
@@ -30,7 +30,7 @@
 static int nowayout = WATCHDOG_NOWAYOUT;
 static unsigned int margin = 60;       /* (secs) Default is 1 minute */
 static unsigned long wdt_status;
-static DEFINE_SPINLOCK(wdt_lock);
+static DEFINE_MUTEX(wdt_lock);
 
 #define WDT_IN_USE             0
 #define WDT_OK_TO_CLOSE                1
@@ -45,26 +45,26 @@ static DEFINE_SPINLOCK(wdt_lock);
 
 static void wdt_send_data(unsigned char command, unsigned char data)
 {
-       outb(command, COMMAND_PORT);
-       msleep(100);
        outb(data, DATA_PORT);
        msleep(200);
+       outb(command, COMMAND_PORT);
+       msleep(100);
 }
 
 static void wdt_enable(void)
 {
-       spin_lock(&wdt_lock);
+       mutex_lock(&wdt_lock);
        wdt_send_data(IFACE_ON_COMMAND, 1);
        wdt_send_data(REBOOT_COMMAND, margin);
-       spin_unlock(&wdt_lock);
+       mutex_unlock(&wdt_lock);
 }
 
 static void wdt_disable(void)
 {
-       spin_lock(&wdt_lock);
+       mutex_lock(&wdt_lock);
        wdt_send_data(IFACE_ON_COMMAND, 0);
        wdt_send_data(REBOOT_COMMAND, 0);
-       spin_unlock(&wdt_lock);
+       mutex_unlock(&wdt_lock);
 }
 
 static int fitpc2_wdt_open(struct inode *inode, struct file *file)
index 565a2c3321e556e89015a0a576585259d1c3dc2c..458c499c1223c6f73aaab93f9a6bdc7c816de5a2 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/miscdevice.h>
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/watchdog.h>
 #include <linux/uaccess.h>
 
index 8162a40d15220aed9f2b6cfe972f9221a4520166..dcabe77ad14128384b26722fa1e57a7e0d5fe22a 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/watchdog.h>
index f6738d8b02bcdd55d7b3ebdde6782f3394726831..1a0d8c2a0354475bd2c331fe8fd8a3690adc5c20 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/mutex.h>
 #include <linux/list.h>
 #include <linux/sysdev.h>
+#include <linux/gfp.h>
 
 #include <asm/page.h>
 #include <asm/pgalloc.h>
index 2f8413794d05b98b48558ac527af7c1c9d63c566..db8f506817f0ad30f2b54bde0ff778a7405ba59b 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/bootmem.h>
+#include <linux/slab.h>
 
 #include <asm/ptrace.h>
 #include <asm/irq.h>
index f70a4f4698c5994348a14dd216bb91ad72ec5b6a..66e185cfe92fa8bb70c29d27de013fed1685c6d2 100644 (file)
@@ -45,7 +45,6 @@
 #include <linux/poll.h>
 #include <linux/irq.h>
 #include <linux/init.h>
-#include <linux/gfp.h>
 #include <linux/mutex.h>
 #include <linux/cpu.h>
 
index 4c6c0bd636a8073ab743dbcc2a643d3ea7fd73a0..f66db3b91d6100b2fe875d410553ca0038fadabc 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/uaccess.h>
 
index 5d42d55e299bd39cbb869fdc264532fb3b06e9dc..8943b8ccee1a2ba3c35ac8eabfc14bd716fb136c 100644 (file)
@@ -3,6 +3,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/reboot.h>
 #include <linux/sysrq.h>
 #include <linux/stop_machine.h>
@@ -79,12 +80,6 @@ static void do_suspend(void)
 
        shutting_down = SHUTDOWN_SUSPEND;
 
-       err = stop_machine_create();
-       if (err) {
-               printk(KERN_ERR "xen suspend: failed to setup stop_machine %d\n", err);
-               goto out;
-       }
-
 #ifdef CONFIG_PREEMPT
        /* If the kernel is preemptible, we need to freeze all the processes
           to prevent them from being in the middle of a pagetable update
@@ -92,7 +87,7 @@ static void do_suspend(void)
        err = freeze_processes();
        if (err) {
                printk(KERN_ERR "xen suspend: freeze failed %d\n", err);
-               goto out_destroy_sm;
+               goto out;
        }
 #endif
 
@@ -135,12 +130,8 @@ out_resume:
 out_thaw:
 #ifdef CONFIG_PREEMPT
        thaw_processes();
-
-out_destroy_sm:
-#endif
-       stop_machine_destroy();
-
 out:
+#endif
        shutting_down = SHUTDOWN_INVALID;
 }
 #endif /* CONFIG_PM_SLEEP */
index bb71ab2336c896069faadd9e2a18b6633843bc77..60f1827a32cb7fc56b70a8ec829fc3c9fcaaee3c 100644 (file)
@@ -7,6 +7,7 @@
  *  published by the Free Software Foundation.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/kobject.h>
index 92a1ef80a288173a7ccae8d5fc10f484d1acd613..7b3e973a1aee8ca5525ae334efba433d6bd3e12a 100644 (file)
@@ -30,6 +30,7 @@
  * IN THE SOFTWARE.
  */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/vmalloc.h>
 #include <asm/xen/hypervisor.h>
index 2f7aaa99dc47e5d26701308e761612a2cdcbec8e..3479332113e998abfd311ffc079d548a342878c5 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/kthread.h>
 #include <linux/mutex.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
index a240b2c20b9952d4c69a1b365590119bcecef477..b91f8ff50d05996148f6cbc589bcdae06d72efc3 100644 (file)
@@ -18,8 +18,8 @@
  * Authors: Hollis Blanchard <hollisb@us.ibm.com>
  */
 
-#include <linux/gfp.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <asm/page.h>
 #include <xen/xencomm.h>
 #include <xen/interface/xen.h>
index 6c4269b836b7f22ddadc2ca39d5531e467cffc95..f28ece397361c8545549b233a2b563a5ef617285 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/init.h>
 #include <linux/namei.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 
 #include "xenfs.h"
 #include "../xenbus/xenbus_comms.h"
index d47c47fc048f7ff5de17e2f25ec37adb8ac977e3..3c7046d796548e443c120ce491d11d4d834894ec 100644 (file)
@@ -97,7 +97,7 @@ static void zorro_seq_stop(struct seq_file *m, void *v)
 
 static int zorro_seq_show(struct seq_file *m, void *v)
 {
-       u_int slot = *(loff_t *)v;
+       unsigned int slot = *(loff_t *)v;
        struct zorro_dev *z = &zorro_autocon[slot];
 
        seq_printf(m, "%02x\t%08x\t%08lx\t%08lx\t%02x\n", slot, z->id,
@@ -129,7 +129,7 @@ static const struct file_operations zorro_devices_proc_fops = {
 
 static struct proc_dir_entry *proc_bus_zorro_dir;
 
-static int __init zorro_proc_attach_device(u_int slot)
+static int __init zorro_proc_attach_device(unsigned int slot)
 {
        struct proc_dir_entry *entry;
        char name[4];
@@ -146,7 +146,7 @@ static int __init zorro_proc_attach_device(u_int slot)
 
 static int __init zorro_proc_init(void)
 {
-       u_int slot;
+       unsigned int slot;
 
        if (MACH_IS_AMIGA && AMIGAHW_PRESENT(ZORRO)) {
                proc_bus_zorro_dir = proc_mkdir("bus/zorro", NULL);
index 53180a37cc9ad2867cf8eecf4213e3f69009e3a7..7ee2b6e7178643af597273a2263f26b962e6db4f 100644 (file)
@@ -137,10 +137,34 @@ static int zorro_bus_match(struct device *dev, struct device_driver *drv)
        return 0;
 }
 
+static int zorro_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+#ifdef CONFIG_HOTPLUG
+       struct zorro_dev *z;
+
+       if (!dev)
+               return -ENODEV;
+
+       z = to_zorro_dev(dev);
+       if (!z)
+               return -ENODEV;
+
+       if (add_uevent_var(env, "ZORRO_ID=%08X", z->id) ||
+           add_uevent_var(env, "ZORRO_SLOT_NAME=%s", dev_name(dev)) ||
+           add_uevent_var(env, "ZORRO_SLOT_ADDR=%04X", z->slotaddr) ||
+           add_uevent_var(env, "MODALIAS=" ZORRO_DEVICE_MODALIAS_FMT, z->id))
+               return -ENOMEM;
+
+       return 0;
+#else /* !CONFIG_HOTPLUG */
+       return -ENODEV;
+#endif /* !CONFIG_HOTPLUG */
+}
 
 struct bus_type zorro_bus_type = {
        .name   = "zorro",
        .match  = zorro_bus_match,
+       .uevent = zorro_uevent,
        .probe  = zorro_device_probe,
        .remove = zorro_device_remove,
 };
index 1d2a772ea14c017419a145ec3a8be582336cda97..eb924e0a64ce798788e72ce87f4b6937d94d8239 100644 (file)
@@ -77,6 +77,16 @@ static struct bin_attribute zorro_config_attr = {
        .read = zorro_read_config,
 };
 
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
+                            char *buf)
+{
+       struct zorro_dev *z = to_zorro_dev(dev);
+
+       return sprintf(buf, ZORRO_DEVICE_MODALIAS_FMT "\n", z->id);
+}
+
+static DEVICE_ATTR(modalias, S_IRUGO, modalias_show, NULL);
+
 int zorro_create_sysfs_dev_files(struct zorro_dev *z)
 {
        struct device *dev = &z->dev;
@@ -89,6 +99,7 @@ int zorro_create_sysfs_dev_files(struct zorro_dev *z)
            (error = device_create_file(dev, &dev_attr_slotaddr)) ||
            (error = device_create_file(dev, &dev_attr_slotsize)) ||
            (error = device_create_file(dev, &dev_attr_resource)) ||
+           (error = device_create_file(dev, &dev_attr_modalias)) ||
            (error = sysfs_create_bin_file(&dev->kobj, &zorro_config_attr)))
                return error;
 
index d45fb34e2d2371f49b26bfd0f787ac0cb5ddf06b..6455f3a244c594334b04f6c6ac46c2bf527fd1f0 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/zorro.h>
 #include <linux/bitops.h>
 #include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/setup.h>
 #include <asm/amigahw.h>
      *  Zorro Expansion Devices
      */
 
-u_int zorro_num_autocon = 0;
+unsigned int zorro_num_autocon;
 struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO];
 
 
     /*
-     *  Single Zorro bus
+     *  Zorro bus
      */
 
-struct zorro_bus zorro_bus = {\
-    .resources = {
-       /* Zorro II regions (on Zorro II/III) */
-       { .name = "Zorro II exp", .start = 0x00e80000, .end = 0x00efffff },
-       { .name = "Zorro II mem", .start = 0x00200000, .end = 0x009fffff },
-       /* Zorro III regions (on Zorro III only) */
-       { .name = "Zorro III exp", .start = 0xff000000, .end = 0xffffffff },
-       { .name = "Zorro III cfg", .start = 0x40000000, .end = 0x7fffffff }
-    },
-    .name = "Zorro bus"
+struct zorro_bus {
+       struct list_head devices;       /* list of devices on this bus */
+       struct device dev;
 };
 
 
@@ -53,18 +48,19 @@ struct zorro_bus zorro_bus = {\
 
 struct zorro_dev *zorro_find_device(zorro_id id, struct zorro_dev *from)
 {
-    struct zorro_dev *z;
+       struct zorro_dev *z;
 
-    if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
-       return NULL;
+       if (!zorro_num_autocon)
+               return NULL;
 
-    for (z = from ? from+1 : &zorro_autocon[0];
-        z < zorro_autocon+zorro_num_autocon;
-        z++)
-       if (id == ZORRO_WILDCARD || id == z->id)
-           return z;
-    return NULL;
+       for (z = from ? from+1 : &zorro_autocon[0];
+            z < zorro_autocon+zorro_num_autocon;
+            z++)
+               if (id == ZORRO_WILDCARD || id == z->id)
+                       return z;
+       return NULL;
 }
+EXPORT_SYMBOL(zorro_find_device);
 
 
     /*
@@ -83,121 +79,138 @@ struct zorro_dev *zorro_find_device(zorro_id id, struct zorro_dev *from)
      */
 
 DECLARE_BITMAP(zorro_unused_z2ram, 128);
+EXPORT_SYMBOL(zorro_unused_z2ram);
 
 
 static void __init mark_region(unsigned long start, unsigned long end,
                               int flag)
 {
-    if (flag)
-       start += Z2RAM_CHUNKMASK;
-    else
-       end += Z2RAM_CHUNKMASK;
-    start &= ~Z2RAM_CHUNKMASK;
-    end &= ~Z2RAM_CHUNKMASK;
-
-    if (end <= Z2RAM_START || start >= Z2RAM_END)
-       return;
-    start = start < Z2RAM_START ? 0x00000000 : start-Z2RAM_START;
-    end = end > Z2RAM_END ? Z2RAM_SIZE : end-Z2RAM_START;
-    while (start < end) {
-       u32 chunk = start>>Z2RAM_CHUNKSHIFT;
        if (flag)
-           set_bit(chunk, zorro_unused_z2ram);
+               start += Z2RAM_CHUNKMASK;
        else
-           clear_bit(chunk, zorro_unused_z2ram);
-       start += Z2RAM_CHUNKSIZE;
-    }
+               end += Z2RAM_CHUNKMASK;
+       start &= ~Z2RAM_CHUNKMASK;
+       end &= ~Z2RAM_CHUNKMASK;
+
+       if (end <= Z2RAM_START || start >= Z2RAM_END)
+               return;
+       start = start < Z2RAM_START ? 0x00000000 : start-Z2RAM_START;
+       end = end > Z2RAM_END ? Z2RAM_SIZE : end-Z2RAM_START;
+       while (start < end) {
+               u32 chunk = start>>Z2RAM_CHUNKSHIFT;
+               if (flag)
+                       set_bit(chunk, zorro_unused_z2ram);
+               else
+                       clear_bit(chunk, zorro_unused_z2ram);
+               start += Z2RAM_CHUNKSIZE;
+       }
 }
 
 
-static struct resource __init *zorro_find_parent_resource(struct zorro_dev *z)
+static struct resource __init *zorro_find_parent_resource(
+       struct platform_device *bridge, struct zorro_dev *z)
 {
-    int i;
+       int i;
 
-    for (i = 0; i < zorro_bus.num_resources; i++)
-       if (zorro_resource_start(z) >= zorro_bus.resources[i].start &&
-           zorro_resource_end(z) <= zorro_bus.resources[i].end)
-               return &zorro_bus.resources[i];
-    return &iomem_resource;
+       for (i = 0; i < bridge->num_resources; i++) {
+               struct resource *r = &bridge->resource[i];
+               if (zorro_resource_start(z) >= r->start &&
+                   zorro_resource_end(z) <= r->end)
+                       return r;
+       }
+       return &iomem_resource;
 }
 
 
-    /*
-     *  Initialization
-     */
 
-static int __init zorro_init(void)
+static int __init amiga_zorro_probe(struct platform_device *pdev)
 {
-    struct zorro_dev *z;
-    unsigned int i;
-    int error;
-
-    if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
-       return 0;
-
-    pr_info("Zorro: Probing AutoConfig expansion devices: %d device%s\n",
-          zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
-
-    /* Initialize the Zorro bus */
-    INIT_LIST_HEAD(&zorro_bus.devices);
-    dev_set_name(&zorro_bus.dev, "zorro");
-    error = device_register(&zorro_bus.dev);
-    if (error) {
-       pr_err("Zorro: Error registering zorro_bus\n");
-       return error;
-    }
-
-    /* Request the resources */
-    zorro_bus.num_resources = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2;
-    for (i = 0; i < zorro_bus.num_resources; i++)
-       request_resource(&iomem_resource, &zorro_bus.resources[i]);
-
-    /* Register all devices */
-    for (i = 0; i < zorro_num_autocon; i++) {
-       z = &zorro_autocon[i];
-       z->id = (z->rom.er_Manufacturer<<16) | (z->rom.er_Product<<8);
-       if (z->id == ZORRO_PROD_GVP_EPC_BASE) {
-           /* GVP quirk */
-           unsigned long magic = zorro_resource_start(z)+0x8000;
-           z->id |= *(u16 *)ZTWO_VADDR(magic) & GVP_PRODMASK;
-       }
-       sprintf(z->name, "Zorro device %08x", z->id);
-       zorro_name_device(z);
-       z->resource.name = z->name;
-       if (request_resource(zorro_find_parent_resource(z), &z->resource))
-           pr_err("Zorro: Address space collision on device %s %pR\n",
-                  z->name, &z->resource);
-       dev_set_name(&z->dev, "%02x", i);
-       z->dev.parent = &zorro_bus.dev;
-       z->dev.bus = &zorro_bus_type;
-       error = device_register(&z->dev);
+       struct zorro_bus *bus;
+       struct zorro_dev *z;
+       struct resource *r;
+       unsigned int i;
+       int error;
+
+       /* Initialize the Zorro bus */
+       bus = kzalloc(sizeof(*bus), GFP_KERNEL);
+       if (!bus)
+               return -ENOMEM;
+
+       INIT_LIST_HEAD(&bus->devices);
+       bus->dev.parent = &pdev->dev;
+       dev_set_name(&bus->dev, "zorro");
+       error = device_register(&bus->dev);
        if (error) {
-           pr_err("Zorro: Error registering device %s\n", z->name);
-           continue;
+               pr_err("Zorro: Error registering zorro_bus\n");
+               kfree(bus);
+               return error;
        }
-       error = zorro_create_sysfs_dev_files(z);
-       if (error)
-           dev_err(&z->dev, "Error creating sysfs files\n");
-    }
-
-    /* Mark all available Zorro II memory */
-    zorro_for_each_dev(z) {
-       if (z->rom.er_Type & ERTF_MEMLIST)
-           mark_region(zorro_resource_start(z), zorro_resource_end(z)+1, 1);
-    }
-
-    /* Unmark all used Zorro II memory */
-    for (i = 0; i < m68k_num_memory; i++)
-       if (m68k_memory[i].addr < 16*1024*1024)
-           mark_region(m68k_memory[i].addr,
-                       m68k_memory[i].addr+m68k_memory[i].size, 0);
-
-    return 0;
+       platform_set_drvdata(pdev, bus);
+
+       /* Register all devices */
+       pr_info("Zorro: Probing AutoConfig expansion devices: %u device%s\n",
+                zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
+
+       for (i = 0; i < zorro_num_autocon; i++) {
+               z = &zorro_autocon[i];
+               z->id = (z->rom.er_Manufacturer<<16) | (z->rom.er_Product<<8);
+               if (z->id == ZORRO_PROD_GVP_EPC_BASE) {
+                       /* GVP quirk */
+                       unsigned long magic = zorro_resource_start(z)+0x8000;
+                       z->id |= *(u16 *)ZTWO_VADDR(magic) & GVP_PRODMASK;
+               }
+               sprintf(z->name, "Zorro device %08x", z->id);
+               zorro_name_device(z);
+               z->resource.name = z->name;
+               r = zorro_find_parent_resource(pdev, z);
+               error = request_resource(r, &z->resource);
+               if (error)
+                       dev_err(&bus->dev,
+                               "Address space collision on device %s %pR\n",
+                               z->name, &z->resource);
+               dev_set_name(&z->dev, "%02x", i);
+               z->dev.parent = &bus->dev;
+               z->dev.bus = &zorro_bus_type;
+               error = device_register(&z->dev);
+               if (error) {
+                       dev_err(&bus->dev, "Error registering device %s\n",
+                               z->name);
+                       continue;
+               }
+               error = zorro_create_sysfs_dev_files(z);
+               if (error)
+                       dev_err(&z->dev, "Error creating sysfs files\n");
+       }
+
+       /* Mark all available Zorro II memory */
+       zorro_for_each_dev(z) {
+               if (z->rom.er_Type & ERTF_MEMLIST)
+                       mark_region(zorro_resource_start(z),
+                                   zorro_resource_end(z)+1, 1);
+       }
+
+       /* Unmark all used Zorro II memory */
+       for (i = 0; i < m68k_num_memory; i++)
+               if (m68k_memory[i].addr < 16*1024*1024)
+                       mark_region(m68k_memory[i].addr,
+                                   m68k_memory[i].addr+m68k_memory[i].size,
+                                   0);
+
+       return 0;
 }
 
-subsys_initcall(zorro_init);
+static struct platform_driver amiga_zorro_driver = {
+       .driver   = {
+               .name   = "amiga-zorro",
+               .owner  = THIS_MODULE,
+       },
+};
 
-EXPORT_SYMBOL(zorro_find_device);
-EXPORT_SYMBOL(zorro_unused_z2ram);
+static int __init amiga_zorro_init(void)
+{
+       return platform_driver_probe(&amiga_zorro_driver, amiga_zorro_probe);
+}
+
+module_init(amiga_zorro_init);
 
 MODULE_LICENSE("GPL");
index e777961939f3e6ed0354560c3e256247f6d24f66..0dbe0d139ac2aa3e03375188f1308c7cbadf6b57 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/jiffies.h>
 #include <linux/file.h>
+#include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/sched.h>
 #include <linux/fs.h>
index 08b2eb157048b26aafd052daaeba4c8e38239f0a..7317b39b28159b2e712de1eec7bed5fce2312b3a 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/idr.h>
 #include <net/9p/9p.h>
@@ -110,7 +111,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
 {
        int i, n, l, clone, any, access;
        u32 uid;
-       struct p9_fid *fid;
+       struct p9_fid *fid, *old_fid = NULL;
        struct dentry *d, *ds;
        struct v9fs_session_info *v9ses;
        char **wnames, *uname;
@@ -183,10 +184,18 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
                l = min(n - i, P9_MAXWELEM);
                fid = p9_client_walk(fid, l, &wnames[i], clone);
                if (IS_ERR(fid)) {
+                       if (old_fid) {
+                               /*
+                                * If we fail, clunk fid which are mapping
+                                * to path component and not the last component
+                                * of the path.
+                                */
+                               p9_client_clunk(old_fid);
+                       }
                        kfree(wnames);
                        return fid;
                }
-
+               old_fid = fid;
                i += l;
                clone = 0;
        }
index 6c7f6a2511154a3016eb1bc433f012bb1d3128f5..f8b86e92cd660ef9da7e026be6a06fb7de4863fb 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/sched.h>
 #include <linux/parser.h>
 #include <linux/idr.h>
+#include <linux/slab.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 #include <net/9p/transport.h>
@@ -237,11 +238,18 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
                return ERR_PTR(-ENOMEM);
        }
 
+       rc = bdi_setup_and_register(&v9ses->bdi, "9p", BDI_CAP_MAP_COPY);
+       if (rc) {
+               __putname(v9ses->aname);
+               __putname(v9ses->uname);
+               return ERR_PTR(rc);
+       }
+
        spin_lock(&v9fs_sessionlist_lock);
        list_add(&v9ses->slist, &v9fs_sessionlist);
        spin_unlock(&v9fs_sessionlist_lock);
 
-       v9ses->flags = V9FS_PROTO_2000U | V9FS_ACCESS_USER;
+       v9ses->flags = V9FS_ACCESS_USER;
        strcpy(v9ses->uname, V9FS_DEFUSER);
        strcpy(v9ses->aname, V9FS_DEFANAME);
        v9ses->uid = ~0;
@@ -262,8 +270,10 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
                goto error;
        }
 
-       if (!p9_is_proto_dotu(v9ses->clnt))
-               v9ses->flags &= ~V9FS_PROTO_2000U;
+       if (p9_is_proto_dotl(v9ses->clnt))
+               v9ses->flags |= V9FS_PROTO_2000L;
+       else if (p9_is_proto_dotu(v9ses->clnt))
+               v9ses->flags |= V9FS_PROTO_2000U;
 
        v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ;
 
@@ -298,6 +308,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
        return fid;
 
 error:
+       bdi_destroy(&v9ses->bdi);
        return ERR_PTR(retval);
 }
 
@@ -323,6 +334,8 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
        __putname(v9ses->uname);
        __putname(v9ses->aname);
 
+       bdi_destroy(&v9ses->bdi);
+
        spin_lock(&v9fs_sessionlist_lock);
        list_del(&v9ses->slist);
        spin_unlock(&v9fs_sessionlist_lock);
@@ -340,6 +353,19 @@ void v9fs_session_cancel(struct v9fs_session_info *v9ses) {
        p9_client_disconnect(v9ses->clnt);
 }
 
+/**
+ * v9fs_session_begin_cancel - Begin terminate of a session
+ * @v9ses: session to terminate
+ *
+ * After this call we don't allow any request other than clunk.
+ */
+
+void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses)
+{
+       P9_DPRINTK(P9_DEBUG_ERROR, "begin cancel session %p\n", v9ses);
+       p9_client_begin_disconnect(v9ses->clnt);
+}
+
 extern int v9fs_error_init(void);
 
 static struct kobject *v9fs_kobj;
index 6b801d1ddf4b22de50a7d663d220e5e171facfdc..bec4d0bcb4585d1f41c89406ef9eeb9eb6421115 100644 (file)
@@ -20,6 +20,7 @@
  *  Boston, MA  02111-1301  USA
  *
  */
+#include <linux/backing-dev.h>
 
 /**
  * enum p9_session_flags - option flags for each 9P session
@@ -102,12 +103,14 @@ struct v9fs_session_info {
        u32 uid;                /* if ACCESS_SINGLE, the uid that has access */
        struct p9_client *clnt; /* 9p client */
        struct list_head slist; /* list of sessions registered with v9fs */
+       struct backing_dev_info bdi;
 };
 
 struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
                                                                        char *);
 void v9fs_session_close(struct v9fs_session_info *v9ses);
 void v9fs_session_cancel(struct v9fs_session_info *v9ses);
+void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses);
 
 #define V9FS_MAGIC 0x01021997
 
index d74325295b1e43d74617d89798a8deb78ef6a5d6..cbf4e50f3933aa3cb8b714a518a530203a3e5385 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/namei.h>
 #include <linux/idr.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 
index d8a3afe4ff722fcac539863e59a3278d459ec0bd..0adfd64dfcee88117a93aa9d2a0547cb6852d6e4 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/sched.h>
 #include <linux/inet.h>
 #include <linux/idr.h>
+#include <linux/slab.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 
@@ -130,6 +131,8 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
        rdir = (struct p9_rdir *) fid->rdir;
 
        err = mutex_lock_interruptible(&rdir->mutex);
+       if (err)
+               return err;
        while (err == 0) {
                if (rdir->tail == rdir->head) {
                        err = v9fs_file_readn(filp, rdir->buf, NULL,
index 5fe45d692c9f32d47751209930c3cc4196705671..f2434fc9d2c44f620e2e579a19318321e12d6e71 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/namei.h>
 #include <linux/idr.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 
@@ -431,6 +432,7 @@ error:
 
 static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
 {
+       int retval;
        struct inode *file_inode;
        struct v9fs_session_info *v9ses;
        struct p9_fid *v9fid;
@@ -444,7 +446,10 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
        if (IS_ERR(v9fid))
                return PTR_ERR(v9fid);
 
-       return p9_client_remove(v9fid);
+       retval = p9_client_remove(v9fid);
+       if (!retval)
+               drop_nlink(file_inode);
+       return retval;
 }
 
 static int
@@ -656,6 +661,9 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
        P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n",
                dir, dentry->d_name.name, dentry, nameidata);
 
+       if (dentry->d_name.len > NAME_MAX)
+               return ERR_PTR(-ENAMETOOLONG);
+
        sb = dir->i_sb;
        v9ses = v9fs_inode2v9ses(dir);
        dfid = v9fs_fid_lookup(dentry->d_parent);
index 69357c0d9899c1c3e52e090b0ce3d4725b18c41b..806da5d3b3a0803ee572eab76af384c772dba18d 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/mount.h>
 #include <linux/idr.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 
@@ -76,6 +77,7 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
        sb->s_blocksize = 1 << sb->s_blocksize_bits;
        sb->s_magic = V9FS_MAGIC;
        sb->s_op = &v9fs_super_ops;
+       sb->s_bdi = &v9ses->bdi;
 
        sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC |
            MS_NOATIME;
@@ -193,6 +195,7 @@ static void v9fs_kill_super(struct super_block *s)
 
        kill_anon_super(s);
 
+       v9fs_session_cancel(v9ses);
        v9fs_session_close(v9ses);
        kfree(v9ses);
        s->s_fs_info = NULL;
@@ -205,7 +208,7 @@ v9fs_umount_begin(struct super_block *sb)
        struct v9fs_session_info *v9ses;
 
        v9ses = sb->s_fs_info;
-       v9fs_session_cancel(v9ses);
+       v9fs_session_begin_cancel(v9ses);
 }
 
 static const struct super_operations v9fs_super_ops = {
index 7405f071be671480ebbc4b79b24f1d11e41bc616..5f85b5947613f4a4cfaaf42149d6658d69627799 100644 (file)
@@ -235,6 +235,7 @@ config NFS_COMMON
 
 source "net/sunrpc/Kconfig"
 source "fs/smbfs/Kconfig"
+source "fs/ceph/Kconfig"
 source "fs/cifs/Kconfig"
 source "fs/ncpfs/Kconfig"
 source "fs/coda/Kconfig"
index c3633aa46911556ce8dd56e621bfacdc916769a2..97f340f14ba2d7a181e0788a404ed3698a382ed9 100644 (file)
@@ -125,3 +125,4 @@ obj-$(CONFIG_OCFS2_FS)              += ocfs2/
 obj-$(CONFIG_BTRFS_FS)         += btrfs/
 obj-$(CONFIG_GFS2_FS)           += gfs2/
 obj-$(CONFIG_EXOFS_FS)          += exofs/
+obj-$(CONFIG_CEPH_FS)          += ceph/
index 6910a98bd73cefc29cc0e8435dfd0949625d34fd..4a3af7075c1d09058347ef532edc8c3105a9f9d5 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/parser.h>
 #include <linux/mount.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/statfs.h>
 #include "adfs.h"
index 8306d53307ed0e06a9b1d7b3bb51676c0d9e64ad..3e262711ae06edfc0202e0914bd1627c1ccb643f 100644 (file)
@@ -7,6 +7,7 @@
  *  block allocation, deallocation, calculation of free space.
  */
 
+#include <linux/slab.h>
 #include "affs.h"
 
 /* This is, of course, shamelessly stolen from fs/minix */
index c9744d771d98b80d907378b611d90d4576b6132f..f4b2a4ee4f911bde737b152c0e4434322bb0a82f 100644 (file)
@@ -10,6 +10,7 @@
  *  (C) 1991  Linus Torvalds - minix filesystem
  */
 #include <linux/sched.h>
+#include <linux/gfp.h>
 #include "affs.h"
 
 extern const struct inode_operations affs_symlink_inode_operations;
index d41e9673cd9736fae4efb1db81accbeec6c1f7eb..16a3e4765f68769c80a6d838d39a5b4eb55ce2c6 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/magic.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include "affs.h"
 
 extern struct timezone sys_tz;
index e2b1d3f165191444e96f3eebfbeb909aa07f5db1..0fb315dd4d2a77758da40ae63ce9252282305fcd 100644 (file)
@@ -9,7 +9,6 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#include <linux/slab.h>
 #include <linux/sched.h>
 #include "internal.h"
 
index eb765489164f85c4c51d9ac1595a3b48e5d41cd2..a3bcec75c54aa2302728edddfd93de15f4ac513c 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/ip.h>
 #include "internal.h"
index 88067f36e5e7bea4c4d51cff5dd0a9e24e79b3ad..adc1cb771b57ef6be60bee4b90c5da577d0faaa4 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
 #include <linux/ctype.h>
index 39b301662f22449e0896e77bf9a964e68bd9a9f0..0df9bc2b724d86c1b310d0a987c15132dbf980e8 100644 (file)
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
 #include <linux/writeback.h>
+#include <linux/gfp.h>
 #include "internal.h"
 
 static int afs_readpage(struct file *file, struct page *page);
index 023b95b0d9d7612b41ef895c4a2989513fa6b47a..4bd0218473a9bb407a9c86be49f0400461621f24 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/circ_buf.h>
 #include "internal.h"
index c048f06587512c93535e7ca1221d6d7b3ee77f02..d00b312e31108c8a4477e168f445982cd5e30743 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
 #include <linux/sched.h>
index c54dad4e60636ac687608cacc2e5baf70bcb80b0..a10f2582844fefd9712e36343e27ec1a513620cc 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/workqueue.h>
 #include <linux/sched.h>
 #include <linux/fscache.h>
+#include <linux/backing-dev.h>
 
 #include "afs.h"
 #include "afs_vl.h"
@@ -313,6 +314,7 @@ struct afs_volume {
        unsigned short          rjservers;      /* number of servers discarded due to -ENOMEDIUM */
        struct afs_server       *servers[8];    /* servers on which volume resides (ordered) */
        struct rw_semaphore     server_sem;     /* lock for accessing current server */
+       struct backing_dev_info bdi;
 };
 
 /*
index 5ffb570cd3a8e1d962b62d2b43324012741ff888..b3feddc4f7d649d240487fac866a21878f4258cd 100644 (file)
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
+#include <linux/gfp.h>
 #include "internal.h"
 
 
@@ -138,9 +138,9 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
 {
        struct afs_super_info *super;
        struct vfsmount *mnt;
-       struct page *page = NULL;
+       struct page *page;
        size_t size;
-       char *buf, *devname = NULL, *options = NULL;
+       char *buf, *devname, *options;
        int ret;
 
        _enter("{%s}", mntpt->d_name.name);
@@ -150,22 +150,22 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
        ret = -EINVAL;
        size = mntpt->d_inode->i_size;
        if (size > PAGE_SIZE - 1)
-               goto error;
+               goto error_no_devname;
 
        ret = -ENOMEM;
        devname = (char *) get_zeroed_page(GFP_KERNEL);
        if (!devname)
-               goto error;
+               goto error_no_devname;
 
        options = (char *) get_zeroed_page(GFP_KERNEL);
        if (!options)
-               goto error;
+               goto error_no_options;
 
        /* read the contents of the AFS special symlink */
        page = read_mapping_page(mntpt->d_inode->i_mapping, 0, NULL);
        if (IS_ERR(page)) {
                ret = PTR_ERR(page);
-               goto error;
+               goto error_no_page;
        }
 
        ret = -EIO;
@@ -196,12 +196,12 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
        return mnt;
 
 error:
-       if (page)
-               page_cache_release(page);
-       if (devname)
-               free_page((unsigned long) devname);
-       if (options)
-               free_page((unsigned long) options);
+       page_cache_release(page);
+error_no_page:
+       free_page((unsigned long) options);
+error_no_options:
+       free_page((unsigned long) devname);
+error_no_devname:
        _leave(" = %d", ret);
        return ERR_PTR(ret);
 }
index bde3f19c0995015b2a2496aaf805807a7d7348db..67cf810e0fd6e6cbadde116cf3916555d96226bb 100644 (file)
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
 #include <rxrpc/packet.h>
index 3ef504370034c2311fdd50f631856ac95ab76903..bb4ed144d0e446c627fb8b4e391664058d094b87 100644 (file)
@@ -189,8 +189,9 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key, long acl_order)
        if (!permits)
                goto out_unlock;
 
-       memcpy(permits->permits, xpermits->permits,
-              count * sizeof(struct afs_permit));
+       if (xpermits)
+               memcpy(permits->permits, xpermits->permits,
+                       count * sizeof(struct afs_permit));
 
        _debug("key %x access %x",
               key_serial(key), vnode->status.caller_access);
index 14f6431598adfc57d4b563ca98bb40116f87b1ed..e932e5a3a0c1f6d5628f4e54fb6611515e0d18eb 100644 (file)
@@ -311,6 +311,7 @@ static int afs_fill_super(struct super_block *sb, void *data)
        sb->s_magic             = AFS_FS_MAGIC;
        sb->s_op                = &afs_super_ops;
        sb->s_fs_info           = as;
+       sb->s_bdi               = &as->volume->bdi;
 
        /* allocate the root inode and dentry */
        fid.vid         = as->volume->vid;
index 36c1306e09e017b9461b1aefe773664ba5c9ff8b..340afd0cd18290e319bcc1d9695c887b39284025 100644 (file)
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include "internal.h"
index 6e689208def255c946cf39d1f44c562aedf51448..9ac260d1361de8e3b50f1bd6f9abad13b8b97594 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include "internal.h"
index 2f05c4fc2a70ad4a1e74c1712d7ba562be2f33aa..25cf4c3f4ff7ded56a2b0f0183b00584668104c7 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include "internal.h"
index a353e69e2391bc5f8bb3dd2970f19aeade9ea7e8..401eeb21869ff0657b966f4753fd951bc7897333 100644 (file)
@@ -106,6 +106,10 @@ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params)
        volume->cell            = params->cell;
        volume->vid             = vlocation->vldb.vid[params->type];
 
+       ret = bdi_setup_and_register(&volume->bdi, "afs", BDI_CAP_MAP_COPY);
+       if (ret)
+               goto error_bdi;
+
        init_rwsem(&volume->server_sem);
 
        /* look up all the applicable server records */
@@ -151,6 +155,8 @@ error:
        return ERR_PTR(ret);
 
 error_discard:
+       bdi_destroy(&volume->bdi);
+error_bdi:
        up_write(&params->cell->vl_sem);
 
        for (loop = volume->nservers - 1; loop >= 0; loop--)
@@ -200,6 +206,7 @@ void afs_put_volume(struct afs_volume *volume)
        for (loop = volume->nservers - 1; loop >= 0; loop--)
                afs_put_server(volume->servers[loop]);
 
+       bdi_destroy(&volume->bdi);
        kfree(volume);
 
        _leave(" [destroyed]");
index 2de009565d8ecf305d40fbdd014855246a43dea5..e4b75d6eda839d6fddae166904d1002f85a4d09f 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/file.h>
 #include <linux/poll.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/mount.h>
index 4a1401cea0a1737e45b19d4d7850fe17da55282d..8713c7cfbc799efe1fa604df04dcbebe3966f225 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/capability.h>
 #include <linux/errno.h>
 #include <linux/stat.h>
+#include <linux/slab.h>
 #include <linux/param.h>
 #include <linux/time.h>
 #include <linux/smp_lock.h>
index c8a80dffb4557d80999b71c66b94cb4a7d2b75fe..d29b7f6df86285d173de7340c7a338d2d75d09fc 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/magic.h>
 #include <linux/dcache.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 
 #include "autofs_i.h"
 
index a015b49891df6347f70f6c318666b63a74638dc8..e8e5e63ac9503b6f42d20681a26fc6565e43641b 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/capability.h>
 #include <linux/errno.h>
 #include <linux/stat.h>
+#include <linux/slab.h>
 #include <linux/param.h>
 #include <linux/time.h>
 #include "autofs_i.h"
@@ -176,8 +177,7 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags)
                }
        /* Trigger mount for path component or follow link */
        } else if (ino->flags & AUTOFS_INF_PENDING ||
-                       autofs4_need_mount(flags) ||
-                       current->link_count) {
+                       autofs4_need_mount(flags)) {
                DPRINTK("waiting for mount name=%.*s",
                        dentry->d_name.len, dentry->d_name.name);
 
@@ -261,7 +261,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
                spin_unlock(&dcache_lock);
                spin_unlock(&sbi->fs_lock);
 
-               status = try_to_fill_dentry(dentry, 0);
+               status = try_to_fill_dentry(dentry, nd->flags);
                if (status)
                        goto out_error;
 
index e3287d0d1a58815020044ef9f47383eec92cddcb..59096b5e0fc7e85f64867b7b257fb12d25adbbed 100644 (file)
@@ -11,7 +11,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/buffer_head.h>
 #include <linux/string.h>
 
index 15d80bb35d6f7c9e10adcb7ac62d587813449870..f96eff04e11ab4a8b23f7489ee4b0de50e67e152 100644 (file)
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
-#include <linux/slab.h>
 #include <linux/binfmts.h>
 #include <linux/personality.h>
 #include <linux/init.h>
 #include <linux/coredump.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -75,14 +75,16 @@ static int aout_core_dump(struct coredump_params *cprm)
        struct file *file = cprm->file;
        mm_segment_t fs;
        int has_dumped = 0;
-       unsigned long dump_start, dump_size;
+       void __user *dump_start;
+       int dump_size;
        struct user dump;
 #ifdef __alpha__
-#       define START_DATA(u)   (u.start_data)
+#       define START_DATA(u)   ((void __user *)u.start_data)
 #else
-#      define START_DATA(u)    ((u.u_tsize << PAGE_SHIFT) + u.start_code)
+#      define START_DATA(u)    ((void __user *)((u.u_tsize << PAGE_SHIFT) + \
+                                u.start_code))
 #endif
-#       define START_STACK(u)   (u.start_stack)
+#       define START_STACK(u)   ((void __user *)u.start_stack)
 
        fs = get_fs();
        set_fs(KERNEL_DS);
@@ -104,9 +106,9 @@ static int aout_core_dump(struct coredump_params *cprm)
 
 /* make sure we actually have a data and stack area to dump */
        set_fs(USER_DS);
-       if (!access_ok(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize << PAGE_SHIFT))
+       if (!access_ok(VERIFY_READ, START_DATA(dump), dump.u_dsize << PAGE_SHIFT))
                dump.u_dsize = 0;
-       if (!access_ok(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize << PAGE_SHIFT))
+       if (!access_ok(VERIFY_READ, START_STACK(dump), dump.u_ssize << PAGE_SHIFT))
                dump.u_ssize = 0;
 
        set_fs(KERNEL_DS);
index 2c32d00a66904883339fe2b25ebe991cdeb6a489..2c5f9a0e5d72bb0357c45d5524186c14b3284bca 100644 (file)
@@ -1005,15 +1005,8 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(
                                }
                        } else if (!mm->start_data) {
                                mm->start_data = seg->addr;
-#ifndef CONFIG_MMU
                                mm->end_data = seg->addr + phdr->p_memsz;
-#endif
                        }
-
-#ifdef CONFIG_MMU
-                       if (seg->addr + phdr->p_memsz > mm->end_data)
-                               mm->end_data = seg->addr + phdr->p_memsz;
-#endif
                }
 
                seg++;
@@ -1590,7 +1583,7 @@ static size_t elf_core_vma_data_size(unsigned long mm_flags)
        struct vm_area_struct *vma;
        size_t size = 0;
 
-       for (vma = current->mm->mmap; vma; vma->vm_next)
+       for (vma = current->mm->mmap; vma; vma = vma->vm_next)
                if (maydump(vma, mm_flags))
                        size += vma->vm_end - vma->vm_start;
        return size;
index 32fb00b52cd069ed600d9c1a925f2b831621325e..b8e8b0acf9bd8df4b3ca369a152afbe01cd9d476 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/stat.h>
-#include <linux/slab.h>
 #include <linux/binfmts.h>
 #include <linux/elf.h>
 #include <linux/init.h>
index e0e769bdca59918bc0cc2f6c202ccae7bdcd5546..49566c1687d84943d9187a12ff2d1490c8ec6ad2 100644 (file)
@@ -355,7 +355,7 @@ calc_reloc(unsigned long r, struct lib_info *p, int curid, int internalp)
 
        if (!flat_reloc_valid(r, start_brk - start_data + text_len)) {
                printk("BINFMT_FLAT: reloc outside program 0x%x (0 - 0x%x/0x%x)",
-                      (int) r,(int)(start_brk-start_code),(int)text_len);
+                      (int) r,(int)(start_brk-start_data+text_len),(int)text_len);
                goto failed;
        }
 
index 08343505e18455dedebace59a8c489ecb3b1cf7a..aca9d55afb220fddd5998a5d37bfd7a402bb5995 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/stat.h>
-#include <linux/slab.h>
 #include <linux/binfmts.h>
 #include <linux/init.h>
 #include <linux/file.h>
index a16f29e888cd837dd1de4669755c0883bfeb715a..612a5c38d3c1a5fc49e0d0990e19550c27217650 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/mempool.h>
 #include <linux/bio.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 
 struct integrity_slab {
        struct kmem_cache *slab;
index e1f922184b4506466e20978902fb114905549bcd..e7bf6ca64dcf028caec480f4ecb82b2ff32d2463 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -554,7 +554,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
                                        .bi_rw = bio->bi_rw,
                                };
 
-                               if (q->merge_bvec_fn(q, &bvm, prev) < len) {
+                               if (q->merge_bvec_fn(q, &bvm, prev) < prev->bv_len) {
                                        prev->bv_len -= len;
                                        return 0;
                                }
@@ -607,7 +607,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
                 * merge_bvec_fn() returns number of bytes it can accept
                 * at this offset
                 */
-               if (q->merge_bvec_fn(q, &bvm, bvec) < len) {
+               if (q->merge_bvec_fn(q, &bvm, bvec) < bvec->bv_len) {
                        bvec->bv_page = NULL;
                        bvec->bv_len = 0;
                        bvec->bv_offset = 0;
index d11d0289f3d24bf9489acba6059c5d8ada9eda52..6dcee88c2e5d275fe7df4b3e82caa52375779a74 100644 (file)
@@ -404,20 +404,28 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin)
  *     NULL first argument is nfsd_sync_dir() and that's not a directory.
  */
  
-static int block_fsync(struct file *filp, struct dentry *dentry, int datasync)
+int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync)
 {
-       struct block_device *bdev = I_BDEV(filp->f_mapping->host);
+       struct inode *bd_inode = filp->f_mapping->host;
+       struct block_device *bdev = I_BDEV(bd_inode);
        int error;
 
-       error = sync_blockdev(bdev);
-       if (error)
-               return error;
-       
+       /*
+        * There is no need to serialise calls to blkdev_issue_flush with
+        * i_mutex and doing so causes performance issues with concurrent
+        * O_SYNC writers to a block device.
+        */
+       mutex_unlock(&bd_inode->i_mutex);
+
        error = blkdev_issue_flush(bdev, NULL);
        if (error == -EOPNOTSUPP)
                error = 0;
+
+       mutex_lock(&bd_inode->i_mutex);
+
        return error;
 }
+EXPORT_SYMBOL(blkdev_fsync);
 
 /*
  * pseudo-fs
@@ -1481,7 +1489,7 @@ const struct file_operations def_blk_fops = {
        .aio_read       = generic_file_aio_read,
        .aio_write      = blkdev_aio_write,
        .mmap           = generic_file_mmap,
-       .fsync          = block_fsync,
+       .fsync          = blkdev_fsync,
        .unlocked_ioctl = block_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl   = compat_blkdev_ioctl,
index 6df6d6ed74fd9e6296f1249cbd37d8d1885a552c..6ef7b26724ec6cd964400c1074db9ed5f95289f1 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/posix_acl_xattr.h>
 #include <linux/posix_acl.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include "ctree.h"
 #include "btrfs_inode.h"
index c0861e781cdbdfde4b7c42ec1b90032f2059e69a..462859a30141faa7c6ee645ad750cf0ae48c9692 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/freezer.h>
index 3f1f50d9d916cf5e3c095101a3af0c220035f625..7a4dee19983235660c05679cc615709fa8b2141a 100644 (file)
@@ -153,6 +153,11 @@ struct btrfs_inode {
        unsigned ordered_data_close:1;
        unsigned dummy_inode:1;
 
+       /*
+        * always compress this one file
+        */
+       unsigned force_compress:1;
+
        struct inode vfs_inode;
 };
 
index a11a32058b50a4993f072fd1baddc6e9dafb52a8..396039b3a8a24ecb7f37fbec9ef831ed05d5cf94 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/swap.h>
 #include <linux/writeback.h>
 #include <linux/bit_spinlock.h>
-#include <linux/pagevec.h>
+#include <linux/slab.h>
 #include "compat.h"
 #include "ctree.h"
 #include "disk-io.h"
@@ -445,7 +445,6 @@ static noinline int add_ra_bio_pages(struct inode *inode,
        unsigned long nr_pages = 0;
        struct extent_map *em;
        struct address_space *mapping = inode->i_mapping;
-       struct pagevec pvec;
        struct extent_map_tree *em_tree;
        struct extent_io_tree *tree;
        u64 end;
@@ -461,7 +460,6 @@ static noinline int add_ra_bio_pages(struct inode *inode,
 
        end_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT;
 
-       pagevec_init(&pvec, 0);
        while (last_offset < compressed_end) {
                page_index = last_offset >> PAGE_CACHE_SHIFT;
 
@@ -478,26 +476,17 @@ static noinline int add_ra_bio_pages(struct inode *inode,
                        goto next;
                }
 
-               page = alloc_page(mapping_gfp_mask(mapping) | GFP_NOFS);
+               page = __page_cache_alloc(mapping_gfp_mask(mapping) &
+                                                               ~__GFP_FS);
                if (!page)
                        break;
 
-               page->index = page_index;
-               /*
-                * what we want to do here is call add_to_page_cache_lru,
-                * but that isn't exported, so we reproduce it here
-                */
-               if (add_to_page_cache(page, mapping,
-                                     page->index, GFP_NOFS)) {
+               if (add_to_page_cache_lru(page, mapping, page_index,
+                                                               GFP_NOFS)) {
                        page_cache_release(page);
                        goto next;
                }
 
-               /* open coding of lru_cache_add, also not exported */
-               page_cache_get(page);
-               if (!pagevec_add(&pvec, page))
-                       __pagevec_lru_add_file(&pvec);
-
                end = last_offset + PAGE_CACHE_SIZE - 1;
                /*
                 * at this point, we have a locked page in the page cache
@@ -551,8 +540,6 @@ static noinline int add_ra_bio_pages(struct inode *inode,
 next:
                last_offset += PAGE_CACHE_SIZE;
        }
-       if (pagevec_count(&pvec))
-               __pagevec_lru_add_file(&pvec);
        return 0;
 }
 
index c4bc570a396eebf5ede775dc39b004c9ff493227..6795a713b2052bbd7560590dccbba8b33ca6c717 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
@@ -3040,6 +3041,10 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans,
        if (ret > 0 || item_size != btrfs_item_size_nr(leaf, path->slots[0]))
                goto err;
 
+       /* the leaf has  changed, it now has room.  return now */
+       if (btrfs_leaf_free_space(root, path->nodes[0]) >= ins_len)
+               goto err;
+
        if (key.type == BTRFS_EXTENT_DATA_KEY) {
                fi = btrfs_item_ptr(leaf, path->slots[0],
                                    struct btrfs_file_extent_item);
index 8b5cfdd4bfc1b7b91e6e94ae94e5ee9f2dbaa875..746a7248678ebe3d7396c7bd5746b4ce3b654f80 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/completion.h>
 #include <linux/backing-dev.h>
 #include <linux/wait.h>
+#include <linux/slab.h>
 #include <asm/kmap_types.h>
 #include "extent_io.h"
 #include "extent_map.h"
@@ -373,11 +374,13 @@ struct btrfs_super_block {
  * ones specified below then we will fail to mount
  */
 #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF   (1ULL << 0)
+#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL  (2ULL << 0)
 
 #define BTRFS_FEATURE_COMPAT_SUPP              0ULL
 #define BTRFS_FEATURE_COMPAT_RO_SUPP           0ULL
 #define BTRFS_FEATURE_INCOMPAT_SUPP            \
-       BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF
+       (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \
+        BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)
 
 /*
  * A leaf is full of items. offset and size tell us where to find
@@ -832,7 +835,6 @@ struct btrfs_fs_info {
        u64 last_trans_log_full_commit;
        u64 open_ioctl_trans;
        unsigned long mount_opt;
-       u64 max_extent;
        u64 max_inline;
        u64 alloc_start;
        struct btrfs_transaction *running_transaction;
@@ -1182,7 +1184,6 @@ struct btrfs_root {
 #define BTRFS_INODE_NOATIME            (1 << 9)
 #define BTRFS_INODE_DIRSYNC            (1 << 10)
 
-
 /* some macros to generate set/get funcs for the struct fields.  This
  * assumes there is a lefoo_to_cpu for every type, so lets make a simple
  * one for u8:
@@ -1842,7 +1843,7 @@ BTRFS_SETGET_STACK_FUNCS(super_num_devices, struct btrfs_super_block,
 BTRFS_SETGET_STACK_FUNCS(super_compat_flags, struct btrfs_super_block,
                         compat_flags, 64);
 BTRFS_SETGET_STACK_FUNCS(super_compat_ro_flags, struct btrfs_super_block,
-                        compat_flags, 64);
+                        compat_ro_flags, 64);
 BTRFS_SETGET_STACK_FUNCS(super_incompat_flags, struct btrfs_super_block,
                         incompat_flags, 64);
 BTRFS_SETGET_STACK_FUNCS(super_csum_type, struct btrfs_super_block,
@@ -2310,7 +2311,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
                               u32 min_type);
 
 int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput);
-int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end);
+int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
+                             struct extent_state **cached_state);
 int btrfs_writepages(struct address_space *mapping,
                     struct writeback_control *wbc);
 int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
@@ -2335,7 +2337,7 @@ int btrfs_init_cachep(void);
 void btrfs_destroy_cachep(void);
 long btrfs_ioctl_trans_end(struct file *file);
 struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
-                        struct btrfs_root *root);
+                        struct btrfs_root *root, int *was_new);
 int btrfs_commit_write(struct file *file, struct page *page,
                       unsigned from, unsigned to);
 struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
@@ -2386,7 +2388,6 @@ void btrfs_sysfs_del_super(struct btrfs_fs_info *root);
 ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
 
 /* super.c */
-u64 btrfs_parse_size(char *str);
 int btrfs_parse_options(struct btrfs_root *root, char *options);
 int btrfs_sync_fs(struct super_block *sb, int wait);
 
index 84e6781413b177acfd04c1a922c72da48c8f4e01..902ce507c4e34a01e4e5afbcba26aa31c9d18d63 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/sort.h>
 #include "ctree.h"
 #include "delayed-ref.h"
index 0427183e3e05c0198617427fbc311c9b7f397947..feca04197d028e9d25a73dd177299319e1af351d 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/crc32c.h>
+#include <linux/slab.h>
 #include "compat.h"
 #include "ctree.h"
 #include "disk-io.h"
@@ -43,8 +44,6 @@ static struct extent_io_ops btree_extent_io_ops;
 static void end_workqueue_fn(struct btrfs_work *work);
 static void free_fs_root(struct btrfs_root *root);
 
-static atomic_t btrfs_bdi_num = ATOMIC_INIT(0);
-
 /*
  * end_io_wq structs are used to do processing in task context when an IO is
  * complete.  This is used during reads to verify checksums, and it is used
@@ -263,13 +262,15 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
 static int verify_parent_transid(struct extent_io_tree *io_tree,
                                 struct extent_buffer *eb, u64 parent_transid)
 {
+       struct extent_state *cached_state = NULL;
        int ret;
 
        if (!parent_transid || btrfs_header_generation(eb) == parent_transid)
                return 0;
 
-       lock_extent(io_tree, eb->start, eb->start + eb->len - 1, GFP_NOFS);
-       if (extent_buffer_uptodate(io_tree, eb) &&
+       lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1,
+                        0, &cached_state, GFP_NOFS);
+       if (extent_buffer_uptodate(io_tree, eb, cached_state) &&
            btrfs_header_generation(eb) == parent_transid) {
                ret = 0;
                goto out;
@@ -282,10 +283,10 @@ static int verify_parent_transid(struct extent_io_tree *io_tree,
                       (unsigned long long)btrfs_header_generation(eb));
        }
        ret = 1;
-       clear_extent_buffer_uptodate(io_tree, eb);
+       clear_extent_buffer_uptodate(io_tree, eb, &cached_state);
 out:
-       unlock_extent(io_tree, eb->start, eb->start + eb->len - 1,
-                     GFP_NOFS);
+       unlock_extent_cached(io_tree, eb->start, eb->start + eb->len - 1,
+                            &cached_state, GFP_NOFS);
        return ret;
 }
 
@@ -1372,19 +1373,11 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi)
 {
        int err;
 
-       bdi->name = "btrfs";
        bdi->capabilities = BDI_CAP_MAP_COPY;
-       err = bdi_init(bdi);
+       err = bdi_setup_and_register(bdi, "btrfs", BDI_CAP_MAP_COPY);
        if (err)
                return err;
 
-       err = bdi_register(bdi, NULL, "btrfs-%d",
-                               atomic_inc_return(&btrfs_bdi_num));
-       if (err) {
-               bdi_destroy(bdi);
-               return err;
-       }
-
        bdi->ra_pages   = default_backing_dev_info.ra_pages;
        bdi->unplug_io_fn       = btrfs_unplug_io_fn;
        bdi->unplug_io_data     = info;
@@ -1632,7 +1625,6 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        atomic_set(&fs_info->async_submit_draining, 0);
        atomic_set(&fs_info->nr_async_bios, 0);
        fs_info->sb = sb;
-       fs_info->max_extent = (u64)-1;
        fs_info->max_inline = 8192 * 1024;
        fs_info->metadata_ratio = 0;
 
@@ -1920,7 +1912,11 @@ struct btrfs_root *open_ctree(struct super_block *sb,
 
        csum_root->track_dirty = 1;
 
-       btrfs_read_block_groups(extent_root);
+       ret = btrfs_read_block_groups(extent_root);
+       if (ret) {
+               printk(KERN_ERR "Failed to read block groups: %d\n", ret);
+               goto fail_block_groups;
+       }
 
        fs_info->generation = generation;
        fs_info->last_trans_committed = generation;
@@ -1930,7 +1926,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root,
                                               "btrfs-cleaner");
        if (IS_ERR(fs_info->cleaner_kthread))
-               goto fail_csum_root;
+               goto fail_block_groups;
 
        fs_info->transaction_kthread = kthread_run(transaction_kthread,
                                                   tree_root,
@@ -2018,7 +2014,8 @@ fail_cleaner:
        filemap_write_and_wait(fs_info->btree_inode->i_mapping);
        invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
 
-fail_csum_root:
+fail_block_groups:
+       btrfs_free_block_groups(fs_info);
        free_extent_buffer(csum_root->node);
        free_extent_buffer(csum_root->commit_root);
 fail_dev_root:
@@ -2497,7 +2494,8 @@ int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid)
        int ret;
        struct inode *btree_inode = buf->first_page->mapping->host;
 
-       ret = extent_buffer_uptodate(&BTRFS_I(btree_inode)->io_tree, buf);
+       ret = extent_buffer_uptodate(&BTRFS_I(btree_inode)->io_tree, buf,
+                                    NULL);
        if (!ret)
                return ret;
 
index ba5c3fd5ab8c89e3057aa612f1bd929c1589b2b3..951ef09b82f4abb02d220f259d78c16af180a210 100644 (file)
@@ -95,7 +95,7 @@ static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
        btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
        key.offset = 0;
 
-       inode = btrfs_iget(sb, &key, root);
+       inode = btrfs_iget(sb, &key, root, NULL);
        if (IS_ERR(inode)) {
                err = PTR_ERR(inode);
                goto fail;
@@ -223,7 +223,7 @@ static struct dentry *btrfs_get_parent(struct dentry *child)
 
        key.type = BTRFS_INODE_ITEM_KEY;
        key.offset = 0;
-       dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root));
+       dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root, NULL));
        if (!IS_ERR(dentry))
                dentry->d_op = &btrfs_dentry_operations;
        return dentry;
index 559f72489b3bf02b4477369da854bf371cbbd0e4..b34d32fdaaece73d8ffef286e5f867387b2ba529 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/sort.h>
 #include <linux/rcupdate.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include "compat.h"
 #include "hash.h"
 #include "ctree.h"
@@ -2676,6 +2677,8 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags,
 
        INIT_LIST_HEAD(&found->block_groups);
        init_rwsem(&found->groups_sem);
+       init_waitqueue_head(&found->flush_wait);
+       init_waitqueue_head(&found->allocate_wait);
        spin_lock_init(&found->lock);
        found->flags = flags;
        found->total_bytes = total_bytes;
@@ -2846,7 +2849,7 @@ int btrfs_unreserve_metadata_for_delalloc(struct btrfs_root *root,
        }
        spin_unlock(&BTRFS_I(inode)->accounting_lock);
 
-       BTRFS_I(inode)->reserved_extents--;
+       BTRFS_I(inode)->reserved_extents -= num_items;
        BUG_ON(BTRFS_I(inode)->reserved_extents < 0);
 
        if (meta_sinfo->bytes_delalloc < num_bytes) {
@@ -2944,12 +2947,10 @@ static void flush_delalloc(struct btrfs_root *root,
 
        spin_lock(&info->lock);
 
-       if (!info->flushing) {
+       if (!info->flushing)
                info->flushing = 1;
-               init_waitqueue_head(&info->flush_wait);
-       } else {
+       else
                wait = true;
-       }
 
        spin_unlock(&info->lock);
 
@@ -3011,7 +3012,6 @@ static int maybe_allocate_chunk(struct btrfs_root *root,
        if (!info->allocating_chunk) {
                info->force_alloc = 1;
                info->allocating_chunk = 1;
-               init_waitqueue_head(&info->allocate_wait);
        } else {
                wait = true;
        }
@@ -3111,7 +3111,7 @@ again:
                return -ENOSPC;
        }
 
-       BTRFS_I(inode)->reserved_extents++;
+       BTRFS_I(inode)->reserved_extents += num_items;
        check_force_delalloc(meta_sinfo);
        spin_unlock(&meta_sinfo->lock);
 
@@ -3235,7 +3235,8 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,
                                u64 bytes)
 {
        struct btrfs_space_info *data_sinfo;
-       int ret = 0, committed = 0;
+       u64 used;
+       int ret = 0, committed = 0, flushed = 0;
 
        /* make sure bytes are sectorsize aligned */
        bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1);
@@ -3247,12 +3248,21 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,
 again:
        /* make sure we have enough space to handle the data first */
        spin_lock(&data_sinfo->lock);
-       if (data_sinfo->total_bytes - data_sinfo->bytes_used -
-           data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved -
-           data_sinfo->bytes_pinned - data_sinfo->bytes_readonly -
-           data_sinfo->bytes_may_use - data_sinfo->bytes_super < bytes) {
+       used = data_sinfo->bytes_used + data_sinfo->bytes_delalloc +
+               data_sinfo->bytes_reserved + data_sinfo->bytes_pinned +
+               data_sinfo->bytes_readonly + data_sinfo->bytes_may_use +
+               data_sinfo->bytes_super;
+
+       if (used + bytes > data_sinfo->total_bytes) {
                struct btrfs_trans_handle *trans;
 
+               if (!flushed) {
+                       spin_unlock(&data_sinfo->lock);
+                       flush_delalloc(root, data_sinfo);
+                       flushed = 1;
+                       goto again;
+               }
+
                /*
                 * if we don't have enough free bytes in this space then we need
                 * to alloc a new chunk.
@@ -4170,6 +4180,10 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
        ins->offset = 0;
 
        space_info = __find_space_info(root->fs_info, data);
+       if (!space_info) {
+               printk(KERN_ERR "No space info for %d\n", data);
+               return -ENOSPC;
+       }
 
        if (orig_root->ref_cows || empty_size)
                allowed_chunk_alloc = 1;
@@ -5205,6 +5219,8 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
        next = btrfs_find_tree_block(root, bytenr, blocksize);
        if (!next) {
                next = btrfs_find_create_tree_block(root, bytenr, blocksize);
+               if (!next)
+                       return -ENOMEM;
                reada = 1;
        }
        btrfs_tree_lock(next);
@@ -5417,7 +5433,8 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans,
                if (ret > 0) {
                        path->slots[level]++;
                        continue;
-               }
+               } else if (ret < 0)
+                       return ret;
                level = wc->level;
        }
        return 0;
@@ -6561,6 +6578,7 @@ static noinline int invalidate_extent_cache(struct btrfs_root *root,
        struct btrfs_key key;
        struct inode *inode = NULL;
        struct btrfs_file_extent_item *fi;
+       struct extent_state *cached_state = NULL;
        u64 num_bytes;
        u64 skip_objectid = 0;
        u32 nritems;
@@ -6589,12 +6607,14 @@ static noinline int invalidate_extent_cache(struct btrfs_root *root,
                }
                num_bytes = btrfs_file_extent_num_bytes(leaf, fi);
 
-               lock_extent(&BTRFS_I(inode)->io_tree, key.offset,
-                           key.offset + num_bytes - 1, GFP_NOFS);
+               lock_extent_bits(&BTRFS_I(inode)->io_tree, key.offset,
+                                key.offset + num_bytes - 1, 0, &cached_state,
+                                GFP_NOFS);
                btrfs_drop_extent_cache(inode, key.offset,
                                        key.offset + num_bytes - 1, 1);
-               unlock_extent(&BTRFS_I(inode)->io_tree, key.offset,
-                             key.offset + num_bytes - 1, GFP_NOFS);
+               unlock_extent_cached(&BTRFS_I(inode)->io_tree, key.offset,
+                                    key.offset + num_bytes - 1, &cached_state,
+                                    GFP_NOFS);
                cond_resched();
        }
        iput(inode);
@@ -7366,7 +7386,6 @@ static int find_first_block_group(struct btrfs_root *root,
                }
                path->slots[0]++;
        }
-       ret = -ENOENT;
 out:
        return ret;
 }
index 7073cbb1b2d4cfc169dfea2ca435d353f282250f..d2d03684fab261fb9663f1d18ef19d9f23d98b78 100644 (file)
@@ -2,7 +2,6 @@
 #include <linux/slab.h>
 #include <linux/bio.h>
 #include <linux/mm.h>
-#include <linux/gfp.h>
 #include <linux/pagemap.h>
 #include <linux/page-flags.h>
 #include <linux/module.h>
@@ -513,7 +512,10 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
        u64 last_end;
        int err;
        int set = 0;
+       int clear = 0;
 
+       if (bits & (EXTENT_IOBITS | EXTENT_BOUNDARY))
+               clear = 1;
 again:
        if (!prealloc && (mask & __GFP_WAIT)) {
                prealloc = alloc_extent_state(mask);
@@ -524,14 +526,20 @@ again:
        spin_lock(&tree->lock);
        if (cached_state) {
                cached = *cached_state;
-               *cached_state = NULL;
-               cached_state = NULL;
+
+               if (clear) {
+                       *cached_state = NULL;
+                       cached_state = NULL;
+               }
+
                if (cached && cached->tree && cached->start == start) {
-                       atomic_dec(&cached->refs);
+                       if (clear)
+                               atomic_dec(&cached->refs);
                        state = cached;
                        goto hit_next;
                }
-               free_extent_state(cached);
+               if (clear)
+                       free_extent_state(cached);
        }
        /*
         * this search will find the extents that end after
@@ -946,11 +954,11 @@ int clear_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
 }
 
 int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
-                    gfp_t mask)
+                       struct extent_state **cached_state, gfp_t mask)
 {
        return set_extent_bit(tree, start, end,
                              EXTENT_DELALLOC | EXTENT_DIRTY | EXTENT_UPTODATE,
-                             0, NULL, NULL, mask);
+                             0, NULL, cached_state, mask);
 }
 
 int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
@@ -984,10 +992,11 @@ int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end,
 }
 
 static int clear_extent_uptodate(struct extent_io_tree *tree, u64 start,
-                                u64 end, gfp_t mask)
+                                u64 end, struct extent_state **cached_state,
+                                gfp_t mask)
 {
        return clear_extent_bit(tree, start, end, EXTENT_UPTODATE, 0, 0,
-                               NULL, mask);
+                               cached_state, mask);
 }
 
 int wait_on_extent_writeback(struct extent_io_tree *tree, u64 start, u64 end)
@@ -1171,7 +1180,8 @@ out:
  * 1 is returned if we find something, 0 if nothing was in the tree
  */
 static noinline u64 find_delalloc_range(struct extent_io_tree *tree,
-                                       u64 *start, u64 *end, u64 max_bytes)
+                                       u64 *start, u64 *end, u64 max_bytes,
+                                       struct extent_state **cached_state)
 {
        struct rb_node *node;
        struct extent_state *state;
@@ -1203,8 +1213,11 @@ static noinline u64 find_delalloc_range(struct extent_io_tree *tree,
                                *end = state->end;
                        goto out;
                }
-               if (!found)
+               if (!found) {
                        *start = state->start;
+                       *cached_state = state;
+                       atomic_inc(&state->refs);
+               }
                found++;
                *end = state->end;
                cur_start = state->end + 1;
@@ -1336,10 +1349,11 @@ again:
        delalloc_start = *start;
        delalloc_end = 0;
        found = find_delalloc_range(tree, &delalloc_start, &delalloc_end,
-                                   max_bytes);
+                                   max_bytes, &cached_state);
        if (!found || delalloc_end <= *start) {
                *start = delalloc_start;
                *end = delalloc_end;
+               free_extent_state(cached_state);
                return found;
        }
 
@@ -1722,7 +1736,7 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
                }
 
                if (!uptodate) {
-                       clear_extent_uptodate(tree, start, end, GFP_NOFS);
+                       clear_extent_uptodate(tree, start, end, NULL, GFP_NOFS);
                        ClearPageUptodate(page);
                        SetPageError(page);
                }
@@ -1750,7 +1764,8 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
 static void end_bio_extent_readpage(struct bio *bio, int err)
 {
        int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
-       struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
+       struct bio_vec *bvec_end = bio->bi_io_vec + bio->bi_vcnt - 1;
+       struct bio_vec *bvec = bio->bi_io_vec;
        struct extent_io_tree *tree;
        u64 start;
        u64 end;
@@ -1773,7 +1788,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
                else
                        whole_page = 0;
 
-               if (--bvec >= bio->bi_io_vec)
+               if (++bvec <= bvec_end)
                        prefetchw(&bvec->bv_page->flags);
 
                if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) {
@@ -1818,7 +1833,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
                        }
                        check_page_locked(tree, page);
                }
-       } while (bvec >= bio->bi_io_vec);
+       } while (bvec <= bvec_end);
 
        bio_put(bio);
 }
@@ -2663,33 +2678,20 @@ int extent_readpages(struct extent_io_tree *tree,
 {
        struct bio *bio = NULL;
        unsigned page_idx;
-       struct pagevec pvec;
        unsigned long bio_flags = 0;
 
-       pagevec_init(&pvec, 0);
        for (page_idx = 0; page_idx < nr_pages; page_idx++) {
                struct page *page = list_entry(pages->prev, struct page, lru);
 
                prefetchw(&page->flags);
                list_del(&page->lru);
-               /*
-                * what we want to do here is call add_to_page_cache_lru,
-                * but that isn't exported, so we reproduce it here
-                */
-               if (!add_to_page_cache(page, mapping,
+               if (!add_to_page_cache_lru(page, mapping,
                                        page->index, GFP_KERNEL)) {
-
-                       /* open coding of lru_cache_add, also not exported */
-                       page_cache_get(page);
-                       if (!pagevec_add(&pvec, page))
-                               __pagevec_lru_add_file(&pvec);
                        __extent_read_full_page(tree, page, get_extent,
                                                &bio, 0, &bio_flags);
                }
                page_cache_release(page);
        }
-       if (pagevec_count(&pvec))
-               __pagevec_lru_add_file(&pvec);
        BUG_ON(!list_empty(pages));
        if (bio)
                submit_one_bio(READ, bio, 0, bio_flags);
@@ -2704,6 +2706,7 @@ int extent_readpages(struct extent_io_tree *tree,
 int extent_invalidatepage(struct extent_io_tree *tree,
                          struct page *page, unsigned long offset)
 {
+       struct extent_state *cached_state = NULL;
        u64 start = ((u64)page->index << PAGE_CACHE_SHIFT);
        u64 end = start + PAGE_CACHE_SIZE - 1;
        size_t blocksize = page->mapping->host->i_sb->s_blocksize;
@@ -2712,12 +2715,12 @@ int extent_invalidatepage(struct extent_io_tree *tree,
        if (start > end)
                return 0;
 
-       lock_extent(tree, start, end, GFP_NOFS);
+       lock_extent_bits(tree, start, end, 0, &cached_state, GFP_NOFS);
        wait_on_page_writeback(page);
        clear_extent_bit(tree, start, end,
                         EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC |
                         EXTENT_DO_ACCOUNTING,
-                        1, 1, NULL, GFP_NOFS);
+                        1, 1, &cached_state, GFP_NOFS);
        return 0;
 }
 
@@ -2920,16 +2923,17 @@ sector_t extent_bmap(struct address_space *mapping, sector_t iblock,
                get_extent_t *get_extent)
 {
        struct inode *inode = mapping->host;
+       struct extent_state *cached_state = NULL;
        u64 start = iblock << inode->i_blkbits;
        sector_t sector = 0;
        size_t blksize = (1 << inode->i_blkbits);
        struct extent_map *em;
 
-       lock_extent(&BTRFS_I(inode)->io_tree, start, start + blksize - 1,
-                   GFP_NOFS);
+       lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + blksize - 1,
+                        0, &cached_state, GFP_NOFS);
        em = get_extent(inode, NULL, 0, start, blksize, 0);
-       unlock_extent(&BTRFS_I(inode)->io_tree, start, start + blksize - 1,
-                     GFP_NOFS);
+       unlock_extent_cached(&BTRFS_I(inode)->io_tree, start,
+                            start + blksize - 1, &cached_state, GFP_NOFS);
        if (!em || IS_ERR(em))
                return 0;
 
@@ -2951,6 +2955,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
        u32 flags = 0;
        u64 disko = 0;
        struct extent_map *em = NULL;
+       struct extent_state *cached_state = NULL;
        int end = 0;
        u64 em_start = 0, em_len = 0;
        unsigned long emflags;
@@ -2959,8 +2964,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
        if (len == 0)
                return -EINVAL;
 
-       lock_extent(&BTRFS_I(inode)->io_tree, start, start + len,
-               GFP_NOFS);
+       lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0,
+                        &cached_state, GFP_NOFS);
        em = get_extent(inode, NULL, 0, off, max - off, 0);
        if (!em)
                goto out;
@@ -3023,8 +3028,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
 out_free:
        free_extent_map(em);
 out:
-       unlock_extent(&BTRFS_I(inode)->io_tree, start, start + len,
-                       GFP_NOFS);
+       unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len,
+                            &cached_state, GFP_NOFS);
        return ret;
 }
 
@@ -3264,7 +3269,8 @@ int set_extent_buffer_dirty(struct extent_io_tree *tree,
 }
 
 int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
-                               struct extent_buffer *eb)
+                               struct extent_buffer *eb,
+                               struct extent_state **cached_state)
 {
        unsigned long i;
        struct page *page;
@@ -3274,7 +3280,7 @@ int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
        clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
 
        clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
-                             GFP_NOFS);
+                             cached_state, GFP_NOFS);
        for (i = 0; i < num_pages; i++) {
                page = extent_buffer_page(eb, i);
                if (page)
@@ -3334,7 +3340,8 @@ int extent_range_uptodate(struct extent_io_tree *tree,
 }
 
 int extent_buffer_uptodate(struct extent_io_tree *tree,
-                          struct extent_buffer *eb)
+                          struct extent_buffer *eb,
+                          struct extent_state *cached_state)
 {
        int ret = 0;
        unsigned long num_pages;
@@ -3346,7 +3353,7 @@ int extent_buffer_uptodate(struct extent_io_tree *tree,
                return 1;
 
        ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1,
-                          EXTENT_UPTODATE, 1, NULL);
+                          EXTENT_UPTODATE, 1, cached_state);
        if (ret)
                return ret;
 
index 36de250a7b2bce5ef6f36d35ded4f1f88a2dfc58..bbab4813646f92a2df9c462daabde89b452826ab 100644 (file)
@@ -163,6 +163,8 @@ int lock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask);
 int lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end,
                     int bits, struct extent_state **cached, gfp_t mask);
 int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask);
+int unlock_extent_cached(struct extent_io_tree *tree, u64 start, u64 end,
+                        struct extent_state **cached, gfp_t mask);
 int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end,
                    gfp_t mask);
 int extent_read_full_page(struct extent_io_tree *tree, struct page *page,
@@ -196,7 +198,7 @@ int clear_extent_ordered(struct extent_io_tree *tree, u64 start, u64 end,
 int clear_extent_ordered_metadata(struct extent_io_tree *tree, u64 start,
                                  u64 end, gfp_t mask);
 int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
-                    gfp_t mask);
+                       struct extent_state **cached_state, gfp_t mask);
 int set_extent_ordered(struct extent_io_tree *tree, u64 start, u64 end,
                     gfp_t mask);
 int find_first_extent_bit(struct extent_io_tree *tree, u64 start,
@@ -281,9 +283,11 @@ int test_extent_buffer_dirty(struct extent_io_tree *tree,
 int set_extent_buffer_uptodate(struct extent_io_tree *tree,
                               struct extent_buffer *eb);
 int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
-                               struct extent_buffer *eb);
+                               struct extent_buffer *eb,
+                               struct extent_state **cached_state);
 int extent_buffer_uptodate(struct extent_io_tree *tree,
-                          struct extent_buffer *eb);
+                          struct extent_buffer *eb,
+                          struct extent_state *cached_state);
 int map_extent_buffer(struct extent_buffer *eb, unsigned long offset,
                      unsigned long min_len, char **token, char **map,
                      unsigned long *map_start,
index 28d87ba60ce8170d0c10d14225dc5ce37eb24beb..454ca52d6451b649b78b48cba908f3fd1eb2bada 100644 (file)
@@ -1,5 +1,4 @@
 #include <linux/err.h>
-#include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
index 9b99886562d0b2c8ea9e883f3f2623b0ec6d8674..54a255065aa3235a7672d64f5fcf506615ae8ef3 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/bio.h>
+#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/highmem.h>
 #include "ctree.h"
index 6ed434ac037faac00117e5d633478bd7a2e0805b..29ff749ff4caaa35386f35173b169502e9ac3ded 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/writeback.h>
 #include <linux/statfs.h>
 #include <linux/compat.h>
+#include <linux/slab.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
@@ -123,7 +124,8 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans,
                    root->sectorsize - 1) & ~((u64)root->sectorsize - 1);
 
        end_of_last_block = start_pos + num_bytes - 1;
-       err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block);
+       err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block,
+                                       NULL);
        if (err)
                return err;
 
@@ -753,6 +755,7 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file,
                         loff_t pos, unsigned long first_index,
                         unsigned long last_index, size_t write_bytes)
 {
+       struct extent_state *cached_state = NULL;
        int i;
        unsigned long index = pos >> PAGE_CACHE_SHIFT;
        struct inode *inode = fdentry(file)->d_inode;
@@ -781,16 +784,18 @@ again:
        }
        if (start_pos < inode->i_size) {
                struct btrfs_ordered_extent *ordered;
-               lock_extent(&BTRFS_I(inode)->io_tree,
-                           start_pos, last_pos - 1, GFP_NOFS);
+               lock_extent_bits(&BTRFS_I(inode)->io_tree,
+                                start_pos, last_pos - 1, 0, &cached_state,
+                                GFP_NOFS);
                ordered = btrfs_lookup_first_ordered_extent(inode,
                                                            last_pos - 1);
                if (ordered &&
                    ordered->file_offset + ordered->len > start_pos &&
                    ordered->file_offset < last_pos) {
                        btrfs_put_ordered_extent(ordered);
-                       unlock_extent(&BTRFS_I(inode)->io_tree,
-                                     start_pos, last_pos - 1, GFP_NOFS);
+                       unlock_extent_cached(&BTRFS_I(inode)->io_tree,
+                                            start_pos, last_pos - 1,
+                                            &cached_state, GFP_NOFS);
                        for (i = 0; i < num_pages; i++) {
                                unlock_page(pages[i]);
                                page_cache_release(pages[i]);
@@ -802,12 +807,13 @@ again:
                if (ordered)
                        btrfs_put_ordered_extent(ordered);
 
-               clear_extent_bits(&BTRFS_I(inode)->io_tree, start_pos,
+               clear_extent_bit(&BTRFS_I(inode)->io_tree, start_pos,
                                  last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC |
-                                 EXTENT_DO_ACCOUNTING,
+                                 EXTENT_DO_ACCOUNTING, 0, 0, &cached_state,
                                  GFP_NOFS);
-               unlock_extent(&BTRFS_I(inode)->io_tree,
-                             start_pos, last_pos - 1, GFP_NOFS);
+               unlock_extent_cached(&BTRFS_I(inode)->io_tree,
+                                    start_pos, last_pos - 1, &cached_state,
+                                    GFP_NOFS);
        }
        for (i = 0; i < num_pages; i++) {
                clear_page_dirty_for_io(pages[i]);
index dd831ed31eead2c4bda12eaf37a4c331458a9646..f488fac04d99ea45eea93607bbf17c021b5b2207 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/pagemap.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/math64.h>
 #include "ctree.h"
 #include "free-space-cache.h"
index c41db6d45ab6fb2574ecf7a34fae9e43c18a39d3..2bfdc641d4e3ba046f3afd89400f362ec959e46b 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/xattr.h>
 #include <linux/posix_acl.h>
 #include <linux/falloc.h>
+#include <linux/slab.h>
 #include "compat.h"
 #include "ctree.h"
 #include "disk-io.h"
@@ -379,7 +380,8 @@ again:
         * change at any time if we discover bad compression ratios.
         */
        if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS) &&
-           btrfs_test_opt(root, COMPRESS)) {
+           (btrfs_test_opt(root, COMPRESS) ||
+            (BTRFS_I(inode)->force_compress))) {
                WARN_ON(pages);
                pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS);
 
@@ -483,8 +485,10 @@ again:
                nr_pages_ret = 0;
 
                /* flag the file so we don't compress in the future */
-               if (!btrfs_test_opt(root, FORCE_COMPRESS))
+               if (!btrfs_test_opt(root, FORCE_COMPRESS) &&
+                   !(BTRFS_I(inode)->force_compress)) {
                        BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS;
+               }
        }
        if (will_compress) {
                *num_added += 1;
@@ -570,8 +574,8 @@ retry:
                        unsigned long nr_written = 0;
 
                        lock_extent(io_tree, async_extent->start,
-                                   async_extent->start +
-                                   async_extent->ram_size - 1, GFP_NOFS);
+                                        async_extent->start +
+                                        async_extent->ram_size - 1, GFP_NOFS);
 
                        /* allocate blocks */
                        ret = cow_file_range(inode, async_cow->locked_page,
@@ -793,7 +797,7 @@ static noinline int cow_file_range(struct inode *inode,
        while (disk_num_bytes > 0) {
                unsigned long op;
 
-               cur_alloc_size = min(disk_num_bytes, root->fs_info->max_extent);
+               cur_alloc_size = disk_num_bytes;
                ret = btrfs_reserve_extent(trans, root, cur_alloc_size,
                                           root->sectorsize, 0, alloc_hint,
                                           (u64)-1, &ins, 1);
@@ -1211,7 +1215,8 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
        else if (BTRFS_I(inode)->flags & BTRFS_INODE_PREALLOC)
                ret = run_delalloc_nocow(inode, locked_page, start, end,
                                         page_started, 0, nr_written);
-       else if (!btrfs_test_opt(root, COMPRESS))
+       else if (!btrfs_test_opt(root, COMPRESS) &&
+                !(BTRFS_I(inode)->force_compress))
                ret = cow_file_range(inode, locked_page, start, end,
                                      page_started, nr_written, 1);
        else
@@ -1223,30 +1228,9 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
 static int btrfs_split_extent_hook(struct inode *inode,
                                    struct extent_state *orig, u64 split)
 {
-       struct btrfs_root *root = BTRFS_I(inode)->root;
-       u64 size;
-
        if (!(orig->state & EXTENT_DELALLOC))
                return 0;
 
-       size = orig->end - orig->start + 1;
-       if (size > root->fs_info->max_extent) {
-               u64 num_extents;
-               u64 new_size;
-
-               new_size = orig->end - split + 1;
-               num_extents = div64_u64(size + root->fs_info->max_extent - 1,
-                                       root->fs_info->max_extent);
-
-               /*
-                * if we break a large extent up then leave oustanding_extents
-                * be, since we've already accounted for the large extent.
-                */
-               if (div64_u64(new_size + root->fs_info->max_extent - 1,
-                             root->fs_info->max_extent) < num_extents)
-                       return 0;
-       }
-
        spin_lock(&BTRFS_I(inode)->accounting_lock);
        BTRFS_I(inode)->outstanding_extents++;
        spin_unlock(&BTRFS_I(inode)->accounting_lock);
@@ -1264,38 +1248,10 @@ static int btrfs_merge_extent_hook(struct inode *inode,
                                   struct extent_state *new,
                                   struct extent_state *other)
 {
-       struct btrfs_root *root = BTRFS_I(inode)->root;
-       u64 new_size, old_size;
-       u64 num_extents;
-
        /* not delalloc, ignore it */
        if (!(other->state & EXTENT_DELALLOC))
                return 0;
 
-       old_size = other->end - other->start + 1;
-       if (new->start < other->start)
-               new_size = other->end - new->start + 1;
-       else
-               new_size = new->end - other->start + 1;
-
-       /* we're not bigger than the max, unreserve the space and go */
-       if (new_size <= root->fs_info->max_extent) {
-               spin_lock(&BTRFS_I(inode)->accounting_lock);
-               BTRFS_I(inode)->outstanding_extents--;
-               spin_unlock(&BTRFS_I(inode)->accounting_lock);
-               return 0;
-       }
-
-       /*
-        * If we grew by another max_extent, just return, we want to keep that
-        * reserved amount.
-        */
-       num_extents = div64_u64(old_size + root->fs_info->max_extent - 1,
-                               root->fs_info->max_extent);
-       if (div64_u64(new_size + root->fs_info->max_extent - 1,
-                     root->fs_info->max_extent) > num_extents)
-               return 0;
-
        spin_lock(&BTRFS_I(inode)->accounting_lock);
        BTRFS_I(inode)->outstanding_extents--;
        spin_unlock(&BTRFS_I(inode)->accounting_lock);
@@ -1324,6 +1280,7 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end,
                BTRFS_I(inode)->outstanding_extents++;
                spin_unlock(&BTRFS_I(inode)->accounting_lock);
                btrfs_delalloc_reserve_space(root, inode, end - start + 1);
+
                spin_lock(&root->fs_info->delalloc_lock);
                BTRFS_I(inode)->delalloc_bytes += end - start + 1;
                root->fs_info->delalloc_bytes += end - start + 1;
@@ -1352,6 +1309,7 @@ static int btrfs_clear_bit_hook(struct inode *inode,
 
                if (bits & EXTENT_DO_ACCOUNTING) {
                        spin_lock(&BTRFS_I(inode)->accounting_lock);
+                       WARN_ON(!BTRFS_I(inode)->outstanding_extents);
                        BTRFS_I(inode)->outstanding_extents--;
                        spin_unlock(&BTRFS_I(inode)->accounting_lock);
                        btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
@@ -1508,12 +1466,13 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans,
        return 0;
 }
 
-int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end)
+int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
+                             struct extent_state **cached_state)
 {
        if ((end & (PAGE_CACHE_SIZE - 1)) == 0)
                WARN_ON(1);
        return set_extent_delalloc(&BTRFS_I(inode)->io_tree, start, end,
-                                  GFP_NOFS);
+                                  cached_state, GFP_NOFS);
 }
 
 /* see btrfs_writepage_start_hook for details on why this is required */
@@ -1526,6 +1485,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
 {
        struct btrfs_writepage_fixup *fixup;
        struct btrfs_ordered_extent *ordered;
+       struct extent_state *cached_state = NULL;
        struct page *page;
        struct inode *inode;
        u64 page_start;
@@ -1544,7 +1504,8 @@ again:
        page_start = page_offset(page);
        page_end = page_offset(page) + PAGE_CACHE_SIZE - 1;
 
-       lock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS);
+       lock_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end, 0,
+                        &cached_state, GFP_NOFS);
 
        /* already ordered? We're done */
        if (PagePrivate2(page))
@@ -1552,17 +1513,18 @@ again:
 
        ordered = btrfs_lookup_ordered_extent(inode, page_start);
        if (ordered) {
-               unlock_extent(&BTRFS_I(inode)->io_tree, page_start,
-                             page_end, GFP_NOFS);
+               unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start,
+                                    page_end, &cached_state, GFP_NOFS);
                unlock_page(page);
                btrfs_start_ordered_extent(inode, ordered, 1);
                goto again;
        }
 
-       btrfs_set_extent_delalloc(inode, page_start, page_end);
+       btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state);
        ClearPageChecked(page);
 out:
-       unlock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS);
+       unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end,
+                            &cached_state, GFP_NOFS);
 out_page:
        unlock_page(page);
        page_cache_release(page);
@@ -1691,14 +1653,14 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
        struct btrfs_trans_handle *trans;
        struct btrfs_ordered_extent *ordered_extent = NULL;
        struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
+       struct extent_state *cached_state = NULL;
        int compressed = 0;
        int ret;
 
-       ret = btrfs_dec_test_ordered_pending(inode, start, end - start + 1);
+       ret = btrfs_dec_test_ordered_pending(inode, &ordered_extent, start,
+                                            end - start + 1);
        if (!ret)
                return 0;
-
-       ordered_extent = btrfs_lookup_ordered_extent(inode, start);
        BUG_ON(!ordered_extent);
 
        if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) {
@@ -1713,9 +1675,9 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
                goto out;
        }
 
-       lock_extent(io_tree, ordered_extent->file_offset,
-                   ordered_extent->file_offset + ordered_extent->len - 1,
-                   GFP_NOFS);
+       lock_extent_bits(io_tree, ordered_extent->file_offset,
+                        ordered_extent->file_offset + ordered_extent->len - 1,
+                        0, &cached_state, GFP_NOFS);
 
        trans = btrfs_join_transaction(root, 1);
 
@@ -1742,9 +1704,10 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
                                   ordered_extent->len);
                BUG_ON(ret);
        }
-       unlock_extent(io_tree, ordered_extent->file_offset,
-                   ordered_extent->file_offset + ordered_extent->len - 1,
-                   GFP_NOFS);
+       unlock_extent_cached(io_tree, ordered_extent->file_offset,
+                            ordered_extent->file_offset +
+                            ordered_extent->len - 1, &cached_state, GFP_NOFS);
+
        add_pending_csums(trans, inode, ordered_extent->file_offset,
                          &ordered_extent->list);
 
@@ -2153,7 +2116,7 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
                found_key.objectid = found_key.offset;
                found_key.type = BTRFS_INODE_ITEM_KEY;
                found_key.offset = 0;
-               inode = btrfs_iget(root->fs_info->sb, &found_key, root);
+               inode = btrfs_iget(root->fs_info->sb, &found_key, root, NULL);
                if (IS_ERR(inode))
                        break;
 
@@ -3081,6 +3044,7 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from)
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
        struct btrfs_ordered_extent *ordered;
+       struct extent_state *cached_state = NULL;
        char *kaddr;
        u32 blocksize = root->sectorsize;
        pgoff_t index = from >> PAGE_CACHE_SHIFT;
@@ -3127,12 +3091,14 @@ again:
        }
        wait_on_page_writeback(page);
 
-       lock_extent(io_tree, page_start, page_end, GFP_NOFS);
+       lock_extent_bits(io_tree, page_start, page_end, 0, &cached_state,
+                        GFP_NOFS);
        set_page_extent_mapped(page);
 
        ordered = btrfs_lookup_ordered_extent(inode, page_start);
        if (ordered) {
-               unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+               unlock_extent_cached(io_tree, page_start, page_end,
+                                    &cached_state, GFP_NOFS);
                unlock_page(page);
                page_cache_release(page);
                btrfs_start_ordered_extent(inode, ordered, 1);
@@ -3140,13 +3106,15 @@ again:
                goto again;
        }
 
-       clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end,
+       clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end,
                          EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
-                         GFP_NOFS);
+                         0, 0, &cached_state, GFP_NOFS);
 
-       ret = btrfs_set_extent_delalloc(inode, page_start, page_end);
+       ret = btrfs_set_extent_delalloc(inode, page_start, page_end,
+                                       &cached_state);
        if (ret) {
-               unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+               unlock_extent_cached(io_tree, page_start, page_end,
+                                    &cached_state, GFP_NOFS);
                goto out_unlock;
        }
 
@@ -3159,7 +3127,8 @@ again:
        }
        ClearPageChecked(page);
        set_page_dirty(page);
-       unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+       unlock_extent_cached(io_tree, page_start, page_end, &cached_state,
+                            GFP_NOFS);
 
 out_unlock:
        if (ret)
@@ -3177,6 +3146,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
        struct extent_map *em;
+       struct extent_state *cached_state = NULL;
        u64 mask = root->sectorsize - 1;
        u64 hole_start = (inode->i_size + mask) & ~mask;
        u64 block_end = (size + mask) & ~mask;
@@ -3192,11 +3162,13 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
                struct btrfs_ordered_extent *ordered;
                btrfs_wait_ordered_range(inode, hole_start,
                                         block_end - hole_start);
-               lock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS);
+               lock_extent_bits(io_tree, hole_start, block_end - 1, 0,
+                                &cached_state, GFP_NOFS);
                ordered = btrfs_lookup_ordered_extent(inode, hole_start);
                if (!ordered)
                        break;
-               unlock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS);
+               unlock_extent_cached(io_tree, hole_start, block_end - 1,
+                                    &cached_state, GFP_NOFS);
                btrfs_put_ordered_extent(ordered);
        }
 
@@ -3241,7 +3213,8 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
                        break;
        }
 
-       unlock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS);
+       unlock_extent_cached(io_tree, hole_start, block_end - 1, &cached_state,
+                            GFP_NOFS);
        return err;
 }
 
@@ -3639,6 +3612,7 @@ static noinline void init_btrfs_i(struct inode *inode)
        bi->index_cnt = (u64)-1;
        bi->last_unlink_trans = 0;
        bi->ordered_data_close = 0;
+       bi->force_compress = 0;
        extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS);
        extent_io_tree_init(&BTRFS_I(inode)->io_tree,
                             inode->i_mapping, GFP_NOFS);
@@ -3687,7 +3661,7 @@ static struct inode *btrfs_iget_locked(struct super_block *s,
  * Returns in *is_new if the inode was read from disk
  */
 struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
-                        struct btrfs_root *root)
+                        struct btrfs_root *root, int *new)
 {
        struct inode *inode;
 
@@ -3702,6 +3676,8 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
 
                inode_tree_add(inode);
                unlock_new_inode(inode);
+               if (new)
+                       *new = 1;
        }
 
        return inode;
@@ -3754,7 +3730,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
                return NULL;
 
        if (location.type == BTRFS_INODE_ITEM_KEY) {
-               inode = btrfs_iget(dir->i_sb, &location, root);
+               inode = btrfs_iget(dir->i_sb, &location, root, NULL);
                return inode;
        }
 
@@ -3769,7 +3745,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
                else
                        inode = new_simple_dir(dir->i_sb, &location, sub_root);
        } else {
-               inode = btrfs_iget(dir->i_sb, &location, sub_root);
+               inode = btrfs_iget(dir->i_sb, &location, sub_root, NULL);
        }
        srcu_read_unlock(&root->fs_info->subvol_srcu, index);
 
@@ -4501,7 +4477,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
        if (err) {
                err = -ENOSPC;
-               goto out_unlock;
+               goto out_fail;
        }
 
        inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name,
@@ -4979,6 +4955,7 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
 {
        struct extent_io_tree *tree;
        struct btrfs_ordered_extent *ordered;
+       struct extent_state *cached_state = NULL;
        u64 page_start = page_offset(page);
        u64 page_end = page_start + PAGE_CACHE_SIZE - 1;
 
@@ -4997,7 +4974,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
                btrfs_releasepage(page, GFP_NOFS);
                return;
        }
-       lock_extent(tree, page_start, page_end, GFP_NOFS);
+       lock_extent_bits(tree, page_start, page_end, 0, &cached_state,
+                        GFP_NOFS);
        ordered = btrfs_lookup_ordered_extent(page->mapping->host,
                                           page_offset(page));
        if (ordered) {
@@ -5008,7 +4986,7 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
                clear_extent_bit(tree, page_start, page_end,
                                 EXTENT_DIRTY | EXTENT_DELALLOC |
                                 EXTENT_LOCKED | EXTENT_DO_ACCOUNTING, 1, 0,
-                                NULL, GFP_NOFS);
+                                &cached_state, GFP_NOFS);
                /*
                 * whoever cleared the private bit is responsible
                 * for the finish_ordered_io
@@ -5018,11 +4996,13 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
                                                page_start, page_end);
                }
                btrfs_put_ordered_extent(ordered);
-               lock_extent(tree, page_start, page_end, GFP_NOFS);
+               cached_state = NULL;
+               lock_extent_bits(tree, page_start, page_end, 0, &cached_state,
+                                GFP_NOFS);
        }
        clear_extent_bit(tree, page_start, page_end,
                 EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC |
-                EXTENT_DO_ACCOUNTING, 1, 1, NULL, GFP_NOFS);
+                EXTENT_DO_ACCOUNTING, 1, 1, &cached_state, GFP_NOFS);
        __btrfs_releasepage(page, GFP_NOFS);
 
        ClearPageChecked(page);
@@ -5055,6 +5035,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
        struct btrfs_ordered_extent *ordered;
+       struct extent_state *cached_state = NULL;
        char *kaddr;
        unsigned long zero_start;
        loff_t size;
@@ -5093,7 +5074,8 @@ again:
        }
        wait_on_page_writeback(page);
 
-       lock_extent(io_tree, page_start, page_end, GFP_NOFS);
+       lock_extent_bits(io_tree, page_start, page_end, 0, &cached_state,
+                        GFP_NOFS);
        set_page_extent_mapped(page);
 
        /*
@@ -5102,7 +5084,8 @@ again:
         */
        ordered = btrfs_lookup_ordered_extent(inode, page_start);
        if (ordered) {
-               unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+               unlock_extent_cached(io_tree, page_start, page_end,
+                                    &cached_state, GFP_NOFS);
                unlock_page(page);
                btrfs_start_ordered_extent(inode, ordered, 1);
                btrfs_put_ordered_extent(ordered);
@@ -5116,13 +5099,15 @@ again:
         * is probably a better way to do this, but for now keep consistent with
         * prepare_pages in the normal write path.
         */
-       clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end,
+       clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end,
                          EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
-                         GFP_NOFS);
+                         0, 0, &cached_state, GFP_NOFS);
 
-       ret = btrfs_set_extent_delalloc(inode, page_start, page_end);
+       ret = btrfs_set_extent_delalloc(inode, page_start, page_end,
+                                       &cached_state);
        if (ret) {
-               unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+               unlock_extent_cached(io_tree, page_start, page_end,
+                                    &cached_state, GFP_NOFS);
                ret = VM_FAULT_SIGBUS;
                btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
                goto out_unlock;
@@ -5148,7 +5133,7 @@ again:
        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);
+       unlock_extent_cached(io_tree, page_start, page_end, &cached_state, GFP_NOFS);
 
 out_unlock:
        btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
@@ -5353,7 +5338,6 @@ free:
 void btrfs_drop_inode(struct inode *inode)
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
-
        if (inode->i_nlink > 0 && btrfs_root_refs(&root->root_item) == 0)
                generic_delete_inode(inode);
        else
@@ -5757,18 +5741,15 @@ static int prealloc_file_range(struct inode *inode, u64 start, u64 end,
        struct btrfs_trans_handle *trans;
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_key ins;
-       u64 alloc_size;
        u64 cur_offset = start;
        u64 num_bytes = end - start;
        int ret = 0;
        u64 i_size;
 
        while (num_bytes > 0) {
-               alloc_size = min(num_bytes, root->fs_info->max_extent);
-
                trans = btrfs_start_transaction(root, 1);
 
-               ret = btrfs_reserve_extent(trans, root, alloc_size,
+               ret = btrfs_reserve_extent(trans, root, num_bytes,
                                           root->sectorsize, 0, alloc_hint,
                                           (u64)-1, &ins, 1);
                if (ret) {
@@ -5827,6 +5808,7 @@ stop_trans:
 static long btrfs_fallocate(struct inode *inode, int mode,
                            loff_t offset, loff_t len)
 {
+       struct extent_state *cached_state = NULL;
        u64 cur_offset;
        u64 last_byte;
        u64 alloc_start;
@@ -5865,16 +5847,17 @@ static long btrfs_fallocate(struct inode *inode, int mode,
                /* the extent lock is ordered inside the running
                 * transaction
                 */
-               lock_extent(&BTRFS_I(inode)->io_tree, alloc_start, locked_end,
-                           GFP_NOFS);
+               lock_extent_bits(&BTRFS_I(inode)->io_tree, alloc_start,
+                                locked_end, 0, &cached_state, GFP_NOFS);
                ordered = btrfs_lookup_first_ordered_extent(inode,
                                                            alloc_end - 1);
                if (ordered &&
                    ordered->file_offset + ordered->len > alloc_start &&
                    ordered->file_offset < alloc_end) {
                        btrfs_put_ordered_extent(ordered);
-                       unlock_extent(&BTRFS_I(inode)->io_tree,
-                                     alloc_start, locked_end, GFP_NOFS);
+                       unlock_extent_cached(&BTRFS_I(inode)->io_tree,
+                                            alloc_start, locked_end,
+                                            &cached_state, GFP_NOFS);
                        /*
                         * we can't wait on the range with the transaction
                         * running or with the extent lock held
@@ -5916,8 +5899,8 @@ static long btrfs_fallocate(struct inode *inode, int mode,
                        break;
                }
        }
-       unlock_extent(&BTRFS_I(inode)->io_tree, alloc_start, locked_end,
-                     GFP_NOFS);
+       unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end,
+                            &cached_state, GFP_NOFS);
 
        btrfs_free_reserved_data_space(BTRFS_I(inode)->root, inode,
                                       alloc_end - alloc_start);
index 645a17927a8f7c8edf9b9b1866695f3ab6982b23..97a97839a867f1c0773f8a684a1289ae185d0eb6 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/security.h>
 #include <linux/xattr.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include "compat.h"
 #include "ctree.h"
 #include "disk-io.h"
@@ -474,7 +475,79 @@ out_unlock:
        return error;
 }
 
-static int btrfs_defrag_file(struct file *file)
+static int should_defrag_range(struct inode *inode, u64 start, u64 len,
+                              int thresh, u64 *last_len, u64 *skip,
+                              u64 *defrag_end)
+{
+       struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
+       struct extent_map *em = NULL;
+       struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
+       int ret = 1;
+
+
+       if (thresh == 0)
+               thresh = 256 * 1024;
+
+       /*
+        * make sure that once we start defragging and extent, we keep on
+        * defragging it
+        */
+       if (start < *defrag_end)
+               return 1;
+
+       *skip = 0;
+
+       /*
+        * hopefully we have this extent in the tree already, try without
+        * the full extent lock
+        */
+       read_lock(&em_tree->lock);
+       em = lookup_extent_mapping(em_tree, start, len);
+       read_unlock(&em_tree->lock);
+
+       if (!em) {
+               /* get the big lock and read metadata off disk */
+               lock_extent(io_tree, start, start + len - 1, GFP_NOFS);
+               em = btrfs_get_extent(inode, NULL, 0, start, len, 0);
+               unlock_extent(io_tree, start, start + len - 1, GFP_NOFS);
+
+               if (IS_ERR(em))
+                       return 0;
+       }
+
+       /* this will cover holes, and inline extents */
+       if (em->block_start >= EXTENT_MAP_LAST_BYTE)
+               ret = 0;
+
+       /*
+        * we hit a real extent, if it is big don't bother defragging it again
+        */
+       if ((*last_len == 0 || *last_len >= thresh) && em->len >= thresh)
+               ret = 0;
+
+       /*
+        * last_len ends up being a counter of how many bytes we've defragged.
+        * every time we choose not to defrag an extent, we reset *last_len
+        * so that the next tiny extent will force a defrag.
+        *
+        * The end result of this is that tiny extents before a single big
+        * extent will force at least part of that big extent to be defragged.
+        */
+       if (ret) {
+               *last_len += len;
+               *defrag_end = extent_map_end(em);
+       } else {
+               *last_len = 0;
+               *skip = extent_map_end(em);
+               *defrag_end = 0;
+       }
+
+       free_extent_map(em);
+       return ret;
+}
+
+static int btrfs_defrag_file(struct file *file,
+                            struct btrfs_ioctl_defrag_range_args *range)
 {
        struct inode *inode = fdentry(file)->d_inode;
        struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -486,37 +559,96 @@ static int btrfs_defrag_file(struct file *file)
        unsigned long total_read = 0;
        u64 page_start;
        u64 page_end;
+       u64 last_len = 0;
+       u64 skip = 0;
+       u64 defrag_end = 0;
        unsigned long i;
        int ret;
 
-       ret = btrfs_check_data_free_space(root, inode, inode->i_size);
-       if (ret)
-               return -ENOSPC;
+       if (inode->i_size == 0)
+               return 0;
+
+       if (range->start + range->len > range->start) {
+               last_index = min_t(u64, inode->i_size - 1,
+                        range->start + range->len - 1) >> PAGE_CACHE_SHIFT;
+       } else {
+               last_index = (inode->i_size - 1) >> PAGE_CACHE_SHIFT;
+       }
+
+       i = range->start >> PAGE_CACHE_SHIFT;
+       while (i <= last_index) {
+               if (!should_defrag_range(inode, (u64)i << PAGE_CACHE_SHIFT,
+                                       PAGE_CACHE_SIZE,
+                                       range->extent_thresh,
+                                       &last_len, &skip,
+                                       &defrag_end)) {
+                       unsigned long next;
+                       /*
+                        * the should_defrag function tells us how much to skip
+                        * bump our counter by the suggested amount
+                        */
+                       next = (skip + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+                       i = max(i + 1, next);
+                       continue;
+               }
 
-       mutex_lock(&inode->i_mutex);
-       last_index = inode->i_size >> PAGE_CACHE_SHIFT;
-       for (i = 0; i <= last_index; i++) {
                if (total_read % ra_pages == 0) {
                        btrfs_force_ra(inode->i_mapping, &file->f_ra, file, i,
                                       min(last_index, i + ra_pages - 1));
                }
                total_read++;
+               mutex_lock(&inode->i_mutex);
+               if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)
+                       BTRFS_I(inode)->force_compress = 1;
+
+               ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE);
+               if (ret) {
+                       ret = -ENOSPC;
+                       break;
+               }
+
+               ret = btrfs_reserve_metadata_for_delalloc(root, inode, 1);
+               if (ret) {
+                       btrfs_free_reserved_data_space(root, inode,
+                                                      PAGE_CACHE_SIZE);
+                       ret = -ENOSPC;
+                       break;
+               }
 again:
+               if (inode->i_size == 0 ||
+                   i > ((inode->i_size - 1) >> PAGE_CACHE_SHIFT)) {
+                       ret = 0;
+                       goto err_reservations;
+               }
+
                page = grab_cache_page(inode->i_mapping, i);
                if (!page)
-                       goto out_unlock;
+                       goto err_reservations;
+
                if (!PageUptodate(page)) {
                        btrfs_readpage(NULL, page);
                        lock_page(page);
                        if (!PageUptodate(page)) {
                                unlock_page(page);
                                page_cache_release(page);
-                               goto out_unlock;
+                               goto err_reservations;
                        }
                }
 
+               if (page->mapping != inode->i_mapping) {
+                       unlock_page(page);
+                       page_cache_release(page);
+                       goto again;
+               }
+
                wait_on_page_writeback(page);
 
+               if (PageDirty(page)) {
+                       btrfs_free_reserved_data_space(root, inode,
+                                                      PAGE_CACHE_SIZE);
+                       goto loop_unlock;
+               }
+
                page_start = (u64)page->index << PAGE_CACHE_SHIFT;
                page_end = page_start + PAGE_CACHE_SIZE - 1;
                lock_extent(io_tree, page_start, page_end, GFP_NOFS);
@@ -537,18 +669,54 @@ again:
                 * page if it is dirtied again later
                 */
                clear_page_dirty_for_io(page);
+               clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start,
+                                 page_end, EXTENT_DIRTY | EXTENT_DELALLOC |
+                                 EXTENT_DO_ACCOUNTING, GFP_NOFS);
 
-               btrfs_set_extent_delalloc(inode, page_start, page_end);
+               btrfs_set_extent_delalloc(inode, page_start, page_end, NULL);
+               ClearPageChecked(page);
                set_page_dirty(page);
                unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+
+loop_unlock:
                unlock_page(page);
                page_cache_release(page);
+               mutex_unlock(&inode->i_mutex);
+
+               btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
                balance_dirty_pages_ratelimited_nr(inode->i_mapping, 1);
+               i++;
+       }
+
+       if ((range->flags & BTRFS_DEFRAG_RANGE_START_IO))
+               filemap_flush(inode->i_mapping);
+
+       if ((range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)) {
+               /* the filemap_flush will queue IO into the worker threads, but
+                * we have to make sure the IO is actually started and that
+                * ordered extents get created before we return
+                */
+               atomic_inc(&root->fs_info->async_submit_draining);
+               while (atomic_read(&root->fs_info->nr_async_submits) ||
+                     atomic_read(&root->fs_info->async_delalloc_pages)) {
+                       wait_event(root->fs_info->async_submit_wait,
+                          (atomic_read(&root->fs_info->nr_async_submits) == 0 &&
+                           atomic_read(&root->fs_info->async_delalloc_pages) == 0));
+               }
+               atomic_dec(&root->fs_info->async_submit_draining);
+
+               mutex_lock(&inode->i_mutex);
+               BTRFS_I(inode)->force_compress = 0;
+               mutex_unlock(&inode->i_mutex);
        }
 
-out_unlock:
-       mutex_unlock(&inode->i_mutex);
        return 0;
+
+err_reservations:
+       mutex_unlock(&inode->i_mutex);
+       btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
+       btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
+       return ret;
 }
 
 static noinline int btrfs_ioctl_resize(struct btrfs_root *root,
@@ -608,7 +776,7 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root,
                        mod = 1;
                        sizestr++;
                }
-               new_size = btrfs_parse_size(sizestr);
+               new_size = memparse(sizestr, NULL);
                if (new_size == 0) {
                        ret = -EINVAL;
                        goto out_unlock;
@@ -743,6 +911,330 @@ out:
        return ret;
 }
 
+static noinline int key_in_sk(struct btrfs_key *key,
+                             struct btrfs_ioctl_search_key *sk)
+{
+       struct btrfs_key test;
+       int ret;
+
+       test.objectid = sk->min_objectid;
+       test.type = sk->min_type;
+       test.offset = sk->min_offset;
+
+       ret = btrfs_comp_cpu_keys(key, &test);
+       if (ret < 0)
+               return 0;
+
+       test.objectid = sk->max_objectid;
+       test.type = sk->max_type;
+       test.offset = sk->max_offset;
+
+       ret = btrfs_comp_cpu_keys(key, &test);
+       if (ret > 0)
+               return 0;
+       return 1;
+}
+
+static noinline int copy_to_sk(struct btrfs_root *root,
+                              struct btrfs_path *path,
+                              struct btrfs_key *key,
+                              struct btrfs_ioctl_search_key *sk,
+                              char *buf,
+                              unsigned long *sk_offset,
+                              int *num_found)
+{
+       u64 found_transid;
+       struct extent_buffer *leaf;
+       struct btrfs_ioctl_search_header sh;
+       unsigned long item_off;
+       unsigned long item_len;
+       int nritems;
+       int i;
+       int slot;
+       int found = 0;
+       int ret = 0;
+
+       leaf = path->nodes[0];
+       slot = path->slots[0];
+       nritems = btrfs_header_nritems(leaf);
+
+       if (btrfs_header_generation(leaf) > sk->max_transid) {
+               i = nritems;
+               goto advance_key;
+       }
+       found_transid = btrfs_header_generation(leaf);
+
+       for (i = slot; i < nritems; i++) {
+               item_off = btrfs_item_ptr_offset(leaf, i);
+               item_len = btrfs_item_size_nr(leaf, i);
+
+               if (item_len > BTRFS_SEARCH_ARGS_BUFSIZE)
+                       item_len = 0;
+
+               if (sizeof(sh) + item_len + *sk_offset >
+                   BTRFS_SEARCH_ARGS_BUFSIZE) {
+                       ret = 1;
+                       goto overflow;
+               }
+
+               btrfs_item_key_to_cpu(leaf, key, i);
+               if (!key_in_sk(key, sk))
+                       continue;
+
+               sh.objectid = key->objectid;
+               sh.offset = key->offset;
+               sh.type = key->type;
+               sh.len = item_len;
+               sh.transid = found_transid;
+
+               /* copy search result header */
+               memcpy(buf + *sk_offset, &sh, sizeof(sh));
+               *sk_offset += sizeof(sh);
+
+               if (item_len) {
+                       char *p = buf + *sk_offset;
+                       /* copy the item */
+                       read_extent_buffer(leaf, p,
+                                          item_off, item_len);
+                       *sk_offset += item_len;
+               }
+               found++;
+
+               if (*num_found >= sk->nr_items)
+                       break;
+       }
+advance_key:
+       ret = 0;
+       if (key->offset < (u64)-1 && key->offset < sk->max_offset)
+               key->offset++;
+       else if (key->type < (u8)-1 && key->type < sk->max_type) {
+               key->offset = 0;
+               key->type++;
+       } else if (key->objectid < (u64)-1 && key->objectid < sk->max_objectid) {
+               key->offset = 0;
+               key->type = 0;
+               key->objectid++;
+       } else
+               ret = 1;
+overflow:
+       *num_found += found;
+       return ret;
+}
+
+static noinline int search_ioctl(struct inode *inode,
+                                struct btrfs_ioctl_search_args *args)
+{
+       struct btrfs_root *root;
+       struct btrfs_key key;
+       struct btrfs_key max_key;
+       struct btrfs_path *path;
+       struct btrfs_ioctl_search_key *sk = &args->key;
+       struct btrfs_fs_info *info = BTRFS_I(inode)->root->fs_info;
+       int ret;
+       int num_found = 0;
+       unsigned long sk_offset = 0;
+
+       path = btrfs_alloc_path();
+       if (!path)
+               return -ENOMEM;
+
+       if (sk->tree_id == 0) {
+               /* search the root of the inode that was passed */
+               root = BTRFS_I(inode)->root;
+       } else {
+               key.objectid = sk->tree_id;
+               key.type = BTRFS_ROOT_ITEM_KEY;
+               key.offset = (u64)-1;
+               root = btrfs_read_fs_root_no_name(info, &key);
+               if (IS_ERR(root)) {
+                       printk(KERN_ERR "could not find root %llu\n",
+                              sk->tree_id);
+                       btrfs_free_path(path);
+                       return -ENOENT;
+               }
+       }
+
+       key.objectid = sk->min_objectid;
+       key.type = sk->min_type;
+       key.offset = sk->min_offset;
+
+       max_key.objectid = sk->max_objectid;
+       max_key.type = sk->max_type;
+       max_key.offset = sk->max_offset;
+
+       path->keep_locks = 1;
+
+       while(1) {
+               ret = btrfs_search_forward(root, &key, &max_key, path, 0,
+                                          sk->min_transid);
+               if (ret != 0) {
+                       if (ret > 0)
+                               ret = 0;
+                       goto err;
+               }
+               ret = copy_to_sk(root, path, &key, sk, args->buf,
+                                &sk_offset, &num_found);
+               btrfs_release_path(root, path);
+               if (ret || num_found >= sk->nr_items)
+                       break;
+
+       }
+       ret = 0;
+err:
+       sk->nr_items = num_found;
+       btrfs_free_path(path);
+       return ret;
+}
+
+static noinline int btrfs_ioctl_tree_search(struct file *file,
+                                          void __user *argp)
+{
+        struct btrfs_ioctl_search_args *args;
+        struct inode *inode;
+        int ret;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       args = kmalloc(sizeof(*args), GFP_KERNEL);
+       if (!args)
+               return -ENOMEM;
+
+       if (copy_from_user(args, argp, sizeof(*args))) {
+               kfree(args);
+               return -EFAULT;
+       }
+       inode = fdentry(file)->d_inode;
+       ret = search_ioctl(inode, args);
+       if (ret == 0 && copy_to_user(argp, args, sizeof(*args)))
+               ret = -EFAULT;
+       kfree(args);
+       return ret;
+}
+
+/*
+ * Search INODE_REFs to identify path name of 'dirid' directory
+ * in a 'tree_id' tree. and sets path name to 'name'.
+ */
+static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info,
+                               u64 tree_id, u64 dirid, char *name)
+{
+       struct btrfs_root *root;
+       struct btrfs_key key;
+       char *ptr;
+       int ret = -1;
+       int slot;
+       int len;
+       int total_len = 0;
+       struct btrfs_inode_ref *iref;
+       struct extent_buffer *l;
+       struct btrfs_path *path;
+
+       if (dirid == BTRFS_FIRST_FREE_OBJECTID) {
+               name[0]='\0';
+               return 0;
+       }
+
+       path = btrfs_alloc_path();
+       if (!path)
+               return -ENOMEM;
+
+       ptr = &name[BTRFS_INO_LOOKUP_PATH_MAX];
+
+       key.objectid = tree_id;
+       key.type = BTRFS_ROOT_ITEM_KEY;
+       key.offset = (u64)-1;
+       root = btrfs_read_fs_root_no_name(info, &key);
+       if (IS_ERR(root)) {
+               printk(KERN_ERR "could not find root %llu\n", tree_id);
+               ret = -ENOENT;
+               goto out;
+       }
+
+       key.objectid = dirid;
+       key.type = BTRFS_INODE_REF_KEY;
+       key.offset = (u64)-1;
+
+       while(1) {
+               ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+               if (ret < 0)
+                       goto out;
+
+               l = path->nodes[0];
+               slot = path->slots[0];
+               if (ret > 0 && slot > 0)
+                       slot--;
+               btrfs_item_key_to_cpu(l, &key, slot);
+
+               if (ret > 0 && (key.objectid != dirid ||
+                               key.type != BTRFS_INODE_REF_KEY)) {
+                       ret = -ENOENT;
+                       goto out;
+               }
+
+               iref = btrfs_item_ptr(l, slot, struct btrfs_inode_ref);
+               len = btrfs_inode_ref_name_len(l, iref);
+               ptr -= len + 1;
+               total_len += len + 1;
+               if (ptr < name)
+                       goto out;
+
+               *(ptr + len) = '/';
+               read_extent_buffer(l, ptr,(unsigned long)(iref + 1), len);
+
+               if (key.offset == BTRFS_FIRST_FREE_OBJECTID)
+                       break;
+
+               btrfs_release_path(root, path);
+               key.objectid = key.offset;
+               key.offset = (u64)-1;
+               dirid = key.objectid;
+
+       }
+       if (ptr < name)
+               goto out;
+       memcpy(name, ptr, total_len);
+       name[total_len]='\0';
+       ret = 0;
+out:
+       btrfs_free_path(path);
+       return ret;
+}
+
+static noinline int btrfs_ioctl_ino_lookup(struct file *file,
+                                          void __user *argp)
+{
+        struct btrfs_ioctl_ino_lookup_args *args;
+        struct inode *inode;
+        int ret;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       args = kmalloc(sizeof(*args), GFP_KERNEL);
+       if (!args)
+               return -ENOMEM;
+
+       if (copy_from_user(args, argp, sizeof(*args))) {
+               kfree(args);
+               return -EFAULT;
+       }
+       inode = fdentry(file)->d_inode;
+
+       if (args->treeid == 0)
+               args->treeid = BTRFS_I(inode)->root->root_key.objectid;
+
+       ret = btrfs_search_path_in_tree(BTRFS_I(inode)->root->fs_info,
+                                       args->treeid, args->objectid,
+                                       args->name);
+
+       if (ret == 0 && copy_to_user(argp, args, sizeof(*args)))
+               ret = -EFAULT;
+
+       kfree(args);
+       return ret;
+}
+
 static noinline int btrfs_ioctl_snap_destroy(struct file *file,
                                             void __user *arg)
 {
@@ -849,10 +1341,11 @@ out:
        return err;
 }
 
-static int btrfs_ioctl_defrag(struct file *file)
+static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
 {
        struct inode *inode = fdentry(file)->d_inode;
        struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_ioctl_defrag_range_args *range;
        int ret;
 
        ret = mnt_want_write(file->f_path.mnt);
@@ -873,7 +1366,31 @@ static int btrfs_ioctl_defrag(struct file *file)
                        ret = -EINVAL;
                        goto out;
                }
-               btrfs_defrag_file(file);
+
+               range = kzalloc(sizeof(*range), GFP_KERNEL);
+               if (!range) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+
+               if (argp) {
+                       if (copy_from_user(range, argp,
+                                          sizeof(*range))) {
+                               ret = -EFAULT;
+                               kfree(range);
+                               goto out;
+                       }
+                       /* compression requires us to start the IO */
+                       if ((range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)) {
+                               range->flags |= BTRFS_DEFRAG_RANGE_START_IO;
+                               range->extent_thresh = (u32)-1;
+                       }
+               } else {
+                       /* the rest are all set to zero by kzalloc */
+                       range->len = (u64)-1;
+               }
+               btrfs_defrag_file(file, range);
+               kfree(range);
                break;
        }
 out:
@@ -964,12 +1481,17 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
                ret = -EBADF;
                goto out_drop_write;
        }
+
        src = src_file->f_dentry->d_inode;
 
        ret = -EINVAL;
        if (src == inode)
                goto out_fput;
 
+       /* the src must be open for reading */
+       if (!(src_file->f_mode & FMODE_READ))
+               goto out_fput;
+
        ret = -EISDIR;
        if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode))
                goto out_fput;
@@ -1274,6 +1796,157 @@ out:
        return ret;
 }
 
+static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
+{
+       struct inode *inode = fdentry(file)->d_inode;
+       struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_root *new_root;
+       struct btrfs_dir_item *di;
+       struct btrfs_trans_handle *trans;
+       struct btrfs_path *path;
+       struct btrfs_key location;
+       struct btrfs_disk_key disk_key;
+       struct btrfs_super_block *disk_super;
+       u64 features;
+       u64 objectid = 0;
+       u64 dir_id;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       if (copy_from_user(&objectid, argp, sizeof(objectid)))
+               return -EFAULT;
+
+       if (!objectid)
+               objectid = root->root_key.objectid;
+
+       location.objectid = objectid;
+       location.type = BTRFS_ROOT_ITEM_KEY;
+       location.offset = (u64)-1;
+
+       new_root = btrfs_read_fs_root_no_name(root->fs_info, &location);
+       if (IS_ERR(new_root))
+               return PTR_ERR(new_root);
+
+       if (btrfs_root_refs(&new_root->root_item) == 0)
+               return -ENOENT;
+
+       path = btrfs_alloc_path();
+       if (!path)
+               return -ENOMEM;
+       path->leave_spinning = 1;
+
+       trans = btrfs_start_transaction(root, 1);
+       if (!trans) {
+               btrfs_free_path(path);
+               return -ENOMEM;
+       }
+
+       dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
+       di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path,
+                                  dir_id, "default", 7, 1);
+       if (!di) {
+               btrfs_free_path(path);
+               btrfs_end_transaction(trans, root);
+               printk(KERN_ERR "Umm, you don't have the default dir item, "
+                      "this isn't going to work\n");
+               return -ENOENT;
+       }
+
+       btrfs_cpu_key_to_disk(&disk_key, &new_root->root_key);
+       btrfs_set_dir_item_key(path->nodes[0], di, &disk_key);
+       btrfs_mark_buffer_dirty(path->nodes[0]);
+       btrfs_free_path(path);
+
+       disk_super = &root->fs_info->super_copy;
+       features = btrfs_super_incompat_flags(disk_super);
+       if (!(features & BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)) {
+               features |= BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL;
+               btrfs_set_super_incompat_flags(disk_super, features);
+       }
+       btrfs_end_transaction(trans, root);
+
+       return 0;
+}
+
+long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
+{
+       struct btrfs_ioctl_space_args space_args;
+       struct btrfs_ioctl_space_info space;
+       struct btrfs_ioctl_space_info *dest;
+       struct btrfs_ioctl_space_info *dest_orig;
+       struct btrfs_ioctl_space_info *user_dest;
+       struct btrfs_space_info *info;
+       int alloc_size;
+       int ret = 0;
+       int slot_count = 0;
+
+       if (copy_from_user(&space_args,
+                          (struct btrfs_ioctl_space_args __user *)arg,
+                          sizeof(space_args)))
+               return -EFAULT;
+
+       /* first we count slots */
+       rcu_read_lock();
+       list_for_each_entry_rcu(info, &root->fs_info->space_info, list)
+               slot_count++;
+       rcu_read_unlock();
+
+       /* space_slots == 0 means they are asking for a count */
+       if (space_args.space_slots == 0) {
+               space_args.total_spaces = slot_count;
+               goto out;
+       }
+       alloc_size = sizeof(*dest) * slot_count;
+       /* we generally have at most 6 or so space infos, one for each raid
+        * level.  So, a whole page should be more than enough for everyone
+        */
+       if (alloc_size > PAGE_CACHE_SIZE)
+               return -ENOMEM;
+
+       space_args.total_spaces = 0;
+       dest = kmalloc(alloc_size, GFP_NOFS);
+       if (!dest)
+               return -ENOMEM;
+       dest_orig = dest;
+
+       /* now we have a buffer to copy into */
+       rcu_read_lock();
+       list_for_each_entry_rcu(info, &root->fs_info->space_info, list) {
+               /* make sure we don't copy more than we allocated
+                * in our buffer
+                */
+               if (slot_count == 0)
+                       break;
+               slot_count--;
+
+               /* make sure userland has enough room in their buffer */
+               if (space_args.total_spaces >= space_args.space_slots)
+                       break;
+
+               space.flags = info->flags;
+               space.total_bytes = info->total_bytes;
+               space.used_bytes = info->bytes_used;
+               memcpy(dest, &space, sizeof(space));
+               dest++;
+               space_args.total_spaces++;
+       }
+       rcu_read_unlock();
+
+       user_dest = (struct btrfs_ioctl_space_info *)
+               (arg + sizeof(struct btrfs_ioctl_space_args));
+
+       if (copy_to_user(user_dest, dest_orig, alloc_size))
+               ret = -EFAULT;
+
+       kfree(dest_orig);
+out:
+       if (ret == 0 && copy_to_user(arg, &space_args, sizeof(space_args)))
+               ret = -EFAULT;
+
+       return ret;
+}
+
 /*
  * there are many ways the trans_start and trans_end ioctls can lead
  * to deadlocks.  They should only be used by applications that
@@ -1320,8 +1993,12 @@ long btrfs_ioctl(struct file *file, unsigned int
                return btrfs_ioctl_snap_create(file, argp, 1);
        case BTRFS_IOC_SNAP_DESTROY:
                return btrfs_ioctl_snap_destroy(file, argp);
+       case BTRFS_IOC_DEFAULT_SUBVOL:
+               return btrfs_ioctl_default_subvol(file, argp);
        case BTRFS_IOC_DEFRAG:
-               return btrfs_ioctl_defrag(file);
+               return btrfs_ioctl_defrag(file, NULL);
+       case BTRFS_IOC_DEFRAG_RANGE:
+               return btrfs_ioctl_defrag(file, argp);
        case BTRFS_IOC_RESIZE:
                return btrfs_ioctl_resize(root, argp);
        case BTRFS_IOC_ADD_DEV:
@@ -1338,6 +2015,12 @@ long btrfs_ioctl(struct file *file, unsigned int
                return btrfs_ioctl_trans_start(file);
        case BTRFS_IOC_TRANS_END:
                return btrfs_ioctl_trans_end(file);
+       case BTRFS_IOC_TREE_SEARCH:
+               return btrfs_ioctl_tree_search(file, argp);
+       case BTRFS_IOC_INO_LOOKUP:
+               return btrfs_ioctl_ino_lookup(file, argp);
+       case BTRFS_IOC_SPACE_INFO:
+               return btrfs_ioctl_space_info(root, argp);
        case BTRFS_IOC_SYNC:
                btrfs_sync_fs(file->f_dentry->d_sb, 1);
                return 0;
index bc49914475ebbebc5271f3d26d486d730610178d..424694aa517f5b03fd5ee16e4052d4c6c7fd6777 100644 (file)
@@ -30,12 +30,114 @@ struct btrfs_ioctl_vol_args {
        char name[BTRFS_PATH_NAME_MAX + 1];
 };
 
+#define BTRFS_INO_LOOKUP_PATH_MAX 4080
+struct btrfs_ioctl_ino_lookup_args {
+       __u64 treeid;
+       __u64 objectid;
+       char name[BTRFS_INO_LOOKUP_PATH_MAX];
+};
+
+struct btrfs_ioctl_search_key {
+       /* which root are we searching.  0 is the tree of tree roots */
+       __u64 tree_id;
+
+       /* keys returned will be >= min and <= max */
+       __u64 min_objectid;
+       __u64 max_objectid;
+
+       /* keys returned will be >= min and <= max */
+       __u64 min_offset;
+       __u64 max_offset;
+
+       /* max and min transids to search for */
+       __u64 min_transid;
+       __u64 max_transid;
+
+       /* keys returned will be >= min and <= max */
+       __u32 min_type;
+       __u32 max_type;
+
+       /*
+        * how many items did userland ask for, and how many are we
+        * returning
+        */
+       __u32 nr_items;
+
+       /* align to 64 bits */
+       __u32 unused;
+
+       /* some extra for later */
+       __u64 unused1;
+       __u64 unused2;
+       __u64 unused3;
+       __u64 unused4;
+};
+
+struct btrfs_ioctl_search_header {
+       __u64 transid;
+       __u64 objectid;
+       __u64 offset;
+       __u32 type;
+       __u32 len;
+};
+
+#define BTRFS_SEARCH_ARGS_BUFSIZE (4096 - sizeof(struct btrfs_ioctl_search_key))
+/*
+ * the buf is an array of search headers where
+ * each header is followed by the actual item
+ * the type field is expanded to 32 bits for alignment
+ */
+struct btrfs_ioctl_search_args {
+       struct btrfs_ioctl_search_key key;
+       char buf[BTRFS_SEARCH_ARGS_BUFSIZE];
+};
+
 struct btrfs_ioctl_clone_range_args {
   __s64 src_fd;
   __u64 src_offset, src_length;
   __u64 dest_offset;
 };
 
+/* flags for the defrag range ioctl */
+#define BTRFS_DEFRAG_RANGE_COMPRESS 1
+#define BTRFS_DEFRAG_RANGE_START_IO 2
+
+struct btrfs_ioctl_defrag_range_args {
+       /* start of the defrag operation */
+       __u64 start;
+
+       /* number of bytes to defrag, use (u64)-1 to say all */
+       __u64 len;
+
+       /*
+        * flags for the operation, which can include turning
+        * on compression for this one defrag
+        */
+       __u64 flags;
+
+       /*
+        * any extent bigger than this will be considered
+        * already defragged.  Use 0 to take the kernel default
+        * Use 1 to say every single extent must be rewritten
+        */
+       __u32 extent_thresh;
+
+       /* spare for later */
+       __u32 unused[5];
+};
+
+struct btrfs_ioctl_space_info {
+       __u64 flags;
+       __u64 total_bytes;
+       __u64 used_bytes;
+};
+
+struct btrfs_ioctl_space_args {
+       __u64 space_slots;
+       __u64 total_spaces;
+       struct btrfs_ioctl_space_info spaces[0];
+};
+
 #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
                                   struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
@@ -67,4 +169,13 @@ struct btrfs_ioctl_clone_range_args {
                                   struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_SNAP_DESTROY _IOW(BTRFS_IOCTL_MAGIC, 15, \
                                struct btrfs_ioctl_vol_args)
+#define BTRFS_IOC_DEFRAG_RANGE _IOW(BTRFS_IOCTL_MAGIC, 16, \
+                               struct btrfs_ioctl_defrag_range_args)
+#define BTRFS_IOC_TREE_SEARCH _IOWR(BTRFS_IOCTL_MAGIC, 17, \
+                                  struct btrfs_ioctl_search_args)
+#define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, \
+                                  struct btrfs_ioctl_ino_lookup_args)
+#define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64)
+#define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \
+                                   struct btrfs_ioctl_space_args)
 #endif
index 1c36e5cd8f55495843631f7e5d3e6245d47684dd..6151f2ea38bb193eaeed1f45bc7f2d1f60c0b1d7 100644 (file)
@@ -16,7 +16,6 @@
  * Boston, MA 021110-1307, USA.
  */
 #include <linux/sched.h>
-#include <linux/gfp.h>
 #include <linux/pagemap.h>
 #include <linux/spinlock.h>
 #include <linux/page-flags.h>
index 5c2a9e78a949a03ff239db3b99843c258ce7cd84..a127c0ebb2dcaec1d6ac6733855ac88cb6aff4a3 100644 (file)
@@ -16,7 +16,6 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/writeback.h>
@@ -174,7 +173,6 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
        if (!entry)
                return -ENOMEM;
 
-       mutex_lock(&tree->mutex);
        entry->file_offset = file_offset;
        entry->start = start;
        entry->len = len;
@@ -190,16 +188,17 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
        INIT_LIST_HEAD(&entry->list);
        INIT_LIST_HEAD(&entry->root_extent_list);
 
+       spin_lock(&tree->lock);
        node = tree_insert(&tree->tree, file_offset,
                           &entry->rb_node);
        BUG_ON(node);
+       spin_unlock(&tree->lock);
 
        spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
        list_add_tail(&entry->root_extent_list,
                      &BTRFS_I(inode)->root->fs_info->ordered_extents);
        spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
 
-       mutex_unlock(&tree->mutex);
        BUG_ON(node);
        return 0;
 }
@@ -216,9 +215,9 @@ int btrfs_add_ordered_sum(struct inode *inode,
        struct btrfs_ordered_inode_tree *tree;
 
        tree = &BTRFS_I(inode)->ordered_tree;
-       mutex_lock(&tree->mutex);
+       spin_lock(&tree->lock);
        list_add_tail(&sum->list, &entry->list);
-       mutex_unlock(&tree->mutex);
+       spin_unlock(&tree->lock);
        return 0;
 }
 
@@ -232,15 +231,16 @@ int btrfs_add_ordered_sum(struct inode *inode,
  * to make sure this function only returns 1 once for a given ordered extent.
  */
 int btrfs_dec_test_ordered_pending(struct inode *inode,
+                                  struct btrfs_ordered_extent **cached,
                                   u64 file_offset, u64 io_size)
 {
        struct btrfs_ordered_inode_tree *tree;
        struct rb_node *node;
-       struct btrfs_ordered_extent *entry;
+       struct btrfs_ordered_extent *entry = NULL;
        int ret;
 
        tree = &BTRFS_I(inode)->ordered_tree;
-       mutex_lock(&tree->mutex);
+       spin_lock(&tree->lock);
        node = tree_search(tree, file_offset);
        if (!node) {
                ret = 1;
@@ -264,7 +264,11 @@ int btrfs_dec_test_ordered_pending(struct inode *inode,
        else
                ret = 1;
 out:
-       mutex_unlock(&tree->mutex);
+       if (!ret && cached && entry) {
+               *cached = entry;
+               atomic_inc(&entry->refs);
+       }
+       spin_unlock(&tree->lock);
        return ret == 0;
 }
 
@@ -291,13 +295,14 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry)
 
 /*
  * remove an ordered extent from the tree.  No references are dropped
- * and you must wake_up entry->wait.  You must hold the tree mutex
+ * and you must wake_up entry->wait.  You must hold the tree lock
  * while you call this function.
  */
 static int __btrfs_remove_ordered_extent(struct inode *inode,
                                struct btrfs_ordered_extent *entry)
 {
        struct btrfs_ordered_inode_tree *tree;
+       struct btrfs_root *root = BTRFS_I(inode)->root;
        struct rb_node *node;
 
        tree = &BTRFS_I(inode)->ordered_tree;
@@ -307,12 +312,13 @@ static int __btrfs_remove_ordered_extent(struct inode *inode,
        set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags);
 
        spin_lock(&BTRFS_I(inode)->accounting_lock);
+       WARN_ON(!BTRFS_I(inode)->outstanding_extents);
        BTRFS_I(inode)->outstanding_extents--;
        spin_unlock(&BTRFS_I(inode)->accounting_lock);
        btrfs_unreserve_metadata_for_delalloc(BTRFS_I(inode)->root,
                                              inode, 1);
 
-       spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
+       spin_lock(&root->fs_info->ordered_extent_lock);
        list_del_init(&entry->root_extent_list);
 
        /*
@@ -324,7 +330,7 @@ static int __btrfs_remove_ordered_extent(struct inode *inode,
            !mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY)) {
                list_del_init(&BTRFS_I(inode)->ordered_operations);
        }
-       spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
+       spin_unlock(&root->fs_info->ordered_extent_lock);
 
        return 0;
 }
@@ -340,9 +346,9 @@ int btrfs_remove_ordered_extent(struct inode *inode,
        int ret;
 
        tree = &BTRFS_I(inode)->ordered_tree;
-       mutex_lock(&tree->mutex);
+       spin_lock(&tree->lock);
        ret = __btrfs_remove_ordered_extent(inode, entry);
-       mutex_unlock(&tree->mutex);
+       spin_unlock(&tree->lock);
        wake_up(&entry->wait);
 
        return ret;
@@ -567,7 +573,7 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode,
        struct btrfs_ordered_extent *entry = NULL;
 
        tree = &BTRFS_I(inode)->ordered_tree;
-       mutex_lock(&tree->mutex);
+       spin_lock(&tree->lock);
        node = tree_search(tree, file_offset);
        if (!node)
                goto out;
@@ -578,7 +584,7 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode,
        if (entry)
                atomic_inc(&entry->refs);
 out:
-       mutex_unlock(&tree->mutex);
+       spin_unlock(&tree->lock);
        return entry;
 }
 
@@ -594,7 +600,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset)
        struct btrfs_ordered_extent *entry = NULL;
 
        tree = &BTRFS_I(inode)->ordered_tree;
-       mutex_lock(&tree->mutex);
+       spin_lock(&tree->lock);
        node = tree_search(tree, file_offset);
        if (!node)
                goto out;
@@ -602,7 +608,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset)
        entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
        atomic_inc(&entry->refs);
 out:
-       mutex_unlock(&tree->mutex);
+       spin_unlock(&tree->lock);
        return entry;
 }
 
@@ -629,7 +635,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
        else
                offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize);
 
-       mutex_lock(&tree->mutex);
+       spin_lock(&tree->lock);
        disk_i_size = BTRFS_I(inode)->disk_i_size;
 
        /* truncate file */
@@ -735,7 +741,7 @@ out:
         */
        if (ordered)
                __btrfs_remove_ordered_extent(inode, ordered);
-       mutex_unlock(&tree->mutex);
+       spin_unlock(&tree->lock);
        if (ordered)
                wake_up(&ordered->wait);
        return ret;
@@ -762,7 +768,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
        if (!ordered)
                return 1;
 
-       mutex_lock(&tree->mutex);
+       spin_lock(&tree->lock);
        list_for_each_entry_reverse(ordered_sum, &ordered->list, list) {
                if (disk_bytenr >= ordered_sum->bytenr) {
                        num_sectors = ordered_sum->len / sectorsize;
@@ -777,7 +783,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
                }
        }
 out:
-       mutex_unlock(&tree->mutex);
+       spin_unlock(&tree->lock);
        btrfs_put_ordered_extent(ordered);
        return ret;
 }
index 9116c6d0c5a92154897cd01b60b3206712dc54da..c82f76a9f04082ac254319b14625840170707f66 100644 (file)
@@ -21,7 +21,7 @@
 
 /* one of these per inode */
 struct btrfs_ordered_inode_tree {
-       struct mutex mutex;
+       spinlock_t lock;
        struct rb_root tree;
        struct rb_node *last;
 };
@@ -128,7 +128,7 @@ static inline int btrfs_ordered_sum_size(struct btrfs_root *root,
 static inline void
 btrfs_ordered_inode_tree_init(struct btrfs_ordered_inode_tree *t)
 {
-       mutex_init(&t->mutex);
+       spin_lock_init(&t->lock);
        t->tree = RB_ROOT;
        t->last = NULL;
 }
@@ -137,7 +137,8 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry);
 int btrfs_remove_ordered_extent(struct inode *inode,
                                struct btrfs_ordered_extent *entry);
 int btrfs_dec_test_ordered_pending(struct inode *inode,
-                                      u64 file_offset, u64 io_size);
+                                  struct btrfs_ordered_extent **cached,
+                                  u64 file_offset, u64 io_size);
 int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
                             u64 start, u64 len, u64 disk_len, int tyep);
 int btrfs_add_ordered_sum(struct inode *inode,
index d0cc62bccb948e776fb9845c7da1a8f2119788f6..a97314cf6bd6ef7ac44aa60a4485261a74e241a7 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/sort.h>
 #include "ctree.h"
 #include "ref-cache.h"
index 0109e5606bade9a3293ef57e401745508e36c8ab..e558dd941ded32d39493a9a605156d77983abed2 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/writeback.h>
 #include <linux/blkdev.h>
 #include <linux/rbtree.h>
+#include <linux/slab.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
@@ -2659,7 +2660,7 @@ static int relocate_file_extent_cluster(struct inode *inode,
                                        EXTENT_BOUNDARY, GFP_NOFS);
                        nr++;
                }
-               btrfs_set_extent_delalloc(inode, page_start, page_end);
+               btrfs_set_extent_delalloc(inode, page_start, page_end, NULL);
 
                set_page_dirty(page);
                dirty_page++;
@@ -3487,7 +3488,7 @@ static struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info,
        key.objectid = objectid;
        key.type = BTRFS_INODE_ITEM_KEY;
        key.offset = 0;
-       inode = btrfs_iget(root->fs_info->sb, &key, root);
+       inode = btrfs_iget(root->fs_info->sb, &key, root, NULL);
        BUG_ON(IS_ERR(inode) || is_bad_inode(inode));
        BTRFS_I(inode)->index_cnt = group->key.objectid;
 
index f8b4521de90750c32cd2347baea5e25355748066..1866dff0538ef626a17d2dcbf29d9df4df46b3aa 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/namei.h>
 #include <linux/miscdevice.h>
 #include <linux/magic.h>
+#include <linux/slab.h>
 #include "compat.h"
 #include "ctree.h"
 #include "disk-io.h"
@@ -63,22 +64,21 @@ static void btrfs_put_super(struct super_block *sb)
 }
 
 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_compress_force, Opt_notreelog, Opt_ratio,
-       Opt_flushoncommit,
+       Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum,
+       Opt_nodatacow, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, Opt_ssd,
+       Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress,
+       Opt_compress_force, Opt_notreelog, Opt_ratio, Opt_flushoncommit,
        Opt_discard, Opt_err,
 };
 
 static match_table_t tokens = {
        {Opt_degraded, "degraded"},
        {Opt_subvol, "subvol=%s"},
+       {Opt_subvolid, "subvolid=%d"},
        {Opt_device, "device=%s"},
        {Opt_nodatasum, "nodatasum"},
        {Opt_nodatacow, "nodatacow"},
        {Opt_nobarrier, "nobarrier"},
-       {Opt_max_extent, "max_extent=%s"},
        {Opt_max_inline, "max_inline=%s"},
        {Opt_alloc_start, "alloc_start=%s"},
        {Opt_thread_pool, "thread_pool=%d"},
@@ -95,31 +95,6 @@ static match_table_t tokens = {
        {Opt_err, NULL},
 };
 
-u64 btrfs_parse_size(char *str)
-{
-       u64 res;
-       int mult = 1;
-       char *end;
-       char last;
-
-       res = simple_strtoul(str, &end, 10);
-
-       last = end[0];
-       if (isalpha(last)) {
-               last = tolower(last);
-               switch (last) {
-               case 'g':
-                       mult *= 1024;
-               case 'm':
-                       mult *= 1024;
-               case 'k':
-                       mult *= 1024;
-               }
-               res = res * mult;
-       }
-       return res;
-}
-
 /*
  * Regular mount options parser.  Everything that is needed only when
  * reading in a new superblock is parsed here.
@@ -157,6 +132,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                        btrfs_set_opt(info->mount_opt, DEGRADED);
                        break;
                case Opt_subvol:
+               case Opt_subvolid:
                case Opt_device:
                        /*
                         * These are parsed by btrfs_parse_early_options
@@ -211,22 +187,10 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                                       info->thread_pool_size);
                        }
                        break;
-               case Opt_max_extent:
-                       num = match_strdup(&args[0]);
-                       if (num) {
-                               info->max_extent = btrfs_parse_size(num);
-                               kfree(num);
-
-                               info->max_extent = max_t(u64,
-                                       info->max_extent, root->sectorsize);
-                               printk(KERN_INFO "btrfs: max_extent at %llu\n",
-                                      (unsigned long long)info->max_extent);
-                       }
-                       break;
                case Opt_max_inline:
                        num = match_strdup(&args[0]);
                        if (num) {
-                               info->max_inline = btrfs_parse_size(num);
+                               info->max_inline = memparse(num, NULL);
                                kfree(num);
 
                                if (info->max_inline) {
@@ -241,7 +205,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                case Opt_alloc_start:
                        num = match_strdup(&args[0]);
                        if (num) {
-                               info->alloc_start = btrfs_parse_size(num);
+                               info->alloc_start = memparse(num, NULL);
                                kfree(num);
                                printk(KERN_INFO
                                        "btrfs: allocations start at %llu\n",
@@ -292,12 +256,13 @@ out:
  * only when we need to allocate a new super block.
  */
 static int btrfs_parse_early_options(const char *options, fmode_t flags,
-               void *holder, char **subvol_name,
+               void *holder, char **subvol_name, u64 *subvol_objectid,
                struct btrfs_fs_devices **fs_devices)
 {
        substring_t args[MAX_OPT_ARGS];
        char *opts, *p;
        int error = 0;
+       int intarg;
 
        if (!options)
                goto out;
@@ -320,6 +285,18 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
                case Opt_subvol:
                        *subvol_name = match_strdup(&args[0]);
                        break;
+               case Opt_subvolid:
+                       intarg = 0;
+                       error = match_int(&args[0], &intarg);
+                       if (!error) {
+                               /* we want the original fs_tree */
+                               if (!intarg)
+                                       *subvol_objectid =
+                                               BTRFS_FS_TREE_OBJECTID;
+                               else
+                                       *subvol_objectid = intarg;
+                       }
+                       break;
                case Opt_device:
                        error = btrfs_scan_one_device(match_strdup(&args[0]),
                                        flags, holder, fs_devices);
@@ -347,6 +324,110 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
        return error;
 }
 
+static struct dentry *get_default_root(struct super_block *sb,
+                                      u64 subvol_objectid)
+{
+       struct btrfs_root *root = sb->s_fs_info;
+       struct btrfs_root *new_root;
+       struct btrfs_dir_item *di;
+       struct btrfs_path *path;
+       struct btrfs_key location;
+       struct inode *inode;
+       struct dentry *dentry;
+       u64 dir_id;
+       int new = 0;
+
+       /*
+        * We have a specific subvol we want to mount, just setup location and
+        * go look up the root.
+        */
+       if (subvol_objectid) {
+               location.objectid = subvol_objectid;
+               location.type = BTRFS_ROOT_ITEM_KEY;
+               location.offset = (u64)-1;
+               goto find_root;
+       }
+
+       path = btrfs_alloc_path();
+       if (!path)
+               return ERR_PTR(-ENOMEM);
+       path->leave_spinning = 1;
+
+       /*
+        * Find the "default" dir item which points to the root item that we
+        * will mount by default if we haven't been given a specific subvolume
+        * to mount.
+        */
+       dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
+       di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0);
+       if (!di) {
+               /*
+                * Ok the default dir item isn't there.  This is weird since
+                * it's always been there, but don't freak out, just try and
+                * mount to root most subvolume.
+                */
+               btrfs_free_path(path);
+               dir_id = BTRFS_FIRST_FREE_OBJECTID;
+               new_root = root->fs_info->fs_root;
+               goto setup_root;
+       }
+
+       btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location);
+       btrfs_free_path(path);
+
+find_root:
+       new_root = btrfs_read_fs_root_no_name(root->fs_info, &location);
+       if (IS_ERR(new_root))
+               return ERR_PTR(PTR_ERR(new_root));
+
+       if (btrfs_root_refs(&new_root->root_item) == 0)
+               return ERR_PTR(-ENOENT);
+
+       dir_id = btrfs_root_dirid(&new_root->root_item);
+setup_root:
+       location.objectid = dir_id;
+       location.type = BTRFS_INODE_ITEM_KEY;
+       location.offset = 0;
+
+       inode = btrfs_iget(sb, &location, new_root, &new);
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+
+       /*
+        * If we're just mounting the root most subvol put the inode and return
+        * a reference to the dentry.  We will have already gotten a reference
+        * to the inode in btrfs_fill_super so we're good to go.
+        */
+       if (!new && sb->s_root->d_inode == inode) {
+               iput(inode);
+               return dget(sb->s_root);
+       }
+
+       if (new) {
+               const struct qstr name = { .name = "/", .len = 1 };
+
+               /*
+                * New inode, we need to make the dentry a sibling of s_root so
+                * everything gets cleaned up properly on unmount.
+                */
+               dentry = d_alloc(sb->s_root, &name);
+               if (!dentry) {
+                       iput(inode);
+                       return ERR_PTR(-ENOMEM);
+               }
+               d_splice_alias(inode, dentry);
+       } else {
+               /*
+                * We found the inode in cache, just find a dentry for it and
+                * put the reference to the inode we just got.
+                */
+               dentry = d_find_alias(inode);
+               iput(inode);
+       }
+
+       return dentry;
+}
+
 static int btrfs_fill_super(struct super_block *sb,
                            struct btrfs_fs_devices *fs_devices,
                            void *data, int silent)
@@ -380,7 +461,7 @@ static int btrfs_fill_super(struct super_block *sb,
        key.objectid = BTRFS_FIRST_FREE_OBJECTID;
        key.type = BTRFS_INODE_ITEM_KEY;
        key.offset = 0;
-       inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root);
+       inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root, NULL);
        if (IS_ERR(inode)) {
                err = PTR_ERR(inode);
                goto fail_close;
@@ -392,12 +473,6 @@ static int btrfs_fill_super(struct super_block *sb,
                err = -ENOMEM;
                goto fail_close;
        }
-#if 0
-       /* this does the super kobj at the same time */
-       err = btrfs_sysfs_add_super(tree_root->fs_info);
-       if (err)
-               goto fail_close;
-#endif
 
        sb->s_root = root_dentry;
 
@@ -441,9 +516,6 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
                seq_puts(seq, ",nodatacow");
        if (btrfs_test_opt(root, NOBARRIER))
                seq_puts(seq, ",nobarrier");
-       if (info->max_extent != (u64)-1)
-               seq_printf(seq, ",max_extent=%llu",
-                          (unsigned long long)info->max_extent);
        if (info->max_inline != 8192 * 1024)
                seq_printf(seq, ",max_inline=%llu",
                           (unsigned long long)info->max_inline);
@@ -489,19 +561,22 @@ static int btrfs_test_super(struct super_block *s, void *data)
 static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
                const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       char *subvol_name = NULL;
        struct block_device *bdev = NULL;
        struct super_block *s;
        struct dentry *root;
        struct btrfs_fs_devices *fs_devices = NULL;
        fmode_t mode = FMODE_READ;
+       char *subvol_name = NULL;
+       u64 subvol_objectid = 0;
        int error = 0;
+       int found = 0;
 
        if (!(flags & MS_RDONLY))
                mode |= FMODE_WRITE;
 
        error = btrfs_parse_early_options(data, mode, fs_type,
-                                         &subvol_name, &fs_devices);
+                                         &subvol_name, &subvol_objectid,
+                                         &fs_devices);
        if (error)
                return error;
 
@@ -530,6 +605,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
                        goto error_close_devices;
                }
 
+               found = 1;
                btrfs_close_devices(fs_devices);
        } else {
                char b[BDEVNAME_SIZE];
@@ -547,25 +623,35 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
                s->s_flags |= MS_ACTIVE;
        }
 
-       if (!strcmp(subvol_name, "."))
-               root = dget(s->s_root);
-       else {
-               mutex_lock(&s->s_root->d_inode->i_mutex);
-               root = lookup_one_len(subvol_name, s->s_root,
+       root = get_default_root(s, subvol_objectid);
+       if (IS_ERR(root)) {
+               error = PTR_ERR(root);
+               deactivate_locked_super(s);
+               goto error;
+       }
+       /* if they gave us a subvolume name bind mount into that */
+       if (strcmp(subvol_name, ".")) {
+               struct dentry *new_root;
+               mutex_lock(&root->d_inode->i_mutex);
+               new_root = lookup_one_len(subvol_name, root,
                                      strlen(subvol_name));
-               mutex_unlock(&s->s_root->d_inode->i_mutex);
+               mutex_unlock(&root->d_inode->i_mutex);
 
-               if (IS_ERR(root)) {
+               if (IS_ERR(new_root)) {
                        deactivate_locked_super(s);
-                       error = PTR_ERR(root);
-                       goto error_free_subvol_name;
+                       error = PTR_ERR(new_root);
+                       dput(root);
+                       goto error_close_devices;
                }
-               if (!root->d_inode) {
+               if (!new_root->d_inode) {
                        dput(root);
+                       dput(new_root);
                        deactivate_locked_super(s);
                        error = -ENXIO;
-                       goto error_free_subvol_name;
+                       goto error_close_devices;
                }
+               dput(root);
+               root = new_root;
        }
 
        mnt->mnt_sb = s;
@@ -580,6 +666,7 @@ error_close_devices:
        btrfs_close_devices(fs_devices);
 error_free_subvol_name:
        kfree(subvol_name);
+error:
        return error;
 }
 
@@ -624,14 +711,37 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
        struct btrfs_root *root = btrfs_sb(dentry->d_sb);
        struct btrfs_super_block *disk_super = &root->fs_info->super_copy;
+       struct list_head *head = &root->fs_info->space_info;
+       struct btrfs_space_info *found;
+       u64 total_used = 0;
+       u64 data_used = 0;
        int bits = dentry->d_sb->s_blocksize_bits;
        __be32 *fsid = (__be32 *)root->fs_info->fsid;
 
+       rcu_read_lock();
+       list_for_each_entry_rcu(found, head, list) {
+               if (found->flags & (BTRFS_BLOCK_GROUP_DUP|
+                                   BTRFS_BLOCK_GROUP_RAID10|
+                                   BTRFS_BLOCK_GROUP_RAID1)) {
+                       total_used += found->bytes_used;
+                       if (found->flags & BTRFS_BLOCK_GROUP_DATA)
+                               data_used += found->bytes_used;
+                       else
+                               data_used += found->total_bytes;
+               }
+
+               total_used += found->bytes_used;
+               if (found->flags & BTRFS_BLOCK_GROUP_DATA)
+                       data_used += found->bytes_used;
+               else
+                       data_used += found->total_bytes;
+       }
+       rcu_read_unlock();
+
        buf->f_namelen = BTRFS_NAME_LEN;
        buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits;
-       buf->f_bfree = buf->f_blocks -
-               (btrfs_super_bytes_used(disk_super) >> bits);
-       buf->f_bavail = buf->f_bfree;
+       buf->f_bfree = buf->f_blocks - (total_used >> bits);
+       buf->f_bavail = buf->f_blocks - (data_used >> bits);
        buf->f_bsize = dentry->d_sb->s_blocksize;
        buf->f_type = BTRFS_SUPER_MAGIC;
 
index 2a36e236a4924c978d7b74c416e062f7d92dc921..2cb116099b90207d0f1910176de8a029bd23c93f 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/writeback.h>
 #include <linux/pagemap.h>
@@ -147,18 +148,13 @@ static void wait_current_trans(struct btrfs_root *root)
                while (1) {
                        prepare_to_wait(&root->fs_info->transaction_wait, &wait,
                                        TASK_UNINTERRUPTIBLE);
-                       if (cur_trans->blocked) {
-                               mutex_unlock(&root->fs_info->trans_mutex);
-                               schedule();
-                               mutex_lock(&root->fs_info->trans_mutex);
-                               finish_wait(&root->fs_info->transaction_wait,
-                                           &wait);
-                       } else {
-                               finish_wait(&root->fs_info->transaction_wait,
-                                           &wait);
+                       if (!cur_trans->blocked)
                                break;
-                       }
+                       mutex_unlock(&root->fs_info->trans_mutex);
+                       schedule();
+                       mutex_lock(&root->fs_info->trans_mutex);
                }
+               finish_wait(&root->fs_info->transaction_wait, &wait);
                put_transaction(cur_trans);
        }
 }
@@ -760,10 +756,17 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        struct btrfs_root_item *new_root_item;
        struct btrfs_root *tree_root = fs_info->tree_root;
        struct btrfs_root *root = pending->root;
+       struct btrfs_root *parent_root;
+       struct inode *parent_inode;
        struct extent_buffer *tmp;
        struct extent_buffer *old;
        int ret;
        u64 objectid;
+       int namelen;
+       u64 index = 0;
+
+       parent_inode = pending->dentry->d_parent->d_inode;
+       parent_root = BTRFS_I(parent_inode)->root;
 
        new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
        if (!new_root_item) {
@@ -774,79 +777,59 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        if (ret)
                goto fail;
 
-       record_root_in_trans(trans, root);
-       btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
-       memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
-
        key.objectid = objectid;
        /* record when the snapshot was created in key.offset */
        key.offset = trans->transid;
        btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
 
-       old = btrfs_lock_root_node(root);
-       btrfs_cow_block(trans, root, old, NULL, 0, &old);
-       btrfs_set_lock_blocking(old);
-
-       btrfs_copy_root(trans, root, old, &tmp, objectid);
-       btrfs_tree_unlock(old);
-       free_extent_buffer(old);
-
-       btrfs_set_root_node(new_root_item, tmp);
-       ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key,
-                               new_root_item);
-       btrfs_tree_unlock(tmp);
-       free_extent_buffer(tmp);
-       if (ret)
-               goto fail;
-
-       key.offset = (u64)-1;
        memcpy(&pending->root_key, &key, sizeof(key));
-fail:
-       kfree(new_root_item);
-       return ret;
-}
-
-static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info,
-                                  struct btrfs_pending_snapshot *pending)
-{
-       int ret;
-       int namelen;
-       u64 index = 0;
-       struct btrfs_trans_handle *trans;
-       struct inode *parent_inode;
-       struct btrfs_root *parent_root;
-
-       parent_inode = pending->dentry->d_parent->d_inode;
-       parent_root = BTRFS_I(parent_inode)->root;
-       trans = btrfs_join_transaction(parent_root, 1);
+       pending->root_key.offset = (u64)-1;
 
+       record_root_in_trans(trans, parent_root);
        /*
         * insert the directory item
         */
        namelen = strlen(pending->name);
        ret = btrfs_set_inode_index(parent_inode, &index);
+       BUG_ON(ret);
        ret = btrfs_insert_dir_item(trans, parent_root,
                            pending->name, namelen,
                            parent_inode->i_ino,
                            &pending->root_key, BTRFS_FT_DIR, index);
-
-       if (ret)
-               goto fail;
+       BUG_ON(ret);
 
        btrfs_i_size_write(parent_inode, parent_inode->i_size + namelen * 2);
        ret = btrfs_update_inode(trans, parent_root, parent_inode);
        BUG_ON(ret);
 
+       record_root_in_trans(trans, root);
+       btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
+       memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
+
+       old = btrfs_lock_root_node(root);
+       btrfs_cow_block(trans, root, old, NULL, 0, &old);
+       btrfs_set_lock_blocking(old);
+
+       btrfs_copy_root(trans, root, old, &tmp, objectid);
+       btrfs_tree_unlock(old);
+       free_extent_buffer(old);
+
+       btrfs_set_root_node(new_root_item, tmp);
+       ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key,
+                               new_root_item);
+       BUG_ON(ret);
+       btrfs_tree_unlock(tmp);
+       free_extent_buffer(tmp);
+
        ret = btrfs_add_root_ref(trans, parent_root->fs_info->tree_root,
                                 pending->root_key.objectid,
                                 parent_root->root_key.objectid,
                                 parent_inode->i_ino, index, pending->name,
                                 namelen);
-
        BUG_ON(ret);
 
 fail:
-       btrfs_end_transaction(trans, fs_info->fs_root);
+       kfree(new_root_item);
        return ret;
 }
 
@@ -867,25 +850,6 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
        return 0;
 }
 
-static noinline int finish_pending_snapshots(struct btrfs_trans_handle *trans,
-                                            struct btrfs_fs_info *fs_info)
-{
-       struct btrfs_pending_snapshot *pending;
-       struct list_head *head = &trans->transaction->pending_snapshots;
-       int ret;
-
-       while (!list_empty(head)) {
-               pending = list_entry(head->next,
-                                    struct btrfs_pending_snapshot, list);
-               ret = finish_pending_snapshot(fs_info, pending);
-               BUG_ON(ret);
-               list_del(&pending->list);
-               kfree(pending->name);
-               kfree(pending);
-       }
-       return 0;
-}
-
 static void update_super_roots(struct btrfs_root *root)
 {
        struct btrfs_root_item *root_item;
@@ -997,13 +961,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
 
                mutex_unlock(&root->fs_info->trans_mutex);
 
-               if (flush_on_commit) {
+               if (flush_on_commit || snap_pending) {
                        btrfs_start_delalloc_inodes(root, 1);
                        ret = btrfs_wait_ordered_extents(root, 0, 1);
                        BUG_ON(ret);
-               } else if (snap_pending) {
-                       ret = btrfs_wait_ordered_extents(root, 0, 1);
-                       BUG_ON(ret);
                }
 
                /*
@@ -1100,9 +1061,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
 
        btrfs_finish_extent_commit(trans, root);
 
-       /* do the directory inserts of any pending snapshot creations */
-       finish_pending_snapshots(trans, root->fs_info);
-
        mutex_lock(&root->fs_info->trans_mutex);
 
        cur_trans->commit_done = 1;
index 4a9434b622ecfc0f571c32ea3abf54df3d878123..af57dd2b43d429777ff2530dfbc978ed33f76e2a 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "ctree.h"
 #include "transaction.h"
 #include "disk-io.h"
@@ -445,7 +446,7 @@ static noinline struct inode *read_one_inode(struct btrfs_root *root,
        key.objectid = objectid;
        key.type = BTRFS_INODE_ITEM_KEY;
        key.offset = 0;
-       inode = btrfs_iget(root->fs_info->sb, &key, root);
+       inode = btrfs_iget(root->fs_info->sb, &key, root, NULL);
        if (IS_ERR(inode)) {
                inode = NULL;
        } else if (is_bad_inode(inode)) {
index 41ecbb2347f2d3171f7645782ab4e5a39621c84d..8db7b14bbae8be31c726b8e8596d0ff0640fa35f 100644 (file)
@@ -17,6 +17,7 @@
  */
 #include <linux/sched.h>
 #include <linux/bio.h>
+#include <linux/slab.h>
 #include <linux/buffer_head.h>
 #include <linux/blkdev.h>
 #include <linux/random.h>
@@ -256,13 +257,13 @@ loop_lock:
                        wake_up(&fs_info->async_submit_wait);
 
                BUG_ON(atomic_read(&cur->bi_cnt) == 0);
-               submit_bio(cur->bi_rw, cur);
-               num_run++;
-               batch_run++;
 
                if (bio_rw_flagged(cur, BIO_RW_SYNCIO))
                        num_sync_run++;
 
+               submit_bio(cur->bi_rw, cur);
+               num_run++;
+               batch_run++;
                if (need_resched()) {
                        if (num_sync_run) {
                                blk_run_backing_dev(bdi, NULL);
@@ -325,16 +326,6 @@ loop_lock:
                num_sync_run = 0;
                blk_run_backing_dev(bdi, NULL);
        }
-
-       cond_resched();
-       if (again)
-               goto loop;
-
-       spin_lock(&device->io_lock);
-       if (device->pending_bios.head || device->pending_sync_bios.head)
-               goto loop_lock;
-       spin_unlock(&device->io_lock);
-
        /*
         * IO has already been through a long path to get here.  Checksumming,
         * async helper threads, perhaps compression.  We've done a pretty
@@ -346,6 +337,16 @@ loop_lock:
         * cared about found its way down here.
         */
        blk_run_backing_dev(bdi, NULL);
+
+       cond_resched();
+       if (again)
+               goto loop;
+
+       spin_lock(&device->io_lock);
+       if (device->pending_bios.head || device->pending_sync_bios.head)
+               goto loop_lock;
+       spin_unlock(&device->io_lock);
+
 done:
        return 0;
 }
@@ -365,6 +366,7 @@ static noinline int device_list_add(const char *path,
        struct btrfs_device *device;
        struct btrfs_fs_devices *fs_devices;
        u64 found_transid = btrfs_super_generation(disk_super);
+       char *name;
 
        fs_devices = find_fsid(disk_super->fsid);
        if (!fs_devices) {
@@ -411,6 +413,12 @@ static noinline int device_list_add(const char *path,
 
                device->fs_devices = fs_devices;
                fs_devices->num_devices++;
+       } else if (strcmp(device->name, path)) {
+               name = kstrdup(path, GFP_NOFS);
+               if (!name)
+                       return -ENOMEM;
+               kfree(device->name);
+               device->name = name;
        }
 
        if (found_transid > fs_devices->latest_trans) {
@@ -592,7 +600,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
                        goto error_close;
 
                disk_super = (struct btrfs_super_block *)bh->b_data;
-               devid = le64_to_cpu(disk_super->dev_item.devid);
+               devid = btrfs_stack_device_id(&disk_super->dev_item);
                if (devid != device->devid)
                        goto error_brelse;
 
@@ -694,7 +702,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
                goto error_close;
        }
        disk_super = (struct btrfs_super_block *)bh->b_data;
-       devid = le64_to_cpu(disk_super->dev_item.devid);
+       devid = btrfs_stack_device_id(&disk_super->dev_item);
        transid = btrfs_super_generation(disk_super);
        if (disk_super->label[0])
                printk(KERN_INFO "device label %s ", disk_super->label);
@@ -1187,7 +1195,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
                        goto error_close;
                }
                disk_super = (struct btrfs_super_block *)bh->b_data;
-               devid = le64_to_cpu(disk_super->dev_item.devid);
+               devid = btrfs_stack_device_id(&disk_super->dev_item);
                dev_uuid = disk_super->dev_item.uuid;
                device = btrfs_find_device(root, devid, dev_uuid,
                                           disk_super->fsid);
@@ -2191,9 +2199,9 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
                min_stripes = 2;
        }
        if (type & (BTRFS_BLOCK_GROUP_RAID1)) {
-               num_stripes = min_t(u64, 2, fs_devices->rw_devices);
-               if (num_stripes < 2)
+               if (fs_devices->rw_devices < 2)
                        return -ENOSPC;
+               num_stripes = 2;
                min_stripes = 2;
        }
        if (type & (BTRFS_BLOCK_GROUP_RAID10)) {
@@ -2237,8 +2245,16 @@ again:
                do_div(calc_size, stripe_len);
                calc_size *= stripe_len;
        }
+
        /* we don't want tiny stripes */
-       calc_size = max_t(u64, min_stripe_size, calc_size);
+       if (!looped)
+               calc_size = max_t(u64, min_stripe_size, calc_size);
+
+       /*
+        * we're about to do_div by the stripe_len so lets make sure
+        * we end up with something bigger than a stripe
+        */
+       calc_size = max_t(u64, calc_size, stripe_len * 4);
 
        do_div(calc_size, stripe_len);
        calc_size *= stripe_len;
@@ -3382,6 +3398,8 @@ int btrfs_read_chunk_tree(struct btrfs_root *root)
        key.type = 0;
 again:
        ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+       if (ret < 0)
+               goto error;
        while (1) {
                leaf = path->nodes[0];
                slot = path->slots[0];
index 27089311fbea467b4ca6ec7d6522ae0525231c6f..37fe101a4e0dd22a85f4628e98285cc33c3ad879 100644 (file)
@@ -9,6 +9,7 @@
  * 2 of the Licence, or (at your option) any later version.
  */
 
+#include <linux/slab.h>
 #include <linux/mount.h>
 #include <linux/buffer_head.h>
 #include "internal.h"
index f7c255f9c624eaf3e3e71bca056e41c05ccb64f3..a8cd821226da70406f728851cbdfc8d95dc7fcac 100644 (file)
@@ -34,6 +34,7 @@ struct cachefiles_object {
        loff_t                          i_size;         /* object size */
        unsigned long                   flags;
 #define CACHEFILES_OBJECT_ACTIVE       0               /* T if marked active */
+#define CACHEFILES_OBJECT_BURIED       1               /* T if preemptively buried */
        atomic_t                        usage;          /* object usage count */
        uint8_t                         type;           /* object type */
        uint8_t                         new;            /* T if object new */
index eeb4986ea7db7cbb65b0b48685ae0a0d3f6a1a7e..f4a7840bf42cbb4c4be9cf74a7488e61aab4c94d 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/security.h>
+#include <linux/slab.h>
 #include "internal.h"
 
 #define CACHEFILES_KEYBUF_SIZE 512
@@ -91,6 +92,59 @@ static noinline void cachefiles_printk_object(struct cachefiles_object *object,
        kfree(keybuf);
 }
 
+/*
+ * mark the owner of a dentry, if there is one, to indicate that that dentry
+ * has been preemptively deleted
+ * - the caller must hold the i_mutex on the dentry's parent as required to
+ *   call vfs_unlink(), vfs_rmdir() or vfs_rename()
+ */
+static void cachefiles_mark_object_buried(struct cachefiles_cache *cache,
+                                         struct dentry *dentry)
+{
+       struct cachefiles_object *object;
+       struct rb_node *p;
+
+       _enter(",'%*.*s'",
+              dentry->d_name.len, dentry->d_name.len, dentry->d_name.name);
+
+       write_lock(&cache->active_lock);
+
+       p = cache->active_nodes.rb_node;
+       while (p) {
+               object = rb_entry(p, struct cachefiles_object, active_node);
+               if (object->dentry > dentry)
+                       p = p->rb_left;
+               else if (object->dentry < dentry)
+                       p = p->rb_right;
+               else
+                       goto found_dentry;
+       }
+
+       write_unlock(&cache->active_lock);
+       _leave(" [no owner]");
+       return;
+
+       /* found the dentry for  */
+found_dentry:
+       kdebug("preemptive burial: OBJ%x [%s] %p",
+              object->fscache.debug_id,
+              fscache_object_states[object->fscache.state],
+              dentry);
+
+       if (object->fscache.state < FSCACHE_OBJECT_DYING) {
+               printk(KERN_ERR "\n");
+               printk(KERN_ERR "CacheFiles: Error:"
+                      " Can't preemptively bury live object\n");
+               cachefiles_printk_object(object, NULL);
+       } else if (test_and_set_bit(CACHEFILES_OBJECT_BURIED, &object->flags)) {
+               printk(KERN_ERR "CacheFiles: Error:"
+                      " Object already preemptively buried\n");
+       }
+
+       write_unlock(&cache->active_lock);
+       _leave(" [owner marked]");
+}
+
 /*
  * record the fact that an object is now active
  */
@@ -218,7 +272,8 @@ requeue:
  */
 static int cachefiles_bury_object(struct cachefiles_cache *cache,
                                  struct dentry *dir,
-                                 struct dentry *rep)
+                                 struct dentry *rep,
+                                 bool preemptive)
 {
        struct dentry *grave, *trap;
        char nbuffer[8 + 8 + 1];
@@ -228,11 +283,16 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
               dir->d_name.len, dir->d_name.len, dir->d_name.name,
               rep->d_name.len, rep->d_name.len, rep->d_name.name);
 
+       _debug("remove %p from %p", rep, dir);
+
        /* non-directories can just be unlinked */
        if (!S_ISDIR(rep->d_inode->i_mode)) {
                _debug("unlink stale object");
                ret = vfs_unlink(dir->d_inode, rep);
 
+               if (preemptive)
+                       cachefiles_mark_object_buried(cache, rep);
+
                mutex_unlock(&dir->d_inode->i_mutex);
 
                if (ret == -EIO)
@@ -324,6 +384,9 @@ try_again:
        if (ret != 0 && ret != -ENOMEM)
                cachefiles_io_error(cache, "Rename failed with error %d", ret);
 
+       if (preemptive)
+               cachefiles_mark_object_buried(cache, rep);
+
        unlock_rename(cache->graveyard, dir);
        dput(grave);
        _leave(" = 0");
@@ -339,7 +402,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache,
        struct dentry *dir;
        int ret;
 
-       _enter(",{%p}", object->dentry);
+       _enter(",OBJ%x{%p}", object->fscache.debug_id, object->dentry);
 
        ASSERT(object->dentry);
        ASSERT(object->dentry->d_inode);
@@ -349,15 +412,25 @@ int cachefiles_delete_object(struct cachefiles_cache *cache,
 
        mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
 
-       /* we need to check that our parent is _still_ our parent - it may have
-        * been renamed */
-       if (dir == object->dentry->d_parent) {
-               ret = cachefiles_bury_object(cache, dir, object->dentry);
-       } else {
-               /* it got moved, presumably by cachefilesd culling it, so it's
-                * no longer in the key path and we can ignore it */
+       if (test_bit(CACHEFILES_OBJECT_BURIED, &object->flags)) {
+               /* object allocation for the same key preemptively deleted this
+                * object's file so that it could create its own file */
+               _debug("object preemptively buried");
                mutex_unlock(&dir->d_inode->i_mutex);
                ret = 0;
+       } else {
+               /* we need to check that our parent is _still_ our parent - it
+                * may have been renamed */
+               if (dir == object->dentry->d_parent) {
+                       ret = cachefiles_bury_object(cache, dir,
+                                                    object->dentry, false);
+               } else {
+                       /* it got moved, presumably by cachefilesd culling it,
+                        * so it's no longer in the key path and we can ignore
+                        * it */
+                       mutex_unlock(&dir->d_inode->i_mutex);
+                       ret = 0;
+               }
        }
 
        dput(dir);
@@ -380,7 +453,9 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
        const char *name;
        int ret, nlen;
 
-       _enter("{%p},,%s,", parent->dentry, key);
+       _enter("OBJ%x{%p},OBJ%x,%s,",
+              parent->fscache.debug_id, parent->dentry,
+              object->fscache.debug_id, key);
 
        cache = container_of(parent->fscache.cache,
                             struct cachefiles_cache, cache);
@@ -508,7 +583,7 @@ lookup_again:
                         * mutex) */
                        object->dentry = NULL;
 
-                       ret = cachefiles_bury_object(cache, dir, next);
+                       ret = cachefiles_bury_object(cache, dir, next, true);
                        dput(next);
                        next = NULL;
 
@@ -827,7 +902,7 @@ int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
        /*  actually remove the victim (drops the dir mutex) */
        _debug("bury");
 
-       ret = cachefiles_bury_object(cache, dir, victim);
+       ret = cachefiles_bury_object(cache, dir, victim, false);
        if (ret < 0)
                goto error;
 
index 1d8332563863ce5d858971a68f4a7463c72385c2..0f0d41fbb03f96466393fed9766776d3113d4153 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/mount.h>
+#include <linux/slab.h>
 #include <linux/file.h>
 #include "internal.h"
 
index b5808cdb22325f0f21a1442910690772ad60431c..039b5011d83b0f1481ec200f1229db568f733a02 100644 (file)
@@ -77,6 +77,8 @@ static int cachefiles_check_cache_dir(struct cachefiles_cache *cache,
 /*
  * check the security details of the on-disk cache
  * - must be called with security override in force
+ * - must return with a security override in force - even in the case of an
+ *   error
  */
 int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
                                        struct dentry *root,
@@ -99,6 +101,8 @@ int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
         * which create files */
        ret = set_create_files_as(new, root->d_inode);
        if (ret < 0) {
+               abort_creds(new);
+               cachefiles_begin_secure(cache, _saved_cred);
                _leave(" = %d [cfa]", ret);
                return ret;
        }
index f3e7a0bf068b17cf4cb2e5a5f6fa701daf08d4e5..e18b183b47e1c2e11aa49ad37ec6cf227305f68f 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/fsnotify.h>
 #include <linux/quotaops.h>
 #include <linux/xattr.h>
+#include <linux/slab.h>
 #include "internal.h"
 
 static const char cachefiles_xattr_cache[] =
diff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig
new file mode 100644 (file)
index 0000000..04b8280
--- /dev/null
@@ -0,0 +1,27 @@
+config CEPH_FS
+        tristate "Ceph distributed file system (EXPERIMENTAL)"
+       depends on INET && EXPERIMENTAL
+       select LIBCRC32C
+       select CONFIG_CRYPTO_AES
+       help
+         Choose Y or M here to include support for mounting the
+         experimental Ceph distributed file system.  Ceph is an extremely
+         scalable file system designed to provide high performance,
+         reliable access to petabytes of storage.
+
+         More information at http://ceph.newdream.net/.
+
+         If unsure, say N.
+
+config CEPH_FS_PRETTYDEBUG
+       bool "Include file:line in ceph debug output"
+       depends on CEPH_FS
+       default n
+       help
+         If you say Y here, debug output will include a filename and
+         line to aid debugging.  This icnreases kernel size and slows
+         execution slightly when debug call sites are enabled (e.g.,
+         via CONFIG_DYNAMIC_DEBUG).
+
+         If unsure, say N.
+
diff --git a/fs/ceph/Makefile b/fs/ceph/Makefile
new file mode 100644 (file)
index 0000000..6a660e6
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# Makefile for CEPH filesystem.
+#
+
+ifneq ($(KERNELRELEASE),)
+
+obj-$(CONFIG_CEPH_FS) += ceph.o
+
+ceph-objs := super.o inode.o dir.o file.o addr.o ioctl.o \
+       export.o caps.o snap.o xattr.o \
+       messenger.o msgpool.o buffer.o pagelist.o \
+       mds_client.o mdsmap.o \
+       mon_client.o \
+       osd_client.o osdmap.o crush/crush.o crush/mapper.o crush/hash.o \
+       debugfs.o \
+       auth.o auth_none.o \
+       crypto.o armor.o \
+       auth_x.o \
+       ceph_fs.o ceph_strings.o ceph_hash.o ceph_frag.o
+
+else
+#Otherwise we were called directly from the command
+# line; invoke the kernel build system.
+
+KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+PWD := $(shell pwd)
+
+default: all
+
+all:
+       $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_FS=m modules
+
+modules_install:
+       $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_FS=m modules_install
+
+clean:
+       $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
+
+endif
diff --git a/fs/ceph/README b/fs/ceph/README
new file mode 100644 (file)
index 0000000..18352fa
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# The following files are shared by (and manually synchronized
+# between) the Ceph userland and kernel client.
+#
+# userland                  kernel
+src/include/ceph_fs.h      fs/ceph/ceph_fs.h
+src/include/ceph_fs.cc     fs/ceph/ceph_fs.c
+src/include/msgr.h         fs/ceph/msgr.h
+src/include/rados.h        fs/ceph/rados.h
+src/include/ceph_strings.cc fs/ceph/ceph_strings.c
+src/include/ceph_frag.h            fs/ceph/ceph_frag.h
+src/include/ceph_frag.cc    fs/ceph/ceph_frag.c
+src/include/ceph_hash.h            fs/ceph/ceph_hash.h
+src/include/ceph_hash.cc    fs/ceph/ceph_hash.c
+src/crush/crush.c          fs/ceph/crush/crush.c
+src/crush/crush.h          fs/ceph/crush/crush.h
+src/crush/mapper.c         fs/ceph/crush/mapper.c
+src/crush/mapper.h         fs/ceph/crush/mapper.h
+src/crush/hash.h           fs/ceph/crush/hash.h
+src/crush/hash.c           fs/ceph/crush/hash.c
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
new file mode 100644 (file)
index 0000000..a9005d8
--- /dev/null
@@ -0,0 +1,1187 @@
+#include "ceph_debug.h"
+
+#include <linux/backing-dev.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/writeback.h>   /* generic_writepages */
+#include <linux/slab.h>
+#include <linux/pagevec.h>
+#include <linux/task_io_accounting_ops.h>
+
+#include "super.h"
+#include "osd_client.h"
+
+/*
+ * Ceph address space ops.
+ *
+ * There are a few funny things going on here.
+ *
+ * The page->private field is used to reference a struct
+ * ceph_snap_context for _every_ dirty page.  This indicates which
+ * snapshot the page was logically dirtied in, and thus which snap
+ * context needs to be associated with the osd write during writeback.
+ *
+ * Similarly, struct ceph_inode_info maintains a set of counters to
+ * count dirty pages on the inode.  In the absense of snapshots,
+ * i_wrbuffer_ref == i_wrbuffer_ref_head == the dirty page count.
+ *
+ * When a snapshot is taken (that is, when the client receives
+ * notification that a snapshot was taken), each inode with caps and
+ * with dirty pages (dirty pages implies there is a cap) gets a new
+ * ceph_cap_snap in the i_cap_snaps list (which is sorted in ascending
+ * order, new snaps go to the tail).  The i_wrbuffer_ref_head count is
+ * moved to capsnap->dirty. (Unless a sync write is currently in
+ * progress.  In that case, the capsnap is said to be "pending", new
+ * writes cannot start, and the capsnap isn't "finalized" until the
+ * write completes (or fails) and a final size/mtime for the inode for
+ * that snap can be settled upon.)  i_wrbuffer_ref_head is reset to 0.
+ *
+ * On writeback, we must submit writes to the osd IN SNAP ORDER.  So,
+ * we look for the first capsnap in i_cap_snaps and write out pages in
+ * that snap context _only_.  Then we move on to the next capsnap,
+ * eventually reaching the "live" or "head" context (i.e., pages that
+ * are not yet snapped) and are writing the most recently dirtied
+ * pages.
+ *
+ * Invalidate and so forth must take care to ensure the dirty page
+ * accounting is preserved.
+ */
+
+#define CONGESTION_ON_THRESH(congestion_kb) (congestion_kb >> (PAGE_SHIFT-10))
+#define CONGESTION_OFF_THRESH(congestion_kb)                           \
+       (CONGESTION_ON_THRESH(congestion_kb) -                          \
+        (CONGESTION_ON_THRESH(congestion_kb) >> 2))
+
+
+
+/*
+ * Dirty a page.  Optimistically adjust accounting, on the assumption
+ * that we won't race with invalidate.  If we do, readjust.
+ */
+static int ceph_set_page_dirty(struct page *page)
+{
+       struct address_space *mapping = page->mapping;
+       struct inode *inode;
+       struct ceph_inode_info *ci;
+       int undo = 0;
+       struct ceph_snap_context *snapc;
+
+       if (unlikely(!mapping))
+               return !TestSetPageDirty(page);
+
+       if (TestSetPageDirty(page)) {
+               dout("%p set_page_dirty %p idx %lu -- already dirty\n",
+                    mapping->host, page, page->index);
+               return 0;
+       }
+
+       inode = mapping->host;
+       ci = ceph_inode(inode);
+
+       /*
+        * Note that we're grabbing a snapc ref here without holding
+        * any locks!
+        */
+       snapc = ceph_get_snap_context(ci->i_snap_realm->cached_context);
+
+       /* dirty the head */
+       spin_lock(&inode->i_lock);
+       if (ci->i_wrbuffer_ref_head == 0)
+               ci->i_head_snapc = ceph_get_snap_context(snapc);
+       ++ci->i_wrbuffer_ref_head;
+       if (ci->i_wrbuffer_ref == 0)
+               igrab(inode);
+       ++ci->i_wrbuffer_ref;
+       dout("%p set_page_dirty %p idx %lu head %d/%d -> %d/%d "
+            "snapc %p seq %lld (%d snaps)\n",
+            mapping->host, page, page->index,
+            ci->i_wrbuffer_ref-1, ci->i_wrbuffer_ref_head-1,
+            ci->i_wrbuffer_ref, ci->i_wrbuffer_ref_head,
+            snapc, snapc->seq, snapc->num_snaps);
+       spin_unlock(&inode->i_lock);
+
+       /* now adjust page */
+       spin_lock_irq(&mapping->tree_lock);
+       if (page->mapping) {    /* Race with truncate? */
+               WARN_ON_ONCE(!PageUptodate(page));
+
+               if (mapping_cap_account_dirty(mapping)) {
+                       __inc_zone_page_state(page, NR_FILE_DIRTY);
+                       __inc_bdi_stat(mapping->backing_dev_info,
+                                       BDI_RECLAIMABLE);
+                       task_io_account_write(PAGE_CACHE_SIZE);
+               }
+               radix_tree_tag_set(&mapping->page_tree,
+                               page_index(page), PAGECACHE_TAG_DIRTY);
+
+               /*
+                * Reference snap context in page->private.  Also set
+                * PagePrivate so that we get invalidatepage callback.
+                */
+               page->private = (unsigned long)snapc;
+               SetPagePrivate(page);
+       } else {
+               dout("ANON set_page_dirty %p (raced truncate?)\n", page);
+               undo = 1;
+       }
+
+       spin_unlock_irq(&mapping->tree_lock);
+
+       if (undo)
+               /* whoops, we failed to dirty the page */
+               ceph_put_wrbuffer_cap_refs(ci, 1, snapc);
+
+       __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
+
+       BUG_ON(!PageDirty(page));
+       return 1;
+}
+
+/*
+ * If we are truncating the full page (i.e. offset == 0), adjust the
+ * dirty page counters appropriately.  Only called if there is private
+ * data on the page.
+ */
+static void ceph_invalidatepage(struct page *page, unsigned long offset)
+{
+       struct inode *inode;
+       struct ceph_inode_info *ci;
+       struct ceph_snap_context *snapc = (void *)page->private;
+
+       BUG_ON(!PageLocked(page));
+       BUG_ON(!page->private);
+       BUG_ON(!PagePrivate(page));
+       BUG_ON(!page->mapping);
+
+       inode = page->mapping->host;
+
+       /*
+        * We can get non-dirty pages here due to races between
+        * set_page_dirty and truncate_complete_page; just spit out a
+        * warning, in case we end up with accounting problems later.
+        */
+       if (!PageDirty(page))
+               pr_err("%p invalidatepage %p page not dirty\n", inode, page);
+
+       if (offset == 0)
+               ClearPageChecked(page);
+
+       ci = ceph_inode(inode);
+       if (offset == 0) {
+               dout("%p invalidatepage %p idx %lu full dirty page %lu\n",
+                    inode, page, page->index, offset);
+               ceph_put_wrbuffer_cap_refs(ci, 1, snapc);
+               ceph_put_snap_context(snapc);
+               page->private = 0;
+               ClearPagePrivate(page);
+       } else {
+               dout("%p invalidatepage %p idx %lu partial dirty page\n",
+                    inode, page, page->index);
+       }
+}
+
+/* just a sanity check */
+static int ceph_releasepage(struct page *page, gfp_t g)
+{
+       struct inode *inode = page->mapping ? page->mapping->host : NULL;
+       dout("%p releasepage %p idx %lu\n", inode, page, page->index);
+       WARN_ON(PageDirty(page));
+       WARN_ON(page->private);
+       WARN_ON(PagePrivate(page));
+       return 0;
+}
+
+/*
+ * read a single page, without unlocking it.
+ */
+static int readpage_nounlock(struct file *filp, struct page *page)
+{
+       struct inode *inode = filp->f_dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_osd_client *osdc = &ceph_inode_to_client(inode)->osdc;
+       int err = 0;
+       u64 len = PAGE_CACHE_SIZE;
+
+       dout("readpage inode %p file %p page %p index %lu\n",
+            inode, filp, page, page->index);
+       err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
+                                 page->index << PAGE_CACHE_SHIFT, &len,
+                                 ci->i_truncate_seq, ci->i_truncate_size,
+                                 &page, 1);
+       if (err == -ENOENT)
+               err = 0;
+       if (err < 0) {
+               SetPageError(page);
+               goto out;
+       } else if (err < PAGE_CACHE_SIZE) {
+               /* zero fill remainder of page */
+               zero_user_segment(page, err, PAGE_CACHE_SIZE);
+       }
+       SetPageUptodate(page);
+
+out:
+       return err < 0 ? err : 0;
+}
+
+static int ceph_readpage(struct file *filp, struct page *page)
+{
+       int r = readpage_nounlock(filp, page);
+       unlock_page(page);
+       return r;
+}
+
+/*
+ * Build a vector of contiguous pages from the provided page list.
+ */
+static struct page **page_vector_from_list(struct list_head *page_list,
+                                          unsigned *nr_pages)
+{
+       struct page **pages;
+       struct page *page;
+       int next_index, contig_pages = 0;
+
+       /* build page vector */
+       pages = kmalloc(sizeof(*pages) * *nr_pages, GFP_NOFS);
+       if (!pages)
+               return ERR_PTR(-ENOMEM);
+
+       BUG_ON(list_empty(page_list));
+       next_index = list_entry(page_list->prev, struct page, lru)->index;
+       list_for_each_entry_reverse(page, page_list, lru) {
+               if (page->index == next_index) {
+                       dout("readpages page %d %p\n", contig_pages, page);
+                       pages[contig_pages] = page;
+                       contig_pages++;
+                       next_index++;
+               } else {
+                       break;
+               }
+       }
+       *nr_pages = contig_pages;
+       return pages;
+}
+
+/*
+ * Read multiple pages.  Leave pages we don't read + unlock in page_list;
+ * the caller (VM) cleans them up.
+ */
+static int ceph_readpages(struct file *file, struct address_space *mapping,
+                         struct list_head *page_list, unsigned nr_pages)
+{
+       struct inode *inode = file->f_dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_osd_client *osdc = &ceph_inode_to_client(inode)->osdc;
+       int rc = 0;
+       struct page **pages;
+       struct pagevec pvec;
+       loff_t offset;
+       u64 len;
+
+       dout("readpages %p file %p nr_pages %d\n",
+            inode, file, nr_pages);
+
+       pages = page_vector_from_list(page_list, &nr_pages);
+       if (IS_ERR(pages))
+               return PTR_ERR(pages);
+
+       /* guess read extent */
+       offset = pages[0]->index << PAGE_CACHE_SHIFT;
+       len = nr_pages << PAGE_CACHE_SHIFT;
+       rc = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
+                                offset, &len,
+                                ci->i_truncate_seq, ci->i_truncate_size,
+                                pages, nr_pages);
+       if (rc == -ENOENT)
+               rc = 0;
+       if (rc < 0)
+               goto out;
+
+       /* set uptodate and add to lru in pagevec-sized chunks */
+       pagevec_init(&pvec, 0);
+       for (; !list_empty(page_list) && len > 0;
+            rc -= PAGE_CACHE_SIZE, len -= PAGE_CACHE_SIZE) {
+               struct page *page =
+                       list_entry(page_list->prev, struct page, lru);
+
+               list_del(&page->lru);
+
+               if (rc < (int)PAGE_CACHE_SIZE) {
+                       /* zero (remainder of) page */
+                       int s = rc < 0 ? 0 : rc;
+                       zero_user_segment(page, s, PAGE_CACHE_SIZE);
+               }
+
+               if (add_to_page_cache(page, mapping, page->index, GFP_NOFS)) {
+                       page_cache_release(page);
+                       dout("readpages %p add_to_page_cache failed %p\n",
+                            inode, page);
+                       continue;
+               }
+               dout("readpages %p adding %p idx %lu\n", inode, page,
+                    page->index);
+               flush_dcache_page(page);
+               SetPageUptodate(page);
+               unlock_page(page);
+               if (pagevec_add(&pvec, page) == 0)
+                       pagevec_lru_add_file(&pvec);   /* add to lru */
+       }
+       pagevec_lru_add_file(&pvec);
+       rc = 0;
+
+out:
+       kfree(pages);
+       return rc;
+}
+
+/*
+ * Get ref for the oldest snapc for an inode with dirty data... that is, the
+ * only snap context we are allowed to write back.
+ */
+static struct ceph_snap_context *get_oldest_context(struct inode *inode,
+                                                   u64 *snap_size)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_snap_context *snapc = NULL;
+       struct ceph_cap_snap *capsnap = NULL;
+
+       spin_lock(&inode->i_lock);
+       list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
+               dout(" cap_snap %p snapc %p has %d dirty pages\n", capsnap,
+                    capsnap->context, capsnap->dirty_pages);
+               if (capsnap->dirty_pages) {
+                       snapc = ceph_get_snap_context(capsnap->context);
+                       if (snap_size)
+                               *snap_size = capsnap->size;
+                       break;
+               }
+       }
+       if (!snapc && ci->i_head_snapc) {
+               snapc = ceph_get_snap_context(ci->i_head_snapc);
+               dout(" head snapc %p has %d dirty pages\n",
+                    snapc, ci->i_wrbuffer_ref_head);
+       }
+       spin_unlock(&inode->i_lock);
+       return snapc;
+}
+
+/*
+ * Write a single page, but leave the page locked.
+ *
+ * If we get a write error, set the page error bit, but still adjust the
+ * dirty page accounting (i.e., page is no longer dirty).
+ */
+static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
+{
+       struct inode *inode;
+       struct ceph_inode_info *ci;
+       struct ceph_client *client;
+       struct ceph_osd_client *osdc;
+       loff_t page_off = page->index << PAGE_CACHE_SHIFT;
+       int len = PAGE_CACHE_SIZE;
+       loff_t i_size;
+       int err = 0;
+       struct ceph_snap_context *snapc, *oldest;
+       u64 snap_size = 0;
+       long writeback_stat;
+
+       dout("writepage %p idx %lu\n", page, page->index);
+
+       if (!page->mapping || !page->mapping->host) {
+               dout("writepage %p - no mapping\n", page);
+               return -EFAULT;
+       }
+       inode = page->mapping->host;
+       ci = ceph_inode(inode);
+       client = ceph_inode_to_client(inode);
+       osdc = &client->osdc;
+
+       /* verify this is a writeable snap context */
+       snapc = (void *)page->private;
+       if (snapc == NULL) {
+               dout("writepage %p page %p not dirty?\n", inode, page);
+               goto out;
+       }
+       oldest = get_oldest_context(inode, &snap_size);
+       if (snapc->seq > oldest->seq) {
+               dout("writepage %p page %p snapc %p not writeable - noop\n",
+                    inode, page, (void *)page->private);
+               /* we should only noop if called by kswapd */
+               WARN_ON((current->flags & PF_MEMALLOC) == 0);
+               ceph_put_snap_context(oldest);
+               goto out;
+       }
+       ceph_put_snap_context(oldest);
+
+       /* is this a partial page at end of file? */
+       if (snap_size)
+               i_size = snap_size;
+       else
+               i_size = i_size_read(inode);
+       if (i_size < page_off + len)
+               len = i_size - page_off;
+
+       dout("writepage %p page %p index %lu on %llu~%u\n",
+            inode, page, page->index, page_off, len);
+
+       writeback_stat = atomic_long_inc_return(&client->writeback_count);
+       if (writeback_stat >
+           CONGESTION_ON_THRESH(client->mount_args->congestion_kb))
+               set_bdi_congested(&client->backing_dev_info, BLK_RW_ASYNC);
+
+       set_page_writeback(page);
+       err = ceph_osdc_writepages(osdc, ceph_vino(inode),
+                                  &ci->i_layout, snapc,
+                                  page_off, len,
+                                  ci->i_truncate_seq, ci->i_truncate_size,
+                                  &inode->i_mtime,
+                                  &page, 1, 0, 0, true);
+       if (err < 0) {
+               dout("writepage setting page/mapping error %d %p\n", err, page);
+               SetPageError(page);
+               mapping_set_error(&inode->i_data, err);
+               if (wbc)
+                       wbc->pages_skipped++;
+       } else {
+               dout("writepage cleaned page %p\n", page);
+               err = 0;  /* vfs expects us to return 0 */
+       }
+       page->private = 0;
+       ClearPagePrivate(page);
+       end_page_writeback(page);
+       ceph_put_wrbuffer_cap_refs(ci, 1, snapc);
+       ceph_put_snap_context(snapc);  /* page's reference */
+out:
+       return err;
+}
+
+static int ceph_writepage(struct page *page, struct writeback_control *wbc)
+{
+       int err;
+       struct inode *inode = page->mapping->host;
+       BUG_ON(!inode);
+       igrab(inode);
+       err = writepage_nounlock(page, wbc);
+       unlock_page(page);
+       iput(inode);
+       return err;
+}
+
+
+/*
+ * lame release_pages helper.  release_pages() isn't exported to
+ * modules.
+ */
+static void ceph_release_pages(struct page **pages, int num)
+{
+       struct pagevec pvec;
+       int i;
+
+       pagevec_init(&pvec, 0);
+       for (i = 0; i < num; i++) {
+               if (pagevec_add(&pvec, pages[i]) == 0)
+                       pagevec_release(&pvec);
+       }
+       pagevec_release(&pvec);
+}
+
+
+/*
+ * async writeback completion handler.
+ *
+ * If we get an error, set the mapping error bit, but not the individual
+ * page error bits.
+ */
+static void writepages_finish(struct ceph_osd_request *req,
+                             struct ceph_msg *msg)
+{
+       struct inode *inode = req->r_inode;
+       struct ceph_osd_reply_head *replyhead;
+       struct ceph_osd_op *op;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       unsigned wrote;
+       struct page *page;
+       int i;
+       struct ceph_snap_context *snapc = req->r_snapc;
+       struct address_space *mapping = inode->i_mapping;
+       __s32 rc = -EIO;
+       u64 bytes = 0;
+       struct ceph_client *client = ceph_inode_to_client(inode);
+       long writeback_stat;
+       unsigned issued = ceph_caps_issued(ci);
+
+       /* parse reply */
+       replyhead = msg->front.iov_base;
+       WARN_ON(le32_to_cpu(replyhead->num_ops) == 0);
+       op = (void *)(replyhead + 1);
+       rc = le32_to_cpu(replyhead->result);
+       bytes = le64_to_cpu(op->extent.length);
+
+       if (rc >= 0) {
+               /*
+                * Assume we wrote the pages we originally sent.  The
+                * osd might reply with fewer pages if our writeback
+                * raced with a truncation and was adjusted at the osd,
+                * so don't believe the reply.
+                */
+               wrote = req->r_num_pages;
+       } else {
+               wrote = 0;
+               mapping_set_error(mapping, rc);
+       }
+       dout("writepages_finish %p rc %d bytes %llu wrote %d (pages)\n",
+            inode, rc, bytes, wrote);
+
+       /* clean all pages */
+       for (i = 0; i < req->r_num_pages; i++) {
+               page = req->r_pages[i];
+               BUG_ON(!page);
+               WARN_ON(!PageUptodate(page));
+
+               writeback_stat =
+                       atomic_long_dec_return(&client->writeback_count);
+               if (writeback_stat <
+                   CONGESTION_OFF_THRESH(client->mount_args->congestion_kb))
+                       clear_bdi_congested(&client->backing_dev_info,
+                                           BLK_RW_ASYNC);
+
+               ceph_put_snap_context((void *)page->private);
+               page->private = 0;
+               ClearPagePrivate(page);
+               dout("unlocking %d %p\n", i, page);
+               end_page_writeback(page);
+
+               /*
+                * We lost the cache cap, need to truncate the page before
+                * it is unlocked, otherwise we'd truncate it later in the
+                * page truncation thread, possibly losing some data that
+                * raced its way in
+                */
+               if ((issued & CEPH_CAP_FILE_CACHE) == 0)
+                       generic_error_remove_page(inode->i_mapping, page);
+
+               unlock_page(page);
+       }
+       dout("%p wrote+cleaned %d pages\n", inode, wrote);
+       ceph_put_wrbuffer_cap_refs(ci, req->r_num_pages, snapc);
+
+       ceph_release_pages(req->r_pages, req->r_num_pages);
+       if (req->r_pages_from_pool)
+               mempool_free(req->r_pages,
+                            ceph_client(inode->i_sb)->wb_pagevec_pool);
+       else
+               kfree(req->r_pages);
+       ceph_osdc_put_request(req);
+}
+
+/*
+ * allocate a page vec, either directly, or if necessary, via a the
+ * mempool.  we avoid the mempool if we can because req->r_num_pages
+ * may be less than the maximum write size.
+ */
+static void alloc_page_vec(struct ceph_client *client,
+                          struct ceph_osd_request *req)
+{
+       req->r_pages = kmalloc(sizeof(struct page *) * req->r_num_pages,
+                              GFP_NOFS);
+       if (!req->r_pages) {
+               req->r_pages = mempool_alloc(client->wb_pagevec_pool, GFP_NOFS);
+               req->r_pages_from_pool = 1;
+               WARN_ON(!req->r_pages);
+       }
+}
+
+/*
+ * initiate async writeback
+ */
+static int ceph_writepages_start(struct address_space *mapping,
+                                struct writeback_control *wbc)
+{
+       struct inode *inode = mapping->host;
+       struct backing_dev_info *bdi = mapping->backing_dev_info;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_client *client;
+       pgoff_t index, start, end;
+       int range_whole = 0;
+       int should_loop = 1;
+       pgoff_t max_pages = 0, max_pages_ever = 0;
+       struct ceph_snap_context *snapc = NULL, *last_snapc = NULL, *pgsnapc;
+       struct pagevec pvec;
+       int done = 0;
+       int rc = 0;
+       unsigned wsize = 1 << inode->i_blkbits;
+       struct ceph_osd_request *req = NULL;
+       int do_sync;
+       u64 snap_size = 0;
+
+       /*
+        * Include a 'sync' in the OSD request if this is a data
+        * integrity write (e.g., O_SYNC write or fsync()), or if our
+        * cap is being revoked.
+        */
+       do_sync = wbc->sync_mode == WB_SYNC_ALL;
+       if (ceph_caps_revoking(ci, CEPH_CAP_FILE_BUFFER))
+               do_sync = 1;
+       dout("writepages_start %p dosync=%d (mode=%s)\n",
+            inode, do_sync,
+            wbc->sync_mode == WB_SYNC_NONE ? "NONE" :
+            (wbc->sync_mode == WB_SYNC_ALL ? "ALL" : "HOLD"));
+
+       client = ceph_inode_to_client(inode);
+       if (client->mount_state == CEPH_MOUNT_SHUTDOWN) {
+               pr_warning("writepage_start %p on forced umount\n", inode);
+               return -EIO; /* we're in a forced umount, don't write! */
+       }
+       if (client->mount_args->wsize && client->mount_args->wsize < wsize)
+               wsize = client->mount_args->wsize;
+       if (wsize < PAGE_CACHE_SIZE)
+               wsize = PAGE_CACHE_SIZE;
+       max_pages_ever = wsize >> PAGE_CACHE_SHIFT;
+
+       pagevec_init(&pvec, 0);
+
+       /* ?? */
+       if (wbc->nonblocking && bdi_write_congested(bdi)) {
+               dout(" writepages congested\n");
+               wbc->encountered_congestion = 1;
+               goto out_final;
+       }
+
+       /* where to start/end? */
+       if (wbc->range_cyclic) {
+               start = mapping->writeback_index; /* Start from prev offset */
+               end = -1;
+               dout(" cyclic, start at %lu\n", start);
+       } else {
+               start = wbc->range_start >> PAGE_CACHE_SHIFT;
+               end = wbc->range_end >> PAGE_CACHE_SHIFT;
+               if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
+                       range_whole = 1;
+               should_loop = 0;
+               dout(" not cyclic, %lu to %lu\n", start, end);
+       }
+       index = start;
+
+retry:
+       /* find oldest snap context with dirty data */
+       ceph_put_snap_context(snapc);
+       snapc = get_oldest_context(inode, &snap_size);
+       if (!snapc) {
+               /* hmm, why does writepages get called when there
+                  is no dirty data? */
+               dout(" no snap context with dirty data?\n");
+               goto out;
+       }
+       dout(" oldest snapc is %p seq %lld (%d snaps)\n",
+            snapc, snapc->seq, snapc->num_snaps);
+       if (last_snapc && snapc != last_snapc) {
+               /* if we switched to a newer snapc, restart our scan at the
+                * start of the original file range. */
+               dout("  snapc differs from last pass, restarting at %lu\n",
+                    index);
+               index = start;
+       }
+       last_snapc = snapc;
+
+       while (!done && index <= end) {
+               unsigned i;
+               int first;
+               pgoff_t next;
+               int pvec_pages, locked_pages;
+               struct page *page;
+               int want;
+               u64 offset, len;
+               struct ceph_osd_request_head *reqhead;
+               struct ceph_osd_op *op;
+               long writeback_stat;
+
+               next = 0;
+               locked_pages = 0;
+               max_pages = max_pages_ever;
+
+get_more_pages:
+               first = -1;
+               want = min(end - index,
+                          min((pgoff_t)PAGEVEC_SIZE,
+                              max_pages - (pgoff_t)locked_pages) - 1)
+                       + 1;
+               pvec_pages = pagevec_lookup_tag(&pvec, mapping, &index,
+                                               PAGECACHE_TAG_DIRTY,
+                                               want);
+               dout("pagevec_lookup_tag got %d\n", pvec_pages);
+               if (!pvec_pages && !locked_pages)
+                       break;
+               for (i = 0; i < pvec_pages && locked_pages < max_pages; i++) {
+                       page = pvec.pages[i];
+                       dout("? %p idx %lu\n", page, page->index);
+                       if (locked_pages == 0)
+                               lock_page(page);  /* first page */
+                       else if (!trylock_page(page))
+                               break;
+
+                       /* only dirty pages, or our accounting breaks */
+                       if (unlikely(!PageDirty(page)) ||
+                           unlikely(page->mapping != mapping)) {
+                               dout("!dirty or !mapping %p\n", page);
+                               unlock_page(page);
+                               break;
+                       }
+                       if (!wbc->range_cyclic && page->index > end) {
+                               dout("end of range %p\n", page);
+                               done = 1;
+                               unlock_page(page);
+                               break;
+                       }
+                       if (next && (page->index != next)) {
+                               dout("not consecutive %p\n", page);
+                               unlock_page(page);
+                               break;
+                       }
+                       if (wbc->sync_mode != WB_SYNC_NONE) {
+                               dout("waiting on writeback %p\n", page);
+                               wait_on_page_writeback(page);
+                       }
+                       if ((snap_size && page_offset(page) > snap_size) ||
+                           (!snap_size &&
+                            page_offset(page) > i_size_read(inode))) {
+                               dout("%p page eof %llu\n", page, snap_size ?
+                                    snap_size : i_size_read(inode));
+                               done = 1;
+                               unlock_page(page);
+                               break;
+                       }
+                       if (PageWriteback(page)) {
+                               dout("%p under writeback\n", page);
+                               unlock_page(page);
+                               break;
+                       }
+
+                       /* only if matching snap context */
+                       pgsnapc = (void *)page->private;
+                       if (pgsnapc->seq > snapc->seq) {
+                               dout("page snapc %p %lld > oldest %p %lld\n",
+                                    pgsnapc, pgsnapc->seq, snapc, snapc->seq);
+                               unlock_page(page);
+                               if (!locked_pages)
+                                       continue; /* keep looking for snap */
+                               break;
+                       }
+
+                       if (!clear_page_dirty_for_io(page)) {
+                               dout("%p !clear_page_dirty_for_io\n", page);
+                               unlock_page(page);
+                               break;
+                       }
+
+                       /* ok */
+                       if (locked_pages == 0) {
+                               /* prepare async write request */
+                               offset = page->index << PAGE_CACHE_SHIFT;
+                               len = wsize;
+                               req = ceph_osdc_new_request(&client->osdc,
+                                           &ci->i_layout,
+                                           ceph_vino(inode),
+                                           offset, &len,
+                                           CEPH_OSD_OP_WRITE,
+                                           CEPH_OSD_FLAG_WRITE |
+                                                   CEPH_OSD_FLAG_ONDISK,
+                                           snapc, do_sync,
+                                           ci->i_truncate_seq,
+                                           ci->i_truncate_size,
+                                           &inode->i_mtime, true, 1);
+                               max_pages = req->r_num_pages;
+
+                               alloc_page_vec(client, req);
+                               req->r_callback = writepages_finish;
+                               req->r_inode = inode;
+                       }
+
+                       /* note position of first page in pvec */
+                       if (first < 0)
+                               first = i;
+                       dout("%p will write page %p idx %lu\n",
+                            inode, page, page->index);
+
+                       writeback_stat = atomic_long_inc_return(&client->writeback_count);
+                       if (writeback_stat > CONGESTION_ON_THRESH(client->mount_args->congestion_kb)) {
+                               set_bdi_congested(&client->backing_dev_info, BLK_RW_ASYNC);
+                       }
+
+                       set_page_writeback(page);
+                       req->r_pages[locked_pages] = page;
+                       locked_pages++;
+                       next = page->index + 1;
+               }
+
+               /* did we get anything? */
+               if (!locked_pages)
+                       goto release_pvec_pages;
+               if (i) {
+                       int j;
+                       BUG_ON(!locked_pages || first < 0);
+
+                       if (pvec_pages && i == pvec_pages &&
+                           locked_pages < max_pages) {
+                               dout("reached end pvec, trying for more\n");
+                               pagevec_reinit(&pvec);
+                               goto get_more_pages;
+                       }
+
+                       /* shift unused pages over in the pvec...  we
+                        * will need to release them below. */
+                       for (j = i; j < pvec_pages; j++) {
+                               dout(" pvec leftover page %p\n",
+                                    pvec.pages[j]);
+                               pvec.pages[j-i+first] = pvec.pages[j];
+                       }
+                       pvec.nr -= i-first;
+               }
+
+               /* submit the write */
+               offset = req->r_pages[0]->index << PAGE_CACHE_SHIFT;
+               len = min((snap_size ? snap_size : i_size_read(inode)) - offset,
+                         (u64)locked_pages << PAGE_CACHE_SHIFT);
+               dout("writepages got %d pages at %llu~%llu\n",
+                    locked_pages, offset, len);
+
+               /* revise final length, page count */
+               req->r_num_pages = locked_pages;
+               reqhead = req->r_request->front.iov_base;
+               op = (void *)(reqhead + 1);
+               op->extent.length = cpu_to_le64(len);
+               op->payload_len = cpu_to_le32(len);
+               req->r_request->hdr.data_len = cpu_to_le32(len);
+
+               ceph_osdc_start_request(&client->osdc, req, true);
+               req = NULL;
+
+               /* continue? */
+               index = next;
+               wbc->nr_to_write -= locked_pages;
+               if (wbc->nr_to_write <= 0)
+                       done = 1;
+
+release_pvec_pages:
+               dout("pagevec_release on %d pages (%p)\n", (int)pvec.nr,
+                    pvec.nr ? pvec.pages[0] : NULL);
+               pagevec_release(&pvec);
+
+               if (locked_pages && !done)
+                       goto retry;
+       }
+
+       if (should_loop && !done) {
+               /* more to do; loop back to beginning of file */
+               dout("writepages looping back to beginning of file\n");
+               should_loop = 0;
+               index = 0;
+               goto retry;
+       }
+
+       if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
+               mapping->writeback_index = index;
+
+out:
+       if (req)
+               ceph_osdc_put_request(req);
+       if (rc > 0)
+               rc = 0;  /* vfs expects us to return 0 */
+       ceph_put_snap_context(snapc);
+       dout("writepages done, rc = %d\n", rc);
+out_final:
+       return rc;
+}
+
+
+
+/*
+ * See if a given @snapc is either writeable, or already written.
+ */
+static int context_is_writeable_or_written(struct inode *inode,
+                                          struct ceph_snap_context *snapc)
+{
+       struct ceph_snap_context *oldest = get_oldest_context(inode, NULL);
+       int ret = !oldest || snapc->seq <= oldest->seq;
+
+       ceph_put_snap_context(oldest);
+       return ret;
+}
+
+/*
+ * We are only allowed to write into/dirty the page if the page is
+ * clean, or already dirty within the same snap context.
+ *
+ * called with page locked.
+ * return success with page locked,
+ * or any failure (incl -EAGAIN) with page unlocked.
+ */
+static int ceph_update_writeable_page(struct file *file,
+                           loff_t pos, unsigned len,
+                           struct page *page)
+{
+       struct inode *inode = file->f_dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc;
+       loff_t page_off = pos & PAGE_CACHE_MASK;
+       int pos_in_page = pos & ~PAGE_CACHE_MASK;
+       int end_in_page = pos_in_page + len;
+       loff_t i_size;
+       int r;
+       struct ceph_snap_context *snapc, *oldest;
+
+retry_locked:
+       /* writepages currently holds page lock, but if we change that later, */
+       wait_on_page_writeback(page);
+
+       /* check snap context */
+       BUG_ON(!ci->i_snap_realm);
+       down_read(&mdsc->snap_rwsem);
+       BUG_ON(!ci->i_snap_realm->cached_context);
+       snapc = (void *)page->private;
+       if (snapc && snapc != ci->i_head_snapc) {
+               /*
+                * this page is already dirty in another (older) snap
+                * context!  is it writeable now?
+                */
+               oldest = get_oldest_context(inode, NULL);
+               up_read(&mdsc->snap_rwsem);
+
+               if (snapc->seq > oldest->seq) {
+                       ceph_put_snap_context(oldest);
+                       dout(" page %p snapc %p not current or oldest\n",
+                            page, snapc);
+                       /*
+                        * queue for writeback, and wait for snapc to
+                        * be writeable or written
+                        */
+                       snapc = ceph_get_snap_context(snapc);
+                       unlock_page(page);
+                       ceph_queue_writeback(inode);
+                       r = wait_event_interruptible(ci->i_cap_wq,
+                              context_is_writeable_or_written(inode, snapc));
+                       ceph_put_snap_context(snapc);
+                       if (r == -ERESTARTSYS)
+                               return r;
+                       return -EAGAIN;
+               }
+               ceph_put_snap_context(oldest);
+
+               /* yay, writeable, do it now (without dropping page lock) */
+               dout(" page %p snapc %p not current, but oldest\n",
+                    page, snapc);
+               if (!clear_page_dirty_for_io(page))
+                       goto retry_locked;
+               r = writepage_nounlock(page, NULL);
+               if (r < 0)
+                       goto fail_nosnap;
+               goto retry_locked;
+       }
+
+       if (PageUptodate(page)) {
+               dout(" page %p already uptodate\n", page);
+               return 0;
+       }
+
+       /* full page? */
+       if (pos_in_page == 0 && len == PAGE_CACHE_SIZE)
+               return 0;
+
+       /* past end of file? */
+       i_size = inode->i_size;   /* caller holds i_mutex */
+
+       if (i_size + len > inode->i_sb->s_maxbytes) {
+               /* file is too big */
+               r = -EINVAL;
+               goto fail;
+       }
+
+       if (page_off >= i_size ||
+           (pos_in_page == 0 && (pos+len) >= i_size &&
+            end_in_page - pos_in_page != PAGE_CACHE_SIZE)) {
+               dout(" zeroing %p 0 - %d and %d - %d\n",
+                    page, pos_in_page, end_in_page, (int)PAGE_CACHE_SIZE);
+               zero_user_segments(page,
+                                  0, pos_in_page,
+                                  end_in_page, PAGE_CACHE_SIZE);
+               return 0;
+       }
+
+       /* we need to read it. */
+       up_read(&mdsc->snap_rwsem);
+       r = readpage_nounlock(file, page);
+       if (r < 0)
+               goto fail_nosnap;
+       goto retry_locked;
+
+fail:
+       up_read(&mdsc->snap_rwsem);
+fail_nosnap:
+       unlock_page(page);
+       return r;
+}
+
+/*
+ * We are only allowed to write into/dirty the page if the page is
+ * clean, or already dirty within the same snap context.
+ */
+static int ceph_write_begin(struct file *file, struct address_space *mapping,
+                           loff_t pos, unsigned len, unsigned flags,
+                           struct page **pagep, void **fsdata)
+{
+       struct inode *inode = file->f_dentry->d_inode;
+       struct page *page;
+       pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+       int r;
+
+       do {
+               /* get a page */
+               page = grab_cache_page_write_begin(mapping, index, 0);
+               if (!page)
+                       return -ENOMEM;
+               *pagep = page;
+
+               dout("write_begin file %p inode %p page %p %d~%d\n", file,
+               inode, page, (int)pos, (int)len);
+
+               r = ceph_update_writeable_page(file, pos, len, page);
+       } while (r == -EAGAIN);
+
+       return r;
+}
+
+/*
+ * we don't do anything in here that simple_write_end doesn't do
+ * except adjust dirty page accounting and drop read lock on
+ * mdsc->snap_rwsem.
+ */
+static int ceph_write_end(struct file *file, struct address_space *mapping,
+                         loff_t pos, unsigned len, unsigned copied,
+                         struct page *page, void *fsdata)
+{
+       struct inode *inode = file->f_dentry->d_inode;
+       struct ceph_client *client = ceph_inode_to_client(inode);
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       unsigned from = pos & (PAGE_CACHE_SIZE - 1);
+       int check_cap = 0;
+
+       dout("write_end file %p inode %p page %p %d~%d (%d)\n", file,
+            inode, page, (int)pos, (int)copied, (int)len);
+
+       /* zero the stale part of the page if we did a short copy */
+       if (copied < len)
+               zero_user_segment(page, from+copied, len);
+
+       /* did file size increase? */
+       /* (no need for i_size_read(); we caller holds i_mutex */
+       if (pos+copied > inode->i_size)
+               check_cap = ceph_inode_set_size(inode, pos+copied);
+
+       if (!PageUptodate(page))
+               SetPageUptodate(page);
+
+       set_page_dirty(page);
+
+       unlock_page(page);
+       up_read(&mdsc->snap_rwsem);
+       page_cache_release(page);
+
+       if (check_cap)
+               ceph_check_caps(ceph_inode(inode), CHECK_CAPS_AUTHONLY, NULL);
+
+       return copied;
+}
+
+/*
+ * we set .direct_IO to indicate direct io is supported, but since we
+ * intercept O_DIRECT reads and writes early, this function should
+ * never get called.
+ */
+static ssize_t ceph_direct_io(int rw, struct kiocb *iocb,
+                             const struct iovec *iov,
+                             loff_t pos, unsigned long nr_segs)
+{
+       WARN_ON(1);
+       return -EINVAL;
+}
+
+const struct address_space_operations ceph_aops = {
+       .readpage = ceph_readpage,
+       .readpages = ceph_readpages,
+       .writepage = ceph_writepage,
+       .writepages = ceph_writepages_start,
+       .write_begin = ceph_write_begin,
+       .write_end = ceph_write_end,
+       .set_page_dirty = ceph_set_page_dirty,
+       .invalidatepage = ceph_invalidatepage,
+       .releasepage = ceph_releasepage,
+       .direct_IO = ceph_direct_io,
+};
+
+
+/*
+ * vm ops
+ */
+
+/*
+ * Reuse write_begin here for simplicity.
+ */
+static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+       struct inode *inode = vma->vm_file->f_dentry->d_inode;
+       struct page *page = vmf->page;
+       struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc;
+       loff_t off = page->index << PAGE_CACHE_SHIFT;
+       loff_t size, len;
+       int ret;
+
+       size = i_size_read(inode);
+       if (off + PAGE_CACHE_SIZE <= size)
+               len = PAGE_CACHE_SIZE;
+       else
+               len = size & ~PAGE_CACHE_MASK;
+
+       dout("page_mkwrite %p %llu~%llu page %p idx %lu\n", inode,
+            off, len, page, page->index);
+
+       lock_page(page);
+
+       ret = VM_FAULT_NOPAGE;
+       if ((off > size) ||
+           (page->mapping != inode->i_mapping))
+               goto out;
+
+       ret = ceph_update_writeable_page(vma->vm_file, off, len, page);
+       if (ret == 0) {
+               /* success.  we'll keep the page locked. */
+               set_page_dirty(page);
+               up_read(&mdsc->snap_rwsem);
+               ret = VM_FAULT_LOCKED;
+       } else {
+               if (ret == -ENOMEM)
+                       ret = VM_FAULT_OOM;
+               else
+                       ret = VM_FAULT_SIGBUS;
+       }
+out:
+       dout("page_mkwrite %p %llu~%llu = %d\n", inode, off, len, ret);
+       if (ret != VM_FAULT_LOCKED)
+               unlock_page(page);
+       return ret;
+}
+
+static struct vm_operations_struct ceph_vmops = {
+       .fault          = filemap_fault,
+       .page_mkwrite   = ceph_page_mkwrite,
+};
+
+int ceph_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       struct address_space *mapping = file->f_mapping;
+
+       if (!mapping->a_ops->readpage)
+               return -ENOEXEC;
+       file_accessed(file);
+       vma->vm_ops = &ceph_vmops;
+       vma->vm_flags |= VM_CAN_NONLINEAR;
+       return 0;
+}
diff --git a/fs/ceph/armor.c b/fs/ceph/armor.c
new file mode 100644 (file)
index 0000000..67b2c03
--- /dev/null
@@ -0,0 +1,99 @@
+
+#include <linux/errno.h>
+
+/*
+ * base64 encode/decode.
+ */
+
+const char *pem_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static int encode_bits(int c)
+{
+       return pem_key[c];
+}
+
+static int decode_bits(char c)
+{
+       if (c >= 'A' && c <= 'Z')
+               return c - 'A';
+       if (c >= 'a' && c <= 'z')
+               return c - 'a' + 26;
+       if (c >= '0' && c <= '9')
+               return c - '0' + 52;
+       if (c == '+')
+               return 62;
+       if (c == '/')
+               return 63;
+       if (c == '=')
+               return 0; /* just non-negative, please */
+       return -EINVAL;
+}
+
+int ceph_armor(char *dst, const char *src, const char *end)
+{
+       int olen = 0;
+       int line = 0;
+
+       while (src < end) {
+               unsigned char a, b, c;
+
+               a = *src++;
+               *dst++ = encode_bits(a >> 2);
+               if (src < end) {
+                       b = *src++;
+                       *dst++ = encode_bits(((a & 3) << 4) | (b >> 4));
+                       if (src < end) {
+                               c = *src++;
+                               *dst++ = encode_bits(((b & 15) << 2) |
+                                                    (c >> 6));
+                               *dst++ = encode_bits(c & 63);
+                       } else {
+                               *dst++ = encode_bits((b & 15) << 2);
+                               *dst++ = '=';
+                       }
+               } else {
+                       *dst++ = encode_bits(((a & 3) << 4));
+                       *dst++ = '=';
+                       *dst++ = '=';
+               }
+               olen += 4;
+               line += 4;
+               if (line == 64) {
+                       line = 0;
+                       *(dst++) = '\n';
+                       olen++;
+               }
+       }
+       return olen;
+}
+
+int ceph_unarmor(char *dst, const char *src, const char *end)
+{
+       int olen = 0;
+
+       while (src < end) {
+               int a, b, c, d;
+
+               if (src < end && src[0] == '\n')
+                       src++;
+               if (src + 4 > end)
+                       return -EINVAL;
+               a = decode_bits(src[0]);
+               b = decode_bits(src[1]);
+               c = decode_bits(src[2]);
+               d = decode_bits(src[3]);
+               if (a < 0 || b < 0 || c < 0 || d < 0)
+                       return -EINVAL;
+
+               *dst++ = (a << 2) | (b >> 4);
+               if (src[2] == '=')
+                       return olen + 1;
+               *dst++ = ((b & 15) << 4) | (c >> 2);
+               if (src[3] == '=')
+                       return olen + 2;
+               *dst++ = ((c & 3) << 6) | d;
+               olen += 3;
+               src += 4;
+       }
+       return olen;
+}
diff --git a/fs/ceph/auth.c b/fs/ceph/auth.c
new file mode 100644 (file)
index 0000000..818afe7
--- /dev/null
@@ -0,0 +1,259 @@
+#include "ceph_debug.h"
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include "types.h"
+#include "auth_none.h"
+#include "auth_x.h"
+#include "decode.h"
+#include "super.h"
+
+#include "messenger.h"
+
+/*
+ * get protocol handler
+ */
+static u32 supported_protocols[] = {
+       CEPH_AUTH_NONE,
+       CEPH_AUTH_CEPHX
+};
+
+int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol)
+{
+       switch (protocol) {
+       case CEPH_AUTH_NONE:
+               return ceph_auth_none_init(ac);
+       case CEPH_AUTH_CEPHX:
+               return ceph_x_init(ac);
+       default:
+               return -ENOENT;
+       }
+}
+
+/*
+ * setup, teardown.
+ */
+struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret)
+{
+       struct ceph_auth_client *ac;
+       int ret;
+
+       dout("auth_init name '%s' secret '%s'\n", name, secret);
+
+       ret = -ENOMEM;
+       ac = kzalloc(sizeof(*ac), GFP_NOFS);
+       if (!ac)
+               goto out;
+
+       ac->negotiating = true;
+       if (name)
+               ac->name = name;
+       else
+               ac->name = CEPH_AUTH_NAME_DEFAULT;
+       dout("auth_init name %s secret %s\n", ac->name, secret);
+       ac->secret = secret;
+       return ac;
+
+out:
+       return ERR_PTR(ret);
+}
+
+void ceph_auth_destroy(struct ceph_auth_client *ac)
+{
+       dout("auth_destroy %p\n", ac);
+       if (ac->ops)
+               ac->ops->destroy(ac);
+       kfree(ac);
+}
+
+/*
+ * Reset occurs when reconnecting to the monitor.
+ */
+void ceph_auth_reset(struct ceph_auth_client *ac)
+{
+       dout("auth_reset %p\n", ac);
+       if (ac->ops && !ac->negotiating)
+               ac->ops->reset(ac);
+       ac->negotiating = true;
+}
+
+int ceph_entity_name_encode(const char *name, void **p, void *end)
+{
+       int len = strlen(name);
+
+       if (*p + 2*sizeof(u32) + len > end)
+               return -ERANGE;
+       ceph_encode_32(p, CEPH_ENTITY_TYPE_CLIENT);
+       ceph_encode_32(p, len);
+       ceph_encode_copy(p, name, len);
+       return 0;
+}
+
+/*
+ * Initiate protocol negotiation with monitor.  Include entity name
+ * and list supported protocols.
+ */
+int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len)
+{
+       struct ceph_mon_request_header *monhdr = buf;
+       void *p = monhdr + 1, *end = buf + len, *lenp;
+       int i, num;
+       int ret;
+
+       dout("auth_build_hello\n");
+       monhdr->have_version = 0;
+       monhdr->session_mon = cpu_to_le16(-1);
+       monhdr->session_mon_tid = 0;
+
+       ceph_encode_32(&p, 0);  /* no protocol, yet */
+
+       lenp = p;
+       p += sizeof(u32);
+
+       ceph_decode_need(&p, end, 1 + sizeof(u32), bad);
+       ceph_encode_8(&p, 1);
+       num = ARRAY_SIZE(supported_protocols);
+       ceph_encode_32(&p, num);
+       ceph_decode_need(&p, end, num * sizeof(u32), bad);
+       for (i = 0; i < num; i++)
+               ceph_encode_32(&p, supported_protocols[i]);
+
+       ret = ceph_entity_name_encode(ac->name, &p, end);
+       if (ret < 0)
+               return ret;
+       ceph_decode_need(&p, end, sizeof(u64), bad);
+       ceph_encode_64(&p, ac->global_id);
+
+       ceph_encode_32(&lenp, p - lenp - sizeof(u32));
+       return p - buf;
+
+bad:
+       return -ERANGE;
+}
+
+int ceph_build_auth_request(struct ceph_auth_client *ac,
+                          void *msg_buf, size_t msg_len)
+{
+       struct ceph_mon_request_header *monhdr = msg_buf;
+       void *p = monhdr + 1;
+       void *end = msg_buf + msg_len;
+       int ret;
+
+       monhdr->have_version = 0;
+       monhdr->session_mon = cpu_to_le16(-1);
+       monhdr->session_mon_tid = 0;
+
+       ceph_encode_32(&p, ac->protocol);
+
+       ret = ac->ops->build_request(ac, p + sizeof(u32), end);
+       if (ret < 0) {
+               pr_err("error %d building request\n", ret);
+               return ret;
+       }
+       dout(" built request %d bytes\n", ret);
+       ceph_encode_32(&p, ret);
+       return p + ret - msg_buf;
+}
+
+/*
+ * Handle auth message from monitor.
+ */
+int ceph_handle_auth_reply(struct ceph_auth_client *ac,
+                          void *buf, size_t len,
+                          void *reply_buf, size_t reply_len)
+{
+       void *p = buf;
+       void *end = buf + len;
+       int protocol;
+       s32 result;
+       u64 global_id;
+       void *payload, *payload_end;
+       int payload_len;
+       char *result_msg;
+       int result_msg_len;
+       int ret = -EINVAL;
+
+       dout("handle_auth_reply %p %p\n", p, end);
+       ceph_decode_need(&p, end, sizeof(u32) * 3 + sizeof(u64), bad);
+       protocol = ceph_decode_32(&p);
+       result = ceph_decode_32(&p);
+       global_id = ceph_decode_64(&p);
+       payload_len = ceph_decode_32(&p);
+       payload = p;
+       p += payload_len;
+       ceph_decode_need(&p, end, sizeof(u32), bad);
+       result_msg_len = ceph_decode_32(&p);
+       result_msg = p;
+       p += result_msg_len;
+       if (p != end)
+               goto bad;
+
+       dout(" result %d '%.*s' gid %llu len %d\n", result, result_msg_len,
+            result_msg, global_id, payload_len);
+
+       payload_end = payload + payload_len;
+
+       if (global_id && ac->global_id != global_id) {
+               dout(" set global_id %lld -> %lld\n", ac->global_id, global_id);
+               ac->global_id = global_id;
+       }
+
+       if (ac->negotiating) {
+               /* server does not support our protocols? */
+               if (!protocol && result < 0) {
+                       ret = result;
+                       goto out;
+               }
+               /* set up (new) protocol handler? */
+               if (ac->protocol && ac->protocol != protocol) {
+                       ac->ops->destroy(ac);
+                       ac->protocol = 0;
+                       ac->ops = NULL;
+               }
+               if (ac->protocol != protocol) {
+                       ret = ceph_auth_init_protocol(ac, protocol);
+                       if (ret) {
+                               pr_err("error %d on auth protocol %d init\n",
+                                      ret, protocol);
+                               goto out;
+                       }
+               }
+
+               ac->negotiating = false;
+       }
+
+       ret = ac->ops->handle_reply(ac, result, payload, payload_end);
+       if (ret == -EAGAIN) {
+               return ceph_build_auth_request(ac, reply_buf, reply_len);
+       } else if (ret) {
+               pr_err("authentication error %d\n", ret);
+               return ret;
+       }
+       return 0;
+
+bad:
+       pr_err("failed to decode auth msg\n");
+out:
+       return ret;
+}
+
+int ceph_build_auth(struct ceph_auth_client *ac,
+                   void *msg_buf, size_t msg_len)
+{
+       if (!ac->protocol)
+               return ceph_auth_build_hello(ac, msg_buf, msg_len);
+       BUG_ON(!ac->ops);
+       if (!ac->ops->is_authenticated(ac))
+               return ceph_build_auth_request(ac, msg_buf, msg_len);
+       return 0;
+}
+
+int ceph_auth_is_authenticated(struct ceph_auth_client *ac)
+{
+       if (!ac->ops)
+               return 0;
+       return ac->ops->is_authenticated(ac);
+}
diff --git a/fs/ceph/auth.h b/fs/ceph/auth.h
new file mode 100644 (file)
index 0000000..ca4f57c
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef _FS_CEPH_AUTH_H
+#define _FS_CEPH_AUTH_H
+
+#include "types.h"
+#include "buffer.h"
+
+/*
+ * Abstract interface for communicating with the authenticate module.
+ * There is some handshake that takes place between us and the monitor
+ * to acquire the necessary keys.  These are used to generate an
+ * 'authorizer' that we use when connecting to a service (mds, osd).
+ */
+
+struct ceph_auth_client;
+struct ceph_authorizer;
+
+struct ceph_auth_client_ops {
+       /*
+        * true if we are authenticated and can connect to
+        * services.
+        */
+       int (*is_authenticated)(struct ceph_auth_client *ac);
+
+       /*
+        * build requests and process replies during monitor
+        * handshake.  if handle_reply returns -EAGAIN, we build
+        * another request.
+        */
+       int (*build_request)(struct ceph_auth_client *ac, void *buf, void *end);
+       int (*handle_reply)(struct ceph_auth_client *ac, int result,
+                           void *buf, void *end);
+
+       /*
+        * Create authorizer for connecting to a service, and verify
+        * the response to authenticate the service.
+        */
+       int (*create_authorizer)(struct ceph_auth_client *ac, int peer_type,
+                                struct ceph_authorizer **a,
+                                void **buf, size_t *len,
+                                void **reply_buf, size_t *reply_len);
+       int (*verify_authorizer_reply)(struct ceph_auth_client *ac,
+                                      struct ceph_authorizer *a, size_t len);
+       void (*destroy_authorizer)(struct ceph_auth_client *ac,
+                                  struct ceph_authorizer *a);
+       void (*invalidate_authorizer)(struct ceph_auth_client *ac,
+                                     int peer_type);
+
+       /* reset when we (re)connect to a monitor */
+       void (*reset)(struct ceph_auth_client *ac);
+
+       void (*destroy)(struct ceph_auth_client *ac);
+};
+
+struct ceph_auth_client {
+       u32 protocol;           /* CEPH_AUTH_* */
+       void *private;          /* for use by protocol implementation */
+       const struct ceph_auth_client_ops *ops;  /* null iff protocol==0 */
+
+       bool negotiating;       /* true if negotiating protocol */
+       const char *name;       /* entity name */
+       u64 global_id;          /* our unique id in system */
+       const char *secret;     /* our secret key */
+       unsigned want_keys;     /* which services we want */
+};
+
+extern struct ceph_auth_client *ceph_auth_init(const char *name,
+                                              const char *secret);
+extern void ceph_auth_destroy(struct ceph_auth_client *ac);
+
+extern void ceph_auth_reset(struct ceph_auth_client *ac);
+
+extern int ceph_auth_build_hello(struct ceph_auth_client *ac,
+                                void *buf, size_t len);
+extern int ceph_handle_auth_reply(struct ceph_auth_client *ac,
+                                 void *buf, size_t len,
+                                 void *reply_buf, size_t reply_len);
+extern int ceph_entity_name_encode(const char *name, void **p, void *end);
+
+extern int ceph_build_auth(struct ceph_auth_client *ac,
+                   void *msg_buf, size_t msg_len);
+
+extern int ceph_auth_is_authenticated(struct ceph_auth_client *ac);
+
+#endif
diff --git a/fs/ceph/auth_none.c b/fs/ceph/auth_none.c
new file mode 100644 (file)
index 0000000..8cd9e3a
--- /dev/null
@@ -0,0 +1,122 @@
+
+#include "ceph_debug.h"
+
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+
+#include "auth_none.h"
+#include "auth.h"
+#include "decode.h"
+
+static void reset(struct ceph_auth_client *ac)
+{
+       struct ceph_auth_none_info *xi = ac->private;
+
+       xi->starting = true;
+       xi->built_authorizer = false;
+}
+
+static void destroy(struct ceph_auth_client *ac)
+{
+       kfree(ac->private);
+       ac->private = NULL;
+}
+
+static int is_authenticated(struct ceph_auth_client *ac)
+{
+       struct ceph_auth_none_info *xi = ac->private;
+
+       return !xi->starting;
+}
+
+/*
+ * the generic auth code decode the global_id, and we carry no actual
+ * authenticate state, so nothing happens here.
+ */
+static int handle_reply(struct ceph_auth_client *ac, int result,
+                       void *buf, void *end)
+{
+       struct ceph_auth_none_info *xi = ac->private;
+
+       xi->starting = false;
+       return result;
+}
+
+/*
+ * build an 'authorizer' with our entity_name and global_id.  we can
+ * reuse a single static copy since it is identical for all services
+ * we connect to.
+ */
+static int ceph_auth_none_create_authorizer(
+       struct ceph_auth_client *ac, int peer_type,
+       struct ceph_authorizer **a,
+       void **buf, size_t *len,
+       void **reply_buf, size_t *reply_len)
+{
+       struct ceph_auth_none_info *ai = ac->private;
+       struct ceph_none_authorizer *au = &ai->au;
+       void *p, *end;
+       int ret;
+
+       if (!ai->built_authorizer) {
+               p = au->buf;
+               end = p + sizeof(au->buf);
+               ceph_encode_8(&p, 1);
+               ret = ceph_entity_name_encode(ac->name, &p, end - 8);
+               if (ret < 0)
+                       goto bad;
+               ceph_decode_need(&p, end, sizeof(u64), bad2);
+               ceph_encode_64(&p, ac->global_id);
+               au->buf_len = p - (void *)au->buf;
+               ai->built_authorizer = true;
+               dout("built authorizer len %d\n", au->buf_len);
+       }
+
+       *a = (struct ceph_authorizer *)au;
+       *buf = au->buf;
+       *len = au->buf_len;
+       *reply_buf = au->reply_buf;
+       *reply_len = sizeof(au->reply_buf);
+       return 0;
+
+bad2:
+       ret = -ERANGE;
+bad:
+       return ret;
+}
+
+static void ceph_auth_none_destroy_authorizer(struct ceph_auth_client *ac,
+                                     struct ceph_authorizer *a)
+{
+       /* nothing to do */
+}
+
+static const struct ceph_auth_client_ops ceph_auth_none_ops = {
+       .reset = reset,
+       .destroy = destroy,
+       .is_authenticated = is_authenticated,
+       .handle_reply = handle_reply,
+       .create_authorizer = ceph_auth_none_create_authorizer,
+       .destroy_authorizer = ceph_auth_none_destroy_authorizer,
+};
+
+int ceph_auth_none_init(struct ceph_auth_client *ac)
+{
+       struct ceph_auth_none_info *xi;
+
+       dout("ceph_auth_none_init %p\n", ac);
+       xi = kzalloc(sizeof(*xi), GFP_NOFS);
+       if (!xi)
+               return -ENOMEM;
+
+       xi->starting = true;
+       xi->built_authorizer = false;
+
+       ac->protocol = CEPH_AUTH_NONE;
+       ac->private = xi;
+       ac->ops = &ceph_auth_none_ops;
+       return 0;
+}
+
diff --git a/fs/ceph/auth_none.h b/fs/ceph/auth_none.h
new file mode 100644 (file)
index 0000000..8164df1
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef _FS_CEPH_AUTH_NONE_H
+#define _FS_CEPH_AUTH_NONE_H
+
+#include <linux/slab.h>
+
+#include "auth.h"
+
+/*
+ * null security mode.
+ *
+ * we use a single static authorizer that simply encodes our entity name
+ * and global id.
+ */
+
+struct ceph_none_authorizer {
+       char buf[128];
+       int buf_len;
+       char reply_buf[0];
+};
+
+struct ceph_auth_none_info {
+       bool starting;
+       bool built_authorizer;
+       struct ceph_none_authorizer au;   /* we only need one; it's static */
+};
+
+extern int ceph_auth_none_init(struct ceph_auth_client *ac);
+
+#endif
+
diff --git a/fs/ceph/auth_x.c b/fs/ceph/auth_x.c
new file mode 100644 (file)
index 0000000..fee5a08
--- /dev/null
@@ -0,0 +1,668 @@
+
+#include "ceph_debug.h"
+
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+
+#include "auth_x.h"
+#include "auth_x_protocol.h"
+#include "crypto.h"
+#include "auth.h"
+#include "decode.h"
+
+#define TEMP_TICKET_BUF_LEN    256
+
+static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed);
+
+static int ceph_x_is_authenticated(struct ceph_auth_client *ac)
+{
+       struct ceph_x_info *xi = ac->private;
+       int need;
+
+       ceph_x_validate_tickets(ac, &need);
+       dout("ceph_x_is_authenticated want=%d need=%d have=%d\n",
+            ac->want_keys, need, xi->have_keys);
+       return (ac->want_keys & xi->have_keys) == ac->want_keys;
+}
+
+static int ceph_x_encrypt_buflen(int ilen)
+{
+       return sizeof(struct ceph_x_encrypt_header) + ilen + 16 +
+               sizeof(u32);
+}
+
+static int ceph_x_encrypt(struct ceph_crypto_key *secret,
+                         void *ibuf, int ilen, void *obuf, size_t olen)
+{
+       struct ceph_x_encrypt_header head = {
+               .struct_v = 1,
+               .magic = cpu_to_le64(CEPHX_ENC_MAGIC)
+       };
+       size_t len = olen - sizeof(u32);
+       int ret;
+
+       ret = ceph_encrypt2(secret, obuf + sizeof(u32), &len,
+                           &head, sizeof(head), ibuf, ilen);
+       if (ret)
+               return ret;
+       ceph_encode_32(&obuf, len);
+       return len + sizeof(u32);
+}
+
+static int ceph_x_decrypt(struct ceph_crypto_key *secret,
+                         void **p, void *end, void *obuf, size_t olen)
+{
+       struct ceph_x_encrypt_header head;
+       size_t head_len = sizeof(head);
+       int len, ret;
+
+       len = ceph_decode_32(p);
+       if (*p + len > end)
+               return -EINVAL;
+
+       dout("ceph_x_decrypt len %d\n", len);
+       ret = ceph_decrypt2(secret, &head, &head_len, obuf, &olen,
+                           *p, len);
+       if (ret)
+               return ret;
+       if (head.struct_v != 1 || le64_to_cpu(head.magic) != CEPHX_ENC_MAGIC)
+               return -EPERM;
+       *p += len;
+       return olen;
+}
+
+/*
+ * get existing (or insert new) ticket handler
+ */
+struct ceph_x_ticket_handler *get_ticket_handler(struct ceph_auth_client *ac,
+                                                int service)
+{
+       struct ceph_x_ticket_handler *th;
+       struct ceph_x_info *xi = ac->private;
+       struct rb_node *parent = NULL, **p = &xi->ticket_handlers.rb_node;
+
+       while (*p) {
+               parent = *p;
+               th = rb_entry(parent, struct ceph_x_ticket_handler, node);
+               if (service < th->service)
+                       p = &(*p)->rb_left;
+               else if (service > th->service)
+                       p = &(*p)->rb_right;
+               else
+                       return th;
+       }
+
+       /* add it */
+       th = kzalloc(sizeof(*th), GFP_NOFS);
+       if (!th)
+               return ERR_PTR(-ENOMEM);
+       th->service = service;
+       rb_link_node(&th->node, parent, p);
+       rb_insert_color(&th->node, &xi->ticket_handlers);
+       return th;
+}
+
+static void remove_ticket_handler(struct ceph_auth_client *ac,
+                                 struct ceph_x_ticket_handler *th)
+{
+       struct ceph_x_info *xi = ac->private;
+
+       dout("remove_ticket_handler %p %d\n", th, th->service);
+       rb_erase(&th->node, &xi->ticket_handlers);
+       ceph_crypto_key_destroy(&th->session_key);
+       if (th->ticket_blob)
+               ceph_buffer_put(th->ticket_blob);
+       kfree(th);
+}
+
+static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
+                                   struct ceph_crypto_key *secret,
+                                   void *buf, void *end)
+{
+       struct ceph_x_info *xi = ac->private;
+       int num;
+       void *p = buf;
+       int ret;
+       char *dbuf;
+       char *ticket_buf;
+       u8 struct_v;
+
+       dbuf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS);
+       if (!dbuf)
+               return -ENOMEM;
+
+       ret = -ENOMEM;
+       ticket_buf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS);
+       if (!ticket_buf)
+               goto out_dbuf;
+
+       ceph_decode_need(&p, end, 1 + sizeof(u32), bad);
+       struct_v = ceph_decode_8(&p);
+       if (struct_v != 1)
+               goto bad;
+       num = ceph_decode_32(&p);
+       dout("%d tickets\n", num);
+       while (num--) {
+               int type;
+               u8 struct_v;
+               struct ceph_x_ticket_handler *th;
+               void *dp, *dend;
+               int dlen;
+               char is_enc;
+               struct timespec validity;
+               struct ceph_crypto_key old_key;
+               void *tp, *tpend;
+               struct ceph_timespec new_validity;
+               struct ceph_crypto_key new_session_key;
+               struct ceph_buffer *new_ticket_blob;
+               unsigned long new_expires, new_renew_after;
+               u64 new_secret_id;
+
+               ceph_decode_need(&p, end, sizeof(u32) + 1, bad);
+
+               type = ceph_decode_32(&p);
+               dout(" ticket type %d %s\n", type, ceph_entity_type_name(type));
+
+               struct_v = ceph_decode_8(&p);
+               if (struct_v != 1)
+                       goto bad;
+
+               th = get_ticket_handler(ac, type);
+               if (IS_ERR(th)) {
+                       ret = PTR_ERR(th);
+                       goto out;
+               }
+
+               /* blob for me */
+               dlen = ceph_x_decrypt(secret, &p, end, dbuf,
+                                     TEMP_TICKET_BUF_LEN);
+               if (dlen <= 0) {
+                       ret = dlen;
+                       goto out;
+               }
+               dout(" decrypted %d bytes\n", dlen);
+               dend = dbuf + dlen;
+               dp = dbuf;
+
+               struct_v = ceph_decode_8(&dp);
+               if (struct_v != 1)
+                       goto bad;
+
+               memcpy(&old_key, &th->session_key, sizeof(old_key));
+               ret = ceph_crypto_key_decode(&new_session_key, &dp, dend);
+               if (ret)
+                       goto out;
+
+               ceph_decode_copy(&dp, &new_validity, sizeof(new_validity));
+               ceph_decode_timespec(&validity, &new_validity);
+               new_expires = get_seconds() + validity.tv_sec;
+               new_renew_after = new_expires - (validity.tv_sec / 4);
+               dout(" expires=%lu renew_after=%lu\n", new_expires,
+                    new_renew_after);
+
+               /* ticket blob for service */
+               ceph_decode_8_safe(&p, end, is_enc, bad);
+               tp = ticket_buf;
+               if (is_enc) {
+                       /* encrypted */
+                       dout(" encrypted ticket\n");
+                       dlen = ceph_x_decrypt(&old_key, &p, end, ticket_buf,
+                                             TEMP_TICKET_BUF_LEN);
+                       if (dlen < 0) {
+                               ret = dlen;
+                               goto out;
+                       }
+                       dlen = ceph_decode_32(&tp);
+               } else {
+                       /* unencrypted */
+                       ceph_decode_32_safe(&p, end, dlen, bad);
+                       ceph_decode_need(&p, end, dlen, bad);
+                       ceph_decode_copy(&p, ticket_buf, dlen);
+               }
+               tpend = tp + dlen;
+               dout(" ticket blob is %d bytes\n", dlen);
+               ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad);
+               struct_v = ceph_decode_8(&tp);
+               new_secret_id = ceph_decode_64(&tp);
+               ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend);
+               if (ret)
+                       goto out;
+
+               /* all is well, update our ticket */
+               ceph_crypto_key_destroy(&th->session_key);
+               if (th->ticket_blob)
+                       ceph_buffer_put(th->ticket_blob);
+               th->session_key = new_session_key;
+               th->ticket_blob = new_ticket_blob;
+               th->validity = new_validity;
+               th->secret_id = new_secret_id;
+               th->expires = new_expires;
+               th->renew_after = new_renew_after;
+               dout(" got ticket service %d (%s) secret_id %lld len %d\n",
+                    type, ceph_entity_type_name(type), th->secret_id,
+                    (int)th->ticket_blob->vec.iov_len);
+               xi->have_keys |= th->service;
+       }
+
+       ret = 0;
+out:
+       kfree(ticket_buf);
+out_dbuf:
+       kfree(dbuf);
+       return ret;
+
+bad:
+       ret = -EINVAL;
+       goto out;
+}
+
+static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
+                                  struct ceph_x_ticket_handler *th,
+                                  struct ceph_x_authorizer *au)
+{
+       int maxlen;
+       struct ceph_x_authorize_a *msg_a;
+       struct ceph_x_authorize_b msg_b;
+       void *p, *end;
+       int ret;
+       int ticket_blob_len =
+               (th->ticket_blob ? th->ticket_blob->vec.iov_len : 0);
+
+       dout("build_authorizer for %s %p\n",
+            ceph_entity_type_name(th->service), au);
+
+       maxlen = sizeof(*msg_a) + sizeof(msg_b) +
+               ceph_x_encrypt_buflen(ticket_blob_len);
+       dout("  need len %d\n", maxlen);
+       if (au->buf && au->buf->alloc_len < maxlen) {
+               ceph_buffer_put(au->buf);
+               au->buf = NULL;
+       }
+       if (!au->buf) {
+               au->buf = ceph_buffer_new(maxlen, GFP_NOFS);
+               if (!au->buf)
+                       return -ENOMEM;
+       }
+       au->service = th->service;
+
+       msg_a = au->buf->vec.iov_base;
+       msg_a->struct_v = 1;
+       msg_a->global_id = cpu_to_le64(ac->global_id);
+       msg_a->service_id = cpu_to_le32(th->service);
+       msg_a->ticket_blob.struct_v = 1;
+       msg_a->ticket_blob.secret_id = cpu_to_le64(th->secret_id);
+       msg_a->ticket_blob.blob_len = cpu_to_le32(ticket_blob_len);
+       if (ticket_blob_len) {
+               memcpy(msg_a->ticket_blob.blob, th->ticket_blob->vec.iov_base,
+                      th->ticket_blob->vec.iov_len);
+       }
+       dout(" th %p secret_id %lld %lld\n", th, th->secret_id,
+            le64_to_cpu(msg_a->ticket_blob.secret_id));
+
+       p = msg_a + 1;
+       p += ticket_blob_len;
+       end = au->buf->vec.iov_base + au->buf->vec.iov_len;
+
+       get_random_bytes(&au->nonce, sizeof(au->nonce));
+       msg_b.struct_v = 1;
+       msg_b.nonce = cpu_to_le64(au->nonce);
+       ret = ceph_x_encrypt(&th->session_key, &msg_b, sizeof(msg_b),
+                            p, end - p);
+       if (ret < 0)
+               goto out_buf;
+       p += ret;
+       au->buf->vec.iov_len = p - au->buf->vec.iov_base;
+       dout(" built authorizer nonce %llx len %d\n", au->nonce,
+            (int)au->buf->vec.iov_len);
+       BUG_ON(au->buf->vec.iov_len > maxlen);
+       return 0;
+
+out_buf:
+       ceph_buffer_put(au->buf);
+       au->buf = NULL;
+       return ret;
+}
+
+static int ceph_x_encode_ticket(struct ceph_x_ticket_handler *th,
+                               void **p, void *end)
+{
+       ceph_decode_need(p, end, 1 + sizeof(u64), bad);
+       ceph_encode_8(p, 1);
+       ceph_encode_64(p, th->secret_id);
+       if (th->ticket_blob) {
+               const char *buf = th->ticket_blob->vec.iov_base;
+               u32 len = th->ticket_blob->vec.iov_len;
+
+               ceph_encode_32_safe(p, end, len, bad);
+               ceph_encode_copy_safe(p, end, buf, len, bad);
+       } else {
+               ceph_encode_32_safe(p, end, 0, bad);
+       }
+
+       return 0;
+bad:
+       return -ERANGE;
+}
+
+static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed)
+{
+       int want = ac->want_keys;
+       struct ceph_x_info *xi = ac->private;
+       int service;
+
+       *pneed = ac->want_keys & ~(xi->have_keys);
+
+       for (service = 1; service <= want; service <<= 1) {
+               struct ceph_x_ticket_handler *th;
+
+               if (!(ac->want_keys & service))
+                       continue;
+
+               if (*pneed & service)
+                       continue;
+
+               th = get_ticket_handler(ac, service);
+
+               if (!th) {
+                       *pneed |= service;
+                       continue;
+               }
+
+               if (get_seconds() >= th->renew_after)
+                       *pneed |= service;
+               if (get_seconds() >= th->expires)
+                       xi->have_keys &= ~service;
+       }
+}
+
+
+static int ceph_x_build_request(struct ceph_auth_client *ac,
+                               void *buf, void *end)
+{
+       struct ceph_x_info *xi = ac->private;
+       int need;
+       struct ceph_x_request_header *head = buf;
+       int ret;
+       struct ceph_x_ticket_handler *th =
+               get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH);
+
+       ceph_x_validate_tickets(ac, &need);
+
+       dout("build_request want %x have %x need %x\n",
+            ac->want_keys, xi->have_keys, need);
+
+       if (need & CEPH_ENTITY_TYPE_AUTH) {
+               struct ceph_x_authenticate *auth = (void *)(head + 1);
+               void *p = auth + 1;
+               struct ceph_x_challenge_blob tmp;
+               char tmp_enc[40];
+               u64 *u;
+
+               if (p > end)
+                       return -ERANGE;
+
+               dout(" get_auth_session_key\n");
+               head->op = cpu_to_le16(CEPHX_GET_AUTH_SESSION_KEY);
+
+               /* encrypt and hash */
+               get_random_bytes(&auth->client_challenge, sizeof(u64));
+               tmp.client_challenge = auth->client_challenge;
+               tmp.server_challenge = cpu_to_le64(xi->server_challenge);
+               ret = ceph_x_encrypt(&xi->secret, &tmp, sizeof(tmp),
+                                    tmp_enc, sizeof(tmp_enc));
+               if (ret < 0)
+                       return ret;
+
+               auth->struct_v = 1;
+               auth->key = 0;
+               for (u = (u64 *)tmp_enc; u + 1 <= (u64 *)(tmp_enc + ret); u++)
+                       auth->key ^= *u;
+               dout(" server_challenge %llx client_challenge %llx key %llx\n",
+                    xi->server_challenge, le64_to_cpu(auth->client_challenge),
+                    le64_to_cpu(auth->key));
+
+               /* now encode the old ticket if exists */
+               ret = ceph_x_encode_ticket(th, &p, end);
+               if (ret < 0)
+                       return ret;
+
+               return p - buf;
+       }
+
+       if (need) {
+               void *p = head + 1;
+               struct ceph_x_service_ticket_request *req;
+
+               if (p > end)
+                       return -ERANGE;
+               head->op = cpu_to_le16(CEPHX_GET_PRINCIPAL_SESSION_KEY);
+
+               BUG_ON(!th);
+               ret = ceph_x_build_authorizer(ac, th, &xi->auth_authorizer);
+               if (ret)
+                       return ret;
+               ceph_encode_copy(&p, xi->auth_authorizer.buf->vec.iov_base,
+                                xi->auth_authorizer.buf->vec.iov_len);
+
+               req = p;
+               req->keys = cpu_to_le32(need);
+               p += sizeof(*req);
+               return p - buf;
+       }
+
+       return 0;
+}
+
+static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result,
+                              void *buf, void *end)
+{
+       struct ceph_x_info *xi = ac->private;
+       struct ceph_x_reply_header *head = buf;
+       struct ceph_x_ticket_handler *th;
+       int len = end - buf;
+       int op;
+       int ret;
+
+       if (result)
+               return result;  /* XXX hmm? */
+
+       if (xi->starting) {
+               /* it's a hello */
+               struct ceph_x_server_challenge *sc = buf;
+
+               if (len != sizeof(*sc))
+                       return -EINVAL;
+               xi->server_challenge = le64_to_cpu(sc->server_challenge);
+               dout("handle_reply got server challenge %llx\n",
+                    xi->server_challenge);
+               xi->starting = false;
+               xi->have_keys &= ~CEPH_ENTITY_TYPE_AUTH;
+               return -EAGAIN;
+       }
+
+       op = le32_to_cpu(head->op);
+       result = le32_to_cpu(head->result);
+       dout("handle_reply op %d result %d\n", op, result);
+       switch (op) {
+       case CEPHX_GET_AUTH_SESSION_KEY:
+               /* verify auth key */
+               ret = ceph_x_proc_ticket_reply(ac, &xi->secret,
+                                              buf + sizeof(*head), end);
+               break;
+
+       case CEPHX_GET_PRINCIPAL_SESSION_KEY:
+               th = get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH);
+               BUG_ON(!th);
+               ret = ceph_x_proc_ticket_reply(ac, &th->session_key,
+                                              buf + sizeof(*head), end);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+       if (ret)
+               return ret;
+       if (ac->want_keys == xi->have_keys)
+               return 0;
+       return -EAGAIN;
+}
+
+static int ceph_x_create_authorizer(
+       struct ceph_auth_client *ac, int peer_type,
+       struct ceph_authorizer **a,
+       void **buf, size_t *len,
+       void **reply_buf, size_t *reply_len)
+{
+       struct ceph_x_authorizer *au;
+       struct ceph_x_ticket_handler *th;
+       int ret;
+
+       th = get_ticket_handler(ac, peer_type);
+       if (IS_ERR(th))
+               return PTR_ERR(th);
+
+       au = kzalloc(sizeof(*au), GFP_NOFS);
+       if (!au)
+               return -ENOMEM;
+
+       ret = ceph_x_build_authorizer(ac, th, au);
+       if (ret) {
+               kfree(au);
+               return ret;
+       }
+
+       *a = (struct ceph_authorizer *)au;
+       *buf = au->buf->vec.iov_base;
+       *len = au->buf->vec.iov_len;
+       *reply_buf = au->reply_buf;
+       *reply_len = sizeof(au->reply_buf);
+       return 0;
+}
+
+static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac,
+                                         struct ceph_authorizer *a, size_t len)
+{
+       struct ceph_x_authorizer *au = (void *)a;
+       struct ceph_x_ticket_handler *th;
+       int ret = 0;
+       struct ceph_x_authorize_reply reply;
+       void *p = au->reply_buf;
+       void *end = p + sizeof(au->reply_buf);
+
+       th = get_ticket_handler(ac, au->service);
+       if (!th)
+               return -EIO;  /* hrm! */
+       ret = ceph_x_decrypt(&th->session_key, &p, end, &reply, sizeof(reply));
+       if (ret < 0)
+               return ret;
+       if (ret != sizeof(reply))
+               return -EPERM;
+
+       if (au->nonce + 1 != le64_to_cpu(reply.nonce_plus_one))
+               ret = -EPERM;
+       else
+               ret = 0;
+       dout("verify_authorizer_reply nonce %llx got %llx ret %d\n",
+            au->nonce, le64_to_cpu(reply.nonce_plus_one), ret);
+       return ret;
+}
+
+static void ceph_x_destroy_authorizer(struct ceph_auth_client *ac,
+                                     struct ceph_authorizer *a)
+{
+       struct ceph_x_authorizer *au = (void *)a;
+
+       ceph_buffer_put(au->buf);
+       kfree(au);
+}
+
+
+static void ceph_x_reset(struct ceph_auth_client *ac)
+{
+       struct ceph_x_info *xi = ac->private;
+
+       dout("reset\n");
+       xi->starting = true;
+       xi->server_challenge = 0;
+}
+
+static void ceph_x_destroy(struct ceph_auth_client *ac)
+{
+       struct ceph_x_info *xi = ac->private;
+       struct rb_node *p;
+
+       dout("ceph_x_destroy %p\n", ac);
+       ceph_crypto_key_destroy(&xi->secret);
+
+       while ((p = rb_first(&xi->ticket_handlers)) != NULL) {
+               struct ceph_x_ticket_handler *th =
+                       rb_entry(p, struct ceph_x_ticket_handler, node);
+               remove_ticket_handler(ac, th);
+       }
+
+       kfree(ac->private);
+       ac->private = NULL;
+}
+
+static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac,
+                                  int peer_type)
+{
+       struct ceph_x_ticket_handler *th;
+
+       th = get_ticket_handler(ac, peer_type);
+       if (th && !IS_ERR(th))
+               remove_ticket_handler(ac, th);
+}
+
+
+static const struct ceph_auth_client_ops ceph_x_ops = {
+       .is_authenticated = ceph_x_is_authenticated,
+       .build_request = ceph_x_build_request,
+       .handle_reply = ceph_x_handle_reply,
+       .create_authorizer = ceph_x_create_authorizer,
+       .verify_authorizer_reply = ceph_x_verify_authorizer_reply,
+       .destroy_authorizer = ceph_x_destroy_authorizer,
+       .invalidate_authorizer = ceph_x_invalidate_authorizer,
+       .reset =  ceph_x_reset,
+       .destroy = ceph_x_destroy,
+};
+
+
+int ceph_x_init(struct ceph_auth_client *ac)
+{
+       struct ceph_x_info *xi;
+       int ret;
+
+       dout("ceph_x_init %p\n", ac);
+       ret = -ENOMEM;
+       xi = kzalloc(sizeof(*xi), GFP_NOFS);
+       if (!xi)
+               goto out;
+
+       ret = -EINVAL;
+       if (!ac->secret) {
+               pr_err("no secret set (for auth_x protocol)\n");
+               goto out_nomem;
+       }
+
+       ret = ceph_crypto_key_unarmor(&xi->secret, ac->secret);
+       if (ret)
+               goto out_nomem;
+
+       xi->starting = true;
+       xi->ticket_handlers = RB_ROOT;
+
+       ac->protocol = CEPH_AUTH_CEPHX;
+       ac->private = xi;
+       ac->ops = &ceph_x_ops;
+       return 0;
+
+out_nomem:
+       kfree(xi);
+out:
+       return ret;
+}
+
+
diff --git a/fs/ceph/auth_x.h b/fs/ceph/auth_x.h
new file mode 100644 (file)
index 0000000..ff6f818
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef _FS_CEPH_AUTH_X_H
+#define _FS_CEPH_AUTH_X_H
+
+#include <linux/rbtree.h>
+
+#include "crypto.h"
+#include "auth.h"
+#include "auth_x_protocol.h"
+
+/*
+ * Handle ticket for a single service.
+ */
+struct ceph_x_ticket_handler {
+       struct rb_node node;
+       unsigned service;
+
+       struct ceph_crypto_key session_key;
+       struct ceph_timespec validity;
+
+       u64 secret_id;
+       struct ceph_buffer *ticket_blob;
+
+       unsigned long renew_after, expires;
+};
+
+
+struct ceph_x_authorizer {
+       struct ceph_buffer *buf;
+       unsigned service;
+       u64 nonce;
+       char reply_buf[128];  /* big enough for encrypted blob */
+};
+
+struct ceph_x_info {
+       struct ceph_crypto_key secret;
+
+       bool starting;
+       u64 server_challenge;
+
+       unsigned have_keys;
+       struct rb_root ticket_handlers;
+
+       struct ceph_x_authorizer auth_authorizer;
+};
+
+extern int ceph_x_init(struct ceph_auth_client *ac);
+
+#endif
+
diff --git a/fs/ceph/auth_x_protocol.h b/fs/ceph/auth_x_protocol.h
new file mode 100644 (file)
index 0000000..671d305
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef __FS_CEPH_AUTH_X_PROTOCOL
+#define __FS_CEPH_AUTH_X_PROTOCOL
+
+#define CEPHX_GET_AUTH_SESSION_KEY      0x0100
+#define CEPHX_GET_PRINCIPAL_SESSION_KEY 0x0200
+#define CEPHX_GET_ROTATING_KEY          0x0400
+
+/* common bits */
+struct ceph_x_ticket_blob {
+       __u8 struct_v;
+       __le64 secret_id;
+       __le32 blob_len;
+       char blob[];
+} __attribute__ ((packed));
+
+
+/* common request/reply headers */
+struct ceph_x_request_header {
+       __le16 op;
+} __attribute__ ((packed));
+
+struct ceph_x_reply_header {
+       __le16 op;
+       __le32 result;
+} __attribute__ ((packed));
+
+
+/* authenticate handshake */
+
+/* initial hello (no reply header) */
+struct ceph_x_server_challenge {
+       __u8 struct_v;
+       __le64 server_challenge;
+} __attribute__ ((packed));
+
+struct ceph_x_authenticate {
+       __u8 struct_v;
+       __le64 client_challenge;
+       __le64 key;
+       /* ticket blob */
+} __attribute__ ((packed));
+
+struct ceph_x_service_ticket_request {
+       __u8 struct_v;
+       __le32 keys;
+} __attribute__ ((packed));
+
+struct ceph_x_challenge_blob {
+       __le64 server_challenge;
+       __le64 client_challenge;
+} __attribute__ ((packed));
+
+
+
+/* authorize handshake */
+
+/*
+ * The authorizer consists of two pieces:
+ *  a - service id, ticket blob
+ *  b - encrypted with session key
+ */
+struct ceph_x_authorize_a {
+       __u8 struct_v;
+       __le64 global_id;
+       __le32 service_id;
+       struct ceph_x_ticket_blob ticket_blob;
+} __attribute__ ((packed));
+
+struct ceph_x_authorize_b {
+       __u8 struct_v;
+       __le64 nonce;
+} __attribute__ ((packed));
+
+struct ceph_x_authorize_reply {
+       __u8 struct_v;
+       __le64 nonce_plus_one;
+} __attribute__ ((packed));
+
+
+/*
+ * encyption bundle
+ */
+#define CEPHX_ENC_MAGIC 0xff009cad8826aa55ull
+
+struct ceph_x_encrypt_header {
+       __u8 struct_v;
+       __le64 magic;
+} __attribute__ ((packed));
+
+#endif
diff --git a/fs/ceph/buffer.c b/fs/ceph/buffer.c
new file mode 100644 (file)
index 0000000..c67535d
--- /dev/null
@@ -0,0 +1,81 @@
+
+#include "ceph_debug.h"
+
+#include <linux/slab.h>
+
+#include "buffer.h"
+#include "decode.h"
+
+struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp)
+{
+       struct ceph_buffer *b;
+
+       b = kmalloc(sizeof(*b), gfp);
+       if (!b)
+               return NULL;
+
+       b->vec.iov_base = kmalloc(len, gfp | __GFP_NOWARN);
+       if (b->vec.iov_base) {
+               b->is_vmalloc = false;
+       } else {
+               b->vec.iov_base = __vmalloc(len, gfp, PAGE_KERNEL);
+               if (!b->vec.iov_base) {
+                       kfree(b);
+                       return NULL;
+               }
+               b->is_vmalloc = true;
+       }
+
+       kref_init(&b->kref);
+       b->alloc_len = len;
+       b->vec.iov_len = len;
+       dout("buffer_new %p\n", b);
+       return b;
+}
+
+void ceph_buffer_release(struct kref *kref)
+{
+       struct ceph_buffer *b = container_of(kref, struct ceph_buffer, kref);
+
+       dout("buffer_release %p\n", b);
+       if (b->vec.iov_base) {
+               if (b->is_vmalloc)
+                       vfree(b->vec.iov_base);
+               else
+                       kfree(b->vec.iov_base);
+       }
+       kfree(b);
+}
+
+int ceph_buffer_alloc(struct ceph_buffer *b, int len, gfp_t gfp)
+{
+       b->vec.iov_base = kmalloc(len, gfp | __GFP_NOWARN);
+       if (b->vec.iov_base) {
+               b->is_vmalloc = false;
+       } else {
+               b->vec.iov_base = __vmalloc(len, gfp, PAGE_KERNEL);
+               b->is_vmalloc = true;
+       }
+       if (!b->vec.iov_base)
+               return -ENOMEM;
+       b->alloc_len = len;
+       b->vec.iov_len = len;
+       return 0;
+}
+
+int ceph_decode_buffer(struct ceph_buffer **b, void **p, void *end)
+{
+       size_t len;
+
+       ceph_decode_need(p, end, sizeof(u32), bad);
+       len = ceph_decode_32(p);
+       dout("decode_buffer len %d\n", (int)len);
+       ceph_decode_need(p, end, len, bad);
+       *b = ceph_buffer_new(len, GFP_NOFS);
+       if (!*b)
+               return -ENOMEM;
+       ceph_decode_copy(p, (*b)->vec.iov_base, len);
+       return 0;
+bad:
+       return -EINVAL;
+}
diff --git a/fs/ceph/buffer.h b/fs/ceph/buffer.h
new file mode 100644 (file)
index 0000000..58d1901
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef __FS_CEPH_BUFFER_H
+#define __FS_CEPH_BUFFER_H
+
+#include <linux/kref.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/types.h>
+#include <linux/uio.h>
+
+/*
+ * a simple reference counted buffer.
+ *
+ * use kmalloc for small sizes (<= one page), vmalloc for larger
+ * sizes.
+ */
+struct ceph_buffer {
+       struct kref kref;
+       struct kvec vec;
+       size_t alloc_len;
+       bool is_vmalloc;
+};
+
+extern struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp);
+extern void ceph_buffer_release(struct kref *kref);
+
+static inline struct ceph_buffer *ceph_buffer_get(struct ceph_buffer *b)
+{
+       kref_get(&b->kref);
+       return b;
+}
+
+static inline void ceph_buffer_put(struct ceph_buffer *b)
+{
+       kref_put(&b->kref, ceph_buffer_release);
+}
+
+extern int ceph_decode_buffer(struct ceph_buffer **b, void **p, void *end);
+
+#endif
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
new file mode 100644 (file)
index 0000000..d940053
--- /dev/null
@@ -0,0 +1,2960 @@
+#include "ceph_debug.h"
+
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/wait.h>
+#include <linux/writeback.h>
+
+#include "super.h"
+#include "decode.h"
+#include "messenger.h"
+
+/*
+ * Capability management
+ *
+ * The Ceph metadata servers control client access to inode metadata
+ * and file data by issuing capabilities, granting clients permission
+ * to read and/or write both inode field and file data to OSDs
+ * (storage nodes).  Each capability consists of a set of bits
+ * indicating which operations are allowed.
+ *
+ * If the client holds a *_SHARED cap, the client has a coherent value
+ * that can be safely read from the cached inode.
+ *
+ * In the case of a *_EXCL (exclusive) or FILE_WR capabilities, the
+ * client is allowed to change inode attributes (e.g., file size,
+ * mtime), note its dirty state in the ceph_cap, and asynchronously
+ * flush that metadata change to the MDS.
+ *
+ * In the event of a conflicting operation (perhaps by another
+ * client), the MDS will revoke the conflicting client capabilities.
+ *
+ * In order for a client to cache an inode, it must hold a capability
+ * with at least one MDS server.  When inodes are released, release
+ * notifications are batched and periodically sent en masse to the MDS
+ * cluster to release server state.
+ */
+
+
+/*
+ * Generate readable cap strings for debugging output.
+ */
+#define MAX_CAP_STR 20
+static char cap_str[MAX_CAP_STR][40];
+static DEFINE_SPINLOCK(cap_str_lock);
+static int last_cap_str;
+
+static char *gcap_string(char *s, int c)
+{
+       if (c & CEPH_CAP_GSHARED)
+               *s++ = 's';
+       if (c & CEPH_CAP_GEXCL)
+               *s++ = 'x';
+       if (c & CEPH_CAP_GCACHE)
+               *s++ = 'c';
+       if (c & CEPH_CAP_GRD)
+               *s++ = 'r';
+       if (c & CEPH_CAP_GWR)
+               *s++ = 'w';
+       if (c & CEPH_CAP_GBUFFER)
+               *s++ = 'b';
+       if (c & CEPH_CAP_GLAZYIO)
+               *s++ = 'l';
+       return s;
+}
+
+const char *ceph_cap_string(int caps)
+{
+       int i;
+       char *s;
+       int c;
+
+       spin_lock(&cap_str_lock);
+       i = last_cap_str++;
+       if (last_cap_str == MAX_CAP_STR)
+               last_cap_str = 0;
+       spin_unlock(&cap_str_lock);
+
+       s = cap_str[i];
+
+       if (caps & CEPH_CAP_PIN)
+               *s++ = 'p';
+
+       c = (caps >> CEPH_CAP_SAUTH) & 3;
+       if (c) {
+               *s++ = 'A';
+               s = gcap_string(s, c);
+       }
+
+       c = (caps >> CEPH_CAP_SLINK) & 3;
+       if (c) {
+               *s++ = 'L';
+               s = gcap_string(s, c);
+       }
+
+       c = (caps >> CEPH_CAP_SXATTR) & 3;
+       if (c) {
+               *s++ = 'X';
+               s = gcap_string(s, c);
+       }
+
+       c = caps >> CEPH_CAP_SFILE;
+       if (c) {
+               *s++ = 'F';
+               s = gcap_string(s, c);
+       }
+
+       if (s == cap_str[i])
+               *s++ = '-';
+       *s = 0;
+       return cap_str[i];
+}
+
+/*
+ * Cap reservations
+ *
+ * Maintain a global pool of preallocated struct ceph_caps, referenced
+ * by struct ceph_caps_reservations.  This ensures that we preallocate
+ * memory needed to successfully process an MDS response.  (If an MDS
+ * sends us cap information and we fail to process it, we will have
+ * problems due to the client and MDS being out of sync.)
+ *
+ * Reservations are 'owned' by a ceph_cap_reservation context.
+ */
+static spinlock_t caps_list_lock;
+static struct list_head caps_list;  /* unused (reserved or unreserved) */
+static int caps_total_count;        /* total caps allocated */
+static int caps_use_count;          /* in use */
+static int caps_reserve_count;      /* unused, reserved */
+static int caps_avail_count;        /* unused, unreserved */
+static int caps_min_count;          /* keep at least this many (unreserved) */
+
+void __init ceph_caps_init(void)
+{
+       INIT_LIST_HEAD(&caps_list);
+       spin_lock_init(&caps_list_lock);
+}
+
+void ceph_caps_finalize(void)
+{
+       struct ceph_cap *cap;
+
+       spin_lock(&caps_list_lock);
+       while (!list_empty(&caps_list)) {
+               cap = list_first_entry(&caps_list, struct ceph_cap, caps_item);
+               list_del(&cap->caps_item);
+               kmem_cache_free(ceph_cap_cachep, cap);
+       }
+       caps_total_count = 0;
+       caps_avail_count = 0;
+       caps_use_count = 0;
+       caps_reserve_count = 0;
+       caps_min_count = 0;
+       spin_unlock(&caps_list_lock);
+}
+
+void ceph_adjust_min_caps(int delta)
+{
+       spin_lock(&caps_list_lock);
+       caps_min_count += delta;
+       BUG_ON(caps_min_count < 0);
+       spin_unlock(&caps_list_lock);
+}
+
+int ceph_reserve_caps(struct ceph_cap_reservation *ctx, int need)
+{
+       int i;
+       struct ceph_cap *cap;
+       int have;
+       int alloc = 0;
+       LIST_HEAD(newcaps);
+       int ret = 0;
+
+       dout("reserve caps ctx=%p need=%d\n", ctx, need);
+
+       /* first reserve any caps that are already allocated */
+       spin_lock(&caps_list_lock);
+       if (caps_avail_count >= need)
+               have = need;
+       else
+               have = caps_avail_count;
+       caps_avail_count -= have;
+       caps_reserve_count += have;
+       BUG_ON(caps_total_count != caps_use_count + caps_reserve_count +
+              caps_avail_count);
+       spin_unlock(&caps_list_lock);
+
+       for (i = have; i < need; i++) {
+               cap = kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS);
+               if (!cap) {
+                       ret = -ENOMEM;
+                       goto out_alloc_count;
+               }
+               list_add(&cap->caps_item, &newcaps);
+               alloc++;
+       }
+       BUG_ON(have + alloc != need);
+
+       spin_lock(&caps_list_lock);
+       caps_total_count += alloc;
+       caps_reserve_count += alloc;
+       list_splice(&newcaps, &caps_list);
+
+       BUG_ON(caps_total_count != caps_use_count + caps_reserve_count +
+              caps_avail_count);
+       spin_unlock(&caps_list_lock);
+
+       ctx->count = need;
+       dout("reserve caps ctx=%p %d = %d used + %d resv + %d avail\n",
+            ctx, caps_total_count, caps_use_count, caps_reserve_count,
+            caps_avail_count);
+       return 0;
+
+out_alloc_count:
+       /* we didn't manage to reserve as much as we needed */
+       pr_warning("reserve caps ctx=%p ENOMEM need=%d got=%d\n",
+                  ctx, need, have);
+       return ret;
+}
+
+int ceph_unreserve_caps(struct ceph_cap_reservation *ctx)
+{
+       dout("unreserve caps ctx=%p count=%d\n", ctx, ctx->count);
+       if (ctx->count) {
+               spin_lock(&caps_list_lock);
+               BUG_ON(caps_reserve_count < ctx->count);
+               caps_reserve_count -= ctx->count;
+               caps_avail_count += ctx->count;
+               ctx->count = 0;
+               dout("unreserve caps %d = %d used + %d resv + %d avail\n",
+                    caps_total_count, caps_use_count, caps_reserve_count,
+                    caps_avail_count);
+               BUG_ON(caps_total_count != caps_use_count + caps_reserve_count +
+                      caps_avail_count);
+               spin_unlock(&caps_list_lock);
+       }
+       return 0;
+}
+
+static struct ceph_cap *get_cap(struct ceph_cap_reservation *ctx)
+{
+       struct ceph_cap *cap = NULL;
+
+       /* temporary, until we do something about cap import/export */
+       if (!ctx)
+               return kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS);
+
+       spin_lock(&caps_list_lock);
+       dout("get_cap ctx=%p (%d) %d = %d used + %d resv + %d avail\n",
+            ctx, ctx->count, caps_total_count, caps_use_count,
+            caps_reserve_count, caps_avail_count);
+       BUG_ON(!ctx->count);
+       BUG_ON(ctx->count > caps_reserve_count);
+       BUG_ON(list_empty(&caps_list));
+
+       ctx->count--;
+       caps_reserve_count--;
+       caps_use_count++;
+
+       cap = list_first_entry(&caps_list, struct ceph_cap, caps_item);
+       list_del(&cap->caps_item);
+
+       BUG_ON(caps_total_count != caps_use_count + caps_reserve_count +
+              caps_avail_count);
+       spin_unlock(&caps_list_lock);
+       return cap;
+}
+
+void ceph_put_cap(struct ceph_cap *cap)
+{
+       spin_lock(&caps_list_lock);
+       dout("put_cap %p %d = %d used + %d resv + %d avail\n",
+            cap, caps_total_count, caps_use_count,
+            caps_reserve_count, caps_avail_count);
+       caps_use_count--;
+       /*
+        * Keep some preallocated caps around (ceph_min_count), to
+        * avoid lots of free/alloc churn.
+        */
+       if (caps_avail_count >= caps_reserve_count + caps_min_count) {
+               caps_total_count--;
+               kmem_cache_free(ceph_cap_cachep, cap);
+       } else {
+               caps_avail_count++;
+               list_add(&cap->caps_item, &caps_list);
+       }
+
+       BUG_ON(caps_total_count != caps_use_count + caps_reserve_count +
+              caps_avail_count);
+       spin_unlock(&caps_list_lock);
+}
+
+void ceph_reservation_status(struct ceph_client *client,
+                            int *total, int *avail, int *used, int *reserved,
+                            int *min)
+{
+       if (total)
+               *total = caps_total_count;
+       if (avail)
+               *avail = caps_avail_count;
+       if (used)
+               *used = caps_use_count;
+       if (reserved)
+               *reserved = caps_reserve_count;
+       if (min)
+               *min = caps_min_count;
+}
+
+/*
+ * Find ceph_cap for given mds, if any.
+ *
+ * Called with i_lock held.
+ */
+static struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci, int mds)
+{
+       struct ceph_cap *cap;
+       struct rb_node *n = ci->i_caps.rb_node;
+
+       while (n) {
+               cap = rb_entry(n, struct ceph_cap, ci_node);
+               if (mds < cap->mds)
+                       n = n->rb_left;
+               else if (mds > cap->mds)
+                       n = n->rb_right;
+               else
+                       return cap;
+       }
+       return NULL;
+}
+
+/*
+ * Return id of any MDS with a cap, preferably FILE_WR|WRBUFFER|EXCL, else
+ * -1.
+ */
+static int __ceph_get_cap_mds(struct ceph_inode_info *ci, u32 *mseq)
+{
+       struct ceph_cap *cap;
+       int mds = -1;
+       struct rb_node *p;
+
+       /* prefer mds with WR|WRBUFFER|EXCL caps */
+       for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+               cap = rb_entry(p, struct ceph_cap, ci_node);
+               mds = cap->mds;
+               if (mseq)
+                       *mseq = cap->mseq;
+               if (cap->issued & (CEPH_CAP_FILE_WR |
+                                  CEPH_CAP_FILE_BUFFER |
+                                  CEPH_CAP_FILE_EXCL))
+                       break;
+       }
+       return mds;
+}
+
+int ceph_get_cap_mds(struct inode *inode)
+{
+       int mds;
+       spin_lock(&inode->i_lock);
+       mds = __ceph_get_cap_mds(ceph_inode(inode), NULL);
+       spin_unlock(&inode->i_lock);
+       return mds;
+}
+
+/*
+ * Called under i_lock.
+ */
+static void __insert_cap_node(struct ceph_inode_info *ci,
+                             struct ceph_cap *new)
+{
+       struct rb_node **p = &ci->i_caps.rb_node;
+       struct rb_node *parent = NULL;
+       struct ceph_cap *cap = NULL;
+
+       while (*p) {
+               parent = *p;
+               cap = rb_entry(parent, struct ceph_cap, ci_node);
+               if (new->mds < cap->mds)
+                       p = &(*p)->rb_left;
+               else if (new->mds > cap->mds)
+                       p = &(*p)->rb_right;
+               else
+                       BUG();
+       }
+
+       rb_link_node(&new->ci_node, parent, p);
+       rb_insert_color(&new->ci_node, &ci->i_caps);
+}
+
+/*
+ * (re)set cap hold timeouts, which control the delayed release
+ * of unused caps back to the MDS.  Should be called on cap use.
+ */
+static void __cap_set_timeouts(struct ceph_mds_client *mdsc,
+                              struct ceph_inode_info *ci)
+{
+       struct ceph_mount_args *ma = mdsc->client->mount_args;
+
+       ci->i_hold_caps_min = round_jiffies(jiffies +
+                                           ma->caps_wanted_delay_min * HZ);
+       ci->i_hold_caps_max = round_jiffies(jiffies +
+                                           ma->caps_wanted_delay_max * HZ);
+       dout("__cap_set_timeouts %p min %lu max %lu\n", &ci->vfs_inode,
+            ci->i_hold_caps_min - jiffies, ci->i_hold_caps_max - jiffies);
+}
+
+/*
+ * (Re)queue cap at the end of the delayed cap release list.
+ *
+ * If I_FLUSH is set, leave the inode at the front of the list.
+ *
+ * Caller holds i_lock
+ *    -> we take mdsc->cap_delay_lock
+ */
+static void __cap_delay_requeue(struct ceph_mds_client *mdsc,
+                               struct ceph_inode_info *ci)
+{
+       __cap_set_timeouts(mdsc, ci);
+       dout("__cap_delay_requeue %p flags %d at %lu\n", &ci->vfs_inode,
+            ci->i_ceph_flags, ci->i_hold_caps_max);
+       if (!mdsc->stopping) {
+               spin_lock(&mdsc->cap_delay_lock);
+               if (!list_empty(&ci->i_cap_delay_list)) {
+                       if (ci->i_ceph_flags & CEPH_I_FLUSH)
+                               goto no_change;
+                       list_del_init(&ci->i_cap_delay_list);
+               }
+               list_add_tail(&ci->i_cap_delay_list, &mdsc->cap_delay_list);
+no_change:
+               spin_unlock(&mdsc->cap_delay_lock);
+       }
+}
+
+/*
+ * Queue an inode for immediate writeback.  Mark inode with I_FLUSH,
+ * indicating we should send a cap message to flush dirty metadata
+ * asap, and move to the front of the delayed cap list.
+ */
+static void __cap_delay_requeue_front(struct ceph_mds_client *mdsc,
+                                     struct ceph_inode_info *ci)
+{
+       dout("__cap_delay_requeue_front %p\n", &ci->vfs_inode);
+       spin_lock(&mdsc->cap_delay_lock);
+       ci->i_ceph_flags |= CEPH_I_FLUSH;
+       if (!list_empty(&ci->i_cap_delay_list))
+               list_del_init(&ci->i_cap_delay_list);
+       list_add(&ci->i_cap_delay_list, &mdsc->cap_delay_list);
+       spin_unlock(&mdsc->cap_delay_lock);
+}
+
+/*
+ * Cancel delayed work on cap.
+ *
+ * Caller must hold i_lock.
+ */
+static void __cap_delay_cancel(struct ceph_mds_client *mdsc,
+                              struct ceph_inode_info *ci)
+{
+       dout("__cap_delay_cancel %p\n", &ci->vfs_inode);
+       if (list_empty(&ci->i_cap_delay_list))
+               return;
+       spin_lock(&mdsc->cap_delay_lock);
+       list_del_init(&ci->i_cap_delay_list);
+       spin_unlock(&mdsc->cap_delay_lock);
+}
+
+/*
+ * Common issue checks for add_cap, handle_cap_grant.
+ */
+static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap,
+                             unsigned issued)
+{
+       unsigned had = __ceph_caps_issued(ci, NULL);
+
+       /*
+        * Each time we receive FILE_CACHE anew, we increment
+        * i_rdcache_gen.
+        */
+       if ((issued & CEPH_CAP_FILE_CACHE) &&
+           (had & CEPH_CAP_FILE_CACHE) == 0)
+               ci->i_rdcache_gen++;
+
+       /*
+        * if we are newly issued FILE_SHARED, clear I_COMPLETE; we
+        * don't know what happened to this directory while we didn't
+        * have the cap.
+        */
+       if ((issued & CEPH_CAP_FILE_SHARED) &&
+           (had & CEPH_CAP_FILE_SHARED) == 0) {
+               ci->i_shared_gen++;
+               if (S_ISDIR(ci->vfs_inode.i_mode)) {
+                       dout(" marking %p NOT complete\n", &ci->vfs_inode);
+                       ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
+               }
+       }
+}
+
+/*
+ * Add a capability under the given MDS session.
+ *
+ * Caller should hold session snap_rwsem (read) and s_mutex.
+ *
+ * @fmode is the open file mode, if we are opening a file, otherwise
+ * it is < 0.  (This is so we can atomically add the cap and add an
+ * open file reference to it.)
+ */
+int ceph_add_cap(struct inode *inode,
+                struct ceph_mds_session *session, u64 cap_id,
+                int fmode, unsigned issued, unsigned wanted,
+                unsigned seq, unsigned mseq, u64 realmino, int flags,
+                struct ceph_cap_reservation *caps_reservation)
+{
+       struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_cap *new_cap = NULL;
+       struct ceph_cap *cap;
+       int mds = session->s_mds;
+       int actual_wanted;
+
+       dout("add_cap %p mds%d cap %llx %s seq %d\n", inode,
+            session->s_mds, cap_id, ceph_cap_string(issued), seq);
+
+       /*
+        * If we are opening the file, include file mode wanted bits
+        * in wanted.
+        */
+       if (fmode >= 0)
+               wanted |= ceph_caps_for_mode(fmode);
+
+retry:
+       spin_lock(&inode->i_lock);
+       cap = __get_cap_for_mds(ci, mds);
+       if (!cap) {
+               if (new_cap) {
+                       cap = new_cap;
+                       new_cap = NULL;
+               } else {
+                       spin_unlock(&inode->i_lock);
+                       new_cap = get_cap(caps_reservation);
+                       if (new_cap == NULL)
+                               return -ENOMEM;
+                       goto retry;
+               }
+
+               cap->issued = 0;
+               cap->implemented = 0;
+               cap->mds = mds;
+               cap->mds_wanted = 0;
+
+               cap->ci = ci;
+               __insert_cap_node(ci, cap);
+
+               /* clear out old exporting info?  (i.e. on cap import) */
+               if (ci->i_cap_exporting_mds == mds) {
+                       ci->i_cap_exporting_issued = 0;
+                       ci->i_cap_exporting_mseq = 0;
+                       ci->i_cap_exporting_mds = -1;
+               }
+
+               /* add to session cap list */
+               cap->session = session;
+               spin_lock(&session->s_cap_lock);
+               list_add_tail(&cap->session_caps, &session->s_caps);
+               session->s_nr_caps++;
+               spin_unlock(&session->s_cap_lock);
+       }
+
+       if (!ci->i_snap_realm) {
+               /*
+                * add this inode to the appropriate snap realm
+                */
+               struct ceph_snap_realm *realm = ceph_lookup_snap_realm(mdsc,
+                                                              realmino);
+               if (realm) {
+                       ceph_get_snap_realm(mdsc, realm);
+                       spin_lock(&realm->inodes_with_caps_lock);
+                       ci->i_snap_realm = realm;
+                       list_add(&ci->i_snap_realm_item,
+                                &realm->inodes_with_caps);
+                       spin_unlock(&realm->inodes_with_caps_lock);
+               } else {
+                       pr_err("ceph_add_cap: couldn't find snap realm %llx\n",
+                              realmino);
+               }
+       }
+
+       __check_cap_issue(ci, cap, issued);
+
+       /*
+        * If we are issued caps we don't want, or the mds' wanted
+        * value appears to be off, queue a check so we'll release
+        * later and/or update the mds wanted value.
+        */
+       actual_wanted = __ceph_caps_wanted(ci);
+       if ((wanted & ~actual_wanted) ||
+           (issued & ~actual_wanted & CEPH_CAP_ANY_WR)) {
+               dout(" issued %s, mds wanted %s, actual %s, queueing\n",
+                    ceph_cap_string(issued), ceph_cap_string(wanted),
+                    ceph_cap_string(actual_wanted));
+               __cap_delay_requeue(mdsc, ci);
+       }
+
+       if (flags & CEPH_CAP_FLAG_AUTH)
+               ci->i_auth_cap = cap;
+       else if (ci->i_auth_cap == cap)
+               ci->i_auth_cap = NULL;
+
+       dout("add_cap inode %p (%llx.%llx) cap %p %s now %s seq %d mds%d\n",
+            inode, ceph_vinop(inode), cap, ceph_cap_string(issued),
+            ceph_cap_string(issued|cap->issued), seq, mds);
+       cap->cap_id = cap_id;
+       cap->issued = issued;
+       cap->implemented |= issued;
+       cap->mds_wanted |= wanted;
+       cap->seq = seq;
+       cap->issue_seq = seq;
+       cap->mseq = mseq;
+       cap->cap_gen = session->s_cap_gen;
+
+       if (fmode >= 0)
+               __ceph_get_fmode(ci, fmode);
+       spin_unlock(&inode->i_lock);
+       wake_up(&ci->i_cap_wq);
+       return 0;
+}
+
+/*
+ * Return true if cap has not timed out and belongs to the current
+ * generation of the MDS session (i.e. has not gone 'stale' due to
+ * us losing touch with the mds).
+ */
+static int __cap_is_valid(struct ceph_cap *cap)
+{
+       unsigned long ttl;
+       u32 gen;
+
+       spin_lock(&cap->session->s_cap_lock);
+       gen = cap->session->s_cap_gen;
+       ttl = cap->session->s_cap_ttl;
+       spin_unlock(&cap->session->s_cap_lock);
+
+       if (cap->cap_gen < gen || time_after_eq(jiffies, ttl)) {
+               dout("__cap_is_valid %p cap %p issued %s "
+                    "but STALE (gen %u vs %u)\n", &cap->ci->vfs_inode,
+                    cap, ceph_cap_string(cap->issued), cap->cap_gen, gen);
+               return 0;
+       }
+
+       return 1;
+}
+
+/*
+ * Return set of valid cap bits issued to us.  Note that caps time
+ * out, and may be invalidated in bulk if the client session times out
+ * and session->s_cap_gen is bumped.
+ */
+int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented)
+{
+       int have = ci->i_snap_caps | ci->i_cap_exporting_issued;
+       struct ceph_cap *cap;
+       struct rb_node *p;
+
+       if (implemented)
+               *implemented = 0;
+       for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+               cap = rb_entry(p, struct ceph_cap, ci_node);
+               if (!__cap_is_valid(cap))
+                       continue;
+               dout("__ceph_caps_issued %p cap %p issued %s\n",
+                    &ci->vfs_inode, cap, ceph_cap_string(cap->issued));
+               have |= cap->issued;
+               if (implemented)
+                       *implemented |= cap->implemented;
+       }
+       return have;
+}
+
+/*
+ * Get cap bits issued by caps other than @ocap
+ */
+int __ceph_caps_issued_other(struct ceph_inode_info *ci, struct ceph_cap *ocap)
+{
+       int have = ci->i_snap_caps;
+       struct ceph_cap *cap;
+       struct rb_node *p;
+
+       for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+               cap = rb_entry(p, struct ceph_cap, ci_node);
+               if (cap == ocap)
+                       continue;
+               if (!__cap_is_valid(cap))
+                       continue;
+               have |= cap->issued;
+       }
+       return have;
+}
+
+/*
+ * Move a cap to the end of the LRU (oldest caps at list head, newest
+ * at list tail).
+ */
+static void __touch_cap(struct ceph_cap *cap)
+{
+       struct ceph_mds_session *s = cap->session;
+
+       spin_lock(&s->s_cap_lock);
+       if (s->s_cap_iterator == NULL) {
+               dout("__touch_cap %p cap %p mds%d\n", &cap->ci->vfs_inode, cap,
+                    s->s_mds);
+               list_move_tail(&cap->session_caps, &s->s_caps);
+       } else {
+               dout("__touch_cap %p cap %p mds%d NOP, iterating over caps\n",
+                    &cap->ci->vfs_inode, cap, s->s_mds);
+       }
+       spin_unlock(&s->s_cap_lock);
+}
+
+/*
+ * Check if we hold the given mask.  If so, move the cap(s) to the
+ * front of their respective LRUs.  (This is the preferred way for
+ * callers to check for caps they want.)
+ */
+int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
+{
+       struct ceph_cap *cap;
+       struct rb_node *p;
+       int have = ci->i_snap_caps;
+
+       if ((have & mask) == mask) {
+               dout("__ceph_caps_issued_mask %p snap issued %s"
+                    " (mask %s)\n", &ci->vfs_inode,
+                    ceph_cap_string(have),
+                    ceph_cap_string(mask));
+               return 1;
+       }
+
+       for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+               cap = rb_entry(p, struct ceph_cap, ci_node);
+               if (!__cap_is_valid(cap))
+                       continue;
+               if ((cap->issued & mask) == mask) {
+                       dout("__ceph_caps_issued_mask %p cap %p issued %s"
+                            " (mask %s)\n", &ci->vfs_inode, cap,
+                            ceph_cap_string(cap->issued),
+                            ceph_cap_string(mask));
+                       if (touch)
+                               __touch_cap(cap);
+                       return 1;
+               }
+
+               /* does a combination of caps satisfy mask? */
+               have |= cap->issued;
+               if ((have & mask) == mask) {
+                       dout("__ceph_caps_issued_mask %p combo issued %s"
+                            " (mask %s)\n", &ci->vfs_inode,
+                            ceph_cap_string(cap->issued),
+                            ceph_cap_string(mask));
+                       if (touch) {
+                               struct rb_node *q;
+
+                               /* touch this + preceeding caps */
+                               __touch_cap(cap);
+                               for (q = rb_first(&ci->i_caps); q != p;
+                                    q = rb_next(q)) {
+                                       cap = rb_entry(q, struct ceph_cap,
+                                                      ci_node);
+                                       if (!__cap_is_valid(cap))
+                                               continue;
+                                       __touch_cap(cap);
+                               }
+                       }
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Return true if mask caps are currently being revoked by an MDS.
+ */
+int ceph_caps_revoking(struct ceph_inode_info *ci, int mask)
+{
+       struct inode *inode = &ci->vfs_inode;
+       struct ceph_cap *cap;
+       struct rb_node *p;
+       int ret = 0;
+
+       spin_lock(&inode->i_lock);
+       for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+               cap = rb_entry(p, struct ceph_cap, ci_node);
+               if (__cap_is_valid(cap) &&
+                   (cap->implemented & ~cap->issued & mask)) {
+                       ret = 1;
+                       break;
+               }
+       }
+       spin_unlock(&inode->i_lock);
+       dout("ceph_caps_revoking %p %s = %d\n", inode,
+            ceph_cap_string(mask), ret);
+       return ret;
+}
+
+int __ceph_caps_used(struct ceph_inode_info *ci)
+{
+       int used = 0;
+       if (ci->i_pin_ref)
+               used |= CEPH_CAP_PIN;
+       if (ci->i_rd_ref)
+               used |= CEPH_CAP_FILE_RD;
+       if (ci->i_rdcache_ref || ci->i_rdcache_gen)
+               used |= CEPH_CAP_FILE_CACHE;
+       if (ci->i_wr_ref)
+               used |= CEPH_CAP_FILE_WR;
+       if (ci->i_wrbuffer_ref)
+               used |= CEPH_CAP_FILE_BUFFER;
+       return used;
+}
+
+/*
+ * wanted, by virtue of open file modes
+ */
+int __ceph_caps_file_wanted(struct ceph_inode_info *ci)
+{
+       int want = 0;
+       int mode;
+       for (mode = 0; mode < 4; mode++)
+               if (ci->i_nr_by_mode[mode])
+                       want |= ceph_caps_for_mode(mode);
+       return want;
+}
+
+/*
+ * Return caps we have registered with the MDS(s) as 'wanted'.
+ */
+int __ceph_caps_mds_wanted(struct ceph_inode_info *ci)
+{
+       struct ceph_cap *cap;
+       struct rb_node *p;
+       int mds_wanted = 0;
+
+       for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+               cap = rb_entry(p, struct ceph_cap, ci_node);
+               if (!__cap_is_valid(cap))
+                       continue;
+               mds_wanted |= cap->mds_wanted;
+       }
+       return mds_wanted;
+}
+
+/*
+ * called under i_lock
+ */
+static int __ceph_is_any_caps(struct ceph_inode_info *ci)
+{
+       return !RB_EMPTY_ROOT(&ci->i_caps) || ci->i_cap_exporting_mds >= 0;
+}
+
+/*
+ * Remove a cap.  Take steps to deal with a racing iterate_session_caps.
+ *
+ * caller should hold i_lock.
+ * caller will not hold session s_mutex if called from destroy_inode.
+ */
+void __ceph_remove_cap(struct ceph_cap *cap)
+{
+       struct ceph_mds_session *session = cap->session;
+       struct ceph_inode_info *ci = cap->ci;
+       struct ceph_mds_client *mdsc = &ceph_client(ci->vfs_inode.i_sb)->mdsc;
+       int removed = 0;
+
+       dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode);
+
+       /* remove from session list */
+       spin_lock(&session->s_cap_lock);
+       if (session->s_cap_iterator == cap) {
+               /* not yet, we are iterating over this very cap */
+               dout("__ceph_remove_cap  delaying %p removal from session %p\n",
+                    cap, cap->session);
+       } else {
+               list_del_init(&cap->session_caps);
+               session->s_nr_caps--;
+               cap->session = NULL;
+               removed = 1;
+       }
+       /* protect backpointer with s_cap_lock: see iterate_session_caps */
+       cap->ci = NULL;
+       spin_unlock(&session->s_cap_lock);
+
+       /* remove from inode list */
+       rb_erase(&cap->ci_node, &ci->i_caps);
+       if (ci->i_auth_cap == cap)
+               ci->i_auth_cap = NULL;
+
+       if (removed)
+               ceph_put_cap(cap);
+
+       if (!__ceph_is_any_caps(ci) && ci->i_snap_realm) {
+               struct ceph_snap_realm *realm = ci->i_snap_realm;
+               spin_lock(&realm->inodes_with_caps_lock);
+               list_del_init(&ci->i_snap_realm_item);
+               ci->i_snap_realm_counter++;
+               ci->i_snap_realm = NULL;
+               spin_unlock(&realm->inodes_with_caps_lock);
+               ceph_put_snap_realm(mdsc, realm);
+       }
+       if (!__ceph_is_any_real_caps(ci))
+               __cap_delay_cancel(mdsc, ci);
+}
+
+/*
+ * Build and send a cap message to the given MDS.
+ *
+ * Caller should be holding s_mutex.
+ */
+static int send_cap_msg(struct ceph_mds_session *session,
+                       u64 ino, u64 cid, int op,
+                       int caps, int wanted, int dirty,
+                       u32 seq, u64 flush_tid, u32 issue_seq, u32 mseq,
+                       u64 size, u64 max_size,
+                       struct timespec *mtime, struct timespec *atime,
+                       u64 time_warp_seq,
+                       uid_t uid, gid_t gid, mode_t mode,
+                       u64 xattr_version,
+                       struct ceph_buffer *xattrs_buf,
+                       u64 follows)
+{
+       struct ceph_mds_caps *fc;
+       struct ceph_msg *msg;
+
+       dout("send_cap_msg %s %llx %llx caps %s wanted %s dirty %s"
+            " seq %u/%u mseq %u follows %lld size %llu/%llu"
+            " xattr_ver %llu xattr_len %d\n", ceph_cap_op_name(op),
+            cid, ino, ceph_cap_string(caps), ceph_cap_string(wanted),
+            ceph_cap_string(dirty),
+            seq, issue_seq, mseq, follows, size, max_size,
+            xattr_version, xattrs_buf ? (int)xattrs_buf->vec.iov_len : 0);
+
+       msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPS, sizeof(*fc), 0, 0, NULL);
+       if (IS_ERR(msg))
+               return PTR_ERR(msg);
+
+       msg->hdr.tid = cpu_to_le64(flush_tid);
+
+       fc = msg->front.iov_base;
+       memset(fc, 0, sizeof(*fc));
+
+       fc->cap_id = cpu_to_le64(cid);
+       fc->op = cpu_to_le32(op);
+       fc->seq = cpu_to_le32(seq);
+       fc->issue_seq = cpu_to_le32(issue_seq);
+       fc->migrate_seq = cpu_to_le32(mseq);
+       fc->caps = cpu_to_le32(caps);
+       fc->wanted = cpu_to_le32(wanted);
+       fc->dirty = cpu_to_le32(dirty);
+       fc->ino = cpu_to_le64(ino);
+       fc->snap_follows = cpu_to_le64(follows);
+
+       fc->size = cpu_to_le64(size);
+       fc->max_size = cpu_to_le64(max_size);
+       if (mtime)
+               ceph_encode_timespec(&fc->mtime, mtime);
+       if (atime)
+               ceph_encode_timespec(&fc->atime, atime);
+       fc->time_warp_seq = cpu_to_le32(time_warp_seq);
+
+       fc->uid = cpu_to_le32(uid);
+       fc->gid = cpu_to_le32(gid);
+       fc->mode = cpu_to_le32(mode);
+
+       fc->xattr_version = cpu_to_le64(xattr_version);
+       if (xattrs_buf) {
+               msg->middle = ceph_buffer_get(xattrs_buf);
+               fc->xattr_len = cpu_to_le32(xattrs_buf->vec.iov_len);
+               msg->hdr.middle_len = cpu_to_le32(xattrs_buf->vec.iov_len);
+       }
+
+       ceph_con_send(&session->s_con, msg);
+       return 0;
+}
+
+/*
+ * Queue cap releases when an inode is dropped from our cache.  Since
+ * inode is about to be destroyed, there is no need for i_lock.
+ */
+void ceph_queue_caps_release(struct inode *inode)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct rb_node *p;
+
+       p = rb_first(&ci->i_caps);
+       while (p) {
+               struct ceph_cap *cap = rb_entry(p, struct ceph_cap, ci_node);
+               struct ceph_mds_session *session = cap->session;
+               struct ceph_msg *msg;
+               struct ceph_mds_cap_release *head;
+               struct ceph_mds_cap_item *item;
+
+               spin_lock(&session->s_cap_lock);
+               BUG_ON(!session->s_num_cap_releases);
+               msg = list_first_entry(&session->s_cap_releases,
+                                      struct ceph_msg, list_head);
+
+               dout(" adding %p release to mds%d msg %p (%d left)\n",
+                    inode, session->s_mds, msg, session->s_num_cap_releases);
+
+               BUG_ON(msg->front.iov_len + sizeof(*item) > PAGE_CACHE_SIZE);
+               head = msg->front.iov_base;
+               head->num = cpu_to_le32(le32_to_cpu(head->num) + 1);
+               item = msg->front.iov_base + msg->front.iov_len;
+               item->ino = cpu_to_le64(ceph_ino(inode));
+               item->cap_id = cpu_to_le64(cap->cap_id);
+               item->migrate_seq = cpu_to_le32(cap->mseq);
+               item->seq = cpu_to_le32(cap->issue_seq);
+
+               session->s_num_cap_releases--;
+
+               msg->front.iov_len += sizeof(*item);
+               if (le32_to_cpu(head->num) == CEPH_CAPS_PER_RELEASE) {
+                       dout(" release msg %p full\n", msg);
+                       list_move_tail(&msg->list_head,
+                                      &session->s_cap_releases_done);
+               } else {
+                       dout(" release msg %p at %d/%d (%d)\n", msg,
+                            (int)le32_to_cpu(head->num),
+                            (int)CEPH_CAPS_PER_RELEASE,
+                            (int)msg->front.iov_len);
+               }
+               spin_unlock(&session->s_cap_lock);
+               p = rb_next(p);
+               __ceph_remove_cap(cap);
+       }
+}
+
+/*
+ * Send a cap msg on the given inode.  Update our caps state, then
+ * drop i_lock and send the message.
+ *
+ * Make note of max_size reported/requested from mds, revoked caps
+ * that have now been implemented.
+ *
+ * Make half-hearted attempt ot to invalidate page cache if we are
+ * dropping RDCACHE.  Note that this will leave behind locked pages
+ * that we'll then need to deal with elsewhere.
+ *
+ * Return non-zero if delayed release, or we experienced an error
+ * such that the caller should requeue + retry later.
+ *
+ * called with i_lock, then drops it.
+ * caller should hold snap_rwsem (read), s_mutex.
+ */
+static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
+                     int op, int used, int want, int retain, int flushing,
+                     unsigned *pflush_tid)
+       __releases(cap->ci->vfs_inode->i_lock)
+{
+       struct ceph_inode_info *ci = cap->ci;
+       struct inode *inode = &ci->vfs_inode;
+       u64 cap_id = cap->cap_id;
+       int held, revoking, dropping, keep;
+       u64 seq, issue_seq, mseq, time_warp_seq, follows;
+       u64 size, max_size;
+       struct timespec mtime, atime;
+       int wake = 0;
+       mode_t mode;
+       uid_t uid;
+       gid_t gid;
+       struct ceph_mds_session *session;
+       u64 xattr_version = 0;
+       int delayed = 0;
+       u64 flush_tid = 0;
+       int i;
+       int ret;
+
+       held = cap->issued | cap->implemented;
+       revoking = cap->implemented & ~cap->issued;
+       retain &= ~revoking;
+       dropping = cap->issued & ~retain;
+
+       dout("__send_cap %p cap %p session %p %s -> %s (revoking %s)\n",
+            inode, cap, cap->session,
+            ceph_cap_string(held), ceph_cap_string(held & retain),
+            ceph_cap_string(revoking));
+       BUG_ON((retain & CEPH_CAP_PIN) == 0);
+
+       session = cap->session;
+
+       /* don't release wanted unless we've waited a bit. */
+       if ((ci->i_ceph_flags & CEPH_I_NODELAY) == 0 &&
+           time_before(jiffies, ci->i_hold_caps_min)) {
+               dout(" delaying issued %s -> %s, wanted %s -> %s on send\n",
+                    ceph_cap_string(cap->issued),
+                    ceph_cap_string(cap->issued & retain),
+                    ceph_cap_string(cap->mds_wanted),
+                    ceph_cap_string(want));
+               want |= cap->mds_wanted;
+               retain |= cap->issued;
+               delayed = 1;
+       }
+       ci->i_ceph_flags &= ~(CEPH_I_NODELAY | CEPH_I_FLUSH);
+
+       cap->issued &= retain;  /* drop bits we don't want */
+       if (cap->implemented & ~cap->issued) {
+               /*
+                * Wake up any waiters on wanted -> needed transition.
+                * This is due to the weird transition from buffered
+                * to sync IO... we need to flush dirty pages _before_
+                * allowing sync writes to avoid reordering.
+                */
+               wake = 1;
+       }
+       cap->implemented &= cap->issued | used;
+       cap->mds_wanted = want;
+
+       if (flushing) {
+               /*
+                * assign a tid for flush operations so we can avoid
+                * flush1 -> dirty1 -> flush2 -> flushack1 -> mark
+                * clean type races.  track latest tid for every bit
+                * so we can handle flush AxFw, flush Fw, and have the
+                * first ack clean Ax.
+                */
+               flush_tid = ++ci->i_cap_flush_last_tid;
+               if (pflush_tid)
+                       *pflush_tid = flush_tid;
+               dout(" cap_flush_tid %d\n", (int)flush_tid);
+               for (i = 0; i < CEPH_CAP_BITS; i++)
+                       if (flushing & (1 << i))
+                               ci->i_cap_flush_tid[i] = flush_tid;
+       }
+
+       keep = cap->implemented;
+       seq = cap->seq;
+       issue_seq = cap->issue_seq;
+       mseq = cap->mseq;
+       size = inode->i_size;
+       ci->i_reported_size = size;
+       max_size = ci->i_wanted_max_size;
+       ci->i_requested_max_size = max_size;
+       mtime = inode->i_mtime;
+       atime = inode->i_atime;
+       time_warp_seq = ci->i_time_warp_seq;
+       follows = ci->i_snap_realm->cached_context->seq;
+       uid = inode->i_uid;
+       gid = inode->i_gid;
+       mode = inode->i_mode;
+
+       if (dropping & CEPH_CAP_XATTR_EXCL) {
+               __ceph_build_xattrs_blob(ci);
+               xattr_version = ci->i_xattrs.version + 1;
+       }
+
+       spin_unlock(&inode->i_lock);
+
+       ret = send_cap_msg(session, ceph_vino(inode).ino, cap_id,
+               op, keep, want, flushing, seq, flush_tid, issue_seq, mseq,
+               size, max_size, &mtime, &atime, time_warp_seq,
+               uid, gid, mode,
+               xattr_version,
+               (flushing & CEPH_CAP_XATTR_EXCL) ? ci->i_xattrs.blob : NULL,
+               follows);
+       if (ret < 0) {
+               dout("error sending cap msg, must requeue %p\n", inode);
+               delayed = 1;
+       }
+
+       if (wake)
+               wake_up(&ci->i_cap_wq);
+
+       return delayed;
+}
+
+/*
+ * When a snapshot is taken, clients accumulate dirty metadata on
+ * inodes with capabilities in ceph_cap_snaps to describe the file
+ * state at the time the snapshot was taken.  This must be flushed
+ * asynchronously back to the MDS once sync writes complete and dirty
+ * data is written out.
+ *
+ * Called under i_lock.  Takes s_mutex as needed.
+ */
+void __ceph_flush_snaps(struct ceph_inode_info *ci,
+                       struct ceph_mds_session **psession)
+{
+       struct inode *inode = &ci->vfs_inode;
+       int mds;
+       struct ceph_cap_snap *capsnap;
+       u32 mseq;
+       struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc;
+       struct ceph_mds_session *session = NULL; /* if session != NULL, we hold
+                                                   session->s_mutex */
+       u64 next_follows = 0;  /* keep track of how far we've gotten through the
+                            i_cap_snaps list, and skip these entries next time
+                            around to avoid an infinite loop */
+
+       if (psession)
+               session = *psession;
+
+       dout("__flush_snaps %p\n", inode);
+retry:
+       list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
+               /* avoid an infiniute loop after retry */
+               if (capsnap->follows < next_follows)
+                       continue;
+               /*
+                * we need to wait for sync writes to complete and for dirty
+                * pages to be written out.
+                */
+               if (capsnap->dirty_pages || capsnap->writing)
+                       continue;
+
+               /*
+                * if cap writeback already occurred, we should have dropped
+                * the capsnap in ceph_put_wrbuffer_cap_refs.
+                */
+               BUG_ON(capsnap->dirty == 0);
+
+               /* pick mds, take s_mutex */
+               mds = __ceph_get_cap_mds(ci, &mseq);
+               if (session && session->s_mds != mds) {
+                       dout("oops, wrong session %p mutex\n", session);
+                       mutex_unlock(&session->s_mutex);
+                       ceph_put_mds_session(session);
+                       session = NULL;
+               }
+               if (!session) {
+                       spin_unlock(&inode->i_lock);
+                       mutex_lock(&mdsc->mutex);
+                       session = __ceph_lookup_mds_session(mdsc, mds);
+                       mutex_unlock(&mdsc->mutex);
+                       if (session) {
+                               dout("inverting session/ino locks on %p\n",
+                                    session);
+                               mutex_lock(&session->s_mutex);
+                       }
+                       /*
+                        * if session == NULL, we raced against a cap
+                        * deletion.  retry, and we'll get a better
+                        * @mds value next time.
+                        */
+                       spin_lock(&inode->i_lock);
+                       goto retry;
+               }
+
+               capsnap->flush_tid = ++ci->i_cap_flush_last_tid;
+               atomic_inc(&capsnap->nref);
+               if (!list_empty(&capsnap->flushing_item))
+                       list_del_init(&capsnap->flushing_item);
+               list_add_tail(&capsnap->flushing_item,
+                             &session->s_cap_snaps_flushing);
+               spin_unlock(&inode->i_lock);
+
+               dout("flush_snaps %p cap_snap %p follows %lld size %llu\n",
+                    inode, capsnap, next_follows, capsnap->size);
+               send_cap_msg(session, ceph_vino(inode).ino, 0,
+                            CEPH_CAP_OP_FLUSHSNAP, capsnap->issued, 0,
+                            capsnap->dirty, 0, capsnap->flush_tid, 0, mseq,
+                            capsnap->size, 0,
+                            &capsnap->mtime, &capsnap->atime,
+                            capsnap->time_warp_seq,
+                            capsnap->uid, capsnap->gid, capsnap->mode,
+                            0, NULL,
+                            capsnap->follows);
+
+               next_follows = capsnap->follows + 1;
+               ceph_put_cap_snap(capsnap);
+
+               spin_lock(&inode->i_lock);
+               goto retry;
+       }
+
+       /* we flushed them all; remove this inode from the queue */
+       spin_lock(&mdsc->snap_flush_lock);
+       list_del_init(&ci->i_snap_flush_item);
+       spin_unlock(&mdsc->snap_flush_lock);
+
+       if (psession)
+               *psession = session;
+       else if (session) {
+               mutex_unlock(&session->s_mutex);
+               ceph_put_mds_session(session);
+       }
+}
+
+static void ceph_flush_snaps(struct ceph_inode_info *ci)
+{
+       struct inode *inode = &ci->vfs_inode;
+
+       spin_lock(&inode->i_lock);
+       __ceph_flush_snaps(ci, NULL);
+       spin_unlock(&inode->i_lock);
+}
+
+/*
+ * Mark caps dirty.  If inode is newly dirty, add to the global dirty
+ * list.
+ */
+void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
+{
+       struct ceph_mds_client *mdsc = &ceph_client(ci->vfs_inode.i_sb)->mdsc;
+       struct inode *inode = &ci->vfs_inode;
+       int was = ci->i_dirty_caps;
+       int dirty = 0;
+
+       dout("__mark_dirty_caps %p %s dirty %s -> %s\n", &ci->vfs_inode,
+            ceph_cap_string(mask), ceph_cap_string(was),
+            ceph_cap_string(was | mask));
+       ci->i_dirty_caps |= mask;
+       if (was == 0) {
+               dout(" inode %p now dirty\n", &ci->vfs_inode);
+               BUG_ON(!list_empty(&ci->i_dirty_item));
+               spin_lock(&mdsc->cap_dirty_lock);
+               list_add(&ci->i_dirty_item, &mdsc->cap_dirty);
+               spin_unlock(&mdsc->cap_dirty_lock);
+               if (ci->i_flushing_caps == 0) {
+                       igrab(inode);
+                       dirty |= I_DIRTY_SYNC;
+               }
+       }
+       BUG_ON(list_empty(&ci->i_dirty_item));
+       if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) &&
+           (mask & CEPH_CAP_FILE_BUFFER))
+               dirty |= I_DIRTY_DATASYNC;
+       if (dirty)
+               __mark_inode_dirty(inode, dirty);
+       __cap_delay_requeue(mdsc, ci);
+}
+
+/*
+ * Add dirty inode to the flushing list.  Assigned a seq number so we
+ * can wait for caps to flush without starving.
+ *
+ * Called under i_lock.
+ */
+static int __mark_caps_flushing(struct inode *inode,
+                                struct ceph_mds_session *session)
+{
+       struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int flushing;
+
+       BUG_ON(ci->i_dirty_caps == 0);
+       BUG_ON(list_empty(&ci->i_dirty_item));
+
+       flushing = ci->i_dirty_caps;
+       dout("__mark_caps_flushing flushing %s, flushing_caps %s -> %s\n",
+            ceph_cap_string(flushing),
+            ceph_cap_string(ci->i_flushing_caps),
+            ceph_cap_string(ci->i_flushing_caps | flushing));
+       ci->i_flushing_caps |= flushing;
+       ci->i_dirty_caps = 0;
+       dout(" inode %p now !dirty\n", inode);
+
+       spin_lock(&mdsc->cap_dirty_lock);
+       list_del_init(&ci->i_dirty_item);
+
+       ci->i_cap_flush_seq = ++mdsc->cap_flush_seq;
+       if (list_empty(&ci->i_flushing_item)) {
+               list_add_tail(&ci->i_flushing_item, &session->s_cap_flushing);
+               mdsc->num_cap_flushing++;
+               dout(" inode %p now flushing seq %lld\n", inode,
+                    ci->i_cap_flush_seq);
+       } else {
+               list_move_tail(&ci->i_flushing_item, &session->s_cap_flushing);
+               dout(" inode %p now flushing (more) seq %lld\n", inode,
+                    ci->i_cap_flush_seq);
+       }
+       spin_unlock(&mdsc->cap_dirty_lock);
+
+       return flushing;
+}
+
+/*
+ * try to invalidate mapping pages without blocking.
+ */
+static int mapping_is_empty(struct address_space *mapping)
+{
+       struct page *page = find_get_page(mapping, 0);
+
+       if (!page)
+               return 1;
+
+       put_page(page);
+       return 0;
+}
+
+static int try_nonblocking_invalidate(struct inode *inode)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       u32 invalidating_gen = ci->i_rdcache_gen;
+
+       spin_unlock(&inode->i_lock);
+       invalidate_mapping_pages(&inode->i_data, 0, -1);
+       spin_lock(&inode->i_lock);
+
+       if (mapping_is_empty(&inode->i_data) &&
+           invalidating_gen == ci->i_rdcache_gen) {
+               /* success. */
+               dout("try_nonblocking_invalidate %p success\n", inode);
+               ci->i_rdcache_gen = 0;
+               ci->i_rdcache_revoking = 0;
+               return 0;
+       }
+       dout("try_nonblocking_invalidate %p failed\n", inode);
+       return -1;
+}
+
+/*
+ * Swiss army knife function to examine currently used and wanted
+ * versus held caps.  Release, flush, ack revoked caps to mds as
+ * appropriate.
+ *
+ *  CHECK_CAPS_NODELAY - caller is delayed work and we should not delay
+ *    cap release further.
+ *  CHECK_CAPS_AUTHONLY - we should only check the auth cap
+ *  CHECK_CAPS_FLUSH - we should flush any dirty caps immediately, without
+ *    further delay.
+ */
+void ceph_check_caps(struct ceph_inode_info *ci, int flags,
+                    struct ceph_mds_session *session)
+       __releases(session->s_mutex)
+{
+       struct ceph_client *client = ceph_inode_to_client(&ci->vfs_inode);
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct inode *inode = &ci->vfs_inode;
+       struct ceph_cap *cap;
+       int file_wanted, used;
+       int took_snap_rwsem = 0;             /* true if mdsc->snap_rwsem held */
+       int issued, implemented, want, retain, revoking, flushing = 0;
+       int mds = -1;   /* keep track of how far we've gone through i_caps list
+                          to avoid an infinite loop on retry */
+       struct rb_node *p;
+       int tried_invalidate = 0;
+       int delayed = 0, sent = 0, force_requeue = 0, num;
+       int queue_invalidate = 0;
+       int is_delayed = flags & CHECK_CAPS_NODELAY;
+
+       /* if we are unmounting, flush any unused caps immediately. */
+       if (mdsc->stopping)
+               is_delayed = 1;
+
+       spin_lock(&inode->i_lock);
+
+       if (ci->i_ceph_flags & CEPH_I_FLUSH)
+               flags |= CHECK_CAPS_FLUSH;
+
+       /* flush snaps first time around only */
+       if (!list_empty(&ci->i_cap_snaps))
+               __ceph_flush_snaps(ci, &session);
+       goto retry_locked;
+retry:
+       spin_lock(&inode->i_lock);
+retry_locked:
+       file_wanted = __ceph_caps_file_wanted(ci);
+       used = __ceph_caps_used(ci);
+       want = file_wanted | used;
+       issued = __ceph_caps_issued(ci, &implemented);
+       revoking = implemented & ~issued;
+
+       retain = want | CEPH_CAP_PIN;
+       if (!mdsc->stopping && inode->i_nlink > 0) {
+               if (want) {
+                       retain |= CEPH_CAP_ANY;       /* be greedy */
+               } else {
+                       retain |= CEPH_CAP_ANY_SHARED;
+                       /*
+                        * keep RD only if we didn't have the file open RW,
+                        * because then the mds would revoke it anyway to
+                        * journal max_size=0.
+                        */
+                       if (ci->i_max_size == 0)
+                               retain |= CEPH_CAP_ANY_RD;
+               }
+       }
+
+       dout("check_caps %p file_want %s used %s dirty %s flushing %s"
+            " issued %s revoking %s retain %s %s%s%s\n", inode,
+            ceph_cap_string(file_wanted),
+            ceph_cap_string(used), ceph_cap_string(ci->i_dirty_caps),
+            ceph_cap_string(ci->i_flushing_caps),
+            ceph_cap_string(issued), ceph_cap_string(revoking),
+            ceph_cap_string(retain),
+            (flags & CHECK_CAPS_AUTHONLY) ? " AUTHONLY" : "",
+            (flags & CHECK_CAPS_NODELAY) ? " NODELAY" : "",
+            (flags & CHECK_CAPS_FLUSH) ? " FLUSH" : "");
+
+       /*
+        * If we no longer need to hold onto old our caps, and we may
+        * have cached pages, but don't want them, then try to invalidate.
+        * If we fail, it's because pages are locked.... try again later.
+        */
+       if ((!is_delayed || mdsc->stopping) &&
+           ci->i_wrbuffer_ref == 0 &&               /* no dirty pages... */
+           ci->i_rdcache_gen &&                     /* may have cached pages */
+           (file_wanted == 0 ||                     /* no open files */
+            (revoking & CEPH_CAP_FILE_CACHE)) &&     /*  or revoking cache */
+           !tried_invalidate) {
+               dout("check_caps trying to invalidate on %p\n", inode);
+               if (try_nonblocking_invalidate(inode) < 0) {
+                       if (revoking & CEPH_CAP_FILE_CACHE) {
+                               dout("check_caps queuing invalidate\n");
+                               queue_invalidate = 1;
+                               ci->i_rdcache_revoking = ci->i_rdcache_gen;
+                       } else {
+                               dout("check_caps failed to invalidate pages\n");
+                               /* we failed to invalidate pages.  check these
+                                  caps again later. */
+                               force_requeue = 1;
+                               __cap_set_timeouts(mdsc, ci);
+                       }
+               }
+               tried_invalidate = 1;
+               goto retry_locked;
+       }
+
+       num = 0;
+       for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+               cap = rb_entry(p, struct ceph_cap, ci_node);
+               num++;
+
+               /* avoid looping forever */
+               if (mds >= cap->mds ||
+                   ((flags & CHECK_CAPS_AUTHONLY) && cap != ci->i_auth_cap))
+                       continue;
+
+               /* NOTE: no side-effects allowed, until we take s_mutex */
+
+               revoking = cap->implemented & ~cap->issued;
+               if (revoking)
+                       dout(" mds%d revoking %s\n", cap->mds,
+                            ceph_cap_string(revoking));
+
+               if (cap == ci->i_auth_cap &&
+                   (cap->issued & CEPH_CAP_FILE_WR)) {
+                       /* request larger max_size from MDS? */
+                       if (ci->i_wanted_max_size > ci->i_max_size &&
+                           ci->i_wanted_max_size > ci->i_requested_max_size) {
+                               dout("requesting new max_size\n");
+                               goto ack;
+                       }
+
+                       /* approaching file_max? */
+                       if ((inode->i_size << 1) >= ci->i_max_size &&
+                           (ci->i_reported_size << 1) < ci->i_max_size) {
+                               dout("i_size approaching max_size\n");
+                               goto ack;
+                       }
+               }
+               /* flush anything dirty? */
+               if (cap == ci->i_auth_cap && (flags & CHECK_CAPS_FLUSH) &&
+                   ci->i_dirty_caps) {
+                       dout("flushing dirty caps\n");
+                       goto ack;
+               }
+
+               /* completed revocation? going down and there are no caps? */
+               if (revoking && (revoking & used) == 0) {
+                       dout("completed revocation of %s\n",
+                            ceph_cap_string(cap->implemented & ~cap->issued));
+                       goto ack;
+               }
+
+               /* want more caps from mds? */
+               if (want & ~(cap->mds_wanted | cap->issued))
+                       goto ack;
+
+               /* things we might delay */
+               if ((cap->issued & ~retain) == 0 &&
+                   cap->mds_wanted == want)
+                       continue;     /* nope, all good */
+
+               if (is_delayed)
+                       goto ack;
+
+               /* delay? */
+               if ((ci->i_ceph_flags & CEPH_I_NODELAY) == 0 &&
+                   time_before(jiffies, ci->i_hold_caps_max)) {
+                       dout(" delaying issued %s -> %s, wanted %s -> %s\n",
+                            ceph_cap_string(cap->issued),
+                            ceph_cap_string(cap->issued & retain),
+                            ceph_cap_string(cap->mds_wanted),
+                            ceph_cap_string(want));
+                       delayed++;
+                       continue;
+               }
+
+ack:
+               if (ci->i_ceph_flags & CEPH_I_NOFLUSH) {
+                       dout(" skipping %p I_NOFLUSH set\n", inode);
+                       continue;
+               }
+
+               if (session && session != cap->session) {
+                       dout("oops, wrong session %p mutex\n", session);
+                       mutex_unlock(&session->s_mutex);
+                       session = NULL;
+               }
+               if (!session) {
+                       session = cap->session;
+                       if (mutex_trylock(&session->s_mutex) == 0) {
+                               dout("inverting session/ino locks on %p\n",
+                                    session);
+                               spin_unlock(&inode->i_lock);
+                               if (took_snap_rwsem) {
+                                       up_read(&mdsc->snap_rwsem);
+                                       took_snap_rwsem = 0;
+                               }
+                               mutex_lock(&session->s_mutex);
+                               goto retry;
+                       }
+               }
+               /* take snap_rwsem after session mutex */
+               if (!took_snap_rwsem) {
+                       if (down_read_trylock(&mdsc->snap_rwsem) == 0) {
+                               dout("inverting snap/in locks on %p\n",
+                                    inode);
+                               spin_unlock(&inode->i_lock);
+                               down_read(&mdsc->snap_rwsem);
+                               took_snap_rwsem = 1;
+                               goto retry;
+                       }
+                       took_snap_rwsem = 1;
+               }
+
+               if (cap == ci->i_auth_cap && ci->i_dirty_caps)
+                       flushing = __mark_caps_flushing(inode, session);
+
+               mds = cap->mds;  /* remember mds, so we don't repeat */
+               sent++;
+
+               /* __send_cap drops i_lock */
+               delayed += __send_cap(mdsc, cap, CEPH_CAP_OP_UPDATE, used, want,
+                                     retain, flushing, NULL);
+               goto retry; /* retake i_lock and restart our cap scan. */
+       }
+
+       /*
+        * Reschedule delayed caps release if we delayed anything,
+        * otherwise cancel.
+        */
+       if (delayed && is_delayed)
+               force_requeue = 1;   /* __send_cap delayed release; requeue */
+       if (!delayed && !is_delayed)
+               __cap_delay_cancel(mdsc, ci);
+       else if (!is_delayed || force_requeue)
+               __cap_delay_requeue(mdsc, ci);
+
+       spin_unlock(&inode->i_lock);
+
+       if (queue_invalidate)
+               ceph_queue_invalidate(inode);
+
+       if (session)
+               mutex_unlock(&session->s_mutex);
+       if (took_snap_rwsem)
+               up_read(&mdsc->snap_rwsem);
+}
+
+/*
+ * Try to flush dirty caps back to the auth mds.
+ */
+static int try_flush_caps(struct inode *inode, struct ceph_mds_session *session,
+                         unsigned *flush_tid)
+{
+       struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int unlock_session = session ? 0 : 1;
+       int flushing = 0;
+
+retry:
+       spin_lock(&inode->i_lock);
+       if (ci->i_ceph_flags & CEPH_I_NOFLUSH) {
+               dout("try_flush_caps skipping %p I_NOFLUSH set\n", inode);
+               goto out;
+       }
+       if (ci->i_dirty_caps && ci->i_auth_cap) {
+               struct ceph_cap *cap = ci->i_auth_cap;
+               int used = __ceph_caps_used(ci);
+               int want = __ceph_caps_wanted(ci);
+               int delayed;
+
+               if (!session) {
+                       spin_unlock(&inode->i_lock);
+                       session = cap->session;
+                       mutex_lock(&session->s_mutex);
+                       goto retry;
+               }
+               BUG_ON(session != cap->session);
+               if (cap->session->s_state < CEPH_MDS_SESSION_OPEN)
+                       goto out;
+
+               flushing = __mark_caps_flushing(inode, session);
+
+               /* __send_cap drops i_lock */
+               delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, used, want,
+                                    cap->issued | cap->implemented, flushing,
+                                    flush_tid);
+               if (!delayed)
+                       goto out_unlocked;
+
+               spin_lock(&inode->i_lock);
+               __cap_delay_requeue(mdsc, ci);
+       }
+out:
+       spin_unlock(&inode->i_lock);
+out_unlocked:
+       if (session && unlock_session)
+               mutex_unlock(&session->s_mutex);
+       return flushing;
+}
+
+/*
+ * Return true if we've flushed caps through the given flush_tid.
+ */
+static int caps_are_flushed(struct inode *inode, unsigned tid)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int dirty, i, ret = 1;
+
+       spin_lock(&inode->i_lock);
+       dirty = __ceph_caps_dirty(ci);
+       for (i = 0; i < CEPH_CAP_BITS; i++)
+               if ((ci->i_flushing_caps & (1 << i)) &&
+                   ci->i_cap_flush_tid[i] <= tid) {
+                       /* still flushing this bit */
+                       ret = 0;
+                       break;
+               }
+       spin_unlock(&inode->i_lock);
+       return ret;
+}
+
+/*
+ * Wait on any unsafe replies for the given inode.  First wait on the
+ * newest request, and make that the upper bound.  Then, if there are
+ * more requests, keep waiting on the oldest as long as it is still older
+ * than the original request.
+ */
+static void sync_write_wait(struct inode *inode)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct list_head *head = &ci->i_unsafe_writes;
+       struct ceph_osd_request *req;
+       u64 last_tid;
+
+       spin_lock(&ci->i_unsafe_lock);
+       if (list_empty(head))
+               goto out;
+
+       /* set upper bound as _last_ entry in chain */
+       req = list_entry(head->prev, struct ceph_osd_request,
+                        r_unsafe_item);
+       last_tid = req->r_tid;
+
+       do {
+               ceph_osdc_get_request(req);
+               spin_unlock(&ci->i_unsafe_lock);
+               dout("sync_write_wait on tid %llu (until %llu)\n",
+                    req->r_tid, last_tid);
+               wait_for_completion(&req->r_safe_completion);
+               spin_lock(&ci->i_unsafe_lock);
+               ceph_osdc_put_request(req);
+
+               /*
+                * from here on look at first entry in chain, since we
+                * only want to wait for anything older than last_tid
+                */
+               if (list_empty(head))
+                       break;
+               req = list_entry(head->next, struct ceph_osd_request,
+                                r_unsafe_item);
+       } while (req->r_tid < last_tid);
+out:
+       spin_unlock(&ci->i_unsafe_lock);
+}
+
+int ceph_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+       struct inode *inode = dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       unsigned flush_tid;
+       int ret;
+       int dirty;
+
+       dout("fsync %p%s\n", inode, datasync ? " datasync" : "");
+       sync_write_wait(inode);
+
+       ret = filemap_write_and_wait(inode->i_mapping);
+       if (ret < 0)
+               return ret;
+
+       dirty = try_flush_caps(inode, NULL, &flush_tid);
+       dout("fsync dirty caps are %s\n", ceph_cap_string(dirty));
+
+       /*
+        * only wait on non-file metadata writeback (the mds
+        * can recover size and mtime, so we don't need to
+        * wait for that)
+        */
+       if (!datasync && (dirty & ~CEPH_CAP_ANY_FILE_WR)) {
+               dout("fsync waiting for flush_tid %u\n", flush_tid);
+               ret = wait_event_interruptible(ci->i_cap_wq,
+                                      caps_are_flushed(inode, flush_tid));
+       }
+
+       dout("fsync %p%s done\n", inode, datasync ? " datasync" : "");
+       return ret;
+}
+
+/*
+ * Flush any dirty caps back to the mds.  If we aren't asked to wait,
+ * queue inode for flush but don't do so immediately, because we can
+ * get by with fewer MDS messages if we wait for data writeback to
+ * complete first.
+ */
+int ceph_write_inode(struct inode *inode, struct writeback_control *wbc)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       unsigned flush_tid;
+       int err = 0;
+       int dirty;
+       int wait = wbc->sync_mode == WB_SYNC_ALL;
+
+       dout("write_inode %p wait=%d\n", inode, wait);
+       if (wait) {
+               dirty = try_flush_caps(inode, NULL, &flush_tid);
+               if (dirty)
+                       err = wait_event_interruptible(ci->i_cap_wq,
+                                      caps_are_flushed(inode, flush_tid));
+       } else {
+               struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc;
+
+               spin_lock(&inode->i_lock);
+               if (__ceph_caps_dirty(ci))
+                       __cap_delay_requeue_front(mdsc, ci);
+               spin_unlock(&inode->i_lock);
+       }
+       return err;
+}
+
+/*
+ * After a recovering MDS goes active, we need to resend any caps
+ * we were flushing.
+ *
+ * Caller holds session->s_mutex.
+ */
+static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc,
+                                  struct ceph_mds_session *session)
+{
+       struct ceph_cap_snap *capsnap;
+
+       dout("kick_flushing_capsnaps mds%d\n", session->s_mds);
+       list_for_each_entry(capsnap, &session->s_cap_snaps_flushing,
+                           flushing_item) {
+               struct ceph_inode_info *ci = capsnap->ci;
+               struct inode *inode = &ci->vfs_inode;
+               struct ceph_cap *cap;
+
+               spin_lock(&inode->i_lock);
+               cap = ci->i_auth_cap;
+               if (cap && cap->session == session) {
+                       dout("kick_flushing_caps %p cap %p capsnap %p\n", inode,
+                            cap, capsnap);
+                       __ceph_flush_snaps(ci, &session);
+               } else {
+                       pr_err("%p auth cap %p not mds%d ???\n", inode,
+                              cap, session->s_mds);
+               }
+               spin_unlock(&inode->i_lock);
+       }
+}
+
+void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,
+                            struct ceph_mds_session *session)
+{
+       struct ceph_inode_info *ci;
+
+       kick_flushing_capsnaps(mdsc, session);
+
+       dout("kick_flushing_caps mds%d\n", session->s_mds);
+       list_for_each_entry(ci, &session->s_cap_flushing, i_flushing_item) {
+               struct inode *inode = &ci->vfs_inode;
+               struct ceph_cap *cap;
+               int delayed = 0;
+
+               spin_lock(&inode->i_lock);
+               cap = ci->i_auth_cap;
+               if (cap && cap->session == session) {
+                       dout("kick_flushing_caps %p cap %p %s\n", inode,
+                            cap, ceph_cap_string(ci->i_flushing_caps));
+                       delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH,
+                                            __ceph_caps_used(ci),
+                                            __ceph_caps_wanted(ci),
+                                            cap->issued | cap->implemented,
+                                            ci->i_flushing_caps, NULL);
+                       if (delayed) {
+                               spin_lock(&inode->i_lock);
+                               __cap_delay_requeue(mdsc, ci);
+                               spin_unlock(&inode->i_lock);
+                       }
+               } else {
+                       pr_err("%p auth cap %p not mds%d ???\n", inode,
+                              cap, session->s_mds);
+                       spin_unlock(&inode->i_lock);
+               }
+       }
+}
+
+
+/*
+ * Take references to capabilities we hold, so that we don't release
+ * them to the MDS prematurely.
+ *
+ * Protected by i_lock.
+ */
+static void __take_cap_refs(struct ceph_inode_info *ci, int got)
+{
+       if (got & CEPH_CAP_PIN)
+               ci->i_pin_ref++;
+       if (got & CEPH_CAP_FILE_RD)
+               ci->i_rd_ref++;
+       if (got & CEPH_CAP_FILE_CACHE)
+               ci->i_rdcache_ref++;
+       if (got & CEPH_CAP_FILE_WR)
+               ci->i_wr_ref++;
+       if (got & CEPH_CAP_FILE_BUFFER) {
+               if (ci->i_wrbuffer_ref == 0)
+                       igrab(&ci->vfs_inode);
+               ci->i_wrbuffer_ref++;
+               dout("__take_cap_refs %p wrbuffer %d -> %d (?)\n",
+                    &ci->vfs_inode, ci->i_wrbuffer_ref-1, ci->i_wrbuffer_ref);
+       }
+}
+
+/*
+ * Try to grab cap references.  Specify those refs we @want, and the
+ * minimal set we @need.  Also include the larger offset we are writing
+ * to (when applicable), and check against max_size here as well.
+ * Note that caller is responsible for ensuring max_size increases are
+ * requested from the MDS.
+ */
+static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want,
+                           int *got, loff_t endoff, int *check_max, int *err)
+{
+       struct inode *inode = &ci->vfs_inode;
+       int ret = 0;
+       int have, implemented;
+       int file_wanted;
+
+       dout("get_cap_refs %p need %s want %s\n", inode,
+            ceph_cap_string(need), ceph_cap_string(want));
+       spin_lock(&inode->i_lock);
+
+       /* make sure file is actually open */
+       file_wanted = __ceph_caps_file_wanted(ci);
+       if ((file_wanted & need) == 0) {
+               dout("try_get_cap_refs need %s file_wanted %s, EBADF\n",
+                    ceph_cap_string(need), ceph_cap_string(file_wanted));
+               *err = -EBADF;
+               ret = 1;
+               goto out;
+       }
+
+       if (need & CEPH_CAP_FILE_WR) {
+               if (endoff >= 0 && endoff > (loff_t)ci->i_max_size) {
+                       dout("get_cap_refs %p endoff %llu > maxsize %llu\n",
+                            inode, endoff, ci->i_max_size);
+                       if (endoff > ci->i_wanted_max_size) {
+                               *check_max = 1;
+                               ret = 1;
+                       }
+                       goto out;
+               }
+               /*
+                * If a sync write is in progress, we must wait, so that we
+                * can get a final snapshot value for size+mtime.
+                */
+               if (__ceph_have_pending_cap_snap(ci)) {
+                       dout("get_cap_refs %p cap_snap_pending\n", inode);
+                       goto out;
+               }
+       }
+       have = __ceph_caps_issued(ci, &implemented);
+
+       /*
+        * disallow writes while a truncate is pending
+        */
+       if (ci->i_truncate_pending)
+               have &= ~CEPH_CAP_FILE_WR;
+
+       if ((have & need) == need) {
+               /*
+                * Look at (implemented & ~have & not) so that we keep waiting
+                * on transition from wanted -> needed caps.  This is needed
+                * for WRBUFFER|WR -> WR to avoid a new WR sync write from
+                * going before a prior buffered writeback happens.
+                */
+               int not = want & ~(have & need);
+               int revoking = implemented & ~have;
+               dout("get_cap_refs %p have %s but not %s (revoking %s)\n",
+                    inode, ceph_cap_string(have), ceph_cap_string(not),
+                    ceph_cap_string(revoking));
+               if ((revoking & not) == 0) {
+                       *got = need | (have & want);
+                       __take_cap_refs(ci, *got);
+                       ret = 1;
+               }
+       } else {
+               dout("get_cap_refs %p have %s needed %s\n", inode,
+                    ceph_cap_string(have), ceph_cap_string(need));
+       }
+out:
+       spin_unlock(&inode->i_lock);
+       dout("get_cap_refs %p ret %d got %s\n", inode,
+            ret, ceph_cap_string(*got));
+       return ret;
+}
+
+/*
+ * Check the offset we are writing up to against our current
+ * max_size.  If necessary, tell the MDS we want to write to
+ * a larger offset.
+ */
+static void check_max_size(struct inode *inode, loff_t endoff)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int check = 0;
+
+       /* do we need to explicitly request a larger max_size? */
+       spin_lock(&inode->i_lock);
+       if ((endoff >= ci->i_max_size ||
+            endoff > (inode->i_size << 1)) &&
+           endoff > ci->i_wanted_max_size) {
+               dout("write %p at large endoff %llu, req max_size\n",
+                    inode, endoff);
+               ci->i_wanted_max_size = endoff;
+               check = 1;
+       }
+       spin_unlock(&inode->i_lock);
+       if (check)
+               ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
+}
+
+/*
+ * Wait for caps, and take cap references.  If we can't get a WR cap
+ * due to a small max_size, make sure we check_max_size (and possibly
+ * ask the mds) so we don't get hung up indefinitely.
+ */
+int ceph_get_caps(struct ceph_inode_info *ci, int need, int want, int *got,
+                 loff_t endoff)
+{
+       int check_max, ret, err;
+
+retry:
+       if (endoff > 0)
+               check_max_size(&ci->vfs_inode, endoff);
+       check_max = 0;
+       err = 0;
+       ret = wait_event_interruptible(ci->i_cap_wq,
+                                      try_get_cap_refs(ci, need, want,
+                                                       got, endoff,
+                                                       &check_max, &err));
+       if (err)
+               ret = err;
+       if (check_max)
+               goto retry;
+       return ret;
+}
+
+/*
+ * Take cap refs.  Caller must already know we hold at least one ref
+ * on the caps in question or we don't know this is safe.
+ */
+void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps)
+{
+       spin_lock(&ci->vfs_inode.i_lock);
+       __take_cap_refs(ci, caps);
+       spin_unlock(&ci->vfs_inode.i_lock);
+}
+
+/*
+ * Release cap refs.
+ *
+ * If we released the last ref on any given cap, call ceph_check_caps
+ * to release (or schedule a release).
+ *
+ * If we are releasing a WR cap (from a sync write), finalize any affected
+ * cap_snap, and wake up any waiters.
+ */
+void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
+{
+       struct inode *inode = &ci->vfs_inode;
+       int last = 0, put = 0, flushsnaps = 0, wake = 0;
+       struct ceph_cap_snap *capsnap;
+
+       spin_lock(&inode->i_lock);
+       if (had & CEPH_CAP_PIN)
+               --ci->i_pin_ref;
+       if (had & CEPH_CAP_FILE_RD)
+               if (--ci->i_rd_ref == 0)
+                       last++;
+       if (had & CEPH_CAP_FILE_CACHE)
+               if (--ci->i_rdcache_ref == 0)
+                       last++;
+       if (had & CEPH_CAP_FILE_BUFFER) {
+               if (--ci->i_wrbuffer_ref == 0) {
+                       last++;
+                       put++;
+               }
+               dout("put_cap_refs %p wrbuffer %d -> %d (?)\n",
+                    inode, ci->i_wrbuffer_ref+1, ci->i_wrbuffer_ref);
+       }
+       if (had & CEPH_CAP_FILE_WR)
+               if (--ci->i_wr_ref == 0) {
+                       last++;
+                       if (!list_empty(&ci->i_cap_snaps)) {
+                               capsnap = list_first_entry(&ci->i_cap_snaps,
+                                                    struct ceph_cap_snap,
+                                                    ci_item);
+                               if (capsnap->writing) {
+                                       capsnap->writing = 0;
+                                       flushsnaps =
+                                               __ceph_finish_cap_snap(ci,
+                                                                      capsnap);
+                                       wake = 1;
+                               }
+                       }
+               }
+       spin_unlock(&inode->i_lock);
+
+       dout("put_cap_refs %p had %s%s%s\n", inode, ceph_cap_string(had),
+            last ? " last" : "", put ? " put" : "");
+
+       if (last && !flushsnaps)
+               ceph_check_caps(ci, 0, NULL);
+       else if (flushsnaps)
+               ceph_flush_snaps(ci);
+       if (wake)
+               wake_up(&ci->i_cap_wq);
+       if (put)
+               iput(inode);
+}
+
+/*
+ * Release @nr WRBUFFER refs on dirty pages for the given @snapc snap
+ * context.  Adjust per-snap dirty page accounting as appropriate.
+ * Once all dirty data for a cap_snap is flushed, flush snapped file
+ * metadata back to the MDS.  If we dropped the last ref, call
+ * ceph_check_caps.
+ */
+void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
+                               struct ceph_snap_context *snapc)
+{
+       struct inode *inode = &ci->vfs_inode;
+       int last = 0;
+       int complete_capsnap = 0;
+       int drop_capsnap = 0;
+       int found = 0;
+       struct ceph_cap_snap *capsnap = NULL;
+
+       spin_lock(&inode->i_lock);
+       ci->i_wrbuffer_ref -= nr;
+       last = !ci->i_wrbuffer_ref;
+
+       if (ci->i_head_snapc == snapc) {
+               ci->i_wrbuffer_ref_head -= nr;
+               if (!ci->i_wrbuffer_ref_head) {
+                       ceph_put_snap_context(ci->i_head_snapc);
+                       ci->i_head_snapc = NULL;
+               }
+               dout("put_wrbuffer_cap_refs on %p head %d/%d -> %d/%d %s\n",
+                    inode,
+                    ci->i_wrbuffer_ref+nr, ci->i_wrbuffer_ref_head+nr,
+                    ci->i_wrbuffer_ref, ci->i_wrbuffer_ref_head,
+                    last ? " LAST" : "");
+       } else {
+               list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
+                       if (capsnap->context == snapc) {
+                               found = 1;
+                               break;
+                       }
+               }
+               BUG_ON(!found);
+               capsnap->dirty_pages -= nr;
+               if (capsnap->dirty_pages == 0) {
+                       complete_capsnap = 1;
+                       if (capsnap->dirty == 0)
+                               /* cap writeback completed before we created
+                                * the cap_snap; no FLUSHSNAP is needed */
+                               drop_capsnap = 1;
+               }
+               dout("put_wrbuffer_cap_refs on %p cap_snap %p "
+                    " snap %lld %d/%d -> %d/%d %s%s%s\n",
+                    inode, capsnap, capsnap->context->seq,
+                    ci->i_wrbuffer_ref+nr, capsnap->dirty_pages + nr,
+                    ci->i_wrbuffer_ref, capsnap->dirty_pages,
+                    last ? " (wrbuffer last)" : "",
+                    complete_capsnap ? " (complete capsnap)" : "",
+                    drop_capsnap ? " (drop capsnap)" : "");
+               if (drop_capsnap) {
+                       ceph_put_snap_context(capsnap->context);
+                       list_del(&capsnap->ci_item);
+                       list_del(&capsnap->flushing_item);
+                       ceph_put_cap_snap(capsnap);
+               }
+       }
+
+       spin_unlock(&inode->i_lock);
+
+       if (last) {
+               ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
+               iput(inode);
+       } else if (complete_capsnap) {
+               ceph_flush_snaps(ci);
+               wake_up(&ci->i_cap_wq);
+       }
+       if (drop_capsnap)
+               iput(inode);
+}
+
+/*
+ * Handle a cap GRANT message from the MDS.  (Note that a GRANT may
+ * actually be a revocation if it specifies a smaller cap set.)
+ *
+ * caller holds s_mutex and i_lock, we drop both.
+ *
+ * return value:
+ *  0 - ok
+ *  1 - check_caps on auth cap only (writeback)
+ *  2 - check_caps (ack revoke)
+ */
+static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
+                            struct ceph_mds_session *session,
+                            struct ceph_cap *cap,
+                            struct ceph_buffer *xattr_buf)
+       __releases(inode->i_lock)
+       __releases(session->s_mutex)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int mds = session->s_mds;
+       int seq = le32_to_cpu(grant->seq);
+       int newcaps = le32_to_cpu(grant->caps);
+       int issued, implemented, used, wanted, dirty;
+       u64 size = le64_to_cpu(grant->size);
+       u64 max_size = le64_to_cpu(grant->max_size);
+       struct timespec mtime, atime, ctime;
+       int check_caps = 0;
+       int wake = 0;
+       int writeback = 0;
+       int revoked_rdcache = 0;
+       int queue_invalidate = 0;
+
+       dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n",
+            inode, cap, mds, seq, ceph_cap_string(newcaps));
+       dout(" size %llu max_size %llu, i_size %llu\n", size, max_size,
+               inode->i_size);
+
+       /*
+        * If CACHE is being revoked, and we have no dirty buffers,
+        * try to invalidate (once).  (If there are dirty buffers, we
+        * will invalidate _after_ writeback.)
+        */
+       if (((cap->issued & ~newcaps) & CEPH_CAP_FILE_CACHE) &&
+           !ci->i_wrbuffer_ref) {
+               if (try_nonblocking_invalidate(inode) == 0) {
+                       revoked_rdcache = 1;
+               } else {
+                       /* there were locked pages.. invalidate later
+                          in a separate thread. */
+                       if (ci->i_rdcache_revoking != ci->i_rdcache_gen) {
+                               queue_invalidate = 1;
+                               ci->i_rdcache_revoking = ci->i_rdcache_gen;
+                       }
+               }
+       }
+
+       /* side effects now are allowed */
+
+       issued = __ceph_caps_issued(ci, &implemented);
+       issued |= implemented | __ceph_caps_dirty(ci);
+
+       cap->cap_gen = session->s_cap_gen;
+
+       __check_cap_issue(ci, cap, newcaps);
+
+       if ((issued & CEPH_CAP_AUTH_EXCL) == 0) {
+               inode->i_mode = le32_to_cpu(grant->mode);
+               inode->i_uid = le32_to_cpu(grant->uid);
+               inode->i_gid = le32_to_cpu(grant->gid);
+               dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode,
+                    inode->i_uid, inode->i_gid);
+       }
+
+       if ((issued & CEPH_CAP_LINK_EXCL) == 0)
+               inode->i_nlink = le32_to_cpu(grant->nlink);
+
+       if ((issued & CEPH_CAP_XATTR_EXCL) == 0 && grant->xattr_len) {
+               int len = le32_to_cpu(grant->xattr_len);
+               u64 version = le64_to_cpu(grant->xattr_version);
+
+               if (version > ci->i_xattrs.version) {
+                       dout(" got new xattrs v%llu on %p len %d\n",
+                            version, inode, len);
+                       if (ci->i_xattrs.blob)
+                               ceph_buffer_put(ci->i_xattrs.blob);
+                       ci->i_xattrs.blob = ceph_buffer_get(xattr_buf);
+                       ci->i_xattrs.version = version;
+               }
+       }
+
+       /* size/ctime/mtime/atime? */
+       ceph_fill_file_size(inode, issued,
+                           le32_to_cpu(grant->truncate_seq),
+                           le64_to_cpu(grant->truncate_size), size);
+       ceph_decode_timespec(&mtime, &grant->mtime);
+       ceph_decode_timespec(&atime, &grant->atime);
+       ceph_decode_timespec(&ctime, &grant->ctime);
+       ceph_fill_file_time(inode, issued,
+                           le32_to_cpu(grant->time_warp_seq), &ctime, &mtime,
+                           &atime);
+
+       /* max size increase? */
+       if (max_size != ci->i_max_size) {
+               dout("max_size %lld -> %llu\n", ci->i_max_size, max_size);
+               ci->i_max_size = max_size;
+               if (max_size >= ci->i_wanted_max_size) {
+                       ci->i_wanted_max_size = 0;  /* reset */
+                       ci->i_requested_max_size = 0;
+               }
+               wake = 1;
+       }
+
+       /* check cap bits */
+       wanted = __ceph_caps_wanted(ci);
+       used = __ceph_caps_used(ci);
+       dirty = __ceph_caps_dirty(ci);
+       dout(" my wanted = %s, used = %s, dirty %s\n",
+            ceph_cap_string(wanted),
+            ceph_cap_string(used),
+            ceph_cap_string(dirty));
+       if (wanted != le32_to_cpu(grant->wanted)) {
+               dout("mds wanted %s -> %s\n",
+                    ceph_cap_string(le32_to_cpu(grant->wanted)),
+                    ceph_cap_string(wanted));
+               grant->wanted = cpu_to_le32(wanted);
+       }
+
+       cap->seq = seq;
+
+       /* file layout may have changed */
+       ci->i_layout = grant->layout;
+
+       /* revocation, grant, or no-op? */
+       if (cap->issued & ~newcaps) {
+               dout("revocation: %s -> %s\n", ceph_cap_string(cap->issued),
+                    ceph_cap_string(newcaps));
+               if ((used & ~newcaps) & CEPH_CAP_FILE_BUFFER)
+                       writeback = 1; /* will delay ack */
+               else if (dirty & ~newcaps)
+                       check_caps = 1;  /* initiate writeback in check_caps */
+               else if (((used & ~newcaps) & CEPH_CAP_FILE_CACHE) == 0 ||
+                          revoked_rdcache)
+                       check_caps = 2;     /* send revoke ack in check_caps */
+               cap->issued = newcaps;
+               cap->implemented |= newcaps;
+       } else if (cap->issued == newcaps) {
+               dout("caps unchanged: %s -> %s\n",
+                    ceph_cap_string(cap->issued), ceph_cap_string(newcaps));
+       } else {
+               dout("grant: %s -> %s\n", ceph_cap_string(cap->issued),
+                    ceph_cap_string(newcaps));
+               cap->issued = newcaps;
+               cap->implemented |= newcaps; /* add bits only, to
+                                             * avoid stepping on a
+                                             * pending revocation */
+               wake = 1;
+       }
+       BUG_ON(cap->issued & ~cap->implemented);
+
+       spin_unlock(&inode->i_lock);
+       if (writeback)
+               /*
+                * queue inode for writeback: we can't actually call
+                * filemap_write_and_wait, etc. from message handler
+                * context.
+                */
+               ceph_queue_writeback(inode);
+       if (queue_invalidate)
+               ceph_queue_invalidate(inode);
+       if (wake)
+               wake_up(&ci->i_cap_wq);
+
+       if (check_caps == 1)
+               ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_AUTHONLY,
+                               session);
+       else if (check_caps == 2)
+               ceph_check_caps(ci, CHECK_CAPS_NODELAY, session);
+       else
+               mutex_unlock(&session->s_mutex);
+}
+
+/*
+ * Handle FLUSH_ACK from MDS, indicating that metadata we sent to the
+ * MDS has been safely committed.
+ */
+static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid,
+                                struct ceph_mds_caps *m,
+                                struct ceph_mds_session *session,
+                                struct ceph_cap *cap)
+       __releases(inode->i_lock)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc;
+       unsigned seq = le32_to_cpu(m->seq);
+       int dirty = le32_to_cpu(m->dirty);
+       int cleaned = 0;
+       int drop = 0;
+       int i;
+
+       for (i = 0; i < CEPH_CAP_BITS; i++)
+               if ((dirty & (1 << i)) &&
+                   flush_tid == ci->i_cap_flush_tid[i])
+                       cleaned |= 1 << i;
+
+       dout("handle_cap_flush_ack inode %p mds%d seq %d on %s cleaned %s,"
+            " flushing %s -> %s\n",
+            inode, session->s_mds, seq, ceph_cap_string(dirty),
+            ceph_cap_string(cleaned), ceph_cap_string(ci->i_flushing_caps),
+            ceph_cap_string(ci->i_flushing_caps & ~cleaned));
+
+       if (ci->i_flushing_caps == (ci->i_flushing_caps & ~cleaned))
+               goto out;
+
+       ci->i_flushing_caps &= ~cleaned;
+
+       spin_lock(&mdsc->cap_dirty_lock);
+       if (ci->i_flushing_caps == 0) {
+               list_del_init(&ci->i_flushing_item);
+               if (!list_empty(&session->s_cap_flushing))
+                       dout(" mds%d still flushing cap on %p\n",
+                            session->s_mds,
+                            &list_entry(session->s_cap_flushing.next,
+                                        struct ceph_inode_info,
+                                        i_flushing_item)->vfs_inode);
+               mdsc->num_cap_flushing--;
+               wake_up(&mdsc->cap_flushing_wq);
+               dout(" inode %p now !flushing\n", inode);
+
+               if (ci->i_dirty_caps == 0) {
+                       dout(" inode %p now clean\n", inode);
+                       BUG_ON(!list_empty(&ci->i_dirty_item));
+                       drop = 1;
+               } else {
+                       BUG_ON(list_empty(&ci->i_dirty_item));
+               }
+       }
+       spin_unlock(&mdsc->cap_dirty_lock);
+       wake_up(&ci->i_cap_wq);
+
+out:
+       spin_unlock(&inode->i_lock);
+       if (drop)
+               iput(inode);
+}
+
+/*
+ * Handle FLUSHSNAP_ACK.  MDS has flushed snap data to disk and we can
+ * throw away our cap_snap.
+ *
+ * Caller hold s_mutex.
+ */
+static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid,
+                                    struct ceph_mds_caps *m,
+                                    struct ceph_mds_session *session)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       u64 follows = le64_to_cpu(m->snap_follows);
+       struct ceph_cap_snap *capsnap;
+       int drop = 0;
+
+       dout("handle_cap_flushsnap_ack inode %p ci %p mds%d follows %lld\n",
+            inode, ci, session->s_mds, follows);
+
+       spin_lock(&inode->i_lock);
+       list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
+               if (capsnap->follows == follows) {
+                       if (capsnap->flush_tid != flush_tid) {
+                               dout(" cap_snap %p follows %lld tid %lld !="
+                                    " %lld\n", capsnap, follows,
+                                    flush_tid, capsnap->flush_tid);
+                               break;
+                       }
+                       WARN_ON(capsnap->dirty_pages || capsnap->writing);
+                       dout(" removing %p cap_snap %p follows %lld\n",
+                            inode, capsnap, follows);
+                       ceph_put_snap_context(capsnap->context);
+                       list_del(&capsnap->ci_item);
+                       list_del(&capsnap->flushing_item);
+                       ceph_put_cap_snap(capsnap);
+                       drop = 1;
+                       break;
+               } else {
+                       dout(" skipping cap_snap %p follows %lld\n",
+                            capsnap, capsnap->follows);
+               }
+       }
+       spin_unlock(&inode->i_lock);
+       if (drop)
+               iput(inode);
+}
+
+/*
+ * Handle TRUNC from MDS, indicating file truncation.
+ *
+ * caller hold s_mutex.
+ */
+static void handle_cap_trunc(struct inode *inode,
+                            struct ceph_mds_caps *trunc,
+                            struct ceph_mds_session *session)
+       __releases(inode->i_lock)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int mds = session->s_mds;
+       int seq = le32_to_cpu(trunc->seq);
+       u32 truncate_seq = le32_to_cpu(trunc->truncate_seq);
+       u64 truncate_size = le64_to_cpu(trunc->truncate_size);
+       u64 size = le64_to_cpu(trunc->size);
+       int implemented = 0;
+       int dirty = __ceph_caps_dirty(ci);
+       int issued = __ceph_caps_issued(ceph_inode(inode), &implemented);
+       int queue_trunc = 0;
+
+       issued |= implemented | dirty;
+
+       dout("handle_cap_trunc inode %p mds%d seq %d to %lld seq %d\n",
+            inode, mds, seq, truncate_size, truncate_seq);
+       queue_trunc = ceph_fill_file_size(inode, issued,
+                                         truncate_seq, truncate_size, size);
+       spin_unlock(&inode->i_lock);
+
+       if (queue_trunc)
+               ceph_queue_vmtruncate(inode);
+}
+
+/*
+ * Handle EXPORT from MDS.  Cap is being migrated _from_ this mds to a
+ * different one.  If we are the most recent migration we've seen (as
+ * indicated by mseq), make note of the migrating cap bits for the
+ * duration (until we see the corresponding IMPORT).
+ *
+ * caller holds s_mutex
+ */
+static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex,
+                             struct ceph_mds_session *session)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int mds = session->s_mds;
+       unsigned mseq = le32_to_cpu(ex->migrate_seq);
+       struct ceph_cap *cap = NULL, *t;
+       struct rb_node *p;
+       int remember = 1;
+
+       dout("handle_cap_export inode %p ci %p mds%d mseq %d\n",
+            inode, ci, mds, mseq);
+
+       spin_lock(&inode->i_lock);
+
+       /* make sure we haven't seen a higher mseq */
+       for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+               t = rb_entry(p, struct ceph_cap, ci_node);
+               if (ceph_seq_cmp(t->mseq, mseq) > 0) {
+                       dout(" higher mseq on cap from mds%d\n",
+                            t->session->s_mds);
+                       remember = 0;
+               }
+               if (t->session->s_mds == mds)
+                       cap = t;
+       }
+
+       if (cap) {
+               if (remember) {
+                       /* make note */
+                       ci->i_cap_exporting_mds = mds;
+                       ci->i_cap_exporting_mseq = mseq;
+                       ci->i_cap_exporting_issued = cap->issued;
+               }
+               __ceph_remove_cap(cap);
+       }
+       /* else, we already released it */
+
+       spin_unlock(&inode->i_lock);
+}
+
+/*
+ * Handle cap IMPORT.  If there are temp bits from an older EXPORT,
+ * clean them up.
+ *
+ * caller holds s_mutex.
+ */
+static void handle_cap_import(struct ceph_mds_client *mdsc,
+                             struct inode *inode, struct ceph_mds_caps *im,
+                             struct ceph_mds_session *session,
+                             void *snaptrace, int snaptrace_len)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int mds = session->s_mds;
+       unsigned issued = le32_to_cpu(im->caps);
+       unsigned wanted = le32_to_cpu(im->wanted);
+       unsigned seq = le32_to_cpu(im->seq);
+       unsigned mseq = le32_to_cpu(im->migrate_seq);
+       u64 realmino = le64_to_cpu(im->realm);
+       u64 cap_id = le64_to_cpu(im->cap_id);
+
+       if (ci->i_cap_exporting_mds >= 0 &&
+           ceph_seq_cmp(ci->i_cap_exporting_mseq, mseq) < 0) {
+               dout("handle_cap_import inode %p ci %p mds%d mseq %d"
+                    " - cleared exporting from mds%d\n",
+                    inode, ci, mds, mseq,
+                    ci->i_cap_exporting_mds);
+               ci->i_cap_exporting_issued = 0;
+               ci->i_cap_exporting_mseq = 0;
+               ci->i_cap_exporting_mds = -1;
+       } else {
+               dout("handle_cap_import inode %p ci %p mds%d mseq %d\n",
+                    inode, ci, mds, mseq);
+       }
+
+       down_write(&mdsc->snap_rwsem);
+       ceph_update_snap_trace(mdsc, snaptrace, snaptrace+snaptrace_len,
+                              false);
+       downgrade_write(&mdsc->snap_rwsem);
+       ceph_add_cap(inode, session, cap_id, -1,
+                    issued, wanted, seq, mseq, realmino, CEPH_CAP_FLAG_AUTH,
+                    NULL /* no caps context */);
+       try_flush_caps(inode, session, NULL);
+       up_read(&mdsc->snap_rwsem);
+}
+
+/*
+ * Handle a caps message from the MDS.
+ *
+ * Identify the appropriate session, inode, and call the right handler
+ * based on the cap op.
+ */
+void ceph_handle_caps(struct ceph_mds_session *session,
+                     struct ceph_msg *msg)
+{
+       struct ceph_mds_client *mdsc = session->s_mdsc;
+       struct super_block *sb = mdsc->client->sb;
+       struct inode *inode;
+       struct ceph_cap *cap;
+       struct ceph_mds_caps *h;
+       int mds = session->s_mds;
+       int op;
+       u32 seq;
+       struct ceph_vino vino;
+       u64 cap_id;
+       u64 size, max_size;
+       u64 tid;
+       void *snaptrace;
+
+       dout("handle_caps from mds%d\n", mds);
+
+       /* decode */
+       tid = le64_to_cpu(msg->hdr.tid);
+       if (msg->front.iov_len < sizeof(*h))
+               goto bad;
+       h = msg->front.iov_base;
+       snaptrace = h + 1;
+       op = le32_to_cpu(h->op);
+       vino.ino = le64_to_cpu(h->ino);
+       vino.snap = CEPH_NOSNAP;
+       cap_id = le64_to_cpu(h->cap_id);
+       seq = le32_to_cpu(h->seq);
+       size = le64_to_cpu(h->size);
+       max_size = le64_to_cpu(h->max_size);
+
+       mutex_lock(&session->s_mutex);
+       session->s_seq++;
+       dout(" mds%d seq %lld cap seq %u\n", session->s_mds, session->s_seq,
+            (unsigned)seq);
+
+       /* lookup ino */
+       inode = ceph_find_inode(sb, vino);
+       dout(" op %s ino %llx.%llx inode %p\n", ceph_cap_op_name(op), vino.ino,
+            vino.snap, inode);
+       if (!inode) {
+               dout(" i don't have ino %llx\n", vino.ino);
+               goto done;
+       }
+
+       /* these will work even if we don't have a cap yet */
+       switch (op) {
+       case CEPH_CAP_OP_FLUSHSNAP_ACK:
+               handle_cap_flushsnap_ack(inode, tid, h, session);
+               goto done;
+
+       case CEPH_CAP_OP_EXPORT:
+               handle_cap_export(inode, h, session);
+               goto done;
+
+       case CEPH_CAP_OP_IMPORT:
+               handle_cap_import(mdsc, inode, h, session,
+                                 snaptrace, le32_to_cpu(h->snap_trace_len));
+               ceph_check_caps(ceph_inode(inode), CHECK_CAPS_NODELAY,
+                               session);
+               goto done_unlocked;
+       }
+
+       /* the rest require a cap */
+       spin_lock(&inode->i_lock);
+       cap = __get_cap_for_mds(ceph_inode(inode), mds);
+       if (!cap) {
+               dout("no cap on %p ino %llx.%llx from mds%d, releasing\n",
+                    inode, ceph_ino(inode), ceph_snap(inode), mds);
+               spin_unlock(&inode->i_lock);
+               goto done;
+       }
+
+       /* note that each of these drops i_lock for us */
+       switch (op) {
+       case CEPH_CAP_OP_REVOKE:
+       case CEPH_CAP_OP_GRANT:
+               handle_cap_grant(inode, h, session, cap, msg->middle);
+               goto done_unlocked;
+
+       case CEPH_CAP_OP_FLUSH_ACK:
+               handle_cap_flush_ack(inode, tid, h, session, cap);
+               break;
+
+       case CEPH_CAP_OP_TRUNC:
+               handle_cap_trunc(inode, h, session);
+               break;
+
+       default:
+               spin_unlock(&inode->i_lock);
+               pr_err("ceph_handle_caps: unknown cap op %d %s\n", op,
+                      ceph_cap_op_name(op));
+       }
+
+done:
+       mutex_unlock(&session->s_mutex);
+done_unlocked:
+       if (inode)
+               iput(inode);
+       return;
+
+bad:
+       pr_err("ceph_handle_caps: corrupt message\n");
+       ceph_msg_dump(msg);
+       return;
+}
+
+/*
+ * Delayed work handler to process end of delayed cap release LRU list.
+ */
+void ceph_check_delayed_caps(struct ceph_mds_client *mdsc)
+{
+       struct ceph_inode_info *ci;
+       int flags = CHECK_CAPS_NODELAY;
+
+       dout("check_delayed_caps\n");
+       while (1) {
+               spin_lock(&mdsc->cap_delay_lock);
+               if (list_empty(&mdsc->cap_delay_list))
+                       break;
+               ci = list_first_entry(&mdsc->cap_delay_list,
+                                     struct ceph_inode_info,
+                                     i_cap_delay_list);
+               if ((ci->i_ceph_flags & CEPH_I_FLUSH) == 0 &&
+                   time_before(jiffies, ci->i_hold_caps_max))
+                       break;
+               list_del_init(&ci->i_cap_delay_list);
+               spin_unlock(&mdsc->cap_delay_lock);
+               dout("check_delayed_caps on %p\n", &ci->vfs_inode);
+               ceph_check_caps(ci, flags, NULL);
+       }
+       spin_unlock(&mdsc->cap_delay_lock);
+}
+
+/*
+ * Flush all dirty caps to the mds
+ */
+void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc)
+{
+       struct ceph_inode_info *ci, *nci = NULL;
+       struct inode *inode, *ninode = NULL;
+       struct list_head *p, *n;
+
+       dout("flush_dirty_caps\n");
+       spin_lock(&mdsc->cap_dirty_lock);
+       list_for_each_safe(p, n, &mdsc->cap_dirty) {
+               if (nci) {
+                       ci = nci;
+                       inode = ninode;
+                       ci->i_ceph_flags &= ~CEPH_I_NOFLUSH;
+                       dout("flush_dirty_caps inode %p (was next inode)\n",
+                            inode);
+               } else {
+                       ci = list_entry(p, struct ceph_inode_info,
+                                       i_dirty_item);
+                       inode = igrab(&ci->vfs_inode);
+                       BUG_ON(!inode);
+                       dout("flush_dirty_caps inode %p\n", inode);
+               }
+               if (n != &mdsc->cap_dirty) {
+                       nci = list_entry(n, struct ceph_inode_info,
+                                        i_dirty_item);
+                       ninode = igrab(&nci->vfs_inode);
+                       BUG_ON(!ninode);
+                       nci->i_ceph_flags |= CEPH_I_NOFLUSH;
+                       dout("flush_dirty_caps next inode %p, noflush\n",
+                            ninode);
+               } else {
+                       nci = NULL;
+                       ninode = NULL;
+               }
+               spin_unlock(&mdsc->cap_dirty_lock);
+               if (inode) {
+                       ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH,
+                                       NULL);
+                       iput(inode);
+               }
+               spin_lock(&mdsc->cap_dirty_lock);
+       }
+       spin_unlock(&mdsc->cap_dirty_lock);
+}
+
+/*
+ * Drop open file reference.  If we were the last open file,
+ * we may need to release capabilities to the MDS (or schedule
+ * their delayed release).
+ */
+void ceph_put_fmode(struct ceph_inode_info *ci, int fmode)
+{
+       struct inode *inode = &ci->vfs_inode;
+       int last = 0;
+
+       spin_lock(&inode->i_lock);
+       dout("put_fmode %p fmode %d %d -> %d\n", inode, fmode,
+            ci->i_nr_by_mode[fmode], ci->i_nr_by_mode[fmode]-1);
+       BUG_ON(ci->i_nr_by_mode[fmode] == 0);
+       if (--ci->i_nr_by_mode[fmode] == 0)
+               last++;
+       spin_unlock(&inode->i_lock);
+
+       if (last && ci->i_vino.snap == CEPH_NOSNAP)
+               ceph_check_caps(ci, 0, NULL);
+}
+
+/*
+ * Helpers for embedding cap and dentry lease releases into mds
+ * requests.
+ *
+ * @force is used by dentry_release (below) to force inclusion of a
+ * record for the directory inode, even when there aren't any caps to
+ * drop.
+ */
+int ceph_encode_inode_release(void **p, struct inode *inode,
+                             int mds, int drop, int unless, int force)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_cap *cap;
+       struct ceph_mds_request_release *rel = *p;
+       int ret = 0;
+       int used = 0;
+
+       spin_lock(&inode->i_lock);
+       used = __ceph_caps_used(ci);
+
+       dout("encode_inode_release %p mds%d used %s drop %s unless %s\n", inode,
+            mds, ceph_cap_string(used), ceph_cap_string(drop),
+            ceph_cap_string(unless));
+
+       /* only drop unused caps */
+       drop &= ~used;
+
+       cap = __get_cap_for_mds(ci, mds);
+       if (cap && __cap_is_valid(cap)) {
+               if (force ||
+                   ((cap->issued & drop) &&
+                    (cap->issued & unless) == 0)) {
+                       if ((cap->issued & drop) &&
+                           (cap->issued & unless) == 0) {
+                               dout("encode_inode_release %p cap %p %s -> "
+                                    "%s\n", inode, cap,
+                                    ceph_cap_string(cap->issued),
+                                    ceph_cap_string(cap->issued & ~drop));
+                               cap->issued &= ~drop;
+                               cap->implemented &= ~drop;
+                               if (ci->i_ceph_flags & CEPH_I_NODELAY) {
+                                       int wanted = __ceph_caps_wanted(ci);
+                                       dout("  wanted %s -> %s (act %s)\n",
+                                            ceph_cap_string(cap->mds_wanted),
+                                            ceph_cap_string(cap->mds_wanted &
+                                                            ~wanted),
+                                            ceph_cap_string(wanted));
+                                       cap->mds_wanted &= wanted;
+                               }
+                       } else {
+                               dout("encode_inode_release %p cap %p %s"
+                                    " (force)\n", inode, cap,
+                                    ceph_cap_string(cap->issued));
+                       }
+
+                       rel->ino = cpu_to_le64(ceph_ino(inode));
+                       rel->cap_id = cpu_to_le64(cap->cap_id);
+                       rel->seq = cpu_to_le32(cap->seq);
+                       rel->issue_seq = cpu_to_le32(cap->issue_seq),
+                       rel->mseq = cpu_to_le32(cap->mseq);
+                       rel->caps = cpu_to_le32(cap->issued);
+                       rel->wanted = cpu_to_le32(cap->mds_wanted);
+                       rel->dname_len = 0;
+                       rel->dname_seq = 0;
+                       *p += sizeof(*rel);
+                       ret = 1;
+               } else {
+                       dout("encode_inode_release %p cap %p %s\n",
+                            inode, cap, ceph_cap_string(cap->issued));
+               }
+       }
+       spin_unlock(&inode->i_lock);
+       return ret;
+}
+
+int ceph_encode_dentry_release(void **p, struct dentry *dentry,
+                              int mds, int drop, int unless)
+{
+       struct inode *dir = dentry->d_parent->d_inode;
+       struct ceph_mds_request_release *rel = *p;
+       struct ceph_dentry_info *di = ceph_dentry(dentry);
+       int force = 0;
+       int ret;
+
+       /*
+        * force an record for the directory caps if we have a dentry lease.
+        * this is racy (can't take i_lock and d_lock together), but it
+        * doesn't have to be perfect; the mds will revoke anything we don't
+        * release.
+        */
+       spin_lock(&dentry->d_lock);
+       if (di->lease_session && di->lease_session->s_mds == mds)
+               force = 1;
+       spin_unlock(&dentry->d_lock);
+
+       ret = ceph_encode_inode_release(p, dir, mds, drop, unless, force);
+
+       spin_lock(&dentry->d_lock);
+       if (ret && di->lease_session && di->lease_session->s_mds == mds) {
+               dout("encode_dentry_release %p mds%d seq %d\n",
+                    dentry, mds, (int)di->lease_seq);
+               rel->dname_len = cpu_to_le32(dentry->d_name.len);
+               memcpy(*p, dentry->d_name.name, dentry->d_name.len);
+               *p += dentry->d_name.len;
+               rel->dname_seq = cpu_to_le32(di->lease_seq);
+       }
+       spin_unlock(&dentry->d_lock);
+       return ret;
+}
diff --git a/fs/ceph/ceph_debug.h b/fs/ceph/ceph_debug.h
new file mode 100644 (file)
index 0000000..1818c23
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef _FS_CEPH_DEBUG_H
+#define _FS_CEPH_DEBUG_H
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#ifdef CONFIG_CEPH_FS_PRETTYDEBUG
+
+/*
+ * wrap pr_debug to include a filename:lineno prefix on each line.
+ * this incurs some overhead (kernel size and execution time) due to
+ * the extra function call at each call site.
+ */
+
+# if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
+extern const char *ceph_file_part(const char *s, int len);
+#  define dout(fmt, ...)                                               \
+       pr_debug(" %12.12s:%-4d : " fmt,                                \
+                ceph_file_part(__FILE__, sizeof(__FILE__)),            \
+                __LINE__, ##__VA_ARGS__)
+# else
+/* faux printk call just to see any compiler warnings. */
+#  define dout(fmt, ...)       do {                            \
+               if (0)                                          \
+                       printk(KERN_DEBUG fmt, ##__VA_ARGS__);  \
+       } while (0)
+# endif
+
+#else
+
+/*
+ * or, just wrap pr_debug
+ */
+# define dout(fmt, ...)        pr_debug(" " fmt, ##__VA_ARGS__)
+
+#endif
+
+#endif
diff --git a/fs/ceph/ceph_frag.c b/fs/ceph/ceph_frag.c
new file mode 100644 (file)
index 0000000..ab6cf35
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Ceph 'frag' type
+ */
+#include "types.h"
+
+int ceph_frag_compare(__u32 a, __u32 b)
+{
+       unsigned va = ceph_frag_value(a);
+       unsigned vb = ceph_frag_value(b);
+       if (va < vb)
+               return -1;
+       if (va > vb)
+               return 1;
+       va = ceph_frag_bits(a);
+       vb = ceph_frag_bits(b);
+       if (va < vb)
+               return -1;
+       if (va > vb)
+               return 1;
+       return 0;
+}
diff --git a/fs/ceph/ceph_frag.h b/fs/ceph/ceph_frag.h
new file mode 100644 (file)
index 0000000..793f50c
--- /dev/null
@@ -0,0 +1,109 @@
+#ifndef _FS_CEPH_FRAG_H
+#define _FS_CEPH_FRAG_H
+
+/*
+ * "Frags" are a way to describe a subset of a 32-bit number space,
+ * using a mask and a value to match against that mask.  Any given frag
+ * (subset of the number space) can be partitioned into 2^n sub-frags.
+ *
+ * Frags are encoded into a 32-bit word:
+ *   8 upper bits = "bits"
+ *  24 lower bits = "value"
+ * (We could go to 5+27 bits, but who cares.)
+ *
+ * We use the _most_ significant bits of the 24 bit value.  This makes
+ * values logically sort.
+ *
+ * Unfortunately, because the "bits" field is still in the high bits, we
+ * can't sort encoded frags numerically.  However, it does allow you
+ * to feed encoded frags as values into frag_contains_value.
+ */
+static inline __u32 ceph_frag_make(__u32 b, __u32 v)
+{
+       return (b << 24) |
+               (v & (0xffffffu << (24-b)) & 0xffffffu);
+}
+static inline __u32 ceph_frag_bits(__u32 f)
+{
+       return f >> 24;
+}
+static inline __u32 ceph_frag_value(__u32 f)
+{
+       return f & 0xffffffu;
+}
+static inline __u32 ceph_frag_mask(__u32 f)
+{
+       return (0xffffffu << (24-ceph_frag_bits(f))) & 0xffffffu;
+}
+static inline __u32 ceph_frag_mask_shift(__u32 f)
+{
+       return 24 - ceph_frag_bits(f);
+}
+
+static inline int ceph_frag_contains_value(__u32 f, __u32 v)
+{
+       return (v & ceph_frag_mask(f)) == ceph_frag_value(f);
+}
+static inline int ceph_frag_contains_frag(__u32 f, __u32 sub)
+{
+       /* is sub as specific as us, and contained by us? */
+       return ceph_frag_bits(sub) >= ceph_frag_bits(f) &&
+              (ceph_frag_value(sub) & ceph_frag_mask(f)) == ceph_frag_value(f);
+}
+
+static inline __u32 ceph_frag_parent(__u32 f)
+{
+       return ceph_frag_make(ceph_frag_bits(f) - 1,
+                        ceph_frag_value(f) & (ceph_frag_mask(f) << 1));
+}
+static inline int ceph_frag_is_left_child(__u32 f)
+{
+       return ceph_frag_bits(f) > 0 &&
+               (ceph_frag_value(f) & (0x1000000 >> ceph_frag_bits(f))) == 0;
+}
+static inline int ceph_frag_is_right_child(__u32 f)
+{
+       return ceph_frag_bits(f) > 0 &&
+               (ceph_frag_value(f) & (0x1000000 >> ceph_frag_bits(f))) == 1;
+}
+static inline __u32 ceph_frag_sibling(__u32 f)
+{
+       return ceph_frag_make(ceph_frag_bits(f),
+                     ceph_frag_value(f) ^ (0x1000000 >> ceph_frag_bits(f)));
+}
+static inline __u32 ceph_frag_left_child(__u32 f)
+{
+       return ceph_frag_make(ceph_frag_bits(f)+1, ceph_frag_value(f));
+}
+static inline __u32 ceph_frag_right_child(__u32 f)
+{
+       return ceph_frag_make(ceph_frag_bits(f)+1,
+             ceph_frag_value(f) | (0x1000000 >> (1+ceph_frag_bits(f))));
+}
+static inline __u32 ceph_frag_make_child(__u32 f, int by, int i)
+{
+       int newbits = ceph_frag_bits(f) + by;
+       return ceph_frag_make(newbits,
+                        ceph_frag_value(f) | (i << (24 - newbits)));
+}
+static inline int ceph_frag_is_leftmost(__u32 f)
+{
+       return ceph_frag_value(f) == 0;
+}
+static inline int ceph_frag_is_rightmost(__u32 f)
+{
+       return ceph_frag_value(f) == ceph_frag_mask(f);
+}
+static inline __u32 ceph_frag_next(__u32 f)
+{
+       return ceph_frag_make(ceph_frag_bits(f),
+                        ceph_frag_value(f) + (0x1000000 >> ceph_frag_bits(f)));
+}
+
+/*
+ * comparator to sort frags logically, as when traversing the
+ * number space in ascending order...
+ */
+int ceph_frag_compare(__u32 a, __u32 b);
+
+#endif
diff --git a/fs/ceph/ceph_fs.c b/fs/ceph/ceph_fs.c
new file mode 100644 (file)
index 0000000..79d76bc
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Some non-inline ceph helpers
+ */
+#include "types.h"
+
+/*
+ * return true if @layout appears to be valid
+ */
+int ceph_file_layout_is_valid(const struct ceph_file_layout *layout)
+{
+       __u32 su = le32_to_cpu(layout->fl_stripe_unit);
+       __u32 sc = le32_to_cpu(layout->fl_stripe_count);
+       __u32 os = le32_to_cpu(layout->fl_object_size);
+
+       /* stripe unit, object size must be non-zero, 64k increment */
+       if (!su || (su & (CEPH_MIN_STRIPE_UNIT-1)))
+               return 0;
+       if (!os || (os & (CEPH_MIN_STRIPE_UNIT-1)))
+               return 0;
+       /* object size must be a multiple of stripe unit */
+       if (os < su || os % su)
+               return 0;
+       /* stripe count must be non-zero */
+       if (!sc)
+               return 0;
+       return 1;
+}
+
+
+int ceph_flags_to_mode(int flags)
+{
+#ifdef O_DIRECTORY  /* fixme */
+       if ((flags & O_DIRECTORY) == O_DIRECTORY)
+               return CEPH_FILE_MODE_PIN;
+#endif
+#ifdef O_LAZY
+       if (flags & O_LAZY)
+               return CEPH_FILE_MODE_LAZY;
+#endif
+       if ((flags & O_APPEND) == O_APPEND)
+               flags |= O_WRONLY;
+
+       flags &= O_ACCMODE;
+       if ((flags & O_RDWR) == O_RDWR)
+               return CEPH_FILE_MODE_RDWR;
+       if ((flags & O_WRONLY) == O_WRONLY)
+               return CEPH_FILE_MODE_WR;
+       return CEPH_FILE_MODE_RD;
+}
+
+int ceph_caps_for_mode(int mode)
+{
+       switch (mode) {
+       case CEPH_FILE_MODE_PIN:
+               return CEPH_CAP_PIN;
+       case CEPH_FILE_MODE_RD:
+               return CEPH_CAP_PIN | CEPH_CAP_FILE_SHARED |
+                       CEPH_CAP_FILE_RD | CEPH_CAP_FILE_CACHE;
+       case CEPH_FILE_MODE_RDWR:
+               return CEPH_CAP_PIN | CEPH_CAP_FILE_SHARED |
+                       CEPH_CAP_FILE_EXCL |
+                       CEPH_CAP_FILE_RD | CEPH_CAP_FILE_CACHE |
+                       CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER |
+                       CEPH_CAP_AUTH_SHARED | CEPH_CAP_AUTH_EXCL |
+                       CEPH_CAP_XATTR_SHARED | CEPH_CAP_XATTR_EXCL;
+       case CEPH_FILE_MODE_WR:
+               return CEPH_CAP_PIN | CEPH_CAP_FILE_SHARED |
+                       CEPH_CAP_FILE_EXCL |
+                       CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER |
+                       CEPH_CAP_AUTH_SHARED | CEPH_CAP_AUTH_EXCL |
+                       CEPH_CAP_XATTR_SHARED | CEPH_CAP_XATTR_EXCL;
+       }
+       return 0;
+}
diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h
new file mode 100644 (file)
index 0000000..0c2241e
--- /dev/null
@@ -0,0 +1,650 @@
+/*
+ * ceph_fs.h - Ceph constants and data types to share between kernel and
+ * user space.
+ *
+ * Most types in this file are defined as little-endian, and are
+ * primarily intended to describe data structures that pass over the
+ * wire or that are stored on disk.
+ *
+ * LGPL2
+ */
+
+#ifndef _FS_CEPH_CEPH_FS_H
+#define _FS_CEPH_CEPH_FS_H
+
+#include "msgr.h"
+#include "rados.h"
+
+/*
+ * Ceph release version
+ */
+#define CEPH_VERSION_MAJOR 0
+#define CEPH_VERSION_MINOR 19
+#define CEPH_VERSION_PATCH 0
+
+#define _CEPH_STRINGIFY(x) #x
+#define CEPH_STRINGIFY(x) _CEPH_STRINGIFY(x)
+#define CEPH_MAKE_VERSION(x, y, z) CEPH_STRINGIFY(x) "." CEPH_STRINGIFY(y) \
+       "." CEPH_STRINGIFY(z)
+#define CEPH_VERSION CEPH_MAKE_VERSION(CEPH_VERSION_MAJOR, \
+                                      CEPH_VERSION_MINOR, CEPH_VERSION_PATCH)
+
+/*
+ * subprotocol versions.  when specific messages types or high-level
+ * protocols change, bump the affected components.  we keep rev
+ * internal cluster protocols separately from the public,
+ * client-facing protocol.
+ */
+#define CEPH_OSD_PROTOCOL     8 /* cluster internal */
+#define CEPH_MDS_PROTOCOL     9 /* cluster internal */
+#define CEPH_MON_PROTOCOL     5 /* cluster internal */
+#define CEPH_OSDC_PROTOCOL   24 /* server/client */
+#define CEPH_MDSC_PROTOCOL   32 /* server/client */
+#define CEPH_MONC_PROTOCOL   15 /* server/client */
+
+
+#define CEPH_INO_ROOT  1
+#define CEPH_INO_CEPH  2        /* hidden .ceph dir */
+
+/* arbitrary limit on max # of monitors (cluster of 3 is typical) */
+#define CEPH_MAX_MON   31
+
+
+/*
+ * feature bits
+ */
+#define CEPH_FEATURE_SUPPORTED  0
+#define CEPH_FEATURE_REQUIRED   0
+
+
+/*
+ * ceph_file_layout - describe data layout for a file/inode
+ */
+struct ceph_file_layout {
+       /* file -> object mapping */
+       __le32 fl_stripe_unit;     /* stripe unit, in bytes.  must be multiple
+                                     of page size. */
+       __le32 fl_stripe_count;    /* over this many objects */
+       __le32 fl_object_size;     /* until objects are this big, then move to
+                                     new objects */
+       __le32 fl_cas_hash;        /* 0 = none; 1 = sha256 */
+
+       /* pg -> disk layout */
+       __le32 fl_object_stripe_unit;  /* for per-object parity, if any */
+
+       /* object -> pg layout */
+       __le32 fl_pg_preferred; /* preferred primary for pg (-1 for none) */
+       __le32 fl_pg_pool;      /* namespace, crush ruleset, rep level */
+} __attribute__ ((packed));
+
+#define CEPH_MIN_STRIPE_UNIT 65536
+
+int ceph_file_layout_is_valid(const struct ceph_file_layout *layout);
+
+
+/* crypto algorithms */
+#define CEPH_CRYPTO_NONE 0x0
+#define CEPH_CRYPTO_AES  0x1
+
+/* security/authentication protocols */
+#define CEPH_AUTH_UNKNOWN      0x0
+#define CEPH_AUTH_NONE         0x1
+#define CEPH_AUTH_CEPHX                0x2
+
+
+/*********************************************
+ * message layer
+ */
+
+/*
+ * message types
+ */
+
+/* misc */
+#define CEPH_MSG_SHUTDOWN               1
+#define CEPH_MSG_PING                   2
+
+/* client <-> monitor */
+#define CEPH_MSG_MON_MAP                4
+#define CEPH_MSG_MON_GET_MAP            5
+#define CEPH_MSG_STATFS                 13
+#define CEPH_MSG_STATFS_REPLY           14
+#define CEPH_MSG_MON_SUBSCRIBE          15
+#define CEPH_MSG_MON_SUBSCRIBE_ACK      16
+#define CEPH_MSG_AUTH                  17
+#define CEPH_MSG_AUTH_REPLY            18
+
+/* client <-> mds */
+#define CEPH_MSG_MDS_MAP                21
+
+#define CEPH_MSG_CLIENT_SESSION         22
+#define CEPH_MSG_CLIENT_RECONNECT       23
+
+#define CEPH_MSG_CLIENT_REQUEST         24
+#define CEPH_MSG_CLIENT_REQUEST_FORWARD 25
+#define CEPH_MSG_CLIENT_REPLY           26
+#define CEPH_MSG_CLIENT_CAPS            0x310
+#define CEPH_MSG_CLIENT_LEASE           0x311
+#define CEPH_MSG_CLIENT_SNAP            0x312
+#define CEPH_MSG_CLIENT_CAPRELEASE      0x313
+
+/* osd */
+#define CEPH_MSG_OSD_MAP          41
+#define CEPH_MSG_OSD_OP           42
+#define CEPH_MSG_OSD_OPREPLY      43
+
+struct ceph_mon_request_header {
+       __le64 have_version;
+       __le16 session_mon;
+       __le64 session_mon_tid;
+} __attribute__ ((packed));
+
+struct ceph_mon_statfs {
+       struct ceph_mon_request_header monhdr;
+       struct ceph_fsid fsid;
+} __attribute__ ((packed));
+
+struct ceph_statfs {
+       __le64 kb, kb_used, kb_avail;
+       __le64 num_objects;
+} __attribute__ ((packed));
+
+struct ceph_mon_statfs_reply {
+       struct ceph_fsid fsid;
+       __le64 version;
+       struct ceph_statfs st;
+} __attribute__ ((packed));
+
+struct ceph_osd_getmap {
+       struct ceph_mon_request_header monhdr;
+       struct ceph_fsid fsid;
+       __le32 start;
+} __attribute__ ((packed));
+
+struct ceph_mds_getmap {
+       struct ceph_mon_request_header monhdr;
+       struct ceph_fsid fsid;
+} __attribute__ ((packed));
+
+struct ceph_client_mount {
+       struct ceph_mon_request_header monhdr;
+} __attribute__ ((packed));
+
+struct ceph_mon_subscribe_item {
+       __le64 have_version;    __le64 have;
+       __u8 onetime;
+} __attribute__ ((packed));
+
+struct ceph_mon_subscribe_ack {
+       __le32 duration;         /* seconds */
+       struct ceph_fsid fsid;
+} __attribute__ ((packed));
+
+/*
+ * mds states
+ *   > 0 -> in
+ *  <= 0 -> out
+ */
+#define CEPH_MDS_STATE_DNE          0  /* down, does not exist. */
+#define CEPH_MDS_STATE_STOPPED     -1  /* down, once existed, but no subtrees.
+                                         empty log. */
+#define CEPH_MDS_STATE_BOOT        -4  /* up, boot announcement. */
+#define CEPH_MDS_STATE_STANDBY     -5  /* up, idle.  waiting for assignment. */
+#define CEPH_MDS_STATE_CREATING    -6  /* up, creating MDS instance. */
+#define CEPH_MDS_STATE_STARTING    -7  /* up, starting previously stopped mds */
+#define CEPH_MDS_STATE_STANDBY_REPLAY -8 /* up, tailing active node's journal */
+
+#define CEPH_MDS_STATE_REPLAY       8  /* up, replaying journal. */
+#define CEPH_MDS_STATE_RESOLVE      9  /* up, disambiguating distributed
+                                         operations (import, rename, etc.) */
+#define CEPH_MDS_STATE_RECONNECT    10 /* up, reconnect to clients */
+#define CEPH_MDS_STATE_REJOIN       11 /* up, rejoining distributed cache */
+#define CEPH_MDS_STATE_CLIENTREPLAY 12 /* up, replaying client operations */
+#define CEPH_MDS_STATE_ACTIVE       13 /* up, active */
+#define CEPH_MDS_STATE_STOPPING     14 /* up, but exporting metadata */
+
+extern const char *ceph_mds_state_name(int s);
+
+
+/*
+ * metadata lock types.
+ *  - these are bitmasks.. we can compose them
+ *  - they also define the lock ordering by the MDS
+ *  - a few of these are internal to the mds
+ */
+#define CEPH_LOCK_DN          1
+#define CEPH_LOCK_ISNAP       2
+#define CEPH_LOCK_IVERSION    4     /* mds internal */
+#define CEPH_LOCK_IFILE       8     /* mds internal */
+#define CEPH_LOCK_IAUTH       32
+#define CEPH_LOCK_ILINK       64
+#define CEPH_LOCK_IDFT        128   /* dir frag tree */
+#define CEPH_LOCK_INEST       256   /* mds internal */
+#define CEPH_LOCK_IXATTR      512
+#define CEPH_LOCK_INO         2048  /* immutable inode bits; not a lock */
+
+/* client_session ops */
+enum {
+       CEPH_SESSION_REQUEST_OPEN,
+       CEPH_SESSION_OPEN,
+       CEPH_SESSION_REQUEST_CLOSE,
+       CEPH_SESSION_CLOSE,
+       CEPH_SESSION_REQUEST_RENEWCAPS,
+       CEPH_SESSION_RENEWCAPS,
+       CEPH_SESSION_STALE,
+       CEPH_SESSION_RECALL_STATE,
+};
+
+extern const char *ceph_session_op_name(int op);
+
+struct ceph_mds_session_head {
+       __le32 op;
+       __le64 seq;
+       struct ceph_timespec stamp;
+       __le32 max_caps, max_leases;
+} __attribute__ ((packed));
+
+/* client_request */
+/*
+ * metadata ops.
+ *  & 0x001000 -> write op
+ *  & 0x010000 -> follow symlink (e.g. stat(), not lstat()).
+ &  & 0x100000 -> use weird ino/path trace
+ */
+#define CEPH_MDS_OP_WRITE        0x001000
+enum {
+       CEPH_MDS_OP_LOOKUP     = 0x00100,
+       CEPH_MDS_OP_GETATTR    = 0x00101,
+       CEPH_MDS_OP_LOOKUPHASH = 0x00102,
+       CEPH_MDS_OP_LOOKUPPARENT = 0x00103,
+
+       CEPH_MDS_OP_SETXATTR   = 0x01105,
+       CEPH_MDS_OP_RMXATTR    = 0x01106,
+       CEPH_MDS_OP_SETLAYOUT  = 0x01107,
+       CEPH_MDS_OP_SETATTR    = 0x01108,
+
+       CEPH_MDS_OP_MKNOD      = 0x01201,
+       CEPH_MDS_OP_LINK       = 0x01202,
+       CEPH_MDS_OP_UNLINK     = 0x01203,
+       CEPH_MDS_OP_RENAME     = 0x01204,
+       CEPH_MDS_OP_MKDIR      = 0x01220,
+       CEPH_MDS_OP_RMDIR      = 0x01221,
+       CEPH_MDS_OP_SYMLINK    = 0x01222,
+
+       CEPH_MDS_OP_CREATE     = 0x01301,
+       CEPH_MDS_OP_OPEN       = 0x00302,
+       CEPH_MDS_OP_READDIR    = 0x00305,
+
+       CEPH_MDS_OP_LOOKUPSNAP = 0x00400,
+       CEPH_MDS_OP_MKSNAP     = 0x01400,
+       CEPH_MDS_OP_RMSNAP     = 0x01401,
+       CEPH_MDS_OP_LSSNAP     = 0x00402,
+};
+
+extern const char *ceph_mds_op_name(int op);
+
+
+#define CEPH_SETATTR_MODE   1
+#define CEPH_SETATTR_UID    2
+#define CEPH_SETATTR_GID    4
+#define CEPH_SETATTR_MTIME  8
+#define CEPH_SETATTR_ATIME 16
+#define CEPH_SETATTR_SIZE  32
+#define CEPH_SETATTR_CTIME 64
+
+union ceph_mds_request_args {
+       struct {
+               __le32 mask;                 /* CEPH_CAP_* */
+       } __attribute__ ((packed)) getattr;
+       struct {
+               __le32 mode;
+               __le32 uid;
+               __le32 gid;
+               struct ceph_timespec mtime;
+               struct ceph_timespec atime;
+               __le64 size, old_size;       /* old_size needed by truncate */
+               __le32 mask;                 /* CEPH_SETATTR_* */
+       } __attribute__ ((packed)) setattr;
+       struct {
+               __le32 frag;                 /* which dir fragment */
+               __le32 max_entries;          /* how many dentries to grab */
+       } __attribute__ ((packed)) readdir;
+       struct {
+               __le32 mode;
+               __le32 rdev;
+       } __attribute__ ((packed)) mknod;
+       struct {
+               __le32 mode;
+       } __attribute__ ((packed)) mkdir;
+       struct {
+               __le32 flags;
+               __le32 mode;
+               __le32 stripe_unit;          /* layout for newly created file */
+               __le32 stripe_count;         /* ... */
+               __le32 object_size;
+               __le32 file_replication;
+               __le32 preferred;
+       } __attribute__ ((packed)) open;
+       struct {
+               __le32 flags;
+       } __attribute__ ((packed)) setxattr;
+       struct {
+               struct ceph_file_layout layout;
+       } __attribute__ ((packed)) setlayout;
+} __attribute__ ((packed));
+
+#define CEPH_MDS_FLAG_REPLAY        1  /* this is a replayed op */
+#define CEPH_MDS_FLAG_WANT_DENTRY   2  /* want dentry in reply */
+
+struct ceph_mds_request_head {
+       __le64 oldest_client_tid;
+       __le32 mdsmap_epoch;           /* on client */
+       __le32 flags;                  /* CEPH_MDS_FLAG_* */
+       __u8 num_retry, num_fwd;       /* count retry, fwd attempts */
+       __le16 num_releases;           /* # include cap/lease release records */
+       __le32 op;                     /* mds op code */
+       __le32 caller_uid, caller_gid;
+       __le64 ino;                    /* use this ino for openc, mkdir, mknod,
+                                         etc. (if replaying) */
+       union ceph_mds_request_args args;
+} __attribute__ ((packed));
+
+/* cap/lease release record */
+struct ceph_mds_request_release {
+       __le64 ino, cap_id;            /* ino and unique cap id */
+       __le32 caps, wanted;           /* new issued, wanted */
+       __le32 seq, issue_seq, mseq;
+       __le32 dname_seq;              /* if releasing a dentry lease, a */
+       __le32 dname_len;              /* string follows. */
+} __attribute__ ((packed));
+
+/* client reply */
+struct ceph_mds_reply_head {
+       __le32 op;
+       __le32 result;
+       __le32 mdsmap_epoch;
+       __u8 safe;                     /* true if committed to disk */
+       __u8 is_dentry, is_target;     /* true if dentry, target inode records
+                                         are included with reply */
+} __attribute__ ((packed));
+
+/* one for each node split */
+struct ceph_frag_tree_split {
+       __le32 frag;                   /* this frag splits... */
+       __le32 by;                     /* ...by this many bits */
+} __attribute__ ((packed));
+
+struct ceph_frag_tree_head {
+       __le32 nsplits;                /* num ceph_frag_tree_split records */
+       struct ceph_frag_tree_split splits[];
+} __attribute__ ((packed));
+
+/* capability issue, for bundling with mds reply */
+struct ceph_mds_reply_cap {
+       __le32 caps, wanted;           /* caps issued, wanted */
+       __le64 cap_id;
+       __le32 seq, mseq;
+       __le64 realm;                  /* snap realm */
+       __u8 flags;                    /* CEPH_CAP_FLAG_* */
+} __attribute__ ((packed));
+
+#define CEPH_CAP_FLAG_AUTH  1          /* cap is issued by auth mds */
+
+/* inode record, for bundling with mds reply */
+struct ceph_mds_reply_inode {
+       __le64 ino;
+       __le64 snapid;
+       __le32 rdev;
+       __le64 version;                /* inode version */
+       __le64 xattr_version;          /* version for xattr blob */
+       struct ceph_mds_reply_cap cap; /* caps issued for this inode */
+       struct ceph_file_layout layout;
+       struct ceph_timespec ctime, mtime, atime;
+       __le32 time_warp_seq;
+       __le64 size, max_size, truncate_size;
+       __le32 truncate_seq;
+       __le32 mode, uid, gid;
+       __le32 nlink;
+       __le64 files, subdirs, rbytes, rfiles, rsubdirs;  /* dir stats */
+       struct ceph_timespec rctime;
+       struct ceph_frag_tree_head fragtree;  /* (must be at end of struct) */
+} __attribute__ ((packed));
+/* followed by frag array, then symlink string, then xattr blob */
+
+/* reply_lease follows dname, and reply_inode */
+struct ceph_mds_reply_lease {
+       __le16 mask;            /* lease type(s) */
+       __le32 duration_ms;     /* lease duration */
+       __le32 seq;
+} __attribute__ ((packed));
+
+struct ceph_mds_reply_dirfrag {
+       __le32 frag;            /* fragment */
+       __le32 auth;            /* auth mds, if this is a delegation point */
+       __le32 ndist;           /* number of mds' this is replicated on */
+       __le32 dist[];
+} __attribute__ ((packed));
+
+/* file access modes */
+#define CEPH_FILE_MODE_PIN        0
+#define CEPH_FILE_MODE_RD         1
+#define CEPH_FILE_MODE_WR         2
+#define CEPH_FILE_MODE_RDWR       3  /* RD | WR */
+#define CEPH_FILE_MODE_LAZY       4  /* lazy io */
+#define CEPH_FILE_MODE_NUM        8  /* bc these are bit fields.. mostly */
+
+int ceph_flags_to_mode(int flags);
+
+
+/* capability bits */
+#define CEPH_CAP_PIN         1  /* no specific capabilities beyond the pin */
+
+/* generic cap bits */
+#define CEPH_CAP_GSHARED     1  /* client can reads */
+#define CEPH_CAP_GEXCL       2  /* client can read and update */
+#define CEPH_CAP_GCACHE      4  /* (file) client can cache reads */
+#define CEPH_CAP_GRD         8  /* (file) client can read */
+#define CEPH_CAP_GWR        16  /* (file) client can write */
+#define CEPH_CAP_GBUFFER    32  /* (file) client can buffer writes */
+#define CEPH_CAP_GWREXTEND  64  /* (file) client can extend EOF */
+#define CEPH_CAP_GLAZYIO   128  /* (file) client can perform lazy io */
+
+/* per-lock shift */
+#define CEPH_CAP_SAUTH      2
+#define CEPH_CAP_SLINK      4
+#define CEPH_CAP_SXATTR     6
+#define CEPH_CAP_SFILE      8   /* goes at the end (uses >2 cap bits) */
+
+#define CEPH_CAP_BITS       16
+
+/* composed values */
+#define CEPH_CAP_AUTH_SHARED  (CEPH_CAP_GSHARED  << CEPH_CAP_SAUTH)
+#define CEPH_CAP_AUTH_EXCL     (CEPH_CAP_GEXCL     << CEPH_CAP_SAUTH)
+#define CEPH_CAP_LINK_SHARED  (CEPH_CAP_GSHARED  << CEPH_CAP_SLINK)
+#define CEPH_CAP_LINK_EXCL     (CEPH_CAP_GEXCL     << CEPH_CAP_SLINK)
+#define CEPH_CAP_XATTR_SHARED (CEPH_CAP_GSHARED  << CEPH_CAP_SXATTR)
+#define CEPH_CAP_XATTR_EXCL    (CEPH_CAP_GEXCL     << CEPH_CAP_SXATTR)
+#define CEPH_CAP_FILE(x)    (x << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_SHARED   (CEPH_CAP_GSHARED   << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_EXCL     (CEPH_CAP_GEXCL     << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_CACHE    (CEPH_CAP_GCACHE    << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_RD       (CEPH_CAP_GRD       << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_WR       (CEPH_CAP_GWR       << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_BUFFER   (CEPH_CAP_GBUFFER   << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_WREXTEND (CEPH_CAP_GWREXTEND << CEPH_CAP_SFILE)
+#define CEPH_CAP_FILE_LAZYIO   (CEPH_CAP_GLAZYIO   << CEPH_CAP_SFILE)
+
+/* cap masks (for getattr) */
+#define CEPH_STAT_CAP_INODE    CEPH_CAP_PIN
+#define CEPH_STAT_CAP_TYPE     CEPH_CAP_PIN  /* mode >> 12 */
+#define CEPH_STAT_CAP_SYMLINK  CEPH_CAP_PIN
+#define CEPH_STAT_CAP_UID      CEPH_CAP_AUTH_SHARED
+#define CEPH_STAT_CAP_GID      CEPH_CAP_AUTH_SHARED
+#define CEPH_STAT_CAP_MODE     CEPH_CAP_AUTH_SHARED
+#define CEPH_STAT_CAP_NLINK    CEPH_CAP_LINK_SHARED
+#define CEPH_STAT_CAP_LAYOUT   CEPH_CAP_FILE_SHARED
+#define CEPH_STAT_CAP_MTIME    CEPH_CAP_FILE_SHARED
+#define CEPH_STAT_CAP_SIZE     CEPH_CAP_FILE_SHARED
+#define CEPH_STAT_CAP_ATIME    CEPH_CAP_FILE_SHARED  /* fixme */
+#define CEPH_STAT_CAP_XATTR    CEPH_CAP_XATTR_SHARED
+#define CEPH_STAT_CAP_INODE_ALL (CEPH_CAP_PIN |                        \
+                                CEPH_CAP_AUTH_SHARED | \
+                                CEPH_CAP_LINK_SHARED | \
+                                CEPH_CAP_FILE_SHARED | \
+                                CEPH_CAP_XATTR_SHARED)
+
+#define CEPH_CAP_ANY_SHARED (CEPH_CAP_AUTH_SHARED |                    \
+                             CEPH_CAP_LINK_SHARED |                    \
+                             CEPH_CAP_XATTR_SHARED |                   \
+                             CEPH_CAP_FILE_SHARED)
+#define CEPH_CAP_ANY_RD   (CEPH_CAP_ANY_SHARED | CEPH_CAP_FILE_RD |    \
+                          CEPH_CAP_FILE_CACHE)
+
+#define CEPH_CAP_ANY_EXCL (CEPH_CAP_AUTH_EXCL |                \
+                          CEPH_CAP_LINK_EXCL |         \
+                          CEPH_CAP_XATTR_EXCL |        \
+                          CEPH_CAP_FILE_EXCL)
+#define CEPH_CAP_ANY_FILE_WR (CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER |        \
+                             CEPH_CAP_FILE_EXCL)
+#define CEPH_CAP_ANY_WR   (CEPH_CAP_ANY_EXCL | CEPH_CAP_ANY_FILE_WR)
+#define CEPH_CAP_ANY      (CEPH_CAP_ANY_RD | CEPH_CAP_ANY_EXCL | \
+                          CEPH_CAP_ANY_FILE_WR | CEPH_CAP_PIN)
+
+#define CEPH_CAP_LOCKS (CEPH_LOCK_IFILE | CEPH_LOCK_IAUTH | CEPH_LOCK_ILINK | \
+                       CEPH_LOCK_IXATTR)
+
+int ceph_caps_for_mode(int mode);
+
+enum {
+       CEPH_CAP_OP_GRANT,         /* mds->client grant */
+       CEPH_CAP_OP_REVOKE,        /* mds->client revoke */
+       CEPH_CAP_OP_TRUNC,         /* mds->client trunc notify */
+       CEPH_CAP_OP_EXPORT,        /* mds has exported the cap */
+       CEPH_CAP_OP_IMPORT,        /* mds has imported the cap */
+       CEPH_CAP_OP_UPDATE,        /* client->mds update */
+       CEPH_CAP_OP_DROP,          /* client->mds drop cap bits */
+       CEPH_CAP_OP_FLUSH,         /* client->mds cap writeback */
+       CEPH_CAP_OP_FLUSH_ACK,     /* mds->client flushed */
+       CEPH_CAP_OP_FLUSHSNAP,     /* client->mds flush snapped metadata */
+       CEPH_CAP_OP_FLUSHSNAP_ACK, /* mds->client flushed snapped metadata */
+       CEPH_CAP_OP_RELEASE,       /* client->mds release (clean) cap */
+       CEPH_CAP_OP_RENEW,         /* client->mds renewal request */
+};
+
+extern const char *ceph_cap_op_name(int op);
+
+/*
+ * caps message, used for capability callbacks, acks, requests, etc.
+ */
+struct ceph_mds_caps {
+       __le32 op;                  /* CEPH_CAP_OP_* */
+       __le64 ino, realm;
+       __le64 cap_id;
+       __le32 seq, issue_seq;
+       __le32 caps, wanted, dirty; /* latest issued/wanted/dirty */
+       __le32 migrate_seq;
+       __le64 snap_follows;
+       __le32 snap_trace_len;
+
+       /* authlock */
+       __le32 uid, gid, mode;
+
+       /* linklock */
+       __le32 nlink;
+
+       /* xattrlock */
+       __le32 xattr_len;
+       __le64 xattr_version;
+
+       /* filelock */
+       __le64 size, max_size, truncate_size;
+       __le32 truncate_seq;
+       struct ceph_timespec mtime, atime, ctime;
+       struct ceph_file_layout layout;
+       __le32 time_warp_seq;
+} __attribute__ ((packed));
+
+/* cap release msg head */
+struct ceph_mds_cap_release {
+       __le32 num;                /* number of cap_items that follow */
+} __attribute__ ((packed));
+
+struct ceph_mds_cap_item {
+       __le64 ino;
+       __le64 cap_id;
+       __le32 migrate_seq, seq;
+} __attribute__ ((packed));
+
+#define CEPH_MDS_LEASE_REVOKE           1  /*    mds  -> client */
+#define CEPH_MDS_LEASE_RELEASE          2  /* client  -> mds    */
+#define CEPH_MDS_LEASE_RENEW            3  /* client <-> mds    */
+#define CEPH_MDS_LEASE_REVOKE_ACK       4  /* client  -> mds    */
+
+extern const char *ceph_lease_op_name(int o);
+
+/* lease msg header */
+struct ceph_mds_lease {
+       __u8 action;            /* CEPH_MDS_LEASE_* */
+       __le16 mask;            /* which lease */
+       __le64 ino;
+       __le64 first, last;     /* snap range */
+       __le32 seq;
+       __le32 duration_ms;     /* duration of renewal */
+} __attribute__ ((packed));
+/* followed by a __le32+string for dname */
+
+/* client reconnect */
+struct ceph_mds_cap_reconnect {
+       __le64 cap_id;
+       __le32 wanted;
+       __le32 issued;
+       __le64 size;
+       struct ceph_timespec mtime, atime;
+       __le64 snaprealm;
+       __le64 pathbase;        /* base ino for our path to this ino */
+} __attribute__ ((packed));
+/* followed by encoded string */
+
+struct ceph_mds_snaprealm_reconnect {
+       __le64 ino;     /* snap realm base */
+       __le64 seq;     /* snap seq for this snap realm */
+       __le64 parent;  /* parent realm */
+} __attribute__ ((packed));
+
+/*
+ * snaps
+ */
+enum {
+       CEPH_SNAP_OP_UPDATE,  /* CREATE or DESTROY */
+       CEPH_SNAP_OP_CREATE,
+       CEPH_SNAP_OP_DESTROY,
+       CEPH_SNAP_OP_SPLIT,
+};
+
+extern const char *ceph_snap_op_name(int o);
+
+/* snap msg header */
+struct ceph_mds_snap_head {
+       __le32 op;                /* CEPH_SNAP_OP_* */
+       __le64 split;             /* ino to split off, if any */
+       __le32 num_split_inos;    /* # inos belonging to new child realm */
+       __le32 num_split_realms;  /* # child realms udner new child realm */
+       __le32 trace_len;         /* size of snap trace blob */
+} __attribute__ ((packed));
+/* followed by split ino list, then split realms, then the trace blob */
+
+/*
+ * encode info about a snaprealm, as viewed by a client
+ */
+struct ceph_mds_snap_realm {
+       __le64 ino;           /* ino */
+       __le64 created;       /* snap: when created */
+       __le64 parent;        /* ino: parent realm */
+       __le64 parent_since;  /* snap: same parent since */
+       __le64 seq;           /* snap: version */
+       __le32 num_snaps;
+       __le32 num_prior_parent_snaps;
+} __attribute__ ((packed));
+/* followed by my snap list, then prior parent snap list */
+
+#endif
diff --git a/fs/ceph/ceph_hash.c b/fs/ceph/ceph_hash.c
new file mode 100644 (file)
index 0000000..bd57001
--- /dev/null
@@ -0,0 +1,118 @@
+
+#include "types.h"
+
+/*
+ * Robert Jenkin's hash function.
+ * http://burtleburtle.net/bob/hash/evahash.html
+ * This is in the public domain.
+ */
+#define mix(a, b, c)                                           \
+       do {                                                    \
+               a = a - b;  a = a - c;  a = a ^ (c >> 13);      \
+               b = b - c;  b = b - a;  b = b ^ (a << 8);       \
+               c = c - a;  c = c - b;  c = c ^ (b >> 13);      \
+               a = a - b;  a = a - c;  a = a ^ (c >> 12);      \
+               b = b - c;  b = b - a;  b = b ^ (a << 16);      \
+               c = c - a;  c = c - b;  c = c ^ (b >> 5);       \
+               a = a - b;  a = a - c;  a = a ^ (c >> 3);       \
+               b = b - c;  b = b - a;  b = b ^ (a << 10);      \
+               c = c - a;  c = c - b;  c = c ^ (b >> 15);      \
+       } while (0)
+
+unsigned ceph_str_hash_rjenkins(const char *str, unsigned length)
+{
+       const unsigned char *k = (const unsigned char *)str;
+       __u32 a, b, c;  /* the internal state */
+       __u32 len;      /* how many key bytes still need mixing */
+
+       /* Set up the internal state */
+       len = length;
+       a = 0x9e3779b9;      /* the golden ratio; an arbitrary value */
+       b = a;
+       c = 0;               /* variable initialization of internal state */
+
+       /* handle most of the key */
+       while (len >= 12) {
+               a = a + (k[0] + ((__u32)k[1] << 8) + ((__u32)k[2] << 16) +
+                        ((__u32)k[3] << 24));
+               b = b + (k[4] + ((__u32)k[5] << 8) + ((__u32)k[6] << 16) +
+                        ((__u32)k[7] << 24));
+               c = c + (k[8] + ((__u32)k[9] << 8) + ((__u32)k[10] << 16) +
+                        ((__u32)k[11] << 24));
+               mix(a, b, c);
+               k = k + 12;
+               len = len - 12;
+       }
+
+       /* handle the last 11 bytes */
+       c = c + length;
+       switch (len) {            /* all the case statements fall through */
+       case 11:
+               c = c + ((__u32)k[10] << 24);
+       case 10:
+               c = c + ((__u32)k[9] << 16);
+       case 9:
+               c = c + ((__u32)k[8] << 8);
+               /* the first byte of c is reserved for the length */
+       case 8:
+               b = b + ((__u32)k[7] << 24);
+       case 7:
+               b = b + ((__u32)k[6] << 16);
+       case 6:
+               b = b + ((__u32)k[5] << 8);
+       case 5:
+               b = b + k[4];
+       case 4:
+               a = a + ((__u32)k[3] << 24);
+       case 3:
+               a = a + ((__u32)k[2] << 16);
+       case 2:
+               a = a + ((__u32)k[1] << 8);
+       case 1:
+               a = a + k[0];
+               /* case 0: nothing left to add */
+       }
+       mix(a, b, c);
+
+       return c;
+}
+
+/*
+ * linux dcache hash
+ */
+unsigned ceph_str_hash_linux(const char *str, unsigned length)
+{
+       unsigned long hash = 0;
+       unsigned char c;
+
+       while (length--) {
+               c = *str++;
+               hash = (hash + (c << 4) + (c >> 4)) * 11;
+       }
+       return hash;
+}
+
+
+unsigned ceph_str_hash(int type, const char *s, unsigned len)
+{
+       switch (type) {
+       case CEPH_STR_HASH_LINUX:
+               return ceph_str_hash_linux(s, len);
+       case CEPH_STR_HASH_RJENKINS:
+               return ceph_str_hash_rjenkins(s, len);
+       default:
+               return -1;
+       }
+}
+
+const char *ceph_str_hash_name(int type)
+{
+       switch (type) {
+       case CEPH_STR_HASH_LINUX:
+               return "linux";
+       case CEPH_STR_HASH_RJENKINS:
+               return "rjenkins";
+       default:
+               return "unknown";
+       }
+}
diff --git a/fs/ceph/ceph_hash.h b/fs/ceph/ceph_hash.h
new file mode 100644 (file)
index 0000000..5ac470c
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _FS_CEPH_HASH_H
+#define _FS_CEPH_HASH_H
+
+#define CEPH_STR_HASH_LINUX      0x1  /* linux dcache hash */
+#define CEPH_STR_HASH_RJENKINS   0x2  /* robert jenkins' */
+
+extern unsigned ceph_str_hash_linux(const char *s, unsigned len);
+extern unsigned ceph_str_hash_rjenkins(const char *s, unsigned len);
+
+extern unsigned ceph_str_hash(int type, const char *s, unsigned len);
+extern const char *ceph_str_hash_name(int type);
+
+#endif
diff --git a/fs/ceph/ceph_strings.c b/fs/ceph/ceph_strings.c
new file mode 100644 (file)
index 0000000..8e4be6a
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Ceph string constants
+ */
+#include "types.h"
+
+const char *ceph_entity_type_name(int type)
+{
+       switch (type) {
+       case CEPH_ENTITY_TYPE_MDS: return "mds";
+       case CEPH_ENTITY_TYPE_OSD: return "osd";
+       case CEPH_ENTITY_TYPE_MON: return "mon";
+       case CEPH_ENTITY_TYPE_CLIENT: return "client";
+       case CEPH_ENTITY_TYPE_ADMIN: return "admin";
+       case CEPH_ENTITY_TYPE_AUTH: return "auth";
+       default: return "unknown";
+       }
+}
+
+const char *ceph_osd_op_name(int op)
+{
+       switch (op) {
+       case CEPH_OSD_OP_READ: return "read";
+       case CEPH_OSD_OP_STAT: return "stat";
+
+       case CEPH_OSD_OP_MASKTRUNC: return "masktrunc";
+
+       case CEPH_OSD_OP_WRITE: return "write";
+       case CEPH_OSD_OP_DELETE: return "delete";
+       case CEPH_OSD_OP_TRUNCATE: return "truncate";
+       case CEPH_OSD_OP_ZERO: return "zero";
+       case CEPH_OSD_OP_WRITEFULL: return "writefull";
+
+       case CEPH_OSD_OP_APPEND: return "append";
+       case CEPH_OSD_OP_STARTSYNC: return "startsync";
+       case CEPH_OSD_OP_SETTRUNC: return "settrunc";
+       case CEPH_OSD_OP_TRIMTRUNC: return "trimtrunc";
+
+       case CEPH_OSD_OP_TMAPUP: return "tmapup";
+       case CEPH_OSD_OP_TMAPGET: return "tmapget";
+       case CEPH_OSD_OP_TMAPPUT: return "tmapput";
+
+       case CEPH_OSD_OP_GETXATTR: return "getxattr";
+       case CEPH_OSD_OP_GETXATTRS: return "getxattrs";
+       case CEPH_OSD_OP_SETXATTR: return "setxattr";
+       case CEPH_OSD_OP_SETXATTRS: return "setxattrs";
+       case CEPH_OSD_OP_RESETXATTRS: return "resetxattrs";
+       case CEPH_OSD_OP_RMXATTR: return "rmxattr";
+
+       case CEPH_OSD_OP_PULL: return "pull";
+       case CEPH_OSD_OP_PUSH: return "push";
+       case CEPH_OSD_OP_BALANCEREADS: return "balance-reads";
+       case CEPH_OSD_OP_UNBALANCEREADS: return "unbalance-reads";
+       case CEPH_OSD_OP_SCRUB: return "scrub";
+
+       case CEPH_OSD_OP_WRLOCK: return "wrlock";
+       case CEPH_OSD_OP_WRUNLOCK: return "wrunlock";
+       case CEPH_OSD_OP_RDLOCK: return "rdlock";
+       case CEPH_OSD_OP_RDUNLOCK: return "rdunlock";
+       case CEPH_OSD_OP_UPLOCK: return "uplock";
+       case CEPH_OSD_OP_DNLOCK: return "dnlock";
+
+       case CEPH_OSD_OP_CALL: return "call";
+
+       case CEPH_OSD_OP_PGLS: return "pgls";
+       }
+       return "???";
+}
+
+const char *ceph_mds_state_name(int s)
+{
+       switch (s) {
+               /* down and out */
+       case CEPH_MDS_STATE_DNE:        return "down:dne";
+       case CEPH_MDS_STATE_STOPPED:    return "down:stopped";
+               /* up and out */
+       case CEPH_MDS_STATE_BOOT:       return "up:boot";
+       case CEPH_MDS_STATE_STANDBY:    return "up:standby";
+       case CEPH_MDS_STATE_STANDBY_REPLAY:    return "up:standby-replay";
+       case CEPH_MDS_STATE_CREATING:   return "up:creating";
+       case CEPH_MDS_STATE_STARTING:   return "up:starting";
+               /* up and in */
+       case CEPH_MDS_STATE_REPLAY:     return "up:replay";
+       case CEPH_MDS_STATE_RESOLVE:    return "up:resolve";
+       case CEPH_MDS_STATE_RECONNECT:  return "up:reconnect";
+       case CEPH_MDS_STATE_REJOIN:     return "up:rejoin";
+       case CEPH_MDS_STATE_CLIENTREPLAY: return "up:clientreplay";
+       case CEPH_MDS_STATE_ACTIVE:     return "up:active";
+       case CEPH_MDS_STATE_STOPPING:   return "up:stopping";
+       }
+       return "???";
+}
+
+const char *ceph_session_op_name(int op)
+{
+       switch (op) {
+       case CEPH_SESSION_REQUEST_OPEN: return "request_open";
+       case CEPH_SESSION_OPEN: return "open";
+       case CEPH_SESSION_REQUEST_CLOSE: return "request_close";
+       case CEPH_SESSION_CLOSE: return "close";
+       case CEPH_SESSION_REQUEST_RENEWCAPS: return "request_renewcaps";
+       case CEPH_SESSION_RENEWCAPS: return "renewcaps";
+       case CEPH_SESSION_STALE: return "stale";
+       case CEPH_SESSION_RECALL_STATE: return "recall_state";
+       }
+       return "???";
+}
+
+const char *ceph_mds_op_name(int op)
+{
+       switch (op) {
+       case CEPH_MDS_OP_LOOKUP:  return "lookup";
+       case CEPH_MDS_OP_LOOKUPHASH:  return "lookuphash";
+       case CEPH_MDS_OP_LOOKUPPARENT:  return "lookupparent";
+       case CEPH_MDS_OP_GETATTR:  return "getattr";
+       case CEPH_MDS_OP_SETXATTR: return "setxattr";
+       case CEPH_MDS_OP_SETATTR: return "setattr";
+       case CEPH_MDS_OP_RMXATTR: return "rmxattr";
+       case CEPH_MDS_OP_READDIR: return "readdir";
+       case CEPH_MDS_OP_MKNOD: return "mknod";
+       case CEPH_MDS_OP_LINK: return "link";
+       case CEPH_MDS_OP_UNLINK: return "unlink";
+       case CEPH_MDS_OP_RENAME: return "rename";
+       case CEPH_MDS_OP_MKDIR: return "mkdir";
+       case CEPH_MDS_OP_RMDIR: return "rmdir";
+       case CEPH_MDS_OP_SYMLINK: return "symlink";
+       case CEPH_MDS_OP_CREATE: return "create";
+       case CEPH_MDS_OP_OPEN: return "open";
+       case CEPH_MDS_OP_LOOKUPSNAP: return "lookupsnap";
+       case CEPH_MDS_OP_LSSNAP: return "lssnap";
+       case CEPH_MDS_OP_MKSNAP: return "mksnap";
+       case CEPH_MDS_OP_RMSNAP: return "rmsnap";
+       }
+       return "???";
+}
+
+const char *ceph_cap_op_name(int op)
+{
+       switch (op) {
+       case CEPH_CAP_OP_GRANT: return "grant";
+       case CEPH_CAP_OP_REVOKE: return "revoke";
+       case CEPH_CAP_OP_TRUNC: return "trunc";
+       case CEPH_CAP_OP_EXPORT: return "export";
+       case CEPH_CAP_OP_IMPORT: return "import";
+       case CEPH_CAP_OP_UPDATE: return "update";
+       case CEPH_CAP_OP_DROP: return "drop";
+       case CEPH_CAP_OP_FLUSH: return "flush";
+       case CEPH_CAP_OP_FLUSH_ACK: return "flush_ack";
+       case CEPH_CAP_OP_FLUSHSNAP: return "flushsnap";
+       case CEPH_CAP_OP_FLUSHSNAP_ACK: return "flushsnap_ack";
+       case CEPH_CAP_OP_RELEASE: return "release";
+       case CEPH_CAP_OP_RENEW: return "renew";
+       }
+       return "???";
+}
+
+const char *ceph_lease_op_name(int o)
+{
+       switch (o) {
+       case CEPH_MDS_LEASE_REVOKE: return "revoke";
+       case CEPH_MDS_LEASE_RELEASE: return "release";
+       case CEPH_MDS_LEASE_RENEW: return "renew";
+       case CEPH_MDS_LEASE_REVOKE_ACK: return "revoke_ack";
+       }
+       return "???";
+}
+
+const char *ceph_snap_op_name(int o)
+{
+       switch (o) {
+       case CEPH_SNAP_OP_UPDATE: return "update";
+       case CEPH_SNAP_OP_CREATE: return "create";
+       case CEPH_SNAP_OP_DESTROY: return "destroy";
+       case CEPH_SNAP_OP_SPLIT: return "split";
+       }
+       return "???";
+}
diff --git a/fs/ceph/crush/crush.c b/fs/ceph/crush/crush.c
new file mode 100644 (file)
index 0000000..fabd302
--- /dev/null
@@ -0,0 +1,151 @@
+
+#ifdef __KERNEL__
+# include <linux/slab.h>
+#else
+# include <stdlib.h>
+# include <assert.h>
+# define kfree(x) do { if (x) free(x); } while (0)
+# define BUG_ON(x) assert(!(x))
+#endif
+
+#include "crush.h"
+
+const char *crush_bucket_alg_name(int alg)
+{
+       switch (alg) {
+       case CRUSH_BUCKET_UNIFORM: return "uniform";
+       case CRUSH_BUCKET_LIST: return "list";
+       case CRUSH_BUCKET_TREE: return "tree";
+       case CRUSH_BUCKET_STRAW: return "straw";
+       default: return "unknown";
+       }
+}
+
+/**
+ * crush_get_bucket_item_weight - Get weight of an item in given bucket
+ * @b: bucket pointer
+ * @p: item index in bucket
+ */
+int crush_get_bucket_item_weight(struct crush_bucket *b, int p)
+{
+       if (p >= b->size)
+               return 0;
+
+       switch (b->alg) {
+       case CRUSH_BUCKET_UNIFORM:
+               return ((struct crush_bucket_uniform *)b)->item_weight;
+       case CRUSH_BUCKET_LIST:
+               return ((struct crush_bucket_list *)b)->item_weights[p];
+       case CRUSH_BUCKET_TREE:
+               if (p & 1)
+                       return ((struct crush_bucket_tree *)b)->node_weights[p];
+               return 0;
+       case CRUSH_BUCKET_STRAW:
+               return ((struct crush_bucket_straw *)b)->item_weights[p];
+       }
+       return 0;
+}
+
+/**
+ * crush_calc_parents - Calculate parent vectors for the given crush map.
+ * @map: crush_map pointer
+ */
+void crush_calc_parents(struct crush_map *map)
+{
+       int i, b, c;
+
+       for (b = 0; b < map->max_buckets; b++) {
+               if (map->buckets[b] == NULL)
+                       continue;
+               for (i = 0; i < map->buckets[b]->size; i++) {
+                       c = map->buckets[b]->items[i];
+                       BUG_ON(c >= map->max_devices ||
+                              c < -map->max_buckets);
+                       if (c >= 0)
+                               map->device_parents[c] = map->buckets[b]->id;
+                       else
+                               map->bucket_parents[-1-c] = map->buckets[b]->id;
+               }
+       }
+}
+
+void crush_destroy_bucket_uniform(struct crush_bucket_uniform *b)
+{
+       kfree(b->h.perm);
+       kfree(b->h.items);
+       kfree(b);
+}
+
+void crush_destroy_bucket_list(struct crush_bucket_list *b)
+{
+       kfree(b->item_weights);
+       kfree(b->sum_weights);
+       kfree(b->h.perm);
+       kfree(b->h.items);
+       kfree(b);
+}
+
+void crush_destroy_bucket_tree(struct crush_bucket_tree *b)
+{
+       kfree(b->node_weights);
+       kfree(b);
+}
+
+void crush_destroy_bucket_straw(struct crush_bucket_straw *b)
+{
+       kfree(b->straws);
+       kfree(b->item_weights);
+       kfree(b->h.perm);
+       kfree(b->h.items);
+       kfree(b);
+}
+
+void crush_destroy_bucket(struct crush_bucket *b)
+{
+       switch (b->alg) {
+       case CRUSH_BUCKET_UNIFORM:
+               crush_destroy_bucket_uniform((struct crush_bucket_uniform *)b);
+               break;
+       case CRUSH_BUCKET_LIST:
+               crush_destroy_bucket_list((struct crush_bucket_list *)b);
+               break;
+       case CRUSH_BUCKET_TREE:
+               crush_destroy_bucket_tree((struct crush_bucket_tree *)b);
+               break;
+       case CRUSH_BUCKET_STRAW:
+               crush_destroy_bucket_straw((struct crush_bucket_straw *)b);
+               break;
+       }
+}
+
+/**
+ * crush_destroy - Destroy a crush_map
+ * @map: crush_map pointer
+ */
+void crush_destroy(struct crush_map *map)
+{
+       int b;
+
+       /* buckets */
+       if (map->buckets) {
+               for (b = 0; b < map->max_buckets; b++) {
+                       if (map->buckets[b] == NULL)
+                               continue;
+                       crush_destroy_bucket(map->buckets[b]);
+               }
+               kfree(map->buckets);
+       }
+
+       /* rules */
+       if (map->rules) {
+               for (b = 0; b < map->max_rules; b++)
+                       kfree(map->rules[b]);
+               kfree(map->rules);
+       }
+
+       kfree(map->bucket_parents);
+       kfree(map->device_parents);
+       kfree(map);
+}
+
+
diff --git a/fs/ceph/crush/crush.h b/fs/ceph/crush/crush.h
new file mode 100644 (file)
index 0000000..dcd7e75
--- /dev/null
@@ -0,0 +1,180 @@
+#ifndef _CRUSH_CRUSH_H
+#define _CRUSH_CRUSH_H
+
+#include <linux/types.h>
+
+/*
+ * CRUSH is a pseudo-random data distribution algorithm that
+ * efficiently distributes input values (typically, data objects)
+ * across a heterogeneous, structured storage cluster.
+ *
+ * The algorithm was originally described in detail in this paper
+ * (although the algorithm has evolved somewhat since then):
+ *
+ *     http://www.ssrc.ucsc.edu/Papers/weil-sc06.pdf
+ *
+ * LGPL2
+ */
+
+
+#define CRUSH_MAGIC 0x00010000ul   /* for detecting algorithm revisions */
+
+
+#define CRUSH_MAX_DEPTH 10  /* max crush hierarchy depth */
+#define CRUSH_MAX_SET   10  /* max size of a mapping result */
+
+
+/*
+ * CRUSH uses user-defined "rules" to describe how inputs should be
+ * mapped to devices.  A rule consists of sequence of steps to perform
+ * to generate the set of output devices.
+ */
+struct crush_rule_step {
+       __u32 op;
+       __s32 arg1;
+       __s32 arg2;
+};
+
+/* step op codes */
+enum {
+       CRUSH_RULE_NOOP = 0,
+       CRUSH_RULE_TAKE = 1,          /* arg1 = value to start with */
+       CRUSH_RULE_CHOOSE_FIRSTN = 2, /* arg1 = num items to pick */
+                                     /* arg2 = type */
+       CRUSH_RULE_CHOOSE_INDEP = 3,  /* same */
+       CRUSH_RULE_EMIT = 4,          /* no args */
+       CRUSH_RULE_CHOOSE_LEAF_FIRSTN = 6,
+       CRUSH_RULE_CHOOSE_LEAF_INDEP = 7,
+};
+
+/*
+ * for specifying choose num (arg1) relative to the max parameter
+ * passed to do_rule
+ */
+#define CRUSH_CHOOSE_N            0
+#define CRUSH_CHOOSE_N_MINUS(x)   (-(x))
+
+/*
+ * The rule mask is used to describe what the rule is intended for.
+ * Given a ruleset and size of output set, we search through the
+ * rule list for a matching rule_mask.
+ */
+struct crush_rule_mask {
+       __u8 ruleset;
+       __u8 type;
+       __u8 min_size;
+       __u8 max_size;
+};
+
+struct crush_rule {
+       __u32 len;
+       struct crush_rule_mask mask;
+       struct crush_rule_step steps[0];
+};
+
+#define crush_rule_size(len) (sizeof(struct crush_rule) + \
+                             (len)*sizeof(struct crush_rule_step))
+
+
+
+/*
+ * A bucket is a named container of other items (either devices or
+ * other buckets).  Items within a bucket are chosen using one of a
+ * few different algorithms.  The table summarizes how the speed of
+ * each option measures up against mapping stability when items are
+ * added or removed.
+ *
+ *  Bucket Alg     Speed       Additions    Removals
+ *  ------------------------------------------------
+ *  uniform         O(1)       poor         poor
+ *  list            O(n)       optimal      poor
+ *  tree            O(log n)   good         good
+ *  straw           O(n)       optimal      optimal
+ */
+enum {
+       CRUSH_BUCKET_UNIFORM = 1,
+       CRUSH_BUCKET_LIST = 2,
+       CRUSH_BUCKET_TREE = 3,
+       CRUSH_BUCKET_STRAW = 4
+};
+extern const char *crush_bucket_alg_name(int alg);
+
+struct crush_bucket {
+       __s32 id;        /* this'll be negative */
+       __u16 type;      /* non-zero; type=0 is reserved for devices */
+       __u8 alg;        /* one of CRUSH_BUCKET_* */
+       __u8 hash;       /* which hash function to use, CRUSH_HASH_* */
+       __u32 weight;    /* 16-bit fixed point */
+       __u32 size;      /* num items */
+       __s32 *items;
+
+       /*
+        * cached random permutation: used for uniform bucket and for
+        * the linear search fallback for the other bucket types.
+        */
+       __u32 perm_x;  /* @x for which *perm is defined */
+       __u32 perm_n;  /* num elements of *perm that are permuted/defined */
+       __u32 *perm;
+};
+
+struct crush_bucket_uniform {
+       struct crush_bucket h;
+       __u32 item_weight;  /* 16-bit fixed point; all items equally weighted */
+};
+
+struct crush_bucket_list {
+       struct crush_bucket h;
+       __u32 *item_weights;  /* 16-bit fixed point */
+       __u32 *sum_weights;   /* 16-bit fixed point.  element i is sum
+                                of weights 0..i, inclusive */
+};
+
+struct crush_bucket_tree {
+       struct crush_bucket h;  /* note: h.size is _tree_ size, not number of
+                                  actual items */
+       __u8 num_nodes;
+       __u32 *node_weights;
+};
+
+struct crush_bucket_straw {
+       struct crush_bucket h;
+       __u32 *item_weights;   /* 16-bit fixed point */
+       __u32 *straws;         /* 16-bit fixed point */
+};
+
+
+
+/*
+ * CRUSH map includes all buckets, rules, etc.
+ */
+struct crush_map {
+       struct crush_bucket **buckets;
+       struct crush_rule **rules;
+
+       /*
+        * Parent pointers to identify the parent bucket a device or
+        * bucket in the hierarchy.  If an item appears more than
+        * once, this is the _last_ time it appeared (where buckets
+        * are processed in bucket id order, from -1 on down to
+        * -max_buckets.
+        */
+       __u32 *bucket_parents;
+       __u32 *device_parents;
+
+       __s32 max_buckets;
+       __u32 max_rules;
+       __s32 max_devices;
+};
+
+
+/* crush.c */
+extern int crush_get_bucket_item_weight(struct crush_bucket *b, int pos);
+extern void crush_calc_parents(struct crush_map *map);
+extern void crush_destroy_bucket_uniform(struct crush_bucket_uniform *b);
+extern void crush_destroy_bucket_list(struct crush_bucket_list *b);
+extern void crush_destroy_bucket_tree(struct crush_bucket_tree *b);
+extern void crush_destroy_bucket_straw(struct crush_bucket_straw *b);
+extern void crush_destroy_bucket(struct crush_bucket *b);
+extern void crush_destroy(struct crush_map *map);
+
+#endif
diff --git a/fs/ceph/crush/hash.c b/fs/ceph/crush/hash.c
new file mode 100644 (file)
index 0000000..5873aed
--- /dev/null
@@ -0,0 +1,149 @@
+
+#include <linux/types.h>
+#include "hash.h"
+
+/*
+ * Robert Jenkins' function for mixing 32-bit values
+ * http://burtleburtle.net/bob/hash/evahash.html
+ * a, b = random bits, c = input and output
+ */
+#define crush_hashmix(a, b, c) do {                    \
+               a = a-b;  a = a-c;  a = a^(c>>13);      \
+               b = b-c;  b = b-a;  b = b^(a<<8);       \
+               c = c-a;  c = c-b;  c = c^(b>>13);      \
+               a = a-b;  a = a-c;  a = a^(c>>12);      \
+               b = b-c;  b = b-a;  b = b^(a<<16);      \
+               c = c-a;  c = c-b;  c = c^(b>>5);       \
+               a = a-b;  a = a-c;  a = a^(c>>3);       \
+               b = b-c;  b = b-a;  b = b^(a<<10);      \
+               c = c-a;  c = c-b;  c = c^(b>>15);      \
+       } while (0)
+
+#define crush_hash_seed 1315423911
+
+static __u32 crush_hash32_rjenkins1(__u32 a)
+{
+       __u32 hash = crush_hash_seed ^ a;
+       __u32 b = a;
+       __u32 x = 231232;
+       __u32 y = 1232;
+       crush_hashmix(b, x, hash);
+       crush_hashmix(y, a, hash);
+       return hash;
+}
+
+static __u32 crush_hash32_rjenkins1_2(__u32 a, __u32 b)
+{
+       __u32 hash = crush_hash_seed ^ a ^ b;
+       __u32 x = 231232;
+       __u32 y = 1232;
+       crush_hashmix(a, b, hash);
+       crush_hashmix(x, a, hash);
+       crush_hashmix(b, y, hash);
+       return hash;
+}
+
+static __u32 crush_hash32_rjenkins1_3(__u32 a, __u32 b, __u32 c)
+{
+       __u32 hash = crush_hash_seed ^ a ^ b ^ c;
+       __u32 x = 231232;
+       __u32 y = 1232;
+       crush_hashmix(a, b, hash);
+       crush_hashmix(c, x, hash);
+       crush_hashmix(y, a, hash);
+       crush_hashmix(b, x, hash);
+       crush_hashmix(y, c, hash);
+       return hash;
+}
+
+static __u32 crush_hash32_rjenkins1_4(__u32 a, __u32 b, __u32 c, __u32 d)
+{
+       __u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d;
+       __u32 x = 231232;
+       __u32 y = 1232;
+       crush_hashmix(a, b, hash);
+       crush_hashmix(c, d, hash);
+       crush_hashmix(a, x, hash);
+       crush_hashmix(y, b, hash);
+       crush_hashmix(c, x, hash);
+       crush_hashmix(y, d, hash);
+       return hash;
+}
+
+static __u32 crush_hash32_rjenkins1_5(__u32 a, __u32 b, __u32 c, __u32 d,
+                                     __u32 e)
+{
+       __u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d ^ e;
+       __u32 x = 231232;
+       __u32 y = 1232;
+       crush_hashmix(a, b, hash);
+       crush_hashmix(c, d, hash);
+       crush_hashmix(e, x, hash);
+       crush_hashmix(y, a, hash);
+       crush_hashmix(b, x, hash);
+       crush_hashmix(y, c, hash);
+       crush_hashmix(d, x, hash);
+       crush_hashmix(y, e, hash);
+       return hash;
+}
+
+
+__u32 crush_hash32(int type, __u32 a)
+{
+       switch (type) {
+       case CRUSH_HASH_RJENKINS1:
+               return crush_hash32_rjenkins1(a);
+       default:
+               return 0;
+       }
+}
+
+__u32 crush_hash32_2(int type, __u32 a, __u32 b)
+{
+       switch (type) {
+       case CRUSH_HASH_RJENKINS1:
+               return crush_hash32_rjenkins1_2(a, b);
+       default:
+               return 0;
+       }
+}
+
+__u32 crush_hash32_3(int type, __u32 a, __u32 b, __u32 c)
+{
+       switch (type) {
+       case CRUSH_HASH_RJENKINS1:
+               return crush_hash32_rjenkins1_3(a, b, c);
+       default:
+               return 0;
+       }
+}
+
+__u32 crush_hash32_4(int type, __u32 a, __u32 b, __u32 c, __u32 d)
+{
+       switch (type) {
+       case CRUSH_HASH_RJENKINS1:
+               return crush_hash32_rjenkins1_4(a, b, c, d);
+       default:
+               return 0;
+       }
+}
+
+__u32 crush_hash32_5(int type, __u32 a, __u32 b, __u32 c, __u32 d, __u32 e)
+{
+       switch (type) {
+       case CRUSH_HASH_RJENKINS1:
+               return crush_hash32_rjenkins1_5(a, b, c, d, e);
+       default:
+               return 0;
+       }
+}
+
+const char *crush_hash_name(int type)
+{
+       switch (type) {
+       case CRUSH_HASH_RJENKINS1:
+               return "rjenkins1";
+       default:
+               return "unknown";
+       }
+}
diff --git a/fs/ceph/crush/hash.h b/fs/ceph/crush/hash.h
new file mode 100644 (file)
index 0000000..ff48e11
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _CRUSH_HASH_H
+#define _CRUSH_HASH_H
+
+#define CRUSH_HASH_RJENKINS1   0
+
+#define CRUSH_HASH_DEFAULT CRUSH_HASH_RJENKINS1
+
+extern const char *crush_hash_name(int type);
+
+extern __u32 crush_hash32(int type, __u32 a);
+extern __u32 crush_hash32_2(int type, __u32 a, __u32 b);
+extern __u32 crush_hash32_3(int type, __u32 a, __u32 b, __u32 c);
+extern __u32 crush_hash32_4(int type, __u32 a, __u32 b, __u32 c, __u32 d);
+extern __u32 crush_hash32_5(int type, __u32 a, __u32 b, __u32 c, __u32 d,
+                           __u32 e);
+
+#endif
diff --git a/fs/ceph/crush/mapper.c b/fs/ceph/crush/mapper.c
new file mode 100644 (file)
index 0000000..9ba54ef
--- /dev/null
@@ -0,0 +1,596 @@
+
+#ifdef __KERNEL__
+# include <linux/string.h>
+# include <linux/slab.h>
+# include <linux/bug.h>
+# include <linux/kernel.h>
+# ifndef dprintk
+#  define dprintk(args...)
+# endif
+#else
+# include <string.h>
+# include <stdio.h>
+# include <stdlib.h>
+# include <assert.h>
+# define BUG_ON(x) assert(!(x))
+# define dprintk(args...) /* printf(args) */
+# define kmalloc(x, f) malloc(x)
+# define kfree(x) free(x)
+#endif
+
+#include "crush.h"
+#include "hash.h"
+
+/*
+ * Implement the core CRUSH mapping algorithm.
+ */
+
+/**
+ * crush_find_rule - find a crush_rule id for a given ruleset, type, and size.
+ * @map: the crush_map
+ * @ruleset: the storage ruleset id (user defined)
+ * @type: storage ruleset type (user defined)
+ * @size: output set size
+ */
+int crush_find_rule(struct crush_map *map, int ruleset, int type, int size)
+{
+       int i;
+
+       for (i = 0; i < map->max_rules; i++) {
+               if (map->rules[i] &&
+                   map->rules[i]->mask.ruleset == ruleset &&
+                   map->rules[i]->mask.type == type &&
+                   map->rules[i]->mask.min_size <= size &&
+                   map->rules[i]->mask.max_size >= size)
+                       return i;
+       }
+       return -1;
+}
+
+
+/*
+ * bucket choose methods
+ *
+ * For each bucket algorithm, we have a "choose" method that, given a
+ * crush input @x and replica position (usually, position in output set) @r,
+ * will produce an item in the bucket.
+ */
+
+/*
+ * Choose based on a random permutation of the bucket.
+ *
+ * We used to use some prime number arithmetic to do this, but it
+ * wasn't very random, and had some other bad behaviors.  Instead, we
+ * calculate an actual random permutation of the bucket members.
+ * Since this is expensive, we optimize for the r=0 case, which
+ * captures the vast majority of calls.
+ */
+static int bucket_perm_choose(struct crush_bucket *bucket,
+                             int x, int r)
+{
+       unsigned pr = r % bucket->size;
+       unsigned i, s;
+
+       /* start a new permutation if @x has changed */
+       if (bucket->perm_x != x || bucket->perm_n == 0) {
+               dprintk("bucket %d new x=%d\n", bucket->id, x);
+               bucket->perm_x = x;
+
+               /* optimize common r=0 case */
+               if (pr == 0) {
+                       s = crush_hash32_3(bucket->hash, x, bucket->id, 0) %
+                               bucket->size;
+                       bucket->perm[0] = s;
+                       bucket->perm_n = 0xffff;   /* magic value, see below */
+                       goto out;
+               }
+
+               for (i = 0; i < bucket->size; i++)
+                       bucket->perm[i] = i;
+               bucket->perm_n = 0;
+       } else if (bucket->perm_n == 0xffff) {
+               /* clean up after the r=0 case above */
+               for (i = 1; i < bucket->size; i++)
+                       bucket->perm[i] = i;
+               bucket->perm[bucket->perm[0]] = 0;
+               bucket->perm_n = 1;
+       }
+
+       /* calculate permutation up to pr */
+       for (i = 0; i < bucket->perm_n; i++)
+               dprintk(" perm_choose have %d: %d\n", i, bucket->perm[i]);
+       while (bucket->perm_n <= pr) {
+               unsigned p = bucket->perm_n;
+               /* no point in swapping the final entry */
+               if (p < bucket->size - 1) {
+                       i = crush_hash32_3(bucket->hash, x, bucket->id, p) %
+                               (bucket->size - p);
+                       if (i) {
+                               unsigned t = bucket->perm[p + i];
+                               bucket->perm[p + i] = bucket->perm[p];
+                               bucket->perm[p] = t;
+                       }
+                       dprintk(" perm_choose swap %d with %d\n", p, p+i);
+               }
+               bucket->perm_n++;
+       }
+       for (i = 0; i < bucket->size; i++)
+               dprintk(" perm_choose  %d: %d\n", i, bucket->perm[i]);
+
+       s = bucket->perm[pr];
+out:
+       dprintk(" perm_choose %d sz=%d x=%d r=%d (%d) s=%d\n", bucket->id,
+               bucket->size, x, r, pr, s);
+       return bucket->items[s];
+}
+
+/* uniform */
+static int bucket_uniform_choose(struct crush_bucket_uniform *bucket,
+                                int x, int r)
+{
+       return bucket_perm_choose(&bucket->h, x, r);
+}
+
+/* list */
+static int bucket_list_choose(struct crush_bucket_list *bucket,
+                             int x, int r)
+{
+       int i;
+
+       for (i = bucket->h.size-1; i >= 0; i--) {
+               __u64 w = crush_hash32_4(bucket->h.hash,x, bucket->h.items[i],
+                                        r, bucket->h.id);
+               w &= 0xffff;
+               dprintk("list_choose i=%d x=%d r=%d item %d weight %x "
+                       "sw %x rand %llx",
+                       i, x, r, bucket->h.items[i], bucket->item_weights[i],
+                       bucket->sum_weights[i], w);
+               w *= bucket->sum_weights[i];
+               w = w >> 16;
+               /*dprintk(" scaled %llx\n", w);*/
+               if (w < bucket->item_weights[i])
+                       return bucket->h.items[i];
+       }
+
+       BUG_ON(1);
+       return 0;
+}
+
+
+/* (binary) tree */
+static int height(int n)
+{
+       int h = 0;
+       while ((n & 1) == 0) {
+               h++;
+               n = n >> 1;
+       }
+       return h;
+}
+
+static int left(int x)
+{
+       int h = height(x);
+       return x - (1 << (h-1));
+}
+
+static int right(int x)
+{
+       int h = height(x);
+       return x + (1 << (h-1));
+}
+
+static int terminal(int x)
+{
+       return x & 1;
+}
+
+static int bucket_tree_choose(struct crush_bucket_tree *bucket,
+                             int x, int r)
+{
+       int n, l;
+       __u32 w;
+       __u64 t;
+
+       /* start at root */
+       n = bucket->num_nodes >> 1;
+
+       while (!terminal(n)) {
+               /* pick point in [0, w) */
+               w = bucket->node_weights[n];
+               t = (__u64)crush_hash32_4(bucket->h.hash, x, n, r,
+                                         bucket->h.id) * (__u64)w;
+               t = t >> 32;
+
+               /* descend to the left or right? */
+               l = left(n);
+               if (t < bucket->node_weights[l])
+                       n = l;
+               else
+                       n = right(n);
+       }
+
+       return bucket->h.items[n >> 1];
+}
+
+
+/* straw */
+
+static int bucket_straw_choose(struct crush_bucket_straw *bucket,
+                              int x, int r)
+{
+       int i;
+       int high = 0;
+       __u64 high_draw = 0;
+       __u64 draw;
+
+       for (i = 0; i < bucket->h.size; i++) {
+               draw = crush_hash32_3(bucket->h.hash, x, bucket->h.items[i], r);
+               draw &= 0xffff;
+               draw *= bucket->straws[i];
+               if (i == 0 || draw > high_draw) {
+                       high = i;
+                       high_draw = draw;
+               }
+       }
+       return bucket->h.items[high];
+}
+
+static int crush_bucket_choose(struct crush_bucket *in, int x, int r)
+{
+       dprintk("choose %d x=%d r=%d\n", in->id, x, r);
+       switch (in->alg) {
+       case CRUSH_BUCKET_UNIFORM:
+               return bucket_uniform_choose((struct crush_bucket_uniform *)in,
+                                         x, r);
+       case CRUSH_BUCKET_LIST:
+               return bucket_list_choose((struct crush_bucket_list *)in,
+                                         x, r);
+       case CRUSH_BUCKET_TREE:
+               return bucket_tree_choose((struct crush_bucket_tree *)in,
+                                         x, r);
+       case CRUSH_BUCKET_STRAW:
+               return bucket_straw_choose((struct crush_bucket_straw *)in,
+                                          x, r);
+       default:
+               BUG_ON(1);
+               return in->items[0];
+       }
+}
+
+/*
+ * true if device is marked "out" (failed, fully offloaded)
+ * of the cluster
+ */
+static int is_out(struct crush_map *map, __u32 *weight, int item, int x)
+{
+       if (weight[item] >= 0x1000)
+               return 0;
+       if (weight[item] == 0)
+               return 1;
+       if ((crush_hash32_2(CRUSH_HASH_RJENKINS1, x, item) & 0xffff)
+           < weight[item])
+               return 0;
+       return 1;
+}
+
+/**
+ * crush_choose - choose numrep distinct items of given type
+ * @map: the crush_map
+ * @bucket: the bucket we are choose an item from
+ * @x: crush input value
+ * @numrep: the number of items to choose
+ * @type: the type of item to choose
+ * @out: pointer to output vector
+ * @outpos: our position in that vector
+ * @firstn: true if choosing "first n" items, false if choosing "indep"
+ * @recurse_to_leaf: true if we want one device under each item of given type
+ * @out2: second output vector for leaf items (if @recurse_to_leaf)
+ */
+static int crush_choose(struct crush_map *map,
+                       struct crush_bucket *bucket,
+                       __u32 *weight,
+                       int x, int numrep, int type,
+                       int *out, int outpos,
+                       int firstn, int recurse_to_leaf,
+                       int *out2)
+{
+       int rep;
+       int ftotal, flocal;
+       int retry_descent, retry_bucket, skip_rep;
+       struct crush_bucket *in = bucket;
+       int r;
+       int i;
+       int item = 0;
+       int itemtype;
+       int collide, reject;
+       const int orig_tries = 5; /* attempts before we fall back to search */
+       dprintk("choose bucket %d x %d outpos %d\n", bucket->id, x, outpos);
+
+       for (rep = outpos; rep < numrep; rep++) {
+               /* keep trying until we get a non-out, non-colliding item */
+               ftotal = 0;
+               skip_rep = 0;
+               do {
+                       retry_descent = 0;
+                       in = bucket;               /* initial bucket */
+
+                       /* choose through intervening buckets */
+                       flocal = 0;
+                       do {
+                               collide = 0;
+                               retry_bucket = 0;
+                               r = rep;
+                               if (in->alg == CRUSH_BUCKET_UNIFORM) {
+                                       /* be careful */
+                                       if (firstn || numrep >= in->size)
+                                               /* r' = r + f_total */
+                                               r += ftotal;
+                                       else if (in->size % numrep == 0)
+                                               /* r'=r+(n+1)*f_local */
+                                               r += (numrep+1) *
+                                                       (flocal+ftotal);
+                                       else
+                                               /* r' = r + n*f_local */
+                                               r += numrep * (flocal+ftotal);
+                               } else {
+                                       if (firstn)
+                                               /* r' = r + f_total */
+                                               r += ftotal;
+                                       else
+                                               /* r' = r + n*f_local */
+                                               r += numrep * (flocal+ftotal);
+                               }
+
+                               /* bucket choose */
+                               if (in->size == 0) {
+                                       reject = 1;
+                                       goto reject;
+                               }
+                               if (flocal >= (in->size>>1) &&
+                                   flocal > orig_tries)
+                                       item = bucket_perm_choose(in, x, r);
+                               else
+                                       item = crush_bucket_choose(in, x, r);
+                               BUG_ON(item >= map->max_devices);
+
+                               /* desired type? */
+                               if (item < 0)
+                                       itemtype = map->buckets[-1-item]->type;
+                               else
+                                       itemtype = 0;
+                               dprintk("  item %d type %d\n", item, itemtype);
+
+                               /* keep going? */
+                               if (itemtype != type) {
+                                       BUG_ON(item >= 0 ||
+                                              (-1-item) >= map->max_buckets);
+                                       in = map->buckets[-1-item];
+                                       continue;
+                               }
+
+                               /* collision? */
+                               for (i = 0; i < outpos; i++) {
+                                       if (out[i] == item) {
+                                               collide = 1;
+                                               break;
+                                       }
+                               }
+
+                               if (recurse_to_leaf &&
+                                   item < 0 &&
+                                   crush_choose(map, map->buckets[-1-item],
+                                                weight,
+                                                x, outpos+1, 0,
+                                                out2, outpos,
+                                                firstn, 0, NULL) <= outpos) {
+                                       reject = 1;
+                               } else {
+                                       /* out? */
+                                       if (itemtype == 0)
+                                               reject = is_out(map, weight,
+                                                               item, x);
+                                       else
+                                               reject = 0;
+                               }
+
+reject:
+                               if (reject || collide) {
+                                       ftotal++;
+                                       flocal++;
+
+                                       if (collide && flocal < 3)
+                                               /* retry locally a few times */
+                                               retry_bucket = 1;
+                                       else if (flocal < in->size + orig_tries)
+                                               /* exhaustive bucket search */
+                                               retry_bucket = 1;
+                                       else if (ftotal < 20)
+                                               /* then retry descent */
+                                               retry_descent = 1;
+                                       else
+                                               /* else give up */
+                                               skip_rep = 1;
+                                       dprintk("  reject %d  collide %d  "
+                                               "ftotal %d  flocal %d\n",
+                                               reject, collide, ftotal,
+                                               flocal);
+                               }
+                       } while (retry_bucket);
+               } while (retry_descent);
+
+               if (skip_rep) {
+                       dprintk("skip rep\n");
+                       continue;
+               }
+
+               dprintk("choose got %d\n", item);
+               out[outpos] = item;
+               outpos++;
+       }
+
+       dprintk("choose returns %d\n", outpos);
+       return outpos;
+}
+
+
+/**
+ * crush_do_rule - calculate a mapping with the given input and rule
+ * @map: the crush_map
+ * @ruleno: the rule id
+ * @x: hash input
+ * @result: pointer to result vector
+ * @result_max: maximum result size
+ * @force: force initial replica choice; -1 for none
+ */
+int crush_do_rule(struct crush_map *map,
+                 int ruleno, int x, int *result, int result_max,
+                 int force, __u32 *weight)
+{
+       int result_len;
+       int force_context[CRUSH_MAX_DEPTH];
+       int force_pos = -1;
+       int a[CRUSH_MAX_SET];
+       int b[CRUSH_MAX_SET];
+       int c[CRUSH_MAX_SET];
+       int recurse_to_leaf;
+       int *w;
+       int wsize = 0;
+       int *o;
+       int osize;
+       int *tmp;
+       struct crush_rule *rule;
+       int step;
+       int i, j;
+       int numrep;
+       int firstn;
+       int rc = -1;
+
+       BUG_ON(ruleno >= map->max_rules);
+
+       rule = map->rules[ruleno];
+       result_len = 0;
+       w = a;
+       o = b;
+
+       /*
+        * determine hierarchical context of force, if any.  note
+        * that this may or may not correspond to the specific types
+        * referenced by the crush rule.
+        */
+       if (force >= 0) {
+               if (force >= map->max_devices ||
+                   map->device_parents[force] == 0) {
+                       /*dprintk("CRUSH: forcefed device dne\n");*/
+                       rc = -1;  /* force fed device dne */
+                       goto out;
+               }
+               if (!is_out(map, weight, force, x)) {
+                       while (1) {
+                               force_context[++force_pos] = force;
+                               if (force >= 0)
+                                       force = map->device_parents[force];
+                               else
+                                       force = map->bucket_parents[-1-force];
+                               if (force == 0)
+                                       break;
+                       }
+               }
+       }
+
+       for (step = 0; step < rule->len; step++) {
+               firstn = 0;
+               switch (rule->steps[step].op) {
+               case CRUSH_RULE_TAKE:
+                       w[0] = rule->steps[step].arg1;
+                       if (force_pos >= 0) {
+                               BUG_ON(force_context[force_pos] != w[0]);
+                               force_pos--;
+                       }
+                       wsize = 1;
+                       break;
+
+               case CRUSH_RULE_CHOOSE_LEAF_FIRSTN:
+               case CRUSH_RULE_CHOOSE_FIRSTN:
+                       firstn = 1;
+               case CRUSH_RULE_CHOOSE_LEAF_INDEP:
+               case CRUSH_RULE_CHOOSE_INDEP:
+                       BUG_ON(wsize == 0);
+
+                       recurse_to_leaf =
+                               rule->steps[step].op ==
+                                CRUSH_RULE_CHOOSE_LEAF_FIRSTN ||
+                               rule->steps[step].op ==
+                               CRUSH_RULE_CHOOSE_LEAF_INDEP;
+
+                       /* reset output */
+                       osize = 0;
+
+                       for (i = 0; i < wsize; i++) {
+                               /*
+                                * see CRUSH_N, CRUSH_N_MINUS macros.
+                                * basically, numrep <= 0 means relative to
+                                * the provided result_max
+                                */
+                               numrep = rule->steps[step].arg1;
+                               if (numrep <= 0) {
+                                       numrep += result_max;
+                                       if (numrep <= 0)
+                                               continue;
+                               }
+                               j = 0;
+                               if (osize == 0 && force_pos >= 0) {
+                                       /* skip any intermediate types */
+                                       while (force_pos &&
+                                              force_context[force_pos] < 0 &&
+                                              rule->steps[step].arg2 !=
+                                              map->buckets[-1 -
+                                              force_context[force_pos]]->type)
+                                               force_pos--;
+                                       o[osize] = force_context[force_pos];
+                                       if (recurse_to_leaf)
+                                               c[osize] = force_context[0];
+                                       j++;
+                                       force_pos--;
+                               }
+                               osize += crush_choose(map,
+                                                     map->buckets[-1-w[i]],
+                                                     weight,
+                                                     x, numrep,
+                                                     rule->steps[step].arg2,
+                                                     o+osize, j,
+                                                     firstn,
+                                                     recurse_to_leaf, c+osize);
+                       }
+
+                       if (recurse_to_leaf)
+                               /* copy final _leaf_ values to output set */
+                               memcpy(o, c, osize*sizeof(*o));
+
+                       /* swap t and w arrays */
+                       tmp = o;
+                       o = w;
+                       w = tmp;
+                       wsize = osize;
+                       break;
+
+
+               case CRUSH_RULE_EMIT:
+                       for (i = 0; i < wsize && result_len < result_max; i++) {
+                               result[result_len] = w[i];
+                               result_len++;
+                       }
+                       wsize = 0;
+                       break;
+
+               default:
+                       BUG_ON(1);
+               }
+       }
+       rc = result_len;
+
+out:
+       return rc;
+}
+
+
diff --git a/fs/ceph/crush/mapper.h b/fs/ceph/crush/mapper.h
new file mode 100644 (file)
index 0000000..98e9004
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef _CRUSH_MAPPER_H
+#define _CRUSH_MAPPER_H
+
+/*
+ * CRUSH functions for find rules and then mapping an input to an
+ * output set.
+ *
+ * LGPL2
+ */
+
+#include "crush.h"
+
+extern int crush_find_rule(struct crush_map *map, int pool, int type, int size);
+extern int crush_do_rule(struct crush_map *map,
+                        int ruleno,
+                        int x, int *result, int result_max,
+                        int forcefeed,    /* -1 for none */
+                        __u32 *weights);
+
+#endif
diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c
new file mode 100644 (file)
index 0000000..f704b3b
--- /dev/null
@@ -0,0 +1,409 @@
+
+#include "ceph_debug.h"
+
+#include <linux/err.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <crypto/hash.h>
+
+#include "crypto.h"
+#include "decode.h"
+
+int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)
+{
+       if (*p + sizeof(u16) + sizeof(key->created) +
+           sizeof(u16) + key->len > end)
+               return -ERANGE;
+       ceph_encode_16(p, key->type);
+       ceph_encode_copy(p, &key->created, sizeof(key->created));
+       ceph_encode_16(p, key->len);
+       ceph_encode_copy(p, key->key, key->len);
+       return 0;
+}
+
+int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end)
+{
+       ceph_decode_need(p, end, 2*sizeof(u16) + sizeof(key->created), bad);
+       key->type = ceph_decode_16(p);
+       ceph_decode_copy(p, &key->created, sizeof(key->created));
+       key->len = ceph_decode_16(p);
+       ceph_decode_need(p, end, key->len, bad);
+       key->key = kmalloc(key->len, GFP_NOFS);
+       if (!key->key)
+               return -ENOMEM;
+       ceph_decode_copy(p, key->key, key->len);
+       return 0;
+
+bad:
+       dout("failed to decode crypto key\n");
+       return -EINVAL;
+}
+
+int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey)
+{
+       int inlen = strlen(inkey);
+       int blen = inlen * 3 / 4;
+       void *buf, *p;
+       int ret;
+
+       dout("crypto_key_unarmor %s\n", inkey);
+       buf = kmalloc(blen, GFP_NOFS);
+       if (!buf)
+               return -ENOMEM;
+       blen = ceph_unarmor(buf, inkey, inkey+inlen);
+       if (blen < 0) {
+               kfree(buf);
+               return blen;
+       }
+
+       p = buf;
+       ret = ceph_crypto_key_decode(key, &p, p + blen);
+       kfree(buf);
+       if (ret)
+               return ret;
+       dout("crypto_key_unarmor key %p type %d len %d\n", key,
+            key->type, key->len);
+       return 0;
+}
+
+
+
+#define AES_KEY_SIZE 16
+
+static struct crypto_blkcipher *ceph_crypto_alloc_cipher(void)
+{
+       return crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
+}
+
+const u8 *aes_iv = "cephsageyudagreg";
+
+int ceph_aes_encrypt(const void *key, int key_len, void *dst, size_t *dst_len,
+                    const void *src, size_t src_len)
+{
+       struct scatterlist sg_in[2], sg_out[1];
+       struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
+       struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 };
+       int ret;
+       void *iv;
+       int ivsize;
+       size_t zero_padding = (0x10 - (src_len & 0x0f));
+       char pad[16];
+
+       if (IS_ERR(tfm))
+               return PTR_ERR(tfm);
+
+       memset(pad, zero_padding, zero_padding);
+
+       *dst_len = src_len + zero_padding;
+
+       crypto_blkcipher_setkey((void *)tfm, key, key_len);
+       sg_init_table(sg_in, 2);
+       sg_set_buf(&sg_in[0], src, src_len);
+       sg_set_buf(&sg_in[1], pad, zero_padding);
+       sg_init_table(sg_out, 1);
+       sg_set_buf(sg_out, dst, *dst_len);
+       iv = crypto_blkcipher_crt(tfm)->iv;
+       ivsize = crypto_blkcipher_ivsize(tfm);
+
+       memcpy(iv, aes_iv, ivsize);
+       /*
+       print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
+                      key, key_len, 1);
+       print_hex_dump(KERN_ERR, "enc src: ", DUMP_PREFIX_NONE, 16, 1,
+                       src, src_len, 1);
+       print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
+                       pad, zero_padding, 1);
+       */
+       ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
+                                    src_len + zero_padding);
+       crypto_free_blkcipher(tfm);
+       if (ret < 0)
+               pr_err("ceph_aes_crypt failed %d\n", ret);
+       /*
+       print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
+                      dst, *dst_len, 1);
+       */
+       return 0;
+}
+
+int ceph_aes_encrypt2(const void *key, int key_len, void *dst, size_t *dst_len,
+                     const void *src1, size_t src1_len,
+                     const void *src2, size_t src2_len)
+{
+       struct scatterlist sg_in[3], sg_out[1];
+       struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
+       struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 };
+       int ret;
+       void *iv;
+       int ivsize;
+       size_t zero_padding = (0x10 - ((src1_len + src2_len) & 0x0f));
+       char pad[16];
+
+       if (IS_ERR(tfm))
+               return PTR_ERR(tfm);
+
+       memset(pad, zero_padding, zero_padding);
+
+       *dst_len = src1_len + src2_len + zero_padding;
+
+       crypto_blkcipher_setkey((void *)tfm, key, key_len);
+       sg_init_table(sg_in, 3);
+       sg_set_buf(&sg_in[0], src1, src1_len);
+       sg_set_buf(&sg_in[1], src2, src2_len);
+       sg_set_buf(&sg_in[2], pad, zero_padding);
+       sg_init_table(sg_out, 1);
+       sg_set_buf(sg_out, dst, *dst_len);
+       iv = crypto_blkcipher_crt(tfm)->iv;
+       ivsize = crypto_blkcipher_ivsize(tfm);
+
+       memcpy(iv, aes_iv, ivsize);
+       /*
+       print_hex_dump(KERN_ERR, "enc  key: ", DUMP_PREFIX_NONE, 16, 1,
+                      key, key_len, 1);
+       print_hex_dump(KERN_ERR, "enc src1: ", DUMP_PREFIX_NONE, 16, 1,
+                       src1, src1_len, 1);
+       print_hex_dump(KERN_ERR, "enc src2: ", DUMP_PREFIX_NONE, 16, 1,
+                       src2, src2_len, 1);
+       print_hex_dump(KERN_ERR, "enc  pad: ", DUMP_PREFIX_NONE, 16, 1,
+                       pad, zero_padding, 1);
+       */
+       ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
+                                    src1_len + src2_len + zero_padding);
+       crypto_free_blkcipher(tfm);
+       if (ret < 0)
+               pr_err("ceph_aes_crypt2 failed %d\n", ret);
+       /*
+       print_hex_dump(KERN_ERR, "enc  out: ", DUMP_PREFIX_NONE, 16, 1,
+                      dst, *dst_len, 1);
+       */
+       return 0;
+}
+
+int ceph_aes_decrypt(const void *key, int key_len, void *dst, size_t *dst_len,
+                    const void *src, size_t src_len)
+{
+       struct scatterlist sg_in[1], sg_out[2];
+       struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
+       struct blkcipher_desc desc = { .tfm = tfm };
+       char pad[16];
+       void *iv;
+       int ivsize;
+       int ret;
+       int last_byte;
+
+       if (IS_ERR(tfm))
+               return PTR_ERR(tfm);
+
+       crypto_blkcipher_setkey((void *)tfm, key, key_len);
+       sg_init_table(sg_in, 1);
+       sg_init_table(sg_out, 2);
+       sg_set_buf(sg_in, src, src_len);
+       sg_set_buf(&sg_out[0], dst, *dst_len);
+       sg_set_buf(&sg_out[1], pad, sizeof(pad));
+
+       iv = crypto_blkcipher_crt(tfm)->iv;
+       ivsize = crypto_blkcipher_ivsize(tfm);
+
+       memcpy(iv, aes_iv, ivsize);
+
+       /*
+       print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
+                      key, key_len, 1);
+       print_hex_dump(KERN_ERR, "dec  in: ", DUMP_PREFIX_NONE, 16, 1,
+                      src, src_len, 1);
+       */
+
+       ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len);
+       crypto_free_blkcipher(tfm);
+       if (ret < 0) {
+               pr_err("ceph_aes_decrypt failed %d\n", ret);
+               return ret;
+       }
+
+       if (src_len <= *dst_len)
+               last_byte = ((char *)dst)[src_len - 1];
+       else
+               last_byte = pad[src_len - *dst_len - 1];
+       if (last_byte <= 16 && src_len >= last_byte) {
+               *dst_len = src_len - last_byte;
+       } else {
+               pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
+                      last_byte, (int)src_len);
+               return -EPERM;  /* bad padding */
+       }
+       /*
+       print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1,
+                      dst, *dst_len, 1);
+       */
+       return 0;
+}
+
+int ceph_aes_decrypt2(const void *key, int key_len,
+                     void *dst1, size_t *dst1_len,
+                     void *dst2, size_t *dst2_len,
+                     const void *src, size_t src_len)
+{
+       struct scatterlist sg_in[1], sg_out[3];
+       struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
+       struct blkcipher_desc desc = { .tfm = tfm };
+       char pad[16];
+       void *iv;
+       int ivsize;
+       int ret;
+       int last_byte;
+
+       if (IS_ERR(tfm))
+               return PTR_ERR(tfm);
+
+       sg_init_table(sg_in, 1);
+       sg_set_buf(sg_in, src, src_len);
+       sg_init_table(sg_out, 3);
+       sg_set_buf(&sg_out[0], dst1, *dst1_len);
+       sg_set_buf(&sg_out[1], dst2, *dst2_len);
+       sg_set_buf(&sg_out[2], pad, sizeof(pad));
+
+       crypto_blkcipher_setkey((void *)tfm, key, key_len);
+       iv = crypto_blkcipher_crt(tfm)->iv;
+       ivsize = crypto_blkcipher_ivsize(tfm);
+
+       memcpy(iv, aes_iv, ivsize);
+
+       /*
+       print_hex_dump(KERN_ERR, "dec  key: ", DUMP_PREFIX_NONE, 16, 1,
+                      key, key_len, 1);
+       print_hex_dump(KERN_ERR, "dec   in: ", DUMP_PREFIX_NONE, 16, 1,
+                      src, src_len, 1);
+       */
+
+       ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len);
+       crypto_free_blkcipher(tfm);
+       if (ret < 0) {
+               pr_err("ceph_aes_decrypt failed %d\n", ret);
+               return ret;
+       }
+
+       if (src_len <= *dst1_len)
+               last_byte = ((char *)dst1)[src_len - 1];
+       else if (src_len <= *dst1_len + *dst2_len)
+               last_byte = ((char *)dst2)[src_len - *dst1_len - 1];
+       else
+               last_byte = pad[src_len - *dst1_len - *dst2_len - 1];
+       if (last_byte <= 16 && src_len >= last_byte) {
+               src_len -= last_byte;
+       } else {
+               pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
+                      last_byte, (int)src_len);
+               return -EPERM;  /* bad padding */
+       }
+
+       if (src_len < *dst1_len) {
+               *dst1_len = src_len;
+               *dst2_len = 0;
+       } else {
+               *dst2_len = src_len - *dst1_len;
+       }
+       /*
+       print_hex_dump(KERN_ERR, "dec  out1: ", DUMP_PREFIX_NONE, 16, 1,
+                      dst1, *dst1_len, 1);
+       print_hex_dump(KERN_ERR, "dec  out2: ", DUMP_PREFIX_NONE, 16, 1,
+                      dst2, *dst2_len, 1);
+       */
+
+       return 0;
+}
+
+
+int ceph_decrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
+                const void *src, size_t src_len)
+{
+       switch (secret->type) {
+       case CEPH_CRYPTO_NONE:
+               if (*dst_len < src_len)
+                       return -ERANGE;
+               memcpy(dst, src, src_len);
+               *dst_len = src_len;
+               return 0;
+
+       case CEPH_CRYPTO_AES:
+               return ceph_aes_decrypt(secret->key, secret->len, dst,
+                                       dst_len, src, src_len);
+
+       default:
+               return -EINVAL;
+       }
+}
+
+int ceph_decrypt2(struct ceph_crypto_key *secret,
+                       void *dst1, size_t *dst1_len,
+                       void *dst2, size_t *dst2_len,
+                       const void *src, size_t src_len)
+{
+       size_t t;
+
+       switch (secret->type) {
+       case CEPH_CRYPTO_NONE:
+               if (*dst1_len + *dst2_len < src_len)
+                       return -ERANGE;
+               t = min(*dst1_len, src_len);
+               memcpy(dst1, src, t);
+               *dst1_len = t;
+               src += t;
+               src_len -= t;
+               if (src_len) {
+                       t = min(*dst2_len, src_len);
+                       memcpy(dst2, src, t);
+                       *dst2_len = t;
+               }
+               return 0;
+
+       case CEPH_CRYPTO_AES:
+               return ceph_aes_decrypt2(secret->key, secret->len,
+                                        dst1, dst1_len, dst2, dst2_len,
+                                        src, src_len);
+
+       default:
+               return -EINVAL;
+       }
+}
+
+int ceph_encrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
+                const void *src, size_t src_len)
+{
+       switch (secret->type) {
+       case CEPH_CRYPTO_NONE:
+               if (*dst_len < src_len)
+                       return -ERANGE;
+               memcpy(dst, src, src_len);
+               *dst_len = src_len;
+               return 0;
+
+       case CEPH_CRYPTO_AES:
+               return ceph_aes_encrypt(secret->key, secret->len, dst,
+                                       dst_len, src, src_len);
+
+       default:
+               return -EINVAL;
+       }
+}
+
+int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
+                 const void *src1, size_t src1_len,
+                 const void *src2, size_t src2_len)
+{
+       switch (secret->type) {
+       case CEPH_CRYPTO_NONE:
+               if (*dst_len < src1_len + src2_len)
+                       return -ERANGE;
+               memcpy(dst, src1, src1_len);
+               memcpy(dst + src1_len, src2, src2_len);
+               *dst_len = src1_len + src2_len;
+               return 0;
+
+       case CEPH_CRYPTO_AES:
+               return ceph_aes_encrypt2(secret->key, secret->len, dst, dst_len,
+                                        src1, src1_len, src2, src2_len);
+
+       default:
+               return -EINVAL;
+       }
+}
diff --git a/fs/ceph/crypto.h b/fs/ceph/crypto.h
new file mode 100644 (file)
index 0000000..40b502e
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef _FS_CEPH_CRYPTO_H
+#define _FS_CEPH_CRYPTO_H
+
+#include "types.h"
+#include "buffer.h"
+
+/*
+ * cryptographic secret
+ */
+struct ceph_crypto_key {
+       int type;
+       struct ceph_timespec created;
+       int len;
+       void *key;
+};
+
+static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
+{
+       kfree(key->key);
+}
+
+extern int ceph_crypto_key_encode(struct ceph_crypto_key *key,
+                                 void **p, void *end);
+extern int ceph_crypto_key_decode(struct ceph_crypto_key *key,
+                                 void **p, void *end);
+extern int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *in);
+
+/* crypto.c */
+extern int ceph_decrypt(struct ceph_crypto_key *secret,
+                       void *dst, size_t *dst_len,
+                       const void *src, size_t src_len);
+extern int ceph_encrypt(struct ceph_crypto_key *secret,
+                       void *dst, size_t *dst_len,
+                       const void *src, size_t src_len);
+extern int ceph_decrypt2(struct ceph_crypto_key *secret,
+                       void *dst1, size_t *dst1_len,
+                       void *dst2, size_t *dst2_len,
+                       const void *src, size_t src_len);
+extern int ceph_encrypt2(struct ceph_crypto_key *secret,
+                        void *dst, size_t *dst_len,
+                        const void *src1, size_t src1_len,
+                        const void *src2, size_t src2_len);
+
+/* armor.c */
+extern int ceph_armor(char *dst, const void *src, const void *end);
+extern int ceph_unarmor(void *dst, const char *src, const char *end);
+
+#endif
diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c
new file mode 100644 (file)
index 0000000..f7048da
--- /dev/null
@@ -0,0 +1,484 @@
+#include "ceph_debug.h"
+
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/ctype.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#include "super.h"
+#include "mds_client.h"
+#include "mon_client.h"
+#include "auth.h"
+
+#ifdef CONFIG_DEBUG_FS
+
+/*
+ * Implement /sys/kernel/debug/ceph fun
+ *
+ * /sys/kernel/debug/ceph/client*  - an instance of the ceph client
+ *      .../osdmap      - current osdmap
+ *      .../mdsmap      - current mdsmap
+ *      .../monmap      - current monmap
+ *      .../osdc        - active osd requests
+ *      .../mdsc        - active mds requests
+ *      .../monc        - mon client state
+ *      .../dentry_lru  - dump contents of dentry lru
+ *      .../caps        - expose cap (reservation) stats
+ *      .../bdi         - symlink to ../../bdi/something
+ */
+
+static struct dentry *ceph_debugfs_dir;
+
+static int monmap_show(struct seq_file *s, void *p)
+{
+       int i;
+       struct ceph_client *client = s->private;
+
+       if (client->monc.monmap == NULL)
+               return 0;
+
+       seq_printf(s, "epoch %d\n", client->monc.monmap->epoch);
+       for (i = 0; i < client->monc.monmap->num_mon; i++) {
+               struct ceph_entity_inst *inst =
+                       &client->monc.monmap->mon_inst[i];
+
+               seq_printf(s, "\t%s%lld\t%s\n",
+                          ENTITY_NAME(inst->name),
+                          pr_addr(&inst->addr.in_addr));
+       }
+       return 0;
+}
+
+static int mdsmap_show(struct seq_file *s, void *p)
+{
+       int i;
+       struct ceph_client *client = s->private;
+
+       if (client->mdsc.mdsmap == NULL)
+               return 0;
+       seq_printf(s, "epoch %d\n", client->mdsc.mdsmap->m_epoch);
+       seq_printf(s, "root %d\n", client->mdsc.mdsmap->m_root);
+       seq_printf(s, "session_timeout %d\n",
+                      client->mdsc.mdsmap->m_session_timeout);
+       seq_printf(s, "session_autoclose %d\n",
+                      client->mdsc.mdsmap->m_session_autoclose);
+       for (i = 0; i < client->mdsc.mdsmap->m_max_mds; i++) {
+               struct ceph_entity_addr *addr =
+                       &client->mdsc.mdsmap->m_info[i].addr;
+               int state = client->mdsc.mdsmap->m_info[i].state;
+
+               seq_printf(s, "\tmds%d\t%s\t(%s)\n", i, pr_addr(&addr->in_addr),
+                              ceph_mds_state_name(state));
+       }
+       return 0;
+}
+
+static int osdmap_show(struct seq_file *s, void *p)
+{
+       int i;
+       struct ceph_client *client = s->private;
+       struct rb_node *n;
+
+       if (client->osdc.osdmap == NULL)
+               return 0;
+       seq_printf(s, "epoch %d\n", client->osdc.osdmap->epoch);
+       seq_printf(s, "flags%s%s\n",
+                  (client->osdc.osdmap->flags & CEPH_OSDMAP_NEARFULL) ?
+                  " NEARFULL" : "",
+                  (client->osdc.osdmap->flags & CEPH_OSDMAP_FULL) ?
+                  " FULL" : "");
+       for (n = rb_first(&client->osdc.osdmap->pg_pools); n; n = rb_next(n)) {
+               struct ceph_pg_pool_info *pool =
+                       rb_entry(n, struct ceph_pg_pool_info, node);
+               seq_printf(s, "pg_pool %d pg_num %d / %d, lpg_num %d / %d\n",
+                          pool->id, pool->v.pg_num, pool->pg_num_mask,
+                          pool->v.lpg_num, pool->lpg_num_mask);
+       }
+       for (i = 0; i < client->osdc.osdmap->max_osd; i++) {
+               struct ceph_entity_addr *addr =
+                       &client->osdc.osdmap->osd_addr[i];
+               int state = client->osdc.osdmap->osd_state[i];
+               char sb[64];
+
+               seq_printf(s, "\tosd%d\t%s\t%3d%%\t(%s)\n",
+                          i, pr_addr(&addr->in_addr),
+                          ((client->osdc.osdmap->osd_weight[i]*100) >> 16),
+                          ceph_osdmap_state_str(sb, sizeof(sb), state));
+       }
+       return 0;
+}
+
+static int monc_show(struct seq_file *s, void *p)
+{
+       struct ceph_client *client = s->private;
+       struct ceph_mon_statfs_request *req;
+       struct ceph_mon_client *monc = &client->monc;
+       struct rb_node *rp;
+
+       mutex_lock(&monc->mutex);
+
+       if (monc->have_mdsmap)
+               seq_printf(s, "have mdsmap %u\n", (unsigned)monc->have_mdsmap);
+       if (monc->have_osdmap)
+               seq_printf(s, "have osdmap %u\n", (unsigned)monc->have_osdmap);
+       if (monc->want_next_osdmap)
+               seq_printf(s, "want next osdmap\n");
+
+       for (rp = rb_first(&monc->statfs_request_tree); rp; rp = rb_next(rp)) {
+               req = rb_entry(rp, struct ceph_mon_statfs_request, node);
+               seq_printf(s, "%lld statfs\n", req->tid);
+       }
+
+       mutex_unlock(&monc->mutex);
+       return 0;
+}
+
+static int mdsc_show(struct seq_file *s, void *p)
+{
+       struct ceph_client *client = s->private;
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct ceph_mds_request *req;
+       struct rb_node *rp;
+       int pathlen;
+       u64 pathbase;
+       char *path;
+
+       mutex_lock(&mdsc->mutex);
+       for (rp = rb_first(&mdsc->request_tree); rp; rp = rb_next(rp)) {
+               req = rb_entry(rp, struct ceph_mds_request, r_node);
+
+               if (req->r_request)
+                       seq_printf(s, "%lld\tmds%d\t", req->r_tid, req->r_mds);
+               else
+                       seq_printf(s, "%lld\t(no request)\t", req->r_tid);
+
+               seq_printf(s, "%s", ceph_mds_op_name(req->r_op));
+
+               if (req->r_got_unsafe)
+                       seq_printf(s, "\t(unsafe)");
+               else
+                       seq_printf(s, "\t");
+
+               if (req->r_inode) {
+                       seq_printf(s, " #%llx", ceph_ino(req->r_inode));
+               } else if (req->r_dentry) {
+                       path = ceph_mdsc_build_path(req->r_dentry, &pathlen,
+                                                   &pathbase, 0);
+                       spin_lock(&req->r_dentry->d_lock);
+                       seq_printf(s, " #%llx/%.*s (%s)",
+                                  ceph_ino(req->r_dentry->d_parent->d_inode),
+                                  req->r_dentry->d_name.len,
+                                  req->r_dentry->d_name.name,
+                                  path ? path : "");
+                       spin_unlock(&req->r_dentry->d_lock);
+                       kfree(path);
+               } else if (req->r_path1) {
+                       seq_printf(s, " #%llx/%s", req->r_ino1.ino,
+                                  req->r_path1);
+               }
+
+               if (req->r_old_dentry) {
+                       path = ceph_mdsc_build_path(req->r_old_dentry, &pathlen,
+                                                   &pathbase, 0);
+                       spin_lock(&req->r_old_dentry->d_lock);
+                       seq_printf(s, " #%llx/%.*s (%s)",
+                          ceph_ino(req->r_old_dentry->d_parent->d_inode),
+                                  req->r_old_dentry->d_name.len,
+                                  req->r_old_dentry->d_name.name,
+                                  path ? path : "");
+                       spin_unlock(&req->r_old_dentry->d_lock);
+                       kfree(path);
+               } else if (req->r_path2) {
+                       if (req->r_ino2.ino)
+                               seq_printf(s, " #%llx/%s", req->r_ino2.ino,
+                                          req->r_path2);
+                       else
+                               seq_printf(s, " %s", req->r_path2);
+               }
+
+               seq_printf(s, "\n");
+       }
+       mutex_unlock(&mdsc->mutex);
+
+       return 0;
+}
+
+static int osdc_show(struct seq_file *s, void *pp)
+{
+       struct ceph_client *client = s->private;
+       struct ceph_osd_client *osdc = &client->osdc;
+       struct rb_node *p;
+
+       mutex_lock(&osdc->request_mutex);
+       for (p = rb_first(&osdc->requests); p; p = rb_next(p)) {
+               struct ceph_osd_request *req;
+               struct ceph_osd_request_head *head;
+               struct ceph_osd_op *op;
+               int num_ops;
+               int opcode, olen;
+               int i;
+
+               req = rb_entry(p, struct ceph_osd_request, r_node);
+
+               seq_printf(s, "%lld\tosd%d\t%d.%x\t", req->r_tid,
+                          req->r_osd ? req->r_osd->o_osd : -1,
+                          le32_to_cpu(req->r_pgid.pool),
+                          le16_to_cpu(req->r_pgid.ps));
+
+               head = req->r_request->front.iov_base;
+               op = (void *)(head + 1);
+
+               num_ops = le16_to_cpu(head->num_ops);
+               olen = le32_to_cpu(head->object_len);
+               seq_printf(s, "%.*s", olen,
+                          (const char *)(head->ops + num_ops));
+
+               if (req->r_reassert_version.epoch)
+                       seq_printf(s, "\t%u'%llu",
+                          (unsigned)le32_to_cpu(req->r_reassert_version.epoch),
+                          le64_to_cpu(req->r_reassert_version.version));
+               else
+                       seq_printf(s, "\t");
+
+               for (i = 0; i < num_ops; i++) {
+                       opcode = le16_to_cpu(op->op);
+                       seq_printf(s, "\t%s", ceph_osd_op_name(opcode));
+                       op++;
+               }
+
+               seq_printf(s, "\n");
+       }
+       mutex_unlock(&osdc->request_mutex);
+       return 0;
+}
+
+static int caps_show(struct seq_file *s, void *p)
+{
+       struct ceph_client *client = p;
+       int total, avail, used, reserved, min;
+
+       ceph_reservation_status(client, &total, &avail, &used, &reserved, &min);
+       seq_printf(s, "total\t\t%d\n"
+                  "avail\t\t%d\n"
+                  "used\t\t%d\n"
+                  "reserved\t%d\n"
+                  "min\t%d\n",
+                  total, avail, used, reserved, min);
+       return 0;
+}
+
+static int dentry_lru_show(struct seq_file *s, void *ptr)
+{
+       struct ceph_client *client = s->private;
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct ceph_dentry_info *di;
+
+       spin_lock(&mdsc->dentry_lru_lock);
+       list_for_each_entry(di, &mdsc->dentry_lru, lru) {
+               struct dentry *dentry = di->dentry;
+               seq_printf(s, "%p %p\t%.*s\n",
+                          di, dentry, dentry->d_name.len, dentry->d_name.name);
+       }
+       spin_unlock(&mdsc->dentry_lru_lock);
+
+       return 0;
+}
+
+#define DEFINE_SHOW_FUNC(name)                                                 \
+static int name##_open(struct inode *inode, struct file *file)         \
+{                                                                      \
+       struct seq_file *sf;                                            \
+       int ret;                                                        \
+                                                                       \
+       ret = single_open(file, name, NULL);                            \
+       sf = file->private_data;                                        \
+       sf->private = inode->i_private;                                 \
+       return ret;                                                     \
+}                                                                      \
+                                                                       \
+static const struct file_operations name##_fops = {                    \
+       .open           = name##_open,                                  \
+       .read           = seq_read,                                     \
+       .llseek         = seq_lseek,                                    \
+       .release        = single_release,                               \
+};
+
+DEFINE_SHOW_FUNC(monmap_show)
+DEFINE_SHOW_FUNC(mdsmap_show)
+DEFINE_SHOW_FUNC(osdmap_show)
+DEFINE_SHOW_FUNC(monc_show)
+DEFINE_SHOW_FUNC(mdsc_show)
+DEFINE_SHOW_FUNC(osdc_show)
+DEFINE_SHOW_FUNC(dentry_lru_show)
+DEFINE_SHOW_FUNC(caps_show)
+
+static int congestion_kb_set(void *data, u64 val)
+{
+       struct ceph_client *client = (struct ceph_client *)data;
+
+       if (client)
+               client->mount_args->congestion_kb = (int)val;
+
+       return 0;
+}
+
+static int congestion_kb_get(void *data, u64 *val)
+{
+       struct ceph_client *client = (struct ceph_client *)data;
+
+       if (client)
+               *val = (u64)client->mount_args->congestion_kb;
+
+       return 0;
+}
+
+
+DEFINE_SIMPLE_ATTRIBUTE(congestion_kb_fops, congestion_kb_get,
+                       congestion_kb_set, "%llu\n");
+
+int __init ceph_debugfs_init(void)
+{
+       ceph_debugfs_dir = debugfs_create_dir("ceph", NULL);
+       if (!ceph_debugfs_dir)
+               return -ENOMEM;
+       return 0;
+}
+
+void ceph_debugfs_cleanup(void)
+{
+       debugfs_remove(ceph_debugfs_dir);
+}
+
+int ceph_debugfs_client_init(struct ceph_client *client)
+{
+       int ret = 0;
+       char name[80];
+
+       snprintf(name, sizeof(name), FSID_FORMAT ".client%lld",
+                PR_FSID(&client->fsid), client->monc.auth->global_id);
+
+       client->debugfs_dir = debugfs_create_dir(name, ceph_debugfs_dir);
+       if (!client->debugfs_dir)
+               goto out;
+
+       client->monc.debugfs_file = debugfs_create_file("monc",
+                                                     0600,
+                                                     client->debugfs_dir,
+                                                     client,
+                                                     &monc_show_fops);
+       if (!client->monc.debugfs_file)
+               goto out;
+
+       client->mdsc.debugfs_file = debugfs_create_file("mdsc",
+                                                     0600,
+                                                     client->debugfs_dir,
+                                                     client,
+                                                     &mdsc_show_fops);
+       if (!client->mdsc.debugfs_file)
+               goto out;
+
+       client->osdc.debugfs_file = debugfs_create_file("osdc",
+                                                     0600,
+                                                     client->debugfs_dir,
+                                                     client,
+                                                     &osdc_show_fops);
+       if (!client->osdc.debugfs_file)
+               goto out;
+
+       client->debugfs_monmap = debugfs_create_file("monmap",
+                                       0600,
+                                       client->debugfs_dir,
+                                       client,
+                                       &monmap_show_fops);
+       if (!client->debugfs_monmap)
+               goto out;
+
+       client->debugfs_mdsmap = debugfs_create_file("mdsmap",
+                                       0600,
+                                       client->debugfs_dir,
+                                       client,
+                                       &mdsmap_show_fops);
+       if (!client->debugfs_mdsmap)
+               goto out;
+
+       client->debugfs_osdmap = debugfs_create_file("osdmap",
+                                       0600,
+                                       client->debugfs_dir,
+                                       client,
+                                       &osdmap_show_fops);
+       if (!client->debugfs_osdmap)
+               goto out;
+
+       client->debugfs_dentry_lru = debugfs_create_file("dentry_lru",
+                                       0600,
+                                       client->debugfs_dir,
+                                       client,
+                                       &dentry_lru_show_fops);
+       if (!client->debugfs_dentry_lru)
+               goto out;
+
+       client->debugfs_caps = debugfs_create_file("caps",
+                                                  0400,
+                                                  client->debugfs_dir,
+                                                  client,
+                                                  &caps_show_fops);
+       if (!client->debugfs_caps)
+               goto out;
+
+       client->debugfs_congestion_kb = debugfs_create_file("writeback_congestion_kb",
+                                                  0600,
+                                                  client->debugfs_dir,
+                                                  client,
+                                                  &congestion_kb_fops);
+       if (!client->debugfs_congestion_kb)
+               goto out;
+
+       sprintf(name, "../../bdi/%s", dev_name(client->sb->s_bdi->dev));
+       client->debugfs_bdi = debugfs_create_symlink("bdi", client->debugfs_dir,
+                                                    name);
+
+       return 0;
+
+out:
+       ceph_debugfs_client_cleanup(client);
+       return ret;
+}
+
+void ceph_debugfs_client_cleanup(struct ceph_client *client)
+{
+       debugfs_remove(client->debugfs_bdi);
+       debugfs_remove(client->debugfs_caps);
+       debugfs_remove(client->debugfs_dentry_lru);
+       debugfs_remove(client->debugfs_osdmap);
+       debugfs_remove(client->debugfs_mdsmap);
+       debugfs_remove(client->debugfs_monmap);
+       debugfs_remove(client->osdc.debugfs_file);
+       debugfs_remove(client->mdsc.debugfs_file);
+       debugfs_remove(client->monc.debugfs_file);
+       debugfs_remove(client->debugfs_congestion_kb);
+       debugfs_remove(client->debugfs_dir);
+}
+
+#else  // CONFIG_DEBUG_FS
+
+int __init ceph_debugfs_init(void)
+{
+       return 0;
+}
+
+void ceph_debugfs_cleanup(void)
+{
+}
+
+int ceph_debugfs_client_init(struct ceph_client *client)
+{
+       return 0;
+}
+
+void ceph_debugfs_client_cleanup(struct ceph_client *client)
+{
+}
+
+#endif  // CONFIG_DEBUG_FS
diff --git a/fs/ceph/decode.h b/fs/ceph/decode.h
new file mode 100644 (file)
index 0000000..65b3e02
--- /dev/null
@@ -0,0 +1,194 @@
+#ifndef __CEPH_DECODE_H
+#define __CEPH_DECODE_H
+
+#include <asm/unaligned.h>
+#include <linux/time.h>
+
+#include "types.h"
+
+/*
+ * in all cases,
+ *   void **p     pointer to position pointer
+ *   void *end    pointer to end of buffer (last byte + 1)
+ */
+
+static inline u64 ceph_decode_64(void **p)
+{
+       u64 v = get_unaligned_le64(*p);
+       *p += sizeof(u64);
+       return v;
+}
+static inline u32 ceph_decode_32(void **p)
+{
+       u32 v = get_unaligned_le32(*p);
+       *p += sizeof(u32);
+       return v;
+}
+static inline u16 ceph_decode_16(void **p)
+{
+       u16 v = get_unaligned_le16(*p);
+       *p += sizeof(u16);
+       return v;
+}
+static inline u8 ceph_decode_8(void **p)
+{
+       u8 v = *(u8 *)*p;
+       (*p)++;
+       return v;
+}
+static inline void ceph_decode_copy(void **p, void *pv, size_t n)
+{
+       memcpy(pv, *p, n);
+       *p += n;
+}
+
+/*
+ * bounds check input.
+ */
+#define ceph_decode_need(p, end, n, bad)               \
+       do {                                            \
+               if (unlikely(*(p) + (n) > (end)))       \
+                       goto bad;                       \
+       } while (0)
+
+#define ceph_decode_64_safe(p, end, v, bad)                    \
+       do {                                                    \
+               ceph_decode_need(p, end, sizeof(u64), bad);     \
+               v = ceph_decode_64(p);                          \
+       } while (0)
+#define ceph_decode_32_safe(p, end, v, bad)                    \
+       do {                                                    \
+               ceph_decode_need(p, end, sizeof(u32), bad);     \
+               v = ceph_decode_32(p);                          \
+       } while (0)
+#define ceph_decode_16_safe(p, end, v, bad)                    \
+       do {                                                    \
+               ceph_decode_need(p, end, sizeof(u16), bad);     \
+               v = ceph_decode_16(p);                          \
+       } while (0)
+#define ceph_decode_8_safe(p, end, v, bad)                     \
+       do {                                                    \
+               ceph_decode_need(p, end, sizeof(u8), bad);      \
+               v = ceph_decode_8(p);                           \
+       } while (0)
+
+#define ceph_decode_copy_safe(p, end, pv, n, bad)              \
+       do {                                                    \
+               ceph_decode_need(p, end, n, bad);               \
+               ceph_decode_copy(p, pv, n);                     \
+       } while (0)
+
+/*
+ * struct ceph_timespec <-> struct timespec
+ */
+static inline void ceph_decode_timespec(struct timespec *ts,
+                                       const struct ceph_timespec *tv)
+{
+       ts->tv_sec = le32_to_cpu(tv->tv_sec);
+       ts->tv_nsec = le32_to_cpu(tv->tv_nsec);
+}
+static inline void ceph_encode_timespec(struct ceph_timespec *tv,
+                                       const struct timespec *ts)
+{
+       tv->tv_sec = cpu_to_le32(ts->tv_sec);
+       tv->tv_nsec = cpu_to_le32(ts->tv_nsec);
+}
+
+/*
+ * sockaddr_storage <-> ceph_sockaddr
+ */
+static inline void ceph_encode_addr(struct ceph_entity_addr *a)
+{
+       a->in_addr.ss_family = htons(a->in_addr.ss_family);
+}
+static inline void ceph_decode_addr(struct ceph_entity_addr *a)
+{
+       a->in_addr.ss_family = ntohs(a->in_addr.ss_family);
+       WARN_ON(a->in_addr.ss_family == 512);
+}
+
+/*
+ * encoders
+ */
+static inline void ceph_encode_64(void **p, u64 v)
+{
+       put_unaligned_le64(v, (__le64 *)*p);
+       *p += sizeof(u64);
+}
+static inline void ceph_encode_32(void **p, u32 v)
+{
+       put_unaligned_le32(v, (__le32 *)*p);
+       *p += sizeof(u32);
+}
+static inline void ceph_encode_16(void **p, u16 v)
+{
+       put_unaligned_le16(v, (__le16 *)*p);
+       *p += sizeof(u16);
+}
+static inline void ceph_encode_8(void **p, u8 v)
+{
+       *(u8 *)*p = v;
+       (*p)++;
+}
+static inline void ceph_encode_copy(void **p, const void *s, int len)
+{
+       memcpy(*p, s, len);
+       *p += len;
+}
+
+/*
+ * filepath, string encoders
+ */
+static inline void ceph_encode_filepath(void **p, void *end,
+                                       u64 ino, const char *path)
+{
+       u32 len = path ? strlen(path) : 0;
+       BUG_ON(*p + sizeof(ino) + sizeof(len) + len > end);
+       ceph_encode_8(p, 1);
+       ceph_encode_64(p, ino);
+       ceph_encode_32(p, len);
+       if (len)
+               memcpy(*p, path, len);
+       *p += len;
+}
+
+static inline void ceph_encode_string(void **p, void *end,
+                                     const char *s, u32 len)
+{
+       BUG_ON(*p + sizeof(len) + len > end);
+       ceph_encode_32(p, len);
+       if (len)
+               memcpy(*p, s, len);
+       *p += len;
+}
+
+#define ceph_encode_need(p, end, n, bad)               \
+       do {                                            \
+               if (unlikely(*(p) + (n) > (end)))       \
+                       goto bad;                       \
+       } while (0)
+
+#define ceph_encode_64_safe(p, end, v, bad)                    \
+       do {                                                    \
+               ceph_encode_need(p, end, sizeof(u64), bad);     \
+               ceph_encode_64(p, v);                           \
+       } while (0)
+#define ceph_encode_32_safe(p, end, v, bad)                    \
+       do {                                                    \
+               ceph_encode_need(p, end, sizeof(u32), bad);     \
+               ceph_encode_32(p, v);                   \
+       } while (0)
+#define ceph_encode_16_safe(p, end, v, bad)                    \
+       do {                                                    \
+               ceph_encode_need(p, end, sizeof(u16), bad);     \
+               ceph_encode_16(p, v);                   \
+       } while (0)
+
+#define ceph_encode_copy_safe(p, end, pv, n, bad)              \
+       do {                                                    \
+               ceph_encode_need(p, end, n, bad);               \
+               ceph_encode_copy(p, pv, n);                     \
+       } while (0)
+
+
+#endif
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
new file mode 100644 (file)
index 0000000..650d2db
--- /dev/null
@@ -0,0 +1,1233 @@
+#include "ceph_debug.h"
+
+#include <linux/spinlock.h>
+#include <linux/fs_struct.h>
+#include <linux/namei.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+
+#include "super.h"
+
+/*
+ * Directory operations: readdir, lookup, create, link, unlink,
+ * rename, etc.
+ */
+
+/*
+ * Ceph MDS operations are specified in terms of a base ino and
+ * relative path.  Thus, the client can specify an operation on a
+ * specific inode (e.g., a getattr due to fstat(2)), or as a path
+ * relative to, say, the root directory.
+ *
+ * Normally, we limit ourselves to strict inode ops (no path component)
+ * or dentry operations (a single path component relative to an ino).  The
+ * exception to this is open_root_dentry(), which will open the mount
+ * point by name.
+ */
+
+const struct inode_operations ceph_dir_iops;
+const struct file_operations ceph_dir_fops;
+struct dentry_operations ceph_dentry_ops;
+
+/*
+ * Initialize ceph dentry state.
+ */
+int ceph_init_dentry(struct dentry *dentry)
+{
+       struct ceph_dentry_info *di;
+
+       if (dentry->d_fsdata)
+               return 0;
+
+       if (ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP)
+               dentry->d_op = &ceph_dentry_ops;
+       else if (ceph_snap(dentry->d_parent->d_inode) == CEPH_SNAPDIR)
+               dentry->d_op = &ceph_snapdir_dentry_ops;
+       else
+               dentry->d_op = &ceph_snap_dentry_ops;
+
+       di = kmem_cache_alloc(ceph_dentry_cachep, GFP_NOFS);
+       if (!di)
+               return -ENOMEM;          /* oh well */
+
+       spin_lock(&dentry->d_lock);
+       if (dentry->d_fsdata) /* lost a race */
+               goto out_unlock;
+       di->dentry = dentry;
+       di->lease_session = NULL;
+       dentry->d_fsdata = di;
+       dentry->d_time = jiffies;
+       ceph_dentry_lru_add(dentry);
+out_unlock:
+       spin_unlock(&dentry->d_lock);
+       return 0;
+}
+
+
+
+/*
+ * for readdir, we encode the directory frag and offset within that
+ * frag into f_pos.
+ */
+static unsigned fpos_frag(loff_t p)
+{
+       return p >> 32;
+}
+static unsigned fpos_off(loff_t p)
+{
+       return p & 0xffffffff;
+}
+
+/*
+ * When possible, we try to satisfy a readdir by peeking at the
+ * dcache.  We make this work by carefully ordering dentries on
+ * d_u.d_child when we initially get results back from the MDS, and
+ * falling back to a "normal" sync readdir if any dentries in the dir
+ * are dropped.
+ *
+ * I_COMPLETE tells indicates we have all dentries in the dir.  It is
+ * defined IFF we hold CEPH_CAP_FILE_SHARED (which will be revoked by
+ * the MDS if/when the directory is modified).
+ */
+static int __dcache_readdir(struct file *filp,
+                           void *dirent, filldir_t filldir)
+{
+       struct inode *inode = filp->f_dentry->d_inode;
+       struct ceph_file_info *fi = filp->private_data;
+       struct dentry *parent = filp->f_dentry;
+       struct inode *dir = parent->d_inode;
+       struct list_head *p;
+       struct dentry *dentry, *last;
+       struct ceph_dentry_info *di;
+       int err = 0;
+
+       /* claim ref on last dentry we returned */
+       last = fi->dentry;
+       fi->dentry = NULL;
+
+       dout("__dcache_readdir %p at %llu (last %p)\n", dir, filp->f_pos,
+            last);
+
+       spin_lock(&dcache_lock);
+
+       /* start at beginning? */
+       if (filp->f_pos == 2 || (last &&
+                                filp->f_pos < ceph_dentry(last)->offset)) {
+               if (list_empty(&parent->d_subdirs))
+                       goto out_unlock;
+               p = parent->d_subdirs.prev;
+               dout(" initial p %p/%p\n", p->prev, p->next);
+       } else {
+               p = last->d_u.d_child.prev;
+       }
+
+more:
+       dentry = list_entry(p, struct dentry, d_u.d_child);
+       di = ceph_dentry(dentry);
+       while (1) {
+               dout(" p %p/%p d_subdirs %p/%p\n", p->prev, p->next,
+                    parent->d_subdirs.prev, parent->d_subdirs.next);
+               if (p == &parent->d_subdirs) {
+                       fi->at_end = 1;
+                       goto out_unlock;
+               }
+               if (!d_unhashed(dentry) && dentry->d_inode &&
+                   ceph_snap(dentry->d_inode) != CEPH_SNAPDIR &&
+                   ceph_ino(dentry->d_inode) != CEPH_INO_CEPH &&
+                   filp->f_pos <= di->offset)
+                       break;
+               dout(" skipping %p %.*s at %llu (%llu)%s%s\n", dentry,
+                    dentry->d_name.len, dentry->d_name.name, di->offset,
+                    filp->f_pos, d_unhashed(dentry) ? " unhashed" : "",
+                    !dentry->d_inode ? " null" : "");
+               p = p->prev;
+               dentry = list_entry(p, struct dentry, d_u.d_child);
+               di = ceph_dentry(dentry);
+       }
+
+       atomic_inc(&dentry->d_count);
+       spin_unlock(&dcache_lock);
+       spin_unlock(&inode->i_lock);
+
+       dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, filp->f_pos,
+            dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode);
+       filp->f_pos = di->offset;
+       err = filldir(dirent, dentry->d_name.name,
+                     dentry->d_name.len, di->offset,
+                     dentry->d_inode->i_ino,
+                     dentry->d_inode->i_mode >> 12);
+
+       if (last) {
+               if (err < 0) {
+                       /* remember our position */
+                       fi->dentry = last;
+                       fi->next_offset = di->offset;
+               } else {
+                       dput(last);
+               }
+               last = NULL;
+       }
+
+       spin_lock(&inode->i_lock);
+       spin_lock(&dcache_lock);
+
+       last = dentry;
+
+       if (err < 0)
+               goto out_unlock;
+
+       p = p->prev;
+       filp->f_pos++;
+
+       /* make sure a dentry wasn't dropped while we didn't have dcache_lock */
+       if ((ceph_inode(dir)->i_ceph_flags & CEPH_I_COMPLETE))
+               goto more;
+       dout(" lost I_COMPLETE on %p; falling back to mds\n", dir);
+       err = -EAGAIN;
+
+out_unlock:
+       spin_unlock(&dcache_lock);
+
+       if (last) {
+               spin_unlock(&inode->i_lock);
+               dput(last);
+               spin_lock(&inode->i_lock);
+       }
+
+       return err;
+}
+
+/*
+ * make note of the last dentry we read, so we can
+ * continue at the same lexicographical point,
+ * regardless of what dir changes take place on the
+ * server.
+ */
+static int note_last_dentry(struct ceph_file_info *fi, const char *name,
+                           int len)
+{
+       kfree(fi->last_name);
+       fi->last_name = kmalloc(len+1, GFP_NOFS);
+       if (!fi->last_name)
+               return -ENOMEM;
+       memcpy(fi->last_name, name, len);
+       fi->last_name[len] = 0;
+       dout("note_last_dentry '%s'\n", fi->last_name);
+       return 0;
+}
+
+static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+       struct ceph_file_info *fi = filp->private_data;
+       struct inode *inode = filp->f_dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_client *client = ceph_inode_to_client(inode);
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       unsigned frag = fpos_frag(filp->f_pos);
+       int off = fpos_off(filp->f_pos);
+       int err;
+       u32 ftype;
+       struct ceph_mds_reply_info_parsed *rinfo;
+       const int max_entries = client->mount_args->max_readdir;
+
+       dout("readdir %p filp %p frag %u off %u\n", inode, filp, frag, off);
+       if (fi->at_end)
+               return 0;
+
+       /* always start with . and .. */
+       if (filp->f_pos == 0) {
+               /* note dir version at start of readdir so we can tell
+                * if any dentries get dropped */
+               fi->dir_release_count = ci->i_release_count;
+
+               dout("readdir off 0 -> '.'\n");
+               if (filldir(dirent, ".", 1, ceph_make_fpos(0, 0),
+                           inode->i_ino, inode->i_mode >> 12) < 0)
+                       return 0;
+               filp->f_pos = 1;
+               off = 1;
+       }
+       if (filp->f_pos == 1) {
+               dout("readdir off 1 -> '..'\n");
+               if (filldir(dirent, "..", 2, ceph_make_fpos(0, 1),
+                           filp->f_dentry->d_parent->d_inode->i_ino,
+                           inode->i_mode >> 12) < 0)
+                       return 0;
+               filp->f_pos = 2;
+               off = 2;
+       }
+
+       /* can we use the dcache? */
+       spin_lock(&inode->i_lock);
+       if ((filp->f_pos == 2 || fi->dentry) &&
+           !ceph_test_opt(client, NOASYNCREADDIR) &&
+           (ci->i_ceph_flags & CEPH_I_COMPLETE) &&
+           __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) {
+               err = __dcache_readdir(filp, dirent, filldir);
+               if (err != -EAGAIN) {
+                       spin_unlock(&inode->i_lock);
+                       return err;
+               }
+       }
+       spin_unlock(&inode->i_lock);
+       if (fi->dentry) {
+               err = note_last_dentry(fi, fi->dentry->d_name.name,
+                                      fi->dentry->d_name.len);
+               if (err)
+                       return err;
+               dput(fi->dentry);
+               fi->dentry = NULL;
+       }
+
+       /* proceed with a normal readdir */
+
+more:
+       /* do we have the correct frag content buffered? */
+       if (fi->frag != frag || fi->last_readdir == NULL) {
+               struct ceph_mds_request *req;
+               int op = ceph_snap(inode) == CEPH_SNAPDIR ?
+                       CEPH_MDS_OP_LSSNAP : CEPH_MDS_OP_READDIR;
+
+               /* discard old result, if any */
+               if (fi->last_readdir) {
+                       ceph_mdsc_put_request(fi->last_readdir);
+                       fi->last_readdir = NULL;
+               }
+
+               /* requery frag tree, as the frag topology may have changed */
+               frag = ceph_choose_frag(ceph_inode(inode), frag, NULL, NULL);
+
+               dout("readdir fetching %llx.%llx frag %x offset '%s'\n",
+                    ceph_vinop(inode), frag, fi->last_name);
+               req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
+               if (IS_ERR(req))
+                       return PTR_ERR(req);
+               req->r_inode = igrab(inode);
+               req->r_dentry = dget(filp->f_dentry);
+               /* hints to request -> mds selection code */
+               req->r_direct_mode = USE_AUTH_MDS;
+               req->r_direct_hash = ceph_frag_value(frag);
+               req->r_direct_is_hash = true;
+               req->r_path2 = kstrdup(fi->last_name, GFP_NOFS);
+               req->r_readdir_offset = fi->next_offset;
+               req->r_args.readdir.frag = cpu_to_le32(frag);
+               req->r_args.readdir.max_entries = cpu_to_le32(max_entries);
+               req->r_num_caps = max_entries + 1;
+               err = ceph_mdsc_do_request(mdsc, NULL, req);
+               if (err < 0) {
+                       ceph_mdsc_put_request(req);
+                       return err;
+               }
+               dout("readdir got and parsed readdir result=%d"
+                    " on frag %x, end=%d, complete=%d\n", err, frag,
+                    (int)req->r_reply_info.dir_end,
+                    (int)req->r_reply_info.dir_complete);
+
+               if (!req->r_did_prepopulate) {
+                       dout("readdir !did_prepopulate");
+                       fi->dir_release_count--;    /* preclude I_COMPLETE */
+               }
+
+               /* note next offset and last dentry name */
+               fi->offset = fi->next_offset;
+               fi->last_readdir = req;
+
+               if (req->r_reply_info.dir_end) {
+                       kfree(fi->last_name);
+                       fi->last_name = NULL;
+                       fi->next_offset = 0;
+               } else {
+                       rinfo = &req->r_reply_info;
+                       err = note_last_dentry(fi,
+                                      rinfo->dir_dname[rinfo->dir_nr-1],
+                                      rinfo->dir_dname_len[rinfo->dir_nr-1]);
+                       if (err)
+                               return err;
+                       fi->next_offset += rinfo->dir_nr;
+               }
+       }
+
+       rinfo = &fi->last_readdir->r_reply_info;
+       dout("readdir frag %x num %d off %d chunkoff %d\n", frag,
+            rinfo->dir_nr, off, fi->offset);
+       while (off - fi->offset >= 0 && off - fi->offset < rinfo->dir_nr) {
+               u64 pos = ceph_make_fpos(frag, off);
+               struct ceph_mds_reply_inode *in =
+                       rinfo->dir_in[off - fi->offset].in;
+               dout("readdir off %d (%d/%d) -> %lld '%.*s' %p\n",
+                    off, off - fi->offset, rinfo->dir_nr, pos,
+                    rinfo->dir_dname_len[off - fi->offset],
+                    rinfo->dir_dname[off - fi->offset], in);
+               BUG_ON(!in);
+               ftype = le32_to_cpu(in->mode) >> 12;
+               if (filldir(dirent,
+                           rinfo->dir_dname[off - fi->offset],
+                           rinfo->dir_dname_len[off - fi->offset],
+                           pos,
+                           le64_to_cpu(in->ino),
+                           ftype) < 0) {
+                       dout("filldir stopping us...\n");
+                       return 0;
+               }
+               off++;
+               filp->f_pos = pos + 1;
+       }
+
+       if (fi->last_name) {
+               ceph_mdsc_put_request(fi->last_readdir);
+               fi->last_readdir = NULL;
+               goto more;
+       }
+
+       /* more frags? */
+       if (!ceph_frag_is_rightmost(frag)) {
+               frag = ceph_frag_next(frag);
+               off = 0;
+               filp->f_pos = ceph_make_fpos(frag, off);
+               dout("readdir next frag is %x\n", frag);
+               goto more;
+       }
+       fi->at_end = 1;
+
+       /*
+        * if dir_release_count still matches the dir, no dentries
+        * were released during the whole readdir, and we should have
+        * the complete dir contents in our cache.
+        */
+       spin_lock(&inode->i_lock);
+       if (ci->i_release_count == fi->dir_release_count) {
+               dout(" marking %p complete\n", inode);
+               ci->i_ceph_flags |= CEPH_I_COMPLETE;
+               ci->i_max_offset = filp->f_pos;
+       }
+       spin_unlock(&inode->i_lock);
+
+       dout("readdir %p filp %p done.\n", inode, filp);
+       return 0;
+}
+
+static void reset_readdir(struct ceph_file_info *fi)
+{
+       if (fi->last_readdir) {
+               ceph_mdsc_put_request(fi->last_readdir);
+               fi->last_readdir = NULL;
+       }
+       kfree(fi->last_name);
+       fi->next_offset = 2;  /* compensate for . and .. */
+       if (fi->dentry) {
+               dput(fi->dentry);
+               fi->dentry = NULL;
+       }
+       fi->at_end = 0;
+}
+
+static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int origin)
+{
+       struct ceph_file_info *fi = file->private_data;
+       struct inode *inode = file->f_mapping->host;
+       loff_t old_offset = offset;
+       loff_t retval;
+
+       mutex_lock(&inode->i_mutex);
+       switch (origin) {
+       case SEEK_END:
+               offset += inode->i_size + 2;   /* FIXME */
+               break;
+       case SEEK_CUR:
+               offset += file->f_pos;
+       }
+       retval = -EINVAL;
+       if (offset >= 0 && offset <= inode->i_sb->s_maxbytes) {
+               if (offset != file->f_pos) {
+                       file->f_pos = offset;
+                       file->f_version = 0;
+                       fi->at_end = 0;
+               }
+               retval = offset;
+
+               /*
+                * discard buffered readdir content on seekdir(0), or
+                * seek to new frag, or seek prior to current chunk.
+                */
+               if (offset == 0 ||
+                   fpos_frag(offset) != fpos_frag(old_offset) ||
+                   fpos_off(offset) < fi->offset) {
+                       dout("dir_llseek dropping %p content\n", file);
+                       reset_readdir(fi);
+               }
+
+               /* bump dir_release_count if we did a forward seek */
+               if (offset > old_offset)
+                       fi->dir_release_count--;
+       }
+       mutex_unlock(&inode->i_mutex);
+       return retval;
+}
+
+/*
+ * Process result of a lookup/open request.
+ *
+ * Mainly, make sure we return the final req->r_dentry (if it already
+ * existed) in place of the original VFS-provided dentry when they
+ * differ.
+ *
+ * Gracefully handle the case where the MDS replies with -ENOENT and
+ * no trace (which it may do, at its discretion, e.g., if it doesn't
+ * care to issue a lease on the negative dentry).
+ */
+struct dentry *ceph_finish_lookup(struct ceph_mds_request *req,
+                                 struct dentry *dentry, int err)
+{
+       struct ceph_client *client = ceph_client(dentry->d_sb);
+       struct inode *parent = dentry->d_parent->d_inode;
+
+       /* .snap dir? */
+       if (err == -ENOENT &&
+           ceph_vino(parent).ino != CEPH_INO_ROOT && /* no .snap in root dir */
+           strcmp(dentry->d_name.name,
+                  client->mount_args->snapdir_name) == 0) {
+               struct inode *inode = ceph_get_snapdir(parent);
+               dout("ENOENT on snapdir %p '%.*s', linking to snapdir %p\n",
+                    dentry, dentry->d_name.len, dentry->d_name.name, inode);
+               BUG_ON(!d_unhashed(dentry));
+               d_add(dentry, inode);
+               err = 0;
+       }
+
+       if (err == -ENOENT) {
+               /* no trace? */
+               err = 0;
+               if (!req->r_reply_info.head->is_dentry) {
+                       dout("ENOENT and no trace, dentry %p inode %p\n",
+                            dentry, dentry->d_inode);
+                       if (dentry->d_inode) {
+                               d_drop(dentry);
+                               err = -ENOENT;
+                       } else {
+                               d_add(dentry, NULL);
+                       }
+               }
+       }
+       if (err)
+               dentry = ERR_PTR(err);
+       else if (dentry != req->r_dentry)
+               dentry = dget(req->r_dentry);   /* we got spliced */
+       else
+               dentry = NULL;
+       return dentry;
+}
+
+static int is_root_ceph_dentry(struct inode *inode, struct dentry *dentry)
+{
+       return ceph_ino(inode) == CEPH_INO_ROOT &&
+               strncmp(dentry->d_name.name, ".ceph", 5) == 0;
+}
+
+/*
+ * Look up a single dir entry.  If there is a lookup intent, inform
+ * the MDS so that it gets our 'caps wanted' value in a single op.
+ */
+static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
+                                 struct nameidata *nd)
+{
+       struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct ceph_mds_request *req;
+       int op;
+       int err;
+
+       dout("lookup %p dentry %p '%.*s'\n",
+            dir, dentry, dentry->d_name.len, dentry->d_name.name);
+
+       if (dentry->d_name.len > NAME_MAX)
+               return ERR_PTR(-ENAMETOOLONG);
+
+       err = ceph_init_dentry(dentry);
+       if (err < 0)
+               return ERR_PTR(err);
+
+       /* open (but not create!) intent? */
+       if (nd &&
+           (nd->flags & LOOKUP_OPEN) &&
+           (nd->flags & LOOKUP_CONTINUE) == 0 && /* only open last component */
+           !(nd->intent.open.flags & O_CREAT)) {
+               int mode = nd->intent.open.create_mode & ~current->fs->umask;
+               return ceph_lookup_open(dir, dentry, nd, mode, 1);
+       }
+
+       /* can we conclude ENOENT locally? */
+       if (dentry->d_inode == NULL) {
+               struct ceph_inode_info *ci = ceph_inode(dir);
+               struct ceph_dentry_info *di = ceph_dentry(dentry);
+
+               spin_lock(&dir->i_lock);
+               dout(" dir %p flags are %d\n", dir, ci->i_ceph_flags);
+               if (strncmp(dentry->d_name.name,
+                           client->mount_args->snapdir_name,
+                           dentry->d_name.len) &&
+                   !is_root_ceph_dentry(dir, dentry) &&
+                   (ci->i_ceph_flags & CEPH_I_COMPLETE) &&
+                   (__ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1))) {
+                       di->offset = ci->i_max_offset++;
+                       spin_unlock(&dir->i_lock);
+                       dout(" dir %p complete, -ENOENT\n", dir);
+                       d_add(dentry, NULL);
+                       di->lease_shared_gen = ci->i_shared_gen;
+                       return NULL;
+               }
+               spin_unlock(&dir->i_lock);
+       }
+
+       op = ceph_snap(dir) == CEPH_SNAPDIR ?
+               CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP;
+       req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS);
+       if (IS_ERR(req))
+               return ERR_PTR(PTR_ERR(req));
+       req->r_dentry = dget(dentry);
+       req->r_num_caps = 2;
+       /* we only need inode linkage */
+       req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE);
+       req->r_locked_dir = dir;
+       err = ceph_mdsc_do_request(mdsc, NULL, req);
+       dentry = ceph_finish_lookup(req, dentry, err);
+       ceph_mdsc_put_request(req);  /* will dput(dentry) */
+       dout("lookup result=%p\n", dentry);
+       return dentry;
+}
+
+/*
+ * If we do a create but get no trace back from the MDS, follow up with
+ * a lookup (the VFS expects us to link up the provided dentry).
+ */
+int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry)
+{
+       struct dentry *result = ceph_lookup(dir, dentry, NULL);
+
+       if (result && !IS_ERR(result)) {
+               /*
+                * We created the item, then did a lookup, and found
+                * it was already linked to another inode we already
+                * had in our cache (and thus got spliced).  Link our
+                * dentry to that inode, but don't hash it, just in
+                * case the VFS wants to dereference it.
+                */
+               BUG_ON(!result->d_inode);
+               d_instantiate(dentry, result->d_inode);
+               return 0;
+       }
+       return PTR_ERR(result);
+}
+
+static int ceph_mknod(struct inode *dir, struct dentry *dentry,
+                     int mode, dev_t rdev)
+{
+       struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct ceph_mds_request *req;
+       int err;
+
+       if (ceph_snap(dir) != CEPH_NOSNAP)
+               return -EROFS;
+
+       dout("mknod in dir %p dentry %p mode 0%o rdev %d\n",
+            dir, dentry, mode, rdev);
+       req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_MKNOD, USE_AUTH_MDS);
+       if (IS_ERR(req)) {
+               d_drop(dentry);
+               return PTR_ERR(req);
+       }
+       req->r_dentry = dget(dentry);
+       req->r_num_caps = 2;
+       req->r_locked_dir = dir;
+       req->r_args.mknod.mode = cpu_to_le32(mode);
+       req->r_args.mknod.rdev = cpu_to_le32(rdev);
+       req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+       req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+       err = ceph_mdsc_do_request(mdsc, dir, req);
+       if (!err && !req->r_reply_info.head->is_dentry)
+               err = ceph_handle_notrace_create(dir, dentry);
+       ceph_mdsc_put_request(req);
+       if (err)
+               d_drop(dentry);
+       return err;
+}
+
+static int ceph_create(struct inode *dir, struct dentry *dentry, int mode,
+                      struct nameidata *nd)
+{
+       dout("create in dir %p dentry %p name '%.*s'\n",
+            dir, dentry, dentry->d_name.len, dentry->d_name.name);
+
+       if (ceph_snap(dir) != CEPH_NOSNAP)
+               return -EROFS;
+
+       if (nd) {
+               BUG_ON((nd->flags & LOOKUP_OPEN) == 0);
+               dentry = ceph_lookup_open(dir, dentry, nd, mode, 0);
+               /* hrm, what should i do here if we get aliased? */
+               if (IS_ERR(dentry))
+                       return PTR_ERR(dentry);
+               return 0;
+       }
+
+       /* fall back to mknod */
+       return ceph_mknod(dir, dentry, (mode & ~S_IFMT) | S_IFREG, 0);
+}
+
+static int ceph_symlink(struct inode *dir, struct dentry *dentry,
+                           const char *dest)
+{
+       struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct ceph_mds_request *req;
+       int err;
+
+       if (ceph_snap(dir) != CEPH_NOSNAP)
+               return -EROFS;
+
+       dout("symlink in dir %p dentry %p to '%s'\n", dir, dentry, dest);
+       req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SYMLINK, USE_AUTH_MDS);
+       if (IS_ERR(req)) {
+               d_drop(dentry);
+               return PTR_ERR(req);
+       }
+       req->r_dentry = dget(dentry);
+       req->r_num_caps = 2;
+       req->r_path2 = kstrdup(dest, GFP_NOFS);
+       req->r_locked_dir = dir;
+       req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+       req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+       err = ceph_mdsc_do_request(mdsc, dir, req);
+       if (!err && !req->r_reply_info.head->is_dentry)
+               err = ceph_handle_notrace_create(dir, dentry);
+       ceph_mdsc_put_request(req);
+       if (err)
+               d_drop(dentry);
+       return err;
+}
+
+static int ceph_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+       struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct ceph_mds_request *req;
+       int err = -EROFS;
+       int op;
+
+       if (ceph_snap(dir) == CEPH_SNAPDIR) {
+               /* mkdir .snap/foo is a MKSNAP */
+               op = CEPH_MDS_OP_MKSNAP;
+               dout("mksnap dir %p snap '%.*s' dn %p\n", dir,
+                    dentry->d_name.len, dentry->d_name.name, dentry);
+       } else if (ceph_snap(dir) == CEPH_NOSNAP) {
+               dout("mkdir dir %p dn %p mode 0%o\n", dir, dentry, mode);
+               op = CEPH_MDS_OP_MKDIR;
+       } else {
+               goto out;
+       }
+       req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto out;
+       }
+
+       req->r_dentry = dget(dentry);
+       req->r_num_caps = 2;
+       req->r_locked_dir = dir;
+       req->r_args.mkdir.mode = cpu_to_le32(mode);
+       req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+       req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+       err = ceph_mdsc_do_request(mdsc, dir, req);
+       if (!err && !req->r_reply_info.head->is_dentry)
+               err = ceph_handle_notrace_create(dir, dentry);
+       ceph_mdsc_put_request(req);
+out:
+       if (err < 0)
+               d_drop(dentry);
+       return err;
+}
+
+static int ceph_link(struct dentry *old_dentry, struct inode *dir,
+                    struct dentry *dentry)
+{
+       struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct ceph_mds_request *req;
+       int err;
+
+       if (ceph_snap(dir) != CEPH_NOSNAP)
+               return -EROFS;
+
+       dout("link in dir %p old_dentry %p dentry %p\n", dir,
+            old_dentry, dentry);
+       req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LINK, USE_AUTH_MDS);
+       if (IS_ERR(req)) {
+               d_drop(dentry);
+               return PTR_ERR(req);
+       }
+       req->r_dentry = dget(dentry);
+       req->r_num_caps = 2;
+       req->r_old_dentry = dget(old_dentry); /* or inode? hrm. */
+       req->r_locked_dir = dir;
+       req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+       req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+       err = ceph_mdsc_do_request(mdsc, dir, req);
+       if (err)
+               d_drop(dentry);
+       else if (!req->r_reply_info.head->is_dentry)
+               d_instantiate(dentry, igrab(old_dentry->d_inode));
+       ceph_mdsc_put_request(req);
+       return err;
+}
+
+/*
+ * For a soon-to-be unlinked file, drop the AUTH_RDCACHE caps.  If it
+ * looks like the link count will hit 0, drop any other caps (other
+ * than PIN) we don't specifically want (due to the file still being
+ * open).
+ */
+static int drop_caps_for_unlink(struct inode *inode)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL;
+
+       spin_lock(&inode->i_lock);
+       if (inode->i_nlink == 1) {
+               drop |= ~(__ceph_caps_wanted(ci) | CEPH_CAP_PIN);
+               ci->i_ceph_flags |= CEPH_I_NODELAY;
+       }
+       spin_unlock(&inode->i_lock);
+       return drop;
+}
+
+/*
+ * rmdir and unlink are differ only by the metadata op code
+ */
+static int ceph_unlink(struct inode *dir, struct dentry *dentry)
+{
+       struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct inode *inode = dentry->d_inode;
+       struct ceph_mds_request *req;
+       int err = -EROFS;
+       int op;
+
+       if (ceph_snap(dir) == CEPH_SNAPDIR) {
+               /* rmdir .snap/foo is RMSNAP */
+               dout("rmsnap dir %p '%.*s' dn %p\n", dir, dentry->d_name.len,
+                    dentry->d_name.name, dentry);
+               op = CEPH_MDS_OP_RMSNAP;
+       } else if (ceph_snap(dir) == CEPH_NOSNAP) {
+               dout("unlink/rmdir dir %p dn %p inode %p\n",
+                    dir, dentry, inode);
+               op = ((dentry->d_inode->i_mode & S_IFMT) == S_IFDIR) ?
+                       CEPH_MDS_OP_RMDIR : CEPH_MDS_OP_UNLINK;
+       } else
+               goto out;
+       req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto out;
+       }
+       req->r_dentry = dget(dentry);
+       req->r_num_caps = 2;
+       req->r_locked_dir = dir;
+       req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+       req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+       req->r_inode_drop = drop_caps_for_unlink(inode);
+       err = ceph_mdsc_do_request(mdsc, dir, req);
+       if (!err && !req->r_reply_info.head->is_dentry)
+               d_delete(dentry);
+       ceph_mdsc_put_request(req);
+out:
+       return err;
+}
+
+static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
+                      struct inode *new_dir, struct dentry *new_dentry)
+{
+       struct ceph_client *client = ceph_sb_to_client(old_dir->i_sb);
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct ceph_mds_request *req;
+       int err;
+
+       if (ceph_snap(old_dir) != ceph_snap(new_dir))
+               return -EXDEV;
+       if (ceph_snap(old_dir) != CEPH_NOSNAP ||
+           ceph_snap(new_dir) != CEPH_NOSNAP)
+               return -EROFS;
+       dout("rename dir %p dentry %p to dir %p dentry %p\n",
+            old_dir, old_dentry, new_dir, new_dentry);
+       req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RENAME, USE_AUTH_MDS);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+       req->r_dentry = dget(new_dentry);
+       req->r_num_caps = 2;
+       req->r_old_dentry = dget(old_dentry);
+       req->r_locked_dir = new_dir;
+       req->r_old_dentry_drop = CEPH_CAP_FILE_SHARED;
+       req->r_old_dentry_unless = CEPH_CAP_FILE_EXCL;
+       req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+       req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+       /* release LINK_RDCACHE on source inode (mds will lock it) */
+       req->r_old_inode_drop = CEPH_CAP_LINK_SHARED;
+       if (new_dentry->d_inode)
+               req->r_inode_drop = drop_caps_for_unlink(new_dentry->d_inode);
+       err = ceph_mdsc_do_request(mdsc, old_dir, req);
+       if (!err && !req->r_reply_info.head->is_dentry) {
+               /*
+                * Normally d_move() is done by fill_trace (called by
+                * do_request, above).  If there is no trace, we need
+                * to do it here.
+                */
+
+               /* d_move screws up d_subdirs order */
+               ceph_i_clear(new_dir, CEPH_I_COMPLETE);
+
+               d_move(old_dentry, new_dentry);
+
+               /* ensure target dentry is invalidated, despite
+                  rehashing bug in vfs_rename_dir */
+               new_dentry->d_time = jiffies;
+               ceph_dentry(new_dentry)->lease_shared_gen = 0;
+       }
+       ceph_mdsc_put_request(req);
+       return err;
+}
+
+
+/*
+ * Check if dentry lease is valid.  If not, delete the lease.  Try to
+ * renew if the least is more than half up.
+ */
+static int dentry_lease_is_valid(struct dentry *dentry)
+{
+       struct ceph_dentry_info *di;
+       struct ceph_mds_session *s;
+       int valid = 0;
+       u32 gen;
+       unsigned long ttl;
+       struct ceph_mds_session *session = NULL;
+       struct inode *dir = NULL;
+       u32 seq = 0;
+
+       spin_lock(&dentry->d_lock);
+       di = ceph_dentry(dentry);
+       if (di && di->lease_session) {
+               s = di->lease_session;
+               spin_lock(&s->s_cap_lock);
+               gen = s->s_cap_gen;
+               ttl = s->s_cap_ttl;
+               spin_unlock(&s->s_cap_lock);
+
+               if (di->lease_gen == gen &&
+                   time_before(jiffies, dentry->d_time) &&
+                   time_before(jiffies, ttl)) {
+                       valid = 1;
+                       if (di->lease_renew_after &&
+                           time_after(jiffies, di->lease_renew_after)) {
+                               /* we should renew */
+                               dir = dentry->d_parent->d_inode;
+                               session = ceph_get_mds_session(s);
+                               seq = di->lease_seq;
+                               di->lease_renew_after = 0;
+                               di->lease_renew_from = jiffies;
+                       }
+               }
+       }
+       spin_unlock(&dentry->d_lock);
+
+       if (session) {
+               ceph_mdsc_lease_send_msg(session, dir, dentry,
+                                        CEPH_MDS_LEASE_RENEW, seq);
+               ceph_put_mds_session(session);
+       }
+       dout("dentry_lease_is_valid - dentry %p = %d\n", dentry, valid);
+       return valid;
+}
+
+/*
+ * Check if directory-wide content lease/cap is valid.
+ */
+static int dir_lease_is_valid(struct inode *dir, struct dentry *dentry)
+{
+       struct ceph_inode_info *ci = ceph_inode(dir);
+       struct ceph_dentry_info *di = ceph_dentry(dentry);
+       int valid = 0;
+
+       spin_lock(&dir->i_lock);
+       if (ci->i_shared_gen == di->lease_shared_gen)
+               valid = __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1);
+       spin_unlock(&dir->i_lock);
+       dout("dir_lease_is_valid dir %p v%u dentry %p v%u = %d\n",
+            dir, (unsigned)ci->i_shared_gen, dentry,
+            (unsigned)di->lease_shared_gen, valid);
+       return valid;
+}
+
+/*
+ * Check if cached dentry can be trusted.
+ */
+static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd)
+{
+       struct inode *dir = dentry->d_parent->d_inode;
+
+       dout("d_revalidate %p '%.*s' inode %p\n", dentry,
+            dentry->d_name.len, dentry->d_name.name, dentry->d_inode);
+
+       /* always trust cached snapped dentries, snapdir dentry */
+       if (ceph_snap(dir) != CEPH_NOSNAP) {
+               dout("d_revalidate %p '%.*s' inode %p is SNAPPED\n", dentry,
+                    dentry->d_name.len, dentry->d_name.name, dentry->d_inode);
+               goto out_touch;
+       }
+       if (dentry->d_inode && ceph_snap(dentry->d_inode) == CEPH_SNAPDIR)
+               goto out_touch;
+
+       if (dentry_lease_is_valid(dentry) ||
+           dir_lease_is_valid(dir, dentry))
+               goto out_touch;
+
+       dout("d_revalidate %p invalid\n", dentry);
+       d_drop(dentry);
+       return 0;
+out_touch:
+       ceph_dentry_lru_touch(dentry);
+       return 1;
+}
+
+/*
+ * When a dentry is released, clear the dir I_COMPLETE if it was part
+ * of the current dir gen.
+ */
+static void ceph_dentry_release(struct dentry *dentry)
+{
+       struct ceph_dentry_info *di = ceph_dentry(dentry);
+       struct inode *parent_inode = dentry->d_parent->d_inode;
+
+       if (parent_inode) {
+               struct ceph_inode_info *ci = ceph_inode(parent_inode);
+
+               spin_lock(&parent_inode->i_lock);
+               if (ci->i_shared_gen == di->lease_shared_gen) {
+                       dout(" clearing %p complete (d_release)\n",
+                            parent_inode);
+                       ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
+                       ci->i_release_count++;
+               }
+               spin_unlock(&parent_inode->i_lock);
+       }
+       if (di) {
+               ceph_dentry_lru_del(dentry);
+               if (di->lease_session)
+                       ceph_put_mds_session(di->lease_session);
+               kmem_cache_free(ceph_dentry_cachep, di);
+               dentry->d_fsdata = NULL;
+       }
+}
+
+static int ceph_snapdir_d_revalidate(struct dentry *dentry,
+                                         struct nameidata *nd)
+{
+       /*
+        * Eventually, we'll want to revalidate snapped metadata
+        * too... probably...
+        */
+       return 1;
+}
+
+
+
+/*
+ * read() on a dir.  This weird interface hack only works if mounted
+ * with '-o dirstat'.
+ */
+static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size,
+                            loff_t *ppos)
+{
+       struct ceph_file_info *cf = file->private_data;
+       struct inode *inode = file->f_dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int left;
+
+       if (!ceph_test_opt(ceph_client(inode->i_sb), DIRSTAT))
+               return -EISDIR;
+
+       if (!cf->dir_info) {
+               cf->dir_info = kmalloc(1024, GFP_NOFS);
+               if (!cf->dir_info)
+                       return -ENOMEM;
+               cf->dir_info_len =
+                       sprintf(cf->dir_info,
+                               "entries:   %20lld\n"
+                               " files:    %20lld\n"
+                               " subdirs:  %20lld\n"
+                               "rentries:  %20lld\n"
+                               " rfiles:   %20lld\n"
+                               " rsubdirs: %20lld\n"
+                               "rbytes:    %20lld\n"
+                               "rctime:    %10ld.%09ld\n",
+                               ci->i_files + ci->i_subdirs,
+                               ci->i_files,
+                               ci->i_subdirs,
+                               ci->i_rfiles + ci->i_rsubdirs,
+                               ci->i_rfiles,
+                               ci->i_rsubdirs,
+                               ci->i_rbytes,
+                               (long)ci->i_rctime.tv_sec,
+                               (long)ci->i_rctime.tv_nsec);
+       }
+
+       if (*ppos >= cf->dir_info_len)
+               return 0;
+       size = min_t(unsigned, size, cf->dir_info_len-*ppos);
+       left = copy_to_user(buf, cf->dir_info + *ppos, size);
+       if (left == size)
+               return -EFAULT;
+       *ppos += (size - left);
+       return size - left;
+}
+
+/*
+ * an fsync() on a dir will wait for any uncommitted directory
+ * operations to commit.
+ */
+static int ceph_dir_fsync(struct file *file, struct dentry *dentry,
+                         int datasync)
+{
+       struct inode *inode = dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct list_head *head = &ci->i_unsafe_dirops;
+       struct ceph_mds_request *req;
+       u64 last_tid;
+       int ret = 0;
+
+       dout("dir_fsync %p\n", inode);
+       spin_lock(&ci->i_unsafe_lock);
+       if (list_empty(head))
+               goto out;
+
+       req = list_entry(head->prev,
+                        struct ceph_mds_request, r_unsafe_dir_item);
+       last_tid = req->r_tid;
+
+       do {
+               ceph_mdsc_get_request(req);
+               spin_unlock(&ci->i_unsafe_lock);
+               dout("dir_fsync %p wait on tid %llu (until %llu)\n",
+                    inode, req->r_tid, last_tid);
+               if (req->r_timeout) {
+                       ret = wait_for_completion_timeout(
+                               &req->r_safe_completion, req->r_timeout);
+                       if (ret > 0)
+                               ret = 0;
+                       else if (ret == 0)
+                               ret = -EIO;  /* timed out */
+               } else {
+                       wait_for_completion(&req->r_safe_completion);
+               }
+               spin_lock(&ci->i_unsafe_lock);
+               ceph_mdsc_put_request(req);
+
+               if (ret || list_empty(head))
+                       break;
+               req = list_entry(head->next,
+                                struct ceph_mds_request, r_unsafe_dir_item);
+       } while (req->r_tid < last_tid);
+out:
+       spin_unlock(&ci->i_unsafe_lock);
+       return ret;
+}
+
+/*
+ * We maintain a private dentry LRU.
+ *
+ * FIXME: this needs to be changed to a per-mds lru to be useful.
+ */
+void ceph_dentry_lru_add(struct dentry *dn)
+{
+       struct ceph_dentry_info *di = ceph_dentry(dn);
+       struct ceph_mds_client *mdsc;
+
+       dout("dentry_lru_add %p %p '%.*s'\n", di, dn,
+            dn->d_name.len, dn->d_name.name);
+       if (di) {
+               mdsc = &ceph_client(dn->d_sb)->mdsc;
+               spin_lock(&mdsc->dentry_lru_lock);
+               list_add_tail(&di->lru, &mdsc->dentry_lru);
+               mdsc->num_dentry++;
+               spin_unlock(&mdsc->dentry_lru_lock);
+       }
+}
+
+void ceph_dentry_lru_touch(struct dentry *dn)
+{
+       struct ceph_dentry_info *di = ceph_dentry(dn);
+       struct ceph_mds_client *mdsc;
+
+       dout("dentry_lru_touch %p %p '%.*s'\n", di, dn,
+            dn->d_name.len, dn->d_name.name);
+       if (di) {
+               mdsc = &ceph_client(dn->d_sb)->mdsc;
+               spin_lock(&mdsc->dentry_lru_lock);
+               list_move_tail(&di->lru, &mdsc->dentry_lru);
+               spin_unlock(&mdsc->dentry_lru_lock);
+       }
+}
+
+void ceph_dentry_lru_del(struct dentry *dn)
+{
+       struct ceph_dentry_info *di = ceph_dentry(dn);
+       struct ceph_mds_client *mdsc;
+
+       dout("dentry_lru_del %p %p '%.*s'\n", di, dn,
+            dn->d_name.len, dn->d_name.name);
+       if (di) {
+               mdsc = &ceph_client(dn->d_sb)->mdsc;
+               spin_lock(&mdsc->dentry_lru_lock);
+               list_del_init(&di->lru);
+               mdsc->num_dentry--;
+               spin_unlock(&mdsc->dentry_lru_lock);
+       }
+}
+
+const struct file_operations ceph_dir_fops = {
+       .read = ceph_read_dir,
+       .readdir = ceph_readdir,
+       .llseek = ceph_dir_llseek,
+       .open = ceph_open,
+       .release = ceph_release,
+       .unlocked_ioctl = ceph_ioctl,
+       .fsync = ceph_dir_fsync,
+};
+
+const struct inode_operations ceph_dir_iops = {
+       .lookup = ceph_lookup,
+       .permission = ceph_permission,
+       .getattr = ceph_getattr,
+       .setattr = ceph_setattr,
+       .setxattr = ceph_setxattr,
+       .getxattr = ceph_getxattr,
+       .listxattr = ceph_listxattr,
+       .removexattr = ceph_removexattr,
+       .mknod = ceph_mknod,
+       .symlink = ceph_symlink,
+       .mkdir = ceph_mkdir,
+       .link = ceph_link,
+       .unlink = ceph_unlink,
+       .rmdir = ceph_unlink,
+       .rename = ceph_rename,
+       .create = ceph_create,
+};
+
+struct dentry_operations ceph_dentry_ops = {
+       .d_revalidate = ceph_d_revalidate,
+       .d_release = ceph_dentry_release,
+};
+
+struct dentry_operations ceph_snapdir_dentry_ops = {
+       .d_revalidate = ceph_snapdir_d_revalidate,
+};
+
+struct dentry_operations ceph_snap_dentry_ops = {
+};
diff --git a/fs/ceph/export.c b/fs/ceph/export.c
new file mode 100644 (file)
index 0000000..9d67572
--- /dev/null
@@ -0,0 +1,224 @@
+#include "ceph_debug.h"
+
+#include <linux/exportfs.h>
+#include <linux/slab.h>
+#include <asm/unaligned.h>
+
+#include "super.h"
+
+/*
+ * NFS export support
+ *
+ * NFS re-export of a ceph mount is, at present, only semireliable.
+ * The basic issue is that the Ceph architectures doesn't lend itself
+ * well to generating filehandles that will remain valid forever.
+ *
+ * So, we do our best.  If you're lucky, your inode will be in the
+ * client's cache.  If it's not, and you have a connectable fh, then
+ * the MDS server may be able to find it for you.  Otherwise, you get
+ * ESTALE.
+ *
+ * There are ways to this more reliable, but in the non-connectable fh
+ * case, we won't every work perfectly, and in the connectable case,
+ * some changes are needed on the MDS side to work better.
+ */
+
+/*
+ * Basic fh
+ */
+struct ceph_nfs_fh {
+       u64 ino;
+} __attribute__ ((packed));
+
+/*
+ * Larger 'connectable' fh that includes parent ino and name hash.
+ * Use this whenever possible, as it works more reliably.
+ */
+struct ceph_nfs_confh {
+       u64 ino, parent_ino;
+       u32 parent_name_hash;
+} __attribute__ ((packed));
+
+static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len,
+                         int connectable)
+{
+       struct ceph_nfs_fh *fh = (void *)rawfh;
+       struct ceph_nfs_confh *cfh = (void *)rawfh;
+       struct dentry *parent = dentry->d_parent;
+       struct inode *inode = dentry->d_inode;
+       int type;
+
+       /* don't re-export snaps */
+       if (ceph_snap(inode) != CEPH_NOSNAP)
+               return -EINVAL;
+
+       if (*max_len >= sizeof(*cfh)) {
+               dout("encode_fh %p connectable\n", dentry);
+               cfh->ino = ceph_ino(dentry->d_inode);
+               cfh->parent_ino = ceph_ino(parent->d_inode);
+               cfh->parent_name_hash = parent->d_name.hash;
+               *max_len = sizeof(*cfh);
+               type = 2;
+       } else if (*max_len > sizeof(*fh)) {
+               if (connectable)
+                       return -ENOSPC;
+               dout("encode_fh %p\n", dentry);
+               fh->ino = ceph_ino(dentry->d_inode);
+               *max_len = sizeof(*fh);
+               type = 1;
+       } else {
+               return -ENOSPC;
+       }
+       return type;
+}
+
+/*
+ * convert regular fh to dentry
+ *
+ * FIXME: we should try harder by querying the mds for the ino.
+ */
+static struct dentry *__fh_to_dentry(struct super_block *sb,
+                                    struct ceph_nfs_fh *fh)
+{
+       struct inode *inode;
+       struct dentry *dentry;
+       struct ceph_vino vino;
+       int err;
+
+       dout("__fh_to_dentry %llx\n", fh->ino);
+       vino.ino = fh->ino;
+       vino.snap = CEPH_NOSNAP;
+       inode = ceph_find_inode(sb, vino);
+       if (!inode)
+               return ERR_PTR(-ESTALE);
+
+       dentry = d_obtain_alias(inode);
+       if (!dentry) {
+               pr_err("fh_to_dentry %llx -- inode %p but ENOMEM\n",
+                      fh->ino, inode);
+               iput(inode);
+               return ERR_PTR(-ENOMEM);
+       }
+       err = ceph_init_dentry(dentry);
+
+       if (err < 0) {
+               iput(inode);
+               return ERR_PTR(err);
+       }
+       dout("__fh_to_dentry %llx %p dentry %p\n", fh->ino, inode, dentry);
+       return dentry;
+}
+
+/*
+ * convert connectable fh to dentry
+ */
+static struct dentry *__cfh_to_dentry(struct super_block *sb,
+                                     struct ceph_nfs_confh *cfh)
+{
+       struct ceph_mds_client *mdsc = &ceph_client(sb)->mdsc;
+       struct inode *inode;
+       struct dentry *dentry;
+       struct ceph_vino vino;
+       int err;
+
+       dout("__cfh_to_dentry %llx (%llx/%x)\n",
+            cfh->ino, cfh->parent_ino, cfh->parent_name_hash);
+
+       vino.ino = cfh->ino;
+       vino.snap = CEPH_NOSNAP;
+       inode = ceph_find_inode(sb, vino);
+       if (!inode) {
+               struct ceph_mds_request *req;
+
+               req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPHASH,
+                                              USE_ANY_MDS);
+               if (IS_ERR(req))
+                       return ERR_PTR(PTR_ERR(req));
+
+               req->r_ino1 = vino;
+               req->r_ino2.ino = cfh->parent_ino;
+               req->r_ino2.snap = CEPH_NOSNAP;
+               req->r_path2 = kmalloc(16, GFP_NOFS);
+               snprintf(req->r_path2, 16, "%d", cfh->parent_name_hash);
+               req->r_num_caps = 1;
+               err = ceph_mdsc_do_request(mdsc, NULL, req);
+               ceph_mdsc_put_request(req);
+               inode = ceph_find_inode(sb, vino);
+               if (!inode)
+                       return ERR_PTR(err ? err : -ESTALE);
+       }
+
+       dentry = d_obtain_alias(inode);
+       if (!dentry) {
+               pr_err("cfh_to_dentry %llx -- inode %p but ENOMEM\n",
+                      cfh->ino, inode);
+               iput(inode);
+               return ERR_PTR(-ENOMEM);
+       }
+       err = ceph_init_dentry(dentry);
+       if (err < 0) {
+               iput(inode);
+               return ERR_PTR(err);
+       }
+       dout("__cfh_to_dentry %llx %p dentry %p\n", cfh->ino, inode, dentry);
+       return dentry;
+}
+
+static struct dentry *ceph_fh_to_dentry(struct super_block *sb, struct fid *fid,
+                                       int fh_len, int fh_type)
+{
+       if (fh_type == 1)
+               return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw);
+       else
+               return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw);
+}
+
+/*
+ * get parent, if possible.
+ *
+ * FIXME: we could do better by querying the mds to discover the
+ * parent.
+ */
+static struct dentry *ceph_fh_to_parent(struct super_block *sb,
+                                        struct fid *fid,
+                                       int fh_len, int fh_type)
+{
+       struct ceph_nfs_confh *cfh = (void *)fid->raw;
+       struct ceph_vino vino;
+       struct inode *inode;
+       struct dentry *dentry;
+       int err;
+
+       if (fh_type == 1)
+               return ERR_PTR(-ESTALE);
+
+       pr_debug("fh_to_parent %llx/%d\n", cfh->parent_ino,
+                cfh->parent_name_hash);
+
+       vino.ino = cfh->ino;
+       vino.snap = CEPH_NOSNAP;
+       inode = ceph_find_inode(sb, vino);
+       if (!inode)
+               return ERR_PTR(-ESTALE);
+
+       dentry = d_obtain_alias(inode);
+       if (!dentry) {
+               pr_err("fh_to_parent %llx -- inode %p but ENOMEM\n",
+                      cfh->ino, inode);
+               iput(inode);
+               return ERR_PTR(-ENOMEM);
+       }
+       err = ceph_init_dentry(dentry);
+       if (err < 0) {
+               iput(inode);
+               return ERR_PTR(err);
+       }
+       dout("fh_to_parent %llx %p dentry %p\n", cfh->ino, inode, dentry);
+       return dentry;
+}
+
+const struct export_operations ceph_export_ops = {
+       .encode_fh = ceph_encode_fh,
+       .fh_to_dentry = ceph_fh_to_dentry,
+       .fh_to_parent = ceph_fh_to_parent,
+};
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
new file mode 100644 (file)
index 0000000..ed6f197
--- /dev/null
@@ -0,0 +1,939 @@
+#include "ceph_debug.h"
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/file.h>
+#include <linux/namei.h>
+#include <linux/writeback.h>
+
+#include "super.h"
+#include "mds_client.h"
+
+/*
+ * Ceph file operations
+ *
+ * Implement basic open/close functionality, and implement
+ * read/write.
+ *
+ * We implement three modes of file I/O:
+ *  - buffered uses the generic_file_aio_{read,write} helpers
+ *
+ *  - synchronous is used when there is multi-client read/write
+ *    sharing, avoids the page cache, and synchronously waits for an
+ *    ack from the OSD.
+ *
+ *  - direct io takes the variant of the sync path that references
+ *    user pages directly.
+ *
+ * fsync() flushes and waits on dirty pages, but just queues metadata
+ * for writeback: since the MDS can recover size and mtime there is no
+ * need to wait for MDS acknowledgement.
+ */
+
+
+/*
+ * Prepare an open request.  Preallocate ceph_cap to avoid an
+ * inopportune ENOMEM later.
+ */
+static struct ceph_mds_request *
+prepare_open_request(struct super_block *sb, int flags, int create_mode)
+{
+       struct ceph_client *client = ceph_sb_to_client(sb);
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct ceph_mds_request *req;
+       int want_auth = USE_ANY_MDS;
+       int op = (flags & O_CREAT) ? CEPH_MDS_OP_CREATE : CEPH_MDS_OP_OPEN;
+
+       if (flags & (O_WRONLY|O_RDWR|O_CREAT|O_TRUNC))
+               want_auth = USE_AUTH_MDS;
+
+       req = ceph_mdsc_create_request(mdsc, op, want_auth);
+       if (IS_ERR(req))
+               goto out;
+       req->r_fmode = ceph_flags_to_mode(flags);
+       req->r_args.open.flags = cpu_to_le32(flags);
+       req->r_args.open.mode = cpu_to_le32(create_mode);
+       req->r_args.open.preferred = cpu_to_le32(-1);
+out:
+       return req;
+}
+
+/*
+ * initialize private struct file data.
+ * if we fail, clean up by dropping fmode reference on the ceph_inode
+ */
+static int ceph_init_file(struct inode *inode, struct file *file, int fmode)
+{
+       struct ceph_file_info *cf;
+       int ret = 0;
+
+       switch (inode->i_mode & S_IFMT) {
+       case S_IFREG:
+       case S_IFDIR:
+               dout("init_file %p %p 0%o (regular)\n", inode, file,
+                    inode->i_mode);
+               cf = kmem_cache_alloc(ceph_file_cachep, GFP_NOFS | __GFP_ZERO);
+               if (cf == NULL) {
+                       ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
+                       return -ENOMEM;
+               }
+               cf->fmode = fmode;
+               cf->next_offset = 2;
+               file->private_data = cf;
+               BUG_ON(inode->i_fop->release != ceph_release);
+               break;
+
+       case S_IFLNK:
+               dout("init_file %p %p 0%o (symlink)\n", inode, file,
+                    inode->i_mode);
+               ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
+               break;
+
+       default:
+               dout("init_file %p %p 0%o (special)\n", inode, file,
+                    inode->i_mode);
+               /*
+                * we need to drop the open ref now, since we don't
+                * have .release set to ceph_release.
+                */
+               ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
+               BUG_ON(inode->i_fop->release == ceph_release);
+
+               /* call the proper open fop */
+               ret = inode->i_fop->open(inode, file);
+       }
+       return ret;
+}
+
+/*
+ * If the filp already has private_data, that means the file was
+ * already opened by intent during lookup, and we do nothing.
+ *
+ * If we already have the requisite capabilities, we can satisfy
+ * the open request locally (no need to request new caps from the
+ * MDS).  We do, however, need to inform the MDS (asynchronously)
+ * if our wanted caps set expands.
+ */
+int ceph_open(struct inode *inode, struct file *file)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_client *client = ceph_sb_to_client(inode->i_sb);
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct ceph_mds_request *req;
+       struct ceph_file_info *cf = file->private_data;
+       struct inode *parent_inode = file->f_dentry->d_parent->d_inode;
+       int err;
+       int flags, fmode, wanted;
+
+       if (cf) {
+               dout("open file %p is already opened\n", file);
+               return 0;
+       }
+
+       /* filter out O_CREAT|O_EXCL; vfs did that already.  yuck. */
+       flags = file->f_flags & ~(O_CREAT|O_EXCL);
+       if (S_ISDIR(inode->i_mode))
+               flags = O_DIRECTORY;  /* mds likes to know */
+
+       dout("open inode %p ino %llx.%llx file %p flags %d (%d)\n", inode,
+            ceph_vinop(inode), file, flags, file->f_flags);
+       fmode = ceph_flags_to_mode(flags);
+       wanted = ceph_caps_for_mode(fmode);
+
+       /* snapped files are read-only */
+       if (ceph_snap(inode) != CEPH_NOSNAP && (file->f_mode & FMODE_WRITE))
+               return -EROFS;
+
+       /* trivially open snapdir */
+       if (ceph_snap(inode) == CEPH_SNAPDIR) {
+               spin_lock(&inode->i_lock);
+               __ceph_get_fmode(ci, fmode);
+               spin_unlock(&inode->i_lock);
+               return ceph_init_file(inode, file, fmode);
+       }
+
+       /*
+        * No need to block if we have any caps.  Update wanted set
+        * asynchronously.
+        */
+       spin_lock(&inode->i_lock);
+       if (__ceph_is_any_real_caps(ci)) {
+               int mds_wanted = __ceph_caps_mds_wanted(ci);
+               int issued = __ceph_caps_issued(ci, NULL);
+
+               dout("open %p fmode %d want %s issued %s using existing\n",
+                    inode, fmode, ceph_cap_string(wanted),
+                    ceph_cap_string(issued));
+               __ceph_get_fmode(ci, fmode);
+               spin_unlock(&inode->i_lock);
+
+               /* adjust wanted? */
+               if ((issued & wanted) != wanted &&
+                   (mds_wanted & wanted) != wanted &&
+                   ceph_snap(inode) != CEPH_SNAPDIR)
+                       ceph_check_caps(ci, 0, NULL);
+
+               return ceph_init_file(inode, file, fmode);
+       } else if (ceph_snap(inode) != CEPH_NOSNAP &&
+                  (ci->i_snap_caps & wanted) == wanted) {
+               __ceph_get_fmode(ci, fmode);
+               spin_unlock(&inode->i_lock);
+               return ceph_init_file(inode, file, fmode);
+       }
+       spin_unlock(&inode->i_lock);
+
+       dout("open fmode %d wants %s\n", fmode, ceph_cap_string(wanted));
+       req = prepare_open_request(inode->i_sb, flags, 0);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto out;
+       }
+       req->r_inode = igrab(inode);
+       req->r_num_caps = 1;
+       err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+       if (!err)
+               err = ceph_init_file(inode, file, req->r_fmode);
+       ceph_mdsc_put_request(req);
+       dout("open result=%d on %llx.%llx\n", err, ceph_vinop(inode));
+out:
+       return err;
+}
+
+
+/*
+ * Do a lookup + open with a single request.
+ *
+ * If this succeeds, but some subsequent check in the vfs
+ * may_open() fails, the struct *file gets cleaned up (i.e.
+ * ceph_release gets called).  So fear not!
+ */
+/*
+ * flags
+ *  path_lookup_open   -> LOOKUP_OPEN
+ *  path_lookup_create -> LOOKUP_OPEN|LOOKUP_CREATE
+ */
+struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
+                               struct nameidata *nd, int mode,
+                               int locked_dir)
+{
+       struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct file *file = nd->intent.open.file;
+       struct inode *parent_inode = get_dentry_parent_inode(file->f_dentry);
+       struct ceph_mds_request *req;
+       int err;
+       int flags = nd->intent.open.flags - 1;  /* silly vfs! */
+
+       dout("ceph_lookup_open dentry %p '%.*s' flags %d mode 0%o\n",
+            dentry, dentry->d_name.len, dentry->d_name.name, flags, mode);
+
+       /* do the open */
+       req = prepare_open_request(dir->i_sb, flags, mode);
+       if (IS_ERR(req))
+               return ERR_PTR(PTR_ERR(req));
+       req->r_dentry = dget(dentry);
+       req->r_num_caps = 2;
+       if (flags & O_CREAT) {
+               req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+               req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
+       }
+       req->r_locked_dir = dir;           /* caller holds dir->i_mutex */
+       err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+       dentry = ceph_finish_lookup(req, dentry, err);
+       if (!err && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
+               err = ceph_handle_notrace_create(dir, dentry);
+       if (!err)
+               err = ceph_init_file(req->r_dentry->d_inode, file,
+                                    req->r_fmode);
+       ceph_mdsc_put_request(req);
+       dout("ceph_lookup_open result=%p\n", dentry);
+       return dentry;
+}
+
+int ceph_release(struct inode *inode, struct file *file)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_file_info *cf = file->private_data;
+
+       dout("release inode %p file %p\n", inode, file);
+       ceph_put_fmode(ci, cf->fmode);
+       if (cf->last_readdir)
+               ceph_mdsc_put_request(cf->last_readdir);
+       kfree(cf->last_name);
+       kfree(cf->dir_info);
+       dput(cf->dentry);
+       kmem_cache_free(ceph_file_cachep, cf);
+
+       /* wake up anyone waiting for caps on this inode */
+       wake_up(&ci->i_cap_wq);
+       return 0;
+}
+
+/*
+ * build a vector of user pages
+ */
+static struct page **get_direct_page_vector(const char __user *data,
+                                           int num_pages,
+                                           loff_t off, size_t len)
+{
+       struct page **pages;
+       int rc;
+
+       pages = kmalloc(sizeof(*pages) * num_pages, GFP_NOFS);
+       if (!pages)
+               return ERR_PTR(-ENOMEM);
+
+       down_read(&current->mm->mmap_sem);
+       rc = get_user_pages(current, current->mm, (unsigned long)data,
+                           num_pages, 0, 0, pages, NULL);
+       up_read(&current->mm->mmap_sem);
+       if (rc < 0)
+               goto fail;
+       return pages;
+
+fail:
+       kfree(pages);
+       return ERR_PTR(rc);
+}
+
+static void put_page_vector(struct page **pages, int num_pages)
+{
+       int i;
+
+       for (i = 0; i < num_pages; i++)
+               put_page(pages[i]);
+       kfree(pages);
+}
+
+void ceph_release_page_vector(struct page **pages, int num_pages)
+{
+       int i;
+
+       for (i = 0; i < num_pages; i++)
+               __free_pages(pages[i], 0);
+       kfree(pages);
+}
+
+/*
+ * allocate a vector new pages
+ */
+static struct page **alloc_page_vector(int num_pages)
+{
+       struct page **pages;
+       int i;
+
+       pages = kmalloc(sizeof(*pages) * num_pages, GFP_NOFS);
+       if (!pages)
+               return ERR_PTR(-ENOMEM);
+       for (i = 0; i < num_pages; i++) {
+               pages[i] = alloc_page(GFP_NOFS);
+               if (pages[i] == NULL) {
+                       ceph_release_page_vector(pages, i);
+                       return ERR_PTR(-ENOMEM);
+               }
+       }
+       return pages;
+}
+
+/*
+ * copy user data into a page vector
+ */
+static int copy_user_to_page_vector(struct page **pages,
+                                   const char __user *data,
+                                   loff_t off, size_t len)
+{
+       int i = 0;
+       int po = off & ~PAGE_CACHE_MASK;
+       int left = len;
+       int l, bad;
+
+       while (left > 0) {
+               l = min_t(int, PAGE_CACHE_SIZE-po, left);
+               bad = copy_from_user(page_address(pages[i]) + po, data, l);
+               if (bad == l)
+                       return -EFAULT;
+               data += l - bad;
+               left -= l - bad;
+               po += l - bad;
+               if (po == PAGE_CACHE_SIZE) {
+                       po = 0;
+                       i++;
+               }
+       }
+       return len;
+}
+
+/*
+ * copy user data from a page vector into a user pointer
+ */
+static int copy_page_vector_to_user(struct page **pages, char __user *data,
+                                   loff_t off, size_t len)
+{
+       int i = 0;
+       int po = off & ~PAGE_CACHE_MASK;
+       int left = len;
+       int l, bad;
+
+       while (left > 0) {
+               l = min_t(int, left, PAGE_CACHE_SIZE-po);
+               bad = copy_to_user(data, page_address(pages[i]) + po, l);
+               if (bad == l)
+                       return -EFAULT;
+               data += l - bad;
+               left -= l - bad;
+               if (po) {
+                       po += l - bad;
+                       if (po == PAGE_CACHE_SIZE)
+                               po = 0;
+               }
+               i++;
+       }
+       return len;
+}
+
+/*
+ * Zero an extent within a page vector.  Offset is relative to the
+ * start of the first page.
+ */
+static void zero_page_vector_range(int off, int len, struct page **pages)
+{
+       int i = off >> PAGE_CACHE_SHIFT;
+
+       off &= ~PAGE_CACHE_MASK;
+
+       dout("zero_page_vector_page %u~%u\n", off, len);
+
+       /* leading partial page? */
+       if (off) {
+               int end = min((int)PAGE_CACHE_SIZE, off + len);
+               dout("zeroing %d %p head from %d\n", i, pages[i],
+                    (int)off);
+               zero_user_segment(pages[i], off, end);
+               len -= (end - off);
+               i++;
+       }
+       while (len >= PAGE_CACHE_SIZE) {
+               dout("zeroing %d %p len=%d\n", i, pages[i], len);
+               zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE);
+               len -= PAGE_CACHE_SIZE;
+               i++;
+       }
+       /* trailing partial page? */
+       if (len) {
+               dout("zeroing %d %p tail to %d\n", i, pages[i], (int)len);
+               zero_user_segment(pages[i], 0, len);
+       }
+}
+
+
+/*
+ * Read a range of bytes striped over one or more objects.  Iterate over
+ * objects we stripe over.  (That's not atomic, but good enough for now.)
+ *
+ * If we get a short result from the OSD, check against i_size; we need to
+ * only return a short read to the caller if we hit EOF.
+ */
+static int striped_read(struct inode *inode,
+                       u64 off, u64 len,
+                       struct page **pages, int num_pages,
+                       int *checkeof)
+{
+       struct ceph_client *client = ceph_inode_to_client(inode);
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       u64 pos, this_len;
+       int page_off = off & ~PAGE_CACHE_MASK; /* first byte's offset in page */
+       int left, pages_left;
+       int read;
+       struct page **page_pos;
+       int ret;
+       bool hit_stripe, was_short;
+
+       /*
+        * we may need to do multiple reads.  not atomic, unfortunately.
+        */
+       pos = off;
+       left = len;
+       page_pos = pages;
+       pages_left = num_pages;
+       read = 0;
+
+more:
+       this_len = left;
+       ret = ceph_osdc_readpages(&client->osdc, ceph_vino(inode),
+                                 &ci->i_layout, pos, &this_len,
+                                 ci->i_truncate_seq,
+                                 ci->i_truncate_size,
+                                 page_pos, pages_left);
+       hit_stripe = this_len < left;
+       was_short = ret >= 0 && ret < this_len;
+       if (ret == -ENOENT)
+               ret = 0;
+       dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left, read,
+            ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "");
+
+       if (ret > 0) {
+               int didpages =
+                       ((pos & ~PAGE_CACHE_MASK) + ret) >> PAGE_CACHE_SHIFT;
+
+               if (read < pos - off) {
+                       dout(" zero gap %llu to %llu\n", off + read, pos);
+                       zero_page_vector_range(page_off + read,
+                                              pos - off - read, pages);
+               }
+               pos += ret;
+               read = pos - off;
+               left -= ret;
+               page_pos += didpages;
+               pages_left -= didpages;
+
+               /* hit stripe? */
+               if (left && hit_stripe)
+                       goto more;
+       }
+
+       if (was_short) {
+               /* was original extent fully inside i_size? */
+               if (pos + left <= inode->i_size) {
+                       dout("zero tail\n");
+                       zero_page_vector_range(page_off + read, len - read,
+                                              pages);
+                       read = len;
+                       goto out;
+               }
+
+               /* check i_size */
+               *checkeof = 1;
+       }
+
+out:
+       if (ret >= 0)
+               ret = read;
+       dout("striped_read returns %d\n", ret);
+       return ret;
+}
+
+/*
+ * Completely synchronous read and write methods.  Direct from __user
+ * buffer to osd, or directly to user pages (if O_DIRECT).
+ *
+ * If the read spans object boundary, just do multiple reads.
+ */
+static ssize_t ceph_sync_read(struct file *file, char __user *data,
+                             unsigned len, loff_t *poff, int *checkeof)
+{
+       struct inode *inode = file->f_dentry->d_inode;
+       struct page **pages;
+       u64 off = *poff;
+       int num_pages = calc_pages_for(off, len);
+       int ret;
+
+       dout("sync_read on file %p %llu~%u %s\n", file, off, len,
+            (file->f_flags & O_DIRECT) ? "O_DIRECT" : "");
+
+       if (file->f_flags & O_DIRECT) {
+               pages = get_direct_page_vector(data, num_pages, off, len);
+
+               /*
+                * flush any page cache pages in this range.  this
+                * will make concurrent normal and O_DIRECT io slow,
+                * but it will at least behave sensibly when they are
+                * in sequence.
+                */
+       } else {
+               pages = alloc_page_vector(num_pages);
+       }
+       if (IS_ERR(pages))
+               return PTR_ERR(pages);
+
+       ret = filemap_write_and_wait(inode->i_mapping);
+       if (ret < 0)
+               goto done;
+
+       ret = striped_read(inode, off, len, pages, num_pages, checkeof);
+
+       if (ret >= 0 && (file->f_flags & O_DIRECT) == 0)
+               ret = copy_page_vector_to_user(pages, data, off, ret);
+       if (ret >= 0)
+               *poff = off + ret;
+
+done:
+       if (file->f_flags & O_DIRECT)
+               put_page_vector(pages, num_pages);
+       else
+               ceph_release_page_vector(pages, num_pages);
+       dout("sync_read result %d\n", ret);
+       return ret;
+}
+
+/*
+ * Write commit callback, called if we requested both an ACK and
+ * ONDISK commit reply from the OSD.
+ */
+static void sync_write_commit(struct ceph_osd_request *req,
+                             struct ceph_msg *msg)
+{
+       struct ceph_inode_info *ci = ceph_inode(req->r_inode);
+
+       dout("sync_write_commit %p tid %llu\n", req, req->r_tid);
+       spin_lock(&ci->i_unsafe_lock);
+       list_del_init(&req->r_unsafe_item);
+       spin_unlock(&ci->i_unsafe_lock);
+       ceph_put_cap_refs(ci, CEPH_CAP_FILE_WR);
+}
+
+/*
+ * Synchronous write, straight from __user pointer or user pages (if
+ * O_DIRECT).
+ *
+ * If write spans object boundary, just do multiple writes.  (For a
+ * correct atomic write, we should e.g. take write locks on all
+ * objects, rollback on failure, etc.)
+ */
+static ssize_t ceph_sync_write(struct file *file, const char __user *data,
+                              size_t left, loff_t *offset)
+{
+       struct inode *inode = file->f_dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_client *client = ceph_inode_to_client(inode);
+       struct ceph_osd_request *req;
+       struct page **pages;
+       int num_pages;
+       long long unsigned pos;
+       u64 len;
+       int written = 0;
+       int flags;
+       int do_sync = 0;
+       int check_caps = 0;
+       int ret;
+       struct timespec mtime = CURRENT_TIME;
+
+       if (ceph_snap(file->f_dentry->d_inode) != CEPH_NOSNAP)
+               return -EROFS;
+
+       dout("sync_write on file %p %lld~%u %s\n", file, *offset,
+            (unsigned)left, (file->f_flags & O_DIRECT) ? "O_DIRECT" : "");
+
+       if (file->f_flags & O_APPEND)
+               pos = i_size_read(inode);
+       else
+               pos = *offset;
+
+       ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left);
+       if (ret < 0)
+               return ret;
+
+       ret = invalidate_inode_pages2_range(inode->i_mapping,
+                                           pos >> PAGE_CACHE_SHIFT,
+                                           (pos + left) >> PAGE_CACHE_SHIFT);
+       if (ret < 0)
+               dout("invalidate_inode_pages2_range returned %d\n", ret);
+
+       flags = CEPH_OSD_FLAG_ORDERSNAP |
+               CEPH_OSD_FLAG_ONDISK |
+               CEPH_OSD_FLAG_WRITE;
+       if ((file->f_flags & (O_SYNC|O_DIRECT)) == 0)
+               flags |= CEPH_OSD_FLAG_ACK;
+       else
+               do_sync = 1;
+
+       /*
+        * we may need to do multiple writes here if we span an object
+        * boundary.  this isn't atomic, unfortunately.  :(
+        */
+more:
+       len = left;
+       req = ceph_osdc_new_request(&client->osdc, &ci->i_layout,
+                                   ceph_vino(inode), pos, &len,
+                                   CEPH_OSD_OP_WRITE, flags,
+                                   ci->i_snap_realm->cached_context,
+                                   do_sync,
+                                   ci->i_truncate_seq, ci->i_truncate_size,
+                                   &mtime, false, 2);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+
+       num_pages = calc_pages_for(pos, len);
+
+       if (file->f_flags & O_DIRECT) {
+               pages = get_direct_page_vector(data, num_pages, pos, len);
+               if (IS_ERR(pages)) {
+                       ret = PTR_ERR(pages);
+                       goto out;
+               }
+
+               /*
+                * throw out any page cache pages in this range. this
+                * may block.
+                */
+               truncate_inode_pages_range(inode->i_mapping, pos, 
+                                          (pos+len) | (PAGE_CACHE_SIZE-1));
+       } else {
+               pages = alloc_page_vector(num_pages);
+               if (IS_ERR(pages)) {
+                       ret = PTR_ERR(pages);
+                       goto out;
+               }
+               ret = copy_user_to_page_vector(pages, data, pos, len);
+               if (ret < 0) {
+                       ceph_release_page_vector(pages, num_pages);
+                       goto out;
+               }
+
+               if ((file->f_flags & O_SYNC) == 0) {
+                       /* get a second commit callback */
+                       req->r_safe_callback = sync_write_commit;
+                       req->r_own_pages = 1;
+               }
+       }
+       req->r_pages = pages;
+       req->r_num_pages = num_pages;
+       req->r_inode = inode;
+
+       ret = ceph_osdc_start_request(&client->osdc, req, false);
+       if (!ret) {
+               if (req->r_safe_callback) {
+                       /*
+                        * Add to inode unsafe list only after we
+                        * start_request so that a tid has been assigned.
+                        */
+                       spin_lock(&ci->i_unsafe_lock);
+                       list_add(&ci->i_unsafe_writes, &req->r_unsafe_item);
+                       spin_unlock(&ci->i_unsafe_lock);
+                       ceph_get_cap_refs(ci, CEPH_CAP_FILE_WR);
+               }
+               ret = ceph_osdc_wait_request(&client->osdc, req);
+       }
+
+       if (file->f_flags & O_DIRECT)
+               put_page_vector(pages, num_pages);
+       else if (file->f_flags & O_SYNC)
+               ceph_release_page_vector(pages, num_pages);
+
+out:
+       ceph_osdc_put_request(req);
+       if (ret == 0) {
+               pos += len;
+               written += len;
+               left -= len;
+               if (left)
+                       goto more;
+
+               ret = written;
+               *offset = pos;
+               if (pos > i_size_read(inode))
+                       check_caps = ceph_inode_set_size(inode, pos);
+               if (check_caps)
+                       ceph_check_caps(ceph_inode(inode), CHECK_CAPS_AUTHONLY,
+                                       NULL);
+       }
+       return ret;
+}
+
+/*
+ * Wrap generic_file_aio_read with checks for cap bits on the inode.
+ * Atomically grab references, so that those bits are not released
+ * back to the MDS mid-read.
+ *
+ * Hmm, the sync read case isn't actually async... should it be?
+ */
+static ssize_t ceph_aio_read(struct kiocb *iocb, const struct iovec *iov,
+                            unsigned long nr_segs, loff_t pos)
+{
+       struct file *filp = iocb->ki_filp;
+       loff_t *ppos = &iocb->ki_pos;
+       size_t len = iov->iov_len;
+       struct inode *inode = filp->f_dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       void *base = iov->iov_base;
+       ssize_t ret;
+       int got = 0;
+       int checkeof = 0, read = 0;
+
+       dout("aio_read %p %llx.%llx %llu~%u trying to get caps on %p\n",
+            inode, ceph_vinop(inode), pos, (unsigned)len, inode);
+again:
+       __ceph_do_pending_vmtruncate(inode);
+       ret = ceph_get_caps(ci, CEPH_CAP_FILE_RD, CEPH_CAP_FILE_CACHE,
+                           &got, -1);
+       if (ret < 0)
+               goto out;
+       dout("aio_read %p %llx.%llx %llu~%u got cap refs on %s\n",
+            inode, ceph_vinop(inode), pos, (unsigned)len,
+            ceph_cap_string(got));
+
+       if ((got & CEPH_CAP_FILE_CACHE) == 0 ||
+           (iocb->ki_filp->f_flags & O_DIRECT) ||
+           (inode->i_sb->s_flags & MS_SYNCHRONOUS))
+               /* hmm, this isn't really async... */
+               ret = ceph_sync_read(filp, base, len, ppos, &checkeof);
+       else
+               ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
+
+out:
+       dout("aio_read %p %llx.%llx dropping cap refs on %s = %d\n",
+            inode, ceph_vinop(inode), ceph_cap_string(got), (int)ret);
+       ceph_put_cap_refs(ci, got);
+
+       if (checkeof && ret >= 0) {
+               int statret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE);
+
+               /* hit EOF or hole? */
+               if (statret == 0 && *ppos < inode->i_size) {
+                       dout("aio_read sync_read hit hole, reading more\n");
+                       read += ret;
+                       base += ret;
+                       len -= ret;
+                       checkeof = 0;
+                       goto again;
+               }
+       }
+       if (ret >= 0)
+               ret += read;
+
+       return ret;
+}
+
+/*
+ * Take cap references to avoid releasing caps to MDS mid-write.
+ *
+ * If we are synchronous, and write with an old snap context, the OSD
+ * may return EOLDSNAPC.  In that case, retry the write.. _after_
+ * dropping our cap refs and allowing the pending snap to logically
+ * complete _before_ this write occurs.
+ *
+ * If we are near ENOSPC, write synchronously.
+ */
+static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov,
+                      unsigned long nr_segs, loff_t pos)
+{
+       struct file *file = iocb->ki_filp;
+       struct inode *inode = file->f_dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_osd_client *osdc = &ceph_client(inode->i_sb)->osdc;
+       loff_t endoff = pos + iov->iov_len;
+       int got = 0;
+       int ret, err;
+
+       if (ceph_snap(inode) != CEPH_NOSNAP)
+               return -EROFS;
+
+retry_snap:
+       if (ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_FULL))
+               return -ENOSPC;
+       __ceph_do_pending_vmtruncate(inode);
+       dout("aio_write %p %llx.%llx %llu~%u getting caps. i_size %llu\n",
+            inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len,
+            inode->i_size);
+       ret = ceph_get_caps(ci, CEPH_CAP_FILE_WR, CEPH_CAP_FILE_BUFFER,
+                           &got, endoff);
+       if (ret < 0)
+               goto out;
+
+       dout("aio_write %p %llx.%llx %llu~%u  got cap refs on %s\n",
+            inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len,
+            ceph_cap_string(got));
+
+       if ((got & CEPH_CAP_FILE_BUFFER) == 0 ||
+           (iocb->ki_filp->f_flags & O_DIRECT) ||
+           (inode->i_sb->s_flags & MS_SYNCHRONOUS)) {
+               ret = ceph_sync_write(file, iov->iov_base, iov->iov_len,
+                       &iocb->ki_pos);
+       } else {
+               ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
+
+               if ((ret >= 0 || ret == -EIOCBQUEUED) &&
+                   ((file->f_flags & O_SYNC) || IS_SYNC(file->f_mapping->host)
+                    || ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_NEARFULL))) {
+                       err = vfs_fsync_range(file, file->f_path.dentry,
+                                             pos, pos + ret - 1, 1);
+                       if (err < 0)
+                               ret = err;
+               }
+       }
+       if (ret >= 0) {
+               spin_lock(&inode->i_lock);
+               __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR);
+               spin_unlock(&inode->i_lock);
+       }
+
+out:
+       dout("aio_write %p %llx.%llx %llu~%u  dropping cap refs on %s\n",
+            inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len,
+            ceph_cap_string(got));
+       ceph_put_cap_refs(ci, got);
+
+       if (ret == -EOLDSNAPC) {
+               dout("aio_write %p %llx.%llx %llu~%u got EOLDSNAPC, retrying\n",
+                    inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len);
+               goto retry_snap;
+       }
+
+       return ret;
+}
+
+/*
+ * llseek.  be sure to verify file size on SEEK_END.
+ */
+static loff_t ceph_llseek(struct file *file, loff_t offset, int origin)
+{
+       struct inode *inode = file->f_mapping->host;
+       int ret;
+
+       mutex_lock(&inode->i_mutex);
+       __ceph_do_pending_vmtruncate(inode);
+       switch (origin) {
+       case SEEK_END:
+               ret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE);
+               if (ret < 0) {
+                       offset = ret;
+                       goto out;
+               }
+               offset += inode->i_size;
+               break;
+       case SEEK_CUR:
+               /*
+                * Here we special-case the lseek(fd, 0, SEEK_CUR)
+                * position-querying operation.  Avoid rewriting the "same"
+                * f_pos value back to the file because a concurrent read(),
+                * write() or lseek() might have altered it
+                */
+               if (offset == 0) {
+                       offset = file->f_pos;
+                       goto out;
+               }
+               offset += file->f_pos;
+               break;
+       }
+
+       if (offset < 0 || offset > inode->i_sb->s_maxbytes) {
+               offset = -EINVAL;
+               goto out;
+       }
+
+       /* Special lock needed here? */
+       if (offset != file->f_pos) {
+               file->f_pos = offset;
+               file->f_version = 0;
+       }
+
+out:
+       mutex_unlock(&inode->i_mutex);
+       return offset;
+}
+
+const struct file_operations ceph_file_fops = {
+       .open = ceph_open,
+       .release = ceph_release,
+       .llseek = ceph_llseek,
+       .read = do_sync_read,
+       .write = do_sync_write,
+       .aio_read = ceph_aio_read,
+       .aio_write = ceph_aio_write,
+       .mmap = ceph_mmap,
+       .fsync = ceph_fsync,
+       .splice_read = generic_file_splice_read,
+       .splice_write = generic_file_splice_write,
+       .unlocked_ioctl = ceph_ioctl,
+       .compat_ioctl   = ceph_ioctl,
+};
+
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
new file mode 100644 (file)
index 0000000..85b4d2f
--- /dev/null
@@ -0,0 +1,1782 @@
+#include "ceph_debug.h"
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/smp_lock.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+#include <linux/kernel.h>
+#include <linux/namei.h>
+#include <linux/writeback.h>
+#include <linux/vmalloc.h>
+#include <linux/pagevec.h>
+
+#include "super.h"
+#include "decode.h"
+
+/*
+ * Ceph inode operations
+ *
+ * Implement basic inode helpers (get, alloc) and inode ops (getattr,
+ * setattr, etc.), xattr helpers, and helpers for assimilating
+ * metadata returned by the MDS into our cache.
+ *
+ * Also define helpers for doing asynchronous writeback, invalidation,
+ * and truncation for the benefit of those who can't afford to block
+ * (typically because they are in the message handler path).
+ */
+
+static const struct inode_operations ceph_symlink_iops;
+
+static void ceph_invalidate_work(struct work_struct *work);
+static void ceph_writeback_work(struct work_struct *work);
+static void ceph_vmtruncate_work(struct work_struct *work);
+
+/*
+ * find or create an inode, given the ceph ino number
+ */
+struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino)
+{
+       struct inode *inode;
+       ino_t t = ceph_vino_to_ino(vino);
+
+       inode = iget5_locked(sb, t, ceph_ino_compare, ceph_set_ino_cb, &vino);
+       if (inode == NULL)
+               return ERR_PTR(-ENOMEM);
+       if (inode->i_state & I_NEW) {
+               dout("get_inode created new inode %p %llx.%llx ino %llx\n",
+                    inode, ceph_vinop(inode), (u64)inode->i_ino);
+               unlock_new_inode(inode);
+       }
+
+       dout("get_inode on %lu=%llx.%llx got %p\n", inode->i_ino, vino.ino,
+            vino.snap, inode);
+       return inode;
+}
+
+/*
+ * get/constuct snapdir inode for a given directory
+ */
+struct inode *ceph_get_snapdir(struct inode *parent)
+{
+       struct ceph_vino vino = {
+               .ino = ceph_ino(parent),
+               .snap = CEPH_SNAPDIR,
+       };
+       struct inode *inode = ceph_get_inode(parent->i_sb, vino);
+       struct ceph_inode_info *ci = ceph_inode(inode);
+
+       BUG_ON(!S_ISDIR(parent->i_mode));
+       if (IS_ERR(inode))
+               return ERR_PTR(PTR_ERR(inode));
+       inode->i_mode = parent->i_mode;
+       inode->i_uid = parent->i_uid;
+       inode->i_gid = parent->i_gid;
+       inode->i_op = &ceph_dir_iops;
+       inode->i_fop = &ceph_dir_fops;
+       ci->i_snap_caps = CEPH_CAP_PIN; /* so we can open */
+       ci->i_rbytes = 0;
+       return inode;
+}
+
+const struct inode_operations ceph_file_iops = {
+       .permission = ceph_permission,
+       .setattr = ceph_setattr,
+       .getattr = ceph_getattr,
+       .setxattr = ceph_setxattr,
+       .getxattr = ceph_getxattr,
+       .listxattr = ceph_listxattr,
+       .removexattr = ceph_removexattr,
+};
+
+
+/*
+ * We use a 'frag tree' to keep track of the MDS's directory fragments
+ * for a given inode (usually there is just a single fragment).  We
+ * need to know when a child frag is delegated to a new MDS, or when
+ * it is flagged as replicated, so we can direct our requests
+ * accordingly.
+ */
+
+/*
+ * find/create a frag in the tree
+ */
+static struct ceph_inode_frag *__get_or_create_frag(struct ceph_inode_info *ci,
+                                                   u32 f)
+{
+       struct rb_node **p;
+       struct rb_node *parent = NULL;
+       struct ceph_inode_frag *frag;
+       int c;
+
+       p = &ci->i_fragtree.rb_node;
+       while (*p) {
+               parent = *p;
+               frag = rb_entry(parent, struct ceph_inode_frag, node);
+               c = ceph_frag_compare(f, frag->frag);
+               if (c < 0)
+                       p = &(*p)->rb_left;
+               else if (c > 0)
+                       p = &(*p)->rb_right;
+               else
+                       return frag;
+       }
+
+       frag = kmalloc(sizeof(*frag), GFP_NOFS);
+       if (!frag) {
+               pr_err("__get_or_create_frag ENOMEM on %p %llx.%llx "
+                      "frag %x\n", &ci->vfs_inode,
+                      ceph_vinop(&ci->vfs_inode), f);
+               return ERR_PTR(-ENOMEM);
+       }
+       frag->frag = f;
+       frag->split_by = 0;
+       frag->mds = -1;
+       frag->ndist = 0;
+
+       rb_link_node(&frag->node, parent, p);
+       rb_insert_color(&frag->node, &ci->i_fragtree);
+
+       dout("get_or_create_frag added %llx.%llx frag %x\n",
+            ceph_vinop(&ci->vfs_inode), f);
+       return frag;
+}
+
+/*
+ * find a specific frag @f
+ */
+struct ceph_inode_frag *__ceph_find_frag(struct ceph_inode_info *ci, u32 f)
+{
+       struct rb_node *n = ci->i_fragtree.rb_node;
+
+       while (n) {
+               struct ceph_inode_frag *frag =
+                       rb_entry(n, struct ceph_inode_frag, node);
+               int c = ceph_frag_compare(f, frag->frag);
+               if (c < 0)
+                       n = n->rb_left;
+               else if (c > 0)
+                       n = n->rb_right;
+               else
+                       return frag;
+       }
+       return NULL;
+}
+
+/*
+ * Choose frag containing the given value @v.  If @pfrag is
+ * specified, copy the frag delegation info to the caller if
+ * it is present.
+ */
+u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
+                    struct ceph_inode_frag *pfrag,
+                    int *found)
+{
+       u32 t = ceph_frag_make(0, 0);
+       struct ceph_inode_frag *frag;
+       unsigned nway, i;
+       u32 n;
+
+       if (found)
+               *found = 0;
+
+       mutex_lock(&ci->i_fragtree_mutex);
+       while (1) {
+               WARN_ON(!ceph_frag_contains_value(t, v));
+               frag = __ceph_find_frag(ci, t);
+               if (!frag)
+                       break; /* t is a leaf */
+               if (frag->split_by == 0) {
+                       if (pfrag)
+                               memcpy(pfrag, frag, sizeof(*pfrag));
+                       if (found)
+                               *found = 1;
+                       break;
+               }
+
+               /* choose child */
+               nway = 1 << frag->split_by;
+               dout("choose_frag(%x) %x splits by %d (%d ways)\n", v, t,
+                    frag->split_by, nway);
+               for (i = 0; i < nway; i++) {
+                       n = ceph_frag_make_child(t, frag->split_by, i);
+                       if (ceph_frag_contains_value(n, v)) {
+                               t = n;
+                               break;
+                       }
+               }
+               BUG_ON(i == nway);
+       }
+       dout("choose_frag(%x) = %x\n", v, t);
+
+       mutex_unlock(&ci->i_fragtree_mutex);
+       return t;
+}
+
+/*
+ * Process dirfrag (delegation) info from the mds.  Include leaf
+ * fragment in tree ONLY if ndist > 0.  Otherwise, only
+ * branches/splits are included in i_fragtree)
+ */
+static int ceph_fill_dirfrag(struct inode *inode,
+                            struct ceph_mds_reply_dirfrag *dirinfo)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_inode_frag *frag;
+       u32 id = le32_to_cpu(dirinfo->frag);
+       int mds = le32_to_cpu(dirinfo->auth);
+       int ndist = le32_to_cpu(dirinfo->ndist);
+       int i;
+       int err = 0;
+
+       mutex_lock(&ci->i_fragtree_mutex);
+       if (ndist == 0) {
+               /* no delegation info needed. */
+               frag = __ceph_find_frag(ci, id);
+               if (!frag)
+                       goto out;
+               if (frag->split_by == 0) {
+                       /* tree leaf, remove */
+                       dout("fill_dirfrag removed %llx.%llx frag %x"
+                            " (no ref)\n", ceph_vinop(inode), id);
+                       rb_erase(&frag->node, &ci->i_fragtree);
+                       kfree(frag);
+               } else {
+                       /* tree branch, keep and clear */
+                       dout("fill_dirfrag cleared %llx.%llx frag %x"
+                            " referral\n", ceph_vinop(inode), id);
+                       frag->mds = -1;
+                       frag->ndist = 0;
+               }
+               goto out;
+       }
+
+
+       /* find/add this frag to store mds delegation info */
+       frag = __get_or_create_frag(ci, id);
+       if (IS_ERR(frag)) {
+               /* this is not the end of the world; we can continue
+                  with bad/inaccurate delegation info */
+               pr_err("fill_dirfrag ENOMEM on mds ref %llx.%llx fg %x\n",
+                      ceph_vinop(inode), le32_to_cpu(dirinfo->frag));
+               err = -ENOMEM;
+               goto out;
+       }
+
+       frag->mds = mds;
+       frag->ndist = min_t(u32, ndist, CEPH_MAX_DIRFRAG_REP);
+       for (i = 0; i < frag->ndist; i++)
+               frag->dist[i] = le32_to_cpu(dirinfo->dist[i]);
+       dout("fill_dirfrag %llx.%llx frag %x ndist=%d\n",
+            ceph_vinop(inode), frag->frag, frag->ndist);
+
+out:
+       mutex_unlock(&ci->i_fragtree_mutex);
+       return err;
+}
+
+
+/*
+ * initialize a newly allocated inode.
+ */
+struct inode *ceph_alloc_inode(struct super_block *sb)
+{
+       struct ceph_inode_info *ci;
+       int i;
+
+       ci = kmem_cache_alloc(ceph_inode_cachep, GFP_NOFS);
+       if (!ci)
+               return NULL;
+
+       dout("alloc_inode %p\n", &ci->vfs_inode);
+
+       ci->i_version = 0;
+       ci->i_time_warp_seq = 0;
+       ci->i_ceph_flags = 0;
+       ci->i_release_count = 0;
+       ci->i_symlink = NULL;
+
+       ci->i_fragtree = RB_ROOT;
+       mutex_init(&ci->i_fragtree_mutex);
+
+       ci->i_xattrs.blob = NULL;
+       ci->i_xattrs.prealloc_blob = NULL;
+       ci->i_xattrs.dirty = false;
+       ci->i_xattrs.index = RB_ROOT;
+       ci->i_xattrs.count = 0;
+       ci->i_xattrs.names_size = 0;
+       ci->i_xattrs.vals_size = 0;
+       ci->i_xattrs.version = 0;
+       ci->i_xattrs.index_version = 0;
+
+       ci->i_caps = RB_ROOT;
+       ci->i_auth_cap = NULL;
+       ci->i_dirty_caps = 0;
+       ci->i_flushing_caps = 0;
+       INIT_LIST_HEAD(&ci->i_dirty_item);
+       INIT_LIST_HEAD(&ci->i_flushing_item);
+       ci->i_cap_flush_seq = 0;
+       ci->i_cap_flush_last_tid = 0;
+       memset(&ci->i_cap_flush_tid, 0, sizeof(ci->i_cap_flush_tid));
+       init_waitqueue_head(&ci->i_cap_wq);
+       ci->i_hold_caps_min = 0;
+       ci->i_hold_caps_max = 0;
+       INIT_LIST_HEAD(&ci->i_cap_delay_list);
+       ci->i_cap_exporting_mds = 0;
+       ci->i_cap_exporting_mseq = 0;
+       ci->i_cap_exporting_issued = 0;
+       INIT_LIST_HEAD(&ci->i_cap_snaps);
+       ci->i_head_snapc = NULL;
+       ci->i_snap_caps = 0;
+
+       for (i = 0; i < CEPH_FILE_MODE_NUM; i++)
+               ci->i_nr_by_mode[i] = 0;
+
+       ci->i_truncate_seq = 0;
+       ci->i_truncate_size = 0;
+       ci->i_truncate_pending = 0;
+
+       ci->i_max_size = 0;
+       ci->i_reported_size = 0;
+       ci->i_wanted_max_size = 0;
+       ci->i_requested_max_size = 0;
+
+       ci->i_pin_ref = 0;
+       ci->i_rd_ref = 0;
+       ci->i_rdcache_ref = 0;
+       ci->i_wr_ref = 0;
+       ci->i_wrbuffer_ref = 0;
+       ci->i_wrbuffer_ref_head = 0;
+       ci->i_shared_gen = 0;
+       ci->i_rdcache_gen = 0;
+       ci->i_rdcache_revoking = 0;
+
+       INIT_LIST_HEAD(&ci->i_unsafe_writes);
+       INIT_LIST_HEAD(&ci->i_unsafe_dirops);
+       spin_lock_init(&ci->i_unsafe_lock);
+
+       ci->i_snap_realm = NULL;
+       INIT_LIST_HEAD(&ci->i_snap_realm_item);
+       INIT_LIST_HEAD(&ci->i_snap_flush_item);
+
+       INIT_WORK(&ci->i_wb_work, ceph_writeback_work);
+       INIT_WORK(&ci->i_pg_inv_work, ceph_invalidate_work);
+
+       INIT_WORK(&ci->i_vmtruncate_work, ceph_vmtruncate_work);
+
+       return &ci->vfs_inode;
+}
+
+void ceph_destroy_inode(struct inode *inode)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_inode_frag *frag;
+       struct rb_node *n;
+
+       dout("destroy_inode %p ino %llx.%llx\n", inode, ceph_vinop(inode));
+
+       ceph_queue_caps_release(inode);
+
+       /*
+        * we may still have a snap_realm reference if there are stray
+        * caps in i_cap_exporting_issued or i_snap_caps.
+        */
+       if (ci->i_snap_realm) {
+               struct ceph_mds_client *mdsc =
+                       &ceph_client(ci->vfs_inode.i_sb)->mdsc;
+               struct ceph_snap_realm *realm = ci->i_snap_realm;
+
+               dout(" dropping residual ref to snap realm %p\n", realm);
+               spin_lock(&realm->inodes_with_caps_lock);
+               list_del_init(&ci->i_snap_realm_item);
+               spin_unlock(&realm->inodes_with_caps_lock);
+               ceph_put_snap_realm(mdsc, realm);
+       }
+
+       kfree(ci->i_symlink);
+       while ((n = rb_first(&ci->i_fragtree)) != NULL) {
+               frag = rb_entry(n, struct ceph_inode_frag, node);
+               rb_erase(n, &ci->i_fragtree);
+               kfree(frag);
+       }
+
+       __ceph_destroy_xattrs(ci);
+       if (ci->i_xattrs.blob)
+               ceph_buffer_put(ci->i_xattrs.blob);
+       if (ci->i_xattrs.prealloc_blob)
+               ceph_buffer_put(ci->i_xattrs.prealloc_blob);
+
+       kmem_cache_free(ceph_inode_cachep, ci);
+}
+
+
+/*
+ * Helpers to fill in size, ctime, mtime, and atime.  We have to be
+ * careful because either the client or MDS may have more up to date
+ * info, depending on which capabilities are held, and whether
+ * time_warp_seq or truncate_seq have increased.  (Ordinarily, mtime
+ * and size are monotonically increasing, except when utimes() or
+ * truncate() increments the corresponding _seq values.)
+ */
+int ceph_fill_file_size(struct inode *inode, int issued,
+                       u32 truncate_seq, u64 truncate_size, u64 size)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int queue_trunc = 0;
+
+       if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) > 0 ||
+           (truncate_seq == ci->i_truncate_seq && size > inode->i_size)) {
+               dout("size %lld -> %llu\n", inode->i_size, size);
+               inode->i_size = size;
+               inode->i_blocks = (size + (1<<9) - 1) >> 9;
+               ci->i_reported_size = size;
+               if (truncate_seq != ci->i_truncate_seq) {
+                       dout("truncate_seq %u -> %u\n",
+                            ci->i_truncate_seq, truncate_seq);
+                       ci->i_truncate_seq = truncate_seq;
+                       /*
+                        * If we hold relevant caps, or in the case where we're
+                        * not the only client referencing this file and we
+                        * don't hold those caps, then we need to check whether
+                        * the file is either opened or mmaped
+                        */
+                       if ((issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_RD|
+                                     CEPH_CAP_FILE_WR|CEPH_CAP_FILE_BUFFER|
+                                     CEPH_CAP_FILE_EXCL)) ||
+                           mapping_mapped(inode->i_mapping) ||
+                           __ceph_caps_file_wanted(ci)) {
+                               ci->i_truncate_pending++;
+                               queue_trunc = 1;
+                       }
+               }
+       }
+       if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) >= 0 &&
+           ci->i_truncate_size != truncate_size) {
+               dout("truncate_size %lld -> %llu\n", ci->i_truncate_size,
+                    truncate_size);
+               ci->i_truncate_size = truncate_size;
+       }
+       return queue_trunc;
+}
+
+void ceph_fill_file_time(struct inode *inode, int issued,
+                        u64 time_warp_seq, struct timespec *ctime,
+                        struct timespec *mtime, struct timespec *atime)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int warn = 0;
+
+       if (issued & (CEPH_CAP_FILE_EXCL|
+                     CEPH_CAP_FILE_WR|
+                     CEPH_CAP_FILE_BUFFER)) {
+               if (timespec_compare(ctime, &inode->i_ctime) > 0) {
+                       dout("ctime %ld.%09ld -> %ld.%09ld inc w/ cap\n",
+                            inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
+                            ctime->tv_sec, ctime->tv_nsec);
+                       inode->i_ctime = *ctime;
+               }
+               if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) {
+                       /* the MDS did a utimes() */
+                       dout("mtime %ld.%09ld -> %ld.%09ld "
+                            "tw %d -> %d\n",
+                            inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
+                            mtime->tv_sec, mtime->tv_nsec,
+                            ci->i_time_warp_seq, (int)time_warp_seq);
+
+                       inode->i_mtime = *mtime;
+                       inode->i_atime = *atime;
+                       ci->i_time_warp_seq = time_warp_seq;
+               } else if (time_warp_seq == ci->i_time_warp_seq) {
+                       /* nobody did utimes(); take the max */
+                       if (timespec_compare(mtime, &inode->i_mtime) > 0) {
+                               dout("mtime %ld.%09ld -> %ld.%09ld inc\n",
+                                    inode->i_mtime.tv_sec,
+                                    inode->i_mtime.tv_nsec,
+                                    mtime->tv_sec, mtime->tv_nsec);
+                               inode->i_mtime = *mtime;
+                       }
+                       if (timespec_compare(atime, &inode->i_atime) > 0) {
+                               dout("atime %ld.%09ld -> %ld.%09ld inc\n",
+                                    inode->i_atime.tv_sec,
+                                    inode->i_atime.tv_nsec,
+                                    atime->tv_sec, atime->tv_nsec);
+                               inode->i_atime = *atime;
+                       }
+               } else if (issued & CEPH_CAP_FILE_EXCL) {
+                       /* we did a utimes(); ignore mds values */
+               } else {
+                       warn = 1;
+               }
+       } else {
+               /* we have no write caps; whatever the MDS says is true */
+               if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) >= 0) {
+                       inode->i_ctime = *ctime;
+                       inode->i_mtime = *mtime;
+                       inode->i_atime = *atime;
+                       ci->i_time_warp_seq = time_warp_seq;
+               } else {
+                       warn = 1;
+               }
+       }
+       if (warn) /* time_warp_seq shouldn't go backwards */
+               dout("%p mds time_warp_seq %llu < %u\n",
+                    inode, time_warp_seq, ci->i_time_warp_seq);
+}
+
+/*
+ * Populate an inode based on info from mds.  May be called on new or
+ * existing inodes.
+ */
+static int fill_inode(struct inode *inode,
+                     struct ceph_mds_reply_info_in *iinfo,
+                     struct ceph_mds_reply_dirfrag *dirinfo,
+                     struct ceph_mds_session *session,
+                     unsigned long ttl_from, int cap_fmode,
+                     struct ceph_cap_reservation *caps_reservation)
+{
+       struct ceph_mds_reply_inode *info = iinfo->in;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int i;
+       int issued, implemented;
+       struct timespec mtime, atime, ctime;
+       u32 nsplits;
+       struct ceph_buffer *xattr_blob = NULL;
+       int err = 0;
+       int queue_trunc = 0;
+
+       dout("fill_inode %p ino %llx.%llx v %llu had %llu\n",
+            inode, ceph_vinop(inode), le64_to_cpu(info->version),
+            ci->i_version);
+
+       /*
+        * prealloc xattr data, if it looks like we'll need it.  only
+        * if len > 4 (meaning there are actually xattrs; the first 4
+        * bytes are the xattr count).
+        */
+       if (iinfo->xattr_len > 4) {
+               xattr_blob = ceph_buffer_new(iinfo->xattr_len, GFP_NOFS);
+               if (!xattr_blob)
+                       pr_err("fill_inode ENOMEM xattr blob %d bytes\n",
+                              iinfo->xattr_len);
+       }
+
+       spin_lock(&inode->i_lock);
+
+       /*
+        * provided version will be odd if inode value is projected,
+        * even if stable.  skip the update if we have a newer info
+        * (e.g., due to inode info racing form multiple MDSs), or if
+        * we are getting projected (unstable) inode info.
+        */
+       if (le64_to_cpu(info->version) > 0 &&
+           (ci->i_version & ~1) > le64_to_cpu(info->version))
+               goto no_change;
+
+       issued = __ceph_caps_issued(ci, &implemented);
+       issued |= implemented | __ceph_caps_dirty(ci);
+
+       /* update inode */
+       ci->i_version = le64_to_cpu(info->version);
+       inode->i_version++;
+       inode->i_rdev = le32_to_cpu(info->rdev);
+
+       if ((issued & CEPH_CAP_AUTH_EXCL) == 0) {
+               inode->i_mode = le32_to_cpu(info->mode);
+               inode->i_uid = le32_to_cpu(info->uid);
+               inode->i_gid = le32_to_cpu(info->gid);
+               dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode,
+                    inode->i_uid, inode->i_gid);
+       }
+
+       if ((issued & CEPH_CAP_LINK_EXCL) == 0)
+               inode->i_nlink = le32_to_cpu(info->nlink);
+
+       /* be careful with mtime, atime, size */
+       ceph_decode_timespec(&atime, &info->atime);
+       ceph_decode_timespec(&mtime, &info->mtime);
+       ceph_decode_timespec(&ctime, &info->ctime);
+       queue_trunc = ceph_fill_file_size(inode, issued,
+                                         le32_to_cpu(info->truncate_seq),
+                                         le64_to_cpu(info->truncate_size),
+                                         le64_to_cpu(info->size));
+       ceph_fill_file_time(inode, issued,
+                           le32_to_cpu(info->time_warp_seq),
+                           &ctime, &mtime, &atime);
+
+       ci->i_max_size = le64_to_cpu(info->max_size);
+       ci->i_layout = info->layout;
+       inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
+
+       /* xattrs */
+       /* note that if i_xattrs.len <= 4, i_xattrs.data will still be NULL. */
+       if ((issued & CEPH_CAP_XATTR_EXCL) == 0 &&
+           le64_to_cpu(info->xattr_version) > ci->i_xattrs.version) {
+               if (ci->i_xattrs.blob)
+                       ceph_buffer_put(ci->i_xattrs.blob);
+               ci->i_xattrs.blob = xattr_blob;
+               if (xattr_blob)
+                       memcpy(ci->i_xattrs.blob->vec.iov_base,
+                              iinfo->xattr_data, iinfo->xattr_len);
+               ci->i_xattrs.version = le64_to_cpu(info->xattr_version);
+       }
+
+       inode->i_mapping->a_ops = &ceph_aops;
+       inode->i_mapping->backing_dev_info =
+               &ceph_client(inode->i_sb)->backing_dev_info;
+
+       switch (inode->i_mode & S_IFMT) {
+       case S_IFIFO:
+       case S_IFBLK:
+       case S_IFCHR:
+       case S_IFSOCK:
+               init_special_inode(inode, inode->i_mode, inode->i_rdev);
+               inode->i_op = &ceph_file_iops;
+               break;
+       case S_IFREG:
+               inode->i_op = &ceph_file_iops;
+               inode->i_fop = &ceph_file_fops;
+               break;
+       case S_IFLNK:
+               inode->i_op = &ceph_symlink_iops;
+               if (!ci->i_symlink) {
+                       int symlen = iinfo->symlink_len;
+                       char *sym;
+
+                       BUG_ON(symlen != inode->i_size);
+                       spin_unlock(&inode->i_lock);
+
+                       err = -ENOMEM;
+                       sym = kmalloc(symlen+1, GFP_NOFS);
+                       if (!sym)
+                               goto out;
+                       memcpy(sym, iinfo->symlink, symlen);
+                       sym[symlen] = 0;
+
+                       spin_lock(&inode->i_lock);
+                       if (!ci->i_symlink)
+                               ci->i_symlink = sym;
+                       else
+                               kfree(sym); /* lost a race */
+               }
+               break;
+       case S_IFDIR:
+               inode->i_op = &ceph_dir_iops;
+               inode->i_fop = &ceph_dir_fops;
+
+               ci->i_files = le64_to_cpu(info->files);
+               ci->i_subdirs = le64_to_cpu(info->subdirs);
+               ci->i_rbytes = le64_to_cpu(info->rbytes);
+               ci->i_rfiles = le64_to_cpu(info->rfiles);
+               ci->i_rsubdirs = le64_to_cpu(info->rsubdirs);
+               ceph_decode_timespec(&ci->i_rctime, &info->rctime);
+
+               /* set dir completion flag? */
+               if (ci->i_files == 0 && ci->i_subdirs == 0 &&
+                   ceph_snap(inode) == CEPH_NOSNAP &&
+                   (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED)) {
+                       dout(" marking %p complete (empty)\n", inode);
+                       ci->i_ceph_flags |= CEPH_I_COMPLETE;
+                       ci->i_max_offset = 2;
+               }
+
+               /* it may be better to set st_size in getattr instead? */
+               if (ceph_test_opt(ceph_client(inode->i_sb), RBYTES))
+                       inode->i_size = ci->i_rbytes;
+               break;
+       default:
+               pr_err("fill_inode %llx.%llx BAD mode 0%o\n",
+                      ceph_vinop(inode), inode->i_mode);
+       }
+
+no_change:
+       spin_unlock(&inode->i_lock);
+
+       /* queue truncate if we saw i_size decrease */
+       if (queue_trunc)
+               ceph_queue_vmtruncate(inode);
+
+       /* populate frag tree */
+       /* FIXME: move me up, if/when version reflects fragtree changes */
+       nsplits = le32_to_cpu(info->fragtree.nsplits);
+       mutex_lock(&ci->i_fragtree_mutex);
+       for (i = 0; i < nsplits; i++) {
+               u32 id = le32_to_cpu(info->fragtree.splits[i].frag);
+               struct ceph_inode_frag *frag = __get_or_create_frag(ci, id);
+
+               if (IS_ERR(frag))
+                       continue;
+               frag->split_by = le32_to_cpu(info->fragtree.splits[i].by);
+               dout(" frag %x split by %d\n", frag->frag, frag->split_by);
+       }
+       mutex_unlock(&ci->i_fragtree_mutex);
+
+       /* were we issued a capability? */
+       if (info->cap.caps) {
+               if (ceph_snap(inode) == CEPH_NOSNAP) {
+                       ceph_add_cap(inode, session,
+                                    le64_to_cpu(info->cap.cap_id),
+                                    cap_fmode,
+                                    le32_to_cpu(info->cap.caps),
+                                    le32_to_cpu(info->cap.wanted),
+                                    le32_to_cpu(info->cap.seq),
+                                    le32_to_cpu(info->cap.mseq),
+                                    le64_to_cpu(info->cap.realm),
+                                    info->cap.flags,
+                                    caps_reservation);
+               } else {
+                       spin_lock(&inode->i_lock);
+                       dout(" %p got snap_caps %s\n", inode,
+                            ceph_cap_string(le32_to_cpu(info->cap.caps)));
+                       ci->i_snap_caps |= le32_to_cpu(info->cap.caps);
+                       if (cap_fmode >= 0)
+                               __ceph_get_fmode(ci, cap_fmode);
+                       spin_unlock(&inode->i_lock);
+               }
+       } else if (cap_fmode >= 0) {
+               pr_warning("mds issued no caps on %llx.%llx\n",
+                          ceph_vinop(inode));
+               __ceph_get_fmode(ci, cap_fmode);
+       }
+
+       /* update delegation info? */
+       if (dirinfo)
+               ceph_fill_dirfrag(inode, dirinfo);
+
+       err = 0;
+
+out:
+       if (xattr_blob)
+               ceph_buffer_put(xattr_blob);
+       return err;
+}
+
+/*
+ * caller should hold session s_mutex.
+ */
+static void update_dentry_lease(struct dentry *dentry,
+                               struct ceph_mds_reply_lease *lease,
+                               struct ceph_mds_session *session,
+                               unsigned long from_time)
+{
+       struct ceph_dentry_info *di = ceph_dentry(dentry);
+       long unsigned duration = le32_to_cpu(lease->duration_ms);
+       long unsigned ttl = from_time + (duration * HZ) / 1000;
+       long unsigned half_ttl = from_time + (duration * HZ / 2) / 1000;
+       struct inode *dir;
+
+       /* only track leases on regular dentries */
+       if (dentry->d_op != &ceph_dentry_ops)
+               return;
+
+       spin_lock(&dentry->d_lock);
+       dout("update_dentry_lease %p mask %d duration %lu ms ttl %lu\n",
+            dentry, le16_to_cpu(lease->mask), duration, ttl);
+
+       /* make lease_rdcache_gen match directory */
+       dir = dentry->d_parent->d_inode;
+       di->lease_shared_gen = ceph_inode(dir)->i_shared_gen;
+
+       if (lease->mask == 0)
+               goto out_unlock;
+
+       if (di->lease_gen == session->s_cap_gen &&
+           time_before(ttl, dentry->d_time))
+               goto out_unlock;  /* we already have a newer lease. */
+
+       if (di->lease_session && di->lease_session != session)
+               goto out_unlock;
+
+       ceph_dentry_lru_touch(dentry);
+
+       if (!di->lease_session)
+               di->lease_session = ceph_get_mds_session(session);
+       di->lease_gen = session->s_cap_gen;
+       di->lease_seq = le32_to_cpu(lease->seq);
+       di->lease_renew_after = half_ttl;
+       di->lease_renew_from = 0;
+       dentry->d_time = ttl;
+out_unlock:
+       spin_unlock(&dentry->d_lock);
+       return;
+}
+
+/*
+ * splice a dentry to an inode.
+ * caller must hold directory i_mutex for this to be safe.
+ *
+ * we will only rehash the resulting dentry if @prehash is
+ * true; @prehash will be set to false (for the benefit of
+ * the caller) if we fail.
+ */
+static struct dentry *splice_dentry(struct dentry *dn, struct inode *in,
+                                   bool *prehash)
+{
+       struct dentry *realdn;
+
+       /* dn must be unhashed */
+       if (!d_unhashed(dn))
+               d_drop(dn);
+       realdn = d_materialise_unique(dn, in);
+       if (IS_ERR(realdn)) {
+               pr_err("splice_dentry error %p inode %p ino %llx.%llx\n",
+                      dn, in, ceph_vinop(in));
+               if (prehash)
+                       *prehash = false; /* don't rehash on error */
+               dn = realdn; /* note realdn contains the error */
+               goto out;
+       } else if (realdn) {
+               dout("dn %p (%d) spliced with %p (%d) "
+                    "inode %p ino %llx.%llx\n",
+                    dn, atomic_read(&dn->d_count),
+                    realdn, atomic_read(&realdn->d_count),
+                    realdn->d_inode, ceph_vinop(realdn->d_inode));
+               dput(dn);
+               dn = realdn;
+       } else {
+               BUG_ON(!ceph_dentry(dn));
+
+               dout("dn %p attached to %p ino %llx.%llx\n",
+                    dn, dn->d_inode, ceph_vinop(dn->d_inode));
+       }
+       if ((!prehash || *prehash) && d_unhashed(dn))
+               d_rehash(dn);
+out:
+       return dn;
+}
+
+/*
+ * Set dentry's directory position based on the current dir's max, and
+ * order it in d_subdirs, so that dcache_readdir behaves.
+ */
+static void ceph_set_dentry_offset(struct dentry *dn)
+{
+       struct dentry *dir = dn->d_parent;
+       struct inode *inode = dn->d_parent->d_inode;
+       struct ceph_dentry_info *di;
+
+       BUG_ON(!inode);
+
+       di = ceph_dentry(dn);
+
+       spin_lock(&inode->i_lock);
+       di->offset = ceph_inode(inode)->i_max_offset++;
+       spin_unlock(&inode->i_lock);
+
+       spin_lock(&dcache_lock);
+       spin_lock(&dn->d_lock);
+       list_move_tail(&dir->d_subdirs, &dn->d_u.d_child);
+       dout("set_dentry_offset %p %lld (%p %p)\n", dn, di->offset,
+            dn->d_u.d_child.prev, dn->d_u.d_child.next);
+       spin_unlock(&dn->d_lock);
+       spin_unlock(&dcache_lock);
+}
+
+/*
+ * Incorporate results into the local cache.  This is either just
+ * one inode, or a directory, dentry, and possibly linked-to inode (e.g.,
+ * after a lookup).
+ *
+ * A reply may contain
+ *         a directory inode along with a dentry.
+ *  and/or a target inode
+ *
+ * Called with snap_rwsem (read).
+ */
+int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
+                   struct ceph_mds_session *session)
+{
+       struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
+       struct inode *in = NULL;
+       struct ceph_mds_reply_inode *ininfo;
+       struct ceph_vino vino;
+       struct ceph_client *client = ceph_sb_to_client(sb);
+       int i = 0;
+       int err = 0;
+
+       dout("fill_trace %p is_dentry %d is_target %d\n", req,
+            rinfo->head->is_dentry, rinfo->head->is_target);
+
+#if 0
+       /*
+        * Debugging hook:
+        *
+        * If we resend completed ops to a recovering mds, we get no
+        * trace.  Since that is very rare, pretend this is the case
+        * to ensure the 'no trace' handlers in the callers behave.
+        *
+        * Fill in inodes unconditionally to avoid breaking cap
+        * invariants.
+        */
+       if (rinfo->head->op & CEPH_MDS_OP_WRITE) {
+               pr_info("fill_trace faking empty trace on %lld %s\n",
+                       req->r_tid, ceph_mds_op_name(rinfo->head->op));
+               if (rinfo->head->is_dentry) {
+                       rinfo->head->is_dentry = 0;
+                       err = fill_inode(req->r_locked_dir,
+                                        &rinfo->diri, rinfo->dirfrag,
+                                        session, req->r_request_started, -1);
+               }
+               if (rinfo->head->is_target) {
+                       rinfo->head->is_target = 0;
+                       ininfo = rinfo->targeti.in;
+                       vino.ino = le64_to_cpu(ininfo->ino);
+                       vino.snap = le64_to_cpu(ininfo->snapid);
+                       in = ceph_get_inode(sb, vino);
+                       err = fill_inode(in, &rinfo->targeti, NULL,
+                                        session, req->r_request_started,
+                                        req->r_fmode);
+                       iput(in);
+               }
+       }
+#endif
+
+       if (!rinfo->head->is_target && !rinfo->head->is_dentry) {
+               dout("fill_trace reply is empty!\n");
+               if (rinfo->head->result == 0 && req->r_locked_dir) {
+                       struct ceph_inode_info *ci =
+                               ceph_inode(req->r_locked_dir);
+                       dout(" clearing %p complete (empty trace)\n",
+                            req->r_locked_dir);
+                       ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
+                       ci->i_release_count++;
+               }
+               return 0;
+       }
+
+       if (rinfo->head->is_dentry) {
+               struct inode *dir = req->r_locked_dir;
+
+               err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag,
+                                session, req->r_request_started, -1,
+                                &req->r_caps_reservation);
+               if (err < 0)
+                       return err;
+       }
+
+       /*
+        * ignore null lease/binding on snapdir ENOENT, or else we
+        * will have trouble splicing in the virtual snapdir later
+        */
+       if (rinfo->head->is_dentry && !req->r_aborted &&
+           (rinfo->head->is_target || strncmp(req->r_dentry->d_name.name,
+                                              client->mount_args->snapdir_name,
+                                              req->r_dentry->d_name.len))) {
+               /*
+                * lookup link rename   : null -> possibly existing inode
+                * mknod symlink mkdir  : null -> new inode
+                * unlink               : linked -> null
+                */
+               struct inode *dir = req->r_locked_dir;
+               struct dentry *dn = req->r_dentry;
+               bool have_dir_cap, have_lease;
+
+               BUG_ON(!dn);
+               BUG_ON(!dir);
+               BUG_ON(dn->d_parent->d_inode != dir);
+               BUG_ON(ceph_ino(dir) !=
+                      le64_to_cpu(rinfo->diri.in->ino));
+               BUG_ON(ceph_snap(dir) !=
+                      le64_to_cpu(rinfo->diri.in->snapid));
+
+               /* do we have a lease on the whole dir? */
+               have_dir_cap =
+                       (le32_to_cpu(rinfo->diri.in->cap.caps) &
+                        CEPH_CAP_FILE_SHARED);
+
+               /* do we have a dn lease? */
+               have_lease = have_dir_cap ||
+                       (le16_to_cpu(rinfo->dlease->mask) &
+                        CEPH_LOCK_DN);
+
+               if (!have_lease)
+                       dout("fill_trace  no dentry lease or dir cap\n");
+
+               /* rename? */
+               if (req->r_old_dentry && req->r_op == CEPH_MDS_OP_RENAME) {
+                       dout(" src %p '%.*s' dst %p '%.*s'\n",
+                            req->r_old_dentry,
+                            req->r_old_dentry->d_name.len,
+                            req->r_old_dentry->d_name.name,
+                            dn, dn->d_name.len, dn->d_name.name);
+                       dout("fill_trace doing d_move %p -> %p\n",
+                            req->r_old_dentry, dn);
+
+                       /* d_move screws up d_subdirs order */
+                       ceph_i_clear(dir, CEPH_I_COMPLETE);
+
+                       d_move(req->r_old_dentry, dn);
+                       dout(" src %p '%.*s' dst %p '%.*s'\n",
+                            req->r_old_dentry,
+                            req->r_old_dentry->d_name.len,
+                            req->r_old_dentry->d_name.name,
+                            dn, dn->d_name.len, dn->d_name.name);
+                       /* ensure target dentry is invalidated, despite
+                          rehashing bug in vfs_rename_dir */
+                       dn->d_time = jiffies;
+                       ceph_dentry(dn)->lease_shared_gen = 0;
+                       /* take overwritten dentry's readdir offset */
+                       ceph_dentry(req->r_old_dentry)->offset =
+                               ceph_dentry(dn)->offset;
+                       dn = req->r_old_dentry;  /* use old_dentry */
+                       in = dn->d_inode;
+               }
+
+               /* null dentry? */
+               if (!rinfo->head->is_target) {
+                       dout("fill_trace null dentry\n");
+                       if (dn->d_inode) {
+                               dout("d_delete %p\n", dn);
+                               d_delete(dn);
+                       } else {
+                               dout("d_instantiate %p NULL\n", dn);
+                               d_instantiate(dn, NULL);
+                               if (have_lease && d_unhashed(dn))
+                                       d_rehash(dn);
+                               update_dentry_lease(dn, rinfo->dlease,
+                                                   session,
+                                                   req->r_request_started);
+                       }
+                       goto done;
+               }
+
+               /* attach proper inode */
+               ininfo = rinfo->targeti.in;
+               vino.ino = le64_to_cpu(ininfo->ino);
+               vino.snap = le64_to_cpu(ininfo->snapid);
+               if (!dn->d_inode) {
+                       in = ceph_get_inode(sb, vino);
+                       if (IS_ERR(in)) {
+                               pr_err("fill_trace bad get_inode "
+                                      "%llx.%llx\n", vino.ino, vino.snap);
+                               err = PTR_ERR(in);
+                               d_delete(dn);
+                               goto done;
+                       }
+                       dn = splice_dentry(dn, in, &have_lease);
+                       if (IS_ERR(dn)) {
+                               err = PTR_ERR(dn);
+                               goto done;
+                       }
+                       req->r_dentry = dn;  /* may have spliced */
+                       ceph_set_dentry_offset(dn);
+                       igrab(in);
+               } else if (ceph_ino(in) == vino.ino &&
+                          ceph_snap(in) == vino.snap) {
+                       igrab(in);
+               } else {
+                       dout(" %p links to %p %llx.%llx, not %llx.%llx\n",
+                            dn, in, ceph_ino(in), ceph_snap(in),
+                            vino.ino, vino.snap);
+                       have_lease = false;
+                       in = NULL;
+               }
+
+               if (have_lease)
+                       update_dentry_lease(dn, rinfo->dlease, session,
+                                           req->r_request_started);
+               dout(" final dn %p\n", dn);
+               i++;
+       } else if (req->r_op == CEPH_MDS_OP_LOOKUPSNAP ||
+                  req->r_op == CEPH_MDS_OP_MKSNAP) {
+               struct dentry *dn = req->r_dentry;
+
+               /* fill out a snapdir LOOKUPSNAP dentry */
+               BUG_ON(!dn);
+               BUG_ON(!req->r_locked_dir);
+               BUG_ON(ceph_snap(req->r_locked_dir) != CEPH_SNAPDIR);
+               ininfo = rinfo->targeti.in;
+               vino.ino = le64_to_cpu(ininfo->ino);
+               vino.snap = le64_to_cpu(ininfo->snapid);
+               in = ceph_get_inode(sb, vino);
+               if (IS_ERR(in)) {
+                       pr_err("fill_inode get_inode badness %llx.%llx\n",
+                              vino.ino, vino.snap);
+                       err = PTR_ERR(in);
+                       d_delete(dn);
+                       goto done;
+               }
+               dout(" linking snapped dir %p to dn %p\n", in, dn);
+               dn = splice_dentry(dn, in, NULL);
+               if (IS_ERR(dn)) {
+                       err = PTR_ERR(dn);
+                       goto done;
+               }
+               ceph_set_dentry_offset(dn);
+               req->r_dentry = dn;  /* may have spliced */
+               igrab(in);
+               rinfo->head->is_dentry = 1;  /* fool notrace handlers */
+       }
+
+       if (rinfo->head->is_target) {
+               vino.ino = le64_to_cpu(rinfo->targeti.in->ino);
+               vino.snap = le64_to_cpu(rinfo->targeti.in->snapid);
+
+               if (in == NULL || ceph_ino(in) != vino.ino ||
+                   ceph_snap(in) != vino.snap) {
+                       in = ceph_get_inode(sb, vino);
+                       if (IS_ERR(in)) {
+                               err = PTR_ERR(in);
+                               goto done;
+                       }
+               }
+               req->r_target_inode = in;
+
+               err = fill_inode(in,
+                                &rinfo->targeti, NULL,
+                                session, req->r_request_started,
+                                (le32_to_cpu(rinfo->head->result) == 0) ?
+                                req->r_fmode : -1,
+                                &req->r_caps_reservation);
+               if (err < 0) {
+                       pr_err("fill_inode badness %p %llx.%llx\n",
+                              in, ceph_vinop(in));
+                       goto done;
+               }
+       }
+
+done:
+       dout("fill_trace done err=%d\n", err);
+       return err;
+}
+
+/*
+ * Prepopulate our cache with readdir results, leases, etc.
+ */
+int ceph_readdir_prepopulate(struct ceph_mds_request *req,
+                            struct ceph_mds_session *session)
+{
+       struct dentry *parent = req->r_dentry;
+       struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
+       struct qstr dname;
+       struct dentry *dn;
+       struct inode *in;
+       int err = 0, i;
+       struct inode *snapdir = NULL;
+       struct ceph_mds_request_head *rhead = req->r_request->front.iov_base;
+       u64 frag = le32_to_cpu(rhead->args.readdir.frag);
+       struct ceph_dentry_info *di;
+
+       if (le32_to_cpu(rinfo->head->op) == CEPH_MDS_OP_LSSNAP) {
+               snapdir = ceph_get_snapdir(parent->d_inode);
+               parent = d_find_alias(snapdir);
+               dout("readdir_prepopulate %d items under SNAPDIR dn %p\n",
+                    rinfo->dir_nr, parent);
+       } else {
+               dout("readdir_prepopulate %d items under dn %p\n",
+                    rinfo->dir_nr, parent);
+               if (rinfo->dir_dir)
+                       ceph_fill_dirfrag(parent->d_inode, rinfo->dir_dir);
+       }
+
+       for (i = 0; i < rinfo->dir_nr; i++) {
+               struct ceph_vino vino;
+
+               dname.name = rinfo->dir_dname[i];
+               dname.len = rinfo->dir_dname_len[i];
+               dname.hash = full_name_hash(dname.name, dname.len);
+
+               vino.ino = le64_to_cpu(rinfo->dir_in[i].in->ino);
+               vino.snap = le64_to_cpu(rinfo->dir_in[i].in->snapid);
+
+retry_lookup:
+               dn = d_lookup(parent, &dname);
+               dout("d_lookup on parent=%p name=%.*s got %p\n",
+                    parent, dname.len, dname.name, dn);
+
+               if (!dn) {
+                       dn = d_alloc(parent, &dname);
+                       dout("d_alloc %p '%.*s' = %p\n", parent,
+                            dname.len, dname.name, dn);
+                       if (dn == NULL) {
+                               dout("d_alloc badness\n");
+                               err = -ENOMEM;
+                               goto out;
+                       }
+                       err = ceph_init_dentry(dn);
+                       if (err < 0)
+                               goto out;
+               } else if (dn->d_inode &&
+                          (ceph_ino(dn->d_inode) != vino.ino ||
+                           ceph_snap(dn->d_inode) != vino.snap)) {
+                       dout(" dn %p points to wrong inode %p\n",
+                            dn, dn->d_inode);
+                       d_delete(dn);
+                       dput(dn);
+                       goto retry_lookup;
+               } else {
+                       /* reorder parent's d_subdirs */
+                       spin_lock(&dcache_lock);
+                       spin_lock(&dn->d_lock);
+                       list_move(&dn->d_u.d_child, &parent->d_subdirs);
+                       spin_unlock(&dn->d_lock);
+                       spin_unlock(&dcache_lock);
+               }
+
+               di = dn->d_fsdata;
+               di->offset = ceph_make_fpos(frag, i + req->r_readdir_offset);
+
+               /* inode */
+               if (dn->d_inode) {
+                       in = dn->d_inode;
+               } else {
+                       in = ceph_get_inode(parent->d_sb, vino);
+                       if (in == NULL) {
+                               dout("new_inode badness\n");
+                               d_delete(dn);
+                               dput(dn);
+                               err = -ENOMEM;
+                               goto out;
+                       }
+                       dn = splice_dentry(dn, in, NULL);
+               }
+
+               if (fill_inode(in, &rinfo->dir_in[i], NULL, session,
+                              req->r_request_started, -1,
+                              &req->r_caps_reservation) < 0) {
+                       pr_err("fill_inode badness on %p\n", in);
+                       dput(dn);
+                       continue;
+               }
+               update_dentry_lease(dn, rinfo->dir_dlease[i],
+                                   req->r_session, req->r_request_started);
+               dput(dn);
+       }
+       req->r_did_prepopulate = true;
+
+out:
+       if (snapdir) {
+               iput(snapdir);
+               dput(parent);
+       }
+       dout("readdir_prepopulate done\n");
+       return err;
+}
+
+int ceph_inode_set_size(struct inode *inode, loff_t size)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int ret = 0;
+
+       spin_lock(&inode->i_lock);
+       dout("set_size %p %llu -> %llu\n", inode, inode->i_size, size);
+       inode->i_size = size;
+       inode->i_blocks = (size + (1 << 9) - 1) >> 9;
+
+       /* tell the MDS if we are approaching max_size */
+       if ((size << 1) >= ci->i_max_size &&
+           (ci->i_reported_size << 1) < ci->i_max_size)
+               ret = 1;
+
+       spin_unlock(&inode->i_lock);
+       return ret;
+}
+
+/*
+ * Write back inode data in a worker thread.  (This can't be done
+ * in the message handler context.)
+ */
+void ceph_queue_writeback(struct inode *inode)
+{
+       if (queue_work(ceph_inode_to_client(inode)->wb_wq,
+                      &ceph_inode(inode)->i_wb_work)) {
+               dout("ceph_queue_writeback %p\n", inode);
+               igrab(inode);
+       } else {
+               dout("ceph_queue_writeback %p failed\n", inode);
+       }
+}
+
+static void ceph_writeback_work(struct work_struct *work)
+{
+       struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
+                                                 i_wb_work);
+       struct inode *inode = &ci->vfs_inode;
+
+       dout("writeback %p\n", inode);
+       filemap_fdatawrite(&inode->i_data);
+       iput(inode);
+}
+
+/*
+ * queue an async invalidation
+ */
+void ceph_queue_invalidate(struct inode *inode)
+{
+       if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq,
+                      &ceph_inode(inode)->i_pg_inv_work)) {
+               dout("ceph_queue_invalidate %p\n", inode);
+               igrab(inode);
+       } else {
+               dout("ceph_queue_invalidate %p failed\n", inode);
+       }
+}
+
+/*
+ * invalidate any pages that are not dirty or under writeback.  this
+ * includes pages that are clean and mapped.
+ */
+static void ceph_invalidate_nondirty_pages(struct address_space *mapping)
+{
+       struct pagevec pvec;
+       pgoff_t next = 0;
+       int i;
+
+       pagevec_init(&pvec, 0);
+       while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
+               for (i = 0; i < pagevec_count(&pvec); i++) {
+                       struct page *page = pvec.pages[i];
+                       pgoff_t index;
+                       int skip_page =
+                               (PageDirty(page) || PageWriteback(page));
+
+                       if (!skip_page)
+                               skip_page = !trylock_page(page);
+
+                       /*
+                        * We really shouldn't be looking at the ->index of an
+                        * unlocked page.  But we're not allowed to lock these
+                        * pages.  So we rely upon nobody altering the ->index
+                        * of this (pinned-by-us) page.
+                        */
+                       index = page->index;
+                       if (index > next)
+                               next = index;
+                       next++;
+
+                       if (skip_page)
+                               continue;
+
+                       generic_error_remove_page(mapping, page);
+                       unlock_page(page);
+               }
+               pagevec_release(&pvec);
+               cond_resched();
+       }
+}
+
+/*
+ * Invalidate inode pages in a worker thread.  (This can't be done
+ * in the message handler context.)
+ */
+static void ceph_invalidate_work(struct work_struct *work)
+{
+       struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
+                                                 i_pg_inv_work);
+       struct inode *inode = &ci->vfs_inode;
+       u32 orig_gen;
+       int check = 0;
+
+       spin_lock(&inode->i_lock);
+       dout("invalidate_pages %p gen %d revoking %d\n", inode,
+            ci->i_rdcache_gen, ci->i_rdcache_revoking);
+       if (ci->i_rdcache_gen == 0 ||
+           ci->i_rdcache_revoking != ci->i_rdcache_gen) {
+               BUG_ON(ci->i_rdcache_revoking > ci->i_rdcache_gen);
+               /* nevermind! */
+               ci->i_rdcache_revoking = 0;
+               spin_unlock(&inode->i_lock);
+               goto out;
+       }
+       orig_gen = ci->i_rdcache_gen;
+       spin_unlock(&inode->i_lock);
+
+       ceph_invalidate_nondirty_pages(inode->i_mapping);
+
+       spin_lock(&inode->i_lock);
+       if (orig_gen == ci->i_rdcache_gen) {
+               dout("invalidate_pages %p gen %d successful\n", inode,
+                    ci->i_rdcache_gen);
+               ci->i_rdcache_gen = 0;
+               ci->i_rdcache_revoking = 0;
+               check = 1;
+       } else {
+               dout("invalidate_pages %p gen %d raced, gen now %d\n",
+                    inode, orig_gen, ci->i_rdcache_gen);
+       }
+       spin_unlock(&inode->i_lock);
+
+       if (check)
+               ceph_check_caps(ci, 0, NULL);
+out:
+       iput(inode);
+}
+
+
+/*
+ * called by trunc_wq; take i_mutex ourselves
+ *
+ * We also truncate in a separate thread as well.
+ */
+static void ceph_vmtruncate_work(struct work_struct *work)
+{
+       struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
+                                                 i_vmtruncate_work);
+       struct inode *inode = &ci->vfs_inode;
+
+       dout("vmtruncate_work %p\n", inode);
+       mutex_lock(&inode->i_mutex);
+       __ceph_do_pending_vmtruncate(inode);
+       mutex_unlock(&inode->i_mutex);
+       iput(inode);
+}
+
+/*
+ * Queue an async vmtruncate.  If we fail to queue work, we will handle
+ * the truncation the next time we call __ceph_do_pending_vmtruncate.
+ */
+void ceph_queue_vmtruncate(struct inode *inode)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+
+       if (queue_work(ceph_client(inode->i_sb)->trunc_wq,
+                      &ci->i_vmtruncate_work)) {
+               dout("ceph_queue_vmtruncate %p\n", inode);
+               igrab(inode);
+       } else {
+               dout("ceph_queue_vmtruncate %p failed, pending=%d\n",
+                    inode, ci->i_truncate_pending);
+       }
+}
+
+/*
+ * called with i_mutex held.
+ *
+ * Make sure any pending truncation is applied before doing anything
+ * that may depend on it.
+ */
+void __ceph_do_pending_vmtruncate(struct inode *inode)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       u64 to;
+       int wrbuffer_refs, wake = 0;
+
+retry:
+       spin_lock(&inode->i_lock);
+       if (ci->i_truncate_pending == 0) {
+               dout("__do_pending_vmtruncate %p none pending\n", inode);
+               spin_unlock(&inode->i_lock);
+               return;
+       }
+
+       /*
+        * make sure any dirty snapped pages are flushed before we
+        * possibly truncate them.. so write AND block!
+        */
+       if (ci->i_wrbuffer_ref_head < ci->i_wrbuffer_ref) {
+               dout("__do_pending_vmtruncate %p flushing snaps first\n",
+                    inode);
+               spin_unlock(&inode->i_lock);
+               filemap_write_and_wait_range(&inode->i_data, 0,
+                                            inode->i_sb->s_maxbytes);
+               goto retry;
+       }
+
+       to = ci->i_truncate_size;
+       wrbuffer_refs = ci->i_wrbuffer_ref;
+       dout("__do_pending_vmtruncate %p (%d) to %lld\n", inode,
+            ci->i_truncate_pending, to);
+       spin_unlock(&inode->i_lock);
+
+       truncate_inode_pages(inode->i_mapping, to);
+
+       spin_lock(&inode->i_lock);
+       ci->i_truncate_pending--;
+       if (ci->i_truncate_pending == 0)
+               wake = 1;
+       spin_unlock(&inode->i_lock);
+
+       if (wrbuffer_refs == 0)
+               ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
+       if (wake)
+               wake_up(&ci->i_cap_wq);
+}
+
+
+/*
+ * symlinks
+ */
+static void *ceph_sym_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+       struct ceph_inode_info *ci = ceph_inode(dentry->d_inode);
+       nd_set_link(nd, ci->i_symlink);
+       return NULL;
+}
+
+static const struct inode_operations ceph_symlink_iops = {
+       .readlink = generic_readlink,
+       .follow_link = ceph_sym_follow_link,
+};
+
+/*
+ * setattr
+ */
+int ceph_setattr(struct dentry *dentry, struct iattr *attr)
+{
+       struct inode *inode = dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct inode *parent_inode = dentry->d_parent->d_inode;
+       const unsigned int ia_valid = attr->ia_valid;
+       struct ceph_mds_request *req;
+       struct ceph_mds_client *mdsc = &ceph_client(dentry->d_sb)->mdsc;
+       int issued;
+       int release = 0, dirtied = 0;
+       int mask = 0;
+       int err = 0;
+
+       if (ceph_snap(inode) != CEPH_NOSNAP)
+               return -EROFS;
+
+       __ceph_do_pending_vmtruncate(inode);
+
+       err = inode_change_ok(inode, attr);
+       if (err != 0)
+               return err;
+
+       req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETATTR,
+                                      USE_AUTH_MDS);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+
+       spin_lock(&inode->i_lock);
+       issued = __ceph_caps_issued(ci, NULL);
+       dout("setattr %p issued %s\n", inode, ceph_cap_string(issued));
+
+       if (ia_valid & ATTR_UID) {
+               dout("setattr %p uid %d -> %d\n", inode,
+                    inode->i_uid, attr->ia_uid);
+               if (issued & CEPH_CAP_AUTH_EXCL) {
+                       inode->i_uid = attr->ia_uid;
+                       dirtied |= CEPH_CAP_AUTH_EXCL;
+               } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
+                          attr->ia_uid != inode->i_uid) {
+                       req->r_args.setattr.uid = cpu_to_le32(attr->ia_uid);
+                       mask |= CEPH_SETATTR_UID;
+                       release |= CEPH_CAP_AUTH_SHARED;
+               }
+       }
+       if (ia_valid & ATTR_GID) {
+               dout("setattr %p gid %d -> %d\n", inode,
+                    inode->i_gid, attr->ia_gid);
+               if (issued & CEPH_CAP_AUTH_EXCL) {
+                       inode->i_gid = attr->ia_gid;
+                       dirtied |= CEPH_CAP_AUTH_EXCL;
+               } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
+                          attr->ia_gid != inode->i_gid) {
+                       req->r_args.setattr.gid = cpu_to_le32(attr->ia_gid);
+                       mask |= CEPH_SETATTR_GID;
+                       release |= CEPH_CAP_AUTH_SHARED;
+               }
+       }
+       if (ia_valid & ATTR_MODE) {
+               dout("setattr %p mode 0%o -> 0%o\n", inode, inode->i_mode,
+                    attr->ia_mode);
+               if (issued & CEPH_CAP_AUTH_EXCL) {
+                       inode->i_mode = attr->ia_mode;
+                       dirtied |= CEPH_CAP_AUTH_EXCL;
+               } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
+                          attr->ia_mode != inode->i_mode) {
+                       req->r_args.setattr.mode = cpu_to_le32(attr->ia_mode);
+                       mask |= CEPH_SETATTR_MODE;
+                       release |= CEPH_CAP_AUTH_SHARED;
+               }
+       }
+
+       if (ia_valid & ATTR_ATIME) {
+               dout("setattr %p atime %ld.%ld -> %ld.%ld\n", inode,
+                    inode->i_atime.tv_sec, inode->i_atime.tv_nsec,
+                    attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec);
+               if (issued & CEPH_CAP_FILE_EXCL) {
+                       ci->i_time_warp_seq++;
+                       inode->i_atime = attr->ia_atime;
+                       dirtied |= CEPH_CAP_FILE_EXCL;
+               } else if ((issued & CEPH_CAP_FILE_WR) &&
+                          timespec_compare(&inode->i_atime,
+                                           &attr->ia_atime) < 0) {
+                       inode->i_atime = attr->ia_atime;
+                       dirtied |= CEPH_CAP_FILE_WR;
+               } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
+                          !timespec_equal(&inode->i_atime, &attr->ia_atime)) {
+                       ceph_encode_timespec(&req->r_args.setattr.atime,
+                                            &attr->ia_atime);
+                       mask |= CEPH_SETATTR_ATIME;
+                       release |= CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_RD |
+                               CEPH_CAP_FILE_WR;
+               }
+       }
+       if (ia_valid & ATTR_MTIME) {
+               dout("setattr %p mtime %ld.%ld -> %ld.%ld\n", inode,
+                    inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
+                    attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec);
+               if (issued & CEPH_CAP_FILE_EXCL) {
+                       ci->i_time_warp_seq++;
+                       inode->i_mtime = attr->ia_mtime;
+                       dirtied |= CEPH_CAP_FILE_EXCL;
+               } else if ((issued & CEPH_CAP_FILE_WR) &&
+                          timespec_compare(&inode->i_mtime,
+                                           &attr->ia_mtime) < 0) {
+                       inode->i_mtime = attr->ia_mtime;
+                       dirtied |= CEPH_CAP_FILE_WR;
+               } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
+                          !timespec_equal(&inode->i_mtime, &attr->ia_mtime)) {
+                       ceph_encode_timespec(&req->r_args.setattr.mtime,
+                                            &attr->ia_mtime);
+                       mask |= CEPH_SETATTR_MTIME;
+                       release |= CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_RD |
+                               CEPH_CAP_FILE_WR;
+               }
+       }
+       if (ia_valid & ATTR_SIZE) {
+               dout("setattr %p size %lld -> %lld\n", inode,
+                    inode->i_size, attr->ia_size);
+               if (attr->ia_size > inode->i_sb->s_maxbytes) {
+                       err = -EINVAL;
+                       goto out;
+               }
+               if ((issued & CEPH_CAP_FILE_EXCL) &&
+                   attr->ia_size > inode->i_size) {
+                       inode->i_size = attr->ia_size;
+                       inode->i_blocks =
+                               (attr->ia_size + (1 << 9) - 1) >> 9;
+                       inode->i_ctime = attr->ia_ctime;
+                       ci->i_reported_size = attr->ia_size;
+                       dirtied |= CEPH_CAP_FILE_EXCL;
+               } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
+                          attr->ia_size != inode->i_size) {
+                       req->r_args.setattr.size = cpu_to_le64(attr->ia_size);
+                       req->r_args.setattr.old_size =
+                               cpu_to_le64(inode->i_size);
+                       mask |= CEPH_SETATTR_SIZE;
+                       release |= CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_RD |
+                               CEPH_CAP_FILE_WR;
+               }
+       }
+
+       /* these do nothing */
+       if (ia_valid & ATTR_CTIME) {
+               bool only = (ia_valid & (ATTR_SIZE|ATTR_MTIME|ATTR_ATIME|
+                                        ATTR_MODE|ATTR_UID|ATTR_GID)) == 0;
+               dout("setattr %p ctime %ld.%ld -> %ld.%ld (%s)\n", inode,
+                    inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
+                    attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec,
+                    only ? "ctime only" : "ignored");
+               inode->i_ctime = attr->ia_ctime;
+               if (only) {
+                       /*
+                        * if kernel wants to dirty ctime but nothing else,
+                        * we need to choose a cap to dirty under, or do
+                        * a almost-no-op setattr
+                        */
+                       if (issued & CEPH_CAP_AUTH_EXCL)
+                               dirtied |= CEPH_CAP_AUTH_EXCL;
+                       else if (issued & CEPH_CAP_FILE_EXCL)
+                               dirtied |= CEPH_CAP_FILE_EXCL;
+                       else if (issued & CEPH_CAP_XATTR_EXCL)
+                               dirtied |= CEPH_CAP_XATTR_EXCL;
+                       else
+                               mask |= CEPH_SETATTR_CTIME;
+               }
+       }
+       if (ia_valid & ATTR_FILE)
+               dout("setattr %p ATTR_FILE ... hrm!\n", inode);
+
+       if (dirtied) {
+               __ceph_mark_dirty_caps(ci, dirtied);
+               inode->i_ctime = CURRENT_TIME;
+       }
+
+       release &= issued;
+       spin_unlock(&inode->i_lock);
+
+       if (mask) {
+               req->r_inode = igrab(inode);
+               req->r_inode_drop = release;
+               req->r_args.setattr.mask = cpu_to_le32(mask);
+               req->r_num_caps = 1;
+               err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+       }
+       dout("setattr %p result=%d (%s locally, %d remote)\n", inode, err,
+            ceph_cap_string(dirtied), mask);
+
+       ceph_mdsc_put_request(req);
+       __ceph_do_pending_vmtruncate(inode);
+       return err;
+out:
+       spin_unlock(&inode->i_lock);
+       ceph_mdsc_put_request(req);
+       return err;
+}
+
+/*
+ * Verify that we have a lease on the given mask.  If not,
+ * do a getattr against an mds.
+ */
+int ceph_do_getattr(struct inode *inode, int mask)
+{
+       struct ceph_client *client = ceph_sb_to_client(inode->i_sb);
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct ceph_mds_request *req;
+       int err;
+
+       if (ceph_snap(inode) == CEPH_SNAPDIR) {
+               dout("do_getattr inode %p SNAPDIR\n", inode);
+               return 0;
+       }
+
+       dout("do_getattr inode %p mask %s\n", inode, ceph_cap_string(mask));
+       if (ceph_caps_issued_mask(ceph_inode(inode), mask, 1))
+               return 0;
+
+       req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+       req->r_inode = igrab(inode);
+       req->r_num_caps = 1;
+       req->r_args.getattr.mask = cpu_to_le32(mask);
+       err = ceph_mdsc_do_request(mdsc, NULL, req);
+       ceph_mdsc_put_request(req);
+       dout("do_getattr result=%d\n", err);
+       return err;
+}
+
+
+/*
+ * Check inode permissions.  We verify we have a valid value for
+ * the AUTH cap, then call the generic handler.
+ */
+int ceph_permission(struct inode *inode, int mask)
+{
+       int err = ceph_do_getattr(inode, CEPH_CAP_AUTH_SHARED);
+
+       if (!err)
+               err = generic_permission(inode, mask, NULL);
+       return err;
+}
+
+/*
+ * Get all attributes.  Hopefully somedata we'll have a statlite()
+ * and can limit the fields we require to be accurate.
+ */
+int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                struct kstat *stat)
+{
+       struct inode *inode = dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int err;
+
+       err = ceph_do_getattr(inode, CEPH_STAT_CAP_INODE_ALL);
+       if (!err) {
+               generic_fillattr(inode, stat);
+               stat->ino = inode->i_ino;
+               if (ceph_snap(inode) != CEPH_NOSNAP)
+                       stat->dev = ceph_snap(inode);
+               else
+                       stat->dev = 0;
+               if (S_ISDIR(inode->i_mode)) {
+                       stat->size = ci->i_rbytes;
+                       stat->blocks = 0;
+                       stat->blksize = 65536;
+               }
+       }
+       return err;
+}
diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c
new file mode 100644 (file)
index 0000000..8a5bcae
--- /dev/null
@@ -0,0 +1,160 @@
+#include <linux/in.h>
+
+#include "ioctl.h"
+#include "super.h"
+#include "ceph_debug.h"
+
+
+/*
+ * ioctls
+ */
+
+/*
+ * get and set the file layout
+ */
+static long ceph_ioctl_get_layout(struct file *file, void __user *arg)
+{
+       struct ceph_inode_info *ci = ceph_inode(file->f_dentry->d_inode);
+       struct ceph_ioctl_layout l;
+       int err;
+
+       err = ceph_do_getattr(file->f_dentry->d_inode, CEPH_STAT_CAP_LAYOUT);
+       if (!err) {
+               l.stripe_unit = ceph_file_layout_su(ci->i_layout);
+               l.stripe_count = ceph_file_layout_stripe_count(ci->i_layout);
+               l.object_size = ceph_file_layout_object_size(ci->i_layout);
+               l.data_pool = le32_to_cpu(ci->i_layout.fl_pg_pool);
+               l.preferred_osd =
+                       (s32)le32_to_cpu(ci->i_layout.fl_pg_preferred);
+               if (copy_to_user(arg, &l, sizeof(l)))
+                       return -EFAULT;
+       }
+
+       return err;
+}
+
+static long ceph_ioctl_set_layout(struct file *file, void __user *arg)
+{
+       struct inode *inode = file->f_dentry->d_inode;
+       struct inode *parent_inode = file->f_dentry->d_parent->d_inode;
+       struct ceph_mds_client *mdsc = &ceph_sb_to_client(inode->i_sb)->mdsc;
+       struct ceph_mds_request *req;
+       struct ceph_ioctl_layout l;
+       int err, i;
+
+       /* copy and validate */
+       if (copy_from_user(&l, arg, sizeof(l)))
+               return -EFAULT;
+
+       if ((l.object_size & ~PAGE_MASK) ||
+           (l.stripe_unit & ~PAGE_MASK) ||
+           !l.stripe_unit ||
+           (l.object_size &&
+            (unsigned)l.object_size % (unsigned)l.stripe_unit))
+               return -EINVAL;
+
+       /* make sure it's a valid data pool */
+       if (l.data_pool > 0) {
+               mutex_lock(&mdsc->mutex);
+               err = -EINVAL;
+               for (i = 0; i < mdsc->mdsmap->m_num_data_pg_pools; i++)
+                       if (mdsc->mdsmap->m_data_pg_pools[i] == l.data_pool) {
+                               err = 0;
+                               break;
+                       }
+               mutex_unlock(&mdsc->mutex);
+               if (err)
+                       return err;
+       }
+
+       req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETLAYOUT,
+                                      USE_AUTH_MDS);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+       req->r_inode = igrab(inode);
+       req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL;
+
+       req->r_args.setlayout.layout.fl_stripe_unit =
+               cpu_to_le32(l.stripe_unit);
+       req->r_args.setlayout.layout.fl_stripe_count =
+               cpu_to_le32(l.stripe_count);
+       req->r_args.setlayout.layout.fl_object_size =
+               cpu_to_le32(l.object_size);
+       req->r_args.setlayout.layout.fl_pg_pool = cpu_to_le32(l.data_pool);
+       req->r_args.setlayout.layout.fl_pg_preferred =
+               cpu_to_le32(l.preferred_osd);
+
+       err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+       ceph_mdsc_put_request(req);
+       return err;
+}
+
+/*
+ * Return object name, size/offset information, and location (OSD
+ * number, network address) for a given file offset.
+ */
+static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg)
+{
+       struct ceph_ioctl_dataloc dl;
+       struct inode *inode = file->f_dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_osd_client *osdc = &ceph_client(inode->i_sb)->osdc;
+       u64 len = 1, olen;
+       u64 tmp;
+       struct ceph_object_layout ol;
+       struct ceph_pg pgid;
+
+       /* copy and validate */
+       if (copy_from_user(&dl, arg, sizeof(dl)))
+               return -EFAULT;
+
+       down_read(&osdc->map_sem);
+       ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, &len,
+                                     &dl.object_no, &dl.object_offset, &olen);
+       dl.file_offset -= dl.object_offset;
+       dl.object_size = ceph_file_layout_object_size(ci->i_layout);
+       dl.block_size = ceph_file_layout_su(ci->i_layout);
+
+       /* block_offset = object_offset % block_size */
+       tmp = dl.object_offset;
+       dl.block_offset = do_div(tmp, dl.block_size);
+
+       snprintf(dl.object_name, sizeof(dl.object_name), "%llx.%08llx",
+                ceph_ino(inode), dl.object_no);
+       ceph_calc_object_layout(&ol, dl.object_name, &ci->i_layout,
+                               osdc->osdmap);
+
+       pgid = ol.ol_pgid;
+       dl.osd = ceph_calc_pg_primary(osdc->osdmap, pgid);
+       if (dl.osd >= 0) {
+               struct ceph_entity_addr *a =
+                       ceph_osd_addr(osdc->osdmap, dl.osd);
+               if (a)
+                       memcpy(&dl.osd_addr, &a->in_addr, sizeof(dl.osd_addr));
+       } else {
+               memset(&dl.osd_addr, 0, sizeof(dl.osd_addr));
+       }
+       up_read(&osdc->map_sem);
+
+       /* send result back to user */
+       if (copy_to_user(arg, &dl, sizeof(dl)))
+               return -EFAULT;
+
+       return 0;
+}
+
+long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       dout("ioctl file %p cmd %u arg %lu\n", file, cmd, arg);
+       switch (cmd) {
+       case CEPH_IOC_GET_LAYOUT:
+               return ceph_ioctl_get_layout(file, (void __user *)arg);
+
+       case CEPH_IOC_SET_LAYOUT:
+               return ceph_ioctl_set_layout(file, (void __user *)arg);
+
+       case CEPH_IOC_GET_DATALOC:
+               return ceph_ioctl_get_dataloc(file, (void __user *)arg);
+       }
+       return -ENOTTY;
+}
diff --git a/fs/ceph/ioctl.h b/fs/ceph/ioctl.h
new file mode 100644 (file)
index 0000000..25e4f1a
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef FS_CEPH_IOCTL_H
+#define FS_CEPH_IOCTL_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define CEPH_IOCTL_MAGIC 0x97
+
+/* just use u64 to align sanely on all archs */
+struct ceph_ioctl_layout {
+       __u64 stripe_unit, stripe_count, object_size;
+       __u64 data_pool;
+       __s64 preferred_osd;
+};
+
+#define CEPH_IOC_GET_LAYOUT _IOR(CEPH_IOCTL_MAGIC, 1,          \
+                                  struct ceph_ioctl_layout)
+#define CEPH_IOC_SET_LAYOUT _IOW(CEPH_IOCTL_MAGIC, 2,          \
+                                  struct ceph_ioctl_layout)
+
+/*
+ * Extract identity, address of the OSD and object storing a given
+ * file offset.
+ */
+struct ceph_ioctl_dataloc {
+       __u64 file_offset;           /* in+out: file offset */
+       __u64 object_offset;         /* out: offset in object */
+       __u64 object_no;             /* out: object # */
+       __u64 object_size;           /* out: object size */
+       char object_name[64];        /* out: object name */
+       __u64 block_offset;          /* out: offset in block */
+       __u64 block_size;            /* out: block length */
+       __s64 osd;                   /* out: osd # */
+       struct sockaddr_storage osd_addr; /* out: osd address */
+};
+
+#define CEPH_IOC_GET_DATALOC _IOWR(CEPH_IOCTL_MAGIC, 3,        \
+                                  struct ceph_ioctl_dataloc)
+
+#endif
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
new file mode 100644 (file)
index 0000000..24561a5
--- /dev/null
@@ -0,0 +1,3047 @@
+#include "ceph_debug.h"
+
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+
+#include "mds_client.h"
+#include "mon_client.h"
+#include "super.h"
+#include "messenger.h"
+#include "decode.h"
+#include "auth.h"
+#include "pagelist.h"
+
+/*
+ * A cluster of MDS (metadata server) daemons is responsible for
+ * managing the file system namespace (the directory hierarchy and
+ * inodes) and for coordinating shared access to storage.  Metadata is
+ * partitioning hierarchically across a number of servers, and that
+ * partition varies over time as the cluster adjusts the distribution
+ * in order to balance load.
+ *
+ * The MDS client is primarily responsible to managing synchronous
+ * metadata requests for operations like open, unlink, and so forth.
+ * If there is a MDS failure, we find out about it when we (possibly
+ * request and) receive a new MDS map, and can resubmit affected
+ * requests.
+ *
+ * For the most part, though, we take advantage of a lossless
+ * communications channel to the MDS, and do not need to worry about
+ * timing out or resubmitting requests.
+ *
+ * We maintain a stateful "session" with each MDS we interact with.
+ * Within each session, we sent periodic heartbeat messages to ensure
+ * any capabilities or leases we have been issues remain valid.  If
+ * the session times out and goes stale, our leases and capabilities
+ * are no longer valid.
+ */
+
+static void __wake_requests(struct ceph_mds_client *mdsc,
+                           struct list_head *head);
+
+const static struct ceph_connection_operations mds_con_ops;
+
+
+/*
+ * mds reply parsing
+ */
+
+/*
+ * parse individual inode info
+ */
+static int parse_reply_info_in(void **p, void *end,
+                              struct ceph_mds_reply_info_in *info)
+{
+       int err = -EIO;
+
+       info->in = *p;
+       *p += sizeof(struct ceph_mds_reply_inode) +
+               sizeof(*info->in->fragtree.splits) *
+               le32_to_cpu(info->in->fragtree.nsplits);
+
+       ceph_decode_32_safe(p, end, info->symlink_len, bad);
+       ceph_decode_need(p, end, info->symlink_len, bad);
+       info->symlink = *p;
+       *p += info->symlink_len;
+
+       ceph_decode_32_safe(p, end, info->xattr_len, bad);
+       ceph_decode_need(p, end, info->xattr_len, bad);
+       info->xattr_data = *p;
+       *p += info->xattr_len;
+       return 0;
+bad:
+       return err;
+}
+
+/*
+ * parse a normal reply, which may contain a (dir+)dentry and/or a
+ * target inode.
+ */
+static int parse_reply_info_trace(void **p, void *end,
+                                 struct ceph_mds_reply_info_parsed *info)
+{
+       int err;
+
+       if (info->head->is_dentry) {
+               err = parse_reply_info_in(p, end, &info->diri);
+               if (err < 0)
+                       goto out_bad;
+
+               if (unlikely(*p + sizeof(*info->dirfrag) > end))
+                       goto bad;
+               info->dirfrag = *p;
+               *p += sizeof(*info->dirfrag) +
+                       sizeof(u32)*le32_to_cpu(info->dirfrag->ndist);
+               if (unlikely(*p > end))
+                       goto bad;
+
+               ceph_decode_32_safe(p, end, info->dname_len, bad);
+               ceph_decode_need(p, end, info->dname_len, bad);
+               info->dname = *p;
+               *p += info->dname_len;
+               info->dlease = *p;
+               *p += sizeof(*info->dlease);
+       }
+
+       if (info->head->is_target) {
+               err = parse_reply_info_in(p, end, &info->targeti);
+               if (err < 0)
+                       goto out_bad;
+       }
+
+       if (unlikely(*p != end))
+               goto bad;
+       return 0;
+
+bad:
+       err = -EIO;
+out_bad:
+       pr_err("problem parsing mds trace %d\n", err);
+       return err;
+}
+
+/*
+ * parse readdir results
+ */
+static int parse_reply_info_dir(void **p, void *end,
+                               struct ceph_mds_reply_info_parsed *info)
+{
+       u32 num, i = 0;
+       int err;
+
+       info->dir_dir = *p;
+       if (*p + sizeof(*info->dir_dir) > end)
+               goto bad;
+       *p += sizeof(*info->dir_dir) +
+               sizeof(u32)*le32_to_cpu(info->dir_dir->ndist);
+       if (*p > end)
+               goto bad;
+
+       ceph_decode_need(p, end, sizeof(num) + 2, bad);
+       num = ceph_decode_32(p);
+       info->dir_end = ceph_decode_8(p);
+       info->dir_complete = ceph_decode_8(p);
+       if (num == 0)
+               goto done;
+
+       /* alloc large array */
+       info->dir_nr = num;
+       info->dir_in = kcalloc(num, sizeof(*info->dir_in) +
+                              sizeof(*info->dir_dname) +
+                              sizeof(*info->dir_dname_len) +
+                              sizeof(*info->dir_dlease),
+                              GFP_NOFS);
+       if (info->dir_in == NULL) {
+               err = -ENOMEM;
+               goto out_bad;
+       }
+       info->dir_dname = (void *)(info->dir_in + num);
+       info->dir_dname_len = (void *)(info->dir_dname + num);
+       info->dir_dlease = (void *)(info->dir_dname_len + num);
+
+       while (num) {
+               /* dentry */
+               ceph_decode_need(p, end, sizeof(u32)*2, bad);
+               info->dir_dname_len[i] = ceph_decode_32(p);
+               ceph_decode_need(p, end, info->dir_dname_len[i], bad);
+               info->dir_dname[i] = *p;
+               *p += info->dir_dname_len[i];
+               dout("parsed dir dname '%.*s'\n", info->dir_dname_len[i],
+                    info->dir_dname[i]);
+               info->dir_dlease[i] = *p;
+               *p += sizeof(struct ceph_mds_reply_lease);
+
+               /* inode */
+               err = parse_reply_info_in(p, end, &info->dir_in[i]);
+               if (err < 0)
+                       goto out_bad;
+               i++;
+               num--;
+       }
+
+done:
+       if (*p != end)
+               goto bad;
+       return 0;
+
+bad:
+       err = -EIO;
+out_bad:
+       pr_err("problem parsing dir contents %d\n", err);
+       return err;
+}
+
+/*
+ * parse entire mds reply
+ */
+static int parse_reply_info(struct ceph_msg *msg,
+                           struct ceph_mds_reply_info_parsed *info)
+{
+       void *p, *end;
+       u32 len;
+       int err;
+
+       info->head = msg->front.iov_base;
+       p = msg->front.iov_base + sizeof(struct ceph_mds_reply_head);
+       end = p + msg->front.iov_len - sizeof(struct ceph_mds_reply_head);
+
+       /* trace */
+       ceph_decode_32_safe(&p, end, len, bad);
+       if (len > 0) {
+               err = parse_reply_info_trace(&p, p+len, info);
+               if (err < 0)
+                       goto out_bad;
+       }
+
+       /* dir content */
+       ceph_decode_32_safe(&p, end, len, bad);
+       if (len > 0) {
+               err = parse_reply_info_dir(&p, p+len, info);
+               if (err < 0)
+                       goto out_bad;
+       }
+
+       /* snap blob */
+       ceph_decode_32_safe(&p, end, len, bad);
+       info->snapblob_len = len;
+       info->snapblob = p;
+       p += len;
+
+       if (p != end)
+               goto bad;
+       return 0;
+
+bad:
+       err = -EIO;
+out_bad:
+       pr_err("mds parse_reply err %d\n", err);
+       return err;
+}
+
+static void destroy_reply_info(struct ceph_mds_reply_info_parsed *info)
+{
+       kfree(info->dir_in);
+}
+
+
+/*
+ * sessions
+ */
+static const char *session_state_name(int s)
+{
+       switch (s) {
+       case CEPH_MDS_SESSION_NEW: return "new";
+       case CEPH_MDS_SESSION_OPENING: return "opening";
+       case CEPH_MDS_SESSION_OPEN: return "open";
+       case CEPH_MDS_SESSION_HUNG: return "hung";
+       case CEPH_MDS_SESSION_CLOSING: return "closing";
+       case CEPH_MDS_SESSION_RESTARTING: return "restarting";
+       case CEPH_MDS_SESSION_RECONNECTING: return "reconnecting";
+       default: return "???";
+       }
+}
+
+static struct ceph_mds_session *get_session(struct ceph_mds_session *s)
+{
+       if (atomic_inc_not_zero(&s->s_ref)) {
+               dout("mdsc get_session %p %d -> %d\n", s,
+                    atomic_read(&s->s_ref)-1, atomic_read(&s->s_ref));
+               return s;
+       } else {
+               dout("mdsc get_session %p 0 -- FAIL", s);
+               return NULL;
+       }
+}
+
+void ceph_put_mds_session(struct ceph_mds_session *s)
+{
+       dout("mdsc put_session %p %d -> %d\n", s,
+            atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1);
+       if (atomic_dec_and_test(&s->s_ref)) {
+               if (s->s_authorizer)
+                       s->s_mdsc->client->monc.auth->ops->destroy_authorizer(
+                               s->s_mdsc->client->monc.auth, s->s_authorizer);
+               kfree(s);
+       }
+}
+
+/*
+ * called under mdsc->mutex
+ */
+struct ceph_mds_session *__ceph_lookup_mds_session(struct ceph_mds_client *mdsc,
+                                                  int mds)
+{
+       struct ceph_mds_session *session;
+
+       if (mds >= mdsc->max_sessions || mdsc->sessions[mds] == NULL)
+               return NULL;
+       session = mdsc->sessions[mds];
+       dout("lookup_mds_session %p %d\n", session,
+            atomic_read(&session->s_ref));
+       get_session(session);
+       return session;
+}
+
+static bool __have_session(struct ceph_mds_client *mdsc, int mds)
+{
+       if (mds >= mdsc->max_sessions)
+               return false;
+       return mdsc->sessions[mds];
+}
+
+static int __verify_registered_session(struct ceph_mds_client *mdsc,
+                                      struct ceph_mds_session *s)
+{
+       if (s->s_mds >= mdsc->max_sessions ||
+           mdsc->sessions[s->s_mds] != s)
+               return -ENOENT;
+       return 0;
+}
+
+/*
+ * create+register a new session for given mds.
+ * called under mdsc->mutex.
+ */
+static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc,
+                                                int mds)
+{
+       struct ceph_mds_session *s;
+
+       s = kzalloc(sizeof(*s), GFP_NOFS);
+       if (!s)
+               return ERR_PTR(-ENOMEM);
+       s->s_mdsc = mdsc;
+       s->s_mds = mds;
+       s->s_state = CEPH_MDS_SESSION_NEW;
+       s->s_ttl = 0;
+       s->s_seq = 0;
+       mutex_init(&s->s_mutex);
+
+       ceph_con_init(mdsc->client->msgr, &s->s_con);
+       s->s_con.private = s;
+       s->s_con.ops = &mds_con_ops;
+       s->s_con.peer_name.type = CEPH_ENTITY_TYPE_MDS;
+       s->s_con.peer_name.num = cpu_to_le64(mds);
+
+       spin_lock_init(&s->s_cap_lock);
+       s->s_cap_gen = 0;
+       s->s_cap_ttl = 0;
+       s->s_renew_requested = 0;
+       s->s_renew_seq = 0;
+       INIT_LIST_HEAD(&s->s_caps);
+       s->s_nr_caps = 0;
+       s->s_trim_caps = 0;
+       atomic_set(&s->s_ref, 1);
+       INIT_LIST_HEAD(&s->s_waiting);
+       INIT_LIST_HEAD(&s->s_unsafe);
+       s->s_num_cap_releases = 0;
+       s->s_cap_iterator = NULL;
+       INIT_LIST_HEAD(&s->s_cap_releases);
+       INIT_LIST_HEAD(&s->s_cap_releases_done);
+       INIT_LIST_HEAD(&s->s_cap_flushing);
+       INIT_LIST_HEAD(&s->s_cap_snaps_flushing);
+
+       dout("register_session mds%d\n", mds);
+       if (mds >= mdsc->max_sessions) {
+               int newmax = 1 << get_count_order(mds+1);
+               struct ceph_mds_session **sa;
+
+               dout("register_session realloc to %d\n", newmax);
+               sa = kcalloc(newmax, sizeof(void *), GFP_NOFS);
+               if (sa == NULL)
+                       goto fail_realloc;
+               if (mdsc->sessions) {
+                       memcpy(sa, mdsc->sessions,
+                              mdsc->max_sessions * sizeof(void *));
+                       kfree(mdsc->sessions);
+               }
+               mdsc->sessions = sa;
+               mdsc->max_sessions = newmax;
+       }
+       mdsc->sessions[mds] = s;
+       atomic_inc(&s->s_ref);  /* one ref to sessions[], one to caller */
+
+       ceph_con_open(&s->s_con, ceph_mdsmap_get_addr(mdsc->mdsmap, mds));
+
+       return s;
+
+fail_realloc:
+       kfree(s);
+       return ERR_PTR(-ENOMEM);
+}
+
+/*
+ * called under mdsc->mutex
+ */
+static void __unregister_session(struct ceph_mds_client *mdsc,
+                              struct ceph_mds_session *s)
+{
+       dout("__unregister_session mds%d %p\n", s->s_mds, s);
+       BUG_ON(mdsc->sessions[s->s_mds] != s);
+       mdsc->sessions[s->s_mds] = NULL;
+       ceph_con_close(&s->s_con);
+       ceph_put_mds_session(s);
+}
+
+/*
+ * drop session refs in request.
+ *
+ * should be last request ref, or hold mdsc->mutex
+ */
+static void put_request_session(struct ceph_mds_request *req)
+{
+       if (req->r_session) {
+               ceph_put_mds_session(req->r_session);
+               req->r_session = NULL;
+       }
+}
+
+void ceph_mdsc_release_request(struct kref *kref)
+{
+       struct ceph_mds_request *req = container_of(kref,
+                                                   struct ceph_mds_request,
+                                                   r_kref);
+       if (req->r_request)
+               ceph_msg_put(req->r_request);
+       if (req->r_reply) {
+               ceph_msg_put(req->r_reply);
+               destroy_reply_info(&req->r_reply_info);
+       }
+       if (req->r_inode) {
+               ceph_put_cap_refs(ceph_inode(req->r_inode),
+                                 CEPH_CAP_PIN);
+               iput(req->r_inode);
+       }
+       if (req->r_locked_dir)
+               ceph_put_cap_refs(ceph_inode(req->r_locked_dir),
+                                 CEPH_CAP_PIN);
+       if (req->r_target_inode)
+               iput(req->r_target_inode);
+       if (req->r_dentry)
+               dput(req->r_dentry);
+       if (req->r_old_dentry) {
+               ceph_put_cap_refs(
+                       ceph_inode(req->r_old_dentry->d_parent->d_inode),
+                       CEPH_CAP_PIN);
+               dput(req->r_old_dentry);
+       }
+       kfree(req->r_path1);
+       kfree(req->r_path2);
+       put_request_session(req);
+       ceph_unreserve_caps(&req->r_caps_reservation);
+       kfree(req);
+}
+
+/*
+ * lookup session, bump ref if found.
+ *
+ * called under mdsc->mutex.
+ */
+static struct ceph_mds_request *__lookup_request(struct ceph_mds_client *mdsc,
+                                            u64 tid)
+{
+       struct ceph_mds_request *req;
+       struct rb_node *n = mdsc->request_tree.rb_node;
+
+       while (n) {
+               req = rb_entry(n, struct ceph_mds_request, r_node);
+               if (tid < req->r_tid)
+                       n = n->rb_left;
+               else if (tid > req->r_tid)
+                       n = n->rb_right;
+               else {
+                       ceph_mdsc_get_request(req);
+                       return req;
+               }
+       }
+       return NULL;
+}
+
+static void __insert_request(struct ceph_mds_client *mdsc,
+                            struct ceph_mds_request *new)
+{
+       struct rb_node **p = &mdsc->request_tree.rb_node;
+       struct rb_node *parent = NULL;
+       struct ceph_mds_request *req = NULL;
+
+       while (*p) {
+               parent = *p;
+               req = rb_entry(parent, struct ceph_mds_request, r_node);
+               if (new->r_tid < req->r_tid)
+                       p = &(*p)->rb_left;
+               else if (new->r_tid > req->r_tid)
+                       p = &(*p)->rb_right;
+               else
+                       BUG();
+       }
+
+       rb_link_node(&new->r_node, parent, p);
+       rb_insert_color(&new->r_node, &mdsc->request_tree);
+}
+
+/*
+ * Register an in-flight request, and assign a tid.  Link to directory
+ * are modifying (if any).
+ *
+ * Called under mdsc->mutex.
+ */
+static void __register_request(struct ceph_mds_client *mdsc,
+                              struct ceph_mds_request *req,
+                              struct inode *dir)
+{
+       req->r_tid = ++mdsc->last_tid;
+       if (req->r_num_caps)
+               ceph_reserve_caps(&req->r_caps_reservation, req->r_num_caps);
+       dout("__register_request %p tid %lld\n", req, req->r_tid);
+       ceph_mdsc_get_request(req);
+       __insert_request(mdsc, req);
+
+       if (dir) {
+               struct ceph_inode_info *ci = ceph_inode(dir);
+
+               spin_lock(&ci->i_unsafe_lock);
+               req->r_unsafe_dir = dir;
+               list_add_tail(&req->r_unsafe_dir_item, &ci->i_unsafe_dirops);
+               spin_unlock(&ci->i_unsafe_lock);
+       }
+}
+
+static void __unregister_request(struct ceph_mds_client *mdsc,
+                                struct ceph_mds_request *req)
+{
+       dout("__unregister_request %p tid %lld\n", req, req->r_tid);
+       rb_erase(&req->r_node, &mdsc->request_tree);
+       RB_CLEAR_NODE(&req->r_node);
+
+       if (req->r_unsafe_dir) {
+               struct ceph_inode_info *ci = ceph_inode(req->r_unsafe_dir);
+
+               spin_lock(&ci->i_unsafe_lock);
+               list_del_init(&req->r_unsafe_dir_item);
+               spin_unlock(&ci->i_unsafe_lock);
+       }
+
+       ceph_mdsc_put_request(req);
+}
+
+/*
+ * Choose mds to send request to next.  If there is a hint set in the
+ * request (e.g., due to a prior forward hint from the mds), use that.
+ * Otherwise, consult frag tree and/or caps to identify the
+ * appropriate mds.  If all else fails, choose randomly.
+ *
+ * Called under mdsc->mutex.
+ */
+static int __choose_mds(struct ceph_mds_client *mdsc,
+                       struct ceph_mds_request *req)
+{
+       struct inode *inode;
+       struct ceph_inode_info *ci;
+       struct ceph_cap *cap;
+       int mode = req->r_direct_mode;
+       int mds = -1;
+       u32 hash = req->r_direct_hash;
+       bool is_hash = req->r_direct_is_hash;
+
+       /*
+        * is there a specific mds we should try?  ignore hint if we have
+        * no session and the mds is not up (active or recovering).
+        */
+       if (req->r_resend_mds >= 0 &&
+           (__have_session(mdsc, req->r_resend_mds) ||
+            ceph_mdsmap_get_state(mdsc->mdsmap, req->r_resend_mds) > 0)) {
+               dout("choose_mds using resend_mds mds%d\n",
+                    req->r_resend_mds);
+               return req->r_resend_mds;
+       }
+
+       if (mode == USE_RANDOM_MDS)
+               goto random;
+
+       inode = NULL;
+       if (req->r_inode) {
+               inode = req->r_inode;
+       } else if (req->r_dentry) {
+               if (req->r_dentry->d_inode) {
+                       inode = req->r_dentry->d_inode;
+               } else {
+                       inode = req->r_dentry->d_parent->d_inode;
+                       hash = req->r_dentry->d_name.hash;
+                       is_hash = true;
+               }
+       }
+       dout("__choose_mds %p is_hash=%d (%d) mode %d\n", inode, (int)is_hash,
+            (int)hash, mode);
+       if (!inode)
+               goto random;
+       ci = ceph_inode(inode);
+
+       if (is_hash && S_ISDIR(inode->i_mode)) {
+               struct ceph_inode_frag frag;
+               int found;
+
+               ceph_choose_frag(ci, hash, &frag, &found);
+               if (found) {
+                       if (mode == USE_ANY_MDS && frag.ndist > 0) {
+                               u8 r;
+
+                               /* choose a random replica */
+                               get_random_bytes(&r, 1);
+                               r %= frag.ndist;
+                               mds = frag.dist[r];
+                               dout("choose_mds %p %llx.%llx "
+                                    "frag %u mds%d (%d/%d)\n",
+                                    inode, ceph_vinop(inode),
+                                    frag.frag, frag.mds,
+                                    (int)r, frag.ndist);
+                               return mds;
+                       }
+
+                       /* since this file/dir wasn't known to be
+                        * replicated, then we want to look for the
+                        * authoritative mds. */
+                       mode = USE_AUTH_MDS;
+                       if (frag.mds >= 0) {
+                               /* choose auth mds */
+                               mds = frag.mds;
+                               dout("choose_mds %p %llx.%llx "
+                                    "frag %u mds%d (auth)\n",
+                                    inode, ceph_vinop(inode), frag.frag, mds);
+                               return mds;
+                       }
+               }
+       }
+
+       spin_lock(&inode->i_lock);
+       cap = NULL;
+       if (mode == USE_AUTH_MDS)
+               cap = ci->i_auth_cap;
+       if (!cap && !RB_EMPTY_ROOT(&ci->i_caps))
+               cap = rb_entry(rb_first(&ci->i_caps), struct ceph_cap, ci_node);
+       if (!cap) {
+               spin_unlock(&inode->i_lock);
+               goto random;
+       }
+       mds = cap->session->s_mds;
+       dout("choose_mds %p %llx.%llx mds%d (%scap %p)\n",
+            inode, ceph_vinop(inode), mds,
+            cap == ci->i_auth_cap ? "auth " : "", cap);
+       spin_unlock(&inode->i_lock);
+       return mds;
+
+random:
+       mds = ceph_mdsmap_get_random_mds(mdsc->mdsmap);
+       dout("choose_mds chose random mds%d\n", mds);
+       return mds;
+}
+
+
+/*
+ * session messages
+ */
+static struct ceph_msg *create_session_msg(u32 op, u64 seq)
+{
+       struct ceph_msg *msg;
+       struct ceph_mds_session_head *h;
+
+       msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h), 0, 0, NULL);
+       if (IS_ERR(msg)) {
+               pr_err("create_session_msg ENOMEM creating msg\n");
+               return ERR_PTR(PTR_ERR(msg));
+       }
+       h = msg->front.iov_base;
+       h->op = cpu_to_le32(op);
+       h->seq = cpu_to_le64(seq);
+       return msg;
+}
+
+/*
+ * send session open request.
+ *
+ * called under mdsc->mutex
+ */
+static int __open_session(struct ceph_mds_client *mdsc,
+                         struct ceph_mds_session *session)
+{
+       struct ceph_msg *msg;
+       int mstate;
+       int mds = session->s_mds;
+       int err = 0;
+
+       /* wait for mds to go active? */
+       mstate = ceph_mdsmap_get_state(mdsc->mdsmap, mds);
+       dout("open_session to mds%d (%s)\n", mds,
+            ceph_mds_state_name(mstate));
+       session->s_state = CEPH_MDS_SESSION_OPENING;
+       session->s_renew_requested = jiffies;
+
+       /* send connect message */
+       msg = create_session_msg(CEPH_SESSION_REQUEST_OPEN, session->s_seq);
+       if (IS_ERR(msg)) {
+               err = PTR_ERR(msg);
+               goto out;
+       }
+       ceph_con_send(&session->s_con, msg);
+
+out:
+       return 0;
+}
+
+/*
+ * session caps
+ */
+
+/*
+ * Free preallocated cap messages assigned to this session
+ */
+static void cleanup_cap_releases(struct ceph_mds_session *session)
+{
+       struct ceph_msg *msg;
+
+       spin_lock(&session->s_cap_lock);
+       while (!list_empty(&session->s_cap_releases)) {
+               msg = list_first_entry(&session->s_cap_releases,
+                                      struct ceph_msg, list_head);
+               list_del_init(&msg->list_head);
+               ceph_msg_put(msg);
+       }
+       while (!list_empty(&session->s_cap_releases_done)) {
+               msg = list_first_entry(&session->s_cap_releases_done,
+                                      struct ceph_msg, list_head);
+               list_del_init(&msg->list_head);
+               ceph_msg_put(msg);
+       }
+       spin_unlock(&session->s_cap_lock);
+}
+
+/*
+ * Helper to safely iterate over all caps associated with a session, with
+ * special care taken to handle a racing __ceph_remove_cap().
+ *
+ * Caller must hold session s_mutex.
+ */
+static int iterate_session_caps(struct ceph_mds_session *session,
+                                int (*cb)(struct inode *, struct ceph_cap *,
+                                           void *), void *arg)
+{
+       struct list_head *p;
+       struct ceph_cap *cap;
+       struct inode *inode, *last_inode = NULL;
+       struct ceph_cap *old_cap = NULL;
+       int ret;
+
+       dout("iterate_session_caps %p mds%d\n", session, session->s_mds);
+       spin_lock(&session->s_cap_lock);
+       p = session->s_caps.next;
+       while (p != &session->s_caps) {
+               cap = list_entry(p, struct ceph_cap, session_caps);
+               inode = igrab(&cap->ci->vfs_inode);
+               if (!inode) {
+                       p = p->next;
+                       continue;
+               }
+               session->s_cap_iterator = cap;
+               spin_unlock(&session->s_cap_lock);
+
+               if (last_inode) {
+                       iput(last_inode);
+                       last_inode = NULL;
+               }
+               if (old_cap) {
+                       ceph_put_cap(old_cap);
+                       old_cap = NULL;
+               }
+
+               ret = cb(inode, cap, arg);
+               last_inode = inode;
+
+               spin_lock(&session->s_cap_lock);
+               p = p->next;
+               if (cap->ci == NULL) {
+                       dout("iterate_session_caps  finishing cap %p removal\n",
+                            cap);
+                       BUG_ON(cap->session != session);
+                       list_del_init(&cap->session_caps);
+                       session->s_nr_caps--;
+                       cap->session = NULL;
+                       old_cap = cap;  /* put_cap it w/o locks held */
+               }
+               if (ret < 0)
+                       goto out;
+       }
+       ret = 0;
+out:
+       session->s_cap_iterator = NULL;
+       spin_unlock(&session->s_cap_lock);
+
+       if (last_inode)
+               iput(last_inode);
+       if (old_cap)
+               ceph_put_cap(old_cap);
+
+       return ret;
+}
+
+static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
+                                  void *arg)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       dout("removing cap %p, ci is %p, inode is %p\n",
+            cap, ci, &ci->vfs_inode);
+       ceph_remove_cap(cap);
+       return 0;
+}
+
+/*
+ * caller must hold session s_mutex
+ */
+static void remove_session_caps(struct ceph_mds_session *session)
+{
+       dout("remove_session_caps on %p\n", session);
+       iterate_session_caps(session, remove_session_caps_cb, NULL);
+       BUG_ON(session->s_nr_caps > 0);
+       cleanup_cap_releases(session);
+}
+
+/*
+ * wake up any threads waiting on this session's caps.  if the cap is
+ * old (didn't get renewed on the client reconnect), remove it now.
+ *
+ * caller must hold s_mutex.
+ */
+static int wake_up_session_cb(struct inode *inode, struct ceph_cap *cap,
+                             void *arg)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+
+       wake_up(&ci->i_cap_wq);
+       if (arg) {
+               spin_lock(&inode->i_lock);
+               ci->i_wanted_max_size = 0;
+               ci->i_requested_max_size = 0;
+               spin_unlock(&inode->i_lock);
+       }
+       return 0;
+}
+
+static void wake_up_session_caps(struct ceph_mds_session *session,
+                                int reconnect)
+{
+       dout("wake_up_session_caps %p mds%d\n", session, session->s_mds);
+       iterate_session_caps(session, wake_up_session_cb,
+                            (void *)(unsigned long)reconnect);
+}
+
+/*
+ * Send periodic message to MDS renewing all currently held caps.  The
+ * ack will reset the expiration for all caps from this session.
+ *
+ * caller holds s_mutex
+ */
+static int send_renew_caps(struct ceph_mds_client *mdsc,
+                          struct ceph_mds_session *session)
+{
+       struct ceph_msg *msg;
+       int state;
+
+       if (time_after_eq(jiffies, session->s_cap_ttl) &&
+           time_after_eq(session->s_cap_ttl, session->s_renew_requested))
+               pr_info("mds%d caps stale\n", session->s_mds);
+       session->s_renew_requested = jiffies;
+
+       /* do not try to renew caps until a recovering mds has reconnected
+        * with its clients. */
+       state = ceph_mdsmap_get_state(mdsc->mdsmap, session->s_mds);
+       if (state < CEPH_MDS_STATE_RECONNECT) {
+               dout("send_renew_caps ignoring mds%d (%s)\n",
+                    session->s_mds, ceph_mds_state_name(state));
+               return 0;
+       }
+
+       dout("send_renew_caps to mds%d (%s)\n", session->s_mds,
+               ceph_mds_state_name(state));
+       msg = create_session_msg(CEPH_SESSION_REQUEST_RENEWCAPS,
+                                ++session->s_renew_seq);
+       if (IS_ERR(msg))
+               return PTR_ERR(msg);
+       ceph_con_send(&session->s_con, msg);
+       return 0;
+}
+
+/*
+ * Note new cap ttl, and any transition from stale -> not stale (fresh?).
+ *
+ * Called under session->s_mutex
+ */
+static void renewed_caps(struct ceph_mds_client *mdsc,
+                        struct ceph_mds_session *session, int is_renew)
+{
+       int was_stale;
+       int wake = 0;
+
+       spin_lock(&session->s_cap_lock);
+       was_stale = is_renew && (session->s_cap_ttl == 0 ||
+                                time_after_eq(jiffies, session->s_cap_ttl));
+
+       session->s_cap_ttl = session->s_renew_requested +
+               mdsc->mdsmap->m_session_timeout*HZ;
+
+       if (was_stale) {
+               if (time_before(jiffies, session->s_cap_ttl)) {
+                       pr_info("mds%d caps renewed\n", session->s_mds);
+                       wake = 1;
+               } else {
+                       pr_info("mds%d caps still stale\n", session->s_mds);
+               }
+       }
+       dout("renewed_caps mds%d ttl now %lu, was %s, now %s\n",
+            session->s_mds, session->s_cap_ttl, was_stale ? "stale" : "fresh",
+            time_before(jiffies, session->s_cap_ttl) ? "stale" : "fresh");
+       spin_unlock(&session->s_cap_lock);
+
+       if (wake)
+               wake_up_session_caps(session, 0);
+}
+
+/*
+ * send a session close request
+ */
+static int request_close_session(struct ceph_mds_client *mdsc,
+                                struct ceph_mds_session *session)
+{
+       struct ceph_msg *msg;
+       int err = 0;
+
+       dout("request_close_session mds%d state %s seq %lld\n",
+            session->s_mds, session_state_name(session->s_state),
+            session->s_seq);
+       msg = create_session_msg(CEPH_SESSION_REQUEST_CLOSE, session->s_seq);
+       if (IS_ERR(msg))
+               err = PTR_ERR(msg);
+       else
+               ceph_con_send(&session->s_con, msg);
+       return err;
+}
+
+/*
+ * Called with s_mutex held.
+ */
+static int __close_session(struct ceph_mds_client *mdsc,
+                        struct ceph_mds_session *session)
+{
+       if (session->s_state >= CEPH_MDS_SESSION_CLOSING)
+               return 0;
+       session->s_state = CEPH_MDS_SESSION_CLOSING;
+       return request_close_session(mdsc, session);
+}
+
+/*
+ * Trim old(er) caps.
+ *
+ * Because we can't cache an inode without one or more caps, we do
+ * this indirectly: if a cap is unused, we prune its aliases, at which
+ * point the inode will hopefully get dropped to.
+ *
+ * Yes, this is a bit sloppy.  Our only real goal here is to respond to
+ * memory pressure from the MDS, though, so it needn't be perfect.
+ */
+static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
+{
+       struct ceph_mds_session *session = arg;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int used, oissued, mine;
+
+       if (session->s_trim_caps <= 0)
+               return -1;
+
+       spin_lock(&inode->i_lock);
+       mine = cap->issued | cap->implemented;
+       used = __ceph_caps_used(ci);
+       oissued = __ceph_caps_issued_other(ci, cap);
+
+       dout("trim_caps_cb %p cap %p mine %s oissued %s used %s\n",
+            inode, cap, ceph_cap_string(mine), ceph_cap_string(oissued),
+            ceph_cap_string(used));
+       if (ci->i_dirty_caps)
+               goto out;   /* dirty caps */
+       if ((used & ~oissued) & mine)
+               goto out;   /* we need these caps */
+
+       session->s_trim_caps--;
+       if (oissued) {
+               /* we aren't the only cap.. just remove us */
+               __ceph_remove_cap(cap);
+       } else {
+               /* try to drop referring dentries */
+               spin_unlock(&inode->i_lock);
+               d_prune_aliases(inode);
+               dout("trim_caps_cb %p cap %p  pruned, count now %d\n",
+                    inode, cap, atomic_read(&inode->i_count));
+               return 0;
+       }
+
+out:
+       spin_unlock(&inode->i_lock);
+       return 0;
+}
+
+/*
+ * Trim session cap count down to some max number.
+ */
+static int trim_caps(struct ceph_mds_client *mdsc,
+                    struct ceph_mds_session *session,
+                    int max_caps)
+{
+       int trim_caps = session->s_nr_caps - max_caps;
+
+       dout("trim_caps mds%d start: %d / %d, trim %d\n",
+            session->s_mds, session->s_nr_caps, max_caps, trim_caps);
+       if (trim_caps > 0) {
+               session->s_trim_caps = trim_caps;
+               iterate_session_caps(session, trim_caps_cb, session);
+               dout("trim_caps mds%d done: %d / %d, trimmed %d\n",
+                    session->s_mds, session->s_nr_caps, max_caps,
+                       trim_caps - session->s_trim_caps);
+               session->s_trim_caps = 0;
+       }
+       return 0;
+}
+
+/*
+ * Allocate cap_release messages.  If there is a partially full message
+ * in the queue, try to allocate enough to cover it's remainder, so that
+ * we can send it immediately.
+ *
+ * Called under s_mutex.
+ */
+static int add_cap_releases(struct ceph_mds_client *mdsc,
+                           struct ceph_mds_session *session,
+                           int extra)
+{
+       struct ceph_msg *msg;
+       struct ceph_mds_cap_release *head;
+       int err = -ENOMEM;
+
+       if (extra < 0)
+               extra = mdsc->client->mount_args->cap_release_safety;
+
+       spin_lock(&session->s_cap_lock);
+
+       if (!list_empty(&session->s_cap_releases)) {
+               msg = list_first_entry(&session->s_cap_releases,
+                                      struct ceph_msg,
+                                list_head);
+               head = msg->front.iov_base;
+               extra += CEPH_CAPS_PER_RELEASE - le32_to_cpu(head->num);
+       }
+
+       while (session->s_num_cap_releases < session->s_nr_caps + extra) {
+               spin_unlock(&session->s_cap_lock);
+               msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPRELEASE, PAGE_CACHE_SIZE,
+                                  0, 0, NULL);
+               if (!msg)
+                       goto out_unlocked;
+               dout("add_cap_releases %p msg %p now %d\n", session, msg,
+                    (int)msg->front.iov_len);
+               head = msg->front.iov_base;
+               head->num = cpu_to_le32(0);
+               msg->front.iov_len = sizeof(*head);
+               spin_lock(&session->s_cap_lock);
+               list_add(&msg->list_head, &session->s_cap_releases);
+               session->s_num_cap_releases += CEPH_CAPS_PER_RELEASE;
+       }
+
+       if (!list_empty(&session->s_cap_releases)) {
+               msg = list_first_entry(&session->s_cap_releases,
+                                      struct ceph_msg,
+                                      list_head);
+               head = msg->front.iov_base;
+               if (head->num) {
+                       dout(" queueing non-full %p (%d)\n", msg,
+                            le32_to_cpu(head->num));
+                       list_move_tail(&msg->list_head,
+                                     &session->s_cap_releases_done);
+                       session->s_num_cap_releases -=
+                               CEPH_CAPS_PER_RELEASE - le32_to_cpu(head->num);
+               }
+       }
+       err = 0;
+       spin_unlock(&session->s_cap_lock);
+out_unlocked:
+       return err;
+}
+
+/*
+ * flush all dirty inode data to disk.
+ *
+ * returns true if we've flushed through want_flush_seq
+ */
+static int check_cap_flush(struct ceph_mds_client *mdsc, u64 want_flush_seq)
+{
+       int mds, ret = 1;
+
+       dout("check_cap_flush want %lld\n", want_flush_seq);
+       mutex_lock(&mdsc->mutex);
+       for (mds = 0; ret && mds < mdsc->max_sessions; mds++) {
+               struct ceph_mds_session *session = mdsc->sessions[mds];
+
+               if (!session)
+                       continue;
+               get_session(session);
+               mutex_unlock(&mdsc->mutex);
+
+               mutex_lock(&session->s_mutex);
+               if (!list_empty(&session->s_cap_flushing)) {
+                       struct ceph_inode_info *ci =
+                               list_entry(session->s_cap_flushing.next,
+                                          struct ceph_inode_info,
+                                          i_flushing_item);
+                       struct inode *inode = &ci->vfs_inode;
+
+                       spin_lock(&inode->i_lock);
+                       if (ci->i_cap_flush_seq <= want_flush_seq) {
+                               dout("check_cap_flush still flushing %p "
+                                    "seq %lld <= %lld to mds%d\n", inode,
+                                    ci->i_cap_flush_seq, want_flush_seq,
+                                    session->s_mds);
+                               ret = 0;
+                       }
+                       spin_unlock(&inode->i_lock);
+               }
+               mutex_unlock(&session->s_mutex);
+               ceph_put_mds_session(session);
+
+               if (!ret)
+                       return ret;
+               mutex_lock(&mdsc->mutex);
+       }
+
+       mutex_unlock(&mdsc->mutex);
+       dout("check_cap_flush ok, flushed thru %lld\n", want_flush_seq);
+       return ret;
+}
+
+/*
+ * called under s_mutex
+ */
+static void send_cap_releases(struct ceph_mds_client *mdsc,
+                      struct ceph_mds_session *session)
+{
+       struct ceph_msg *msg;
+
+       dout("send_cap_releases mds%d\n", session->s_mds);
+       while (1) {
+               spin_lock(&session->s_cap_lock);
+               if (list_empty(&session->s_cap_releases_done))
+                       break;
+               msg = list_first_entry(&session->s_cap_releases_done,
+                                struct ceph_msg, list_head);
+               list_del_init(&msg->list_head);
+               spin_unlock(&session->s_cap_lock);
+               msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
+               dout("send_cap_releases mds%d %p\n", session->s_mds, msg);
+               ceph_con_send(&session->s_con, msg);
+       }
+       spin_unlock(&session->s_cap_lock);
+}
+
+/*
+ * requests
+ */
+
+/*
+ * Create an mds request.
+ */
+struct ceph_mds_request *
+ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
+{
+       struct ceph_mds_request *req = kzalloc(sizeof(*req), GFP_NOFS);
+
+       if (!req)
+               return ERR_PTR(-ENOMEM);
+
+       req->r_started = jiffies;
+       req->r_resend_mds = -1;
+       INIT_LIST_HEAD(&req->r_unsafe_dir_item);
+       req->r_fmode = -1;
+       kref_init(&req->r_kref);
+       INIT_LIST_HEAD(&req->r_wait);
+       init_completion(&req->r_completion);
+       init_completion(&req->r_safe_completion);
+       INIT_LIST_HEAD(&req->r_unsafe_item);
+
+       req->r_op = op;
+       req->r_direct_mode = mode;
+       return req;
+}
+
+/*
+ * return oldest (lowest) request, tid in request tree, 0 if none.
+ *
+ * called under mdsc->mutex.
+ */
+static struct ceph_mds_request *__get_oldest_req(struct ceph_mds_client *mdsc)
+{
+       if (RB_EMPTY_ROOT(&mdsc->request_tree))
+               return NULL;
+       return rb_entry(rb_first(&mdsc->request_tree),
+                       struct ceph_mds_request, r_node);
+}
+
+static u64 __get_oldest_tid(struct ceph_mds_client *mdsc)
+{
+       struct ceph_mds_request *req = __get_oldest_req(mdsc);
+
+       if (req)
+               return req->r_tid;
+       return 0;
+}
+
+/*
+ * Build a dentry's path.  Allocate on heap; caller must kfree.  Based
+ * on build_path_from_dentry in fs/cifs/dir.c.
+ *
+ * If @stop_on_nosnap, generate path relative to the first non-snapped
+ * inode.
+ *
+ * Encode hidden .snap dirs as a double /, i.e.
+ *   foo/.snap/bar -> foo//bar
+ */
+char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base,
+                          int stop_on_nosnap)
+{
+       struct dentry *temp;
+       char *path;
+       int len, pos;
+
+       if (dentry == NULL)
+               return ERR_PTR(-EINVAL);
+
+retry:
+       len = 0;
+       for (temp = dentry; !IS_ROOT(temp);) {
+               struct inode *inode = temp->d_inode;
+               if (inode && ceph_snap(inode) == CEPH_SNAPDIR)
+                       len++;  /* slash only */
+               else if (stop_on_nosnap && inode &&
+                        ceph_snap(inode) == CEPH_NOSNAP)
+                       break;
+               else
+                       len += 1 + temp->d_name.len;
+               temp = temp->d_parent;
+               if (temp == NULL) {
+                       pr_err("build_path_dentry corrupt dentry %p\n", dentry);
+                       return ERR_PTR(-EINVAL);
+               }
+       }
+       if (len)
+               len--;  /* no leading '/' */
+
+       path = kmalloc(len+1, GFP_NOFS);
+       if (path == NULL)
+               return ERR_PTR(-ENOMEM);
+       pos = len;
+       path[pos] = 0;  /* trailing null */
+       for (temp = dentry; !IS_ROOT(temp) && pos != 0; ) {
+               struct inode *inode = temp->d_inode;
+
+               if (inode && ceph_snap(inode) == CEPH_SNAPDIR) {
+                       dout("build_path_dentry path+%d: %p SNAPDIR\n",
+                            pos, temp);
+               } else if (stop_on_nosnap && inode &&
+                          ceph_snap(inode) == CEPH_NOSNAP) {
+                       break;
+               } else {
+                       pos -= temp->d_name.len;
+                       if (pos < 0)
+                               break;
+                       strncpy(path + pos, temp->d_name.name,
+                               temp->d_name.len);
+                       dout("build_path_dentry path+%d: %p '%.*s'\n",
+                            pos, temp, temp->d_name.len, path + pos);
+               }
+               if (pos)
+                       path[--pos] = '/';
+               temp = temp->d_parent;
+               if (temp == NULL) {
+                       pr_err("build_path_dentry corrupt dentry\n");
+                       kfree(path);
+                       return ERR_PTR(-EINVAL);
+               }
+       }
+       if (pos != 0) {
+               pr_err("build_path_dentry did not end path lookup where "
+                      "expected, namelen is %d, pos is %d\n", len, pos);
+               /* presumably this is only possible if racing with a
+                  rename of one of the parent directories (we can not
+                  lock the dentries above us to prevent this, but
+                  retrying should be harmless) */
+               kfree(path);
+               goto retry;
+       }
+
+       *base = ceph_ino(temp->d_inode);
+       *plen = len;
+       dout("build_path_dentry on %p %d built %llx '%.*s'\n",
+            dentry, atomic_read(&dentry->d_count), *base, len, path);
+       return path;
+}
+
+static int build_dentry_path(struct dentry *dentry,
+                            const char **ppath, int *ppathlen, u64 *pino,
+                            int *pfreepath)
+{
+       char *path;
+
+       if (ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP) {
+               *pino = ceph_ino(dentry->d_parent->d_inode);
+               *ppath = dentry->d_name.name;
+               *ppathlen = dentry->d_name.len;
+               return 0;
+       }
+       path = ceph_mdsc_build_path(dentry, ppathlen, pino, 1);
+       if (IS_ERR(path))
+               return PTR_ERR(path);
+       *ppath = path;
+       *pfreepath = 1;
+       return 0;
+}
+
+static int build_inode_path(struct inode *inode,
+                           const char **ppath, int *ppathlen, u64 *pino,
+                           int *pfreepath)
+{
+       struct dentry *dentry;
+       char *path;
+
+       if (ceph_snap(inode) == CEPH_NOSNAP) {
+               *pino = ceph_ino(inode);
+               *ppathlen = 0;
+               return 0;
+       }
+       dentry = d_find_alias(inode);
+       path = ceph_mdsc_build_path(dentry, ppathlen, pino, 1);
+       dput(dentry);
+       if (IS_ERR(path))
+               return PTR_ERR(path);
+       *ppath = path;
+       *pfreepath = 1;
+       return 0;
+}
+
+/*
+ * request arguments may be specified via an inode *, a dentry *, or
+ * an explicit ino+path.
+ */
+static int set_request_path_attr(struct inode *rinode, struct dentry *rdentry,
+                                 const char *rpath, u64 rino,
+                                 const char **ppath, int *pathlen,
+                                 u64 *ino, int *freepath)
+{
+       int r = 0;
+
+       if (rinode) {
+               r = build_inode_path(rinode, ppath, pathlen, ino, freepath);
+               dout(" inode %p %llx.%llx\n", rinode, ceph_ino(rinode),
+                    ceph_snap(rinode));
+       } else if (rdentry) {
+               r = build_dentry_path(rdentry, ppath, pathlen, ino, freepath);
+               dout(" dentry %p %llx/%.*s\n", rdentry, *ino, *pathlen,
+                    *ppath);
+       } else if (rpath) {
+               *ino = rino;
+               *ppath = rpath;
+               *pathlen = strlen(rpath);
+               dout(" path %.*s\n", *pathlen, rpath);
+       }
+
+       return r;
+}
+
+/*
+ * called under mdsc->mutex
+ */
+static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
+                                              struct ceph_mds_request *req,
+                                              int mds)
+{
+       struct ceph_msg *msg;
+       struct ceph_mds_request_head *head;
+       const char *path1 = NULL;
+       const char *path2 = NULL;
+       u64 ino1 = 0, ino2 = 0;
+       int pathlen1 = 0, pathlen2 = 0;
+       int freepath1 = 0, freepath2 = 0;
+       int len;
+       u16 releases;
+       void *p, *end;
+       int ret;
+
+       ret = set_request_path_attr(req->r_inode, req->r_dentry,
+                             req->r_path1, req->r_ino1.ino,
+                             &path1, &pathlen1, &ino1, &freepath1);
+       if (ret < 0) {
+               msg = ERR_PTR(ret);
+               goto out;
+       }
+
+       ret = set_request_path_attr(NULL, req->r_old_dentry,
+                             req->r_path2, req->r_ino2.ino,
+                             &path2, &pathlen2, &ino2, &freepath2);
+       if (ret < 0) {
+               msg = ERR_PTR(ret);
+               goto out_free1;
+       }
+
+       len = sizeof(*head) +
+               pathlen1 + pathlen2 + 2*(1 + sizeof(u32) + sizeof(u64));
+
+       /* calculate (max) length for cap releases */
+       len += sizeof(struct ceph_mds_request_release) *
+               (!!req->r_inode_drop + !!req->r_dentry_drop +
+                !!req->r_old_inode_drop + !!req->r_old_dentry_drop);
+       if (req->r_dentry_drop)
+               len += req->r_dentry->d_name.len;
+       if (req->r_old_dentry_drop)
+               len += req->r_old_dentry->d_name.len;
+
+       msg = ceph_msg_new(CEPH_MSG_CLIENT_REQUEST, len, 0, 0, NULL);
+       if (IS_ERR(msg))
+               goto out_free2;
+
+       msg->hdr.tid = cpu_to_le64(req->r_tid);
+
+       head = msg->front.iov_base;
+       p = msg->front.iov_base + sizeof(*head);
+       end = msg->front.iov_base + msg->front.iov_len;
+
+       head->mdsmap_epoch = cpu_to_le32(mdsc->mdsmap->m_epoch);
+       head->op = cpu_to_le32(req->r_op);
+       head->caller_uid = cpu_to_le32(current_fsuid());
+       head->caller_gid = cpu_to_le32(current_fsgid());
+       head->args = req->r_args;
+
+       ceph_encode_filepath(&p, end, ino1, path1);
+       ceph_encode_filepath(&p, end, ino2, path2);
+
+       /* cap releases */
+       releases = 0;
+       if (req->r_inode_drop)
+               releases += ceph_encode_inode_release(&p,
+                     req->r_inode ? req->r_inode : req->r_dentry->d_inode,
+                     mds, req->r_inode_drop, req->r_inode_unless, 0);
+       if (req->r_dentry_drop)
+               releases += ceph_encode_dentry_release(&p, req->r_dentry,
+                      mds, req->r_dentry_drop, req->r_dentry_unless);
+       if (req->r_old_dentry_drop)
+               releases += ceph_encode_dentry_release(&p, req->r_old_dentry,
+                      mds, req->r_old_dentry_drop, req->r_old_dentry_unless);
+       if (req->r_old_inode_drop)
+               releases += ceph_encode_inode_release(&p,
+                     req->r_old_dentry->d_inode,
+                     mds, req->r_old_inode_drop, req->r_old_inode_unless, 0);
+       head->num_releases = cpu_to_le16(releases);
+
+       BUG_ON(p > end);
+       msg->front.iov_len = p - msg->front.iov_base;
+       msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
+
+       msg->pages = req->r_pages;
+       msg->nr_pages = req->r_num_pages;
+       msg->hdr.data_len = cpu_to_le32(req->r_data_len);
+       msg->hdr.data_off = cpu_to_le16(0);
+
+out_free2:
+       if (freepath2)
+               kfree((char *)path2);
+out_free1:
+       if (freepath1)
+               kfree((char *)path1);
+out:
+       return msg;
+}
+
+/*
+ * called under mdsc->mutex if error, under no mutex if
+ * success.
+ */
+static void complete_request(struct ceph_mds_client *mdsc,
+                            struct ceph_mds_request *req)
+{
+       if (req->r_callback)
+               req->r_callback(mdsc, req);
+       else
+               complete(&req->r_completion);
+}
+
+/*
+ * called under mdsc->mutex
+ */
+static int __prepare_send_request(struct ceph_mds_client *mdsc,
+                                 struct ceph_mds_request *req,
+                                 int mds)
+{
+       struct ceph_mds_request_head *rhead;
+       struct ceph_msg *msg;
+       int flags = 0;
+
+       req->r_mds = mds;
+       req->r_attempts++;
+       dout("prepare_send_request %p tid %lld %s (attempt %d)\n", req,
+            req->r_tid, ceph_mds_op_name(req->r_op), req->r_attempts);
+
+       if (req->r_request) {
+               ceph_msg_put(req->r_request);
+               req->r_request = NULL;
+       }
+       msg = create_request_message(mdsc, req, mds);
+       if (IS_ERR(msg)) {
+               req->r_reply = ERR_PTR(PTR_ERR(msg));
+               complete_request(mdsc, req);
+               return -PTR_ERR(msg);
+       }
+       req->r_request = msg;
+
+       rhead = msg->front.iov_base;
+       rhead->oldest_client_tid = cpu_to_le64(__get_oldest_tid(mdsc));
+       if (req->r_got_unsafe)
+               flags |= CEPH_MDS_FLAG_REPLAY;
+       if (req->r_locked_dir)
+               flags |= CEPH_MDS_FLAG_WANT_DENTRY;
+       rhead->flags = cpu_to_le32(flags);
+       rhead->num_fwd = req->r_num_fwd;
+       rhead->num_retry = req->r_attempts - 1;
+
+       dout(" r_locked_dir = %p\n", req->r_locked_dir);
+
+       if (req->r_target_inode && req->r_got_unsafe)
+               rhead->ino = cpu_to_le64(ceph_ino(req->r_target_inode));
+       else
+               rhead->ino = 0;
+       return 0;
+}
+
+/*
+ * send request, or put it on the appropriate wait list.
+ */
+static int __do_request(struct ceph_mds_client *mdsc,
+                       struct ceph_mds_request *req)
+{
+       struct ceph_mds_session *session = NULL;
+       int mds = -1;
+       int err = -EAGAIN;
+
+       if (req->r_reply)
+               goto out;
+
+       if (req->r_timeout &&
+           time_after_eq(jiffies, req->r_started + req->r_timeout)) {
+               dout("do_request timed out\n");
+               err = -EIO;
+               goto finish;
+       }
+
+       mds = __choose_mds(mdsc, req);
+       if (mds < 0 ||
+           ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) {
+               dout("do_request no mds or not active, waiting for map\n");
+               list_add(&req->r_wait, &mdsc->waiting_for_map);
+               goto out;
+       }
+
+       /* get, open session */
+       session = __ceph_lookup_mds_session(mdsc, mds);
+       if (!session) {
+               session = register_session(mdsc, mds);
+               if (IS_ERR(session)) {
+                       err = PTR_ERR(session);
+                       goto finish;
+               }
+       }
+       dout("do_request mds%d session %p state %s\n", mds, session,
+            session_state_name(session->s_state));
+       if (session->s_state != CEPH_MDS_SESSION_OPEN &&
+           session->s_state != CEPH_MDS_SESSION_HUNG) {
+               if (session->s_state == CEPH_MDS_SESSION_NEW ||
+                   session->s_state == CEPH_MDS_SESSION_CLOSING)
+                       __open_session(mdsc, session);
+               list_add(&req->r_wait, &session->s_waiting);
+               goto out_session;
+       }
+
+       /* send request */
+       req->r_session = get_session(session);
+       req->r_resend_mds = -1;   /* forget any previous mds hint */
+
+       if (req->r_request_started == 0)   /* note request start time */
+               req->r_request_started = jiffies;
+
+       err = __prepare_send_request(mdsc, req, mds);
+       if (!err) {
+               ceph_msg_get(req->r_request);
+               ceph_con_send(&session->s_con, req->r_request);
+       }
+
+out_session:
+       ceph_put_mds_session(session);
+out:
+       return err;
+
+finish:
+       req->r_reply = ERR_PTR(err);
+       complete_request(mdsc, req);
+       goto out;
+}
+
+/*
+ * called under mdsc->mutex
+ */
+static void __wake_requests(struct ceph_mds_client *mdsc,
+                           struct list_head *head)
+{
+       struct ceph_mds_request *req, *nreq;
+
+       list_for_each_entry_safe(req, nreq, head, r_wait) {
+               list_del_init(&req->r_wait);
+               __do_request(mdsc, req);
+       }
+}
+
+/*
+ * Wake up threads with requests pending for @mds, so that they can
+ * resubmit their requests to a possibly different mds.  If @all is set,
+ * wake up if their requests has been forwarded to @mds, too.
+ */
+static void kick_requests(struct ceph_mds_client *mdsc, int mds, int all)
+{
+       struct ceph_mds_request *req;
+       struct rb_node *p;
+
+       dout("kick_requests mds%d\n", mds);
+       for (p = rb_first(&mdsc->request_tree); p; p = rb_next(p)) {
+               req = rb_entry(p, struct ceph_mds_request, r_node);
+               if (req->r_got_unsafe)
+                       continue;
+               if (req->r_session &&
+                   req->r_session->s_mds == mds) {
+                       dout(" kicking tid %llu\n", req->r_tid);
+                       put_request_session(req);
+                       __do_request(mdsc, req);
+               }
+       }
+}
+
+void ceph_mdsc_submit_request(struct ceph_mds_client *mdsc,
+                             struct ceph_mds_request *req)
+{
+       dout("submit_request on %p\n", req);
+       mutex_lock(&mdsc->mutex);
+       __register_request(mdsc, req, NULL);
+       __do_request(mdsc, req);
+       mutex_unlock(&mdsc->mutex);
+}
+
+/*
+ * Synchrously perform an mds request.  Take care of all of the
+ * session setup, forwarding, retry details.
+ */
+int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
+                        struct inode *dir,
+                        struct ceph_mds_request *req)
+{
+       int err;
+
+       dout("do_request on %p\n", req);
+
+       /* take CAP_PIN refs for r_inode, r_locked_dir, r_old_dentry */
+       if (req->r_inode)
+               ceph_get_cap_refs(ceph_inode(req->r_inode), CEPH_CAP_PIN);
+       if (req->r_locked_dir)
+               ceph_get_cap_refs(ceph_inode(req->r_locked_dir), CEPH_CAP_PIN);
+       if (req->r_old_dentry)
+               ceph_get_cap_refs(
+                       ceph_inode(req->r_old_dentry->d_parent->d_inode),
+                       CEPH_CAP_PIN);
+
+       /* issue */
+       mutex_lock(&mdsc->mutex);
+       __register_request(mdsc, req, dir);
+       __do_request(mdsc, req);
+
+       /* wait */
+       if (!req->r_reply) {
+               mutex_unlock(&mdsc->mutex);
+               if (req->r_timeout) {
+                       err = (long)wait_for_completion_interruptible_timeout(
+                               &req->r_completion, req->r_timeout);
+                       if (err == 0)
+                               req->r_reply = ERR_PTR(-EIO);
+                       else if (err < 0)
+                               req->r_reply = ERR_PTR(err);
+               } else {
+                        err = wait_for_completion_interruptible(
+                                &req->r_completion);
+                        if (err)
+                                req->r_reply = ERR_PTR(err);
+               }
+               mutex_lock(&mdsc->mutex);
+       }
+
+       if (IS_ERR(req->r_reply)) {
+               err = PTR_ERR(req->r_reply);
+               req->r_reply = NULL;
+
+               if (err == -ERESTARTSYS) {
+                       /* aborted */
+                       req->r_aborted = true;
+
+                       if (req->r_locked_dir &&
+                           (req->r_op & CEPH_MDS_OP_WRITE)) {
+                               struct ceph_inode_info *ci =
+                                       ceph_inode(req->r_locked_dir);
+
+                               dout("aborted, clearing I_COMPLETE on %p\n", 
+                                    req->r_locked_dir);
+                               spin_lock(&req->r_locked_dir->i_lock);
+                               ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
+                               ci->i_release_count++;
+                               spin_unlock(&req->r_locked_dir->i_lock);
+                       }
+               } else {
+                       /* clean up this request */
+                       __unregister_request(mdsc, req);
+                       if (!list_empty(&req->r_unsafe_item))
+                               list_del_init(&req->r_unsafe_item);
+                       complete(&req->r_safe_completion);
+               }
+       } else if (req->r_err) {
+               err = req->r_err;
+       } else {
+               err = le32_to_cpu(req->r_reply_info.head->result);
+       }
+       mutex_unlock(&mdsc->mutex);
+
+       dout("do_request %p done, result %d\n", req, err);
+       return err;
+}
+
+/*
+ * Handle mds reply.
+ *
+ * We take the session mutex and parse and process the reply immediately.
+ * This preserves the logical ordering of replies, capabilities, etc., sent
+ * by the MDS as they are applied to our local cache.
+ */
+static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
+{
+       struct ceph_mds_client *mdsc = session->s_mdsc;
+       struct ceph_mds_request *req;
+       struct ceph_mds_reply_head *head = msg->front.iov_base;
+       struct ceph_mds_reply_info_parsed *rinfo;  /* parsed reply info */
+       u64 tid;
+       int err, result;
+       int mds = session->s_mds;
+
+       if (msg->front.iov_len < sizeof(*head)) {
+               pr_err("mdsc_handle_reply got corrupt (short) reply\n");
+               ceph_msg_dump(msg);
+               return;
+       }
+
+       /* get request, session */
+       tid = le64_to_cpu(msg->hdr.tid);
+       mutex_lock(&mdsc->mutex);
+       req = __lookup_request(mdsc, tid);
+       if (!req) {
+               dout("handle_reply on unknown tid %llu\n", tid);
+               mutex_unlock(&mdsc->mutex);
+               return;
+       }
+       dout("handle_reply %p\n", req);
+
+       /* correct session? */
+       if (req->r_session != session) {
+               pr_err("mdsc_handle_reply got %llu on session mds%d"
+                      " not mds%d\n", tid, session->s_mds,
+                      req->r_session ? req->r_session->s_mds : -1);
+               mutex_unlock(&mdsc->mutex);
+               goto out;
+       }
+
+       /* dup? */
+       if ((req->r_got_unsafe && !head->safe) ||
+           (req->r_got_safe && head->safe)) {
+               pr_warning("got a dup %s reply on %llu from mds%d\n",
+                          head->safe ? "safe" : "unsafe", tid, mds);
+               mutex_unlock(&mdsc->mutex);
+               goto out;
+       }
+
+       result = le32_to_cpu(head->result);
+
+       /*
+        * Tolerate 2 consecutive ESTALEs from the same mds.
+        * FIXME: we should be looking at the cap migrate_seq.
+        */
+       if (result == -ESTALE) {
+               req->r_direct_mode = USE_AUTH_MDS;
+               req->r_num_stale++;
+               if (req->r_num_stale <= 2) {
+                       __do_request(mdsc, req);
+                       mutex_unlock(&mdsc->mutex);
+                       goto out;
+               }
+       } else {
+               req->r_num_stale = 0;
+       }
+
+       if (head->safe) {
+               req->r_got_safe = true;
+               __unregister_request(mdsc, req);
+               complete(&req->r_safe_completion);
+
+               if (req->r_got_unsafe) {
+                       /*
+                        * We already handled the unsafe response, now do the
+                        * cleanup.  No need to examine the response; the MDS
+                        * doesn't include any result info in the safe
+                        * response.  And even if it did, there is nothing
+                        * useful we could do with a revised return value.
+                        */
+                       dout("got safe reply %llu, mds%d\n", tid, mds);
+                       list_del_init(&req->r_unsafe_item);
+
+                       /* last unsafe request during umount? */
+                       if (mdsc->stopping && !__get_oldest_req(mdsc))
+                               complete(&mdsc->safe_umount_waiters);
+                       mutex_unlock(&mdsc->mutex);
+                       goto out;
+               }
+       }
+
+       BUG_ON(req->r_reply);
+
+       if (!head->safe) {
+               req->r_got_unsafe = true;
+               list_add_tail(&req->r_unsafe_item, &req->r_session->s_unsafe);
+       }
+
+       dout("handle_reply tid %lld result %d\n", tid, result);
+       rinfo = &req->r_reply_info;
+       err = parse_reply_info(msg, rinfo);
+       mutex_unlock(&mdsc->mutex);
+
+       mutex_lock(&session->s_mutex);
+       if (err < 0) {
+               pr_err("mdsc_handle_reply got corrupt reply mds%d\n", mds);
+               ceph_msg_dump(msg);
+               goto out_err;
+       }
+
+       /* snap trace */
+       if (rinfo->snapblob_len) {
+               down_write(&mdsc->snap_rwsem);
+               ceph_update_snap_trace(mdsc, rinfo->snapblob,
+                              rinfo->snapblob + rinfo->snapblob_len,
+                              le32_to_cpu(head->op) == CEPH_MDS_OP_RMSNAP);
+               downgrade_write(&mdsc->snap_rwsem);
+       } else {
+               down_read(&mdsc->snap_rwsem);
+       }
+
+       /* insert trace into our cache */
+       err = ceph_fill_trace(mdsc->client->sb, req, req->r_session);
+       if (err == 0) {
+               if (result == 0 && rinfo->dir_nr)
+                       ceph_readdir_prepopulate(req, req->r_session);
+               ceph_unreserve_caps(&req->r_caps_reservation);
+       }
+
+       up_read(&mdsc->snap_rwsem);
+out_err:
+       if (err) {
+               req->r_err = err;
+       } else {
+               req->r_reply = msg;
+               ceph_msg_get(msg);
+       }
+
+       add_cap_releases(mdsc, req->r_session, -1);
+       mutex_unlock(&session->s_mutex);
+
+       /* kick calling process */
+       complete_request(mdsc, req);
+out:
+       ceph_mdsc_put_request(req);
+       return;
+}
+
+
+
+/*
+ * handle mds notification that our request has been forwarded.
+ */
+static void handle_forward(struct ceph_mds_client *mdsc,
+                          struct ceph_mds_session *session,
+                          struct ceph_msg *msg)
+{
+       struct ceph_mds_request *req;
+       u64 tid = le64_to_cpu(msg->hdr.tid);
+       u32 next_mds;
+       u32 fwd_seq;
+       int err = -EINVAL;
+       void *p = msg->front.iov_base;
+       void *end = p + msg->front.iov_len;
+
+       ceph_decode_need(&p, end, 2*sizeof(u32), bad);
+       next_mds = ceph_decode_32(&p);
+       fwd_seq = ceph_decode_32(&p);
+
+       mutex_lock(&mdsc->mutex);
+       req = __lookup_request(mdsc, tid);
+       if (!req) {
+               dout("forward %llu to mds%d - req dne\n", tid, next_mds);
+               goto out;  /* dup reply? */
+       }
+
+       if (fwd_seq <= req->r_num_fwd) {
+               dout("forward %llu to mds%d - old seq %d <= %d\n",
+                    tid, next_mds, req->r_num_fwd, fwd_seq);
+       } else {
+               /* resend. forward race not possible; mds would drop */
+               dout("forward %llu to mds%d (we resend)\n", tid, next_mds);
+               req->r_num_fwd = fwd_seq;
+               req->r_resend_mds = next_mds;
+               put_request_session(req);
+               __do_request(mdsc, req);
+       }
+       ceph_mdsc_put_request(req);
+out:
+       mutex_unlock(&mdsc->mutex);
+       return;
+
+bad:
+       pr_err("mdsc_handle_forward decode error err=%d\n", err);
+}
+
+/*
+ * handle a mds session control message
+ */
+static void handle_session(struct ceph_mds_session *session,
+                          struct ceph_msg *msg)
+{
+       struct ceph_mds_client *mdsc = session->s_mdsc;
+       u32 op;
+       u64 seq;
+       int mds = session->s_mds;
+       struct ceph_mds_session_head *h = msg->front.iov_base;
+       int wake = 0;
+
+       /* decode */
+       if (msg->front.iov_len != sizeof(*h))
+               goto bad;
+       op = le32_to_cpu(h->op);
+       seq = le64_to_cpu(h->seq);
+
+       mutex_lock(&mdsc->mutex);
+       if (op == CEPH_SESSION_CLOSE)
+               __unregister_session(mdsc, session);
+       /* FIXME: this ttl calculation is generous */
+       session->s_ttl = jiffies + HZ*mdsc->mdsmap->m_session_autoclose;
+       mutex_unlock(&mdsc->mutex);
+
+       mutex_lock(&session->s_mutex);
+
+       dout("handle_session mds%d %s %p state %s seq %llu\n",
+            mds, ceph_session_op_name(op), session,
+            session_state_name(session->s_state), seq);
+
+       if (session->s_state == CEPH_MDS_SESSION_HUNG) {
+               session->s_state = CEPH_MDS_SESSION_OPEN;
+               pr_info("mds%d came back\n", session->s_mds);
+       }
+
+       switch (op) {
+       case CEPH_SESSION_OPEN:
+               session->s_state = CEPH_MDS_SESSION_OPEN;
+               renewed_caps(mdsc, session, 0);
+               wake = 1;
+               if (mdsc->stopping)
+                       __close_session(mdsc, session);
+               break;
+
+       case CEPH_SESSION_RENEWCAPS:
+               if (session->s_renew_seq == seq)
+                       renewed_caps(mdsc, session, 1);
+               break;
+
+       case CEPH_SESSION_CLOSE:
+               remove_session_caps(session);
+               wake = 1; /* for good measure */
+               complete(&mdsc->session_close_waiters);
+               kick_requests(mdsc, mds, 0);      /* cur only */
+               break;
+
+       case CEPH_SESSION_STALE:
+               pr_info("mds%d caps went stale, renewing\n",
+                       session->s_mds);
+               spin_lock(&session->s_cap_lock);
+               session->s_cap_gen++;
+               session->s_cap_ttl = 0;
+               spin_unlock(&session->s_cap_lock);
+               send_renew_caps(mdsc, session);
+               break;
+
+       case CEPH_SESSION_RECALL_STATE:
+               trim_caps(mdsc, session, le32_to_cpu(h->max_caps));
+               break;
+
+       default:
+               pr_err("mdsc_handle_session bad op %d mds%d\n", op, mds);
+               WARN_ON(1);
+       }
+
+       mutex_unlock(&session->s_mutex);
+       if (wake) {
+               mutex_lock(&mdsc->mutex);
+               __wake_requests(mdsc, &session->s_waiting);
+               mutex_unlock(&mdsc->mutex);
+       }
+       return;
+
+bad:
+       pr_err("mdsc_handle_session corrupt message mds%d len %d\n", mds,
+              (int)msg->front.iov_len);
+       ceph_msg_dump(msg);
+       return;
+}
+
+
+/*
+ * called under session->mutex.
+ */
+static void replay_unsafe_requests(struct ceph_mds_client *mdsc,
+                                  struct ceph_mds_session *session)
+{
+       struct ceph_mds_request *req, *nreq;
+       int err;
+
+       dout("replay_unsafe_requests mds%d\n", session->s_mds);
+
+       mutex_lock(&mdsc->mutex);
+       list_for_each_entry_safe(req, nreq, &session->s_unsafe, r_unsafe_item) {
+               err = __prepare_send_request(mdsc, req, session->s_mds);
+               if (!err) {
+                       ceph_msg_get(req->r_request);
+                       ceph_con_send(&session->s_con, req->r_request);
+               }
+       }
+       mutex_unlock(&mdsc->mutex);
+}
+
+/*
+ * Encode information about a cap for a reconnect with the MDS.
+ */
+static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap,
+                         void *arg)
+{
+       struct ceph_mds_cap_reconnect rec;
+       struct ceph_inode_info *ci;
+       struct ceph_pagelist *pagelist = arg;
+       char *path;
+       int pathlen, err;
+       u64 pathbase;
+       struct dentry *dentry;
+
+       ci = cap->ci;
+
+       dout(" adding %p ino %llx.%llx cap %p %lld %s\n",
+            inode, ceph_vinop(inode), cap, cap->cap_id,
+            ceph_cap_string(cap->issued));
+       err = ceph_pagelist_encode_64(pagelist, ceph_ino(inode));
+       if (err)
+               return err;
+
+       dentry = d_find_alias(inode);
+       if (dentry) {
+               path = ceph_mdsc_build_path(dentry, &pathlen, &pathbase, 0);
+               if (IS_ERR(path)) {
+                       err = PTR_ERR(path);
+                       BUG_ON(err);
+               }
+       } else {
+               path = NULL;
+               pathlen = 0;
+       }
+       err = ceph_pagelist_encode_string(pagelist, path, pathlen);
+       if (err)
+               goto out;
+
+       spin_lock(&inode->i_lock);
+       cap->seq = 0;        /* reset cap seq */
+       cap->issue_seq = 0;  /* and issue_seq */
+       rec.cap_id = cpu_to_le64(cap->cap_id);
+       rec.pathbase = cpu_to_le64(pathbase);
+       rec.wanted = cpu_to_le32(__ceph_caps_wanted(ci));
+       rec.issued = cpu_to_le32(cap->issued);
+       rec.size = cpu_to_le64(inode->i_size);
+       ceph_encode_timespec(&rec.mtime, &inode->i_mtime);
+       ceph_encode_timespec(&rec.atime, &inode->i_atime);
+       rec.snaprealm = cpu_to_le64(ci->i_snap_realm->ino);
+       spin_unlock(&inode->i_lock);
+
+       err = ceph_pagelist_append(pagelist, &rec, sizeof(rec));
+
+out:
+       kfree(path);
+       dput(dentry);
+       return err;
+}
+
+
+/*
+ * If an MDS fails and recovers, clients need to reconnect in order to
+ * reestablish shared state.  This includes all caps issued through
+ * this session _and_ the snap_realm hierarchy.  Because it's not
+ * clear which snap realms the mds cares about, we send everything we
+ * know about.. that ensures we'll then get any new info the
+ * recovering MDS might have.
+ *
+ * This is a relatively heavyweight operation, but it's rare.
+ *
+ * called with mdsc->mutex held.
+ */
+static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds)
+{
+       struct ceph_mds_session *session = NULL;
+       struct ceph_msg *reply;
+       struct rb_node *p;
+       int err = -ENOMEM;
+       struct ceph_pagelist *pagelist;
+
+       pr_info("reconnect to recovering mds%d\n", mds);
+
+       pagelist = kmalloc(sizeof(*pagelist), GFP_NOFS);
+       if (!pagelist)
+               goto fail_nopagelist;
+       ceph_pagelist_init(pagelist);
+
+       reply = ceph_msg_new(CEPH_MSG_CLIENT_RECONNECT, 0, 0, 0, NULL);
+       if (IS_ERR(reply)) {
+               err = PTR_ERR(reply);
+               goto fail_nomsg;
+       }
+
+       /* find session */
+       session = __ceph_lookup_mds_session(mdsc, mds);
+       mutex_unlock(&mdsc->mutex);    /* drop lock for duration */
+
+       if (session) {
+               mutex_lock(&session->s_mutex);
+
+               session->s_state = CEPH_MDS_SESSION_RECONNECTING;
+               session->s_seq = 0;
+
+               ceph_con_open(&session->s_con,
+                             ceph_mdsmap_get_addr(mdsc->mdsmap, mds));
+
+               /* replay unsafe requests */
+               replay_unsafe_requests(mdsc, session);
+       } else {
+               dout("no session for mds%d, will send short reconnect\n",
+                    mds);
+       }
+
+       down_read(&mdsc->snap_rwsem);
+
+       if (!session)
+               goto send;
+       dout("session %p state %s\n", session,
+            session_state_name(session->s_state));
+
+       /* traverse this session's caps */
+       err = ceph_pagelist_encode_32(pagelist, session->s_nr_caps);
+       if (err)
+               goto fail;
+       err = iterate_session_caps(session, encode_caps_cb, pagelist);
+       if (err < 0)
+               goto fail;
+
+       /*
+        * snaprealms.  we provide mds with the ino, seq (version), and
+        * parent for all of our realms.  If the mds has any newer info,
+        * it will tell us.
+        */
+       for (p = rb_first(&mdsc->snap_realms); p; p = rb_next(p)) {
+               struct ceph_snap_realm *realm =
+                       rb_entry(p, struct ceph_snap_realm, node);
+               struct ceph_mds_snaprealm_reconnect sr_rec;
+
+               dout(" adding snap realm %llx seq %lld parent %llx\n",
+                    realm->ino, realm->seq, realm->parent_ino);
+               sr_rec.ino = cpu_to_le64(realm->ino);
+               sr_rec.seq = cpu_to_le64(realm->seq);
+               sr_rec.parent = cpu_to_le64(realm->parent_ino);
+               err = ceph_pagelist_append(pagelist, &sr_rec, sizeof(sr_rec));
+               if (err)
+                       goto fail;
+       }
+
+send:
+       reply->pagelist = pagelist;
+       reply->hdr.data_len = cpu_to_le32(pagelist->length);
+       reply->nr_pages = calc_pages_for(0, pagelist->length);
+       ceph_con_send(&session->s_con, reply);
+
+       session->s_state = CEPH_MDS_SESSION_OPEN;
+       mutex_unlock(&session->s_mutex);
+
+       mutex_lock(&mdsc->mutex);
+       __wake_requests(mdsc, &session->s_waiting);
+       mutex_unlock(&mdsc->mutex);
+
+       ceph_put_mds_session(session);
+
+       up_read(&mdsc->snap_rwsem);
+       mutex_lock(&mdsc->mutex);
+       return;
+
+fail:
+       ceph_msg_put(reply);
+       up_read(&mdsc->snap_rwsem);
+       mutex_unlock(&session->s_mutex);
+       ceph_put_mds_session(session);
+fail_nomsg:
+       ceph_pagelist_release(pagelist);
+       kfree(pagelist);
+fail_nopagelist:
+       pr_err("error %d preparing reconnect for mds%d\n", err, mds);
+       mutex_lock(&mdsc->mutex);
+       return;
+}
+
+
+/*
+ * compare old and new mdsmaps, kicking requests
+ * and closing out old connections as necessary
+ *
+ * called under mdsc->mutex.
+ */
+static void check_new_map(struct ceph_mds_client *mdsc,
+                         struct ceph_mdsmap *newmap,
+                         struct ceph_mdsmap *oldmap)
+{
+       int i;
+       int oldstate, newstate;
+       struct ceph_mds_session *s;
+
+       dout("check_new_map new %u old %u\n",
+            newmap->m_epoch, oldmap->m_epoch);
+
+       for (i = 0; i < oldmap->m_max_mds && i < mdsc->max_sessions; i++) {
+               if (mdsc->sessions[i] == NULL)
+                       continue;
+               s = mdsc->sessions[i];
+               oldstate = ceph_mdsmap_get_state(oldmap, i);
+               newstate = ceph_mdsmap_get_state(newmap, i);
+
+               dout("check_new_map mds%d state %s -> %s (session %s)\n",
+                    i, ceph_mds_state_name(oldstate),
+                    ceph_mds_state_name(newstate),
+                    session_state_name(s->s_state));
+
+               if (memcmp(ceph_mdsmap_get_addr(oldmap, i),
+                          ceph_mdsmap_get_addr(newmap, i),
+                          sizeof(struct ceph_entity_addr))) {
+                       if (s->s_state == CEPH_MDS_SESSION_OPENING) {
+                               /* the session never opened, just close it
+                                * out now */
+                               __wake_requests(mdsc, &s->s_waiting);
+                               __unregister_session(mdsc, s);
+                       } else {
+                               /* just close it */
+                               mutex_unlock(&mdsc->mutex);
+                               mutex_lock(&s->s_mutex);
+                               mutex_lock(&mdsc->mutex);
+                               ceph_con_close(&s->s_con);
+                               mutex_unlock(&s->s_mutex);
+                               s->s_state = CEPH_MDS_SESSION_RESTARTING;
+                       }
+
+                       /* kick any requests waiting on the recovering mds */
+                       kick_requests(mdsc, i, 1);
+               } else if (oldstate == newstate) {
+                       continue;  /* nothing new with this mds */
+               }
+
+               /*
+                * send reconnect?
+                */
+               if (s->s_state == CEPH_MDS_SESSION_RESTARTING &&
+                   newstate >= CEPH_MDS_STATE_RECONNECT)
+                       send_mds_reconnect(mdsc, i);
+
+               /*
+                * kick requests on any mds that has gone active.
+                *
+                * kick requests on cur or forwarder: we may have sent
+                * the request to mds1, mds1 told us it forwarded it
+                * to mds2, but then we learn mds1 failed and can't be
+                * sure it successfully forwarded our request before
+                * it died.
+                */
+               if (oldstate < CEPH_MDS_STATE_ACTIVE &&
+                   newstate >= CEPH_MDS_STATE_ACTIVE) {
+                       pr_info("mds%d reconnect completed\n", s->s_mds);
+                       kick_requests(mdsc, i, 1);
+                       ceph_kick_flushing_caps(mdsc, s);
+                       wake_up_session_caps(s, 1);
+               }
+       }
+}
+
+
+
+/*
+ * leases
+ */
+
+/*
+ * caller must hold session s_mutex, dentry->d_lock
+ */
+void __ceph_mdsc_drop_dentry_lease(struct dentry *dentry)
+{
+       struct ceph_dentry_info *di = ceph_dentry(dentry);
+
+       ceph_put_mds_session(di->lease_session);
+       di->lease_session = NULL;
+}
+
+static void handle_lease(struct ceph_mds_client *mdsc,
+                        struct ceph_mds_session *session,
+                        struct ceph_msg *msg)
+{
+       struct super_block *sb = mdsc->client->sb;
+       struct inode *inode;
+       struct ceph_inode_info *ci;
+       struct dentry *parent, *dentry;
+       struct ceph_dentry_info *di;
+       int mds = session->s_mds;
+       struct ceph_mds_lease *h = msg->front.iov_base;
+       struct ceph_vino vino;
+       int mask;
+       struct qstr dname;
+       int release = 0;
+
+       dout("handle_lease from mds%d\n", mds);
+
+       /* decode */
+       if (msg->front.iov_len < sizeof(*h) + sizeof(u32))
+               goto bad;
+       vino.ino = le64_to_cpu(h->ino);
+       vino.snap = CEPH_NOSNAP;
+       mask = le16_to_cpu(h->mask);
+       dname.name = (void *)h + sizeof(*h) + sizeof(u32);
+       dname.len = msg->front.iov_len - sizeof(*h) - sizeof(u32);
+       if (dname.len != get_unaligned_le32(h+1))
+               goto bad;
+
+       mutex_lock(&session->s_mutex);
+       session->s_seq++;
+
+       /* lookup inode */
+       inode = ceph_find_inode(sb, vino);
+       dout("handle_lease '%s', mask %d, ino %llx %p\n",
+            ceph_lease_op_name(h->action), mask, vino.ino, inode);
+       if (inode == NULL) {
+               dout("handle_lease no inode %llx\n", vino.ino);
+               goto release;
+       }
+       ci = ceph_inode(inode);
+
+       /* dentry */
+       parent = d_find_alias(inode);
+       if (!parent) {
+               dout("no parent dentry on inode %p\n", inode);
+               WARN_ON(1);
+               goto release;  /* hrm... */
+       }
+       dname.hash = full_name_hash(dname.name, dname.len);
+       dentry = d_lookup(parent, &dname);
+       dput(parent);
+       if (!dentry)
+               goto release;
+
+       spin_lock(&dentry->d_lock);
+       di = ceph_dentry(dentry);
+       switch (h->action) {
+       case CEPH_MDS_LEASE_REVOKE:
+               if (di && di->lease_session == session) {
+                       h->seq = cpu_to_le32(di->lease_seq);
+                       __ceph_mdsc_drop_dentry_lease(dentry);
+               }
+               release = 1;
+               break;
+
+       case CEPH_MDS_LEASE_RENEW:
+               if (di && di->lease_session == session &&
+                   di->lease_gen == session->s_cap_gen &&
+                   di->lease_renew_from &&
+                   di->lease_renew_after == 0) {
+                       unsigned long duration =
+                               le32_to_cpu(h->duration_ms) * HZ / 1000;
+
+                       di->lease_seq = le32_to_cpu(h->seq);
+                       dentry->d_time = di->lease_renew_from + duration;
+                       di->lease_renew_after = di->lease_renew_from +
+                               (duration >> 1);
+                       di->lease_renew_from = 0;
+               }
+               break;
+       }
+       spin_unlock(&dentry->d_lock);
+       dput(dentry);
+
+       if (!release)
+               goto out;
+
+release:
+       /* let's just reuse the same message */
+       h->action = CEPH_MDS_LEASE_REVOKE_ACK;
+       ceph_msg_get(msg);
+       ceph_con_send(&session->s_con, msg);
+
+out:
+       iput(inode);
+       mutex_unlock(&session->s_mutex);
+       return;
+
+bad:
+       pr_err("corrupt lease message\n");
+       ceph_msg_dump(msg);
+}
+
+void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session,
+                             struct inode *inode,
+                             struct dentry *dentry, char action,
+                             u32 seq)
+{
+       struct ceph_msg *msg;
+       struct ceph_mds_lease *lease;
+       int len = sizeof(*lease) + sizeof(u32);
+       int dnamelen = 0;
+
+       dout("lease_send_msg inode %p dentry %p %s to mds%d\n",
+            inode, dentry, ceph_lease_op_name(action), session->s_mds);
+       dnamelen = dentry->d_name.len;
+       len += dnamelen;
+
+       msg = ceph_msg_new(CEPH_MSG_CLIENT_LEASE, len, 0, 0, NULL);
+       if (IS_ERR(msg))
+               return;
+       lease = msg->front.iov_base;
+       lease->action = action;
+       lease->mask = cpu_to_le16(CEPH_LOCK_DN);
+       lease->ino = cpu_to_le64(ceph_vino(inode).ino);
+       lease->first = lease->last = cpu_to_le64(ceph_vino(inode).snap);
+       lease->seq = cpu_to_le32(seq);
+       put_unaligned_le32(dnamelen, lease + 1);
+       memcpy((void *)(lease + 1) + 4, dentry->d_name.name, dnamelen);
+
+       /*
+        * if this is a preemptive lease RELEASE, no need to
+        * flush request stream, since the actual request will
+        * soon follow.
+        */
+       msg->more_to_follow = (action == CEPH_MDS_LEASE_RELEASE);
+
+       ceph_con_send(&session->s_con, msg);
+}
+
+/*
+ * Preemptively release a lease we expect to invalidate anyway.
+ * Pass @inode always, @dentry is optional.
+ */
+void ceph_mdsc_lease_release(struct ceph_mds_client *mdsc, struct inode *inode,
+                            struct dentry *dentry, int mask)
+{
+       struct ceph_dentry_info *di;
+       struct ceph_mds_session *session;
+       u32 seq;
+
+       BUG_ON(inode == NULL);
+       BUG_ON(dentry == NULL);
+       BUG_ON(mask != CEPH_LOCK_DN);
+
+       /* is dentry lease valid? */
+       spin_lock(&dentry->d_lock);
+       di = ceph_dentry(dentry);
+       if (!di || !di->lease_session ||
+           di->lease_session->s_mds < 0 ||
+           di->lease_gen != di->lease_session->s_cap_gen ||
+           !time_before(jiffies, dentry->d_time)) {
+               dout("lease_release inode %p dentry %p -- "
+                    "no lease on %d\n",
+                    inode, dentry, mask);
+               spin_unlock(&dentry->d_lock);
+               return;
+       }
+
+       /* we do have a lease on this dentry; note mds and seq */
+       session = ceph_get_mds_session(di->lease_session);
+       seq = di->lease_seq;
+       __ceph_mdsc_drop_dentry_lease(dentry);
+       spin_unlock(&dentry->d_lock);
+
+       dout("lease_release inode %p dentry %p mask %d to mds%d\n",
+            inode, dentry, mask, session->s_mds);
+       ceph_mdsc_lease_send_msg(session, inode, dentry,
+                                CEPH_MDS_LEASE_RELEASE, seq);
+       ceph_put_mds_session(session);
+}
+
+/*
+ * drop all leases (and dentry refs) in preparation for umount
+ */
+static void drop_leases(struct ceph_mds_client *mdsc)
+{
+       int i;
+
+       dout("drop_leases\n");
+       mutex_lock(&mdsc->mutex);
+       for (i = 0; i < mdsc->max_sessions; i++) {
+               struct ceph_mds_session *s = __ceph_lookup_mds_session(mdsc, i);
+               if (!s)
+                       continue;
+               mutex_unlock(&mdsc->mutex);
+               mutex_lock(&s->s_mutex);
+               mutex_unlock(&s->s_mutex);
+               ceph_put_mds_session(s);
+               mutex_lock(&mdsc->mutex);
+       }
+       mutex_unlock(&mdsc->mutex);
+}
+
+
+
+/*
+ * delayed work -- periodically trim expired leases, renew caps with mds
+ */
+static void schedule_delayed(struct ceph_mds_client *mdsc)
+{
+       int delay = 5;
+       unsigned hz = round_jiffies_relative(HZ * delay);
+       schedule_delayed_work(&mdsc->delayed_work, hz);
+}
+
+static void delayed_work(struct work_struct *work)
+{
+       int i;
+       struct ceph_mds_client *mdsc =
+               container_of(work, struct ceph_mds_client, delayed_work.work);
+       int renew_interval;
+       int renew_caps;
+
+       dout("mdsc delayed_work\n");
+       ceph_check_delayed_caps(mdsc);
+
+       mutex_lock(&mdsc->mutex);
+       renew_interval = mdsc->mdsmap->m_session_timeout >> 2;
+       renew_caps = time_after_eq(jiffies, HZ*renew_interval +
+                                  mdsc->last_renew_caps);
+       if (renew_caps)
+               mdsc->last_renew_caps = jiffies;
+
+       for (i = 0; i < mdsc->max_sessions; i++) {
+               struct ceph_mds_session *s = __ceph_lookup_mds_session(mdsc, i);
+               if (s == NULL)
+                       continue;
+               if (s->s_state == CEPH_MDS_SESSION_CLOSING) {
+                       dout("resending session close request for mds%d\n",
+                            s->s_mds);
+                       request_close_session(mdsc, s);
+                       ceph_put_mds_session(s);
+                       continue;
+               }
+               if (s->s_ttl && time_after(jiffies, s->s_ttl)) {
+                       if (s->s_state == CEPH_MDS_SESSION_OPEN) {
+                               s->s_state = CEPH_MDS_SESSION_HUNG;
+                               pr_info("mds%d hung\n", s->s_mds);
+                       }
+               }
+               if (s->s_state < CEPH_MDS_SESSION_OPEN) {
+                       /* this mds is failed or recovering, just wait */
+                       ceph_put_mds_session(s);
+                       continue;
+               }
+               mutex_unlock(&mdsc->mutex);
+
+               mutex_lock(&s->s_mutex);
+               if (renew_caps)
+                       send_renew_caps(mdsc, s);
+               else
+                       ceph_con_keepalive(&s->s_con);
+               add_cap_releases(mdsc, s, -1);
+               send_cap_releases(mdsc, s);
+               mutex_unlock(&s->s_mutex);
+               ceph_put_mds_session(s);
+
+               mutex_lock(&mdsc->mutex);
+       }
+       mutex_unlock(&mdsc->mutex);
+
+       schedule_delayed(mdsc);
+}
+
+
+int ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client)
+{
+       mdsc->client = client;
+       mutex_init(&mdsc->mutex);
+       mdsc->mdsmap = kzalloc(sizeof(*mdsc->mdsmap), GFP_NOFS);
+       init_completion(&mdsc->safe_umount_waiters);
+       init_completion(&mdsc->session_close_waiters);
+       INIT_LIST_HEAD(&mdsc->waiting_for_map);
+       mdsc->sessions = NULL;
+       mdsc->max_sessions = 0;
+       mdsc->stopping = 0;
+       init_rwsem(&mdsc->snap_rwsem);
+       mdsc->snap_realms = RB_ROOT;
+       INIT_LIST_HEAD(&mdsc->snap_empty);
+       spin_lock_init(&mdsc->snap_empty_lock);
+       mdsc->last_tid = 0;
+       mdsc->request_tree = RB_ROOT;
+       INIT_DELAYED_WORK(&mdsc->delayed_work, delayed_work);
+       mdsc->last_renew_caps = jiffies;
+       INIT_LIST_HEAD(&mdsc->cap_delay_list);
+       spin_lock_init(&mdsc->cap_delay_lock);
+       INIT_LIST_HEAD(&mdsc->snap_flush_list);
+       spin_lock_init(&mdsc->snap_flush_lock);
+       mdsc->cap_flush_seq = 0;
+       INIT_LIST_HEAD(&mdsc->cap_dirty);
+       mdsc->num_cap_flushing = 0;
+       spin_lock_init(&mdsc->cap_dirty_lock);
+       init_waitqueue_head(&mdsc->cap_flushing_wq);
+       spin_lock_init(&mdsc->dentry_lru_lock);
+       INIT_LIST_HEAD(&mdsc->dentry_lru);
+       return 0;
+}
+
+/*
+ * Wait for safe replies on open mds requests.  If we time out, drop
+ * all requests from the tree to avoid dangling dentry refs.
+ */
+static void wait_requests(struct ceph_mds_client *mdsc)
+{
+       struct ceph_mds_request *req;
+       struct ceph_client *client = mdsc->client;
+
+       mutex_lock(&mdsc->mutex);
+       if (__get_oldest_req(mdsc)) {
+               mutex_unlock(&mdsc->mutex);
+
+               dout("wait_requests waiting for requests\n");
+               wait_for_completion_timeout(&mdsc->safe_umount_waiters,
+                                   client->mount_args->mount_timeout * HZ);
+
+               /* tear down remaining requests */
+               mutex_lock(&mdsc->mutex);
+               while ((req = __get_oldest_req(mdsc))) {
+                       dout("wait_requests timed out on tid %llu\n",
+                            req->r_tid);
+                       __unregister_request(mdsc, req);
+               }
+       }
+       mutex_unlock(&mdsc->mutex);
+       dout("wait_requests done\n");
+}
+
+/*
+ * called before mount is ro, and before dentries are torn down.
+ * (hmm, does this still race with new lookups?)
+ */
+void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc)
+{
+       dout("pre_umount\n");
+       mdsc->stopping = 1;
+
+       drop_leases(mdsc);
+       ceph_flush_dirty_caps(mdsc);
+       wait_requests(mdsc);
+}
+
+/*
+ * wait for all write mds requests to flush.
+ */
+static void wait_unsafe_requests(struct ceph_mds_client *mdsc, u64 want_tid)
+{
+       struct ceph_mds_request *req = NULL, *nextreq;
+       struct rb_node *n;
+
+       mutex_lock(&mdsc->mutex);
+       dout("wait_unsafe_requests want %lld\n", want_tid);
+restart:
+       req = __get_oldest_req(mdsc);
+       while (req && req->r_tid <= want_tid) {
+               /* find next request */
+               n = rb_next(&req->r_node);
+               if (n)
+                       nextreq = rb_entry(n, struct ceph_mds_request, r_node);
+               else
+                       nextreq = NULL;
+               if ((req->r_op & CEPH_MDS_OP_WRITE)) {
+                       /* write op */
+                       ceph_mdsc_get_request(req);
+                       if (nextreq)
+                               ceph_mdsc_get_request(nextreq);
+                       mutex_unlock(&mdsc->mutex);
+                       dout("wait_unsafe_requests  wait on %llu (want %llu)\n",
+                            req->r_tid, want_tid);
+                       wait_for_completion(&req->r_safe_completion);
+                       mutex_lock(&mdsc->mutex);
+                       ceph_mdsc_put_request(req);
+                       if (!nextreq)
+                               break;  /* next dne before, so we're done! */
+                       if (RB_EMPTY_NODE(&nextreq->r_node)) {
+                               /* next request was removed from tree */
+                               ceph_mdsc_put_request(nextreq);
+                               goto restart;
+                       }
+                       ceph_mdsc_put_request(nextreq);  /* won't go away */
+               }
+               req = nextreq;
+       }
+       mutex_unlock(&mdsc->mutex);
+       dout("wait_unsafe_requests done\n");
+}
+
+void ceph_mdsc_sync(struct ceph_mds_client *mdsc)
+{
+       u64 want_tid, want_flush;
+
+       dout("sync\n");
+       mutex_lock(&mdsc->mutex);
+       want_tid = mdsc->last_tid;
+       want_flush = mdsc->cap_flush_seq;
+       mutex_unlock(&mdsc->mutex);
+       dout("sync want tid %lld flush_seq %lld\n", want_tid, want_flush);
+
+       ceph_flush_dirty_caps(mdsc);
+
+       wait_unsafe_requests(mdsc, want_tid);
+       wait_event(mdsc->cap_flushing_wq, check_cap_flush(mdsc, want_flush));
+}
+
+
+/*
+ * called after sb is ro.
+ */
+void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc)
+{
+       struct ceph_mds_session *session;
+       int i;
+       int n;
+       struct ceph_client *client = mdsc->client;
+       unsigned long started, timeout = client->mount_args->mount_timeout * HZ;
+
+       dout("close_sessions\n");
+
+       mutex_lock(&mdsc->mutex);
+
+       /* close sessions */
+       started = jiffies;
+       while (time_before(jiffies, started + timeout)) {
+               dout("closing sessions\n");
+               n = 0;
+               for (i = 0; i < mdsc->max_sessions; i++) {
+                       session = __ceph_lookup_mds_session(mdsc, i);
+                       if (!session)
+                               continue;
+                       mutex_unlock(&mdsc->mutex);
+                       mutex_lock(&session->s_mutex);
+                       __close_session(mdsc, session);
+                       mutex_unlock(&session->s_mutex);
+                       ceph_put_mds_session(session);
+                       mutex_lock(&mdsc->mutex);
+                       n++;
+               }
+               if (n == 0)
+                       break;
+
+               if (client->mount_state == CEPH_MOUNT_SHUTDOWN)
+                       break;
+
+               dout("waiting for sessions to close\n");
+               mutex_unlock(&mdsc->mutex);
+               wait_for_completion_timeout(&mdsc->session_close_waiters,
+                                           timeout);
+               mutex_lock(&mdsc->mutex);
+       }
+
+       /* tear down remaining sessions */
+       for (i = 0; i < mdsc->max_sessions; i++) {
+               if (mdsc->sessions[i]) {
+                       session = get_session(mdsc->sessions[i]);
+                       __unregister_session(mdsc, session);
+                       mutex_unlock(&mdsc->mutex);
+                       mutex_lock(&session->s_mutex);
+                       remove_session_caps(session);
+                       mutex_unlock(&session->s_mutex);
+                       ceph_put_mds_session(session);
+                       mutex_lock(&mdsc->mutex);
+               }
+       }
+
+       WARN_ON(!list_empty(&mdsc->cap_delay_list));
+
+       mutex_unlock(&mdsc->mutex);
+
+       ceph_cleanup_empty_realms(mdsc);
+
+       cancel_delayed_work_sync(&mdsc->delayed_work); /* cancel timer */
+
+       dout("stopped\n");
+}
+
+void ceph_mdsc_stop(struct ceph_mds_client *mdsc)
+{
+       dout("stop\n");
+       cancel_delayed_work_sync(&mdsc->delayed_work); /* cancel timer */
+       if (mdsc->mdsmap)
+               ceph_mdsmap_destroy(mdsc->mdsmap);
+       kfree(mdsc->sessions);
+}
+
+
+/*
+ * handle mds map update.
+ */
+void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
+{
+       u32 epoch;
+       u32 maplen;
+       void *p = msg->front.iov_base;
+       void *end = p + msg->front.iov_len;
+       struct ceph_mdsmap *newmap, *oldmap;
+       struct ceph_fsid fsid;
+       int err = -EINVAL;
+
+       ceph_decode_need(&p, end, sizeof(fsid)+2*sizeof(u32), bad);
+       ceph_decode_copy(&p, &fsid, sizeof(fsid));
+       if (ceph_check_fsid(mdsc->client, &fsid) < 0)
+               return;
+       epoch = ceph_decode_32(&p);
+       maplen = ceph_decode_32(&p);
+       dout("handle_map epoch %u len %d\n", epoch, (int)maplen);
+
+       /* do we need it? */
+       ceph_monc_got_mdsmap(&mdsc->client->monc, epoch);
+       mutex_lock(&mdsc->mutex);
+       if (mdsc->mdsmap && epoch <= mdsc->mdsmap->m_epoch) {
+               dout("handle_map epoch %u <= our %u\n",
+                    epoch, mdsc->mdsmap->m_epoch);
+               mutex_unlock(&mdsc->mutex);
+               return;
+       }
+
+       newmap = ceph_mdsmap_decode(&p, end);
+       if (IS_ERR(newmap)) {
+               err = PTR_ERR(newmap);
+               goto bad_unlock;
+       }
+
+       /* swap into place */
+       if (mdsc->mdsmap) {
+               oldmap = mdsc->mdsmap;
+               mdsc->mdsmap = newmap;
+               check_new_map(mdsc, newmap, oldmap);
+               ceph_mdsmap_destroy(oldmap);
+       } else {
+               mdsc->mdsmap = newmap;  /* first mds map */
+       }
+       mdsc->client->sb->s_maxbytes = mdsc->mdsmap->m_max_file_size;
+
+       __wake_requests(mdsc, &mdsc->waiting_for_map);
+
+       mutex_unlock(&mdsc->mutex);
+       schedule_delayed(mdsc);
+       return;
+
+bad_unlock:
+       mutex_unlock(&mdsc->mutex);
+bad:
+       pr_err("error decoding mdsmap %d\n", err);
+       return;
+}
+
+static struct ceph_connection *con_get(struct ceph_connection *con)
+{
+       struct ceph_mds_session *s = con->private;
+
+       if (get_session(s)) {
+               dout("mdsc con_get %p ok (%d)\n", s, atomic_read(&s->s_ref));
+               return con;
+       }
+       dout("mdsc con_get %p FAIL\n", s);
+       return NULL;
+}
+
+static void con_put(struct ceph_connection *con)
+{
+       struct ceph_mds_session *s = con->private;
+
+       ceph_put_mds_session(s);
+       dout("mdsc con_put %p (%d)\n", s, atomic_read(&s->s_ref));
+}
+
+/*
+ * if the client is unresponsive for long enough, the mds will kill
+ * the session entirely.
+ */
+static void peer_reset(struct ceph_connection *con)
+{
+       struct ceph_mds_session *s = con->private;
+
+       pr_err("mds%d gave us the boot.  IMPLEMENT RECONNECT.\n",
+              s->s_mds);
+}
+
+static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
+{
+       struct ceph_mds_session *s = con->private;
+       struct ceph_mds_client *mdsc = s->s_mdsc;
+       int type = le16_to_cpu(msg->hdr.type);
+
+       mutex_lock(&mdsc->mutex);
+       if (__verify_registered_session(mdsc, s) < 0) {
+               mutex_unlock(&mdsc->mutex);
+               goto out;
+       }
+       mutex_unlock(&mdsc->mutex);
+
+       switch (type) {
+       case CEPH_MSG_MDS_MAP:
+               ceph_mdsc_handle_map(mdsc, msg);
+               break;
+       case CEPH_MSG_CLIENT_SESSION:
+               handle_session(s, msg);
+               break;
+       case CEPH_MSG_CLIENT_REPLY:
+               handle_reply(s, msg);
+               break;
+       case CEPH_MSG_CLIENT_REQUEST_FORWARD:
+               handle_forward(mdsc, s, msg);
+               break;
+       case CEPH_MSG_CLIENT_CAPS:
+               ceph_handle_caps(s, msg);
+               break;
+       case CEPH_MSG_CLIENT_SNAP:
+               ceph_handle_snap(mdsc, s, msg);
+               break;
+       case CEPH_MSG_CLIENT_LEASE:
+               handle_lease(mdsc, s, msg);
+               break;
+
+       default:
+               pr_err("received unknown message type %d %s\n", type,
+                      ceph_msg_type_name(type));
+       }
+out:
+       ceph_msg_put(msg);
+}
+
+/*
+ * authentication
+ */
+static int get_authorizer(struct ceph_connection *con,
+                         void **buf, int *len, int *proto,
+                         void **reply_buf, int *reply_len, int force_new)
+{
+       struct ceph_mds_session *s = con->private;
+       struct ceph_mds_client *mdsc = s->s_mdsc;
+       struct ceph_auth_client *ac = mdsc->client->monc.auth;
+       int ret = 0;
+
+       if (force_new && s->s_authorizer) {
+               ac->ops->destroy_authorizer(ac, s->s_authorizer);
+               s->s_authorizer = NULL;
+       }
+       if (s->s_authorizer == NULL) {
+               if (ac->ops->create_authorizer) {
+                       ret = ac->ops->create_authorizer(
+                               ac, CEPH_ENTITY_TYPE_MDS,
+                               &s->s_authorizer,
+                               &s->s_authorizer_buf,
+                               &s->s_authorizer_buf_len,
+                               &s->s_authorizer_reply_buf,
+                               &s->s_authorizer_reply_buf_len);
+                       if (ret)
+                               return ret;
+               }
+       }
+
+       *proto = ac->protocol;
+       *buf = s->s_authorizer_buf;
+       *len = s->s_authorizer_buf_len;
+       *reply_buf = s->s_authorizer_reply_buf;
+       *reply_len = s->s_authorizer_reply_buf_len;
+       return 0;
+}
+
+
+static int verify_authorizer_reply(struct ceph_connection *con, int len)
+{
+       struct ceph_mds_session *s = con->private;
+       struct ceph_mds_client *mdsc = s->s_mdsc;
+       struct ceph_auth_client *ac = mdsc->client->monc.auth;
+
+       return ac->ops->verify_authorizer_reply(ac, s->s_authorizer, len);
+}
+
+static int invalidate_authorizer(struct ceph_connection *con)
+{
+       struct ceph_mds_session *s = con->private;
+       struct ceph_mds_client *mdsc = s->s_mdsc;
+       struct ceph_auth_client *ac = mdsc->client->monc.auth;
+
+       if (ac->ops->invalidate_authorizer)
+               ac->ops->invalidate_authorizer(ac, CEPH_ENTITY_TYPE_MDS);
+
+       return ceph_monc_validate_auth(&mdsc->client->monc);
+}
+
+const static struct ceph_connection_operations mds_con_ops = {
+       .get = con_get,
+       .put = con_put,
+       .dispatch = dispatch,
+       .get_authorizer = get_authorizer,
+       .verify_authorizer_reply = verify_authorizer_reply,
+       .invalidate_authorizer = invalidate_authorizer,
+       .peer_reset = peer_reset,
+};
+
+
+
+
+/* eof */
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
new file mode 100644 (file)
index 0000000..961cc6f
--- /dev/null
@@ -0,0 +1,335 @@
+#ifndef _FS_CEPH_MDS_CLIENT_H
+#define _FS_CEPH_MDS_CLIENT_H
+
+#include <linux/completion.h>
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/rbtree.h>
+#include <linux/spinlock.h>
+
+#include "types.h"
+#include "messenger.h"
+#include "mdsmap.h"
+
+/*
+ * Some lock dependencies:
+ *
+ * session->s_mutex
+ *         mdsc->mutex
+ *
+ *         mdsc->snap_rwsem
+ *
+ *         inode->i_lock
+ *                 mdsc->snap_flush_lock
+ *                 mdsc->cap_delay_lock
+ *
+ */
+
+struct ceph_client;
+struct ceph_cap;
+
+/*
+ * parsed info about a single inode.  pointers are into the encoded
+ * on-wire structures within the mds reply message payload.
+ */
+struct ceph_mds_reply_info_in {
+       struct ceph_mds_reply_inode *in;
+       u32 symlink_len;
+       char *symlink;
+       u32 xattr_len;
+       char *xattr_data;
+};
+
+/*
+ * parsed info about an mds reply, including information about the
+ * target inode and/or its parent directory and dentry, and directory
+ * contents (for readdir results).
+ */
+struct ceph_mds_reply_info_parsed {
+       struct ceph_mds_reply_head    *head;
+
+       struct ceph_mds_reply_info_in diri, targeti;
+       struct ceph_mds_reply_dirfrag *dirfrag;
+       char                          *dname;
+       u32                           dname_len;
+       struct ceph_mds_reply_lease   *dlease;
+
+       struct ceph_mds_reply_dirfrag *dir_dir;
+       int                           dir_nr;
+       char                          **dir_dname;
+       u32                           *dir_dname_len;
+       struct ceph_mds_reply_lease   **dir_dlease;
+       struct ceph_mds_reply_info_in *dir_in;
+       u8                            dir_complete, dir_end;
+
+       /* encoded blob describing snapshot contexts for certain
+          operations (e.g., open) */
+       void *snapblob;
+       int snapblob_len;
+};
+
+
+/*
+ * cap releases are batched and sent to the MDS en masse.
+ */
+#define CEPH_CAPS_PER_RELEASE ((PAGE_CACHE_SIZE -                      \
+                               sizeof(struct ceph_mds_cap_release)) /  \
+                              sizeof(struct ceph_mds_cap_item))
+
+
+/*
+ * state associated with each MDS<->client session
+ */
+enum {
+       CEPH_MDS_SESSION_NEW = 1,
+       CEPH_MDS_SESSION_OPENING = 2,
+       CEPH_MDS_SESSION_OPEN = 3,
+       CEPH_MDS_SESSION_HUNG = 4,
+       CEPH_MDS_SESSION_CLOSING = 5,
+       CEPH_MDS_SESSION_RESTARTING = 6,
+       CEPH_MDS_SESSION_RECONNECTING = 7,
+};
+
+struct ceph_mds_session {
+       struct ceph_mds_client *s_mdsc;
+       int               s_mds;
+       int               s_state;
+       unsigned long     s_ttl;      /* time until mds kills us */
+       u64               s_seq;      /* incoming msg seq # */
+       struct mutex      s_mutex;    /* serialize session messages */
+
+       struct ceph_connection s_con;
+
+       struct ceph_authorizer *s_authorizer;
+       void             *s_authorizer_buf, *s_authorizer_reply_buf;
+       size_t            s_authorizer_buf_len, s_authorizer_reply_buf_len;
+
+       /* protected by s_cap_lock */
+       spinlock_t        s_cap_lock;
+       u32               s_cap_gen;  /* inc each time we get mds stale msg */
+       unsigned long     s_cap_ttl;  /* when session caps expire */
+       struct list_head  s_caps;     /* all caps issued by this session */
+       int               s_nr_caps, s_trim_caps;
+       int               s_num_cap_releases;
+       struct list_head  s_cap_releases; /* waiting cap_release messages */
+       struct list_head  s_cap_releases_done; /* ready to send */
+       struct ceph_cap  *s_cap_iterator;
+
+       /* protected by mutex */
+       struct list_head  s_cap_flushing;     /* inodes w/ flushing caps */
+       struct list_head  s_cap_snaps_flushing;
+       unsigned long     s_renew_requested; /* last time we sent a renew req */
+       u64               s_renew_seq;
+
+       atomic_t          s_ref;
+       struct list_head  s_waiting;  /* waiting requests */
+       struct list_head  s_unsafe;   /* unsafe requests */
+};
+
+/*
+ * modes of choosing which MDS to send a request to
+ */
+enum {
+       USE_ANY_MDS,
+       USE_RANDOM_MDS,
+       USE_AUTH_MDS,   /* prefer authoritative mds for this metadata item */
+};
+
+struct ceph_mds_request;
+struct ceph_mds_client;
+
+/*
+ * request completion callback
+ */
+typedef void (*ceph_mds_request_callback_t) (struct ceph_mds_client *mdsc,
+                                            struct ceph_mds_request *req);
+
+/*
+ * an in-flight mds request
+ */
+struct ceph_mds_request {
+       u64 r_tid;                   /* transaction id */
+       struct rb_node r_node;
+
+       int r_op;                    /* mds op code */
+       int r_mds;
+
+       /* operation on what? */
+       struct inode *r_inode;              /* arg1 */
+       struct dentry *r_dentry;            /* arg1 */
+       struct dentry *r_old_dentry;        /* arg2: rename from or link from */
+       char *r_path1, *r_path2;
+       struct ceph_vino r_ino1, r_ino2;
+
+       struct inode *r_locked_dir; /* dir (if any) i_mutex locked by vfs */
+       struct inode *r_target_inode;       /* resulting inode */
+
+       union ceph_mds_request_args r_args;
+       int r_fmode;        /* file mode, if expecting cap */
+
+       /* for choosing which mds to send this request to */
+       int r_direct_mode;
+       u32 r_direct_hash;      /* choose dir frag based on this dentry hash */
+       bool r_direct_is_hash;  /* true if r_direct_hash is valid */
+
+       /* data payload is used for xattr ops */
+       struct page **r_pages;
+       int r_num_pages;
+       int r_data_len;
+
+       /* what caps shall we drop? */
+       int r_inode_drop, r_inode_unless;
+       int r_dentry_drop, r_dentry_unless;
+       int r_old_dentry_drop, r_old_dentry_unless;
+       struct inode *r_old_inode;
+       int r_old_inode_drop, r_old_inode_unless;
+
+       struct ceph_msg  *r_request;  /* original request */
+       struct ceph_msg  *r_reply;
+       struct ceph_mds_reply_info_parsed r_reply_info;
+       int r_err;
+       bool r_aborted;
+
+       unsigned long r_timeout;  /* optional.  jiffies */
+       unsigned long r_started;  /* start time to measure timeout against */
+       unsigned long r_request_started; /* start time for mds request only,
+                                           used to measure lease durations */
+
+       /* link unsafe requests to parent directory, for fsync */
+       struct inode    *r_unsafe_dir;
+       struct list_head r_unsafe_dir_item;
+
+       struct ceph_mds_session *r_session;
+
+       int               r_attempts;   /* resend attempts */
+       int               r_num_fwd;    /* number of forward attempts */
+       int               r_num_stale;
+       int               r_resend_mds; /* mds to resend to next, if any*/
+
+       struct kref       r_kref;
+       struct list_head  r_wait;
+       struct completion r_completion;
+       struct completion r_safe_completion;
+       ceph_mds_request_callback_t r_callback;
+       struct list_head  r_unsafe_item;  /* per-session unsafe list item */
+       bool              r_got_unsafe, r_got_safe;
+
+       bool              r_did_prepopulate;
+       u32               r_readdir_offset;
+
+       struct ceph_cap_reservation r_caps_reservation;
+       int r_num_caps;
+};
+
+/*
+ * mds client state
+ */
+struct ceph_mds_client {
+       struct ceph_client      *client;
+       struct mutex            mutex;         /* all nested structures */
+
+       struct ceph_mdsmap      *mdsmap;
+       struct completion       safe_umount_waiters, session_close_waiters;
+       struct list_head        waiting_for_map;
+
+       struct ceph_mds_session **sessions;    /* NULL for mds if no session */
+       int                     max_sessions;  /* len of s_mds_sessions */
+       int                     stopping;      /* true if shutting down */
+
+       /*
+        * snap_rwsem will cover cap linkage into snaprealms, and
+        * realm snap contexts.  (later, we can do per-realm snap
+        * contexts locks..)  the empty list contains realms with no
+        * references (implying they contain no inodes with caps) that
+        * should be destroyed.
+        */
+       struct rw_semaphore     snap_rwsem;
+       struct rb_root          snap_realms;
+       struct list_head        snap_empty;
+       spinlock_t              snap_empty_lock;  /* protect snap_empty */
+
+       u64                    last_tid;      /* most recent mds request */
+       struct rb_root         request_tree;  /* pending mds requests */
+       struct delayed_work    delayed_work;  /* delayed work */
+       unsigned long    last_renew_caps;  /* last time we renewed our caps */
+       struct list_head cap_delay_list;   /* caps with delayed release */
+       spinlock_t       cap_delay_lock;   /* protects cap_delay_list */
+       struct list_head snap_flush_list;  /* cap_snaps ready to flush */
+       spinlock_t       snap_flush_lock;
+
+       u64               cap_flush_seq;
+       struct list_head  cap_dirty;        /* inodes with dirty caps */
+       int               num_cap_flushing; /* # caps we are flushing */
+       spinlock_t        cap_dirty_lock;   /* protects above items */
+       wait_queue_head_t cap_flushing_wq;
+
+#ifdef CONFIG_DEBUG_FS
+       struct dentry     *debugfs_file;
+#endif
+
+       spinlock_t        dentry_lru_lock;
+       struct list_head  dentry_lru;
+       int               num_dentry;
+};
+
+extern const char *ceph_mds_op_name(int op);
+
+extern struct ceph_mds_session *
+__ceph_lookup_mds_session(struct ceph_mds_client *, int mds);
+
+static inline struct ceph_mds_session *
+ceph_get_mds_session(struct ceph_mds_session *s)
+{
+       atomic_inc(&s->s_ref);
+       return s;
+}
+
+extern void ceph_put_mds_session(struct ceph_mds_session *s);
+
+extern int ceph_send_msg_mds(struct ceph_mds_client *mdsc,
+                            struct ceph_msg *msg, int mds);
+
+extern int ceph_mdsc_init(struct ceph_mds_client *mdsc,
+                          struct ceph_client *client);
+extern void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc);
+extern void ceph_mdsc_stop(struct ceph_mds_client *mdsc);
+
+extern void ceph_mdsc_sync(struct ceph_mds_client *mdsc);
+
+extern void ceph_mdsc_lease_release(struct ceph_mds_client *mdsc,
+                                   struct inode *inode,
+                                   struct dentry *dn, int mask);
+
+extern struct ceph_mds_request *
+ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode);
+extern void ceph_mdsc_submit_request(struct ceph_mds_client *mdsc,
+                                    struct ceph_mds_request *req);
+extern int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
+                               struct inode *dir,
+                               struct ceph_mds_request *req);
+static inline void ceph_mdsc_get_request(struct ceph_mds_request *req)
+{
+       kref_get(&req->r_kref);
+}
+extern void ceph_mdsc_release_request(struct kref *kref);
+static inline void ceph_mdsc_put_request(struct ceph_mds_request *req)
+{
+       kref_put(&req->r_kref, ceph_mdsc_release_request);
+}
+
+extern void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc);
+
+extern char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base,
+                                 int stop_on_nosnap);
+
+extern void __ceph_mdsc_drop_dentry_lease(struct dentry *dentry);
+extern void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session,
+                                    struct inode *inode,
+                                    struct dentry *dentry, char action,
+                                    u32 seq);
+
+extern void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc,
+                                struct ceph_msg *msg);
+
+#endif
diff --git a/fs/ceph/mdsmap.c b/fs/ceph/mdsmap.c
new file mode 100644 (file)
index 0000000..c4c498e
--- /dev/null
@@ -0,0 +1,174 @@
+#include "ceph_debug.h"
+
+#include <linux/bug.h>
+#include <linux/err.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "mdsmap.h"
+#include "messenger.h"
+#include "decode.h"
+
+#include "super.h"
+
+
+/*
+ * choose a random mds that is "up" (i.e. has a state > 0), or -1.
+ */
+int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m)
+{
+       int n = 0;
+       int i;
+       char r;
+
+       /* count */
+       for (i = 0; i < m->m_max_mds; i++)
+               if (m->m_info[i].state > 0)
+                       n++;
+       if (n == 0)
+               return -1;
+
+       /* pick */
+       get_random_bytes(&r, 1);
+       n = r % n;
+       i = 0;
+       for (i = 0; n > 0; i++, n--)
+               while (m->m_info[i].state <= 0)
+                       i++;
+
+       return i;
+}
+
+/*
+ * Decode an MDS map
+ *
+ * Ignore any fields we don't care about (there are quite a few of
+ * them).
+ */
+struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
+{
+       struct ceph_mdsmap *m;
+       const void *start = *p;
+       int i, j, n;
+       int err = -EINVAL;
+       u16 version;
+
+       m = kzalloc(sizeof(*m), GFP_NOFS);
+       if (m == NULL)
+               return ERR_PTR(-ENOMEM);
+
+       ceph_decode_16_safe(p, end, version, bad);
+
+       ceph_decode_need(p, end, 8*sizeof(u32) + sizeof(u64), bad);
+       m->m_epoch = ceph_decode_32(p);
+       m->m_client_epoch = ceph_decode_32(p);
+       m->m_last_failure = ceph_decode_32(p);
+       m->m_root = ceph_decode_32(p);
+       m->m_session_timeout = ceph_decode_32(p);
+       m->m_session_autoclose = ceph_decode_32(p);
+       m->m_max_file_size = ceph_decode_64(p);
+       m->m_max_mds = ceph_decode_32(p);
+
+       m->m_info = kcalloc(m->m_max_mds, sizeof(*m->m_info), GFP_NOFS);
+       if (m->m_info == NULL)
+               goto badmem;
+
+       /* pick out active nodes from mds_info (state > 0) */
+       n = ceph_decode_32(p);
+       for (i = 0; i < n; i++) {
+               u64 global_id;
+               u32 namelen;
+               s32 mds, inc, state;
+               u64 state_seq;
+               u8 infoversion;
+               struct ceph_entity_addr addr;
+               u32 num_export_targets;
+               void *pexport_targets = NULL;
+
+               ceph_decode_need(p, end, sizeof(u64)*2 + 1 + sizeof(u32), bad);
+               global_id = ceph_decode_64(p);
+               infoversion = ceph_decode_8(p);
+               *p += sizeof(u64);
+               namelen = ceph_decode_32(p);  /* skip mds name */
+               *p += namelen;
+
+               ceph_decode_need(p, end,
+                                4*sizeof(u32) + sizeof(u64) +
+                                sizeof(addr) + sizeof(struct ceph_timespec),
+                                bad);
+               mds = ceph_decode_32(p);
+               inc = ceph_decode_32(p);
+               state = ceph_decode_32(p);
+               state_seq = ceph_decode_64(p);
+               ceph_decode_copy(p, &addr, sizeof(addr));
+               ceph_decode_addr(&addr);
+               *p += sizeof(struct ceph_timespec);
+               *p += sizeof(u32);
+               ceph_decode_32_safe(p, end, namelen, bad);
+               *p += namelen;
+               if (infoversion >= 2) {
+                       ceph_decode_32_safe(p, end, num_export_targets, bad);
+                       pexport_targets = *p;
+                       *p += num_export_targets * sizeof(u32);
+               } else {
+                       num_export_targets = 0;
+               }
+
+               dout("mdsmap_decode %d/%d %lld mds%d.%d %s %s\n",
+                    i+1, n, global_id, mds, inc, pr_addr(&addr.in_addr),
+                    ceph_mds_state_name(state));
+               if (mds >= 0 && mds < m->m_max_mds && state > 0) {
+                       m->m_info[mds].global_id = global_id;
+                       m->m_info[mds].state = state;
+                       m->m_info[mds].addr = addr;
+                       m->m_info[mds].num_export_targets = num_export_targets;
+                       if (num_export_targets) {
+                               m->m_info[mds].export_targets =
+                                       kcalloc(num_export_targets, sizeof(u32),
+                                               GFP_NOFS);
+                               for (j = 0; j < num_export_targets; j++)
+                                       m->m_info[mds].export_targets[j] =
+                                              ceph_decode_32(&pexport_targets);
+                       } else {
+                               m->m_info[mds].export_targets = NULL;
+                       }
+               }
+       }
+
+       /* pg_pools */
+       ceph_decode_32_safe(p, end, n, bad);
+       m->m_num_data_pg_pools = n;
+       m->m_data_pg_pools = kcalloc(n, sizeof(u32), GFP_NOFS);
+       if (!m->m_data_pg_pools)
+               goto badmem;
+       ceph_decode_need(p, end, sizeof(u32)*(n+1), bad);
+       for (i = 0; i < n; i++)
+               m->m_data_pg_pools[i] = ceph_decode_32(p);
+       m->m_cas_pg_pool = ceph_decode_32(p);
+
+       /* ok, we don't care about the rest. */
+       dout("mdsmap_decode success epoch %u\n", m->m_epoch);
+       return m;
+
+badmem:
+       err = -ENOMEM;
+bad:
+       pr_err("corrupt mdsmap\n");
+       print_hex_dump(KERN_DEBUG, "mdsmap: ",
+                      DUMP_PREFIX_OFFSET, 16, 1,
+                      start, end - start, true);
+       ceph_mdsmap_destroy(m);
+       return ERR_PTR(-EINVAL);
+}
+
+void ceph_mdsmap_destroy(struct ceph_mdsmap *m)
+{
+       int i;
+
+       for (i = 0; i < m->m_max_mds; i++)
+               kfree(m->m_info[i].export_targets);
+       kfree(m->m_info);
+       kfree(m->m_data_pg_pools);
+       kfree(m);
+}
diff --git a/fs/ceph/mdsmap.h b/fs/ceph/mdsmap.h
new file mode 100644 (file)
index 0000000..eacc131
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef _FS_CEPH_MDSMAP_H
+#define _FS_CEPH_MDSMAP_H
+
+#include "types.h"
+
+/*
+ * mds map - describe servers in the mds cluster.
+ *
+ * we limit fields to those the client actually xcares about
+ */
+struct ceph_mds_info {
+       u64 global_id;
+       struct ceph_entity_addr addr;
+       s32 state;
+       int num_export_targets;
+       u32 *export_targets;
+};
+
+struct ceph_mdsmap {
+       u32 m_epoch, m_client_epoch, m_last_failure;
+       u32 m_root;
+       u32 m_session_timeout;          /* seconds */
+       u32 m_session_autoclose;        /* seconds */
+       u64 m_max_file_size;
+       u32 m_max_mds;                  /* size of m_addr, m_state arrays */
+       struct ceph_mds_info *m_info;
+
+       /* which object pools file data can be stored in */
+       int m_num_data_pg_pools;
+       u32 *m_data_pg_pools;
+       u32 m_cas_pg_pool;
+};
+
+static inline struct ceph_entity_addr *
+ceph_mdsmap_get_addr(struct ceph_mdsmap *m, int w)
+{
+       if (w >= m->m_max_mds)
+               return NULL;
+       return &m->m_info[w].addr;
+}
+
+static inline int ceph_mdsmap_get_state(struct ceph_mdsmap *m, int w)
+{
+       BUG_ON(w < 0);
+       if (w >= m->m_max_mds)
+               return CEPH_MDS_STATE_DNE;
+       return m->m_info[w].state;
+}
+
+extern int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m);
+extern struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end);
+extern void ceph_mdsmap_destroy(struct ceph_mdsmap *m);
+
+#endif
diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c
new file mode 100644 (file)
index 0000000..cd4fadb
--- /dev/null
@@ -0,0 +1,2284 @@
+#include "ceph_debug.h"
+
+#include <linux/crc32c.h>
+#include <linux/ctype.h>
+#include <linux/highmem.h>
+#include <linux/inet.h>
+#include <linux/kthread.h>
+#include <linux/net.h>
+#include <linux/slab.h>
+#include <linux/socket.h>
+#include <linux/string.h>
+#include <net/tcp.h>
+
+#include "super.h"
+#include "messenger.h"
+#include "decode.h"
+#include "pagelist.h"
+
+/*
+ * Ceph uses the messenger to exchange ceph_msg messages with other
+ * hosts in the system.  The messenger provides ordered and reliable
+ * delivery.  We tolerate TCP disconnects by reconnecting (with
+ * exponential backoff) in the case of a fault (disconnection, bad
+ * crc, protocol error).  Acks allow sent messages to be discarded by
+ * the sender.
+ */
+
+/* static tag bytes (protocol control messages) */
+static char tag_msg = CEPH_MSGR_TAG_MSG;
+static char tag_ack = CEPH_MSGR_TAG_ACK;
+static char tag_keepalive = CEPH_MSGR_TAG_KEEPALIVE;
+
+#ifdef CONFIG_LOCKDEP
+static struct lock_class_key socket_class;
+#endif
+
+
+static void queue_con(struct ceph_connection *con);
+static void con_work(struct work_struct *);
+static void ceph_fault(struct ceph_connection *con);
+
+const char *ceph_name_type_str(int t)
+{
+       switch (t) {
+       case CEPH_ENTITY_TYPE_MON: return "mon";
+       case CEPH_ENTITY_TYPE_MDS: return "mds";
+       case CEPH_ENTITY_TYPE_OSD: return "osd";
+       case CEPH_ENTITY_TYPE_CLIENT: return "client";
+       case CEPH_ENTITY_TYPE_ADMIN: return "admin";
+       default: return "???";
+       }
+}
+
+/*
+ * nicely render a sockaddr as a string.
+ */
+#define MAX_ADDR_STR 20
+static char addr_str[MAX_ADDR_STR][40];
+static DEFINE_SPINLOCK(addr_str_lock);
+static int last_addr_str;
+
+const char *pr_addr(const struct sockaddr_storage *ss)
+{
+       int i;
+       char *s;
+       struct sockaddr_in *in4 = (void *)ss;
+       unsigned char *quad = (void *)&in4->sin_addr.s_addr;
+       struct sockaddr_in6 *in6 = (void *)ss;
+
+       spin_lock(&addr_str_lock);
+       i = last_addr_str++;
+       if (last_addr_str == MAX_ADDR_STR)
+               last_addr_str = 0;
+       spin_unlock(&addr_str_lock);
+       s = addr_str[i];
+
+       switch (ss->ss_family) {
+       case AF_INET:
+               sprintf(s, "%u.%u.%u.%u:%u",
+                       (unsigned int)quad[0],
+                       (unsigned int)quad[1],
+                       (unsigned int)quad[2],
+                       (unsigned int)quad[3],
+                       (unsigned int)ntohs(in4->sin_port));
+               break;
+
+       case AF_INET6:
+               sprintf(s, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%u",
+                       in6->sin6_addr.s6_addr16[0],
+                       in6->sin6_addr.s6_addr16[1],
+                       in6->sin6_addr.s6_addr16[2],
+                       in6->sin6_addr.s6_addr16[3],
+                       in6->sin6_addr.s6_addr16[4],
+                       in6->sin6_addr.s6_addr16[5],
+                       in6->sin6_addr.s6_addr16[6],
+                       in6->sin6_addr.s6_addr16[7],
+                       (unsigned int)ntohs(in6->sin6_port));
+               break;
+
+       default:
+               sprintf(s, "(unknown sockaddr family %d)", (int)ss->ss_family);
+       }
+
+       return s;
+}
+
+static void encode_my_addr(struct ceph_messenger *msgr)
+{
+       memcpy(&msgr->my_enc_addr, &msgr->inst.addr, sizeof(msgr->my_enc_addr));
+       ceph_encode_addr(&msgr->my_enc_addr);
+}
+
+/*
+ * work queue for all reading and writing to/from the socket.
+ */
+struct workqueue_struct *ceph_msgr_wq;
+
+int __init ceph_msgr_init(void)
+{
+       ceph_msgr_wq = create_workqueue("ceph-msgr");
+       if (IS_ERR(ceph_msgr_wq)) {
+               int ret = PTR_ERR(ceph_msgr_wq);
+               pr_err("msgr_init failed to create workqueue: %d\n", ret);
+               ceph_msgr_wq = NULL;
+               return ret;
+       }
+       return 0;
+}
+
+void ceph_msgr_exit(void)
+{
+       destroy_workqueue(ceph_msgr_wq);
+}
+
+/*
+ * socket callback functions
+ */
+
+/* data available on socket, or listen socket received a connect */
+static void ceph_data_ready(struct sock *sk, int count_unused)
+{
+       struct ceph_connection *con =
+               (struct ceph_connection *)sk->sk_user_data;
+       if (sk->sk_state != TCP_CLOSE_WAIT) {
+               dout("ceph_data_ready on %p state = %lu, queueing work\n",
+                    con, con->state);
+               queue_con(con);
+       }
+}
+
+/* socket has buffer space for writing */
+static void ceph_write_space(struct sock *sk)
+{
+       struct ceph_connection *con =
+               (struct ceph_connection *)sk->sk_user_data;
+
+       /* only queue to workqueue if there is data we want to write. */
+       if (test_bit(WRITE_PENDING, &con->state)) {
+               dout("ceph_write_space %p queueing write work\n", con);
+               queue_con(con);
+       } else {
+               dout("ceph_write_space %p nothing to write\n", con);
+       }
+
+       /* since we have our own write_space, clear the SOCK_NOSPACE flag */
+       clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
+}
+
+/* socket's state has changed */
+static void ceph_state_change(struct sock *sk)
+{
+       struct ceph_connection *con =
+               (struct ceph_connection *)sk->sk_user_data;
+
+       dout("ceph_state_change %p state = %lu sk_state = %u\n",
+            con, con->state, sk->sk_state);
+
+       if (test_bit(CLOSED, &con->state))
+               return;
+
+       switch (sk->sk_state) {
+       case TCP_CLOSE:
+               dout("ceph_state_change TCP_CLOSE\n");
+       case TCP_CLOSE_WAIT:
+               dout("ceph_state_change TCP_CLOSE_WAIT\n");
+               if (test_and_set_bit(SOCK_CLOSED, &con->state) == 0) {
+                       if (test_bit(CONNECTING, &con->state))
+                               con->error_msg = "connection failed";
+                       else
+                               con->error_msg = "socket closed";
+                       queue_con(con);
+               }
+               break;
+       case TCP_ESTABLISHED:
+               dout("ceph_state_change TCP_ESTABLISHED\n");
+               queue_con(con);
+               break;
+       }
+}
+
+/*
+ * set up socket callbacks
+ */
+static void set_sock_callbacks(struct socket *sock,
+                              struct ceph_connection *con)
+{
+       struct sock *sk = sock->sk;
+       sk->sk_user_data = (void *)con;
+       sk->sk_data_ready = ceph_data_ready;
+       sk->sk_write_space = ceph_write_space;
+       sk->sk_state_change = ceph_state_change;
+}
+
+
+/*
+ * socket helpers
+ */
+
+/*
+ * initiate connection to a remote socket.
+ */
+static struct socket *ceph_tcp_connect(struct ceph_connection *con)
+{
+       struct sockaddr *paddr = (struct sockaddr *)&con->peer_addr.in_addr;
+       struct socket *sock;
+       int ret;
+
+       BUG_ON(con->sock);
+       ret = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
+       if (ret)
+               return ERR_PTR(ret);
+       con->sock = sock;
+       sock->sk->sk_allocation = GFP_NOFS;
+
+#ifdef CONFIG_LOCKDEP
+       lockdep_set_class(&sock->sk->sk_lock, &socket_class);
+#endif
+
+       set_sock_callbacks(sock, con);
+
+       dout("connect %s\n", pr_addr(&con->peer_addr.in_addr));
+
+       ret = sock->ops->connect(sock, paddr, sizeof(*paddr), O_NONBLOCK);
+       if (ret == -EINPROGRESS) {
+               dout("connect %s EINPROGRESS sk_state = %u\n",
+                    pr_addr(&con->peer_addr.in_addr),
+                    sock->sk->sk_state);
+               ret = 0;
+       }
+       if (ret < 0) {
+               pr_err("connect %s error %d\n",
+                      pr_addr(&con->peer_addr.in_addr), ret);
+               sock_release(sock);
+               con->sock = NULL;
+               con->error_msg = "connect error";
+       }
+
+       if (ret < 0)
+               return ERR_PTR(ret);
+       return sock;
+}
+
+static int ceph_tcp_recvmsg(struct socket *sock, void *buf, size_t len)
+{
+       struct kvec iov = {buf, len};
+       struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL };
+
+       return kernel_recvmsg(sock, &msg, &iov, 1, len, msg.msg_flags);
+}
+
+/*
+ * write something.  @more is true if caller will be sending more data
+ * shortly.
+ */
+static int ceph_tcp_sendmsg(struct socket *sock, struct kvec *iov,
+                    size_t kvlen, size_t len, int more)
+{
+       struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL };
+
+       if (more)
+               msg.msg_flags |= MSG_MORE;
+       else
+               msg.msg_flags |= MSG_EOR;  /* superfluous, but what the hell */
+
+       return kernel_sendmsg(sock, &msg, iov, kvlen, len);
+}
+
+
+/*
+ * Shutdown/close the socket for the given connection.
+ */
+static int con_close_socket(struct ceph_connection *con)
+{
+       int rc;
+
+       dout("con_close_socket on %p sock %p\n", con, con->sock);
+       if (!con->sock)
+               return 0;
+       set_bit(SOCK_CLOSED, &con->state);
+       rc = con->sock->ops->shutdown(con->sock, SHUT_RDWR);
+       sock_release(con->sock);
+       con->sock = NULL;
+       clear_bit(SOCK_CLOSED, &con->state);
+       return rc;
+}
+
+/*
+ * Reset a connection.  Discard all incoming and outgoing messages
+ * and clear *_seq state.
+ */
+static void ceph_msg_remove(struct ceph_msg *msg)
+{
+       list_del_init(&msg->list_head);
+       ceph_msg_put(msg);
+}
+static void ceph_msg_remove_list(struct list_head *head)
+{
+       while (!list_empty(head)) {
+               struct ceph_msg *msg = list_first_entry(head, struct ceph_msg,
+                                                       list_head);
+               ceph_msg_remove(msg);
+       }
+}
+
+static void reset_connection(struct ceph_connection *con)
+{
+       /* reset connection, out_queue, msg_ and connect_seq */
+       /* discard existing out_queue and msg_seq */
+       ceph_msg_remove_list(&con->out_queue);
+       ceph_msg_remove_list(&con->out_sent);
+
+       if (con->in_msg) {
+               ceph_msg_put(con->in_msg);
+               con->in_msg = NULL;
+       }
+
+       con->connect_seq = 0;
+       con->out_seq = 0;
+       if (con->out_msg) {
+               ceph_msg_put(con->out_msg);
+               con->out_msg = NULL;
+       }
+       con->in_seq = 0;
+       con->in_seq_acked = 0;
+}
+
+/*
+ * mark a peer down.  drop any open connections.
+ */
+void ceph_con_close(struct ceph_connection *con)
+{
+       dout("con_close %p peer %s\n", con, pr_addr(&con->peer_addr.in_addr));
+       set_bit(CLOSED, &con->state);  /* in case there's queued work */
+       clear_bit(STANDBY, &con->state);  /* avoid connect_seq bump */
+       clear_bit(LOSSYTX, &con->state);  /* so we retry next connect */
+       clear_bit(KEEPALIVE_PENDING, &con->state);
+       clear_bit(WRITE_PENDING, &con->state);
+       mutex_lock(&con->mutex);
+       reset_connection(con);
+       cancel_delayed_work(&con->work);
+       mutex_unlock(&con->mutex);
+       queue_con(con);
+}
+
+/*
+ * Reopen a closed connection, with a new peer address.
+ */
+void ceph_con_open(struct ceph_connection *con, struct ceph_entity_addr *addr)
+{
+       dout("con_open %p %s\n", con, pr_addr(&addr->in_addr));
+       set_bit(OPENING, &con->state);
+       clear_bit(CLOSED, &con->state);
+       memcpy(&con->peer_addr, addr, sizeof(*addr));
+       con->delay = 0;      /* reset backoff memory */
+       queue_con(con);
+}
+
+/*
+ * return true if this connection ever successfully opened
+ */
+bool ceph_con_opened(struct ceph_connection *con)
+{
+       return con->connect_seq > 0;
+}
+
+/*
+ * generic get/put
+ */
+struct ceph_connection *ceph_con_get(struct ceph_connection *con)
+{
+       dout("con_get %p nref = %d -> %d\n", con,
+            atomic_read(&con->nref), atomic_read(&con->nref) + 1);
+       if (atomic_inc_not_zero(&con->nref))
+               return con;
+       return NULL;
+}
+
+void ceph_con_put(struct ceph_connection *con)
+{
+       dout("con_put %p nref = %d -> %d\n", con,
+            atomic_read(&con->nref), atomic_read(&con->nref) - 1);
+       BUG_ON(atomic_read(&con->nref) == 0);
+       if (atomic_dec_and_test(&con->nref)) {
+               BUG_ON(con->sock);
+               kfree(con);
+       }
+}
+
+/*
+ * initialize a new connection.
+ */
+void ceph_con_init(struct ceph_messenger *msgr, struct ceph_connection *con)
+{
+       dout("con_init %p\n", con);
+       memset(con, 0, sizeof(*con));
+       atomic_set(&con->nref, 1);
+       con->msgr = msgr;
+       mutex_init(&con->mutex);
+       INIT_LIST_HEAD(&con->out_queue);
+       INIT_LIST_HEAD(&con->out_sent);
+       INIT_DELAYED_WORK(&con->work, con_work);
+}
+
+
+/*
+ * We maintain a global counter to order connection attempts.  Get
+ * a unique seq greater than @gt.
+ */
+static u32 get_global_seq(struct ceph_messenger *msgr, u32 gt)
+{
+       u32 ret;
+
+       spin_lock(&msgr->global_seq_lock);
+       if (msgr->global_seq < gt)
+               msgr->global_seq = gt;
+       ret = ++msgr->global_seq;
+       spin_unlock(&msgr->global_seq_lock);
+       return ret;
+}
+
+
+/*
+ * Prepare footer for currently outgoing message, and finish things
+ * off.  Assumes out_kvec* are already valid.. we just add on to the end.
+ */
+static void prepare_write_message_footer(struct ceph_connection *con, int v)
+{
+       struct ceph_msg *m = con->out_msg;
+
+       dout("prepare_write_message_footer %p\n", con);
+       con->out_kvec_is_msg = true;
+       con->out_kvec[v].iov_base = &m->footer;
+       con->out_kvec[v].iov_len = sizeof(m->footer);
+       con->out_kvec_bytes += sizeof(m->footer);
+       con->out_kvec_left++;
+       con->out_more = m->more_to_follow;
+       con->out_msg_done = true;
+}
+
+/*
+ * Prepare headers for the next outgoing message.
+ */
+static void prepare_write_message(struct ceph_connection *con)
+{
+       struct ceph_msg *m;
+       int v = 0;
+
+       con->out_kvec_bytes = 0;
+       con->out_kvec_is_msg = true;
+       con->out_msg_done = false;
+
+       /* Sneak an ack in there first?  If we can get it into the same
+        * TCP packet that's a good thing. */
+       if (con->in_seq > con->in_seq_acked) {
+               con->in_seq_acked = con->in_seq;
+               con->out_kvec[v].iov_base = &tag_ack;
+               con->out_kvec[v++].iov_len = 1;
+               con->out_temp_ack = cpu_to_le64(con->in_seq_acked);
+               con->out_kvec[v].iov_base = &con->out_temp_ack;
+               con->out_kvec[v++].iov_len = sizeof(con->out_temp_ack);
+               con->out_kvec_bytes = 1 + sizeof(con->out_temp_ack);
+       }
+
+       m = list_first_entry(&con->out_queue,
+                      struct ceph_msg, list_head);
+       con->out_msg = m;
+       if (test_bit(LOSSYTX, &con->state)) {
+               list_del_init(&m->list_head);
+       } else {
+               /* put message on sent list */
+               ceph_msg_get(m);
+               list_move_tail(&m->list_head, &con->out_sent);
+       }
+
+       /*
+        * only assign outgoing seq # if we haven't sent this message
+        * yet.  if it is requeued, resend with it's original seq.
+        */
+       if (m->needs_out_seq) {
+               m->hdr.seq = cpu_to_le64(++con->out_seq);
+               m->needs_out_seq = false;
+       }
+
+       dout("prepare_write_message %p seq %lld type %d len %d+%d+%d %d pgs\n",
+            m, con->out_seq, le16_to_cpu(m->hdr.type),
+            le32_to_cpu(m->hdr.front_len), le32_to_cpu(m->hdr.middle_len),
+            le32_to_cpu(m->hdr.data_len),
+            m->nr_pages);
+       BUG_ON(le32_to_cpu(m->hdr.front_len) != m->front.iov_len);
+
+       /* tag + hdr + front + middle */
+       con->out_kvec[v].iov_base = &tag_msg;
+       con->out_kvec[v++].iov_len = 1;
+       con->out_kvec[v].iov_base = &m->hdr;
+       con->out_kvec[v++].iov_len = sizeof(m->hdr);
+       con->out_kvec[v++] = m->front;
+       if (m->middle)
+               con->out_kvec[v++] = m->middle->vec;
+       con->out_kvec_left = v;
+       con->out_kvec_bytes += 1 + sizeof(m->hdr) + m->front.iov_len +
+               (m->middle ? m->middle->vec.iov_len : 0);
+       con->out_kvec_cur = con->out_kvec;
+
+       /* fill in crc (except data pages), footer */
+       con->out_msg->hdr.crc =
+               cpu_to_le32(crc32c(0, (void *)&m->hdr,
+                                     sizeof(m->hdr) - sizeof(m->hdr.crc)));
+       con->out_msg->footer.flags = CEPH_MSG_FOOTER_COMPLETE;
+       con->out_msg->footer.front_crc =
+               cpu_to_le32(crc32c(0, m->front.iov_base, m->front.iov_len));
+       if (m->middle)
+               con->out_msg->footer.middle_crc =
+                       cpu_to_le32(crc32c(0, m->middle->vec.iov_base,
+                                          m->middle->vec.iov_len));
+       else
+               con->out_msg->footer.middle_crc = 0;
+       con->out_msg->footer.data_crc = 0;
+       dout("prepare_write_message front_crc %u data_crc %u\n",
+            le32_to_cpu(con->out_msg->footer.front_crc),
+            le32_to_cpu(con->out_msg->footer.middle_crc));
+
+       /* is there a data payload? */
+       if (le32_to_cpu(m->hdr.data_len) > 0) {
+               /* initialize page iterator */
+               con->out_msg_pos.page = 0;
+               con->out_msg_pos.page_pos =
+                       le16_to_cpu(m->hdr.data_off) & ~PAGE_MASK;
+               con->out_msg_pos.data_pos = 0;
+               con->out_msg_pos.did_page_crc = 0;
+               con->out_more = 1;  /* data + footer will follow */
+       } else {
+               /* no, queue up footer too and be done */
+               prepare_write_message_footer(con, v);
+       }
+
+       set_bit(WRITE_PENDING, &con->state);
+}
+
+/*
+ * Prepare an ack.
+ */
+static void prepare_write_ack(struct ceph_connection *con)
+{
+       dout("prepare_write_ack %p %llu -> %llu\n", con,
+            con->in_seq_acked, con->in_seq);
+       con->in_seq_acked = con->in_seq;
+
+       con->out_kvec[0].iov_base = &tag_ack;
+       con->out_kvec[0].iov_len = 1;
+       con->out_temp_ack = cpu_to_le64(con->in_seq_acked);
+       con->out_kvec[1].iov_base = &con->out_temp_ack;
+       con->out_kvec[1].iov_len = sizeof(con->out_temp_ack);
+       con->out_kvec_left = 2;
+       con->out_kvec_bytes = 1 + sizeof(con->out_temp_ack);
+       con->out_kvec_cur = con->out_kvec;
+       con->out_more = 1;  /* more will follow.. eventually.. */
+       set_bit(WRITE_PENDING, &con->state);
+}
+
+/*
+ * Prepare to write keepalive byte.
+ */
+static void prepare_write_keepalive(struct ceph_connection *con)
+{
+       dout("prepare_write_keepalive %p\n", con);
+       con->out_kvec[0].iov_base = &tag_keepalive;
+       con->out_kvec[0].iov_len = 1;
+       con->out_kvec_left = 1;
+       con->out_kvec_bytes = 1;
+       con->out_kvec_cur = con->out_kvec;
+       set_bit(WRITE_PENDING, &con->state);
+}
+
+/*
+ * Connection negotiation.
+ */
+
+static void prepare_connect_authorizer(struct ceph_connection *con)
+{
+       void *auth_buf;
+       int auth_len = 0;
+       int auth_protocol = 0;
+
+       mutex_unlock(&con->mutex);
+       if (con->ops->get_authorizer)
+               con->ops->get_authorizer(con, &auth_buf, &auth_len,
+                                        &auth_protocol, &con->auth_reply_buf,
+                                        &con->auth_reply_buf_len,
+                                        con->auth_retry);
+       mutex_lock(&con->mutex);
+
+       con->out_connect.authorizer_protocol = cpu_to_le32(auth_protocol);
+       con->out_connect.authorizer_len = cpu_to_le32(auth_len);
+
+       con->out_kvec[con->out_kvec_left].iov_base = auth_buf;
+       con->out_kvec[con->out_kvec_left].iov_len = auth_len;
+       con->out_kvec_left++;
+       con->out_kvec_bytes += auth_len;
+}
+
+/*
+ * We connected to a peer and are saying hello.
+ */
+static void prepare_write_banner(struct ceph_messenger *msgr,
+                                struct ceph_connection *con)
+{
+       int len = strlen(CEPH_BANNER);
+
+       con->out_kvec[0].iov_base = CEPH_BANNER;
+       con->out_kvec[0].iov_len = len;
+       con->out_kvec[1].iov_base = &msgr->my_enc_addr;
+       con->out_kvec[1].iov_len = sizeof(msgr->my_enc_addr);
+       con->out_kvec_left = 2;
+       con->out_kvec_bytes = len + sizeof(msgr->my_enc_addr);
+       con->out_kvec_cur = con->out_kvec;
+       con->out_more = 0;
+       set_bit(WRITE_PENDING, &con->state);
+}
+
+static void prepare_write_connect(struct ceph_messenger *msgr,
+                                 struct ceph_connection *con,
+                                 int after_banner)
+{
+       unsigned global_seq = get_global_seq(con->msgr, 0);
+       int proto;
+
+       switch (con->peer_name.type) {
+       case CEPH_ENTITY_TYPE_MON:
+               proto = CEPH_MONC_PROTOCOL;
+               break;
+       case CEPH_ENTITY_TYPE_OSD:
+               proto = CEPH_OSDC_PROTOCOL;
+               break;
+       case CEPH_ENTITY_TYPE_MDS:
+               proto = CEPH_MDSC_PROTOCOL;
+               break;
+       default:
+               BUG();
+       }
+
+       dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con,
+            con->connect_seq, global_seq, proto);
+
+       con->out_connect.features = CEPH_FEATURE_SUPPORTED;
+       con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT);
+       con->out_connect.connect_seq = cpu_to_le32(con->connect_seq);
+       con->out_connect.global_seq = cpu_to_le32(global_seq);
+       con->out_connect.protocol_version = cpu_to_le32(proto);
+       con->out_connect.flags = 0;
+
+       if (!after_banner) {
+               con->out_kvec_left = 0;
+               con->out_kvec_bytes = 0;
+       }
+       con->out_kvec[con->out_kvec_left].iov_base = &con->out_connect;
+       con->out_kvec[con->out_kvec_left].iov_len = sizeof(con->out_connect);
+       con->out_kvec_left++;
+       con->out_kvec_bytes += sizeof(con->out_connect);
+       con->out_kvec_cur = con->out_kvec;
+       con->out_more = 0;
+       set_bit(WRITE_PENDING, &con->state);
+
+       prepare_connect_authorizer(con);
+}
+
+
+/*
+ * write as much of pending kvecs to the socket as we can.
+ *  1 -> done
+ *  0 -> socket full, but more to do
+ * <0 -> error
+ */
+static int write_partial_kvec(struct ceph_connection *con)
+{
+       int ret;
+
+       dout("write_partial_kvec %p %d left\n", con, con->out_kvec_bytes);
+       while (con->out_kvec_bytes > 0) {
+               ret = ceph_tcp_sendmsg(con->sock, con->out_kvec_cur,
+                                      con->out_kvec_left, con->out_kvec_bytes,
+                                      con->out_more);
+               if (ret <= 0)
+                       goto out;
+               con->out_kvec_bytes -= ret;
+               if (con->out_kvec_bytes == 0)
+                       break;            /* done */
+               while (ret > 0) {
+                       if (ret >= con->out_kvec_cur->iov_len) {
+                               ret -= con->out_kvec_cur->iov_len;
+                               con->out_kvec_cur++;
+                               con->out_kvec_left--;
+                       } else {
+                               con->out_kvec_cur->iov_len -= ret;
+                               con->out_kvec_cur->iov_base += ret;
+                               ret = 0;
+                               break;
+                       }
+               }
+       }
+       con->out_kvec_left = 0;
+       con->out_kvec_is_msg = false;
+       ret = 1;
+out:
+       dout("write_partial_kvec %p %d left in %d kvecs ret = %d\n", con,
+            con->out_kvec_bytes, con->out_kvec_left, ret);
+       return ret;  /* done! */
+}
+
+/*
+ * Write as much message data payload as we can.  If we finish, queue
+ * up the footer.
+ *  1 -> done, footer is now queued in out_kvec[].
+ *  0 -> socket full, but more to do
+ * <0 -> error
+ */
+static int write_partial_msg_pages(struct ceph_connection *con)
+{
+       struct ceph_msg *msg = con->out_msg;
+       unsigned data_len = le32_to_cpu(msg->hdr.data_len);
+       size_t len;
+       int crc = con->msgr->nocrc;
+       int ret;
+
+       dout("write_partial_msg_pages %p msg %p page %d/%d offset %d\n",
+            con, con->out_msg, con->out_msg_pos.page, con->out_msg->nr_pages,
+            con->out_msg_pos.page_pos);
+
+       while (con->out_msg_pos.page < con->out_msg->nr_pages) {
+               struct page *page = NULL;
+               void *kaddr = NULL;
+
+               /*
+                * if we are calculating the data crc (the default), we need
+                * to map the page.  if our pages[] has been revoked, use the
+                * zero page.
+                */
+               if (msg->pages) {
+                       page = msg->pages[con->out_msg_pos.page];
+                       if (crc)
+                               kaddr = kmap(page);
+               } else if (msg->pagelist) {
+                       page = list_first_entry(&msg->pagelist->head,
+                                               struct page, lru);
+                       if (crc)
+                               kaddr = kmap(page);
+               } else {
+                       page = con->msgr->zero_page;
+                       if (crc)
+                               kaddr = page_address(con->msgr->zero_page);
+               }
+               len = min((int)(PAGE_SIZE - con->out_msg_pos.page_pos),
+                         (int)(data_len - con->out_msg_pos.data_pos));
+               if (crc && !con->out_msg_pos.did_page_crc) {
+                       void *base = kaddr + con->out_msg_pos.page_pos;
+                       u32 tmpcrc = le32_to_cpu(con->out_msg->footer.data_crc);
+
+                       BUG_ON(kaddr == NULL);
+                       con->out_msg->footer.data_crc =
+                               cpu_to_le32(crc32c(tmpcrc, base, len));
+                       con->out_msg_pos.did_page_crc = 1;
+               }
+
+               ret = kernel_sendpage(con->sock, page,
+                                     con->out_msg_pos.page_pos, len,
+                                     MSG_DONTWAIT | MSG_NOSIGNAL |
+                                     MSG_MORE);
+
+               if (crc && (msg->pages || msg->pagelist))
+                       kunmap(page);
+
+               if (ret <= 0)
+                       goto out;
+
+               con->out_msg_pos.data_pos += ret;
+               con->out_msg_pos.page_pos += ret;
+               if (ret == len) {
+                       con->out_msg_pos.page_pos = 0;
+                       con->out_msg_pos.page++;
+                       con->out_msg_pos.did_page_crc = 0;
+                       if (msg->pagelist)
+                               list_move_tail(&page->lru,
+                                              &msg->pagelist->head);
+               }
+       }
+
+       dout("write_partial_msg_pages %p msg %p done\n", con, msg);
+
+       /* prepare and queue up footer, too */
+       if (!crc)
+               con->out_msg->footer.flags |= CEPH_MSG_FOOTER_NOCRC;
+       con->out_kvec_bytes = 0;
+       con->out_kvec_left = 0;
+       con->out_kvec_cur = con->out_kvec;
+       prepare_write_message_footer(con, 0);
+       ret = 1;
+out:
+       return ret;
+}
+
+/*
+ * write some zeros
+ */
+static int write_partial_skip(struct ceph_connection *con)
+{
+       int ret;
+
+       while (con->out_skip > 0) {
+               struct kvec iov = {
+                       .iov_base = page_address(con->msgr->zero_page),
+                       .iov_len = min(con->out_skip, (int)PAGE_CACHE_SIZE)
+               };
+
+               ret = ceph_tcp_sendmsg(con->sock, &iov, 1, iov.iov_len, 1);
+               if (ret <= 0)
+                       goto out;
+               con->out_skip -= ret;
+       }
+       ret = 1;
+out:
+       return ret;
+}
+
+/*
+ * Prepare to read connection handshake, or an ack.
+ */
+static void prepare_read_banner(struct ceph_connection *con)
+{
+       dout("prepare_read_banner %p\n", con);
+       con->in_base_pos = 0;
+}
+
+static void prepare_read_connect(struct ceph_connection *con)
+{
+       dout("prepare_read_connect %p\n", con);
+       con->in_base_pos = 0;
+}
+
+static void prepare_read_ack(struct ceph_connection *con)
+{
+       dout("prepare_read_ack %p\n", con);
+       con->in_base_pos = 0;
+}
+
+static void prepare_read_tag(struct ceph_connection *con)
+{
+       dout("prepare_read_tag %p\n", con);
+       con->in_base_pos = 0;
+       con->in_tag = CEPH_MSGR_TAG_READY;
+}
+
+/*
+ * Prepare to read a message.
+ */
+static int prepare_read_message(struct ceph_connection *con)
+{
+       dout("prepare_read_message %p\n", con);
+       BUG_ON(con->in_msg != NULL);
+       con->in_base_pos = 0;
+       con->in_front_crc = con->in_middle_crc = con->in_data_crc = 0;
+       return 0;
+}
+
+
+static int read_partial(struct ceph_connection *con,
+                       int *to, int size, void *object)
+{
+       *to += size;
+       while (con->in_base_pos < *to) {
+               int left = *to - con->in_base_pos;
+               int have = size - left;
+               int ret = ceph_tcp_recvmsg(con->sock, object + have, left);
+               if (ret <= 0)
+                       return ret;
+               con->in_base_pos += ret;
+       }
+       return 1;
+}
+
+
+/*
+ * Read all or part of the connect-side handshake on a new connection
+ */
+static int read_partial_banner(struct ceph_connection *con)
+{
+       int ret, to = 0;
+
+       dout("read_partial_banner %p at %d\n", con, con->in_base_pos);
+
+       /* peer's banner */
+       ret = read_partial(con, &to, strlen(CEPH_BANNER), con->in_banner);
+       if (ret <= 0)
+               goto out;
+       ret = read_partial(con, &to, sizeof(con->actual_peer_addr),
+                          &con->actual_peer_addr);
+       if (ret <= 0)
+               goto out;
+       ret = read_partial(con, &to, sizeof(con->peer_addr_for_me),
+                          &con->peer_addr_for_me);
+       if (ret <= 0)
+               goto out;
+out:
+       return ret;
+}
+
+static int read_partial_connect(struct ceph_connection *con)
+{
+       int ret, to = 0;
+
+       dout("read_partial_connect %p at %d\n", con, con->in_base_pos);
+
+       ret = read_partial(con, &to, sizeof(con->in_reply), &con->in_reply);
+       if (ret <= 0)
+               goto out;
+       ret = read_partial(con, &to, le32_to_cpu(con->in_reply.authorizer_len),
+                          con->auth_reply_buf);
+       if (ret <= 0)
+               goto out;
+
+       dout("read_partial_connect %p tag %d, con_seq = %u, g_seq = %u\n",
+            con, (int)con->in_reply.tag,
+            le32_to_cpu(con->in_reply.connect_seq),
+            le32_to_cpu(con->in_reply.global_seq));
+out:
+       return ret;
+
+}
+
+/*
+ * Verify the hello banner looks okay.
+ */
+static int verify_hello(struct ceph_connection *con)
+{
+       if (memcmp(con->in_banner, CEPH_BANNER, strlen(CEPH_BANNER))) {
+               pr_err("connect to %s got bad banner\n",
+                      pr_addr(&con->peer_addr.in_addr));
+               con->error_msg = "protocol error, bad banner";
+               return -1;
+       }
+       return 0;
+}
+
+static bool addr_is_blank(struct sockaddr_storage *ss)
+{
+       switch (ss->ss_family) {
+       case AF_INET:
+               return ((struct sockaddr_in *)ss)->sin_addr.s_addr == 0;
+       case AF_INET6:
+               return
+                    ((struct sockaddr_in6 *)ss)->sin6_addr.s6_addr32[0] == 0 &&
+                    ((struct sockaddr_in6 *)ss)->sin6_addr.s6_addr32[1] == 0 &&
+                    ((struct sockaddr_in6 *)ss)->sin6_addr.s6_addr32[2] == 0 &&
+                    ((struct sockaddr_in6 *)ss)->sin6_addr.s6_addr32[3] == 0;
+       }
+       return false;
+}
+
+static int addr_port(struct sockaddr_storage *ss)
+{
+       switch (ss->ss_family) {
+       case AF_INET:
+               return ntohs(((struct sockaddr_in *)ss)->sin_port);
+       case AF_INET6:
+               return ntohs(((struct sockaddr_in6 *)ss)->sin6_port);
+       }
+       return 0;
+}
+
+static void addr_set_port(struct sockaddr_storage *ss, int p)
+{
+       switch (ss->ss_family) {
+       case AF_INET:
+               ((struct sockaddr_in *)ss)->sin_port = htons(p);
+       case AF_INET6:
+               ((struct sockaddr_in6 *)ss)->sin6_port = htons(p);
+       }
+}
+
+/*
+ * Parse an ip[:port] list into an addr array.  Use the default
+ * monitor port if a port isn't specified.
+ */
+int ceph_parse_ips(const char *c, const char *end,
+                  struct ceph_entity_addr *addr,
+                  int max_count, int *count)
+{
+       int i;
+       const char *p = c;
+
+       dout("parse_ips on '%.*s'\n", (int)(end-c), c);
+       for (i = 0; i < max_count; i++) {
+               const char *ipend;
+               struct sockaddr_storage *ss = &addr[i].in_addr;
+               struct sockaddr_in *in4 = (void *)ss;
+               struct sockaddr_in6 *in6 = (void *)ss;
+               int port;
+
+               memset(ss, 0, sizeof(*ss));
+               if (in4_pton(p, end - p, (u8 *)&in4->sin_addr.s_addr,
+                            ',', &ipend)) {
+                       ss->ss_family = AF_INET;
+               } else if (in6_pton(p, end - p, (u8 *)&in6->sin6_addr.s6_addr,
+                                   ',', &ipend)) {
+                       ss->ss_family = AF_INET6;
+               } else {
+                       goto bad;
+               }
+               p = ipend;
+
+               /* port? */
+               if (p < end && *p == ':') {
+                       port = 0;
+                       p++;
+                       while (p < end && *p >= '0' && *p <= '9') {
+                               port = (port * 10) + (*p - '0');
+                               p++;
+                       }
+                       if (port > 65535 || port == 0)
+                               goto bad;
+               } else {
+                       port = CEPH_MON_PORT;
+               }
+
+               addr_set_port(ss, port);
+
+               dout("parse_ips got %s\n", pr_addr(ss));
+
+               if (p == end)
+                       break;
+               if (*p != ',')
+                       goto bad;
+               p++;
+       }
+
+       if (p != end)
+               goto bad;
+
+       if (count)
+               *count = i + 1;
+       return 0;
+
+bad:
+       pr_err("parse_ips bad ip '%s'\n", c);
+       return -EINVAL;
+}
+
+static int process_banner(struct ceph_connection *con)
+{
+       dout("process_banner on %p\n", con);
+
+       if (verify_hello(con) < 0)
+               return -1;
+
+       ceph_decode_addr(&con->actual_peer_addr);
+       ceph_decode_addr(&con->peer_addr_for_me);
+
+       /*
+        * Make sure the other end is who we wanted.  note that the other
+        * end may not yet know their ip address, so if it's 0.0.0.0, give
+        * them the benefit of the doubt.
+        */
+       if (memcmp(&con->peer_addr, &con->actual_peer_addr,
+                  sizeof(con->peer_addr)) != 0 &&
+           !(addr_is_blank(&con->actual_peer_addr.in_addr) &&
+             con->actual_peer_addr.nonce == con->peer_addr.nonce)) {
+               pr_warning("wrong peer, want %s/%lld, got %s/%lld\n",
+                          pr_addr(&con->peer_addr.in_addr),
+                          le64_to_cpu(con->peer_addr.nonce),
+                          pr_addr(&con->actual_peer_addr.in_addr),
+                          le64_to_cpu(con->actual_peer_addr.nonce));
+               con->error_msg = "wrong peer at address";
+               return -1;
+       }
+
+       /*
+        * did we learn our address?
+        */
+       if (addr_is_blank(&con->msgr->inst.addr.in_addr)) {
+               int port = addr_port(&con->msgr->inst.addr.in_addr);
+
+               memcpy(&con->msgr->inst.addr.in_addr,
+                      &con->peer_addr_for_me.in_addr,
+                      sizeof(con->peer_addr_for_me.in_addr));
+               addr_set_port(&con->msgr->inst.addr.in_addr, port);
+               encode_my_addr(con->msgr);
+               dout("process_banner learned my addr is %s\n",
+                    pr_addr(&con->msgr->inst.addr.in_addr));
+       }
+
+       set_bit(NEGOTIATING, &con->state);
+       prepare_read_connect(con);
+       return 0;
+}
+
+static void fail_protocol(struct ceph_connection *con)
+{
+       reset_connection(con);
+       set_bit(CLOSED, &con->state);  /* in case there's queued work */
+
+       mutex_unlock(&con->mutex);
+       if (con->ops->bad_proto)
+               con->ops->bad_proto(con);
+       mutex_lock(&con->mutex);
+}
+
+static int process_connect(struct ceph_connection *con)
+{
+       u64 sup_feat = CEPH_FEATURE_SUPPORTED;
+       u64 req_feat = CEPH_FEATURE_REQUIRED;
+       u64 server_feat = le64_to_cpu(con->in_reply.features);
+
+       dout("process_connect on %p tag %d\n", con, (int)con->in_tag);
+
+       switch (con->in_reply.tag) {
+       case CEPH_MSGR_TAG_FEATURES:
+               pr_err("%s%lld %s feature set mismatch,"
+                      " my %llx < server's %llx, missing %llx\n",
+                      ENTITY_NAME(con->peer_name),
+                      pr_addr(&con->peer_addr.in_addr),
+                      sup_feat, server_feat, server_feat & ~sup_feat);
+               con->error_msg = "missing required protocol features";
+               fail_protocol(con);
+               return -1;
+
+       case CEPH_MSGR_TAG_BADPROTOVER:
+               pr_err("%s%lld %s protocol version mismatch,"
+                      " my %d != server's %d\n",
+                      ENTITY_NAME(con->peer_name),
+                      pr_addr(&con->peer_addr.in_addr),
+                      le32_to_cpu(con->out_connect.protocol_version),
+                      le32_to_cpu(con->in_reply.protocol_version));
+               con->error_msg = "protocol version mismatch";
+               fail_protocol(con);
+               return -1;
+
+       case CEPH_MSGR_TAG_BADAUTHORIZER:
+               con->auth_retry++;
+               dout("process_connect %p got BADAUTHORIZER attempt %d\n", con,
+                    con->auth_retry);
+               if (con->auth_retry == 2) {
+                       con->error_msg = "connect authorization failure";
+                       reset_connection(con);
+                       set_bit(CLOSED, &con->state);
+                       return -1;
+               }
+               con->auth_retry = 1;
+               prepare_write_connect(con->msgr, con, 0);
+               prepare_read_connect(con);
+               break;
+
+       case CEPH_MSGR_TAG_RESETSESSION:
+               /*
+                * If we connected with a large connect_seq but the peer
+                * has no record of a session with us (no connection, or
+                * connect_seq == 0), they will send RESETSESION to indicate
+                * that they must have reset their session, and may have
+                * dropped messages.
+                */
+               dout("process_connect got RESET peer seq %u\n",
+                    le32_to_cpu(con->in_connect.connect_seq));
+               pr_err("%s%lld %s connection reset\n",
+                      ENTITY_NAME(con->peer_name),
+                      pr_addr(&con->peer_addr.in_addr));
+               reset_connection(con);
+               prepare_write_connect(con->msgr, con, 0);
+               prepare_read_connect(con);
+
+               /* Tell ceph about it. */
+               mutex_unlock(&con->mutex);
+               pr_info("reset on %s%lld\n", ENTITY_NAME(con->peer_name));
+               if (con->ops->peer_reset)
+                       con->ops->peer_reset(con);
+               mutex_lock(&con->mutex);
+               break;
+
+       case CEPH_MSGR_TAG_RETRY_SESSION:
+               /*
+                * If we sent a smaller connect_seq than the peer has, try
+                * again with a larger value.
+                */
+               dout("process_connect got RETRY my seq = %u, peer_seq = %u\n",
+                    le32_to_cpu(con->out_connect.connect_seq),
+                    le32_to_cpu(con->in_connect.connect_seq));
+               con->connect_seq = le32_to_cpu(con->in_connect.connect_seq);
+               prepare_write_connect(con->msgr, con, 0);
+               prepare_read_connect(con);
+               break;
+
+       case CEPH_MSGR_TAG_RETRY_GLOBAL:
+               /*
+                * If we sent a smaller global_seq than the peer has, try
+                * again with a larger value.
+                */
+               dout("process_connect got RETRY_GLOBAL my %u peer_gseq %u\n",
+                    con->peer_global_seq,
+                    le32_to_cpu(con->in_connect.global_seq));
+               get_global_seq(con->msgr,
+                              le32_to_cpu(con->in_connect.global_seq));
+               prepare_write_connect(con->msgr, con, 0);
+               prepare_read_connect(con);
+               break;
+
+       case CEPH_MSGR_TAG_READY:
+               if (req_feat & ~server_feat) {
+                       pr_err("%s%lld %s protocol feature mismatch,"
+                              " my required %llx > server's %llx, need %llx\n",
+                              ENTITY_NAME(con->peer_name),
+                              pr_addr(&con->peer_addr.in_addr),
+                              req_feat, server_feat, req_feat & ~server_feat);
+                       con->error_msg = "missing required protocol features";
+                       fail_protocol(con);
+                       return -1;
+               }
+               clear_bit(CONNECTING, &con->state);
+               con->peer_global_seq = le32_to_cpu(con->in_reply.global_seq);
+               con->connect_seq++;
+               dout("process_connect got READY gseq %d cseq %d (%d)\n",
+                    con->peer_global_seq,
+                    le32_to_cpu(con->in_reply.connect_seq),
+                    con->connect_seq);
+               WARN_ON(con->connect_seq !=
+                       le32_to_cpu(con->in_reply.connect_seq));
+
+               if (con->in_reply.flags & CEPH_MSG_CONNECT_LOSSY)
+                       set_bit(LOSSYTX, &con->state);
+
+               prepare_read_tag(con);
+               break;
+
+       case CEPH_MSGR_TAG_WAIT:
+               /*
+                * If there is a connection race (we are opening
+                * connections to each other), one of us may just have
+                * to WAIT.  This shouldn't happen if we are the
+                * client.
+                */
+               pr_err("process_connect peer connecting WAIT\n");
+
+       default:
+               pr_err("connect protocol error, will retry\n");
+               con->error_msg = "protocol error, garbage tag during connect";
+               return -1;
+       }
+       return 0;
+}
+
+
+/*
+ * read (part of) an ack
+ */
+static int read_partial_ack(struct ceph_connection *con)
+{
+       int to = 0;
+
+       return read_partial(con, &to, sizeof(con->in_temp_ack),
+                           &con->in_temp_ack);
+}
+
+
+/*
+ * We can finally discard anything that's been acked.
+ */
+static void process_ack(struct ceph_connection *con)
+{
+       struct ceph_msg *m;
+       u64 ack = le64_to_cpu(con->in_temp_ack);
+       u64 seq;
+
+       while (!list_empty(&con->out_sent)) {
+               m = list_first_entry(&con->out_sent, struct ceph_msg,
+                                    list_head);
+               seq = le64_to_cpu(m->hdr.seq);
+               if (seq > ack)
+                       break;
+               dout("got ack for seq %llu type %d at %p\n", seq,
+                    le16_to_cpu(m->hdr.type), m);
+               ceph_msg_remove(m);
+       }
+       prepare_read_tag(con);
+}
+
+
+
+
+static int read_partial_message_section(struct ceph_connection *con,
+                                       struct kvec *section, unsigned int sec_len,
+                                       u32 *crc)
+{
+       int left;
+       int ret;
+
+       BUG_ON(!section);
+
+       while (section->iov_len < sec_len) {
+               BUG_ON(section->iov_base == NULL);
+               left = sec_len - section->iov_len;
+               ret = ceph_tcp_recvmsg(con->sock, (char *)section->iov_base +
+                                      section->iov_len, left);
+               if (ret <= 0)
+                       return ret;
+               section->iov_len += ret;
+               if (section->iov_len == sec_len)
+                       *crc = crc32c(0, section->iov_base,
+                                     section->iov_len);
+       }
+
+       return 1;
+}
+
+static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con,
+                               struct ceph_msg_header *hdr,
+                               int *skip);
+/*
+ * read (part of) a message.
+ */
+static int read_partial_message(struct ceph_connection *con)
+{
+       struct ceph_msg *m = con->in_msg;
+       void *p;
+       int ret;
+       int to, left;
+       unsigned front_len, middle_len, data_len, data_off;
+       int datacrc = con->msgr->nocrc;
+       int skip;
+       u64 seq;
+
+       dout("read_partial_message con %p msg %p\n", con, m);
+
+       /* header */
+       while (con->in_base_pos < sizeof(con->in_hdr)) {
+               left = sizeof(con->in_hdr) - con->in_base_pos;
+               ret = ceph_tcp_recvmsg(con->sock,
+                                      (char *)&con->in_hdr + con->in_base_pos,
+                                      left);
+               if (ret <= 0)
+                       return ret;
+               con->in_base_pos += ret;
+               if (con->in_base_pos == sizeof(con->in_hdr)) {
+                       u32 crc = crc32c(0, (void *)&con->in_hdr,
+                                sizeof(con->in_hdr) - sizeof(con->in_hdr.crc));
+                       if (crc != le32_to_cpu(con->in_hdr.crc)) {
+                               pr_err("read_partial_message bad hdr "
+                                      " crc %u != expected %u\n",
+                                      crc, con->in_hdr.crc);
+                               return -EBADMSG;
+                       }
+               }
+       }
+       front_len = le32_to_cpu(con->in_hdr.front_len);
+       if (front_len > CEPH_MSG_MAX_FRONT_LEN)
+               return -EIO;
+       middle_len = le32_to_cpu(con->in_hdr.middle_len);
+       if (middle_len > CEPH_MSG_MAX_DATA_LEN)
+               return -EIO;
+       data_len = le32_to_cpu(con->in_hdr.data_len);
+       if (data_len > CEPH_MSG_MAX_DATA_LEN)
+               return -EIO;
+       data_off = le16_to_cpu(con->in_hdr.data_off);
+
+       /* verify seq# */
+       seq = le64_to_cpu(con->in_hdr.seq);
+       if ((s64)seq - (s64)con->in_seq < 1) {
+               pr_info("skipping %s%lld %s seq %lld, expected %lld\n",
+                       ENTITY_NAME(con->peer_name),
+                       pr_addr(&con->peer_addr.in_addr),
+                       seq, con->in_seq + 1);
+               con->in_base_pos = -front_len - middle_len - data_len -
+                       sizeof(m->footer);
+               con->in_tag = CEPH_MSGR_TAG_READY;
+               con->in_seq++;
+               return 0;
+       } else if ((s64)seq - (s64)con->in_seq > 1) {
+               pr_err("read_partial_message bad seq %lld expected %lld\n",
+                      seq, con->in_seq + 1);
+               con->error_msg = "bad message sequence # for incoming message";
+               return -EBADMSG;
+       }
+
+       /* allocate message? */
+       if (!con->in_msg) {
+               dout("got hdr type %d front %d data %d\n", con->in_hdr.type,
+                    con->in_hdr.front_len, con->in_hdr.data_len);
+               con->in_msg = ceph_alloc_msg(con, &con->in_hdr, &skip);
+               if (skip) {
+                       /* skip this message */
+                       dout("alloc_msg returned NULL, skipping message\n");
+                       con->in_base_pos = -front_len - middle_len - data_len -
+                               sizeof(m->footer);
+                       con->in_tag = CEPH_MSGR_TAG_READY;
+                       con->in_seq++;
+                       return 0;
+               }
+               if (IS_ERR(con->in_msg)) {
+                       ret = PTR_ERR(con->in_msg);
+                       con->in_msg = NULL;
+                       con->error_msg =
+                               "error allocating memory for incoming message";
+                       return ret;
+               }
+               m = con->in_msg;
+               m->front.iov_len = 0;    /* haven't read it yet */
+               if (m->middle)
+                       m->middle->vec.iov_len = 0;
+
+               con->in_msg_pos.page = 0;
+               con->in_msg_pos.page_pos = data_off & ~PAGE_MASK;
+               con->in_msg_pos.data_pos = 0;
+       }
+
+       /* front */
+       ret = read_partial_message_section(con, &m->front, front_len,
+                                          &con->in_front_crc);
+       if (ret <= 0)
+               return ret;
+
+       /* middle */
+       if (m->middle) {
+               ret = read_partial_message_section(con, &m->middle->vec, middle_len,
+                                                  &con->in_middle_crc);
+               if (ret <= 0)
+                       return ret;
+       }
+
+       /* (page) data */
+       while (con->in_msg_pos.data_pos < data_len) {
+               left = min((int)(data_len - con->in_msg_pos.data_pos),
+                          (int)(PAGE_SIZE - con->in_msg_pos.page_pos));
+               BUG_ON(m->pages == NULL);
+               p = kmap(m->pages[con->in_msg_pos.page]);
+               ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos,
+                                      left);
+               if (ret > 0 && datacrc)
+                       con->in_data_crc =
+                               crc32c(con->in_data_crc,
+                                         p + con->in_msg_pos.page_pos, ret);
+               kunmap(m->pages[con->in_msg_pos.page]);
+               if (ret <= 0)
+                       return ret;
+               con->in_msg_pos.data_pos += ret;
+               con->in_msg_pos.page_pos += ret;
+               if (con->in_msg_pos.page_pos == PAGE_SIZE) {
+                       con->in_msg_pos.page_pos = 0;
+                       con->in_msg_pos.page++;
+               }
+       }
+
+       /* footer */
+       to = sizeof(m->hdr) + sizeof(m->footer);
+       while (con->in_base_pos < to) {
+               left = to - con->in_base_pos;
+               ret = ceph_tcp_recvmsg(con->sock, (char *)&m->footer +
+                                      (con->in_base_pos - sizeof(m->hdr)),
+                                      left);
+               if (ret <= 0)
+                       return ret;
+               con->in_base_pos += ret;
+       }
+       dout("read_partial_message got msg %p %d (%u) + %d (%u) + %d (%u)\n",
+            m, front_len, m->footer.front_crc, middle_len,
+            m->footer.middle_crc, data_len, m->footer.data_crc);
+
+       /* crc ok? */
+       if (con->in_front_crc != le32_to_cpu(m->footer.front_crc)) {
+               pr_err("read_partial_message %p front crc %u != exp. %u\n",
+                      m, con->in_front_crc, m->footer.front_crc);
+               return -EBADMSG;
+       }
+       if (con->in_middle_crc != le32_to_cpu(m->footer.middle_crc)) {
+               pr_err("read_partial_message %p middle crc %u != exp %u\n",
+                      m, con->in_middle_crc, m->footer.middle_crc);
+               return -EBADMSG;
+       }
+       if (datacrc &&
+           (m->footer.flags & CEPH_MSG_FOOTER_NOCRC) == 0 &&
+           con->in_data_crc != le32_to_cpu(m->footer.data_crc)) {
+               pr_err("read_partial_message %p data crc %u != exp. %u\n", m,
+                      con->in_data_crc, le32_to_cpu(m->footer.data_crc));
+               return -EBADMSG;
+       }
+
+       return 1; /* done! */
+}
+
+/*
+ * Process message.  This happens in the worker thread.  The callback should
+ * be careful not to do anything that waits on other incoming messages or it
+ * may deadlock.
+ */
+static void process_message(struct ceph_connection *con)
+{
+       struct ceph_msg *msg;
+
+       msg = con->in_msg;
+       con->in_msg = NULL;
+
+       /* if first message, set peer_name */
+       if (con->peer_name.type == 0)
+               con->peer_name = msg->hdr.src.name;
+
+       con->in_seq++;
+       mutex_unlock(&con->mutex);
+
+       dout("===== %p %llu from %s%lld %d=%s len %d+%d (%u %u %u) =====\n",
+            msg, le64_to_cpu(msg->hdr.seq),
+            ENTITY_NAME(msg->hdr.src.name),
+            le16_to_cpu(msg->hdr.type),
+            ceph_msg_type_name(le16_to_cpu(msg->hdr.type)),
+            le32_to_cpu(msg->hdr.front_len),
+            le32_to_cpu(msg->hdr.data_len),
+            con->in_front_crc, con->in_middle_crc, con->in_data_crc);
+       con->ops->dispatch(con, msg);
+
+       mutex_lock(&con->mutex);
+       prepare_read_tag(con);
+}
+
+
+/*
+ * Write something to the socket.  Called in a worker thread when the
+ * socket appears to be writeable and we have something ready to send.
+ */
+static int try_write(struct ceph_connection *con)
+{
+       struct ceph_messenger *msgr = con->msgr;
+       int ret = 1;
+
+       dout("try_write start %p state %lu nref %d\n", con, con->state,
+            atomic_read(&con->nref));
+
+       mutex_lock(&con->mutex);
+more:
+       dout("try_write out_kvec_bytes %d\n", con->out_kvec_bytes);
+
+       /* open the socket first? */
+       if (con->sock == NULL) {
+               /*
+                * if we were STANDBY and are reconnecting _this_
+                * connection, bump connect_seq now.  Always bump
+                * global_seq.
+                */
+               if (test_and_clear_bit(STANDBY, &con->state))
+                       con->connect_seq++;
+
+               prepare_write_banner(msgr, con);
+               prepare_write_connect(msgr, con, 1);
+               prepare_read_banner(con);
+               set_bit(CONNECTING, &con->state);
+               clear_bit(NEGOTIATING, &con->state);
+
+               BUG_ON(con->in_msg);
+               con->in_tag = CEPH_MSGR_TAG_READY;
+               dout("try_write initiating connect on %p new state %lu\n",
+                    con, con->state);
+               con->sock = ceph_tcp_connect(con);
+               if (IS_ERR(con->sock)) {
+                       con->sock = NULL;
+                       con->error_msg = "connect error";
+                       ret = -1;
+                       goto out;
+               }
+       }
+
+more_kvec:
+       /* kvec data queued? */
+       if (con->out_skip) {
+               ret = write_partial_skip(con);
+               if (ret <= 0)
+                       goto done;
+               if (ret < 0) {
+                       dout("try_write write_partial_skip err %d\n", ret);
+                       goto done;
+               }
+       }
+       if (con->out_kvec_left) {
+               ret = write_partial_kvec(con);
+               if (ret <= 0)
+                       goto done;
+       }
+
+       /* msg pages? */
+       if (con->out_msg) {
+               if (con->out_msg_done) {
+                       ceph_msg_put(con->out_msg);
+                       con->out_msg = NULL;   /* we're done with this one */
+                       goto do_next;
+               }
+
+               ret = write_partial_msg_pages(con);
+               if (ret == 1)
+                       goto more_kvec;  /* we need to send the footer, too! */
+               if (ret == 0)
+                       goto done;
+               if (ret < 0) {
+                       dout("try_write write_partial_msg_pages err %d\n",
+                            ret);
+                       goto done;
+               }
+       }
+
+do_next:
+       if (!test_bit(CONNECTING, &con->state)) {
+               /* is anything else pending? */
+               if (!list_empty(&con->out_queue)) {
+                       prepare_write_message(con);
+                       goto more;
+               }
+               if (con->in_seq > con->in_seq_acked) {
+                       prepare_write_ack(con);
+                       goto more;
+               }
+               if (test_and_clear_bit(KEEPALIVE_PENDING, &con->state)) {
+                       prepare_write_keepalive(con);
+                       goto more;
+               }
+       }
+
+       /* Nothing to do! */
+       clear_bit(WRITE_PENDING, &con->state);
+       dout("try_write nothing else to write.\n");
+done:
+       ret = 0;
+out:
+       mutex_unlock(&con->mutex);
+       dout("try_write done on %p\n", con);
+       return ret;
+}
+
+
+
+/*
+ * Read what we can from the socket.
+ */
+static int try_read(struct ceph_connection *con)
+{
+       struct ceph_messenger *msgr;
+       int ret = -1;
+
+       if (!con->sock)
+               return 0;
+
+       if (test_bit(STANDBY, &con->state))
+               return 0;
+
+       dout("try_read start on %p\n", con);
+       msgr = con->msgr;
+
+       mutex_lock(&con->mutex);
+
+more:
+       dout("try_read tag %d in_base_pos %d\n", (int)con->in_tag,
+            con->in_base_pos);
+       if (test_bit(CONNECTING, &con->state)) {
+               if (!test_bit(NEGOTIATING, &con->state)) {
+                       dout("try_read connecting\n");
+                       ret = read_partial_banner(con);
+                       if (ret <= 0)
+                               goto done;
+                       if (process_banner(con) < 0) {
+                               ret = -1;
+                               goto out;
+                       }
+               }
+               ret = read_partial_connect(con);
+               if (ret <= 0)
+                       goto done;
+               if (process_connect(con) < 0) {
+                       ret = -1;
+                       goto out;
+               }
+               goto more;
+       }
+
+       if (con->in_base_pos < 0) {
+               /*
+                * skipping + discarding content.
+                *
+                * FIXME: there must be a better way to do this!
+                */
+               static char buf[1024];
+               int skip = min(1024, -con->in_base_pos);
+               dout("skipping %d / %d bytes\n", skip, -con->in_base_pos);
+               ret = ceph_tcp_recvmsg(con->sock, buf, skip);
+               if (ret <= 0)
+                       goto done;
+               con->in_base_pos += ret;
+               if (con->in_base_pos)
+                       goto more;
+       }
+       if (con->in_tag == CEPH_MSGR_TAG_READY) {
+               /*
+                * what's next?
+                */
+               ret = ceph_tcp_recvmsg(con->sock, &con->in_tag, 1);
+               if (ret <= 0)
+                       goto done;
+               dout("try_read got tag %d\n", (int)con->in_tag);
+               switch (con->in_tag) {
+               case CEPH_MSGR_TAG_MSG:
+                       prepare_read_message(con);
+                       break;
+               case CEPH_MSGR_TAG_ACK:
+                       prepare_read_ack(con);
+                       break;
+               case CEPH_MSGR_TAG_CLOSE:
+                       set_bit(CLOSED, &con->state);   /* fixme */
+                       goto done;
+               default:
+                       goto bad_tag;
+               }
+       }
+       if (con->in_tag == CEPH_MSGR_TAG_MSG) {
+               ret = read_partial_message(con);
+               if (ret <= 0) {
+                       switch (ret) {
+                       case -EBADMSG:
+                               con->error_msg = "bad crc";
+                               ret = -EIO;
+                               goto out;
+                       case -EIO:
+                               con->error_msg = "io error";
+                               goto out;
+                       default:
+                               goto done;
+                       }
+               }
+               if (con->in_tag == CEPH_MSGR_TAG_READY)
+                       goto more;
+               process_message(con);
+               goto more;
+       }
+       if (con->in_tag == CEPH_MSGR_TAG_ACK) {
+               ret = read_partial_ack(con);
+               if (ret <= 0)
+                       goto done;
+               process_ack(con);
+               goto more;
+       }
+
+done:
+       ret = 0;
+out:
+       mutex_unlock(&con->mutex);
+       dout("try_read done on %p\n", con);
+       return ret;
+
+bad_tag:
+       pr_err("try_read bad con->in_tag = %d\n", (int)con->in_tag);
+       con->error_msg = "protocol error, garbage tag";
+       ret = -1;
+       goto out;
+}
+
+
+/*
+ * Atomically queue work on a connection.  Bump @con reference to
+ * avoid races with connection teardown.
+ *
+ * There is some trickery going on with QUEUED and BUSY because we
+ * only want a _single_ thread operating on each connection at any
+ * point in time, but we want to use all available CPUs.
+ *
+ * The worker thread only proceeds if it can atomically set BUSY.  It
+ * clears QUEUED and does it's thing.  When it thinks it's done, it
+ * clears BUSY, then rechecks QUEUED.. if it's set again, it loops
+ * (tries again to set BUSY).
+ *
+ * To queue work, we first set QUEUED, _then_ if BUSY isn't set, we
+ * try to queue work.  If that fails (work is already queued, or BUSY)
+ * we give up (work also already being done or is queued) but leave QUEUED
+ * set so that the worker thread will loop if necessary.
+ */
+static void queue_con(struct ceph_connection *con)
+{
+       if (test_bit(DEAD, &con->state)) {
+               dout("queue_con %p ignoring: DEAD\n",
+                    con);
+               return;
+       }
+
+       if (!con->ops->get(con)) {
+               dout("queue_con %p ref count 0\n", con);
+               return;
+       }
+
+       set_bit(QUEUED, &con->state);
+       if (test_bit(BUSY, &con->state)) {
+               dout("queue_con %p - already BUSY\n", con);
+               con->ops->put(con);
+       } else if (!queue_work(ceph_msgr_wq, &con->work.work)) {
+               dout("queue_con %p - already queued\n", con);
+               con->ops->put(con);
+       } else {
+               dout("queue_con %p\n", con);
+       }
+}
+
+/*
+ * Do some work on a connection.  Drop a connection ref when we're done.
+ */
+static void con_work(struct work_struct *work)
+{
+       struct ceph_connection *con = container_of(work, struct ceph_connection,
+                                                  work.work);
+       int backoff = 0;
+
+more:
+       if (test_and_set_bit(BUSY, &con->state) != 0) {
+               dout("con_work %p BUSY already set\n", con);
+               goto out;
+       }
+       dout("con_work %p start, clearing QUEUED\n", con);
+       clear_bit(QUEUED, &con->state);
+
+       if (test_bit(CLOSED, &con->state)) { /* e.g. if we are replaced */
+               dout("con_work CLOSED\n");
+               con_close_socket(con);
+               goto done;
+       }
+       if (test_and_clear_bit(OPENING, &con->state)) {
+               /* reopen w/ new peer */
+               dout("con_work OPENING\n");
+               con_close_socket(con);
+       }
+
+       if (test_and_clear_bit(SOCK_CLOSED, &con->state) ||
+           try_read(con) < 0 ||
+           try_write(con) < 0) {
+               backoff = 1;
+               ceph_fault(con);     /* error/fault path */
+       }
+
+done:
+       clear_bit(BUSY, &con->state);
+       dout("con->state=%lu\n", con->state);
+       if (test_bit(QUEUED, &con->state)) {
+               if (!backoff || test_bit(OPENING, &con->state)) {
+                       dout("con_work %p QUEUED reset, looping\n", con);
+                       goto more;
+               }
+               dout("con_work %p QUEUED reset, but just faulted\n", con);
+               clear_bit(QUEUED, &con->state);
+       }
+       dout("con_work %p done\n", con);
+
+out:
+       con->ops->put(con);
+}
+
+
+/*
+ * Generic error/fault handler.  A retry mechanism is used with
+ * exponential backoff
+ */
+static void ceph_fault(struct ceph_connection *con)
+{
+       pr_err("%s%lld %s %s\n", ENTITY_NAME(con->peer_name),
+              pr_addr(&con->peer_addr.in_addr), con->error_msg);
+       dout("fault %p state %lu to peer %s\n",
+            con, con->state, pr_addr(&con->peer_addr.in_addr));
+
+       if (test_bit(LOSSYTX, &con->state)) {
+               dout("fault on LOSSYTX channel\n");
+               goto out;
+       }
+
+       mutex_lock(&con->mutex);
+       if (test_bit(CLOSED, &con->state))
+               goto out_unlock;
+
+       con_close_socket(con);
+
+       if (con->in_msg) {
+               ceph_msg_put(con->in_msg);
+               con->in_msg = NULL;
+       }
+
+       /* Requeue anything that hasn't been acked */
+       list_splice_init(&con->out_sent, &con->out_queue);
+
+       /* If there are no messages in the queue, place the connection
+        * in a STANDBY state (i.e., don't try to reconnect just yet). */
+       if (list_empty(&con->out_queue) && !con->out_keepalive_pending) {
+               dout("fault setting STANDBY\n");
+               set_bit(STANDBY, &con->state);
+       } else {
+               /* retry after a delay. */
+               if (con->delay == 0)
+                       con->delay = BASE_DELAY_INTERVAL;
+               else if (con->delay < MAX_DELAY_INTERVAL)
+                       con->delay *= 2;
+               dout("fault queueing %p delay %lu\n", con, con->delay);
+               con->ops->get(con);
+               if (queue_delayed_work(ceph_msgr_wq, &con->work,
+                                      round_jiffies_relative(con->delay)) == 0)
+                       con->ops->put(con);
+       }
+
+out_unlock:
+       mutex_unlock(&con->mutex);
+out:
+       /*
+        * in case we faulted due to authentication, invalidate our
+        * current tickets so that we can get new ones.
+         */
+       if (con->auth_retry && con->ops->invalidate_authorizer) {
+               dout("calling invalidate_authorizer()\n");
+               con->ops->invalidate_authorizer(con);
+       }
+
+       if (con->ops->fault)
+               con->ops->fault(con);
+}
+
+
+
+/*
+ * create a new messenger instance
+ */
+struct ceph_messenger *ceph_messenger_create(struct ceph_entity_addr *myaddr)
+{
+       struct ceph_messenger *msgr;
+
+       msgr = kzalloc(sizeof(*msgr), GFP_KERNEL);
+       if (msgr == NULL)
+               return ERR_PTR(-ENOMEM);
+
+       spin_lock_init(&msgr->global_seq_lock);
+
+       /* the zero page is needed if a request is "canceled" while the message
+        * is being written over the socket */
+       msgr->zero_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+       if (!msgr->zero_page) {
+               kfree(msgr);
+               return ERR_PTR(-ENOMEM);
+       }
+       kmap(msgr->zero_page);
+
+       if (myaddr)
+               msgr->inst.addr = *myaddr;
+
+       /* select a random nonce */
+       msgr->inst.addr.type = 0;
+       get_random_bytes(&msgr->inst.addr.nonce, sizeof(msgr->inst.addr.nonce));
+       encode_my_addr(msgr);
+
+       dout("messenger_create %p\n", msgr);
+       return msgr;
+}
+
+void ceph_messenger_destroy(struct ceph_messenger *msgr)
+{
+       dout("destroy %p\n", msgr);
+       kunmap(msgr->zero_page);
+       __free_page(msgr->zero_page);
+       kfree(msgr);
+       dout("destroyed messenger %p\n", msgr);
+}
+
+/*
+ * Queue up an outgoing message on the given connection.
+ */
+void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg)
+{
+       if (test_bit(CLOSED, &con->state)) {
+               dout("con_send %p closed, dropping %p\n", con, msg);
+               ceph_msg_put(msg);
+               return;
+       }
+
+       /* set src+dst */
+       msg->hdr.src.name = con->msgr->inst.name;
+       msg->hdr.src.addr = con->msgr->my_enc_addr;
+       msg->hdr.orig_src = msg->hdr.src;
+
+       BUG_ON(msg->front.iov_len != le32_to_cpu(msg->hdr.front_len));
+
+       msg->needs_out_seq = true;
+
+       /* queue */
+       mutex_lock(&con->mutex);
+       BUG_ON(!list_empty(&msg->list_head));
+       list_add_tail(&msg->list_head, &con->out_queue);
+       dout("----- %p to %s%lld %d=%s len %d+%d+%d -----\n", msg,
+            ENTITY_NAME(con->peer_name), le16_to_cpu(msg->hdr.type),
+            ceph_msg_type_name(le16_to_cpu(msg->hdr.type)),
+            le32_to_cpu(msg->hdr.front_len),
+            le32_to_cpu(msg->hdr.middle_len),
+            le32_to_cpu(msg->hdr.data_len));
+       mutex_unlock(&con->mutex);
+
+       /* if there wasn't anything waiting to send before, queue
+        * new work */
+       if (test_and_set_bit(WRITE_PENDING, &con->state) == 0)
+               queue_con(con);
+}
+
+/*
+ * Revoke a message that was previously queued for send
+ */
+void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg)
+{
+       mutex_lock(&con->mutex);
+       if (!list_empty(&msg->list_head)) {
+               dout("con_revoke %p msg %p\n", con, msg);
+               list_del_init(&msg->list_head);
+               ceph_msg_put(msg);
+               msg->hdr.seq = 0;
+               if (con->out_msg == msg) {
+                       ceph_msg_put(con->out_msg);
+                       con->out_msg = NULL;
+               }
+               if (con->out_kvec_is_msg) {
+                       con->out_skip = con->out_kvec_bytes;
+                       con->out_kvec_is_msg = false;
+               }
+       } else {
+               dout("con_revoke %p msg %p - not queued (sent?)\n", con, msg);
+       }
+       mutex_unlock(&con->mutex);
+}
+
+/*
+ * Revoke a message that we may be reading data into
+ */
+void ceph_con_revoke_message(struct ceph_connection *con, struct ceph_msg *msg)
+{
+       mutex_lock(&con->mutex);
+       if (con->in_msg && con->in_msg == msg) {
+               unsigned front_len = le32_to_cpu(con->in_hdr.front_len);
+               unsigned middle_len = le32_to_cpu(con->in_hdr.middle_len);
+               unsigned data_len = le32_to_cpu(con->in_hdr.data_len);
+
+               /* skip rest of message */
+               dout("con_revoke_pages %p msg %p revoked\n", con, msg);
+                       con->in_base_pos = con->in_base_pos -
+                               sizeof(struct ceph_msg_header) -
+                               front_len -
+                               middle_len -
+                               data_len -
+                               sizeof(struct ceph_msg_footer);
+               ceph_msg_put(con->in_msg);
+               con->in_msg = NULL;
+               con->in_tag = CEPH_MSGR_TAG_READY;
+               con->in_seq++;
+       } else {
+               dout("con_revoke_pages %p msg %p pages %p no-op\n",
+                    con, con->in_msg, msg);
+       }
+       mutex_unlock(&con->mutex);
+}
+
+/*
+ * Queue a keepalive byte to ensure the tcp connection is alive.
+ */
+void ceph_con_keepalive(struct ceph_connection *con)
+{
+       if (test_and_set_bit(KEEPALIVE_PENDING, &con->state) == 0 &&
+           test_and_set_bit(WRITE_PENDING, &con->state) == 0)
+               queue_con(con);
+}
+
+
+/*
+ * construct a new message with given type, size
+ * the new msg has a ref count of 1.
+ */
+struct ceph_msg *ceph_msg_new(int type, int front_len,
+                             int page_len, int page_off, struct page **pages)
+{
+       struct ceph_msg *m;
+
+       m = kmalloc(sizeof(*m), GFP_NOFS);
+       if (m == NULL)
+               goto out;
+       kref_init(&m->kref);
+       INIT_LIST_HEAD(&m->list_head);
+
+       m->hdr.tid = 0;
+       m->hdr.type = cpu_to_le16(type);
+       m->hdr.priority = cpu_to_le16(CEPH_MSG_PRIO_DEFAULT);
+       m->hdr.version = 0;
+       m->hdr.front_len = cpu_to_le32(front_len);
+       m->hdr.middle_len = 0;
+       m->hdr.data_len = cpu_to_le32(page_len);
+       m->hdr.data_off = cpu_to_le16(page_off);
+       m->hdr.reserved = 0;
+       m->footer.front_crc = 0;
+       m->footer.middle_crc = 0;
+       m->footer.data_crc = 0;
+       m->footer.flags = 0;
+       m->front_max = front_len;
+       m->front_is_vmalloc = false;
+       m->more_to_follow = false;
+       m->pool = NULL;
+
+       /* front */
+       if (front_len) {
+               if (front_len > PAGE_CACHE_SIZE) {
+                       m->front.iov_base = __vmalloc(front_len, GFP_NOFS,
+                                                     PAGE_KERNEL);
+                       m->front_is_vmalloc = true;
+               } else {
+                       m->front.iov_base = kmalloc(front_len, GFP_NOFS);
+               }
+               if (m->front.iov_base == NULL) {
+                       pr_err("msg_new can't allocate %d bytes\n",
+                            front_len);
+                       goto out2;
+               }
+       } else {
+               m->front.iov_base = NULL;
+       }
+       m->front.iov_len = front_len;
+
+       /* middle */
+       m->middle = NULL;
+
+       /* data */
+       m->nr_pages = calc_pages_for(page_off, page_len);
+       m->pages = pages;
+       m->pagelist = NULL;
+
+       dout("ceph_msg_new %p page %d~%d -> %d\n", m, page_off, page_len,
+            m->nr_pages);
+       return m;
+
+out2:
+       ceph_msg_put(m);
+out:
+       pr_err("msg_new can't create type %d len %d\n", type, front_len);
+       return ERR_PTR(-ENOMEM);
+}
+
+/*
+ * Allocate "middle" portion of a message, if it is needed and wasn't
+ * allocated by alloc_msg.  This allows us to read a small fixed-size
+ * per-type header in the front and then gracefully fail (i.e.,
+ * propagate the error to the caller based on info in the front) when
+ * the middle is too large.
+ */
+static int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg)
+{
+       int type = le16_to_cpu(msg->hdr.type);
+       int middle_len = le32_to_cpu(msg->hdr.middle_len);
+
+       dout("alloc_middle %p type %d %s middle_len %d\n", msg, type,
+            ceph_msg_type_name(type), middle_len);
+       BUG_ON(!middle_len);
+       BUG_ON(msg->middle);
+
+       msg->middle = ceph_buffer_new(middle_len, GFP_NOFS);
+       if (!msg->middle)
+               return -ENOMEM;
+       return 0;
+}
+
+/*
+ * Generic message allocator, for incoming messages.
+ */
+static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con,
+                               struct ceph_msg_header *hdr,
+                               int *skip)
+{
+       int type = le16_to_cpu(hdr->type);
+       int front_len = le32_to_cpu(hdr->front_len);
+       int middle_len = le32_to_cpu(hdr->middle_len);
+       struct ceph_msg *msg = NULL;
+       int ret;
+
+       if (con->ops->alloc_msg) {
+               mutex_unlock(&con->mutex);
+               msg = con->ops->alloc_msg(con, hdr, skip);
+               mutex_lock(&con->mutex);
+               if (IS_ERR(msg))
+                       return msg;
+
+               if (*skip)
+                       return NULL;
+       }
+       if (!msg) {
+               *skip = 0;
+               msg = ceph_msg_new(type, front_len, 0, 0, NULL);
+               if (!msg) {
+                       pr_err("unable to allocate msg type %d len %d\n",
+                              type, front_len);
+                       return ERR_PTR(-ENOMEM);
+               }
+       }
+       memcpy(&msg->hdr, &con->in_hdr, sizeof(con->in_hdr));
+
+       if (middle_len) {
+               ret = ceph_alloc_middle(con, msg);
+
+               if (ret < 0) {
+                       ceph_msg_put(msg);
+                       return msg;
+               }
+       }
+
+       return msg;
+}
+
+
+/*
+ * Free a generically kmalloc'd message.
+ */
+void ceph_msg_kfree(struct ceph_msg *m)
+{
+       dout("msg_kfree %p\n", m);
+       if (m->front_is_vmalloc)
+               vfree(m->front.iov_base);
+       else
+               kfree(m->front.iov_base);
+       kfree(m);
+}
+
+/*
+ * Drop a msg ref.  Destroy as needed.
+ */
+void ceph_msg_last_put(struct kref *kref)
+{
+       struct ceph_msg *m = container_of(kref, struct ceph_msg, kref);
+
+       dout("ceph_msg_put last one on %p\n", m);
+       WARN_ON(!list_empty(&m->list_head));
+
+       /* drop middle, data, if any */
+       if (m->middle) {
+               ceph_buffer_put(m->middle);
+               m->middle = NULL;
+       }
+       m->nr_pages = 0;
+       m->pages = NULL;
+
+       if (m->pagelist) {
+               ceph_pagelist_release(m->pagelist);
+               kfree(m->pagelist);
+               m->pagelist = NULL;
+       }
+
+       if (m->pool)
+               ceph_msgpool_put(m->pool, m);
+       else
+               ceph_msg_kfree(m);
+}
+
+void ceph_msg_dump(struct ceph_msg *msg)
+{
+       pr_debug("msg_dump %p (front_max %d nr_pages %d)\n", msg,
+                msg->front_max, msg->nr_pages);
+       print_hex_dump(KERN_DEBUG, "header: ",
+                      DUMP_PREFIX_OFFSET, 16, 1,
+                      &msg->hdr, sizeof(msg->hdr), true);
+       print_hex_dump(KERN_DEBUG, " front: ",
+                      DUMP_PREFIX_OFFSET, 16, 1,
+                      msg->front.iov_base, msg->front.iov_len, true);
+       if (msg->middle)
+               print_hex_dump(KERN_DEBUG, "middle: ",
+                              DUMP_PREFIX_OFFSET, 16, 1,
+                              msg->middle->vec.iov_base,
+                              msg->middle->vec.iov_len, true);
+       print_hex_dump(KERN_DEBUG, "footer: ",
+                      DUMP_PREFIX_OFFSET, 16, 1,
+                      &msg->footer, sizeof(msg->footer), true);
+}
diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h
new file mode 100644 (file)
index 0000000..a5caf91
--- /dev/null
@@ -0,0 +1,256 @@
+#ifndef __FS_CEPH_MESSENGER_H
+#define __FS_CEPH_MESSENGER_H
+
+#include <linux/kref.h>
+#include <linux/mutex.h>
+#include <linux/net.h>
+#include <linux/radix-tree.h>
+#include <linux/uio.h>
+#include <linux/version.h>
+#include <linux/workqueue.h>
+
+#include "types.h"
+#include "buffer.h"
+
+struct ceph_msg;
+struct ceph_connection;
+
+extern struct workqueue_struct *ceph_msgr_wq;       /* receive work queue */
+
+/*
+ * Ceph defines these callbacks for handling connection events.
+ */
+struct ceph_connection_operations {
+       struct ceph_connection *(*get)(struct ceph_connection *);
+       void (*put)(struct ceph_connection *);
+
+       /* handle an incoming message. */
+       void (*dispatch) (struct ceph_connection *con, struct ceph_msg *m);
+
+       /* authorize an outgoing connection */
+       int (*get_authorizer) (struct ceph_connection *con,
+                              void **buf, int *len, int *proto,
+                              void **reply_buf, int *reply_len, int force_new);
+       int (*verify_authorizer_reply) (struct ceph_connection *con, int len);
+       int (*invalidate_authorizer)(struct ceph_connection *con);
+
+       /* protocol version mismatch */
+       void (*bad_proto) (struct ceph_connection *con);
+
+       /* there was some error on the socket (disconnect, whatever) */
+       void (*fault) (struct ceph_connection *con);
+
+       /* a remote host as terminated a message exchange session, and messages
+        * we sent (or they tried to send us) may be lost. */
+       void (*peer_reset) (struct ceph_connection *con);
+
+       struct ceph_msg * (*alloc_msg) (struct ceph_connection *con,
+                                       struct ceph_msg_header *hdr,
+                                       int *skip);
+};
+
+extern const char *ceph_name_type_str(int t);
+
+/* use format string %s%d */
+#define ENTITY_NAME(n) ceph_name_type_str((n).type), le64_to_cpu((n).num)
+
+struct ceph_messenger {
+       struct ceph_entity_inst inst;    /* my name+address */
+       struct ceph_entity_addr my_enc_addr;
+       struct page *zero_page;          /* used in certain error cases */
+
+       bool nocrc;
+
+       /*
+        * the global_seq counts connections i (attempt to) initiate
+        * in order to disambiguate certain connect race conditions.
+        */
+       u32 global_seq;
+       spinlock_t global_seq_lock;
+};
+
+/*
+ * a single message.  it contains a header (src, dest, message type, etc.),
+ * footer (crc values, mainly), a "front" message body, and possibly a
+ * data payload (stored in some number of pages).
+ */
+struct ceph_msg {
+       struct ceph_msg_header hdr;     /* header */
+       struct ceph_msg_footer footer;  /* footer */
+       struct kvec front;              /* unaligned blobs of message */
+       struct ceph_buffer *middle;
+       struct page **pages;            /* data payload.  NOT OWNER. */
+       unsigned nr_pages;              /* size of page array */
+       struct ceph_pagelist *pagelist; /* instead of pages */
+       struct list_head list_head;
+       struct kref kref;
+       bool front_is_vmalloc;
+       bool more_to_follow;
+       bool needs_out_seq;
+       int front_max;
+
+       struct ceph_msgpool *pool;
+};
+
+struct ceph_msg_pos {
+       int page, page_pos;  /* which page; offset in page */
+       int data_pos;        /* offset in data payload */
+       int did_page_crc;    /* true if we've calculated crc for current page */
+};
+
+/* ceph connection fault delay defaults, for exponential backoff */
+#define BASE_DELAY_INTERVAL    (HZ/2)
+#define MAX_DELAY_INTERVAL     (5 * 60 * HZ)
+
+/*
+ * ceph_connection state bit flags
+ *
+ * QUEUED and BUSY are used together to ensure that only a single
+ * thread is currently opening, reading or writing data to the socket.
+ */
+#define LOSSYTX         0  /* we can close channel or drop messages on errors */
+#define CONNECTING     1
+#define NEGOTIATING    2
+#define KEEPALIVE_PENDING      3
+#define WRITE_PENDING  4  /* we have data ready to send */
+#define QUEUED          5  /* there is work queued on this connection */
+#define BUSY            6  /* work is being done */
+#define STANDBY                8  /* no outgoing messages, socket closed.  we keep
+                           * the ceph_connection around to maintain shared
+                           * state with the peer. */
+#define CLOSED         10 /* we've closed the connection */
+#define SOCK_CLOSED    11 /* socket state changed to closed */
+#define OPENING         13 /* open connection w/ (possibly new) peer */
+#define DEAD            14 /* dead, about to kfree */
+
+/*
+ * A single connection with another host.
+ *
+ * We maintain a queue of outgoing messages, and some session state to
+ * ensure that we can preserve the lossless, ordered delivery of
+ * messages in the case of a TCP disconnect.
+ */
+struct ceph_connection {
+       void *private;
+       atomic_t nref;
+
+       const struct ceph_connection_operations *ops;
+
+       struct ceph_messenger *msgr;
+       struct socket *sock;
+       unsigned long state;    /* connection state (see flags above) */
+       const char *error_msg;  /* error message, if any */
+
+       struct ceph_entity_addr peer_addr; /* peer address */
+       struct ceph_entity_name peer_name; /* peer name */
+       struct ceph_entity_addr peer_addr_for_me;
+       u32 connect_seq;      /* identify the most recent connection
+                                attempt for this connection, client */
+       u32 peer_global_seq;  /* peer's global seq for this connection */
+
+       int auth_retry;       /* true if we need a newer authorizer */
+       void *auth_reply_buf;   /* where to put the authorizer reply */
+       int auth_reply_buf_len;
+
+       struct mutex mutex;
+
+       /* out queue */
+       struct list_head out_queue;
+       struct list_head out_sent;   /* sending or sent but unacked */
+       u64 out_seq;                 /* last message queued for send */
+       u64 out_seq_sent;            /* last message sent */
+       bool out_keepalive_pending;
+
+       u64 in_seq, in_seq_acked;  /* last message received, acked */
+
+       /* connection negotiation temps */
+       char in_banner[CEPH_BANNER_MAX_LEN];
+       union {
+               struct {  /* outgoing connection */
+                       struct ceph_msg_connect out_connect;
+                       struct ceph_msg_connect_reply in_reply;
+               };
+               struct {  /* incoming */
+                       struct ceph_msg_connect in_connect;
+                       struct ceph_msg_connect_reply out_reply;
+               };
+       };
+       struct ceph_entity_addr actual_peer_addr;
+
+       /* message out temps */
+       struct ceph_msg *out_msg;        /* sending message (== tail of
+                                           out_sent) */
+       bool out_msg_done;
+       struct ceph_msg_pos out_msg_pos;
+
+       struct kvec out_kvec[8],         /* sending header/footer data */
+               *out_kvec_cur;
+       int out_kvec_left;   /* kvec's left in out_kvec */
+       int out_skip;        /* skip this many bytes */
+       int out_kvec_bytes;  /* total bytes left */
+       bool out_kvec_is_msg; /* kvec refers to out_msg */
+       int out_more;        /* there is more data after the kvecs */
+       __le64 out_temp_ack; /* for writing an ack */
+
+       /* message in temps */
+       struct ceph_msg_header in_hdr;
+       struct ceph_msg *in_msg;
+       struct ceph_msg_pos in_msg_pos;
+       u32 in_front_crc, in_middle_crc, in_data_crc;  /* calculated crc */
+
+       char in_tag;         /* protocol control byte */
+       int in_base_pos;     /* bytes read */
+       __le64 in_temp_ack;  /* for reading an ack */
+
+       struct delayed_work work;           /* send|recv work */
+       unsigned long       delay;          /* current delay interval */
+};
+
+
+extern const char *pr_addr(const struct sockaddr_storage *ss);
+extern int ceph_parse_ips(const char *c, const char *end,
+                         struct ceph_entity_addr *addr,
+                         int max_count, int *count);
+
+
+extern int ceph_msgr_init(void);
+extern void ceph_msgr_exit(void);
+
+extern struct ceph_messenger *ceph_messenger_create(
+       struct ceph_entity_addr *myaddr);
+extern void ceph_messenger_destroy(struct ceph_messenger *);
+
+extern void ceph_con_init(struct ceph_messenger *msgr,
+                         struct ceph_connection *con);
+extern void ceph_con_open(struct ceph_connection *con,
+                         struct ceph_entity_addr *addr);
+extern bool ceph_con_opened(struct ceph_connection *con);
+extern void ceph_con_close(struct ceph_connection *con);
+extern void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg);
+extern void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg);
+extern void ceph_con_revoke_message(struct ceph_connection *con,
+                                 struct ceph_msg *msg);
+extern void ceph_con_keepalive(struct ceph_connection *con);
+extern struct ceph_connection *ceph_con_get(struct ceph_connection *con);
+extern void ceph_con_put(struct ceph_connection *con);
+
+extern struct ceph_msg *ceph_msg_new(int type, int front_len,
+                                    int page_len, int page_off,
+                                    struct page **pages);
+extern void ceph_msg_kfree(struct ceph_msg *m);
+
+
+static inline struct ceph_msg *ceph_msg_get(struct ceph_msg *msg)
+{
+       kref_get(&msg->kref);
+       return msg;
+}
+extern void ceph_msg_last_put(struct kref *kref);
+static inline void ceph_msg_put(struct ceph_msg *msg)
+{
+       kref_put(&msg->kref, ceph_msg_last_put);
+}
+
+extern void ceph_msg_dump(struct ceph_msg *msg);
+
+#endif
diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c
new file mode 100644 (file)
index 0000000..8fdc011
--- /dev/null
@@ -0,0 +1,835 @@
+#include "ceph_debug.h"
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+
+#include "mon_client.h"
+#include "super.h"
+#include "auth.h"
+#include "decode.h"
+
+/*
+ * Interact with Ceph monitor cluster.  Handle requests for new map
+ * versions, and periodically resend as needed.  Also implement
+ * statfs() and umount().
+ *
+ * A small cluster of Ceph "monitors" are responsible for managing critical
+ * cluster configuration and state information.  An odd number (e.g., 3, 5)
+ * of cmon daemons use a modified version of the Paxos part-time parliament
+ * algorithm to manage the MDS map (mds cluster membership), OSD map, and
+ * list of clients who have mounted the file system.
+ *
+ * We maintain an open, active session with a monitor at all times in order to
+ * receive timely MDSMap updates.  We periodically send a keepalive byte on the
+ * TCP socket to ensure we detect a failure.  If the connection does break, we
+ * randomly hunt for a new monitor.  Once the connection is reestablished, we
+ * resend any outstanding requests.
+ */
+
+const static struct ceph_connection_operations mon_con_ops;
+
+static int __validate_auth(struct ceph_mon_client *monc);
+
+/*
+ * Decode a monmap blob (e.g., during mount).
+ */
+struct ceph_monmap *ceph_monmap_decode(void *p, void *end)
+{
+       struct ceph_monmap *m = NULL;
+       int i, err = -EINVAL;
+       struct ceph_fsid fsid;
+       u32 epoch, num_mon;
+       u16 version;
+       u32 len;
+
+       ceph_decode_32_safe(&p, end, len, bad);
+       ceph_decode_need(&p, end, len, bad);
+
+       dout("monmap_decode %p %p len %d\n", p, end, (int)(end-p));
+
+       ceph_decode_16_safe(&p, end, version, bad);
+
+       ceph_decode_need(&p, end, sizeof(fsid) + 2*sizeof(u32), bad);
+       ceph_decode_copy(&p, &fsid, sizeof(fsid));
+       epoch = ceph_decode_32(&p);
+
+       num_mon = ceph_decode_32(&p);
+       ceph_decode_need(&p, end, num_mon*sizeof(m->mon_inst[0]), bad);
+
+       if (num_mon >= CEPH_MAX_MON)
+               goto bad;
+       m = kmalloc(sizeof(*m) + sizeof(m->mon_inst[0])*num_mon, GFP_NOFS);
+       if (m == NULL)
+               return ERR_PTR(-ENOMEM);
+       m->fsid = fsid;
+       m->epoch = epoch;
+       m->num_mon = num_mon;
+       ceph_decode_copy(&p, m->mon_inst, num_mon*sizeof(m->mon_inst[0]));
+       for (i = 0; i < num_mon; i++)
+               ceph_decode_addr(&m->mon_inst[i].addr);
+
+       dout("monmap_decode epoch %d, num_mon %d\n", m->epoch,
+            m->num_mon);
+       for (i = 0; i < m->num_mon; i++)
+               dout("monmap_decode  mon%d is %s\n", i,
+                    pr_addr(&m->mon_inst[i].addr.in_addr));
+       return m;
+
+bad:
+       dout("monmap_decode failed with %d\n", err);
+       kfree(m);
+       return ERR_PTR(err);
+}
+
+/*
+ * return true if *addr is included in the monmap.
+ */
+int ceph_monmap_contains(struct ceph_monmap *m, struct ceph_entity_addr *addr)
+{
+       int i;
+
+       for (i = 0; i < m->num_mon; i++)
+               if (memcmp(addr, &m->mon_inst[i].addr, sizeof(*addr)) == 0)
+                       return 1;
+       return 0;
+}
+
+/*
+ * Send an auth request.
+ */
+static void __send_prepared_auth_request(struct ceph_mon_client *monc, int len)
+{
+       monc->pending_auth = 1;
+       monc->m_auth->front.iov_len = len;
+       monc->m_auth->hdr.front_len = cpu_to_le32(len);
+       ceph_msg_get(monc->m_auth);  /* keep our ref */
+       ceph_con_send(monc->con, monc->m_auth);
+}
+
+/*
+ * Close monitor session, if any.
+ */
+static void __close_session(struct ceph_mon_client *monc)
+{
+       if (monc->con) {
+               dout("__close_session closing mon%d\n", monc->cur_mon);
+               ceph_con_revoke(monc->con, monc->m_auth);
+               ceph_con_close(monc->con);
+               monc->cur_mon = -1;
+               monc->pending_auth = 0;
+               ceph_auth_reset(monc->auth);
+       }
+}
+
+/*
+ * Open a session with a (new) monitor.
+ */
+static int __open_session(struct ceph_mon_client *monc)
+{
+       char r;
+       int ret;
+
+       if (monc->cur_mon < 0) {
+               get_random_bytes(&r, 1);
+               monc->cur_mon = r % monc->monmap->num_mon;
+               dout("open_session num=%d r=%d -> mon%d\n",
+                    monc->monmap->num_mon, r, monc->cur_mon);
+               monc->sub_sent = 0;
+               monc->sub_renew_after = jiffies;  /* i.e., expired */
+               monc->want_next_osdmap = !!monc->want_next_osdmap;
+
+               dout("open_session mon%d opening\n", monc->cur_mon);
+               monc->con->peer_name.type = CEPH_ENTITY_TYPE_MON;
+               monc->con->peer_name.num = cpu_to_le64(monc->cur_mon);
+               ceph_con_open(monc->con,
+                             &monc->monmap->mon_inst[monc->cur_mon].addr);
+
+               /* initiatiate authentication handshake */
+               ret = ceph_auth_build_hello(monc->auth,
+                                           monc->m_auth->front.iov_base,
+                                           monc->m_auth->front_max);
+               __send_prepared_auth_request(monc, ret);
+       } else {
+               dout("open_session mon%d already open\n", monc->cur_mon);
+       }
+       return 0;
+}
+
+static bool __sub_expired(struct ceph_mon_client *monc)
+{
+       return time_after_eq(jiffies, monc->sub_renew_after);
+}
+
+/*
+ * Reschedule delayed work timer.
+ */
+static void __schedule_delayed(struct ceph_mon_client *monc)
+{
+       unsigned delay;
+
+       if (monc->cur_mon < 0 || __sub_expired(monc))
+               delay = 10 * HZ;
+       else
+               delay = 20 * HZ;
+       dout("__schedule_delayed after %u\n", delay);
+       schedule_delayed_work(&monc->delayed_work, delay);
+}
+
+/*
+ * Send subscribe request for mdsmap and/or osdmap.
+ */
+static void __send_subscribe(struct ceph_mon_client *monc)
+{
+       dout("__send_subscribe sub_sent=%u exp=%u want_osd=%d\n",
+            (unsigned)monc->sub_sent, __sub_expired(monc),
+            monc->want_next_osdmap);
+       if ((__sub_expired(monc) && !monc->sub_sent) ||
+           monc->want_next_osdmap == 1) {
+               struct ceph_msg *msg;
+               struct ceph_mon_subscribe_item *i;
+               void *p, *end;
+
+               msg = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE, 96, 0, 0, NULL);
+               if (!msg)
+                       return;
+
+               p = msg->front.iov_base;
+               end = p + msg->front.iov_len;
+
+               dout("__send_subscribe to 'mdsmap' %u+\n",
+                    (unsigned)monc->have_mdsmap);
+               if (monc->want_next_osdmap) {
+                       dout("__send_subscribe to 'osdmap' %u\n",
+                            (unsigned)monc->have_osdmap);
+                       ceph_encode_32(&p, 3);
+                       ceph_encode_string(&p, end, "osdmap", 6);
+                       i = p;
+                       i->have = cpu_to_le64(monc->have_osdmap);
+                       i->onetime = 1;
+                       p += sizeof(*i);
+                       monc->want_next_osdmap = 2;  /* requested */
+               } else {
+                       ceph_encode_32(&p, 2);
+               }
+               ceph_encode_string(&p, end, "mdsmap", 6);
+               i = p;
+               i->have = cpu_to_le64(monc->have_mdsmap);
+               i->onetime = 0;
+               p += sizeof(*i);
+               ceph_encode_string(&p, end, "monmap", 6);
+               i = p;
+               i->have = 0;
+               i->onetime = 0;
+               p += sizeof(*i);
+
+               msg->front.iov_len = p - msg->front.iov_base;
+               msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
+               ceph_con_send(monc->con, msg);
+
+               monc->sub_sent = jiffies | 1;  /* never 0 */
+       }
+}
+
+static void handle_subscribe_ack(struct ceph_mon_client *monc,
+                                struct ceph_msg *msg)
+{
+       unsigned seconds;
+       struct ceph_mon_subscribe_ack *h = msg->front.iov_base;
+
+       if (msg->front.iov_len < sizeof(*h))
+               goto bad;
+       seconds = le32_to_cpu(h->duration);
+
+       mutex_lock(&monc->mutex);
+       if (monc->hunting) {
+               pr_info("mon%d %s session established\n",
+                       monc->cur_mon, pr_addr(&monc->con->peer_addr.in_addr));
+               monc->hunting = false;
+       }
+       dout("handle_subscribe_ack after %d seconds\n", seconds);
+       monc->sub_renew_after = monc->sub_sent + (seconds >> 1)*HZ - 1;
+       monc->sub_sent = 0;
+       mutex_unlock(&monc->mutex);
+       return;
+bad:
+       pr_err("got corrupt subscribe-ack msg\n");
+       ceph_msg_dump(msg);
+}
+
+/*
+ * Keep track of which maps we have
+ */
+int ceph_monc_got_mdsmap(struct ceph_mon_client *monc, u32 got)
+{
+       mutex_lock(&monc->mutex);
+       monc->have_mdsmap = got;
+       mutex_unlock(&monc->mutex);
+       return 0;
+}
+
+int ceph_monc_got_osdmap(struct ceph_mon_client *monc, u32 got)
+{
+       mutex_lock(&monc->mutex);
+       monc->have_osdmap = got;
+       monc->want_next_osdmap = 0;
+       mutex_unlock(&monc->mutex);
+       return 0;
+}
+
+/*
+ * Register interest in the next osdmap
+ */
+void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc)
+{
+       dout("request_next_osdmap have %u\n", monc->have_osdmap);
+       mutex_lock(&monc->mutex);
+       if (!monc->want_next_osdmap)
+               monc->want_next_osdmap = 1;
+       if (monc->want_next_osdmap < 2)
+               __send_subscribe(monc);
+       mutex_unlock(&monc->mutex);
+}
+
+/*
+ *
+ */
+int ceph_monc_open_session(struct ceph_mon_client *monc)
+{
+       if (!monc->con) {
+               monc->con = kmalloc(sizeof(*monc->con), GFP_KERNEL);
+               if (!monc->con)
+                       return -ENOMEM;
+               ceph_con_init(monc->client->msgr, monc->con);
+               monc->con->private = monc;
+               monc->con->ops = &mon_con_ops;
+       }
+
+       mutex_lock(&monc->mutex);
+       __open_session(monc);
+       __schedule_delayed(monc);
+       mutex_unlock(&monc->mutex);
+       return 0;
+}
+
+/*
+ * The monitor responds with mount ack indicate mount success.  The
+ * included client ticket allows the client to talk to MDSs and OSDs.
+ */
+static void ceph_monc_handle_map(struct ceph_mon_client *monc,
+                                struct ceph_msg *msg)
+{
+       struct ceph_client *client = monc->client;
+       struct ceph_monmap *monmap = NULL, *old = monc->monmap;
+       void *p, *end;
+
+       mutex_lock(&monc->mutex);
+
+       dout("handle_monmap\n");
+       p = msg->front.iov_base;
+       end = p + msg->front.iov_len;
+
+       monmap = ceph_monmap_decode(p, end);
+       if (IS_ERR(monmap)) {
+               pr_err("problem decoding monmap, %d\n",
+                      (int)PTR_ERR(monmap));
+               goto out;
+       }
+
+       if (ceph_check_fsid(monc->client, &monmap->fsid) < 0) {
+               kfree(monmap);
+               goto out;
+       }
+
+       client->monc.monmap = monmap;
+       kfree(old);
+
+out:
+       mutex_unlock(&monc->mutex);
+       wake_up(&client->auth_wq);
+}
+
+/*
+ * statfs
+ */
+static struct ceph_mon_statfs_request *__lookup_statfs(
+       struct ceph_mon_client *monc, u64 tid)
+{
+       struct ceph_mon_statfs_request *req;
+       struct rb_node *n = monc->statfs_request_tree.rb_node;
+
+       while (n) {
+               req = rb_entry(n, struct ceph_mon_statfs_request, node);
+               if (tid < req->tid)
+                       n = n->rb_left;
+               else if (tid > req->tid)
+                       n = n->rb_right;
+               else
+                       return req;
+       }
+       return NULL;
+}
+
+static void __insert_statfs(struct ceph_mon_client *monc,
+                           struct ceph_mon_statfs_request *new)
+{
+       struct rb_node **p = &monc->statfs_request_tree.rb_node;
+       struct rb_node *parent = NULL;
+       struct ceph_mon_statfs_request *req = NULL;
+
+       while (*p) {
+               parent = *p;
+               req = rb_entry(parent, struct ceph_mon_statfs_request, node);
+               if (new->tid < req->tid)
+                       p = &(*p)->rb_left;
+               else if (new->tid > req->tid)
+                       p = &(*p)->rb_right;
+               else
+                       BUG();
+       }
+
+       rb_link_node(&new->node, parent, p);
+       rb_insert_color(&new->node, &monc->statfs_request_tree);
+}
+
+static void handle_statfs_reply(struct ceph_mon_client *monc,
+                               struct ceph_msg *msg)
+{
+       struct ceph_mon_statfs_request *req;
+       struct ceph_mon_statfs_reply *reply = msg->front.iov_base;
+       u64 tid;
+
+       if (msg->front.iov_len != sizeof(*reply))
+               goto bad;
+       tid = le64_to_cpu(msg->hdr.tid);
+       dout("handle_statfs_reply %p tid %llu\n", msg, tid);
+
+       mutex_lock(&monc->mutex);
+       req = __lookup_statfs(monc, tid);
+       if (req) {
+               *req->buf = reply->st;
+               req->result = 0;
+       }
+       mutex_unlock(&monc->mutex);
+       if (req)
+               complete(&req->completion);
+       return;
+
+bad:
+       pr_err("corrupt statfs reply, no tid\n");
+       ceph_msg_dump(msg);
+}
+
+/*
+ * (re)send a statfs request
+ */
+static int send_statfs(struct ceph_mon_client *monc,
+                      struct ceph_mon_statfs_request *req)
+{
+       struct ceph_msg *msg;
+       struct ceph_mon_statfs *h;
+
+       dout("send_statfs tid %llu\n", req->tid);
+       msg = ceph_msg_new(CEPH_MSG_STATFS, sizeof(*h), 0, 0, NULL);
+       if (IS_ERR(msg))
+               return PTR_ERR(msg);
+       req->request = msg;
+       msg->hdr.tid = cpu_to_le64(req->tid);
+       h = msg->front.iov_base;
+       h->monhdr.have_version = 0;
+       h->monhdr.session_mon = cpu_to_le16(-1);
+       h->monhdr.session_mon_tid = 0;
+       h->fsid = monc->monmap->fsid;
+       ceph_con_send(monc->con, msg);
+       return 0;
+}
+
+/*
+ * Do a synchronous statfs().
+ */
+int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf)
+{
+       struct ceph_mon_statfs_request req;
+       int err;
+
+       req.buf = buf;
+       init_completion(&req.completion);
+
+       /* allocate memory for reply */
+       err = ceph_msgpool_resv(&monc->msgpool_statfs_reply, 1);
+       if (err)
+               return err;
+
+       /* register request */
+       mutex_lock(&monc->mutex);
+       req.tid = ++monc->last_tid;
+       req.last_attempt = jiffies;
+       req.delay = BASE_DELAY_INTERVAL;
+       __insert_statfs(monc, &req);
+       monc->num_statfs_requests++;
+       mutex_unlock(&monc->mutex);
+
+       /* send request and wait */
+       err = send_statfs(monc, &req);
+       if (!err)
+               err = wait_for_completion_interruptible(&req.completion);
+
+       mutex_lock(&monc->mutex);
+       rb_erase(&req.node, &monc->statfs_request_tree);
+       monc->num_statfs_requests--;
+       ceph_msgpool_resv(&monc->msgpool_statfs_reply, -1);
+       mutex_unlock(&monc->mutex);
+
+       if (!err)
+               err = req.result;
+       return err;
+}
+
+/*
+ * Resend pending statfs requests.
+ */
+static void __resend_statfs(struct ceph_mon_client *monc)
+{
+       struct ceph_mon_statfs_request *req;
+       struct rb_node *p;
+
+       for (p = rb_first(&monc->statfs_request_tree); p; p = rb_next(p)) {
+               req = rb_entry(p, struct ceph_mon_statfs_request, node);
+               send_statfs(monc, req);
+       }
+}
+
+/*
+ * Delayed work.  If we haven't mounted yet, retry.  Otherwise,
+ * renew/retry subscription as needed (in case it is timing out, or we
+ * got an ENOMEM).  And keep the monitor connection alive.
+ */
+static void delayed_work(struct work_struct *work)
+{
+       struct ceph_mon_client *monc =
+               container_of(work, struct ceph_mon_client, delayed_work.work);
+
+       dout("monc delayed_work\n");
+       mutex_lock(&monc->mutex);
+       if (monc->hunting) {
+               __close_session(monc);
+               __open_session(monc);  /* continue hunting */
+       } else {
+               ceph_con_keepalive(monc->con);
+
+               __validate_auth(monc);
+
+               if (monc->auth->ops->is_authenticated(monc->auth))
+                       __send_subscribe(monc);
+       }
+       __schedule_delayed(monc);
+       mutex_unlock(&monc->mutex);
+}
+
+/*
+ * On startup, we build a temporary monmap populated with the IPs
+ * provided by mount(2).
+ */
+static int build_initial_monmap(struct ceph_mon_client *monc)
+{
+       struct ceph_mount_args *args = monc->client->mount_args;
+       struct ceph_entity_addr *mon_addr = args->mon_addr;
+       int num_mon = args->num_mon;
+       int i;
+
+       /* build initial monmap */
+       monc->monmap = kzalloc(sizeof(*monc->monmap) +
+                              num_mon*sizeof(monc->monmap->mon_inst[0]),
+                              GFP_KERNEL);
+       if (!monc->monmap)
+               return -ENOMEM;
+       for (i = 0; i < num_mon; i++) {
+               monc->monmap->mon_inst[i].addr = mon_addr[i];
+               monc->monmap->mon_inst[i].addr.nonce = 0;
+               monc->monmap->mon_inst[i].name.type =
+                       CEPH_ENTITY_TYPE_MON;
+               monc->monmap->mon_inst[i].name.num = cpu_to_le64(i);
+       }
+       monc->monmap->num_mon = num_mon;
+       monc->have_fsid = false;
+
+       /* release addr memory */
+       kfree(args->mon_addr);
+       args->mon_addr = NULL;
+       args->num_mon = 0;
+       return 0;
+}
+
+int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
+{
+       int err = 0;
+
+       dout("init\n");
+       memset(monc, 0, sizeof(*monc));
+       monc->client = cl;
+       monc->monmap = NULL;
+       mutex_init(&monc->mutex);
+
+       err = build_initial_monmap(monc);
+       if (err)
+               goto out;
+
+       monc->con = NULL;
+
+       /* authentication */
+       monc->auth = ceph_auth_init(cl->mount_args->name,
+                                   cl->mount_args->secret);
+       if (IS_ERR(monc->auth))
+               return PTR_ERR(monc->auth);
+       monc->auth->want_keys =
+               CEPH_ENTITY_TYPE_AUTH | CEPH_ENTITY_TYPE_MON |
+               CEPH_ENTITY_TYPE_OSD | CEPH_ENTITY_TYPE_MDS;
+
+       /* msg pools */
+       err = ceph_msgpool_init(&monc->msgpool_subscribe_ack,
+                              sizeof(struct ceph_mon_subscribe_ack), 1, false);
+       if (err < 0)
+               goto out_monmap;
+       err = ceph_msgpool_init(&monc->msgpool_statfs_reply,
+                               sizeof(struct ceph_mon_statfs_reply), 0, false);
+       if (err < 0)
+               goto out_pool1;
+       err = ceph_msgpool_init(&monc->msgpool_auth_reply, 4096, 1, false);
+       if (err < 0)
+               goto out_pool2;
+
+       monc->m_auth = ceph_msg_new(CEPH_MSG_AUTH, 4096, 0, 0, NULL);
+       monc->pending_auth = 0;
+       if (IS_ERR(monc->m_auth)) {
+               err = PTR_ERR(monc->m_auth);
+               monc->m_auth = NULL;
+               goto out_pool3;
+       }
+
+       monc->cur_mon = -1;
+       monc->hunting = true;
+       monc->sub_renew_after = jiffies;
+       monc->sub_sent = 0;
+
+       INIT_DELAYED_WORK(&monc->delayed_work, delayed_work);
+       monc->statfs_request_tree = RB_ROOT;
+       monc->num_statfs_requests = 0;
+       monc->last_tid = 0;
+
+       monc->have_mdsmap = 0;
+       monc->have_osdmap = 0;
+       monc->want_next_osdmap = 1;
+       return 0;
+
+out_pool3:
+       ceph_msgpool_destroy(&monc->msgpool_auth_reply);
+out_pool2:
+       ceph_msgpool_destroy(&monc->msgpool_subscribe_ack);
+out_pool1:
+       ceph_msgpool_destroy(&monc->msgpool_statfs_reply);
+out_monmap:
+       kfree(monc->monmap);
+out:
+       return err;
+}
+
+void ceph_monc_stop(struct ceph_mon_client *monc)
+{
+       dout("stop\n");
+       cancel_delayed_work_sync(&monc->delayed_work);
+
+       mutex_lock(&monc->mutex);
+       __close_session(monc);
+       if (monc->con) {
+               monc->con->private = NULL;
+               monc->con->ops->put(monc->con);
+               monc->con = NULL;
+       }
+       mutex_unlock(&monc->mutex);
+
+       ceph_auth_destroy(monc->auth);
+
+       ceph_msg_put(monc->m_auth);
+       ceph_msgpool_destroy(&monc->msgpool_subscribe_ack);
+       ceph_msgpool_destroy(&monc->msgpool_statfs_reply);
+       ceph_msgpool_destroy(&monc->msgpool_auth_reply);
+
+       kfree(monc->monmap);
+}
+
+static void handle_auth_reply(struct ceph_mon_client *monc,
+                             struct ceph_msg *msg)
+{
+       int ret;
+
+       mutex_lock(&monc->mutex);
+       monc->pending_auth = 0;
+       ret = ceph_handle_auth_reply(monc->auth, msg->front.iov_base,
+                                    msg->front.iov_len,
+                                    monc->m_auth->front.iov_base,
+                                    monc->m_auth->front_max);
+       if (ret < 0) {
+               monc->client->auth_err = ret;
+               wake_up(&monc->client->auth_wq);
+       } else if (ret > 0) {
+               __send_prepared_auth_request(monc, ret);
+       } else if (monc->auth->ops->is_authenticated(monc->auth)) {
+               dout("authenticated, starting session\n");
+
+               monc->client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT;
+               monc->client->msgr->inst.name.num = monc->auth->global_id;
+
+               __send_subscribe(monc);
+               __resend_statfs(monc);
+       }
+       mutex_unlock(&monc->mutex);
+}
+
+static int __validate_auth(struct ceph_mon_client *monc)
+{
+       int ret;
+
+       if (monc->pending_auth)
+               return 0;
+
+       ret = ceph_build_auth(monc->auth, monc->m_auth->front.iov_base,
+                             monc->m_auth->front_max);
+       if (ret <= 0)
+               return ret; /* either an error, or no need to authenticate */
+       __send_prepared_auth_request(monc, ret);
+       return 0;
+}
+
+int ceph_monc_validate_auth(struct ceph_mon_client *monc)
+{
+       int ret;
+
+       mutex_lock(&monc->mutex);
+       ret = __validate_auth(monc);
+       mutex_unlock(&monc->mutex);
+       return ret;
+}
+
+/*
+ * handle incoming message
+ */
+static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
+{
+       struct ceph_mon_client *monc = con->private;
+       int type = le16_to_cpu(msg->hdr.type);
+
+       if (!monc)
+               return;
+
+       switch (type) {
+       case CEPH_MSG_AUTH_REPLY:
+               handle_auth_reply(monc, msg);
+               break;
+
+       case CEPH_MSG_MON_SUBSCRIBE_ACK:
+               handle_subscribe_ack(monc, msg);
+               break;
+
+       case CEPH_MSG_STATFS_REPLY:
+               handle_statfs_reply(monc, msg);
+               break;
+
+       case CEPH_MSG_MON_MAP:
+               ceph_monc_handle_map(monc, msg);
+               break;
+
+       case CEPH_MSG_MDS_MAP:
+               ceph_mdsc_handle_map(&monc->client->mdsc, msg);
+               break;
+
+       case CEPH_MSG_OSD_MAP:
+               ceph_osdc_handle_map(&monc->client->osdc, msg);
+               break;
+
+       default:
+               pr_err("received unknown message type %d %s\n", type,
+                      ceph_msg_type_name(type));
+       }
+       ceph_msg_put(msg);
+}
+
+/*
+ * Allocate memory for incoming message
+ */
+static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con,
+                                     struct ceph_msg_header *hdr,
+                                     int *skip)
+{
+       struct ceph_mon_client *monc = con->private;
+       int type = le16_to_cpu(hdr->type);
+       int front_len = le32_to_cpu(hdr->front_len);
+       struct ceph_msg *m = NULL;
+
+       *skip = 0;
+
+       switch (type) {
+       case CEPH_MSG_MON_SUBSCRIBE_ACK:
+               m = ceph_msgpool_get(&monc->msgpool_subscribe_ack, front_len);
+               break;
+       case CEPH_MSG_STATFS_REPLY:
+               m = ceph_msgpool_get(&monc->msgpool_statfs_reply, front_len);
+               break;
+       case CEPH_MSG_AUTH_REPLY:
+               m = ceph_msgpool_get(&monc->msgpool_auth_reply, front_len);
+               break;
+       case CEPH_MSG_MON_MAP:
+       case CEPH_MSG_MDS_MAP:
+       case CEPH_MSG_OSD_MAP:
+               m = ceph_msg_new(type, front_len, 0, 0, NULL);
+               break;
+       }
+
+       if (!m) {
+               pr_info("alloc_msg unknown type %d\n", type);
+               *skip = 1;
+       }
+       return m;
+}
+
+/*
+ * If the monitor connection resets, pick a new monitor and resubmit
+ * any pending requests.
+ */
+static void mon_fault(struct ceph_connection *con)
+{
+       struct ceph_mon_client *monc = con->private;
+
+       if (!monc)
+               return;
+
+       dout("mon_fault\n");
+       mutex_lock(&monc->mutex);
+       if (!con->private)
+               goto out;
+
+       if (monc->con && !monc->hunting)
+               pr_info("mon%d %s session lost, "
+                       "hunting for new mon\n", monc->cur_mon,
+                       pr_addr(&monc->con->peer_addr.in_addr));
+
+       __close_session(monc);
+       if (!monc->hunting) {
+               /* start hunting */
+               monc->hunting = true;
+               __open_session(monc);
+       } else {
+               /* already hunting, let's wait a bit */
+               __schedule_delayed(monc);
+       }
+out:
+       mutex_unlock(&monc->mutex);
+}
+
+const static struct ceph_connection_operations mon_con_ops = {
+       .get = ceph_con_get,
+       .put = ceph_con_put,
+       .dispatch = dispatch,
+       .fault = mon_fault,
+       .alloc_msg = mon_alloc_msg,
+};
diff --git a/fs/ceph/mon_client.h b/fs/ceph/mon_client.h
new file mode 100644 (file)
index 0000000..b958ad5
--- /dev/null
@@ -0,0 +1,119 @@
+#ifndef _FS_CEPH_MON_CLIENT_H
+#define _FS_CEPH_MON_CLIENT_H
+
+#include <linux/completion.h>
+#include <linux/rbtree.h>
+
+#include "messenger.h"
+#include "msgpool.h"
+
+struct ceph_client;
+struct ceph_mount_args;
+struct ceph_auth_client;
+
+/*
+ * The monitor map enumerates the set of all monitors.
+ */
+struct ceph_monmap {
+       struct ceph_fsid fsid;
+       u32 epoch;
+       u32 num_mon;
+       struct ceph_entity_inst mon_inst[0];
+};
+
+struct ceph_mon_client;
+struct ceph_mon_statfs_request;
+
+
+/*
+ * Generic mechanism for resending monitor requests.
+ */
+typedef void (*ceph_monc_request_func_t)(struct ceph_mon_client *monc,
+                                        int newmon);
+
+/* a pending monitor request */
+struct ceph_mon_request {
+       struct ceph_mon_client *monc;
+       struct delayed_work delayed_work;
+       unsigned long delay;
+       ceph_monc_request_func_t do_request;
+};
+
+/*
+ * statfs() is done a bit differently because we need to get data back
+ * to the caller
+ */
+struct ceph_mon_statfs_request {
+       u64 tid;
+       struct rb_node node;
+       int result;
+       struct ceph_statfs *buf;
+       struct completion completion;
+       unsigned long last_attempt, delay; /* jiffies */
+       struct ceph_msg *request;  /* original request */
+};
+
+struct ceph_mon_client {
+       struct ceph_client *client;
+       struct ceph_monmap *monmap;
+
+       struct mutex mutex;
+       struct delayed_work delayed_work;
+
+       struct ceph_auth_client *auth;
+       struct ceph_msg *m_auth;
+       int pending_auth;
+
+       bool hunting;
+       int cur_mon;                       /* last monitor i contacted */
+       unsigned long sub_sent, sub_renew_after;
+       struct ceph_connection *con;
+       bool have_fsid;
+
+       /* msg pools */
+       struct ceph_msgpool msgpool_subscribe_ack;
+       struct ceph_msgpool msgpool_statfs_reply;
+       struct ceph_msgpool msgpool_auth_reply;
+
+       /* pending statfs requests */
+       struct rb_root statfs_request_tree;
+       int num_statfs_requests;
+       u64 last_tid;
+
+       /* mds/osd map */
+       int want_next_osdmap; /* 1 = want, 2 = want+asked */
+       u32 have_osdmap, have_mdsmap;
+
+#ifdef CONFIG_DEBUG_FS
+       struct dentry *debugfs_file;
+#endif
+};
+
+extern struct ceph_monmap *ceph_monmap_decode(void *p, void *end);
+extern int ceph_monmap_contains(struct ceph_monmap *m,
+                               struct ceph_entity_addr *addr);
+
+extern int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl);
+extern void ceph_monc_stop(struct ceph_mon_client *monc);
+
+/*
+ * The model here is to indicate that we need a new map of at least
+ * epoch @want, and also call in when we receive a map.  We will
+ * periodically rerequest the map from the monitor cluster until we
+ * get what we want.
+ */
+extern int ceph_monc_got_mdsmap(struct ceph_mon_client *monc, u32 have);
+extern int ceph_monc_got_osdmap(struct ceph_mon_client *monc, u32 have);
+
+extern void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc);
+
+extern int ceph_monc_do_statfs(struct ceph_mon_client *monc,
+                              struct ceph_statfs *buf);
+
+extern int ceph_monc_open_session(struct ceph_mon_client *monc);
+
+extern int ceph_monc_validate_auth(struct ceph_mon_client *monc);
+
+
+
+#endif
diff --git a/fs/ceph/msgpool.c b/fs/ceph/msgpool.c
new file mode 100644 (file)
index 0000000..ca3b44a
--- /dev/null
@@ -0,0 +1,186 @@
+#include "ceph_debug.h"
+
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+
+#include "msgpool.h"
+
+/*
+ * We use msg pools to preallocate memory for messages we expect to
+ * receive over the wire, to avoid getting ourselves into OOM
+ * conditions at unexpected times.  We take use a few different
+ * strategies:
+ *
+ *  - for request/response type interactions, we preallocate the
+ * memory needed for the response when we generate the request.
+ *
+ *  - for messages we can receive at any time from the MDS, we preallocate
+ * a pool of messages we can re-use.
+ *
+ *  - for writeback, we preallocate some number of messages to use for
+ * requests and their replies, so that we always make forward
+ * progress.
+ *
+ * The msgpool behaves like a mempool_t, but keeps preallocated
+ * ceph_msgs strung together on a list_head instead of using a pointer
+ * vector.  This avoids vector reallocation when we adjust the number
+ * of preallocated items (which happens frequently).
+ */
+
+
+/*
+ * Allocate or release as necessary to meet our target pool size.
+ */
+static int __fill_msgpool(struct ceph_msgpool *pool)
+{
+       struct ceph_msg *msg;
+
+       while (pool->num < pool->min) {
+               dout("fill_msgpool %p %d/%d allocating\n", pool, pool->num,
+                    pool->min);
+               spin_unlock(&pool->lock);
+               msg = ceph_msg_new(0, pool->front_len, 0, 0, NULL);
+               spin_lock(&pool->lock);
+               if (IS_ERR(msg))
+                       return PTR_ERR(msg);
+               msg->pool = pool;
+               list_add(&msg->list_head, &pool->msgs);
+               pool->num++;
+       }
+       while (pool->num > pool->min) {
+               msg = list_first_entry(&pool->msgs, struct ceph_msg, list_head);
+               dout("fill_msgpool %p %d/%d releasing %p\n", pool, pool->num,
+                    pool->min, msg);
+               list_del_init(&msg->list_head);
+               pool->num--;
+               ceph_msg_kfree(msg);
+       }
+       return 0;
+}
+
+int ceph_msgpool_init(struct ceph_msgpool *pool,
+                     int front_len, int min, bool blocking)
+{
+       int ret;
+
+       dout("msgpool_init %p front_len %d min %d\n", pool, front_len, min);
+       spin_lock_init(&pool->lock);
+       pool->front_len = front_len;
+       INIT_LIST_HEAD(&pool->msgs);
+       pool->num = 0;
+       pool->min = min;
+       pool->blocking = blocking;
+       init_waitqueue_head(&pool->wait);
+
+       spin_lock(&pool->lock);
+       ret = __fill_msgpool(pool);
+       spin_unlock(&pool->lock);
+       return ret;
+}
+
+void ceph_msgpool_destroy(struct ceph_msgpool *pool)
+{
+       dout("msgpool_destroy %p\n", pool);
+       spin_lock(&pool->lock);
+       pool->min = 0;
+       __fill_msgpool(pool);
+       spin_unlock(&pool->lock);
+}
+
+int ceph_msgpool_resv(struct ceph_msgpool *pool, int delta)
+{
+       int ret;
+
+       spin_lock(&pool->lock);
+       dout("msgpool_resv %p delta %d\n", pool, delta);
+       pool->min += delta;
+       ret = __fill_msgpool(pool);
+       spin_unlock(&pool->lock);
+       return ret;
+}
+
+struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, int front_len)
+{
+       wait_queue_t wait;
+       struct ceph_msg *msg;
+
+       if (front_len && front_len > pool->front_len) {
+               pr_err("msgpool_get pool %p need front %d, pool size is %d\n",
+                      pool, front_len, pool->front_len);
+               WARN_ON(1);
+
+               /* try to alloc a fresh message */
+               msg = ceph_msg_new(0, front_len, 0, 0, NULL);
+               if (!IS_ERR(msg))
+                       return msg;
+       }
+
+       if (!front_len)
+               front_len = pool->front_len;
+
+       if (pool->blocking) {
+               /* mempool_t behavior; first try to alloc */
+               msg = ceph_msg_new(0, front_len, 0, 0, NULL);
+               if (!IS_ERR(msg))
+                       return msg;
+       }
+
+       while (1) {
+               spin_lock(&pool->lock);
+               if (likely(pool->num)) {
+                       msg = list_entry(pool->msgs.next, struct ceph_msg,
+                                        list_head);
+                       list_del_init(&msg->list_head);
+                       pool->num--;
+                       dout("msgpool_get %p got %p, now %d/%d\n", pool, msg,
+                            pool->num, pool->min);
+                       spin_unlock(&pool->lock);
+                       return msg;
+               }
+               pr_err("msgpool_get %p now %d/%d, %s\n", pool, pool->num,
+                      pool->min, pool->blocking ? "waiting" : "may fail");
+               spin_unlock(&pool->lock);
+
+               if (!pool->blocking) {
+                       WARN_ON(1);
+
+                       /* maybe we can allocate it now? */
+                       msg = ceph_msg_new(0, front_len, 0, 0, NULL);
+                       if (!IS_ERR(msg))
+                               return msg;
+
+                       pr_err("msgpool_get %p empty + alloc failed\n", pool);
+                       return ERR_PTR(-ENOMEM);
+               }
+
+               init_wait(&wait);
+               prepare_to_wait(&pool->wait, &wait, TASK_UNINTERRUPTIBLE);
+               schedule();
+               finish_wait(&pool->wait, &wait);
+       }
+}
+
+void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg)
+{
+       spin_lock(&pool->lock);
+       if (pool->num < pool->min) {
+               /* reset msg front_len; user may have changed it */
+               msg->front.iov_len = pool->front_len;
+               msg->hdr.front_len = cpu_to_le32(pool->front_len);
+
+               kref_set(&msg->kref, 1);  /* retake a single ref */
+               list_add(&msg->list_head, &pool->msgs);
+               pool->num++;
+               dout("msgpool_put %p reclaim %p, now %d/%d\n", pool, msg,
+                    pool->num, pool->min);
+               spin_unlock(&pool->lock);
+               wake_up(&pool->wait);
+       } else {
+               dout("msgpool_put %p drop %p, at %d/%d\n", pool, msg,
+                    pool->num, pool->min);
+               spin_unlock(&pool->lock);
+               ceph_msg_kfree(msg);
+       }
+}
diff --git a/fs/ceph/msgpool.h b/fs/ceph/msgpool.h
new file mode 100644 (file)
index 0000000..bc834bf
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef _FS_CEPH_MSGPOOL
+#define _FS_CEPH_MSGPOOL
+
+#include "messenger.h"
+
+/*
+ * we use memory pools for preallocating messages we may receive, to
+ * avoid unexpected OOM conditions.
+ */
+struct ceph_msgpool {
+       spinlock_t lock;
+       int front_len;          /* preallocated payload size */
+       struct list_head msgs;  /* msgs in the pool; each has 1 ref */
+       int num, min;           /* cur, min # msgs in the pool */
+       bool blocking;
+       wait_queue_head_t wait;
+};
+
+extern int ceph_msgpool_init(struct ceph_msgpool *pool,
+                            int front_len, int size, bool blocking);
+extern void ceph_msgpool_destroy(struct ceph_msgpool *pool);
+extern int ceph_msgpool_resv(struct ceph_msgpool *, int delta);
+extern struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *,
+                                        int front_len);
+extern void ceph_msgpool_put(struct ceph_msgpool *, struct ceph_msg *);
+
+#endif
diff --git a/fs/ceph/msgr.h b/fs/ceph/msgr.h
new file mode 100644 (file)
index 0000000..8aaab41
--- /dev/null
@@ -0,0 +1,158 @@
+#ifndef __MSGR_H
+#define __MSGR_H
+
+/*
+ * Data types for message passing layer used by Ceph.
+ */
+
+#define CEPH_MON_PORT    6789  /* default monitor port */
+
+/*
+ * client-side processes will try to bind to ports in this
+ * range, simply for the benefit of tools like nmap or wireshark
+ * that would like to identify the protocol.
+ */
+#define CEPH_PORT_FIRST  6789
+#define CEPH_PORT_START  6800  /* non-monitors start here */
+#define CEPH_PORT_LAST   6900
+
+/*
+ * tcp connection banner.  include a protocol version. and adjust
+ * whenever the wire protocol changes.  try to keep this string length
+ * constant.
+ */
+#define CEPH_BANNER "ceph v027"
+#define CEPH_BANNER_MAX_LEN 30
+
+
+/*
+ * Rollover-safe type and comparator for 32-bit sequence numbers.
+ * Comparator returns -1, 0, or 1.
+ */
+typedef __u32 ceph_seq_t;
+
+static inline __s32 ceph_seq_cmp(__u32 a, __u32 b)
+{
+       return (__s32)a - (__s32)b;
+}
+
+
+/*
+ * entity_name -- logical name for a process participating in the
+ * network, e.g. 'mds0' or 'osd3'.
+ */
+struct ceph_entity_name {
+       __u8 type;      /* CEPH_ENTITY_TYPE_* */
+       __le64 num;
+} __attribute__ ((packed));
+
+#define CEPH_ENTITY_TYPE_MON    0x01
+#define CEPH_ENTITY_TYPE_MDS    0x02
+#define CEPH_ENTITY_TYPE_OSD    0x04
+#define CEPH_ENTITY_TYPE_CLIENT 0x08
+#define CEPH_ENTITY_TYPE_ADMIN  0x10
+#define CEPH_ENTITY_TYPE_AUTH   0x20
+
+#define CEPH_ENTITY_TYPE_ANY    0xFF
+
+extern const char *ceph_entity_type_name(int type);
+
+/*
+ * entity_addr -- network address
+ */
+struct ceph_entity_addr {
+       __le32 type;
+       __le32 nonce;  /* unique id for process (e.g. pid) */
+       struct sockaddr_storage in_addr;
+} __attribute__ ((packed));
+
+struct ceph_entity_inst {
+       struct ceph_entity_name name;
+       struct ceph_entity_addr addr;
+} __attribute__ ((packed));
+
+
+/* used by message exchange protocol */
+#define CEPH_MSGR_TAG_READY         1  /* server->client: ready for messages */
+#define CEPH_MSGR_TAG_RESETSESSION  2  /* server->client: reset, try again */
+#define CEPH_MSGR_TAG_WAIT          3  /* server->client: wait for racing
+                                         incoming connection */
+#define CEPH_MSGR_TAG_RETRY_SESSION 4  /* server->client + cseq: try again
+                                         with higher cseq */
+#define CEPH_MSGR_TAG_RETRY_GLOBAL  5  /* server->client + gseq: try again
+                                         with higher gseq */
+#define CEPH_MSGR_TAG_CLOSE         6  /* closing pipe */
+#define CEPH_MSGR_TAG_MSG           7  /* message */
+#define CEPH_MSGR_TAG_ACK           8  /* message ack */
+#define CEPH_MSGR_TAG_KEEPALIVE     9  /* just a keepalive byte! */
+#define CEPH_MSGR_TAG_BADPROTOVER  10  /* bad protocol version */
+#define CEPH_MSGR_TAG_BADAUTHORIZER 11 /* bad authorizer */
+#define CEPH_MSGR_TAG_FEATURES      12 /* insufficient features */
+
+
+/*
+ * connection negotiation
+ */
+struct ceph_msg_connect {
+       __le64 features;     /* supported feature bits */
+       __le32 host_type;    /* CEPH_ENTITY_TYPE_* */
+       __le32 global_seq;   /* count connections initiated by this host */
+       __le32 connect_seq;  /* count connections initiated in this session */
+       __le32 protocol_version;
+       __le32 authorizer_protocol;
+       __le32 authorizer_len;
+       __u8  flags;         /* CEPH_MSG_CONNECT_* */
+} __attribute__ ((packed));
+
+struct ceph_msg_connect_reply {
+       __u8 tag;
+       __le64 features;     /* feature bits for this session */
+       __le32 global_seq;
+       __le32 connect_seq;
+       __le32 protocol_version;
+       __le32 authorizer_len;
+       __u8 flags;
+} __attribute__ ((packed));
+
+#define CEPH_MSG_CONNECT_LOSSY  1  /* messages i send may be safely dropped */
+
+
+/*
+ * message header
+ */
+struct ceph_msg_header {
+       __le64 seq;       /* message seq# for this session */
+       __le64 tid;       /* transaction id */
+       __le16 type;      /* message type */
+       __le16 priority;  /* priority.  higher value == higher priority */
+       __le16 version;   /* version of message encoding */
+
+       __le32 front_len; /* bytes in main payload */
+       __le32 middle_len;/* bytes in middle payload */
+       __le32 data_len;  /* bytes of data payload */
+       __le16 data_off;  /* sender: include full offset;
+                            receiver: mask against ~PAGE_MASK */
+
+       struct ceph_entity_inst src, orig_src;
+       __le32 reserved;
+       __le32 crc;       /* header crc32c */
+} __attribute__ ((packed));
+
+#define CEPH_MSG_PRIO_LOW     64
+#define CEPH_MSG_PRIO_DEFAULT 127
+#define CEPH_MSG_PRIO_HIGH    196
+#define CEPH_MSG_PRIO_HIGHEST 255
+
+/*
+ * follows data payload
+ */
+struct ceph_msg_footer {
+       __le32 front_crc, middle_crc, data_crc;
+       __u8 flags;
+} __attribute__ ((packed));
+
+#define CEPH_MSG_FOOTER_COMPLETE  (1<<0)   /* msg wasn't aborted */
+#define CEPH_MSG_FOOTER_NOCRC     (1<<1)   /* no data crc */
+
+
+#endif
diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c
new file mode 100644 (file)
index 0000000..3514f71
--- /dev/null
@@ -0,0 +1,1564 @@
+#include "ceph_debug.h"
+
+#include <linux/err.h>
+#include <linux/highmem.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include "super.h"
+#include "osd_client.h"
+#include "messenger.h"
+#include "decode.h"
+#include "auth.h"
+
+#define OSD_OP_FRONT_LEN       4096
+#define OSD_OPREPLY_FRONT_LEN  512
+
+const static struct ceph_connection_operations osd_con_ops;
+static int __kick_requests(struct ceph_osd_client *osdc,
+                         struct ceph_osd *kickosd);
+
+static void kick_requests(struct ceph_osd_client *osdc, struct ceph_osd *osd);
+
+/*
+ * Implement client access to distributed object storage cluster.
+ *
+ * All data objects are stored within a cluster/cloud of OSDs, or
+ * "object storage devices."  (Note that Ceph OSDs have _nothing_ to
+ * do with the T10 OSD extensions to SCSI.)  Ceph OSDs are simply
+ * remote daemons serving up and coordinating consistent and safe
+ * access to storage.
+ *
+ * Cluster membership and the mapping of data objects onto storage devices
+ * are described by the osd map.
+ *
+ * We keep track of pending OSD requests (read, write), resubmit
+ * requests to different OSDs when the cluster topology/data layout
+ * change, or retry the affected requests when the communications
+ * channel with an OSD is reset.
+ */
+
+/*
+ * calculate the mapping of a file extent onto an object, and fill out the
+ * request accordingly.  shorten extent as necessary if it crosses an
+ * object boundary.
+ *
+ * fill osd op in request message.
+ */
+static void calc_layout(struct ceph_osd_client *osdc,
+                       struct ceph_vino vino, struct ceph_file_layout *layout,
+                       u64 off, u64 *plen,
+                       struct ceph_osd_request *req)
+{
+       struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
+       struct ceph_osd_op *op = (void *)(reqhead + 1);
+       u64 orig_len = *plen;
+       u64 objoff, objlen;    /* extent in object */
+       u64 bno;
+
+       reqhead->snapid = cpu_to_le64(vino.snap);
+
+       /* object extent? */
+       ceph_calc_file_object_mapping(layout, off, plen, &bno,
+                                     &objoff, &objlen);
+       if (*plen < orig_len)
+               dout(" skipping last %llu, final file extent %llu~%llu\n",
+                    orig_len - *plen, off, *plen);
+
+       sprintf(req->r_oid, "%llx.%08llx", vino.ino, bno);
+       req->r_oid_len = strlen(req->r_oid);
+
+       op->extent.offset = cpu_to_le64(objoff);
+       op->extent.length = cpu_to_le64(objlen);
+       req->r_num_pages = calc_pages_for(off, *plen);
+
+       dout("calc_layout %s (%d) %llu~%llu (%d pages)\n",
+            req->r_oid, req->r_oid_len, objoff, objlen, req->r_num_pages);
+}
+
+/*
+ * requests
+ */
+void ceph_osdc_release_request(struct kref *kref)
+{
+       struct ceph_osd_request *req = container_of(kref,
+                                                   struct ceph_osd_request,
+                                                   r_kref);
+
+       if (req->r_request)
+               ceph_msg_put(req->r_request);
+       if (req->r_reply)
+               ceph_msg_put(req->r_reply);
+       if (req->r_con_filling_msg) {
+               dout("release_request revoking pages %p from con %p\n",
+                    req->r_pages, req->r_con_filling_msg);
+               ceph_con_revoke_message(req->r_con_filling_msg,
+                                     req->r_reply);
+               ceph_con_put(req->r_con_filling_msg);
+       }
+       if (req->r_own_pages)
+               ceph_release_page_vector(req->r_pages,
+                                        req->r_num_pages);
+       ceph_put_snap_context(req->r_snapc);
+       if (req->r_mempool)
+               mempool_free(req, req->r_osdc->req_mempool);
+       else
+               kfree(req);
+}
+
+/*
+ * build new request AND message, calculate layout, and adjust file
+ * extent as needed.
+ *
+ * if the file was recently truncated, we include information about its
+ * old and new size so that the object can be updated appropriately.  (we
+ * avoid synchronously deleting truncated objects because it's slow.)
+ *
+ * if @do_sync, include a 'startsync' command so that the osd will flush
+ * data quickly.
+ */
+struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
+                                              struct ceph_file_layout *layout,
+                                              struct ceph_vino vino,
+                                              u64 off, u64 *plen,
+                                              int opcode, int flags,
+                                              struct ceph_snap_context *snapc,
+                                              int do_sync,
+                                              u32 truncate_seq,
+                                              u64 truncate_size,
+                                              struct timespec *mtime,
+                                              bool use_mempool, int num_reply)
+{
+       struct ceph_osd_request *req;
+       struct ceph_msg *msg;
+       struct ceph_osd_request_head *head;
+       struct ceph_osd_op *op;
+       void *p;
+       int num_op = 1 + do_sync;
+       size_t msg_size = sizeof(*head) + num_op*sizeof(*op);
+       int i;
+
+       if (use_mempool) {
+               req = mempool_alloc(osdc->req_mempool, GFP_NOFS);
+               memset(req, 0, sizeof(*req));
+       } else {
+               req = kzalloc(sizeof(*req), GFP_NOFS);
+       }
+       if (req == NULL)
+               return ERR_PTR(-ENOMEM);
+
+       req->r_osdc = osdc;
+       req->r_mempool = use_mempool;
+       kref_init(&req->r_kref);
+       init_completion(&req->r_completion);
+       init_completion(&req->r_safe_completion);
+       INIT_LIST_HEAD(&req->r_unsafe_item);
+       req->r_flags = flags;
+
+       WARN_ON((flags & (CEPH_OSD_FLAG_READ|CEPH_OSD_FLAG_WRITE)) == 0);
+
+       /* create reply message */
+       if (use_mempool)
+               msg = ceph_msgpool_get(&osdc->msgpool_op_reply, 0);
+       else
+               msg = ceph_msg_new(CEPH_MSG_OSD_OPREPLY,
+                                  OSD_OPREPLY_FRONT_LEN, 0, 0, NULL);
+       if (IS_ERR(msg)) {
+               ceph_osdc_put_request(req);
+               return ERR_PTR(PTR_ERR(msg));
+       }
+       req->r_reply = msg;
+
+       /* create request message; allow space for oid */
+       msg_size += 40;
+       if (snapc)
+               msg_size += sizeof(u64) * snapc->num_snaps;
+       if (use_mempool)
+               msg = ceph_msgpool_get(&osdc->msgpool_op, 0);
+       else
+               msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, 0, 0, NULL);
+       if (IS_ERR(msg)) {
+               ceph_osdc_put_request(req);
+               return ERR_PTR(PTR_ERR(msg));
+       }
+       msg->hdr.type = cpu_to_le16(CEPH_MSG_OSD_OP);
+       memset(msg->front.iov_base, 0, msg->front.iov_len);
+       head = msg->front.iov_base;
+       op = (void *)(head + 1);
+       p = (void *)(op + num_op);
+
+       req->r_request = msg;
+       req->r_snapc = ceph_get_snap_context(snapc);
+
+       head->client_inc = cpu_to_le32(1); /* always, for now. */
+       head->flags = cpu_to_le32(flags);
+       if (flags & CEPH_OSD_FLAG_WRITE)
+               ceph_encode_timespec(&head->mtime, mtime);
+       head->num_ops = cpu_to_le16(num_op);
+       op->op = cpu_to_le16(opcode);
+
+       /* calculate max write size */
+       calc_layout(osdc, vino, layout, off, plen, req);
+       req->r_file_layout = *layout;  /* keep a copy */
+
+       if (flags & CEPH_OSD_FLAG_WRITE) {
+               req->r_request->hdr.data_off = cpu_to_le16(off);
+               req->r_request->hdr.data_len = cpu_to_le32(*plen);
+               op->payload_len = cpu_to_le32(*plen);
+       }
+       op->extent.truncate_size = cpu_to_le64(truncate_size);
+       op->extent.truncate_seq = cpu_to_le32(truncate_seq);
+
+       /* fill in oid */
+       head->object_len = cpu_to_le32(req->r_oid_len);
+       memcpy(p, req->r_oid, req->r_oid_len);
+       p += req->r_oid_len;
+
+       if (do_sync) {
+               op++;
+               op->op = cpu_to_le16(CEPH_OSD_OP_STARTSYNC);
+       }
+       if (snapc) {
+               head->snap_seq = cpu_to_le64(snapc->seq);
+               head->num_snaps = cpu_to_le32(snapc->num_snaps);
+               for (i = 0; i < snapc->num_snaps; i++) {
+                       put_unaligned_le64(snapc->snaps[i], p);
+                       p += sizeof(u64);
+               }
+       }
+
+       BUG_ON(p > msg->front.iov_base + msg->front.iov_len);
+       msg_size = p - msg->front.iov_base;
+       msg->front.iov_len = msg_size;
+       msg->hdr.front_len = cpu_to_le32(msg_size);
+       return req;
+}
+
+/*
+ * We keep osd requests in an rbtree, sorted by ->r_tid.
+ */
+static void __insert_request(struct ceph_osd_client *osdc,
+                            struct ceph_osd_request *new)
+{
+       struct rb_node **p = &osdc->requests.rb_node;
+       struct rb_node *parent = NULL;
+       struct ceph_osd_request *req = NULL;
+
+       while (*p) {
+               parent = *p;
+               req = rb_entry(parent, struct ceph_osd_request, r_node);
+               if (new->r_tid < req->r_tid)
+                       p = &(*p)->rb_left;
+               else if (new->r_tid > req->r_tid)
+                       p = &(*p)->rb_right;
+               else
+                       BUG();
+       }
+
+       rb_link_node(&new->r_node, parent, p);
+       rb_insert_color(&new->r_node, &osdc->requests);
+}
+
+static struct ceph_osd_request *__lookup_request(struct ceph_osd_client *osdc,
+                                                u64 tid)
+{
+       struct ceph_osd_request *req;
+       struct rb_node *n = osdc->requests.rb_node;
+
+       while (n) {
+               req = rb_entry(n, struct ceph_osd_request, r_node);
+               if (tid < req->r_tid)
+                       n = n->rb_left;
+               else if (tid > req->r_tid)
+                       n = n->rb_right;
+               else
+                       return req;
+       }
+       return NULL;
+}
+
+static struct ceph_osd_request *
+__lookup_request_ge(struct ceph_osd_client *osdc,
+                   u64 tid)
+{
+       struct ceph_osd_request *req;
+       struct rb_node *n = osdc->requests.rb_node;
+
+       while (n) {
+               req = rb_entry(n, struct ceph_osd_request, r_node);
+               if (tid < req->r_tid) {
+                       if (!n->rb_left)
+                               return req;
+                       n = n->rb_left;
+               } else if (tid > req->r_tid) {
+                       n = n->rb_right;
+               } else {
+                       return req;
+               }
+       }
+       return NULL;
+}
+
+
+/*
+ * If the osd connection drops, we need to resubmit all requests.
+ */
+static void osd_reset(struct ceph_connection *con)
+{
+       struct ceph_osd *osd = con->private;
+       struct ceph_osd_client *osdc;
+
+       if (!osd)
+               return;
+       dout("osd_reset osd%d\n", osd->o_osd);
+       osdc = osd->o_osdc;
+       down_read(&osdc->map_sem);
+       kick_requests(osdc, osd);
+       up_read(&osdc->map_sem);
+}
+
+/*
+ * Track open sessions with osds.
+ */
+static struct ceph_osd *create_osd(struct ceph_osd_client *osdc)
+{
+       struct ceph_osd *osd;
+
+       osd = kzalloc(sizeof(*osd), GFP_NOFS);
+       if (!osd)
+               return NULL;
+
+       atomic_set(&osd->o_ref, 1);
+       osd->o_osdc = osdc;
+       INIT_LIST_HEAD(&osd->o_requests);
+       INIT_LIST_HEAD(&osd->o_osd_lru);
+       osd->o_incarnation = 1;
+
+       ceph_con_init(osdc->client->msgr, &osd->o_con);
+       osd->o_con.private = osd;
+       osd->o_con.ops = &osd_con_ops;
+       osd->o_con.peer_name.type = CEPH_ENTITY_TYPE_OSD;
+
+       INIT_LIST_HEAD(&osd->o_keepalive_item);
+       return osd;
+}
+
+static struct ceph_osd *get_osd(struct ceph_osd *osd)
+{
+       if (atomic_inc_not_zero(&osd->o_ref)) {
+               dout("get_osd %p %d -> %d\n", osd, atomic_read(&osd->o_ref)-1,
+                    atomic_read(&osd->o_ref));
+               return osd;
+       } else {
+               dout("get_osd %p FAIL\n", osd);
+               return NULL;
+       }
+}
+
+static void put_osd(struct ceph_osd *osd)
+{
+       dout("put_osd %p %d -> %d\n", osd, atomic_read(&osd->o_ref),
+            atomic_read(&osd->o_ref) - 1);
+       if (atomic_dec_and_test(&osd->o_ref))
+               kfree(osd);
+}
+
+/*
+ * remove an osd from our map
+ */
+static void __remove_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd)
+{
+       dout("__remove_osd %p\n", osd);
+       BUG_ON(!list_empty(&osd->o_requests));
+       rb_erase(&osd->o_node, &osdc->osds);
+       list_del_init(&osd->o_osd_lru);
+       ceph_con_close(&osd->o_con);
+       put_osd(osd);
+}
+
+static void __move_osd_to_lru(struct ceph_osd_client *osdc,
+                             struct ceph_osd *osd)
+{
+       dout("__move_osd_to_lru %p\n", osd);
+       BUG_ON(!list_empty(&osd->o_osd_lru));
+       list_add_tail(&osd->o_osd_lru, &osdc->osd_lru);
+       osd->lru_ttl = jiffies + osdc->client->mount_args->osd_idle_ttl * HZ;
+}
+
+static void __remove_osd_from_lru(struct ceph_osd *osd)
+{
+       dout("__remove_osd_from_lru %p\n", osd);
+       if (!list_empty(&osd->o_osd_lru))
+               list_del_init(&osd->o_osd_lru);
+}
+
+static void remove_old_osds(struct ceph_osd_client *osdc, int remove_all)
+{
+       struct ceph_osd *osd, *nosd;
+
+       dout("__remove_old_osds %p\n", osdc);
+       mutex_lock(&osdc->request_mutex);
+       list_for_each_entry_safe(osd, nosd, &osdc->osd_lru, o_osd_lru) {
+               if (!remove_all && time_before(jiffies, osd->lru_ttl))
+                       break;
+               __remove_osd(osdc, osd);
+       }
+       mutex_unlock(&osdc->request_mutex);
+}
+
+/*
+ * reset osd connect
+ */
+static int __reset_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd)
+{
+       struct ceph_osd_request *req;
+       int ret = 0;
+
+       dout("__reset_osd %p osd%d\n", osd, osd->o_osd);
+       if (list_empty(&osd->o_requests)) {
+               __remove_osd(osdc, osd);
+       } else if (memcmp(&osdc->osdmap->osd_addr[osd->o_osd],
+                         &osd->o_con.peer_addr,
+                         sizeof(osd->o_con.peer_addr)) == 0 &&
+                  !ceph_con_opened(&osd->o_con)) {
+               dout(" osd addr hasn't changed and connection never opened,"
+                    " letting msgr retry");
+               /* touch each r_stamp for handle_timeout()'s benfit */
+               list_for_each_entry(req, &osd->o_requests, r_osd_item)
+                       req->r_stamp = jiffies;
+               ret = -EAGAIN;
+       } else {
+               ceph_con_close(&osd->o_con);
+               ceph_con_open(&osd->o_con, &osdc->osdmap->osd_addr[osd->o_osd]);
+               osd->o_incarnation++;
+       }
+       return ret;
+}
+
+static void __insert_osd(struct ceph_osd_client *osdc, struct ceph_osd *new)
+{
+       struct rb_node **p = &osdc->osds.rb_node;
+       struct rb_node *parent = NULL;
+       struct ceph_osd *osd = NULL;
+
+       while (*p) {
+               parent = *p;
+               osd = rb_entry(parent, struct ceph_osd, o_node);
+               if (new->o_osd < osd->o_osd)
+                       p = &(*p)->rb_left;
+               else if (new->o_osd > osd->o_osd)
+                       p = &(*p)->rb_right;
+               else
+                       BUG();
+       }
+
+       rb_link_node(&new->o_node, parent, p);
+       rb_insert_color(&new->o_node, &osdc->osds);
+}
+
+static struct ceph_osd *__lookup_osd(struct ceph_osd_client *osdc, int o)
+{
+       struct ceph_osd *osd;
+       struct rb_node *n = osdc->osds.rb_node;
+
+       while (n) {
+               osd = rb_entry(n, struct ceph_osd, o_node);
+               if (o < osd->o_osd)
+                       n = n->rb_left;
+               else if (o > osd->o_osd)
+                       n = n->rb_right;
+               else
+                       return osd;
+       }
+       return NULL;
+}
+
+static void __schedule_osd_timeout(struct ceph_osd_client *osdc)
+{
+       schedule_delayed_work(&osdc->timeout_work,
+                       osdc->client->mount_args->osd_keepalive_timeout * HZ);
+}
+
+static void __cancel_osd_timeout(struct ceph_osd_client *osdc)
+{
+       cancel_delayed_work(&osdc->timeout_work);
+}
+
+/*
+ * Register request, assign tid.  If this is the first request, set up
+ * the timeout event.
+ */
+static void register_request(struct ceph_osd_client *osdc,
+                            struct ceph_osd_request *req)
+{
+       mutex_lock(&osdc->request_mutex);
+       req->r_tid = ++osdc->last_tid;
+       req->r_request->hdr.tid = cpu_to_le64(req->r_tid);
+       INIT_LIST_HEAD(&req->r_req_lru_item);
+
+       dout("register_request %p tid %lld\n", req, req->r_tid);
+       __insert_request(osdc, req);
+       ceph_osdc_get_request(req);
+       osdc->num_requests++;
+
+       if (osdc->num_requests == 1) {
+               dout(" first request, scheduling timeout\n");
+               __schedule_osd_timeout(osdc);
+       }
+       mutex_unlock(&osdc->request_mutex);
+}
+
+/*
+ * called under osdc->request_mutex
+ */
+static void __unregister_request(struct ceph_osd_client *osdc,
+                                struct ceph_osd_request *req)
+{
+       dout("__unregister_request %p tid %lld\n", req, req->r_tid);
+       rb_erase(&req->r_node, &osdc->requests);
+       osdc->num_requests--;
+
+       if (req->r_osd) {
+               /* make sure the original request isn't in flight. */
+               ceph_con_revoke(&req->r_osd->o_con, req->r_request);
+
+               list_del_init(&req->r_osd_item);
+               if (list_empty(&req->r_osd->o_requests))
+                       __move_osd_to_lru(osdc, req->r_osd);
+               req->r_osd = NULL;
+       }
+
+       ceph_osdc_put_request(req);
+
+       list_del_init(&req->r_req_lru_item);
+       if (osdc->num_requests == 0) {
+               dout(" no requests, canceling timeout\n");
+               __cancel_osd_timeout(osdc);
+       }
+}
+
+/*
+ * Cancel a previously queued request message
+ */
+static void __cancel_request(struct ceph_osd_request *req)
+{
+       if (req->r_sent) {
+               ceph_con_revoke(&req->r_osd->o_con, req->r_request);
+               req->r_sent = 0;
+       }
+       list_del_init(&req->r_req_lru_item);
+}
+
+/*
+ * Pick an osd (the first 'up' osd in the pg), allocate the osd struct
+ * (as needed), and set the request r_osd appropriately.  If there is
+ * no up osd, set r_osd to NULL.
+ *
+ * Return 0 if unchanged, 1 if changed, or negative on error.
+ *
+ * Caller should hold map_sem for read and request_mutex.
+ */
+static int __map_osds(struct ceph_osd_client *osdc,
+                     struct ceph_osd_request *req)
+{
+       struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
+       struct ceph_pg pgid;
+       int acting[CEPH_PG_MAX_SIZE];
+       int o = -1, num = 0;
+       int err;
+
+       dout("map_osds %p tid %lld\n", req, req->r_tid);
+       err = ceph_calc_object_layout(&reqhead->layout, req->r_oid,
+                                     &req->r_file_layout, osdc->osdmap);
+       if (err)
+               return err;
+       pgid = reqhead->layout.ol_pgid;
+       req->r_pgid = pgid;
+
+       err = ceph_calc_pg_acting(osdc->osdmap, pgid, acting);
+       if (err > 0) {
+               o = acting[0];
+               num = err;
+       }
+
+       if ((req->r_osd && req->r_osd->o_osd == o &&
+            req->r_sent >= req->r_osd->o_incarnation &&
+            req->r_num_pg_osds == num &&
+            memcmp(req->r_pg_osds, acting, sizeof(acting[0])*num) == 0) ||
+           (req->r_osd == NULL && o == -1))
+               return 0;  /* no change */
+
+       dout("map_osds tid %llu pgid %d.%x osd%d (was osd%d)\n",
+            req->r_tid, le32_to_cpu(pgid.pool), le16_to_cpu(pgid.ps), o,
+            req->r_osd ? req->r_osd->o_osd : -1);
+
+       /* record full pg acting set */
+       memcpy(req->r_pg_osds, acting, sizeof(acting[0]) * num);
+       req->r_num_pg_osds = num;
+
+       if (req->r_osd) {
+               __cancel_request(req);
+               list_del_init(&req->r_osd_item);
+               req->r_osd = NULL;
+       }
+
+       req->r_osd = __lookup_osd(osdc, o);
+       if (!req->r_osd && o >= 0) {
+               err = -ENOMEM;
+               req->r_osd = create_osd(osdc);
+               if (!req->r_osd)
+                       goto out;
+
+               dout("map_osds osd %p is osd%d\n", req->r_osd, o);
+               req->r_osd->o_osd = o;
+               req->r_osd->o_con.peer_name.num = cpu_to_le64(o);
+               __insert_osd(osdc, req->r_osd);
+
+               ceph_con_open(&req->r_osd->o_con, &osdc->osdmap->osd_addr[o]);
+       }
+
+       if (req->r_osd) {
+               __remove_osd_from_lru(req->r_osd);
+               list_add(&req->r_osd_item, &req->r_osd->o_requests);
+       }
+       err = 1;   /* osd or pg changed */
+
+out:
+       return err;
+}
+
+/*
+ * caller should hold map_sem (for read) and request_mutex
+ */
+static int __send_request(struct ceph_osd_client *osdc,
+                         struct ceph_osd_request *req)
+{
+       struct ceph_osd_request_head *reqhead;
+       int err;
+
+       err = __map_osds(osdc, req);
+       if (err < 0)
+               return err;
+       if (req->r_osd == NULL) {
+               dout("send_request %p no up osds in pg\n", req);
+               ceph_monc_request_next_osdmap(&osdc->client->monc);
+               return 0;
+       }
+
+       dout("send_request %p tid %llu to osd%d flags %d\n",
+            req, req->r_tid, req->r_osd->o_osd, req->r_flags);
+
+       reqhead = req->r_request->front.iov_base;
+       reqhead->osdmap_epoch = cpu_to_le32(osdc->osdmap->epoch);
+       reqhead->flags |= cpu_to_le32(req->r_flags);  /* e.g., RETRY */
+       reqhead->reassert_version = req->r_reassert_version;
+
+       req->r_stamp = jiffies;
+       list_move_tail(&osdc->req_lru, &req->r_req_lru_item);
+
+       ceph_msg_get(req->r_request); /* send consumes a ref */
+       ceph_con_send(&req->r_osd->o_con, req->r_request);
+       req->r_sent = req->r_osd->o_incarnation;
+       return 0;
+}
+
+/*
+ * Timeout callback, called every N seconds when 1 or more osd
+ * requests has been active for more than N seconds.  When this
+ * happens, we ping all OSDs with requests who have timed out to
+ * ensure any communications channel reset is detected.  Reset the
+ * request timeouts another N seconds in the future as we go.
+ * Reschedule the timeout event another N seconds in future (unless
+ * there are no open requests).
+ */
+static void handle_timeout(struct work_struct *work)
+{
+       struct ceph_osd_client *osdc =
+               container_of(work, struct ceph_osd_client, timeout_work.work);
+       struct ceph_osd_request *req, *last_req = NULL;
+       struct ceph_osd *osd;
+       unsigned long timeout = osdc->client->mount_args->osd_timeout * HZ;
+       unsigned long keepalive =
+               osdc->client->mount_args->osd_keepalive_timeout * HZ;
+       unsigned long last_stamp = 0;
+       struct rb_node *p;
+       struct list_head slow_osds;
+
+       dout("timeout\n");
+       down_read(&osdc->map_sem);
+
+       ceph_monc_request_next_osdmap(&osdc->client->monc);
+
+       mutex_lock(&osdc->request_mutex);
+       for (p = rb_first(&osdc->requests); p; p = rb_next(p)) {
+               req = rb_entry(p, struct ceph_osd_request, r_node);
+
+               if (req->r_resend) {
+                       int err;
+
+                       dout("osdc resending prev failed %lld\n", req->r_tid);
+                       err = __send_request(osdc, req);
+                       if (err)
+                               dout("osdc failed again on %lld\n", req->r_tid);
+                       else
+                               req->r_resend = false;
+                       continue;
+               }
+       }
+
+       /*
+        * reset osds that appear to be _really_ unresponsive.  this
+        * is a failsafe measure.. we really shouldn't be getting to
+        * this point if the system is working properly.  the monitors
+        * should mark the osd as failed and we should find out about
+        * it from an updated osd map.
+        */
+       while (!list_empty(&osdc->req_lru)) {
+               req = list_entry(osdc->req_lru.next, struct ceph_osd_request,
+                                r_req_lru_item);
+
+               if (time_before(jiffies, req->r_stamp + timeout))
+                       break;
+
+               BUG_ON(req == last_req && req->r_stamp == last_stamp);
+               last_req = req;
+               last_stamp = req->r_stamp;
+
+               osd = req->r_osd;
+               BUG_ON(!osd);
+               pr_warning(" tid %llu timed out on osd%d, will reset osd\n",
+                          req->r_tid, osd->o_osd);
+               __kick_requests(osdc, osd);
+       }
+
+       /*
+        * ping osds that are a bit slow.  this ensures that if there
+        * is a break in the TCP connection we will notice, and reopen
+        * a connection with that osd (from the fault callback).
+        */
+       INIT_LIST_HEAD(&slow_osds);
+       list_for_each_entry(req, &osdc->req_lru, r_req_lru_item) {
+               if (time_before(jiffies, req->r_stamp + keepalive))
+                       break;
+
+               osd = req->r_osd;
+               BUG_ON(!osd);
+               dout(" tid %llu is slow, will send keepalive on osd%d\n",
+                    req->r_tid, osd->o_osd);
+               list_move_tail(&osd->o_keepalive_item, &slow_osds);
+       }
+       while (!list_empty(&slow_osds)) {
+               osd = list_entry(slow_osds.next, struct ceph_osd,
+                                o_keepalive_item);
+               list_del_init(&osd->o_keepalive_item);
+               ceph_con_keepalive(&osd->o_con);
+       }
+
+       __schedule_osd_timeout(osdc);
+       mutex_unlock(&osdc->request_mutex);
+
+       up_read(&osdc->map_sem);
+}
+
+static void handle_osds_timeout(struct work_struct *work)
+{
+       struct ceph_osd_client *osdc =
+               container_of(work, struct ceph_osd_client,
+                            osds_timeout_work.work);
+       unsigned long delay =
+               osdc->client->mount_args->osd_idle_ttl * HZ >> 2;
+
+       dout("osds timeout\n");
+       down_read(&osdc->map_sem);
+       remove_old_osds(osdc, 0);
+       up_read(&osdc->map_sem);
+
+       schedule_delayed_work(&osdc->osds_timeout_work,
+                             round_jiffies_relative(delay));
+}
+
+/*
+ * handle osd op reply.  either call the callback if it is specified,
+ * or do the completion to wake up the waiting thread.
+ */
+static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
+                        struct ceph_connection *con)
+{
+       struct ceph_osd_reply_head *rhead = msg->front.iov_base;
+       struct ceph_osd_request *req;
+       u64 tid;
+       int numops, object_len, flags;
+       s32 result;
+
+       tid = le64_to_cpu(msg->hdr.tid);
+       if (msg->front.iov_len < sizeof(*rhead))
+               goto bad;
+       numops = le32_to_cpu(rhead->num_ops);
+       object_len = le32_to_cpu(rhead->object_len);
+       result = le32_to_cpu(rhead->result);
+       if (msg->front.iov_len != sizeof(*rhead) + object_len +
+           numops * sizeof(struct ceph_osd_op))
+               goto bad;
+       dout("handle_reply %p tid %llu result %d\n", msg, tid, (int)result);
+
+       /* lookup */
+       mutex_lock(&osdc->request_mutex);
+       req = __lookup_request(osdc, tid);
+       if (req == NULL) {
+               dout("handle_reply tid %llu dne\n", tid);
+               mutex_unlock(&osdc->request_mutex);
+               return;
+       }
+       ceph_osdc_get_request(req);
+       flags = le32_to_cpu(rhead->flags);
+
+       /*
+        * if this connection filled our message, drop our reference now, to
+        * avoid a (safe but slower) revoke later.
+        */
+       if (req->r_con_filling_msg == con && req->r_reply == msg) {
+               dout(" dropping con_filling_msg ref %p\n", con);
+               req->r_con_filling_msg = NULL;
+               ceph_con_put(con);
+       }
+
+       if (!req->r_got_reply) {
+               unsigned bytes;
+
+               req->r_result = le32_to_cpu(rhead->result);
+               bytes = le32_to_cpu(msg->hdr.data_len);
+               dout("handle_reply result %d bytes %d\n", req->r_result,
+                    bytes);
+               if (req->r_result == 0)
+                       req->r_result = bytes;
+
+               /* in case this is a write and we need to replay, */
+               req->r_reassert_version = rhead->reassert_version;
+
+               req->r_got_reply = 1;
+       } else if ((flags & CEPH_OSD_FLAG_ONDISK) == 0) {
+               dout("handle_reply tid %llu dup ack\n", tid);
+               mutex_unlock(&osdc->request_mutex);
+               goto done;
+       }
+
+       dout("handle_reply tid %llu flags %d\n", tid, flags);
+
+       /* either this is a read, or we got the safe response */
+       if (result < 0 ||
+           (flags & CEPH_OSD_FLAG_ONDISK) ||
+           ((flags & CEPH_OSD_FLAG_WRITE) == 0))
+               __unregister_request(osdc, req);
+
+       mutex_unlock(&osdc->request_mutex);
+
+       if (req->r_callback)
+               req->r_callback(req, msg);
+       else
+               complete(&req->r_completion);
+
+       if (flags & CEPH_OSD_FLAG_ONDISK) {
+               if (req->r_safe_callback)
+                       req->r_safe_callback(req, msg);
+               complete(&req->r_safe_completion);  /* fsync waiter */
+       }
+
+done:
+       ceph_osdc_put_request(req);
+       return;
+
+bad:
+       pr_err("corrupt osd_op_reply got %d %d expected %d\n",
+              (int)msg->front.iov_len, le32_to_cpu(msg->hdr.front_len),
+              (int)sizeof(*rhead));
+       ceph_msg_dump(msg);
+}
+
+
+static int __kick_requests(struct ceph_osd_client *osdc,
+                         struct ceph_osd *kickosd)
+{
+       struct ceph_osd_request *req;
+       struct rb_node *p, *n;
+       int needmap = 0;
+       int err;
+
+       dout("kick_requests osd%d\n", kickosd ? kickosd->o_osd : -1);
+       if (kickosd) {
+               err = __reset_osd(osdc, kickosd);
+               if (err == -EAGAIN)
+                       return 1;
+       } else {
+               for (p = rb_first(&osdc->osds); p; p = n) {
+                       struct ceph_osd *osd =
+                               rb_entry(p, struct ceph_osd, o_node);
+
+                       n = rb_next(p);
+                       if (!ceph_osd_is_up(osdc->osdmap, osd->o_osd) ||
+                           memcmp(&osd->o_con.peer_addr,
+                                  ceph_osd_addr(osdc->osdmap,
+                                                osd->o_osd),
+                                  sizeof(struct ceph_entity_addr)) != 0)
+                               __reset_osd(osdc, osd);
+               }
+       }
+
+       for (p = rb_first(&osdc->requests); p; p = rb_next(p)) {
+               req = rb_entry(p, struct ceph_osd_request, r_node);
+
+               if (req->r_resend) {
+                       dout(" r_resend set on tid %llu\n", req->r_tid);
+                       __cancel_request(req);
+                       goto kick;
+               }
+               if (req->r_osd && kickosd == req->r_osd) {
+                       __cancel_request(req);
+                       goto kick;
+               }
+
+               err = __map_osds(osdc, req);
+               if (err == 0)
+                       continue;  /* no change */
+               if (err < 0) {
+                       /*
+                        * FIXME: really, we should set the request
+                        * error and fail if this isn't a 'nofail'
+                        * request, but that's a fair bit more
+                        * complicated to do.  So retry!
+                        */
+                       dout(" setting r_resend on %llu\n", req->r_tid);
+                       req->r_resend = true;
+                       continue;
+               }
+               if (req->r_osd == NULL) {
+                       dout("tid %llu maps to no valid osd\n", req->r_tid);
+                       needmap++;  /* request a newer map */
+                       continue;
+               }
+
+kick:
+               dout("kicking %p tid %llu osd%d\n", req, req->r_tid,
+                    req->r_osd ? req->r_osd->o_osd : -1);
+               req->r_flags |= CEPH_OSD_FLAG_RETRY;
+               err = __send_request(osdc, req);
+               if (err) {
+                       dout(" setting r_resend on %llu\n", req->r_tid);
+                       req->r_resend = true;
+               }
+       }
+
+       return needmap;
+}
+
+/*
+ * Resubmit osd requests whose osd or osd address has changed.  Request
+ * a new osd map if osds are down, or we are otherwise unable to determine
+ * how to direct a request.
+ *
+ * Close connections to down osds.
+ *
+ * If @who is specified, resubmit requests for that specific osd.
+ *
+ * Caller should hold map_sem for read and request_mutex.
+ */
+static void kick_requests(struct ceph_osd_client *osdc,
+                         struct ceph_osd *kickosd)
+{
+       int needmap;
+
+       mutex_lock(&osdc->request_mutex);
+       needmap = __kick_requests(osdc, kickosd);
+       mutex_unlock(&osdc->request_mutex);
+
+       if (needmap) {
+               dout("%d requests for down osds, need new map\n", needmap);
+               ceph_monc_request_next_osdmap(&osdc->client->monc);
+       }
+
+}
+/*
+ * Process updated osd map.
+ *
+ * The message contains any number of incremental and full maps, normally
+ * indicating some sort of topology change in the cluster.  Kick requests
+ * off to different OSDs as needed.
+ */
+void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
+{
+       void *p, *end, *next;
+       u32 nr_maps, maplen;
+       u32 epoch;
+       struct ceph_osdmap *newmap = NULL, *oldmap;
+       int err;
+       struct ceph_fsid fsid;
+
+       dout("handle_map have %u\n", osdc->osdmap ? osdc->osdmap->epoch : 0);
+       p = msg->front.iov_base;
+       end = p + msg->front.iov_len;
+
+       /* verify fsid */
+       ceph_decode_need(&p, end, sizeof(fsid), bad);
+       ceph_decode_copy(&p, &fsid, sizeof(fsid));
+       if (ceph_check_fsid(osdc->client, &fsid) < 0)
+               return;
+
+       down_write(&osdc->map_sem);
+
+       /* incremental maps */
+       ceph_decode_32_safe(&p, end, nr_maps, bad);
+       dout(" %d inc maps\n", nr_maps);
+       while (nr_maps > 0) {
+               ceph_decode_need(&p, end, 2*sizeof(u32), bad);
+               epoch = ceph_decode_32(&p);
+               maplen = ceph_decode_32(&p);
+               ceph_decode_need(&p, end, maplen, bad);
+               next = p + maplen;
+               if (osdc->osdmap && osdc->osdmap->epoch+1 == epoch) {
+                       dout("applying incremental map %u len %d\n",
+                            epoch, maplen);
+                       newmap = osdmap_apply_incremental(&p, next,
+                                                         osdc->osdmap,
+                                                         osdc->client->msgr);
+                       if (IS_ERR(newmap)) {
+                               err = PTR_ERR(newmap);
+                               goto bad;
+                       }
+                       BUG_ON(!newmap);
+                       if (newmap != osdc->osdmap) {
+                               ceph_osdmap_destroy(osdc->osdmap);
+                               osdc->osdmap = newmap;
+                       }
+               } else {
+                       dout("ignoring incremental map %u len %d\n",
+                            epoch, maplen);
+               }
+               p = next;
+               nr_maps--;
+       }
+       if (newmap)
+               goto done;
+
+       /* full maps */
+       ceph_decode_32_safe(&p, end, nr_maps, bad);
+       dout(" %d full maps\n", nr_maps);
+       while (nr_maps) {
+               ceph_decode_need(&p, end, 2*sizeof(u32), bad);
+               epoch = ceph_decode_32(&p);
+               maplen = ceph_decode_32(&p);
+               ceph_decode_need(&p, end, maplen, bad);
+               if (nr_maps > 1) {
+                       dout("skipping non-latest full map %u len %d\n",
+                            epoch, maplen);
+               } else if (osdc->osdmap && osdc->osdmap->epoch >= epoch) {
+                       dout("skipping full map %u len %d, "
+                            "older than our %u\n", epoch, maplen,
+                            osdc->osdmap->epoch);
+               } else {
+                       dout("taking full map %u len %d\n", epoch, maplen);
+                       newmap = osdmap_decode(&p, p+maplen);
+                       if (IS_ERR(newmap)) {
+                               err = PTR_ERR(newmap);
+                               goto bad;
+                       }
+                       BUG_ON(!newmap);
+                       oldmap = osdc->osdmap;
+                       osdc->osdmap = newmap;
+                       if (oldmap)
+                               ceph_osdmap_destroy(oldmap);
+               }
+               p += maplen;
+               nr_maps--;
+       }
+
+done:
+       downgrade_write(&osdc->map_sem);
+       ceph_monc_got_osdmap(&osdc->client->monc, osdc->osdmap->epoch);
+       if (newmap)
+               kick_requests(osdc, NULL);
+       up_read(&osdc->map_sem);
+       return;
+
+bad:
+       pr_err("osdc handle_map corrupt msg\n");
+       ceph_msg_dump(msg);
+       up_write(&osdc->map_sem);
+       return;
+}
+
+
+/*
+ * A read request prepares specific pages that data is to be read into.
+ * When a message is being read off the wire, we call prepare_pages to
+ * find those pages.
+ *  0 = success, -1 failure.
+ */
+static int __prepare_pages(struct ceph_connection *con,
+                        struct ceph_msg_header *hdr,
+                        struct ceph_osd_request *req,
+                        u64 tid,
+                        struct ceph_msg *m)
+{
+       struct ceph_osd *osd = con->private;
+       struct ceph_osd_client *osdc;
+       int ret = -1;
+       int data_len = le32_to_cpu(hdr->data_len);
+       unsigned data_off = le16_to_cpu(hdr->data_off);
+
+       int want = calc_pages_for(data_off & ~PAGE_MASK, data_len);
+
+       if (!osd)
+               return -1;
+
+       osdc = osd->o_osdc;
+
+       dout("__prepare_pages on msg %p tid %llu, has %d pages, want %d\n", m,
+            tid, req->r_num_pages, want);
+       if (unlikely(req->r_num_pages < want))
+               goto out;
+       m->pages = req->r_pages;
+       m->nr_pages = req->r_num_pages;
+       ret = 0; /* success */
+out:
+       BUG_ON(ret < 0 || m->nr_pages < want);
+
+       return ret;
+}
+
+/*
+ * Register request, send initial attempt.
+ */
+int ceph_osdc_start_request(struct ceph_osd_client *osdc,
+                           struct ceph_osd_request *req,
+                           bool nofail)
+{
+       int rc = 0;
+
+       req->r_request->pages = req->r_pages;
+       req->r_request->nr_pages = req->r_num_pages;
+
+       register_request(osdc, req);
+
+       down_read(&osdc->map_sem);
+       mutex_lock(&osdc->request_mutex);
+       /*
+        * a racing kick_requests() may have sent the message for us
+        * while we dropped request_mutex above, so only send now if
+        * the request still han't been touched yet.
+        */
+       if (req->r_sent == 0) {
+               rc = __send_request(osdc, req);
+               if (rc) {
+                       if (nofail) {
+                               dout("osdc_start_request failed send, "
+                                    " marking %lld\n", req->r_tid);
+                               req->r_resend = true;
+                               rc = 0;
+                       } else {
+                               __unregister_request(osdc, req);
+                       }
+               }
+       }
+       mutex_unlock(&osdc->request_mutex);
+       up_read(&osdc->map_sem);
+       return rc;
+}
+
+/*
+ * wait for a request to complete
+ */
+int ceph_osdc_wait_request(struct ceph_osd_client *osdc,
+                          struct ceph_osd_request *req)
+{
+       int rc;
+
+       rc = wait_for_completion_interruptible(&req->r_completion);
+       if (rc < 0) {
+               mutex_lock(&osdc->request_mutex);
+               __cancel_request(req);
+               __unregister_request(osdc, req);
+               mutex_unlock(&osdc->request_mutex);
+               dout("wait_request tid %llu canceled/timed out\n", req->r_tid);
+               return rc;
+       }
+
+       dout("wait_request tid %llu result %d\n", req->r_tid, req->r_result);
+       return req->r_result;
+}
+
+/*
+ * sync - wait for all in-flight requests to flush.  avoid starvation.
+ */
+void ceph_osdc_sync(struct ceph_osd_client *osdc)
+{
+       struct ceph_osd_request *req;
+       u64 last_tid, next_tid = 0;
+
+       mutex_lock(&osdc->request_mutex);
+       last_tid = osdc->last_tid;
+       while (1) {
+               req = __lookup_request_ge(osdc, next_tid);
+               if (!req)
+                       break;
+               if (req->r_tid > last_tid)
+                       break;
+
+               next_tid = req->r_tid + 1;
+               if ((req->r_flags & CEPH_OSD_FLAG_WRITE) == 0)
+                       continue;
+
+               ceph_osdc_get_request(req);
+               mutex_unlock(&osdc->request_mutex);
+               dout("sync waiting on tid %llu (last is %llu)\n",
+                    req->r_tid, last_tid);
+               wait_for_completion(&req->r_safe_completion);
+               mutex_lock(&osdc->request_mutex);
+               ceph_osdc_put_request(req);
+       }
+       mutex_unlock(&osdc->request_mutex);
+       dout("sync done (thru tid %llu)\n", last_tid);
+}
+
+/*
+ * init, shutdown
+ */
+int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client)
+{
+       int err;
+
+       dout("init\n");
+       osdc->client = client;
+       osdc->osdmap = NULL;
+       init_rwsem(&osdc->map_sem);
+       init_completion(&osdc->map_waiters);
+       osdc->last_requested_map = 0;
+       mutex_init(&osdc->request_mutex);
+       osdc->last_tid = 0;
+       osdc->osds = RB_ROOT;
+       INIT_LIST_HEAD(&osdc->osd_lru);
+       osdc->requests = RB_ROOT;
+       INIT_LIST_HEAD(&osdc->req_lru);
+       osdc->num_requests = 0;
+       INIT_DELAYED_WORK(&osdc->timeout_work, handle_timeout);
+       INIT_DELAYED_WORK(&osdc->osds_timeout_work, handle_osds_timeout);
+
+       schedule_delayed_work(&osdc->osds_timeout_work,
+          round_jiffies_relative(osdc->client->mount_args->osd_idle_ttl * HZ));
+
+       err = -ENOMEM;
+       osdc->req_mempool = mempool_create_kmalloc_pool(10,
+                                       sizeof(struct ceph_osd_request));
+       if (!osdc->req_mempool)
+               goto out;
+
+       err = ceph_msgpool_init(&osdc->msgpool_op, OSD_OP_FRONT_LEN, 10, true);
+       if (err < 0)
+               goto out_mempool;
+       err = ceph_msgpool_init(&osdc->msgpool_op_reply,
+                               OSD_OPREPLY_FRONT_LEN, 10, true);
+       if (err < 0)
+               goto out_msgpool;
+       return 0;
+
+out_msgpool:
+       ceph_msgpool_destroy(&osdc->msgpool_op);
+out_mempool:
+       mempool_destroy(osdc->req_mempool);
+out:
+       return err;
+}
+
+void ceph_osdc_stop(struct ceph_osd_client *osdc)
+{
+       cancel_delayed_work_sync(&osdc->timeout_work);
+       cancel_delayed_work_sync(&osdc->osds_timeout_work);
+       if (osdc->osdmap) {
+               ceph_osdmap_destroy(osdc->osdmap);
+               osdc->osdmap = NULL;
+       }
+       remove_old_osds(osdc, 1);
+       mempool_destroy(osdc->req_mempool);
+       ceph_msgpool_destroy(&osdc->msgpool_op);
+       ceph_msgpool_destroy(&osdc->msgpool_op_reply);
+}
+
+/*
+ * Read some contiguous pages.  If we cross a stripe boundary, shorten
+ * *plen.  Return number of bytes read, or error.
+ */
+int ceph_osdc_readpages(struct ceph_osd_client *osdc,
+                       struct ceph_vino vino, struct ceph_file_layout *layout,
+                       u64 off, u64 *plen,
+                       u32 truncate_seq, u64 truncate_size,
+                       struct page **pages, int num_pages)
+{
+       struct ceph_osd_request *req;
+       int rc = 0;
+
+       dout("readpages on ino %llx.%llx on %llu~%llu\n", vino.ino,
+            vino.snap, off, *plen);
+       req = ceph_osdc_new_request(osdc, layout, vino, off, plen,
+                                   CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ,
+                                   NULL, 0, truncate_seq, truncate_size, NULL,
+                                   false, 1);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+
+       /* it may be a short read due to an object boundary */
+       req->r_pages = pages;
+       num_pages = calc_pages_for(off, *plen);
+       req->r_num_pages = num_pages;
+
+       dout("readpages  final extent is %llu~%llu (%d pages)\n",
+            off, *plen, req->r_num_pages);
+
+       rc = ceph_osdc_start_request(osdc, req, false);
+       if (!rc)
+               rc = ceph_osdc_wait_request(osdc, req);
+
+       ceph_osdc_put_request(req);
+       dout("readpages result %d\n", rc);
+       return rc;
+}
+
+/*
+ * do a synchronous write on N pages
+ */
+int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
+                        struct ceph_file_layout *layout,
+                        struct ceph_snap_context *snapc,
+                        u64 off, u64 len,
+                        u32 truncate_seq, u64 truncate_size,
+                        struct timespec *mtime,
+                        struct page **pages, int num_pages,
+                        int flags, int do_sync, bool nofail)
+{
+       struct ceph_osd_request *req;
+       int rc = 0;
+
+       BUG_ON(vino.snap != CEPH_NOSNAP);
+       req = ceph_osdc_new_request(osdc, layout, vino, off, &len,
+                                   CEPH_OSD_OP_WRITE,
+                                   flags | CEPH_OSD_FLAG_ONDISK |
+                                           CEPH_OSD_FLAG_WRITE,
+                                   snapc, do_sync,
+                                   truncate_seq, truncate_size, mtime,
+                                   nofail, 1);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+
+       /* it may be a short write due to an object boundary */
+       req->r_pages = pages;
+       req->r_num_pages = calc_pages_for(off, len);
+       dout("writepages %llu~%llu (%d pages)\n", off, len,
+            req->r_num_pages);
+
+       rc = ceph_osdc_start_request(osdc, req, nofail);
+       if (!rc)
+               rc = ceph_osdc_wait_request(osdc, req);
+
+       ceph_osdc_put_request(req);
+       if (rc == 0)
+               rc = len;
+       dout("writepages result %d\n", rc);
+       return rc;
+}
+
+/*
+ * handle incoming message
+ */
+static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
+{
+       struct ceph_osd *osd = con->private;
+       struct ceph_osd_client *osdc;
+       int type = le16_to_cpu(msg->hdr.type);
+
+       if (!osd)
+               return;
+       osdc = osd->o_osdc;
+
+       switch (type) {
+       case CEPH_MSG_OSD_MAP:
+               ceph_osdc_handle_map(osdc, msg);
+               break;
+       case CEPH_MSG_OSD_OPREPLY:
+               handle_reply(osdc, msg, con);
+               break;
+
+       default:
+               pr_err("received unknown message type %d %s\n", type,
+                      ceph_msg_type_name(type));
+       }
+       ceph_msg_put(msg);
+}
+
+/*
+ * lookup and return message for incoming reply
+ */
+static struct ceph_msg *get_reply(struct ceph_connection *con,
+                                 struct ceph_msg_header *hdr,
+                                 int *skip)
+{
+       struct ceph_osd *osd = con->private;
+       struct ceph_osd_client *osdc = osd->o_osdc;
+       struct ceph_msg *m;
+       struct ceph_osd_request *req;
+       int front = le32_to_cpu(hdr->front_len);
+       int data_len = le32_to_cpu(hdr->data_len);
+       u64 tid;
+       int err;
+
+       tid = le64_to_cpu(hdr->tid);
+       mutex_lock(&osdc->request_mutex);
+       req = __lookup_request(osdc, tid);
+       if (!req) {
+               *skip = 1;
+               m = NULL;
+               pr_info("get_reply unknown tid %llu from osd%d\n", tid,
+                       osd->o_osd);
+               goto out;
+       }
+
+       if (req->r_con_filling_msg) {
+               dout("get_reply revoking msg %p from old con %p\n",
+                    req->r_reply, req->r_con_filling_msg);
+               ceph_con_revoke_message(req->r_con_filling_msg, req->r_reply);
+               ceph_con_put(req->r_con_filling_msg);
+       }
+
+       if (front > req->r_reply->front.iov_len) {
+               pr_warning("get_reply front %d > preallocated %d\n",
+                          front, (int)req->r_reply->front.iov_len);
+               m = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, front, 0, 0, NULL);
+               if (IS_ERR(m))
+                       goto out;
+               ceph_msg_put(req->r_reply);
+               req->r_reply = m;
+       }
+       m = ceph_msg_get(req->r_reply);
+
+       if (data_len > 0) {
+               err = __prepare_pages(con, hdr, req, tid, m);
+               if (err < 0) {
+                       *skip = 1;
+                       ceph_msg_put(m);
+                       m = ERR_PTR(err);
+               }
+       }
+       *skip = 0;
+       req->r_con_filling_msg = ceph_con_get(con);
+       dout("get_reply tid %lld %p\n", tid, m);
+
+out:
+       mutex_unlock(&osdc->request_mutex);
+       return m;
+
+}
+
+static struct ceph_msg *alloc_msg(struct ceph_connection *con,
+                                 struct ceph_msg_header *hdr,
+                                 int *skip)
+{
+       struct ceph_osd *osd = con->private;
+       int type = le16_to_cpu(hdr->type);
+       int front = le32_to_cpu(hdr->front_len);
+
+       switch (type) {
+       case CEPH_MSG_OSD_MAP:
+               return ceph_msg_new(type, front, 0, 0, NULL);
+       case CEPH_MSG_OSD_OPREPLY:
+               return get_reply(con, hdr, skip);
+       default:
+               pr_info("alloc_msg unexpected msg type %d from osd%d\n", type,
+                       osd->o_osd);
+               *skip = 1;
+               return NULL;
+       }
+}
+
+/*
+ * Wrappers to refcount containing ceph_osd struct
+ */
+static struct ceph_connection *get_osd_con(struct ceph_connection *con)
+{
+       struct ceph_osd *osd = con->private;
+       if (get_osd(osd))
+               return con;
+       return NULL;
+}
+
+static void put_osd_con(struct ceph_connection *con)
+{
+       struct ceph_osd *osd = con->private;
+       put_osd(osd);
+}
+
+/*
+ * authentication
+ */
+static int get_authorizer(struct ceph_connection *con,
+                         void **buf, int *len, int *proto,
+                         void **reply_buf, int *reply_len, int force_new)
+{
+       struct ceph_osd *o = con->private;
+       struct ceph_osd_client *osdc = o->o_osdc;
+       struct ceph_auth_client *ac = osdc->client->monc.auth;
+       int ret = 0;
+
+       if (force_new && o->o_authorizer) {
+               ac->ops->destroy_authorizer(ac, o->o_authorizer);
+               o->o_authorizer = NULL;
+       }
+       if (o->o_authorizer == NULL) {
+               ret = ac->ops->create_authorizer(
+                       ac, CEPH_ENTITY_TYPE_OSD,
+                       &o->o_authorizer,
+                       &o->o_authorizer_buf,
+                       &o->o_authorizer_buf_len,
+                       &o->o_authorizer_reply_buf,
+                       &o->o_authorizer_reply_buf_len);
+               if (ret)
+               return ret;
+       }
+
+       *proto = ac->protocol;
+       *buf = o->o_authorizer_buf;
+       *len = o->o_authorizer_buf_len;
+       *reply_buf = o->o_authorizer_reply_buf;
+       *reply_len = o->o_authorizer_reply_buf_len;
+       return 0;
+}
+
+
+static int verify_authorizer_reply(struct ceph_connection *con, int len)
+{
+       struct ceph_osd *o = con->private;
+       struct ceph_osd_client *osdc = o->o_osdc;
+       struct ceph_auth_client *ac = osdc->client->monc.auth;
+
+       return ac->ops->verify_authorizer_reply(ac, o->o_authorizer, len);
+}
+
+static int invalidate_authorizer(struct ceph_connection *con)
+{
+       struct ceph_osd *o = con->private;
+       struct ceph_osd_client *osdc = o->o_osdc;
+       struct ceph_auth_client *ac = osdc->client->monc.auth;
+
+       if (ac->ops->invalidate_authorizer)
+               ac->ops->invalidate_authorizer(ac, CEPH_ENTITY_TYPE_OSD);
+
+       return ceph_monc_validate_auth(&osdc->client->monc);
+}
+
+const static struct ceph_connection_operations osd_con_ops = {
+       .get = get_osd_con,
+       .put = put_osd_con,
+       .dispatch = dispatch,
+       .get_authorizer = get_authorizer,
+       .verify_authorizer_reply = verify_authorizer_reply,
+       .invalidate_authorizer = invalidate_authorizer,
+       .alloc_msg = alloc_msg,
+       .fault = osd_reset,
+};
diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h
new file mode 100644 (file)
index 0000000..ce77698
--- /dev/null
@@ -0,0 +1,167 @@
+#ifndef _FS_CEPH_OSD_CLIENT_H
+#define _FS_CEPH_OSD_CLIENT_H
+
+#include <linux/completion.h>
+#include <linux/kref.h>
+#include <linux/mempool.h>
+#include <linux/rbtree.h>
+
+#include "types.h"
+#include "osdmap.h"
+#include "messenger.h"
+
+struct ceph_msg;
+struct ceph_snap_context;
+struct ceph_osd_request;
+struct ceph_osd_client;
+struct ceph_authorizer;
+
+/*
+ * completion callback for async writepages
+ */
+typedef void (*ceph_osdc_callback_t)(struct ceph_osd_request *,
+                                    struct ceph_msg *);
+
+/* a given osd we're communicating with */
+struct ceph_osd {
+       atomic_t o_ref;
+       struct ceph_osd_client *o_osdc;
+       int o_osd;
+       int o_incarnation;
+       struct rb_node o_node;
+       struct ceph_connection o_con;
+       struct list_head o_requests;
+       struct list_head o_osd_lru;
+       struct ceph_authorizer *o_authorizer;
+       void *o_authorizer_buf, *o_authorizer_reply_buf;
+       size_t o_authorizer_buf_len, o_authorizer_reply_buf_len;
+       unsigned long lru_ttl;
+       int o_marked_for_keepalive;
+       struct list_head o_keepalive_item;
+};
+
+/* an in-flight request */
+struct ceph_osd_request {
+       u64             r_tid;              /* unique for this client */
+       struct rb_node  r_node;
+       struct list_head r_req_lru_item;
+       struct list_head r_osd_item;
+       struct ceph_osd *r_osd;
+       struct ceph_pg   r_pgid;
+       int              r_pg_osds[CEPH_PG_MAX_SIZE];
+       int              r_num_pg_osds;
+
+       struct ceph_connection *r_con_filling_msg;
+
+       struct ceph_msg  *r_request, *r_reply;
+       int               r_result;
+       int               r_flags;     /* any additional flags for the osd */
+       u32               r_sent;      /* >0 if r_request is sending/sent */
+       int               r_got_reply;
+
+       struct ceph_osd_client *r_osdc;
+       struct kref       r_kref;
+       bool              r_mempool;
+       struct completion r_completion, r_safe_completion;
+       ceph_osdc_callback_t r_callback, r_safe_callback;
+       struct ceph_eversion r_reassert_version;
+       struct list_head  r_unsafe_item;
+
+       struct inode *r_inode;                /* for use by callbacks */
+
+       char              r_oid[40];          /* object name */
+       int               r_oid_len;
+       unsigned long     r_stamp;            /* send OR check time */
+       bool              r_resend;           /* msg send failed, needs retry */
+
+       struct ceph_file_layout r_file_layout;
+       struct ceph_snap_context *r_snapc;    /* snap context for writes */
+       unsigned          r_num_pages;        /* size of page array (follows) */
+       struct page     **r_pages;            /* pages for data payload */
+       int               r_pages_from_pool;
+       int               r_own_pages;        /* if true, i own page list */
+};
+
+struct ceph_osd_client {
+       struct ceph_client     *client;
+
+       struct ceph_osdmap     *osdmap;       /* current map */
+       struct rw_semaphore    map_sem;
+       struct completion      map_waiters;
+       u64                    last_requested_map;
+
+       struct mutex           request_mutex;
+       struct rb_root         osds;          /* osds */
+       struct list_head       osd_lru;       /* idle osds */
+       u64                    timeout_tid;   /* tid of timeout triggering rq */
+       u64                    last_tid;      /* tid of last request */
+       struct rb_root         requests;      /* pending requests */
+       struct list_head       req_lru;       /* pending requests lru */
+       int                    num_requests;
+       struct delayed_work    timeout_work;
+       struct delayed_work    osds_timeout_work;
+#ifdef CONFIG_DEBUG_FS
+       struct dentry          *debugfs_file;
+#endif
+
+       mempool_t              *req_mempool;
+
+       struct ceph_msgpool     msgpool_op;
+       struct ceph_msgpool     msgpool_op_reply;
+};
+
+extern int ceph_osdc_init(struct ceph_osd_client *osdc,
+                         struct ceph_client *client);
+extern void ceph_osdc_stop(struct ceph_osd_client *osdc);
+
+extern void ceph_osdc_handle_reply(struct ceph_osd_client *osdc,
+                                  struct ceph_msg *msg);
+extern void ceph_osdc_handle_map(struct ceph_osd_client *osdc,
+                                struct ceph_msg *msg);
+
+extern struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *,
+                                     struct ceph_file_layout *layout,
+                                     struct ceph_vino vino,
+                                     u64 offset, u64 *len, int op, int flags,
+                                     struct ceph_snap_context *snapc,
+                                     int do_sync, u32 truncate_seq,
+                                     u64 truncate_size,
+                                     struct timespec *mtime,
+                                     bool use_mempool, int num_reply);
+
+static inline void ceph_osdc_get_request(struct ceph_osd_request *req)
+{
+       kref_get(&req->r_kref);
+}
+extern void ceph_osdc_release_request(struct kref *kref);
+static inline void ceph_osdc_put_request(struct ceph_osd_request *req)
+{
+       kref_put(&req->r_kref, ceph_osdc_release_request);
+}
+
+extern int ceph_osdc_start_request(struct ceph_osd_client *osdc,
+                                  struct ceph_osd_request *req,
+                                  bool nofail);
+extern int ceph_osdc_wait_request(struct ceph_osd_client *osdc,
+                                 struct ceph_osd_request *req);
+extern void ceph_osdc_sync(struct ceph_osd_client *osdc);
+
+extern int ceph_osdc_readpages(struct ceph_osd_client *osdc,
+                              struct ceph_vino vino,
+                              struct ceph_file_layout *layout,
+                              u64 off, u64 *plen,
+                              u32 truncate_seq, u64 truncate_size,
+                              struct page **pages, int nr_pages);
+
+extern int ceph_osdc_writepages(struct ceph_osd_client *osdc,
+                               struct ceph_vino vino,
+                               struct ceph_file_layout *layout,
+                               struct ceph_snap_context *sc,
+                               u64 off, u64 len,
+                               u32 truncate_seq, u64 truncate_size,
+                               struct timespec *mtime,
+                               struct page **pages, int nr_pages,
+                               int flags, int do_sync, bool nofail);
+
+#endif
+
diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c
new file mode 100644 (file)
index 0000000..cfdd8f4
--- /dev/null
@@ -0,0 +1,1081 @@
+
+#include "ceph_debug.h"
+
+#include <linux/slab.h>
+#include <asm/div64.h>
+
+#include "super.h"
+#include "osdmap.h"
+#include "crush/hash.h"
+#include "crush/mapper.h"
+#include "decode.h"
+
+char *ceph_osdmap_state_str(char *str, int len, int state)
+{
+       int flag = 0;
+
+       if (!len)
+               goto done;
+
+       *str = '\0';
+       if (state) {
+               if (state & CEPH_OSD_EXISTS) {
+                       snprintf(str, len, "exists");
+                       flag = 1;
+               }
+               if (state & CEPH_OSD_UP) {
+                       snprintf(str, len, "%s%s%s", str, (flag ? ", " : ""),
+                                "up");
+                       flag = 1;
+               }
+       } else {
+               snprintf(str, len, "doesn't exist");
+       }
+done:
+       return str;
+}
+
+/* maps */
+
+static int calc_bits_of(unsigned t)
+{
+       int b = 0;
+       while (t) {
+               t = t >> 1;
+               b++;
+       }
+       return b;
+}
+
+/*
+ * the foo_mask is the smallest value 2^n-1 that is >= foo.
+ */
+static void calc_pg_masks(struct ceph_pg_pool_info *pi)
+{
+       pi->pg_num_mask = (1 << calc_bits_of(le32_to_cpu(pi->v.pg_num)-1)) - 1;
+       pi->pgp_num_mask =
+               (1 << calc_bits_of(le32_to_cpu(pi->v.pgp_num)-1)) - 1;
+       pi->lpg_num_mask =
+               (1 << calc_bits_of(le32_to_cpu(pi->v.lpg_num)-1)) - 1;
+       pi->lpgp_num_mask =
+               (1 << calc_bits_of(le32_to_cpu(pi->v.lpgp_num)-1)) - 1;
+}
+
+/*
+ * decode crush map
+ */
+static int crush_decode_uniform_bucket(void **p, void *end,
+                                      struct crush_bucket_uniform *b)
+{
+       dout("crush_decode_uniform_bucket %p to %p\n", *p, end);
+       ceph_decode_need(p, end, (1+b->h.size) * sizeof(u32), bad);
+       b->item_weight = ceph_decode_32(p);
+       return 0;
+bad:
+       return -EINVAL;
+}
+
+static int crush_decode_list_bucket(void **p, void *end,
+                                   struct crush_bucket_list *b)
+{
+       int j;
+       dout("crush_decode_list_bucket %p to %p\n", *p, end);
+       b->item_weights = kcalloc(b->h.size, sizeof(u32), GFP_NOFS);
+       if (b->item_weights == NULL)
+               return -ENOMEM;
+       b->sum_weights = kcalloc(b->h.size, sizeof(u32), GFP_NOFS);
+       if (b->sum_weights == NULL)
+               return -ENOMEM;
+       ceph_decode_need(p, end, 2 * b->h.size * sizeof(u32), bad);
+       for (j = 0; j < b->h.size; j++) {
+               b->item_weights[j] = ceph_decode_32(p);
+               b->sum_weights[j] = ceph_decode_32(p);
+       }
+       return 0;
+bad:
+       return -EINVAL;
+}
+
+static int crush_decode_tree_bucket(void **p, void *end,
+                                   struct crush_bucket_tree *b)
+{
+       int j;
+       dout("crush_decode_tree_bucket %p to %p\n", *p, end);
+       ceph_decode_32_safe(p, end, b->num_nodes, bad);
+       b->node_weights = kcalloc(b->num_nodes, sizeof(u32), GFP_NOFS);
+       if (b->node_weights == NULL)
+               return -ENOMEM;
+       ceph_decode_need(p, end, b->num_nodes * sizeof(u32), bad);
+       for (j = 0; j < b->num_nodes; j++)
+               b->node_weights[j] = ceph_decode_32(p);
+       return 0;
+bad:
+       return -EINVAL;
+}
+
+static int crush_decode_straw_bucket(void **p, void *end,
+                                    struct crush_bucket_straw *b)
+{
+       int j;
+       dout("crush_decode_straw_bucket %p to %p\n", *p, end);
+       b->item_weights = kcalloc(b->h.size, sizeof(u32), GFP_NOFS);
+       if (b->item_weights == NULL)
+               return -ENOMEM;
+       b->straws = kcalloc(b->h.size, sizeof(u32), GFP_NOFS);
+       if (b->straws == NULL)
+               return -ENOMEM;
+       ceph_decode_need(p, end, 2 * b->h.size * sizeof(u32), bad);
+       for (j = 0; j < b->h.size; j++) {
+               b->item_weights[j] = ceph_decode_32(p);
+               b->straws[j] = ceph_decode_32(p);
+       }
+       return 0;
+bad:
+       return -EINVAL;
+}
+
+static struct crush_map *crush_decode(void *pbyval, void *end)
+{
+       struct crush_map *c;
+       int err = -EINVAL;
+       int i, j;
+       void **p = &pbyval;
+       void *start = pbyval;
+       u32 magic;
+
+       dout("crush_decode %p to %p len %d\n", *p, end, (int)(end - *p));
+
+       c = kzalloc(sizeof(*c), GFP_NOFS);
+       if (c == NULL)
+               return ERR_PTR(-ENOMEM);
+
+       ceph_decode_need(p, end, 4*sizeof(u32), bad);
+       magic = ceph_decode_32(p);
+       if (magic != CRUSH_MAGIC) {
+               pr_err("crush_decode magic %x != current %x\n",
+                      (unsigned)magic, (unsigned)CRUSH_MAGIC);
+               goto bad;
+       }
+       c->max_buckets = ceph_decode_32(p);
+       c->max_rules = ceph_decode_32(p);
+       c->max_devices = ceph_decode_32(p);
+
+       c->device_parents = kcalloc(c->max_devices, sizeof(u32), GFP_NOFS);
+       if (c->device_parents == NULL)
+               goto badmem;
+       c->bucket_parents = kcalloc(c->max_buckets, sizeof(u32), GFP_NOFS);
+       if (c->bucket_parents == NULL)
+               goto badmem;
+
+       c->buckets = kcalloc(c->max_buckets, sizeof(*c->buckets), GFP_NOFS);
+       if (c->buckets == NULL)
+               goto badmem;
+       c->rules = kcalloc(c->max_rules, sizeof(*c->rules), GFP_NOFS);
+       if (c->rules == NULL)
+               goto badmem;
+
+       /* buckets */
+       for (i = 0; i < c->max_buckets; i++) {
+               int size = 0;
+               u32 alg;
+               struct crush_bucket *b;
+
+               ceph_decode_32_safe(p, end, alg, bad);
+               if (alg == 0) {
+                       c->buckets[i] = NULL;
+                       continue;
+               }
+               dout("crush_decode bucket %d off %x %p to %p\n",
+                    i, (int)(*p-start), *p, end);
+
+               switch (alg) {
+               case CRUSH_BUCKET_UNIFORM:
+                       size = sizeof(struct crush_bucket_uniform);
+                       break;
+               case CRUSH_BUCKET_LIST:
+                       size = sizeof(struct crush_bucket_list);
+                       break;
+               case CRUSH_BUCKET_TREE:
+                       size = sizeof(struct crush_bucket_tree);
+                       break;
+               case CRUSH_BUCKET_STRAW:
+                       size = sizeof(struct crush_bucket_straw);
+                       break;
+               default:
+                       err = -EINVAL;
+                       goto bad;
+               }
+               BUG_ON(size == 0);
+               b = c->buckets[i] = kzalloc(size, GFP_NOFS);
+               if (b == NULL)
+                       goto badmem;
+
+               ceph_decode_need(p, end, 4*sizeof(u32), bad);
+               b->id = ceph_decode_32(p);
+               b->type = ceph_decode_16(p);
+               b->alg = ceph_decode_8(p);
+               b->hash = ceph_decode_8(p);
+               b->weight = ceph_decode_32(p);
+               b->size = ceph_decode_32(p);
+
+               dout("crush_decode bucket size %d off %x %p to %p\n",
+                    b->size, (int)(*p-start), *p, end);
+
+               b->items = kcalloc(b->size, sizeof(__s32), GFP_NOFS);
+               if (b->items == NULL)
+                       goto badmem;
+               b->perm = kcalloc(b->size, sizeof(u32), GFP_NOFS);
+               if (b->perm == NULL)
+                       goto badmem;
+               b->perm_n = 0;
+
+               ceph_decode_need(p, end, b->size*sizeof(u32), bad);
+               for (j = 0; j < b->size; j++)
+                       b->items[j] = ceph_decode_32(p);
+
+               switch (b->alg) {
+               case CRUSH_BUCKET_UNIFORM:
+                       err = crush_decode_uniform_bucket(p, end,
+                                 (struct crush_bucket_uniform *)b);
+                       if (err < 0)
+                               goto bad;
+                       break;
+               case CRUSH_BUCKET_LIST:
+                       err = crush_decode_list_bucket(p, end,
+                              (struct crush_bucket_list *)b);
+                       if (err < 0)
+                               goto bad;
+                       break;
+               case CRUSH_BUCKET_TREE:
+                       err = crush_decode_tree_bucket(p, end,
+                               (struct crush_bucket_tree *)b);
+                       if (err < 0)
+                               goto bad;
+                       break;
+               case CRUSH_BUCKET_STRAW:
+                       err = crush_decode_straw_bucket(p, end,
+                               (struct crush_bucket_straw *)b);
+                       if (err < 0)
+                               goto bad;
+                       break;
+               }
+       }
+
+       /* rules */
+       dout("rule vec is %p\n", c->rules);
+       for (i = 0; i < c->max_rules; i++) {
+               u32 yes;
+               struct crush_rule *r;
+
+               ceph_decode_32_safe(p, end, yes, bad);
+               if (!yes) {
+                       dout("crush_decode NO rule %d off %x %p to %p\n",
+                            i, (int)(*p-start), *p, end);
+                       c->rules[i] = NULL;
+                       continue;
+               }
+
+               dout("crush_decode rule %d off %x %p to %p\n",
+                    i, (int)(*p-start), *p, end);
+
+               /* len */
+               ceph_decode_32_safe(p, end, yes, bad);
+#if BITS_PER_LONG == 32
+               err = -EINVAL;
+               if (yes > ULONG_MAX / sizeof(struct crush_rule_step))
+                       goto bad;
+#endif
+               r = c->rules[i] = kmalloc(sizeof(*r) +
+                                         yes*sizeof(struct crush_rule_step),
+                                         GFP_NOFS);
+               if (r == NULL)
+                       goto badmem;
+               dout(" rule %d is at %p\n", i, r);
+               r->len = yes;
+               ceph_decode_copy_safe(p, end, &r->mask, 4, bad); /* 4 u8's */
+               ceph_decode_need(p, end, r->len*3*sizeof(u32), bad);
+               for (j = 0; j < r->len; j++) {
+                       r->steps[j].op = ceph_decode_32(p);
+                       r->steps[j].arg1 = ceph_decode_32(p);
+                       r->steps[j].arg2 = ceph_decode_32(p);
+               }
+       }
+
+       /* ignore trailing name maps. */
+
+       dout("crush_decode success\n");
+       return c;
+
+badmem:
+       err = -ENOMEM;
+bad:
+       dout("crush_decode fail %d\n", err);
+       crush_destroy(c);
+       return ERR_PTR(err);
+}
+
+/*
+ * rbtree of pg_mapping for handling pg_temp (explicit mapping of pgid
+ * to a set of osds)
+ */
+static int pgid_cmp(struct ceph_pg l, struct ceph_pg r)
+{
+       u64 a = *(u64 *)&l;
+       u64 b = *(u64 *)&r;
+
+       if (a < b)
+               return -1;
+       if (a > b)
+               return 1;
+       return 0;
+}
+
+static int __insert_pg_mapping(struct ceph_pg_mapping *new,
+                              struct rb_root *root)
+{
+       struct rb_node **p = &root->rb_node;
+       struct rb_node *parent = NULL;
+       struct ceph_pg_mapping *pg = NULL;
+       int c;
+
+       while (*p) {
+               parent = *p;
+               pg = rb_entry(parent, struct ceph_pg_mapping, node);
+               c = pgid_cmp(new->pgid, pg->pgid);
+               if (c < 0)
+                       p = &(*p)->rb_left;
+               else if (c > 0)
+                       p = &(*p)->rb_right;
+               else
+                       return -EEXIST;
+       }
+
+       rb_link_node(&new->node, parent, p);
+       rb_insert_color(&new->node, root);
+       return 0;
+}
+
+static struct ceph_pg_mapping *__lookup_pg_mapping(struct rb_root *root,
+                                                  struct ceph_pg pgid)
+{
+       struct rb_node *n = root->rb_node;
+       struct ceph_pg_mapping *pg;
+       int c;
+
+       while (n) {
+               pg = rb_entry(n, struct ceph_pg_mapping, node);
+               c = pgid_cmp(pgid, pg->pgid);
+               if (c < 0)
+                       n = n->rb_left;
+               else if (c > 0)
+                       n = n->rb_right;
+               else
+                       return pg;
+       }
+       return NULL;
+}
+
+/*
+ * rbtree of pg pool info
+ */
+static int __insert_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *new)
+{
+       struct rb_node **p = &root->rb_node;
+       struct rb_node *parent = NULL;
+       struct ceph_pg_pool_info *pi = NULL;
+
+       while (*p) {
+               parent = *p;
+               pi = rb_entry(parent, struct ceph_pg_pool_info, node);
+               if (new->id < pi->id)
+                       p = &(*p)->rb_left;
+               else if (new->id > pi->id)
+                       p = &(*p)->rb_right;
+               else
+                       return -EEXIST;
+       }
+
+       rb_link_node(&new->node, parent, p);
+       rb_insert_color(&new->node, root);
+       return 0;
+}
+
+static struct ceph_pg_pool_info *__lookup_pg_pool(struct rb_root *root, int id)
+{
+       struct ceph_pg_pool_info *pi;
+       struct rb_node *n = root->rb_node;
+
+       while (n) {
+               pi = rb_entry(n, struct ceph_pg_pool_info, node);
+               if (id < pi->id)
+                       n = n->rb_left;
+               else if (id > pi->id)
+                       n = n->rb_right;
+               else
+                       return pi;
+       }
+       return NULL;
+}
+
+static void __remove_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *pi)
+{
+       rb_erase(&pi->node, root);
+       kfree(pi->name);
+       kfree(pi);
+}
+
+void __decode_pool(void **p, struct ceph_pg_pool_info *pi)
+{
+       ceph_decode_copy(p, &pi->v, sizeof(pi->v));
+       calc_pg_masks(pi);
+       *p += le32_to_cpu(pi->v.num_snaps) * sizeof(u64);
+       *p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2;
+}
+
+static int __decode_pool_names(void **p, void *end, struct ceph_osdmap *map)
+{
+       struct ceph_pg_pool_info *pi;
+       u32 num, len, pool;
+
+       ceph_decode_32_safe(p, end, num, bad);
+       dout(" %d pool names\n", num);
+       while (num--) {
+               ceph_decode_32_safe(p, end, pool, bad);
+               ceph_decode_32_safe(p, end, len, bad);
+               dout("  pool %d len %d\n", pool, len);
+               pi = __lookup_pg_pool(&map->pg_pools, pool);
+               if (pi) {
+                       kfree(pi->name);
+                       pi->name = kmalloc(len + 1, GFP_NOFS);
+                       if (pi->name) {
+                               memcpy(pi->name, *p, len);
+                               pi->name[len] = '\0';
+                               dout("  name is %s\n", pi->name);
+                       }
+               }
+               *p += len;
+       }
+       return 0;
+
+bad:
+       return -EINVAL;
+}
+
+/*
+ * osd map
+ */
+void ceph_osdmap_destroy(struct ceph_osdmap *map)
+{
+       dout("osdmap_destroy %p\n", map);
+       if (map->crush)
+               crush_destroy(map->crush);
+       while (!RB_EMPTY_ROOT(&map->pg_temp)) {
+               struct ceph_pg_mapping *pg =
+                       rb_entry(rb_first(&map->pg_temp),
+                                struct ceph_pg_mapping, node);
+               rb_erase(&pg->node, &map->pg_temp);
+               kfree(pg);
+       }
+       while (!RB_EMPTY_ROOT(&map->pg_pools)) {
+               struct ceph_pg_pool_info *pi =
+                       rb_entry(rb_first(&map->pg_pools),
+                                struct ceph_pg_pool_info, node);
+               __remove_pg_pool(&map->pg_pools, pi);
+       }
+       kfree(map->osd_state);
+       kfree(map->osd_weight);
+       kfree(map->osd_addr);
+       kfree(map);
+}
+
+/*
+ * adjust max osd value.  reallocate arrays.
+ */
+static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
+{
+       u8 *state;
+       struct ceph_entity_addr *addr;
+       u32 *weight;
+
+       state = kcalloc(max, sizeof(*state), GFP_NOFS);
+       addr = kcalloc(max, sizeof(*addr), GFP_NOFS);
+       weight = kcalloc(max, sizeof(*weight), GFP_NOFS);
+       if (state == NULL || addr == NULL || weight == NULL) {
+               kfree(state);
+               kfree(addr);
+               kfree(weight);
+               return -ENOMEM;
+       }
+
+       /* copy old? */
+       if (map->osd_state) {
+               memcpy(state, map->osd_state, map->max_osd*sizeof(*state));
+               memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr));
+               memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight));
+               kfree(map->osd_state);
+               kfree(map->osd_addr);
+               kfree(map->osd_weight);
+       }
+
+       map->osd_state = state;
+       map->osd_weight = weight;
+       map->osd_addr = addr;
+       map->max_osd = max;
+       return 0;
+}
+
+/*
+ * decode a full map.
+ */
+struct ceph_osdmap *osdmap_decode(void **p, void *end)
+{
+       struct ceph_osdmap *map;
+       u16 version;
+       u32 len, max, i;
+       u8 ev;
+       int err = -EINVAL;
+       void *start = *p;
+       struct ceph_pg_pool_info *pi;
+
+       dout("osdmap_decode %p to %p len %d\n", *p, end, (int)(end - *p));
+
+       map = kzalloc(sizeof(*map), GFP_NOFS);
+       if (map == NULL)
+               return ERR_PTR(-ENOMEM);
+       map->pg_temp = RB_ROOT;
+
+       ceph_decode_16_safe(p, end, version, bad);
+       if (version > CEPH_OSDMAP_VERSION) {
+               pr_warning("got unknown v %d > %d of osdmap\n", version,
+                          CEPH_OSDMAP_VERSION);
+               goto bad;
+       }
+
+       ceph_decode_need(p, end, 2*sizeof(u64)+6*sizeof(u32), bad);
+       ceph_decode_copy(p, &map->fsid, sizeof(map->fsid));
+       map->epoch = ceph_decode_32(p);
+       ceph_decode_copy(p, &map->created, sizeof(map->created));
+       ceph_decode_copy(p, &map->modified, sizeof(map->modified));
+
+       ceph_decode_32_safe(p, end, max, bad);
+       while (max--) {
+               ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad);
+               pi = kzalloc(sizeof(*pi), GFP_NOFS);
+               if (!pi)
+                       goto bad;
+               pi->id = ceph_decode_32(p);
+               ev = ceph_decode_8(p); /* encoding version */
+               if (ev > CEPH_PG_POOL_VERSION) {
+                       pr_warning("got unknown v %d > %d of ceph_pg_pool\n",
+                                  ev, CEPH_PG_POOL_VERSION);
+                       goto bad;
+               }
+               __decode_pool(p, pi);
+               __insert_pg_pool(&map->pg_pools, pi);
+       }
+
+       if (version >= 5 && __decode_pool_names(p, end, map) < 0)
+               goto bad;
+
+       ceph_decode_32_safe(p, end, map->pool_max, bad);
+
+       ceph_decode_32_safe(p, end, map->flags, bad);
+
+       max = ceph_decode_32(p);
+
+       /* (re)alloc osd arrays */
+       err = osdmap_set_max_osd(map, max);
+       if (err < 0)
+               goto bad;
+       dout("osdmap_decode max_osd = %d\n", map->max_osd);
+
+       /* osds */
+       err = -EINVAL;
+       ceph_decode_need(p, end, 3*sizeof(u32) +
+                        map->max_osd*(1 + sizeof(*map->osd_weight) +
+                                      sizeof(*map->osd_addr)), bad);
+       *p += 4; /* skip length field (should match max) */
+       ceph_decode_copy(p, map->osd_state, map->max_osd);
+
+       *p += 4; /* skip length field (should match max) */
+       for (i = 0; i < map->max_osd; i++)
+               map->osd_weight[i] = ceph_decode_32(p);
+
+       *p += 4; /* skip length field (should match max) */
+       ceph_decode_copy(p, map->osd_addr, map->max_osd*sizeof(*map->osd_addr));
+       for (i = 0; i < map->max_osd; i++)
+               ceph_decode_addr(&map->osd_addr[i]);
+
+       /* pg_temp */
+       ceph_decode_32_safe(p, end, len, bad);
+       for (i = 0; i < len; i++) {
+               int n, j;
+               struct ceph_pg pgid;
+               struct ceph_pg_mapping *pg;
+
+               ceph_decode_need(p, end, sizeof(u32) + sizeof(u64), bad);
+               ceph_decode_copy(p, &pgid, sizeof(pgid));
+               n = ceph_decode_32(p);
+               ceph_decode_need(p, end, n * sizeof(u32), bad);
+               err = -ENOMEM;
+               pg = kmalloc(sizeof(*pg) + n*sizeof(u32), GFP_NOFS);
+               if (!pg)
+                       goto bad;
+               pg->pgid = pgid;
+               pg->len = n;
+               for (j = 0; j < n; j++)
+                       pg->osds[j] = ceph_decode_32(p);
+
+               err = __insert_pg_mapping(pg, &map->pg_temp);
+               if (err)
+                       goto bad;
+               dout(" added pg_temp %llx len %d\n", *(u64 *)&pgid, len);
+       }
+
+       /* crush */
+       ceph_decode_32_safe(p, end, len, bad);
+       dout("osdmap_decode crush len %d from off 0x%x\n", len,
+            (int)(*p - start));
+       ceph_decode_need(p, end, len, bad);
+       map->crush = crush_decode(*p, end);
+       *p += len;
+       if (IS_ERR(map->crush)) {
+               err = PTR_ERR(map->crush);
+               map->crush = NULL;
+               goto bad;
+       }
+
+       /* ignore the rest of the map */
+       *p = end;
+
+       dout("osdmap_decode done %p %p\n", *p, end);
+       return map;
+
+bad:
+       dout("osdmap_decode fail\n");
+       ceph_osdmap_destroy(map);
+       return ERR_PTR(err);
+}
+
+/*
+ * decode and apply an incremental map update.
+ */
+struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
+                                            struct ceph_osdmap *map,
+                                            struct ceph_messenger *msgr)
+{
+       struct crush_map *newcrush = NULL;
+       struct ceph_fsid fsid;
+       u32 epoch = 0;
+       struct ceph_timespec modified;
+       u32 len, pool;
+       __s32 new_pool_max, new_flags, max;
+       void *start = *p;
+       int err = -EINVAL;
+       u16 version;
+       struct rb_node *rbp;
+
+       ceph_decode_16_safe(p, end, version, bad);
+       if (version > CEPH_OSDMAP_INC_VERSION) {
+               pr_warning("got unknown v %d > %d of inc osdmap\n", version,
+                          CEPH_OSDMAP_INC_VERSION);
+               goto bad;
+       }
+
+       ceph_decode_need(p, end, sizeof(fsid)+sizeof(modified)+2*sizeof(u32),
+                        bad);
+       ceph_decode_copy(p, &fsid, sizeof(fsid));
+       epoch = ceph_decode_32(p);
+       BUG_ON(epoch != map->epoch+1);
+       ceph_decode_copy(p, &modified, sizeof(modified));
+       new_pool_max = ceph_decode_32(p);
+       new_flags = ceph_decode_32(p);
+
+       /* full map? */
+       ceph_decode_32_safe(p, end, len, bad);
+       if (len > 0) {
+               dout("apply_incremental full map len %d, %p to %p\n",
+                    len, *p, end);
+               return osdmap_decode(p, min(*p+len, end));
+       }
+
+       /* new crush? */
+       ceph_decode_32_safe(p, end, len, bad);
+       if (len > 0) {
+               dout("apply_incremental new crush map len %d, %p to %p\n",
+                    len, *p, end);
+               newcrush = crush_decode(*p, min(*p+len, end));
+               if (IS_ERR(newcrush))
+                       return ERR_PTR(PTR_ERR(newcrush));
+       }
+
+       /* new flags? */
+       if (new_flags >= 0)
+               map->flags = new_flags;
+       if (new_pool_max >= 0)
+               map->pool_max = new_pool_max;
+
+       ceph_decode_need(p, end, 5*sizeof(u32), bad);
+
+       /* new max? */
+       max = ceph_decode_32(p);
+       if (max >= 0) {
+               err = osdmap_set_max_osd(map, max);
+               if (err < 0)
+                       goto bad;
+       }
+
+       map->epoch++;
+       map->modified = map->modified;
+       if (newcrush) {
+               if (map->crush)
+                       crush_destroy(map->crush);
+               map->crush = newcrush;
+               newcrush = NULL;
+       }
+
+       /* new_pool */
+       ceph_decode_32_safe(p, end, len, bad);
+       while (len--) {
+               __u8 ev;
+               struct ceph_pg_pool_info *pi;
+
+               ceph_decode_32_safe(p, end, pool, bad);
+               ceph_decode_need(p, end, 1 + sizeof(pi->v), bad);
+               ev = ceph_decode_8(p);  /* encoding version */
+               if (ev > CEPH_PG_POOL_VERSION) {
+                       pr_warning("got unknown v %d > %d of ceph_pg_pool\n",
+                                  ev, CEPH_PG_POOL_VERSION);
+                       goto bad;
+               }
+               pi = __lookup_pg_pool(&map->pg_pools, pool);
+               if (!pi) {
+                       pi = kzalloc(sizeof(*pi), GFP_NOFS);
+                       if (!pi) {
+                               err = -ENOMEM;
+                               goto bad;
+                       }
+                       pi->id = pool;
+                       __insert_pg_pool(&map->pg_pools, pi);
+               }
+               __decode_pool(p, pi);
+       }
+       if (version >= 5 && __decode_pool_names(p, end, map) < 0)
+               goto bad;
+
+       /* old_pool */
+       ceph_decode_32_safe(p, end, len, bad);
+       while (len--) {
+               struct ceph_pg_pool_info *pi;
+
+               ceph_decode_32_safe(p, end, pool, bad);
+               pi = __lookup_pg_pool(&map->pg_pools, pool);
+               if (pi)
+                       __remove_pg_pool(&map->pg_pools, pi);
+       }
+
+       /* new_up */
+       err = -EINVAL;
+       ceph_decode_32_safe(p, end, len, bad);
+       while (len--) {
+               u32 osd;
+               struct ceph_entity_addr addr;
+               ceph_decode_32_safe(p, end, osd, bad);
+               ceph_decode_copy_safe(p, end, &addr, sizeof(addr), bad);
+               ceph_decode_addr(&addr);
+               pr_info("osd%d up\n", osd);
+               BUG_ON(osd >= map->max_osd);
+               map->osd_state[osd] |= CEPH_OSD_UP;
+               map->osd_addr[osd] = addr;
+       }
+
+       /* new_down */
+       ceph_decode_32_safe(p, end, len, bad);
+       while (len--) {
+               u32 osd;
+               ceph_decode_32_safe(p, end, osd, bad);
+               (*p)++;  /* clean flag */
+               pr_info("osd%d down\n", osd);
+               if (osd < map->max_osd)
+                       map->osd_state[osd] &= ~CEPH_OSD_UP;
+       }
+
+       /* new_weight */
+       ceph_decode_32_safe(p, end, len, bad);
+       while (len--) {
+               u32 osd, off;
+               ceph_decode_need(p, end, sizeof(u32)*2, bad);
+               osd = ceph_decode_32(p);
+               off = ceph_decode_32(p);
+               pr_info("osd%d weight 0x%x %s\n", osd, off,
+                    off == CEPH_OSD_IN ? "(in)" :
+                    (off == CEPH_OSD_OUT ? "(out)" : ""));
+               if (osd < map->max_osd)
+                       map->osd_weight[osd] = off;
+       }
+
+       /* new_pg_temp */
+       rbp = rb_first(&map->pg_temp);
+       ceph_decode_32_safe(p, end, len, bad);
+       while (len--) {
+               struct ceph_pg_mapping *pg;
+               int j;
+               struct ceph_pg pgid;
+               u32 pglen;
+               ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad);
+               ceph_decode_copy(p, &pgid, sizeof(pgid));
+               pglen = ceph_decode_32(p);
+
+               /* remove any? */
+               while (rbp && pgid_cmp(rb_entry(rbp, struct ceph_pg_mapping,
+                                               node)->pgid, pgid) <= 0) {
+                       struct rb_node *cur = rbp;
+                       rbp = rb_next(rbp);
+                       dout(" removed pg_temp %llx\n",
+                            *(u64 *)&rb_entry(cur, struct ceph_pg_mapping,
+                                              node)->pgid);
+                       rb_erase(cur, &map->pg_temp);
+               }
+
+               if (pglen) {
+                       /* insert */
+                       ceph_decode_need(p, end, pglen*sizeof(u32), bad);
+                       pg = kmalloc(sizeof(*pg) + sizeof(u32)*pglen, GFP_NOFS);
+                       if (!pg) {
+                               err = -ENOMEM;
+                               goto bad;
+                       }
+                       pg->pgid = pgid;
+                       pg->len = pglen;
+                       for (j = 0; j < pglen; j++)
+                               pg->osds[j] = ceph_decode_32(p);
+                       err = __insert_pg_mapping(pg, &map->pg_temp);
+                       if (err)
+                               goto bad;
+                       dout(" added pg_temp %llx len %d\n", *(u64 *)&pgid,
+                            pglen);
+               }
+       }
+       while (rbp) {
+               struct rb_node *cur = rbp;
+               rbp = rb_next(rbp);
+               dout(" removed pg_temp %llx\n",
+                    *(u64 *)&rb_entry(cur, struct ceph_pg_mapping,
+                                      node)->pgid);
+               rb_erase(cur, &map->pg_temp);
+       }
+
+       /* ignore the rest */
+       *p = end;
+       return map;
+
+bad:
+       pr_err("corrupt inc osdmap epoch %d off %d (%p of %p-%p)\n",
+              epoch, (int)(*p - start), *p, start, end);
+       print_hex_dump(KERN_DEBUG, "osdmap: ",
+                      DUMP_PREFIX_OFFSET, 16, 1,
+                      start, end - start, true);
+       if (newcrush)
+               crush_destroy(newcrush);
+       return ERR_PTR(err);
+}
+
+
+
+
+/*
+ * calculate file layout from given offset, length.
+ * fill in correct oid, logical length, and object extent
+ * offset, length.
+ *
+ * for now, we write only a single su, until we can
+ * pass a stride back to the caller.
+ */
+void ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
+                                  u64 off, u64 *plen,
+                                  u64 *ono,
+                                  u64 *oxoff, u64 *oxlen)
+{
+       u32 osize = le32_to_cpu(layout->fl_object_size);
+       u32 su = le32_to_cpu(layout->fl_stripe_unit);
+       u32 sc = le32_to_cpu(layout->fl_stripe_count);
+       u32 bl, stripeno, stripepos, objsetno;
+       u32 su_per_object;
+       u64 t, su_offset;
+
+       dout("mapping %llu~%llu  osize %u fl_su %u\n", off, *plen,
+            osize, su);
+       su_per_object = osize / su;
+       dout("osize %u / su %u = su_per_object %u\n", osize, su,
+            su_per_object);
+
+       BUG_ON((su & ~PAGE_MASK) != 0);
+       /* bl = *off / su; */
+       t = off;
+       do_div(t, su);
+       bl = t;
+       dout("off %llu / su %u = bl %u\n", off, su, bl);
+
+       stripeno = bl / sc;
+       stripepos = bl % sc;
+       objsetno = stripeno / su_per_object;
+
+       *ono = objsetno * sc + stripepos;
+       dout("objset %u * sc %u = ono %u\n", objsetno, sc, (unsigned)*ono);
+
+       /* *oxoff = *off % layout->fl_stripe_unit;  # offset in su */
+       t = off;
+       su_offset = do_div(t, su);
+       *oxoff = su_offset + (stripeno % su_per_object) * su;
+
+       /*
+        * Calculate the length of the extent being written to the selected
+        * object. This is the minimum of the full length requested (plen) or
+        * the remainder of the current stripe being written to.
+        */
+       *oxlen = min_t(u64, *plen, su - su_offset);
+       *plen = *oxlen;
+
+       dout(" obj extent %llu~%llu\n", *oxoff, *oxlen);
+}
+
+/*
+ * calculate an object layout (i.e. pgid) from an oid,
+ * file_layout, and osdmap
+ */
+int ceph_calc_object_layout(struct ceph_object_layout *ol,
+                           const char *oid,
+                           struct ceph_file_layout *fl,
+                           struct ceph_osdmap *osdmap)
+{
+       unsigned num, num_mask;
+       struct ceph_pg pgid;
+       s32 preferred = (s32)le32_to_cpu(fl->fl_pg_preferred);
+       int poolid = le32_to_cpu(fl->fl_pg_pool);
+       struct ceph_pg_pool_info *pool;
+       unsigned ps;
+
+       BUG_ON(!osdmap);
+
+       pool = __lookup_pg_pool(&osdmap->pg_pools, poolid);
+       if (!pool)
+               return -EIO;
+       ps = ceph_str_hash(pool->v.object_hash, oid, strlen(oid));
+       if (preferred >= 0) {
+               ps += preferred;
+               num = le32_to_cpu(pool->v.lpg_num);
+               num_mask = pool->lpg_num_mask;
+       } else {
+               num = le32_to_cpu(pool->v.pg_num);
+               num_mask = pool->pg_num_mask;
+       }
+
+       pgid.ps = cpu_to_le16(ps);
+       pgid.preferred = cpu_to_le16(preferred);
+       pgid.pool = fl->fl_pg_pool;
+       if (preferred >= 0)
+               dout("calc_object_layout '%s' pgid %d.%xp%d\n", oid, poolid, ps,
+                    (int)preferred);
+       else
+               dout("calc_object_layout '%s' pgid %d.%x\n", oid, poolid, ps);
+
+       ol->ol_pgid = pgid;
+       ol->ol_stripe_unit = fl->fl_object_stripe_unit;
+       return 0;
+}
+
+/*
+ * Calculate raw osd vector for the given pgid.  Return pointer to osd
+ * array, or NULL on failure.
+ */
+static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
+                       int *osds, int *num)
+{
+       struct ceph_pg_mapping *pg;
+       struct ceph_pg_pool_info *pool;
+       int ruleno;
+       unsigned poolid, ps, pps;
+       int preferred;
+
+       /* pg_temp? */
+       pg = __lookup_pg_mapping(&osdmap->pg_temp, pgid);
+       if (pg) {
+               *num = pg->len;
+               return pg->osds;
+       }
+
+       /* crush */
+       poolid = le32_to_cpu(pgid.pool);
+       ps = le16_to_cpu(pgid.ps);
+       preferred = (s16)le16_to_cpu(pgid.preferred);
+
+       /* don't forcefeed bad device ids to crush */
+       if (preferred >= osdmap->max_osd ||
+           preferred >= osdmap->crush->max_devices)
+               preferred = -1;
+
+       pool = __lookup_pg_pool(&osdmap->pg_pools, poolid);
+       if (!pool)
+               return NULL;
+       ruleno = crush_find_rule(osdmap->crush, pool->v.crush_ruleset,
+                                pool->v.type, pool->v.size);
+       if (ruleno < 0) {
+               pr_err("no crush rule pool %d type %d size %d\n",
+                      poolid, pool->v.type, pool->v.size);
+               return NULL;
+       }
+
+       if (preferred >= 0)
+               pps = ceph_stable_mod(ps,
+                                     le32_to_cpu(pool->v.lpgp_num),
+                                     pool->lpgp_num_mask);
+       else
+               pps = ceph_stable_mod(ps,
+                                     le32_to_cpu(pool->v.pgp_num),
+                                     pool->pgp_num_mask);
+       pps += poolid;
+       *num = crush_do_rule(osdmap->crush, ruleno, pps, osds,
+                            min_t(int, pool->v.size, *num),
+                            preferred, osdmap->osd_weight);
+       return osds;
+}
+
+/*
+ * Return acting set for given pgid.
+ */
+int ceph_calc_pg_acting(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
+                       int *acting)
+{
+       int rawosds[CEPH_PG_MAX_SIZE], *osds;
+       int i, o, num = CEPH_PG_MAX_SIZE;
+
+       osds = calc_pg_raw(osdmap, pgid, rawosds, &num);
+       if (!osds)
+               return -1;
+
+       /* primary is first up osd */
+       o = 0;
+       for (i = 0; i < num; i++)
+               if (ceph_osd_is_up(osdmap, osds[i]))
+                       acting[o++] = osds[i];
+       return o;
+}
+
+/*
+ * Return primary osd for given pgid, or -1 if none.
+ */
+int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, struct ceph_pg pgid)
+{
+       int rawosds[CEPH_PG_MAX_SIZE], *osds;
+       int i, num = CEPH_PG_MAX_SIZE;
+
+       osds = calc_pg_raw(osdmap, pgid, rawosds, &num);
+       if (!osds)
+               return -1;
+
+       /* primary is first up osd */
+       for (i = 0; i < num; i++)
+               if (ceph_osd_is_up(osdmap, osds[i]))
+                       return osds[i];
+       return -1;
+}
diff --git a/fs/ceph/osdmap.h b/fs/ceph/osdmap.h
new file mode 100644 (file)
index 0000000..970b547
--- /dev/null
@@ -0,0 +1,128 @@
+#ifndef _FS_CEPH_OSDMAP_H
+#define _FS_CEPH_OSDMAP_H
+
+#include <linux/rbtree.h>
+#include "types.h"
+#include "ceph_fs.h"
+#include "crush/crush.h"
+
+/*
+ * The osd map describes the current membership of the osd cluster and
+ * specifies the mapping of objects to placement groups and placement
+ * groups to (sets of) osds.  That is, it completely specifies the
+ * (desired) distribution of all data objects in the system at some
+ * point in time.
+ *
+ * Each map version is identified by an epoch, which increases monotonically.
+ *
+ * The map can be updated either via an incremental map (diff) describing
+ * the change between two successive epochs, or as a fully encoded map.
+ */
+struct ceph_pg_pool_info {
+       struct rb_node node;
+       int id;
+       struct ceph_pg_pool v;
+       int pg_num_mask, pgp_num_mask, lpg_num_mask, lpgp_num_mask;
+       char *name;
+};
+
+struct ceph_pg_mapping {
+       struct rb_node node;
+       struct ceph_pg pgid;
+       int len;
+       int osds[];
+};
+
+struct ceph_osdmap {
+       struct ceph_fsid fsid;
+       u32 epoch;
+       u32 mkfs_epoch;
+       struct ceph_timespec created, modified;
+
+       u32 flags;         /* CEPH_OSDMAP_* */
+
+       u32 max_osd;       /* size of osd_state, _offload, _addr arrays */
+       u8 *osd_state;     /* CEPH_OSD_* */
+       u32 *osd_weight;   /* 0 = failed, 0x10000 = 100% normal */
+       struct ceph_entity_addr *osd_addr;
+
+       struct rb_root pg_temp;
+       struct rb_root pg_pools;
+       u32 pool_max;
+
+       /* the CRUSH map specifies the mapping of placement groups to
+        * the list of osds that store+replicate them. */
+       struct crush_map *crush;
+};
+
+/*
+ * file layout helpers
+ */
+#define ceph_file_layout_su(l) ((__s32)le32_to_cpu((l).fl_stripe_unit))
+#define ceph_file_layout_stripe_count(l) \
+       ((__s32)le32_to_cpu((l).fl_stripe_count))
+#define ceph_file_layout_object_size(l) ((__s32)le32_to_cpu((l).fl_object_size))
+#define ceph_file_layout_cas_hash(l) ((__s32)le32_to_cpu((l).fl_cas_hash))
+#define ceph_file_layout_object_su(l) \
+       ((__s32)le32_to_cpu((l).fl_object_stripe_unit))
+#define ceph_file_layout_pg_preferred(l) \
+       ((__s32)le32_to_cpu((l).fl_pg_preferred))
+#define ceph_file_layout_pg_pool(l) \
+       ((__s32)le32_to_cpu((l).fl_pg_pool))
+
+static inline unsigned ceph_file_layout_stripe_width(struct ceph_file_layout *l)
+{
+       return le32_to_cpu(l->fl_stripe_unit) *
+               le32_to_cpu(l->fl_stripe_count);
+}
+
+/* "period" == bytes before i start on a new set of objects */
+static inline unsigned ceph_file_layout_period(struct ceph_file_layout *l)
+{
+       return le32_to_cpu(l->fl_object_size) *
+               le32_to_cpu(l->fl_stripe_count);
+}
+
+
+static inline int ceph_osd_is_up(struct ceph_osdmap *map, int osd)
+{
+       return (osd < map->max_osd) && (map->osd_state[osd] & CEPH_OSD_UP);
+}
+
+static inline bool ceph_osdmap_flag(struct ceph_osdmap *map, int flag)
+{
+       return map && (map->flags & flag);
+}
+
+extern char *ceph_osdmap_state_str(char *str, int len, int state);
+
+static inline struct ceph_entity_addr *ceph_osd_addr(struct ceph_osdmap *map,
+                                                    int osd)
+{
+       if (osd >= map->max_osd)
+               return NULL;
+       return &map->osd_addr[osd];
+}
+
+extern struct ceph_osdmap *osdmap_decode(void **p, void *end);
+extern struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
+                                           struct ceph_osdmap *map,
+                                           struct ceph_messenger *msgr);
+extern void ceph_osdmap_destroy(struct ceph_osdmap *map);
+
+/* calculate mapping of a file extent to an object */
+extern void ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
+                                         u64 off, u64 *plen,
+                                         u64 *bno, u64 *oxoff, u64 *oxlen);
+
+/* calculate mapping of object to a placement group */
+extern int ceph_calc_object_layout(struct ceph_object_layout *ol,
+                                  const char *oid,
+                                  struct ceph_file_layout *fl,
+                                  struct ceph_osdmap *osdmap);
+extern int ceph_calc_pg_acting(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
+                              int *acting);
+extern int ceph_calc_pg_primary(struct ceph_osdmap *osdmap,
+                               struct ceph_pg pgid);
+
+#endif
diff --git a/fs/ceph/pagelist.c b/fs/ceph/pagelist.c
new file mode 100644 (file)
index 0000000..5f8dbf7
--- /dev/null
@@ -0,0 +1,55 @@
+
+#include <linux/gfp.h>
+#include <linux/pagemap.h>
+#include <linux/highmem.h>
+
+#include "pagelist.h"
+
+int ceph_pagelist_release(struct ceph_pagelist *pl)
+{
+       if (pl->mapped_tail)
+               kunmap(pl->mapped_tail);
+       while (!list_empty(&pl->head)) {
+               struct page *page = list_first_entry(&pl->head, struct page,
+                                                    lru);
+               list_del(&page->lru);
+               __free_page(page);
+       }
+       return 0;
+}
+
+static int ceph_pagelist_addpage(struct ceph_pagelist *pl)
+{
+       struct page *page = alloc_page(GFP_NOFS);
+       if (!page)
+               return -ENOMEM;
+       pl->room += PAGE_SIZE;
+       list_add_tail(&page->lru, &pl->head);
+       if (pl->mapped_tail)
+               kunmap(pl->mapped_tail);
+       pl->mapped_tail = kmap(page);
+       return 0;
+}
+
+int ceph_pagelist_append(struct ceph_pagelist *pl, void *buf, size_t len)
+{
+       while (pl->room < len) {
+               size_t bit = pl->room;
+               int ret;
+
+               memcpy(pl->mapped_tail + (pl->length & ~PAGE_CACHE_MASK),
+                      buf, bit);
+               pl->length += bit;
+               pl->room -= bit;
+               buf += bit;
+               len -= bit;
+               ret = ceph_pagelist_addpage(pl);
+               if (ret)
+                       return ret;
+       }
+
+       memcpy(pl->mapped_tail + (pl->length & ~PAGE_CACHE_MASK), buf, len);
+       pl->length += len;
+       pl->room -= len;
+       return 0;
+}
diff --git a/fs/ceph/pagelist.h b/fs/ceph/pagelist.h
new file mode 100644 (file)
index 0000000..e8a4187
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef __FS_CEPH_PAGELIST_H
+#define __FS_CEPH_PAGELIST_H
+
+#include <linux/list.h>
+
+struct ceph_pagelist {
+       struct list_head head;
+       void *mapped_tail;
+       size_t length;
+       size_t room;
+};
+
+static inline void ceph_pagelist_init(struct ceph_pagelist *pl)
+{
+       INIT_LIST_HEAD(&pl->head);
+       pl->mapped_tail = NULL;
+       pl->length = 0;
+       pl->room = 0;
+}
+extern int ceph_pagelist_release(struct ceph_pagelist *pl);
+
+extern int ceph_pagelist_append(struct ceph_pagelist *pl, void *d, size_t l);
+
+static inline int ceph_pagelist_encode_64(struct ceph_pagelist *pl, u64 v)
+{
+       __le64 ev = cpu_to_le64(v);
+       return ceph_pagelist_append(pl, &ev, sizeof(ev));
+}
+static inline int ceph_pagelist_encode_32(struct ceph_pagelist *pl, u32 v)
+{
+       __le32 ev = cpu_to_le32(v);
+       return ceph_pagelist_append(pl, &ev, sizeof(ev));
+}
+static inline int ceph_pagelist_encode_16(struct ceph_pagelist *pl, u16 v)
+{
+       __le16 ev = cpu_to_le16(v);
+       return ceph_pagelist_append(pl, &ev, sizeof(ev));
+}
+static inline int ceph_pagelist_encode_8(struct ceph_pagelist *pl, u8 v)
+{
+       return ceph_pagelist_append(pl, &v, 1);
+}
+static inline int ceph_pagelist_encode_string(struct ceph_pagelist *pl,
+                                             char *s, size_t len)
+{
+       int ret = ceph_pagelist_encode_32(pl, len);
+       if (ret)
+               return ret;
+       if (len)
+               return ceph_pagelist_append(pl, s, len);
+       return 0;
+}
+
+#endif
diff --git a/fs/ceph/rados.h b/fs/ceph/rados.h
new file mode 100644 (file)
index 0000000..fd56451
--- /dev/null
@@ -0,0 +1,377 @@
+#ifndef __RADOS_H
+#define __RADOS_H
+
+/*
+ * Data types for the Ceph distributed object storage layer RADOS
+ * (Reliable Autonomic Distributed Object Store).
+ */
+
+#include "msgr.h"
+
+/*
+ * osdmap encoding versions
+ */
+#define CEPH_OSDMAP_INC_VERSION     5
+#define CEPH_OSDMAP_INC_VERSION_EXT 5
+#define CEPH_OSDMAP_VERSION         5
+#define CEPH_OSDMAP_VERSION_EXT     5
+
+/*
+ * fs id
+ */
+struct ceph_fsid {
+       unsigned char fsid[16];
+};
+
+static inline int ceph_fsid_compare(const struct ceph_fsid *a,
+                                   const struct ceph_fsid *b)
+{
+       return memcmp(a, b, sizeof(*a));
+}
+
+/*
+ * ino, object, etc.
+ */
+typedef __le64 ceph_snapid_t;
+#define CEPH_SNAPDIR ((__u64)(-1))  /* reserved for hidden .snap dir */
+#define CEPH_NOSNAP  ((__u64)(-2))  /* "head", "live" revision */
+#define CEPH_MAXSNAP ((__u64)(-3))  /* largest valid snapid */
+
+struct ceph_timespec {
+       __le32 tv_sec;
+       __le32 tv_nsec;
+} __attribute__ ((packed));
+
+
+/*
+ * object layout - how objects are mapped into PGs
+ */
+#define CEPH_OBJECT_LAYOUT_HASH     1
+#define CEPH_OBJECT_LAYOUT_LINEAR   2
+#define CEPH_OBJECT_LAYOUT_HASHINO  3
+
+/*
+ * pg layout -- how PGs are mapped onto (sets of) OSDs
+ */
+#define CEPH_PG_LAYOUT_CRUSH  0
+#define CEPH_PG_LAYOUT_HASH   1
+#define CEPH_PG_LAYOUT_LINEAR 2
+#define CEPH_PG_LAYOUT_HYBRID 3
+
+#define CEPH_PG_MAX_SIZE      16  /* max # osds in a single pg */
+
+/*
+ * placement group.
+ * we encode this into one __le64.
+ */
+struct ceph_pg {
+       __le16 preferred; /* preferred primary osd */
+       __le16 ps;        /* placement seed */
+       __le32 pool;      /* object pool */
+} __attribute__ ((packed));
+
+/*
+ * pg_pool is a set of pgs storing a pool of objects
+ *
+ *  pg_num -- base number of pseudorandomly placed pgs
+ *
+ *  pgp_num -- effective number when calculating pg placement.  this
+ * is used for pg_num increases.  new pgs result in data being "split"
+ * into new pgs.  for this to proceed smoothly, new pgs are intiially
+ * colocated with their parents; that is, pgp_num doesn't increase
+ * until the new pgs have successfully split.  only _then_ are the new
+ * pgs placed independently.
+ *
+ *  lpg_num -- localized pg count (per device).  replicas are randomly
+ * selected.
+ *
+ *  lpgp_num -- as above.
+ */
+#define CEPH_PG_TYPE_REP     1
+#define CEPH_PG_TYPE_RAID4   2
+#define CEPH_PG_POOL_VERSION 2
+struct ceph_pg_pool {
+       __u8 type;                /* CEPH_PG_TYPE_* */
+       __u8 size;                /* number of osds in each pg */
+       __u8 crush_ruleset;       /* crush placement rule */
+       __u8 object_hash;         /* hash mapping object name to ps */
+       __le32 pg_num, pgp_num;   /* number of pg's */
+       __le32 lpg_num, lpgp_num; /* number of localized pg's */
+       __le32 last_change;       /* most recent epoch changed */
+       __le64 snap_seq;          /* seq for per-pool snapshot */
+       __le32 snap_epoch;        /* epoch of last snap */
+       __le32 num_snaps;
+       __le32 num_removed_snap_intervals;
+       __le64 uid;
+} __attribute__ ((packed));
+
+/*
+ * stable_mod func is used to control number of placement groups.
+ * similar to straight-up modulo, but produces a stable mapping as b
+ * increases over time.  b is the number of bins, and bmask is the
+ * containing power of 2 minus 1.
+ *
+ * b <= bmask and bmask=(2**n)-1
+ * e.g., b=12 -> bmask=15, b=123 -> bmask=127
+ */
+static inline int ceph_stable_mod(int x, int b, int bmask)
+{
+       if ((x & bmask) < b)
+               return x & bmask;
+       else
+               return x & (bmask >> 1);
+}
+
+/*
+ * object layout - how a given object should be stored.
+ */
+struct ceph_object_layout {
+       struct ceph_pg ol_pgid;   /* raw pg, with _full_ ps precision. */
+       __le32 ol_stripe_unit;    /* for per-object parity, if any */
+} __attribute__ ((packed));
+
+/*
+ * compound epoch+version, used by storage layer to serialize mutations
+ */
+struct ceph_eversion {
+       __le32 epoch;
+       __le64 version;
+} __attribute__ ((packed));
+
+/*
+ * osd map bits
+ */
+
+/* status bits */
+#define CEPH_OSD_EXISTS 1
+#define CEPH_OSD_UP     2
+
+/* osd weights.  fixed point value: 0x10000 == 1.0 ("in"), 0 == "out" */
+#define CEPH_OSD_IN  0x10000
+#define CEPH_OSD_OUT 0
+
+
+/*
+ * osd map flag bits
+ */
+#define CEPH_OSDMAP_NEARFULL (1<<0)  /* sync writes (near ENOSPC) */
+#define CEPH_OSDMAP_FULL     (1<<1)  /* no data writes (ENOSPC) */
+#define CEPH_OSDMAP_PAUSERD  (1<<2)  /* pause all reads */
+#define CEPH_OSDMAP_PAUSEWR  (1<<3)  /* pause all writes */
+#define CEPH_OSDMAP_PAUSEREC (1<<4)  /* pause recovery */
+
+/*
+ * osd ops
+ */
+#define CEPH_OSD_OP_MODE       0xf000
+#define CEPH_OSD_OP_MODE_RD    0x1000
+#define CEPH_OSD_OP_MODE_WR    0x2000
+#define CEPH_OSD_OP_MODE_RMW   0x3000
+#define CEPH_OSD_OP_MODE_SUB   0x4000
+
+#define CEPH_OSD_OP_TYPE       0x0f00
+#define CEPH_OSD_OP_TYPE_LOCK  0x0100
+#define CEPH_OSD_OP_TYPE_DATA  0x0200
+#define CEPH_OSD_OP_TYPE_ATTR  0x0300
+#define CEPH_OSD_OP_TYPE_EXEC  0x0400
+#define CEPH_OSD_OP_TYPE_PG    0x0500
+
+enum {
+       /** data **/
+       /* read */
+       CEPH_OSD_OP_READ      = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 1,
+       CEPH_OSD_OP_STAT      = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 2,
+
+       /* fancy read */
+       CEPH_OSD_OP_MASKTRUNC = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 4,
+
+       /* write */
+       CEPH_OSD_OP_WRITE     = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 1,
+       CEPH_OSD_OP_WRITEFULL = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 2,
+       CEPH_OSD_OP_TRUNCATE  = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 3,
+       CEPH_OSD_OP_ZERO      = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 4,
+       CEPH_OSD_OP_DELETE    = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 5,
+
+       /* fancy write */
+       CEPH_OSD_OP_APPEND    = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 6,
+       CEPH_OSD_OP_STARTSYNC = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 7,
+       CEPH_OSD_OP_SETTRUNC  = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 8,
+       CEPH_OSD_OP_TRIMTRUNC = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 9,
+
+       CEPH_OSD_OP_TMAPUP  = CEPH_OSD_OP_MODE_RMW | CEPH_OSD_OP_TYPE_DATA | 10,
+       CEPH_OSD_OP_TMAPPUT = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 11,
+       CEPH_OSD_OP_TMAPGET = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 12,
+
+       CEPH_OSD_OP_CREATE  = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 13,
+
+       /** attrs **/
+       /* read */
+       CEPH_OSD_OP_GETXATTR  = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_ATTR | 1,
+       CEPH_OSD_OP_GETXATTRS = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_ATTR | 2,
+
+       /* write */
+       CEPH_OSD_OP_SETXATTR  = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_ATTR | 1,
+       CEPH_OSD_OP_SETXATTRS = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_ATTR | 2,
+       CEPH_OSD_OP_RESETXATTRS = CEPH_OSD_OP_MODE_WR|CEPH_OSD_OP_TYPE_ATTR | 3,
+       CEPH_OSD_OP_RMXATTR   = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_ATTR | 4,
+
+       /** subop **/
+       CEPH_OSD_OP_PULL           = CEPH_OSD_OP_MODE_SUB | 1,
+       CEPH_OSD_OP_PUSH           = CEPH_OSD_OP_MODE_SUB | 2,
+       CEPH_OSD_OP_BALANCEREADS   = CEPH_OSD_OP_MODE_SUB | 3,
+       CEPH_OSD_OP_UNBALANCEREADS = CEPH_OSD_OP_MODE_SUB | 4,
+       CEPH_OSD_OP_SCRUB          = CEPH_OSD_OP_MODE_SUB | 5,
+
+       /** lock **/
+       CEPH_OSD_OP_WRLOCK    = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 1,
+       CEPH_OSD_OP_WRUNLOCK  = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 2,
+       CEPH_OSD_OP_RDLOCK    = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 3,
+       CEPH_OSD_OP_RDUNLOCK  = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 4,
+       CEPH_OSD_OP_UPLOCK    = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 5,
+       CEPH_OSD_OP_DNLOCK    = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 6,
+
+       /** exec **/
+       CEPH_OSD_OP_CALL    = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_EXEC | 1,
+
+       /** pg **/
+       CEPH_OSD_OP_PGLS      = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_PG | 1,
+};
+
+static inline int ceph_osd_op_type_lock(int op)
+{
+       return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_LOCK;
+}
+static inline int ceph_osd_op_type_data(int op)
+{
+       return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_DATA;
+}
+static inline int ceph_osd_op_type_attr(int op)
+{
+       return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_ATTR;
+}
+static inline int ceph_osd_op_type_exec(int op)
+{
+       return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_EXEC;
+}
+static inline int ceph_osd_op_type_pg(int op)
+{
+       return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_PG;
+}
+
+static inline int ceph_osd_op_mode_subop(int op)
+{
+       return (op & CEPH_OSD_OP_MODE) == CEPH_OSD_OP_MODE_SUB;
+}
+static inline int ceph_osd_op_mode_read(int op)
+{
+       return (op & CEPH_OSD_OP_MODE) == CEPH_OSD_OP_MODE_RD;
+}
+static inline int ceph_osd_op_mode_modify(int op)
+{
+       return (op & CEPH_OSD_OP_MODE) == CEPH_OSD_OP_MODE_WR;
+}
+
+#define CEPH_OSD_TMAP_HDR 'h'
+#define CEPH_OSD_TMAP_SET 's'
+#define CEPH_OSD_TMAP_RM  'r'
+
+extern const char *ceph_osd_op_name(int op);
+
+
+/*
+ * osd op flags
+ *
+ * An op may be READ, WRITE, or READ|WRITE.
+ */
+enum {
+       CEPH_OSD_FLAG_ACK = 1,          /* want (or is) "ack" ack */
+       CEPH_OSD_FLAG_ONNVRAM = 2,      /* want (or is) "onnvram" ack */
+       CEPH_OSD_FLAG_ONDISK = 4,       /* want (or is) "ondisk" ack */
+       CEPH_OSD_FLAG_RETRY = 8,        /* resend attempt */
+       CEPH_OSD_FLAG_READ = 16,        /* op may read */
+       CEPH_OSD_FLAG_WRITE = 32,       /* op may write */
+       CEPH_OSD_FLAG_ORDERSNAP = 64,   /* EOLDSNAP if snapc is out of order */
+       CEPH_OSD_FLAG_PEERSTAT = 128,   /* msg includes osd_peer_stat */
+       CEPH_OSD_FLAG_BALANCE_READS = 256,
+       CEPH_OSD_FLAG_PARALLELEXEC = 512, /* execute op in parallel */
+       CEPH_OSD_FLAG_PGOP = 1024,      /* pg op, no object */
+       CEPH_OSD_FLAG_EXEC = 2048,      /* op may exec */
+};
+
+enum {
+       CEPH_OSD_OP_FLAG_EXCL = 1,      /* EXCL object create */
+};
+
+#define EOLDSNAPC    ERESTART  /* ORDERSNAP flag set; writer has old snapc*/
+#define EBLACKLISTED ESHUTDOWN /* blacklisted */
+
+/*
+ * an individual object operation.  each may be accompanied by some data
+ * payload
+ */
+struct ceph_osd_op {
+       __le16 op;           /* CEPH_OSD_OP_* */
+       __le32 flags;        /* CEPH_OSD_FLAG_* */
+       union {
+               struct {
+                       __le64 offset, length;
+                       __le64 truncate_size;
+                       __le32 truncate_seq;
+               } __attribute__ ((packed)) extent;
+               struct {
+                       __le32 name_len;
+                       __le32 value_len;
+               } __attribute__ ((packed)) xattr;
+               struct {
+                       __u8 class_len;
+                       __u8 method_len;
+                       __u8 argc;
+                       __le32 indata_len;
+               } __attribute__ ((packed)) cls;
+               struct {
+                       __le64 cookie, count;
+               } __attribute__ ((packed)) pgls;
+       };
+       __le32 payload_len;
+} __attribute__ ((packed));
+
+/*
+ * osd request message header.  each request may include multiple
+ * ceph_osd_op object operations.
+ */
+struct ceph_osd_request_head {
+       __le32 client_inc;                 /* client incarnation */
+       struct ceph_object_layout layout;  /* pgid */
+       __le32 osdmap_epoch;               /* client's osdmap epoch */
+
+       __le32 flags;
+
+       struct ceph_timespec mtime;        /* for mutations only */
+       struct ceph_eversion reassert_version; /* if we are replaying op */
+
+       __le32 object_len;     /* length of object name */
+
+       __le64 snapid;         /* snapid to read */
+       __le64 snap_seq;       /* writer's snap context */
+       __le32 num_snaps;
+
+       __le16 num_ops;
+       struct ceph_osd_op ops[];  /* followed by ops[], obj, ticket, snaps */
+} __attribute__ ((packed));
+
+struct ceph_osd_reply_head {
+       __le32 client_inc;                /* client incarnation */
+       __le32 flags;
+       struct ceph_object_layout layout;
+       __le32 osdmap_epoch;
+       struct ceph_eversion reassert_version; /* for replaying uncommitted */
+
+       __le32 result;                    /* result code */
+
+       __le32 object_len;                /* length of object name */
+       __le32 num_ops;
+       struct ceph_osd_op ops[0];  /* ops[], object */
+} __attribute__ ((packed));
+
+
+#endif
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c
new file mode 100644 (file)
index 0000000..d5114db
--- /dev/null
@@ -0,0 +1,911 @@
+#include "ceph_debug.h"
+
+#include <linux/sort.h>
+#include <linux/slab.h>
+
+#include "super.h"
+#include "decode.h"
+
+/*
+ * Snapshots in ceph are driven in large part by cooperation from the
+ * client.  In contrast to local file systems or file servers that
+ * implement snapshots at a single point in the system, ceph's
+ * distributed access to storage requires clients to help decide
+ * whether a write logically occurs before or after a recently created
+ * snapshot.
+ *
+ * This provides a perfect instantanous client-wide snapshot.  Between
+ * clients, however, snapshots may appear to be applied at slightly
+ * different points in time, depending on delays in delivering the
+ * snapshot notification.
+ *
+ * Snapshots are _not_ file system-wide.  Instead, each snapshot
+ * applies to the subdirectory nested beneath some directory.  This
+ * effectively divides the hierarchy into multiple "realms," where all
+ * of the files contained by each realm share the same set of
+ * snapshots.  An individual realm's snap set contains snapshots
+ * explicitly created on that realm, as well as any snaps in its
+ * parent's snap set _after_ the point at which the parent became it's
+ * parent (due to, say, a rename).  Similarly, snaps from prior parents
+ * during the time intervals during which they were the parent are included.
+ *
+ * The client is spared most of this detail, fortunately... it must only
+ * maintains a hierarchy of realms reflecting the current parent/child
+ * realm relationship, and for each realm has an explicit list of snaps
+ * inherited from prior parents.
+ *
+ * A snap_realm struct is maintained for realms containing every inode
+ * with an open cap in the system.  (The needed snap realm information is
+ * provided by the MDS whenever a cap is issued, i.e., on open.)  A 'seq'
+ * version number is used to ensure that as realm parameters change (new
+ * snapshot, new parent, etc.) the client's realm hierarchy is updated.
+ *
+ * The realm hierarchy drives the generation of a 'snap context' for each
+ * realm, which simply lists the resulting set of snaps for the realm.  This
+ * is attached to any writes sent to OSDs.
+ */
+/*
+ * Unfortunately error handling is a bit mixed here.  If we get a snap
+ * update, but don't have enough memory to update our realm hierarchy,
+ * it's not clear what we can do about it (besides complaining to the
+ * console).
+ */
+
+
+/*
+ * increase ref count for the realm
+ *
+ * caller must hold snap_rwsem for write.
+ */
+void ceph_get_snap_realm(struct ceph_mds_client *mdsc,
+                        struct ceph_snap_realm *realm)
+{
+       dout("get_realm %p %d -> %d\n", realm,
+            atomic_read(&realm->nref), atomic_read(&realm->nref)+1);
+       /*
+        * since we _only_ increment realm refs or empty the empty
+        * list with snap_rwsem held, adjusting the empty list here is
+        * safe.  we do need to protect against concurrent empty list
+        * additions, however.
+        */
+       if (atomic_read(&realm->nref) == 0) {
+               spin_lock(&mdsc->snap_empty_lock);
+               list_del_init(&realm->empty_item);
+               spin_unlock(&mdsc->snap_empty_lock);
+       }
+
+       atomic_inc(&realm->nref);
+}
+
+static void __insert_snap_realm(struct rb_root *root,
+                               struct ceph_snap_realm *new)
+{
+       struct rb_node **p = &root->rb_node;
+       struct rb_node *parent = NULL;
+       struct ceph_snap_realm *r = NULL;
+
+       while (*p) {
+               parent = *p;
+               r = rb_entry(parent, struct ceph_snap_realm, node);
+               if (new->ino < r->ino)
+                       p = &(*p)->rb_left;
+               else if (new->ino > r->ino)
+                       p = &(*p)->rb_right;
+               else
+                       BUG();
+       }
+
+       rb_link_node(&new->node, parent, p);
+       rb_insert_color(&new->node, root);
+}
+
+/*
+ * create and get the realm rooted at @ino and bump its ref count.
+ *
+ * caller must hold snap_rwsem for write.
+ */
+static struct ceph_snap_realm *ceph_create_snap_realm(
+       struct ceph_mds_client *mdsc,
+       u64 ino)
+{
+       struct ceph_snap_realm *realm;
+
+       realm = kzalloc(sizeof(*realm), GFP_NOFS);
+       if (!realm)
+               return ERR_PTR(-ENOMEM);
+
+       atomic_set(&realm->nref, 0);    /* tree does not take a ref */
+       realm->ino = ino;
+       INIT_LIST_HEAD(&realm->children);
+       INIT_LIST_HEAD(&realm->child_item);
+       INIT_LIST_HEAD(&realm->empty_item);
+       INIT_LIST_HEAD(&realm->inodes_with_caps);
+       spin_lock_init(&realm->inodes_with_caps_lock);
+       __insert_snap_realm(&mdsc->snap_realms, realm);
+       dout("create_snap_realm %llx %p\n", realm->ino, realm);
+       return realm;
+}
+
+/*
+ * lookup the realm rooted at @ino.
+ *
+ * caller must hold snap_rwsem for write.
+ */
+struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc,
+                                              u64 ino)
+{
+       struct rb_node *n = mdsc->snap_realms.rb_node;
+       struct ceph_snap_realm *r;
+
+       while (n) {
+               r = rb_entry(n, struct ceph_snap_realm, node);
+               if (ino < r->ino)
+                       n = n->rb_left;
+               else if (ino > r->ino)
+                       n = n->rb_right;
+               else {
+                       dout("lookup_snap_realm %llx %p\n", r->ino, r);
+                       return r;
+               }
+       }
+       return NULL;
+}
+
+static void __put_snap_realm(struct ceph_mds_client *mdsc,
+                            struct ceph_snap_realm *realm);
+
+/*
+ * called with snap_rwsem (write)
+ */
+static void __destroy_snap_realm(struct ceph_mds_client *mdsc,
+                                struct ceph_snap_realm *realm)
+{
+       dout("__destroy_snap_realm %p %llx\n", realm, realm->ino);
+
+       rb_erase(&realm->node, &mdsc->snap_realms);
+
+       if (realm->parent) {
+               list_del_init(&realm->child_item);
+               __put_snap_realm(mdsc, realm->parent);
+       }
+
+       kfree(realm->prior_parent_snaps);
+       kfree(realm->snaps);
+       ceph_put_snap_context(realm->cached_context);
+       kfree(realm);
+}
+
+/*
+ * caller holds snap_rwsem (write)
+ */
+static void __put_snap_realm(struct ceph_mds_client *mdsc,
+                            struct ceph_snap_realm *realm)
+{
+       dout("__put_snap_realm %llx %p %d -> %d\n", realm->ino, realm,
+            atomic_read(&realm->nref), atomic_read(&realm->nref)-1);
+       if (atomic_dec_and_test(&realm->nref))
+               __destroy_snap_realm(mdsc, realm);
+}
+
+/*
+ * caller needn't hold any locks
+ */
+void ceph_put_snap_realm(struct ceph_mds_client *mdsc,
+                        struct ceph_snap_realm *realm)
+{
+       dout("put_snap_realm %llx %p %d -> %d\n", realm->ino, realm,
+            atomic_read(&realm->nref), atomic_read(&realm->nref)-1);
+       if (!atomic_dec_and_test(&realm->nref))
+               return;
+
+       if (down_write_trylock(&mdsc->snap_rwsem)) {
+               __destroy_snap_realm(mdsc, realm);
+               up_write(&mdsc->snap_rwsem);
+       } else {
+               spin_lock(&mdsc->snap_empty_lock);
+               list_add(&mdsc->snap_empty, &realm->empty_item);
+               spin_unlock(&mdsc->snap_empty_lock);
+       }
+}
+
+/*
+ * Clean up any realms whose ref counts have dropped to zero.  Note
+ * that this does not include realms who were created but not yet
+ * used.
+ *
+ * Called under snap_rwsem (write)
+ */
+static void __cleanup_empty_realms(struct ceph_mds_client *mdsc)
+{
+       struct ceph_snap_realm *realm;
+
+       spin_lock(&mdsc->snap_empty_lock);
+       while (!list_empty(&mdsc->snap_empty)) {
+               realm = list_first_entry(&mdsc->snap_empty,
+                                  struct ceph_snap_realm, empty_item);
+               list_del(&realm->empty_item);
+               spin_unlock(&mdsc->snap_empty_lock);
+               __destroy_snap_realm(mdsc, realm);
+               spin_lock(&mdsc->snap_empty_lock);
+       }
+       spin_unlock(&mdsc->snap_empty_lock);
+}
+
+void ceph_cleanup_empty_realms(struct ceph_mds_client *mdsc)
+{
+       down_write(&mdsc->snap_rwsem);
+       __cleanup_empty_realms(mdsc);
+       up_write(&mdsc->snap_rwsem);
+}
+
+/*
+ * adjust the parent realm of a given @realm.  adjust child list, and parent
+ * pointers, and ref counts appropriately.
+ *
+ * return true if parent was changed, 0 if unchanged, <0 on error.
+ *
+ * caller must hold snap_rwsem for write.
+ */
+static int adjust_snap_realm_parent(struct ceph_mds_client *mdsc,
+                                   struct ceph_snap_realm *realm,
+                                   u64 parentino)
+{
+       struct ceph_snap_realm *parent;
+
+       if (realm->parent_ino == parentino)
+               return 0;
+
+       parent = ceph_lookup_snap_realm(mdsc, parentino);
+       if (!parent) {
+               parent = ceph_create_snap_realm(mdsc, parentino);
+               if (IS_ERR(parent))
+                       return PTR_ERR(parent);
+       }
+       dout("adjust_snap_realm_parent %llx %p: %llx %p -> %llx %p\n",
+            realm->ino, realm, realm->parent_ino, realm->parent,
+            parentino, parent);
+       if (realm->parent) {
+               list_del_init(&realm->child_item);
+               ceph_put_snap_realm(mdsc, realm->parent);
+       }
+       realm->parent_ino = parentino;
+       realm->parent = parent;
+       ceph_get_snap_realm(mdsc, parent);
+       list_add(&realm->child_item, &parent->children);
+       return 1;
+}
+
+
+static int cmpu64_rev(const void *a, const void *b)
+{
+       if (*(u64 *)a < *(u64 *)b)
+               return 1;
+       if (*(u64 *)a > *(u64 *)b)
+               return -1;
+       return 0;
+}
+
+/*
+ * build the snap context for a given realm.
+ */
+static int build_snap_context(struct ceph_snap_realm *realm)
+{
+       struct ceph_snap_realm *parent = realm->parent;
+       struct ceph_snap_context *snapc;
+       int err = 0;
+       int i;
+       int num = realm->num_prior_parent_snaps + realm->num_snaps;
+
+       /*
+        * build parent context, if it hasn't been built.
+        * conservatively estimate that all parent snaps might be
+        * included by us.
+        */
+       if (parent) {
+               if (!parent->cached_context) {
+                       err = build_snap_context(parent);
+                       if (err)
+                               goto fail;
+               }
+               num += parent->cached_context->num_snaps;
+       }
+
+       /* do i actually need to update?  not if my context seq
+          matches realm seq, and my parents' does to.  (this works
+          because we rebuild_snap_realms() works _downward_ in
+          hierarchy after each update.) */
+       if (realm->cached_context &&
+           realm->cached_context->seq == realm->seq &&
+           (!parent ||
+            realm->cached_context->seq >= parent->cached_context->seq)) {
+               dout("build_snap_context %llx %p: %p seq %lld (%d snaps)"
+                    " (unchanged)\n",
+                    realm->ino, realm, realm->cached_context,
+                    realm->cached_context->seq,
+                    realm->cached_context->num_snaps);
+               return 0;
+       }
+
+       /* alloc new snap context */
+       err = -ENOMEM;
+       if (num > ULONG_MAX / sizeof(u64) - sizeof(*snapc))
+               goto fail;
+       snapc = kzalloc(sizeof(*snapc) + num*sizeof(u64), GFP_NOFS);
+       if (!snapc)
+               goto fail;
+       atomic_set(&snapc->nref, 1);
+
+       /* build (reverse sorted) snap vector */
+       num = 0;
+       snapc->seq = realm->seq;
+       if (parent) {
+               /* include any of parent's snaps occuring _after_ my
+                  parent became my parent */
+               for (i = 0; i < parent->cached_context->num_snaps; i++)
+                       if (parent->cached_context->snaps[i] >=
+                           realm->parent_since)
+                               snapc->snaps[num++] =
+                                       parent->cached_context->snaps[i];
+               if (parent->cached_context->seq > snapc->seq)
+                       snapc->seq = parent->cached_context->seq;
+       }
+       memcpy(snapc->snaps + num, realm->snaps,
+              sizeof(u64)*realm->num_snaps);
+       num += realm->num_snaps;
+       memcpy(snapc->snaps + num, realm->prior_parent_snaps,
+              sizeof(u64)*realm->num_prior_parent_snaps);
+       num += realm->num_prior_parent_snaps;
+
+       sort(snapc->snaps, num, sizeof(u64), cmpu64_rev, NULL);
+       snapc->num_snaps = num;
+       dout("build_snap_context %llx %p: %p seq %lld (%d snaps)\n",
+            realm->ino, realm, snapc, snapc->seq, snapc->num_snaps);
+
+       if (realm->cached_context)
+               ceph_put_snap_context(realm->cached_context);
+       realm->cached_context = snapc;
+       return 0;
+
+fail:
+       /*
+        * if we fail, clear old (incorrect) cached_context... hopefully
+        * we'll have better luck building it later
+        */
+       if (realm->cached_context) {
+               ceph_put_snap_context(realm->cached_context);
+               realm->cached_context = NULL;
+       }
+       pr_err("build_snap_context %llx %p fail %d\n", realm->ino,
+              realm, err);
+       return err;
+}
+
+/*
+ * rebuild snap context for the given realm and all of its children.
+ */
+static void rebuild_snap_realms(struct ceph_snap_realm *realm)
+{
+       struct ceph_snap_realm *child;
+
+       dout("rebuild_snap_realms %llx %p\n", realm->ino, realm);
+       build_snap_context(realm);
+
+       list_for_each_entry(child, &realm->children, child_item)
+               rebuild_snap_realms(child);
+}
+
+
+/*
+ * helper to allocate and decode an array of snapids.  free prior
+ * instance, if any.
+ */
+static int dup_array(u64 **dst, __le64 *src, int num)
+{
+       int i;
+
+       kfree(*dst);
+       if (num) {
+               *dst = kcalloc(num, sizeof(u64), GFP_NOFS);
+               if (!*dst)
+                       return -ENOMEM;
+               for (i = 0; i < num; i++)
+                       (*dst)[i] = get_unaligned_le64(src + i);
+       } else {
+               *dst = NULL;
+       }
+       return 0;
+}
+
+
+/*
+ * When a snapshot is applied, the size/mtime inode metadata is queued
+ * in a ceph_cap_snap (one for each snapshot) until writeback
+ * completes and the metadata can be flushed back to the MDS.
+ *
+ * However, if a (sync) write is currently in-progress when we apply
+ * the snapshot, we have to wait until the write succeeds or fails
+ * (and a final size/mtime is known).  In this case the
+ * cap_snap->writing = 1, and is said to be "pending."  When the write
+ * finishes, we __ceph_finish_cap_snap().
+ *
+ * Caller must hold snap_rwsem for read (i.e., the realm topology won't
+ * change).
+ */
+void ceph_queue_cap_snap(struct ceph_inode_info *ci)
+{
+       struct inode *inode = &ci->vfs_inode;
+       struct ceph_cap_snap *capsnap;
+       int used;
+
+       capsnap = kzalloc(sizeof(*capsnap), GFP_NOFS);
+       if (!capsnap) {
+               pr_err("ENOMEM allocating ceph_cap_snap on %p\n", inode);
+               return;
+       }
+
+       spin_lock(&inode->i_lock);
+       used = __ceph_caps_used(ci);
+       if (__ceph_have_pending_cap_snap(ci)) {
+               /* there is no point in queuing multiple "pending" cap_snaps,
+                  as no new writes are allowed to start when pending, so any
+                  writes in progress now were started before the previous
+                  cap_snap.  lucky us. */
+               dout("queue_cap_snap %p already pending\n", inode);
+               kfree(capsnap);
+       } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR)) {
+               struct ceph_snap_context *snapc = ci->i_head_snapc;
+
+               igrab(inode);
+
+               atomic_set(&capsnap->nref, 1);
+               capsnap->ci = ci;
+               INIT_LIST_HEAD(&capsnap->ci_item);
+               INIT_LIST_HEAD(&capsnap->flushing_item);
+
+               capsnap->follows = snapc->seq - 1;
+               capsnap->issued = __ceph_caps_issued(ci, NULL);
+               capsnap->dirty = __ceph_caps_dirty(ci);
+
+               capsnap->mode = inode->i_mode;
+               capsnap->uid = inode->i_uid;
+               capsnap->gid = inode->i_gid;
+
+               /* fixme? */
+               capsnap->xattr_blob = NULL;
+               capsnap->xattr_len = 0;
+
+               /* dirty page count moved from _head to this cap_snap;
+                  all subsequent writes page dirties occur _after_ this
+                  snapshot. */
+               capsnap->dirty_pages = ci->i_wrbuffer_ref_head;
+               ci->i_wrbuffer_ref_head = 0;
+               capsnap->context = snapc;
+               ci->i_head_snapc = NULL;
+               list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps);
+
+               if (used & CEPH_CAP_FILE_WR) {
+                       dout("queue_cap_snap %p cap_snap %p snapc %p"
+                            " seq %llu used WR, now pending\n", inode,
+                            capsnap, snapc, snapc->seq);
+                       capsnap->writing = 1;
+               } else {
+                       /* note mtime, size NOW. */
+                       __ceph_finish_cap_snap(ci, capsnap);
+               }
+       } else {
+               dout("queue_cap_snap %p nothing dirty|writing\n", inode);
+               kfree(capsnap);
+       }
+
+       spin_unlock(&inode->i_lock);
+}
+
+/*
+ * Finalize the size, mtime for a cap_snap.. that is, settle on final values
+ * to be used for the snapshot, to be flushed back to the mds.
+ *
+ * If capsnap can now be flushed, add to snap_flush list, and return 1.
+ *
+ * Caller must hold i_lock.
+ */
+int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
+                           struct ceph_cap_snap *capsnap)
+{
+       struct inode *inode = &ci->vfs_inode;
+       struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc;
+
+       BUG_ON(capsnap->writing);
+       capsnap->size = inode->i_size;
+       capsnap->mtime = inode->i_mtime;
+       capsnap->atime = inode->i_atime;
+       capsnap->ctime = inode->i_ctime;
+       capsnap->time_warp_seq = ci->i_time_warp_seq;
+       if (capsnap->dirty_pages) {
+               dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu "
+                    "still has %d dirty pages\n", inode, capsnap,
+                    capsnap->context, capsnap->context->seq,
+                    ceph_cap_string(capsnap->dirty), capsnap->size,
+                    capsnap->dirty_pages);
+               return 0;
+       }
+       dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu\n",
+            inode, capsnap, capsnap->context,
+            capsnap->context->seq, ceph_cap_string(capsnap->dirty),
+            capsnap->size);
+
+       spin_lock(&mdsc->snap_flush_lock);
+       list_add_tail(&ci->i_snap_flush_item, &mdsc->snap_flush_list);
+       spin_unlock(&mdsc->snap_flush_lock);
+       return 1;  /* caller may want to ceph_flush_snaps */
+}
+
+
+/*
+ * Parse and apply a snapblob "snap trace" from the MDS.  This specifies
+ * the snap realm parameters from a given realm and all of its ancestors,
+ * up to the root.
+ *
+ * Caller must hold snap_rwsem for write.
+ */
+int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
+                          void *p, void *e, bool deletion)
+{
+       struct ceph_mds_snap_realm *ri;    /* encoded */
+       __le64 *snaps;                     /* encoded */
+       __le64 *prior_parent_snaps;        /* encoded */
+       struct ceph_snap_realm *realm;
+       int invalidate = 0;
+       int err = -ENOMEM;
+
+       dout("update_snap_trace deletion=%d\n", deletion);
+more:
+       ceph_decode_need(&p, e, sizeof(*ri), bad);
+       ri = p;
+       p += sizeof(*ri);
+       ceph_decode_need(&p, e, sizeof(u64)*(le32_to_cpu(ri->num_snaps) +
+                           le32_to_cpu(ri->num_prior_parent_snaps)), bad);
+       snaps = p;
+       p += sizeof(u64) * le32_to_cpu(ri->num_snaps);
+       prior_parent_snaps = p;
+       p += sizeof(u64) * le32_to_cpu(ri->num_prior_parent_snaps);
+
+       realm = ceph_lookup_snap_realm(mdsc, le64_to_cpu(ri->ino));
+       if (!realm) {
+               realm = ceph_create_snap_realm(mdsc, le64_to_cpu(ri->ino));
+               if (IS_ERR(realm)) {
+                       err = PTR_ERR(realm);
+                       goto fail;
+               }
+       }
+
+       if (le64_to_cpu(ri->seq) > realm->seq) {
+               dout("update_snap_trace updating %llx %p %lld -> %lld\n",
+                    realm->ino, realm, realm->seq, le64_to_cpu(ri->seq));
+               /*
+                * if the realm seq has changed, queue a cap_snap for every
+                * inode with open caps.  we do this _before_ we update
+                * the realm info so that we prepare for writeback under the
+                * _previous_ snap context.
+                *
+                * ...unless it's a snap deletion!
+                */
+               if (!deletion) {
+                       struct ceph_inode_info *ci;
+                       struct inode *lastinode = NULL;
+
+                       spin_lock(&realm->inodes_with_caps_lock);
+                       list_for_each_entry(ci, &realm->inodes_with_caps,
+                                           i_snap_realm_item) {
+                               struct inode *inode = igrab(&ci->vfs_inode);
+                               if (!inode)
+                                       continue;
+                               spin_unlock(&realm->inodes_with_caps_lock);
+                               if (lastinode)
+                                       iput(lastinode);
+                               lastinode = inode;
+                               ceph_queue_cap_snap(ci);
+                               spin_lock(&realm->inodes_with_caps_lock);
+                       }
+                       spin_unlock(&realm->inodes_with_caps_lock);
+                       if (lastinode)
+                               iput(lastinode);
+                       dout("update_snap_trace cap_snaps queued\n");
+               }
+
+       } else {
+               dout("update_snap_trace %llx %p seq %lld unchanged\n",
+                    realm->ino, realm, realm->seq);
+       }
+
+       /* ensure the parent is correct */
+       err = adjust_snap_realm_parent(mdsc, realm, le64_to_cpu(ri->parent));
+       if (err < 0)
+               goto fail;
+       invalidate += err;
+
+       if (le64_to_cpu(ri->seq) > realm->seq) {
+               /* update realm parameters, snap lists */
+               realm->seq = le64_to_cpu(ri->seq);
+               realm->created = le64_to_cpu(ri->created);
+               realm->parent_since = le64_to_cpu(ri->parent_since);
+
+               realm->num_snaps = le32_to_cpu(ri->num_snaps);
+               err = dup_array(&realm->snaps, snaps, realm->num_snaps);
+               if (err < 0)
+                       goto fail;
+
+               realm->num_prior_parent_snaps =
+                       le32_to_cpu(ri->num_prior_parent_snaps);
+               err = dup_array(&realm->prior_parent_snaps, prior_parent_snaps,
+                               realm->num_prior_parent_snaps);
+               if (err < 0)
+                       goto fail;
+
+               invalidate = 1;
+       } else if (!realm->cached_context) {
+               invalidate = 1;
+       }
+
+       dout("done with %llx %p, invalidated=%d, %p %p\n", realm->ino,
+            realm, invalidate, p, e);
+
+       if (p < e)
+               goto more;
+
+       /* invalidate when we reach the _end_ (root) of the trace */
+       if (invalidate)
+               rebuild_snap_realms(realm);
+
+       __cleanup_empty_realms(mdsc);
+       return 0;
+
+bad:
+       err = -EINVAL;
+fail:
+       pr_err("update_snap_trace error %d\n", err);
+       return err;
+}
+
+
+/*
+ * Send any cap_snaps that are queued for flush.  Try to carry
+ * s_mutex across multiple snap flushes to avoid locking overhead.
+ *
+ * Caller holds no locks.
+ */
+static void flush_snaps(struct ceph_mds_client *mdsc)
+{
+       struct ceph_inode_info *ci;
+       struct inode *inode;
+       struct ceph_mds_session *session = NULL;
+
+       dout("flush_snaps\n");
+       spin_lock(&mdsc->snap_flush_lock);
+       while (!list_empty(&mdsc->snap_flush_list)) {
+               ci = list_first_entry(&mdsc->snap_flush_list,
+                               struct ceph_inode_info, i_snap_flush_item);
+               inode = &ci->vfs_inode;
+               igrab(inode);
+               spin_unlock(&mdsc->snap_flush_lock);
+               spin_lock(&inode->i_lock);
+               __ceph_flush_snaps(ci, &session);
+               spin_unlock(&inode->i_lock);
+               iput(inode);
+               spin_lock(&mdsc->snap_flush_lock);
+       }
+       spin_unlock(&mdsc->snap_flush_lock);
+
+       if (session) {
+               mutex_unlock(&session->s_mutex);
+               ceph_put_mds_session(session);
+       }
+       dout("flush_snaps done\n");
+}
+
+
+/*
+ * Handle a snap notification from the MDS.
+ *
+ * This can take two basic forms: the simplest is just a snap creation
+ * or deletion notification on an existing realm.  This should update the
+ * realm and its children.
+ *
+ * The more difficult case is realm creation, due to snap creation at a
+ * new point in the file hierarchy, or due to a rename that moves a file or
+ * directory into another realm.
+ */
+void ceph_handle_snap(struct ceph_mds_client *mdsc,
+                     struct ceph_mds_session *session,
+                     struct ceph_msg *msg)
+{
+       struct super_block *sb = mdsc->client->sb;
+       int mds = session->s_mds;
+       u64 split;
+       int op;
+       int trace_len;
+       struct ceph_snap_realm *realm = NULL;
+       void *p = msg->front.iov_base;
+       void *e = p + msg->front.iov_len;
+       struct ceph_mds_snap_head *h;
+       int num_split_inos, num_split_realms;
+       __le64 *split_inos = NULL, *split_realms = NULL;
+       int i;
+       int locked_rwsem = 0;
+
+       /* decode */
+       if (msg->front.iov_len < sizeof(*h))
+               goto bad;
+       h = p;
+       op = le32_to_cpu(h->op);
+       split = le64_to_cpu(h->split);   /* non-zero if we are splitting an
+                                         * existing realm */
+       num_split_inos = le32_to_cpu(h->num_split_inos);
+       num_split_realms = le32_to_cpu(h->num_split_realms);
+       trace_len = le32_to_cpu(h->trace_len);
+       p += sizeof(*h);
+
+       dout("handle_snap from mds%d op %s split %llx tracelen %d\n", mds,
+            ceph_snap_op_name(op), split, trace_len);
+
+       mutex_lock(&session->s_mutex);
+       session->s_seq++;
+       mutex_unlock(&session->s_mutex);
+
+       down_write(&mdsc->snap_rwsem);
+       locked_rwsem = 1;
+
+       if (op == CEPH_SNAP_OP_SPLIT) {
+               struct ceph_mds_snap_realm *ri;
+
+               /*
+                * A "split" breaks part of an existing realm off into
+                * a new realm.  The MDS provides a list of inodes
+                * (with caps) and child realms that belong to the new
+                * child.
+                */
+               split_inos = p;
+               p += sizeof(u64) * num_split_inos;
+               split_realms = p;
+               p += sizeof(u64) * num_split_realms;
+               ceph_decode_need(&p, e, sizeof(*ri), bad);
+               /* we will peek at realm info here, but will _not_
+                * advance p, as the realm update will occur below in
+                * ceph_update_snap_trace. */
+               ri = p;
+
+               realm = ceph_lookup_snap_realm(mdsc, split);
+               if (!realm) {
+                       realm = ceph_create_snap_realm(mdsc, split);
+                       if (IS_ERR(realm))
+                               goto out;
+               }
+               ceph_get_snap_realm(mdsc, realm);
+
+               dout("splitting snap_realm %llx %p\n", realm->ino, realm);
+               for (i = 0; i < num_split_inos; i++) {
+                       struct ceph_vino vino = {
+                               .ino = le64_to_cpu(split_inos[i]),
+                               .snap = CEPH_NOSNAP,
+                       };
+                       struct inode *inode = ceph_find_inode(sb, vino);
+                       struct ceph_inode_info *ci;
+
+                       if (!inode)
+                               continue;
+                       ci = ceph_inode(inode);
+
+                       spin_lock(&inode->i_lock);
+                       if (!ci->i_snap_realm)
+                               goto skip_inode;
+                       /*
+                        * If this inode belongs to a realm that was
+                        * created after our new realm, we experienced
+                        * a race (due to another split notifications
+                        * arriving from a different MDS).  So skip
+                        * this inode.
+                        */
+                       if (ci->i_snap_realm->created >
+                           le64_to_cpu(ri->created)) {
+                               dout(" leaving %p in newer realm %llx %p\n",
+                                    inode, ci->i_snap_realm->ino,
+                                    ci->i_snap_realm);
+                               goto skip_inode;
+                       }
+                       dout(" will move %p to split realm %llx %p\n",
+                            inode, realm->ino, realm);
+                       /*
+                        * Remove the inode from the realm's inode
+                        * list, but don't add it to the new realm
+                        * yet.  We don't want the cap_snap to be
+                        * queued (again) by ceph_update_snap_trace()
+                        * below.  Queue it _now_, under the old context.
+                        */
+                       spin_lock(&realm->inodes_with_caps_lock);
+                       list_del_init(&ci->i_snap_realm_item);
+                       spin_unlock(&realm->inodes_with_caps_lock);
+                       spin_unlock(&inode->i_lock);
+
+                       ceph_queue_cap_snap(ci);
+
+                       iput(inode);
+                       continue;
+
+skip_inode:
+                       spin_unlock(&inode->i_lock);
+                       iput(inode);
+               }
+
+               /* we may have taken some of the old realm's children. */
+               for (i = 0; i < num_split_realms; i++) {
+                       struct ceph_snap_realm *child =
+                               ceph_lookup_snap_realm(mdsc,
+                                          le64_to_cpu(split_realms[i]));
+                       if (!child)
+                               continue;
+                       adjust_snap_realm_parent(mdsc, child, realm->ino);
+               }
+       }
+
+       /*
+        * update using the provided snap trace. if we are deleting a
+        * snap, we can avoid queueing cap_snaps.
+        */
+       ceph_update_snap_trace(mdsc, p, e,
+                              op == CEPH_SNAP_OP_DESTROY);
+
+       if (op == CEPH_SNAP_OP_SPLIT) {
+               /*
+                * ok, _now_ add the inodes into the new realm.
+                */
+               for (i = 0; i < num_split_inos; i++) {
+                       struct ceph_vino vino = {
+                               .ino = le64_to_cpu(split_inos[i]),
+                               .snap = CEPH_NOSNAP,
+                       };
+                       struct inode *inode = ceph_find_inode(sb, vino);
+                       struct ceph_inode_info *ci;
+
+                       if (!inode)
+                               continue;
+                       ci = ceph_inode(inode);
+                       spin_lock(&inode->i_lock);
+                       if (list_empty(&ci->i_snap_realm_item)) {
+                               struct ceph_snap_realm *oldrealm =
+                                       ci->i_snap_realm;
+
+                               dout(" moving %p to split realm %llx %p\n",
+                                    inode, realm->ino, realm);
+                               spin_lock(&realm->inodes_with_caps_lock);
+                               list_add(&ci->i_snap_realm_item,
+                                        &realm->inodes_with_caps);
+                               ci->i_snap_realm = realm;
+                               spin_unlock(&realm->inodes_with_caps_lock);
+                               ceph_get_snap_realm(mdsc, realm);
+                               ceph_put_snap_realm(mdsc, oldrealm);
+                       }
+                       spin_unlock(&inode->i_lock);
+                       iput(inode);
+               }
+
+               /* we took a reference when we created the realm, above */
+               ceph_put_snap_realm(mdsc, realm);
+       }
+
+       __cleanup_empty_realms(mdsc);
+
+       up_write(&mdsc->snap_rwsem);
+
+       flush_snaps(mdsc);
+       return;
+
+bad:
+       pr_err("corrupt snap message from mds%d\n", mds);
+       ceph_msg_dump(msg);
+out:
+       if (locked_rwsem)
+               up_write(&mdsc->snap_rwsem);
+       return;
+}
+
+
+
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
new file mode 100644 (file)
index 0000000..110857b
--- /dev/null
@@ -0,0 +1,1041 @@
+
+#include "ceph_debug.h"
+
+#include <linux/backing-dev.h>
+#include <linux/fs.h>
+#include <linux/inet.h>
+#include <linux/in6.h>
+#include <linux/module.h>
+#include <linux/mount.h>
+#include <linux/parser.h>
+#include <linux/rwsem.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/statfs.h>
+#include <linux/string.h>
+#include <linux/version.h>
+#include <linux/vmalloc.h>
+
+#include "decode.h"
+#include "super.h"
+#include "mon_client.h"
+#include "auth.h"
+
+/*
+ * Ceph superblock operations
+ *
+ * Handle the basics of mounting, unmounting.
+ */
+
+
+/*
+ * find filename portion of a path (/foo/bar/baz -> baz)
+ */
+const char *ceph_file_part(const char *s, int len)
+{
+       const char *e = s + len;
+
+       while (e != s && *(e-1) != '/')
+               e--;
+       return e;
+}
+
+
+/*
+ * super ops
+ */
+static void ceph_put_super(struct super_block *s)
+{
+       struct ceph_client *client = ceph_sb_to_client(s);
+
+       dout("put_super\n");
+       ceph_mdsc_close_sessions(&client->mdsc);
+
+       /*
+        * ensure we release the bdi before put_anon_super releases
+        * the device name.
+        */
+       if (s->s_bdi == &client->backing_dev_info) {
+               bdi_unregister(&client->backing_dev_info);
+               s->s_bdi = NULL;
+       }
+
+       return;
+}
+
+static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+       struct ceph_client *client = ceph_inode_to_client(dentry->d_inode);
+       struct ceph_monmap *monmap = client->monc.monmap;
+       struct ceph_statfs st;
+       u64 fsid;
+       int err;
+
+       dout("statfs\n");
+       err = ceph_monc_do_statfs(&client->monc, &st);
+       if (err < 0)
+               return err;
+
+       /* fill in kstatfs */
+       buf->f_type = CEPH_SUPER_MAGIC;  /* ?? */
+
+       /*
+        * express utilization in terms of large blocks to avoid
+        * overflow on 32-bit machines.
+        */
+       buf->f_bsize = 1 << CEPH_BLOCK_SHIFT;
+       buf->f_blocks = le64_to_cpu(st.kb) >> (CEPH_BLOCK_SHIFT-10);
+       buf->f_bfree = (le64_to_cpu(st.kb) - le64_to_cpu(st.kb_used)) >>
+               (CEPH_BLOCK_SHIFT-10);
+       buf->f_bavail = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);
+
+       buf->f_files = le64_to_cpu(st.num_objects);
+       buf->f_ffree = -1;
+       buf->f_namelen = PATH_MAX;
+       buf->f_frsize = PAGE_CACHE_SIZE;
+
+       /* leave fsid little-endian, regardless of host endianness */
+       fsid = *(u64 *)(&monmap->fsid) ^ *((u64 *)&monmap->fsid + 1);
+       buf->f_fsid.val[0] = fsid & 0xffffffff;
+       buf->f_fsid.val[1] = fsid >> 32;
+
+       return 0;
+}
+
+
+static int ceph_syncfs(struct super_block *sb, int wait)
+{
+       dout("sync_fs %d\n", wait);
+       ceph_osdc_sync(&ceph_client(sb)->osdc);
+       ceph_mdsc_sync(&ceph_client(sb)->mdsc);
+       dout("sync_fs %d done\n", wait);
+       return 0;
+}
+
+
+/**
+ * ceph_show_options - Show mount options in /proc/mounts
+ * @m: seq_file to write to
+ * @mnt: mount descriptor
+ */
+static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt)
+{
+       struct ceph_client *client = ceph_sb_to_client(mnt->mnt_sb);
+       struct ceph_mount_args *args = client->mount_args;
+
+       if (args->flags & CEPH_OPT_FSID)
+               seq_printf(m, ",fsidmajor=%llu,fsidminor%llu",
+                          le64_to_cpu(*(__le64 *)&args->fsid.fsid[0]),
+                          le64_to_cpu(*(__le64 *)&args->fsid.fsid[8]));
+       if (args->flags & CEPH_OPT_NOSHARE)
+               seq_puts(m, ",noshare");
+       if (args->flags & CEPH_OPT_DIRSTAT)
+               seq_puts(m, ",dirstat");
+       if ((args->flags & CEPH_OPT_RBYTES) == 0)
+               seq_puts(m, ",norbytes");
+       if (args->flags & CEPH_OPT_NOCRC)
+               seq_puts(m, ",nocrc");
+       if (args->flags & CEPH_OPT_NOASYNCREADDIR)
+               seq_puts(m, ",noasyncreaddir");
+       if (strcmp(args->snapdir_name, CEPH_SNAPDIRNAME_DEFAULT))
+               seq_printf(m, ",snapdirname=%s", args->snapdir_name);
+       if (args->name)
+               seq_printf(m, ",name=%s", args->name);
+       if (args->secret)
+               seq_puts(m, ",secret=<hidden>");
+       return 0;
+}
+
+/*
+ * caches
+ */
+struct kmem_cache *ceph_inode_cachep;
+struct kmem_cache *ceph_cap_cachep;
+struct kmem_cache *ceph_dentry_cachep;
+struct kmem_cache *ceph_file_cachep;
+
+static void ceph_inode_init_once(void *foo)
+{
+       struct ceph_inode_info *ci = foo;
+       inode_init_once(&ci->vfs_inode);
+}
+
+static int default_congestion_kb(void)
+{
+       int congestion_kb;
+
+       /*
+        * Copied from NFS
+        *
+        * congestion size, scale with available memory.
+        *
+        *  64MB:    8192k
+        * 128MB:   11585k
+        * 256MB:   16384k
+        * 512MB:   23170k
+        *   1GB:   32768k
+        *   2GB:   46340k
+        *   4GB:   65536k
+        *   8GB:   92681k
+        *  16GB:  131072k
+        *
+        * This allows larger machines to have larger/more transfers.
+        * Limit the default to 256M
+        */
+       congestion_kb = (16*int_sqrt(totalram_pages)) << (PAGE_SHIFT-10);
+       if (congestion_kb > 256*1024)
+               congestion_kb = 256*1024;
+
+       return congestion_kb;
+}
+
+static int __init init_caches(void)
+{
+       ceph_inode_cachep = kmem_cache_create("ceph_inode_info",
+                                     sizeof(struct ceph_inode_info),
+                                     __alignof__(struct ceph_inode_info),
+                                     (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD),
+                                     ceph_inode_init_once);
+       if (ceph_inode_cachep == NULL)
+               return -ENOMEM;
+
+       ceph_cap_cachep = KMEM_CACHE(ceph_cap,
+                                    SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD);
+       if (ceph_cap_cachep == NULL)
+               goto bad_cap;
+
+       ceph_dentry_cachep = KMEM_CACHE(ceph_dentry_info,
+                                       SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD);
+       if (ceph_dentry_cachep == NULL)
+               goto bad_dentry;
+
+       ceph_file_cachep = KMEM_CACHE(ceph_file_info,
+                                     SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD);
+       if (ceph_file_cachep == NULL)
+               goto bad_file;
+
+       return 0;
+
+bad_file:
+       kmem_cache_destroy(ceph_dentry_cachep);
+bad_dentry:
+       kmem_cache_destroy(ceph_cap_cachep);
+bad_cap:
+       kmem_cache_destroy(ceph_inode_cachep);
+       return -ENOMEM;
+}
+
+static void destroy_caches(void)
+{
+       kmem_cache_destroy(ceph_inode_cachep);
+       kmem_cache_destroy(ceph_cap_cachep);
+       kmem_cache_destroy(ceph_dentry_cachep);
+       kmem_cache_destroy(ceph_file_cachep);
+}
+
+
+/*
+ * ceph_umount_begin - initiate forced umount.  Tear down down the
+ * mount, skipping steps that may hang while waiting for server(s).
+ */
+static void ceph_umount_begin(struct super_block *sb)
+{
+       struct ceph_client *client = ceph_sb_to_client(sb);
+
+       dout("ceph_umount_begin - starting forced umount\n");
+       if (!client)
+               return;
+       client->mount_state = CEPH_MOUNT_SHUTDOWN;
+       return;
+}
+
+static const struct super_operations ceph_super_ops = {
+       .alloc_inode    = ceph_alloc_inode,
+       .destroy_inode  = ceph_destroy_inode,
+       .write_inode    = ceph_write_inode,
+       .sync_fs        = ceph_syncfs,
+       .put_super      = ceph_put_super,
+       .show_options   = ceph_show_options,
+       .statfs         = ceph_statfs,
+       .umount_begin   = ceph_umount_begin,
+};
+
+
+const char *ceph_msg_type_name(int type)
+{
+       switch (type) {
+       case CEPH_MSG_SHUTDOWN: return "shutdown";
+       case CEPH_MSG_PING: return "ping";
+       case CEPH_MSG_AUTH: return "auth";
+       case CEPH_MSG_AUTH_REPLY: return "auth_reply";
+       case CEPH_MSG_MON_MAP: return "mon_map";
+       case CEPH_MSG_MON_GET_MAP: return "mon_get_map";
+       case CEPH_MSG_MON_SUBSCRIBE: return "mon_subscribe";
+       case CEPH_MSG_MON_SUBSCRIBE_ACK: return "mon_subscribe_ack";
+       case CEPH_MSG_STATFS: return "statfs";
+       case CEPH_MSG_STATFS_REPLY: return "statfs_reply";
+       case CEPH_MSG_MDS_MAP: return "mds_map";
+       case CEPH_MSG_CLIENT_SESSION: return "client_session";
+       case CEPH_MSG_CLIENT_RECONNECT: return "client_reconnect";
+       case CEPH_MSG_CLIENT_REQUEST: return "client_request";
+       case CEPH_MSG_CLIENT_REQUEST_FORWARD: return "client_request_forward";
+       case CEPH_MSG_CLIENT_REPLY: return "client_reply";
+       case CEPH_MSG_CLIENT_CAPS: return "client_caps";
+       case CEPH_MSG_CLIENT_CAPRELEASE: return "client_cap_release";
+       case CEPH_MSG_CLIENT_SNAP: return "client_snap";
+       case CEPH_MSG_CLIENT_LEASE: return "client_lease";
+       case CEPH_MSG_OSD_MAP: return "osd_map";
+       case CEPH_MSG_OSD_OP: return "osd_op";
+       case CEPH_MSG_OSD_OPREPLY: return "osd_opreply";
+       default: return "unknown";
+       }
+}
+
+
+/*
+ * mount options
+ */
+enum {
+       Opt_fsidmajor,
+       Opt_fsidminor,
+       Opt_monport,
+       Opt_wsize,
+       Opt_rsize,
+       Opt_osdtimeout,
+       Opt_osdkeepalivetimeout,
+       Opt_mount_timeout,
+       Opt_osd_idle_ttl,
+       Opt_caps_wanted_delay_min,
+       Opt_caps_wanted_delay_max,
+       Opt_readdir_max_entries,
+       Opt_congestion_kb,
+       Opt_last_int,
+       /* int args above */
+       Opt_snapdirname,
+       Opt_name,
+       Opt_secret,
+       Opt_last_string,
+       /* string args above */
+       Opt_ip,
+       Opt_noshare,
+       Opt_dirstat,
+       Opt_nodirstat,
+       Opt_rbytes,
+       Opt_norbytes,
+       Opt_nocrc,
+       Opt_noasyncreaddir,
+};
+
+static match_table_t arg_tokens = {
+       {Opt_fsidmajor, "fsidmajor=%ld"},
+       {Opt_fsidminor, "fsidminor=%ld"},
+       {Opt_monport, "monport=%d"},
+       {Opt_wsize, "wsize=%d"},
+       {Opt_rsize, "rsize=%d"},
+       {Opt_osdtimeout, "osdtimeout=%d"},
+       {Opt_osdkeepalivetimeout, "osdkeepalive=%d"},
+       {Opt_mount_timeout, "mount_timeout=%d"},
+       {Opt_osd_idle_ttl, "osd_idle_ttl=%d"},
+       {Opt_caps_wanted_delay_min, "caps_wanted_delay_min=%d"},
+       {Opt_caps_wanted_delay_max, "caps_wanted_delay_max=%d"},
+       {Opt_readdir_max_entries, "readdir_max_entries=%d"},
+       {Opt_congestion_kb, "write_congestion_kb=%d"},
+       /* int args above */
+       {Opt_snapdirname, "snapdirname=%s"},
+       {Opt_name, "name=%s"},
+       {Opt_secret, "secret=%s"},
+       /* string args above */
+       {Opt_ip, "ip=%s"},
+       {Opt_noshare, "noshare"},
+       {Opt_dirstat, "dirstat"},
+       {Opt_nodirstat, "nodirstat"},
+       {Opt_rbytes, "rbytes"},
+       {Opt_norbytes, "norbytes"},
+       {Opt_nocrc, "nocrc"},
+       {Opt_noasyncreaddir, "noasyncreaddir"},
+       {-1, NULL}
+};
+
+
+static struct ceph_mount_args *parse_mount_args(int flags, char *options,
+                                               const char *dev_name,
+                                               const char **path)
+{
+       struct ceph_mount_args *args;
+       const char *c;
+       int err = -ENOMEM;
+       substring_t argstr[MAX_OPT_ARGS];
+
+       args = kzalloc(sizeof(*args), GFP_KERNEL);
+       if (!args)
+               return ERR_PTR(-ENOMEM);
+       args->mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*args->mon_addr),
+                                GFP_KERNEL);
+       if (!args->mon_addr)
+               goto out;
+
+       dout("parse_mount_args %p, dev_name '%s'\n", args, dev_name);
+
+       /* start with defaults */
+       args->sb_flags = flags;
+       args->flags = CEPH_OPT_DEFAULT;
+       args->osd_timeout = CEPH_OSD_TIMEOUT_DEFAULT;
+       args->osd_keepalive_timeout = CEPH_OSD_KEEPALIVE_DEFAULT;
+       args->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT; /* seconds */
+       args->osd_idle_ttl = CEPH_OSD_IDLE_TTL_DEFAULT;   /* seconds */
+       args->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT;
+       args->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT;
+       args->rsize = CEPH_MOUNT_RSIZE_DEFAULT;
+       args->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL);
+       args->cap_release_safety = CEPH_CAPS_PER_RELEASE * 4;
+       args->max_readdir = 1024;
+       args->congestion_kb = default_congestion_kb();
+
+       /* ip1[:port1][,ip2[:port2]...]:/subdir/in/fs */
+       err = -EINVAL;
+       if (!dev_name)
+               goto out;
+       *path = strstr(dev_name, ":/");
+       if (*path == NULL) {
+               pr_err("device name is missing path (no :/ in %s)\n",
+                      dev_name);
+               goto out;
+       }
+
+       /* get mon ip(s) */
+       err = ceph_parse_ips(dev_name, *path, args->mon_addr,
+                            CEPH_MAX_MON, &args->num_mon);
+       if (err < 0)
+               goto out;
+
+       /* path on server */
+       *path += 2;
+       dout("server path '%s'\n", *path);
+
+       /* parse mount options */
+       while ((c = strsep(&options, ",")) != NULL) {
+               int token, intval, ret;
+               if (!*c)
+                       continue;
+               err = -EINVAL;
+               token = match_token((char *)c, arg_tokens, argstr);
+               if (token < 0) {
+                       pr_err("bad mount option at '%s'\n", c);
+                       goto out;
+               }
+               if (token < Opt_last_int) {
+                       ret = match_int(&argstr[0], &intval);
+                       if (ret < 0) {
+                               pr_err("bad mount option arg (not int) "
+                                      "at '%s'\n", c);
+                               continue;
+                       }
+                       dout("got int token %d val %d\n", token, intval);
+               } else if (token > Opt_last_int && token < Opt_last_string) {
+                       dout("got string token %d val %s\n", token,
+                            argstr[0].from);
+               } else {
+                       dout("got token %d\n", token);
+               }
+               switch (token) {
+               case Opt_fsidmajor:
+                       *(__le64 *)&args->fsid.fsid[0] = cpu_to_le64(intval);
+                       break;
+               case Opt_fsidminor:
+                       *(__le64 *)&args->fsid.fsid[8] = cpu_to_le64(intval);
+                       break;
+               case Opt_ip:
+                       err = ceph_parse_ips(argstr[0].from,
+                                            argstr[0].to,
+                                            &args->my_addr,
+                                            1, NULL);
+                       if (err < 0)
+                               goto out;
+                       args->flags |= CEPH_OPT_MYIP;
+                       break;
+
+               case Opt_snapdirname:
+                       kfree(args->snapdir_name);
+                       args->snapdir_name = kstrndup(argstr[0].from,
+                                             argstr[0].to-argstr[0].from,
+                                             GFP_KERNEL);
+                       break;
+               case Opt_name:
+                       args->name = kstrndup(argstr[0].from,
+                                             argstr[0].to-argstr[0].from,
+                                             GFP_KERNEL);
+                       break;
+               case Opt_secret:
+                       args->secret = kstrndup(argstr[0].from,
+                                               argstr[0].to-argstr[0].from,
+                                               GFP_KERNEL);
+                       break;
+
+                       /* misc */
+               case Opt_wsize:
+                       args->wsize = intval;
+                       break;
+               case Opt_rsize:
+                       args->rsize = intval;
+                       break;
+               case Opt_osdtimeout:
+                       args->osd_timeout = intval;
+                       break;
+               case Opt_osdkeepalivetimeout:
+                       args->osd_keepalive_timeout = intval;
+                       break;
+               case Opt_mount_timeout:
+                       args->mount_timeout = intval;
+                       break;
+               case Opt_caps_wanted_delay_min:
+                       args->caps_wanted_delay_min = intval;
+                       break;
+               case Opt_caps_wanted_delay_max:
+                       args->caps_wanted_delay_max = intval;
+                       break;
+               case Opt_readdir_max_entries:
+                       args->max_readdir = intval;
+                       break;
+               case Opt_congestion_kb:
+                       args->congestion_kb = intval;
+                       break;
+
+               case Opt_noshare:
+                       args->flags |= CEPH_OPT_NOSHARE;
+                       break;
+
+               case Opt_dirstat:
+                       args->flags |= CEPH_OPT_DIRSTAT;
+                       break;
+               case Opt_nodirstat:
+                       args->flags &= ~CEPH_OPT_DIRSTAT;
+                       break;
+               case Opt_rbytes:
+                       args->flags |= CEPH_OPT_RBYTES;
+                       break;
+               case Opt_norbytes:
+                       args->flags &= ~CEPH_OPT_RBYTES;
+                       break;
+               case Opt_nocrc:
+                       args->flags |= CEPH_OPT_NOCRC;
+                       break;
+               case Opt_noasyncreaddir:
+                       args->flags |= CEPH_OPT_NOASYNCREADDIR;
+                       break;
+
+               default:
+                       BUG_ON(token);
+               }
+       }
+       return args;
+
+out:
+       kfree(args->mon_addr);
+       kfree(args);
+       return ERR_PTR(err);
+}
+
+static void destroy_mount_args(struct ceph_mount_args *args)
+{
+       dout("destroy_mount_args %p\n", args);
+       kfree(args->snapdir_name);
+       args->snapdir_name = NULL;
+       kfree(args->name);
+       args->name = NULL;
+       kfree(args->secret);
+       args->secret = NULL;
+       kfree(args);
+}
+
+/*
+ * create a fresh client instance
+ */
+static struct ceph_client *ceph_create_client(struct ceph_mount_args *args)
+{
+       struct ceph_client *client;
+       int err = -ENOMEM;
+
+       client = kzalloc(sizeof(*client), GFP_KERNEL);
+       if (client == NULL)
+               return ERR_PTR(-ENOMEM);
+
+       mutex_init(&client->mount_mutex);
+
+       init_waitqueue_head(&client->auth_wq);
+
+       client->sb = NULL;
+       client->mount_state = CEPH_MOUNT_MOUNTING;
+       client->mount_args = args;
+
+       client->msgr = NULL;
+
+       client->auth_err = 0;
+       atomic_long_set(&client->writeback_count, 0);
+
+       err = bdi_init(&client->backing_dev_info);
+       if (err < 0)
+               goto fail;
+
+       err = -ENOMEM;
+       client->wb_wq = create_workqueue("ceph-writeback");
+       if (client->wb_wq == NULL)
+               goto fail_bdi;
+       client->pg_inv_wq = create_singlethread_workqueue("ceph-pg-invalid");
+       if (client->pg_inv_wq == NULL)
+               goto fail_wb_wq;
+       client->trunc_wq = create_singlethread_workqueue("ceph-trunc");
+       if (client->trunc_wq == NULL)
+               goto fail_pg_inv_wq;
+
+       /* set up mempools */
+       err = -ENOMEM;
+       client->wb_pagevec_pool = mempool_create_kmalloc_pool(10,
+                             client->mount_args->wsize >> PAGE_CACHE_SHIFT);
+       if (!client->wb_pagevec_pool)
+               goto fail_trunc_wq;
+
+       /* caps */
+       client->min_caps = args->max_readdir;
+       ceph_adjust_min_caps(client->min_caps);
+
+       /* subsystems */
+       err = ceph_monc_init(&client->monc, client);
+       if (err < 0)
+               goto fail_mempool;
+       err = ceph_osdc_init(&client->osdc, client);
+       if (err < 0)
+               goto fail_monc;
+       err = ceph_mdsc_init(&client->mdsc, client);
+       if (err < 0)
+               goto fail_osdc;
+       return client;
+
+fail_osdc:
+       ceph_osdc_stop(&client->osdc);
+fail_monc:
+       ceph_monc_stop(&client->monc);
+fail_mempool:
+       mempool_destroy(client->wb_pagevec_pool);
+fail_trunc_wq:
+       destroy_workqueue(client->trunc_wq);
+fail_pg_inv_wq:
+       destroy_workqueue(client->pg_inv_wq);
+fail_wb_wq:
+       destroy_workqueue(client->wb_wq);
+fail_bdi:
+       bdi_destroy(&client->backing_dev_info);
+fail:
+       kfree(client);
+       return ERR_PTR(err);
+}
+
+static void ceph_destroy_client(struct ceph_client *client)
+{
+       dout("destroy_client %p\n", client);
+
+       /* unmount */
+       ceph_mdsc_stop(&client->mdsc);
+       ceph_monc_stop(&client->monc);
+       ceph_osdc_stop(&client->osdc);
+
+       ceph_adjust_min_caps(-client->min_caps);
+
+       ceph_debugfs_client_cleanup(client);
+       destroy_workqueue(client->wb_wq);
+       destroy_workqueue(client->pg_inv_wq);
+       destroy_workqueue(client->trunc_wq);
+
+       bdi_destroy(&client->backing_dev_info);
+
+       if (client->msgr)
+               ceph_messenger_destroy(client->msgr);
+       mempool_destroy(client->wb_pagevec_pool);
+
+       destroy_mount_args(client->mount_args);
+
+       kfree(client);
+       dout("destroy_client %p done\n", client);
+}
+
+/*
+ * Initially learn our fsid, or verify an fsid matches.
+ */
+int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid)
+{
+       if (client->have_fsid) {
+               if (ceph_fsid_compare(&client->fsid, fsid)) {
+                       pr_err("bad fsid, had " FSID_FORMAT " got " FSID_FORMAT,
+                              PR_FSID(&client->fsid), PR_FSID(fsid));
+                       return -1;
+               }
+       } else {
+               pr_info("client%lld fsid " FSID_FORMAT "\n",
+                       client->monc.auth->global_id, PR_FSID(fsid));
+               memcpy(&client->fsid, fsid, sizeof(*fsid));
+               ceph_debugfs_client_init(client);
+               client->have_fsid = true;
+       }
+       return 0;
+}
+
+/*
+ * true if we have the mon map (and have thus joined the cluster)
+ */
+static int have_mon_map(struct ceph_client *client)
+{
+       return client->monc.monmap && client->monc.monmap->epoch;
+}
+
+/*
+ * Bootstrap mount by opening the root directory.  Note the mount
+ * @started time from caller, and time out if this takes too long.
+ */
+static struct dentry *open_root_dentry(struct ceph_client *client,
+                                      const char *path,
+                                      unsigned long started)
+{
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct ceph_mds_request *req = NULL;
+       int err;
+       struct dentry *root;
+
+       /* open dir */
+       dout("open_root_inode opening '%s'\n", path);
+       req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS);
+       if (IS_ERR(req))
+               return ERR_PTR(PTR_ERR(req));
+       req->r_path1 = kstrdup(path, GFP_NOFS);
+       req->r_ino1.ino = CEPH_INO_ROOT;
+       req->r_ino1.snap = CEPH_NOSNAP;
+       req->r_started = started;
+       req->r_timeout = client->mount_args->mount_timeout * HZ;
+       req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE);
+       req->r_num_caps = 2;
+       err = ceph_mdsc_do_request(mdsc, NULL, req);
+       if (err == 0) {
+               dout("open_root_inode success\n");
+               if (ceph_ino(req->r_target_inode) == CEPH_INO_ROOT &&
+                   client->sb->s_root == NULL)
+                       root = d_alloc_root(req->r_target_inode);
+               else
+                       root = d_obtain_alias(req->r_target_inode);
+               req->r_target_inode = NULL;
+               dout("open_root_inode success, root dentry is %p\n", root);
+       } else {
+               root = ERR_PTR(err);
+       }
+       ceph_mdsc_put_request(req);
+       return root;
+}
+
+/*
+ * mount: join the ceph cluster, and open root directory.
+ */
+static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt,
+                     const char *path)
+{
+       struct ceph_entity_addr *myaddr = NULL;
+       int err;
+       unsigned long timeout = client->mount_args->mount_timeout * HZ;
+       unsigned long started = jiffies;  /* note the start time */
+       struct dentry *root;
+
+       dout("mount start\n");
+       mutex_lock(&client->mount_mutex);
+
+       /* initialize the messenger */
+       if (client->msgr == NULL) {
+               if (ceph_test_opt(client, MYIP))
+                       myaddr = &client->mount_args->my_addr;
+               client->msgr = ceph_messenger_create(myaddr);
+               if (IS_ERR(client->msgr)) {
+                       err = PTR_ERR(client->msgr);
+                       client->msgr = NULL;
+                       goto out;
+               }
+               client->msgr->nocrc = ceph_test_opt(client, NOCRC);
+       }
+
+       /* open session, and wait for mon, mds, and osd maps */
+       err = ceph_monc_open_session(&client->monc);
+       if (err < 0)
+               goto out;
+
+       while (!have_mon_map(client)) {
+               err = -EIO;
+               if (timeout && time_after_eq(jiffies, started + timeout))
+                       goto out;
+
+               /* wait */
+               dout("mount waiting for mon_map\n");
+               err = wait_event_interruptible_timeout(client->auth_wq,
+                              have_mon_map(client) || (client->auth_err < 0),
+                              timeout);
+               if (err == -EINTR || err == -ERESTARTSYS)
+                       goto out;
+               if (client->auth_err < 0) {
+                       err = client->auth_err;
+                       goto out;
+               }
+       }
+
+       dout("mount opening root\n");
+       root = open_root_dentry(client, "", started);
+       if (IS_ERR(root)) {
+               err = PTR_ERR(root);
+               goto out;
+       }
+       if (client->sb->s_root)
+               dput(root);
+       else
+               client->sb->s_root = root;
+
+       if (path[0] == 0) {
+               dget(root);
+       } else {
+               dout("mount opening base mountpoint\n");
+               root = open_root_dentry(client, path, started);
+               if (IS_ERR(root)) {
+                       err = PTR_ERR(root);
+                       dput(client->sb->s_root);
+                       client->sb->s_root = NULL;
+                       goto out;
+               }
+       }
+
+       mnt->mnt_root = root;
+       mnt->mnt_sb = client->sb;
+
+       client->mount_state = CEPH_MOUNT_MOUNTED;
+       dout("mount success\n");
+       err = 0;
+
+out:
+       mutex_unlock(&client->mount_mutex);
+       return err;
+}
+
+static int ceph_set_super(struct super_block *s, void *data)
+{
+       struct ceph_client *client = data;
+       int ret;
+
+       dout("set_super %p data %p\n", s, data);
+
+       s->s_flags = client->mount_args->sb_flags;
+       s->s_maxbytes = 1ULL << 40;  /* temp value until we get mdsmap */
+
+       s->s_fs_info = client;
+       client->sb = s;
+
+       s->s_op = &ceph_super_ops;
+       s->s_export_op = &ceph_export_ops;
+
+       s->s_time_gran = 1000;  /* 1000 ns == 1 us */
+
+       ret = set_anon_super(s, NULL);  /* what is that second arg for? */
+       if (ret != 0)
+               goto fail;
+
+       return ret;
+
+fail:
+       s->s_fs_info = NULL;
+       client->sb = NULL;
+       return ret;
+}
+
+/*
+ * share superblock if same fs AND options
+ */
+static int ceph_compare_super(struct super_block *sb, void *data)
+{
+       struct ceph_client *new = data;
+       struct ceph_mount_args *args = new->mount_args;
+       struct ceph_client *other = ceph_sb_to_client(sb);
+       int i;
+
+       dout("ceph_compare_super %p\n", sb);
+       if (args->flags & CEPH_OPT_FSID) {
+               if (ceph_fsid_compare(&args->fsid, &other->fsid)) {
+                       dout("fsid doesn't match\n");
+                       return 0;
+               }
+       } else {
+               /* do we share (a) monitor? */
+               for (i = 0; i < new->monc.monmap->num_mon; i++)
+                       if (ceph_monmap_contains(other->monc.monmap,
+                                        &new->monc.monmap->mon_inst[i].addr))
+                               break;
+               if (i == new->monc.monmap->num_mon) {
+                       dout("mon ip not part of monmap\n");
+                       return 0;
+               }
+               dout("mon ip matches existing sb %p\n", sb);
+       }
+       if (args->sb_flags != other->mount_args->sb_flags) {
+               dout("flags differ\n");
+               return 0;
+       }
+       return 1;
+}
+
+/*
+ * construct our own bdi so we can control readahead, etc.
+ */
+static int ceph_register_bdi(struct super_block *sb, struct ceph_client *client)
+{
+       int err;
+
+       /* set ra_pages based on rsize mount option? */
+       if (client->mount_args->rsize >= PAGE_CACHE_SIZE)
+               client->backing_dev_info.ra_pages =
+                       (client->mount_args->rsize + PAGE_CACHE_SIZE - 1)
+                       >> PAGE_SHIFT;
+       err = bdi_register_dev(&client->backing_dev_info, sb->s_dev);
+       if (!err)
+               sb->s_bdi = &client->backing_dev_info;
+       return err;
+}
+
+static int ceph_get_sb(struct file_system_type *fs_type,
+                      int flags, const char *dev_name, void *data,
+                      struct vfsmount *mnt)
+{
+       struct super_block *sb;
+       struct ceph_client *client;
+       int err;
+       int (*compare_super)(struct super_block *, void *) = ceph_compare_super;
+       const char *path = NULL;
+       struct ceph_mount_args *args;
+
+       dout("ceph_get_sb\n");
+       args = parse_mount_args(flags, data, dev_name, &path);
+       if (IS_ERR(args)) {
+               err = PTR_ERR(args);
+               goto out_final;
+       }
+
+       /* create client (which we may/may not use) */
+       client = ceph_create_client(args);
+       if (IS_ERR(client)) {
+               err = PTR_ERR(client);
+               goto out_final;
+       }
+
+       if (client->mount_args->flags & CEPH_OPT_NOSHARE)
+               compare_super = NULL;
+       sb = sget(fs_type, compare_super, ceph_set_super, client);
+       if (IS_ERR(sb)) {
+               err = PTR_ERR(sb);
+               goto out;
+       }
+
+       if (ceph_client(sb) != client) {
+               ceph_destroy_client(client);
+               client = ceph_client(sb);
+               dout("get_sb got existing client %p\n", client);
+       } else {
+               dout("get_sb using new client %p\n", client);
+               err = ceph_register_bdi(sb, client);
+               if (err < 0)
+                       goto out_splat;
+       }
+
+       err = ceph_mount(client, mnt, path);
+       if (err < 0)
+               goto out_splat;
+       dout("root %p inode %p ino %llx.%llx\n", mnt->mnt_root,
+            mnt->mnt_root->d_inode, ceph_vinop(mnt->mnt_root->d_inode));
+       return 0;
+
+out_splat:
+       ceph_mdsc_close_sessions(&client->mdsc);
+       up_write(&sb->s_umount);
+       deactivate_super(sb);
+       goto out_final;
+
+out:
+       ceph_destroy_client(client);
+out_final:
+       dout("ceph_get_sb fail %d\n", err);
+       return err;
+}
+
+static void ceph_kill_sb(struct super_block *s)
+{
+       struct ceph_client *client = ceph_sb_to_client(s);
+       dout("kill_sb %p\n", s);
+       ceph_mdsc_pre_umount(&client->mdsc);
+       kill_anon_super(s);    /* will call put_super after sb is r/o */
+       ceph_destroy_client(client);
+}
+
+static struct file_system_type ceph_fs_type = {
+       .owner          = THIS_MODULE,
+       .name           = "ceph",
+       .get_sb         = ceph_get_sb,
+       .kill_sb        = ceph_kill_sb,
+       .fs_flags       = FS_RENAME_DOES_D_MOVE,
+};
+
+#define _STRINGIFY(x) #x
+#define STRINGIFY(x) _STRINGIFY(x)
+
+static int __init init_ceph(void)
+{
+       int ret = 0;
+
+       ret = ceph_debugfs_init();
+       if (ret < 0)
+               goto out;
+
+       ret = ceph_msgr_init();
+       if (ret < 0)
+               goto out_debugfs;
+
+       ret = init_caches();
+       if (ret)
+               goto out_msgr;
+
+       ceph_caps_init();
+
+       ret = register_filesystem(&ceph_fs_type);
+       if (ret)
+               goto out_icache;
+
+       pr_info("loaded (mon/mds/osd proto %d/%d/%d, osdmap %d/%d %d/%d)\n",
+               CEPH_MONC_PROTOCOL, CEPH_MDSC_PROTOCOL, CEPH_OSDC_PROTOCOL,
+               CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT,
+               CEPH_OSDMAP_INC_VERSION, CEPH_OSDMAP_INC_VERSION_EXT);
+       return 0;
+
+out_icache:
+       destroy_caches();
+out_msgr:
+       ceph_msgr_exit();
+out_debugfs:
+       ceph_debugfs_cleanup();
+out:
+       return ret;
+}
+
+static void __exit exit_ceph(void)
+{
+       dout("exit_ceph\n");
+       unregister_filesystem(&ceph_fs_type);
+       ceph_caps_finalize();
+       destroy_caches();
+       ceph_msgr_exit();
+       ceph_debugfs_cleanup();
+}
+
+module_init(init_ceph);
+module_exit(exit_ceph);
+
+MODULE_AUTHOR("Sage Weil <sage@newdream.net>");
+MODULE_AUTHOR("Yehuda Sadeh <yehuda@hq.newdream.net>");
+MODULE_AUTHOR("Patience Warnick <patience@newdream.net>");
+MODULE_DESCRIPTION("Ceph filesystem for Linux");
+MODULE_LICENSE("GPL");
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
new file mode 100644 (file)
index 0000000..13513b8
--- /dev/null
@@ -0,0 +1,902 @@
+#ifndef _FS_CEPH_SUPER_H
+#define _FS_CEPH_SUPER_H
+
+#include "ceph_debug.h"
+
+#include <asm/unaligned.h>
+#include <linux/backing-dev.h>
+#include <linux/completion.h>
+#include <linux/exportfs.h>
+#include <linux/fs.h>
+#include <linux/mempool.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/writeback.h>
+#include <linux/slab.h>
+
+#include "types.h"
+#include "messenger.h"
+#include "msgpool.h"
+#include "mon_client.h"
+#include "mds_client.h"
+#include "osd_client.h"
+#include "ceph_fs.h"
+
+/* f_type in struct statfs */
+#define CEPH_SUPER_MAGIC 0x00c36400
+
+/* large granularity for statfs utilization stats to facilitate
+ * large volume sizes on 32-bit machines. */
+#define CEPH_BLOCK_SHIFT   20  /* 1 MB */
+#define CEPH_BLOCK         (1 << CEPH_BLOCK_SHIFT)
+
+/*
+ * mount options
+ */
+#define CEPH_OPT_FSID             (1<<0)
+#define CEPH_OPT_NOSHARE          (1<<1) /* don't share client with other sbs */
+#define CEPH_OPT_MYIP             (1<<2) /* specified my ip */
+#define CEPH_OPT_DIRSTAT          (1<<4) /* funky `cat dirname` for stats */
+#define CEPH_OPT_RBYTES           (1<<5) /* dir st_bytes = rbytes */
+#define CEPH_OPT_NOCRC            (1<<6) /* no data crc on writes */
+#define CEPH_OPT_NOASYNCREADDIR   (1<<7) /* no dcache readdir */
+
+#define CEPH_OPT_DEFAULT   (CEPH_OPT_RBYTES)
+
+#define ceph_set_opt(client, opt) \
+       (client)->mount_args->flags |= CEPH_OPT_##opt;
+#define ceph_test_opt(client, opt) \
+       (!!((client)->mount_args->flags & CEPH_OPT_##opt))
+
+
+struct ceph_mount_args {
+       int sb_flags;
+       int num_mon;
+       struct ceph_entity_addr *mon_addr;
+       int flags;
+       int mount_timeout;
+       int osd_idle_ttl;
+       int caps_wanted_delay_min, caps_wanted_delay_max;
+       struct ceph_fsid fsid;
+       struct ceph_entity_addr my_addr;
+       int wsize;
+       int rsize;            /* max readahead */
+       int max_readdir;      /* max readdir size */
+       int congestion_kb;      /* max readdir size */
+       int osd_timeout;
+       int osd_keepalive_timeout;
+       char *snapdir_name;   /* default ".snap" */
+       char *name;
+       char *secret;
+       int cap_release_safety;
+};
+
+/*
+ * defaults
+ */
+#define CEPH_MOUNT_TIMEOUT_DEFAULT  60
+#define CEPH_OSD_TIMEOUT_DEFAULT    60  /* seconds */
+#define CEPH_OSD_KEEPALIVE_DEFAULT  5
+#define CEPH_OSD_IDLE_TTL_DEFAULT    60
+#define CEPH_MOUNT_RSIZE_DEFAULT    (512*1024) /* readahead */
+
+#define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024)
+#define CEPH_MSG_MAX_DATA_LEN  (16*1024*1024)
+
+#define CEPH_SNAPDIRNAME_DEFAULT ".snap"
+#define CEPH_AUTH_NAME_DEFAULT   "guest"
+
+/*
+ * Delay telling the MDS we no longer want caps, in case we reopen
+ * the file.  Delay a minimum amount of time, even if we send a cap
+ * message for some other reason.  Otherwise, take the oppotunity to
+ * update the mds to avoid sending another message later.
+ */
+#define CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT      5  /* cap release delay */
+#define CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT     60  /* cap release delay */
+
+
+/* mount state */
+enum {
+       CEPH_MOUNT_MOUNTING,
+       CEPH_MOUNT_MOUNTED,
+       CEPH_MOUNT_UNMOUNTING,
+       CEPH_MOUNT_UNMOUNTED,
+       CEPH_MOUNT_SHUTDOWN,
+};
+
+/*
+ * subtract jiffies
+ */
+static inline unsigned long time_sub(unsigned long a, unsigned long b)
+{
+       BUG_ON(time_after(b, a));
+       return (long)a - (long)b;
+}
+
+/*
+ * per-filesystem client state
+ *
+ * possibly shared by multiple mount points, if they are
+ * mounting the same ceph filesystem/cluster.
+ */
+struct ceph_client {
+       struct ceph_fsid fsid;
+       bool have_fsid;
+
+       struct mutex mount_mutex;       /* serialize mount attempts */
+       struct ceph_mount_args *mount_args;
+
+       struct super_block *sb;
+
+       unsigned long mount_state;
+       wait_queue_head_t auth_wq;
+
+       int auth_err;
+
+       int min_caps;                  /* min caps i added */
+
+       struct ceph_messenger *msgr;   /* messenger instance */
+       struct ceph_mon_client monc;
+       struct ceph_mds_client mdsc;
+       struct ceph_osd_client osdc;
+
+       /* writeback */
+       mempool_t *wb_pagevec_pool;
+       struct workqueue_struct *wb_wq;
+       struct workqueue_struct *pg_inv_wq;
+       struct workqueue_struct *trunc_wq;
+       atomic_long_t writeback_count;
+
+       struct backing_dev_info backing_dev_info;
+
+#ifdef CONFIG_DEBUG_FS
+       struct dentry *debugfs_monmap;
+       struct dentry *debugfs_mdsmap, *debugfs_osdmap;
+       struct dentry *debugfs_dir, *debugfs_dentry_lru, *debugfs_caps;
+       struct dentry *debugfs_congestion_kb;
+       struct dentry *debugfs_bdi;
+#endif
+};
+
+static inline struct ceph_client *ceph_client(struct super_block *sb)
+{
+       return sb->s_fs_info;
+}
+
+
+/*
+ * File i/o capability.  This tracks shared state with the metadata
+ * server that allows us to cache or writeback attributes or to read
+ * and write data.  For any given inode, we should have one or more
+ * capabilities, one issued by each metadata server, and our
+ * cumulative access is the OR of all issued capabilities.
+ *
+ * Each cap is referenced by the inode's i_caps rbtree and by per-mds
+ * session capability lists.
+ */
+struct ceph_cap {
+       struct ceph_inode_info *ci;
+       struct rb_node ci_node;          /* per-ci cap tree */
+       struct ceph_mds_session *session;
+       struct list_head session_caps;   /* per-session caplist */
+       int mds;
+       u64 cap_id;       /* unique cap id (mds provided) */
+       int issued;       /* latest, from the mds */
+       int implemented;  /* implemented superset of issued (for revocation) */
+       int mds_wanted;
+       u32 seq, issue_seq, mseq;
+       u32 cap_gen;      /* active/stale cycle */
+       unsigned long last_used;
+       struct list_head caps_item;
+};
+
+#define CHECK_CAPS_NODELAY    1  /* do not delay any further */
+#define CHECK_CAPS_AUTHONLY   2  /* only check auth cap */
+#define CHECK_CAPS_FLUSH      4  /* flush any dirty caps */
+
+/*
+ * Snapped cap state that is pending flush to mds.  When a snapshot occurs,
+ * we first complete any in-process sync writes and writeback any dirty
+ * data before flushing the snapped state (tracked here) back to the MDS.
+ */
+struct ceph_cap_snap {
+       atomic_t nref;
+       struct ceph_inode_info *ci;
+       struct list_head ci_item, flushing_item;
+
+       u64 follows, flush_tid;
+       int issued, dirty;
+       struct ceph_snap_context *context;
+
+       mode_t mode;
+       uid_t uid;
+       gid_t gid;
+
+       void *xattr_blob;
+       int xattr_len;
+       u64 xattr_version;
+
+       u64 size;
+       struct timespec mtime, atime, ctime;
+       u64 time_warp_seq;
+       int writing;   /* a sync write is still in progress */
+       int dirty_pages;     /* dirty pages awaiting writeback */
+};
+
+static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap)
+{
+       if (atomic_dec_and_test(&capsnap->nref))
+               kfree(capsnap);
+}
+
+/*
+ * The frag tree describes how a directory is fragmented, potentially across
+ * multiple metadata servers.  It is also used to indicate points where
+ * metadata authority is delegated, and whether/where metadata is replicated.
+ *
+ * A _leaf_ frag will be present in the i_fragtree IFF there is
+ * delegation info.  That is, if mds >= 0 || ndist > 0.
+ */
+#define CEPH_MAX_DIRFRAG_REP 4
+
+struct ceph_inode_frag {
+       struct rb_node node;
+
+       /* fragtree state */
+       u32 frag;
+       int split_by;         /* i.e. 2^(split_by) children */
+
+       /* delegation and replication info */
+       int mds;              /* -1 if same authority as parent */
+       int ndist;            /* >0 if replicated */
+       int dist[CEPH_MAX_DIRFRAG_REP];
+};
+
+/*
+ * We cache inode xattrs as an encoded blob until they are first used,
+ * at which point we parse them into an rbtree.
+ */
+struct ceph_inode_xattr {
+       struct rb_node node;
+
+       const char *name;
+       int name_len;
+       const char *val;
+       int val_len;
+       int dirty;
+
+       int should_free_name;
+       int should_free_val;
+};
+
+struct ceph_inode_xattrs_info {
+       /*
+        * (still encoded) xattr blob. we avoid the overhead of parsing
+        * this until someone actually calls getxattr, etc.
+        *
+        * blob->vec.iov_len == 4 implies there are no xattrs; blob ==
+        * NULL means we don't know.
+       */
+       struct ceph_buffer *blob, *prealloc_blob;
+
+       struct rb_root index;
+       bool dirty;
+       int count;
+       int names_size;
+       int vals_size;
+       u64 version, index_version;
+};
+
+/*
+ * Ceph inode.
+ */
+#define CEPH_I_COMPLETE  1  /* we have complete directory cached */
+#define CEPH_I_NODELAY   4  /* do not delay cap release */
+#define CEPH_I_FLUSH     8  /* do not delay flush of dirty metadata */
+#define CEPH_I_NOFLUSH  16  /* do not flush dirty caps */
+
+struct ceph_inode_info {
+       struct ceph_vino i_vino;   /* ceph ino + snap */
+
+       u64 i_version;
+       u32 i_time_warp_seq;
+
+       unsigned i_ceph_flags;
+       unsigned long i_release_count;
+
+       struct ceph_file_layout i_layout;
+       char *i_symlink;
+
+       /* for dirs */
+       struct timespec i_rctime;
+       u64 i_rbytes, i_rfiles, i_rsubdirs;
+       u64 i_files, i_subdirs;
+       u64 i_max_offset;  /* largest readdir offset, set with I_COMPLETE */
+
+       struct rb_root i_fragtree;
+       struct mutex i_fragtree_mutex;
+
+       struct ceph_inode_xattrs_info i_xattrs;
+
+       /* capabilities.  protected _both_ by i_lock and cap->session's
+        * s_mutex. */
+       struct rb_root i_caps;           /* cap list */
+       struct ceph_cap *i_auth_cap;     /* authoritative cap, if any */
+       unsigned i_dirty_caps, i_flushing_caps;     /* mask of dirtied fields */
+       struct list_head i_dirty_item, i_flushing_item;
+       u64 i_cap_flush_seq;
+       /* we need to track cap writeback on a per-cap-bit basis, to allow
+        * overlapping, pipelined cap flushes to the mds.  we can probably
+        * reduce the tid to 8 bits if we're concerned about inode size. */
+       u16 i_cap_flush_last_tid, i_cap_flush_tid[CEPH_CAP_BITS];
+       wait_queue_head_t i_cap_wq;      /* threads waiting on a capability */
+       unsigned long i_hold_caps_min; /* jiffies */
+       unsigned long i_hold_caps_max; /* jiffies */
+       struct list_head i_cap_delay_list;  /* for delayed cap release to mds */
+       int i_cap_exporting_mds;         /* to handle cap migration between */
+       unsigned i_cap_exporting_mseq;   /*  mds's. */
+       unsigned i_cap_exporting_issued;
+       struct ceph_cap_reservation i_cap_migration_resv;
+       struct list_head i_cap_snaps;   /* snapped state pending flush to mds */
+       struct ceph_snap_context *i_head_snapc;  /* set if wr_buffer_head > 0 */
+       unsigned i_snap_caps;           /* cap bits for snapped files */
+
+       int i_nr_by_mode[CEPH_FILE_MODE_NUM];  /* open file counts */
+
+       u32 i_truncate_seq;        /* last truncate to smaller size */
+       u64 i_truncate_size;       /*  and the size we last truncated down to */
+       int i_truncate_pending;    /*  still need to call vmtruncate */
+
+       u64 i_max_size;            /* max file size authorized by mds */
+       u64 i_reported_size; /* (max_)size reported to or requested of mds */
+       u64 i_wanted_max_size;     /* offset we'd like to write too */
+       u64 i_requested_max_size;  /* max_size we've requested */
+
+       /* held references to caps */
+       int i_pin_ref;
+       int i_rd_ref, i_rdcache_ref, i_wr_ref;
+       int i_wrbuffer_ref, i_wrbuffer_ref_head;
+       u32 i_shared_gen;       /* increment each time we get FILE_SHARED */
+       u32 i_rdcache_gen;      /* we increment this each time we get
+                                  FILE_CACHE.  If it's non-zero, we
+                                  _may_ have cached pages. */
+       u32 i_rdcache_revoking; /* RDCACHE gen to async invalidate, if any */
+
+       struct list_head i_unsafe_writes; /* uncommitted sync writes */
+       struct list_head i_unsafe_dirops; /* uncommitted mds dir ops */
+       spinlock_t i_unsafe_lock;
+
+       struct ceph_snap_realm *i_snap_realm; /* snap realm (if caps) */
+       int i_snap_realm_counter; /* snap realm (if caps) */
+       struct list_head i_snap_realm_item;
+       struct list_head i_snap_flush_item;
+
+       struct work_struct i_wb_work;  /* writeback work */
+       struct work_struct i_pg_inv_work;  /* page invalidation work */
+
+       struct work_struct i_vmtruncate_work;
+
+       struct inode vfs_inode; /* at end */
+};
+
+static inline struct ceph_inode_info *ceph_inode(struct inode *inode)
+{
+       return container_of(inode, struct ceph_inode_info, vfs_inode);
+}
+
+static inline void ceph_i_clear(struct inode *inode, unsigned mask)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+
+       spin_lock(&inode->i_lock);
+       ci->i_ceph_flags &= ~mask;
+       spin_unlock(&inode->i_lock);
+}
+
+static inline void ceph_i_set(struct inode *inode, unsigned mask)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+
+       spin_lock(&inode->i_lock);
+       ci->i_ceph_flags |= mask;
+       spin_unlock(&inode->i_lock);
+}
+
+static inline bool ceph_i_test(struct inode *inode, unsigned mask)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       bool r;
+
+       smp_mb();
+       r = (ci->i_ceph_flags & mask) == mask;
+       return r;
+}
+
+
+/* find a specific frag @f */
+extern struct ceph_inode_frag *__ceph_find_frag(struct ceph_inode_info *ci,
+                                               u32 f);
+
+/*
+ * choose fragment for value @v.  copy frag content to pfrag, if leaf
+ * exists
+ */
+extern u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
+                           struct ceph_inode_frag *pfrag,
+                           int *found);
+
+/*
+ * Ceph dentry state
+ */
+struct ceph_dentry_info {
+       struct ceph_mds_session *lease_session;
+       u32 lease_gen, lease_shared_gen;
+       u32 lease_seq;
+       unsigned long lease_renew_after, lease_renew_from;
+       struct list_head lru;
+       struct dentry *dentry;
+       u64 time;
+       u64 offset;
+};
+
+static inline struct ceph_dentry_info *ceph_dentry(struct dentry *dentry)
+{
+       return (struct ceph_dentry_info *)dentry->d_fsdata;
+}
+
+static inline loff_t ceph_make_fpos(unsigned frag, unsigned off)
+{
+       return ((loff_t)frag << 32) | (loff_t)off;
+}
+
+/*
+ * ino_t is <64 bits on many architectures, blech.
+ *
+ * don't include snap in ino hash, at least for now.
+ */
+static inline ino_t ceph_vino_to_ino(struct ceph_vino vino)
+{
+       ino_t ino = (ino_t)vino.ino;  /* ^ (vino.snap << 20); */
+#if BITS_PER_LONG == 32
+       ino ^= vino.ino >> (sizeof(u64)-sizeof(ino_t)) * 8;
+       if (!ino)
+               ino = 1;
+#endif
+       return ino;
+}
+
+static inline int ceph_set_ino_cb(struct inode *inode, void *data)
+{
+       ceph_inode(inode)->i_vino = *(struct ceph_vino *)data;
+       inode->i_ino = ceph_vino_to_ino(*(struct ceph_vino *)data);
+       return 0;
+}
+
+static inline struct ceph_vino ceph_vino(struct inode *inode)
+{
+       return ceph_inode(inode)->i_vino;
+}
+
+/* for printf-style formatting */
+#define ceph_vinop(i) ceph_inode(i)->i_vino.ino, ceph_inode(i)->i_vino.snap
+
+static inline u64 ceph_ino(struct inode *inode)
+{
+       return ceph_inode(inode)->i_vino.ino;
+}
+static inline u64 ceph_snap(struct inode *inode)
+{
+       return ceph_inode(inode)->i_vino.snap;
+}
+
+static inline int ceph_ino_compare(struct inode *inode, void *data)
+{
+       struct ceph_vino *pvino = (struct ceph_vino *)data;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       return ci->i_vino.ino == pvino->ino &&
+               ci->i_vino.snap == pvino->snap;
+}
+
+static inline struct inode *ceph_find_inode(struct super_block *sb,
+                                           struct ceph_vino vino)
+{
+       ino_t t = ceph_vino_to_ino(vino);
+       return ilookup5(sb, t, ceph_ino_compare, &vino);
+}
+
+
+/*
+ * caps helpers
+ */
+static inline bool __ceph_is_any_real_caps(struct ceph_inode_info *ci)
+{
+       return !RB_EMPTY_ROOT(&ci->i_caps);
+}
+
+extern int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented);
+extern int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int t);
+extern int __ceph_caps_issued_other(struct ceph_inode_info *ci,
+                                   struct ceph_cap *cap);
+
+static inline int ceph_caps_issued(struct ceph_inode_info *ci)
+{
+       int issued;
+       spin_lock(&ci->vfs_inode.i_lock);
+       issued = __ceph_caps_issued(ci, NULL);
+       spin_unlock(&ci->vfs_inode.i_lock);
+       return issued;
+}
+
+static inline int ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask,
+                                       int touch)
+{
+       int r;
+       spin_lock(&ci->vfs_inode.i_lock);
+       r = __ceph_caps_issued_mask(ci, mask, touch);
+       spin_unlock(&ci->vfs_inode.i_lock);
+       return r;
+}
+
+static inline int __ceph_caps_dirty(struct ceph_inode_info *ci)
+{
+       return ci->i_dirty_caps | ci->i_flushing_caps;
+}
+extern void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask);
+
+extern int ceph_caps_revoking(struct ceph_inode_info *ci, int mask);
+extern int __ceph_caps_used(struct ceph_inode_info *ci);
+
+extern int __ceph_caps_file_wanted(struct ceph_inode_info *ci);
+
+/*
+ * wanted, by virtue of open file modes AND cap refs (buffered/cached data)
+ */
+static inline int __ceph_caps_wanted(struct ceph_inode_info *ci)
+{
+       int w = __ceph_caps_file_wanted(ci) | __ceph_caps_used(ci);
+       if (w & CEPH_CAP_FILE_BUFFER)
+               w |= CEPH_CAP_FILE_EXCL;  /* we want EXCL if dirty data */
+       return w;
+}
+
+/* what the mds thinks we want */
+extern int __ceph_caps_mds_wanted(struct ceph_inode_info *ci);
+
+extern void ceph_caps_init(void);
+extern void ceph_caps_finalize(void);
+extern void ceph_adjust_min_caps(int delta);
+extern int ceph_reserve_caps(struct ceph_cap_reservation *ctx, int need);
+extern int ceph_unreserve_caps(struct ceph_cap_reservation *ctx);
+extern void ceph_reservation_status(struct ceph_client *client,
+                                   int *total, int *avail, int *used,
+                                   int *reserved, int *min);
+
+static inline struct ceph_client *ceph_inode_to_client(struct inode *inode)
+{
+       return (struct ceph_client *)inode->i_sb->s_fs_info;
+}
+
+static inline struct ceph_client *ceph_sb_to_client(struct super_block *sb)
+{
+       return (struct ceph_client *)sb->s_fs_info;
+}
+
+
+/*
+ * we keep buffered readdir results attached to file->private_data
+ */
+struct ceph_file_info {
+       int fmode;     /* initialized on open */
+
+       /* readdir: position within the dir */
+       u32 frag;
+       struct ceph_mds_request *last_readdir;
+       int at_end;
+
+       /* readdir: position within a frag */
+       unsigned offset;       /* offset of last chunk, adjusted for . and .. */
+       u64 next_offset;       /* offset of next chunk (last_name's + 1) */
+       char *last_name;       /* last entry in previous chunk */
+       struct dentry *dentry; /* next dentry (for dcache readdir) */
+       unsigned long dir_release_count;
+
+       /* used for -o dirstat read() on directory thing */
+       char *dir_info;
+       int dir_info_len;
+};
+
+
+
+/*
+ * snapshots
+ */
+
+/*
+ * A "snap context" is the set of existing snapshots when we
+ * write data.  It is used by the OSD to guide its COW behavior.
+ *
+ * The ceph_snap_context is refcounted, and attached to each dirty
+ * page, indicating which context the dirty data belonged when it was
+ * dirtied.
+ */
+struct ceph_snap_context {
+       atomic_t nref;
+       u64 seq;
+       int num_snaps;
+       u64 snaps[];
+};
+
+static inline struct ceph_snap_context *
+ceph_get_snap_context(struct ceph_snap_context *sc)
+{
+       /*
+       printk("get_snap_context %p %d -> %d\n", sc, atomic_read(&sc->nref),
+              atomic_read(&sc->nref)+1);
+       */
+       if (sc)
+               atomic_inc(&sc->nref);
+       return sc;
+}
+
+static inline void ceph_put_snap_context(struct ceph_snap_context *sc)
+{
+       if (!sc)
+               return;
+       /*
+       printk("put_snap_context %p %d -> %d\n", sc, atomic_read(&sc->nref),
+              atomic_read(&sc->nref)-1);
+       */
+       if (atomic_dec_and_test(&sc->nref)) {
+               /*printk(" deleting snap_context %p\n", sc);*/
+               kfree(sc);
+       }
+}
+
+/*
+ * A "snap realm" describes a subset of the file hierarchy sharing
+ * the same set of snapshots that apply to it.  The realms themselves
+ * are organized into a hierarchy, such that children inherit (some of)
+ * the snapshots of their parents.
+ *
+ * All inodes within the realm that have capabilities are linked into a
+ * per-realm list.
+ */
+struct ceph_snap_realm {
+       u64 ino;
+       atomic_t nref;
+       struct rb_node node;
+
+       u64 created, seq;
+       u64 parent_ino;
+       u64 parent_since;   /* snapid when our current parent became so */
+
+       u64 *prior_parent_snaps;      /* snaps inherited from any parents we */
+       int num_prior_parent_snaps;   /*  had prior to parent_since */
+       u64 *snaps;                   /* snaps specific to this realm */
+       int num_snaps;
+
+       struct ceph_snap_realm *parent;
+       struct list_head children;       /* list of child realms */
+       struct list_head child_item;
+
+       struct list_head empty_item;     /* if i have ref==0 */
+
+       /* the current set of snaps for this realm */
+       struct ceph_snap_context *cached_context;
+
+       struct list_head inodes_with_caps;
+       spinlock_t inodes_with_caps_lock;
+};
+
+
+
+/*
+ * calculate the number of pages a given length and offset map onto,
+ * if we align the data.
+ */
+static inline int calc_pages_for(u64 off, u64 len)
+{
+       return ((off+len+PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT) -
+               (off >> PAGE_CACHE_SHIFT);
+}
+
+
+
+/* snap.c */
+struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc,
+                                              u64 ino);
+extern void ceph_get_snap_realm(struct ceph_mds_client *mdsc,
+                               struct ceph_snap_realm *realm);
+extern void ceph_put_snap_realm(struct ceph_mds_client *mdsc,
+                               struct ceph_snap_realm *realm);
+extern int ceph_update_snap_trace(struct ceph_mds_client *m,
+                                 void *p, void *e, bool deletion);
+extern void ceph_handle_snap(struct ceph_mds_client *mdsc,
+                            struct ceph_mds_session *session,
+                            struct ceph_msg *msg);
+extern void ceph_queue_cap_snap(struct ceph_inode_info *ci);
+extern int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
+                                 struct ceph_cap_snap *capsnap);
+extern void ceph_cleanup_empty_realms(struct ceph_mds_client *mdsc);
+
+/*
+ * a cap_snap is "pending" if it is still awaiting an in-progress
+ * sync write (that may/may not still update size, mtime, etc.).
+ */
+static inline bool __ceph_have_pending_cap_snap(struct ceph_inode_info *ci)
+{
+       return !list_empty(&ci->i_cap_snaps) &&
+               list_entry(ci->i_cap_snaps.prev, struct ceph_cap_snap,
+                          ci_item)->writing;
+}
+
+
+/* super.c */
+extern struct kmem_cache *ceph_inode_cachep;
+extern struct kmem_cache *ceph_cap_cachep;
+extern struct kmem_cache *ceph_dentry_cachep;
+extern struct kmem_cache *ceph_file_cachep;
+
+extern const char *ceph_msg_type_name(int type);
+extern int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid);
+
+#define FSID_FORMAT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" \
+       "%02x%02x%02x%02x%02x%02x"
+#define PR_FSID(f) (f)->fsid[0], (f)->fsid[1], (f)->fsid[2], (f)->fsid[3], \
+               (f)->fsid[4], (f)->fsid[5], (f)->fsid[6], (f)->fsid[7],    \
+               (f)->fsid[8], (f)->fsid[9], (f)->fsid[10], (f)->fsid[11],  \
+               (f)->fsid[12], (f)->fsid[13], (f)->fsid[14], (f)->fsid[15]
+
+/* inode.c */
+extern const struct inode_operations ceph_file_iops;
+
+extern struct inode *ceph_alloc_inode(struct super_block *sb);
+extern void ceph_destroy_inode(struct inode *inode);
+
+extern struct inode *ceph_get_inode(struct super_block *sb,
+                                   struct ceph_vino vino);
+extern struct inode *ceph_get_snapdir(struct inode *parent);
+extern int ceph_fill_file_size(struct inode *inode, int issued,
+                              u32 truncate_seq, u64 truncate_size, u64 size);
+extern void ceph_fill_file_time(struct inode *inode, int issued,
+                               u64 time_warp_seq, struct timespec *ctime,
+                               struct timespec *mtime, struct timespec *atime);
+extern int ceph_fill_trace(struct super_block *sb,
+                          struct ceph_mds_request *req,
+                          struct ceph_mds_session *session);
+extern int ceph_readdir_prepopulate(struct ceph_mds_request *req,
+                                   struct ceph_mds_session *session);
+
+extern int ceph_inode_holds_cap(struct inode *inode, int mask);
+
+extern int ceph_inode_set_size(struct inode *inode, loff_t size);
+extern void __ceph_do_pending_vmtruncate(struct inode *inode);
+extern void ceph_queue_vmtruncate(struct inode *inode);
+
+extern void ceph_queue_invalidate(struct inode *inode);
+extern void ceph_queue_writeback(struct inode *inode);
+
+extern int ceph_do_getattr(struct inode *inode, int mask);
+extern int ceph_permission(struct inode *inode, int mask);
+extern int ceph_setattr(struct dentry *dentry, struct iattr *attr);
+extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                       struct kstat *stat);
+
+/* xattr.c */
+extern int ceph_setxattr(struct dentry *, const char *, const void *,
+                        size_t, int);
+extern ssize_t ceph_getxattr(struct dentry *, const char *, void *, size_t);
+extern ssize_t ceph_listxattr(struct dentry *, char *, size_t);
+extern int ceph_removexattr(struct dentry *, const char *);
+extern void __ceph_build_xattrs_blob(struct ceph_inode_info *ci);
+extern void __ceph_destroy_xattrs(struct ceph_inode_info *ci);
+
+/* caps.c */
+extern const char *ceph_cap_string(int c);
+extern void ceph_handle_caps(struct ceph_mds_session *session,
+                            struct ceph_msg *msg);
+extern int ceph_add_cap(struct inode *inode,
+                       struct ceph_mds_session *session, u64 cap_id,
+                       int fmode, unsigned issued, unsigned wanted,
+                       unsigned cap, unsigned seq, u64 realmino, int flags,
+                       struct ceph_cap_reservation *caps_reservation);
+extern void __ceph_remove_cap(struct ceph_cap *cap);
+static inline void ceph_remove_cap(struct ceph_cap *cap)
+{
+       struct inode *inode = &cap->ci->vfs_inode;
+       spin_lock(&inode->i_lock);
+       __ceph_remove_cap(cap);
+       spin_unlock(&inode->i_lock);
+}
+extern void ceph_put_cap(struct ceph_cap *cap);
+
+extern void ceph_queue_caps_release(struct inode *inode);
+extern int ceph_write_inode(struct inode *inode, struct writeback_control *wbc);
+extern int ceph_fsync(struct file *file, struct dentry *dentry, int datasync);
+extern void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,
+                                   struct ceph_mds_session *session);
+extern int ceph_get_cap_mds(struct inode *inode);
+extern void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps);
+extern void ceph_put_cap_refs(struct ceph_inode_info *ci, int had);
+extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
+                                      struct ceph_snap_context *snapc);
+extern void __ceph_flush_snaps(struct ceph_inode_info *ci,
+                              struct ceph_mds_session **psession);
+extern void ceph_check_caps(struct ceph_inode_info *ci, int flags,
+                           struct ceph_mds_session *session);
+extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc);
+extern void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc);
+
+extern int ceph_encode_inode_release(void **p, struct inode *inode,
+                                    int mds, int drop, int unless, int force);
+extern int ceph_encode_dentry_release(void **p, struct dentry *dn,
+                                     int mds, int drop, int unless);
+
+extern int ceph_get_caps(struct ceph_inode_info *ci, int need, int want,
+                        int *got, loff_t endoff);
+
+/* for counting open files by mode */
+static inline void __ceph_get_fmode(struct ceph_inode_info *ci, int mode)
+{
+       ci->i_nr_by_mode[mode]++;
+}
+extern void ceph_put_fmode(struct ceph_inode_info *ci, int mode);
+
+/* addr.c */
+extern const struct address_space_operations ceph_aops;
+extern int ceph_mmap(struct file *file, struct vm_area_struct *vma);
+
+/* file.c */
+extern const struct file_operations ceph_file_fops;
+extern const struct address_space_operations ceph_aops;
+extern int ceph_open(struct inode *inode, struct file *file);
+extern struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
+                                      struct nameidata *nd, int mode,
+                                      int locked_dir);
+extern int ceph_release(struct inode *inode, struct file *filp);
+extern void ceph_release_page_vector(struct page **pages, int num_pages);
+
+/* dir.c */
+extern const struct file_operations ceph_dir_fops;
+extern const struct inode_operations ceph_dir_iops;
+extern struct dentry_operations ceph_dentry_ops, ceph_snap_dentry_ops,
+       ceph_snapdir_dentry_ops;
+
+extern int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry);
+extern struct dentry *ceph_finish_lookup(struct ceph_mds_request *req,
+                                        struct dentry *dentry, int err);
+
+extern void ceph_dentry_lru_add(struct dentry *dn);
+extern void ceph_dentry_lru_touch(struct dentry *dn);
+extern void ceph_dentry_lru_del(struct dentry *dn);
+
+/*
+ * our d_ops vary depending on whether the inode is live,
+ * snapshotted (read-only), or a virtual ".snap" directory.
+ */
+int ceph_init_dentry(struct dentry *dentry);
+
+
+/* ioctl.c */
+extern long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+
+/* export.c */
+extern const struct export_operations ceph_export_ops;
+
+/* debugfs.c */
+extern int ceph_debugfs_init(void);
+extern void ceph_debugfs_cleanup(void);
+extern int ceph_debugfs_client_init(struct ceph_client *client);
+extern void ceph_debugfs_client_cleanup(struct ceph_client *client);
+
+static inline struct inode *get_dentry_parent_inode(struct dentry *dentry)
+{
+       if (dentry && dentry->d_parent)
+               return dentry->d_parent->d_inode;
+
+       return NULL;
+}
+
+#endif /* _FS_CEPH_SUPER_H */
diff --git a/fs/ceph/types.h b/fs/ceph/types.h
new file mode 100644 (file)
index 0000000..28b35a0
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _FS_CEPH_TYPES_H
+#define _FS_CEPH_TYPES_H
+
+/* needed before including ceph_fs.h */
+#include <linux/in.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/string.h>
+
+#include "ceph_fs.h"
+#include "ceph_frag.h"
+#include "ceph_hash.h"
+
+/*
+ * Identify inodes by both their ino AND snapshot id (a u64).
+ */
+struct ceph_vino {
+       u64 ino;
+       u64 snap;
+};
+
+
+/* context for the caps reservation mechanism */
+struct ceph_cap_reservation {
+       int count;
+};
+
+
+#endif
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
new file mode 100644 (file)
index 0000000..2845422
--- /dev/null
@@ -0,0 +1,845 @@
+#include "ceph_debug.h"
+#include "super.h"
+#include "decode.h"
+
+#include <linux/xattr.h>
+#include <linux/slab.h>
+
+static bool ceph_is_valid_xattr(const char *name)
+{
+       return !strncmp(name, XATTR_SECURITY_PREFIX,
+                       XATTR_SECURITY_PREFIX_LEN) ||
+              !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) ||
+              !strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
+}
+
+/*
+ * These define virtual xattrs exposing the recursive directory
+ * statistics and layout metadata.
+ */
+struct ceph_vxattr_cb {
+       bool readonly;
+       char *name;
+       size_t (*getxattr_cb)(struct ceph_inode_info *ci, char *val,
+                             size_t size);
+};
+
+/* directories */
+
+static size_t ceph_vxattrcb_entries(struct ceph_inode_info *ci, char *val,
+                                       size_t size)
+{
+       return snprintf(val, size, "%lld", ci->i_files + ci->i_subdirs);
+}
+
+static size_t ceph_vxattrcb_files(struct ceph_inode_info *ci, char *val,
+                                     size_t size)
+{
+       return snprintf(val, size, "%lld", ci->i_files);
+}
+
+static size_t ceph_vxattrcb_subdirs(struct ceph_inode_info *ci, char *val,
+                                       size_t size)
+{
+       return snprintf(val, size, "%lld", ci->i_subdirs);
+}
+
+static size_t ceph_vxattrcb_rentries(struct ceph_inode_info *ci, char *val,
+                                        size_t size)
+{
+       return snprintf(val, size, "%lld", ci->i_rfiles + ci->i_rsubdirs);
+}
+
+static size_t ceph_vxattrcb_rfiles(struct ceph_inode_info *ci, char *val,
+                                      size_t size)
+{
+       return snprintf(val, size, "%lld", ci->i_rfiles);
+}
+
+static size_t ceph_vxattrcb_rsubdirs(struct ceph_inode_info *ci, char *val,
+                                        size_t size)
+{
+       return snprintf(val, size, "%lld", ci->i_rsubdirs);
+}
+
+static size_t ceph_vxattrcb_rbytes(struct ceph_inode_info *ci, char *val,
+                                      size_t size)
+{
+       return snprintf(val, size, "%lld", ci->i_rbytes);
+}
+
+static size_t ceph_vxattrcb_rctime(struct ceph_inode_info *ci, char *val,
+                                      size_t size)
+{
+       return snprintf(val, size, "%ld.%ld", (long)ci->i_rctime.tv_sec,
+                       (long)ci->i_rctime.tv_nsec);
+}
+
+static struct ceph_vxattr_cb ceph_dir_vxattrs[] = {
+       { true, "user.ceph.dir.entries", ceph_vxattrcb_entries},
+       { true, "user.ceph.dir.files", ceph_vxattrcb_files},
+       { true, "user.ceph.dir.subdirs", ceph_vxattrcb_subdirs},
+       { true, "user.ceph.dir.rentries", ceph_vxattrcb_rentries},
+       { true, "user.ceph.dir.rfiles", ceph_vxattrcb_rfiles},
+       { true, "user.ceph.dir.rsubdirs", ceph_vxattrcb_rsubdirs},
+       { true, "user.ceph.dir.rbytes", ceph_vxattrcb_rbytes},
+       { true, "user.ceph.dir.rctime", ceph_vxattrcb_rctime},
+       { true, NULL, NULL }
+};
+
+/* files */
+
+static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val,
+                                  size_t size)
+{
+       int ret;
+
+       ret = snprintf(val, size,
+               "chunk_bytes=%lld\nstripe_count=%lld\nobject_size=%lld\n",
+               (unsigned long long)ceph_file_layout_su(ci->i_layout),
+               (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout),
+               (unsigned long long)ceph_file_layout_object_size(ci->i_layout));
+       if (ceph_file_layout_pg_preferred(ci->i_layout))
+               ret += snprintf(val + ret, size, "preferred_osd=%lld\n",
+                           (unsigned long long)ceph_file_layout_pg_preferred(
+                                   ci->i_layout));
+       return ret;
+}
+
+static struct ceph_vxattr_cb ceph_file_vxattrs[] = {
+       { true, "user.ceph.layout", ceph_vxattrcb_layout},
+       { NULL, NULL }
+};
+
+static struct ceph_vxattr_cb *ceph_inode_vxattrs(struct inode *inode)
+{
+       if (S_ISDIR(inode->i_mode))
+               return ceph_dir_vxattrs;
+       else if (S_ISREG(inode->i_mode))
+               return ceph_file_vxattrs;
+       return NULL;
+}
+
+static struct ceph_vxattr_cb *ceph_match_vxattr(struct ceph_vxattr_cb *vxattr,
+                                               const char *name)
+{
+       do {
+               if (strcmp(vxattr->name, name) == 0)
+                       return vxattr;
+               vxattr++;
+       } while (vxattr->name);
+       return NULL;
+}
+
+static int __set_xattr(struct ceph_inode_info *ci,
+                          const char *name, int name_len,
+                          const char *val, int val_len,
+                          int dirty,
+                          int should_free_name, int should_free_val,
+                          struct ceph_inode_xattr **newxattr)
+{
+       struct rb_node **p;
+       struct rb_node *parent = NULL;
+       struct ceph_inode_xattr *xattr = NULL;
+       int c;
+       int new = 0;
+
+       p = &ci->i_xattrs.index.rb_node;
+       while (*p) {
+               parent = *p;
+               xattr = rb_entry(parent, struct ceph_inode_xattr, node);
+               c = strncmp(name, xattr->name, min(name_len, xattr->name_len));
+               if (c < 0)
+                       p = &(*p)->rb_left;
+               else if (c > 0)
+                       p = &(*p)->rb_right;
+               else {
+                       if (name_len == xattr->name_len)
+                               break;
+                       else if (name_len < xattr->name_len)
+                               p = &(*p)->rb_left;
+                       else
+                               p = &(*p)->rb_right;
+               }
+               xattr = NULL;
+       }
+
+       if (!xattr) {
+               new = 1;
+               xattr = *newxattr;
+               xattr->name = name;
+               xattr->name_len = name_len;
+               xattr->should_free_name = should_free_name;
+
+               ci->i_xattrs.count++;
+               dout("__set_xattr count=%d\n", ci->i_xattrs.count);
+       } else {
+               kfree(*newxattr);
+               *newxattr = NULL;
+               if (xattr->should_free_val)
+                       kfree((void *)xattr->val);
+
+               if (should_free_name) {
+                       kfree((void *)name);
+                       name = xattr->name;
+               }
+               ci->i_xattrs.names_size -= xattr->name_len;
+               ci->i_xattrs.vals_size -= xattr->val_len;
+       }
+       if (!xattr) {
+               pr_err("__set_xattr ENOMEM on %p %llx.%llx xattr %s=%s\n",
+                      &ci->vfs_inode, ceph_vinop(&ci->vfs_inode), name,
+                      xattr->val);
+               return -ENOMEM;
+       }
+       ci->i_xattrs.names_size += name_len;
+       ci->i_xattrs.vals_size += val_len;
+       if (val)
+               xattr->val = val;
+       else
+               xattr->val = "";
+
+       xattr->val_len = val_len;
+       xattr->dirty = dirty;
+       xattr->should_free_val = (val && should_free_val);
+
+       if (new) {
+               rb_link_node(&xattr->node, parent, p);
+               rb_insert_color(&xattr->node, &ci->i_xattrs.index);
+               dout("__set_xattr_val p=%p\n", p);
+       }
+
+       dout("__set_xattr_val added %llx.%llx xattr %p %s=%.*s\n",
+            ceph_vinop(&ci->vfs_inode), xattr, name, val_len, val);
+
+       return 0;
+}
+
+static struct ceph_inode_xattr *__get_xattr(struct ceph_inode_info *ci,
+                          const char *name)
+{
+       struct rb_node **p;
+       struct rb_node *parent = NULL;
+       struct ceph_inode_xattr *xattr = NULL;
+       int c;
+
+       p = &ci->i_xattrs.index.rb_node;
+       while (*p) {
+               parent = *p;
+               xattr = rb_entry(parent, struct ceph_inode_xattr, node);
+               c = strncmp(name, xattr->name, xattr->name_len);
+               if (c < 0)
+                       p = &(*p)->rb_left;
+               else if (c > 0)
+                       p = &(*p)->rb_right;
+               else {
+                       dout("__get_xattr %s: found %.*s\n", name,
+                            xattr->val_len, xattr->val);
+                       return xattr;
+               }
+       }
+
+       dout("__get_xattr %s: not found\n", name);
+
+       return NULL;
+}
+
+static void __free_xattr(struct ceph_inode_xattr *xattr)
+{
+       BUG_ON(!xattr);
+
+       if (xattr->should_free_name)
+               kfree((void *)xattr->name);
+       if (xattr->should_free_val)
+               kfree((void *)xattr->val);
+
+       kfree(xattr);
+}
+
+static int __remove_xattr(struct ceph_inode_info *ci,
+                         struct ceph_inode_xattr *xattr)
+{
+       if (!xattr)
+               return -EOPNOTSUPP;
+
+       rb_erase(&xattr->node, &ci->i_xattrs.index);
+
+       if (xattr->should_free_name)
+               kfree((void *)xattr->name);
+       if (xattr->should_free_val)
+               kfree((void *)xattr->val);
+
+       ci->i_xattrs.names_size -= xattr->name_len;
+       ci->i_xattrs.vals_size -= xattr->val_len;
+       ci->i_xattrs.count--;
+       kfree(xattr);
+
+       return 0;
+}
+
+static int __remove_xattr_by_name(struct ceph_inode_info *ci,
+                          const char *name)
+{
+       struct rb_node **p;
+       struct ceph_inode_xattr *xattr;
+       int err;
+
+       p = &ci->i_xattrs.index.rb_node;
+       xattr = __get_xattr(ci, name);
+       err = __remove_xattr(ci, xattr);
+       return err;
+}
+
+static char *__copy_xattr_names(struct ceph_inode_info *ci,
+                               char *dest)
+{
+       struct rb_node *p;
+       struct ceph_inode_xattr *xattr = NULL;
+
+       p = rb_first(&ci->i_xattrs.index);
+       dout("__copy_xattr_names count=%d\n", ci->i_xattrs.count);
+
+       while (p) {
+               xattr = rb_entry(p, struct ceph_inode_xattr, node);
+               memcpy(dest, xattr->name, xattr->name_len);
+               dest[xattr->name_len] = '\0';
+
+               dout("dest=%s %p (%s) (%d/%d)\n", dest, xattr, xattr->name,
+                    xattr->name_len, ci->i_xattrs.names_size);
+
+               dest += xattr->name_len + 1;
+               p = rb_next(p);
+       }
+
+       return dest;
+}
+
+void __ceph_destroy_xattrs(struct ceph_inode_info *ci)
+{
+       struct rb_node *p, *tmp;
+       struct ceph_inode_xattr *xattr = NULL;
+
+       p = rb_first(&ci->i_xattrs.index);
+
+       dout("__ceph_destroy_xattrs p=%p\n", p);
+
+       while (p) {
+               xattr = rb_entry(p, struct ceph_inode_xattr, node);
+               tmp = p;
+               p = rb_next(tmp);
+               dout("__ceph_destroy_xattrs next p=%p (%.*s)\n", p,
+                    xattr->name_len, xattr->name);
+               rb_erase(tmp, &ci->i_xattrs.index);
+
+               __free_xattr(xattr);
+       }
+
+       ci->i_xattrs.names_size = 0;
+       ci->i_xattrs.vals_size = 0;
+       ci->i_xattrs.index_version = 0;
+       ci->i_xattrs.count = 0;
+       ci->i_xattrs.index = RB_ROOT;
+}
+
+static int __build_xattrs(struct inode *inode)
+{
+       u32 namelen;
+       u32 numattr = 0;
+       void *p, *end;
+       u32 len;
+       const char *name, *val;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int xattr_version;
+       struct ceph_inode_xattr **xattrs = NULL;
+       int err = 0;
+       int i;
+
+       dout("__build_xattrs() len=%d\n",
+            ci->i_xattrs.blob ? (int)ci->i_xattrs.blob->vec.iov_len : 0);
+
+       if (ci->i_xattrs.index_version >= ci->i_xattrs.version)
+               return 0; /* already built */
+
+       __ceph_destroy_xattrs(ci);
+
+start:
+       /* updated internal xattr rb tree */
+       if (ci->i_xattrs.blob && ci->i_xattrs.blob->vec.iov_len > 4) {
+               p = ci->i_xattrs.blob->vec.iov_base;
+               end = p + ci->i_xattrs.blob->vec.iov_len;
+               ceph_decode_32_safe(&p, end, numattr, bad);
+               xattr_version = ci->i_xattrs.version;
+               spin_unlock(&inode->i_lock);
+
+               xattrs = kcalloc(numattr, sizeof(struct ceph_xattr *),
+                                GFP_NOFS);
+               err = -ENOMEM;
+               if (!xattrs)
+                       goto bad_lock;
+               memset(xattrs, 0, numattr*sizeof(struct ceph_xattr *));
+               for (i = 0; i < numattr; i++) {
+                       xattrs[i] = kmalloc(sizeof(struct ceph_inode_xattr),
+                                           GFP_NOFS);
+                       if (!xattrs[i])
+                               goto bad_lock;
+               }
+
+               spin_lock(&inode->i_lock);
+               if (ci->i_xattrs.version != xattr_version) {
+                       /* lost a race, retry */
+                       for (i = 0; i < numattr; i++)
+                               kfree(xattrs[i]);
+                       kfree(xattrs);
+                       goto start;
+               }
+               err = -EIO;
+               while (numattr--) {
+                       ceph_decode_32_safe(&p, end, len, bad);
+                       namelen = len;
+                       name = p;
+                       p += len;
+                       ceph_decode_32_safe(&p, end, len, bad);
+                       val = p;
+                       p += len;
+
+                       err = __set_xattr(ci, name, namelen, val, len,
+                                         0, 0, 0, &xattrs[numattr]);
+
+                       if (err < 0)
+                               goto bad;
+               }
+               kfree(xattrs);
+       }
+       ci->i_xattrs.index_version = ci->i_xattrs.version;
+       ci->i_xattrs.dirty = false;
+
+       return err;
+bad_lock:
+       spin_lock(&inode->i_lock);
+bad:
+       if (xattrs) {
+               for (i = 0; i < numattr; i++)
+                       kfree(xattrs[i]);
+               kfree(xattrs);
+       }
+       ci->i_xattrs.names_size = 0;
+       return err;
+}
+
+static int __get_required_blob_size(struct ceph_inode_info *ci, int name_size,
+                                   int val_size)
+{
+       /*
+        * 4 bytes for the length, and additional 4 bytes per each xattr name,
+        * 4 bytes per each value
+        */
+       int size = 4 + ci->i_xattrs.count*(4 + 4) +
+                            ci->i_xattrs.names_size +
+                            ci->i_xattrs.vals_size;
+       dout("__get_required_blob_size c=%d names.size=%d vals.size=%d\n",
+            ci->i_xattrs.count, ci->i_xattrs.names_size,
+            ci->i_xattrs.vals_size);
+
+       if (name_size)
+               size += 4 + 4 + name_size + val_size;
+
+       return size;
+}
+
+/*
+ * If there are dirty xattrs, reencode xattrs into the prealloc_blob
+ * and swap into place.
+ */
+void __ceph_build_xattrs_blob(struct ceph_inode_info *ci)
+{
+       struct rb_node *p;
+       struct ceph_inode_xattr *xattr = NULL;
+       void *dest;
+
+       dout("__build_xattrs_blob %p\n", &ci->vfs_inode);
+       if (ci->i_xattrs.dirty) {
+               int need = __get_required_blob_size(ci, 0, 0);
+
+               BUG_ON(need > ci->i_xattrs.prealloc_blob->alloc_len);
+
+               p = rb_first(&ci->i_xattrs.index);
+               dest = ci->i_xattrs.prealloc_blob->vec.iov_base;
+
+               ceph_encode_32(&dest, ci->i_xattrs.count);
+               while (p) {
+                       xattr = rb_entry(p, struct ceph_inode_xattr, node);
+
+                       ceph_encode_32(&dest, xattr->name_len);
+                       memcpy(dest, xattr->name, xattr->name_len);
+                       dest += xattr->name_len;
+                       ceph_encode_32(&dest, xattr->val_len);
+                       memcpy(dest, xattr->val, xattr->val_len);
+                       dest += xattr->val_len;
+
+                       p = rb_next(p);
+               }
+
+               /* adjust buffer len; it may be larger than we need */
+               ci->i_xattrs.prealloc_blob->vec.iov_len =
+                       dest - ci->i_xattrs.prealloc_blob->vec.iov_base;
+
+               if (ci->i_xattrs.blob)
+                       ceph_buffer_put(ci->i_xattrs.blob);
+               ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob;
+               ci->i_xattrs.prealloc_blob = NULL;
+               ci->i_xattrs.dirty = false;
+       }
+}
+
+ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value,
+                     size_t size)
+{
+       struct inode *inode = dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
+       int err;
+       struct ceph_inode_xattr *xattr;
+       struct ceph_vxattr_cb *vxattr = NULL;
+
+       if (!ceph_is_valid_xattr(name))
+               return -ENODATA;
+
+       /* let's see if a virtual xattr was requested */
+       if (vxattrs)
+               vxattr = ceph_match_vxattr(vxattrs, name);
+
+       spin_lock(&inode->i_lock);
+       dout("getxattr %p ver=%lld index_ver=%lld\n", inode,
+            ci->i_xattrs.version, ci->i_xattrs.index_version);
+
+       if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) &&
+           (ci->i_xattrs.index_version >= ci->i_xattrs.version)) {
+               goto get_xattr;
+       } else {
+               spin_unlock(&inode->i_lock);
+               /* get xattrs from mds (if we don't already have them) */
+               err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR);
+               if (err)
+                       return err;
+       }
+
+       spin_lock(&inode->i_lock);
+
+       if (vxattr && vxattr->readonly) {
+               err = vxattr->getxattr_cb(ci, value, size);
+               goto out;
+       }
+
+       err = __build_xattrs(inode);
+       if (err < 0)
+               goto out;
+
+get_xattr:
+       err = -ENODATA;  /* == ENOATTR */
+       xattr = __get_xattr(ci, name);
+       if (!xattr) {
+               if (vxattr)
+                       err = vxattr->getxattr_cb(ci, value, size);
+               goto out;
+       }
+
+       err = -ERANGE;
+       if (size && size < xattr->val_len)
+               goto out;
+
+       err = xattr->val_len;
+       if (size == 0)
+               goto out;
+
+       memcpy(value, xattr->val, xattr->val_len);
+
+out:
+       spin_unlock(&inode->i_lock);
+       return err;
+}
+
+ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size)
+{
+       struct inode *inode = dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
+       u32 vir_namelen = 0;
+       u32 namelen;
+       int err;
+       u32 len;
+       int i;
+
+       spin_lock(&inode->i_lock);
+       dout("listxattr %p ver=%lld index_ver=%lld\n", inode,
+            ci->i_xattrs.version, ci->i_xattrs.index_version);
+
+       if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) &&
+           (ci->i_xattrs.index_version > ci->i_xattrs.version)) {
+               goto list_xattr;
+       } else {
+               spin_unlock(&inode->i_lock);
+               err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR);
+               if (err)
+                       return err;
+       }
+
+       spin_lock(&inode->i_lock);
+
+       err = __build_xattrs(inode);
+       if (err < 0)
+               goto out;
+
+list_xattr:
+       vir_namelen = 0;
+       /* include virtual dir xattrs */
+       if (vxattrs)
+               for (i = 0; vxattrs[i].name; i++)
+                       vir_namelen += strlen(vxattrs[i].name) + 1;
+       /* adding 1 byte per each variable due to the null termination */
+       namelen = vir_namelen + ci->i_xattrs.names_size + ci->i_xattrs.count;
+       err = -ERANGE;
+       if (size && namelen > size)
+               goto out;
+
+       err = namelen;
+       if (size == 0)
+               goto out;
+
+       names = __copy_xattr_names(ci, names);
+
+       /* virtual xattr names, too */
+       if (vxattrs)
+               for (i = 0; vxattrs[i].name; i++) {
+                       len = sprintf(names, "%s", vxattrs[i].name);
+                       names += len + 1;
+               }
+
+out:
+       spin_unlock(&inode->i_lock);
+       return err;
+}
+
+static int ceph_sync_setxattr(struct dentry *dentry, const char *name,
+                             const char *value, size_t size, int flags)
+{
+       struct ceph_client *client = ceph_client(dentry->d_sb);
+       struct inode *inode = dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct inode *parent_inode = dentry->d_parent->d_inode;
+       struct ceph_mds_request *req;
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       int err;
+       int i, nr_pages;
+       struct page **pages = NULL;
+       void *kaddr;
+
+       /* copy value into some pages */
+       nr_pages = calc_pages_for(0, size);
+       if (nr_pages) {
+               pages = kmalloc(sizeof(pages[0])*nr_pages, GFP_NOFS);
+               if (!pages)
+                       return -ENOMEM;
+               err = -ENOMEM;
+               for (i = 0; i < nr_pages; i++) {
+                       pages[i] = alloc_page(GFP_NOFS);
+                       if (!pages[i]) {
+                               nr_pages = i;
+                               goto out;
+                       }
+                       kaddr = kmap(pages[i]);
+                       memcpy(kaddr, value + i*PAGE_CACHE_SIZE,
+                              min(PAGE_CACHE_SIZE, size-i*PAGE_CACHE_SIZE));
+               }
+       }
+
+       dout("setxattr value=%.*s\n", (int)size, value);
+
+       /* do request */
+       req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETXATTR,
+                                      USE_AUTH_MDS);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto out;
+       }
+       req->r_inode = igrab(inode);
+       req->r_inode_drop = CEPH_CAP_XATTR_SHARED;
+       req->r_num_caps = 1;
+       req->r_args.setxattr.flags = cpu_to_le32(flags);
+       req->r_path2 = kstrdup(name, GFP_NOFS);
+
+       req->r_pages = pages;
+       req->r_num_pages = nr_pages;
+       req->r_data_len = size;
+
+       dout("xattr.ver (before): %lld\n", ci->i_xattrs.version);
+       err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+       ceph_mdsc_put_request(req);
+       dout("xattr.ver (after): %lld\n", ci->i_xattrs.version);
+
+out:
+       if (pages) {
+               for (i = 0; i < nr_pages; i++)
+                       __free_page(pages[i]);
+               kfree(pages);
+       }
+       return err;
+}
+
+int ceph_setxattr(struct dentry *dentry, const char *name,
+                 const void *value, size_t size, int flags)
+{
+       struct inode *inode = dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
+       int err;
+       int name_len = strlen(name);
+       int val_len = size;
+       char *newname = NULL;
+       char *newval = NULL;
+       struct ceph_inode_xattr *xattr = NULL;
+       int issued;
+       int required_blob_size;
+
+       if (ceph_snap(inode) != CEPH_NOSNAP)
+               return -EROFS;
+
+       if (!ceph_is_valid_xattr(name))
+               return -EOPNOTSUPP;
+
+       if (vxattrs) {
+               struct ceph_vxattr_cb *vxattr =
+                       ceph_match_vxattr(vxattrs, name);
+               if (vxattr && vxattr->readonly)
+                       return -EOPNOTSUPP;
+       }
+
+       /* preallocate memory for xattr name, value, index node */
+       err = -ENOMEM;
+       newname = kmalloc(name_len + 1, GFP_NOFS);
+       if (!newname)
+               goto out;
+       memcpy(newname, name, name_len + 1);
+
+       if (val_len) {
+               newval = kmalloc(val_len + 1, GFP_NOFS);
+               if (!newval)
+                       goto out;
+               memcpy(newval, value, val_len);
+               newval[val_len] = '\0';
+       }
+
+       xattr = kmalloc(sizeof(struct ceph_inode_xattr), GFP_NOFS);
+       if (!xattr)
+               goto out;
+
+       spin_lock(&inode->i_lock);
+retry:
+       issued = __ceph_caps_issued(ci, NULL);
+       if (!(issued & CEPH_CAP_XATTR_EXCL))
+               goto do_sync;
+       __build_xattrs(inode);
+
+       required_blob_size = __get_required_blob_size(ci, name_len, val_len);
+
+       if (!ci->i_xattrs.prealloc_blob ||
+           required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) {
+               struct ceph_buffer *blob = NULL;
+
+               spin_unlock(&inode->i_lock);
+               dout(" preaallocating new blob size=%d\n", required_blob_size);
+               blob = ceph_buffer_new(required_blob_size, GFP_NOFS);
+               if (!blob)
+                       goto out;
+               spin_lock(&inode->i_lock);
+               if (ci->i_xattrs.prealloc_blob)
+                       ceph_buffer_put(ci->i_xattrs.prealloc_blob);
+               ci->i_xattrs.prealloc_blob = blob;
+               goto retry;
+       }
+
+       dout("setxattr %p issued %s\n", inode, ceph_cap_string(issued));
+       err = __set_xattr(ci, newname, name_len, newval,
+                         val_len, 1, 1, 1, &xattr);
+       __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
+       ci->i_xattrs.dirty = true;
+       inode->i_ctime = CURRENT_TIME;
+       spin_unlock(&inode->i_lock);
+
+       return err;
+
+do_sync:
+       spin_unlock(&inode->i_lock);
+       err = ceph_sync_setxattr(dentry, name, value, size, flags);
+out:
+       kfree(newname);
+       kfree(newval);
+       kfree(xattr);
+       return err;
+}
+
+static int ceph_send_removexattr(struct dentry *dentry, const char *name)
+{
+       struct ceph_client *client = ceph_client(dentry->d_sb);
+       struct ceph_mds_client *mdsc = &client->mdsc;
+       struct inode *inode = dentry->d_inode;
+       struct inode *parent_inode = dentry->d_parent->d_inode;
+       struct ceph_mds_request *req;
+       int err;
+
+       req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RMXATTR,
+                                      USE_AUTH_MDS);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+       req->r_inode = igrab(inode);
+       req->r_inode_drop = CEPH_CAP_XATTR_SHARED;
+       req->r_num_caps = 1;
+       req->r_path2 = kstrdup(name, GFP_NOFS);
+
+       err = ceph_mdsc_do_request(mdsc, parent_inode, req);
+       ceph_mdsc_put_request(req);
+       return err;
+}
+
+int ceph_removexattr(struct dentry *dentry, const char *name)
+{
+       struct inode *inode = dentry->d_inode;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
+       int issued;
+       int err;
+
+       if (ceph_snap(inode) != CEPH_NOSNAP)
+               return -EROFS;
+
+       if (!ceph_is_valid_xattr(name))
+               return -EOPNOTSUPP;
+
+       if (vxattrs) {
+               struct ceph_vxattr_cb *vxattr =
+                       ceph_match_vxattr(vxattrs, name);
+               if (vxattr && vxattr->readonly)
+                       return -EOPNOTSUPP;
+       }
+
+       spin_lock(&inode->i_lock);
+       __build_xattrs(inode);
+       issued = __ceph_caps_issued(ci, NULL);
+       dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued));
+
+       if (!(issued & CEPH_CAP_XATTR_EXCL))
+               goto do_sync;
+
+       err = __remove_xattr_by_name(ceph_inode(inode), name);
+       __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
+       ci->i_xattrs.dirty = true;
+       inode->i_ctime = CURRENT_TIME;
+
+       spin_unlock(&inode->i_lock);
+
+       return err;
+do_sync:
+       spin_unlock(&inode->i_lock);
+       err = ceph_send_removexattr(dentry, name);
+       return err;
+}
+
index a20bea598933459f24bed25f64ade645dea18ca9..cfd1ce34e0bc7b8c4794c81e1aa937e7f009ca75 100644 (file)
@@ -492,17 +492,13 @@ compare_oid(unsigned long *oid1, unsigned int oid1len,
 
 int
 decode_negTokenInit(unsigned char *security_blob, int length,
-                   enum securityEnum *secType)
+                   struct TCP_Server_Info *server)
 {
        struct asn1_ctx ctx;
        unsigned char *end;
        unsigned char *sequence_end;
        unsigned long *oid = NULL;
        unsigned int cls, con, tag, oidlen, rc;
-       bool use_ntlmssp = false;
-       bool use_kerberos = false;
-       bool use_kerberosu2u = false;
-       bool use_mskerberos = false;
 
        /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */
 
@@ -510,11 +506,11 @@ decode_negTokenInit(unsigned char *security_blob, int length,
 
        /* GSSAPI header */
        if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, ("Error decoding negTokenInit header"));
+               cFYI(1, "Error decoding negTokenInit header");
                return 0;
        } else if ((cls != ASN1_APL) || (con != ASN1_CON)
                   || (tag != ASN1_EOC)) {
-               cFYI(1, ("cls = %d con = %d tag = %d", cls, con, tag));
+               cFYI(1, "cls = %d con = %d tag = %d", cls, con, tag);
                return 0;
        }
 
@@ -535,56 +531,52 @@ decode_negTokenInit(unsigned char *security_blob, int length,
 
        /* SPNEGO OID not present or garbled -- bail out */
        if (!rc) {
-               cFYI(1, ("Error decoding negTokenInit header"));
+               cFYI(1, "Error decoding negTokenInit header");
                return 0;
        }
 
        /* SPNEGO */
        if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, ("Error decoding negTokenInit"));
+               cFYI(1, "Error decoding negTokenInit");
                return 0;
        } else if ((cls != ASN1_CTX) || (con != ASN1_CON)
                   || (tag != ASN1_EOC)) {
-               cFYI(1,
-                    ("cls = %d con = %d tag = %d end = %p (%d) exit 0",
-                     cls, con, tag, end, *end));
+               cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 0",
+                    cls, con, tag, end, *end);
                return 0;
        }
 
        /* negTokenInit */
        if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, ("Error decoding negTokenInit"));
+               cFYI(1, "Error decoding negTokenInit");
                return 0;
        } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
                   || (tag != ASN1_SEQ)) {
-               cFYI(1,
-                    ("cls = %d con = %d tag = %d end = %p (%d) exit 1",
-                     cls, con, tag, end, *end));
+               cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 1",
+                    cls, con, tag, end, *end);
                return 0;
        }
 
        /* sequence */
        if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, ("Error decoding 2nd part of negTokenInit"));
+               cFYI(1, "Error decoding 2nd part of negTokenInit");
                return 0;
        } else if ((cls != ASN1_CTX) || (con != ASN1_CON)
                   || (tag != ASN1_EOC)) {
-               cFYI(1,
-                    ("cls = %d con = %d tag = %d end = %p (%d) exit 0",
-                     cls, con, tag, end, *end));
+               cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 0",
+                    cls, con, tag, end, *end);
                return 0;
        }
 
        /* sequence of */
        if (asn1_header_decode
            (&ctx, &sequence_end, &cls, &con, &tag) == 0) {
-               cFYI(1, ("Error decoding 2nd part of negTokenInit"));
+               cFYI(1, "Error decoding 2nd part of negTokenInit");
                return 0;
        } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
                   || (tag != ASN1_SEQ)) {
-               cFYI(1,
-                    ("cls = %d con = %d tag = %d end = %p (%d) exit 1",
-                     cls, con, tag, end, *end));
+               cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 1",
+                    cls, con, tag, end, *end);
                return 0;
        }
 
@@ -592,37 +584,33 @@ decode_negTokenInit(unsigned char *security_blob, int length,
        while (!asn1_eoc_decode(&ctx, sequence_end)) {
                rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
                if (!rc) {
-                       cFYI(1,
-                            ("Error decoding negTokenInit hdr exit2"));
+                       cFYI(1, "Error decoding negTokenInit hdr exit2");
                        return 0;
                }
                if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
                        if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) {
 
-                               cFYI(1, ("OID len = %d oid = 0x%lx 0x%lx "
-                                        "0x%lx 0x%lx", oidlen, *oid,
-                                        *(oid + 1), *(oid + 2), *(oid + 3)));
+                               cFYI(1, "OID len = %d oid = 0x%lx 0x%lx "
+                                       "0x%lx 0x%lx", oidlen, *oid,
+                                       *(oid + 1), *(oid + 2), *(oid + 3));
 
                                if (compare_oid(oid, oidlen, MSKRB5_OID,
-                                               MSKRB5_OID_LEN) &&
-                                               !use_mskerberos)
-                                       use_mskerberos = true;
+                                               MSKRB5_OID_LEN))
+                                       server->sec_mskerberos = true;
                                else if (compare_oid(oid, oidlen, KRB5U2U_OID,
-                                                    KRB5U2U_OID_LEN) &&
-                                                    !use_kerberosu2u)
-                                       use_kerberosu2u = true;
+                                                    KRB5U2U_OID_LEN))
+                                       server->sec_kerberosu2u = true;
                                else if (compare_oid(oid, oidlen, KRB5_OID,
-                                                    KRB5_OID_LEN) &&
-                                                    !use_kerberos)
-                                       use_kerberos = true;
+                                                    KRB5_OID_LEN))
+                                       server->sec_kerberos = true;
                                else if (compare_oid(oid, oidlen, NTLMSSP_OID,
                                                     NTLMSSP_OID_LEN))
-                                       use_ntlmssp = true;
+                                       server->sec_ntlmssp = true;
 
                                kfree(oid);
                        }
                } else {
-                       cFYI(1, ("Should be an oid what is going on?"));
+                       cFYI(1, "Should be an oid what is going on?");
                }
        }
 
@@ -632,54 +620,47 @@ decode_negTokenInit(unsigned char *security_blob, int length,
                   no mechListMic (e.g. NTLMSSP instead of KRB5) */
                if (ctx.error == ASN1_ERR_DEC_EMPTY)
                        goto decode_negtoken_exit;
-               cFYI(1, ("Error decoding last part negTokenInit exit3"));
+               cFYI(1, "Error decoding last part negTokenInit exit3");
                return 0;
        } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
                /* tag = 3 indicating mechListMIC */
-               cFYI(1, ("Exit 4 cls = %d con = %d tag = %d end = %p (%d)",
-                        cls, con, tag, end, *end));
+               cFYI(1, "Exit 4 cls = %d con = %d tag = %d end = %p (%d)",
+                       cls, con, tag, end, *end);
                return 0;
        }
 
        /* sequence */
        if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, ("Error decoding last part negTokenInit exit5"));
+               cFYI(1, "Error decoding last part negTokenInit exit5");
                return 0;
        } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
                   || (tag != ASN1_SEQ)) {
-               cFYI(1, ("cls = %d con = %d tag = %d end = %p (%d)",
-                       cls, con, tag, end, *end));
+               cFYI(1, "cls = %d con = %d tag = %d end = %p (%d)",
+                       cls, con, tag, end, *end);
        }
 
        /* sequence of */
        if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, ("Error decoding last part negTokenInit exit 7"));
+               cFYI(1, "Error decoding last part negTokenInit exit 7");
                return 0;
        } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
-               cFYI(1, ("Exit 8 cls = %d con = %d tag = %d end = %p (%d)",
-                        cls, con, tag, end, *end));
+               cFYI(1, "Exit 8 cls = %d con = %d tag = %d end = %p (%d)",
+                       cls, con, tag, end, *end);
                return 0;
        }
 
        /* general string */
        if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, ("Error decoding last part negTokenInit exit9"));
+               cFYI(1, "Error decoding last part negTokenInit exit9");
                return 0;
        } else if ((cls != ASN1_UNI) || (con != ASN1_PRI)
                   || (tag != ASN1_GENSTR)) {
-               cFYI(1, ("Exit10 cls = %d con = %d tag = %d end = %p (%d)",
-                        cls, con, tag, end, *end));
+               cFYI(1, "Exit10 cls = %d con = %d tag = %d end = %p (%d)",
+                       cls, con, tag, end, *end);
                return 0;
        }
-       cFYI(1, ("Need to call asn1_octets_decode() function for %s",
-                ctx.pointer)); /* is this UTF-8 or ASCII? */
+       cFYI(1, "Need to call asn1_octets_decode() function for %s",
+               ctx.pointer);   /* is this UTF-8 or ASCII? */
 decode_negtoken_exit:
-       if (use_kerberos)
-               *secType = Kerberos;
-       else if (use_mskerberos)
-               *secType = MSKerberos;
-       else if (use_ntlmssp)
-               *secType = RawNTLMSSP;
-
        return 1;
 }
index 42cec2a7c0cf41aa250aa01a18df4cc67a9264f9..4fce6e61b34e9e889fae5fdbfbf938a7526b8ccb 100644 (file)
@@ -60,10 +60,10 @@ cifs_dump_mem(char *label, void *data, int length)
 #ifdef CONFIG_CIFS_DEBUG2
 void cifs_dump_detail(struct smb_hdr *smb)
 {
-       cERROR(1, ("Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d",
+       cERROR(1, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d",
                  smb->Command, smb->Status.CifsError,
-                 smb->Flags, smb->Flags2, smb->Mid, smb->Pid));
-       cERROR(1, ("smb buf %p len %d", smb, smbCalcSize_LE(smb)));
+                 smb->Flags, smb->Flags2, smb->Mid, smb->Pid);
+       cERROR(1, "smb buf %p len %d", smb, smbCalcSize_LE(smb));
 }
 
 
@@ -75,25 +75,25 @@ void cifs_dump_mids(struct TCP_Server_Info *server)
        if (server == NULL)
                return;
 
-       cERROR(1, ("Dump pending requests:"));
+       cERROR(1, "Dump pending requests:");
        spin_lock(&GlobalMid_Lock);
        list_for_each(tmp, &server->pending_mid_q) {
                mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
-               cERROR(1, ("State: %d Cmd: %d Pid: %d Tsk: %p Mid %d",
+               cERROR(1, "State: %d Cmd: %d Pid: %d Tsk: %p Mid %d",
                        mid_entry->midState,
                        (int)mid_entry->command,
                        mid_entry->pid,
                        mid_entry->tsk,
-                       mid_entry->mid));
+                       mid_entry->mid);
 #ifdef CONFIG_CIFS_STATS2
-               cERROR(1, ("IsLarge: %d buf: %p time rcv: %ld now: %ld",
+               cERROR(1, "IsLarge: %d buf: %p time rcv: %ld now: %ld",
                        mid_entry->largeBuf,
                        mid_entry->resp_buf,
                        mid_entry->when_received,
-                       jiffies));
+                       jiffies);
 #endif /* STATS2 */
-               cERROR(1, ("IsMult: %d IsEnd: %d", mid_entry->multiRsp,
-                         mid_entry->multiEnd));
+               cERROR(1, "IsMult: %d IsEnd: %d", mid_entry->multiRsp,
+                         mid_entry->multiEnd);
                if (mid_entry->resp_buf) {
                        cifs_dump_detail(mid_entry->resp_buf);
                        cifs_dump_mem("existing buf: ",
@@ -716,7 +716,7 @@ static const struct file_operations cifs_multiuser_mount_proc_fops = {
 
 static int cifs_security_flags_proc_show(struct seq_file *m, void *v)
 {
-       seq_printf(m, "0x%x\n", extended_security);
+       seq_printf(m, "0x%x\n", global_secflags);
        return 0;
 }
 
@@ -744,13 +744,13 @@ static ssize_t cifs_security_flags_proc_write(struct file *file,
                /* single char or single char followed by null */
                c = flags_string[0];
                if (c == '0' || c == 'n' || c == 'N') {
-                       extended_security = CIFSSEC_DEF; /* default */
+                       global_secflags = CIFSSEC_DEF; /* default */
                        return count;
                } else if (c == '1' || c == 'y' || c == 'Y') {
-                       extended_security = CIFSSEC_MAX;
+                       global_secflags = CIFSSEC_MAX;
                        return count;
                } else if (!isdigit(c)) {
-                       cERROR(1, ("invalid flag %c", c));
+                       cERROR(1, "invalid flag %c", c);
                        return -EINVAL;
                }
        }
@@ -758,26 +758,26 @@ static ssize_t cifs_security_flags_proc_write(struct file *file,
 
        flags = simple_strtoul(flags_string, NULL, 0);
 
-       cFYI(1, ("sec flags 0x%x", flags));
+       cFYI(1, "sec flags 0x%x", flags);
 
        if (flags <= 0)  {
-               cERROR(1, ("invalid security flags %s", flags_string));
+               cERROR(1, "invalid security flags %s", flags_string);
                return -EINVAL;
        }
 
        if (flags & ~CIFSSEC_MASK) {
-               cERROR(1, ("attempt to set unsupported security flags 0x%x",
-                       flags & ~CIFSSEC_MASK));
+               cERROR(1, "attempt to set unsupported security flags 0x%x",
+                       flags & ~CIFSSEC_MASK);
                return -EINVAL;
        }
        /* flags look ok - update the global security flags for cifs module */
-       extended_security = flags;
-       if (extended_security & CIFSSEC_MUST_SIGN) {
+       global_secflags = flags;
+       if (global_secflags & CIFSSEC_MUST_SIGN) {
                /* requiring signing implies signing is allowed */
-               extended_security |= CIFSSEC_MAY_SIGN;
-               cFYI(1, ("packet signing now required"));
-       } else if ((extended_security & CIFSSEC_MAY_SIGN) == 0) {
-               cFYI(1, ("packet signing disabled"));
+               global_secflags |= CIFSSEC_MAY_SIGN;
+               cFYI(1, "packet signing now required");
+       } else if ((global_secflags & CIFSSEC_MAY_SIGN) == 0) {
+               cFYI(1, "packet signing disabled");
        }
        /* BB should we turn on MAY flags for other MUST options? */
        return count;
index 5eb3b83bbfa76b90992f8bfbc805758f6a2e71bf..aa316891ac0ca4f082c4e5664e50991dc44ea0e7 100644 (file)
@@ -43,34 +43,54 @@ void dump_smb(struct smb_hdr *, int);
  */
 #ifdef CIFS_DEBUG
 
-
 /* information message: e.g., configuration, major event */
 extern int cifsFYI;
-#define cifsfyi(format,arg...) if (cifsFYI & CIFS_INFO) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg)
+#define cifsfyi(fmt, arg...)                                           \
+do {                                                                   \
+       if (cifsFYI & CIFS_INFO)                                        \
+               printk(KERN_DEBUG "%s: " fmt "\n", __FILE__, ##arg);    \
+} while (0)
 
-#define cFYI(button,prspec) if (button) cifsfyi prspec
+#define cFYI(set, fmt, arg...)                 \
+do {                                           \
+       if (set)                                \
+               cifsfyi(fmt, ##arg);            \
+} while (0)
 
-#define cifswarn(format, arg...) printk(KERN_WARNING ": " format "\n" , ## arg)
+#define cifswarn(fmt, arg...)                  \
+       printk(KERN_WARNING fmt "\n", ##arg)
 
 /* debug event message: */
 extern int cifsERROR;
 
-#define cEVENT(format,arg...) if (cifsERROR) printk(KERN_EVENT __FILE__ ": " format "\n" , ## arg)
+#define cEVENT(fmt, arg...)                                            \
+do {                                                                   \
+       if (cifsERROR)                                                  \
+               printk(KERN_EVENT "%s: " fmt "\n", __FILE__, ##arg);    \
+} while (0)
 
 /* error event message: e.g., i/o error */
-#define cifserror(format,arg...) if (cifsERROR) printk(KERN_ERR " CIFS VFS: " format "\n" "" , ## arg)
+#define cifserror(fmt, arg...)                                 \
+do {                                                           \
+       if (cifsERROR)                                          \
+               printk(KERN_ERR "CIFS VFS: " fmt "\n", ##arg);  \
+} while (0)
 
-#define cERROR(button, prspec) if (button) cifserror prspec
+#define cERROR(set, fmt, arg...)               \
+do {                                           \
+       if (set)                                \
+               cifserror(fmt, ##arg);          \
+} while (0)
 
 /*
  *     debug OFF
  *     ---------
  */
 #else          /* _CIFS_DEBUG */
-#define cERROR(button, prspec)
-#define cEVENT(format, arg...)
-#define cFYI(button, prspec)
-#define cifserror(format, arg...)
+#define cERROR(set, fmt, arg...)
+#define cEVENT(fmt, arg...)
+#define cFYI(set, fmt, arg...)
+#define cifserror(fmt, arg...)
 #endif         /* _CIFS_DEBUG */
 
 #endif                         /* _H_CIFS_DEBUG */
index b1d61d0bdfc778943fb50a6f2a8ff586201ff44b..ac19a6f3dae079c3b1caa34d0157e3536e609ba8 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/dcache.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
+#include <linux/slab.h>
 #include <linux/vfs.h>
 #include <linux/fs.h>
 #include "cifsglob.h"
@@ -84,8 +85,8 @@ static char *cifs_get_share_name(const char *node_name)
        /* find server name end */
        pSep = memchr(UNC+2, '\\', len-2);
        if (!pSep) {
-               cERROR(1, ("%s: no server name end in node name: %s",
-                       __func__, node_name));
+               cERROR(1, "%s: no server name end in node name: %s",
+                       __func__, node_name);
                kfree(UNC);
                return ERR_PTR(-EINVAL);
        }
@@ -141,8 +142,8 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
 
        rc = dns_resolve_server_name_to_ip(*devname, &srvIP);
        if (rc != 0) {
-               cERROR(1, ("%s: Failed to resolve server part of %s to IP: %d",
-                         __func__, *devname, rc));
+               cERROR(1, "%s: Failed to resolve server part of %s to IP: %d",
+                         __func__, *devname, rc);
                goto compose_mount_options_err;
        }
        /* md_len = strlen(...) + 12 for 'sep+prefixpath='
@@ -216,8 +217,8 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
                strcat(mountdata, fullpath + ref->path_consumed);
        }
 
-       /*cFYI(1,("%s: parent mountdata: %s", __func__,sb_mountdata));*/
-       /*cFYI(1, ("%s: submount mountdata: %s", __func__, mountdata ));*/
+       /*cFYI(1, "%s: parent mountdata: %s", __func__,sb_mountdata);*/
+       /*cFYI(1, "%s: submount mountdata: %s", __func__, mountdata );*/
 
 compose_mount_options_out:
        kfree(srvIP);
@@ -293,11 +294,11 @@ static int add_mount_helper(struct vfsmount *newmnt, struct nameidata *nd,
 
 static void dump_referral(const struct dfs_info3_param *ref)
 {
-       cFYI(1, ("DFS: ref path: %s", ref->path_name));
-       cFYI(1, ("DFS: node path: %s", ref->node_name));
-       cFYI(1, ("DFS: fl: %hd, srv_type: %hd", ref->flags, ref->server_type));
-       cFYI(1, ("DFS: ref_flags: %hd, path_consumed: %hd", ref->ref_flag,
-                               ref->path_consumed));
+       cFYI(1, "DFS: ref path: %s", ref->path_name);
+       cFYI(1, "DFS: node path: %s", ref->node_name);
+       cFYI(1, "DFS: fl: %hd, srv_type: %hd", ref->flags, ref->server_type);
+       cFYI(1, "DFS: ref_flags: %hd, path_consumed: %hd", ref->ref_flag,
+                               ref->path_consumed);
 }
 
 
@@ -313,7 +314,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
        int rc = 0;
        struct vfsmount *mnt = ERR_PTR(-ENOENT);
 
-       cFYI(1, ("in %s", __func__));
+       cFYI(1, "in %s", __func__);
        BUG_ON(IS_ROOT(dentry));
 
        xid = GetXid();
@@ -351,15 +352,15 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
                /* connect to a node */
                len = strlen(referrals[i].node_name);
                if (len < 2) {
-                       cERROR(1, ("%s: Net Address path too short: %s",
-                                       __func__, referrals[i].node_name));
+                       cERROR(1, "%s: Net Address path too short: %s",
+                                       __func__, referrals[i].node_name);
                        rc = -EINVAL;
                        goto out_err;
                }
                mnt = cifs_dfs_do_refmount(nd->path.mnt,
                                nd->path.dentry, referrals + i);
-               cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p", __func__,
-                                       referrals[i].node_name, mnt));
+               cFYI(1, "%s: cifs_dfs_do_refmount:%s , mnt:%p", __func__,
+                                       referrals[i].node_name, mnt);
 
                /* complete mount procedure if we accured submount */
                if (!IS_ERR(mnt))
@@ -377,7 +378,7 @@ out:
        FreeXid(xid);
        free_dfs_info_array(referrals, num_referrals);
        kfree(full_path);
-       cFYI(1, ("leaving %s" , __func__));
+       cFYI(1, "leaving %s" , __func__);
        return ERR_PTR(rc);
 out_err:
        path_put(&nd->path);
index 4797787c6a4450cc14c9faa062ee55fac762f03d..246a167cb91354e39455e11dacd84b25f22ec0a9 100644 (file)
@@ -18,6 +18,8 @@
 #ifndef _CIFS_FS_SB_H
 #define _CIFS_FS_SB_H
 
+#include <linux/backing-dev.h>
+
 #define CIFS_MOUNT_NO_PERM      1 /* do not do client vfs_perm check */
 #define CIFS_MOUNT_SET_UID      2 /* set current's euid in create etc. */
 #define CIFS_MOUNT_SERVER_INUM  4 /* inode numbers from uniqueid from server  */
@@ -50,5 +52,6 @@ struct cifs_sb_info {
 #ifdef CONFIG_CIFS_DFS_UPCALL
        char   *mountdata; /* mount options received at mount time */
 #endif
+       struct backing_dev_info bdi;
 };
 #endif                         /* _CIFS_FS_SB_H */
index 8ec7736ce954cd63cbe7a1cea7c368d248ad20ba..379bd7d9c05f8ade3045f6c19a17f81b089c7a5a 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <keys/user-type.h>
 #include <linux/key-type.h>
@@ -132,9 +133,9 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
        dp = description + strlen(description);
 
        /* for now, only sec=krb5 and sec=mskrb5 are valid */
-       if (server->secType == Kerberos)
+       if (server->sec_kerberos)
                sprintf(dp, ";sec=krb5");
-       else if (server->secType == MSKerberos)
+       else if (server->sec_mskerberos)
                sprintf(dp, ";sec=mskrb5");
        else
                goto out;
@@ -148,7 +149,7 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
        dp = description + strlen(description);
        sprintf(dp, ";pid=0x%x", current->pid);
 
-       cFYI(1, ("key description = %s", description));
+       cFYI(1, "key description = %s", description);
        spnego_key = request_key(&cifs_spnego_key_type, description, "");
 
 #ifdef CONFIG_CIFS_DEBUG2
index 714a542cbafce7f3efbe242339bec3d99a0c929f..430f510a1720a5659a2ea73eef0cf7bcf0a22182 100644 (file)
@@ -19,6 +19,7 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include "cifs_unicode.h"
 #include "cifs_uniupr.h"
 #include "cifspdu.h"
@@ -199,9 +200,8 @@ cifs_strtoUCS(__le16 *to, const char *from, int len,
                /* works for 2.4.0 kernel or later */
                charlen = codepage->char2uni(from, len, &wchar_to[i]);
                if (charlen < 1) {
-                       cERROR(1,
-                              ("strtoUCS: char2uni of %d returned %d",
-                               (int)*from, charlen));
+                       cERROR(1, "strtoUCS: char2uni of %d returned %d",
+                               (int)*from, charlen);
                        /* A question mark */
                        to[i] = cpu_to_le16(0x003f);
                        charlen = 1;
index 7dfe0842a6f6046ac590ebdb6b7762b6aad91315..85d7cf7ff2c8f263780433f54abd101a2ca3d831 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include "cifspdu.h"
 #include "cifsglob.h"
 #include "cifsacl.h"
@@ -86,11 +87,11 @@ int match_sid(struct cifs_sid *ctsid)
                                continue; /* all sub_auth values do not match */
                }
 
-               cFYI(1, ("matching sid: %s\n", wksidarr[i].sidname));
+               cFYI(1, "matching sid: %s\n", wksidarr[i].sidname);
                return 0; /* sids compare/match */
        }
 
-       cFYI(1, ("No matching sid"));
+       cFYI(1, "No matching sid");
        return -1;
 }
 
@@ -207,14 +208,14 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
                        *pbits_to_set &= ~S_IXUGO;
                return;
        } else if (type != ACCESS_ALLOWED) {
-               cERROR(1, ("unknown access control type %d", type));
+               cERROR(1, "unknown access control type %d", type);
                return;
        }
        /* else ACCESS_ALLOWED type */
 
        if (flags & GENERIC_ALL) {
                *pmode |= (S_IRWXUGO & (*pbits_to_set));
-               cFYI(DBG2, ("all perms"));
+               cFYI(DBG2, "all perms");
                return;
        }
        if ((flags & GENERIC_WRITE) ||
@@ -227,7 +228,7 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
                        ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
                *pmode |= (S_IXUGO & (*pbits_to_set));
 
-       cFYI(DBG2, ("access flags 0x%x mode now 0x%x", flags, *pmode));
+       cFYI(DBG2, "access flags 0x%x mode now 0x%x", flags, *pmode);
        return;
 }
 
@@ -256,7 +257,7 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
        if (mode & S_IXUGO)
                *pace_flags |= SET_FILE_EXEC_RIGHTS;
 
-       cFYI(DBG2, ("mode: 0x%x, access flags now 0x%x", mode, *pace_flags));
+       cFYI(DBG2, "mode: 0x%x, access flags now 0x%x", mode, *pace_flags);
        return;
 }
 
@@ -296,24 +297,24 @@ static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
        /* validate that we do not go past end of acl */
 
        if (le16_to_cpu(pace->size) < 16) {
-               cERROR(1, ("ACE too small, %d", le16_to_cpu(pace->size)));
+               cERROR(1, "ACE too small %d", le16_to_cpu(pace->size));
                return;
        }
 
        if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
-               cERROR(1, ("ACL too small to parse ACE"));
+               cERROR(1, "ACL too small to parse ACE");
                return;
        }
 
        num_subauth = pace->sid.num_subauth;
        if (num_subauth) {
                int i;
-               cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d",
+               cFYI(1, "ACE revision %d num_auth %d type %d flags %d size %d",
                        pace->sid.revision, pace->sid.num_subauth, pace->type,
-                       pace->flags, le16_to_cpu(pace->size)));
+                       pace->flags, le16_to_cpu(pace->size));
                for (i = 0; i < num_subauth; ++i) {
-                       cFYI(1, ("ACE sub_auth[%d]: 0x%x", i,
-                               le32_to_cpu(pace->sid.sub_auth[i])));
+                       cFYI(1, "ACE sub_auth[%d]: 0x%x", i,
+                               le32_to_cpu(pace->sid.sub_auth[i]));
                }
 
                /* BB add length check to make sure that we do not have huge
@@ -346,13 +347,13 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
 
        /* validate that we do not go past end of acl */
        if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
-               cERROR(1, ("ACL too small to parse DACL"));
+               cERROR(1, "ACL too small to parse DACL");
                return;
        }
 
-       cFYI(DBG2, ("DACL revision %d size %d num aces %d",
+       cFYI(DBG2, "DACL revision %d size %d num aces %d",
                le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
-               le32_to_cpu(pdacl->num_aces)));
+               le32_to_cpu(pdacl->num_aces));
 
        /* reset rwx permissions for user/group/other.
           Also, if num_aces is 0 i.e. DACL has no ACEs,
@@ -436,25 +437,25 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
        /* validate that we do not go past end of ACL - sid must be at least 8
           bytes long (assuming no sub-auths - e.g. the null SID */
        if (end_of_acl < (char *)psid + 8) {
-               cERROR(1, ("ACL too small to parse SID %p", psid));
+               cERROR(1, "ACL too small to parse SID %p", psid);
                return -EINVAL;
        }
 
        if (psid->num_subauth) {
 #ifdef CONFIG_CIFS_DEBUG2
                int i;
-               cFYI(1, ("SID revision %d num_auth %d",
-                       psid->revision, psid->num_subauth));
+               cFYI(1, "SID revision %d num_auth %d",
+                       psid->revision, psid->num_subauth);
 
                for (i = 0; i < psid->num_subauth; i++) {
-                       cFYI(1, ("SID sub_auth[%d]: 0x%x ", i,
-                               le32_to_cpu(psid->sub_auth[i])));
+                       cFYI(1, "SID sub_auth[%d]: 0x%x ", i,
+                               le32_to_cpu(psid->sub_auth[i]));
                }
 
                /* BB add length check to make sure that we do not have huge
                        num auths and therefore go off the end */
-               cFYI(1, ("RID 0x%x",
-                       le32_to_cpu(psid->sub_auth[psid->num_subauth-1])));
+               cFYI(1, "RID 0x%x",
+                       le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
 #endif
        }
 
@@ -481,11 +482,11 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
                                le32_to_cpu(pntsd->gsidoffset));
        dacloffset = le32_to_cpu(pntsd->dacloffset);
        dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
-       cFYI(DBG2, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x "
+       cFYI(DBG2, "revision %d type 0x%x ooffset 0x%x goffset 0x%x "
                 "sacloffset 0x%x dacloffset 0x%x",
                 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
                 le32_to_cpu(pntsd->gsidoffset),
-                le32_to_cpu(pntsd->sacloffset), dacloffset));
+                le32_to_cpu(pntsd->sacloffset), dacloffset);
 /*     cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
        rc = parse_sid(owner_sid_ptr, end_of_acl);
        if (rc)
@@ -499,7 +500,7 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
                parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
                           group_sid_ptr, fattr);
        else
-               cFYI(1, ("no ACL")); /* BB grant all or default perms? */
+               cFYI(1, "no ACL"); /* BB grant all or default perms? */
 
 /*     cifscred->uid = owner_sid_ptr->rid;
        cifscred->gid = group_sid_ptr->rid;
@@ -562,7 +563,7 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
        FreeXid(xid);
 
 
-       cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen));
+       cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
        return pntsd;
 }
 
@@ -580,12 +581,12 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
                         &fid, &oplock, NULL, cifs_sb->local_nls,
                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
        if (rc) {
-               cERROR(1, ("Unable to open file to get ACL"));
+               cERROR(1, "Unable to open file to get ACL");
                goto out;
        }
 
        rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen);
-       cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen));
+       cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
 
        CIFSSMBClose(xid, cifs_sb->tcon, fid);
  out:
@@ -620,7 +621,7 @@ static int set_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, __u16 fid,
        rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
        FreeXid(xid);
 
-       cFYI(DBG2, ("SetCIFSACL rc = %d", rc));
+       cFYI(DBG2, "SetCIFSACL rc = %d", rc);
        return rc;
 }
 
@@ -637,12 +638,12 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
                         &fid, &oplock, NULL, cifs_sb->local_nls,
                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
        if (rc) {
-               cERROR(1, ("Unable to open file to set ACL"));
+               cERROR(1, "Unable to open file to set ACL");
                goto out;
        }
 
        rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
-       cFYI(DBG2, ("SetCIFSACL rc = %d", rc));
+       cFYI(DBG2, "SetCIFSACL rc = %d", rc);
 
        CIFSSMBClose(xid, cifs_sb->tcon, fid);
  out:
@@ -658,7 +659,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
        struct cifsFileInfo *open_file;
        int rc;
 
-       cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode));
+       cFYI(DBG2, "set ACL for %s from mode 0x%x", path, inode->i_mode);
 
        open_file = find_readable_file(CIFS_I(inode));
        if (!open_file)
@@ -678,7 +679,7 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
        u32 acllen = 0;
        int rc = 0;
 
-       cFYI(DBG2, ("converting ACL to mode for %s", path));
+       cFYI(DBG2, "converting ACL to mode for %s", path);
 
        if (pfid)
                pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen);
@@ -689,7 +690,7 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
        if (pntsd)
                rc = parse_sec_desc(pntsd, acllen, fattr);
        if (rc)
-               cFYI(1, ("parse sec desc failed rc = %d", rc));
+               cFYI(1, "parse sec desc failed rc = %d", rc);
 
        kfree(pntsd);
        return;
@@ -703,7 +704,7 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
        struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
        struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
 
-       cFYI(DBG2, ("set ACL from mode for %s", path));
+       cFYI(DBG2, "set ACL from mode for %s", path);
 
        /* Get the security descriptor */
        pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen);
@@ -720,19 +721,19 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
                                        DEFSECDESCLEN : secdesclen;
                pnntsd = kmalloc(secdesclen, GFP_KERNEL);
                if (!pnntsd) {
-                       cERROR(1, ("Unable to allocate security descriptor"));
+                       cERROR(1, "Unable to allocate security descriptor");
                        kfree(pntsd);
                        return -ENOMEM;
                }
 
                rc = build_sec_desc(pntsd, pnntsd, inode, nmode);
 
-               cFYI(DBG2, ("build_sec_desc rc: %d", rc));
+               cFYI(DBG2, "build_sec_desc rc: %d", rc);
 
                if (!rc) {
                        /* Set the security descriptor */
                        rc = set_cifs_acl(pnntsd, secdesclen, inode, path);
-                       cFYI(DBG2, ("set_cifs_acl rc: %d", rc));
+                       cFYI(DBG2, "set_cifs_acl rc: %d", rc);
                }
 
                kfree(pnntsd);
index 7efe1745494d10a4968ef09f308af577d6ccc1c9..847628dfdc44fa95c5c0ea232b8b28ccb03347e3 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include "cifspdu.h"
 #include "cifsglob.h"
 #include "cifs_debug.h"
@@ -102,7 +103,7 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
                if (iov[i].iov_len == 0)
                        continue;
                if (iov[i].iov_base == NULL) {
-                       cERROR(1, ("null iovec entry"));
+                       cERROR(1, "null iovec entry");
                        return -EIO;
                }
                /* The first entry includes a length field (which does not get
@@ -180,8 +181,8 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
 
        /* Do not need to verify session setups with signature "BSRSPYL "  */
        if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0)
-               cFYI(1, ("dummy signature received for smb command 0x%x",
-                       cifs_pdu->Command));
+               cFYI(1, "dummy signature received for smb command 0x%x",
+                       cifs_pdu->Command);
 
        /* save off the origiginal signature so we can modify the smb and check
                its signature against what the server sent */
@@ -290,7 +291,7 @@ void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
        if (password)
                strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE);
 
-       if (!encrypt && extended_security & CIFSSEC_MAY_PLNTXT) {
+       if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) {
                memset(lnm_session_key, 0, CIFS_SESS_KEY_SIZE);
                memcpy(lnm_session_key, password_with_pad,
                        CIFS_ENCPWD_SIZE);
@@ -397,7 +398,7 @@ void setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
        /* calculate buf->ntlmv2_hash */
        rc = calc_ntlmv2_hash(ses, nls_cp);
        if (rc)
-               cERROR(1, ("could not get v2 hash rc %d", rc));
+               cERROR(1, "could not get v2 hash rc %d", rc);
        CalcNTLMv2_response(ses, resp_buf);
 
        /* now calculate the MAC key for NTLMv2 */
index 8c6a03627176bbce7dd94641455111a736b78458..78c02eb4cb1f107f6c2503acc4f6d56f7e1b1524 100644 (file)
 #include "cifs_spnego.h"
 #define CIFS_MAGIC_NUMBER 0xFF534D42   /* the first four bytes of SMB PDUs */
 
-#ifdef CONFIG_CIFS_QUOTA
-static const struct quotactl_ops cifs_quotactl_ops;
-#endif /* QUOTA */
-
 int cifsFYI = 0;
 int cifsERROR = 1;
 int traceSMB = 0;
@@ -61,7 +57,7 @@ unsigned int experimEnabled = 0;
 unsigned int linuxExtEnabled = 1;
 unsigned int lookupCacheEnabled = 1;
 unsigned int multiuser_mount = 0;
-unsigned int extended_security = CIFSSEC_DEF;
+unsigned int global_secflags = CIFSSEC_DEF;
 /* unsigned int ntlmv2_support = 0; */
 unsigned int sign_CIFS_PDUs = 1;
 static const struct super_operations cifs_super_ops;
@@ -86,8 +82,6 @@ extern mempool_t *cifs_sm_req_poolp;
 extern mempool_t *cifs_req_poolp;
 extern mempool_t *cifs_mid_poolp;
 
-extern struct kmem_cache *cifs_oplock_cachep;
-
 static int
 cifs_read_super(struct super_block *sb, void *data,
                const char *devname, int silent)
@@ -103,6 +97,12 @@ cifs_read_super(struct super_block *sb, void *data,
        if (cifs_sb == NULL)
                return -ENOMEM;
 
+       rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
+       if (rc) {
+               kfree(cifs_sb);
+               return rc;
+       }
+
 #ifdef CONFIG_CIFS_DFS_UPCALL
        /* copy mount params to sb for use in submounts */
        /* BB: should we move this after the mount so we
@@ -115,6 +115,7 @@ cifs_read_super(struct super_block *sb, void *data,
                int len = strlen(data);
                cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL);
                if (cifs_sb->mountdata == NULL) {
+                       bdi_destroy(&cifs_sb->bdi);
                        kfree(sb->s_fs_info);
                        sb->s_fs_info = NULL;
                        return -ENOMEM;
@@ -128,19 +129,16 @@ cifs_read_super(struct super_block *sb, void *data,
 
        if (rc) {
                if (!silent)
-                       cERROR(1,
-                              ("cifs_mount failed w/return code = %d", rc));
+                       cERROR(1, "cifs_mount failed w/return code = %d", rc);
                goto out_mount_failed;
        }
 
        sb->s_magic = CIFS_MAGIC_NUMBER;
        sb->s_op = &cifs_super_ops;
+       sb->s_bdi = &cifs_sb->bdi;
 /*     if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
            sb->s_blocksize =
                cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
-#ifdef CONFIG_CIFS_QUOTA
-       sb->s_qcop = &cifs_quotactl_ops;
-#endif
        sb->s_blocksize = CIFS_MAX_MSGSIZE;
        sb->s_blocksize_bits = 14;      /* default 2**14 = CIFS_MAX_MSGSIZE */
        inode = cifs_root_iget(sb, ROOT_I);
@@ -160,7 +158,7 @@ cifs_read_super(struct super_block *sb, void *data,
 
 #ifdef CONFIG_CIFS_EXPERIMENTAL
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
-               cFYI(1, ("export ops supported"));
+               cFYI(1, "export ops supported");
                sb->s_export_op = &cifs_export_ops;
        }
 #endif /* EXPERIMENTAL */
@@ -168,7 +166,7 @@ cifs_read_super(struct super_block *sb, void *data,
        return 0;
 
 out_no_root:
-       cERROR(1, ("cifs_read_super: get root inode failed"));
+       cERROR(1, "cifs_read_super: get root inode failed");
        if (inode)
                iput(inode);
 
@@ -183,6 +181,7 @@ out_mount_failed:
                }
 #endif
                unload_nls(cifs_sb->local_nls);
+               bdi_destroy(&cifs_sb->bdi);
                kfree(cifs_sb);
        }
        return rc;
@@ -194,10 +193,10 @@ cifs_put_super(struct super_block *sb)
        int rc = 0;
        struct cifs_sb_info *cifs_sb;
 
-       cFYI(1, ("In cifs_put_super"));
+       cFYI(1, "In cifs_put_super");
        cifs_sb = CIFS_SB(sb);
        if (cifs_sb == NULL) {
-               cFYI(1, ("Empty cifs superblock info passed to unmount"));
+               cFYI(1, "Empty cifs superblock info passed to unmount");
                return;
        }
 
@@ -205,7 +204,7 @@ cifs_put_super(struct super_block *sb)
 
        rc = cifs_umount(sb, cifs_sb);
        if (rc)
-               cERROR(1, ("cifs_umount failed with return code %d", rc));
+               cERROR(1, "cifs_umount failed with return code %d", rc);
 #ifdef CONFIG_CIFS_DFS_UPCALL
        if (cifs_sb->mountdata) {
                kfree(cifs_sb->mountdata);
@@ -214,6 +213,7 @@ cifs_put_super(struct super_block *sb)
 #endif
 
        unload_nls(cifs_sb->local_nls);
+       bdi_destroy(&cifs_sb->bdi);
        kfree(cifs_sb);
 
        unlock_kernel();
@@ -290,7 +290,6 @@ static int cifs_permission(struct inode *inode, int mask)
 static struct kmem_cache *cifs_inode_cachep;
 static struct kmem_cache *cifs_req_cachep;
 static struct kmem_cache *cifs_mid_cachep;
-struct kmem_cache *cifs_oplock_cachep;
 static struct kmem_cache *cifs_sm_req_cachep;
 mempool_t *cifs_sm_req_poolp;
 mempool_t *cifs_req_poolp;
@@ -312,6 +311,7 @@ cifs_alloc_inode(struct super_block *sb)
        cifs_inode->clientCanCacheRead = false;
        cifs_inode->clientCanCacheAll = false;
        cifs_inode->delete_pending = false;
+       cifs_inode->invalid_mapping = false;
        cifs_inode->vfs_inode.i_blkbits = 14;  /* 2**14 = CIFS_MAX_MSGSIZE */
        cifs_inode->server_eof = 0;
 
@@ -421,106 +421,6 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
        return 0;
 }
 
-#ifdef CONFIG_CIFS_QUOTA
-int cifs_xquota_set(struct super_block *sb, int quota_type, qid_t qid,
-               struct fs_disk_quota *pdquota)
-{
-       int xid;
-       int rc = 0;
-       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-       struct cifsTconInfo *pTcon;
-
-       if (cifs_sb)
-               pTcon = cifs_sb->tcon;
-       else
-               return -EIO;
-
-
-       xid = GetXid();
-       if (pTcon) {
-               cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
-       } else
-               rc = -EIO;
-
-       FreeXid(xid);
-       return rc;
-}
-
-int cifs_xquota_get(struct super_block *sb, int quota_type, qid_t qid,
-                   struct fs_disk_quota *pdquota)
-{
-       int xid;
-       int rc = 0;
-       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-       struct cifsTconInfo *pTcon;
-
-       if (cifs_sb)
-               pTcon = cifs_sb->tcon;
-       else
-               return -EIO;
-
-       xid = GetXid();
-       if (pTcon) {
-               cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
-       } else
-               rc = -EIO;
-
-       FreeXid(xid);
-       return rc;
-}
-
-int cifs_xstate_set(struct super_block *sb, unsigned int flags, int operation)
-{
-       int xid;
-       int rc = 0;
-       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-       struct cifsTconInfo *pTcon;
-
-       if (cifs_sb)
-               pTcon = cifs_sb->tcon;
-       else
-               return -EIO;
-
-       xid = GetXid();
-       if (pTcon) {
-               cFYI(1, ("flags: 0x%x operation: 0x%x", flags, operation));
-       } else
-               rc = -EIO;
-
-       FreeXid(xid);
-       return rc;
-}
-
-int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats)
-{
-       int xid;
-       int rc = 0;
-       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-       struct cifsTconInfo *pTcon;
-
-       if (cifs_sb)
-               pTcon = cifs_sb->tcon;
-       else
-               return -EIO;
-
-       xid = GetXid();
-       if (pTcon) {
-               cFYI(1, ("pqstats %p", qstats));
-       } else
-               rc = -EIO;
-
-       FreeXid(xid);
-       return rc;
-}
-
-static const struct quotactl_ops cifs_quotactl_ops = {
-       .set_xquota     = cifs_xquota_set,
-       .get_xquota     = cifs_xquota_get,
-       .set_xstate     = cifs_xstate_set,
-       .get_xstate     = cifs_xstate_get,
-};
-#endif
-
 static void cifs_umount_begin(struct super_block *sb)
 {
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
@@ -547,7 +447,7 @@ static void cifs_umount_begin(struct super_block *sb)
        /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
        /* cancel_notify_requests(tcon); */
        if (tcon->ses && tcon->ses->server) {
-               cFYI(1, ("wake up tasks now - umount begin not complete"));
+               cFYI(1, "wake up tasks now - umount begin not complete");
                wake_up_all(&tcon->ses->server->request_q);
                wake_up_all(&tcon->ses->server->response_q);
                msleep(1); /* yield */
@@ -598,7 +498,7 @@ cifs_get_sb(struct file_system_type *fs_type,
        int rc;
        struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL);
 
-       cFYI(1, ("Devname: %s flags: %d ", dev_name, flags));
+       cFYI(1, "Devname: %s flags: %d ", dev_name, flags);
 
        if (IS_ERR(sb))
                return PTR_ERR(sb);
@@ -638,14 +538,13 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
                   setting the revalidate time to zero */
                CIFS_I(file->f_path.dentry->d_inode)->time = 0;
 
-               retval = cifs_revalidate(file->f_path.dentry);
+               retval = cifs_revalidate_file(file);
                if (retval < 0)
                        return (loff_t)retval;
        }
        return generic_file_llseek_unlocked(file, offset, origin);
 }
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
 {
        /* note that this is called by vfs setlease with the BKL held
@@ -674,7 +573,6 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
        else
                return -EAGAIN;
 }
-#endif
 
 struct file_system_type cifs_fs_type = {
        .owner = THIS_MODULE,
@@ -751,10 +649,7 @@ const struct file_operations cifs_file_ops = {
 #ifdef CONFIG_CIFS_POSIX
        .unlocked_ioctl = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
-
-#ifdef CONFIG_CIFS_EXPERIMENTAL
        .setlease = cifs_setlease,
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
 };
 
 const struct file_operations cifs_file_direct_ops = {
@@ -773,9 +668,7 @@ const struct file_operations cifs_file_direct_ops = {
        .unlocked_ioctl  = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
        .llseek = cifs_llseek,
-#ifdef CONFIG_CIFS_EXPERIMENTAL
        .setlease = cifs_setlease,
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
 };
 const struct file_operations cifs_file_nobrl_ops = {
        .read = do_sync_read,
@@ -792,10 +685,7 @@ const struct file_operations cifs_file_nobrl_ops = {
 #ifdef CONFIG_CIFS_POSIX
        .unlocked_ioctl = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
-
-#ifdef CONFIG_CIFS_EXPERIMENTAL
        .setlease = cifs_setlease,
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
 };
 
 const struct file_operations cifs_file_direct_nobrl_ops = {
@@ -807,14 +697,13 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
        .release = cifs_close,
        .fsync = cifs_fsync,
        .flush = cifs_flush,
+       .mmap = cifs_file_mmap,
        .splice_read = generic_file_splice_read,
 #ifdef CONFIG_CIFS_POSIX
        .unlocked_ioctl  = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
        .llseek = cifs_llseek,
-#ifdef CONFIG_CIFS_EXPERIMENTAL
        .setlease = cifs_setlease,
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
 };
 
 const struct file_operations cifs_dir_ops = {
@@ -866,7 +755,7 @@ cifs_init_request_bufs(void)
        } else {
                CIFSMaxBufSize &= 0x1FE00; /* Round size to even 512 byte mult*/
        }
-/*     cERROR(1,("CIFSMaxBufSize %d 0x%x",CIFSMaxBufSize,CIFSMaxBufSize)); */
+/*     cERROR(1, "CIFSMaxBufSize %d 0x%x",CIFSMaxBufSize,CIFSMaxBufSize); */
        cifs_req_cachep = kmem_cache_create("cifs_request",
                                            CIFSMaxBufSize +
                                            MAX_CIFS_HDR_SIZE, 0,
@@ -878,7 +767,7 @@ cifs_init_request_bufs(void)
                cifs_min_rcv = 1;
        else if (cifs_min_rcv > 64) {
                cifs_min_rcv = 64;
-               cERROR(1, ("cifs_min_rcv set to maximum (64)"));
+               cERROR(1, "cifs_min_rcv set to maximum (64)");
        }
 
        cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv,
@@ -909,7 +798,7 @@ cifs_init_request_bufs(void)
                cifs_min_small = 2;
        else if (cifs_min_small > 256) {
                cifs_min_small = 256;
-               cFYI(1, ("cifs_min_small set to maximum (256)"));
+               cFYI(1, "cifs_min_small set to maximum (256)");
        }
 
        cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small,
@@ -950,15 +839,6 @@ cifs_init_mids(void)
                return -ENOMEM;
        }
 
-       cifs_oplock_cachep = kmem_cache_create("cifs_oplock_structs",
-                                       sizeof(struct oplock_q_entry), 0,
-                                       SLAB_HWCACHE_ALIGN, NULL);
-       if (cifs_oplock_cachep == NULL) {
-               mempool_destroy(cifs_mid_poolp);
-               kmem_cache_destroy(cifs_mid_cachep);
-               return -ENOMEM;
-       }
-
        return 0;
 }
 
@@ -967,7 +847,6 @@ cifs_destroy_mids(void)
 {
        mempool_destroy(cifs_mid_poolp);
        kmem_cache_destroy(cifs_mid_cachep);
-       kmem_cache_destroy(cifs_oplock_cachep);
 }
 
 static int __init
@@ -1007,10 +886,10 @@ init_cifs(void)
 
        if (cifs_max_pending < 2) {
                cifs_max_pending = 2;
-               cFYI(1, ("cifs_max_pending set to min of 2"));
+               cFYI(1, "cifs_max_pending set to min of 2");
        } else if (cifs_max_pending > 256) {
                cifs_max_pending = 256;
-               cFYI(1, ("cifs_max_pending set to max of 256"));
+               cFYI(1, "cifs_max_pending set to max of 256");
        }
 
        rc = cifs_init_inodecache();
@@ -1068,7 +947,7 @@ init_cifs(void)
 static void __exit
 exit_cifs(void)
 {
-       cFYI(DBG2, ("exit_cifs"));
+       cFYI(DBG2, "exit_cifs");
        cifs_proc_clean();
 #ifdef CONFIG_CIFS_DFS_UPCALL
        cifs_dfs_release_automount_timer();
index 78c1b86d55f6fcf3a42eeec70968e9f7efc69b3b..0242ff9cbf41f5bb6bcc3b44a32347427ae8b539 100644 (file)
@@ -61,7 +61,8 @@ extern int cifs_mkdir(struct inode *, struct dentry *, int);
 extern int cifs_rmdir(struct inode *, struct dentry *);
 extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
                       struct dentry *);
-extern int cifs_revalidate(struct dentry *);
+extern int cifs_revalidate_file(struct file *filp);
+extern int cifs_revalidate_dentry(struct dentry *);
 extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
 extern int cifs_setattr(struct dentry *, struct iattr *);
 
@@ -113,5 +114,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
 extern const struct export_operations cifs_export_ops;
 #endif /* EXPERIMENTAL */
 
-#define CIFS_VERSION   "1.62"
+#define CIFS_VERSION   "1.64"
 #endif                         /* _CIFSFS_H */
index a1c817eb291aa6ca2b2fb20ced21f9d9c991ac8c..a88479ceaad59602919d3d6d1a1c7a01855d69ac 100644 (file)
@@ -18,6 +18,7 @@
  */
 #include <linux/in.h>
 #include <linux/in6.h>
+#include <linux/slab.h>
 #include <linux/slow-work.h>
 #include "cifs_fs_sb.h"
 #include "cifsacl.h"
@@ -86,7 +87,6 @@ enum securityEnum {
        RawNTLMSSP,             /* NTLMSSP without SPNEGO, NTLMv2 hash */
 /*     NTLMSSP, */ /* can use rawNTLMSSP instead of NTLMSSP via SPNEGO */
        Kerberos,               /* Kerberos via SPNEGO */
-       MSKerberos,             /* MS Kerberos via SPNEGO */
 };
 
 enum protocolEnum {
@@ -184,6 +184,12 @@ struct TCP_Server_Info {
        struct mac_key mac_signing_key;
        char ntlmv2_hash[16];
        unsigned long lstrp; /* when we got last response from this server */
+       u16 dialect; /* dialect index that server chose */
+       /* extended security flavors that server supports */
+       bool    sec_kerberos;           /* supports plain Kerberos */
+       bool    sec_mskerberos;         /* supports legacy MS Kerberos */
+       bool    sec_kerberosu2u;        /* supports U2U Kerberos */
+       bool    sec_ntlmssp;            /* supports NTLMSSP */
 };
 
 /*
@@ -389,6 +395,7 @@ struct cifsInodeInfo {
        bool clientCanCacheRead:1;      /* read oplock */
        bool clientCanCacheAll:1;       /* read and writebehind oplock */
        bool delete_pending:1;          /* DELETE_ON_CLOSE is set */
+       bool invalid_mapping:1;         /* pagecache is invalid */
        u64  server_eof;                /* current file size on server */
        u64  uniqueid;                  /* server inode number */
        struct inode vfs_inode;
@@ -500,6 +507,7 @@ struct dfs_info3_param {
 #define CIFS_FATTR_DFS_REFERRAL                0x1
 #define CIFS_FATTR_DELETE_PENDING      0x2
 #define CIFS_FATTR_NEED_REVAL          0x4
+#define CIFS_FATTR_INO_COLLISION       0x8
 
 struct cifs_fattr {
        u32             cf_flags;
@@ -715,7 +723,7 @@ GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions
 GLOBAL_EXTERN unsigned int oplockEnabled;
 GLOBAL_EXTERN unsigned int experimEnabled;
 GLOBAL_EXTERN unsigned int lookupCacheEnabled;
-GLOBAL_EXTERN unsigned int extended_security;  /* if on, session setup sent
+GLOBAL_EXTERN unsigned int global_secflags;    /* if on, session setup sent
                                with more secure ntlmssp2 challenge/resp */
 GLOBAL_EXTERN unsigned int sign_CIFS_PDUs;  /* enable smb packet signing */
 GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/
index 88e2bc44ac583860e15391041e4c0659e885094f..fb1657e0fdb812d204b3a9309e3e245e3032e985 100644 (file)
@@ -39,8 +39,20 @@ extern int smb_send(struct TCP_Server_Info *, struct smb_hdr *,
                        unsigned int /* length */);
 extern unsigned int _GetXid(void);
 extern void _FreeXid(unsigned int);
-#define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current_fsuid()));
-#define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__func__,curr_xid,(int)rc));}
+#define GetXid()                                               \
+({                                                             \
+       int __xid = (int)_GetXid();                             \
+       cFYI(1, "CIFS VFS: in %s as Xid: %d with uid: %d",      \
+            __func__, __xid, current_fsuid());                 \
+       __xid;                                                  \
+})
+
+#define FreeXid(curr_xid)                                      \
+do {                                                           \
+       _FreeXid(curr_xid);                                     \
+       cFYI(1, "CIFS VFS: leaving %s (xid = %d) rc = %d",      \
+            __func__, curr_xid, (int)rc);                      \
+} while (0)
 extern char *build_path_from_dentry(struct dentry *);
 extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb);
 extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
@@ -73,7 +85,7 @@ extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *);
 extern unsigned int smbCalcSize(struct smb_hdr *ptr);
 extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
 extern int decode_negTokenInit(unsigned char *security_blob, int length,
-                       enum securityEnum *secType);
+                       struct TCP_Server_Info *server);
 extern int cifs_convert_address(char *src, void *dst);
 extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr);
 extern void header_assemble(struct smb_hdr *, char /* command */ ,
@@ -83,7 +95,6 @@ extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
                                struct cifsSesInfo *ses,
                                void **request_buf);
 extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
-                            const int stage,
                             const struct nls_table *nls_cp);
 extern __u16 GetNextMid(struct TCP_Server_Info *server);
 extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
@@ -95,8 +106,11 @@ extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode,
                                __u16 fileHandle, struct file *file,
                                struct vfsmount *mnt, unsigned int oflags);
 extern int cifs_posix_open(char *full_path, struct inode **pinode,
-                          struct vfsmount *mnt, int mode, int oflags,
-                          __u32 *poplock, __u16 *pnetfid, int xid);
+                               struct vfsmount *mnt,
+                               struct super_block *sb,
+                               int mode, int oflags,
+                               __u32 *poplock, __u16 *pnetfid, int xid);
+void cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr);
 extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
                                     FILE_UNIX_BASIC_INFO *info,
                                     struct cifs_sb_info *cifs_sb);
@@ -104,10 +118,12 @@ extern void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
 extern struct inode *cifs_iget(struct super_block *sb,
                               struct cifs_fattr *fattr);
 
+extern int cifs_get_file_info(struct file *filp);
 extern int cifs_get_inode_info(struct inode **pinode,
                        const unsigned char *search_path,
                        FILE_ALL_INFO *pfile_info,
                        struct super_block *sb, int xid, const __u16 *pfid);
+extern int cifs_get_file_info_unix(struct file *filp);
 extern int cifs_get_inode_info_unix(struct inode **pinode,
                        const unsigned char *search_path,
                        struct super_block *sb, int xid);
@@ -123,7 +139,9 @@ extern void cifs_dfs_release_automount_timer(void);
 void cifs_proc_init(void);
 void cifs_proc_clean(void);
 
-extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
+extern int cifs_negotiate_protocol(unsigned int xid,
+                                 struct cifsSesInfo *ses);
+extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
                        struct nls_table *nls_info);
 extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses);
 
@@ -142,6 +160,8 @@ extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
 extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
                        const __u16 search_handle);
 
+extern int CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon,
+                       u16 netfid, FILE_ALL_INFO *pFindData);
 extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
                        const unsigned char *searchName,
                        FILE_ALL_INFO *findData,
@@ -152,6 +172,8 @@ extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
                        FILE_ALL_INFO *findData,
                        const struct nls_table *nls_codepage, int remap);
 
+extern int CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon,
+                       u16 netfid, FILE_UNIX_BASIC_INFO *pFindData);
 extern int CIFSSMBUnixQPathInfo(const int xid,
                        struct cifsTconInfo *tcon,
                        const unsigned char *searchName,
index 6118358998440791183ce19bd6ead2e7cf0c1d1b..c65c3419dd3703f12bb4994e9333c085c907ecfa 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/cifssmb.c
  *
- *   Copyright (C) International Business Machines  Corp., 2002,2009
+ *   Copyright (C) International Business Machines  Corp., 2002,2010
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   Contains the routines for constructing the SMB PDUs themselves
@@ -30,6 +30,7 @@
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/vfs.h>
+#include <linux/slab.h>
 #include <linux/posix_acl_xattr.h>
 #include <asm/uaccess.h>
 #include "cifspdu.h"
@@ -129,8 +130,8 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
                if (smb_command != SMB_COM_WRITE_ANDX &&
                    smb_command != SMB_COM_OPEN_ANDX &&
                    smb_command != SMB_COM_TREE_DISCONNECT) {
-                       cFYI(1, ("can not send cmd %d while umounting",
-                               smb_command));
+                       cFYI(1, "can not send cmd %d while umounting",
+                               smb_command);
                        return -ENODEV;
                }
        }
@@ -156,7 +157,7 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
                 * back on-line
                 */
                if (!tcon->retry || ses->status == CifsExiting) {
-                       cFYI(1, ("gave up waiting on reconnect in smb_init"));
+                       cFYI(1, "gave up waiting on reconnect in smb_init");
                        return -EHOSTDOWN;
                }
        }
@@ -171,7 +172,8 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
         * reconnect the same SMB session
         */
        mutex_lock(&ses->session_mutex);
-       if (ses->need_reconnect)
+       rc = cifs_negotiate_protocol(0, ses);
+       if (rc == 0 && ses->need_reconnect)
                rc = cifs_setup_session(0, ses, nls_codepage);
 
        /* do we need to reconnect tcon? */
@@ -183,7 +185,7 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
        mark_open_files_invalid(tcon);
        rc = CIFSTCon(0, ses, tcon->treeName, tcon, nls_codepage);
        mutex_unlock(&ses->session_mutex);
-       cFYI(1, ("reconnect tcon rc = %d", rc));
+       cFYI(1, "reconnect tcon rc = %d", rc);
 
        if (rc)
                goto out;
@@ -354,7 +356,6 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        struct TCP_Server_Info *server;
        u16 count;
        unsigned int secFlags;
-       u16 dialect;
 
        if (ses->server)
                server = ses->server;
@@ -371,9 +372,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
                secFlags = ses->overrideSecFlg;  /* BB FIXME fix sign flags? */
        else /* if override flags set only sign/seal OR them with global auth */
-               secFlags = extended_security | ses->overrideSecFlg;
+               secFlags = global_secflags | ses->overrideSecFlg;
 
-       cFYI(1, ("secFlags 0x%x", secFlags));
+       cFYI(1, "secFlags 0x%x", secFlags);
 
        pSMB->hdr.Mid = GetNextMid(server);
        pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
@@ -381,14 +382,14 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
                pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
        else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) {
-               cFYI(1, ("Kerberos only mechanism, enable extended security"));
+               cFYI(1, "Kerberos only mechanism, enable extended security");
                pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
        }
 #ifdef CONFIG_CIFS_EXPERIMENTAL
        else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
                pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
        else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) {
-               cFYI(1, ("NTLMSSP only mechanism, enable extended security"));
+               cFYI(1, "NTLMSSP only mechanism, enable extended security");
                pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
        }
 #endif
@@ -407,10 +408,10 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        if (rc != 0)
                goto neg_err_exit;
 
-       dialect = le16_to_cpu(pSMBr->DialectIndex);
-       cFYI(1, ("Dialect: %d", dialect));
+       server->dialect = le16_to_cpu(pSMBr->DialectIndex);
+       cFYI(1, "Dialect: %d", server->dialect);
        /* Check wct = 1 error case */
-       if ((pSMBr->hdr.WordCount < 13) || (dialect == BAD_PROT)) {
+       if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
                /* core returns wct = 1, but we do not ask for core - otherwise
                small wct just comes when dialect index is -1 indicating we
                could not negotiate a common dialect */
@@ -418,8 +419,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                goto neg_err_exit;
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
        } else if ((pSMBr->hdr.WordCount == 13)
-                       && ((dialect == LANMAN_PROT)
-                               || (dialect == LANMAN2_PROT))) {
+                       && ((server->dialect == LANMAN_PROT)
+                               || (server->dialect == LANMAN2_PROT))) {
                __s16 tmp;
                struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
 
@@ -427,8 +428,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                        (secFlags & CIFSSEC_MAY_PLNTXT))
                        server->secType = LANMAN;
                else {
-                       cERROR(1, ("mount failed weak security disabled"
-                                  " in /proc/fs/cifs/SecurityFlags"));
+                       cERROR(1, "mount failed weak security disabled"
+                                  " in /proc/fs/cifs/SecurityFlags");
                        rc = -EOPNOTSUPP;
                        goto neg_err_exit;
                }
@@ -461,9 +462,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                        utc = CURRENT_TIME;
                        ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
                                            rsp->SrvTime.Time, 0);
-                       cFYI(1, ("SrvTime %d sec since 1970 (utc: %d) diff: %d",
+                       cFYI(1, "SrvTime %d sec since 1970 (utc: %d) diff: %d",
                                (int)ts.tv_sec, (int)utc.tv_sec,
-                               (int)(utc.tv_sec - ts.tv_sec)));
+                               (int)(utc.tv_sec - ts.tv_sec));
                        val = (int)(utc.tv_sec - ts.tv_sec);
                        seconds = abs(val);
                        result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
@@ -477,7 +478,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                        server->timeAdj = (int)tmp;
                        server->timeAdj *= 60; /* also in seconds */
                }
-               cFYI(1, ("server->timeAdj: %d seconds", server->timeAdj));
+               cFYI(1, "server->timeAdj: %d seconds", server->timeAdj);
 
 
                /* BB get server time for time conversions and add
@@ -492,15 +493,15 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                        goto neg_err_exit;
                }
 
-               cFYI(1, ("LANMAN negotiated"));
+               cFYI(1, "LANMAN negotiated");
                /* we will not end up setting signing flags - as no signing
                was in LANMAN and server did not return the flags on */
                goto signing_check;
 #else /* weak security disabled */
        } else if (pSMBr->hdr.WordCount == 13) {
-               cERROR(1, ("mount failed, cifs module not built "
-                         "with CIFS_WEAK_PW_HASH support"));
-                       rc = -EOPNOTSUPP;
+               cERROR(1, "mount failed, cifs module not built "
+                         "with CIFS_WEAK_PW_HASH support");
+               rc = -EOPNOTSUPP;
 #endif /* WEAK_PW_HASH */
                goto neg_err_exit;
        } else if (pSMBr->hdr.WordCount != 17) {
@@ -511,14 +512,14 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        /* else wct == 17 NTLM */
        server->secMode = pSMBr->SecurityMode;
        if ((server->secMode & SECMODE_USER) == 0)
-               cFYI(1, ("share mode security"));
+               cFYI(1, "share mode security");
 
        if ((server->secMode & SECMODE_PW_ENCRYPT) == 0)
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
                if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
 #endif /* CIFS_WEAK_PW_HASH */
-                       cERROR(1, ("Server requests plain text password"
-                                 " but client support disabled"));
+                       cERROR(1, "Server requests plain text password"
+                                 " but client support disabled");
 
        if ((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
                server->secType = NTLMv2;
@@ -538,7 +539,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
 #endif */
        else {
                rc = -EOPNOTSUPP;
-               cERROR(1, ("Invalid security type"));
+               cERROR(1, "Invalid security type");
                goto neg_err_exit;
        }
        /* else ... any others ...? */
@@ -550,7 +551,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize),
                        (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
        server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
-       cFYI(DBG2, ("Max buf = %d", ses->server->maxBuf));
+       cFYI(DBG2, "Max buf = %d", ses->server->maxBuf);
        GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey);
        server->capabilities = le32_to_cpu(pSMBr->Capabilities);
        server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
@@ -581,7 +582,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                        if (memcmp(server->server_GUID,
                                   pSMBr->u.extended_response.
                                   GUID, 16) != 0) {
-                               cFYI(1, ("server UID changed"));
+                               cFYI(1, "server UID changed");
                                memcpy(server->server_GUID,
                                        pSMBr->u.extended_response.GUID,
                                        16);
@@ -596,13 +597,19 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                        server->secType = RawNTLMSSP;
                } else {
                        rc = decode_negTokenInit(pSMBr->u.extended_response.
-                                                SecurityBlob,
-                                                count - 16,
-                                                &server->secType);
+                                                SecurityBlob, count - 16,
+                                                server);
                        if (rc == 1)
                                rc = 0;
                        else
                                rc = -EINVAL;
+
+                       if (server->sec_kerberos || server->sec_mskerberos)
+                               server->secType = Kerberos;
+                       else if (server->sec_ntlmssp)
+                               server->secType = RawNTLMSSP;
+                       else
+                               rc = -EOPNOTSUPP;
                }
        } else
                server->capabilities &= ~CAP_EXTENDED_SECURITY;
@@ -613,22 +620,21 @@ signing_check:
        if ((secFlags & CIFSSEC_MAY_SIGN) == 0) {
                /* MUST_SIGN already includes the MAY_SIGN FLAG
                   so if this is zero it means that signing is disabled */
-               cFYI(1, ("Signing disabled"));
+               cFYI(1, "Signing disabled");
                if (server->secMode & SECMODE_SIGN_REQUIRED) {
-                       cERROR(1, ("Server requires "
+                       cERROR(1, "Server requires "
                                   "packet signing to be enabled in "
-                                  "/proc/fs/cifs/SecurityFlags."));
+                                  "/proc/fs/cifs/SecurityFlags.");
                        rc = -EOPNOTSUPP;
                }
                server->secMode &=
                        ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
        } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
                /* signing required */
-               cFYI(1, ("Must sign - secFlags 0x%x", secFlags));
+               cFYI(1, "Must sign - secFlags 0x%x", secFlags);
                if ((server->secMode &
                        (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
-                       cERROR(1,
-                               ("signing required but server lacks support"));
+                       cERROR(1, "signing required but server lacks support");
                        rc = -EOPNOTSUPP;
                } else
                        server->secMode |= SECMODE_SIGN_REQUIRED;
@@ -642,7 +648,7 @@ signing_check:
 neg_err_exit:
        cifs_buf_release(pSMB);
 
-       cFYI(1, ("negprot rc %d", rc));
+       cFYI(1, "negprot rc %d", rc);
        return rc;
 }
 
@@ -652,7 +658,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
        struct smb_hdr *smb_buffer;
        int rc = 0;
 
-       cFYI(1, ("In tree disconnect"));
+       cFYI(1, "In tree disconnect");
 
        /* BB: do we need to check this? These should never be NULL. */
        if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
@@ -674,7 +680,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
 
        rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0);
        if (rc)
-               cFYI(1, ("Tree disconnect failed %d", rc));
+               cFYI(1, "Tree disconnect failed %d", rc);
 
        /* No need to return error on this operation if tid invalidated and
           closed on server already e.g. due to tcp session crashing */
@@ -690,7 +696,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
        LOGOFF_ANDX_REQ *pSMB;
        int rc = 0;
 
-       cFYI(1, ("In SMBLogoff for session disconnect"));
+       cFYI(1, "In SMBLogoff for session disconnect");
 
        /*
         * BB: do we need to check validity of ses and server? They should
@@ -743,7 +749,7 @@ CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName,
        int bytes_returned = 0;
        __u16 params, param_offset, offset, byte_count;
 
-       cFYI(1, ("In POSIX delete"));
+       cFYI(1, "In POSIX delete");
 PsxDelete:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -795,7 +801,7 @@ PsxDelete:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc)
-               cFYI(1, ("Posix delete returned %d", rc));
+               cFYI(1, "Posix delete returned %d", rc);
        cifs_buf_release(pSMB);
 
        cifs_stats_inc(&tcon->num_deletes);
@@ -842,7 +848,7 @@ DelFileRetry:
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_deletes);
        if (rc)
-               cFYI(1, ("Error in RMFile = %d", rc));
+               cFYI(1, "Error in RMFile = %d", rc);
 
        cifs_buf_release(pSMB);
        if (rc == -EAGAIN)
@@ -861,7 +867,7 @@ CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName,
        int bytes_returned;
        int name_len;
 
-       cFYI(1, ("In CIFSSMBRmDir"));
+       cFYI(1, "In CIFSSMBRmDir");
 RmDirRetry:
        rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -886,7 +892,7 @@ RmDirRetry:
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_rmdirs);
        if (rc)
-               cFYI(1, ("Error in RMDir = %d", rc));
+               cFYI(1, "Error in RMDir = %d", rc);
 
        cifs_buf_release(pSMB);
        if (rc == -EAGAIN)
@@ -904,7 +910,7 @@ CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned;
        int name_len;
 
-       cFYI(1, ("In CIFSSMBMkDir"));
+       cFYI(1, "In CIFSSMBMkDir");
 MkDirRetry:
        rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -929,7 +935,7 @@ MkDirRetry:
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_mkdirs);
        if (rc)
-               cFYI(1, ("Error in Mkdir = %d", rc));
+               cFYI(1, "Error in Mkdir = %d", rc);
 
        cifs_buf_release(pSMB);
        if (rc == -EAGAIN)
@@ -952,7 +958,7 @@ CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags,
        OPEN_PSX_REQ *pdata;
        OPEN_PSX_RSP *psx_rsp;
 
-       cFYI(1, ("In POSIX Create"));
+       cFYI(1, "In POSIX Create");
 PsxCreat:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -1006,11 +1012,11 @@ PsxCreat:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Posix create returned %d", rc));
+               cFYI(1, "Posix create returned %d", rc);
                goto psx_create_err;
        }
 
-       cFYI(1, ("copying inode info"));
+       cFYI(1, "copying inode info");
        rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
        if (rc || (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP))) {
@@ -1032,11 +1038,11 @@ PsxCreat:
        /* check to make sure response data is there */
        if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
                pRetData->Type = cpu_to_le32(-1); /* unknown */
-               cFYI(DBG2, ("unknown type"));
+               cFYI(DBG2, "unknown type");
        } else {
                if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP)
                                        + sizeof(FILE_UNIX_BASIC_INFO)) {
-                       cERROR(1, ("Open response data too small"));
+                       cERROR(1, "Open response data too small");
                        pRetData->Type = cpu_to_le32(-1);
                        goto psx_create_err;
                }
@@ -1083,7 +1089,7 @@ static __u16 convert_disposition(int disposition)
                        ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
                        break;
                default:
-                       cFYI(1, ("unknown disposition %d", disposition));
+                       cFYI(1, "unknown disposition %d", disposition);
                        ofun =  SMBOPEN_OAPPEND; /* regular open */
        }
        return ofun;
@@ -1174,7 +1180,7 @@ OldOpenRetry:
                        (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP);
        cifs_stats_inc(&tcon->num_opens);
        if (rc) {
-               cFYI(1, ("Error in Open = %d", rc));
+               cFYI(1, "Error in Open = %d", rc);
        } else {
        /* BB verify if wct == 15 */
 
@@ -1287,7 +1293,7 @@ openRetry:
                        (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP);
        cifs_stats_inc(&tcon->num_opens);
        if (rc) {
-               cFYI(1, ("Error in Open = %d", rc));
+               cFYI(1, "Error in Open = %d", rc);
        } else {
                *pOplock = pSMBr->OplockLevel; /* 1 byte no need to le_to_cpu */
                *netfid = pSMBr->Fid;   /* cifs fid stays in le */
@@ -1325,7 +1331,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
        int resp_buf_type = 0;
        struct kvec iov[1];
 
-       cFYI(1, ("Reading %d bytes on fid %d", count, netfid));
+       cFYI(1, "Reading %d bytes on fid %d", count, netfid);
        if (tcon->ses->capabilities & CAP_LARGE_FILES)
                wct = 12;
        else {
@@ -1370,7 +1376,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
        cifs_stats_inc(&tcon->num_reads);
        pSMBr = (READ_RSP *)iov[0].iov_base;
        if (rc) {
-               cERROR(1, ("Send error in read = %d", rc));
+               cERROR(1, "Send error in read = %d", rc);
        } else {
                int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
                data_length = data_length << 16;
@@ -1380,15 +1386,15 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
                /*check that DataLength would not go beyond end of SMB */
                if ((data_length > CIFSMaxBufSize)
                                || (data_length > count)) {
-                       cFYI(1, ("bad length %d for count %d",
-                                data_length, count));
+                       cFYI(1, "bad length %d for count %d",
+                                data_length, count);
                        rc = -EIO;
                        *nbytes = 0;
                } else {
                        pReadData = (char *) (&pSMBr->hdr.Protocol) +
                                        le16_to_cpu(pSMBr->DataOffset);
 /*                     if (rc = copy_to_user(buf, pReadData, data_length)) {
-                               cERROR(1,("Faulting on read rc = %d",rc));
+                               cERROR(1, "Faulting on read rc = %d",rc);
                                rc = -EFAULT;
                        }*/ /* can not use copy_to_user when using page cache*/
                        if (*buf)
@@ -1430,7 +1436,9 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
        __u32 bytes_sent;
        __u16 byte_count;
 
-       /* cFYI(1, ("write at %lld %d bytes", offset, count));*/
+       *nbytes = 0;
+
+       /* cFYI(1, "write at %lld %d bytes", offset, count);*/
        if (tcon->ses == NULL)
                return -ECONNABORTED;
 
@@ -1511,12 +1519,19 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
                         (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
        cifs_stats_inc(&tcon->num_writes);
        if (rc) {
-               cFYI(1, ("Send error in write = %d", rc));
-               *nbytes = 0;
+               cFYI(1, "Send error in write = %d", rc);
        } else {
                *nbytes = le16_to_cpu(pSMBr->CountHigh);
                *nbytes = (*nbytes) << 16;
                *nbytes += le16_to_cpu(pSMBr->Count);
+
+               /*
+                * Mask off high 16 bits when bytes written as returned by the
+                * server is greater than bytes requested by the client. Some
+                * OS/2 servers are known to set incorrect CountHigh values.
+                */
+               if (*nbytes > count)
+                       *nbytes &= 0xFFFF;
        }
 
        cifs_buf_release(pSMB);
@@ -1541,7 +1556,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
 
        *nbytes = 0;
 
-       cFYI(1, ("write2 at %lld %d bytes", (long long)offset, count));
+       cFYI(1, "write2 at %lld %d bytes", (long long)offset, count);
 
        if (tcon->ses->capabilities & CAP_LARGE_FILES) {
                wct = 14;
@@ -1596,7 +1611,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
                          long_op);
        cifs_stats_inc(&tcon->num_writes);
        if (rc) {
-               cFYI(1, ("Send error Write2 = %d", rc));
+               cFYI(1, "Send error Write2 = %d", rc);
        } else if (resp_buf_type == 0) {
                /* presumably this can not happen, but best to be safe */
                rc = -EIO;
@@ -1605,6 +1620,14 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
                *nbytes = le16_to_cpu(pSMBr->CountHigh);
                *nbytes = (*nbytes) << 16;
                *nbytes += le16_to_cpu(pSMBr->Count);
+
+               /*
+                * Mask off high 16 bits when bytes written as returned by the
+                * server is greater than bytes requested by the client. OS/2
+                * servers are known to set incorrect CountHigh values.
+                */
+               if (*nbytes > count)
+                       *nbytes &= 0xFFFF;
        }
 
 /*     cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
@@ -1633,7 +1656,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
        int timeout = 0;
        __u16 count;
 
-       cFYI(1, ("CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock));
+       cFYI(1, "CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock);
        rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
 
        if (rc)
@@ -1681,7 +1704,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
        }
        cifs_stats_inc(&tcon->num_locks);
        if (rc)
-               cFYI(1, ("Send error in Lock = %d", rc));
+               cFYI(1, "Send error in Lock = %d", rc);
 
        /* Note: On -EAGAIN error only caller can retry on handle based calls
        since file handle passed in no longer valid */
@@ -1704,7 +1727,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
        __u16 params, param_offset, offset, byte_count, count;
        struct kvec iov[1];
 
-       cFYI(1, ("Posix Lock"));
+       cFYI(1, "Posix Lock");
 
        if (pLockData == NULL)
                return -EINVAL;
@@ -1774,7 +1797,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
        }
 
        if (rc) {
-               cFYI(1, ("Send error in Posix Lock = %d", rc));
+               cFYI(1, "Send error in Posix Lock = %d", rc);
        } else if (get_flag) {
                /* lock structure can be returned on get */
                __u16 data_offset;
@@ -1793,8 +1816,21 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
                }
                parm_data = (struct cifs_posix_lock *)
                        ((char *)&pSMBr->hdr.Protocol + data_offset);
-               if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
+               if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
                        pLockData->fl_type = F_UNLCK;
+               else {
+                       if (parm_data->lock_type ==
+                                       __constant_cpu_to_le16(CIFS_RDLCK))
+                               pLockData->fl_type = F_RDLCK;
+                       else if (parm_data->lock_type ==
+                                       __constant_cpu_to_le16(CIFS_WRLCK))
+                               pLockData->fl_type = F_WRLCK;
+
+                       pLockData->fl_start = parm_data->start;
+                       pLockData->fl_end = parm_data->start +
+                                               parm_data->length - 1;
+                       pLockData->fl_pid = parm_data->pid;
+               }
        }
 
 plk_err_exit:
@@ -1818,7 +1854,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
 {
        int rc = 0;
        CLOSE_REQ *pSMB = NULL;
-       cFYI(1, ("In CIFSSMBClose"));
+       cFYI(1, "In CIFSSMBClose");
 
 /* do not retry on dead session on close */
        rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
@@ -1835,7 +1871,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
        if (rc) {
                if (rc != -EINTR) {
                        /* EINTR is expected when user ctl-c to kill app */
-                       cERROR(1, ("Send error in Close = %d", rc));
+                       cERROR(1, "Send error in Close = %d", rc);
                }
        }
 
@@ -1851,7 +1887,7 @@ CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
 {
        int rc = 0;
        FLUSH_REQ *pSMB = NULL;
-       cFYI(1, ("In CIFSSMBFlush"));
+       cFYI(1, "In CIFSSMBFlush");
 
        rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
        if (rc)
@@ -1862,7 +1898,7 @@ CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
        rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
        cifs_stats_inc(&tcon->num_flushes);
        if (rc)
-               cERROR(1, ("Send error in Flush = %d", rc));
+               cERROR(1, "Send error in Flush = %d", rc);
 
        return rc;
 }
@@ -1879,7 +1915,7 @@ CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
        int name_len, name_len2;
        __u16 count;
 
-       cFYI(1, ("In CIFSSMBRename"));
+       cFYI(1, "In CIFSSMBRename");
 renameRetry:
        rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -1925,7 +1961,7 @@ renameRetry:
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_renames);
        if (rc)
-               cFYI(1, ("Send error in rename = %d", rc));
+               cFYI(1, "Send error in rename = %d", rc);
 
        cifs_buf_release(pSMB);
 
@@ -1949,7 +1985,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
        int len_of_str;
        __u16 params, param_offset, offset, count, byte_count;
 
-       cFYI(1, ("Rename to File by handle"));
+       cFYI(1, "Rename to File by handle");
        rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
                        (void **) &pSMBr);
        if (rc)
@@ -2004,7 +2040,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&pTcon->num_t2renames);
        if (rc)
-               cFYI(1, ("Send error in Rename (by file handle) = %d", rc));
+               cFYI(1, "Send error in Rename (by file handle) = %d", rc);
 
        cifs_buf_release(pSMB);
 
@@ -2026,7 +2062,7 @@ CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char *fromName,
        int name_len, name_len2;
        __u16 count;
 
-       cFYI(1, ("In CIFSSMBCopy"));
+       cFYI(1, "In CIFSSMBCopy");
 copyRetry:
        rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
                        (void **) &pSMBr);
@@ -2071,8 +2107,8 @@ copyRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in copy = %d with %d files copied",
-                       rc, le16_to_cpu(pSMBr->CopyCount)));
+               cFYI(1, "Send error in copy = %d with %d files copied",
+                       rc, le16_to_cpu(pSMBr->CopyCount));
        }
        cifs_buf_release(pSMB);
 
@@ -2096,7 +2132,7 @@ CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned = 0;
        __u16 params, param_offset, offset, byte_count;
 
-       cFYI(1, ("In Symlink Unix style"));
+       cFYI(1, "In Symlink Unix style");
 createSymLinkRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -2161,7 +2197,7 @@ createSymLinkRetry:
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_symlinks);
        if (rc)
-               cFYI(1, ("Send error in SetPathInfo create symlink = %d", rc));
+               cFYI(1, "Send error in SetPathInfo create symlink = %d", rc);
 
        cifs_buf_release(pSMB);
 
@@ -2185,7 +2221,7 @@ CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned = 0;
        __u16 params, param_offset, offset, byte_count;
 
-       cFYI(1, ("In Create Hard link Unix style"));
+       cFYI(1, "In Create Hard link Unix style");
 createHardLinkRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -2247,7 +2283,7 @@ createHardLinkRetry:
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_hardlinks);
        if (rc)
-               cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc));
+               cFYI(1, "Send error in SetPathInfo (hard link) = %d", rc);
 
        cifs_buf_release(pSMB);
        if (rc == -EAGAIN)
@@ -2268,7 +2304,7 @@ CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon,
        int name_len, name_len2;
        __u16 count;
 
-       cFYI(1, ("In CIFSCreateHardLink"));
+       cFYI(1, "In CIFSCreateHardLink");
 winCreateHardLinkRetry:
 
        rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
@@ -2319,7 +2355,7 @@ winCreateHardLinkRetry:
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_hardlinks);
        if (rc)
-               cFYI(1, ("Send error in hard link (NT rename) = %d", rc));
+               cFYI(1, "Send error in hard link (NT rename) = %d", rc);
 
        cifs_buf_release(pSMB);
        if (rc == -EAGAIN)
@@ -2342,7 +2378,7 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
        __u16 params, byte_count;
        char *data_start;
 
-       cFYI(1, ("In QPathSymLinkInfo (Unix) for path %s", searchName));
+       cFYI(1, "In QPathSymLinkInfo (Unix) for path %s", searchName);
 
 querySymLinkRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -2389,7 +2425,7 @@ querySymLinkRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QuerySymLinkInfo = %d", rc));
+               cFYI(1, "Send error in QuerySymLinkInfo = %d", rc);
        } else {
                /* decode response */
 
@@ -2490,21 +2526,21 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
 
        /* should we also check that parm and data areas do not overlap? */
        if (*ppparm > end_of_smb) {
-               cFYI(1, ("parms start after end of smb"));
+               cFYI(1, "parms start after end of smb");
                return -EINVAL;
        } else if (parm_count + *ppparm > end_of_smb) {
-               cFYI(1, ("parm end after end of smb"));
+               cFYI(1, "parm end after end of smb");
                return -EINVAL;
        } else if (*ppdata > end_of_smb) {
-               cFYI(1, ("data starts after end of smb"));
+               cFYI(1, "data starts after end of smb");
                return -EINVAL;
        } else if (data_count + *ppdata > end_of_smb) {
-               cFYI(1, ("data %p + count %d (%p) ends after end of smb %p start %p",
+               cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
                        *ppdata, data_count, (data_count + *ppdata),
-                       end_of_smb, pSMBr));
+                       end_of_smb, pSMBr);
                return -EINVAL;
        } else if (parm_count + data_count > pSMBr->ByteCount) {
-               cFYI(1, ("parm count and data count larger than SMB"));
+               cFYI(1, "parm count and data count larger than SMB");
                return -EINVAL;
        }
        *pdatalen = data_count;
@@ -2523,7 +2559,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
        struct smb_com_transaction_ioctl_req *pSMB;
        struct smb_com_transaction_ioctl_rsp *pSMBr;
 
-       cFYI(1, ("In Windows reparse style QueryLink for path %s", searchName));
+       cFYI(1, "In Windows reparse style QueryLink for path %s", searchName);
        rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
        if (rc)
@@ -2552,7 +2588,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QueryReparseLinkInfo = %d", rc));
+               cFYI(1, "Send error in QueryReparseLinkInfo = %d", rc);
        } else {                /* decode response */
                __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
                __u32 data_count = le32_to_cpu(pSMBr->DataCount);
@@ -2576,7 +2612,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
                        if ((reparse_buf->LinkNamesBuf +
                                reparse_buf->TargetNameOffset +
                                reparse_buf->TargetNameLen) > end_of_smb) {
-                               cFYI(1, ("reparse buf beyond SMB"));
+                               cFYI(1, "reparse buf beyond SMB");
                                rc = -EIO;
                                goto qreparse_out;
                        }
@@ -2597,12 +2633,12 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
                        }
                } else {
                        rc = -EIO;
-                       cFYI(1, ("Invalid return data count on "
-                                "get reparse info ioctl"));
+                       cFYI(1, "Invalid return data count on "
+                                "get reparse info ioctl");
                }
                symlinkinfo[buflen] = 0; /* just in case so the caller
                                        does not go off the end of the buffer */
-               cFYI(1, ("readlink result - %s", symlinkinfo));
+               cFYI(1, "readlink result - %s", symlinkinfo);
        }
 
 qreparse_out:
@@ -2625,7 +2661,7 @@ static void cifs_convert_ace(posix_acl_xattr_entry *ace,
        ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
        ace->e_tag  = cpu_to_le16(cifs_ace->cifs_e_tag);
        ace->e_id   = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
-       /* cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id)); */
+       /* cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id); */
 
        return;
 }
@@ -2651,8 +2687,8 @@ static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
                size += sizeof(struct cifs_posix_ace) * count;
                /* check if we would go beyond end of SMB */
                if (size_of_data_area < size) {
-                       cFYI(1, ("bad CIFS POSIX ACL size %d vs. %d",
-                               size_of_data_area, size));
+                       cFYI(1, "bad CIFS POSIX ACL size %d vs. %d",
+                               size_of_data_area, size);
                        return -EINVAL;
                }
        } else if (acl_type & ACL_TYPE_DEFAULT) {
@@ -2699,7 +2735,7 @@ static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
                cifs_ace->cifs_uid = cpu_to_le64(-1);
        } else
                cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
-       /*cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id));*/
+       /*cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id);*/
        return rc;
 }
 
@@ -2717,12 +2753,12 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
                return 0;
 
        count = posix_acl_xattr_count((size_t)buflen);
-       cFYI(1, ("setting acl with %d entries from buf of length %d and "
+       cFYI(1, "setting acl with %d entries from buf of length %d and "
                "version of %d",
-               count, buflen, le32_to_cpu(local_acl->a_version)));
+               count, buflen, le32_to_cpu(local_acl->a_version));
        if (le32_to_cpu(local_acl->a_version) != 2) {
-               cFYI(1, ("unknown POSIX ACL version %d",
-                    le32_to_cpu(local_acl->a_version)));
+               cFYI(1, "unknown POSIX ACL version %d",
+                    le32_to_cpu(local_acl->a_version));
                return 0;
        }
        cifs_acl->version = cpu_to_le16(1);
@@ -2731,7 +2767,7 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
        else if (acl_type == ACL_TYPE_DEFAULT)
                cifs_acl->default_entry_count = cpu_to_le16(count);
        else {
-               cFYI(1, ("unknown ACL type %d", acl_type));
+               cFYI(1, "unknown ACL type %d", acl_type);
                return 0;
        }
        for (i = 0; i < count; i++) {
@@ -2764,7 +2800,7 @@ CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
        int name_len;
        __u16 params, byte_count;
 
-       cFYI(1, ("In GetPosixACL (Unix) for path %s", searchName));
+       cFYI(1, "In GetPosixACL (Unix) for path %s", searchName);
 
 queryAclRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -2816,7 +2852,7 @@ queryAclRetry:
                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_acl_get);
        if (rc) {
-               cFYI(1, ("Send error in Query POSIX ACL = %d", rc));
+               cFYI(1, "Send error in Query POSIX ACL = %d", rc);
        } else {
                /* decode response */
 
@@ -2853,7 +2889,7 @@ CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned = 0;
        __u16 params, byte_count, data_count, param_offset, offset;
 
-       cFYI(1, ("In SetPosixACL (Unix) for path %s", fileName));
+       cFYI(1, "In SetPosixACL (Unix) for path %s", fileName);
 setAclRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -2908,7 +2944,7 @@ setAclRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc)
-               cFYI(1, ("Set POSIX ACL returned %d", rc));
+               cFYI(1, "Set POSIX ACL returned %d", rc);
 
 setACLerrorExit:
        cifs_buf_release(pSMB);
@@ -2928,7 +2964,7 @@ CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned;
        __u16 params, byte_count;
 
-       cFYI(1, ("In GetExtAttr"));
+       cFYI(1, "In GetExtAttr");
        if (tcon == NULL)
                return -ENODEV;
 
@@ -2967,7 +3003,7 @@ GetExtAttrRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("error %d in GetExtAttr", rc));
+               cFYI(1, "error %d in GetExtAttr", rc);
        } else {
                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
@@ -2982,7 +3018,7 @@ GetExtAttrRetry:
                        struct file_chattr_info *pfinfo;
                        /* BB Do we need a cast or hash here ? */
                        if (count != 16) {
-                               cFYI(1, ("Illegal size ret in GetExtAttr"));
+                               cFYI(1, "Illegal size ret in GetExtAttr");
                                rc = -EIO;
                                goto GetExtAttrOut;
                        }
@@ -3012,7 +3048,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
        QUERY_SEC_DESC_REQ *pSMB;
        struct kvec iov[1];
 
-       cFYI(1, ("GetCifsACL"));
+       cFYI(1, "GetCifsACL");
 
        *pbuflen = 0;
        *acl_inf = NULL;
@@ -3037,7 +3073,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
                         CIFS_STD_OP);
        cifs_stats_inc(&tcon->num_acl_get);
        if (rc) {
-               cFYI(1, ("Send error in QuerySecDesc = %d", rc));
+               cFYI(1, "Send error in QuerySecDesc = %d", rc);
        } else {                /* decode response */
                __le32 *parm;
                __u32 parm_len;
@@ -3052,7 +3088,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
                        goto qsec_out;
                pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
 
-               cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, *acl_inf));
+               cFYI(1, "smb %p parm %p data %p", pSMBr, parm, *acl_inf);
 
                if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
                        rc = -EIO;      /* bad smb */
@@ -3064,8 +3100,8 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
 
                acl_len = le32_to_cpu(*parm);
                if (acl_len != *pbuflen) {
-                       cERROR(1, ("acl length %d does not match %d",
-                                  acl_len, *pbuflen));
+                       cERROR(1, "acl length %d does not match %d",
+                                  acl_len, *pbuflen);
                        if (*pbuflen > acl_len)
                                *pbuflen = acl_len;
                }
@@ -3074,7 +3110,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
                   header followed by the smallest SID */
                if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
                    (*pbuflen >= 64 * 1024)) {
-                       cERROR(1, ("bad acl length %d", *pbuflen));
+                       cERROR(1, "bad acl length %d", *pbuflen);
                        rc = -EINVAL;
                        *pbuflen = 0;
                } else {
@@ -3148,9 +3184,9 @@ setCifsAclRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
 
-       cFYI(1, ("SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc));
+       cFYI(1, "SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc);
        if (rc)
-               cFYI(1, ("Set CIFS ACL returned %d", rc));
+               cFYI(1, "Set CIFS ACL returned %d", rc);
        cifs_buf_release(pSMB);
 
        if (rc == -EAGAIN)
@@ -3174,7 +3210,7 @@ int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned;
        int name_len;
 
-       cFYI(1, ("In SMBQPath path %s", searchName));
+       cFYI(1, "In SMBQPath path %s", searchName);
 QInfRetry:
        rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -3200,7 +3236,7 @@ QInfRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QueryInfo = %d", rc));
+               cFYI(1, "Send error in QueryInfo = %d", rc);
        } else if (pFinfo) {
                struct timespec ts;
                __u32 time = le32_to_cpu(pSMBr->last_write_time);
@@ -3230,8 +3266,72 @@ QInfRetry:
        return rc;
 }
 
+int
+CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon,
+                u16 netfid, FILE_ALL_INFO *pFindData)
+{
+       struct smb_t2_qfi_req *pSMB = NULL;
+       struct smb_t2_qfi_rsp *pSMBr = NULL;
+       int rc = 0;
+       int bytes_returned;
+       __u16 params, byte_count;
+
+QFileInfoRetry:
+       rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+                     (void **) &pSMBr);
+       if (rc)
+               return rc;
 
+       params = 2 /* level */ + 2 /* fid */;
+       pSMB->t2.TotalDataCount = 0;
+       pSMB->t2.MaxParameterCount = cpu_to_le16(4);
+       /* BB find exact max data count below from sess structure BB */
+       pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
+       pSMB->t2.MaxSetupCount = 0;
+       pSMB->t2.Reserved = 0;
+       pSMB->t2.Flags = 0;
+       pSMB->t2.Timeout = 0;
+       pSMB->t2.Reserved2 = 0;
+       pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
+                                              Fid) - 4);
+       pSMB->t2.DataCount = 0;
+       pSMB->t2.DataOffset = 0;
+       pSMB->t2.SetupCount = 1;
+       pSMB->t2.Reserved3 = 0;
+       pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
+       byte_count = params + 1 /* pad */ ;
+       pSMB->t2.TotalParameterCount = cpu_to_le16(params);
+       pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
+       pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
+       pSMB->Pad = 0;
+       pSMB->Fid = netfid;
+       pSMB->hdr.smb_buf_length += byte_count;
 
+       rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+                        (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+       if (rc) {
+               cFYI(1, "Send error in QPathInfo = %d", rc);
+       } else {                /* decode response */
+               rc = validate_t2((struct smb_t2_rsp *)pSMBr);
+
+               if (rc) /* BB add auto retry on EOPNOTSUPP? */
+                       rc = -EIO;
+               else if (pSMBr->ByteCount < 40)
+                       rc = -EIO;      /* bad smb */
+               else if (pFindData) {
+                       __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
+                       memcpy((char *) pFindData,
+                              (char *) &pSMBr->hdr.Protocol +
+                              data_offset, sizeof(FILE_ALL_INFO));
+               } else
+                   rc = -ENOMEM;
+       }
+       cifs_buf_release(pSMB);
+       if (rc == -EAGAIN)
+               goto QFileInfoRetry;
+
+       return rc;
+}
 
 int
 CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
@@ -3248,7 +3348,7 @@ CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
        int name_len;
        __u16 params, byte_count;
 
-/* cFYI(1, ("In QPathInfo path %s", searchName)); */
+/* cFYI(1, "In QPathInfo path %s", searchName); */
 QPathInfoRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -3298,7 +3398,7 @@ QPathInfoRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QPathInfo = %d", rc));
+               cFYI(1, "Send error in QPathInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -3334,6 +3434,75 @@ QPathInfoRetry:
        return rc;
 }
 
+int
+CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon,
+                u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
+{
+       struct smb_t2_qfi_req *pSMB = NULL;
+       struct smb_t2_qfi_rsp *pSMBr = NULL;
+       int rc = 0;
+       int bytes_returned;
+       __u16 params, byte_count;
+
+UnixQFileInfoRetry:
+       rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+                     (void **) &pSMBr);
+       if (rc)
+               return rc;
+
+       params = 2 /* level */ + 2 /* fid */;
+       pSMB->t2.TotalDataCount = 0;
+       pSMB->t2.MaxParameterCount = cpu_to_le16(4);
+       /* BB find exact max data count below from sess structure BB */
+       pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
+       pSMB->t2.MaxSetupCount = 0;
+       pSMB->t2.Reserved = 0;
+       pSMB->t2.Flags = 0;
+       pSMB->t2.Timeout = 0;
+       pSMB->t2.Reserved2 = 0;
+       pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
+                                              Fid) - 4);
+       pSMB->t2.DataCount = 0;
+       pSMB->t2.DataOffset = 0;
+       pSMB->t2.SetupCount = 1;
+       pSMB->t2.Reserved3 = 0;
+       pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
+       byte_count = params + 1 /* pad */ ;
+       pSMB->t2.TotalParameterCount = cpu_to_le16(params);
+       pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
+       pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
+       pSMB->Pad = 0;
+       pSMB->Fid = netfid;
+       pSMB->hdr.smb_buf_length += byte_count;
+
+       rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+                        (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+       if (rc) {
+               cFYI(1, "Send error in QPathInfo = %d", rc);
+       } else {                /* decode response */
+               rc = validate_t2((struct smb_t2_rsp *)pSMBr);
+
+               if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) {
+                       cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
+                                  "Unix Extensions can be disabled on mount "
+                                  "by specifying the nosfu mount option.");
+                       rc = -EIO;      /* bad smb */
+               } else {
+                       __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
+                       memcpy((char *) pFindData,
+                              (char *) &pSMBr->hdr.Protocol +
+                              data_offset,
+                              sizeof(FILE_UNIX_BASIC_INFO));
+               }
+       }
+
+       cifs_buf_release(pSMB);
+       if (rc == -EAGAIN)
+               goto UnixQFileInfoRetry;
+
+       return rc;
+}
+
 int
 CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
                     const unsigned char *searchName,
@@ -3348,7 +3517,7 @@ CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
        int name_len;
        __u16 params, byte_count;
 
-       cFYI(1, ("In QPathInfo (Unix) the path %s", searchName));
+       cFYI(1, "In QPathInfo (Unix) the path %s", searchName);
 UnixQPathInfoRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -3395,14 +3564,14 @@ UnixQPathInfoRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QPathInfo = %d", rc));
+               cFYI(1, "Send error in QPathInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
                if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) {
-                       cERROR(1, ("Malformed FILE_UNIX_BASIC_INFO response.\n"
+                       cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
                                   "Unix Extensions can be disabled on mount "
-                                  "by specifying the nosfu mount option."));
+                                  "by specifying the nosfu mount option.");
                        rc = -EIO;      /* bad smb */
                } else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -3436,7 +3605,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
        int name_len;
        __u16 params, byte_count;
 
-       cFYI(1, ("In FindFirst for %s", searchName));
+       cFYI(1, "In FindFirst for %s", searchName);
 
 findFirstRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -3513,7 +3682,7 @@ findFirstRetry:
        if (rc) {/* BB add logic to retry regular search if Unix search
                        rejected unexpectedly by server */
                /* BB Add code to handle unsupported level rc */
-               cFYI(1, ("Error in FindFirst = %d", rc));
+               cFYI(1, "Error in FindFirst = %d", rc);
 
                cifs_buf_release(pSMB);
 
@@ -3552,7 +3721,7 @@ findFirstRetry:
                        lnoff = le16_to_cpu(parms->LastNameOffset);
                        if (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE <
                              lnoff) {
-                               cERROR(1, ("ignoring corrupt resume name"));
+                               cERROR(1, "ignoring corrupt resume name");
                                psrch_inf->last_entry = NULL;
                                return rc;
                        }
@@ -3580,7 +3749,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned, name_len;
        __u16 params, byte_count;
 
-       cFYI(1, ("In FindNext"));
+       cFYI(1, "In FindNext");
 
        if (psrch_inf->endOfSearch)
                return -ENOENT;
@@ -3644,7 +3813,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
                        cifs_buf_release(pSMB);
                        rc = 0; /* search probably was closed at end of search*/
                } else
-                       cFYI(1, ("FindNext returned = %d", rc));
+                       cFYI(1, "FindNext returned = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -3680,15 +3849,15 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
                        lnoff = le16_to_cpu(parms->LastNameOffset);
                        if (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE <
                              lnoff) {
-                               cERROR(1, ("ignoring corrupt resume name"));
+                               cERROR(1, "ignoring corrupt resume name");
                                psrch_inf->last_entry = NULL;
                                return rc;
                        } else
                                psrch_inf->last_entry =
                                        psrch_inf->srch_entries_start + lnoff;
 
-/*  cFYI(1,("fnxt2 entries in buf %d index_of_last %d",
-           psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry)); */
+/*  cFYI(1, "fnxt2 entries in buf %d index_of_last %d",
+           psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
 
                        /* BB fixme add unlock here */
                }
@@ -3713,7 +3882,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
        int rc = 0;
        FINDCLOSE_REQ *pSMB = NULL;
 
-       cFYI(1, ("In CIFSSMBFindClose"));
+       cFYI(1, "In CIFSSMBFindClose");
        rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
 
        /* no sense returning error if session restarted
@@ -3727,7 +3896,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
        pSMB->ByteCount = 0;
        rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
        if (rc)
-               cERROR(1, ("Send error in FindClose = %d", rc));
+               cERROR(1, "Send error in FindClose = %d", rc);
 
        cifs_stats_inc(&tcon->num_fclose);
 
@@ -3750,7 +3919,7 @@ CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
        int name_len, bytes_returned;
        __u16 params, byte_count;
 
-       cFYI(1, ("In GetSrvInodeNum for %s", searchName));
+       cFYI(1, "In GetSrvInodeNum for %s", searchName);
        if (tcon == NULL)
                return -ENODEV;
 
@@ -3800,7 +3969,7 @@ GetInodeNumberRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("error %d in QueryInternalInfo", rc));
+               cFYI(1, "error %d in QueryInternalInfo", rc);
        } else {
                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
@@ -3815,7 +3984,7 @@ GetInodeNumberRetry:
                        struct file_internal_info *pfinfo;
                        /* BB Do we need a cast or hash here ? */
                        if (count < 8) {
-                               cFYI(1, ("Illegal size ret in QryIntrnlInf"));
+                               cFYI(1, "Illegal size ret in QryIntrnlInf");
                                rc = -EIO;
                                goto GetInodeNumOut;
                        }
@@ -3856,16 +4025,16 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
        *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
 
        if (*num_of_nodes < 1) {
-               cERROR(1, ("num_referrals: must be at least > 0,"
-                       "but we get num_referrals = %d\n", *num_of_nodes));
+               cERROR(1, "num_referrals: must be at least > 0,"
+                       "but we get num_referrals = %d\n", *num_of_nodes);
                rc = -EINVAL;
                goto parse_DFS_referrals_exit;
        }
 
        ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
        if (ref->VersionNumber != cpu_to_le16(3)) {
-               cERROR(1, ("Referrals of V%d version are not supported,"
-                       "should be V3", le16_to_cpu(ref->VersionNumber)));
+               cERROR(1, "Referrals of V%d version are not supported,"
+                       "should be V3", le16_to_cpu(ref->VersionNumber));
                rc = -EINVAL;
                goto parse_DFS_referrals_exit;
        }
@@ -3874,14 +4043,14 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
        data_end = (char *)(&(pSMBr->PathConsumed)) +
                                le16_to_cpu(pSMBr->t2.DataCount);
 
-       cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n",
+       cFYI(1, "num_referrals: %d dfs flags: 0x%x ...\n",
                        *num_of_nodes,
-                       le32_to_cpu(pSMBr->DFSFlags)));
+                       le32_to_cpu(pSMBr->DFSFlags));
 
        *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
                        *num_of_nodes, GFP_KERNEL);
        if (*target_nodes == NULL) {
-               cERROR(1, ("Failed to allocate buffer for target_nodes\n"));
+               cERROR(1, "Failed to allocate buffer for target_nodes\n");
                rc = -ENOMEM;
                goto parse_DFS_referrals_exit;
        }
@@ -3957,7 +4126,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
        *num_of_nodes = 0;
        *target_nodes = NULL;
 
-       cFYI(1, ("In GetDFSRefer the path %s", searchName));
+       cFYI(1, "In GetDFSRefer the path %s", searchName);
        if (ses == NULL)
                return -ENODEV;
 getDFSRetry:
@@ -4024,7 +4193,7 @@ getDFSRetry:
        rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in GetDFSRefer = %d", rc));
+               cFYI(1, "Send error in GetDFSRefer = %d", rc);
                goto GetDFSRefExit;
        }
        rc = validate_t2((struct smb_t2_rsp *)pSMBr);
@@ -4035,9 +4204,9 @@ getDFSRetry:
                goto GetDFSRefExit;
        }
 
-       cFYI(1, ("Decoding GetDFSRefer response BCC: %d  Offset %d",
+       cFYI(1, "Decoding GetDFSRefer response BCC: %d  Offset %d",
                                pSMBr->ByteCount,
-                               le16_to_cpu(pSMBr->t2.DataOffset)));
+                               le16_to_cpu(pSMBr->t2.DataOffset));
 
        /* parse returned result into more usable form */
        rc = parse_DFS_referrals(pSMBr, num_of_nodes,
@@ -4065,7 +4234,7 @@ SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
        int bytes_returned = 0;
        __u16 params, byte_count;
 
-       cFYI(1, ("OldQFSInfo"));
+       cFYI(1, "OldQFSInfo");
 oldQFSInfoRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                (void **) &pSMBr);
@@ -4098,7 +4267,7 @@ oldQFSInfoRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QFSInfo = %d", rc));
+               cFYI(1, "Send error in QFSInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -4106,8 +4275,8 @@ oldQFSInfoRetry:
                        rc = -EIO;      /* bad smb */
                else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
-                       cFYI(1, ("qfsinf resp BCC: %d  Offset %d",
-                                pSMBr->ByteCount, data_offset));
+                       cFYI(1, "qfsinf resp BCC: %d  Offset %d",
+                                pSMBr->ByteCount, data_offset);
 
                        response_data = (FILE_SYSTEM_ALLOC_INFO *)
                                (((char *) &pSMBr->hdr.Protocol) + data_offset);
@@ -4119,11 +4288,10 @@ oldQFSInfoRetry:
                               le32_to_cpu(response_data->TotalAllocationUnits);
                        FSData->f_bfree = FSData->f_bavail =
                                le32_to_cpu(response_data->FreeAllocationUnits);
-                       cFYI(1,
-                            ("Blocks: %lld  Free: %lld Block size %ld",
-                             (unsigned long long)FSData->f_blocks,
-                             (unsigned long long)FSData->f_bfree,
-                             FSData->f_bsize));
+                       cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
+                            (unsigned long long)FSData->f_blocks,
+                            (unsigned long long)FSData->f_bfree,
+                            FSData->f_bsize);
                }
        }
        cifs_buf_release(pSMB);
@@ -4145,7 +4313,7 @@ CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
        int bytes_returned = 0;
        __u16 params, byte_count;
 
-       cFYI(1, ("In QFSInfo"));
+       cFYI(1, "In QFSInfo");
 QFSInfoRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -4178,7 +4346,7 @@ QFSInfoRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QFSInfo = %d", rc));
+               cFYI(1, "Send error in QFSInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -4199,11 +4367,10 @@ QFSInfoRetry:
                            le64_to_cpu(response_data->TotalAllocationUnits);
                        FSData->f_bfree = FSData->f_bavail =
                            le64_to_cpu(response_data->FreeAllocationUnits);
-                       cFYI(1,
-                            ("Blocks: %lld  Free: %lld Block size %ld",
-                             (unsigned long long)FSData->f_blocks,
-                             (unsigned long long)FSData->f_bfree,
-                             FSData->f_bsize));
+                       cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
+                            (unsigned long long)FSData->f_blocks,
+                            (unsigned long long)FSData->f_bfree,
+                            FSData->f_bsize);
                }
        }
        cifs_buf_release(pSMB);
@@ -4225,7 +4392,7 @@ CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon)
        int bytes_returned = 0;
        __u16 params, byte_count;
 
-       cFYI(1, ("In QFSAttributeInfo"));
+       cFYI(1, "In QFSAttributeInfo");
 QFSAttributeRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -4259,7 +4426,7 @@ QFSAttributeRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cERROR(1, ("Send error in QFSAttributeInfo = %d", rc));
+               cERROR(1, "Send error in QFSAttributeInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -4295,7 +4462,7 @@ CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon)
        int bytes_returned = 0;
        __u16 params, byte_count;
 
-       cFYI(1, ("In QFSDeviceInfo"));
+       cFYI(1, "In QFSDeviceInfo");
 QFSDeviceRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -4330,7 +4497,7 @@ QFSDeviceRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QFSDeviceInfo = %d", rc));
+               cFYI(1, "Send error in QFSDeviceInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -4365,7 +4532,7 @@ CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon)
        int bytes_returned = 0;
        __u16 params, byte_count;
 
-       cFYI(1, ("In QFSUnixInfo"));
+       cFYI(1, "In QFSUnixInfo");
 QFSUnixRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -4399,7 +4566,7 @@ QFSUnixRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cERROR(1, ("Send error in QFSUnixInfo = %d", rc));
+               cERROR(1, "Send error in QFSUnixInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -4434,7 +4601,7 @@ CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap)
        int bytes_returned = 0;
        __u16 params, param_offset, offset, byte_count;
 
-       cFYI(1, ("In SETFSUnixInfo"));
+       cFYI(1, "In SETFSUnixInfo");
 SETFSUnixRetry:
        /* BB switch to small buf init to save memory */
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -4482,7 +4649,7 @@ SETFSUnixRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cERROR(1, ("Send error in SETFSUnixInfo = %d", rc));
+               cERROR(1, "Send error in SETFSUnixInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
                if (rc)
@@ -4510,7 +4677,7 @@ CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned = 0;
        __u16 params, byte_count;
 
-       cFYI(1, ("In QFSPosixInfo"));
+       cFYI(1, "In QFSPosixInfo");
 QFSPosixRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -4544,7 +4711,7 @@ QFSPosixRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QFSUnixInfo = %d", rc));
+               cFYI(1, "Send error in QFSUnixInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -4604,7 +4771,7 @@ CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName,
        int bytes_returned = 0;
        __u16 params, byte_count, data_count, param_offset, offset;
 
-       cFYI(1, ("In SetEOF"));
+       cFYI(1, "In SetEOF");
 SetEOFRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -4670,7 +4837,7 @@ SetEOFRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc)
-               cFYI(1, ("SetPathInfo (file size) returned %d", rc));
+               cFYI(1, "SetPathInfo (file size) returned %d", rc);
 
        cifs_buf_release(pSMB);
 
@@ -4690,8 +4857,8 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
        int rc = 0;
        __u16 params, param_offset, offset, byte_count, count;
 
-       cFYI(1, ("SetFileSize (via SetFileInfo) %lld",
-                       (long long)size));
+       cFYI(1, "SetFileSize (via SetFileInfo) %lld",
+                       (long long)size);
        rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
 
        if (rc)
@@ -4750,9 +4917,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
        pSMB->ByteCount = cpu_to_le16(byte_count);
        rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
        if (rc) {
-               cFYI(1,
-                    ("Send error in SetFileInfo (SetFileSize) = %d",
-                     rc));
+               cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
        }
 
        /* Note: On -EAGAIN error only caller can retry on handle based calls
@@ -4776,7 +4941,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
        int rc = 0;
        __u16 params, param_offset, offset, byte_count, count;
 
-       cFYI(1, ("Set Times (via SetFileInfo)"));
+       cFYI(1, "Set Times (via SetFileInfo)");
        rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
 
        if (rc)
@@ -4821,7 +4986,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
        memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
        rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
        if (rc)
-               cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc));
+               cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
 
        /* Note: On -EAGAIN error only caller can retry on handle based calls
                since file handle passed in no longer valid */
@@ -4838,7 +5003,7 @@ CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
        int rc = 0;
        __u16 params, param_offset, offset, byte_count, count;
 
-       cFYI(1, ("Set File Disposition (via SetFileInfo)"));
+       cFYI(1, "Set File Disposition (via SetFileInfo)");
        rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
 
        if (rc)
@@ -4880,7 +5045,7 @@ CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
        *data_offset = delete_file ? 1 : 0;
        rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
        if (rc)
-               cFYI(1, ("Send error in SetFileDisposition = %d", rc));
+               cFYI(1, "Send error in SetFileDisposition = %d", rc);
 
        return rc;
 }
@@ -4898,7 +5063,7 @@ CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,
        char *data_offset;
        __u16 params, param_offset, offset, byte_count, count;
 
-       cFYI(1, ("In SetTimes"));
+       cFYI(1, "In SetTimes");
 
 SetTimesRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -4954,7 +5119,7 @@ SetTimesRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc)
-               cFYI(1, ("SetPathInfo (times) returned %d", rc));
+               cFYI(1, "SetPathInfo (times) returned %d", rc);
 
        cifs_buf_release(pSMB);
 
@@ -4979,7 +5144,7 @@ CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, char *fileName,
        int bytes_returned;
        int name_len;
 
-       cFYI(1, ("In SetAttrLegacy"));
+       cFYI(1, "In SetAttrLegacy");
 
 SetAttrLgcyRetry:
        rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
@@ -5005,7 +5170,7 @@ SetAttrLgcyRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc)
-               cFYI(1, ("Error in LegacySetAttr = %d", rc));
+               cFYI(1, "Error in LegacySetAttr = %d", rc);
 
        cifs_buf_release(pSMB);
 
@@ -5067,7 +5232,7 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
        int rc = 0;
        u16 params, param_offset, offset, byte_count, count;
 
-       cFYI(1, ("Set Unix Info (via SetFileInfo)"));
+       cFYI(1, "Set Unix Info (via SetFileInfo)");
        rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
 
        if (rc)
@@ -5112,7 +5277,7 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
 
        rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
        if (rc)
-               cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc));
+               cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
 
        /* Note: On -EAGAIN error only caller can retry on handle based calls
                since file handle passed in no longer valid */
@@ -5133,7 +5298,7 @@ CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *tcon, char *fileName,
        FILE_UNIX_BASIC_INFO *data_offset;
        __u16 params, param_offset, offset, count, byte_count;
 
-       cFYI(1, ("In SetUID/GID/Mode"));
+       cFYI(1, "In SetUID/GID/Mode");
 setPermsRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -5189,7 +5354,7 @@ setPermsRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc)
-               cFYI(1, ("SetPathInfo (perms) returned %d", rc));
+               cFYI(1, "SetPathInfo (perms) returned %d", rc);
 
        cifs_buf_release(pSMB);
        if (rc == -EAGAIN)
@@ -5208,7 +5373,7 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
        struct dir_notify_req *dnotify_req;
        int bytes_returned;
 
-       cFYI(1, ("In CIFSSMBNotify for file handle %d", (int)netfid));
+       cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
        rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
        if (rc)
@@ -5242,7 +5407,7 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
                         (struct smb_hdr *)pSMBr, &bytes_returned,
                         CIFS_ASYNC_OP);
        if (rc) {
-               cFYI(1, ("Error in Notify = %d", rc));
+               cFYI(1, "Error in Notify = %d", rc);
        } else {
                /* Add file to outstanding requests */
                /* BB change to kmem cache alloc */
@@ -5298,7 +5463,7 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
        char *end_of_smb;
        __u16 params, byte_count, data_offset;
 
-       cFYI(1, ("In Query All EAs path %s", searchName));
+       cFYI(1, "In Query All EAs path %s", searchName);
 QAllEAsRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -5345,7 +5510,7 @@ QAllEAsRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QueryAllEAs = %d", rc));
+               cFYI(1, "Send error in QueryAllEAs = %d", rc);
                goto QAllEAsOut;
        }
 
@@ -5373,16 +5538,16 @@ QAllEAsRetry:
                                (((char *) &pSMBr->hdr.Protocol) + data_offset);
 
        list_len = le32_to_cpu(ea_response_data->list_len);
-       cFYI(1, ("ea length %d", list_len));
+       cFYI(1, "ea length %d", list_len);
        if (list_len <= 8) {
-               cFYI(1, ("empty EA list returned from server"));
+               cFYI(1, "empty EA list returned from server");
                goto QAllEAsOut;
        }
 
        /* make sure list_len doesn't go past end of SMB */
        end_of_smb = (char *)pByteArea(&pSMBr->hdr) + BCC(&pSMBr->hdr);
        if ((char *)ea_response_data + list_len > end_of_smb) {
-               cFYI(1, ("EA list appears to go beyond SMB"));
+               cFYI(1, "EA list appears to go beyond SMB");
                rc = -EIO;
                goto QAllEAsOut;
        }
@@ -5399,7 +5564,7 @@ QAllEAsRetry:
                temp_ptr += 4;
                /* make sure we can read name_len and value_len */
                if (list_len < 0) {
-                       cFYI(1, ("EA entry goes beyond length of list"));
+                       cFYI(1, "EA entry goes beyond length of list");
                        rc = -EIO;
                        goto QAllEAsOut;
                }
@@ -5408,7 +5573,7 @@ QAllEAsRetry:
                value_len = le16_to_cpu(temp_fea->value_len);
                list_len -= name_len + 1 + value_len;
                if (list_len < 0) {
-                       cFYI(1, ("EA entry goes beyond length of list"));
+                       cFYI(1, "EA entry goes beyond length of list");
                        rc = -EIO;
                        goto QAllEAsOut;
                }
@@ -5475,7 +5640,7 @@ CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName,
        int bytes_returned = 0;
        __u16 params, param_offset, byte_count, offset, count;
 
-       cFYI(1, ("In SetEA"));
+       cFYI(1, "In SetEA");
 SetEARetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -5557,7 +5722,7 @@ SetEARetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc)
-               cFYI(1, ("SetPathInfo (EA) returned %d", rc));
+               cFYI(1, "SetPathInfo (EA) returned %d", rc);
 
        cifs_buf_release(pSMB);
 
index 45eb6cba793fe70287da57a533275027d8e4053a..2208f06e4c45ec17d1908b5435ee556be54d6dbe 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/string.h>
 #include <linux/list.h>
 #include <linux/wait.h>
+#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/ctype.h>
 #include <linux/utsname.h>
@@ -101,6 +102,7 @@ struct smb_vol {
        bool sockopt_tcp_nodelay:1;
        unsigned short int port;
        char *prepath;
+       struct nls_table *local_nls;
 };
 
 static int ipv4_connect(struct TCP_Server_Info *server);
@@ -134,7 +136,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
        spin_unlock(&GlobalMid_Lock);
        server->maxBuf = 0;
 
-       cFYI(1, ("Reconnecting tcp session"));
+       cFYI(1, "Reconnecting tcp session");
 
        /* before reconnecting the tcp session, mark the smb session (uid)
                and the tid bad so they are not used until reconnected */
@@ -152,12 +154,12 @@ cifs_reconnect(struct TCP_Server_Info *server)
        /* do not want to be sending data on a socket we are freeing */
        mutex_lock(&server->srv_mutex);
        if (server->ssocket) {
-               cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
-                       server->ssocket->flags));
+               cFYI(1, "State: 0x%x Flags: 0x%lx", server->ssocket->state,
+                       server->ssocket->flags);
                kernel_sock_shutdown(server->ssocket, SHUT_WR);
-               cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx",
+               cFYI(1, "Post shutdown state: 0x%x Flags: 0x%lx",
                        server->ssocket->state,
-                       server->ssocket->flags));
+                       server->ssocket->flags);
                sock_release(server->ssocket);
                server->ssocket = NULL;
        }
@@ -186,7 +188,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
                else
                        rc = ipv4_connect(server);
                if (rc) {
-                       cFYI(1, ("reconnect error %d", rc));
+                       cFYI(1, "reconnect error %d", rc);
                        msleep(3000);
                } else {
                        atomic_inc(&tcpSesReconnectCount);
@@ -222,7 +224,7 @@ static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
        /* check for plausible wct, bcc and t2 data and parm sizes */
        /* check for parm and data offset going beyond end of smb */
        if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
-               cFYI(1, ("invalid transact2 word count"));
+               cFYI(1, "invalid transact2 word count");
                return -EINVAL;
        }
 
@@ -236,15 +238,15 @@ static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
        if (remaining == 0)
                return 0;
        else if (remaining < 0) {
-               cFYI(1, ("total data %d smaller than data in frame %d",
-                       total_data_size, data_in_this_rsp));
+               cFYI(1, "total data %d smaller than data in frame %d",
+                       total_data_size, data_in_this_rsp);
                return -EINVAL;
        } else {
-               cFYI(1, ("missing %d bytes from transact2, check next response",
-                       remaining));
+               cFYI(1, "missing %d bytes from transact2, check next response",
+                       remaining);
                if (total_data_size > maxBufSize) {
-                       cERROR(1, ("TotalDataSize %d is over maximum buffer %d",
-                               total_data_size, maxBufSize));
+                       cERROR(1, "TotalDataSize %d is over maximum buffer %d",
+                               total_data_size, maxBufSize);
                        return -EINVAL;
                }
                return remaining;
@@ -266,7 +268,7 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
        total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
 
        if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
-               cFYI(1, ("total data size of primary and secondary t2 differ"));
+               cFYI(1, "total data size of primary and secondary t2 differ");
        }
 
        total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
@@ -281,7 +283,7 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
 
        total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
        if (remaining < total_in_buf2) {
-               cFYI(1, ("transact2 2nd response contains too much data"));
+               cFYI(1, "transact2 2nd response contains too much data");
        }
 
        /* find end of first SMB data area */
@@ -310,7 +312,7 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
        pTargetSMB->smb_buf_length = byte_count;
 
        if (remaining == total_in_buf2) {
-               cFYI(1, ("found the last secondary response"));
+               cFYI(1, "found the last secondary response");
                return 0; /* we are done */
        } else /* more responses to go */
                return 1;
@@ -338,7 +340,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
        int reconnect;
 
        current->flags |= PF_MEMALLOC;
-       cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
+       cFYI(1, "Demultiplex PID: %d", task_pid_nr(current));
 
        length = atomic_inc_return(&tcpSesAllocCount);
        if (length > 1)
@@ -352,7 +354,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                if (bigbuf == NULL) {
                        bigbuf = cifs_buf_get();
                        if (!bigbuf) {
-                               cERROR(1, ("No memory for large SMB response"));
+                               cERROR(1, "No memory for large SMB response");
                                msleep(3000);
                                /* retry will check if exiting */
                                continue;
@@ -365,7 +367,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                if (smallbuf == NULL) {
                        smallbuf = cifs_small_buf_get();
                        if (!smallbuf) {
-                               cERROR(1, ("No memory for SMB response"));
+                               cERROR(1, "No memory for SMB response");
                                msleep(1000);
                                /* retry will check if exiting */
                                continue;
@@ -390,9 +392,9 @@ incomplete_rcv:
                if (server->tcpStatus == CifsExiting) {
                        break;
                } else if (server->tcpStatus == CifsNeedReconnect) {
-                       cFYI(1, ("Reconnect after server stopped responding"));
+                       cFYI(1, "Reconnect after server stopped responding");
                        cifs_reconnect(server);
-                       cFYI(1, ("call to reconnect done"));
+                       cFYI(1, "call to reconnect done");
                        csocket = server->ssocket;
                        continue;
                } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
@@ -410,7 +412,7 @@ incomplete_rcv:
                                continue;
                } else if (length <= 0) {
                        if (server->tcpStatus == CifsNew) {
-                               cFYI(1, ("tcp session abend after SMBnegprot"));
+                               cFYI(1, "tcp session abend after SMBnegprot");
                                /* some servers kill the TCP session rather than
                                   returning an SMB negprot error, in which
                                   case reconnecting here is not going to help,
@@ -418,18 +420,18 @@ incomplete_rcv:
                                break;
                        }
                        if (!try_to_freeze() && (length == -EINTR)) {
-                               cFYI(1, ("cifsd thread killed"));
+                               cFYI(1, "cifsd thread killed");
                                break;
                        }
-                       cFYI(1, ("Reconnect after unexpected peek error %d",
-                               length));
+                       cFYI(1, "Reconnect after unexpected peek error %d",
+                               length);
                        cifs_reconnect(server);
                        csocket = server->ssocket;
                        wake_up(&server->response_q);
                        continue;
                } else if (length < pdu_length) {
-                       cFYI(1, ("requested %d bytes but only got %d bytes",
-                                 pdu_length, length));
+                       cFYI(1, "requested %d bytes but only got %d bytes",
+                                 pdu_length, length);
                        pdu_length -= length;
                        msleep(1);
                        goto incomplete_rcv;
@@ -449,18 +451,18 @@ incomplete_rcv:
                pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
                smb_buffer->smb_buf_length = pdu_length;
 
-               cFYI(1, ("rfc1002 length 0x%x", pdu_length+4));
+               cFYI(1, "rfc1002 length 0x%x", pdu_length+4);
 
                if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
                        continue;
                } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
-                       cFYI(1, ("Good RFC 1002 session rsp"));
+                       cFYI(1, "Good RFC 1002 session rsp");
                        continue;
                } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
                        /* we get this from Windows 98 instead of
                           an error on SMB negprot response */
-                       cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)",
-                               pdu_length));
+                       cFYI(1, "Negative RFC1002 Session Response Error 0x%x)",
+                               pdu_length);
                        if (server->tcpStatus == CifsNew) {
                                /* if nack on negprot (rather than
                                ret of smb negprot error) reconnecting
@@ -483,7 +485,7 @@ incomplete_rcv:
                                continue;
                        }
                } else if (temp != (char) 0) {
-                       cERROR(1, ("Unknown RFC 1002 frame"));
+                       cERROR(1, "Unknown RFC 1002 frame");
                        cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
                                      length);
                        cifs_reconnect(server);
@@ -494,8 +496,8 @@ incomplete_rcv:
                /* else we have an SMB response */
                if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
                            (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
-                       cERROR(1, ("Invalid size SMB length %d pdu_length %d",
-                                       length, pdu_length+4));
+                       cERROR(1, "Invalid size SMB length %d pdu_length %d",
+                                       length, pdu_length+4);
                        cifs_reconnect(server);
                        csocket = server->ssocket;
                        wake_up(&server->response_q);
@@ -538,8 +540,8 @@ incomplete_rcv:
                                length = 0;
                                continue;
                        } else if (length <= 0) {
-                               cERROR(1, ("Received no data, expecting %d",
-                                             pdu_length - total_read));
+                               cERROR(1, "Received no data, expecting %d",
+                                             pdu_length - total_read);
                                cifs_reconnect(server);
                                csocket = server->ssocket;
                                reconnect = 1;
@@ -587,7 +589,7 @@ incomplete_rcv:
                                                }
                                        } else {
                                                if (!isLargeBuf) {
-                                                       cERROR(1,("1st trans2 resp needs bigbuf"));
+                                                       cERROR(1, "1st trans2 resp needs bigbuf");
                                        /* BB maybe we can fix this up,  switch
                                           to already allocated large buffer? */
                                                } else {
@@ -629,8 +631,8 @@ multi_t2_fnd:
                        wake_up_process(task_to_wake);
                } else if (!is_valid_oplock_break(smb_buffer, server) &&
                           !isMultiRsp) {
-                       cERROR(1, ("No task to wake, unknown frame received! "
-                                  "NumMids %d", midCount.counter));
+                       cERROR(1, "No task to wake, unknown frame received! "
+                                  "NumMids %d", midCount.counter);
                        cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
                                      sizeof(struct smb_hdr));
 #ifdef CONFIG_CIFS_DEBUG2
@@ -707,8 +709,8 @@ multi_t2_fnd:
                list_for_each(tmp, &server->pending_mid_q) {
                mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
                        if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
-                               cFYI(1, ("Clearing Mid 0x%x - waking up ",
-                                        mid_entry->mid));
+                               cFYI(1, "Clearing Mid 0x%x - waking up ",
+                                        mid_entry->mid);
                                task_to_wake = mid_entry->tsk;
                                if (task_to_wake)
                                        wake_up_process(task_to_wake);
@@ -727,7 +729,7 @@ multi_t2_fnd:
                to wait at least 45 seconds before giving up
                on a request getting a response and going ahead
                and killing cifsd */
-               cFYI(1, ("Wait for exit from demultiplex thread"));
+               cFYI(1, "Wait for exit from demultiplex thread");
                msleep(46000);
                /* if threads still have not exited they are probably never
                coming home not much else we can do but free the memory */
@@ -848,7 +850,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                        separator[0] = options[4];
                        options += 5;
                } else {
-                       cFYI(1, ("Null separator not allowed"));
+                       cFYI(1, "Null separator not allowed");
                }
        }
 
@@ -973,7 +975,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                        }
                } else if (strnicmp(data, "sec", 3) == 0) {
                        if (!value || !*value) {
-                               cERROR(1, ("no security value specified"));
+                               cERROR(1, "no security value specified");
                                continue;
                        } else if (strnicmp(value, "krb5i", 5) == 0) {
                                vol->secFlg |= CIFSSEC_MAY_KRB5 |
@@ -981,7 +983,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                        } else if (strnicmp(value, "krb5p", 5) == 0) {
                                /* vol->secFlg |= CIFSSEC_MUST_SEAL |
                                        CIFSSEC_MAY_KRB5; */
-                               cERROR(1, ("Krb5 cifs privacy not supported"));
+                               cERROR(1, "Krb5 cifs privacy not supported");
                                return 1;
                        } else if (strnicmp(value, "krb5", 4) == 0) {
                                vol->secFlg |= CIFSSEC_MAY_KRB5;
@@ -1013,7 +1015,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                        } else if (strnicmp(value, "none", 4) == 0) {
                                vol->nullauth = 1;
                        } else {
-                               cERROR(1, ("bad security option: %s", value));
+                               cERROR(1, "bad security option: %s", value);
                                return 1;
                        }
                } else if ((strnicmp(data, "unc", 3) == 0)
@@ -1052,7 +1054,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                        a domain name and need special handling? */
                        if (strnlen(value, 256) < 256) {
                                vol->domainname = value;
-                               cFYI(1, ("Domain name set"));
+                               cFYI(1, "Domain name set");
                        } else {
                                printk(KERN_WARNING "CIFS: domain name too "
                                                    "long\n");
@@ -1075,7 +1077,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                                        strcpy(vol->prepath+1, value);
                                } else
                                        strcpy(vol->prepath, value);
-                               cFYI(1, ("prefix path %s", vol->prepath));
+                               cFYI(1, "prefix path %s", vol->prepath);
                        } else {
                                printk(KERN_WARNING "CIFS: prefix too long\n");
                                return 1;
@@ -1091,7 +1093,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                                        vol->iocharset = value;
                                /* if iocharset not set then load_nls_default
                                   is used by caller */
-                               cFYI(1, ("iocharset set to %s", value));
+                               cFYI(1, "iocharset set to %s", value);
                        } else {
                                printk(KERN_WARNING "CIFS: iocharset name "
                                                    "too long.\n");
@@ -1143,14 +1145,14 @@ cifs_parse_mount_options(char *options, const char *devname,
                        }
                } else if (strnicmp(data, "sockopt", 5) == 0) {
                        if (!value || !*value) {
-                               cERROR(1, ("no socket option specified"));
+                               cERROR(1, "no socket option specified");
                                continue;
                        } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) {
                                vol->sockopt_tcp_nodelay = 1;
                        }
                } else if (strnicmp(data, "netbiosname", 4) == 0) {
                        if (!value || !*value || (*value == ' ')) {
-                               cFYI(1, ("invalid (empty) netbiosname"));
+                               cFYI(1, "invalid (empty) netbiosname");
                        } else {
                                memset(vol->source_rfc1001_name, 0x20, 15);
                                for (i = 0; i < 15; i++) {
@@ -1174,7 +1176,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                } else if (strnicmp(data, "servern", 7) == 0) {
                        /* servernetbiosname specified override *SMBSERVER */
                        if (!value || !*value || (*value == ' ')) {
-                               cFYI(1, ("empty server netbiosname specified"));
+                               cFYI(1, "empty server netbiosname specified");
                        } else {
                                /* last byte, type, is 0x20 for servr type */
                                memset(vol->target_rfc1001_name, 0x20, 16);
@@ -1433,7 +1435,7 @@ cifs_find_tcp_session(struct sockaddr_storage *addr, unsigned short int port)
 
                ++server->srv_count;
                write_unlock(&cifs_tcp_ses_lock);
-               cFYI(1, ("Existing tcp session with server found"));
+               cFYI(1, "Existing tcp session with server found");
                return server;
        }
        write_unlock(&cifs_tcp_ses_lock);
@@ -1474,7 +1476,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
 
        memset(&addr, 0, sizeof(struct sockaddr_storage));
 
-       cFYI(1, ("UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip));
+       cFYI(1, "UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip);
 
        if (volume_info->UNCip && volume_info->UNC) {
                rc = cifs_convert_address(volume_info->UNCip, &addr);
@@ -1486,13 +1488,12 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
        } else if (volume_info->UNCip) {
                /* BB using ip addr as tcp_ses name to connect to the
                   DFS root below */
-               cERROR(1, ("Connecting to DFS root not implemented yet"));
+               cERROR(1, "Connecting to DFS root not implemented yet");
                rc = -EINVAL;
                goto out_err;
        } else /* which tcp_sess DFS root would we conect to */ {
-               cERROR(1,
-                      ("CIFS mount error: No UNC path (e.g. -o "
-                       "unc=//192.168.1.100/public) specified"));
+               cERROR(1, "CIFS mount error: No UNC path (e.g. -o "
+                       "unc=//192.168.1.100/public) specified");
                rc = -EINVAL;
                goto out_err;
        }
@@ -1539,7 +1540,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
        ++tcp_ses->srv_count;
 
        if (addr.ss_family == AF_INET6) {
-               cFYI(1, ("attempting ipv6 connect"));
+               cFYI(1, "attempting ipv6 connect");
                /* BB should we allow ipv6 on port 139? */
                /* other OS never observed in Wild doing 139 with v6 */
                sin_server6->sin6_port = htons(volume_info->port);
@@ -1553,7 +1554,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
                rc = ipv4_connect(tcp_ses);
        }
        if (rc < 0) {
-               cERROR(1, ("Error connecting to socket. Aborting operation"));
+               cERROR(1, "Error connecting to socket. Aborting operation");
                goto out_err;
        }
 
@@ -1566,7 +1567,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
                                  tcp_ses, "cifsd");
        if (IS_ERR(tcp_ses->tsk)) {
                rc = PTR_ERR(tcp_ses->tsk);
-               cERROR(1, ("error %d create cifsd thread", rc));
+               cERROR(1, "error %d create cifsd thread", rc);
                module_put(THIS_MODULE);
                goto out_err;
        }
@@ -1615,6 +1616,7 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
        int xid;
        struct TCP_Server_Info *server = ses->server;
 
+       cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count);
        write_lock(&cifs_tcp_ses_lock);
        if (--ses->ses_count > 0) {
                write_unlock(&cifs_tcp_ses_lock);
@@ -1633,6 +1635,102 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
        cifs_put_tcp_session(server);
 }
 
+static struct cifsSesInfo *
+cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
+{
+       int rc = -ENOMEM, xid;
+       struct cifsSesInfo *ses;
+
+       xid = GetXid();
+
+       ses = cifs_find_smb_ses(server, volume_info->username);
+       if (ses) {
+               cFYI(1, "Existing smb sess found (status=%d)", ses->status);
+
+               /* existing SMB ses has a server reference already */
+               cifs_put_tcp_session(server);
+
+               mutex_lock(&ses->session_mutex);
+               rc = cifs_negotiate_protocol(xid, ses);
+               if (rc) {
+                       mutex_unlock(&ses->session_mutex);
+                       /* problem -- put our ses reference */
+                       cifs_put_smb_ses(ses);
+                       FreeXid(xid);
+                       return ERR_PTR(rc);
+               }
+               if (ses->need_reconnect) {
+                       cFYI(1, "Session needs reconnect");
+                       rc = cifs_setup_session(xid, ses,
+                                               volume_info->local_nls);
+                       if (rc) {
+                               mutex_unlock(&ses->session_mutex);
+                               /* problem -- put our reference */
+                               cifs_put_smb_ses(ses);
+                               FreeXid(xid);
+                               return ERR_PTR(rc);
+                       }
+               }
+               mutex_unlock(&ses->session_mutex);
+               FreeXid(xid);
+               return ses;
+       }
+
+       cFYI(1, "Existing smb sess not found");
+       ses = sesInfoAlloc();
+       if (ses == NULL)
+               goto get_ses_fail;
+
+       /* new SMB session uses our server ref */
+       ses->server = server;
+       if (server->addr.sockAddr6.sin6_family == AF_INET6)
+               sprintf(ses->serverName, "%pI6",
+                       &server->addr.sockAddr6.sin6_addr);
+       else
+               sprintf(ses->serverName, "%pI4",
+                       &server->addr.sockAddr.sin_addr.s_addr);
+
+       if (volume_info->username)
+               strncpy(ses->userName, volume_info->username,
+                       MAX_USERNAME_SIZE);
+
+       /* volume_info->password freed at unmount */
+       if (volume_info->password) {
+               ses->password = kstrdup(volume_info->password, GFP_KERNEL);
+               if (!ses->password)
+                       goto get_ses_fail;
+       }
+       if (volume_info->domainname) {
+               int len = strlen(volume_info->domainname);
+               ses->domainName = kmalloc(len + 1, GFP_KERNEL);
+               if (ses->domainName)
+                       strcpy(ses->domainName, volume_info->domainname);
+       }
+       ses->linux_uid = volume_info->linux_uid;
+       ses->overrideSecFlg = volume_info->secFlg;
+
+       mutex_lock(&ses->session_mutex);
+       rc = cifs_negotiate_protocol(xid, ses);
+       if (!rc)
+               rc = cifs_setup_session(xid, ses, volume_info->local_nls);
+       mutex_unlock(&ses->session_mutex);
+       if (rc)
+               goto get_ses_fail;
+
+       /* success, put it on the list */
+       write_lock(&cifs_tcp_ses_lock);
+       list_add(&ses->smb_ses_list, &server->smb_ses_list);
+       write_unlock(&cifs_tcp_ses_lock);
+
+       FreeXid(xid);
+       return ses;
+
+get_ses_fail:
+       sesInfoFree(ses);
+       FreeXid(xid);
+       return ERR_PTR(rc);
+}
+
 static struct cifsTconInfo *
 cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
 {
@@ -1661,6 +1759,7 @@ cifs_put_tcon(struct cifsTconInfo *tcon)
        int xid;
        struct cifsSesInfo *ses = tcon->ses;
 
+       cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
        write_lock(&cifs_tcp_ses_lock);
        if (--tcon->tc_count > 0) {
                write_unlock(&cifs_tcp_ses_lock);
@@ -1678,6 +1777,80 @@ cifs_put_tcon(struct cifsTconInfo *tcon)
        cifs_put_smb_ses(ses);
 }
 
+static struct cifsTconInfo *
+cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info)
+{
+       int rc, xid;
+       struct cifsTconInfo *tcon;
+
+       tcon = cifs_find_tcon(ses, volume_info->UNC);
+       if (tcon) {
+               cFYI(1, "Found match on UNC path");
+               /* existing tcon already has a reference */
+               cifs_put_smb_ses(ses);
+               if (tcon->seal != volume_info->seal)
+                       cERROR(1, "transport encryption setting "
+                                  "conflicts with existing tid");
+               return tcon;
+       }
+
+       tcon = tconInfoAlloc();
+       if (tcon == NULL) {
+               rc = -ENOMEM;
+               goto out_fail;
+       }
+
+       tcon->ses = ses;
+       if (volume_info->password) {
+               tcon->password = kstrdup(volume_info->password, GFP_KERNEL);
+               if (!tcon->password) {
+                       rc = -ENOMEM;
+                       goto out_fail;
+               }
+       }
+
+       if (strchr(volume_info->UNC + 3, '\\') == NULL
+           && strchr(volume_info->UNC + 3, '/') == NULL) {
+               cERROR(1, "Missing share name");
+               rc = -ENODEV;
+               goto out_fail;
+       }
+
+       /* BB Do we need to wrap session_mutex around
+        * this TCon call and Unix SetFS as
+        * we do on SessSetup and reconnect? */
+       xid = GetXid();
+       rc = CIFSTCon(xid, ses, volume_info->UNC, tcon, volume_info->local_nls);
+       FreeXid(xid);
+       cFYI(1, "CIFS Tcon rc = %d", rc);
+       if (rc)
+               goto out_fail;
+
+       if (volume_info->nodfs) {
+               tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
+               cFYI(1, "DFS disabled (%d)", tcon->Flags);
+       }
+       tcon->seal = volume_info->seal;
+       /* we can have only one retry value for a connection
+          to a share so for resources mounted more than once
+          to the same server share the last value passed in
+          for the retry flag is used */
+       tcon->retry = volume_info->retry;
+       tcon->nocase = volume_info->nocase;
+       tcon->local_lease = volume_info->local_lease;
+
+       write_lock(&cifs_tcp_ses_lock);
+       list_add(&tcon->tcon_list, &ses->tcon_list);
+       write_unlock(&cifs_tcp_ses_lock);
+
+       return tcon;
+
+out_fail:
+       tconInfoFree(tcon);
+       return ERR_PTR(rc);
+}
+
+
 int
 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
             const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
@@ -1702,8 +1875,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
                strcpy(temp_unc + 2, pSesInfo->serverName);
                strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
                rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
-               cFYI(1,
-                    ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
+               cFYI(1, "CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid);
                kfree(temp_unc);
        }
        if (rc == 0)
@@ -1776,12 +1948,12 @@ ipv4_connect(struct TCP_Server_Info *server)
                rc = sock_create_kern(PF_INET, SOCK_STREAM,
                                      IPPROTO_TCP, &socket);
                if (rc < 0) {
-                       cERROR(1, ("Error %d creating socket", rc));
+                       cERROR(1, "Error %d creating socket", rc);
                        return rc;
                }
 
                /* BB other socket options to set KEEPALIVE, NODELAY? */
-               cFYI(1, ("Socket created"));
+               cFYI(1, "Socket created");
                server->ssocket = socket;
                socket->sk->sk_allocation = GFP_NOFS;
                cifs_reclassify_socket4(socket);
@@ -1826,7 +1998,7 @@ ipv4_connect(struct TCP_Server_Info *server)
        if (!connected) {
                if (orig_port)
                        server->addr.sockAddr.sin_port = orig_port;
-               cFYI(1, ("Error %d connecting to server via ipv4", rc));
+               cFYI(1, "Error %d connecting to server via ipv4", rc);
                sock_release(socket);
                server->ssocket = NULL;
                return rc;
@@ -1854,12 +2026,12 @@ ipv4_connect(struct TCP_Server_Info *server)
                rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
                                (char *)&val, sizeof(val));
                if (rc)
-                       cFYI(1, ("set TCP_NODELAY socket option error %d", rc));
+                       cFYI(1, "set TCP_NODELAY socket option error %d", rc);
        }
 
-        cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
+        cFYI(1, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
                 socket->sk->sk_sndbuf,
-                socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo));
+                socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
 
        /* send RFC1001 sessinit */
        if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) {
@@ -1937,13 +2109,13 @@ ipv6_connect(struct TCP_Server_Info *server)
                rc = sock_create_kern(PF_INET6, SOCK_STREAM,
                                      IPPROTO_TCP, &socket);
                if (rc < 0) {
-                       cERROR(1, ("Error %d creating ipv6 socket", rc));
+                       cERROR(1, "Error %d creating ipv6 socket", rc);
                        socket = NULL;
                        return rc;
                }
 
                /* BB other socket options to set KEEPALIVE, NODELAY? */
-               cFYI(1, ("ipv6 Socket created"));
+               cFYI(1, "ipv6 Socket created");
                server->ssocket = socket;
                socket->sk->sk_allocation = GFP_NOFS;
                cifs_reclassify_socket6(socket);
@@ -1987,7 +2159,7 @@ ipv6_connect(struct TCP_Server_Info *server)
        if (!connected) {
                if (orig_port)
                        server->addr.sockAddr6.sin6_port = orig_port;
-               cFYI(1, ("Error %d connecting to server via ipv6", rc));
+               cFYI(1, "Error %d connecting to server via ipv6", rc);
                sock_release(socket);
                server->ssocket = NULL;
                return rc;
@@ -2006,7 +2178,7 @@ ipv6_connect(struct TCP_Server_Info *server)
                rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
                                (char *)&val, sizeof(val));
                if (rc)
-                       cFYI(1, ("set TCP_NODELAY socket option error %d", rc));
+                       cFYI(1, "set TCP_NODELAY socket option error %d", rc);
        }
 
        server->ssocket = socket;
@@ -2031,13 +2203,13 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
        if (vol_info && vol_info->no_linux_ext) {
                tcon->fsUnixInfo.Capability = 0;
                tcon->unix_ext = 0; /* Unix Extensions disabled */
-               cFYI(1, ("Linux protocol extensions disabled"));
+               cFYI(1, "Linux protocol extensions disabled");
                return;
        } else if (vol_info)
                tcon->unix_ext = 1; /* Unix Extensions supported */
 
        if (tcon->unix_ext == 0) {
-               cFYI(1, ("Unix extensions disabled so not set on reconnect"));
+               cFYI(1, "Unix extensions disabled so not set on reconnect");
                return;
        }
 
@@ -2053,12 +2225,11 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
                                cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
                        if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
                                if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
-                                       cERROR(1, ("POSIXPATH support change"));
+                                       cERROR(1, "POSIXPATH support change");
                                cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
                        } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
-                               cERROR(1, ("possible reconnect error"));
-                               cERROR(1,
-                                       ("server disabled POSIX path support"));
+                               cERROR(1, "possible reconnect error");
+                               cERROR(1, "server disabled POSIX path support");
                        }
                }
 
@@ -2066,7 +2237,7 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
                if (vol_info && vol_info->no_psx_acl)
                        cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
                else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
-                       cFYI(1, ("negotiated posix acl support"));
+                       cFYI(1, "negotiated posix acl support");
                        if (sb)
                                sb->s_flags |= MS_POSIXACL;
                }
@@ -2074,7 +2245,7 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
                if (vol_info && vol_info->posix_paths == 0)
                        cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
                else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
-                       cFYI(1, ("negotiate posix pathnames"));
+                       cFYI(1, "negotiate posix pathnames");
                        if (sb)
                                CIFS_SB(sb)->mnt_cifs_flags |=
                                        CIFS_MOUNT_POSIX_PATHS;
@@ -2089,39 +2260,38 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
                if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
                        if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
                                CIFS_SB(sb)->rsize = 127 * 1024;
-                               cFYI(DBG2,
-                                       ("larger reads not supported by srv"));
+                               cFYI(DBG2, "larger reads not supported by srv");
                        }
                }
 
 
-               cFYI(1, ("Negotiate caps 0x%x", (int)cap));
+               cFYI(1, "Negotiate caps 0x%x", (int)cap);
 #ifdef CONFIG_CIFS_DEBUG2
                if (cap & CIFS_UNIX_FCNTL_CAP)
-                       cFYI(1, ("FCNTL cap"));
+                       cFYI(1, "FCNTL cap");
                if (cap & CIFS_UNIX_EXTATTR_CAP)
-                       cFYI(1, ("EXTATTR cap"));
+                       cFYI(1, "EXTATTR cap");
                if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
-                       cFYI(1, ("POSIX path cap"));
+                       cFYI(1, "POSIX path cap");
                if (cap & CIFS_UNIX_XATTR_CAP)
-                       cFYI(1, ("XATTR cap"));
+                       cFYI(1, "XATTR cap");
                if (cap & CIFS_UNIX_POSIX_ACL_CAP)
-                       cFYI(1, ("POSIX ACL cap"));
+                       cFYI(1, "POSIX ACL cap");
                if (cap & CIFS_UNIX_LARGE_READ_CAP)
-                       cFYI(1, ("very large read cap"));
+                       cFYI(1, "very large read cap");
                if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
-                       cFYI(1, ("very large write cap"));
+                       cFYI(1, "very large write cap");
 #endif /* CIFS_DEBUG2 */
                if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
                        if (vol_info == NULL) {
-                               cFYI(1, ("resetting capabilities failed"));
+                               cFYI(1, "resetting capabilities failed");
                        } else
-                               cERROR(1, ("Negotiating Unix capabilities "
+                               cERROR(1, "Negotiating Unix capabilities "
                                           "with the server failed.  Consider "
                                           "mounting with the Unix Extensions\n"
                                           "disabled, if problems are found, "
                                           "by specifying the nounix mount "
-                                          "option."));
+                                          "option.");
 
                }
        }
@@ -2151,8 +2321,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
                          struct cifs_sb_info *cifs_sb)
 {
        if (pvolume_info->rsize > CIFSMaxBufSize) {
-               cERROR(1, ("rsize %d too large, using MaxBufSize",
-                       pvolume_info->rsize));
+               cERROR(1, "rsize %d too large, using MaxBufSize",
+                       pvolume_info->rsize);
                cifs_sb->rsize = CIFSMaxBufSize;
        } else if ((pvolume_info->rsize) &&
                        (pvolume_info->rsize <= CIFSMaxBufSize))
@@ -2161,8 +2331,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
                cifs_sb->rsize = CIFSMaxBufSize;
 
        if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
-               cERROR(1, ("wsize %d too large, using 4096 instead",
-                         pvolume_info->wsize));
+               cERROR(1, "wsize %d too large, using 4096 instead",
+                         pvolume_info->wsize);
                cifs_sb->wsize = 4096;
        } else if (pvolume_info->wsize)
                cifs_sb->wsize = pvolume_info->wsize;
@@ -2180,7 +2350,7 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
        if (cifs_sb->rsize < 2048) {
                cifs_sb->rsize = 2048;
                /* Windows ME may prefer this */
-               cFYI(1, ("readsize set to minimum: 2048"));
+               cFYI(1, "readsize set to minimum: 2048");
        }
        /* calculate prepath */
        cifs_sb->prepath = pvolume_info->prepath;
@@ -2198,8 +2368,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
        cifs_sb->mnt_gid = pvolume_info->linux_gid;
        cifs_sb->mnt_file_mode = pvolume_info->file_mode;
        cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
-       cFYI(1, ("file mode: 0x%x  dir mode: 0x%x",
-               cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
+       cFYI(1, "file mode: 0x%x  dir mode: 0x%x",
+               cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
 
        if (pvolume_info->noperm)
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
@@ -2228,13 +2398,13 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
        if (pvolume_info->dynperm)
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
        if (pvolume_info->direct_io) {
-               cFYI(1, ("mounting share using direct i/o"));
+               cFYI(1, "mounting share using direct i/o");
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
        }
 
        if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
-               cERROR(1, ("mount option dynperm ignored if cifsacl "
-                          "mount option supported"));
+               cERROR(1, "mount option dynperm ignored if cifsacl "
+                          "mount option supported");
 }
 
 static int
@@ -2261,7 +2431,7 @@ cleanup_volume_info(struct smb_vol **pvolume_info)
 {
        struct smb_vol *volume_info;
 
-       if (!pvolume_info && !*pvolume_info)
+       if (!pvolume_info || !*pvolume_info)
                return;
 
        volume_info = *pvolume_info;
@@ -2343,11 +2513,11 @@ try_mount_again:
        }
 
        if (volume_info->nullauth) {
-               cFYI(1, ("null user"));
+               cFYI(1, "null user");
                volume_info->username = "";
        } else if (volume_info->username) {
                /* BB fixme parse for domain name here */
-               cFYI(1, ("Username: %s", volume_info->username));
+               cFYI(1, "Username: %s", volume_info->username);
        } else {
                cifserror("No username specified");
        /* In userspace mount helper we can get user name from alternate
@@ -2356,20 +2526,20 @@ try_mount_again:
                goto out;
        }
 
-
        /* this is needed for ASCII cp to Unicode converts */
        if (volume_info->iocharset == NULL) {
-               cifs_sb->local_nls = load_nls_default();
-       /* load_nls_default can not return null */
+               /* load_nls_default cannot return null */
+               volume_info->local_nls = load_nls_default();
        } else {
-               cifs_sb->local_nls = load_nls(volume_info->iocharset);
-               if (cifs_sb->local_nls == NULL) {
-                       cERROR(1, ("CIFS mount error: iocharset %s not found",
-                                volume_info->iocharset));
+               volume_info->local_nls = load_nls(volume_info->iocharset);
+               if (volume_info->local_nls == NULL) {
+                       cERROR(1, "CIFS mount error: iocharset %s not found",
+                                volume_info->iocharset);
                        rc = -ELIBACC;
                        goto out;
                }
        }
+       cifs_sb->local_nls = volume_info->local_nls;
 
        /* get a reference to a tcp session */
        srvTcp = cifs_get_tcp_session(volume_info);
@@ -2378,148 +2548,30 @@ try_mount_again:
                goto out;
        }
 
-       pSesInfo = cifs_find_smb_ses(srvTcp, volume_info->username);
-       if (pSesInfo) {
-               cFYI(1, ("Existing smb sess found (status=%d)",
-                       pSesInfo->status));
-               /*
-                * The existing SMB session already has a reference to srvTcp,
-                * so we can put back the extra one we got before
-                */
-               cifs_put_tcp_session(srvTcp);
-
-               mutex_lock(&pSesInfo->session_mutex);
-               if (pSesInfo->need_reconnect) {
-                       cFYI(1, ("Session needs reconnect"));
-                       rc = cifs_setup_session(xid, pSesInfo,
-                                               cifs_sb->local_nls);
-               }
-               mutex_unlock(&pSesInfo->session_mutex);
-       } else if (!rc) {
-               cFYI(1, ("Existing smb sess not found"));
-               pSesInfo = sesInfoAlloc();
-               if (pSesInfo == NULL) {
-                       rc = -ENOMEM;
-                       goto mount_fail_check;
-               }
-
-               /* new SMB session uses our srvTcp ref */
-               pSesInfo->server = srvTcp;
-               if (srvTcp->addr.sockAddr6.sin6_family == AF_INET6)
-                       sprintf(pSesInfo->serverName, "%pI6",
-                               &srvTcp->addr.sockAddr6.sin6_addr);
-               else
-                       sprintf(pSesInfo->serverName, "%pI4",
-                               &srvTcp->addr.sockAddr.sin_addr.s_addr);
-
-               write_lock(&cifs_tcp_ses_lock);
-               list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list);
-               write_unlock(&cifs_tcp_ses_lock);
-
-               /* volume_info->password freed at unmount */
-               if (volume_info->password) {
-                       pSesInfo->password = kstrdup(volume_info->password,
-                                                    GFP_KERNEL);
-                       if (!pSesInfo->password) {
-                               rc = -ENOMEM;
-                               goto mount_fail_check;
-                       }
-               }
-               if (volume_info->username)
-                       strncpy(pSesInfo->userName, volume_info->username,
-                               MAX_USERNAME_SIZE);
-               if (volume_info->domainname) {
-                       int len = strlen(volume_info->domainname);
-                       pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL);
-                       if (pSesInfo->domainName)
-                               strcpy(pSesInfo->domainName,
-                                       volume_info->domainname);
-               }
-               pSesInfo->linux_uid = volume_info->linux_uid;
-               pSesInfo->overrideSecFlg = volume_info->secFlg;
-               mutex_lock(&pSesInfo->session_mutex);
-
-               /* BB FIXME need to pass vol->secFlgs BB */
-               rc = cifs_setup_session(xid, pSesInfo,
-                                       cifs_sb->local_nls);
-               mutex_unlock(&pSesInfo->session_mutex);
+       /* get a reference to a SMB session */
+       pSesInfo = cifs_get_smb_ses(srvTcp, volume_info);
+       if (IS_ERR(pSesInfo)) {
+               rc = PTR_ERR(pSesInfo);
+               pSesInfo = NULL;
+               goto mount_fail_check;
        }
 
-       /* search for existing tcon to this server share */
-       if (!rc) {
-               setup_cifs_sb(volume_info, cifs_sb);
-
-               tcon = cifs_find_tcon(pSesInfo, volume_info->UNC);
-               if (tcon) {
-                       cFYI(1, ("Found match on UNC path"));
-                       /* existing tcon already has a reference */
-                       cifs_put_smb_ses(pSesInfo);
-                       if (tcon->seal != volume_info->seal)
-                               cERROR(1, ("transport encryption setting "
-                                          "conflicts with existing tid"));
-               } else {
-                       tcon = tconInfoAlloc();
-                       if (tcon == NULL) {
-                               rc = -ENOMEM;
-                               goto mount_fail_check;
-                       }
-
-                       tcon->ses = pSesInfo;
-                       if (volume_info->password) {
-                               tcon->password = kstrdup(volume_info->password,
-                                                        GFP_KERNEL);
-                               if (!tcon->password) {
-                                       rc = -ENOMEM;
-                                       goto mount_fail_check;
-                               }
-                       }
-
-                       if ((strchr(volume_info->UNC + 3, '\\') == NULL)
-                           && (strchr(volume_info->UNC + 3, '/') == NULL)) {
-                               cERROR(1, ("Missing share name"));
-                               rc = -ENODEV;
-                               goto mount_fail_check;
-                       } else {
-                               /* BB Do we need to wrap sesSem around
-                                * this TCon call and Unix SetFS as
-                                * we do on SessSetup and reconnect? */
-                               rc = CIFSTCon(xid, pSesInfo, volume_info->UNC,
-                                             tcon, cifs_sb->local_nls);
-                               cFYI(1, ("CIFS Tcon rc = %d", rc));
-                               if (volume_info->nodfs) {
-                                       tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
-                                       cFYI(1, ("DFS disabled (%d)",
-                                               tcon->Flags));
-                               }
-                       }
-                       if (rc)
-                               goto remote_path_check;
-                       tcon->seal = volume_info->seal;
-                       write_lock(&cifs_tcp_ses_lock);
-                       list_add(&tcon->tcon_list, &pSesInfo->tcon_list);
-                       write_unlock(&cifs_tcp_ses_lock);
-               }
-
-               /* we can have only one retry value for a connection
-                  to a share so for resources mounted more than once
-                  to the same server share the last value passed in
-                  for the retry flag is used */
-               tcon->retry = volume_info->retry;
-               tcon->nocase = volume_info->nocase;
-               tcon->local_lease = volume_info->local_lease;
-       }
-       if (pSesInfo) {
-               if (pSesInfo->capabilities & CAP_LARGE_FILES)
-                       sb->s_maxbytes = MAX_LFS_FILESIZE;
-               else
-                       sb->s_maxbytes = MAX_NON_LFS;
-       }
+       setup_cifs_sb(volume_info, cifs_sb);
+       if (pSesInfo->capabilities & CAP_LARGE_FILES)
+               sb->s_maxbytes = MAX_LFS_FILESIZE;
+       else
+               sb->s_maxbytes = MAX_NON_LFS;
 
        /* BB FIXME fix time_gran to be larger for LANMAN sessions */
        sb->s_time_gran = 100;
 
-       if (rc)
+       /* search for existing tcon to this server share */
+       tcon = cifs_get_tcon(pSesInfo, volume_info);
+       if (IS_ERR(tcon)) {
+               rc = PTR_ERR(tcon);
+               tcon = NULL;
                goto remote_path_check;
+       }
 
        cifs_sb->tcon = tcon;
 
@@ -2543,7 +2595,7 @@ try_mount_again:
 
        if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
                cifs_sb->rsize = 1024 * 127;
-               cFYI(DBG2, ("no very large read support, rsize now 127K"));
+               cFYI(DBG2, "no very large read support, rsize now 127K");
        }
        if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
                cifs_sb->wsize = min(cifs_sb->wsize,
@@ -2592,7 +2644,7 @@ remote_path_check:
                        goto mount_fail_check;
                }
 
-               cFYI(1, ("Getting referral for: %s", full_path));
+               cFYI(1, "Getting referral for: %s", full_path);
                rc = get_dfs_path(xid, pSesInfo , full_path + 1,
                        cifs_sb->local_nls, &num_referrals, &referrals,
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -2706,7 +2758,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                   by Samba (not sure whether other servers allow
                   NTLMv2 password here) */
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
-               if ((extended_security & CIFSSEC_MAY_LANMAN) &&
+               if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
                    (ses->server->secType == LANMAN))
                        calc_lanman_hash(tcon->password, ses->server->cryptKey,
                                         ses->server->secMode &
@@ -2777,13 +2829,13 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                if (length == 3) {
                        if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
                            (bcc_ptr[2] == 'C')) {
-                               cFYI(1, ("IPC connection"));
+                               cFYI(1, "IPC connection");
                                tcon->ipc = 1;
                        }
                } else if (length == 2) {
                        if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
                                /* the most common case */
-                               cFYI(1, ("disk share connection"));
+                               cFYI(1, "disk share connection");
                        }
                }
                bcc_ptr += length + 1;
@@ -2796,7 +2848,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                                                      bytes_left, is_unicode,
                                                      nls_codepage);
 
-               cFYI(1, ("nativeFileSystem=%s", tcon->nativeFileSystem));
+               cFYI(1, "nativeFileSystem=%s", tcon->nativeFileSystem);
 
                if ((smb_buffer_response->WordCount == 3) ||
                         (smb_buffer_response->WordCount == 7))
@@ -2804,7 +2856,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                        tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
                else
                        tcon->Flags = 0;
-               cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
+               cFYI(1, "Tcon flags: 0x%x ", tcon->Flags);
        } else if ((rc == 0) && tcon == NULL) {
                /* all we need to save for IPC$ connection */
                ses->ipc_tid = smb_buffer_response->Tid;
@@ -2832,57 +2884,61 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
        return rc;
 }
 
-int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
-                                          struct nls_table *nls_info)
+int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
 {
        int rc = 0;
-       int first_time = 0;
-       struct TCP_Server_Info *server = pSesInfo->server;
-
-       /* what if server changes its buffer size after dropping the session? */
-       if (server->maxBuf == 0) /* no need to send on reconnect */ {
-               rc = CIFSSMBNegotiate(xid, pSesInfo);
-               if (rc == -EAGAIN) {
-                       /* retry only once on 1st time connection */
-                       rc = CIFSSMBNegotiate(xid, pSesInfo);
-                       if (rc == -EAGAIN)
-                               rc = -EHOSTDOWN;
-               }
-               if (rc == 0) {
-                       spin_lock(&GlobalMid_Lock);
-                       if (server->tcpStatus != CifsExiting)
-                               server->tcpStatus = CifsGood;
-                       else
-                               rc = -EHOSTDOWN;
-                       spin_unlock(&GlobalMid_Lock);
+       struct TCP_Server_Info *server = ses->server;
+
+       /* only send once per connect */
+       if (server->maxBuf != 0)
+               return 0;
+
+       rc = CIFSSMBNegotiate(xid, ses);
+       if (rc == -EAGAIN) {
+               /* retry only once on 1st time connection */
+               rc = CIFSSMBNegotiate(xid, ses);
+               if (rc == -EAGAIN)
+                       rc = -EHOSTDOWN;
+       }
+       if (rc == 0) {
+               spin_lock(&GlobalMid_Lock);
+               if (server->tcpStatus != CifsExiting)
+                       server->tcpStatus = CifsGood;
+               else
+                       rc = -EHOSTDOWN;
+               spin_unlock(&GlobalMid_Lock);
 
-               }
-               first_time = 1;
        }
 
-       if (rc)
-               goto ss_err_exit;
+       return rc;
+}
+
+
+int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
+                       struct nls_table *nls_info)
+{
+       int rc = 0;
+       struct TCP_Server_Info *server = ses->server;
 
-       pSesInfo->flags = 0;
-       pSesInfo->capabilities = server->capabilities;
+       ses->flags = 0;
+       ses->capabilities = server->capabilities;
        if (linuxExtEnabled == 0)
-               pSesInfo->capabilities &= (~CAP_UNIX);
+               ses->capabilities &= (~CAP_UNIX);
 
-       cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
-                server->secMode, server->capabilities, server->timeAdj));
+       cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
+                server->secMode, server->capabilities, server->timeAdj);
 
-       rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
+       rc = CIFS_SessSetup(xid, ses, nls_info);
        if (rc) {
-               cERROR(1, ("Send error in SessSetup = %d", rc));
+               cERROR(1, "Send error in SessSetup = %d", rc);
        } else {
-               cFYI(1, ("CIFS Session Established successfully"));
+               cFYI(1, "CIFS Session Established successfully");
                spin_lock(&GlobalMid_Lock);
-               pSesInfo->status = CifsGood;
-               pSesInfo->need_reconnect = false;
+               ses->status = CifsGood;
+               ses->need_reconnect = false;
                spin_unlock(&GlobalMid_Lock);
        }
 
-ss_err_exit:
        return rc;
 }
 
index 6ccf7262d1b7c78267263ca7dd1eb6ce3b3b86e2..391816b461ca1872328cec6e9d3ec3abbd7502e0 100644 (file)
@@ -73,7 +73,7 @@ cifs_bp_rename_retry:
                namelen += (1 + temp->d_name.len);
                temp = temp->d_parent;
                if (temp == NULL) {
-                       cERROR(1, ("corrupt dentry"));
+                       cERROR(1, "corrupt dentry");
                        return NULL;
                }
        }
@@ -90,19 +90,18 @@ cifs_bp_rename_retry:
                        full_path[namelen] = dirsep;
                        strncpy(full_path + namelen + 1, temp->d_name.name,
                                temp->d_name.len);
-                       cFYI(0, ("name: %s", full_path + namelen));
+                       cFYI(0, "name: %s", full_path + namelen);
                }
                temp = temp->d_parent;
                if (temp == NULL) {
-                       cERROR(1, ("corrupt dentry"));
+                       cERROR(1, "corrupt dentry");
                        kfree(full_path);
                        return NULL;
                }
        }
        if (namelen != pplen + dfsplen) {
-               cERROR(1,
-                      ("did not end path lookup where expected namelen is %d",
-                       namelen));
+               cERROR(1, "did not end path lookup where expected namelen is %d",
+                       namelen);
                /* presumably this is only possible if racing with a rename
                of one of the parent directories  (we can not lock the dentries
                above us to prevent this, but retrying should be harmless) */
@@ -130,6 +129,12 @@ cifs_bp_rename_retry:
        return full_path;
 }
 
+/*
+ * When called with struct file pointer set to NULL, there is no way we could
+ * update file->private_data, but getting it stuck on openFileList provides a
+ * way to access it from cifs_fill_filedata and thereby set file->private_data
+ * from cifs_open.
+ */
 struct cifsFileInfo *
 cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
                  struct file *file, struct vfsmount *mnt, unsigned int oflags)
@@ -173,7 +178,7 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
                if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
                        pCifsInode->clientCanCacheAll = true;
                        pCifsInode->clientCanCacheRead = true;
-                       cFYI(1, ("Exclusive Oplock inode %p", newinode));
+                       cFYI(1, "Exclusive Oplock inode %p", newinode);
                } else if ((oplock & 0xF) == OPLOCK_READ)
                                pCifsInode->clientCanCacheRead = true;
        }
@@ -183,16 +188,17 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
 }
 
 int cifs_posix_open(char *full_path, struct inode **pinode,
-                   struct vfsmount *mnt, int mode, int oflags,
-                   __u32 *poplock, __u16 *pnetfid, int xid)
+                       struct vfsmount *mnt, struct super_block *sb,
+                       int mode, int oflags,
+                       __u32 *poplock, __u16 *pnetfid, int xid)
 {
        int rc;
        FILE_UNIX_BASIC_INFO *presp_data;
        __u32 posix_flags = 0;
-       struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb);
+       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
        struct cifs_fattr fattr;
 
-       cFYI(1, ("posix open %s", full_path));
+       cFYI(1, "posix open %s", full_path);
 
        presp_data = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
        if (presp_data == NULL)
@@ -242,7 +248,8 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
 
        /* get new inode and set it up */
        if (*pinode == NULL) {
-               *pinode = cifs_iget(mnt->mnt_sb, &fattr);
+               cifs_fill_uniqueid(sb, &fattr);
+               *pinode = cifs_iget(sb, &fattr);
                if (!*pinode) {
                        rc = -ENOMEM;
                        goto posix_open_ret;
@@ -251,7 +258,18 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
                cifs_fattr_to_inode(*pinode, &fattr);
        }
 
-       cifs_new_fileinfo(*pinode, *pnetfid, NULL, mnt, oflags);
+       /*
+        * cifs_fill_filedata() takes care of setting cifsFileInfo pointer to
+        * file->private_data.
+        */
+       if (mnt) {
+               struct cifsFileInfo *pfile_info;
+
+               pfile_info = cifs_new_fileinfo(*pinode, *pnetfid, NULL, mnt,
+                                              oflags);
+               if (pfile_info == NULL)
+                       rc = -ENOMEM;
+       }
 
 posix_open_ret:
        kfree(presp_data);
@@ -315,13 +333,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
        if (nd && (nd->flags & LOOKUP_OPEN))
                oflags = nd->intent.open.flags;
        else
-               oflags = FMODE_READ;
+               oflags = FMODE_READ | SMB_O_CREAT;
 
        if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
            (CIFS_UNIX_POSIX_PATH_OPS_CAP &
                        le64_to_cpu(tcon->fsUnixInfo.Capability))) {
-               rc = cifs_posix_open(full_path, &newinode, nd->path.mnt,
-                                    mode, oflags, &oplock, &fileHandle, xid);
+               rc = cifs_posix_open(full_path, &newinode,
+                       nd ? nd->path.mnt : NULL,
+                       inode->i_sb, mode, oflags, &oplock, &fileHandle, xid);
                /* EIO could indicate that (posix open) operation is not
                   supported, despite what server claimed in capability
                   negotation.  EREMOTE indicates DFS junction, which is not
@@ -358,7 +377,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                else if ((oflags & O_CREAT) == O_CREAT)
                        disposition = FILE_OPEN_IF;
                else
-                       cFYI(1, ("Create flag not set in create function"));
+                       cFYI(1, "Create flag not set in create function");
        }
 
        /* BB add processing to set equivalent of mode - e.g. via CreateX with
@@ -394,7 +413,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
        }
        if (rc) {
-               cFYI(1, ("cifs_create returned 0x%x", rc));
+               cFYI(1, "cifs_create returned 0x%x", rc);
                goto cifs_create_out;
        }
 
@@ -457,15 +476,22 @@ cifs_create_set_dentry:
        if (rc == 0)
                setup_cifs_dentry(tcon, direntry, newinode);
        else
-               cFYI(1, ("Create worked, get_inode_info failed rc = %d", rc));
+               cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
 
        /* nfsd case - nfs srv does not set nd */
        if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) {
                /* mknod case - do not leave file open */
                CIFSSMBClose(xid, tcon, fileHandle);
        } else if (!(posix_create) && (newinode)) {
-                       cifs_new_fileinfo(newinode, fileHandle, NULL,
-                                               nd->path.mnt, oflags);
+               struct cifsFileInfo *pfile_info;
+               /*
+                * cifs_fill_filedata() takes care of setting cifsFileInfo
+                * pointer to file->private_data.
+                */
+               pfile_info = cifs_new_fileinfo(newinode, fileHandle, NULL,
+                                              nd->path.mnt, oflags);
+               if (pfile_info == NULL)
+                       rc = -ENOMEM;
        }
 cifs_create_out:
        kfree(buf);
@@ -531,7 +557,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
                        u16 fileHandle;
                        FILE_ALL_INFO *buf;
 
-                       cFYI(1, ("sfu compat create special file"));
+                       cFYI(1, "sfu compat create special file");
 
                        buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
                        if (buf == NULL) {
@@ -616,8 +642,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
 
        xid = GetXid();
 
-       cFYI(1, ("parent inode = 0x%p name is: %s and dentry = 0x%p",
-             parent_dir_inode, direntry->d_name.name, direntry));
+       cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
+             parent_dir_inode, direntry->d_name.name, direntry);
 
        /* check whether path exists */
 
@@ -632,7 +658,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
                int i;
                for (i = 0; i < direntry->d_name.len; i++)
                        if (direntry->d_name.name[i] == '\\') {
-                               cFYI(1, ("Invalid file name"));
+                               cFYI(1, "Invalid file name");
                                FreeXid(xid);
                                return ERR_PTR(-EINVAL);
                        }
@@ -657,11 +683,11 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
        }
 
        if (direntry->d_inode != NULL) {
-               cFYI(1, ("non-NULL inode in lookup"));
+               cFYI(1, "non-NULL inode in lookup");
        } else {
-               cFYI(1, ("NULL inode in lookup"));
+               cFYI(1, "NULL inode in lookup");
        }
-       cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode));
+       cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode);
 
        /* Posix open is only called (at lookup time) for file create now.
         * For opens (rather than creates), because we do not know if it
@@ -678,6 +704,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
                     (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
                     (nd->intent.open.flags & O_CREAT)) {
                        rc = cifs_posix_open(full_path, &newInode, nd->path.mnt,
+                                       parent_dir_inode->i_sb,
                                        nd->intent.open.create_mode,
                                        nd->intent.open.flags, &oplock,
                                        &fileHandle, xid);
@@ -723,7 +750,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
        /*      if it was once a directory (but how can we tell?) we could do
                shrink_dcache_parent(direntry); */
        } else if (rc != -EACCES) {
-               cERROR(1, ("Unexpected lookup error %d", rc));
+               cERROR(1, "Unexpected lookup error %d", rc);
                /* We special case check for Access Denied - since that
                is a common return code */
        }
@@ -739,11 +766,11 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
        int isValid = 1;
 
        if (direntry->d_inode) {
-               if (cifs_revalidate(direntry))
+               if (cifs_revalidate_dentry(direntry))
                        return 0;
        } else {
-               cFYI(1, ("neg dentry 0x%p name = %s",
-                        direntry, direntry->d_name.name));
+               cFYI(1, "neg dentry 0x%p name = %s",
+                        direntry, direntry->d_name.name);
                if (time_after(jiffies, direntry->d_time + HZ) ||
                        !lookupCacheEnabled) {
                        d_drop(direntry);
@@ -758,7 +785,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
 {
        int rc = 0;
 
-       cFYI(1, ("In cifs d_delete, name = %s", direntry->d_name.name));
+       cFYI(1, "In cifs d_delete, name = %s", direntry->d_name.name);
 
        return rc;
 }     */
index 87948147d7ece68d64e7218c8331624410ac2196..4db2c5e7283fa27f6c17848cbc5ab7386ace0432 100644 (file)
@@ -23,6 +23,7 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
+#include <linux/slab.h>
 #include <keys/user-type.h>
 #include "dns_resolve.h"
 #include "cifsglob.h"
@@ -105,14 +106,14 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
        /* search for server name delimiter */
        len = strlen(unc);
        if (len < 3) {
-               cFYI(1, ("%s: unc is too short: %s", __func__, unc));
+               cFYI(1, "%s: unc is too short: %s", __func__, unc);
                return -EINVAL;
        }
        len -= 2;
        name = memchr(unc+2, '\\', len);
        if (!name) {
-               cFYI(1, ("%s: probably server name is whole unc: %s",
-                                       __func__, unc));
+               cFYI(1, "%s: probably server name is whole unc: %s",
+                                       __func__, unc);
        } else {
                len = (name - unc) - 2/* leading // */;
        }
@@ -126,8 +127,8 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
        name[len] = 0;
 
        if (is_ip(name)) {
-               cFYI(1, ("%s: it is IP, skipping dns upcall: %s",
-                                       __func__, name));
+               cFYI(1, "%s: it is IP, skipping dns upcall: %s",
+                                       __func__, name);
                data = name;
                goto skip_upcall;
        }
@@ -137,7 +138,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
                len = rkey->type_data.x[0];
                data = rkey->payload.data;
        } else {
-               cERROR(1, ("%s: unable to resolve: %s", __func__, name));
+               cERROR(1, "%s: unable to resolve: %s", __func__, name);
                goto out;
        }
 
@@ -147,10 +148,10 @@ skip_upcall:
                if (*ip_addr) {
                        memcpy(*ip_addr, data, len + 1);
                        if (!IS_ERR(rkey))
-                               cFYI(1, ("%s: resolved: %s to %s", __func__,
+                               cFYI(1, "%s: resolved: %s to %s", __func__,
                                                        name,
                                                        *ip_addr
-                                       ));
+                                       );
                        rc = 0;
                } else {
                        rc = -ENOMEM;
index 6177f7cca16af1e71969ea72173056dcd5e37afd..993f82045bf6f84f94d78ac597ccc7aaa1123a36 100644 (file)
@@ -49,7 +49,7 @@
 static struct dentry *cifs_get_parent(struct dentry *dentry)
 {
        /* BB need to add code here eventually to enable export via NFSD */
-       cFYI(1, ("get parent for %p", dentry));
+       cFYI(1, "get parent for %p", dentry);
        return ERR_PTR(-EACCES);
 }
 
index 3d8f8a96f5a350a96e732cc65f45bc843ab6f08e..a83541ec97131af495e339dfa1e0a482d98dee72 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   vfs operations that deal with files
  *
- *   Copyright (C) International Business Machines  Corp., 2002,2007
+ *   Copyright (C) International Business Machines  Corp., 2002,2010
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *              Jeremy Allison (jra@samba.org)
  *
@@ -31,6 +31,7 @@
 #include <linux/task_io_accounting_ops.h>
 #include <linux/delay.h>
 #include <linux/mount.h>
+#include <linux/slab.h>
 #include <asm/div64.h>
 #include "cifsfs.h"
 #include "cifspdu.h"
@@ -107,8 +108,7 @@ static inline int cifs_get_disposition(unsigned int flags)
 /* all arguments to this function must be checked for validity in caller */
 static inline int
 cifs_posix_open_inode_helper(struct inode *inode, struct file *file,
-                            struct cifsInodeInfo *pCifsInode,
-                            struct cifsFileInfo *pCifsFile, __u32 oplock,
+                            struct cifsInodeInfo *pCifsInode, __u32 oplock,
                             u16 netfid)
 {
 
@@ -135,15 +135,15 @@ cifs_posix_open_inode_helper(struct inode *inode, struct file *file,
        if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) &&
                           (file->f_path.dentry->d_inode->i_size ==
                            (loff_t)le64_to_cpu(buf->EndOfFile))) {
-               cFYI(1, ("inode unchanged on server"));
+               cFYI(1, "inode unchanged on server");
        } else {
                if (file->f_path.dentry->d_inode->i_mapping) {
                        rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping);
                        if (rc != 0)
                                CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc;
                }
-               cFYI(1, ("invalidating remote inode since open detected it "
-                        "changed"));
+               cFYI(1, "invalidating remote inode since open detected it "
+                        "changed");
                invalidate_remote_inode(file->f_path.dentry->d_inode);
        } */
 
@@ -151,8 +151,8 @@ psx_client_can_cache:
        if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
                pCifsInode->clientCanCacheAll = true;
                pCifsInode->clientCanCacheRead = true;
-               cFYI(1, ("Exclusive Oplock granted on inode %p",
-                        file->f_path.dentry->d_inode));
+               cFYI(1, "Exclusive Oplock granted on inode %p",
+                        file->f_path.dentry->d_inode);
        } else if ((oplock & 0xF) == OPLOCK_READ)
                pCifsInode->clientCanCacheRead = true;
 
@@ -189,8 +189,8 @@ cifs_fill_filedata(struct file *file)
        if (file->private_data != NULL) {
                return pCifsFile;
        } else if ((file->f_flags & O_CREAT) && (file->f_flags & O_EXCL))
-                       cERROR(1, ("could not find file instance for "
-                                  "new file %p", file));
+                       cERROR(1, "could not find file instance for "
+                                  "new file %p", file);
        return NULL;
 }
 
@@ -216,17 +216,17 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
        if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) &&
                           (file->f_path.dentry->d_inode->i_size ==
                            (loff_t)le64_to_cpu(buf->EndOfFile))) {
-               cFYI(1, ("inode unchanged on server"));
+               cFYI(1, "inode unchanged on server");
        } else {
                if (file->f_path.dentry->d_inode->i_mapping) {
-               /* BB no need to lock inode until after invalidate
-                  since namei code should already have it locked? */
+                       /* BB no need to lock inode until after invalidate
+                       since namei code should already have it locked? */
                        rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping);
                        if (rc != 0)
                                CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc;
                }
-               cFYI(1, ("invalidating remote inode since open detected it "
-                        "changed"));
+               cFYI(1, "invalidating remote inode since open detected it "
+                        "changed");
                invalidate_remote_inode(file->f_path.dentry->d_inode);
        }
 
@@ -241,8 +241,8 @@ client_can_cache:
        if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) {
                pCifsInode->clientCanCacheAll = true;
                pCifsInode->clientCanCacheRead = true;
-               cFYI(1, ("Exclusive Oplock granted on inode %p",
-                        file->f_path.dentry->d_inode));
+               cFYI(1, "Exclusive Oplock granted on inode %p",
+                        file->f_path.dentry->d_inode);
        } else if ((*oplock & 0xF) == OPLOCK_READ)
                pCifsInode->clientCanCacheRead = true;
 
@@ -284,8 +284,8 @@ int cifs_open(struct inode *inode, struct file *file)
                return rc;
        }
 
-       cFYI(1, ("inode = 0x%p file flags are 0x%x for %s",
-                inode, file->f_flags, full_path));
+       cFYI(1, "inode = 0x%p file flags are 0x%x for %s",
+                inode, file->f_flags, full_path);
 
        if (oplockEnabled)
                oplock = REQ_OPLOCK;
@@ -297,27 +297,29 @@ int cifs_open(struct inode *inode, struct file *file)
            (CIFS_UNIX_POSIX_PATH_OPS_CAP &
                        le64_to_cpu(tcon->fsUnixInfo.Capability))) {
                int oflags = (int) cifs_posix_convert_flags(file->f_flags);
+               oflags |= SMB_O_CREAT;
                /* can not refresh inode info since size could be stale */
                rc = cifs_posix_open(full_path, &inode, file->f_path.mnt,
-                                    cifs_sb->mnt_file_mode /* ignored */,
-                                    oflags, &oplock, &netfid, xid);
+                               inode->i_sb,
+                               cifs_sb->mnt_file_mode /* ignored */,
+                               oflags, &oplock, &netfid, xid);
                if (rc == 0) {
-                       cFYI(1, ("posix open succeeded"));
+                       cFYI(1, "posix open succeeded");
                        /* no need for special case handling of setting mode
                           on read only files needed here */
 
                        pCifsFile = cifs_fill_filedata(file);
                        cifs_posix_open_inode_helper(inode, file, pCifsInode,
-                                                    pCifsFile, oplock, netfid);
+                                                    oplock, netfid);
                        goto out;
                } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
                        if (tcon->ses->serverNOS)
-                               cERROR(1, ("server %s of type %s returned"
+                               cERROR(1, "server %s of type %s returned"
                                           " unexpected error on SMB posix open"
                                           ", disabling posix open support."
                                           " Check if server update available.",
                                           tcon->ses->serverName,
-                                          tcon->ses->serverNOS));
+                                          tcon->ses->serverNOS);
                        tcon->broken_posix_open = true;
                } else if ((rc != -EIO) && (rc != -EREMOTE) &&
                         (rc != -EOPNOTSUPP)) /* path not found or net err */
@@ -385,7 +387,7 @@ int cifs_open(struct inode *inode, struct file *file)
                                & CIFS_MOUNT_MAP_SPECIAL_CHR);
        }
        if (rc) {
-               cFYI(1, ("cifs_open returned 0x%x", rc));
+               cFYI(1, "cifs_open returned 0x%x", rc);
                goto out;
        }
 
@@ -468,7 +470,7 @@ static int cifs_reopen_file(struct file *file, bool can_flush)
        }
 
        if (file->f_path.dentry == NULL) {
-               cERROR(1, ("no valid name if dentry freed"));
+               cERROR(1, "no valid name if dentry freed");
                dump_stack();
                rc = -EBADF;
                goto reopen_error_exit;
@@ -476,7 +478,7 @@ static int cifs_reopen_file(struct file *file, bool can_flush)
 
        inode = file->f_path.dentry->d_inode;
        if (inode == NULL) {
-               cERROR(1, ("inode not valid"));
+               cERROR(1, "inode not valid");
                dump_stack();
                rc = -EBADF;
                goto reopen_error_exit;
@@ -498,8 +500,8 @@ reopen_error_exit:
                return rc;
        }
 
-       cFYI(1, ("inode = 0x%p file flags 0x%x for %s",
-                inode, file->f_flags, full_path));
+       cFYI(1, "inode = 0x%p file flags 0x%x for %s",
+                inode, file->f_flags, full_path);
 
        if (oplockEnabled)
                oplock = REQ_OPLOCK;
@@ -512,10 +514,11 @@ reopen_error_exit:
                int oflags = (int) cifs_posix_convert_flags(file->f_flags);
                /* can not refresh inode info since size could be stale */
                rc = cifs_posix_open(full_path, NULL, file->f_path.mnt,
-                                    cifs_sb->mnt_file_mode /* ignored */,
-                                    oflags, &oplock, &netfid, xid);
+                               inode->i_sb,
+                               cifs_sb->mnt_file_mode /* ignored */,
+                               oflags, &oplock, &netfid, xid);
                if (rc == 0) {
-                       cFYI(1, ("posix reopen succeeded"));
+                       cFYI(1, "posix reopen succeeded");
                        goto reopen_success;
                }
                /* fallthrough to retry open the old way on errors, especially
@@ -536,8 +539,8 @@ reopen_error_exit:
                                CIFS_MOUNT_MAP_SPECIAL_CHR);
        if (rc) {
                mutex_unlock(&pCifsFile->fh_mutex);
-               cFYI(1, ("cifs_open returned 0x%x", rc));
-               cFYI(1, ("oplock: %d", oplock));
+               cFYI(1, "cifs_open returned 0x%x", rc);
+               cFYI(1, "oplock: %d", oplock);
        } else {
 reopen_success:
                pCifsFile->netfid = netfid;
@@ -569,8 +572,8 @@ reopen_success:
                        if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
                                pCifsInode->clientCanCacheAll = true;
                                pCifsInode->clientCanCacheRead = true;
-                               cFYI(1, ("Exclusive Oplock granted on inode %p",
-                                        file->f_path.dentry->d_inode));
+                               cFYI(1, "Exclusive Oplock granted on inode %p",
+                                        file->f_path.dentry->d_inode);
                        } else if ((oplock & 0xF) == OPLOCK_READ) {
                                pCifsInode->clientCanCacheRead = true;
                                pCifsInode->clientCanCacheAll = false;
@@ -618,8 +621,7 @@ int cifs_close(struct inode *inode, struct file *file)
                                        the struct would be in each open file,
                                        but this should give enough time to
                                        clear the socket */
-                                       cFYI(DBG2,
-                                               ("close delay, write pending"));
+                                       cFYI(DBG2, "close delay, write pending");
                                        msleep(timeout);
                                        timeout *= 4;
                                }
@@ -652,7 +654,7 @@ int cifs_close(struct inode *inode, struct file *file)
 
        read_lock(&GlobalSMBSeslock);
        if (list_empty(&(CIFS_I(inode)->openFileList))) {
-               cFYI(1, ("closing last open instance for inode %p", inode));
+               cFYI(1, "closing last open instance for inode %p", inode);
                /* if the file is not open we do not know if we can cache info
                   on this inode, much less write behind and read ahead */
                CIFS_I(inode)->clientCanCacheRead = false;
@@ -673,7 +675,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
            (struct cifsFileInfo *)file->private_data;
        char *ptmp;
 
-       cFYI(1, ("Closedir inode = 0x%p", inode));
+       cFYI(1, "Closedir inode = 0x%p", inode);
 
        xid = GetXid();
 
@@ -684,22 +686,22 @@ int cifs_closedir(struct inode *inode, struct file *file)
 
                pTcon = cifs_sb->tcon;
 
-               cFYI(1, ("Freeing private data in close dir"));
+               cFYI(1, "Freeing private data in close dir");
                write_lock(&GlobalSMBSeslock);
                if (!pCFileStruct->srch_inf.endOfSearch &&
                    !pCFileStruct->invalidHandle) {
                        pCFileStruct->invalidHandle = true;
                        write_unlock(&GlobalSMBSeslock);
                        rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid);
-                       cFYI(1, ("Closing uncompleted readdir with rc %d",
-                                rc));
+                       cFYI(1, "Closing uncompleted readdir with rc %d",
+                                rc);
                        /* not much we can do if it fails anyway, ignore rc */
                        rc = 0;
                } else
                        write_unlock(&GlobalSMBSeslock);
                ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;
                if (ptmp) {
-                       cFYI(1, ("closedir free smb buf in srch struct"));
+                       cFYI(1, "closedir free smb buf in srch struct");
                        pCFileStruct->srch_inf.ntwrk_buf_start = NULL;
                        if (pCFileStruct->srch_inf.smallBuf)
                                cifs_small_buf_release(ptmp);
@@ -747,49 +749,49 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
        rc = -EACCES;
        xid = GetXid();
 
-       cFYI(1, ("Lock parm: 0x%x flockflags: "
+       cFYI(1, "Lock parm: 0x%x flockflags: "
                 "0x%x flocktype: 0x%x start: %lld end: %lld",
                cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start,
-               pfLock->fl_end));
+               pfLock->fl_end);
 
        if (pfLock->fl_flags & FL_POSIX)
-               cFYI(1, ("Posix"));
+               cFYI(1, "Posix");
        if (pfLock->fl_flags & FL_FLOCK)
-               cFYI(1, ("Flock"));
+               cFYI(1, "Flock");
        if (pfLock->fl_flags & FL_SLEEP) {
-               cFYI(1, ("Blocking lock"));
+               cFYI(1, "Blocking lock");
                wait_flag = true;
        }
        if (pfLock->fl_flags & FL_ACCESS)
-               cFYI(1, ("Process suspended by mandatory locking - "
-                        "not implemented yet"));
+               cFYI(1, "Process suspended by mandatory locking - "
+                        "not implemented yet");
        if (pfLock->fl_flags & FL_LEASE)
-               cFYI(1, ("Lease on file - not implemented yet"));
+               cFYI(1, "Lease on file - not implemented yet");
        if (pfLock->fl_flags &
            (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE)))
-               cFYI(1, ("Unknown lock flags 0x%x", pfLock->fl_flags));
+               cFYI(1, "Unknown lock flags 0x%x", pfLock->fl_flags);
 
        if (pfLock->fl_type == F_WRLCK) {
-               cFYI(1, ("F_WRLCK "));
+               cFYI(1, "F_WRLCK ");
                numLock = 1;
        } else if (pfLock->fl_type == F_UNLCK) {
-               cFYI(1, ("F_UNLCK"));
+               cFYI(1, "F_UNLCK");
                numUnlock = 1;
                /* Check if unlock includes more than
                one lock range */
        } else if (pfLock->fl_type == F_RDLCK) {
-               cFYI(1, ("F_RDLCK"));
+               cFYI(1, "F_RDLCK");
                lockType |= LOCKING_ANDX_SHARED_LOCK;
                numLock = 1;
        } else if (pfLock->fl_type == F_EXLCK) {
-               cFYI(1, ("F_EXLCK"));
+               cFYI(1, "F_EXLCK");
                numLock = 1;
        } else if (pfLock->fl_type == F_SHLCK) {
-               cFYI(1, ("F_SHLCK"));
+               cFYI(1, "F_SHLCK");
                lockType |= LOCKING_ANDX_SHARED_LOCK;
                numLock = 1;
        } else
-               cFYI(1, ("Unknown type of lock"));
+               cFYI(1, "Unknown type of lock");
 
        cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
        tcon = cifs_sb->tcon;
@@ -832,14 +834,38 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
                                         0 /* wait flag */ );
                        pfLock->fl_type = F_UNLCK;
                        if (rc != 0)
-                               cERROR(1, ("Error unlocking previously locked "
-                                          "range %d during test of lock", rc));
+                               cERROR(1, "Error unlocking previously locked "
+                                          "range %d during test of lock", rc);
                        rc = 0;
 
                } else {
                        /* if rc == ERR_SHARING_VIOLATION ? */
-                       rc = 0; /* do not change lock type to unlock
-                                  since range in use */
+                       rc = 0;
+
+                       if (lockType & LOCKING_ANDX_SHARED_LOCK) {
+                               pfLock->fl_type = F_WRLCK;
+                       } else {
+                               rc = CIFSSMBLock(xid, tcon, netfid, length,
+                                       pfLock->fl_start, 0, 1,
+                                       lockType | LOCKING_ANDX_SHARED_LOCK,
+                                       0 /* wait flag */);
+                               if (rc == 0) {
+                                       rc = CIFSSMBLock(xid, tcon, netfid,
+                                               length, pfLock->fl_start, 1, 0,
+                                               lockType |
+                                               LOCKING_ANDX_SHARED_LOCK,
+                                               0 /* wait flag */);
+                                       pfLock->fl_type = F_RDLCK;
+                                       if (rc != 0)
+                                               cERROR(1, "Error unlocking "
+                                               "previously locked range %d "
+                                               "during test of lock", rc);
+                                       rc = 0;
+                               } else {
+                                       pfLock->fl_type = F_WRLCK;
+                                       rc = 0;
+                               }
+                       }
                }
 
                FreeXid(xid);
@@ -898,9 +924,10 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
                                                        1, 0, li->type, false);
                                        if (stored_rc)
                                                rc = stored_rc;
-
-                                       list_del(&li->llist);
-                                       kfree(li);
+                                       else {
+                                               list_del(&li->llist);
+                                               kfree(li);
+                                       }
                                }
                        }
                        mutex_unlock(&fid->lock_mutex);
@@ -963,9 +990,8 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
 
        pTcon = cifs_sb->tcon;
 
-       /* cFYI(1,
-          (" write %d bytes to offset %lld of %s", write_size,
-          *poffset, file->f_path.dentry->d_name.name)); */
+       /* cFYI(1, " write %d bytes to offset %lld of %s", write_size,
+          *poffset, file->f_path.dentry->d_name.name); */
 
        if (file->private_data == NULL)
                return -EBADF;
@@ -1066,8 +1092,8 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
 
        pTcon = cifs_sb->tcon;
 
-       cFYI(1, ("write %zd bytes to offset %lld of %s", write_size,
-          *poffset, file->f_path.dentry->d_name.name));
+       cFYI(1, "write %zd bytes to offset %lld of %s", write_size,
+          *poffset, file->f_path.dentry->d_name.name);
 
        if (file->private_data == NULL)
                return -EBADF;
@@ -1208,7 +1234,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
        it being zero) during stress testcases so we need to check for it */
 
        if (cifs_inode == NULL) {
-               cERROR(1, ("Null inode passed to cifs_writeable_file"));
+               cERROR(1, "Null inode passed to cifs_writeable_file");
                dump_stack();
                return NULL;
        }
@@ -1252,7 +1278,7 @@ refind_writable:
                        again. Note that it would be bad
                        to hold up writepages here (rather than
                        in caller) with continuous retries */
-                       cFYI(1, ("wp failed on reopen file"));
+                       cFYI(1, "wp failed on reopen file");
                        read_lock(&GlobalSMBSeslock);
                        /* can not use this handle, no write
                           pending on this one after all */
@@ -1328,7 +1354,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
                else if (bytes_written < 0)
                        rc = bytes_written;
        } else {
-               cFYI(1, ("No writeable filehandles for inode"));
+               cFYI(1, "No writeable filehandles for inode");
                rc = -EIO;
        }
 
@@ -1500,7 +1526,7 @@ retry:
                         */
                        open_file = find_writable_file(CIFS_I(mapping->host));
                        if (!open_file) {
-                               cERROR(1, ("No writable handles for inode"));
+                               cERROR(1, "No writable handles for inode");
                                rc = -EBADF;
                        } else {
                                long_op = cifs_write_timeout(cifsi, offset);
@@ -1513,8 +1539,8 @@ retry:
                                cifs_update_eof(cifsi, offset, bytes_written);
 
                                if (rc || bytes_written < bytes_to_write) {
-                                       cERROR(1, ("Write2 ret %d, wrote %d",
-                                                 rc, bytes_written));
+                                       cERROR(1, "Write2 ret %d, wrote %d",
+                                                 rc, bytes_written);
                                        /* BB what if continued retry is
                                           requested via mount flags? */
                                        if (rc == -ENOSPC)
@@ -1575,7 +1601,7 @@ static int cifs_writepage(struct page *page, struct writeback_control *wbc)
 /* BB add check for wbc flags */
        page_cache_get(page);
        if (!PageUptodate(page))
-               cFYI(1, ("ppw - page not up to date"));
+               cFYI(1, "ppw - page not up to date");
 
        /*
         * Set the "writeback" flag, and clear "dirty" in the radix tree.
@@ -1604,8 +1630,8 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
        int rc;
        struct inode *inode = mapping->host;
 
-       cFYI(1, ("write_end for page %p from pos %lld with %d bytes",
-                page, pos, copied));
+       cFYI(1, "write_end for page %p from pos %lld with %d bytes",
+                page, pos, copied);
 
        if (PageChecked(page)) {
                if (copied == len)
@@ -1661,8 +1687,8 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
 
        xid = GetXid();
 
-       cFYI(1, ("Sync file - name: %s datasync: 0x%x",
-               dentry->d_name.name, datasync));
+       cFYI(1, "Sync file - name: %s datasync: 0x%x",
+               dentry->d_name.name, datasync);
 
        rc = filemap_write_and_wait(inode->i_mapping);
        if (rc == 0) {
@@ -1686,7 +1712,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
        unsigned int rpages = 0;
        int rc = 0;
 
-       cFYI(1, ("sync page %p",page));
+       cFYI(1, "sync page %p", page);
        mapping = page->mapping;
        if (!mapping)
                return 0;
@@ -1697,7 +1723,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
 /*     fill in rpages then
        result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */
 
-/*     cFYI(1, ("rpages is %d for sync page of Index %ld", rpages, index));
+/*     cFYI(1, "rpages is %d for sync page of Index %ld", rpages, index);
 
 #if 0
        if (rc < 0)
@@ -1731,7 +1757,7 @@ int cifs_flush(struct file *file, fl_owner_t id)
                CIFS_I(inode)->write_behind_rc = 0;
        }
 
-       cFYI(1, ("Flush inode %p file %p rc %d", inode, file, rc));
+       cFYI(1, "Flush inode %p file %p rc %d", inode, file, rc);
 
        return rc;
 }
@@ -1763,7 +1789,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
        open_file = (struct cifsFileInfo *)file->private_data;
 
        if ((file->f_flags & O_ACCMODE) == O_WRONLY)
-               cFYI(1, ("attempting read on write only file instance"));
+               cFYI(1, "attempting read on write only file instance");
 
        for (total_read = 0, current_offset = read_data;
             read_size > total_read;
@@ -1844,7 +1870,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
        open_file = (struct cifsFileInfo *)file->private_data;
 
        if ((file->f_flags & O_ACCMODE) == O_WRONLY)
-               cFYI(1, ("attempting read on write only file instance"));
+               cFYI(1, "attempting read on write only file instance");
 
        for (total_read = 0, current_offset = read_data;
             read_size > total_read;
@@ -1890,13 +1916,12 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
 
 int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
 {
-       struct dentry *dentry = file->f_path.dentry;
        int rc, xid;
 
        xid = GetXid();
-       rc = cifs_revalidate(dentry);
+       rc = cifs_revalidate_file(file);
        if (rc) {
-               cFYI(1, ("Validation prior to mmap failed, error=%d", rc));
+               cFYI(1, "Validation prior to mmap failed, error=%d", rc);
                FreeXid(xid);
                return rc;
        }
@@ -1907,8 +1932,7 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
 
 
 static void cifs_copy_cache_pages(struct address_space *mapping,
-       struct list_head *pages, int bytes_read, char *data,
-       struct pagevec *plru_pvec)
+       struct list_head *pages, int bytes_read, char *data)
 {
        struct page *page;
        char *target;
@@ -1920,10 +1944,10 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
                page = list_entry(pages->prev, struct page, lru);
                list_del(&page->lru);
 
-               if (add_to_page_cache(page, mapping, page->index,
+               if (add_to_page_cache_lru(page, mapping, page->index,
                                      GFP_KERNEL)) {
                        page_cache_release(page);
-                       cFYI(1, ("Add page cache failed"));
+                       cFYI(1, "Add page cache failed");
                        data += PAGE_CACHE_SIZE;
                        bytes_read -= PAGE_CACHE_SIZE;
                        continue;
@@ -1946,8 +1970,6 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
                flush_dcache_page(page);
                SetPageUptodate(page);
                unlock_page(page);
-               if (!pagevec_add(plru_pvec, page))
-                       __pagevec_lru_add_file(plru_pvec);
                data += PAGE_CACHE_SIZE;
        }
        return;
@@ -1966,7 +1988,6 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
        unsigned int read_size, i;
        char *smb_read_data = NULL;
        struct smb_com_read_rsp *pSMBr;
-       struct pagevec lru_pvec;
        struct cifsFileInfo *open_file;
        int buf_type = CIFS_NO_BUFFER;
 
@@ -1980,8 +2001,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
        cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
        pTcon = cifs_sb->tcon;
 
-       pagevec_init(&lru_pvec, 0);
-       cFYI(DBG2, ("rpages: num pages %d", num_pages));
+       cFYI(DBG2, "rpages: num pages %d", num_pages);
        for (i = 0; i < num_pages; ) {
                unsigned contig_pages;
                struct page *tmp_page;
@@ -2014,8 +2034,8 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                /* Read size needs to be in multiples of one page */
                read_size = min_t(const unsigned int, read_size,
                                  cifs_sb->rsize & PAGE_CACHE_MASK);
-               cFYI(DBG2, ("rpages: read size 0x%x  contiguous pages %d",
-                               read_size, contig_pages));
+               cFYI(DBG2, "rpages: read size 0x%x  contiguous pages %d",
+                               read_size, contig_pages);
                rc = -EAGAIN;
                while (rc == -EAGAIN) {
                        if ((open_file->invalidHandle) &&
@@ -2042,14 +2062,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                        }
                }
                if ((rc < 0) || (smb_read_data == NULL)) {
-                       cFYI(1, ("Read error in readpages: %d", rc));
+                       cFYI(1, "Read error in readpages: %d", rc);
                        break;
                } else if (bytes_read > 0) {
                        task_io_account_read(bytes_read);
                        pSMBr = (struct smb_com_read_rsp *)smb_read_data;
                        cifs_copy_cache_pages(mapping, page_list, bytes_read,
                                smb_read_data + 4 /* RFC1001 hdr */ +
-                               le16_to_cpu(pSMBr->DataOffset), &lru_pvec);
+                               le16_to_cpu(pSMBr->DataOffset));
 
                        i +=  bytes_read >> PAGE_CACHE_SHIFT;
                        cifs_stats_bytes_read(pTcon, bytes_read);
@@ -2065,9 +2085,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                                /* break; */
                        }
                } else {
-                       cFYI(1, ("No bytes read (%d) at offset %lld . "
-                                "Cleaning remaining pages from readahead list",
-                                bytes_read, offset));
+                       cFYI(1, "No bytes read (%d) at offset %lld . "
+                               "Cleaning remaining pages from readahead list",
+                               bytes_read, offset);
                        /* BB turn off caching and do new lookup on
                           file size at server? */
                        break;
@@ -2082,8 +2102,6 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                bytes_read = 0;
        }
 
-       pagevec_lru_add_file(&lru_pvec);
-
 /* need to free smb_read_data buf before exit */
        if (smb_read_data) {
                if (buf_type == CIFS_SMALL_BUFFER)
@@ -2112,7 +2130,7 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
        if (rc < 0)
                goto io_error;
        else
-               cFYI(1, ("Bytes read %d", rc));
+               cFYI(1, "Bytes read %d", rc);
 
        file->f_path.dentry->d_inode->i_atime =
                current_fs_time(file->f_path.dentry->d_inode->i_sb);
@@ -2144,8 +2162,8 @@ static int cifs_readpage(struct file *file, struct page *page)
                return rc;
        }
 
-       cFYI(1, ("readpage %p at offset %d 0x%x\n",
-                page, (int)offset, (int)offset));
+       cFYI(1, "readpage %p at offset %d 0x%x\n",
+                page, (int)offset, (int)offset);
 
        rc = cifs_readpage_worker(file, page, &offset);
 
@@ -2215,7 +2233,7 @@ static int cifs_write_begin(struct file *file, struct address_space *mapping,
        struct page *page;
        int rc = 0;
 
-       cFYI(1, ("write_begin from %lld len %d", (long long)pos, len));
+       cFYI(1, "write_begin from %lld len %d", (long long)pos, len);
 
        page = grab_cache_page_write_begin(mapping, index, flags);
        if (!page) {
@@ -2287,12 +2305,10 @@ cifs_oplock_break(struct slow_work *work)
        int rc, waitrc = 0;
 
        if (inode && S_ISREG(inode->i_mode)) {
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-               if (cinode->clientCanCacheAll == 0)
+               if (cinode->clientCanCacheRead)
                        break_lease(inode, O_RDONLY);
-               else if (cinode->clientCanCacheRead == 0)
+               else
                        break_lease(inode, O_WRONLY);
-#endif
                rc = filemap_fdatawrite(inode->i_mapping);
                if (cinode->clientCanCacheRead == 0) {
                        waitrc = filemap_fdatawait(inode->i_mapping);
@@ -2302,7 +2318,7 @@ cifs_oplock_break(struct slow_work *work)
                        rc = waitrc;
                if (rc)
                        cinode->write_behind_rc = rc;
-               cFYI(1, ("Oplock flush inode %p rc %d", inode, rc));
+               cFYI(1, "Oplock flush inode %p rc %d", inode, rc);
        }
 
        /*
@@ -2314,7 +2330,7 @@ cifs_oplock_break(struct slow_work *work)
        if (!cfile->closePend && !cfile->oplock_break_cancelled) {
                rc = CIFSSMBLock(0, cifs_sb->tcon, cfile->netfid, 0, 0, 0, 0,
                                 LOCKING_ANDX_OPLOCK_RELEASE, false);
-               cFYI(1, ("Oplock release rc = %d", rc));
+               cFYI(1, "Oplock release rc = %d", rc);
        }
 }
 
index 8bdbc818164cbc87df5455c92b1d61ac2f915c90..62b324f26a565b112b59d6cdd7f688dbf735e715 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/inode.c
  *
- *   Copyright (C) International Business Machines  Corp., 2002,2008
+ *   Copyright (C) International Business Machines  Corp., 2002,2010
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
@@ -20,6 +20,7 @@
  */
 #include <linux/fs.h>
 #include <linux/stat.h>
+#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <asm/div64.h>
 #include "cifsfs.h"
@@ -77,6 +78,41 @@ static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral)
        }
 }
 
+/* check inode attributes against fattr. If they don't match, tag the
+ * inode for cache invalidation
+ */
+static void
+cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
+{
+       struct cifsInodeInfo *cifs_i = CIFS_I(inode);
+
+       cFYI(1, "%s: revalidating inode %llu", __func__, cifs_i->uniqueid);
+
+       if (inode->i_state & I_NEW) {
+               cFYI(1, "%s: inode %llu is new", __func__, cifs_i->uniqueid);
+               return;
+       }
+
+       /* don't bother with revalidation if we have an oplock */
+       if (cifs_i->clientCanCacheRead) {
+               cFYI(1, "%s: inode %llu is oplocked", __func__,
+                        cifs_i->uniqueid);
+               return;
+       }
+
+        /* revalidate if mtime or size have changed */
+       if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) &&
+           cifs_i->server_eof == fattr->cf_eof) {
+               cFYI(1, "%s: inode %llu is unchanged", __func__,
+                        cifs_i->uniqueid);
+               return;
+       }
+
+       cFYI(1, "%s: invalidating inode %llu mapping", __func__,
+                cifs_i->uniqueid);
+       cifs_i->invalid_mapping = true;
+}
+
 /* populate an inode with info from a cifs_fattr struct */
 void
 cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
@@ -85,6 +121,8 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
        unsigned long oldtime = cifs_i->time;
 
+       cifs_revalidate_cache(inode, fattr);
+
        inode->i_atime = fattr->cf_atime;
        inode->i_mtime = fattr->cf_mtime;
        inode->i_ctime = fattr->cf_ctime;
@@ -99,15 +137,14 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
                inode->i_mode = fattr->cf_mode;
 
        cifs_i->cifsAttrs = fattr->cf_cifsattrs;
-       cifs_i->uniqueid = fattr->cf_uniqueid;
 
        if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
                cifs_i->time = 0;
        else
                cifs_i->time = jiffies;
 
-       cFYI(1, ("inode 0x%p old_time=%ld new_time=%ld", inode,
-                oldtime, cifs_i->time));
+       cFYI(1, "inode 0x%p old_time=%ld new_time=%ld", inode,
+                oldtime, cifs_i->time);
 
        cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING;
 
@@ -132,6 +169,17 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
        cifs_set_ops(inode, fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL);
 }
 
+void
+cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr)
+{
+       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
+               return;
+
+       fattr->cf_uniqueid = iunique(sb, ROOT_I);
+}
+
 /* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */
 void
 cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
@@ -189,7 +237,7 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
                /* safest to call it a file if we do not know */
                fattr->cf_mode |= S_IFREG;
                fattr->cf_dtype = DT_REG;
-               cFYI(1, ("unknown type %d", le32_to_cpu(info->Type)));
+               cFYI(1, "unknown type %d", le32_to_cpu(info->Type));
                break;
        }
 
@@ -218,7 +266,7 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
 {
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 
-       cFYI(1, ("creating fake fattr for DFS referral"));
+       cFYI(1, "creating fake fattr for DFS referral");
 
        memset(fattr, 0, sizeof(*fattr));
        fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
@@ -231,6 +279,31 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
        fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
 }
 
+int cifs_get_file_info_unix(struct file *filp)
+{
+       int rc;
+       int xid;
+       FILE_UNIX_BASIC_INFO find_data;
+       struct cifs_fattr fattr;
+       struct inode *inode = filp->f_path.dentry->d_inode;
+       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+       struct cifsTconInfo *tcon = cifs_sb->tcon;
+       struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
+
+       xid = GetXid();
+       rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
+       if (!rc) {
+               cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
+       } else if (rc == -EREMOTE) {
+               cifs_create_dfs_fattr(&fattr, inode->i_sb);
+               rc = 0;
+       }
+
+       cifs_fattr_to_inode(inode, &fattr);
+       FreeXid(xid);
+       return rc;
+}
+
 int cifs_get_inode_info_unix(struct inode **pinode,
                             const unsigned char *full_path,
                             struct super_block *sb, int xid)
@@ -242,7 +315,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 
        tcon = cifs_sb->tcon;
-       cFYI(1, ("Getting info on %s", full_path));
+       cFYI(1, "Getting info on %s", full_path);
 
        /* could have done a find first instead but this returns more info */
        rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
@@ -260,6 +333,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
 
        if (*pinode == NULL) {
                /* get new inode */
+               cifs_fill_uniqueid(sb, &fattr);
                *pinode = cifs_iget(sb, &fattr);
                if (!*pinode)
                        rc = -ENOMEM;
@@ -310,7 +384,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
                                 &bytes_read, &pbuf, &buf_type);
                if ((rc == 0) && (bytes_read >= 8)) {
                        if (memcmp("IntxBLK", pbuf, 8) == 0) {
-                               cFYI(1, ("Block device"));
+                               cFYI(1, "Block device");
                                fattr->cf_mode |= S_IFBLK;
                                fattr->cf_dtype = DT_BLK;
                                if (bytes_read == 24) {
@@ -322,7 +396,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
                                        fattr->cf_rdev = MKDEV(mjr, mnr);
                                }
                        } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
-                               cFYI(1, ("Char device"));
+                               cFYI(1, "Char device");
                                fattr->cf_mode |= S_IFCHR;
                                fattr->cf_dtype = DT_CHR;
                                if (bytes_read == 24) {
@@ -334,7 +408,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
                                        fattr->cf_rdev = MKDEV(mjr, mnr);
                                }
                        } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
-                               cFYI(1, ("Symlink"));
+                               cFYI(1, "Symlink");
                                fattr->cf_mode |= S_IFLNK;
                                fattr->cf_dtype = DT_LNK;
                        } else {
@@ -376,10 +450,10 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
        else if (rc > 3) {
                mode = le32_to_cpu(*((__le32 *)ea_value));
                fattr->cf_mode &= ~SFBITS_MASK;
-               cFYI(1, ("special bits 0%o org mode 0%o", mode,
-                        fattr->cf_mode));
+               cFYI(1, "special bits 0%o org mode 0%o", mode,
+                        fattr->cf_mode);
                fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode;
-               cFYI(1, ("special mode bits 0%o", mode));
+               cFYI(1, "special mode bits 0%o", mode);
        }
 
        return 0;
@@ -432,6 +506,47 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
        fattr->cf_gid = cifs_sb->mnt_gid;
 }
 
+int cifs_get_file_info(struct file *filp)
+{
+       int rc;
+       int xid;
+       FILE_ALL_INFO find_data;
+       struct cifs_fattr fattr;
+       struct inode *inode = filp->f_path.dentry->d_inode;
+       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+       struct cifsTconInfo *tcon = cifs_sb->tcon;
+       struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
+
+       xid = GetXid();
+       rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
+       if (rc == -EOPNOTSUPP || rc == -EINVAL) {
+               /*
+                * FIXME: legacy server -- fall back to path-based call?
+                * for now, just skip revalidating and mark inode for
+                * immediate reval.
+                */
+               rc = 0;
+               CIFS_I(inode)->time = 0;
+               goto cgfi_exit;
+       } else if (rc == -EREMOTE) {
+               cifs_create_dfs_fattr(&fattr, inode->i_sb);
+               rc = 0;
+       } else if (rc)
+               goto cgfi_exit;
+
+       /*
+        * don't bother with SFU junk here -- just mark inode as needing
+        * revalidation.
+        */
+       cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false);
+       fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
+       fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
+       cifs_fattr_to_inode(inode, &fattr);
+cgfi_exit:
+       FreeXid(xid);
+       return rc;
+}
+
 int cifs_get_inode_info(struct inode **pinode,
        const unsigned char *full_path, FILE_ALL_INFO *pfindData,
        struct super_block *sb, int xid, const __u16 *pfid)
@@ -444,11 +559,11 @@ int cifs_get_inode_info(struct inode **pinode,
        struct cifs_fattr fattr;
 
        pTcon = cifs_sb->tcon;
-       cFYI(1, ("Getting info on %s", full_path));
+       cFYI(1, "Getting info on %s", full_path);
 
        if ((pfindData == NULL) && (*pinode != NULL)) {
                if (CIFS_I(*pinode)->clientCanCacheRead) {
-                       cFYI(1, ("No need to revalidate cached inode sizes"));
+                       cFYI(1, "No need to revalidate cached inode sizes");
                        return rc;
                }
        }
@@ -514,7 +629,7 @@ int cifs_get_inode_info(struct inode **pinode,
                                        cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                        if (rc1 || !fattr.cf_uniqueid) {
-                               cFYI(1, ("GetSrvInodeNum rc %d", rc1));
+                               cFYI(1, "GetSrvInodeNum rc %d", rc1);
                                fattr.cf_uniqueid = iunique(sb, ROOT_I);
                                cifs_autodisable_serverino(cifs_sb);
                        }
@@ -530,13 +645,13 @@ int cifs_get_inode_info(struct inode **pinode,
            cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
                tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid);
                if (tmprc)
-                       cFYI(1, ("cifs_sfu_type failed: %d", tmprc));
+                       cFYI(1, "cifs_sfu_type failed: %d", tmprc);
        }
 
 #ifdef CONFIG_CIFS_EXPERIMENTAL
        /* fill in 0777 bits from ACL */
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
-               cFYI(1, ("Getting mode bits from ACL"));
+               cFYI(1, "Getting mode bits from ACL");
                cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, pfid);
        }
 #endif
@@ -611,6 +726,16 @@ cifs_find_inode(struct inode *inode, void *opaque)
        if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
                return 0;
 
+       /*
+        * uh oh -- it's a directory. We can't use it since hardlinked dirs are
+        * verboten. Disable serverino and return it as if it were found, the
+        * caller can discard it, generate a uniqueid and retry the find
+        */
+       if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry)) {
+               fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;
+               cifs_autodisable_serverino(CIFS_SB(inode->i_sb));
+       }
+
        return 1;
 }
 
@@ -630,15 +755,22 @@ cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
        unsigned long hash;
        struct inode *inode;
 
-       cFYI(1, ("looking for uniqueid=%llu", fattr->cf_uniqueid));
+retry_iget5_locked:
+       cFYI(1, "looking for uniqueid=%llu", fattr->cf_uniqueid);
 
        /* hash down to 32-bits on 32-bit arch */
        hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
 
        inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
-
-       /* we have fattrs in hand, update the inode */
        if (inode) {
+               /* was there a problematic inode number collision? */
+               if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) {
+                       iput(inode);
+                       fattr->cf_uniqueid = iunique(sb, ROOT_I);
+                       fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION;
+                       goto retry_iget5_locked;
+               }
+
                cifs_fattr_to_inode(inode, fattr);
                if (sb->s_flags & MS_NOATIME)
                        inode->i_flags |= S_NOATIME | S_NOCMTIME;
@@ -676,7 +808,7 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
                return ERR_PTR(-ENOMEM);
 
        if (rc && cifs_sb->tcon->ipc) {
-               cFYI(1, ("ipc connection - fake read inode"));
+               cFYI(1, "ipc connection - fake read inode");
                inode->i_mode |= S_IFDIR;
                inode->i_nlink = 2;
                inode->i_op = &cifs_ipc_inode_ops;
@@ -738,7 +870,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
         * server times.
         */
        if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
-               cFYI(1, ("CIFS - CTIME changed"));
+               cFYI(1, "CIFS - CTIME changed");
                info_buf.ChangeTime =
                    cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
        } else
@@ -773,8 +905,8 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
                        goto out;
        }
 
-       cFYI(1, ("calling SetFileInfo since SetPathInfo for "
-                "times not supported by this server"));
+       cFYI(1, "calling SetFileInfo since SetPathInfo for "
+                "times not supported by this server");
        rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
                         SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
                         CREATE_NOT_DIR, &netfid, &oplock,
@@ -932,7 +1064,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
        struct iattr *attrs = NULL;
        __u32 dosattr = 0, origattr = 0;
 
-       cFYI(1, ("cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry));
+       cFYI(1, "cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry);
 
        xid = GetXid();
 
@@ -951,7 +1083,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
                rc = CIFSPOSIXDelFile(xid, tcon, full_path,
                        SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
-               cFYI(1, ("posix del rc %d", rc));
+               cFYI(1, "posix del rc %d", rc);
                if ((rc == 0) || (rc == -ENOENT))
                        goto psx_del_no_retry;
        }
@@ -1025,7 +1157,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
        struct inode *newinode = NULL;
        struct cifs_fattr fattr;
 
-       cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
+       cFYI(1, "In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode);
 
        xid = GetXid();
 
@@ -1060,7 +1192,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
                        kfree(pInfo);
                        goto mkdir_retry_old;
                } else if (rc) {
-                       cFYI(1, ("posix mkdir returned 0x%x", rc));
+                       cFYI(1, "posix mkdir returned 0x%x", rc);
                        d_drop(direntry);
                } else {
                        if (pInfo->Type == cpu_to_le32(-1)) {
@@ -1077,6 +1209,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
                                direntry->d_op = &cifs_dentry_ops;
 
                        cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
+                       cifs_fill_uniqueid(inode->i_sb, &fattr);
                        newinode = cifs_iget(inode->i_sb, &fattr);
                        if (!newinode) {
                                kfree(pInfo);
@@ -1086,12 +1219,12 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
                        d_instantiate(direntry, newinode);
 
 #ifdef CONFIG_CIFS_DEBUG2
-                       cFYI(1, ("instantiated dentry %p %s to inode %p",
-                               direntry, direntry->d_name.name, newinode));
+                       cFYI(1, "instantiated dentry %p %s to inode %p",
+                               direntry, direntry->d_name.name, newinode);
 
                        if (newinode->i_nlink != 2)
-                               cFYI(1, ("unexpected number of links %d",
-                                       newinode->i_nlink));
+                               cFYI(1, "unexpected number of links %d",
+                                       newinode->i_nlink);
 #endif
                }
                kfree(pInfo);
@@ -1102,7 +1235,7 @@ mkdir_retry_old:
        rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
                          cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
        if (rc) {
-               cFYI(1, ("cifs_mkdir returned 0x%x", rc));
+               cFYI(1, "cifs_mkdir returned 0x%x", rc);
                d_drop(direntry);
        } else {
 mkdir_get_info:
@@ -1205,7 +1338,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
        char *full_path = NULL;
        struct cifsInodeInfo *cifsInode;
 
-       cFYI(1, ("cifs_rmdir, inode = 0x%p", inode));
+       cFYI(1, "cifs_rmdir, inode = 0x%p", inode);
 
        xid = GetXid();
 
@@ -1389,135 +1522,108 @@ cifs_rename_exit:
        return rc;
 }
 
-int cifs_revalidate(struct dentry *direntry)
+static bool
+cifs_inode_needs_reval(struct inode *inode)
 {
-       int xid;
-       int rc = 0, wbrc = 0;
-       char *full_path;
-       struct cifs_sb_info *cifs_sb;
-       struct cifsInodeInfo *cifsInode;
-       loff_t local_size;
-       struct timespec local_mtime;
-       bool invalidate_inode = false;
+       struct cifsInodeInfo *cifs_i = CIFS_I(inode);
 
-       if (direntry->d_inode == NULL)
-               return -ENOENT;
+       if (cifs_i->clientCanCacheRead)
+               return false;
 
-       cifsInode = CIFS_I(direntry->d_inode);
+       if (!lookupCacheEnabled)
+               return true;
 
-       if (cifsInode == NULL)
-               return -ENOENT;
+       if (cifs_i->time == 0)
+               return true;
 
-       /* no sense revalidating inode info on file that no one can write */
-       if (CIFS_I(direntry->d_inode)->clientCanCacheRead)
-               return rc;
+       /* FIXME: the actimeo should be tunable */
+       if (time_after_eq(jiffies, cifs_i->time + HZ))
+               return true;
+
+       /* hardlinked files w/ noserverino get "special" treatment */
+       if (!(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
+           S_ISREG(inode->i_mode) && inode->i_nlink != 1)
+               return true;
+
+       return false;
+}
+
+/* check invalid_mapping flag and zap the cache if it's set */
+static void
+cifs_invalidate_mapping(struct inode *inode)
+{
+       int rc;
+       struct cifsInodeInfo *cifs_i = CIFS_I(inode);
+
+       cifs_i->invalid_mapping = false;
+
+       /* write back any cached data */
+       if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
+               rc = filemap_write_and_wait(inode->i_mapping);
+               if (rc)
+                       cifs_i->write_behind_rc = rc;
+       }
+       invalidate_remote_inode(inode);
+}
+
+int cifs_revalidate_file(struct file *filp)
+{
+       int rc = 0;
+       struct inode *inode = filp->f_path.dentry->d_inode;
+
+       if (!cifs_inode_needs_reval(inode))
+               goto check_inval;
+
+       if (CIFS_SB(inode->i_sb)->tcon->unix_ext)
+               rc = cifs_get_file_info_unix(filp);
+       else
+               rc = cifs_get_file_info(filp);
+
+check_inval:
+       if (CIFS_I(inode)->invalid_mapping)
+               cifs_invalidate_mapping(inode);
+
+       return rc;
+}
+
+/* revalidate a dentry's inode attributes */
+int cifs_revalidate_dentry(struct dentry *dentry)
+{
+       int xid;
+       int rc = 0;
+       char *full_path = NULL;
+       struct inode *inode = dentry->d_inode;
+       struct super_block *sb = dentry->d_sb;
+
+       if (inode == NULL)
+               return -ENOENT;
 
        xid = GetXid();
 
-       cifs_sb = CIFS_SB(direntry->d_sb);
+       if (!cifs_inode_needs_reval(inode))
+               goto check_inval;
 
        /* can not safely grab the rename sem here if rename calls revalidate
           since that would deadlock */
-       full_path = build_path_from_dentry(direntry);
+       full_path = build_path_from_dentry(dentry);
        if (full_path == NULL) {
                rc = -ENOMEM;
-               FreeXid(xid);
-               return rc;
-       }
-       cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
-                "jiffies %ld", full_path, direntry->d_inode,
-                direntry->d_inode->i_count.counter, direntry,
-                direntry->d_time, jiffies));
-
-       if (cifsInode->time == 0) {
-               /* was set to zero previously to force revalidate */
-       } else if (time_before(jiffies, cifsInode->time + HZ) &&
-                  lookupCacheEnabled) {
-               if ((S_ISREG(direntry->d_inode->i_mode) == 0) ||
-                   (direntry->d_inode->i_nlink == 1)) {
-                       kfree(full_path);
-                       FreeXid(xid);
-                       return rc;
-               } else {
-                       cFYI(1, ("Have to revalidate file due to hardlinks"));
-               }
+               goto check_inval;
        }
 
-       /* save mtime and size */
-       local_mtime = direntry->d_inode->i_mtime;
-       local_size = direntry->d_inode->i_size;
+       cFYI(1, "Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
+                "jiffies %ld", full_path, inode, inode->i_count.counter,
+                dentry, dentry->d_time, jiffies);
 
-       if (cifs_sb->tcon->unix_ext) {
-               rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path,
-                                             direntry->d_sb, xid);
-               if (rc) {
-                       cFYI(1, ("error on getting revalidate info %d", rc));
-/*                     if (rc != -ENOENT)
-                               rc = 0; */      /* BB should we cache info on
-                                                  certain errors? */
-               }
-       } else {
-               rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
-                                        direntry->d_sb, xid, NULL);
-               if (rc) {
-                       cFYI(1, ("error on getting revalidate info %d", rc));
-/*                     if (rc != -ENOENT)
-                               rc = 0; */      /* BB should we cache info on
-                                                  certain errors? */
-               }
-       }
-       /* should we remap certain errors, access denied?, to zero */
-
-       /* if not oplocked, we invalidate inode pages if mtime or file size
-          had changed on server */
-
-       if (timespec_equal(&local_mtime, &direntry->d_inode->i_mtime) &&
-           (local_size == direntry->d_inode->i_size)) {
-               cFYI(1, ("cifs_revalidate - inode unchanged"));
-       } else {
-               /* file may have changed on server */
-               if (cifsInode->clientCanCacheRead) {
-                       /* no need to invalidate inode pages since we were the
-                          only ones who could have modified the file and the
-                          server copy is staler than ours */
-               } else {
-                       invalidate_inode = true;
-               }
-       }
+       if (CIFS_SB(sb)->tcon->unix_ext)
+               rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
+       else
+               rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
+                                        xid, NULL);
 
-       /* can not grab this sem since kernel filesys locking documentation
-          indicates i_mutex may be taken by the kernel on lookup and rename
-          which could deadlock if we grab the i_mutex here as well */
-/*     mutex_lock(&direntry->d_inode->i_mutex);*/
-       /* need to write out dirty pages here  */
-       if (direntry->d_inode->i_mapping) {
-               /* do we need to lock inode until after invalidate completes
-                  below? */
-               wbrc = filemap_fdatawrite(direntry->d_inode->i_mapping);
-               if (wbrc)
-                       CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
-       }
-       if (invalidate_inode) {
-       /* shrink_dcache not necessary now that cifs dentry ops
-       are exported for negative dentries */
-/*             if (S_ISDIR(direntry->d_inode->i_mode))
-                       shrink_dcache_parent(direntry); */
-               if (S_ISREG(direntry->d_inode->i_mode)) {
-                       if (direntry->d_inode->i_mapping) {
-                               wbrc = filemap_fdatawait(direntry->d_inode->i_mapping);
-                               if (wbrc)
-                                       CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
-                       }
-                       /* may eventually have to do this for open files too */
-                       if (list_empty(&(cifsInode->openFileList))) {
-                               /* changed on server - flush read ahead pages */
-                               cFYI(1, ("Invalidating read ahead data on "
-                                        "closed file"));
-                               invalidate_remote_inode(direntry->d_inode);
-                       }
-               }
-       }
-/*     mutex_unlock(&direntry->d_inode->i_mutex); */
+check_inval:
+       if (CIFS_I(inode)->invalid_mapping)
+               cifs_invalidate_mapping(inode);
 
        kfree(full_path);
        FreeXid(xid);
@@ -1527,7 +1633,7 @@ int cifs_revalidate(struct dentry *direntry)
 int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
        struct kstat *stat)
 {
-       int err = cifs_revalidate(dentry);
+       int err = cifs_revalidate_dentry(dentry);
        if (!err) {
                generic_fillattr(dentry->d_inode, stat);
                stat->blksize = CIFS_MAX_MSGSIZE;
@@ -1601,12 +1707,12 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
                rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
                                        npid, false);
                cifsFileInfo_put(open_file);
-               cFYI(1, ("SetFSize for attrs rc = %d", rc));
+               cFYI(1, "SetFSize for attrs rc = %d", rc);
                if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
                        unsigned int bytes_written;
                        rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
                                          &bytes_written, NULL, NULL, 1);
-                       cFYI(1, ("Wrt seteof rc %d", rc));
+                       cFYI(1, "Wrt seteof rc %d", rc);
                }
        } else
                rc = -EINVAL;
@@ -1620,7 +1726,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
                                   false, cifs_sb->local_nls,
                                   cifs_sb->mnt_cifs_flags &
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
-               cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
+               cFYI(1, "SetEOF by path (setattrs) rc = %d", rc);
                if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
                        __u16 netfid;
                        int oplock = 0;
@@ -1637,7 +1743,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
                                                  attrs->ia_size,
                                                  &bytes_written, NULL,
                                                  NULL, 1);
-                               cFYI(1, ("wrt seteof rc %d", rc));
+                               cFYI(1, "wrt seteof rc %d", rc);
                                CIFSSMBClose(xid, pTcon, netfid);
                        }
                }
@@ -1665,8 +1771,8 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
        struct cifs_unix_set_info_args *args = NULL;
        struct cifsFileInfo *open_file;
 
-       cFYI(1, ("setattr_unix on file %s attrs->ia_valid=0x%x",
-                direntry->d_name.name, attrs->ia_valid));
+       cFYI(1, "setattr_unix on file %s attrs->ia_valid=0x%x",
+                direntry->d_name.name, attrs->ia_valid);
 
        xid = GetXid();
 
@@ -1796,8 +1902,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
 
        xid = GetXid();
 
-       cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
-                direntry->d_name.name, attrs->ia_valid));
+       cFYI(1, "setattr on file %s attrs->iavalid 0x%x",
+                direntry->d_name.name, attrs->ia_valid);
 
        if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
                /* check if we have permission to change attrs */
@@ -1854,7 +1960,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
                attrs->ia_valid &= ~ATTR_MODE;
 
        if (attrs->ia_valid & ATTR_MODE) {
-               cFYI(1, ("Mode changed to 0%o", attrs->ia_mode));
+               cFYI(1, "Mode changed to 0%o", attrs->ia_mode);
                mode = attrs->ia_mode;
        }
 
@@ -1940,7 +2046,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 #if 0
 void cifs_delete_inode(struct inode *inode)
 {
-       cFYI(1, ("In cifs_delete_inode, inode = 0x%p", inode));
+       cFYI(1, "In cifs_delete_inode, inode = 0x%p", inode);
        /* may have to add back in if and when safe distributed caching of
           directories added e.g. via FindNotify */
 }
index f94650683a00355d48f6fa545e72baaf6721e95e..505926f1ee6b99d9f3388fb2bb8208dc1f498758 100644 (file)
@@ -47,7 +47,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
 
        xid = GetXid();
 
-       cFYI(1, ("ioctl file %p  cmd %u  arg %lu", filep, command, arg));
+       cFYI(1, "ioctl file %p  cmd %u  arg %lu", filep, command, arg);
 
        cifs_sb = CIFS_SB(inode->i_sb);
 
@@ -64,12 +64,12 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
 
        switch (command) {
                case CIFS_IOC_CHECKUMOUNT:
-                       cFYI(1, ("User unmount attempted"));
+                       cFYI(1, "User unmount attempted");
                        if (cifs_sb->mnt_uid == current_uid())
                                rc = 0;
                        else {
                                rc = -EACCES;
-                               cFYI(1, ("uids do not match"));
+                               cFYI(1, "uids do not match");
                        }
                        break;
 #ifdef CONFIG_CIFS_POSIX
@@ -97,11 +97,11 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
                                /* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid,
                                        extAttrBits, &ExtAttrMask);*/
                        }
-                       cFYI(1, ("set flags not implemented yet"));
+                       cFYI(1, "set flags not implemented yet");
                        break;
 #endif /* CONFIG_CIFS_POSIX */
                default:
-                       cFYI(1, ("unsupported ioctl"));
+                       cFYI(1, "unsupported ioctl");
                        break;
        }
 
index fc1e0487eaee3c5a2b0c4fba34e4c532e930e06b..473ca8033656fc1c8ab14a7a9d78bafd12722217 100644 (file)
@@ -20,6 +20,7 @@
  */
 #include <linux/fs.h>
 #include <linux/stat.h>
+#include <linux/slab.h>
 #include <linux/namei.h>
 #include "cifsfs.h"
 #include "cifspdu.h"
@@ -138,7 +139,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
        if (!full_path)
                goto out;
 
-       cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode));
+       cFYI(1, "Full path: %s inode = 0x%p", full_path, inode);
 
        rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
                                     cifs_sb->local_nls);
@@ -177,8 +178,8 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
                return rc;
        }
 
-       cFYI(1, ("Full path: %s", full_path));
-       cFYI(1, ("symname is %s", symname));
+       cFYI(1, "Full path: %s", full_path);
+       cFYI(1, "symname is %s", symname);
 
        /* BB what if DFS and this volume is on different share? BB */
        if (pTcon->unix_ext)
@@ -197,8 +198,8 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
                                                 inode->i_sb, xid, NULL);
 
                if (rc != 0) {
-                       cFYI(1, ("Create symlink ok, getinodeinfo fail rc = %d",
-                             rc));
+                       cFYI(1, "Create symlink ok, getinodeinfo fail rc = %d",
+                             rc);
                } else {
                        if (pTcon->nocase)
                                direntry->d_op = &cifs_ci_dentry_ops;
index d1474996a8121d4f9eed2811fadb0b68ca0160e5..1394aa37f26c59c057baee608f55ff44ac3401d7 100644 (file)
@@ -51,7 +51,7 @@ _GetXid(void)
        if (GlobalTotalActiveXid > GlobalMaxActiveXid)
                GlobalMaxActiveXid = GlobalTotalActiveXid;
        if (GlobalTotalActiveXid > 65000)
-               cFYI(1, ("warning: more than 65000 requests active"));
+               cFYI(1, "warning: more than 65000 requests active");
        xid = GlobalCurrentXid++;
        spin_unlock(&GlobalMid_Lock);
        return xid;
@@ -88,7 +88,7 @@ void
 sesInfoFree(struct cifsSesInfo *buf_to_free)
 {
        if (buf_to_free == NULL) {
-               cFYI(1, ("Null buffer passed to sesInfoFree"));
+               cFYI(1, "Null buffer passed to sesInfoFree");
                return;
        }
 
@@ -126,7 +126,7 @@ void
 tconInfoFree(struct cifsTconInfo *buf_to_free)
 {
        if (buf_to_free == NULL) {
-               cFYI(1, ("Null buffer passed to tconInfoFree"));
+               cFYI(1, "Null buffer passed to tconInfoFree");
                return;
        }
        atomic_dec(&tconInfoAllocCount);
@@ -166,7 +166,7 @@ void
 cifs_buf_release(void *buf_to_free)
 {
        if (buf_to_free == NULL) {
-               /* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/
+               /* cFYI(1, "Null buffer passed to cifs_buf_release");*/
                return;
        }
        mempool_free(buf_to_free, cifs_req_poolp);
@@ -202,7 +202,7 @@ cifs_small_buf_release(void *buf_to_free)
 {
 
        if (buf_to_free == NULL) {
-               cFYI(1, ("Null buffer passed to cifs_small_buf_release"));
+               cFYI(1, "Null buffer passed to cifs_small_buf_release");
                return;
        }
        mempool_free(buf_to_free, cifs_sm_req_poolp);
@@ -345,19 +345,19 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
                /*      with userid/password pairs found on the smb session   */
                /*      for other target tcp/ip addresses               BB    */
                                if (current_fsuid() != treeCon->ses->linux_uid) {
-                                       cFYI(1, ("Multiuser mode and UID "
-                                                "did not match tcon uid"));
+                                       cFYI(1, "Multiuser mode and UID "
+                                                "did not match tcon uid");
                                        read_lock(&cifs_tcp_ses_lock);
                                        list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
                                                ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list);
                                                if (ses->linux_uid == current_fsuid()) {
                                                        if (ses->server == treeCon->ses->server) {
-                                                               cFYI(1, ("found matching uid substitute right smb_uid"));
+                                                               cFYI(1, "found matching uid substitute right smb_uid");
                                                                buffer->Uid = ses->Suid;
                                                                break;
                                                        } else {
                                /* BB eventually call cifs_setup_session here */
-                                                               cFYI(1, ("local UID found but no smb sess with this server exists"));
+                                                               cFYI(1, "local UID found but no smb sess with this server exists");
                                                        }
                                                }
                                        }
@@ -394,17 +394,16 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid)
                        if (smb->Command == SMB_COM_LOCKING_ANDX)
                                return 0;
                        else
-                               cERROR(1, ("Received Request not response"));
+                               cERROR(1, "Received Request not response");
                }
        } else { /* bad signature or mid */
                if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff))
-                       cERROR(1,
-                              ("Bad protocol string signature header %x",
-                               *(unsigned int *) smb->Protocol));
+                       cERROR(1, "Bad protocol string signature header %x",
+                               *(unsigned int *) smb->Protocol);
                if (mid != smb->Mid)
-                       cERROR(1, ("Mids do not match"));
+                       cERROR(1, "Mids do not match");
        }
-       cERROR(1, ("bad smb detected. The Mid=%d", smb->Mid));
+       cERROR(1, "bad smb detected. The Mid=%d", smb->Mid);
        return 1;
 }
 
@@ -413,7 +412,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
 {
        __u32 len = smb->smb_buf_length;
        __u32 clc_len;  /* calculated length */
-       cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len));
+       cFYI(0, "checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len);
 
        if (length < 2 + sizeof(struct smb_hdr)) {
                if ((length >= sizeof(struct smb_hdr) - 1)
@@ -437,15 +436,15 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
                                tmp[sizeof(struct smb_hdr)+1] = 0;
                                return 0;
                        }
-                       cERROR(1, ("rcvd invalid byte count (bcc)"));
+                       cERROR(1, "rcvd invalid byte count (bcc)");
                } else {
-                       cERROR(1, ("Length less than smb header size"));
+                       cERROR(1, "Length less than smb header size");
                }
                return 1;
        }
        if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
-               cERROR(1, ("smb length greater than MaxBufSize, mid=%d",
-                                  smb->Mid));
+               cERROR(1, "smb length greater than MaxBufSize, mid=%d",
+                                  smb->Mid);
                return 1;
        }
 
@@ -454,8 +453,8 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
        clc_len = smbCalcSize_LE(smb);
 
        if (4 + len != length) {
-               cERROR(1, ("Length read does not match RFC1001 length %d",
-                          len));
+               cERROR(1, "Length read does not match RFC1001 length %d",
+                          len);
                return 1;
        }
 
@@ -466,8 +465,8 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
                        if (((4 + len) & 0xFFFF) == (clc_len & 0xFFFF))
                                return 0; /* bcc wrapped */
                }
-               cFYI(1, ("Calculated size %d vs length %d mismatch for mid %d",
-                               clc_len, 4 + len, smb->Mid));
+               cFYI(1, "Calculated size %d vs length %d mismatch for mid %d",
+                               clc_len, 4 + len, smb->Mid);
                /* Windows XP can return a few bytes too much, presumably
                an illegal pad, at the end of byte range lock responses
                so we allow for that three byte pad, as long as actual
@@ -482,8 +481,8 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
                if ((4+len > clc_len) && (len <= clc_len + 512))
                        return 0;
                else {
-                       cERROR(1, ("RFC1001 size %d bigger than SMB for Mid=%d",
-                                       len, smb->Mid));
+                       cERROR(1, "RFC1001 size %d bigger than SMB for Mid=%d",
+                                       len, smb->Mid);
                        return 1;
                }
        }
@@ -501,7 +500,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
        struct cifsFileInfo *netfile;
        int rc;
 
-       cFYI(1, ("Checking for oplock break or dnotify response"));
+       cFYI(1, "Checking for oplock break or dnotify response");
        if ((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) &&
           (pSMB->hdr.Flags & SMBFLG_RESPONSE)) {
                struct smb_com_transaction_change_notify_rsp *pSMBr =
@@ -513,15 +512,15 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
 
                        pnotify = (struct file_notify_information *)
                                ((char *)&pSMBr->hdr.Protocol + data_offset);
-                       cFYI(1, ("dnotify on %s Action: 0x%x",
-                                pnotify->FileName, pnotify->Action));
+                       cFYI(1, "dnotify on %s Action: 0x%x",
+                                pnotify->FileName, pnotify->Action);
                        /*   cifs_dump_mem("Rcvd notify Data: ",buf,
                                sizeof(struct smb_hdr)+60); */
                        return true;
                }
                if (pSMBr->hdr.Status.CifsError) {
-                       cFYI(1, ("notify err 0x%d",
-                               pSMBr->hdr.Status.CifsError));
+                       cFYI(1, "notify err 0x%d",
+                               pSMBr->hdr.Status.CifsError);
                        return true;
                }
                return false;
@@ -535,7 +534,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
                   large dirty files cached on the client */
                if ((NT_STATUS_INVALID_HANDLE) ==
                   le32_to_cpu(pSMB->hdr.Status.CifsError)) {
-                       cFYI(1, ("invalid handle on oplock break"));
+                       cFYI(1, "invalid handle on oplock break");
                        return true;
                } else if (ERRbadfid ==
                   le16_to_cpu(pSMB->hdr.Status.DosError.Error)) {
@@ -547,8 +546,8 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
        if (pSMB->hdr.WordCount != 8)
                return false;
 
-       cFYI(1, ("oplock type 0x%d level 0x%d",
-                pSMB->LockType, pSMB->OplockLevel));
+       cFYI(1, "oplock type 0x%d level 0x%d",
+                pSMB->LockType, pSMB->OplockLevel);
        if (!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE))
                return false;
 
@@ -579,15 +578,15 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
                                        return true;
                                }
 
-                               cFYI(1, ("file id match, oplock break"));
+                               cFYI(1, "file id match, oplock break");
                                pCifsInode = CIFS_I(netfile->pInode);
                                pCifsInode->clientCanCacheAll = false;
                                if (pSMB->OplockLevel == 0)
                                        pCifsInode->clientCanCacheRead = false;
                                rc = slow_work_enqueue(&netfile->oplock_break);
                                if (rc) {
-                                       cERROR(1, ("failed to enqueue oplock "
-                                                  "break: %d\n", rc));
+                                       cERROR(1, "failed to enqueue oplock "
+                                                  "break: %d\n", rc);
                                } else {
                                        netfile->oplock_break_cancelled = false;
                                }
@@ -597,12 +596,12 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
                        }
                        read_unlock(&GlobalSMBSeslock);
                        read_unlock(&cifs_tcp_ses_lock);
-                       cFYI(1, ("No matching file for oplock break"));
+                       cFYI(1, "No matching file for oplock break");
                        return true;
                }
        }
        read_unlock(&cifs_tcp_ses_lock);
-       cFYI(1, ("Can not process oplock break for non-existent connection"));
+       cFYI(1, "Can not process oplock break for non-existent connection");
        return true;
 }
 
@@ -721,11 +720,11 @@ 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 "
+               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));
+                          cifs_sb->tcon->treeName);
        }
 }
index bd6d6895730d885442f5715e7d4c4e3e693ce333..d35d52889cb54a57e62b99b6e6d6e31e4cb19dd0 100644 (file)
@@ -149,7 +149,7 @@ cifs_inet_pton(const int address_family, const char *cp, void *dst)
        else if (address_family == AF_INET6)
                ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL);
 
-       cFYI(DBG2, ("address conversion returned %d for %s", ret, cp));
+       cFYI(DBG2, "address conversion returned %d for %s", ret, cp);
        if (ret > 0)
                ret = 1;
        return ret;
@@ -870,8 +870,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr)
        }
        /* else ERRHRD class errors or junk  - return EIO */
 
-       cFYI(1, ("Mapping smb error code %d to POSIX err %d",
-                smberrcode, rc));
+       cFYI(1, "Mapping smb error code %d to POSIX err %d",
+                smberrcode, rc);
 
        /* generic corrective action e.g. reconnect SMB session on
         * ERRbaduid could be added */
@@ -940,20 +940,20 @@ struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
        SMB_TIME *st = (SMB_TIME *)&time;
        SMB_DATE *sd = (SMB_DATE *)&date;
 
-       cFYI(1, ("date %d time %d", date, time));
+       cFYI(1, "date %d time %d", date, time);
 
        sec = 2 * st->TwoSeconds;
        min = st->Minutes;
        if ((sec > 59) || (min > 59))
-               cERROR(1, ("illegal time min %d sec %d", min, sec));
+               cERROR(1, "illegal time min %d sec %d", min, sec);
        sec += (min * 60);
        sec += 60 * 60 * st->Hours;
        if (st->Hours > 24)
-               cERROR(1, ("illegal hours %d", st->Hours));
+               cERROR(1, "illegal hours %d", st->Hours);
        days = sd->Day;
        month = sd->Month;
        if ((days > 31) || (month > 12)) {
-               cERROR(1, ("illegal date, month %d day: %d", month, days));
+               cERROR(1, "illegal date, month %d day: %d", month, days);
                if (month > 12)
                        month = 12;
        }
@@ -979,7 +979,7 @@ struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
 
        ts.tv_sec = sec + offset;
 
-       /* cFYI(1,("sec after cnvrt dos to unix time %d",sec)); */
+       /* cFYI(1, "sec after cnvrt dos to unix time %d",sec); */
 
        ts.tv_nsec = 0;
        return ts;
index c343b14ba2d3eea99e7de45c7eed87311668e873..daf1753af674584e2f83f5c1c974da7762097801 100644 (file)
@@ -22,6 +22,7 @@
  */
 #include <linux/fs.h>
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 #include <linux/stat.h>
 #include "cifspdu.h"
 #include "cifsglob.h"
@@ -46,15 +47,15 @@ static void dump_cifs_file_struct(struct file *file, char *label)
        if (file) {
                cf = file->private_data;
                if (cf == NULL) {
-                       cFYI(1, ("empty cifs private file data"));
+                       cFYI(1, "empty cifs private file data");
                        return;
                }
                if (cf->invalidHandle)
-                       cFYI(1, ("invalid handle"));
+                       cFYI(1, "invalid handle");
                if (cf->srch_inf.endOfSearch)
-                       cFYI(1, ("end of search"));
+                       cFYI(1, "end of search");
                if (cf->srch_inf.emptyDir)
-                       cFYI(1, ("empty dir"));
+                       cFYI(1, "empty dir");
        }
 }
 #else
@@ -75,7 +76,7 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
        struct inode *inode;
        struct super_block *sb = parent->d_inode->i_sb;
 
-       cFYI(1, ("For %s", name->name));
+       cFYI(1, "For %s", name->name);
 
        if (parent->d_op && parent->d_op->d_hash)
                parent->d_op->d_hash(parent, name);
@@ -213,7 +214,7 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
                                fid,
                                cifs_sb->local_nls);
                if (CIFSSMBClose(xid, ptcon, fid)) {
-                       cFYI(1, ("Error closing temporary reparsepoint open)"));
+                       cFYI(1, "Error closing temporary reparsepoint open");
                }
        }
 }
@@ -251,7 +252,7 @@ static int initiate_cifs_search(const int xid, struct file *file)
        if (full_path == NULL)
                return -ENOMEM;
 
-       cFYI(1, ("Full path: %s start at: %lld", full_path, file->f_pos));
+       cFYI(1, "Full path: %s start at: %lld", full_path, file->f_pos);
 
 ffirst_retry:
        /* test for Unix extensions */
@@ -296,7 +297,7 @@ static int cifs_unicode_bytelen(char *str)
                if (ustr[len] == 0)
                        return len << 1;
        }
-       cFYI(1, ("Unicode string longer than PATH_MAX found"));
+       cFYI(1, "Unicode string longer than PATH_MAX found");
        return len << 1;
 }
 
@@ -313,19 +314,18 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
                                pfData->FileNameLength;
        } else
                new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset);
-       cFYI(1, ("new entry %p old entry %p", new_entry, old_entry));
+       cFYI(1, "new entry %p old entry %p", new_entry, old_entry);
        /* validate that new_entry is not past end of SMB */
        if (new_entry >= end_of_smb) {
-               cERROR(1,
-                     ("search entry %p began after end of SMB %p old entry %p",
-                       new_entry, end_of_smb, old_entry));
+               cERROR(1, "search entry %p began after end of SMB %p old entry %p",
+                       new_entry, end_of_smb, old_entry);
                return NULL;
        } else if (((level == SMB_FIND_FILE_INFO_STANDARD) &&
                    (new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb))
                  || ((level != SMB_FIND_FILE_INFO_STANDARD) &&
                   (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb)))  {
-               cERROR(1, ("search entry %p extends after end of SMB %p",
-                       new_entry, end_of_smb));
+               cERROR(1, "search entry %p extends after end of SMB %p",
+                       new_entry, end_of_smb);
                return NULL;
        } else
                return new_entry;
@@ -379,8 +379,8 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
                filename = &pFindData->FileName[0];
                len = pFindData->FileNameLength;
        } else {
-               cFYI(1, ("Unknown findfirst level %d",
-                        cfile->srch_inf.info_level));
+               cFYI(1, "Unknown findfirst level %d",
+                        cfile->srch_inf.info_level);
        }
 
        if (filename) {
@@ -480,7 +480,7 @@ static int cifs_save_resume_key(const char *current_entry,
                len = (unsigned int)pFindData->FileNameLength;
                cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
        } else {
-               cFYI(1, ("Unknown findfirst level %d", level));
+               cFYI(1, "Unknown findfirst level %d", level);
                return -EINVAL;
        }
        cifsFile->srch_inf.resume_name_len = len;
@@ -524,7 +524,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
             is_dir_changed(file)) ||
           (index_to_find < first_entry_in_buffer)) {
                /* close and restart search */
-               cFYI(1, ("search backing up - close and restart search"));
+               cFYI(1, "search backing up - close and restart search");
                write_lock(&GlobalSMBSeslock);
                if (!cifsFile->srch_inf.endOfSearch &&
                    !cifsFile->invalidHandle) {
@@ -534,7 +534,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
                } else
                        write_unlock(&GlobalSMBSeslock);
                if (cifsFile->srch_inf.ntwrk_buf_start) {
-                       cFYI(1, ("freeing SMB ff cache buf on search rewind"));
+                       cFYI(1, "freeing SMB ff cache buf on search rewind");
                        if (cifsFile->srch_inf.smallBuf)
                                cifs_small_buf_release(cifsFile->srch_inf.
                                                ntwrk_buf_start);
@@ -545,8 +545,8 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
                }
                rc = initiate_cifs_search(xid, file);
                if (rc) {
-                       cFYI(1, ("error %d reinitiating a search on rewind",
-                                rc));
+                       cFYI(1, "error %d reinitiating a search on rewind",
+                                rc);
                        return rc;
                }
                cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
@@ -554,7 +554,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
 
        while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
              (rc == 0) && !cifsFile->srch_inf.endOfSearch) {
-               cFYI(1, ("calling findnext2"));
+               cFYI(1, "calling findnext2");
                rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
                                  &cifsFile->srch_inf);
                cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
@@ -574,7 +574,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
                first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
                                        - cifsFile->srch_inf.entries_in_buffer;
                pos_in_buf = index_to_find - first_entry_in_buffer;
-               cFYI(1, ("found entry - pos_in_buf %d", pos_in_buf));
+               cFYI(1, "found entry - pos_in_buf %d", pos_in_buf);
 
                for (i = 0; (i < (pos_in_buf)) && (current_entry != NULL); i++) {
                        /* go entry by entry figuring out which is first */
@@ -583,19 +583,19 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
                }
                if ((current_entry == NULL) && (i < pos_in_buf)) {
                        /* BB fixme - check if we should flag this error */
-                       cERROR(1, ("reached end of buf searching for pos in buf"
+                       cERROR(1, "reached end of buf searching for pos in buf"
                          " %d index to find %lld rc %d",
-                         pos_in_buf, index_to_find, rc));
+                         pos_in_buf, index_to_find, rc);
                }
                rc = 0;
                *ppCurrentEntry = current_entry;
        } else {
-               cFYI(1, ("index not in buffer - could not findnext into it"));
+               cFYI(1, "index not in buffer - could not findnext into it");
                return 0;
        }
 
        if (pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) {
-               cFYI(1, ("can not return entries pos_in_buf beyond last"));
+               cFYI(1, "can not return entries pos_in_buf beyond last");
                *num_to_ret = 0;
        } else
                *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf;
@@ -655,12 +655,12 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
                /* one byte length, no name conversion */
                len = (unsigned int)pFindData->FileNameLength;
        } else {
-               cFYI(1, ("Unknown findfirst level %d", level));
+               cFYI(1, "Unknown findfirst level %d", level);
                return -EINVAL;
        }
 
        if (len > max_len) {
-               cERROR(1, ("bad search response length %d past smb end", len));
+               cERROR(1, "bad search response length %d past smb end", len);
                return -EINVAL;
        }
 
@@ -753,7 +753,7 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
         * case already. Why should we be clobbering other errors from it?
         */
        if (rc) {
-               cFYI(1, ("filldir rc = %d", rc));
+               cFYI(1, "filldir rc = %d", rc);
                rc = -EOVERFLOW;
        }
        dput(tmp_dentry);
@@ -785,7 +785,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
        case 0:
                if (filldir(direntry, ".", 1, file->f_pos,
                     file->f_path.dentry->d_inode->i_ino, DT_DIR) < 0) {
-                       cERROR(1, ("Filldir for current dir failed"));
+                       cERROR(1, "Filldir for current dir failed");
                        rc = -ENOMEM;
                        break;
                }
@@ -793,7 +793,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
        case 1:
                if (filldir(direntry, "..", 2, file->f_pos,
                     file->f_path.dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
-                       cERROR(1, ("Filldir for parent dir failed"));
+                       cERROR(1, "Filldir for parent dir failed");
                        rc = -ENOMEM;
                        break;
                }
@@ -806,7 +806,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
 
                if (file->private_data == NULL) {
                        rc = initiate_cifs_search(xid, file);
-                       cFYI(1, ("initiate cifs search rc %d", rc));
+                       cFYI(1, "initiate cifs search rc %d", rc);
                        if (rc) {
                                FreeXid(xid);
                                return rc;
@@ -820,7 +820,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
                cifsFile = file->private_data;
                if (cifsFile->srch_inf.endOfSearch) {
                        if (cifsFile->srch_inf.emptyDir) {
-                               cFYI(1, ("End of search, empty dir"));
+                               cFYI(1, "End of search, empty dir");
                                rc = 0;
                                break;
                        }
@@ -832,16 +832,16 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
                rc = find_cifs_entry(xid, pTcon, file,
                                &current_entry, &num_to_fill);
                if (rc) {
-                       cFYI(1, ("fce error %d", rc));
+                       cFYI(1, "fce error %d", rc);
                        goto rddir2_exit;
                } else if (current_entry != NULL) {
-                       cFYI(1, ("entry %lld found", file->f_pos));
+                       cFYI(1, "entry %lld found", file->f_pos);
                } else {
-                       cFYI(1, ("could not find entry"));
+                       cFYI(1, "could not find entry");
                        goto rddir2_exit;
                }
-               cFYI(1, ("loop through %d times filling dir for net buf %p",
-                       num_to_fill, cifsFile->srch_inf.ntwrk_buf_start));
+               cFYI(1, "loop through %d times filling dir for net buf %p",
+                       num_to_fill, cifsFile->srch_inf.ntwrk_buf_start);
                max_len = smbCalcSize((struct smb_hdr *)
                                cifsFile->srch_inf.ntwrk_buf_start);
                end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
@@ -850,8 +850,8 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
                for (i = 0; (i < num_to_fill) && (rc == 0); i++) {
                        if (current_entry == NULL) {
                                /* evaluate whether this case is an error */
-                               cERROR(1, ("past SMB end,  num to fill %d i %d",
-                                         num_to_fill, i));
+                               cERROR(1, "past SMB end,  num to fill %d i %d",
+                                         num_to_fill, i);
                                break;
                        }
                        /* if buggy server returns . and .. late do
@@ -866,8 +866,8 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
                        file->f_pos++;
                        if (file->f_pos ==
                                cifsFile->srch_inf.index_of_last_entry) {
-                               cFYI(1, ("last entry in buf at pos %lld %s",
-                                       file->f_pos, tmp_buf));
+                               cFYI(1, "last entry in buf at pos %lld %s",
+                                       file->f_pos, tmp_buf);
                                cifs_save_resume_key(current_entry, cifsFile);
                                break;
                        } else
index aaa9c1c5a5bd243e398b96fe6a278c85595c64c9..7707389bdf2c21643e5ad979e44a24ac59057f30 100644 (file)
 #include "ntlmssp.h"
 #include "nterr.h"
 #include <linux/utsname.h>
+#include <linux/slab.h>
 #include "cifs_spnego.h"
 
 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
                         unsigned char *p24);
 
-/* Checks if this is the first smb session to be reconnected after
-   the socket has been reestablished (so we know whether to use vc 0).
-   Called while holding the cifs_tcp_ses_lock, so do not block */
+/*
+ * Checks if this is the first smb session to be reconnected after
+ * the socket has been reestablished (so we know whether to use vc 0).
+ * Called while holding the cifs_tcp_ses_lock, so do not block
+ */
 static bool is_first_ses_reconnect(struct cifsSesInfo *ses)
 {
        struct list_head *tmp;
@@ -283,7 +286,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
        int len;
        char *data = *pbcc_area;
 
-       cFYI(1, ("bleft %d", bleft));
+       cFYI(1, "bleft %d", bleft);
 
        /*
         * Windows servers do not always double null terminate their final
@@ -300,7 +303,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
 
        kfree(ses->serverOS);
        ses->serverOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
-       cFYI(1, ("serverOS=%s", ses->serverOS));
+       cFYI(1, "serverOS=%s", ses->serverOS);
        len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
        data += len;
        bleft -= len;
@@ -309,7 +312,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
 
        kfree(ses->serverNOS);
        ses->serverNOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
-       cFYI(1, ("serverNOS=%s", ses->serverNOS));
+       cFYI(1, "serverNOS=%s", ses->serverNOS);
        len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
        data += len;
        bleft -= len;
@@ -318,7 +321,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
 
        kfree(ses->serverDomain);
        ses->serverDomain = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
-       cFYI(1, ("serverDomain=%s", ses->serverDomain));
+       cFYI(1, "serverDomain=%s", ses->serverDomain);
 
        return;
 }
@@ -331,7 +334,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
        int len;
        char *bcc_ptr = *pbcc_area;
 
-       cFYI(1, ("decode sessetup ascii. bleft %d", bleft));
+       cFYI(1, "decode sessetup ascii. bleft %d", bleft);
 
        len = strnlen(bcc_ptr, bleft);
        if (len >= bleft)
@@ -343,7 +346,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
        if (ses->serverOS)
                strncpy(ses->serverOS, bcc_ptr, len);
        if (strncmp(ses->serverOS, "OS/2", 4) == 0) {
-                       cFYI(1, ("OS/2 server"));
+                       cFYI(1, "OS/2 server");
                        ses->flags |= CIFS_SES_OS2;
        }
 
@@ -372,7 +375,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
        /* BB For newer servers which do not support Unicode,
           but thus do return domain here we could add parsing
           for it later, but it is not very important */
-       cFYI(1, ("ascii: bytes left %d", bleft));
+       cFYI(1, "ascii: bytes left %d", bleft);
 
        return rc;
 }
@@ -383,16 +386,16 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
        CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
 
        if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
-               cERROR(1, ("challenge blob len %d too small", blob_len));
+               cERROR(1, "challenge blob len %d too small", blob_len);
                return -EINVAL;
        }
 
        if (memcmp(pblob->Signature, "NTLMSSP", 8)) {
-               cERROR(1, ("blob signature incorrect %s", pblob->Signature));
+               cERROR(1, "blob signature incorrect %s", pblob->Signature);
                return -EINVAL;
        }
        if (pblob->MessageType != NtLmChallenge) {
-               cERROR(1, ("Incorrect message type %d", pblob->MessageType));
+               cERROR(1, "Incorrect message type %d", pblob->MessageType);
                return -EINVAL;
        }
 
@@ -446,7 +449,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
    This function returns the length of the data in the blob */
 static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
                                   struct cifsSesInfo *ses,
-                                  const struct nls_table *nls_cp, int first)
+                                  const struct nls_table *nls_cp, bool first)
 {
        AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
        __u32 flags;
@@ -545,7 +548,7 @@ static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB,
 
 static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB,
                                  struct cifsSesInfo *ses,
-                                 const struct nls_table *nls, int first_time)
+                                 const struct nls_table *nls, bool first_time)
 {
        int bloblen;
 
@@ -558,8 +561,8 @@ static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB,
 #endif
 
 int
-CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
-               const struct nls_table *nls_cp)
+CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
+              const struct nls_table *nls_cp)
 {
        int rc = 0;
        int wct;
@@ -576,13 +579,18 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
        int bytes_remaining;
        struct key *spnego_key = NULL;
        __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
+       bool first_time;
 
        if (ses == NULL)
                return -EINVAL;
 
+       read_lock(&cifs_tcp_ses_lock);
+       first_time = is_first_ses_reconnect(ses);
+       read_unlock(&cifs_tcp_ses_lock);
+
        type = ses->server->secType;
 
-       cFYI(1, ("sess setup type %d", type));
+       cFYI(1, "sess setup type %d", type);
 ssetup_ntlmssp_authenticate:
        if (phase == NtLmChallenge)
                phase = NtLmAuthenticate; /* if ntlmssp, now final phase */
@@ -663,7 +671,7 @@ ssetup_ntlmssp_authenticate:
                changed to do higher than lanman dialect and
                we reconnected would we ever calc signing_key? */
 
-               cFYI(1, ("Negotiating LANMAN setting up strings"));
+               cFYI(1, "Negotiating LANMAN setting up strings");
                /* Unicode not allowed for LANMAN dialects */
                ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
 #endif
@@ -743,7 +751,7 @@ ssetup_ntlmssp_authenticate:
                        unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
                } else
                        ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
-       } else if (type == Kerberos || type == MSKerberos) {
+       } else if (type == Kerberos) {
 #ifdef CONFIG_CIFS_UPCALL
                struct cifs_spnego_msg *msg;
                spnego_key = cifs_get_spnego_key(ses);
@@ -757,17 +765,17 @@ ssetup_ntlmssp_authenticate:
                /* check version field to make sure that cifs.upcall is
                   sending us a response in an expected form */
                if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
-                       cERROR(1, ("incorrect version of cifs.upcall (expected"
+                       cERROR(1, "incorrect version of cifs.upcall (expected"
                                   " %d but got %d)",
-                                  CIFS_SPNEGO_UPCALL_VERSION, msg->version));
+                                  CIFS_SPNEGO_UPCALL_VERSION, msg->version);
                        rc = -EKEYREJECTED;
                        goto ssetup_exit;
                }
                /* bail out if key is too long */
                if (msg->sesskey_len >
                    sizeof(ses->server->mac_signing_key.data.krb5)) {
-                       cERROR(1, ("Kerberos signing key too long (%u bytes)",
-                               msg->sesskey_len));
+                       cERROR(1, "Kerberos signing key too long (%u bytes)",
+                               msg->sesskey_len);
                        rc = -EOVERFLOW;
                        goto ssetup_exit;
                }
@@ -795,7 +803,7 @@ ssetup_ntlmssp_authenticate:
                /* BB: is this right? */
                        ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
 #else /* ! CONFIG_CIFS_UPCALL */
-               cERROR(1, ("Kerberos negotiated but upcall support disabled!"));
+               cERROR(1, "Kerberos negotiated but upcall support disabled!");
                rc = -ENOSYS;
                goto ssetup_exit;
 #endif /* CONFIG_CIFS_UPCALL */
@@ -803,12 +811,12 @@ ssetup_ntlmssp_authenticate:
 #ifdef CONFIG_CIFS_EXPERIMENTAL
                if (type == RawNTLMSSP) {
                        if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
-                               cERROR(1, ("NTLMSSP requires Unicode support"));
+                               cERROR(1, "NTLMSSP requires Unicode support");
                                rc = -ENOSYS;
                                goto ssetup_exit;
                        }
 
-                       cFYI(1, ("ntlmssp session setup phase %d", phase));
+                       cFYI(1, "ntlmssp session setup phase %d", phase);
                        pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
                        capabilities |= CAP_EXTENDED_SECURITY;
                        pSMB->req.Capabilities |= cpu_to_le32(capabilities);
@@ -826,7 +834,7 @@ ssetup_ntlmssp_authenticate:
                                   on the response (challenge) */
                                smb_buf->Uid = ses->Suid;
                        } else {
-                               cERROR(1, ("invalid phase %d", phase));
+                               cERROR(1, "invalid phase %d", phase);
                                rc = -ENOSYS;
                                goto ssetup_exit;
                        }
@@ -838,12 +846,12 @@ ssetup_ntlmssp_authenticate:
                        }
                        unicode_oslm_strings(&bcc_ptr, nls_cp);
                } else {
-                       cERROR(1, ("secType %d not supported!", type));
+                       cERROR(1, "secType %d not supported!", type);
                        rc = -ENOSYS;
                        goto ssetup_exit;
                }
 #else
-               cERROR(1, ("secType %d not supported!", type));
+               cERROR(1, "secType %d not supported!", type);
                rc = -ENOSYS;
                goto ssetup_exit;
 #endif
@@ -861,7 +869,7 @@ ssetup_ntlmssp_authenticate:
                          CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR);
        /* SMB request buf freed in SendReceive2 */
 
-       cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
+       cFYI(1, "ssetup rc from sendrecv2 is %d", rc);
 
        pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
        smb_buf = (struct smb_hdr *)iov[0].iov_base;
@@ -869,7 +877,7 @@ ssetup_ntlmssp_authenticate:
        if ((type == RawNTLMSSP) && (smb_buf->Status.CifsError ==
                        cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))) {
                if (phase != NtLmNegotiate) {
-                       cERROR(1, ("Unexpected more processing error"));
+                       cERROR(1, "Unexpected more processing error");
                        goto ssetup_exit;
                }
                /* NTLMSSP Negotiate sent now processing challenge (response) */
@@ -881,14 +889,14 @@ ssetup_ntlmssp_authenticate:
 
        if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
                rc = -EIO;
-               cERROR(1, ("bad word count %d", smb_buf->WordCount));
+               cERROR(1, "bad word count %d", smb_buf->WordCount);
                goto ssetup_exit;
        }
        action = le16_to_cpu(pSMB->resp.Action);
        if (action & GUEST_LOGIN)
-               cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
+               cFYI(1, "Guest login"); /* BB mark SesInfo struct? */
        ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
-       cFYI(1, ("UID = %d ", ses->Suid));
+       cFYI(1, "UID = %d ", ses->Suid);
        /* response can have either 3 or 4 word count - Samba sends 3 */
        /* and lanman response is 3 */
        bytes_remaining = BCC(smb_buf);
@@ -898,7 +906,7 @@ ssetup_ntlmssp_authenticate:
                __u16 blob_len;
                blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
                if (blob_len > bytes_remaining) {
-                       cERROR(1, ("bad security blob length %d", blob_len));
+                       cERROR(1, "bad security blob length %d", blob_len);
                        rc = -EINVAL;
                        goto ssetup_exit;
                }
@@ -932,7 +940,7 @@ ssetup_exit:
        }
        kfree(str_area);
        if (resp_buf_type == CIFS_SMALL_BUFFER) {
-               cFYI(1, ("ssetup freeing small buf %p", iov[0].iov_base));
+               cFYI(1, "ssetup freeing small buf %p", iov[0].iov_base);
                cifs_small_buf_release(iov[0].iov_base);
        } else if (resp_buf_type == CIFS_LARGE_BUFFER)
                cifs_buf_release(iov[0].iov_base);
index 93fb09a99c690285f466a1d1734b38dd4ef80f46..192ea51af20f49c8976fa734ca44f79e988d7f6b 100644 (file)
@@ -24,6 +24,7 @@
 */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
index 07b8e71544ee254e8941b03680cc8eaf62a20847..82f78c4d6978ceafdab5789182193b899a435202 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/fs.h>
 #include <linux/list.h>
+#include <linux/gfp.h>
 #include <linux/wait.h>
 #include <linux/net.h>
 #include <linux/delay.h>
@@ -34,7 +35,6 @@
 #include "cifs_debug.h"
 
 extern mempool_t *cifs_mid_poolp;
-extern struct kmem_cache *cifs_oplock_cachep;
 
 static struct mid_q_entry *
 AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
@@ -42,7 +42,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
        struct mid_q_entry *temp;
 
        if (server == NULL) {
-               cERROR(1, ("Null TCP session in AllocMidQEntry"));
+               cERROR(1, "Null TCP session in AllocMidQEntry");
                return NULL;
        }
 
@@ -54,7 +54,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
                temp->mid = smb_buffer->Mid;    /* always LE */
                temp->pid = current->pid;
                temp->command = smb_buffer->Command;
-               cFYI(1, ("For smb_command %d", temp->command));
+               cFYI(1, "For smb_command %d", temp->command);
        /*      do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
                /* when mid allocated can be before when sent */
                temp->when_alloc = jiffies;
@@ -139,7 +139,7 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
                total_len += iov[i].iov_len;
 
        smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
-       cFYI(1, ("Sending smb:  total_len %d", total_len));
+       cFYI(1, "Sending smb:  total_len %d", total_len);
        dump_smb(smb_buffer, len);
 
        i = 0;
@@ -167,9 +167,8 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
                           reconnect which may clear the network problem.
                        */
                        if ((i >= 14) || (!server->noblocksnd && (i > 2))) {
-                               cERROR(1,
-                                  ("sends on sock %p stuck for 15 seconds",
-                                   ssocket));
+                               cERROR(1, "sends on sock %p stuck for 15 seconds",
+                                   ssocket);
                                rc = -EAGAIN;
                                break;
                        }
@@ -183,13 +182,13 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
                        total_len = 0;
                        break;
                } else if (rc > total_len) {
-                       cERROR(1, ("sent %d requested %d", rc, total_len));
+                       cERROR(1, "sent %d requested %d", rc, total_len);
                        break;
                }
                if (rc == 0) {
                        /* should never happen, letting socket clear before
                           retrying is our only obvious option here */
-                       cERROR(1, ("tcp sent no data"));
+                       cERROR(1, "tcp sent no data");
                        msleep(500);
                        continue;
                }
@@ -212,8 +211,8 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
        }
 
        if ((total_len > 0) && (total_len != smb_buf_length + 4)) {
-               cFYI(1, ("partial send (%d remaining), terminating session",
-                       total_len));
+               cFYI(1, "partial send (%d remaining), terminating session",
+                       total_len);
                /* If we have only sent part of an SMB then the next SMB
                   could be taken as the remainder of this one.  We need
                   to kill the socket so the server throws away the partial
@@ -222,7 +221,7 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
        }
 
        if (rc < 0) {
-               cERROR(1, ("Error %d sending data on socket to server", rc));
+               cERROR(1, "Error %d sending data on socket to server", rc);
        } else
                rc = 0;
 
@@ -295,7 +294,7 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
        }
 
        if (ses->server->tcpStatus == CifsNeedReconnect) {
-               cFYI(1, ("tcp session dead - return to caller to retry"));
+               cFYI(1, "tcp session dead - return to caller to retry");
                return -EAGAIN;
        }
 
@@ -347,7 +346,7 @@ static int wait_for_response(struct cifsSesInfo *ses,
                        lrt += time_to_wait;
                        if (time_after(jiffies, lrt)) {
                                /* No replies for time_to_wait. */
-                               cERROR(1, ("server not responding"));
+                               cERROR(1, "server not responding");
                                return -1;
                        }
                } else {
@@ -378,7 +377,7 @@ SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
        iov[0].iov_len = in_buf->smb_buf_length + 4;
        flags |= CIFS_NO_RESP;
        rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
-       cFYI(DBG2, ("SendRcvNoRsp flags %d rc %d", flags, rc));
+       cFYI(DBG2, "SendRcvNoRsp flags %d rc %d", flags, rc);
 
        return rc;
 }
@@ -401,7 +400,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
 
        if ((ses == NULL) || (ses->server == NULL)) {
                cifs_small_buf_release(in_buf);
-               cERROR(1, ("Null session"));
+               cERROR(1, "Null session");
                return -EIO;
        }
 
@@ -470,7 +469,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
        else if (long_op == CIFS_BLOCKING_OP)
                timeout = 0x7FFFFFFF; /*  large, but not so large as to wrap */
        else {
-               cERROR(1, ("unknown timeout flag %d", long_op));
+               cERROR(1, "unknown timeout flag %d", long_op);
                rc = -EIO;
                goto out;
        }
@@ -489,8 +488,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
        spin_lock(&GlobalMid_Lock);
 
        if (midQ->resp_buf == NULL) {
-               cERROR(1, ("No response to cmd %d mid %d",
-                       midQ->command, midQ->mid));
+               cERROR(1, "No response to cmd %d mid %d",
+                       midQ->command, midQ->mid);
                if (midQ->midState == MID_REQUEST_SUBMITTED) {
                        if (ses->server->tcpStatus == CifsExiting)
                                rc = -EHOSTDOWN;
@@ -503,7 +502,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                if (rc != -EHOSTDOWN) {
                        if (midQ->midState == MID_RETRY_NEEDED) {
                                rc = -EAGAIN;
-                               cFYI(1, ("marking request for retry"));
+                               cFYI(1, "marking request for retry");
                        } else {
                                rc = -EIO;
                        }
@@ -520,8 +519,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
        receive_len = midQ->resp_buf->smb_buf_length;
 
        if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
-               cERROR(1, ("Frame too large received.  Length: %d  Xid: %d",
-                       receive_len, xid));
+               cERROR(1, "Frame too large received.  Length: %d  Xid: %d",
+                       receive_len, xid);
                rc = -EIO;
                goto out;
        }
@@ -547,7 +546,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                                                &ses->server->mac_signing_key,
                                                midQ->sequence_number+1);
                        if (rc) {
-                               cERROR(1, ("Unexpected SMB signature"));
+                               cERROR(1, "Unexpected SMB signature");
                                /* BB FIXME add code to kill session */
                        }
                }
@@ -568,7 +567,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                                                   DeleteMidQEntry */
        } else {
                rc = -EIO;
-               cFYI(1, ("Bad MID state?"));
+               cFYI(1, "Bad MID state?");
        }
 
 out:
@@ -590,11 +589,11 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
        struct mid_q_entry *midQ;
 
        if (ses == NULL) {
-               cERROR(1, ("Null smb session"));
+               cERROR(1, "Null smb session");
                return -EIO;
        }
        if (ses->server == NULL) {
-               cERROR(1, ("Null tcp session"));
+               cERROR(1, "Null tcp session");
                return -EIO;
        }
 
@@ -606,8 +605,8 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
           use ses->maxReq */
 
        if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
-               cERROR(1, ("Illegal length, greater than maximum frame, %d",
-                          in_buf->smb_buf_length));
+               cERROR(1, "Illegal length, greater than maximum frame, %d",
+                          in_buf->smb_buf_length);
                return -EIO;
        }
 
@@ -664,7 +663,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
        else if (long_op == CIFS_BLOCKING_OP)
                timeout = 0x7FFFFFFF; /* large but no so large as to wrap */
        else {
-               cERROR(1, ("unknown timeout flag %d", long_op));
+               cERROR(1, "unknown timeout flag %d", long_op);
                rc = -EIO;
                goto out;
        }
@@ -680,8 +679,8 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
 
        spin_lock(&GlobalMid_Lock);
        if (midQ->resp_buf == NULL) {
-               cERROR(1, ("No response for cmd %d mid %d",
-                         midQ->command, midQ->mid));
+               cERROR(1, "No response for cmd %d mid %d",
+                         midQ->command, midQ->mid);
                if (midQ->midState == MID_REQUEST_SUBMITTED) {
                        if (ses->server->tcpStatus == CifsExiting)
                                rc = -EHOSTDOWN;
@@ -694,7 +693,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
                if (rc != -EHOSTDOWN) {
                        if (midQ->midState == MID_RETRY_NEEDED) {
                                rc = -EAGAIN;
-                               cFYI(1, ("marking request for retry"));
+                               cFYI(1, "marking request for retry");
                        } else {
                                rc = -EIO;
                        }
@@ -711,8 +710,8 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
        receive_len = midQ->resp_buf->smb_buf_length;
 
        if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
-               cERROR(1, ("Frame too large received.  Length: %d  Xid: %d",
-                       receive_len, xid));
+               cERROR(1, "Frame too large received.  Length: %d  Xid: %d",
+                       receive_len, xid);
                rc = -EIO;
                goto out;
        }
@@ -735,7 +734,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
                                                &ses->server->mac_signing_key,
                                                midQ->sequence_number+1);
                        if (rc) {
-                               cERROR(1, ("Unexpected SMB signature"));
+                               cERROR(1, "Unexpected SMB signature");
                                /* BB FIXME add code to kill session */
                        }
                }
@@ -752,7 +751,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
                        BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
        } else {
                rc = -EIO;
-               cERROR(1, ("Bad MID state?"));
+               cERROR(1, "Bad MID state?");
        }
 
 out:
@@ -823,13 +822,13 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
        struct cifsSesInfo *ses;
 
        if (tcon == NULL || tcon->ses == NULL) {
-               cERROR(1, ("Null smb session"));
+               cERROR(1, "Null smb session");
                return -EIO;
        }
        ses = tcon->ses;
 
        if (ses->server == NULL) {
-               cERROR(1, ("Null tcp session"));
+               cERROR(1, "Null tcp session");
                return -EIO;
        }
 
@@ -841,8 +840,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
           use ses->maxReq */
 
        if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
-               cERROR(1, ("Illegal length, greater than maximum frame, %d",
-                          in_buf->smb_buf_length));
+               cERROR(1, "Illegal length, greater than maximum frame, %d",
+                          in_buf->smb_buf_length);
                return -EIO;
        }
 
@@ -932,8 +931,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
                spin_unlock(&GlobalMid_Lock);
                receive_len = midQ->resp_buf->smb_buf_length;
        } else {
-               cERROR(1, ("No response for cmd %d mid %d",
-                         midQ->command, midQ->mid));
+               cERROR(1, "No response for cmd %d mid %d",
+                         midQ->command, midQ->mid);
                if (midQ->midState == MID_REQUEST_SUBMITTED) {
                        if (ses->server->tcpStatus == CifsExiting)
                                rc = -EHOSTDOWN;
@@ -946,7 +945,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
                if (rc != -EHOSTDOWN) {
                        if (midQ->midState == MID_RETRY_NEEDED) {
                                rc = -EAGAIN;
-                               cFYI(1, ("marking request for retry"));
+                               cFYI(1, "marking request for retry");
                        } else {
                                rc = -EIO;
                        }
@@ -957,8 +956,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
        }
 
        if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
-               cERROR(1, ("Frame too large received.  Length: %d  Xid: %d",
-                       receive_len, xid));
+               cERROR(1, "Frame too large received.  Length: %d  Xid: %d",
+                       receive_len, xid);
                rc = -EIO;
                goto out;
        }
@@ -967,7 +966,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
 
        if ((out_buf == NULL) || (midQ->midState != MID_RESPONSE_RECEIVED)) {
                rc = -EIO;
-               cERROR(1, ("Bad MID state?"));
+               cERROR(1, "Bad MID state?");
                goto out;
        }
 
@@ -985,7 +984,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
                                           &ses->server->mac_signing_key,
                                           midQ->sequence_number+1);
                if (rc) {
-                       cERROR(1, ("Unexpected SMB signature"));
+                       cERROR(1, "Unexpected SMB signature");
                        /* BB FIXME add code to kill session */
                }
        }
index 3e2ef0de120968e8e8012486f188e2b537590950..a1509207bfa63a92a9e735437d675672139a82d1 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/fs.h>
 #include <linux/posix_acl_xattr.h>
+#include <linux/slab.h>
 #include "cifsfs.h"
 #include "cifspdu.h"
 #include "cifsglob.h"
@@ -69,12 +70,12 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
                return rc;
        }
        if (ea_name == NULL) {
-               cFYI(1, ("Null xattr names not supported"));
+               cFYI(1, "Null xattr names not supported");
        } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5)
                && (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4))) {
                cFYI(1,
-                   ("illegal xattr request %s (only user namespace supported)",
-                       ea_name));
+                    "illegal xattr request %s (only user namespace supported)",
+                    ea_name);
                /* BB what if no namespace prefix? */
                /* Should we just pass them to server, except for
                system and perhaps security prefixes? */
@@ -130,19 +131,19 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
                search server for EAs or streams to
                returns as xattrs */
        if (value_size > MAX_EA_VALUE_SIZE) {
-               cFYI(1, ("size of EA value too large"));
+               cFYI(1, "size of EA value too large");
                kfree(full_path);
                FreeXid(xid);
                return -EOPNOTSUPP;
        }
 
        if (ea_name == NULL) {
-               cFYI(1, ("Null xattr names not supported"));
+               cFYI(1, "Null xattr names not supported");
        } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) {
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
                        goto set_ea_exit;
                if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0)
-                       cFYI(1, ("attempt to set cifs inode metadata"));
+                       cFYI(1, "attempt to set cifs inode metadata");
 
                ea_name += 5; /* skip past user. prefix */
                rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
@@ -168,9 +169,9 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
                                        ACL_TYPE_ACCESS, cifs_sb->local_nls,
                                        cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
-                       cFYI(1, ("set POSIX ACL rc %d", rc));
+                       cFYI(1, "set POSIX ACL rc %d", rc);
 #else
-                       cFYI(1, ("set POSIX ACL not supported"));
+                       cFYI(1, "set POSIX ACL not supported");
 #endif
                } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
                                   strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
@@ -181,13 +182,13 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
                                        ACL_TYPE_DEFAULT, cifs_sb->local_nls,
                                        cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
-                       cFYI(1, ("set POSIX default ACL rc %d", rc));
+                       cFYI(1, "set POSIX default ACL rc %d", rc);
 #else
-                       cFYI(1, ("set default POSIX ACL not supported"));
+                       cFYI(1, "set default POSIX ACL not supported");
 #endif
                } else {
-                       cFYI(1, ("illegal xattr request %s (only user namespace"
-                                " supported)", ea_name));
+                       cFYI(1, "illegal xattr request %s (only user namespace"
+                               " supported)", ea_name);
                  /* BB what if no namespace prefix? */
                  /* Should we just pass them to server, except for
                  system and perhaps security prefixes? */
@@ -234,13 +235,13 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
        /* return dos attributes as pseudo xattr */
        /* return alt name if available as pseudo attr */
        if (ea_name == NULL) {
-               cFYI(1, ("Null xattr names not supported"));
+               cFYI(1, "Null xattr names not supported");
        } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) {
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
                        goto get_ea_exit;
 
                if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) {
-                       cFYI(1, ("attempt to query cifs inode metadata"));
+                       cFYI(1, "attempt to query cifs inode metadata");
                        /* revalidate/getattr then populate from inode */
                } /* BB add else when above is implemented */
                ea_name += 5; /* skip past user. prefix */
@@ -286,7 +287,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                }
 #endif /* EXPERIMENTAL */
 #else
-               cFYI(1, ("query POSIX ACL not supported yet"));
+               cFYI(1, "query POSIX ACL not supported yet");
 #endif /* CONFIG_CIFS_POSIX */
        } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
                          strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
@@ -298,18 +299,18 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                                cifs_sb->mnt_cifs_flags &
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
 #else
-               cFYI(1, ("query POSIX default ACL not supported yet"));
+               cFYI(1, "query POSIX default ACL not supported yet");
 #endif
        } else if (strncmp(ea_name,
                  CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) {
-               cFYI(1, ("Trusted xattr namespace not supported yet"));
+               cFYI(1, "Trusted xattr namespace not supported yet");
        } else if (strncmp(ea_name,
                  CIFS_XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0) {
-               cFYI(1, ("Security xattr namespace not supported yet"));
+               cFYI(1, "Security xattr namespace not supported yet");
        } else
                cFYI(1,
-                   ("illegal xattr request %s (only user namespace supported)",
-                       ea_name));
+                   "illegal xattr request %s (only user namespace supported)",
+                    ea_name);
 
        /* We could add an additional check for streams ie
            if proc/fs/cifs/streamstoxattr is set then
index 4bb9d0a5decc2a7f168a1886a01ef72cec5a5351..ccd98b0f2b0b9c3d37f10b101a86b36572054240 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/time.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/file.h>
 #include <linux/stat.h>
 #include <linux/errno.h>
index ffd42815fda1e6a528030c13712a5c7455e28f21..4c813f2cdc52dcaa7074322ffaeb11d34e4c8726 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/errno.h>
 #include <linux/smp_lock.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 #include <linux/coda.h>
index 830f51abb97138d20d8dc07c8bc9ffb5e325659e..d97f9935a0285ea150f885cb7609b65b4eccc41f 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/smp_lock.h>
 #include <linux/file.h>
 #include <linux/vfs.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -166,6 +167,10 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
                return -EBUSY;
        }
 
+       error = bdi_setup_and_register(&vc->bdi, "coda", BDI_CAP_MAP_COPY);
+       if (error)
+               goto bdi_err;
+
        vc->vc_sb = sb;
 
        sb->s_fs_info = vc;
@@ -174,6 +179,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_blocksize_bits = 12;
        sb->s_magic = CODA_SUPER_MAGIC;
        sb->s_op = &coda_super_operations;
+       sb->s_bdi = &vc->bdi;
 
        /* get root fid from Venus: this needs the root inode */
        error = venus_rootfid(sb, &fid);
@@ -199,6 +205,8 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
         return 0;
 
  error:
+       bdi_destroy(&vc->bdi);
+ bdi_err:
        if (root)
                iput(root);
        if (vc)
@@ -209,6 +217,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
 
 static void coda_put_super(struct super_block *sb)
 {
+       bdi_destroy(&coda_vcp(sb)->bdi);
        coda_vcp(sb)->vc_sb = NULL;
        sb->s_fs_info = NULL;
 
index c274d949179de383ea86f284e13fa5cd396e77db..f09c5ed76f6cdcafd715ee0c759af45290073094 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/stat.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/vmalloc.h>
 #include <linux/vfs.h>
index 030602d453b76a0a371880a63990a08cd17fd5b0..05448730f840be408e6bd7079df8c8ef26b03fd9 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/mm.h>
 #include <linux/eventpoll.h>
 #include <linux/fs_struct.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -1530,8 +1531,6 @@ 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;
index 6d55b61bfa7942252944cabf02d90e9418d2d325..641640dc7ae54e7d55a86d4d149ac1ec54d3f92e 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/ioctl.h>
 #include <linux/if.h>
 #include <linux/if_bridge.h>
-#include <linux/slab.h>
 #include <linux/raid/md_u.h>
 #include <linux/kd.h>
 #include <linux/route.h>
@@ -60,6 +59,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c-dev.h>
 #include <linux/atalk.h>
+#include <linux/gfp.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci.h>
 #include <linux/nbd.h>
 #include <linux/random.h>
 #include <linux/filter.h>
-#include <linux/pktcdvd.h>
 
 #include <linux/hiddev.h>
 
@@ -1126,8 +1125,6 @@ COMPATIBLE_IOCTL(PPGETMODE)
 COMPATIBLE_IOCTL(PPGETPHASE)
 COMPATIBLE_IOCTL(PPGETFLAGS)
 COMPATIBLE_IOCTL(PPSETFLAGS)
-/* pktcdvd */
-COMPATIBLE_IOCTL(PACKET_CTRL_CMD)
 /* Big A */
 /* sparc only */
 /* Big Q for sound/OSS */
index 8e48b52205aac439106638c82546ff351f0ed955..0b502f80c691796afc46cfcfb1e1cfdeaafbba5e 100644 (file)
@@ -645,6 +645,7 @@ static void detach_groups(struct config_group *group)
 
                configfs_detach_group(sd->s_element);
                child->d_inode->i_flags |= S_DEAD;
+               dont_mount(child);
 
                mutex_unlock(&child->d_inode->i_mutex);
 
@@ -840,6 +841,7 @@ static int configfs_attach_item(struct config_item *parent_item,
                        mutex_lock(&dentry->d_inode->i_mutex);
                        configfs_remove_dir(item);
                        dentry->d_inode->i_flags |= S_DEAD;
+                       dont_mount(dentry);
                        mutex_unlock(&dentry->d_inode->i_mutex);
                        d_delete(dentry);
                }
@@ -882,6 +884,7 @@ static int configfs_attach_group(struct config_item *parent_item,
                if (ret) {
                        configfs_detach_item(item);
                        dentry->d_inode->i_flags |= S_DEAD;
+                       dont_mount(dentry);
                }
                configfs_adjust_dir_dirent_depth_after_populate(sd);
                mutex_unlock(&dentry->d_inode->i_mutex);
@@ -1725,6 +1728,7 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
        mutex_unlock(&configfs_symlink_mutex);
        configfs_detach_group(&group->cg_item);
        dentry->d_inode->i_flags |= S_DEAD;
+       dont_mount(dentry);
        mutex_unlock(&dentry->d_inode->i_mutex);
 
        d_delete(dentry);
index a2f746066c5da12fc8dc3623d47c04592141a055..c8af2d91174b42b6ce33f0bfac759910589be268 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/capability.h>
 #include <linux/sched.h>
 #include <linux/lockdep.h>
+#include <linux/slab.h>
 
 #include <linux/configfs.h>
 #include "configfs_internal.h"
index 8421cea7d8c7b1460b0cfdf90e831a3012ddf803..8c8d64230c2d040d1946444eb33c6533288f6019 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/mount.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #include <linux/configfs.h>
 #include "configfs_internal.h"
index 32a5f46b11578d2f0b319379cc8f2b940508a2f4..0f3eb41d9201e6884db26cc8cedf6f3b8328dd25 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/fs.h>
 #include <linux/module.h>
 #include <linux/namei.h>
+#include <linux/slab.h>
 
 #include <linux/configfs.h>
 #include "configfs_internal.h"
index 049d6c36da0992eb0e7bbf1938ff5ff2a8d35156..30a87b3dbcac1286de7fa400f6855b2937796d5b 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/fsnotify.h>
 #include <linux/string.h>
 #include <linux/magic.h>
+#include <linux/slab.h>
 
 static struct vfsmount *debugfs_mount;
 static int debugfs_mount_count;
index 8882ecc0f1bfbec879c7b9c27795ac8b5dd9f63a..0120247b41c0d6661e112fa4e0c34f7eade0a887 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/namei.h>
+#include <linux/slab.h>
 #include <linux/mount.h>
 #include <linux/tty.h>
 #include <linux/mutex.h>
index 0df243850818340c4423fa56ae9264151285c0a1..b54bca03d92f467da2d0e09ef74a341c1cdaa5ce 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/configfs.h>
+#include <linux/slab.h>
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <net/ipv6.h>
index 29d6139c35fcc1b3b51f62082a778ec3c5018038..c6cf251587467dc9af1c12c7391c6e529fa4249a 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/ctype.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 
 #include "dlm_internal.h"
 #include "lock.h"
index 46ffd3eeaaf7350cf1b9b5969722abfe2f9a89b7..17903b491298521839ebfe9c3d6100d225fd6e64 100644 (file)
@@ -56,6 +56,7 @@
    L: receive_xxxx_reply()     <-  R: send_xxxx_reply()
 */
 #include <linux/types.h>
+#include <linux/slab.h>
 #include "dlm_internal.h"
 #include <linux/dlm_device.h>
 #include "memory.h"
index 52cab160893ce0d095e771dd1abe72a4b170162f..c0d35c620526bc0d202dd843867e05b8dbf44c7b 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/file.h>
 #include <linux/mutex.h>
 #include <linux/sctp.h>
+#include <linux/slab.h>
 #include <net/sctp/user.h>
 #include <net/ipv6.h>
 
index 052095cd592f3787ed20f525e1c7c08e0e30378b..2c6ad518100d509d2d0013ff466370a585559986 100644 (file)
@@ -9,6 +9,7 @@
 #include <net/genetlink.h>
 #include <linux/dlm.h>
 #include <linux/dlm_netlink.h>
+#include <linux/gfp.h>
 
 #include "dlm_internal.h"
 
index b5f89aef3b29c88a1447201504a797eb16e93dcb..d45c02db694393a1989119ec510709b653dd76e9 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/poll.h>
 #include <linux/dlm.h>
 #include <linux/dlm_plock.h>
+#include <linux/slab.h>
 
 #include "dlm_internal.h"
 #include "lockspace.h"
index a4bfd31ac45bec4ad5e1010e0ad6a386a338f18b..8b6e73c47435611127ea73ba58d1d8df1fd4ae28 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/spinlock.h>
 #include <linux/dlm.h>
 #include <linux/dlm_device.h>
+#include <linux/slab.h>
 
 #include "dlm_internal.h"
 #include "lockspace.h"
index 7cb0a59f4b9d2e7e6576be83d4787e599f9dd834..1cc087635a5ea4fc1502834152113c582b0cf9fb 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/crypto.h>
 #include <linux/file.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include "ecryptfs_kernel.h"
 
@@ -381,8 +382,8 @@ out:
 static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num,
                                             struct ecryptfs_crypt_stat *crypt_stat)
 {
-       (*offset) = (crypt_stat->num_header_bytes_at_front
-                    + (crypt_stat->extent_size * extent_num));
+       (*offset) = ecryptfs_lower_header_size(crypt_stat)
+                   + (crypt_stat->extent_size * extent_num);
 }
 
 /**
@@ -834,13 +835,13 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat)
        set_extent_mask_and_shift(crypt_stat);
        crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES;
        if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
-               crypt_stat->num_header_bytes_at_front = 0;
+               crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
        else {
                if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)
-                       crypt_stat->num_header_bytes_at_front =
+                       crypt_stat->metadata_size =
                                ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
                else
-                       crypt_stat->num_header_bytes_at_front = PAGE_CACHE_SIZE;
+                       crypt_stat->metadata_size = PAGE_CACHE_SIZE;
        }
 }
 
@@ -1107,9 +1108,9 @@ static void write_ecryptfs_marker(char *page_virt, size_t *written)
        (*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
 }
 
-static void
-write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat,
-                    size_t *written)
+void ecryptfs_write_crypt_stat_flags(char *page_virt,
+                                    struct ecryptfs_crypt_stat *crypt_stat,
+                                    size_t *written)
 {
        u32 flags = 0;
        int i;
@@ -1237,8 +1238,7 @@ ecryptfs_write_header_metadata(char *virt,
 
        header_extent_size = (u32)crypt_stat->extent_size;
        num_header_extents_at_front =
-               (u16)(crypt_stat->num_header_bytes_at_front
-                     / crypt_stat->extent_size);
+               (u16)(crypt_stat->metadata_size / crypt_stat->extent_size);
        put_unaligned_be32(header_extent_size, virt);
        virt += 4;
        put_unaligned_be16(num_header_extents_at_front, virt);
@@ -1291,7 +1291,8 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t max,
        offset = ECRYPTFS_FILE_SIZE_BYTES;
        write_ecryptfs_marker((page_virt + offset), &written);
        offset += written;
-       write_ecryptfs_flags((page_virt + offset), crypt_stat, &written);
+       ecryptfs_write_crypt_stat_flags((page_virt + offset), crypt_stat,
+                                       &written);
        offset += written;
        ecryptfs_write_header_metadata((page_virt + offset), crypt_stat,
                                       &written);
@@ -1381,7 +1382,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
                rc = -EINVAL;
                goto out;
        }
-       virt_len = crypt_stat->num_header_bytes_at_front;
+       virt_len = crypt_stat->metadata_size;
        order = get_order(virt_len);
        /* Released in this function */
        virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order);
@@ -1427,16 +1428,15 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
        header_extent_size = get_unaligned_be32(virt);
        virt += sizeof(__be32);
        num_header_extents_at_front = get_unaligned_be16(virt);
-       crypt_stat->num_header_bytes_at_front =
-               (((size_t)num_header_extents_at_front
-                 * (size_t)header_extent_size));
+       crypt_stat->metadata_size = (((size_t)num_header_extents_at_front
+                                    * (size_t)header_extent_size));
        (*bytes_read) = (sizeof(__be32) + sizeof(__be16));
        if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE)
-           && (crypt_stat->num_header_bytes_at_front
+           && (crypt_stat->metadata_size
                < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) {
                rc = -EINVAL;
                printk(KERN_WARNING "Invalid header size: [%zd]\n",
-                      crypt_stat->num_header_bytes_at_front);
+                      crypt_stat->metadata_size);
        }
        return rc;
 }
@@ -1451,8 +1451,7 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
  */
 static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
 {
-       crypt_stat->num_header_bytes_at_front =
-               ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
+       crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
 }
 
 /**
@@ -1606,6 +1605,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
                                                ecryptfs_dentry,
                                                ECRYPTFS_VALIDATE_HEADER_SIZE);
        if (rc) {
+               memset(page_virt, 0, PAGE_CACHE_SIZE);
                rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode);
                if (rc) {
                        printk(KERN_DEBUG "Valid eCryptfs headers not found in "
index 8f006a0d6076f3dbe61ce9d2dd956e7b853d0132..906e803f7f79fd5e7e8bc542f5b4be2e91064d67 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/namei.h>
 #include <linux/mount.h>
 #include <linux/fs_stack.h>
+#include <linux/slab.h>
 #include "ecryptfs_kernel.h"
 
 /**
index 542f625312f30a424023e07b7146af58e9b57144..bfc2e0f78f0019a7cac763c19336bdf287559d15 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/scatterlist.h>
 #include <linux/hash.h>
 #include <linux/nsproxy.h>
+#include <linux/backing-dev.h>
 
 /* Version verification for shared data structures w/ userspace */
 #define ECRYPTFS_VERSION_MAJOR 0x00
@@ -273,7 +274,7 @@ struct ecryptfs_crypt_stat {
        u32 flags;
        unsigned int file_version;
        size_t iv_bytes;
-       size_t num_header_bytes_at_front;
+       size_t metadata_size;
        size_t extent_size; /* Data extent size; default is 4096 */
        size_t key_size;
        size_t extent_shift;
@@ -393,6 +394,7 @@ struct ecryptfs_mount_crypt_stat {
 struct ecryptfs_sb_info {
        struct super_block *wsi_sb;
        struct ecryptfs_mount_crypt_stat mount_crypt_stat;
+       struct backing_dev_info bdi;
 };
 
 /* file private data. */
@@ -464,6 +466,14 @@ struct ecryptfs_daemon {
 
 extern struct mutex ecryptfs_daemon_hash_mux;
 
+static inline size_t
+ecryptfs_lower_header_size(struct ecryptfs_crypt_stat *crypt_stat)
+{
+       if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
+               return 0;
+       return crypt_stat->metadata_size;
+}
+
 static inline struct ecryptfs_file_info *
 ecryptfs_file_to_private(struct file *file)
 {
@@ -651,6 +661,9 @@ int ecryptfs_decrypt_page(struct page *page);
 int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry);
 int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry);
 int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry);
+void ecryptfs_write_crypt_stat_flags(char *page_virt,
+                                    struct ecryptfs_crypt_stat *crypt_stat,
+                                    size_t *written);
 int ecryptfs_read_and_validate_header_region(char *data,
                                             struct inode *ecryptfs_inode);
 int ecryptfs_read_and_validate_xattr_region(char *page_virt,
index 678172b61be2a676de90fa8d7e5101e04f566ed4..e7440a6f5ebf0cffb9e9bee7a770b80553e72b15 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/file.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/mount.h>
 #include <linux/pagemap.h>
 #include <linux/security.h>
index 4a430ab4115c056851a9a98788417a44751e6205..e2d4418affac91df98e3e70c01f577c4c10e57cf 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/mount.h>
 #include <linux/crypto.h>
 #include <linux/fs_stack.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include "ecryptfs_kernel.h"
 
@@ -323,6 +324,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
        rc = ecryptfs_read_and_validate_header_region(page_virt,
                                                      ecryptfs_dentry->d_inode);
        if (rc) {
+               memset(page_virt, 0, PAGE_CACHE_SIZE);
                rc = ecryptfs_read_and_validate_xattr_region(page_virt,
                                                             ecryptfs_dentry);
                if (rc) {
@@ -335,7 +337,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
                ecryptfs_dentry->d_sb)->mount_crypt_stat;
        if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
                if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
-                       file_size = (crypt_stat->num_header_bytes_at_front
+                       file_size = (crypt_stat->metadata_size
                                     + i_size_read(lower_dentry->d_inode));
                else
                        file_size = i_size_read(lower_dentry->d_inode);
@@ -387,9 +389,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
        mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
        if (IS_ERR(lower_dentry)) {
                rc = PTR_ERR(lower_dentry);
-               printk(KERN_ERR "%s: lookup_one_len() returned [%d] on "
-                      "lower_dentry = [%s]\n", __func__, rc,
-                      ecryptfs_dentry->d_name.name);
+               ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
+                               "[%d] on lower_dentry = [%s]\n", __func__, rc,
+                               encrypted_and_encoded_name);
                goto out_d_drop;
        }
        if (lower_dentry->d_inode)
@@ -416,9 +418,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
        mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
        if (IS_ERR(lower_dentry)) {
                rc = PTR_ERR(lower_dentry);
-               printk(KERN_ERR "%s: lookup_one_len() returned [%d] on "
-                      "lower_dentry = [%s]\n", __func__, rc,
-                      encrypted_and_encoded_name);
+               ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
+                               "[%d] on lower_dentry = [%s]\n", __func__, rc,
+                               encrypted_and_encoded_name);
                goto out_d_drop;
        }
 lookup_and_interpose:
@@ -455,8 +457,8 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
        rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
        if (rc)
                goto out_lock;
-       fsstack_copy_attr_times(dir, lower_new_dentry->d_inode);
-       fsstack_copy_inode_size(dir, lower_new_dentry->d_inode);
+       fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
+       fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode);
        old_dentry->d_inode->i_nlink =
                ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink;
        i_size_write(new_dentry->d_inode, file_size_save);
@@ -647,38 +649,17 @@ out_lock:
        return rc;
 }
 
-static int
-ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
+static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf,
+                                  size_t *bufsiz)
 {
+       struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
        char *lower_buf;
-       size_t lower_bufsiz;
-       struct dentry *lower_dentry;
-       struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
-       char *plaintext_name;
-       size_t plaintext_name_size;
+       size_t lower_bufsiz = PATH_MAX;
        mm_segment_t old_fs;
        int rc;
 
-       lower_dentry = ecryptfs_dentry_to_lower(dentry);
-       if (!lower_dentry->d_inode->i_op->readlink) {
-               rc = -EINVAL;
-               goto out;
-       }
-       mount_crypt_stat = &ecryptfs_superblock_to_private(
-                                               dentry->d_sb)->mount_crypt_stat;
-       /*
-        * If the lower filename is encrypted, it will result in a significantly
-        * longer name.  If needed, truncate the name after decode and decrypt.
-        */
-       if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)
-               lower_bufsiz = PATH_MAX;
-       else
-               lower_bufsiz = bufsiz;
-       /* Released in this function */
        lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL);
-       if (lower_buf == NULL) {
-               printk(KERN_ERR "%s: Out of memory whilst attempting to "
-                      "kmalloc [%zd] bytes\n", __func__, lower_bufsiz);
+       if (!lower_buf) {
                rc = -ENOMEM;
                goto out;
        }
@@ -688,29 +669,31 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
                                                   (char __user *)lower_buf,
                                                   lower_bufsiz);
        set_fs(old_fs);
-       if (rc >= 0) {
-               rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name,
-                                                         &plaintext_name_size,
-                                                         dentry, lower_buf,
-                                                         rc);
-               if (rc) {
-                       printk(KERN_ERR "%s: Error attempting to decode and "
-                              "decrypt filename; rc = [%d]\n", __func__,
-                               rc);
-                       goto out_free_lower_buf;
-               }
-               /* Check for bufsiz <= 0 done in sys_readlinkat() */
-               rc = copy_to_user(buf, plaintext_name,
-                                 min((size_t) bufsiz, plaintext_name_size));
-               if (rc)
-                       rc = -EFAULT;
-               else
-                       rc = plaintext_name_size;
-               kfree(plaintext_name);
-               fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode);
-       }
-out_free_lower_buf:
+       if (rc < 0)
+               goto out;
+       lower_bufsiz = rc;
+       rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry,
+                                                 lower_buf, lower_bufsiz);
+out:
        kfree(lower_buf);
+       return rc;
+}
+
+static int
+ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
+{
+       char *kbuf;
+       size_t kbufsiz, copied;
+       int rc;
+
+       rc = ecryptfs_readlink_lower(dentry, &kbuf, &kbufsiz);
+       if (rc)
+               goto out;
+       copied = min_t(size_t, bufsiz, kbufsiz);
+       rc = copy_to_user(buf, kbuf, copied) ? -EFAULT : copied;
+       kfree(kbuf);
+       fsstack_copy_attr_atime(dentry->d_inode,
+                               ecryptfs_dentry_to_lower(dentry)->d_inode);
 out:
        return rc;
 }
@@ -768,7 +751,7 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat,
 {
        loff_t lower_size;
 
-       lower_size = crypt_stat->num_header_bytes_at_front;
+       lower_size = ecryptfs_lower_header_size(crypt_stat);
        if (upper_size != 0) {
                loff_t num_extents;
 
@@ -1015,6 +998,28 @@ out:
        return rc;
 }
 
+int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry,
+                         struct kstat *stat)
+{
+       struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
+       int rc = 0;
+
+       mount_crypt_stat = &ecryptfs_superblock_to_private(
+                                               dentry->d_sb)->mount_crypt_stat;
+       generic_fillattr(dentry->d_inode, stat);
+       if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
+               char *target;
+               size_t targetsiz;
+
+               rc = ecryptfs_readlink_lower(dentry, &target, &targetsiz);
+               if (!rc) {
+                       kfree(target);
+                       stat->size = targetsiz;
+               }
+       }
+       return rc;
+}
+
 int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
                     struct kstat *stat)
 {
@@ -1039,7 +1044,7 @@ ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 
        lower_dentry = ecryptfs_dentry_to_lower(dentry);
        if (!lower_dentry->d_inode->i_op->setxattr) {
-               rc = -ENOSYS;
+               rc = -EOPNOTSUPP;
                goto out;
        }
        mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1057,7 +1062,7 @@ ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name,
        int rc = 0;
 
        if (!lower_dentry->d_inode->i_op->getxattr) {
-               rc = -ENOSYS;
+               rc = -EOPNOTSUPP;
                goto out;
        }
        mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1084,7 +1089,7 @@ ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size)
 
        lower_dentry = ecryptfs_dentry_to_lower(dentry);
        if (!lower_dentry->d_inode->i_op->listxattr) {
-               rc = -ENOSYS;
+               rc = -EOPNOTSUPP;
                goto out;
        }
        mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1101,7 +1106,7 @@ static int ecryptfs_removexattr(struct dentry *dentry, const char *name)
 
        lower_dentry = ecryptfs_dentry_to_lower(dentry);
        if (!lower_dentry->d_inode->i_op->removexattr) {
-               rc = -ENOSYS;
+               rc = -EOPNOTSUPP;
                goto out;
        }
        mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1132,6 +1137,7 @@ const struct inode_operations ecryptfs_symlink_iops = {
        .put_link = ecryptfs_put_link,
        .permission = ecryptfs_permission,
        .setattr = ecryptfs_setattr,
+       .getattr = ecryptfs_getattr_link,
        .setxattr = ecryptfs_setxattr,
        .getxattr = ecryptfs_getxattr,
        .listxattr = ecryptfs_listxattr,
index a0a7847567e902284d828d53a4731cd5d6326078..89c5476506ef36c8c3de7520565b8360d70eb83b 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/random.h>
 #include <linux/crypto.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include "ecryptfs_kernel.h"
 
 /**
index e14cf7e588db665d84ee50c10db6323e465d3eb9..d8c3a373aafa40547090427c0ae1e96b73f49dbe 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/kthread.h>
 #include <linux/freezer.h>
+#include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/mount.h>
 #include "ecryptfs_kernel.h"
index ea2f92101dfedab1101d98d5a4a8b88010d35897..760983d0f25eafd2addd76d35c571f45d25d45d3 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/key.h>
 #include <linux/parser.h>
 #include <linux/fs_stack.h>
+#include <linux/slab.h>
 #include "ecryptfs_kernel.h"
 
 /**
@@ -496,17 +497,25 @@ struct kmem_cache *ecryptfs_sb_info_cache;
 static int
 ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent)
 {
+       struct ecryptfs_sb_info *esi;
        int rc = 0;
 
        /* Released in ecryptfs_put_super() */
        ecryptfs_set_superblock_private(sb,
                                        kmem_cache_zalloc(ecryptfs_sb_info_cache,
                                                         GFP_KERNEL));
-       if (!ecryptfs_superblock_to_private(sb)) {
+       esi = ecryptfs_superblock_to_private(sb);
+       if (!esi) {
                ecryptfs_printk(KERN_WARNING, "Out of memory\n");
                rc = -ENOMEM;
                goto out;
        }
+
+       rc = bdi_setup_and_register(&esi->bdi, "ecryptfs", BDI_CAP_MAP_COPY);
+       if (rc)
+               goto out;
+
+       sb->s_bdi = &esi->bdi;
        sb->s_op = &ecryptfs_sops;
        /* Released through deactivate_super(sb) from get_sb_nodev */
        sb->s_root = d_alloc(NULL, &(const struct qstr) {
index f1c17e87c5fbc852443f01da834f256f3c33262b..2d8dbce9d485e4a453903eb1f93473c5942155cc 100644 (file)
@@ -20,6 +20,7 @@
  * 02111-1307, USA.
  */
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/user_namespace.h>
 #include <linux/nsproxy.h>
 #include "ecryptfs_kernel.h"
index 4ec8f61ccf5a09d82bd84a67a68aa9e1b25c91d1..3745f612bcd438cb477f8bb245afeb5f47495f89 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/random.h>
 #include <linux/miscdevice.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/module.h>
 #include "ecryptfs_kernel.h"
index df4ce99d0597bb2743dfd3c6b2fccfc807ec55d7..2ee9a3a7b68c4f69be50770a79bf849a79663cbe 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/file.h>
 #include <linux/crypto.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include "ecryptfs_kernel.h"
 
@@ -82,6 +83,19 @@ out:
        return rc;
 }
 
+static void strip_xattr_flag(char *page_virt,
+                            struct ecryptfs_crypt_stat *crypt_stat)
+{
+       if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
+               size_t written;
+
+               crypt_stat->flags &= ~ECRYPTFS_METADATA_IN_XATTR;
+               ecryptfs_write_crypt_stat_flags(page_virt, crypt_stat,
+                                               &written);
+               crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
+       }
+}
+
 /**
  *   Header Extent:
  *     Octets 0-7:        Unencrypted file size (big-endian)
@@ -97,19 +111,6 @@ out:
  *                        (big-endian)
  *     Octet  26:         Begin RFC 2440 authentication token packet set
  */
-static void set_header_info(char *page_virt,
-                           struct ecryptfs_crypt_stat *crypt_stat)
-{
-       size_t written;
-       size_t save_num_header_bytes_at_front =
-               crypt_stat->num_header_bytes_at_front;
-
-       crypt_stat->num_header_bytes_at_front =
-               ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
-       ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written);
-       crypt_stat->num_header_bytes_at_front =
-               save_num_header_bytes_at_front;
-}
 
 /**
  * ecryptfs_copy_up_encrypted_with_header
@@ -135,8 +136,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
                                           * num_extents_per_page)
                                          + extent_num_in_page);
                size_t num_header_extents_at_front =
-                       (crypt_stat->num_header_bytes_at_front
-                        / crypt_stat->extent_size);
+                       (crypt_stat->metadata_size / crypt_stat->extent_size);
 
                if (view_extent_num < num_header_extents_at_front) {
                        /* This is a header extent */
@@ -146,9 +146,14 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
                        memset(page_virt, 0, PAGE_CACHE_SIZE);
                        /* TODO: Support more than one header extent */
                        if (view_extent_num == 0) {
+                               size_t written;
+
                                rc = ecryptfs_read_xattr_region(
                                        page_virt, page->mapping->host);
-                               set_header_info(page_virt, crypt_stat);
+                               strip_xattr_flag(page_virt + 16, crypt_stat);
+                               ecryptfs_write_header_metadata(page_virt + 20,
+                                                              crypt_stat,
+                                                              &written);
                        }
                        kunmap_atomic(page_virt, KM_USER0);
                        flush_dcache_page(page);
@@ -161,7 +166,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
                        /* This is an encrypted data extent */
                        loff_t lower_offset =
                                ((view_extent_num * crypt_stat->extent_size)
-                                - crypt_stat->num_header_bytes_at_front);
+                                - crypt_stat->metadata_size);
 
                        rc = ecryptfs_read_lower_page_segment(
                                page, (lower_offset >> PAGE_CACHE_SHIFT),
index b15a43a80ab78cc7dbb9e05dedef0dbb0dd0e6ee..0c0ae491d231ad94568d1c003ced8b21503a6877 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/fs.h>
 #include <linux/mount.h>
 #include <linux/key.h>
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/smp_lock.h>
 #include <linux/file.h>
@@ -85,7 +86,6 @@ static void ecryptfs_destroy_inode(struct inode *inode)
                if (lower_dentry->d_inode) {
                        fput(inode_info->lower_file);
                        inode_info->lower_file = NULL;
-                       d_drop(lower_dentry);
                }
        }
        ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat);
@@ -122,6 +122,7 @@ static void ecryptfs_put_super(struct super_block *sb)
        lock_kernel();
 
        ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat);
+       bdi_destroy(&sb_info->bdi);
        kmem_cache_free(ecryptfs_sb_info_cache, sb_info);
        ecryptfs_set_superblock_private(sb, NULL);
 
index 7758cc382ef0a80b56dc6e9687838f3a5d5468c0..6bd3f76fdf881ffc4973bc2d7a0d8346a3464bba 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/anon_inodes.h>
index bd056a5b4efc59ceccb8b121100d40e2bb16cf3f..3817149919cb81fa298686f183f67e0c86fe1c50 100644 (file)
@@ -1140,8 +1140,7 @@ retry:
                 * ep_poll_callback() when events will become available.
                 */
                init_waitqueue_entry(&wait, current);
-               wait.flags |= WQ_FLAG_EXCLUSIVE;
-               __add_wait_queue(&ep->wq, &wait);
+               __add_wait_queue_exclusive(&ep->wq, &wait);
 
                for (;;) {
                        /*
index 49cdaa19e5b9b800f9c23b8770f28e4cb33c8fbf..e6e94c626c2cbebb7699597271a953b65e611e6e 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1387,8 +1387,6 @@ int 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;
index 8442e353309f5d9eb09e39c21f3f7ddc31cc8c3f..22721b2fd890140676d7976b0251c48679be7d27 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <linux/fs.h>
 #include <linux/time.h>
+#include <linux/backing-dev.h>
 #include "common.h"
 
 /* FIXME: Remove once pnfs hits mainline
@@ -84,6 +85,7 @@ struct exofs_sb_info {
        u32             s_next_generation;      /* next gen # to use          */
        atomic_t        s_curr_pending;         /* number of pending commands */
        uint8_t         s_cred[OSD_CAP_LEN];    /* credential for the fscb    */
+       struct          backing_dev_info bdi;   /* register our bdi with VFS  */
 
        struct pnfs_osd_data_map data_map;      /* Default raid to use
                                                 * FIXME: Needed ?
index a17e4b733e35116f2c6bb83960a03680e714efe8..76d2a79ef93e887900928f4dc8115ada961a0e29 100644 (file)
@@ -31,6 +31,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <linux/slab.h>
 #include <linux/writeback.h>
 #include <linux/buffer_head.h>
 #include <scsi/scsi_device.h>
index 5293bc411d17735fcfed8b685e7d3ab9d0e80da4..4337cad7777b13f98c1d428942387d61a8503c4e 100644 (file)
@@ -22,6 +22,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <linux/slab.h>
 #include <scsi/scsi_device.h>
 #include <asm/div64.h>
 
index 6cf5e4e84d6162dcb461eb4a0521023e2142c00a..03149b9a51781b7db258ee8350c8072a2048b9c3 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/vfs.h>
 #include <linux/random.h>
 #include <linux/exportfs.h>
+#include <linux/slab.h>
 
 #include "exofs.h"
 
@@ -301,6 +302,7 @@ static void exofs_put_super(struct super_block *sb)
        _exofs_print_device("Unmounting", NULL, sbi->layout.s_ods[0],
                            sbi->layout.s_pid);
 
+       bdi_destroy(&sbi->bdi);
        exofs_free_sbi(sbi);
        sb->s_fs_info = NULL;
 }
@@ -545,6 +547,10 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
        if (!sbi)
                return -ENOMEM;
 
+       ret = bdi_setup_and_register(&sbi->bdi, "exofs", BDI_CAP_MAP_COPY);
+       if (ret)
+               goto free_bdi;
+
        /* use mount options to fill superblock */
        od = osduld_path_lookup(opts->dev_name);
        if (IS_ERR(od)) {
@@ -611,6 +617,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
        }
 
        /* set up operation vectors */
+       sb->s_bdi = &sbi->bdi;
        sb->s_fs_info = sbi;
        sb->s_op = &exofs_sops;
        sb->s_export_op = &exofs_export_ops;
@@ -642,6 +649,8 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
        return 0;
 
 free_sbi:
+       bdi_destroy(&sbi->bdi);
+free_bdi:
        EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n",
                  opts->dev_name, sbi->layout.s_pid, ret);
        exofs_free_sbi(sbi);
index 1d081f0cfec2ce13dac7422ad514aaf92c44969e..3cf038c055d7b587290b05bd659624985e9d1056 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "ext2.h"
 #include <linux/quotaops.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/buffer_head.h>
 #include <linux/capability.h>
index 4e2426e22bbe6377d6f853d9fed196afdd9971cf..565cf817bbf15d4660003f31889e51060a7044ef 100644 (file)
@@ -32,6 +32,7 @@ const struct inode_operations ext2_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = page_follow_link_light,
        .put_link       = page_put_link,
+       .setattr        = ext2_setattr,
 #ifdef CONFIG_EXT2_FS_XATTR
        .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
@@ -43,6 +44,7 @@ const struct inode_operations ext2_symlink_inode_operations = {
 const struct inode_operations ext2_fast_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = ext2_follow_link,
+       .setattr        = ext2_setattr,
 #ifdef CONFIG_EXT2_FS_XATTR
        .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
index c8155845ac0518e8665e122be57fcfe988a9fa56..b118c6383c6d0d05647cf66011eeec4298b1f927 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/fs.h>
 #include <linux/ext2_fs.h>
index 161da2d3f890e4f2cb854ee7c16b6feb00d27d4a..a177122a1b2584170d609b0282bf1fd094bd86b9 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/time.h>
 #include <linux/capability.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/jbd.h>
 #include <linux/ext3_fs.h>
 #include <linux/ext3_jbd.h>
index ef9008b885b57b81c757f0e79ddf55d0e520a857..0d0e97ed3ff6029659837f1394a4827506eb1704 100644 (file)
@@ -582,7 +582,9 @@ got:
        inode->i_generation = sbi->s_next_generation++;
        spin_unlock(&sbi->s_next_gen_lock);
 
-       ei->i_state = EXT3_STATE_NEW;
+       ei->i_state_flags = 0;
+       ext3_set_inode_state(inode, EXT3_STATE_NEW);
+
        ei->i_extra_isize =
                (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) ?
                sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE : 0;
index 7f920b7263a4056612d05fea439c5b7c93c7cfe8..ea33bdf0a3004b927c10be9289b21125dcf53c38 100644 (file)
@@ -2811,7 +2811,7 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino)
        inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime);
        inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0;
 
-       ei->i_state = 0;
+       ei->i_state_flags = 0;
        ei->i_dir_start_lookup = 0;
        ei->i_dtime = le32_to_cpu(raw_inode->i_dtime);
        /* We now have enough fields to check if the inode was active or not.
index ff7b4ccd898383715e9db7348bd95e9ce4162cee..7c4898207776e91d0e8af56d2d80fefeea158453 100644 (file)
@@ -34,6 +34,7 @@ const struct inode_operations ext3_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = page_follow_link_light,
        .put_link       = page_put_link,
+       .setattr        = ext3_setattr,
 #ifdef CONFIG_EXT3_FS_XATTR
        .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
@@ -45,6 +46,7 @@ const struct inode_operations ext3_symlink_inode_operations = {
 const struct inode_operations ext3_fast_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = ext3_follow_link,
+       .setattr        = ext3_setattr,
 #ifdef CONFIG_EXT3_FS_XATTR
        .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
index 474348788dd96ed35fb8ac771509a930212d11c2..3af91f476dff738f36eb5949c6d40487de4386f9 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/fs.h>
 #include <linux/ext3_jbd.h>
index 983f0e1274939b4506c91ea23c3c7d38ae624a88..538c48655084594482d94c3ff38e949f4cb6ffd7 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/pagemap.h>
 #include <linux/blkdev.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include "ext4.h"
 
 struct ext4_system_zone {
index 94c8ee81f5e1e38aa52964f95ab6b7dc9a51eae4..236b834b4ca811913f98caf6c9a264844fe8f7de 100644 (file)
@@ -3879,6 +3879,7 @@ static int ext4_xattr_fiemap(struct inode *inode,
                physical += offset;
                length = EXT4_SB(inode->i_sb)->s_inode_size - offset;
                flags |= FIEMAP_EXTENT_DATA_INLINE;
+               brelse(iloc.bh);
        } else { /* external block */
                physical = EXT4_I(inode)->i_file_acl << blockbits;
                length = inode->i_sb->s_blocksize;
index 361c0b9962a8142b38823e8e9202d0d070c0130b..57f6eef6ccd6c03afbd4c35d0fa364f4e350bbf8 100644 (file)
@@ -263,7 +263,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
                                        ext4_group_t f;
 
                                        f = ext4_flex_group(sbi, block_group);
-                                       atomic_dec(&sbi->s_flex_groups[f].free_inodes);
+                                       atomic_dec(&sbi->s_flex_groups[f].used_dirs);
                                }
 
                        }
@@ -773,7 +773,7 @@ static int ext4_claim_inode(struct super_block *sb,
                if (sbi->s_log_groups_per_flex) {
                        ext4_group_t f = ext4_flex_group(sbi, group);
 
-                       atomic_inc(&sbi->s_flex_groups[f].free_inodes);
+                       atomic_inc(&sbi->s_flex_groups[f].used_dirs);
                }
        }
        gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
index 986120f30066c68b68f7b40906a489cc2870810b..81d605412844895c4386c92c0f4920db39acbd94 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/bio.h>
 #include <linux/workqueue.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include "ext4_jbd2.h"
 #include "xattr.h"
@@ -1035,7 +1036,7 @@ static int ext4_indirect_calc_metadata_amount(struct inode *inode,
                                              sector_t lblock)
 {
        struct ext4_inode_info *ei = EXT4_I(inode);
-       int dind_mask = EXT4_ADDR_PER_BLOCK(inode->i_sb) - 1;
+       sector_t dind_mask = ~((sector_t)EXT4_ADDR_PER_BLOCK(inode->i_sb) - 1);
        int blk_bits;
 
        if (lblock < EXT4_NDIR_BLOCKS)
@@ -1050,7 +1051,7 @@ static int ext4_indirect_calc_metadata_amount(struct inode *inode,
        }
        ei->i_da_metadata_calc_last_lblock = lblock & dind_mask;
        ei->i_da_metadata_calc_len = 1;
-       blk_bits = roundup_pow_of_two(lblock + 1);
+       blk_bits = order_base_2(lblock);
        return (blk_bits / EXT4_ADDR_PER_BLOCK_BITS(inode->i_sb)) + 1;
 }
 
@@ -5374,7 +5375,7 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc)
        } else {
                struct ext4_iloc iloc;
 
-               err = ext4_get_inode_loc(inode, &iloc);
+               err = __ext4_get_inode_loc(inode, &iloc, 0);
                if (err)
                        return err;
                if (wbc->sync_mode == WB_SYNC_ALL)
@@ -5385,6 +5386,7 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc)
                                   (unsigned long long)iloc.bh->b_blocknr);
                        err = -EIO;
                }
+               brelse(iloc.bh);
        }
        return err;
 }
index 54df209d2eed5a4d840e2b4b1ee21adff3322eb2..b423a364dca3c16cf8268861f3107f275c32474e 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "mballoc.h"
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include <trace/events/ext4.h>
 
 /*
@@ -2534,6 +2535,17 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
                mb_debug(1, "gonna free %u blocks in group %u (0x%p):",
                         entry->count, entry->group, entry);
 
+               if (test_opt(sb, DISCARD)) {
+                       ext4_fsblk_t discard_block;
+
+                       discard_block = entry->start_blk +
+                               ext4_group_first_block_no(sb, entry->group);
+                       trace_ext4_discard_blocks(sb,
+                                       (unsigned long long)discard_block,
+                                       entry->count);
+                       sb_issue_discard(sb, discard_block, entry->count);
+               }
+
                err = ext4_mb_load_buddy(sb, entry->group, &e4b);
                /* we expect to find existing buddy because it's pinned */
                BUG_ON(err != 0);
@@ -2555,16 +2567,6 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
                        page_cache_release(e4b.bd_bitmap_page);
                }
                ext4_unlock_group(sb, entry->group);
-               if (test_opt(sb, DISCARD)) {
-                       ext4_fsblk_t discard_block;
-
-                       discard_block = entry->start_blk +
-                               ext4_group_first_block_no(sb, entry->group);
-                       trace_ext4_discard_blocks(sb,
-                                       (unsigned long long)discard_block,
-                                       entry->count);
-                       sb_issue_discard(sb, discard_block, entry->count);
-               }
                kmem_cache_free(ext4_free_ext_cachep, entry);
                ext4_mb_release_desc(&e4b);
        }
index 8b87bd0eac954fc292b8644bebe758e03b0ca023..34dcfc52ef44b4f228fc6403460f294dbc13a95b 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include "ext4_jbd2.h"
 #include "ext4_extents.h"
 
index aa5fe28d180f2dedc3950a1e54b0b372462c8d32..d1fc662cc311070c19742a5cb7522f167c8a4774 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/fs.h>
 #include <linux/quotaops.h>
+#include <linux/slab.h>
 #include "ext4_jbd2.h"
 #include "ext4_extents.h"
 #include "ext4.h"
index ba191dae87304e9106940dfe25e8af41573181ca..e14d22c170d542f3d65b7b50065f0256e0c940b3 100644 (file)
@@ -68,7 +68,21 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf);
 static int ext4_unfreeze(struct super_block *sb);
 static void ext4_write_super(struct super_block *sb);
 static int ext4_freeze(struct super_block *sb);
+static int ext4_get_sb(struct file_system_type *fs_type, int flags,
+                      const char *dev_name, void *data, struct vfsmount *mnt);
 
+#if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
+static struct file_system_type ext3_fs_type = {
+       .owner          = THIS_MODULE,
+       .name           = "ext3",
+       .get_sb         = ext4_get_sb,
+       .kill_sb        = kill_block_super,
+       .fs_flags       = FS_REQUIRES_DEV,
+};
+#define IS_EXT3_SB(sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type)
+#else
+#define IS_EXT3_SB(sb) (0)
+#endif
 
 ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
                               struct ext4_group_desc *bg)
@@ -2539,7 +2553,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
         * enable delayed allocation by default
         * Use -o nodelalloc to turn it off
         */
-       set_opt(sbi->s_mount_opt, DELALLOC);
+       if (!IS_EXT3_SB(sb))
+               set_opt(sbi->s_mount_opt, DELALLOC);
 
        if (!parse_options((char *) data, sb, &journal_devnum,
                           &journal_ioprio, NULL, 0))
@@ -4068,7 +4083,7 @@ static int ext4_get_sb(struct file_system_type *fs_type, int flags,
        return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt);
 }
 
-#if !defined(CONTIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
+#if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
 static struct file_system_type ext2_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "ext2",
@@ -4095,15 +4110,7 @@ static inline void register_as_ext2(void) { }
 static inline void unregister_as_ext2(void) { }
 #endif
 
-#if !defined(CONTIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
-static struct file_system_type ext3_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "ext3",
-       .get_sb         = ext4_get_sb,
-       .kill_sb        = kill_block_super,
-       .fs_flags       = FS_REQUIRES_DEV,
-};
-
+#if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
 static inline void register_as_ext3(void)
 {
        int err = register_filesystem(&ext3_fs_type);
index 983c253999a7f32965a384ae116aa856f25011ed..8b145e98df0771efc2735e38a151fa605f5a8b6f 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/string.h>
 #include <linux/fs.h>
 #include <linux/security.h>
+#include <linux/slab.h>
 #include "ext4_jbd2.h"
 #include "ext4.h"
 #include "xattr.h"
index 923990e4f16e13b4ebc2f9f9435aee64b24633f8..113f0a1e565d17cb1fc4500496f84e966d89fd91 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/buffer_head.h>
 #include "fat.h"
 
index c1ef50154868efd0ce58c3ddca97c04e1a7f1371..6fcc7e71fbaaf0c8f1d21b3cf50fab86d67f50ee 100644 (file)
@@ -309,7 +309,7 @@ static int vfat_create_shortname(struct inode *dir, struct nls_table *nls,
 {
        struct fat_mount_options *opts = &MSDOS_SB(dir->i_sb)->options;
        wchar_t *ip, *ext_start, *end, *name_start;
-       unsigned char base[9], ext[4], buf[8], *p;
+       unsigned char base[9], ext[4], buf[5], *p;
        unsigned char charbuf[NLS_MAX_CHARSET_SIZE];
        int chl, chi;
        int sz = 0, extlen, baselen, i, numtail_baselen, numtail2_baselen;
@@ -467,7 +467,7 @@ static int vfat_create_shortname(struct inode *dir, struct nls_table *nls,
                        return 0;
        }
 
-       i = jiffies & 0xffff;
+       i = jiffies;
        sz = (jiffies >> 16) & 0x7;
        if (baselen > 2) {
                baselen = numtail2_baselen;
@@ -476,7 +476,7 @@ static int vfat_create_shortname(struct inode *dir, struct nls_table *nls,
        name_res[baselen + 4] = '~';
        name_res[baselen + 5] = '1' + sz;
        while (1) {
-               sprintf(buf, "%04X", i);
+               snprintf(buf, sizeof(buf), "%04X", i & 0xffff);
                memcpy(&name_res[baselen], buf, 4);
                if (vfat_find_form(dir, name_res) < 0)
                        break;
index f8f97b8b6d44c82056a970b549eb3272d457263d..5d6606ffc2d28de7b94c4dc3bb04367ac6a57f93 100644 (file)
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -10,7 +10,6 @@
  */
 
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/pipe_fs_i.h>
index a24c58e181db1624b9df3ba2493f48b7652a8418..68ba492d8eeff968ddecdc1c2fd7c5974961e6d7 100644 (file)
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 /*
index ed8f0b0dd880087a5cb1135a725b151d4bcd099b..1429f3ae1e868f2cb6f066542c3675d1d09134cd 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/fs.h>
 #include <linux/buffer_head.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/pagemap.h>
 
 #include "vxfs_extern.h"
index 76fc4d594acb4a3c8091531df7ee37f974f192b6..4b37f7cea4dd28edac895ebbe9017d80e7031c16 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
@@ -553,108 +554,85 @@ select_queue:
        return ret;
 }
 
-static void unpin_sb_for_writeback(struct super_block **psb)
+static void unpin_sb_for_writeback(struct super_block *sb)
 {
-       struct super_block *sb = *psb;
-
-       if (sb) {
-               up_read(&sb->s_umount);
-               put_super(sb);
-               *psb = NULL;
-       }
+       up_read(&sb->s_umount);
+       put_super(sb);
 }
 
+enum sb_pin_state {
+       SB_PINNED,
+       SB_NOT_PINNED,
+       SB_PIN_FAILED
+};
+
 /*
  * For WB_SYNC_NONE writeback, the caller does not have the sb pinned
  * before calling writeback. So make sure that we do pin it, so it doesn't
  * go away while we are writing inodes from it.
- *
- * Returns 0 if the super was successfully pinned (or pinning wasn't needed),
- * 1 if we failed.
  */
-static int pin_sb_for_writeback(struct writeback_control *wbc,
-                               struct inode *inode, struct super_block **psb)
+static enum sb_pin_state pin_sb_for_writeback(struct writeback_control *wbc,
+                                             struct super_block *sb)
 {
-       struct super_block *sb = inode->i_sb;
-
-       /*
-        * If this sb is already pinned, nothing more to do. If not and
-        * *psb is non-NULL, unpin the old one first
-        */
-       if (sb == *psb)
-               return 0;
-       else if (*psb)
-               unpin_sb_for_writeback(psb);
-
        /*
         * Caller must already hold the ref for this
         */
        if (wbc->sync_mode == WB_SYNC_ALL) {
                WARN_ON(!rwsem_is_locked(&sb->s_umount));
-               return 0;
+               return SB_NOT_PINNED;
        }
-
        spin_lock(&sb_lock);
        sb->s_count++;
        if (down_read_trylock(&sb->s_umount)) {
                if (sb->s_root) {
                        spin_unlock(&sb_lock);
-                       goto pinned;
+                       return SB_PINNED;
                }
                /*
                 * umounted, drop rwsem again and fall through to failure
                 */
                up_read(&sb->s_umount);
        }
-
        sb->s_count--;
        spin_unlock(&sb_lock);
-       return 1;
-pinned:
-       *psb = sb;
-       return 0;
+       return SB_PIN_FAILED;
 }
 
-static void writeback_inodes_wb(struct bdi_writeback *wb,
-                               struct writeback_control *wbc)
+/*
+ * Write a portion of b_io inodes which belong to @sb.
+ * If @wbc->sb != NULL, then find and write all such
+ * inodes. Otherwise write only ones which go sequentially
+ * in reverse order.
+ * Return 1, if the caller writeback routine should be
+ * interrupted. Otherwise return 0.
+ */
+static int writeback_sb_inodes(struct super_block *sb,
+                              struct bdi_writeback *wb,
+                              struct writeback_control *wbc)
 {
-       struct super_block *sb = wbc->sb, *pin_sb = NULL;
-       const unsigned long start = jiffies;    /* livelock avoidance */
-
-       spin_lock(&inode_lock);
-
-       if (!wbc->for_kupdate || list_empty(&wb->b_io))
-               queue_io(wb, wbc->older_than_this);
-
        while (!list_empty(&wb->b_io)) {
-               struct inode *inode = list_entry(wb->b_io.prev,
-                                               struct inode, i_list);
                long pages_skipped;
-
-               /*
-                * super block given and doesn't match, skip this inode
-                */
-               if (sb && sb != inode->i_sb) {
+               struct inode *inode = list_entry(wb->b_io.prev,
+                                                struct inode, i_list);
+               if (wbc->sb && sb != inode->i_sb) {
+                       /* super block given and doesn't
+                          match, skip this inode */
                        redirty_tail(inode);
                        continue;
                }
-
+               if (sb != inode->i_sb)
+                       /* finish with this superblock */
+                       return 0;
                if (inode->i_state & (I_NEW | I_WILL_FREE)) {
                        requeue_io(inode);
                        continue;
                }
-
                /*
                 * Was this inode dirtied after sync_sb_inodes was called?
                 * This keeps sync from extra jobs and livelock.
                 */
-               if (inode_dirtied_after(inode, start))
-                       break;
-
-               if (pin_sb_for_writeback(wbc, inode, &pin_sb)) {
-                       requeue_io(inode);
-                       continue;
-               }
+               if (inode_dirtied_after(inode, wbc->wb_start))
+                       return 1;
 
                BUG_ON(inode->i_state & (I_FREEING | I_CLEAR));
                __iget(inode);
@@ -673,14 +651,50 @@ static void writeback_inodes_wb(struct bdi_writeback *wb,
                spin_lock(&inode_lock);
                if (wbc->nr_to_write <= 0) {
                        wbc->more_io = 1;
-                       break;
+                       return 1;
                }
                if (!list_empty(&wb->b_more_io))
                        wbc->more_io = 1;
        }
+       /* b_io is empty */
+       return 1;
+}
+
+static void writeback_inodes_wb(struct bdi_writeback *wb,
+                               struct writeback_control *wbc)
+{
+       int ret = 0;
 
-       unpin_sb_for_writeback(&pin_sb);
+       wbc->wb_start = jiffies; /* livelock avoidance */
+       spin_lock(&inode_lock);
+       if (!wbc->for_kupdate || list_empty(&wb->b_io))
+               queue_io(wb, wbc->older_than_this);
+
+       while (!list_empty(&wb->b_io)) {
+               struct inode *inode = list_entry(wb->b_io.prev,
+                                                struct inode, i_list);
+               struct super_block *sb = inode->i_sb;
+               enum sb_pin_state state;
+
+               if (wbc->sb && sb != wbc->sb) {
+                       /* super block given and doesn't
+                          match, skip this inode */
+                       redirty_tail(inode);
+                       continue;
+               }
+               state = pin_sb_for_writeback(wbc, sb);
+
+               if (state == SB_PIN_FAILED) {
+                       requeue_io(inode);
+                       continue;
+               }
+               ret = writeback_sb_inodes(sb, wb, wbc);
 
+               if (state == SB_PINNED)
+                       unpin_sb_for_writeback(sb);
+               if (ret)
+                       break;
+       }
        spin_unlock(&inode_lock);
        /* Leave any unwritten inodes on b_io */
 }
index 3221a0c7944e32fbe02c5d8c6c759b5766d6ce69..1e1f286dd70eeb0ea7e98b46012e378280e0cf58 100644 (file)
@@ -12,6 +12,7 @@
 #define FSCACHE_DEBUG_LEVEL COOKIE
 #include <linux/module.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/key.h>
 #include <keys/user-type.h>
 #include "internal.h"
index e513ac599c8e9b587c8646e33485be20d2ce1c4e..0b589a9b4ffcf623b9b1544cff596ee24b52cbb0 100644 (file)
@@ -53,7 +53,7 @@ const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5] = {
 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
+#ifdef CONFIG_SLOW_WORK_DEBUG
 static void fscache_object_slow_work_desc(struct slow_work *, struct seq_file *);
 #endif
 static void fscache_initialise_object(struct fscache_object *);
@@ -69,7 +69,7 @@ const struct slow_work_ops fscache_object_slow_work_ops = {
        .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
+#ifdef CONFIG_SLOW_WORK_DEBUG
        .desc           = fscache_object_slow_work_desc,
 #endif
 };
@@ -364,7 +364,7 @@ static void fscache_object_slow_work_execute(struct slow_work *work)
 /*
  * describe an object for slow-work debugging
  */
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
 static void fscache_object_slow_work_desc(struct slow_work *work,
                                          struct seq_file *m)
 {
index 313e79a14266e69e2a47aafdffefc89b29f510df..f17cecafae44c1a49665c7e0b865c98693d61f89 100644 (file)
@@ -14,6 +14,7 @@
 #define FSCACHE_DEBUG_LEVEL OPERATION
 #include <linux/module.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "internal.h"
 
 atomic_t fscache_op_debug_id;
@@ -500,7 +501,7 @@ static void fscache_op_execute(struct slow_work *work)
 /*
  * describe an operation for slow-work debugging
  */
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
 static void fscache_op_desc(struct slow_work *work, struct seq_file *m)
 {
        struct fscache_operation *op =
@@ -517,7 +518,7 @@ const struct slow_work_ops fscache_op_slow_work_ops = {
        .get_ref        = fscache_op_get_ref,
        .put_ref        = fscache_op_put_ref,
        .execute        = fscache_op_execute,
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
        .desc           = fscache_op_desc,
 #endif
 };
index c598ea4c4e7d580d9046e1cb8ccb42e1d14db6c6..47aefd376e54060341d15a31ab5cf96a2755a13e 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/fscache-cache.h>
 #include <linux/buffer_head.h>
 #include <linux/pagevec.h>
+#include <linux/slab.h>
 #include "internal.h"
 
 /*
@@ -881,6 +882,7 @@ submit_failed:
        goto nobufs;
 
 nobufs_unlock_obj:
+       spin_unlock(&cookie->stores_lock);
        spin_unlock(&object->lock);
 nobufs:
        spin_unlock(&cookie->lock);
index 46435f3aae689936404bf1ecd5e3c6d6094a214b..4765190d537f827f5c8e10c1e75f026d714a00d6 100644 (file)
@@ -165,8 +165,8 @@ static int fscache_stats_show(struct seq_file *m, void *v)
                   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));
+                  atomic_read(&fscache_n_object_created),
+                  atomic_read(&fscache_n_object_lookups_timed_out));
 
        seq_printf(m, "Updates: n=%u nul=%u run=%u\n",
                   atomic_read(&fscache_n_updates),
index de792dcf327484c8cf5d8a97e50763d9a5164aeb..e1f8171278bdeac8b5ba7f5b71abfe1d9984c307 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/magic.h>
 #include <linux/miscdevice.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/stat.h>
 
index 55458031e501405b06371b04f958323d44e12549..fe5df5457656e43fa2757a37b322c106b63af17f 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/gfp.h>
 #include <linux/fs.h>
 #include <linux/generic_acl.h>
 #include <linux/posix_acl.h>
index 583e823307ae7a17cd58b34027f11cea4e3f6437..5e411d5f4697a2ce2912aa917106a47acc3829b6 100644 (file)
@@ -7,7 +7,6 @@
  * of the GNU General Public License version 2.
  */
 
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/buffer_head.h>
index 91beddadd38876367d5163ad0b73617d023b158c..bb7907bde3d81b63b6ae5b198283a52db36e97b0 100644 (file)
@@ -7,7 +7,6 @@
  * of the GNU General Public License version 2.
  */
 
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/buffer_head.h>
index d15876e9aa26c42292ab9b836661a8b692c89c2a..c22c2117483365abed04aba0165df3b2d03b65f3 100644 (file)
@@ -7,7 +7,6 @@
  * of the GNU General Public License version 2.
  */
 
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/buffer_head.h>
index 38e3749d476ce04afa59bd416e3ff190388afcb7..49f97d3bb690c512cb0f338d85938e622d501a49 100644 (file)
@@ -7,7 +7,6 @@
  * of the GNU General Public License version 2.
  */
 
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/buffer_head.h>
index 569b46240f613c1a17e4ff0653c1bb53dc59cfe1..0e0470ed34c273a341aed5860191bfadf42b41e5 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/fs.h>
 #include <linux/dlm.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/gfs2_ondisk.h>
 
index b4106ddaaa98219362c23addea091d2ea582d53f..f07119d89557855fc9a8673b32e9119cad921570 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef __RGRP_DOT_H__
 #define __RGRP_DOT_H__
 
+#include <linux/slab.h>
+
 struct gfs2_rgrpd;
 struct gfs2_sbd;
 struct gfs2_holder;
index 419042f7f0b6d14d21da858504775856657e58ea..54fd9842599169a3551d8b57d292164406a74480 100644 (file)
@@ -8,7 +8,6 @@
  */
 
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/buffer_head.h>
index 226f2bfbf16abe9dbc6d6bf972f2c88014f3da48..53511291fe3661363144b55156c7f4eac4312c58 100644 (file)
@@ -7,7 +7,6 @@
  * of the GNU General Public License version 2.
  */
 
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/buffer_head.h>
index 0d200068d0afaff014db5279d46c74dab06332bb..cdb41a1f6a646bd957fdfa2cf2b835d2078d9731 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 #include <linux/swap.h>
 
 #include "btree.h"
index 052f214ea6f0c39657d4cfb84e3eb96f7a391818..38a0a9917d7f3a67b0eaad49a75246430eef7d76 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 #include <linux/log2.h>
 
 #include "btree.h"
index 8bbe03c3f6d54e5286ff3c0c0cce4e6c5f653134..86428f5ac991c59dd46a088b25cffe12b5a13dee 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/cdrom.h>
 #include <linux/genhd.h>
 #include <linux/nls.h>
+#include <linux/slab.h>
 
 #include "hfs_fs.h"
 #include "btree.h"
index 5ed7252b7b23246aabdb015341ba19cbb101379a..0a81eb7111f3505600b626e1c88145692aa8c725 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/nls.h>
 #include <linux/parser.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/vfs.h>
 
index 3fcbb0e1f6fc09ea43f1918d4099f695937b0db1..572628b4b07d23af08f98ca7b757c85acfbcbc0c 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/nls.h>
 #include <linux/mount.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "hfsplus_fs.h"
 
 enum {
index 032604e5ef2ca36b1f9171d4fc2a775e9bcd7074..3a029d8f4cf1d564f0e64c7f1ead796a193769d5 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/statfs.h>
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/mount.h>
 #include "hostfs.h"
index b6fca543544c5acd63907d9227331178489d8256..eac5f96323e3d9640a197ee5eb10acdbf6046591 100644 (file)
@@ -6,6 +6,7 @@
  *  general buffer i/o
  */
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include "hpfs_fn.h"
 
 void hpfs_lock_creation(struct super_block *s)
index 26e3964a4b8c19a7075d0ef623ab041392c78b53..2338130ccebaab85c33ba86f1d2d0c16b1f6a76d 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include "hpfs_fn.h"
 
 static int hpfs_dir_release(struct inode *inode, struct file *filp)
index ff90affb94e16ebdd2b2a76156dab515d4a0a050..1042a9bc97f3710c0930c80333afd303ae10a8d5 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include "hpfs_fn.h"
 
 void hpfs_init_inode(struct inode *i)
index cadc4ce48656674358e44eeb62e16f4f5bdc9b01..aa53842c599c2eec917086af4d2c8b1d2fea1384 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
 #include <linux/bitmap.h>
+#include <linux/slab.h>
 
 /* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */
 
index 6c751106c2e56c7bc318a0fa5f42f528fb8ac363..7faefb4da93915be59bfe6a8ab2a9b37014b9b52 100644 (file)
@@ -228,14 +228,23 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg)
 
 #ifdef CONFIG_BLOCK
 
-#define blk_to_logical(inode, blk) (blk << (inode)->i_blkbits)
-#define logical_to_blk(inode, offset) (offset >> (inode)->i_blkbits);
+static inline sector_t logical_to_blk(struct inode *inode, loff_t offset)
+{
+       return (offset >> inode->i_blkbits);
+}
+
+static inline loff_t blk_to_logical(struct inode *inode, sector_t blk)
+{
+       return (blk << inode->i_blkbits);
+}
 
 /**
  * __generic_block_fiemap - FIEMAP for block based inodes (no locking)
- * @inode - the inode to map
- * @arg - the pointer to userspace where we copy everything to
- * @get_block - the fs's get_block function
+ * @inode: the inode to map
+ * @fieinfo: the fiemap info struct that will be passed back to userspace
+ * @start: where to start mapping in the inode
+ * @len: how much space to map
+ * @get_block: the fs's get_block function
  *
  * This does FIEMAP for block based inodes.  Basically it will just loop
  * through get_block until we hit the number of extents we want to map, or we
@@ -250,58 +259,63 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg)
  */
 
 int __generic_block_fiemap(struct inode *inode,
-                          struct fiemap_extent_info *fieinfo, u64 start,
-                          u64 len, get_block_t *get_block)
+                          struct fiemap_extent_info *fieinfo, loff_t start,
+                          loff_t len, get_block_t *get_block)
 {
-       struct buffer_head tmp;
-       unsigned long long start_blk;
-       long long length = 0, map_len = 0;
+       struct buffer_head map_bh;
+       sector_t start_blk, last_blk;
+       loff_t isize = i_size_read(inode);
        u64 logical = 0, phys = 0, size = 0;
        u32 flags = FIEMAP_EXTENT_MERGED;
-       int ret = 0, past_eof = 0, whole_file = 0;
+       bool past_eof = false, whole_file = false;
+       int ret = 0;
 
-       if ((ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC)))
+       ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC);
+       if (ret)
                return ret;
 
-       start_blk = logical_to_blk(inode, start);
-
-       length = (long long)min_t(u64, len, i_size_read(inode));
-       if (length < len)
-               whole_file = 1;
+       /*
+        * Either the i_mutex or other appropriate locking needs to be held
+        * since we expect isize to not change at all through the duration of
+        * this call.
+        */
+       if (len >= isize) {
+               whole_file = true;
+               len = isize;
+       }
 
-       map_len = length;
+       start_blk = logical_to_blk(inode, start);
+       last_blk = logical_to_blk(inode, start + len - 1);
 
        do {
                /*
                 * we set b_size to the total size we want so it will map as
                 * many contiguous blocks as possible at once
                 */
-               memset(&tmp, 0, sizeof(struct buffer_head));
-               tmp.b_size = map_len;
+               memset(&map_bh, 0, sizeof(struct buffer_head));
+               map_bh.b_size = len;
 
-               ret = get_block(inode, start_blk, &tmp, 0);
+               ret = get_block(inode, start_blk, &map_bh, 0);
                if (ret)
                        break;
 
                /* HOLE */
-               if (!buffer_mapped(&tmp)) {
-                       length -= blk_to_logical(inode, 1);
+               if (!buffer_mapped(&map_bh)) {
                        start_blk++;
 
                        /*
-                        * we want to handle the case where there is an
+                        * We want to handle the case where there is an
                         * allocated block at the front of the file, and then
                         * nothing but holes up to the end of the file properly,
                         * to make sure that extent at the front gets properly
                         * marked with FIEMAP_EXTENT_LAST
                         */
                        if (!past_eof &&
-                           blk_to_logical(inode, start_blk) >=
-                           blk_to_logical(inode, 0)+i_size_read(inode))
+                           blk_to_logical(inode, start_blk) >= isize)
                                past_eof = 1;
 
                        /*
-                        * first hole after going past the EOF, this is our
+                        * First hole after going past the EOF, this is our
                         * last extent
                         */
                        if (past_eof && size) {
@@ -309,15 +323,18 @@ int __generic_block_fiemap(struct inode *inode,
                                ret = fiemap_fill_next_extent(fieinfo, logical,
                                                              phys, size,
                                                              flags);
-                               break;
+                       } else if (size) {
+                               ret = fiemap_fill_next_extent(fieinfo, logical,
+                                                             phys, size, flags);
+                               size = 0;
                        }
 
                        /* if we have holes up to/past EOF then we're done */
-                       if (length <= 0 || past_eof)
+                       if (start_blk > last_blk || past_eof || ret)
                                break;
                } else {
                        /*
-                        * we have gone over the length of what we wanted to
+                        * We have gone over the length of what we wanted to
                         * map, and it wasn't the entire file, so add the extent
                         * we got last time and exit.
                         *
@@ -331,7 +348,7 @@ int __generic_block_fiemap(struct inode *inode,
                         * are good to go, just add the extent to the fieinfo
                         * and break
                         */
-                       if (length <= 0 && !whole_file) {
+                       if (start_blk > last_blk && !whole_file) {
                                ret = fiemap_fill_next_extent(fieinfo, logical,
                                                              phys, size,
                                                              flags);
@@ -351,11 +368,10 @@ int __generic_block_fiemap(struct inode *inode,
                        }
 
                        logical = blk_to_logical(inode, start_blk);
-                       phys = blk_to_logical(inode, tmp.b_blocknr);
-                       size = tmp.b_size;
+                       phys = blk_to_logical(inode, map_bh.b_blocknr);
+                       size = map_bh.b_size;
                        flags = FIEMAP_EXTENT_MERGED;
 
-                       length -= tmp.b_size;
                        start_blk += logical_to_blk(inode, size);
 
                        /*
@@ -363,15 +379,13 @@ int __generic_block_fiemap(struct inode *inode,
                         * soon as we find a hole that the last extent we found
                         * is marked with FIEMAP_EXTENT_LAST
                         */
-                       if (!past_eof &&
-                           logical+size >=
-                           blk_to_logical(inode, 0)+i_size_read(inode))
-                               past_eof = 1;
+                       if (!past_eof && logical + size >= isize)
+                               past_eof = true;
                }
                cond_resched();
        } while (1);
 
-       /* if ret is 1 then we just hit the end of the extent array */
+       /* If ret is 1 then we just hit the end of the extent array */
        if (ret == 1)
                ret = 0;
 
index c7c0b28d7d2177c7c88d32f3f62856e97cfc7ff5..748cfb92dcc6203897c62d87ee113876f197a28b 100644 (file)
@@ -19,6 +19,7 @@
  * See also Documentation/block/ioprio.txt
  *
  */
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/ioprio.h>
 #include <linux/blkdev.h>
index 8ba5441063be82c37af8477b90b9eabf7b1d34c0..b9ab69b3a482ce86bcbefd9f7703d0079f516bce 100644 (file)
@@ -11,6 +11,7 @@
  *  isofs directory handling functions
  */
 #include <linux/smp_lock.h>
+#include <linux/gfp.h>
 #include "isofs.h"
 
 int isofs_name_translate(struct iso_directory_record *de, char *new, struct inode *inode)
index eaa831311c9cb49b243d5f5426ee9479f26885ac..ab438beb867cca718bcedf66e0355f09168b8669 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/smp_lock.h>
+#include <linux/gfp.h>
 #include "isofs.h"
 
 /*
index 2c90e3ef625f35ae0bfdfa74270273c9d35a1695..ecb44c94ba8de4251de699bd6e35a317ecee8a85 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/fs.h>
 #include <linux/jbd.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/bio.h>
index cb1a49ae605e0a0c7b01c706a743e912dfe70ea1..54c9bc9e1b17e01487cca2eb81d5bfdf7a649585 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/fs.h>
 #include <linux/jbd.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #endif
 
 /*
index 73063285b13f7c7d868fb8553690bb2d0cbe5a03..049281b7cb8966ab236f8085c65f5230f891aaae 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/fs.h>
 #include <linux/jbd2.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/crc32.h>
 #endif
 
index 90cb60d0978767c305ce1ed888e712471b72b0d3..cd02acafde8a3352a8fd639704b924b86c9e0160 100644 (file)
@@ -11,7 +11,6 @@
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <linux/lzo.h>
index cfd301a5edfc2db804cb1b3ab008543211c0c4aa..b46661a4275866e95f0cd174cd82e498db13532d 100644 (file)
@@ -14,7 +14,6 @@
 #endif
 
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/zlib.h>
 #include <linux/zutil.h>
 #include "nodelist.h"
index 5544d31c066be22fb25cc857df3691de8e420ea6..ec3538413926f677feb3d763df9a7ebaa5d7a07d 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/crc32.h>
 #include <linux/jffs2.h>
 #include <linux/mtd/mtd.h>
+#include <linux/slab.h>
 #include "nodelist.h"
 #include "debug.h"
 
index b7b74e299142bd964330ca2b88570b381420ad8b..e7291c161a1989c2abeb55659eb67b80fdc1a8d0 100644 (file)
@@ -10,7 +10,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/time.h>
 #include <linux/pagemap.h>
index 87c6f555e1a0a696ee2fe52e57c9b3978bc8716f..af02bd13846967a8d9288358e1e3979c89520fe7 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/rbtree.h>
 #include <linux/crc32.h>
-#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include "nodelist.h"
 
index 21a052915aa9363acb0cd1e2b34567ef782b57f5..191359dde4e1a3f9e34d64eaf43626466ffc3333 100644 (file)
@@ -10,7 +10,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/mtd/mtd.h>
 #include <linux/compiler.h>
 #include <linux/sched.h> /* For cond_resched() */
index e22de8397b7430f3e48bcd2ae32ca0af70fe0a12..d32ee9412cb991a82ba04b0d1eb1abcec98d570d 100644 (file)
@@ -567,7 +567,7 @@ static void jffs2_free_tmp_dnode_info_list(struct rb_root *list)
                        else BUG();
                }
        }
-       list->rb_node = NULL;
+       *list = RB_ROOT;
 }
 
 static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
index 4ec11e8bda8c75a33336cba971128c2cd5ca073e..b955626071c28acb8be9728b88399f8c9cdd7ab4 100644 (file)
@@ -10,7 +10,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/namei.h>
 #include "nodelist.h"
index ca29440e9435867650514303b256c54528b8c1ef..c819eb0e982d8b95a216a09ab9398c9bd7e3ea58 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/crc32.h>
-#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/mtd/mtd.h>
 #include "nodelist.h"
index 213169780b6cb7292fda108700056ec02f5758bd..1057a4998e4e793f7a5706dbd4026916c7f3e9b6 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/posix_acl_xattr.h>
 #include "jfs_incore.h"
index 9dd126276c9f429c2be8990bca4af460d8d2a2af..ed9ba6fe04f55839f94b21bc20f0c681aebae364 100644 (file)
@@ -61,7 +61,7 @@ struct inode *jfs_iget(struct super_block *sb, unsigned long ino)
                        inode->i_op = &page_symlink_inode_operations;
                        inode->i_mapping->a_ops = &jfs_aops;
                } else {
-                       inode->i_op = &jfs_symlink_inode_operations;
+                       inode->i_op = &jfs_fast_symlink_inode_operations;
                        /*
                         * The inline data should be null-terminated, but
                         * don't let on-disk corruption crash the kernel
index d9b031cf69f56581eedd4870a2c8321823575465..9e2f6a721668c067846d44d5bcfc9aa2d172e5ea 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include "jfs_incore.h"
 #include "jfs_superblock.h"
 #include "jfs_dmap.h"
@@ -195,7 +196,7 @@ int dbMount(struct inode *ipbmap)
        bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag);
        bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref);
        bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel);
-       bmp->db_agheigth = le32_to_cpu(dbmp_le->dn_agheigth);
+       bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight);
        bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
        bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart);
        bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size);
@@ -287,7 +288,7 @@ int dbSync(struct inode *ipbmap)
        dbmp_le->dn_maxag = cpu_to_le32(bmp->db_maxag);
        dbmp_le->dn_agpref = cpu_to_le32(bmp->db_agpref);
        dbmp_le->dn_aglevel = cpu_to_le32(bmp->db_aglevel);
-       dbmp_le->dn_agheigth = cpu_to_le32(bmp->db_agheigth);
+       dbmp_le->dn_agheight = cpu_to_le32(bmp->db_agheight);
        dbmp_le->dn_agwidth = cpu_to_le32(bmp->db_agwidth);
        dbmp_le->dn_agstart = cpu_to_le32(bmp->db_agstart);
        dbmp_le->dn_agl2size = cpu_to_le32(bmp->db_agl2size);
@@ -1440,7 +1441,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
         * tree index of this allocation group within the control page.
         */
        agperlev =
-           (1 << (L2LPERCTL - (bmp->db_agheigth << 1))) / bmp->db_agwidth;
+           (1 << (L2LPERCTL - (bmp->db_agheight << 1))) / bmp->db_agwidth;
        ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1));
 
        /* dmap control page trees fan-out by 4 and a single allocation
@@ -1459,7 +1460,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
                 * the subtree to find the leftmost leaf that describes this
                 * free space.
                 */
-               for (k = bmp->db_agheigth; k > 0; k--) {
+               for (k = bmp->db_agheight; k > 0; k--) {
                        for (n = 0, m = (ti << 2) + 1; n < 4; n++) {
                                if (l2nb <= dcp->stree[m + n]) {
                                        ti = m + n;
@@ -3606,7 +3607,7 @@ void dbFinalizeBmap(struct inode *ipbmap)
        }
 
        /*
-        * compute db_aglevel, db_agheigth, db_width, db_agstart:
+        * compute db_aglevel, db_agheight, db_width, db_agstart:
         * an ag is covered in aglevel dmapctl summary tree,
         * at agheight level height (from leaf) with agwidth number of nodes
         * each, which starts at agstart index node of the smmary tree node
@@ -3615,9 +3616,9 @@ void dbFinalizeBmap(struct inode *ipbmap)
        bmp->db_aglevel = BMAPSZTOLEV(bmp->db_agsize);
        l2nl =
            bmp->db_agl2size - (L2BPERDMAP + bmp->db_aglevel * L2LPERCTL);
-       bmp->db_agheigth = l2nl >> 1;
-       bmp->db_agwidth = 1 << (l2nl - (bmp->db_agheigth << 1));
-       for (i = 5 - bmp->db_agheigth, bmp->db_agstart = 0, n = 1; i > 0;
+       bmp->db_agheight = l2nl >> 1;
+       bmp->db_agwidth = 1 << (l2nl - (bmp->db_agheight << 1));
+       for (i = 5 - bmp->db_agheight, bmp->db_agstart = 0, n = 1; i > 0;
             i--) {
                bmp->db_agstart += n;
                n <<= 2;
index 1a6eb41569bc45c12174952481ad2abfc601b9f1..6dcb906c55d847647257aa0dbb4b776c125642b5 100644 (file)
@@ -210,7 +210,7 @@ struct dbmap_disk {
        __le32 dn_maxag;        /* 4: max active alloc group number     */
        __le32 dn_agpref;       /* 4: preferred alloc group (hint)      */
        __le32 dn_aglevel;      /* 4: dmapctl level holding the AG      */
-       __le32 dn_agheigth;     /* 4: height in dmapctl of the AG       */
+       __le32 dn_agheight;     /* 4: height in dmapctl of the AG       */
        __le32 dn_agwidth;      /* 4: width in dmapctl of the AG        */
        __le32 dn_agstart;      /* 4: start tree index at AG height     */
        __le32 dn_agl2size;     /* 4: l2 num of blks per alloc group    */
@@ -229,7 +229,7 @@ struct dbmap {
        int dn_maxag;           /* max active alloc group number        */
        int dn_agpref;          /* preferred alloc group (hint)         */
        int dn_aglevel;         /* dmapctl level holding the AG         */
-       int dn_agheigth;        /* height in dmapctl of the AG          */
+       int dn_agheight;        /* height in dmapctl of the AG          */
        int dn_agwidth;         /* width in dmapctl of the AG           */
        int dn_agstart;         /* start tree index at AG height        */
        int dn_agl2size;        /* l2 num of blks per alloc group       */
@@ -255,7 +255,7 @@ struct bmap {
 #define        db_agsize       db_bmap.dn_agsize
 #define        db_agl2size     db_bmap.dn_agl2size
 #define        db_agwidth      db_bmap.dn_agwidth
-#define        db_agheigth     db_bmap.dn_agheigth
+#define        db_agheight     db_bmap.dn_agheight
 #define        db_agstart      db_bmap.dn_agstart
 #define        db_numag        db_bmap.dn_numag
 #define        db_maxlevel     db_bmap.dn_maxlevel
index 0e4623be70ceb6dcee419d1c392c8e92cf1bfac3..9197a1b0d02db05943ed3bc646e53109253044e3 100644 (file)
 
 #include <linux/fs.h>
 #include <linux/quotaops.h>
+#include <linux/slab.h>
 #include "jfs_incore.h"
 #include "jfs_superblock.h"
 #include "jfs_filsys.h"
index 0fc30407f03912e98a41cadd345afb88282b36f0..f8332dc8eeb2111430d2a16ae716b6d1925fde99 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/buffer_head.h>
 #include <linux/pagemap.h>
 #include <linux/quotaops.h>
+#include <linux/slab.h>
 
 #include "jfs_incore.h"
 #include "jfs_inode.h"
index 79e2c79661dfdf897ecac4832f55c91164c24a14..9e6bda30a6e86671abc5b878cecc6c7441c7376d 100644 (file)
@@ -48,5 +48,6 @@ extern const struct file_operations jfs_dir_operations;
 extern const struct inode_operations jfs_file_inode_operations;
 extern const struct file_operations jfs_file_operations;
 extern const struct inode_operations jfs_symlink_inode_operations;
+extern const struct inode_operations jfs_fast_symlink_inode_operations;
 extern const struct dentry_operations jfs_ci_dentry_operations;
 #endif                         /* _H_JFS_INODE */
index 335c4de6552d1a8fb7b1450fd5c20bd9ac5dc29e..c51af2a14516b88ba4aad33fc6fa28c64c8fb15a 100644 (file)
@@ -70,6 +70,7 @@
 #include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "jfs_incore.h"
 #include "jfs_filsys.h"
 #include "jfs_metapage.h"
index 07b6c5dfb4b6e641cda09581c4fff8abb8603ea5..48b44bd8267b960e7e5bd330521f9da93d6d1a6f 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/bio.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/buffer_head.h>
 #include <linux/mempool.h>
index 3fbb3a22559077e0fbfd21ae4a44cb91ebd7605e..8f0f02cb6ca6285831be3966c2e1ee655ec30f50 100644 (file)
@@ -19,6 +19,7 @@
 #ifndef _H_JFS_UNICODE
 #define _H_JFS_UNICODE
 
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 #include "jfs_types.h"
 
index 4a3e9f39c21d05a430dba68a87e9a1fb0a73428b..a9cf8e8675be8713dc5f9311faa20fefcac85156 100644 (file)
@@ -956,7 +956,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
         */
 
        if (ssize <= IDATASIZE) {
-               ip->i_op = &jfs_symlink_inode_operations;
+               ip->i_op = &jfs_fast_symlink_inode_operations;
 
                i_fastsymlink = JFS_IP(ip)->i_inline;
                memcpy(i_fastsymlink, name, ssize);
@@ -978,7 +978,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
        else {
                jfs_info("jfs_symlink: allocate extent ip:0x%p", ip);
 
-               ip->i_op = &page_symlink_inode_operations;
+               ip->i_op = &jfs_symlink_inode_operations;
                ip->i_mapping->a_ops = &jfs_aops;
 
                /*
index 7f24a0bb08ca0a25d31352e9611273de87d2ee1b..1aba0039f1c995ab0909664cc325a917ee5d8c0b 100644 (file)
@@ -81,6 +81,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
        struct inode *iplist[1];
        struct jfs_superblock *j_sb, *j_sb2;
        uint old_agsize;
+       int agsizechanged = 0;
        struct buffer_head *bh, *bh2;
 
        /* If the volume hasn't grown, get out now */
@@ -333,6 +334,9 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
         */
        if ((rc = dbExtendFS(ipbmap, XAddress, nblocks)))
                goto error_out;
+
+       agsizechanged |= (bmp->db_agsize != old_agsize);
+
        /*
         * the map now has extended to cover additional nblocks:
         * dn_mapsize = oldMapsize + nblocks;
@@ -432,7 +436,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
         * will correctly identify the new ag);
         */
        /* if new AG size the same as old AG size, done! */
-       if (bmp->db_agsize != old_agsize) {
+       if (agsizechanged) {
                if ((rc = diExtendFS(ipimap, ipbmap)))
                        goto error_out;
 
index 266699deb1c68825d29eee529d0109dcf9ce50a0..b66832ac33ac5d5869d90084227a321174e0b95d 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/buffer_head.h>
 #include <linux/exportfs.h>
 #include <linux/crc32.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/seq_file.h>
 #include <linux/smp_lock.h>
@@ -445,10 +446,8 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
        /* initialize the mount flag and determine the default error handler */
        flag = JFS_ERR_REMOUNT_RO;
 
-       if (!parse_options((char *) data, sb, &newLVSize, &flag)) {
-               kfree(sbi);
-               return -EINVAL;
-       }
+       if (!parse_options((char *) data, sb, &newLVSize, &flag))
+               goto out_kfree;
        sbi->flag = flag;
 
 #ifdef CONFIG_JFS_POSIX_ACL
@@ -457,7 +456,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
 
        if (newLVSize) {
                printk(KERN_ERR "resize option for remount only\n");
-               return -EINVAL;
+               goto out_kfree;
        }
 
        /*
@@ -477,7 +476,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
        inode = new_inode(sb);
        if (inode == NULL) {
                ret = -ENOMEM;
-               goto out_kfree;
+               goto out_unload;
        }
        inode->i_ino = 0;
        inode->i_nlink = 1;
@@ -549,9 +548,10 @@ out_mount_failed:
        make_bad_inode(sbi->direct_inode);
        iput(sbi->direct_inode);
        sbi->direct_inode = NULL;
-out_kfree:
+out_unload:
        if (sbi->nls_tab)
                unload_nls(sbi->nls_tab);
+out_kfree:
        kfree(sbi);
        return ret;
 }
index 4af1a05aad0af2445658df5cbbf765c61d37b627..205b946d8e0d3a2abd805896b93536dfc1193e39 100644 (file)
@@ -29,9 +29,21 @@ static void *jfs_follow_link(struct dentry *dentry, struct nameidata *nd)
        return NULL;
 }
 
-const struct inode_operations jfs_symlink_inode_operations = {
+const struct inode_operations jfs_fast_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = jfs_follow_link,
+       .setattr        = jfs_setattr,
+       .setxattr       = jfs_setxattr,
+       .getxattr       = jfs_getxattr,
+       .listxattr      = jfs_listxattr,
+       .removexattr    = jfs_removexattr,
+};
+
+const struct inode_operations jfs_symlink_inode_operations = {
+       .readlink       = generic_readlink,
+       .follow_link    = page_follow_link_light,
+       .put_link       = page_put_link,
+       .setattr        = jfs_setattr,
        .setxattr       = jfs_setxattr,
        .getxattr       = jfs_getxattr,
        .listxattr      = jfs_listxattr,
index 1f594ab21895cb28c81f3b0238a434147d485198..fa96bbb263434618e1c3bc050a2208ccbe3c8fc0 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/fs.h>
 #include <linux/xattr.h>
 #include <linux/posix_acl_xattr.h>
+#include <linux/slab.h>
 #include <linux/quotaops.h>
 #include <linux/security.h>
 #include "jfs_incore.h"
index 9e50bcf55857eaebd8fc4106f21bae8ad69afbf1..ea9a6cc9b35c6b08ef1517837d1c05a4d2da47e1 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/module.h>
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 #include <linux/mount.h>
 #include <linux/vfs.h>
 #include <linux/mutex.h>
index fc9032dc8862df3408a56e7208aef0fb446e3a5e..64fd427c993cce81eb5246ba9717a975575c0017 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/nfs_fs.h>
 #include <linux/sunrpc/clnt.h>
index c81249fef11f9a3f48b02d772e4d09d3216a2557..7932c399fab41421095fbb0f98f0b21819e96514 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/module.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
index fefa4df3f005bd9cdf0e1a10b0ab0bfce72f976e..e3015464fbab8ac1a9a48f0ea5465080923731bb 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/utsname.h>
 #include <linux/kernel.h>
 #include <linux/ktime.h>
+#include <linux/slab.h>
 
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/xprtsock.h>
index 7d150517ddf0445943ed58e2625494deef712d4e..f1bacf1a03912bb52939e5d0595b9c71f70ff8d6 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/uio.h>
-#include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/mutex.h>
index a7966eed3c17a2bfe34ec4bb6ed6ea492e1b9021..031c6569a134aa7efcfc776d1cab5ef03bc742b8 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <linux/types.h>
 #include <linux/time.h>
-#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/lockd/lockd.h>
 #include <linux/lockd/share.h>
index d1001790fa9ac77569ede0eae646b7b116f2211f..84055d31bfc5e427a87c2412eea17f6ea59e2fc4 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
index 56c9519d900a32ea203112f24b4866227b1bdd33..0f2ab741ae7c8205edeed842e7bbf6f89d6d482f 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <linux/types.h>
 #include <linux/time.h>
-#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/lockd/lockd.h>
 #include <linux/lockd/share.h>
index ad478da7ca63138e6dda728ed6640c4630c5e02e..d0ef94cfb3da4d218b66a0a4046d96ab30506f3b 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/string.h>
 #include <linux/time.h>
 #include <linux/in.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/clnt.h>
index 9718c22f186d04ff309614dbeee6337a8d5ec185..9bd2ce2a30407897557b32a2fa9f97708695593e 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/bio.h>
 #include <linux/blkdev.h>
 #include <linux/buffer_head.h>
+#include <linux/gfp.h>
 
 #define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1))
 
@@ -80,6 +81,7 @@ static void writeseg_end_io(struct bio *bio, int err)
                        prefetchw(&bvec->bv_page->flags);
 
                end_page_writeback(page);
+               page_cache_release(page);
        } while (bvec >= bio->bi_io_vec);
        bio_put(bio);
        if (atomic_dec_and_test(&super->s_pending_writes))
@@ -97,8 +99,10 @@ static int __bdev_writeseg(struct super_block *sb, u64 ofs, pgoff_t index,
        unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9);
        int i;
 
+       if (max_pages > BIO_MAX_PAGES)
+               max_pages = BIO_MAX_PAGES;
        bio = bio_alloc(GFP_NOFS, max_pages);
-       BUG_ON(!bio); /* FIXME: handle this */
+       BUG_ON(!bio);
 
        for (i = 0; i < nr_pages; i++) {
                if (i >= max_pages) {
@@ -191,8 +195,10 @@ static int do_erase(struct super_block *sb, u64 ofs, pgoff_t index,
        unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9);
        int i;
 
+       if (max_pages > BIO_MAX_PAGES)
+               max_pages = BIO_MAX_PAGES;
        bio = bio_alloc(GFP_NOFS, max_pages);
-       BUG_ON(!bio); /* FIXME: handle this */
+       BUG_ON(!bio);
 
        for (i = 0; i < nr_pages; i++) {
                if (i >= max_pages) {
@@ -297,6 +303,11 @@ static void bdev_put_device(struct super_block *sb)
        close_bdev_exclusive(logfs_super(sb)->s_bdev, FMODE_READ|FMODE_WRITE);
 }
 
+static int bdev_can_write_buf(struct super_block *sb, u64 ofs)
+{
+       return 0;
+}
+
 static const struct logfs_device_ops bd_devops = {
        .find_first_sb  = bdev_find_first_sb,
        .find_last_sb   = bdev_find_last_sb,
@@ -304,6 +315,7 @@ static const struct logfs_device_ops bd_devops = {
        .readpage       = bdev_readpage,
        .writeseg       = bdev_writeseg,
        .erase          = bdev_erase,
+       .can_write_buf  = bdev_can_write_buf,
        .sync           = bdev_sync,
        .put_device     = bdev_put_device,
 };
index cafb6ef2e05b5e53c81dab70789f3126a00ad390..a85d47d13e4b04623dff3d873c66cc107b7f8599 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/completion.h>
 #include <linux/mount.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1))
 
@@ -126,7 +127,8 @@ static int mtd_readpage(void *_sb, struct page *page)
 
        err = mtd_read(sb, page->index << PAGE_SHIFT, PAGE_SIZE,
                        page_address(page));
-       if (err == -EUCLEAN) {
+       if (err == -EUCLEAN || err == -EBADMSG) {
+               /* -EBADMSG happens regularly on power failures */
                err = 0;
                /* FIXME: force GC this segment */
        }
@@ -233,12 +235,32 @@ static void mtd_put_device(struct super_block *sb)
        put_mtd_device(logfs_super(sb)->s_mtd);
 }
 
+static int mtd_can_write_buf(struct super_block *sb, u64 ofs)
+{
+       struct logfs_super *super = logfs_super(sb);
+       void *buf;
+       int err;
+
+       buf = kmalloc(super->s_writesize, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+       err = mtd_read(sb, ofs, super->s_writesize, buf);
+       if (err)
+               goto out;
+       if (memchr_inv(buf, 0xff, super->s_writesize))
+               err = -EIO;
+       kfree(buf);
+out:
+       return err;
+}
+
 static const struct logfs_device_ops mtd_devops = {
        .find_first_sb  = mtd_find_first_sb,
        .find_last_sb   = mtd_find_last_sb,
        .readpage       = mtd_readpage,
        .writeseg       = mtd_writeseg,
        .erase          = mtd_erase,
+       .can_write_buf  = mtd_can_write_buf,
        .sync           = mtd_sync,
        .put_device     = mtd_put_device,
 };
@@ -250,5 +272,7 @@ int logfs_get_sb_mtd(struct file_system_type *type, int flags,
        const struct logfs_device_ops *devops = &mtd_devops;
 
        mtd = get_mtd_device(NULL, mtdnr);
+       if (IS_ERR(mtd))
+               return PTR_ERR(mtd);
        return logfs_get_sb_device(type, flags, mtd, NULL, devops, mnt);
 }
index 56a8bfbb012041be7279216ff334831ea911edbe..2396a85c0f55ab9de07faf6687ae6d4433a9c348 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
  */
 #include "logfs.h"
-
+#include <linux/slab.h>
 
 /*
  * Atomic dir operations
@@ -303,12 +303,12 @@ static int __logfs_readdir(struct file *file, void *buf, filldir_t filldir)
                                (filler_t *)logfs_readpage, NULL);
                if (IS_ERR(page))
                        return PTR_ERR(page);
-               dd = kmap_atomic(page, KM_USER0);
+               dd = kmap(page);
                BUG_ON(dd->namelen == 0);
 
                full = filldir(buf, (char *)dd->name, be16_to_cpu(dd->namelen),
                                pos, be64_to_cpu(dd->ino), dd->type);
-               kunmap_atomic(dd, KM_USER0);
+               kunmap(page);
                page_cache_release(page);
                if (full)
                        break;
index 370f367a933eb3ef88104f61ab57eb2cd9048a86..0de52407187042f9fd0a1a1d59049a0ce93c1b55 100644 (file)
@@ -161,7 +161,17 @@ static int logfs_writepage(struct page *page, struct writeback_control *wbc)
 
 static void logfs_invalidatepage(struct page *page, unsigned long offset)
 {
-       move_page_to_btree(page);
+       struct logfs_block *block = logfs_block(page);
+
+       if (block->reserved_bytes) {
+               struct super_block *sb = page->mapping->host->i_sb;
+               struct logfs_super *super = logfs_super(sb);
+
+               super->s_dirty_pages -= block->reserved_bytes;
+               block->ops->free_block(sb, block);
+               BUG_ON(bitmap_weight(block->alias_map, LOGFS_BLOCK_FACTOR));
+       } else
+               move_page_to_btree(page);
        BUG_ON(PagePrivate(page) || page->private);
 }
 
@@ -212,10 +222,8 @@ int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 int logfs_fsync(struct file *file, struct dentry *dentry, int datasync)
 {
        struct super_block *sb = dentry->d_inode->i_sb;
-       struct logfs_super *super = logfs_super(sb);
 
-       /* FIXME: write anchor */
-       super->s_devops->sync(sb);
+       logfs_write_anchor(sb);
        return 0;
 }
 
index 92949f95a901079ec6a0c72464b09d588ce2b85d..caa4419285dcac78e1743a0e2e602eadd57b19bb 100644 (file)
@@ -7,6 +7,7 @@
  */
 #include "logfs.h"
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 /*
  * Wear leveling needs to kick in when the difference between low erase
@@ -121,7 +122,7 @@ static void logfs_cleanse_block(struct super_block *sb, u64 ofs, u64 ino,
        logfs_safe_iput(inode, cookie);
 }
 
-static u32 logfs_gc_segment(struct super_block *sb, u32 segno, u8 dist)
+static u32 logfs_gc_segment(struct super_block *sb, u32 segno)
 {
        struct logfs_super *super = logfs_super(sb);
        struct logfs_segment_header sh;
@@ -400,7 +401,7 @@ static int __logfs_gc_once(struct super_block *sb, struct gc_candidate *cand)
                        segno, (u64)segno << super->s_segshift,
                        dist, no_free_segments(sb), valid,
                        super->s_free_bytes);
-       cleaned = logfs_gc_segment(sb, segno, dist);
+       cleaned = logfs_gc_segment(sb, segno);
        log_gc("GC segment #%02x complete - now %x valid\n", segno,
                        valid - cleaned);
        BUG_ON(cleaned != valid);
@@ -458,6 +459,14 @@ static void __logfs_gc_pass(struct super_block *sb, int target)
        struct logfs_block *block;
        int round, progress, last_progress = 0;
 
+       /*
+        * Doing too many changes to the segfile at once would result
+        * in a large number of aliases.  Write the journal before
+        * things get out of hand.
+        */
+       if (super->s_shadow_tree.no_shadowed_segments >= MAX_OBJ_ALIASES)
+               logfs_write_anchor(sb);
+
        if (no_free_segments(sb) >= target &&
                        super->s_no_object_aliases < MAX_OBJ_ALIASES)
                return;
@@ -623,38 +632,31 @@ static int check_area(struct super_block *sb, int i)
 {
        struct logfs_super *super = logfs_super(sb);
        struct logfs_area *area = super->s_area[i];
-       struct logfs_object_header oh;
+       gc_level_t gc_level;
+       u32 cleaned, valid, ec;
        u32 segno = area->a_segno;
-       u32 ofs = area->a_used_bytes;
-       __be32 crc;
-       int err;
+       u64 ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes);
 
        if (!area->a_is_open)
                return 0;
 
-       for (ofs = area->a_used_bytes;
-            ofs <= super->s_segsize - sizeof(oh);
-            ofs += (u32)be16_to_cpu(oh.len) + sizeof(oh)) {
-               err = wbuf_read(sb, dev_ofs(sb, segno, ofs), sizeof(oh), &oh);
-               if (err)
-                       return err;
-
-               if (!memchr_inv(&oh, 0xff, sizeof(oh)))
-                       break;
+       if (super->s_devops->can_write_buf(sb, ofs) == 0)
+               return 0;
 
-               crc = logfs_crc32(&oh, sizeof(oh) - 4, 4);
-               if (crc != oh.crc) {
-                       printk(KERN_INFO "interrupted header at %llx\n",
-                                       dev_ofs(sb, segno, ofs));
-                       return 0;
-               }
-       }
-       if (ofs != area->a_used_bytes) {
-               printk(KERN_INFO "%x bytes unaccounted data found at %llx\n",
-                               ofs - area->a_used_bytes,
-                               dev_ofs(sb, segno, area->a_used_bytes));
-               area->a_used_bytes = ofs;
-       }
+       printk(KERN_INFO"LogFS: Possibly incomplete write at %llx\n", ofs);
+       /*
+        * The device cannot write back the write buffer.  Most likely the
+        * wbuf was already written out and the system crashed at some point
+        * before the journal commit happened.  In that case we wouldn't have
+        * to do anything.  But if the crash happened before the wbuf was
+        * written out correctly, we must GC this segment.  So assume the
+        * worst and always do the GC run.
+        */
+       area->a_is_open = 0;
+       valid = logfs_valid_bytes(sb, segno, &ec, &gc_level);
+       cleaned = logfs_gc_segment(sb, segno);
+       if (cleaned != valid)
+               return -EIO;
        return 0;
 }
 
index 33ec1aeaeec4f9d614a75140042753d441558f1a..755a92e8daa774b109d55b89346f09525552e160 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
  */
 #include "logfs.h"
+#include <linux/slab.h>
 #include <linux/writeback.h>
 #include <linux/backing-dev.h>
 
@@ -192,6 +193,7 @@ static void logfs_init_inode(struct super_block *sb, struct inode *inode)
        inode->i_ctime  = CURRENT_TIME;
        inode->i_mtime  = CURRENT_TIME;
        inode->i_nlink  = 1;
+       li->li_refcount = 1;
        INIT_LIST_HEAD(&li->li_freeing_list);
 
        for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
@@ -325,7 +327,7 @@ static void logfs_set_ino_generation(struct super_block *sb,
        u64 ino;
 
        mutex_lock(&super->s_journal_mutex);
-       ino = logfs_seek_hole(super->s_master_inode, super->s_last_ino);
+       ino = logfs_seek_hole(super->s_master_inode, super->s_last_ino + 1);
        super->s_last_ino = ino;
        super->s_inos_till_wrap--;
        if (super->s_inos_till_wrap < 0) {
@@ -385,8 +387,7 @@ static void logfs_init_once(void *_li)
 
 static int logfs_sync_fs(struct super_block *sb, int wait)
 {
-       /* FIXME: write anchor */
-       logfs_super(sb)->s_devops->sync(sb);
+       logfs_write_anchor(sb);
        return 0;
 }
 
index 6ad30a4c9052179b4fe56da98a81f381b7a531a7..4b0e0616b357d59ba89fda8f7450c24e85a2abba 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
  */
 #include "logfs.h"
+#include <linux/slab.h>
 
 static void logfs_calc_free(struct super_block *sb)
 {
@@ -131,10 +132,9 @@ static int read_area(struct super_block *sb, struct logfs_je_area *a)
 
        ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes);
        if (super->s_writesize > 1)
-               logfs_buf_recover(area, ofs, a + 1, super->s_writesize);
+               return logfs_buf_recover(area, ofs, a + 1, super->s_writesize);
        else
-               logfs_buf_recover(area, ofs, NULL, 0);
-       return 0;
+               return logfs_buf_recover(area, ofs, NULL, 0);
 }
 
 static void *unpack(void *from, void *to)
@@ -244,7 +244,7 @@ static int read_je(struct super_block *sb, u64 ofs)
                read_erasecount(sb, unpack(jh, scratch));
                break;
        case JE_AREA:
-               read_area(sb, unpack(jh, scratch));
+               err = read_area(sb, unpack(jh, scratch));
                break;
        case JE_OBJ_ALIAS:
                err = logfs_load_object_aliases(sb, unpack(jh, scratch),
@@ -388,7 +388,10 @@ static void journal_get_erase_count(struct logfs_area *area)
 static int journal_erase_segment(struct logfs_area *area)
 {
        struct super_block *sb = area->a_sb;
-       struct logfs_segment_header sh;
+       union {
+               struct logfs_segment_header sh;
+               unsigned char c[ALIGN(sizeof(struct logfs_segment_header), 16)];
+       } u;
        u64 ofs;
        int err;
 
@@ -396,20 +399,21 @@ static int journal_erase_segment(struct logfs_area *area)
        if (err)
                return err;
 
-       sh.pad = 0;
-       sh.type = SEG_JOURNAL;
-       sh.level = 0;
-       sh.segno = cpu_to_be32(area->a_segno);
-       sh.ec = cpu_to_be32(area->a_erase_count);
-       sh.gec = cpu_to_be64(logfs_super(sb)->s_gec);
-       sh.crc = logfs_crc32(&sh, sizeof(sh), 4);
+       memset(&u, 0, sizeof(u));
+       u.sh.pad = 0;
+       u.sh.type = SEG_JOURNAL;
+       u.sh.level = 0;
+       u.sh.segno = cpu_to_be32(area->a_segno);
+       u.sh.ec = cpu_to_be32(area->a_erase_count);
+       u.sh.gec = cpu_to_be64(logfs_super(sb)->s_gec);
+       u.sh.crc = logfs_crc32(&u.sh, sizeof(u.sh), 4);
 
        /* This causes a bug in segment.c.  Not yet. */
        //logfs_set_segment_erased(sb, area->a_segno, area->a_erase_count, 0);
 
        ofs = dev_ofs(sb, area->a_segno, 0);
-       area->a_used_bytes = ALIGN(sizeof(sh), 16);
-       logfs_buf_write(area, ofs, &sh, sizeof(sh));
+       area->a_used_bytes = sizeof(u);
+       logfs_buf_write(area, ofs, &u, sizeof(u));
        return 0;
 }
 
@@ -493,6 +497,8 @@ static void account_shadows(struct super_block *sb)
 
        btree_grim_visitor64(&tree->new, (unsigned long)sb, account_shadow);
        btree_grim_visitor64(&tree->old, (unsigned long)sb, account_shadow);
+       btree_grim_visitor32(&tree->segment_map, 0, NULL);
+       tree->no_shadowed_segments = 0;
 
        if (li->li_block) {
                /*
@@ -606,9 +612,9 @@ static size_t __logfs_write_je(struct super_block *sb, void *buf, u16 type,
        if (len == 0)
                return logfs_write_header(super, header, 0, type);
 
+       BUG_ON(len > sb->s_blocksize);
        compr_len = logfs_compress(buf, data, len, sb->s_blocksize);
        if (compr_len < 0 || type == JE_ANCHOR) {
-               BUG_ON(len > sb->s_blocksize);
                memcpy(data, buf, len);
                compr_len = len;
                compr = COMPR_NONE;
@@ -660,6 +666,7 @@ static int logfs_write_je_buf(struct super_block *sb, void *buf, u16 type,
        if (ofs < 0)
                return ofs;
        logfs_buf_write(area, ofs, super->s_compressed_je, len);
+       BUG_ON(super->s_no_je >= MAX_JOURNAL_ENTRIES);
        super->s_je_array[super->s_no_je++] = cpu_to_be64(ofs);
        return 0;
 }
@@ -800,6 +807,7 @@ void do_logfs_journal_wl_pass(struct super_block *sb)
 {
        struct logfs_super *super = logfs_super(sb);
        struct logfs_area *area = super->s_journal_area;
+       struct btree_head32 *head = &super->s_reserved_segments;
        u32 segno, ec;
        int i, err;
 
@@ -807,6 +815,7 @@ void do_logfs_journal_wl_pass(struct super_block *sb)
        /* Drop old segments */
        journal_for_each(i)
                if (super->s_journal_seg[i]) {
+                       btree_remove32(head, super->s_journal_seg[i]);
                        logfs_set_segment_unreserved(sb,
                                        super->s_journal_seg[i],
                                        super->s_journal_ec[i]);
@@ -819,8 +828,13 @@ void do_logfs_journal_wl_pass(struct super_block *sb)
                super->s_journal_seg[i] = segno;
                super->s_journal_ec[i] = ec;
                logfs_set_segment_reserved(sb, segno);
+               err = btree_insert32(head, segno, (void *)1, GFP_KERNEL);
+               BUG_ON(err); /* mempool should prevent this */
+               err = logfs_erase_segment(sb, segno, 1);
+               BUG_ON(err); /* FIXME: remount-ro would be nicer */
        }
        /* Manually move journal_area */
+       freeseg(sb, area->a_segno);
        area->a_segno = super->s_journal_seg[0];
        area->a_is_open = 0;
        area->a_used_bytes = 0;
index 129779431373adfbf5f674b48e26913f80986f19..93b55f3372451b00fd03bad81424808ede0b1825 100644 (file)
@@ -144,6 +144,7 @@ struct logfs_area_ops {
  * @erase:                     erase one segment
  * @read:                      read from the device
  * @erase:                     erase part of the device
+ * @can_write_buf:             decide whether wbuf can be written to ofs
  */
 struct logfs_device_ops {
        struct page *(*find_first_sb)(struct super_block *sb, u64 *ofs);
@@ -153,6 +154,7 @@ struct logfs_device_ops {
        void (*writeseg)(struct super_block *sb, u64 ofs, size_t len);
        int (*erase)(struct super_block *sb, loff_t ofs, size_t len,
                        int ensure_write);
+       int (*can_write_buf)(struct super_block *sb, u64 ofs);
        void (*sync)(struct super_block *sb);
        void (*put_device)(struct super_block *sb);
 };
@@ -257,10 +259,14 @@ struct logfs_shadow {
  * struct shadow_tree
  * @new:                       shadows where old_ofs==0, indexed by new_ofs
  * @old:                       shadows where old_ofs!=0, indexed by old_ofs
+ * @segment_map:               bitfield of segments containing shadows
+ * @no_shadowed_segment:       number of segments containing shadows
  */
 struct shadow_tree {
        struct btree_head64 new;
        struct btree_head64 old;
+       struct btree_head32 segment_map;
+       int no_shadowed_segments;
 };
 
 struct object_alias_item {
@@ -305,13 +311,14 @@ typedef int write_alias_t(struct super_block *sb, u64 ino, u64 bix,
                level_t level, int child_no, __be64 val);
 struct logfs_block_ops {
        void    (*write_block)(struct logfs_block *block);
-       gc_level_t      (*block_level)(struct logfs_block *block);
        void    (*free_block)(struct super_block *sb, struct logfs_block*block);
        int     (*write_alias)(struct super_block *sb,
                        struct logfs_block *block,
                        write_alias_t *write_one_alias);
 };
 
+#define MAX_JOURNAL_ENTRIES 256
+
 struct logfs_super {
        struct mtd_info *s_mtd;                 /* underlying device */
        struct block_device *s_bdev;            /* underlying device */
@@ -378,7 +385,7 @@ struct logfs_super {
        u32      s_journal_ec[LOGFS_JOURNAL_SEGS]; /* journal erasecounts */
        u64      s_last_version;
        struct logfs_area *s_journal_area;      /* open journal segment */
-       __be64  s_je_array[64];
+       __be64  s_je_array[MAX_JOURNAL_ENTRIES];
        int     s_no_je;
 
        int      s_sum_index;                   /* for the 12 summaries */
@@ -389,6 +396,7 @@ struct logfs_super {
        int      s_lock_count;
        mempool_t *s_block_pool;                /* struct logfs_block pool */
        mempool_t *s_shadow_pool;               /* struct logfs_shadow pool */
+       struct list_head s_writeback_list;      /* writeback pages */
        /*
         * Space accounting:
         * - s_used_bytes specifies space used to store valid data objects.
@@ -587,24 +595,25 @@ void move_page_to_btree(struct page *page);
 int logfs_init_mapping(struct super_block *sb);
 void logfs_sync_area(struct logfs_area *area);
 void logfs_sync_segments(struct super_block *sb);
+void freeseg(struct super_block *sb, u32 segno);
 
 /* area handling */
 int logfs_init_areas(struct super_block *sb);
 void logfs_cleanup_areas(struct super_block *sb);
 int logfs_open_area(struct logfs_area *area, size_t bytes);
-void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
+int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
                int use_filler);
 
-static inline void logfs_buf_write(struct logfs_area *area, u64 ofs,
+static inline int logfs_buf_write(struct logfs_area *area, u64 ofs,
                void *buf, size_t len)
 {
-       __logfs_buf_write(area, ofs, buf, len, 0);
+       return __logfs_buf_write(area, ofs, buf, len, 0);
 }
 
-static inline void logfs_buf_recover(struct logfs_area *area, u64 ofs,
+static inline int logfs_buf_recover(struct logfs_area *area, u64 ofs,
                void *buf, size_t len)
 {
-       __logfs_buf_write(area, ofs, buf, len, 1);
+       return __logfs_buf_write(area, ofs, buf, len, 1);
 }
 
 /* super.c */
@@ -721,4 +730,10 @@ static inline struct logfs_area *get_area(struct super_block *sb,
        return logfs_super(sb)->s_area[(__force u8)gc_level];
 }
 
+static inline void logfs_mempool_destroy(mempool_t *pool)
+{
+       if (pool)
+               mempool_destroy(pool);
+}
+
 #endif
index 7a23b3e7c0a798c3b750d96f08cf1351950cefde..0718d112a1a59a7f92e98469e0311fbaddf7cd7d 100644 (file)
@@ -18,6 +18,7 @@
  */
 #include "logfs.h"
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 static u64 adjust_bix(u64 bix, level_t level)
 {
@@ -429,25 +430,6 @@ static void inode_write_block(struct logfs_block *block)
        }
 }
 
-static gc_level_t inode_block_level(struct logfs_block *block)
-{
-       BUG_ON(block->inode->i_ino == LOGFS_INO_MASTER);
-       return GC_LEVEL(LOGFS_MAX_LEVELS);
-}
-
-static gc_level_t indirect_block_level(struct logfs_block *block)
-{
-       struct page *page;
-       struct inode *inode;
-       u64 bix;
-       level_t level;
-
-       page = block->page;
-       inode = page->mapping->host;
-       logfs_unpack_index(page->index, &bix, &level);
-       return expand_level(inode->i_ino, level);
-}
-
 /*
  * This silences a false, yet annoying gcc warning.  I hate it when my editor
  * jumps into bitops.h each time I recompile this file.
@@ -586,14 +568,12 @@ static void indirect_free_block(struct super_block *sb,
 
 static struct logfs_block_ops inode_block_ops = {
        .write_block = inode_write_block,
-       .block_level = inode_block_level,
        .free_block = inode_free_block,
        .write_alias = inode_write_alias,
 };
 
 struct logfs_block_ops indirect_block_ops = {
        .write_block = indirect_write_block,
-       .block_level = indirect_block_level,
        .free_block = indirect_free_block,
        .write_alias = indirect_write_alias,
 };
@@ -912,6 +892,8 @@ u64 logfs_seek_hole(struct inode *inode, u64 bix)
                return bix;
        else if (li->li_data[INDIRECT_INDEX] & LOGFS_FULLY_POPULATED)
                bix = maxbix(li->li_height);
+       else if (bix >= maxbix(li->li_height))
+               return bix;
        else {
                bix = seek_holedata_loop(inode, bix, 0);
                if (bix < maxbix(li->li_height))
@@ -1113,17 +1095,25 @@ static int logfs_reserve_bytes(struct inode *inode, int bytes)
 int get_page_reserve(struct inode *inode, struct page *page)
 {
        struct logfs_super *super = logfs_super(inode->i_sb);
+       struct logfs_block *block = logfs_block(page);
        int ret;
 
-       if (logfs_block(page) && logfs_block(page)->reserved_bytes)
+       if (block && block->reserved_bytes)
                return 0;
 
        logfs_get_wblocks(inode->i_sb, page, WF_LOCK);
-       ret = logfs_reserve_bytes(inode, 6 * LOGFS_MAX_OBJECTSIZE);
+       while ((ret = logfs_reserve_bytes(inode, 6 * LOGFS_MAX_OBJECTSIZE)) &&
+                       !list_empty(&super->s_writeback_list)) {
+               block = list_entry(super->s_writeback_list.next,
+                               struct logfs_block, alias_list);
+               block->ops->write_block(block);
+       }
        if (!ret) {
                alloc_data_block(inode, page);
-               logfs_block(page)->reserved_bytes += 6 * LOGFS_MAX_OBJECTSIZE;
+               block = logfs_block(page);
+               block->reserved_bytes += 6 * LOGFS_MAX_OBJECTSIZE;
                super->s_dirty_pages += 6 * LOGFS_MAX_OBJECTSIZE;
+               list_move_tail(&block->alias_list, &super->s_writeback_list);
        }
        logfs_put_wblocks(inode->i_sb, page, WF_LOCK);
        return ret;
@@ -1240,6 +1230,18 @@ static void free_shadow(struct inode *inode, struct logfs_shadow *shadow)
        mempool_free(shadow, super->s_shadow_pool);
 }
 
+static void mark_segment(struct shadow_tree *tree, u32 segno)
+{
+       int err;
+
+       if (!btree_lookup32(&tree->segment_map, segno)) {
+               err = btree_insert32(&tree->segment_map, segno, (void *)1,
+                               GFP_NOFS);
+               BUG_ON(err);
+               tree->no_shadowed_segments++;
+       }
+}
+
 /**
  * fill_shadow_tree - Propagate shadow tree changes due to a write
  * @inode:     Inode owning the page
@@ -1287,6 +1289,8 @@ static void fill_shadow_tree(struct inode *inode, struct page *page,
 
                super->s_dirty_used_bytes += shadow->new_len;
                super->s_dirty_free_bytes += shadow->old_len;
+               mark_segment(tree, shadow->old_ofs >> super->s_segshift);
+               mark_segment(tree, shadow->new_ofs >> super->s_segshift);
        }
 }
 
@@ -1594,7 +1598,6 @@ int logfs_delete(struct inode *inode, pgoff_t index,
        return ret;
 }
 
-/* Rewrite cannot mark the inode dirty but has to write it immediatly. */
 int logfs_rewrite_block(struct inode *inode, u64 bix, u64 ofs,
                gc_level_t gc_level, long flags)
 {
@@ -1611,6 +1614,18 @@ int logfs_rewrite_block(struct inode *inode, u64 bix, u64 ofs,
                if (level != 0)
                        alloc_indirect_block(inode, page, 0);
                err = logfs_write_buf(inode, page, flags);
+               if (!err && shrink_level(gc_level) == 0) {
+                       /* Rewrite cannot mark the inode dirty but has to
+                        * write it immediatly.
+                        * Q: Can't we just create an alias for the inode
+                        * instead?  And if not, why not?
+                        */
+                       if (inode->i_ino == LOGFS_INO_MASTER)
+                               logfs_write_anchor(inode->i_sb);
+                       else {
+                               err = __logfs_write_inode(inode, flags);
+                       }
+               }
        }
        logfs_put_write_page(page);
        return err;
@@ -1833,19 +1848,37 @@ static int __logfs_truncate(struct inode *inode, u64 size)
        return logfs_truncate_direct(inode, size);
 }
 
-int logfs_truncate(struct inode *inode, u64 size)
+/*
+ * Truncate, by changing the segment file, can consume a fair amount
+ * of resources.  So back off from time to time and do some GC.
+ * 8 or 2048 blocks should be well within safety limits even if
+ * every single block resided in a different segment.
+ */
+#define TRUNCATE_STEP  (8 * 1024 * 1024)
+int logfs_truncate(struct inode *inode, u64 target)
 {
        struct super_block *sb = inode->i_sb;
-       int err;
+       u64 size = i_size_read(inode);
+       int err = 0;
 
-       logfs_get_wblocks(sb, NULL, 1);
-       err = __logfs_truncate(inode, size);
-       if (!err)
-               err = __logfs_write_inode(inode, 0);
-       logfs_put_wblocks(sb, NULL, 1);
+       size = ALIGN(size, TRUNCATE_STEP);
+       while (size > target) {
+               if (size > TRUNCATE_STEP)
+                       size -= TRUNCATE_STEP;
+               else
+                       size = 0;
+               if (size < target)
+                       size = target;
+
+               logfs_get_wblocks(sb, NULL, 1);
+               err = __logfs_truncate(inode, size);
+               if (!err)
+                       err = __logfs_write_inode(inode, 0);
+               logfs_put_wblocks(sb, NULL, 1);
+       }
 
        if (!err)
-               err = vmtruncate(inode, size);
+               err = vmtruncate(inode, target);
 
        /* I don't trust error recovery yet. */
        WARN_ON(err);
@@ -2226,6 +2259,7 @@ int logfs_init_rw(struct super_block *sb)
        int min_fill = 3 * super->s_no_blocks;
 
        INIT_LIST_HEAD(&super->s_object_alias);
+       INIT_LIST_HEAD(&super->s_writeback_list);
        mutex_init(&super->s_write_mutex);
        super->s_block_pool = mempool_create_kmalloc_pool(min_fill,
                        sizeof(struct logfs_block));
@@ -2239,8 +2273,6 @@ void logfs_cleanup_rw(struct super_block *sb)
        struct logfs_super *super = logfs_super(sb);
 
        destroy_meta_inode(super->s_segfile_inode);
-       if (super->s_block_pool)
-               mempool_destroy(super->s_block_pool);
-       if (super->s_shadow_pool)
-               mempool_destroy(super->s_shadow_pool);
+       logfs_mempool_destroy(super->s_block_pool);
+       logfs_mempool_destroy(super->s_shadow_pool);
 }
index 1a14f9910d55ef94a46c64ba910caa1d92bbfdec..a9657afb70ad1a562bdb36a2f789d8eda672deec 100644 (file)
@@ -10,6 +10,7 @@
  * three kinds of objects: inodes, dentries and blocks, both data and indirect.
  */
 #include "logfs.h"
+#include <linux/slab.h>
 
 static int logfs_mark_segment_bad(struct super_block *sb, u32 segno)
 {
@@ -66,7 +67,7 @@ static struct page *get_mapping_page(struct super_block *sb, pgoff_t index,
        return page;
 }
 
-void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
+int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
                int use_filler)
 {
        pgoff_t index = ofs >> PAGE_SHIFT;
@@ -80,8 +81,10 @@ void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
                copylen = min((ulong)len, PAGE_SIZE - offset);
 
                page = get_mapping_page(area->a_sb, index, use_filler);
-               SetPageUptodate(page);
+               if (IS_ERR(page))
+                       return PTR_ERR(page);
                BUG_ON(!page); /* FIXME: reserve a pool */
+               SetPageUptodate(page);
                memcpy(page_address(page) + offset, buf, copylen);
                SetPagePrivate(page);
                page_cache_release(page);
@@ -91,51 +94,60 @@ void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
                offset = 0;
                index++;
        } while (len);
+       return 0;
 }
 
-/*
- * bdev_writeseg will write full pages.  Memset the tail to prevent data leaks.
- */
-static void pad_wbuf(struct logfs_area *area, int final)
+static void pad_partial_page(struct logfs_area *area)
 {
        struct super_block *sb = area->a_sb;
-       struct logfs_super *super = logfs_super(sb);
        struct page *page;
        u64 ofs = dev_ofs(sb, area->a_segno, area->a_used_bytes);
        pgoff_t index = ofs >> PAGE_SHIFT;
        long offset = ofs & (PAGE_SIZE-1);
        u32 len = PAGE_SIZE - offset;
 
-       if (len == PAGE_SIZE) {
-               /* The math in this function can surely use some love */
-               len = 0;
-       }
-       if (len) {
-               BUG_ON(area->a_used_bytes >= super->s_segsize);
-
-               page = get_mapping_page(area->a_sb, index, 0);
+       if (len % PAGE_SIZE) {
+               page = get_mapping_page(sb, index, 0);
                BUG_ON(!page); /* FIXME: reserve a pool */
                memset(page_address(page) + offset, 0xff, len);
                SetPagePrivate(page);
                page_cache_release(page);
        }
+}
 
-       if (!final)
-               return;
+static void pad_full_pages(struct logfs_area *area)
+{
+       struct super_block *sb = area->a_sb;
+       struct logfs_super *super = logfs_super(sb);
+       u64 ofs = dev_ofs(sb, area->a_segno, area->a_used_bytes);
+       u32 len = super->s_segsize - area->a_used_bytes;
+       pgoff_t index = PAGE_CACHE_ALIGN(ofs) >> PAGE_CACHE_SHIFT;
+       pgoff_t no_indizes = len >> PAGE_CACHE_SHIFT;
+       struct page *page;
 
-       area->a_used_bytes += len;
-       for ( ; area->a_used_bytes < super->s_segsize;
-                       area->a_used_bytes += PAGE_SIZE) {
-               /* Memset another page */
-               index++;
-               page = get_mapping_page(area->a_sb, index, 0);
+       while (no_indizes) {
+               page = get_mapping_page(sb, index, 0);
                BUG_ON(!page); /* FIXME: reserve a pool */
-               memset(page_address(page), 0xff, PAGE_SIZE);
+               SetPageUptodate(page);
+               memset(page_address(page), 0xff, PAGE_CACHE_SIZE);
                SetPagePrivate(page);
                page_cache_release(page);
+               index++;
+               no_indizes--;
        }
 }
 
+/*
+ * bdev_writeseg will write full pages.  Memset the tail to prevent data leaks.
+ * Also make sure we allocate (and memset) all pages for final writeout.
+ */
+static void pad_wbuf(struct logfs_area *area, int final)
+{
+       pad_partial_page(area);
+       if (final)
+               pad_full_pages(area);
+}
+
 /*
  * We have to be careful with the alias tree.  Since lookup is done by bix,
  * it needs to be normalized, so 14, 15, 16, etc. all match when dealing with
@@ -174,14 +186,8 @@ static int btree_write_alias(struct super_block *sb, struct logfs_block *block,
        return 0;
 }
 
-static gc_level_t btree_block_level(struct logfs_block *block)
-{
-       return expand_level(block->ino, block->level);
-}
-
 static struct logfs_block_ops btree_block_ops = {
        .write_block    = btree_write_block,
-       .block_level    = btree_block_level,
        .free_block     = __free_block,
        .write_alias    = btree_write_alias,
 };
@@ -683,7 +689,7 @@ int logfs_segment_delete(struct inode *inode, struct logfs_shadow *shadow)
        return 0;
 }
 
-static void freeseg(struct super_block *sb, u32 segno)
+void freeseg(struct super_block *sb, u32 segno)
 {
        struct logfs_super *super = logfs_super(sb);
        struct address_space *mapping = super->s_mapping_inode->i_mapping;
@@ -910,7 +916,7 @@ err:
        for (i--; i >= 0; i--)
                free_area(super->s_area[i]);
        free_area(super->s_journal_area);
-       mempool_destroy(super->s_alias_pool);
+       logfs_mempool_destroy(super->s_alias_pool);
        return -ENOMEM;
 }
 
index c66beab78deedb5efd8fa5d7dfb27a7f4d78b95b..d651e10a1e9c1e589ed55269c0b1c9bab6488b83 100644 (file)
@@ -11,6 +11,8 @@
  */
 #include "logfs.h"
 #include <linux/bio.h>
+#include <linux/slab.h>
+#include <linux/blkdev.h>
 #include <linux/mtd/mtd.h>
 #include <linux/statfs.h>
 #include <linux/buffer_head.h>
@@ -136,6 +138,14 @@ static int logfs_sb_set(struct super_block *sb, void *_super)
        sb->s_fs_info = super;
        sb->s_mtd = super->s_mtd;
        sb->s_bdev = super->s_bdev;
+#ifdef CONFIG_BLOCK
+       if (sb->s_bdev)
+               sb->s_bdi = &bdev_get_queue(sb->s_bdev)->backing_dev_info;
+#endif
+#ifdef CONFIG_MTD
+       if (sb->s_mtd)
+               sb->s_bdi = sb->s_mtd->backing_dev_info;
+#endif
        return 0;
 }
 
@@ -277,7 +287,7 @@ static int logfs_recover_sb(struct super_block *sb)
        }
        if (valid0 && valid1 && ds_cmp(ds0, ds1)) {
                printk(KERN_INFO"Superblocks don't match - fixing.\n");
-               return write_one_sb(sb, super->s_devops->find_last_sb);
+               return logfs_write_sb(sb);
        }
        /* If neither is valid now, something's wrong.  Didn't we properly
         * check them before?!? */
@@ -289,6 +299,10 @@ static int logfs_make_writeable(struct super_block *sb)
 {
        int err;
 
+       err = logfs_open_segfile(sb);
+       if (err)
+               return err;
+
        /* Repair any broken superblock copies */
        err = logfs_recover_sb(sb);
        if (err)
@@ -299,10 +313,6 @@ static int logfs_make_writeable(struct super_block *sb)
        if (err)
                return err;
 
-       err = logfs_open_segfile(sb);
-       if (err)
-               return err;
-
        /* Do one GC pass before any data gets dirtied */
        logfs_gc_pass(sb);
 
@@ -327,27 +337,27 @@ static int logfs_get_sb_final(struct super_block *sb, struct vfsmount *mnt)
                goto fail;
 
        sb->s_root = d_alloc_root(rootdir);
-       if (!sb->s_root)
+       if (!sb->s_root) {
+               iput(rootdir);
                goto fail;
+       }
 
        super->s_erase_page = alloc_pages(GFP_KERNEL, 0);
        if (!super->s_erase_page)
-               goto fail2;
+               goto fail;
        memset(page_address(super->s_erase_page), 0xFF, PAGE_SIZE);
 
        /* FIXME: check for read-only mounts */
        err = logfs_make_writeable(sb);
        if (err)
-               goto fail3;
+               goto fail1;
 
        log_super("LogFS: Finished mounting\n");
        simple_set_mnt(mnt, sb);
        return 0;
 
-fail3:
+fail1:
        __free_page(super->s_erase_page);
-fail2:
-       iput(rootdir);
 fail:
        iput(logfs_super(sb)->s_master_inode);
        return -EIO;
@@ -376,7 +386,7 @@ static struct page *find_super_block(struct super_block *sb)
        if (!first || IS_ERR(first))
                return NULL;
        last = super->s_devops->find_last_sb(sb, &super->s_sb_ofs[1]);
-       if (!last || IS_ERR(first)) {
+       if (!last || IS_ERR(last)) {
                page_cache_release(first);
                return NULL;
        }
@@ -407,7 +417,7 @@ static int __logfs_read_sb(struct super_block *sb)
 
        page = find_super_block(sb);
        if (!page)
-               return -EIO;
+               return -EINVAL;
 
        ds = page_address(page);
        super->s_size = be64_to_cpu(ds->ds_filesystem_size);
@@ -451,6 +461,8 @@ static int logfs_read_sb(struct super_block *sb, int read_only)
 
        btree_init_mempool64(&super->s_shadow_tree.new, super->s_btree_pool);
        btree_init_mempool64(&super->s_shadow_tree.old, super->s_btree_pool);
+       btree_init_mempool32(&super->s_shadow_tree.segment_map,
+                       super->s_btree_pool);
 
        ret = logfs_init_mapping(sb);
        if (ret)
@@ -515,8 +527,8 @@ static void logfs_kill_sb(struct super_block *sb)
        if (super->s_erase_page)
                __free_page(super->s_erase_page);
        super->s_devops->put_device(sb);
-       mempool_destroy(super->s_btree_pool);
-       mempool_destroy(super->s_alias_pool);
+       logfs_mempool_destroy(super->s_btree_pool);
+       logfs_mempool_destroy(super->s_alias_pool);
        kfree(super);
        log_super("LogFS: Finished unmounting\n");
 }
@@ -572,8 +584,7 @@ int logfs_get_sb_device(struct file_system_type *type, int flags,
        return 0;
 
 err1:
-       up_write(&sb->s_umount);
-       deactivate_super(sb);
+       deactivate_locked_super(sb);
        return err;
 err0:
        kfree(super);
index 82d6554b02fec5a9f813ee9c026831c9db310455..282e15ad8cd8c8ce24da286263acbd284985ed17 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/buffer_head.h>
+#include <linux/slab.h>
 #include "minix.h"
 
 enum {DEPTH = 3, DIRECT = 7};  /* Only double indirect */
index 598d54e200ebea1e64d1a54f0416db04d2365aa0..fd56ca2ea55611314a841c9a65abba0c88b6ffa6 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/kdev_t.h>
+#include <linux/gfp.h>
 #include <linux/bio.h>
 #include <linux/fs.h>
 #include <linux/buffer_head.h>
index 1c0fca6e899eef7aa768ed704e2216c3d024c7df..b86b96fe1dc33926eb242a2a2e21061fe46145a5 100644 (file)
@@ -1610,8 +1610,7 @@ exit:
 
 static struct file *do_last(struct nameidata *nd, struct path *path,
                            int open_flag, int acc_mode,
-                           int mode, const char *pathname,
-                           int *want_dir)
+                           int mode, const char *pathname)
 {
        struct dentry *dir = nd->path.dentry;
        struct file *filp;
@@ -1642,7 +1641,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
        if (nd->last.name[nd->last.len]) {
                if (open_flag & O_CREAT)
                        goto exit;
-               *want_dir = 1;
+               nd->flags |= LOOKUP_DIRECTORY | LOOKUP_FOLLOW;
        }
 
        /* just plain open? */
@@ -1656,8 +1655,10 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
                if (path->dentry->d_inode->i_op->follow_link)
                        return NULL;
                error = -ENOTDIR;
-               if (*want_dir && !path->dentry->d_inode->i_op->lookup)
-                       goto exit_dput;
+               if (nd->flags & LOOKUP_DIRECTORY) {
+                       if (!path->dentry->d_inode->i_op->lookup)
+                               goto exit_dput;
+               }
                path_to_nameidata(path, nd);
                audit_inode(pathname, nd->path.dentry);
                goto ok;
@@ -1766,7 +1767,6 @@ struct file *do_filp_open(int dfd, const char *pathname,
        int count = 0;
        int flag = open_to_namei_flags(open_flag);
        int force_reval = 0;
-       int want_dir = open_flag & O_DIRECTORY;
 
        if (!(open_flag & O_CREAT))
                mode = 0;
@@ -1828,14 +1828,18 @@ reval:
                if (open_flag & O_EXCL)
                        nd.flags |= LOOKUP_EXCL;
        }
-       filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname, &want_dir);
+       if (open_flag & O_DIRECTORY)
+               nd.flags |= LOOKUP_DIRECTORY;
+       if (!(open_flag & O_NOFOLLOW))
+               nd.flags |= LOOKUP_FOLLOW;
+       filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname);
        while (unlikely(!filp)) { /* trailing symlink */
                struct path holder;
                struct inode *inode = path.dentry->d_inode;
                void *cookie;
                error = -ELOOP;
                /* S_ISDIR part is a temporary automount kludge */
-               if ((open_flag & O_NOFOLLOW) && !S_ISDIR(inode->i_mode))
+               if (!(nd.flags & LOOKUP_FOLLOW) && !S_ISDIR(inode->i_mode))
                        goto exit_dput;
                if (count++ == 32)
                        goto exit_dput;
@@ -1866,7 +1870,7 @@ reval:
                }
                holder = path;
                nd.flags &= ~LOOKUP_PARENT;
-               filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname, &want_dir);
+               filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname);
                if (inode->i_op->put_link)
                        inode->i_op->put_link(holder.dentry, &nd, cookie);
                path_put(&holder);
@@ -2172,8 +2176,10 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
                error = security_inode_rmdir(dir, dentry);
                if (!error) {
                        error = dir->i_op->rmdir(dir, dentry);
-                       if (!error)
+                       if (!error) {
                                dentry->d_inode->i_flags |= S_DEAD;
+                               dont_mount(dentry);
+                       }
                }
        }
        mutex_unlock(&dentry->d_inode->i_mutex);
@@ -2257,7 +2263,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
                if (!error) {
                        error = dir->i_op->unlink(dir, dentry);
                        if (!error)
-                               dentry->d_inode->i_flags |= S_DEAD;
+                               dont_mount(dentry);
                }
        }
        mutex_unlock(&dentry->d_inode->i_mutex);
@@ -2568,17 +2574,20 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
                return error;
 
        target = new_dentry->d_inode;
-       if (target) {
+       if (target)
                mutex_lock(&target->i_mutex);
-               dentry_unhash(new_dentry);
-       }
        if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
                error = -EBUSY;
-       else 
+       else {
+               if (target)
+                       dentry_unhash(new_dentry);
                error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
+       }
        if (target) {
-               if (!error)
+               if (!error) {
                        target->i_flags |= S_DEAD;
+                       dont_mount(new_dentry);
+               }
                mutex_unlock(&target->i_mutex);
                if (d_unhashed(new_dentry))
                        d_rehash(new_dentry);
@@ -2610,7 +2619,7 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
                error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
        if (!error) {
                if (target)
-                       target->i_flags |= S_DEAD;
+                       dont_mount(new_dentry);
                if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
                        d_move(old_dentry, new_dentry);
        }
index 8174c8ab5c70e71316403e2f879a51c77566e422..f20cb57d1067adc0b409a56a5881da45edf6692e 100644 (file)
@@ -1432,7 +1432,7 @@ static int graft_tree(struct vfsmount *mnt, struct path *path)
 
        err = -ENOENT;
        mutex_lock(&path->dentry->d_inode->i_mutex);
-       if (IS_DEADDIR(path->dentry->d_inode))
+       if (cant_mount(path->dentry))
                goto out_unlock;
 
        err = security_sb_check_sb(mnt, path);
@@ -1623,7 +1623,7 @@ static int do_move_mount(struct path *path, char *old_name)
 
        err = -ENOENT;
        mutex_lock(&path->dentry->d_inode->i_mutex);
-       if (IS_DEADDIR(path->dentry->d_inode))
+       if (cant_mount(path->dentry))
                goto out1;
 
        if (d_unlinked(path->dentry))
@@ -2234,7 +2234,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
        if (!check_mnt(root.mnt))
                goto out2;
        error = -ENOENT;
-       if (IS_DEADDIR(new.dentry->d_inode))
+       if (cant_mount(old.dentry))
                goto out2;
        if (d_unlinked(new.dentry))
                goto out2;
index b8b5b30d53f0c03a8c11c580bf29470225246293..7edfcd4d5e524b5ad1ace0f64a11f508437ef5c9 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/errno.h>
 #include <linux/stat.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 #include <asm/uaccess.h>
index 6a7d901f1936e555a530981c6fc6e53bab000f00..1daabb90e0a54bba1a3c65146fb7098b3fdb8218 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/fcntl.h>
 #include <linux/stat.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
index cf98da1be23e861dbbeedc76849969f0fa454aff..fa3385154023484659003aeb98b6f421c5eb3b4a 100644 (file)
@@ -526,10 +526,15 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
        sb->s_blocksize_bits = 10;
        sb->s_magic = NCP_SUPER_MAGIC;
        sb->s_op = &ncp_sops;
+       sb->s_bdi = &server->bdi;
 
        server = NCP_SBP(sb);
        memset(server, 0, sizeof(*server));
 
+       error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY);
+       if (error)
+               goto out_bdi;
+
        server->ncp_filp = ncp_filp;
        server->ncp_sock = sock;
        
@@ -719,6 +724,8 @@ out_fput2:
        if (server->info_filp)
                fput(server->info_filp);
 out_fput:
+       bdi_destroy(&server->bdi);
+out_bdi:
        /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
         * 
         * The previously used put_filp(ncp_filp); was bogous, since
@@ -756,6 +763,7 @@ static void ncp_put_super(struct super_block *sb)
        kill_pid(server->m.wdog_pid, SIGTERM, 1);
        put_pid(server->m.wdog_pid);
 
+       bdi_destroy(&server->bdi);
        kfree(server->priv.data);
        kfree(server->auth.object_name);
        vfree(server->rxbuf);
index ec8f45f12e058ff7ee73869b2c1a425ce6f45f16..60a5e2864ea8b9b97e41de53875480959e17400f 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/mount.h>
+#include <linux/slab.h>
 #include <linux/highuid.h>
 #include <linux/smp_lock.h>
 #include <linux/vmalloc.h>
index 15458decdb8a33b547f7f3fb401e2ca4ac169d71..56f5b3a0e1ee3c4c5383f858fd297c6e787ba57b 100644 (file)
@@ -9,12 +9,12 @@
 #include <linux/stat.h>
 #include <linux/time.h>
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/shm.h>
 #include <linux/errno.h>
 #include <linux/mman.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/fcntl.h>
 #include <linux/ncp_fs.h>
 
index e37df8d5fe707968d0720de94b45c6a4bf5d8f2e..c7ff6c700a6efdca195b43a18414e221ecafc824 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/mm.h>
 #include <linux/netdevice.h>
 #include <linux/signal.h>
+#include <linux/slab.h>
 #include <net/scm.h>
 #include <net/sock.h>
 #include <linux/ipx.h>
index e3d26c1bd105a388cf032c3586b192e6b5e56907..c634fd17b337ceffdb4e21c1a143955dd166f66a 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/fs.h>
 #include <linux/ncp_fs.h>
 #include <linux/time.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/stat.h>
 #include "ncplib_kernel.h"
index b4ffd0146ea61cb2c4ff80fa098d7f1a45200976..84690319e625d5ef35aadeee5d9535291f9ffd5e 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/moduleparam.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
+#include <linux/slab.h>
 #include <linux/sunrpc/cache.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
 
index 84761b5bb8e22142fd8eaefa82e48d1af927ee3c..a08770a7e857bf10ef5f21f9e10d1465c2c9ce88 100644 (file)
@@ -7,6 +7,7 @@
  */
 #include <linux/nfs4.h>
 #include <linux/nfs_fs.h>
+#include <linux/slab.h>
 #include "nfs4_fs.h"
 #include "callback.h"
 #include "delegation.h"
index db30c0b398b5809b6bd892f8cc9b8bb987a23603..05af212f0edfb1558e238bb0ce95a5ef7688987f 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/sunrpc/svc.h>
 #include <linux/nfs4.h>
 #include <linux/nfs_fs.h>
+#include <linux/slab.h>
 #include "nfs4_fs.h"
 #include "callback.h"
 
@@ -782,6 +783,7 @@ struct svc_version nfs4_callback_version1 = {
        .vs_proc = nfs4_callback_procedures1,
        .vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
        .vs_dispatch = NULL,
+       .vs_hidden = 1,
 };
 
 struct svc_version nfs4_callback_version4 = {
index 2274f1737336485f30fcfd7fdfab841e9bc39600..acc9c4943b84723639cdcf88dd2656c06c67010f 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/vfs.h>
 #include <linux/inet.h>
 #include <linux/in6.h>
+#include <linux/slab.h>
 #include <net/ipv6.h>
 #include <linux/nfs_xdr.h>
 #include <linux/sunrpc/bc_xprt.h>
@@ -965,6 +966,8 @@ out_error:
 static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source)
 {
        target->flags = source->flags;
+       target->rsize = source->rsize;
+       target->wsize = source->wsize;
        target->acregmin = source->acregmin;
        target->acregmax = source->acregmax;
        target->acdirmin = source->acdirmin;
@@ -1293,7 +1296,8 @@ static int nfs4_init_server(struct nfs_server *server,
 
        /* Initialise the client representation from the mount data */
        server->flags = data->flags;
-       server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR;
+       server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR|
+               NFS_CAP_POSIX_LOCK;
        server->options = data->options;
 
        /* Get a client record */
index 2563bebc4c670915f73de93625411062a52f3582..ea61d26e7871bcb72e939a4dee96ebc330b579a2 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kthread.h>
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 
@@ -23,6 +24,8 @@
 
 static void nfs_do_free_delegation(struct nfs_delegation *delegation)
 {
+       if (delegation->cred)
+               put_rpccred(delegation->cred);
        kfree(delegation);
 }
 
@@ -35,13 +38,7 @@ static void nfs_free_delegation_callback(struct rcu_head *head)
 
 static void nfs_free_delegation(struct nfs_delegation *delegation)
 {
-       struct rpc_cred *cred;
-
-       cred = rcu_dereference(delegation->cred);
-       rcu_assign_pointer(delegation->cred, NULL);
        call_rcu(&delegation->rcu, nfs_free_delegation_callback);
-       if (cred)
-               put_rpccred(cred);
 }
 
 void nfs_mark_delegation_referenced(struct nfs_delegation *delegation)
@@ -128,21 +125,35 @@ again:
  */
 void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res)
 {
-       struct nfs_delegation *delegation = NFS_I(inode)->delegation;
-       struct rpc_cred *oldcred;
+       struct nfs_delegation *delegation;
+       struct rpc_cred *oldcred = NULL;
 
-       if (delegation == NULL)
-               return;
-       memcpy(delegation->stateid.data, res->delegation.data,
-                       sizeof(delegation->stateid.data));
-       delegation->type = res->delegation_type;
-       delegation->maxsize = res->maxsize;
-       oldcred = delegation->cred;
-       delegation->cred = get_rpccred(cred);
-       clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
-       NFS_I(inode)->delegation_state = delegation->type;
-       smp_wmb();
-       put_rpccred(oldcred);
+       rcu_read_lock();
+       delegation = rcu_dereference(NFS_I(inode)->delegation);
+       if (delegation != NULL) {
+               spin_lock(&delegation->lock);
+               if (delegation->inode != NULL) {
+                       memcpy(delegation->stateid.data, res->delegation.data,
+                              sizeof(delegation->stateid.data));
+                       delegation->type = res->delegation_type;
+                       delegation->maxsize = res->maxsize;
+                       oldcred = delegation->cred;
+                       delegation->cred = get_rpccred(cred);
+                       clear_bit(NFS_DELEGATION_NEED_RECLAIM,
+                                 &delegation->flags);
+                       NFS_I(inode)->delegation_state = delegation->type;
+                       spin_unlock(&delegation->lock);
+                       put_rpccred(oldcred);
+                       rcu_read_unlock();
+               } else {
+                       /* We appear to have raced with a delegation return. */
+                       spin_unlock(&delegation->lock);
+                       rcu_read_unlock();
+                       nfs_inode_set_delegation(inode, cred, res);
+               }
+       } else {
+               rcu_read_unlock();
+       }
 }
 
 static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
@@ -165,9 +176,13 @@ static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation
        return inode;
 }
 
-static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi, const nfs4_stateid *stateid)
+static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi,
+                                                          const nfs4_stateid *stateid,
+                                                          struct nfs_client *clp)
 {
-       struct nfs_delegation *delegation = rcu_dereference(nfsi->delegation);
+       struct nfs_delegation *delegation =
+               rcu_dereference_protected(nfsi->delegation,
+                                         lockdep_is_held(&clp->cl_lock));
 
        if (delegation == NULL)
                goto nomatch;
@@ -194,7 +209,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
 {
        struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
        struct nfs_inode *nfsi = NFS_I(inode);
-       struct nfs_delegation *delegation;
+       struct nfs_delegation *delegation, *old_delegation;
        struct nfs_delegation *freeme = NULL;
        int status = 0;
 
@@ -212,10 +227,12 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
        spin_lock_init(&delegation->lock);
 
        spin_lock(&clp->cl_lock);
-       if (rcu_dereference(nfsi->delegation) != NULL) {
-               if (memcmp(&delegation->stateid, &nfsi->delegation->stateid,
-                                       sizeof(delegation->stateid)) == 0 &&
-                               delegation->type == nfsi->delegation->type) {
+       old_delegation = rcu_dereference_protected(nfsi->delegation,
+                                                  lockdep_is_held(&clp->cl_lock));
+       if (old_delegation != NULL) {
+               if (memcmp(&delegation->stateid, &old_delegation->stateid,
+                                       sizeof(old_delegation->stateid)) == 0 &&
+                               delegation->type == old_delegation->type) {
                        goto out;
                }
                /*
@@ -225,12 +242,12 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
                dfprintk(FILE, "%s: server %s handed out "
                                "a duplicate delegation!\n",
                                __func__, clp->cl_hostname);
-               if (delegation->type <= nfsi->delegation->type) {
+               if (delegation->type <= old_delegation->type) {
                        freeme = delegation;
                        delegation = NULL;
                        goto out;
                }
-               freeme = nfs_detach_delegation_locked(nfsi, NULL);
+               freeme = nfs_detach_delegation_locked(nfsi, NULL, clp);
        }
        list_add_rcu(&delegation->super_list, &clp->cl_delegations);
        nfsi->delegation_state = delegation->type;
@@ -300,7 +317,7 @@ restart:
                if (inode == NULL)
                        continue;
                spin_lock(&clp->cl_lock);
-               delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
+               delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL, clp);
                spin_unlock(&clp->cl_lock);
                rcu_read_unlock();
                if (delegation != NULL) {
@@ -329,9 +346,9 @@ void nfs_inode_return_delegation_noreclaim(struct inode *inode)
        struct nfs_inode *nfsi = NFS_I(inode);
        struct nfs_delegation *delegation;
 
-       if (rcu_dereference(nfsi->delegation) != NULL) {
+       if (rcu_access_pointer(nfsi->delegation) != NULL) {
                spin_lock(&clp->cl_lock);
-               delegation = nfs_detach_delegation_locked(nfsi, NULL);
+               delegation = nfs_detach_delegation_locked(nfsi, NULL, clp);
                spin_unlock(&clp->cl_lock);
                if (delegation != NULL)
                        nfs_do_return_delegation(inode, delegation, 0);
@@ -345,9 +362,9 @@ int nfs_inode_return_delegation(struct inode *inode)
        struct nfs_delegation *delegation;
        int err = 0;
 
-       if (rcu_dereference(nfsi->delegation) != NULL) {
+       if (rcu_access_pointer(nfsi->delegation) != NULL) {
                spin_lock(&clp->cl_lock);
-               delegation = nfs_detach_delegation_locked(nfsi, NULL);
+               delegation = nfs_detach_delegation_locked(nfsi, NULL, clp);
                spin_unlock(&clp->cl_lock);
                if (delegation != NULL) {
                        nfs_msync_inode(inode);
@@ -525,7 +542,7 @@ restart:
                if (inode == NULL)
                        continue;
                spin_lock(&clp->cl_lock);
-               delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
+               delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL, clp);
                spin_unlock(&clp->cl_lock);
                rcu_read_unlock();
                if (delegation != NULL)
index 944b627ec6e1a956340ee8c0464b5510b185b336..69e7b8140122d7ed4feec5e5fad1dddb307ae150 100644 (file)
@@ -71,4 +71,10 @@ static inline int nfs_inode_return_delegation(struct inode *inode)
 }
 #endif
 
+static inline int nfs_have_delegated_attributes(struct inode *inode)
+{
+       return nfs_have_delegation(inode, FMODE_READ) &&
+               !(NFS_I(inode)->cache_validity & NFS_INO_REVAL_FORCED);
+}
+
 #endif
index a1f6b4438fb12cbd5b49a648b986f58354079bf0..a7bb5c694aa303640640938e0a87670aaba9545c 100644 (file)
@@ -837,6 +837,8 @@ out_zap_parent:
                /* If we have submounts, don't unhash ! */
                if (have_submounts(dentry))
                        goto out_valid;
+               if (dentry->d_flags & DCACHE_DISCONNECTED)
+                       goto out_valid;
                shrink_dcache_parent(dentry);
        }
        d_drop(dentry);
@@ -1025,12 +1027,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
                                res = NULL;
                                goto out;
                        /* This turned out not to be a regular file */
+                       case -EISDIR:
                        case -ENOTDIR:
                                goto no_open;
                        case -ELOOP:
                                if (!(nd->intent.open.flags & O_NOFOLLOW))
                                        goto no_open;
-                       /* case -EISDIR: */
                        /* case -EINVAL: */
                        default:
                                goto out;
@@ -1050,7 +1052,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
        struct inode *dir;
        int openflags, ret = 0;
 
-       if (!is_atomic_open(nd))
+       if (!is_atomic_open(nd) || d_mountpoint(dentry))
                goto no_open;
        parent = dget_parent(dentry);
        dir = parent->d_inode;
@@ -1789,7 +1791,7 @@ static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, str
        cache = nfs_access_search_rbtree(inode, cred);
        if (cache == NULL)
                goto out;
-       if (!nfs_have_delegation(inode, FMODE_READ) &&
+       if (!nfs_have_delegated_attributes(inode) &&
            !time_in_range_open(jiffies, cache->jiffies, cache->jiffies + nfsi->attrtimeo))
                goto out_stale;
        res->jiffies = cache->jiffies;
index 0d289823e8564b49969710e4c16688abbc61b15d..ad4cd31d6050d22c2a6267b005bab48b84f70f66 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/file.h>
 #include <linux/pagemap.h>
 #include <linux/kref.h>
+#include <linux/slab.h>
 
 #include <linux/nfs_fs.h>
 #include <linux/nfs_page.h>
index 3f0cd4dfddaf809d710dd1f53d19dae987105615..76fd235d0024e1970d44044536d2d929c02b9256 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/hash.h>
 #include <linux/string.h>
 #include <linux/kmod.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/socket.h>
 #include <linux/seq_file.h>
index ae8d02294e462283eb2c421048dc381c8d87bf36..8d965bddb87e6f5c8d340eec081ac03d88084047 100644 (file)
@@ -24,9 +24,9 @@
 #include <linux/nfs_fs.h>
 #include <linux/nfs_mount.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/aio.h>
+#include <linux/gfp.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -491,7 +491,8 @@ static int nfs_release_page(struct page *page, gfp_t gfp)
 {
        dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page);
 
-       if (gfp & __GFP_WAIT)
+       /* Only do I/O if gfp is a superset of GFP_KERNEL */
+       if ((gfp & GFP_KERNEL) == GFP_KERNEL)
                nfs_wb_page(page->mapping->host, page);
        /* If PagePrivate() is set, then the page is not freeable */
        if (PagePrivate(page))
index 237874f1af23697d3d092147eaa39bcf25958006..a6b16ed932291cb524d90feb49ae4ab48f878032 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/nfs_fs_sb.h>
 #include <linux/in6.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include "internal.h"
 #include "iostat.h"
index 657201acda84ba2232851971b098787eb1a0b2f4..50a56edca0b572fc7bd274ab809f3df7b4f4d031 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/vfs.h>
 #include <linux/inet.h>
 #include <linux/nfs_xdr.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -622,10 +623,10 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c
        list_for_each_entry(pos, &nfsi->open_files, list) {
                if (cred != NULL && pos->cred != cred)
                        continue;
-               if ((pos->mode & mode) == mode) {
-                       ctx = get_nfs_open_context(pos);
-                       break;
-               }
+               if ((pos->mode & (FMODE_READ|FMODE_WRITE)) != mode)
+                       continue;
+               ctx = get_nfs_open_context(pos);
+               break;
        }
        spin_unlock(&inode->i_lock);
        return ctx;
@@ -729,7 +730,7 @@ int nfs_attribute_timeout(struct inode *inode)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
 
-       if (nfs_have_delegation(inode, FMODE_READ))
+       if (nfs_have_delegated_attributes(inode))
                return 0;
        return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
 }
index 40c76678289168ed0cbbe3e653f58485a56003eb..7888cf36022d2dee78b983ff216a8371ee89164c 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/dcache.h>
+#include <linux/gfp.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/nfs_fs.h>
index 7bc2da8efd4a352a962d8aac259cd6279fe3f6eb..81cf142579167e9654b3332348e92e3eee48c37b 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/param.h>
 #include <linux/time.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/in.h>
index bac60515a4b35437c95b9cbd3ebfd8e01f177d89..d150ae0c5ecd5ccfef5260bc2985f0a446a9a803 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <linux/nfs.h>
 #include <linux/nfs3.h>
 #include <linux/nfs_fs.h>
index 24992f0a29f22b12c753004c065f23f34d19df36..e701002694e5687fa43f0ae5b2e3daaa5569df13 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/sunrpc/clnt.h>
+#include <linux/slab.h>
 #include <linux/nfs.h>
 #include <linux/nfs3.h>
 #include <linux/nfs_fs.h>
index 5fe5492fbd29e51fab41de8930b29f6863e76747..56a86f6ac8b5cc3c4b79cd5f2fbe1c6d9874a4f8 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/param.h>
 #include <linux/time.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/in.h>
index fa3408f201126790eb66ac42db7eff3b12f345e4..f071d12c613b621433dab4b0e498f0b8c979575f 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/nfs_fs.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/vfs.h>
index eda74c42d552a044b5ba3b8541b9034cc29afff8..071fcedd517caecc0ab7cd3cb38c482a3abf4a4d 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/nfs.h>
 #include <linux/nfs4.h>
@@ -1522,6 +1523,8 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
                nfs_post_op_update_inode(dir, o_res->dir_attr);
        } else
                nfs_refresh_inode(dir, o_res->dir_attr);
+       if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0)
+               server->caps &= ~NFS_CAP_POSIX_LOCK;
        if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
                status = _nfs4_proc_open_confirm(data);
                if (status != 0)
@@ -1663,7 +1666,7 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in
        status = PTR_ERR(state);
        if (IS_ERR(state))
                goto err_opendata_put;
-       if ((opendata->o_res.rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) != 0)
+       if (server->caps & NFS_CAP_POSIX_LOCK)
                set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
        nfs4_opendata_put(opendata);
        nfs4_put_state_owner(sp);
@@ -2067,8 +2070,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
                        case -EDQUOT:
                        case -ENOSPC:
                        case -EROFS:
-                               lookup_instantiate_filp(nd, (struct dentry *)state, NULL);
-                               return 1;
+                               return PTR_ERR(state);
                        default:
                                goto out_drop;
                }
@@ -5107,6 +5109,7 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp,
        res = kzalloc(sizeof(*res), GFP_KERNEL);
        if (!args || !res) {
                kfree(args);
+               kfree(res);
                nfs_put_client(clp);
                return -ENOMEM;
        }
@@ -5215,9 +5218,12 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp)
        msg.rpc_resp = &calldata->res;
        task_setup_data.callback_data = calldata;
        task = rpc_run_task(&task_setup_data);
-       if (IS_ERR(task))
+       if (IS_ERR(task)) {
                status = PTR_ERR(task);
+               goto out;
+       }
        rpc_put_task(task);
+       return 0;
 out:
        dprintk("<-- %s status=%d\n", __func__, status);
        return status;
index 4d338be492cb28f6e91ae9eecfe30af64555154d..38f3b582e7c246c4552b2b1b11a618b8eff93f26 100644 (file)
@@ -38,7 +38,6 @@
 #include <linux/param.h>
 #include <linux/time.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/in.h>
@@ -5552,6 +5551,8 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nf
        if (status != 0)
                goto out;
        status = decode_delegreturn(&xdr);
+       if (status != 0)
+               goto out;
        decode_getfattr(&xdr, res->fattr, res->server,
                        !RPC_IS_ASYNC(rqstp->rq_task));
 out:
index a12c45b65dd42bc1712f23c7050923a6d83eed28..29d9d36cd5f431e603fcae5daccebbd5d62d7fa3 100644 (file)
@@ -112,12 +112,10 @@ void nfs_unlock_request(struct nfs_page *req)
  */
 int nfs_set_page_tag_locked(struct nfs_page *req)
 {
-       struct nfs_inode *nfsi = NFS_I(req->wb_context->path.dentry->d_inode);
-
        if (!nfs_lock_request_dontget(req))
                return 0;
        if (req->wb_page != NULL)
-               radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
+               radix_tree_tag_set(&NFS_I(req->wb_context->path.dentry->d_inode)->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
        return 1;
 }
 
@@ -126,10 +124,10 @@ int nfs_set_page_tag_locked(struct nfs_page *req)
  */
 void nfs_clear_page_tag_locked(struct nfs_page *req)
 {
-       struct inode *inode = req->wb_context->path.dentry->d_inode;
-       struct nfs_inode *nfsi = NFS_I(inode);
-
        if (req->wb_page != NULL) {
+               struct inode *inode = req->wb_context->path.dentry->d_inode;
+               struct nfs_inode *nfsi = NFS_I(inode);
+
                spin_lock(&inode->i_lock);
                radix_tree_tag_clear(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
                nfs_unlock_request(req);
@@ -142,16 +140,22 @@ void nfs_clear_page_tag_locked(struct nfs_page *req)
  * nfs_clear_request - Free up all resources allocated to the request
  * @req:
  *
- * Release page resources associated with a write request after it
- * has completed.
+ * Release page and open context resources associated with a read/write
+ * request after it has completed.
  */
 void nfs_clear_request(struct nfs_page *req)
 {
        struct page *page = req->wb_page;
+       struct nfs_open_context *ctx = req->wb_context;
+
        if (page != NULL) {
                page_cache_release(page);
                req->wb_page = NULL;
        }
+       if (ctx != NULL) {
+               put_nfs_open_context(ctx);
+               req->wb_context = NULL;
+       }
 }
 
 
@@ -165,9 +169,8 @@ static void nfs_free_request(struct kref *kref)
 {
        struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref);
 
-       /* Release struct file or cached credential */
+       /* Release struct file and open context */
        nfs_clear_request(req);
-       put_nfs_open_context(req->wb_context);
        nfs_page_free(req);
 }
 
index c752d944fe9e93e2cf1759b49e6c671a1caaa7b7..0288be80444fc6b3e1e29f2b504cf55acc294740 100644 (file)
@@ -29,7 +29,6 @@
 
 #include <linux/types.h>
 #include <linux/param.h>
-#include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
index f1afee4eea77b8eaf9229897a7d23d61e12007b8..b4148fc00f9fb54e8c2aeadbc0faf05f113b86b0 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/vfs.h>
 #include <linux/inet.h>
 #include <linux/in6.h>
+#include <linux/slab.h>
 #include <net/ipv6.h>
 #include <linux/netdevice.h>
 #include <linux/nfs_xdr.h>
@@ -2186,6 +2187,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
        if (data->version == 4) {
                error = nfs4_try_mount(flags, dev_name, data, mnt);
                kfree(data->client_address);
+               kfree(data->nfs_server.export_path);
                goto out;
        }
 #endif /* CONFIG_NFS_V4 */
@@ -2214,7 +2216,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
        } else {
                error = nfs_bdi_register(server);
                if (error)
-                       goto error_splat_super;
+                       goto error_splat_bdi;
        }
 
        if (!s->s_root) {
@@ -2256,6 +2258,9 @@ out_err_nosb:
 error_splat_root:
        dput(mntroot);
 error_splat_super:
+       if (server && !s->s_root)
+               bdi_unregister(&server->backing_dev_info);
+error_splat_bdi:
        deactivate_locked_super(s);
        goto out;
 }
@@ -2326,7 +2331,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
        } else {
                error = nfs_bdi_register(server);
                if (error)
-                       goto error_splat_super;
+                       goto error_splat_bdi;
        }
 
        if (!s->s_root) {
@@ -2363,6 +2368,9 @@ out_err_noserver:
        return error;
 
 error_splat_super:
+       if (server && !s->s_root)
+               bdi_unregister(&server->backing_dev_info);
+error_splat_bdi:
        deactivate_locked_super(s);
        dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error);
        return error;
@@ -2578,7 +2586,7 @@ static int nfs4_remote_get_sb(struct file_system_type *fs_type,
        } else {
                error = nfs_bdi_register(server);
                if (error)
-                       goto error_splat_super;
+                       goto error_splat_bdi;
        }
 
        if (!s->s_root) {
@@ -2616,6 +2624,9 @@ out_free:
 error_splat_root:
        dput(mntroot);
 error_splat_super:
+       if (server && !s->s_root)
+               bdi_unregister(&server->backing_dev_info);
+error_splat_bdi:
        deactivate_locked_super(s);
        goto out;
 }
@@ -2647,7 +2658,7 @@ static void nfs_fix_devname(const struct path *path, struct vfsmount *mnt)
        devname = nfs_path(path->mnt->mnt_devname,
                        path->mnt->mnt_root, path->dentry,
                        page, PAGE_SIZE);
-       if (devname == NULL)
+       if (IS_ERR(devname))
                goto out_freepage;
        tmp = kstrdup(devname, GFP_KERNEL);
        if (tmp == NULL)
@@ -2811,7 +2822,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
        } else {
                error = nfs_bdi_register(server);
                if (error)
-                       goto error_splat_super;
+                       goto error_splat_bdi;
        }
 
        if (!s->s_root) {
@@ -2847,6 +2858,9 @@ out_err_noserver:
        return error;
 
 error_splat_super:
+       if (server && !s->s_root)
+               bdi_unregister(&server->backing_dev_info);
+error_splat_bdi:
        deactivate_locked_super(s);
        dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error);
        return error;
@@ -2893,7 +2907,7 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type,
        } else {
                error = nfs_bdi_register(server);
                if (error)
-                       goto error_splat_super;
+                       goto error_splat_bdi;
        }
 
        if (!s->s_root) {
@@ -2929,6 +2943,9 @@ out_err_noserver:
        return error;
 
 error_splat_super:
+       if (server && !s->s_root)
+               bdi_unregister(&server->backing_dev_info);
+error_splat_bdi:
        deactivate_locked_super(s);
        dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
        return error;
index 2ea9e5c27e5521d10b82d893b316c43c85ccad57..05c9e02f4153e340d94035bfdef6cc8db34b5a06 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/pagemap.h>
 #include <linux/stat.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/namei.h>
 
index 53ff70e2399335a408a38c6f779282c1663a2f30..3aea3ca98ab788c5dae67c0769ff723eb9b94217 100644 (file)
@@ -201,6 +201,7 @@ static int nfs_set_page_writeback(struct page *page)
                struct inode *inode = page->mapping->host;
                struct nfs_server *nfss = NFS_SERVER(inode);
 
+               page_cache_get(page);
                if (atomic_long_inc_return(&nfss->writeback) >
                                NFS_CONGESTION_ON_THRESH) {
                        set_bdi_congested(&nfss->backing_dev_info,
@@ -216,6 +217,7 @@ static void nfs_end_page_writeback(struct page *page)
        struct nfs_server *nfss = NFS_SERVER(inode);
 
        end_page_writeback(page);
+       page_cache_release(page);
        if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH)
                clear_bdi_congested(&nfss->backing_dev_info, BLK_RW_ASYNC);
 }
@@ -421,6 +423,7 @@ static void
 nfs_mark_request_dirty(struct nfs_page *req)
 {
        __set_page_dirty_nobuffers(req->wb_page);
+       __mark_inode_dirty(req->wb_page->mapping->host, I_DIRTY_DATASYNC);
 }
 
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
@@ -660,9 +663,11 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
        req = nfs_setup_write_request(ctx, page, offset, count);
        if (IS_ERR(req))
                return PTR_ERR(req);
+       nfs_mark_request_dirty(req);
        /* Update file length */
        nfs_grow_file(page, offset, count);
        nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes);
+       nfs_mark_request_dirty(req);
        nfs_clear_page_tag_locked(req);
        return 0;
 }
@@ -739,8 +744,6 @@ int nfs_updatepage(struct file *file, struct page *page,
        status = nfs_writepage_setup(ctx, page, offset, count);
        if (status < 0)
                nfs_set_pageerror(page);
-       else
-               __set_page_dirty_nobuffers(page);
 
        dprintk("NFS:       nfs_updatepage returns %d (isize %lld)\n",
                        status, (long long)i_size_read(inode));
@@ -749,13 +752,12 @@ int nfs_updatepage(struct file *file, struct page *page,
 
 static void nfs_writepage_release(struct nfs_page *req)
 {
+       struct page *page = req->wb_page;
 
-       if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req)) {
-               nfs_end_page_writeback(req->wb_page);
+       if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req))
                nfs_inode_remove_request(req);
-       } else
-               nfs_end_page_writeback(req->wb_page);
        nfs_clear_page_tag_locked(req);
+       nfs_end_page_writeback(page);
 }
 
 static int flush_task_priority(int how)
@@ -779,7 +781,6 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
                int how)
 {
        struct inode *inode = req->wb_context->path.dentry->d_inode;
-       int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
        int priority = flush_task_priority(how);
        struct rpc_task *task;
        struct rpc_message msg = {
@@ -794,9 +795,10 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
                .callback_ops = call_ops,
                .callback_data = data,
                .workqueue = nfsiod_workqueue,
-               .flags = flags,
+               .flags = RPC_TASK_ASYNC,
                .priority = priority,
        };
+       int ret = 0;
 
        /* Set up the RPC argument and reply structs
         * NB: take care not to mess about with data->commit et al. */
@@ -835,10 +837,18 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
                (unsigned long long)data->args.offset);
 
        task = rpc_run_task(&task_setup_data);
-       if (IS_ERR(task))
-               return PTR_ERR(task);
+       if (IS_ERR(task)) {
+               ret = PTR_ERR(task);
+               goto out;
+       }
+       if (how & FLUSH_SYNC) {
+               ret = rpc_wait_for_completion_task(task);
+               if (ret == 0)
+                       ret = task->tk_status;
+       }
        rpc_put_task(task);
-       return 0;
+out:
+       return ret;
 }
 
 /* If a nfs_flush_* function fails, it should remove reqs from @head and
@@ -847,9 +857,11 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
  */
 static void nfs_redirty_request(struct nfs_page *req)
 {
+       struct page *page = req->wb_page;
+
        nfs_mark_request_dirty(req);
-       nfs_end_page_writeback(req->wb_page);
        nfs_clear_page_tag_locked(req);
+       nfs_end_page_writeback(page);
 }
 
 /*
@@ -1084,16 +1096,15 @@ static void nfs_writeback_release_full(void *calldata)
                if (nfs_write_need_commit(data)) {
                        memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf));
                        nfs_mark_request_commit(req);
-                       nfs_end_page_writeback(page);
                        dprintk(" marked for commit\n");
                        goto next;
                }
                dprintk(" OK\n");
 remove_request:
-               nfs_end_page_writeback(page);
                nfs_inode_remove_request(req);
        next:
                nfs_clear_page_tag_locked(req);
+               nfs_end_page_writeback(page);
        }
        nfs_writedata_release(calldata);
 }
@@ -1190,6 +1201,25 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
 
 
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
+static int nfs_commit_set_lock(struct nfs_inode *nfsi, int may_wait)
+{
+       if (!test_and_set_bit(NFS_INO_COMMIT, &nfsi->flags))
+               return 1;
+       if (may_wait && !out_of_line_wait_on_bit_lock(&nfsi->flags,
+                               NFS_INO_COMMIT, nfs_wait_bit_killable,
+                               TASK_KILLABLE))
+               return 1;
+       return 0;
+}
+
+static void nfs_commit_clear_lock(struct nfs_inode *nfsi)
+{
+       clear_bit(NFS_INO_COMMIT, &nfsi->flags);
+       smp_mb__after_clear_bit();
+       wake_up_bit(&nfsi->flags, NFS_INO_COMMIT);
+}
+
+
 static void nfs_commitdata_release(void *data)
 {
        struct nfs_write_data *wdata = data;
@@ -1207,7 +1237,6 @@ static int nfs_commit_rpcsetup(struct list_head *head,
 {
        struct nfs_page *first = nfs_list_entry(head->next);
        struct inode *inode = first->wb_context->path.dentry->d_inode;
-       int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
        int priority = flush_task_priority(how);
        struct rpc_task *task;
        struct rpc_message msg = {
@@ -1222,7 +1251,7 @@ static int nfs_commit_rpcsetup(struct list_head *head,
                .callback_ops = &nfs_commit_ops,
                .callback_data = data,
                .workqueue = nfsiod_workqueue,
-               .flags = flags,
+               .flags = RPC_TASK_ASYNC,
                .priority = priority,
        };
 
@@ -1282,6 +1311,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how)
                                BDI_RECLAIMABLE);
                nfs_clear_page_tag_locked(req);
        }
+       nfs_commit_clear_lock(NFS_I(inode));
        return -ENOMEM;
 }
 
@@ -1337,6 +1367,7 @@ static void nfs_commit_release(void *calldata)
        next:
                nfs_clear_page_tag_locked(req);
        }
+       nfs_commit_clear_lock(NFS_I(data->inode));
        nfs_commitdata_release(calldata);
 }
 
@@ -1351,8 +1382,11 @@ static const struct rpc_call_ops nfs_commit_ops = {
 static int nfs_commit_inode(struct inode *inode, int how)
 {
        LIST_HEAD(head);
-       int res;
+       int may_wait = how & FLUSH_SYNC;
+       int res = 0;
 
+       if (!nfs_commit_set_lock(NFS_I(inode), may_wait))
+               goto out;
        spin_lock(&inode->i_lock);
        res = nfs_scan_commit(inode, &head, 0, 0);
        spin_unlock(&inode->i_lock);
@@ -1360,7 +1394,13 @@ static int nfs_commit_inode(struct inode *inode, int how)
                int error = nfs_commit_list(inode, &head, how);
                if (error < 0)
                        return error;
-       }
+               if (may_wait)
+                       wait_on_bit(&NFS_I(inode)->flags, NFS_INO_COMMIT,
+                                       nfs_wait_bit_killable,
+                                       TASK_KILLABLE);
+       } else
+               nfs_commit_clear_lock(NFS_I(inode));
+out:
        return res;
 }
 
@@ -1432,6 +1472,7 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page)
 
        BUG_ON(!PageLocked(page));
        for (;;) {
+               wait_on_page_writeback(page);
                req = nfs_page_find_request(page);
                if (req == NULL)
                        break;
@@ -1466,30 +1507,18 @@ int nfs_wb_page(struct inode *inode, struct page *page)
                .range_start = range_start,
                .range_end = range_end,
        };
-       struct nfs_page *req;
-       int need_commit;
        int ret;
 
        while(PagePrivate(page)) {
+               wait_on_page_writeback(page);
                if (clear_page_dirty_for_io(page)) {
                        ret = nfs_writepage_locked(page, &wbc);
                        if (ret < 0)
                                goto out_error;
                }
-               req = nfs_find_and_lock_request(page);
-               if (!req)
-                       break;
-               if (IS_ERR(req)) {
-                       ret = PTR_ERR(req);
+               ret = sync_inode(inode, &wbc);
+               if (ret < 0)
                        goto out_error;
-               }
-               need_commit = test_bit(PG_CLEAN, &req->wb_flags);
-               nfs_clear_page_tag_locked(req);
-               if (need_commit) {
-                       ret = nfs_commit_inode(inode, FLUSH_SYNC);
-                       if (ret < 0)
-                               goto out_error;
-               }
        }
        return 0;
 out_error:
index 04133aacb1e519efe83d9ebe41d7ffe187616845..fc1c52571c03ea9eaf0d4e96a4026f119cd026e9 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/module.h>
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <linux/sunrpc/xdr.h>
 #include <linux/nfsacl.h>
 #include <linux/nfs3.h>
index a0c4016413f16117c1c5141fd01d3b27eabf871e..872a5ef550c7733c79650180ed453aaec25e7752 100644 (file)
@@ -12,6 +12,7 @@
  * Copyright (C) 1995, 1996 Olaf Kirch, <okir@monad.swb.de>
  */
 
+#include <linux/slab.h>
 #include <linux/namei.h>
 #include <linux/module.h>
 #include <linux/exportfs.h>
index f20589d2ae27be2aab0379b7d0ba1e2674490182..6aa5590c3679135279d2731b2af79fd8804b44a2 100644 (file)
@@ -7,6 +7,7 @@
 #include "nfsd.h"
 /* FIXME: nfsacl.h is a broken header */
 #include <linux/nfsacl.h>
+#include <linux/gfp.h>
 #include "cache.h"
 #include "xdr3.h"
 #include "vfs.h"
index e0c4846bad922be3307add94510a9b96330f691b..a596e9d987e46abb499ee8ac6dcd44472d02bc71 100644 (file)
@@ -7,6 +7,7 @@
 #include "nfsd.h"
 /* FIXME: nfsacl.h is a broken header */
 #include <linux/nfsacl.h>
+#include <linux/gfp.h>
 #include "cache.h"
 #include "xdr3.h"
 #include "vfs.h"
index 88150685df349e6abbc44d57d75c1d65fcc9649f..e48052615159c24689989b5ebe0a803e0946755f 100644 (file)
@@ -34,6 +34,7 @@
  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/slab.h>
 #include <linux/nfs_fs.h>
 #include <linux/nfs4_acl.h>
 
index 4bc22c763de7b433b4a37f2affdf75cc560d3908..7e32bd394e8696afac48c56bc27c768155c9db7e 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <linux/sunrpc/clnt.h>
+#include <linux/slab.h>
 #include "nfsd.h"
 #include "state.h"
 
index 6e2983b27f3ca4e6db8529da74adfeaffe09f4a4..c78dbf4934247e101d6fee19dd1e3ee150957e80 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/nfsd_idmap.h>
 #include <linux/seq_file.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 /*
  * Cache entry
index 37514c46984611467c95f89b82c2aa097779311b..2ab9e8501bfead1a451fb75cd7441407b412019b 100644 (file)
@@ -33,6 +33,7 @@
  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <linux/file.h>
+#include <linux/slab.h>
 
 #include "cache.h"
 #include "xdr4.h"
index 98fb98e330b4004907d899937e13e2f1c32368ee..7a9ae3254a4b2f858bce392ed5f719ae2ef126e7 100644 (file)
@@ -32,6 +32,7 @@
 */
 
 #include <linux/file.h>
+#include <linux/slab.h>
 #include <linux/namei.h>
 #include <linux/crypto.h>
 #include <linux/sched.h>
index c97fddbd17db8d15f0ce5a21d1ec6580a1be603c..6a8fedaa4f55a8ad0f6236296063e385d8eb1a17 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <linux/file.h>
 #include <linux/smp_lock.h>
+#include <linux/slab.h>
 #include <linux/namei.h>
 #include <linux/swap.h>
 #include <linux/sunrpc/svcauth_gss.h>
index c47b4d7bafa72d400b6249d0b0c7cd6908f0fd85..34ccf815ea8aa48f854a8ad6f9d15e64c2c59e51 100644 (file)
@@ -40,6 +40,7 @@
  * at the end of nfs4svc_decode_compoundargs.
  */
 
+#include <linux/slab.h>
 #include <linux/namei.h>
 #include <linux/statfs.h>
 #include <linux/utsname.h>
@@ -160,10 +161,10 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
        argp->p = page_address(argp->pagelist[0]);
        argp->pagelist++;
        if (argp->pagelen < PAGE_SIZE) {
-               argp->end = p + (argp->pagelen>>2);
+               argp->end = argp->p + (argp->pagelen>>2);
                argp->pagelen = 0;
        } else {
-               argp->end = p + (PAGE_SIZE>>2);
+               argp->end = argp->p + (PAGE_SIZE>>2);
                argp->pagelen -= PAGE_SIZE;
        }
        memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
@@ -1425,10 +1426,10 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
                        argp->p = page_address(argp->pagelist[0]);
                        argp->pagelist++;
                        if (argp->pagelen < PAGE_SIZE) {
-                               argp->end = p + (argp->pagelen>>2);
+                               argp->end = argp->p + (argp->pagelen>>2);
                                argp->pagelen = 0;
                        } else {
-                               argp->end = p + (PAGE_SIZE>>2);
+                               argp->end = argp->p + (PAGE_SIZE>>2);
                                argp->pagelen -= PAGE_SIZE;
                        }
                }
index da08560c4818defa358feb7b75e88b4d33dee70b..4666a209678a4d88ee0b1aea08078407df9b0938 100644 (file)
@@ -8,6 +8,8 @@
  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
  */
 
+#include <linux/slab.h>
+
 #include "nfsd.h"
 #include "cache.h"
 
index 0f0e77f2012f64951d9b8c1fc54f19156fab6f62..e3591073098f769e2d3658e1fa17a1abb30661ad 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
  */
 
+#include <linux/slab.h>
 #include <linux/namei.h>
 #include <linux/ctype.h>
 
index a11b0e8678eeff6585687afe1d0701663e11144a..6dd5f1970e01dedc3da245d8d26d87236dfadaf4 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/xattr.h>
 #include <linux/jhash.h>
 #include <linux/ima.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/exportfs.h>
 #include <linux/writeback.h>
index 3f959f1879d8b813a0ce775af216c5e5cd8df617..7cfb87e692da9b7594ee0666d3b912e6bc48a21d 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/buffer_head.h>
 #include <linux/fs.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include "mdt.h"
 #include "alloc.h"
 
@@ -425,7 +426,7 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode,
        bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh);
        if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group),
                                    group_offset, bitmap))
-               printk(KERN_WARNING "%s: entry numer %llu already freed\n",
+               printk(KERN_WARNING "%s: entry number %llu already freed\n",
                       __func__, (unsigned long long)req->pr_entry_nr);
 
        nilfs_palloc_group_desc_add_entries(inode, group, desc, 1);
index 471e269536ae1f24e07d84c9d412abcd5068d17d..447ce47a3306f6635a0512a8e25580ae93c0620b 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/buffer_head.h>
 #include <linux/mm.h>
 #include <linux/backing-dev.h>
+#include <linux/gfp.h>
 #include "nilfs.h"
 #include "mdt.h"
 #include "dat.h"
index 7cdd98b8d51482c02ea1b24c3a954d5213ffaa46..76c38e3e19d20ec53d708fcd3d8453c502092150 100644 (file)
@@ -1879,7 +1879,7 @@ static int nilfs_btree_propagate_v(struct nilfs_btree *btree,
                                   struct nilfs_btree_path *path,
                                   int level, struct buffer_head *bh)
 {
-       int maxlevel, ret;
+       int maxlevel = 0, ret;
        struct nilfs_btree_node *parent;
        struct inode *dat = nilfs_bmap_get_dat(&btree->bt_bmap);
        __u64 ptr;
index 8880a9e281e7bd11fd1c4ea7c9cc7974ec81d02a..145f03cd7d3e0299cda6786313804f1f1bf009ce 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/buffer_head.h>
 #include <linux/mpage.h>
 #include <linux/hash.h>
+#include <linux/slab.h>
 #include <linux/swap.h>
 #include "nilfs.h"
 #include "page.h"
index 7868cc122ac764dba74d6d55f0305239ff91ed8f..0957b58f909dc414348ea4b2529da54a468aabd4 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/buffer_head.h>
+#include <linux/gfp.h>
 #include <linux/mpage.h>
 #include <linux/writeback.h>
 #include <linux/uio.h>
index 313d0a21da480afc05afacfb46bec6f74e34b76a..f90a33d9a5b097c06038f614cbbcecb1abfab191 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/fs.h>
 #include <linux/wait.h>
 #include <linux/smp_lock.h>    /* lock_kernel(), unlock_kernel() */
+#include <linux/slab.h>
 #include <linux/capability.h>  /* capable() */
 #include <linux/uaccess.h>     /* copy_from_user(), copy_to_user() */
 #include <linux/vmalloc.h>
@@ -648,7 +649,7 @@ static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
 long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        struct inode *inode = filp->f_dentry->d_inode;
-       void __user *argp = (void __user *)arg;
+       void __user *argp = (void __user *)arg;
 
        switch (cmd) {
        case NILFS_IOCTL_CHANGE_CPMODE:
index 06713ffcc7f2dc2f6a668e35c46e97e64be15884..024be8c35bb65bef3ef5e1daf8f05da5fbb1b7b2 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/writeback.h>
 #include <linux/backing-dev.h>
 #include <linux/swap.h>
+#include <linux/slab.h>
 #include "nilfs.h"
 #include "segment.h"
 #include "page.h"
index fc246dba112af8cbbb20c79e8885194713f76f4d..8de3e1e48130ff6e042e3ba7c7d10b218e1d1268 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/list.h>
 #include <linux/highmem.h>
 #include <linux/pagevec.h>
+#include <linux/gfp.h>
 #include "nilfs.h"
 #include "page.h"
 #include "mdt.h"
index 017bedc761a048c66b538008ef4b561163f474e0..ba43146f3c309308cfd8505382570906f971ee57 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/buffer_head.h>
 #include <linux/blkdev.h>
 #include <linux/swap.h>
+#include <linux/slab.h>
 #include <linux/crc32.h>
 #include "nilfs.h"
 #include "segment.h"
index 636eaafd6ea257c7bfaf53dc7b7ce8399f81a103..17851f77f739d1942c8f0aad04d78fd82b8347e4 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/writeback.h>
 #include <linux/crc32.h>
 #include <linux/backing-dev.h>
+#include <linux/slab.h>
 #include "page.h"
 #include "segbuf.h"
 
@@ -323,14 +324,14 @@ int nilfs_write_logs(struct list_head *logs, struct the_nilfs *nilfs)
 int nilfs_wait_on_logs(struct list_head *logs)
 {
        struct nilfs_segment_buffer *segbuf;
-       int err;
+       int err, ret = 0;
 
        list_for_each_entry(segbuf, logs, sb_list) {
                err = nilfs_segbuf_wait(segbuf);
-               if (err)
-                       return err;
+               if (err && !ret)
+                       ret = err;
        }
-       return 0;
+       return ret;
 }
 
 /*
index 69576a95e13f918b340c51b1ffdc701d1053fc2f..6a7dbd8451db73d40080156ff325c82183437f51 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/kthread.h>
 #include <linux/crc32.h>
 #include <linux/pagevec.h>
+#include <linux/slab.h>
 #include "nilfs.h"
 #include "btnode.h"
 #include "page.h"
@@ -1510,6 +1511,12 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
                if (mode != SC_LSEG_SR || sci->sc_stage.scnt < NILFS_ST_CPFILE)
                        break;
 
+               nilfs_clear_logs(&sci->sc_segbufs);
+
+               err = nilfs_segctor_extend_segments(sci, nilfs, nadd);
+               if (unlikely(err))
+                       return err;
+
                if (sci->sc_stage.flags & NILFS_CF_SUFREED) {
                        err = nilfs_sufile_cancel_freev(nilfs->ns_sufile,
                                                        sci->sc_freesegs,
@@ -1517,12 +1524,6 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
                                                        NULL);
                        WARN_ON(err); /* do not happen */
                }
-               nilfs_clear_logs(&sci->sc_segbufs);
-
-               err = nilfs_segctor_extend_segments(sci, nilfs, nadd);
-               if (unlikely(err))
-                       return err;
-
                nadd = min_t(int, nadd << 1, SC_MAX_SEGDELTA);
                sci->sc_stage = prev_stage;
        }
@@ -1897,8 +1898,7 @@ static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci,
 
        list_splice_tail_init(&sci->sc_write_logs, &logs);
        ret = nilfs_wait_on_logs(&logs);
-       if (ret)
-               nilfs_abort_logs(&logs, NULL, sci->sc_super_root, ret);
+       nilfs_abort_logs(&logs, NULL, sci->sc_super_root, ret ? : err);
 
        list_splice_tail_init(&sci->sc_segbufs, &logs);
        nilfs_cancel_segusage(&logs, nilfs->ns_sufile);
index 0cdbc5e7655a60129adbbc69ebbae8830f8d1645..48145f505a6a8e7dbd33c8435b259a0e828a3f8c 100644 (file)
@@ -749,6 +749,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
        sb->s_export_op = &nilfs_export_ops;
        sb->s_root = NULL;
        sb->s_time_gran = 1;
+       sb->s_bdi = nilfs->ns_bdi;
 
        err = load_nilfs(nilfs, sbi);
        if (err)
index e9795f1724d7f0cc487729fd1e7cc2bb982a3b7a..1ab974533697ea91609386da13e88c323ee8157e 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/fs.h>
 #include <linux/blkdev.h>
 #include <linux/backing-dev.h>
+#include <linux/slab.h>
 #include "sb.h"
 
 /* the_nilfs struct */
index 037e878e03fcac70005fd6da12f776c76d89b38f..fcc2f064af8305b49c2387196bdb24bcc2f15d1e 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/dcache.h>
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/srcu.h>
index 3165d85aada2d5ee14a7e46dee6f0c8d07ee8686..0399bcbe09c83f02bdf1627b1dcfc6b12c316d5f 100644 (file)
@@ -87,7 +87,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
-#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/writeback.h> /* for inode_lock */
 
index 3e56dbffe7294421e58c17184d98b817c867ac0e..b3a159b21cfd001d8d2b928de1854e3cc6ad352e 100644 (file)
@@ -15,6 +15,7 @@ config INOTIFY
 
 config INOTIFY_USER
        bool "Inotify support for userspace"
+       select ANON_INODES
        select FSNOTIFY
        default y
        ---help---
index 1afb0a10229f448b55be812d2d1939817250cf77..e27960cd76ab9046257826783d907bdb6f3ca2a8 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/path.h> /* struct path */
 #include <linux/slab.h> /* kmem_* */
 #include <linux/types.h>
+#include <linux/sched.h>
 
 #include "inotify.h"
 
@@ -146,6 +147,7 @@ static void inotify_free_group_priv(struct fsnotify_group *group)
        idr_for_each(&group->inotify_data.idr, idr_callback, group);
        idr_remove_all(&group->inotify_data.idr);
        idr_destroy(&group->inotify_data.idr);
+       free_uid(group->inotify_data.user);
 }
 
 void inotify_free_event_priv(struct fsnotify_event_private_data *fsn_event_priv)
index 472cdf29ef82598586a52f32c405bc43a8ab6b26..e46ca685b9be39fc5f1f59ae5d6c6309d60aa644 100644 (file)
@@ -546,21 +546,24 @@ retry:
        if (unlikely(!idr_pre_get(&group->inotify_data.idr, GFP_KERNEL)))
                goto out_err;
 
+       /* we are putting the mark on the idr, take a reference */
+       fsnotify_get_mark(&tmp_ientry->fsn_entry);
+
        spin_lock(&group->inotify_data.idr_lock);
        ret = idr_get_new_above(&group->inotify_data.idr, &tmp_ientry->fsn_entry,
                                group->inotify_data.last_wd+1,
                                &tmp_ientry->wd);
        spin_unlock(&group->inotify_data.idr_lock);
        if (ret) {
+               /* we didn't get on the idr, drop the idr reference */
+               fsnotify_put_mark(&tmp_ientry->fsn_entry);
+
                /* idr was out of memory allocate and try again */
                if (ret == -EAGAIN)
                        goto retry;
                goto out_err;
        }
 
-       /* we put the mark on the idr, take a reference */
-       fsnotify_get_mark(&tmp_ientry->fsn_entry);
-
        /* we are on the idr, now get on the inode */
        ret = fsnotify_add_mark(&tmp_ientry->fsn_entry, group, inode);
        if (ret) {
@@ -578,16 +581,13 @@ retry:
        /* return the watch descriptor for this new entry */
        ret = tmp_ientry->wd;
 
-       /* match the ref from fsnotify_init_markentry() */
-       fsnotify_put_mark(&tmp_ientry->fsn_entry);
-
        /* if this mark added a new event update the group mask */
        if (mask & ~group->mask)
                fsnotify_recalc_group_mask(group);
 
 out_err:
-       if (ret < 0)
-               kmem_cache_free(inotify_inode_mark_cachep, tmp_ientry);
+       /* match the ref from fsnotify_init_markentry() */
+       fsnotify_put_mark(&tmp_ientry->fsn_entry);
 
        return ret;
 }
index cfce53cb65d76e0177601b129d972b8365d7d892..c3c2c7ac9020402d28dd0d2357ae2828c6e639a5 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/errno.h>
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/swap.h>
index 50d3b0c258e37cd0413568aef6d4216086a6bb02..f5094ee224c1fc1fbba40c4eddcb6f9480eea819 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/buffer_head.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/swap.h>
 #include <linux/writeback.h>
 
index 08f7530e9341cf06f55a17b1fabef30a64e12363..6551c7cbad92954202258d8715a3d44e06bc7d4b 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/buffer_head.h>
 #include <linux/blkdev.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 
 #include "attrib.h"
 #include "inode.h"
index 9173e82a45d132f92caa4b066b762ee608e95e79..fe44d3feee4a1b06222600e6028abfca4d5c0df0 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/buffer_head.h>
+#include <linux/slab.h>
 
 #include "dir.h"
 #include "aops.h"
index b681c71d70698f3b8df25e2d06cfe52e77aa4bc5..8804f093ba7512d309f6b94e7080cb0eb561ef74 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/buffer_head.h>
+#include <linux/gfp.h>
 #include <linux/pagemap.h>
 #include <linux/pagevec.h>
 #include <linux/sched.h>
index 2194eff4974379062c1d19578228766555da2519..096c135691aeda354c553fdb622286ea7f048e06 100644 (file)
@@ -19,6 +19,8 @@
  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/slab.h>
+
 #include "aops.h"
 #include "collate.h"
 #include "debug.h"
index 1caa0ef0b2bba8c0e27fe2154d8e633210feb0e7..b572b672718110e317a6895698bdf612b2e8eced 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/buffer_head.h>
+#include <linux/slab.h>
 #include <linux/swap.h>
 
 #include "attrib.h"
index 2ca00153b6ece6ea51de28d8eb3925eb86be36bc..358273e59aded3d416dea0f1e67627731d9d0d8f 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/dcache.h>
 #include <linux/exportfs.h>
 #include <linux/security.h>
+#include <linux/slab.h>
 
 #include "attrib.h"
 #include "debug.h"
index 1cf39dfaee7a7395f89763528bf63eb957fec106..0de1db6cddbfee225bde0314669fbcde82cc70c2 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/vfs.h>
 #include <linux/moduleparam.h>
 #include <linux/smp_lock.h>
+#include <linux/bitmap.h>
 
 #include "sysctl.h"
 #include "logfile.h"
@@ -2458,7 +2459,6 @@ static void ntfs_put_super(struct super_block *sb)
 static s64 get_nr_free_clusters(ntfs_volume *vol)
 {
        s64 nr_free = vol->nr_clusters;
-       u32 *kaddr;
        struct address_space *mapping = vol->lcnbmp_ino->i_mapping;
        struct page *page;
        pgoff_t index, max_index;
@@ -2477,7 +2477,8 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
        ntfs_debug("Reading $Bitmap, max_index = 0x%lx, max_size = 0x%lx.",
                        max_index, PAGE_CACHE_SIZE / 4);
        for (index = 0; index < max_index; index++) {
-               unsigned int i;
+               unsigned long *kaddr;
+
                /*
                 * Read the page from page cache, getting it from backing store
                 * if necessary, and increment the use count.
@@ -2490,16 +2491,16 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
                        nr_free -= PAGE_CACHE_SIZE * 8;
                        continue;
                }
-               kaddr = (u32*)kmap_atomic(page, KM_USER0);
+               kaddr = kmap_atomic(page, KM_USER0);
                /*
-                * For each 4 bytes, subtract the number of set bits. If this
+                * Subtract the number of set bits. If this
                 * is the last page and it is partial we don't really care as
                 * it just means we do a little extra work but it won't affect
                 * the result as all out of range bytes are set to zero by
                 * ntfs_readpage().
                 */
-               for (i = 0; i < PAGE_CACHE_SIZE / 4; i++)
-                       nr_free -= (s64)hweight32(kaddr[i]);
+               nr_free -= bitmap_weight(kaddr,
+                                       PAGE_CACHE_SIZE * BITS_PER_BYTE);
                kunmap_atomic(kaddr, KM_USER0);
                page_cache_release(page);
        }
@@ -2538,7 +2539,6 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
 static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
                s64 nr_free, const pgoff_t max_index)
 {
-       u32 *kaddr;
        struct address_space *mapping = vol->mftbmp_ino->i_mapping;
        struct page *page;
        pgoff_t index;
@@ -2548,7 +2548,8 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
        ntfs_debug("Reading $MFT/$BITMAP, max_index = 0x%lx, max_size = "
                        "0x%lx.", max_index, PAGE_CACHE_SIZE / 4);
        for (index = 0; index < max_index; index++) {
-               unsigned int i;
+               unsigned long *kaddr;
+
                /*
                 * Read the page from page cache, getting it from backing store
                 * if necessary, and increment the use count.
@@ -2561,16 +2562,16 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
                        nr_free -= PAGE_CACHE_SIZE * 8;
                        continue;
                }
-               kaddr = (u32*)kmap_atomic(page, KM_USER0);
+               kaddr = kmap_atomic(page, KM_USER0);
                /*
-                * For each 4 bytes, subtract the number of set bits. If this
+                * Subtract the number of set bits. If this
                 * is the last page and it is partial we don't really care as
                 * it just means we do a little extra work but it won't affect
                 * the result as all out of range bytes are set to zero by
                 * ntfs_readpage().
                 */
-               for (i = 0; i < PAGE_CACHE_SIZE / 4; i++)
-                       nr_free -= (s64)hweight32(kaddr[i]);
+               nr_free -= bitmap_weight(kaddr,
+                                       PAGE_CACHE_SIZE * BITS_PER_BYTE);
                kunmap_atomic(kaddr, KM_USER0);
                page_cache_release(page);
        }
index 0501974bedd0d3b96764b48b5725054fbe7ca412..e13fc9e8fcdc02bc55964f673b51d228cb6811cc 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 
 #define MLOG_MASK_PREFIX ML_INODE
@@ -30,6 +31,8 @@
 #include "alloc.h"
 #include "dlmglue.h"
 #include "file.h"
+#include "inode.h"
+#include "journal.h"
 #include "ocfs2_fs.h"
 
 #include "xattr.h"
@@ -165,6 +168,60 @@ static struct posix_acl *ocfs2_get_acl(struct inode *inode, int type)
        return acl;
 }
 
+/*
+ * Helper function to set i_mode in memory and disk. Some call paths
+ * will not have di_bh or a journal handle to pass, in which case it
+ * will create it's own.
+ */
+static int ocfs2_acl_set_mode(struct inode *inode, struct buffer_head *di_bh,
+                             handle_t *handle, umode_t new_mode)
+{
+       int ret, commit_handle = 0;
+       struct ocfs2_dinode *di;
+
+       if (di_bh == NULL) {
+               ret = ocfs2_read_inode_block(inode, &di_bh);
+               if (ret) {
+                       mlog_errno(ret);
+                       goto out;
+               }
+       } else
+               get_bh(di_bh);
+
+       if (handle == NULL) {
+               handle = ocfs2_start_trans(OCFS2_SB(inode->i_sb),
+                                          OCFS2_INODE_UPDATE_CREDITS);
+               if (IS_ERR(handle)) {
+                       ret = PTR_ERR(handle);
+                       mlog_errno(ret);
+                       goto out_brelse;
+               }
+
+               commit_handle = 1;
+       }
+
+       di = (struct ocfs2_dinode *)di_bh->b_data;
+       ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh,
+                                     OCFS2_JOURNAL_ACCESS_WRITE);
+       if (ret) {
+               mlog_errno(ret);
+               goto out_commit;
+       }
+
+       inode->i_mode = new_mode;
+       di->i_mode = cpu_to_le16(inode->i_mode);
+
+       ocfs2_journal_dirty(handle, di_bh);
+
+out_commit:
+       if (commit_handle)
+               ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
+out_brelse:
+       brelse(di_bh);
+out:
+       return ret;
+}
+
 /*
  * Set the access or default ACL of an inode.
  */
@@ -193,9 +250,14 @@ static int ocfs2_set_acl(handle_t *handle,
                        if (ret < 0)
                                return ret;
                        else {
-                               inode->i_mode = mode;
                                if (ret == 0)
                                        acl = NULL;
+
+                               ret = ocfs2_acl_set_mode(inode, di_bh,
+                                                        handle, mode);
+                               if (ret)
+                                       return ret;
+
                        }
                }
                break;
@@ -283,6 +345,7 @@ int ocfs2_init_acl(handle_t *handle,
        struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
        struct posix_acl *acl = NULL;
        int ret = 0;
+       mode_t mode;
 
        if (!S_ISLNK(inode->i_mode)) {
                if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) {
@@ -291,12 +354,17 @@ int ocfs2_init_acl(handle_t *handle,
                        if (IS_ERR(acl))
                                return PTR_ERR(acl);
                }
-               if (!acl)
-                       inode->i_mode &= ~current_umask();
+               if (!acl) {
+                       mode = inode->i_mode & ~current_umask();
+                       ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
+                       if (ret) {
+                               mlog_errno(ret);
+                               goto cleanup;
+                       }
+               }
        }
        if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) {
                struct posix_acl *clone;
-               mode_t mode;
 
                if (S_ISDIR(inode->i_mode)) {
                        ret = ocfs2_set_acl(handle, inode, di_bh,
@@ -313,7 +381,7 @@ int ocfs2_init_acl(handle_t *handle,
                mode = inode->i_mode;
                ret = posix_acl_create_masq(clone, &mode);
                if (ret >= 0) {
-                       inode->i_mode = mode;
+                       ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
                        if (ret > 0) {
                                ret = ocfs2_set_acl(handle, inode,
                                                    di_bh, ACL_TYPE_ACCESS,
index 21c808f752d8dc42381ce556547d7ae60c4c82bb..f9d5d3ffc75a9011b0a63a76a97184853ee7f063 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <linux/fs.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/highmem.h>
 
 #include <cluster/masklog.h>
@@ -407,6 +406,7 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb,
                                struct buffer_head *bh)
 {
        int ret = 0;
+       struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
 
        mlog_entry_void();
 
@@ -426,6 +426,7 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb,
 
        get_bh(bh); /* for end_buffer_write_sync() */
        bh->b_end_io = end_buffer_write_sync;
+       ocfs2_compute_meta_ecc(osb->sb, bh->b_data, &di->i_check);
        submit_bh(WRITE, bh);
 
        wait_on_buffer(bh);
index 5c98900067082d6066b26e50cc33dec31e7a769d..41d5f1f92d56f60a45f6066d875598bda7caddf2 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/crc32.h>
 #include <linux/time.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 
 #include "heartbeat.h"
 #include "tcp.h"
index c81142e3ef844def09ef96725f2ebb68247aaecc..ed0c9f367fed03fe0114b6956b6bb4a34ade5b77 100644 (file)
@@ -19,6 +19,7 @@
  * Boston, MA 021110-1307, USA.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/configfs.h>
index 639024033fceeea6cc5978bcdcf3c3a65f216986..cf3e16696216d4fa95f30c0247ee58e608f54047 100644 (file)
@@ -44,7 +44,6 @@
  * and if they're the last, they fire off the decision.
  */
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/reboot.h>
 
index dccc439fa087ce65a202ed7a5aa994dd79fa6e9e..12d5eb78a11a0ec192f721aad767f8bd7e94073f 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/highmem.h>
 #include <linux/init.h>
 #include <linux/sysctl.h>
@@ -185,9 +184,8 @@ static void dlm_update_lvb(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
        BUG_ON(!lksb);
 
        /* only updates if this node masters the lockres */
+       spin_lock(&res->spinlock);
        if (res->owner == dlm->node_num) {
-
-               spin_lock(&res->spinlock);
                /* check the lksb flags for the direction */
                if (lksb->flags & DLM_LKSB_GET_LVB) {
                        mlog(0, "getting lvb from lockres for %s node\n",
@@ -202,8 +200,8 @@ static void dlm_update_lvb(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
                 * here. In the future we might want to clear it at the time
                 * the put is actually done.
                 */
-               spin_unlock(&res->spinlock);
        }
+       spin_unlock(&res->spinlock);
 
        /* reset any lvb flags on the lksb */
        lksb->flags &= ~(DLM_LKSB_PUT_LVB|DLM_LKSB_GET_LVB);
index f283bce776b48e4d916cd4a6b4d84c7b38775c69..90803b47cd8cfb71945908c4fe120a2a0641429a 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/highmem.h>
 #include <linux/init.h>
 #include <linux/sysctl.h>
index a659606dcb9592f1d0c719ed7167b1fe158296f2..9289b4357d27dcf0559a5b6f438e0ca4205e359b 100644 (file)
@@ -1875,7 +1875,6 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data,
 ok:
                spin_unlock(&res->spinlock);
        }
-       spin_unlock(&dlm->spinlock);
 
        // mlog(0, "woo!  got an assert_master from node %u!\n",
        //           assert->node_idx);
@@ -1926,7 +1925,6 @@ ok:
                /* master is known, detach if not already detached.
                 * ensures that only one assert_master call will happen
                 * on this mle. */
-               spin_lock(&dlm->spinlock);
                spin_lock(&dlm->master_lock);
 
                rr = atomic_read(&mle->mle_refs.refcount);
@@ -1959,7 +1957,6 @@ ok:
                        __dlm_put_mle(mle);
                }
                spin_unlock(&dlm->master_lock);
-               spin_unlock(&dlm->spinlock);
        } else if (res) {
                if (res->owner != assert->node_idx) {
                        mlog(0, "assert_master from %u, but current "
@@ -1967,6 +1964,7 @@ ok:
                             res->owner, namelen, name);
                }
        }
+       spin_unlock(&dlm->spinlock);
 
 done:
        ret = 0;
index 52ec020ea78b42f11ad83b3a2632dbcf08a20dde..11a6d1fd1d35ad71670515efcc204cc3170eb3a6 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/highmem.h>
 #include <linux/init.h>
 #include <linux/sysctl.h>
index 49e29ecd02017be2144c2f50df76b8b0f761ad2d..b47c1b92b82b6d6065abc6e9145def26b0a2e829 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/highmem.h>
 #include <linux/init.h>
 #include <linux/sysctl.h>
index 1b0de157a08c604aa8731c6f11291cbd97154af1..b83d6107a1f5e0eb9e63c4dae29746c3b3888fce 100644 (file)
@@ -112,20 +112,20 @@ MODULE_PARM_DESC(capabilities, DLMFS_CAPABILITIES);
  * O_RDONLY -> PRMODE level
  * O_WRONLY -> EXMODE level
  *
- * O_NONBLOCK -> LKM_NOQUEUE
+ * O_NONBLOCK -> NOQUEUE
  */
 static int dlmfs_decode_open_flags(int open_flags,
                                   int *level,
                                   int *flags)
 {
        if (open_flags & (O_WRONLY|O_RDWR))
-               *level = LKM_EXMODE;
+               *level = DLM_LOCK_EX;
        else
-               *level = LKM_PRMODE;
+               *level = DLM_LOCK_PR;
 
        *flags = 0;
        if (open_flags & O_NONBLOCK)
-               *flags |= LKM_NOQUEUE;
+               *flags |= DLM_LKF_NOQUEUE;
 
        return 0;
 }
@@ -166,7 +166,7 @@ static int dlmfs_file_open(struct inode *inode,
                 * to be able userspace to be able to distinguish a
                 * valid lock request from one that simply couldn't be
                 * granted. */
-               if (flags & LKM_NOQUEUE && status == -EAGAIN)
+               if (flags & DLM_LKF_NOQUEUE && status == -EAGAIN)
                        status = -ETXTBSY;
                kfree(fp);
                goto bail;
@@ -193,7 +193,7 @@ static int dlmfs_file_release(struct inode *inode,
        status = 0;
        if (fp) {
                level = fp->fp_lock_level;
-               if (level != LKM_IVMODE)
+               if (level != DLM_LOCK_IV)
                        user_dlm_cluster_unlock(&ip->ip_lockres, level);
 
                kfree(fp);
@@ -262,7 +262,7 @@ static ssize_t dlmfs_file_read(struct file *filp,
        if ((count + *ppos) > i_size_read(inode))
                readlen = i_size_read(inode) - *ppos;
        else
-               readlen = count - *ppos;
+               readlen = count;
 
        lvb_buf = kmalloc(readlen, GFP_NOFS);
        if (!lvb_buf)
index c562a7581cf93b709e79d70be22034f1e5be7a63..09e3fdfa6d33f603f6fe2a9bcdade3f979565e61 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/fs.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/fiemap.h>
 
index 17947dc8341e95d187ed13fa69f1a4bdaf5803dc..a5fbd9cea9687429ba5f1aeae1bec3b86e0d216a 100644 (file)
@@ -684,6 +684,7 @@ restarted_transaction:
                if (why == RESTART_META) {
                        mlog(0, "restarting function.\n");
                        restart_func = 1;
+                       status = 0;
                } else {
                        BUG_ON(why != RESTART_TRANS);
 
@@ -1981,18 +1982,18 @@ relock:
        /* communicate with ocfs2_dio_end_io */
        ocfs2_iocb_set_rw_locked(iocb, rw_level);
 
-       if (direct_io) {
-               ret = generic_segment_checks(iov, &nr_segs, &ocount,
-                                            VERIFY_READ);
-               if (ret)
-                       goto out_dio;
+       ret = generic_segment_checks(iov, &nr_segs, &ocount,
+                                    VERIFY_READ);
+       if (ret)
+               goto out_dio;
 
-               count = ocount;
-               ret = generic_write_checks(file, ppos, &count,
-                                          S_ISBLK(inode->i_mode));
-               if (ret)
-                       goto out_dio;
+       count = ocount;
+       ret = generic_write_checks(file, ppos, &count,
+                                  S_ISBLK(inode->i_mode));
+       if (ret)
+               goto out_dio;
 
+       if (direct_io) {
                written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos,
                                                    ppos, count, ocount);
                if (written < 0) {
@@ -2007,7 +2008,10 @@ relock:
                        goto out_dio;
                }
        } else {
-               written = __generic_file_aio_write(iocb, iov, nr_segs, ppos);
+               current->backing_dev_info = file->f_mapping->backing_dev_info;
+               written = generic_file_buffered_write(iocb, iov, nr_segs, *ppos,
+                                                     ppos, count, 0);
+               current->backing_dev_info = NULL;
        }
 
 out_dio:
@@ -2021,9 +2025,9 @@ out_dio:
                if (ret < 0)
                        written = ret;
 
-               if (!ret && (old_size != i_size_read(inode) ||
-                   old_clusters != OCFS2_I(inode)->ip_clusters ||
-                   has_refcount)) {
+               if (!ret && ((old_size != i_size_read(inode)) ||
+                            (old_clusters != OCFS2_I(inode)->ip_clusters) ||
+                            has_refcount)) {
                        ret = jbd2_journal_force_commit(osb->journal->j_journal);
                        if (ret < 0)
                                written = ret;
index c6e7213db8688744bdd21d05d5f6296a5e7dcc91..1aa863dd901f783d71e54f19b37e78440fe46693 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <linux/fs.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/highmem.h>
 
 #define MLOG_MASK_PREFIX ML_SUPER
index 278a223aae14b8a2d347890735c729567e3840cc..af189887201c4a356d0e06f798474e4e031486a3 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <linux/fs.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/quotaops.h>
@@ -559,6 +558,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
                handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
                if (IS_ERR(handle)) {
                        status = PTR_ERR(handle);
+                       handle = NULL;
                        mlog_errno(status);
                        goto out;
                }
@@ -640,11 +640,13 @@ static int ocfs2_remove_inode(struct inode *inode,
                goto bail_unlock;
        }
 
-       status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
-                                 orphan_dir_bh);
-       if (status < 0) {
-               mlog_errno(status);
-               goto bail_commit;
+       if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
+               status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
+                                         orphan_dir_bh);
+               if (status < 0) {
+                       mlog_errno(status);
+                       goto bail_commit;
+               }
        }
 
        /* set the inodes dtime */
@@ -723,38 +725,39 @@ static void ocfs2_signal_wipe_completion(struct ocfs2_super *osb,
 static int ocfs2_wipe_inode(struct inode *inode,
                            struct buffer_head *di_bh)
 {
-       int status, orphaned_slot;
+       int status, orphaned_slot = -1;
        struct inode *orphan_dir_inode = NULL;
        struct buffer_head *orphan_dir_bh = NULL;
        struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
-       struct ocfs2_dinode *di;
+       struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data;
 
-       di = (struct ocfs2_dinode *) di_bh->b_data;
-       orphaned_slot = le16_to_cpu(di->i_orphaned_slot);
+       if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
+               orphaned_slot = le16_to_cpu(di->i_orphaned_slot);
 
-       status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot);
-       if (status)
-               return status;
+               status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot);
+               if (status)
+                       return status;
 
-       orphan_dir_inode = ocfs2_get_system_file_inode(osb,
-                                                      ORPHAN_DIR_SYSTEM_INODE,
-                                                      orphaned_slot);
-       if (!orphan_dir_inode) {
-               status = -EEXIST;
-               mlog_errno(status);
-               goto bail;
-       }
+               orphan_dir_inode = ocfs2_get_system_file_inode(osb,
+                                                              ORPHAN_DIR_SYSTEM_INODE,
+                                                              orphaned_slot);
+               if (!orphan_dir_inode) {
+                       status = -EEXIST;
+                       mlog_errno(status);
+                       goto bail;
+               }
 
-       /* Lock the orphan dir. The lock will be held for the entire
-        * delete_inode operation. We do this now to avoid races with
-        * recovery completion on other nodes. */
-       mutex_lock(&orphan_dir_inode->i_mutex);
-       status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
-       if (status < 0) {
-               mutex_unlock(&orphan_dir_inode->i_mutex);
+               /* Lock the orphan dir. The lock will be held for the entire
+                * delete_inode operation. We do this now to avoid races with
+                * recovery completion on other nodes. */
+               mutex_lock(&orphan_dir_inode->i_mutex);
+               status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
+               if (status < 0) {
+                       mutex_unlock(&orphan_dir_inode->i_mutex);
 
-               mlog_errno(status);
-               goto bail;
+                       mlog_errno(status);
+                       goto bail;
+               }
        }
 
        /* we do this while holding the orphan dir lock because we
@@ -795,6 +798,9 @@ static int ocfs2_wipe_inode(struct inode *inode,
                mlog_errno(status);
 
 bail_unlock_dir:
+       if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)
+               return status;
+
        ocfs2_inode_unlock(orphan_dir_inode, 1);
        mutex_unlock(&orphan_dir_inode->i_mutex);
        brelse(orphan_dir_bh);
@@ -890,7 +896,23 @@ static int ocfs2_query_inode_wipe(struct inode *inode,
 
        /* Do some basic inode verification... */
        di = (struct ocfs2_dinode *) di_bh->b_data;
-       if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL))) {
+       if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL)) &&
+           !(oi->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
+               /*
+                * Inodes in the orphan dir must have ORPHANED_FL.  The only
+                * inodes that come back out of the orphan dir are reflink
+                * targets. A reflink target may be moved out of the orphan
+                * dir between the time we scan the directory and the time we
+                * process it. This would lead to HAS_REFCOUNT_FL being set but
+                * ORPHANED_FL not.
+                */
+               if (di->i_dyn_features & cpu_to_le16(OCFS2_HAS_REFCOUNT_FL)) {
+                       mlog(0, "Reflinked inode %llu is no longer orphaned.  "
+                            "it shouldn't be deleted\n",
+                            (unsigned long long)oi->ip_blkno);
+                       goto bail;
+               }
+
                /* for lack of a better error? */
                status = -EEXIST;
                mlog(ML_ERROR,
index ba4fe07b293c6f4c2d6d864a7e5a491ad082d7ea..0b28e1921a39a5f8fcf5884426f07676ca94d995 100644 (file)
@@ -100,6 +100,8 @@ struct ocfs2_inode_info
 #define OCFS2_INODE_MAYBE_ORPHANED     0x00000020
 /* Does someone have the file open O_DIRECT */
 #define OCFS2_INODE_OPEN_DIRECT                0x00000040
+/* Tell the inode wipe code it's not in orphan dir */
+#define OCFS2_INODE_SKIP_ORPHAN_DIR     0x00000080
 
 static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode)
 {
index ca992d91f5110e9a376ca4a0f71a5101f4294e29..c983715d8d8c3d7d734ade4ae339f39439d82aa0 100644 (file)
@@ -872,8 +872,10 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb,
                             (unsigned long long)la_start_blk,
                             (unsigned long long)blkno);
 
-                       status = ocfs2_free_clusters(handle, main_bm_inode,
-                                                    main_bm_bh, blkno, count);
+                       status = ocfs2_release_clusters(handle,
+                                                       main_bm_inode,
+                                                       main_bm_bh, blkno,
+                                                       count);
                        if (status < 0) {
                                mlog_errno(status);
                                goto bail;
@@ -984,8 +986,7 @@ static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb,
        }
 
 retry_enospc:
-       (*ac)->ac_bits_wanted = osb->local_alloc_bits;
-
+       (*ac)->ac_bits_wanted = osb->local_alloc_default_bits;
        status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac);
        if (status == -ENOSPC) {
                if (ocfs2_recalc_la_window(osb, OCFS2_LA_EVENT_ENOSPC) ==
@@ -1061,6 +1062,7 @@ retry_enospc:
                    OCFS2_LA_DISABLED)
                        goto bail;
 
+               ac->ac_bits_wanted = osb->local_alloc_default_bits;
                status = ocfs2_claim_clusters(osb, handle, ac,
                                              osb->local_alloc_bits,
                                              &cluster_off,
index 544ac6245175f26c23249cf916c5001ae8f5d067..b5cb3ede9408944d99abc7c7c3b28c01b1ddadeb 100644 (file)
@@ -133,7 +133,7 @@ int ocfs2_lock(struct file *file, int cmd, struct file_lock *fl)
 
        if (!(fl->fl_flags & FL_POSIX))
                return -ENOLCK;
-       if (__mandatory_lock(inode))
+       if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
                return -ENOLCK;
 
        return ocfs2_plock(osb->cconn, OCFS2_I(inode)->ip_blkno, file, cmd, fl);
index 39737613424a2c073c21c540e7b022b96e344da9..7898bd3a99f54a50de060af137d996b699ac8952 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <linux/fs.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/uio.h>
index d9cd4e373a5309e24602b5dab9899f208a756523..4cbb18f26c5fadc4f9f2eff9f07f9341116df5d0 100644 (file)
@@ -84,7 +84,7 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
 static int ocfs2_orphan_add(struct ocfs2_super *osb,
                            handle_t *handle,
                            struct inode *inode,
-                           struct ocfs2_dinode *fe,
+                           struct buffer_head *fe_bh,
                            char *name,
                            struct ocfs2_dir_lookup_result *lookup,
                            struct inode *orphan_dir_inode);
@@ -408,23 +408,28 @@ static int ocfs2_mknod(struct inode *dir,
                }
        }
 
-       status = ocfs2_add_entry(handle, dentry, inode,
-                                OCFS2_I(inode)->ip_blkno, parent_fe_bh,
-                                &lookup);
-       if (status < 0) {
+       /*
+        * Do this before adding the entry to the directory. We add
+        * also set d_op after success so that ->d_iput() will cleanup
+        * the dentry lock even if ocfs2_add_entry() fails below.
+        */
+       status = ocfs2_dentry_attach_lock(dentry, inode,
+                                         OCFS2_I(dir)->ip_blkno);
+       if (status) {
                mlog_errno(status);
                goto leave;
        }
+       dentry->d_op = &ocfs2_dentry_ops;
 
-       status = ocfs2_dentry_attach_lock(dentry, inode,
-                                         OCFS2_I(dir)->ip_blkno);
-       if (status) {
+       status = ocfs2_add_entry(handle, dentry, inode,
+                                OCFS2_I(inode)->ip_blkno, parent_fe_bh,
+                                &lookup);
+       if (status < 0) {
                mlog_errno(status);
                goto leave;
        }
 
        insert_inode_hash(inode);
-       dentry->d_op = &ocfs2_dentry_ops;
        d_instantiate(dentry, inode);
        status = 0;
 leave:
@@ -445,11 +450,6 @@ leave:
 
        ocfs2_free_dir_lookup_result(&lookup);
 
-       if ((status < 0) && inode) {
-               clear_nlink(inode);
-               iput(inode);
-       }
-
        if (inode_ac)
                ocfs2_free_alloc_context(inode_ac);
 
@@ -459,6 +459,17 @@ leave:
        if (meta_ac)
                ocfs2_free_alloc_context(meta_ac);
 
+       /*
+        * We should call iput after the i_mutex of the bitmap been
+        * unlocked in ocfs2_free_alloc_context, or the
+        * ocfs2_delete_inode will mutex_lock again.
+        */
+       if ((status < 0) && inode) {
+               OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR;
+               clear_nlink(inode);
+               iput(inode);
+       }
+
        mlog_exit(status);
 
        return status;
@@ -879,7 +890,7 @@ static int ocfs2_unlink(struct inode *dir,
        fe = (struct ocfs2_dinode *) fe_bh->b_data;
 
        if (inode_is_unlinkable(inode)) {
-               status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name,
+               status = ocfs2_orphan_add(osb, handle, inode, fe_bh, orphan_name,
                                          &orphan_insert, orphan_dir);
                if (status < 0) {
                        mlog_errno(status);
@@ -1300,7 +1311,7 @@ static int ocfs2_rename(struct inode *old_dir,
                if (S_ISDIR(new_inode->i_mode) ||
                    (ocfs2_read_links_count(newfe) == 1)) {
                        status = ocfs2_orphan_add(osb, handle, new_inode,
-                                                 newfe, orphan_name,
+                                                 newfe_bh, orphan_name,
                                                  &orphan_insert, orphan_dir);
                        if (status < 0) {
                                mlog_errno(status);
@@ -1771,22 +1782,27 @@ static int ocfs2_symlink(struct inode *dir,
                }
        }
 
-       status = ocfs2_add_entry(handle, dentry, inode,
-                                le64_to_cpu(fe->i_blkno), parent_fe_bh,
-                                &lookup);
-       if (status < 0) {
+       /*
+        * Do this before adding the entry to the directory. We add
+        * also set d_op after success so that ->d_iput() will cleanup
+        * the dentry lock even if ocfs2_add_entry() fails below.
+        */
+       status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
+       if (status) {
                mlog_errno(status);
                goto bail;
        }
+       dentry->d_op = &ocfs2_dentry_ops;
 
-       status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
-       if (status) {
+       status = ocfs2_add_entry(handle, dentry, inode,
+                                le64_to_cpu(fe->i_blkno), parent_fe_bh,
+                                &lookup);
+       if (status < 0) {
                mlog_errno(status);
                goto bail;
        }
 
        insert_inode_hash(inode);
-       dentry->d_op = &ocfs2_dentry_ops;
        d_instantiate(dentry, inode);
 bail:
        if (status < 0 && did_quota)
@@ -1811,6 +1827,7 @@ bail:
        if (xattr_ac)
                ocfs2_free_alloc_context(xattr_ac);
        if ((status < 0) && inode) {
+               OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR;
                clear_nlink(inode);
                iput(inode);
        }
@@ -1911,7 +1928,7 @@ leave:
 static int ocfs2_orphan_add(struct ocfs2_super *osb,
                            handle_t *handle,
                            struct inode *inode,
-                           struct ocfs2_dinode *fe,
+                           struct buffer_head *fe_bh,
                            char *name,
                            struct ocfs2_dir_lookup_result *lookup,
                            struct inode *orphan_dir_inode)
@@ -1919,6 +1936,7 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
        struct buffer_head *orphan_dir_bh = NULL;
        int status = 0;
        struct ocfs2_dinode *orphan_fe;
+       struct ocfs2_dinode *fe = (struct ocfs2_dinode *) fe_bh->b_data;
 
        mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino);
 
@@ -1959,13 +1977,31 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
                goto leave;
        }
 
+       /*
+        * We're going to journal the change of i_flags and i_orphaned_slot.
+        * It's safe anyway, though some callers may duplicate the journaling.
+        * Journaling within the func just make the logic look more
+        * straightforward.
+        */
+       status = ocfs2_journal_access_di(handle,
+                                        INODE_CACHE(inode),
+                                        fe_bh,
+                                        OCFS2_JOURNAL_ACCESS_WRITE);
+       if (status < 0) {
+               mlog_errno(status);
+               goto leave;
+       }
+
        le32_add_cpu(&fe->i_flags, OCFS2_ORPHANED_FL);
+       OCFS2_I(inode)->ip_flags &= ~OCFS2_INODE_SKIP_ORPHAN_DIR;
 
        /* Record which orphan dir our inode now resides
         * in. delete_inode will use this to determine which orphan
         * dir to lock. */
        fe->i_orphaned_slot = cpu_to_le16(osb->slot_num);
 
+       ocfs2_journal_dirty(handle, fe_bh);
+
        mlog(0, "Inode %llu orphaned in slot %d\n",
             (unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num);
 
@@ -2123,7 +2159,7 @@ int ocfs2_create_inode_in_orphan(struct inode *dir,
        }
 
        di = (struct ocfs2_dinode *)new_di_bh->b_data;
-       status = ocfs2_orphan_add(osb, handle, inode, di, orphan_name,
+       status = ocfs2_orphan_add(osb, handle, inode, new_di_bh, orphan_name,
                                  &orphan_insert, orphan_dir);
        if (status < 0) {
                mlog_errno(status);
index 1238b491db90d5635059f07a44178b8a7e9a1571..adf5e2ebc2c436b60992dfc39ae506327aaf9054 100644 (file)
@@ -763,8 +763,18 @@ static inline unsigned int ocfs2_megabytes_to_clusters(struct super_block *sb,
        return megs << (20 - OCFS2_SB(sb)->s_clustersize_bits);
 }
 
-#define ocfs2_set_bit ext2_set_bit
-#define ocfs2_clear_bit ext2_clear_bit
+static inline void _ocfs2_set_bit(unsigned int bit, unsigned long *bitmap)
+{
+       ext2_set_bit(bit, bitmap);
+}
+#define ocfs2_set_bit(bit, addr) _ocfs2_set_bit((bit), (unsigned long *)(addr))
+
+static inline void _ocfs2_clear_bit(unsigned int bit, unsigned long *bitmap)
+{
+       ext2_clear_bit(bit, bitmap);
+}
+#define ocfs2_clear_bit(bit, addr) _ocfs2_clear_bit((bit), (unsigned long *)(addr))
+
 #define ocfs2_test_bit ext2_test_bit
 #define ocfs2_find_next_zero_bit ext2_find_next_zero_bit
 #define ocfs2_find_next_bit ext2_find_next_bit
index 355f41d1d520742b7ebb650333c705515c72f01e..ab42a74c7539246a5adfaf4d4412e06e7fbfd6f1 100644 (file)
@@ -3,6 +3,7 @@
  */
 #include <linux/spinlock.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/quota.h>
 #include <linux/quotaops.h>
 #include <linux/dqblk_qtree.h>
index a6467f3d262ee6bd720a732d396e23b3e4637ade..9ad49305f4505d57b04271ab56a91d7f238d5739 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/quota.h>
 #include <linux/quotaops.h>
 #include <linux/module.h>
index 9e96921dffda4f9f9b32970c142bacc59984802a..5cbcd0f008fc96a5f9c65d4fb26f393eb7f3db15 100644 (file)
@@ -37,7 +37,6 @@
 
 #include <linux/bio.h>
 #include <linux/blkdev.h>
-#include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/writeback.h>
 #include <linux/pagevec.h>
@@ -4075,6 +4074,7 @@ static int ocfs2_complete_reflink(struct inode *s_inode,
        OCFS2_I(t_inode)->ip_dyn_features = OCFS2_I(s_inode)->ip_dyn_features;
        spin_unlock(&OCFS2_I(t_inode)->ip_lock);
        i_size_write(t_inode, size);
+       t_inode->i_blocks = s_inode->i_blocks;
 
        di->i_xattr_inline_size = s_di->i_xattr_inline_size;
        di->i_clusters = s_di->i_clusters;
@@ -4083,6 +4083,9 @@ static int ocfs2_complete_reflink(struct inode *s_inode,
        di->i_attr = s_di->i_attr;
 
        if (preserve) {
+               t_inode->i_uid = s_inode->i_uid;
+               t_inode->i_gid = s_inode->i_gid;
+               t_inode->i_mode = s_inode->i_mode;
                di->i_uid = s_di->i_uid;
                di->i_gid = s_di->i_gid;
                di->i_mode = s_di->i_mode;
index 7020e1253ffae91c5aa359f51405a8c99ee60061..0d3049f696c5418448173ed3538020bd5d51b9d0 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/kernel.h>
 #include <linux/crc32.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 
 /* Needed for AOP_TRUNCATED_PAGE in mlog_errno() */
index 5ae8812b28647975bdba323cd09997f6c6213d5c..2dc57bca0688165366364d88448d1e884ef6dd9f 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/reboot.h>
 #include <asm/uaccess.h>
index c3c60bc3e0729a5fb55f99254dc5babd150ae6ff..19ba00f28547bcf0d31fc8bc69ed34c340660c85 100644 (file)
@@ -95,13 +95,6 @@ static inline int ocfs2_block_group_set_bits(handle_t *handle,
                                             struct buffer_head *group_bh,
                                             unsigned int bit_off,
                                             unsigned int num_bits);
-static inline int ocfs2_block_group_clear_bits(handle_t *handle,
-                                              struct inode *alloc_inode,
-                                              struct ocfs2_group_desc *bg,
-                                              struct buffer_head *group_bh,
-                                              unsigned int bit_off,
-                                              unsigned int num_bits);
-
 static int ocfs2_relink_block_group(handle_t *handle,
                                    struct inode *alloc_inode,
                                    struct buffer_head *fe_bh,
@@ -152,7 +145,7 @@ static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl)
 
 #define do_error(fmt, ...)                                             \
        do{                                                             \
-               if (clean_error)                                        \
+               if (resize)                                     \
                        mlog(ML_ERROR, fmt "\n", ##__VA_ARGS__);        \
                else                                                    \
                        ocfs2_error(sb, fmt, ##__VA_ARGS__);            \
@@ -160,7 +153,7 @@ static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl)
 
 static int ocfs2_validate_gd_self(struct super_block *sb,
                                  struct buffer_head *bh,
-                                 int clean_error)
+                                 int resize)
 {
        struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
 
@@ -211,7 +204,7 @@ static int ocfs2_validate_gd_self(struct super_block *sb,
 static int ocfs2_validate_gd_parent(struct super_block *sb,
                                    struct ocfs2_dinode *di,
                                    struct buffer_head *bh,
-                                   int clean_error)
+                                   int resize)
 {
        unsigned int max_bits;
        struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
@@ -233,8 +226,11 @@ static int ocfs2_validate_gd_parent(struct super_block *sb,
                return -EINVAL;
        }
 
-       if (le16_to_cpu(gd->bg_chain) >=
-           le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) {
+       /* In resize, we may meet the case bg_chain == cl_next_free_rec. */
+       if ((le16_to_cpu(gd->bg_chain) >
+            le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) ||
+           ((le16_to_cpu(gd->bg_chain) ==
+            le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) && !resize)) {
                do_error("Group descriptor #%llu has bad chain %u",
                         (unsigned long long)bh->b_blocknr,
                         le16_to_cpu(gd->bg_chain));
@@ -1975,18 +1971,18 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb,
                                      bits_wanted, cluster_start, num_clusters);
 }
 
-static inline int ocfs2_block_group_clear_bits(handle_t *handle,
-                                              struct inode *alloc_inode,
-                                              struct ocfs2_group_desc *bg,
-                                              struct buffer_head *group_bh,
-                                              unsigned int bit_off,
-                                              unsigned int num_bits)
+static int ocfs2_block_group_clear_bits(handle_t *handle,
+                                       struct inode *alloc_inode,
+                                       struct ocfs2_group_desc *bg,
+                                       struct buffer_head *group_bh,
+                                       unsigned int bit_off,
+                                       unsigned int num_bits,
+                                       void (*undo_fn)(unsigned int bit,
+                                                       unsigned long *bmap))
 {
        int status;
        unsigned int tmp;
-       int journal_type = OCFS2_JOURNAL_ACCESS_WRITE;
        struct ocfs2_group_desc *undo_bg = NULL;
-       int cluster_bitmap = 0;
 
        mlog_entry_void();
 
@@ -1996,20 +1992,18 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle,
 
        mlog(0, "off = %u, num = %u\n", bit_off, num_bits);
 
-       if (ocfs2_is_cluster_bitmap(alloc_inode))
-               journal_type = OCFS2_JOURNAL_ACCESS_UNDO;
-
+       BUG_ON(undo_fn && !ocfs2_is_cluster_bitmap(alloc_inode));
        status = ocfs2_journal_access_gd(handle, INODE_CACHE(alloc_inode),
-                                        group_bh, journal_type);
+                                        group_bh,
+                                        undo_fn ?
+                                        OCFS2_JOURNAL_ACCESS_UNDO :
+                                        OCFS2_JOURNAL_ACCESS_WRITE);
        if (status < 0) {
                mlog_errno(status);
                goto bail;
        }
 
-       if (ocfs2_is_cluster_bitmap(alloc_inode))
-               cluster_bitmap = 1;
-
-       if (cluster_bitmap) {
+       if (undo_fn) {
                jbd_lock_bh_state(group_bh);
                undo_bg = (struct ocfs2_group_desc *)
                                        bh2jh(group_bh)->b_committed_data;
@@ -2020,13 +2014,13 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle,
        while(tmp--) {
                ocfs2_clear_bit((bit_off + tmp),
                                (unsigned long *) bg->bg_bitmap);
-               if (cluster_bitmap)
-                       ocfs2_set_bit(bit_off + tmp,
-                                     (unsigned long *) undo_bg->bg_bitmap);
+               if (undo_fn)
+                       undo_fn(bit_off + tmp,
+                               (unsigned long *) undo_bg->bg_bitmap);
        }
        le16_add_cpu(&bg->bg_free_bits_count, num_bits);
 
-       if (cluster_bitmap)
+       if (undo_fn)
                jbd_unlock_bh_state(group_bh);
 
        status = ocfs2_journal_dirty(handle, group_bh);
@@ -2039,12 +2033,14 @@ bail:
 /*
  * expects the suballoc inode to already be locked.
  */
-int ocfs2_free_suballoc_bits(handle_t *handle,
-                            struct inode *alloc_inode,
-                            struct buffer_head *alloc_bh,
-                            unsigned int start_bit,
-                            u64 bg_blkno,
-                            unsigned int count)
+static int _ocfs2_free_suballoc_bits(handle_t *handle,
+                                    struct inode *alloc_inode,
+                                    struct buffer_head *alloc_bh,
+                                    unsigned int start_bit,
+                                    u64 bg_blkno,
+                                    unsigned int count,
+                                    void (*undo_fn)(unsigned int bit,
+                                                    unsigned long *bitmap))
 {
        int status = 0;
        u32 tmp_used;
@@ -2079,7 +2075,7 @@ int ocfs2_free_suballoc_bits(handle_t *handle,
 
        status = ocfs2_block_group_clear_bits(handle, alloc_inode,
                                              group, group_bh,
-                                             start_bit, count);
+                                             start_bit, count, undo_fn);
        if (status < 0) {
                mlog_errno(status);
                goto bail;
@@ -2110,6 +2106,17 @@ bail:
        return status;
 }
 
+int ocfs2_free_suballoc_bits(handle_t *handle,
+                            struct inode *alloc_inode,
+                            struct buffer_head *alloc_bh,
+                            unsigned int start_bit,
+                            u64 bg_blkno,
+                            unsigned int count)
+{
+       return _ocfs2_free_suballoc_bits(handle, alloc_inode, alloc_bh,
+                                        start_bit, bg_blkno, count, NULL);
+}
+
 int ocfs2_free_dinode(handle_t *handle,
                      struct inode *inode_alloc_inode,
                      struct buffer_head *inode_alloc_bh,
@@ -2123,11 +2130,13 @@ int ocfs2_free_dinode(handle_t *handle,
                                        inode_alloc_bh, bit, bg_blkno, 1);
 }
 
-int ocfs2_free_clusters(handle_t *handle,
-                      struct inode *bitmap_inode,
-                      struct buffer_head *bitmap_bh,
-                      u64 start_blk,
-                      unsigned int num_clusters)
+static int _ocfs2_free_clusters(handle_t *handle,
+                               struct inode *bitmap_inode,
+                               struct buffer_head *bitmap_bh,
+                               u64 start_blk,
+                               unsigned int num_clusters,
+                               void (*undo_fn)(unsigned int bit,
+                                               unsigned long *bitmap))
 {
        int status;
        u16 bg_start_bit;
@@ -2154,9 +2163,9 @@ int ocfs2_free_clusters(handle_t *handle,
        mlog(0, "bg_blkno = %llu, bg_start_bit = %u\n",
             (unsigned long long)bg_blkno, bg_start_bit);
 
-       status = ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh,
-                                         bg_start_bit, bg_blkno,
-                                         num_clusters);
+       status = _ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh,
+                                          bg_start_bit, bg_blkno,
+                                          num_clusters, undo_fn);
        if (status < 0) {
                mlog_errno(status);
                goto out;
@@ -2170,6 +2179,32 @@ out:
        return status;
 }
 
+int ocfs2_free_clusters(handle_t *handle,
+                       struct inode *bitmap_inode,
+                       struct buffer_head *bitmap_bh,
+                       u64 start_blk,
+                       unsigned int num_clusters)
+{
+       return _ocfs2_free_clusters(handle, bitmap_inode, bitmap_bh,
+                                   start_blk, num_clusters,
+                                   _ocfs2_set_bit);
+}
+
+/*
+ * Give never-used clusters back to the global bitmap.  We don't need
+ * to protect these bits in the undo buffer.
+ */
+int ocfs2_release_clusters(handle_t *handle,
+                          struct inode *bitmap_inode,
+                          struct buffer_head *bitmap_bh,
+                          u64 start_blk,
+                          unsigned int num_clusters)
+{
+       return _ocfs2_free_clusters(handle, bitmap_inode, bitmap_bh,
+                                   start_blk, num_clusters,
+                                   _ocfs2_clear_bit);
+}
+
 static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg)
 {
        printk("Block Group:\n");
index fa60723c43e82b0a6d766e8ea439af393a7ce7bd..e0f46df357e664cc7b8c883b1d509fe884fcb950 100644 (file)
@@ -127,6 +127,11 @@ int ocfs2_free_clusters(handle_t *handle,
                        struct buffer_head *bitmap_bh,
                        u64 start_blk,
                        unsigned int num_clusters);
+int ocfs2_release_clusters(handle_t *handle,
+                          struct inode *bitmap_inode,
+                          struct buffer_head *bitmap_bh,
+                          u64 start_blk,
+                          unsigned int num_clusters);
 
 static inline u64 ocfs2_which_suballoc_group(u64 block, unsigned int bit)
 {
index 40e53702948cdbc2ed92ce1e22f0827f76017417..bfe7190cdbf1b0969cc5e2ade3096a9cea16e9ad 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <linux/fs.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/highmem.h>
 
 #define MLOG_MASK_PREFIX ML_INODE
index d1b0d386f6d1c43c58b8e0016530f7830ea6eddf..3e7773089b968d7f29a0986fd65731646d0a382d 100644 (file)
@@ -1622,7 +1622,7 @@ static void ocfs2_xa_block_wipe_namevalue(struct ocfs2_xa_loc *loc)
        /* Now tell xh->xh_entries about it */
        for (i = 0; i < count; i++) {
                offset = le16_to_cpu(xh->xh_entries[i].xe_name_offset);
-               if (offset < namevalue_offset)
+               if (offset <= namevalue_offset)
                        le16_add_cpu(&xh->xh_entries[i].xe_name_offset,
                                     namevalue_size);
        }
@@ -6528,13 +6528,11 @@ static int ocfs2_create_empty_xattr_block(struct inode *inode,
                                          int indexed)
 {
        int ret;
-       struct ocfs2_alloc_context *meta_ac;
        struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
-       struct ocfs2_xattr_set_ctxt ctxt = {
-               .meta_ac = meta_ac,
-       };
+       struct ocfs2_xattr_set_ctxt ctxt;
 
-       ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac);
+       memset(&ctxt, 0, sizeof(ctxt));
+       ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &ctxt.meta_ac);
        if (ret < 0) {
                mlog_errno(ret);
                return ret;
@@ -6556,7 +6554,7 @@ static int ocfs2_create_empty_xattr_block(struct inode *inode,
 
        ocfs2_commit_trans(osb, ctxt.handle);
 out:
-       ocfs2_free_alloc_context(meta_ac);
+       ocfs2_free_alloc_context(ctxt.meta_ac);
        return ret;
 }
 
index 75d9b5ba1d451c9bbdb40fc0baeb49bcd825cf78..c82af6acc2e7250d56db070b549e33e2a2787b50 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/vfs.h>
 #include <linux/parser.h>
index e17f54454b5076b231e37c023abd31a1237445d5..74e5cd9f718e8b43eb17e8dad2f28074591fbaaf 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -10,7 +10,6 @@
 #include <linux/fdtable.h>
 #include <linux/fsnotify.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/namei.h>
 #include <linux/backing-dev.h>
@@ -20,6 +19,7 @@
 #include <linux/mount.h>
 #include <linux/vfs.h>
 #include <linux/fcntl.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/fs.h>
 #include <linux/personality.h>
index e8865c11777f726a9622f7f7835a6c0ac8551021..e238ab23a9e7ff50f712847e3660f4f67a5912d2 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/ctype.h>
 #include <linux/genhd.h>
index 49cfd5f5423894df4c2f52ac48bac1f82a9b43a3..91babdae75875bc0e7510c9594529cca1247e20c 100644 (file)
@@ -95,6 +95,7 @@
  ************************************************************/
 #include <linux/crc32.h>
 #include <linux/math64.h>
+#include <linux/slab.h>
 #include "check.h"
 #include "efi.h"
 
index 0028d2ef0662b0f01fd21b7685754d9939ebbd51..90be97f1f5a8c8ce5cf737c3e52020e0e516a291 100644 (file)
  */
 #include <asm/unaligned.h>
 
-#define SYS_IND(p)     (get_unaligned(&p->sys_ind))
-#define NR_SECTS(p)    ({ __le32 __a = get_unaligned(&p->nr_sects);    \
-                               le32_to_cpu(__a); \
-                       })
+#define SYS_IND(p)     get_unaligned(&p->sys_ind)
 
-#define START_SECT(p)  ({ __le32 __a = get_unaligned(&p->start_sect);  \
-                               le32_to_cpu(__a); \
-                       })
+static inline sector_t nr_sects(struct partition *p)
+{
+       return (sector_t)get_unaligned_le32(&p->nr_sects);
+}
+
+static inline sector_t start_sect(struct partition *p)
+{
+       return (sector_t)get_unaligned_le32(&p->start_sect);
+}
 
 static inline int is_extended_partition(struct partition *p)
 {
@@ -104,13 +107,13 @@ static int aix_magic_present(unsigned char *p, struct block_device *bdev)
 
 static void
 parse_extended(struct parsed_partitions *state, struct block_device *bdev,
-                       u32 first_sector, u32 first_size)
+                       sector_t first_sector, sector_t first_size)
 {
        struct partition *p;
        Sector sect;
        unsigned char *data;
-       u32 this_sector, this_size;
-       int sector_size = bdev_logical_block_size(bdev) / 512;
+       sector_t this_sector, this_size;
+       sector_t sector_size = bdev_logical_block_size(bdev) / 512;
        int loopct = 0;         /* number of links followed
                                   without finding a data partition */
        int i;
@@ -145,14 +148,14 @@ parse_extended(struct parsed_partitions *state, struct block_device *bdev,
                 * First process the data partition(s)
                 */
                for (i=0; i<4; i++, p++) {
-                       u32 offs, size, next;
-                       if (!NR_SECTS(p) || is_extended_partition(p))
+                       sector_t offs, size, next;
+                       if (!nr_sects(p) || is_extended_partition(p))
                                continue;
 
                        /* Check the 3rd and 4th entries -
                           these sometimes contain random garbage */
-                       offs = START_SECT(p)*sector_size;
-                       size = NR_SECTS(p)*sector_size;
+                       offs = start_sect(p)*sector_size;
+                       size = nr_sects(p)*sector_size;
                        next = this_sector + offs;
                        if (i >= 2) {
                                if (offs + size > this_size)
@@ -179,13 +182,13 @@ parse_extended(struct parsed_partitions *state, struct block_device *bdev,
                 */
                p -= 4;
                for (i=0; i<4; i++, p++)
-                       if (NR_SECTS(p) && is_extended_partition(p))
+                       if (nr_sects(p) && is_extended_partition(p))
                                break;
                if (i == 4)
                        goto done;       /* nothing left to do */
 
-               this_sector = first_sector + START_SECT(p) * sector_size;
-               this_size = NR_SECTS(p) * sector_size;
+               this_sector = first_sector + start_sect(p) * sector_size;
+               this_size = nr_sects(p) * sector_size;
                put_dev_sector(sect);
        }
 done:
@@ -197,7 +200,7 @@ done:
 
 static void
 parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev,
-                       u32 offset, u32 size, int origin)
+                       sector_t offset, sector_t size, int origin)
 {
 #ifdef CONFIG_SOLARIS_X86_PARTITION
        Sector sect;
@@ -244,7 +247,7 @@ parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev,
  */
 static void
 parse_bsd(struct parsed_partitions *state, struct block_device *bdev,
-               u32 offset, u32 size, int origin, char *flavour,
+               sector_t offset, sector_t size, int origin, char *flavour,
                int max_partitions)
 {
        Sector sect;
@@ -263,7 +266,7 @@ parse_bsd(struct parsed_partitions *state, struct block_device *bdev,
        if (le16_to_cpu(l->d_npartitions) < max_partitions)
                max_partitions = le16_to_cpu(l->d_npartitions);
        for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) {
-               u32 bsd_start, bsd_size;
+               sector_t bsd_start, bsd_size;
 
                if (state->next == state->limit)
                        break;
@@ -290,7 +293,7 @@ parse_bsd(struct parsed_partitions *state, struct block_device *bdev,
 
 static void
 parse_freebsd(struct parsed_partitions *state, struct block_device *bdev,
-               u32 offset, u32 size, int origin)
+               sector_t offset, sector_t size, int origin)
 {
 #ifdef CONFIG_BSD_DISKLABEL
        parse_bsd(state, bdev, offset, size, origin,
@@ -300,7 +303,7 @@ parse_freebsd(struct parsed_partitions *state, struct block_device *bdev,
 
 static void
 parse_netbsd(struct parsed_partitions *state, struct block_device *bdev,
-               u32 offset, u32 size, int origin)
+               sector_t offset, sector_t size, int origin)
 {
 #ifdef CONFIG_BSD_DISKLABEL
        parse_bsd(state, bdev, offset, size, origin,
@@ -310,7 +313,7 @@ parse_netbsd(struct parsed_partitions *state, struct block_device *bdev,
 
 static void
 parse_openbsd(struct parsed_partitions *state, struct block_device *bdev,
-               u32 offset, u32 size, int origin)
+               sector_t offset, sector_t size, int origin)
 {
 #ifdef CONFIG_BSD_DISKLABEL
        parse_bsd(state, bdev, offset, size, origin,
@@ -324,7 +327,7 @@ parse_openbsd(struct parsed_partitions *state, struct block_device *bdev,
  */
 static void
 parse_unixware(struct parsed_partitions *state, struct block_device *bdev,
-               u32 offset, u32 size, int origin)
+               sector_t offset, sector_t size, int origin)
 {
 #ifdef CONFIG_UNIXWARE_DISKLABEL
        Sector sect;
@@ -348,7 +351,8 @@ parse_unixware(struct parsed_partitions *state, struct block_device *bdev,
 
                if (p->s_label != UNIXWARE_FS_UNUSED)
                        put_partition(state, state->next++,
-                                               START_SECT(p), NR_SECTS(p));
+                                     le32_to_cpu(p->start_sect),
+                                     le32_to_cpu(p->nr_sects));
                p++;
        }
        put_dev_sector(sect);
@@ -363,7 +367,7 @@ parse_unixware(struct parsed_partitions *state, struct block_device *bdev,
  */
 static void
 parse_minix(struct parsed_partitions *state, struct block_device *bdev,
-               u32 offset, u32 size, int origin)
+               sector_t offset, sector_t size, int origin)
 {
 #ifdef CONFIG_MINIX_SUBPARTITION
        Sector sect;
@@ -390,7 +394,7 @@ parse_minix(struct parsed_partitions *state, struct block_device *bdev,
                        /* add each partition in use */
                        if (SYS_IND(p) == MINIX_PARTITION)
                                put_partition(state, state->next++,
-                                             START_SECT(p), NR_SECTS(p));
+                                             start_sect(p), nr_sects(p));
                }
                printk(" >\n");
        }
@@ -401,7 +405,7 @@ parse_minix(struct parsed_partitions *state, struct block_device *bdev,
 static struct {
        unsigned char id;
        void (*parse)(struct parsed_partitions *, struct block_device *,
-                       u32, u32, int);
+                       sector_t, sector_t, int);
 } subtypes[] = {
        {FREEBSD_PARTITION, parse_freebsd},
        {NETBSD_PARTITION, parse_netbsd},
@@ -415,7 +419,7 @@ static struct {
  
 int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
-       int sector_size = bdev_logical_block_size(bdev) / 512;
+       sector_t sector_size = bdev_logical_block_size(bdev) / 512;
        Sector sect;
        unsigned char *data;
        struct partition *p;
@@ -483,14 +487,21 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
 
        state->next = 5;
        for (slot = 1 ; slot <= 4 ; slot++, p++) {
-               u32 start = START_SECT(p)*sector_size;
-               u32 size = NR_SECTS(p)*sector_size;
+               sector_t start = start_sect(p)*sector_size;
+               sector_t size = nr_sects(p)*sector_size;
                if (!size)
                        continue;
                if (is_extended_partition(p)) {
-                       /* prevent someone doing mkfs or mkswap on an
-                          extended partition, but leave room for LILO */
-                       put_partition(state, slot, start, size == 1 ? 1 : 2);
+                       /*
+                        * prevent someone doing mkfs or mkswap on an
+                        * extended partition, but leave room for LILO
+                        * FIXME: this uses one logical sector for > 512b
+                        * sector, although it may not be enough/proper.
+                        */
+                       sector_t n = 2;
+                       n = min(size, max(sector_size, n));
+                       put_partition(state, slot, start, n);
+
                        printk(" <");
                        parse_extended(state, bdev, start, size);
                        printk(" >");
@@ -513,7 +524,7 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
                unsigned char id = SYS_IND(p);
                int n;
 
-               if (!NR_SECTS(p))
+               if (!nr_sects(p))
                        continue;
 
                for (n = 0; subtypes[n].parse && id != subtypes[n].id; n++)
@@ -521,8 +532,8 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev)
 
                if (!subtypes[n].parse)
                        continue;
-               subtypes[n].parse(state, bdev, START_SECT(p)*sector_size,
-                                               NR_SECTS(p)*sector_size, slot);
+               subtypes[n].parse(state, bdev, start_sect(p)*sector_size,
+                                               nr_sects(p)*sector_size, slot);
        }
        put_dev_sector(sect);
        return 1;
index aa8637b81028b573c4feb395541be560aab5a1a3..885ab5513ac5cfe10e18c4fba149ddf478252f40 100644 (file)
@@ -68,7 +68,6 @@
 #include <linux/hugetlb.h>
 #include <linux/pagemap.h>
 #include <linux/swap.h>
-#include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/signal.h>
 #include <linux/highmem.h>
@@ -82,7 +81,6 @@
 #include <linux/pid_namespace.h>
 #include <linux/ptrace.h>
 #include <linux/tracehook.h>
-#include <linux/swapops.h>
 
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -496,7 +494,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 && mm) ? task->stack_start : 0,
+               (permitted && mm) ? mm->start_stack : 0,
                esp,
                eip,
                /* The signal information here is obsolete.
index a7310841c83149e406c1089d30a8c27b2c1e67fb..8418fcc0a6abd1efb58c0c66efdb1fef411d81d8 100644 (file)
@@ -81,6 +81,7 @@
 #include <linux/elf.h>
 #include <linux/pid_namespace.h>
 #include <linux/fs_struct.h>
+#include <linux/slab.h>
 #include "internal.h"
 
 /* NOTE:
@@ -442,12 +443,13 @@ static const struct file_operations proc_lstats_operations = {
 unsigned long badness(struct task_struct *p, unsigned long uptime);
 static int proc_oom_score(struct task_struct *task, char *buffer)
 {
-       unsigned long points;
+       unsigned long points = 0;
        struct timespec uptime;
 
        do_posix_clock_monotonic_gettime(&uptime);
        read_lock(&tasklist_lock);
-       points = badness(task->group_leader, uptime.tv_sec);
+       if (pid_alive(task))
+               points = badness(task, uptime.tv_sec);
        read_unlock(&tasklist_lock);
        return sprintf(buffer, "%lu\n", points);
 }
@@ -2907,7 +2909,7 @@ out_no_task:
  */
 static const struct pid_entry tid_base_stuff[] = {
        DIR("fd",        S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
-       DIR("fdinfo",    S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fd_operations),
+       DIR("fdinfo",    S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fdinfo_operations),
        REG("environ",   S_IRUSR, proc_environ_operations),
        INF("auxv",      S_IRUSR, proc_pid_auxv),
        ONE("status",    S_IRUGO, proc_pid_status),
index 08f4d71dacd7fba3e9a704cb77c9131b6d0c5d69..43c127490606d1a3ab3c47bee8309b92176d5f3c 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/mount.h>
 #include <linux/init.h>
 #include <linux/idr.h>
index 445a02bcaab31d88963e1d0c7deeeb25572efb97..d35b23238fb1902416ff953f87c9edd2a636899c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/smp_lock.h>
 #include <linux/sysctl.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
index a44a7897fd4d20988aa933a89fab2d9c1600d53a..19979a2ce27204d1851c96bc3126fd201a68651f 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/highmem.h>
 #include <linux/bootmem.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <linux/list.h>
@@ -490,7 +491,7 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
                }
                read_unlock(&kclist_lock);
 
-               if (m == NULL) {
+               if (&m->list == &kclist_head) {
                        if (clear_user(buffer, tsz))
                                return -EFAULT;
                } else if (is_vmalloc_or_module_addr((void *)start)) {
index 9fe7d7ebe1157864561a8cb3d0166eb827e5839a..b1822dde55c2a992cb1cfb16c3dd0b56d0ed1e4e 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/mmzone.h>
 #include <linux/pagemap.h>
 #include <linux/swap.h>
-#include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/seq_file.h>
 #include <linux/hugetlb.h>
index f8650dce74fb069c6a66a497c4933cc50e630539..ce94801f48cafefce01dcc37da6f0037b77de3e5 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/string.h>
 #include <linux/of.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/prom.h>
 #include <asm/uaccess.h>
 #include "internal.h"
index 04d1270f1c38687da3e925ef395e73dfcdd79022..9020ac15baaaf4d3791fb190a50654e557851e95 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/time.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/module.h>
index b9b7aad2003d10f757e048a6b1dc1564c2c8e8c1..bf31b03fc275295e576554abdbea4f5264b99a23 100644 (file)
@@ -1,6 +1,5 @@
 #include <linux/cpumask.h>
 #include <linux/fs.h>
-#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
index 183f8ff5f400b90d8b128465551d8157004f20d2..47f5b145f56eee5aaefc3b52aac8fa78b978b692 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/seq_file.h>
 #include <linux/highmem.h>
 #include <linux/ptrace.h>
+#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/mempolicy.h>
 #include <linux/swap.h>
@@ -246,25 +247,6 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
                                } else if (vma->vm_start <= mm->start_stack &&
                                           vma->vm_end >= mm->start_stack) {
                                        name = "[stack]";
-                               } else {
-                                       unsigned long stack_start;
-                                       struct proc_maps_private *pmp;
-
-                                       pmp = m->private;
-                                       stack_start = pmp->task->stack_start;
-
-                                       if (vma->vm_start <= stack_start &&
-                                           vma->vm_end >= stack_start) {
-                                               pad_len_spaces(m, len);
-                                               seq_printf(m,
-                                                "[threadstack:%08lx]",
-#ifdef CONFIG_STACK_GROWSUP
-                                                vma->vm_end - stack_start
-#else
-                                                stack_start - vma->vm_start
-#endif
-                                               );
-                                       }
                                }
                        } else {
                                name = "[vdso]";
@@ -406,6 +388,7 @@ static int show_smap(struct seq_file *m, void *v)
 
        memset(&mss, 0, sizeof mss);
        mss.vma = vma;
+       /* mmap_sem is held in m_start */
        if (vma->vm_mm && !is_vm_hugetlb_page(vma))
                walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
 
@@ -552,7 +535,8 @@ const struct file_operations proc_clear_refs_operations = {
 };
 
 struct pagemapread {
-       u64 __user *out, *end;
+       int pos, len;
+       u64 *buffer;
 };
 
 #define PM_ENTRY_BYTES      sizeof(u64)
@@ -575,10 +559,8 @@ struct pagemapread {
 static int add_to_pagemap(unsigned long addr, u64 pfn,
                          struct pagemapread *pm)
 {
-       if (put_user(pfn, pm->out))
-               return -EFAULT;
-       pm->out++;
-       if (pm->out >= pm->end)
+       pm->buffer[pm->pos++] = pfn;
+       if (pm->pos >= pm->len)
                return PM_END_OF_BUFFER;
        return 0;
 }
@@ -661,31 +643,18 @@ static u64 huge_pte_to_pagemap_entry(pte_t pte, int offset)
        return pme;
 }
 
-static int pagemap_hugetlb_range(pte_t *pte, unsigned long addr,
-                                unsigned long end, struct mm_walk *walk)
+/* This function walks within one hugetlb entry in the single call */
+static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask,
+                                unsigned long addr, unsigned long end,
+                                struct mm_walk *walk)
 {
-       struct vm_area_struct *vma;
        struct pagemapread *pm = walk->private;
-       struct hstate *hs = NULL;
        int err = 0;
+       u64 pfn;
 
-       vma = find_vma(walk->mm, addr);
-       if (vma)
-               hs = hstate_vma(vma);
        for (; addr != end; addr += PAGE_SIZE) {
-               u64 pfn = PM_NOT_PRESENT;
-
-               if (vma && (addr >= vma->vm_end)) {
-                       vma = find_vma(walk->mm, addr);
-                       if (vma)
-                               hs = hstate_vma(vma);
-               }
-
-               if (vma && (vma->vm_start <= addr) && is_vm_hugetlb_page(vma)) {
-                       /* calculate pfn of the "raw" page in the hugepage. */
-                       int offset = (addr & ~huge_page_mask(hs)) >> PAGE_SHIFT;
-                       pfn = huge_pte_to_pagemap_entry(*pte, offset);
-               }
+               int offset = (addr & ~hmask) >> PAGE_SHIFT;
+               pfn = huge_pte_to_pagemap_entry(*pte, offset);
                err = add_to_pagemap(addr, pfn, pm);
                if (err)
                        return err;
@@ -720,21 +689,20 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long addr,
  * determine which areas of memory are actually mapped and llseek to
  * skip over unmapped regions.
  */
+#define PAGEMAP_WALK_SIZE      (PMD_SIZE)
 static ssize_t pagemap_read(struct file *file, char __user *buf,
                            size_t count, loff_t *ppos)
 {
        struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
-       struct page **pages, *page;
-       unsigned long uaddr, uend;
        struct mm_struct *mm;
        struct pagemapread pm;
-       int pagecount;
        int ret = -ESRCH;
        struct mm_walk pagemap_walk = {};
        unsigned long src;
        unsigned long svpfn;
        unsigned long start_vaddr;
        unsigned long end_vaddr;
+       int copied = 0;
 
        if (!task)
                goto out;
@@ -757,35 +725,12 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
        if (!mm)
                goto out_task;
 
-
-       uaddr = (unsigned long)buf & PAGE_MASK;
-       uend = (unsigned long)(buf + count);
-       pagecount = (PAGE_ALIGN(uend) - uaddr) / PAGE_SIZE;
-       ret = 0;
-       if (pagecount == 0)
-               goto out_mm;
-       pages = kcalloc(pagecount, sizeof(struct page *), GFP_KERNEL);
+       pm.len = PM_ENTRY_BYTES * (PAGEMAP_WALK_SIZE >> PAGE_SHIFT);
+       pm.buffer = kmalloc(pm.len, GFP_TEMPORARY);
        ret = -ENOMEM;
-       if (!pages)
+       if (!pm.buffer)
                goto out_mm;
 
-       down_read(&current->mm->mmap_sem);
-       ret = get_user_pages(current, current->mm, uaddr, pagecount,
-                            1, 0, pages, NULL);
-       up_read(&current->mm->mmap_sem);
-
-       if (ret < 0)
-               goto out_free;
-
-       if (ret != pagecount) {
-               pagecount = ret;
-               ret = -EFAULT;
-               goto out_pages;
-       }
-
-       pm.out = (u64 __user *)buf;
-       pm.end = (u64 __user *)(buf + count);
-
        pagemap_walk.pmd_entry = pagemap_pte_range;
        pagemap_walk.pte_hole = pagemap_pte_hole;
        pagemap_walk.hugetlb_entry = pagemap_hugetlb_range;
@@ -807,23 +752,36 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
         * user buffer is tracked in "pm", and the walk
         * will stop when we hit the end of the buffer.
         */
-       ret = walk_page_range(start_vaddr, end_vaddr, &pagemap_walk);
-       if (ret == PM_END_OF_BUFFER)
-               ret = 0;
-       /* don't need mmap_sem for these, but this looks cleaner */
-       *ppos += (char __user *)pm.out - buf;
-       if (!ret)
-               ret = (char __user *)pm.out - buf;
-
-out_pages:
-       for (; pagecount; pagecount--) {
-               page = pages[pagecount-1];
-               if (!PageReserved(page))
-                       SetPageDirty(page);
-               page_cache_release(page);
+       ret = 0;
+       while (count && (start_vaddr < end_vaddr)) {
+               int len;
+               unsigned long end;
+
+               pm.pos = 0;
+               end = start_vaddr + PAGEMAP_WALK_SIZE;
+               /* overflow ? */
+               if (end < start_vaddr || end > end_vaddr)
+                       end = end_vaddr;
+               down_read(&mm->mmap_sem);
+               ret = walk_page_range(start_vaddr, end, &pagemap_walk);
+               up_read(&mm->mmap_sem);
+               start_vaddr = end;
+
+               len = min(count, PM_ENTRY_BYTES * pm.pos);
+               if (copy_to_user(buf, pm.buffer, len)) {
+                       ret = -EFAULT;
+                       goto out_free;
+               }
+               copied += len;
+               buf += len;
+               count -= len;
        }
+       *ppos += copied;
+       if (!ret || ret == PM_END_OF_BUFFER)
+               ret = copied;
+
 out_free:
-       kfree(pages);
+       kfree(pm.buffer);
 out_mm:
        mmput(mm);
 out_task:
index 5d9fd64ef81a9ad76b1525943cc34a79b0a6a33d..46d4b5d72bd33d2e01b9c5e731e8842e616f70f9 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/fs_struct.h>
 #include <linux/mount.h>
 #include <linux/ptrace.h>
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 #include "internal.h"
 
index 0872afa58d3987682bbdb4afdfdf5e24a95669f7..9fbc99ec799a5636e455cc1982b5196ad3096690 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/user.h>
 #include <linux/elf.h>
 #include <linux/elfcore.h>
+#include <linux/slab.h>
 #include <linux/highmem.h>
 #include <linux/bootmem.h>
 #include <linux/init.h>
index dad7fb247ddc30a387a55870d051062c2d8c78f9..3e21b1e2ad3a7c63203c4bf6291ffb6f82907aba 100644 (file)
@@ -33,6 +33,14 @@ config PRINT_QUOTA_WARNING
          Note that this behavior is currently deprecated and may go away in
          future. Please use notification via netlink socket instead.
 
+config QUOTA_DEBUG
+       bool "Additional quota sanity checks"
+       depends on QUOTA
+       default n
+       help
+         If you say Y here, quota subsystem will perform some additional
+         sanity checks of quota internal structures. If unsure, say N.
+
 # Generic support for tree structured quota files. Selected when needed.
 config QUOTA_TREE
         tristate
index e0b870f4749f2ad01abab80d56e66759359f43c2..788b5802a7ce5dc043066d9fa20278aa0e9ef2bf 100644 (file)
@@ -80,8 +80,6 @@
 
 #include <asm/uaccess.h>
 
-#define __DQUOT_PARANOIA
-
 /*
  * There are three quota SMP locks. dq_list_lock protects all lists with quotas
  * and quota formats, dqstats structure containing statistics about the lists
@@ -695,7 +693,7 @@ void dqput(struct dquot *dquot)
 
        if (!dquot)
                return;
-#ifdef __DQUOT_PARANOIA
+#ifdef CONFIG_QUOTA_DEBUG
        if (!atomic_read(&dquot->dq_count)) {
                printk("VFS: dqput: trying to free free dquot\n");
                printk("VFS: device %s, dquot of %s %d\n",
@@ -748,7 +746,7 @@ we_slept:
                goto we_slept;
        }
        atomic_dec(&dquot->dq_count);
-#ifdef __DQUOT_PARANOIA
+#ifdef CONFIG_QUOTA_DEBUG
        /* sanity check */
        BUG_ON(!list_empty(&dquot->dq_free));
 #endif
@@ -845,7 +843,7 @@ we_slept:
                dquot = NULL;
                goto out;
        }
-#ifdef __DQUOT_PARANOIA
+#ifdef CONFIG_QUOTA_DEBUG
        BUG_ON(!dquot->dq_sb);  /* Has somebody invalidated entry under us? */
 #endif
 out:
@@ -874,14 +872,18 @@ static int dqinit_needed(struct inode *inode, int type)
 static void add_dquot_ref(struct super_block *sb, int type)
 {
        struct inode *inode, *old_inode = NULL;
+#ifdef CONFIG_QUOTA_DEBUG
        int reserved = 0;
+#endif
 
        spin_lock(&inode_lock);
        list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
                if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW))
                        continue;
+#ifdef CONFIG_QUOTA_DEBUG
                if (unlikely(inode_get_rsv_space(inode) > 0))
                        reserved = 1;
+#endif
                if (!atomic_read(&inode->i_writecount))
                        continue;
                if (!dqinit_needed(inode, type))
@@ -903,11 +905,13 @@ static void add_dquot_ref(struct super_block *sb, int type)
        spin_unlock(&inode_lock);
        iput(old_inode);
 
+#ifdef CONFIG_QUOTA_DEBUG
        if (reserved) {
                printk(KERN_WARNING "VFS (%s): Writes happened before quota"
                        " was turned on thus quota information is probably "
                        "inconsistent. Please run quotacheck(8).\n", sb->s_id);
        }
+#endif
 }
 
 /*
@@ -934,7 +938,7 @@ static int remove_inode_dquot_ref(struct inode *inode, int type,
        inode->i_dquot[type] = NULL;
        if (dquot) {
                if (dqput_blocks(dquot)) {
-#ifdef __DQUOT_PARANOIA
+#ifdef CONFIG_QUOTA_DEBUG
                        if (atomic_read(&dquot->dq_count) != 1)
                                printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", atomic_read(&dquot->dq_count));
 #endif
@@ -2322,34 +2326,34 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
        if (di->dqb_valid & QIF_SPACE) {
                dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace;
                check_blim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
        }
        if (di->dqb_valid & QIF_BLIMITS) {
                dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit);
                dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit);
                check_blim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
        }
        if (di->dqb_valid & QIF_INODES) {
                dm->dqb_curinodes = di->dqb_curinodes;
                check_ilim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
        }
        if (di->dqb_valid & QIF_ILIMITS) {
                dm->dqb_isoftlimit = di->dqb_isoftlimit;
                dm->dqb_ihardlimit = di->dqb_ihardlimit;
                check_ilim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
        }
        if (di->dqb_valid & QIF_BTIME) {
                dm->dqb_btime = di->dqb_btime;
                check_blim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
        }
        if (di->dqb_valid & QIF_ITIME) {
                dm->dqb_itime = di->dqb_itime;
                check_ilim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
        }
 
        if (check_blim) {
index 2663ed90fb0340d54c8d863014b4258352837a7c..d67908b407d99dbad1f3f91a1e0c561cbab60768 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/kernel.h>
 #include <linux/quotaops.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <net/netlink.h>
 #include <net/genetlink.h>
 
index 1739a4aba25fc02cee3bbbec52354940fb0166dd..5ea4ad81a429c24e5be49fbb1fc7317b4431d91f 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/pagevec.h>
 #include <linux/mman.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include "internal.h"
index a6090aa1a7c138e31fd71eb3b99b8f9c3cbc6ab4..c94853473ca993d134f84df734791c8d4715e588 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/sched.h>
 #include <linux/parser.h>
 #include <linux/magic.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include "internal.h"
 
index b7f4a1f94d48eff7711d8d2761b019385142d7f7..113386d6fd2de0bdd12721e65b85a0fcbe8ab7b1 100644 (file)
@@ -258,6 +258,7 @@ ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *pp
        init_sync_kiocb(&kiocb, filp);
        kiocb.ki_pos = *ppos;
        kiocb.ki_left = len;
+       kiocb.ki_nbytes = len;
 
        for (;;) {
                ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
@@ -313,6 +314,7 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof
        init_sync_kiocb(&kiocb, filp);
        kiocb.ki_pos = *ppos;
        kiocb.ki_left = len;
+       kiocb.ki_nbytes = len;
 
        for (;;) {
                ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
index c094f58c7448b06d1da88d87ebbbeb4e27dd7872..07930449a9583ebee29e5781c3e4dbf9f609aa6f 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/reiserfs_fs.h>
 #include <linux/stat.h>
 #include <linux/buffer_head.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 extern const struct reiserfs_key MIN_KEY;
@@ -45,8 +46,6 @@ static inline bool is_privroot_deh(struct dentry *dir,
                                   struct reiserfs_de_head *deh)
 {
        struct dentry *privroot = REISERFS_SB(dir->d_sb)->priv_root;
-       if (reiserfs_expose_privroot(dir->d_sb))
-               return 0;
        return (dir == dir->d_parent && privroot->d_inode &&
                deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid);
 }
index 6591cb21edf6597fbd04d3bbd31695745dfc1b38..1e4250bc3a6f168d49ab2ead734e1e16726dedc7 100644 (file)
@@ -35,6 +35,7 @@
  **/
 
 #include <linux/time.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/buffer_head.h>
index d1da94b82d8f77115a714f1cc75ab36f9a84ba6c..dc2c65e04853b8750d0a1fad38ea5521daa185af 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/smp_lock.h>
 #include <linux/pagemap.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 #include <linux/buffer_head.h>
index ba98546fabbd1921beedc54074f7399115f14f54..19fbc810e8e74f951a33e3f6611ca7ec2ee2f6e1 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/blkdev.h>
 #include <linux/backing-dev.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 
@@ -2217,6 +2218,15 @@ static int journal_read_transaction(struct super_block *sb,
                brelse(d_bh);
                return 1;
        }
+
+       if (bdev_read_only(sb->s_bdev)) {
+               reiserfs_warning(sb, "clm-2076",
+                                "device is readonly, unable to replay log");
+               brelse(c_bh);
+               brelse(d_bh);
+               return -EROFS;
+       }
+
        trans_id = get_desc_trans_id(desc);
        /* now we know we've got a good transaction, and it was inside the valid time ranges */
        log_blocks = kmalloc(get_desc_trans_len(desc) *
@@ -2459,12 +2469,6 @@ static int journal_read(struct super_block *sb)
                goto start_log_replay;
        }
 
-       if (continue_replay && bdev_read_only(sb->s_bdev)) {
-               reiserfs_warning(sb, "clm-2076",
-                                "device is readonly, unable to replay log");
-               return -1;
-       }
-
        /* ok, there are transactions that need to be replayed.  start with the first log block, find
         ** all the valid transactions, and pick out the oldest.
         */
index 96e4cbbfaa1887337660ce65b1795f125dec6623..d0c43cb99ffc3b87da5e68fbe6d94b5b20970e63 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/time.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/reiserfs_acl.h>
 #include <linux/reiserfs_xattr.h>
index 04bf5d791bdad8b9fea4c6eecc6d7772035d7144..59125fb36d42482fd8fc3b6cfc9d63576890ca8e 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/time.h>
 #include <asm/uaccess.h>
@@ -1618,10 +1619,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
        save_mount_options(s, data);
 
        sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL);
-       if (!sbi) {
-               errval = -ENOMEM;
-               goto error_alloc;
-       }
+       if (!sbi)
+               return -ENOMEM;
        s->s_fs_info = sbi;
        /* Set default values for options: non-aggressive tails, RO on errors */
        REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL);
@@ -1878,12 +1877,12 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
        return (0);
 
 error:
-       reiserfs_write_unlock(s);
-error_alloc:
        if (jinit_done) {       /* kill the commit thread, free journal ram */
                journal_release_error(NULL, s);
        }
 
+       reiserfs_write_unlock(s);
+
        reiserfs_free_bitmap_cache(s);
        if (SB_BUFFER_WITH_SB(s))
                brelse(SB_BUFFER_WITH_SB(s));
index 37d034ca7d994a8c84496dde7d9d88c54a3f441b..e7cc00e636dcb0d8049754c73c2ef397b9b33fc4 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/dcache.h>
 #include <linux/namei.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <linux/fs.h>
 #include <linux/file.h>
 #include <linux/pagemap.h>
@@ -553,7 +554,7 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th,
        if (!err && new_size < i_size_read(dentry->d_inode)) {
                struct iattr newattrs = {
                        .ia_ctime = current_fs_time(inode->i_sb),
-                       .ia_size = buffer_size,
+                       .ia_size = new_size,
                        .ia_valid = ATTR_SIZE | ATTR_CTIME,
                };
 
@@ -972,21 +973,13 @@ int reiserfs_permission(struct inode *inode, int mask)
        return generic_permission(inode, mask, NULL);
 }
 
-/* This will catch lookups from the fs root to .reiserfs_priv */
-static int
-xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name)
+static int xattr_hide_revalidate(struct dentry *dentry, struct nameidata *nd)
 {
-       struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root;
-       if (container_of(q1, struct dentry, d_name) == priv_root)
-               return -ENOENT;
-       if (q1->len == name->len &&
-                  !memcmp(q1->name, name->name, name->len))
-               return 0;
-       return 1;
+       return -EPERM;
 }
 
 static const struct dentry_operations xattr_lookup_poison_ops = {
-       .d_compare = xattr_lookup_poison,
+       .d_revalidate = xattr_hide_revalidate,
 };
 
 int reiserfs_lookup_privroot(struct super_block *s)
@@ -1000,8 +993,7 @@ int reiserfs_lookup_privroot(struct super_block *s)
                                strlen(PRIVROOT_NAME));
        if (!IS_ERR(dentry)) {
                REISERFS_SB(s)->priv_root = dentry;
-               if (!reiserfs_expose_privroot(s))
-                       s->s_root->d_op = &xattr_lookup_poison_ops;
+               dentry->d_op = &xattr_lookup_poison_ops;
                if (dentry->d_inode)
                        dentry->d_inode->i_flags |= S_PRIVATE;
        } else
index dd20a7883f0f3a2606d3b4d8bf9ca2a65f274fbb..9cdb759645a958405f054aef790d574bc2f006a2 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/errno.h>
 #include <linux/pagemap.h>
 #include <linux/xattr.h>
+#include <linux/slab.h>
 #include <linux/posix_acl_xattr.h>
 #include <linux/reiserfs_xattr.h>
 #include <linux/reiserfs_acl.h>
index d8b5bfcbdd30b027aae6c9eae937b566b7b2043d..7271a477c041de88251e0a9faa0286ce539eb392 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/fs.h>
 #include <linux/pagemap.h>
 #include <linux/xattr.h>
+#include <linux/slab.h>
 #include <linux/reiserfs_xattr.h>
 #include <linux/security.h>
 #include <asm/uaccess.h>
@@ -76,7 +77,7 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode,
                return error;
        }
 
-       if (sec->length) {
+       if (sec->length && reiserfs_xattrs_initialized(inode->i_sb)) {
                blocks = reiserfs_xattr_jcreate_nblocks(inode) +
                         reiserfs_xattr_nblocks(inode, sec->length);
                /* We don't want to count the directories twice if we have
index 1dabe4ee02fe93931ae741344405bee1daca3cd0..f329849ce3c0d36fc268a1ae9b56638035d76361 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/list.h>
index 92d5e8ffb63923062680d09906f8baa7ad53d8c8..dbf6548bbf06b6bc761a38d05232d928ce61b866 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/fcntl.h>
 #include <linux/stat.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/smp_lock.h>
 #include <linux/net.h>
index 1c4c8f089970041c49de182704bf537dbfce9259..dfa1d67f8fca7be9b365dcd1976810aeaf8fe4cb 100644 (file)
@@ -479,6 +479,7 @@ smb_put_super(struct super_block *sb)
        if (server->conn_pid)
                kill_pid(server->conn_pid, SIGTERM, 1);
 
+       bdi_destroy(&server->bdi);
        kfree(server->ops);
        smb_unload_nls(server);
        sb->s_fs_info = NULL;
@@ -525,6 +526,11 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
        if (!server)
                goto out_no_server;
        sb->s_fs_info = server;
+       
+       if (bdi_setup_and_register(&server->bdi, "smbfs", BDI_CAP_MAP_COPY))
+               goto out_bdi;
+
+       sb->s_bdi = &server->bdi;
 
        server->super_block = sb;
        server->mnt = NULL;
@@ -624,6 +630,8 @@ out_no_smbiod:
 out_bad_option:
        kfree(mem);
 out_no_mem:
+       bdi_destroy(&server->bdi);
+out_bdi:
        if (!server->mnt)
                printk(KERN_ERR "smb_fill_super: allocation failure\n");
        sb->s_fs_info = NULL;
index 6bd9b691a463f783058b03a84d6de28b49813ee7..0e39a924f10af29fc90697353501b9f6a18008eb 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/string.h>
 #include <linux/stat.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/file.h>
 #include <linux/dcache.h>
index 00b2909bd469e30fc9c074029cd1d2789515f2b8..54350b59046ba26ccf4a4d339ec1fc793b960e69 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/pagemap.h>
 #include <linux/net.h>
 #include <linux/namei.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
index 39208663aaf177f56b3e500fd33d8a56a5ecb500..9313b6124a2e40c7824e6f03b4fc5af72c1cd00a 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/syscalls.h>
 #include <linux/uio.h>
 #include <linux/security.h>
+#include <linux/gfp.h>
 
 /*
  * Attempt to steal a page from a pipe buffer. This should perhaps go into
index 1cb0d81b164b5cf02ff67ceedc8275838b6db868..653c030eb840db0757df698745beca793ce03bf5 100644 (file)
@@ -87,9 +87,8 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
        u64 cur_index = index >> msblk->devblksize_log2;
        int bytes, compressed, b = 0, k = 0, page = 0, avail;
 
-
-       bh = kcalloc((msblk->block_size >> msblk->devblksize_log2) + 1,
-                               sizeof(*bh), GFP_KERNEL);
+       bh = kcalloc(((srclength + msblk->devblksize - 1)
+               >> msblk->devblksize_log2) + 1, sizeof(*bh), GFP_KERNEL);
        if (bh == NULL)
                return -ENOMEM;
 
index 3550aec2f655ccb1a9a8a04dae5a9bb2df4fdc52..48b6f4a385a60ccf40276bb08c0e591edd3561b1 100644 (file)
@@ -275,7 +275,8 @@ allocate_root:
 
        err = squashfs_read_inode(root, root_inode);
        if (err) {
-               iget_failed(root);
+               make_bad_inode(root);
+               iput(root);
                goto failed_mount;
        }
        insert_inode_hash(root);
@@ -353,6 +354,7 @@ static void squashfs_put_super(struct super_block *sb)
                kfree(sbi->id_table);
                kfree(sbi->fragment_index);
                kfree(sbi->meta_index);
+               kfree(sbi->inode_lookup_table);
                kfree(sb->s_fs_info);
                sb->s_fs_info = NULL;
        }
index e80be2022a7fceebfbd37383c65f3b032b45ed00..32b911f4ee39e859d9a03d7b68b8ef7e33e11552 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/fs.h>
 #include <linux/vfs.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/pagemap.h>
 
index 4dd70e04333bdd8bd1347dbbaaed97cf72eab838..7a603874e483166022a58ee788d0877b99d4505f 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/mutex.h>
 #include <linux/buffer_head.h>
+#include <linux/slab.h>
 #include <linux/zlib.h>
 
 #include "squashfs_fs.h"
@@ -127,8 +128,9 @@ static int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer,
                goto release_mutex;
        }
 
+       length = stream->total_out;
        mutex_unlock(&msblk->read_data_mutex);
-       return stream->total_out;
+       return length;
 
 release_mutex:
        mutex_unlock(&msblk->read_data_mutex);
index f35ac6022109d3a61e1ddb7cabbc67db8d5cf107..1527e6a0ee358d084a29f542816a91c4418f5ef6 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/kobject.h>
 #include <linux/mutex.h>
 #include <linux/file.h>
+#include <linux/backing-dev.h>
 #include <asm/uaccess.h>
 #include "internal.h"
 
@@ -693,6 +694,7 @@ int set_anon_super(struct super_block *s, void *data)
                return -EMFILE;
        }
        s->s_dev = MKDEV(0, dev & MINORMASK);
+       s->s_bdi = &noop_backing_dev_info;
        return 0;
 }
 
@@ -954,10 +956,11 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
        if (error < 0)
                goto out_free_secdata;
        BUG_ON(!mnt->mnt_sb);
+       WARN_ON(!mnt->mnt_sb->s_bdi);
 
-       error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata);
-       if (error)
-               goto out_sb;
+       error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata);
+       if (error)
+               goto out_sb;
 
        /*
         * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE
index f557d71cb0971692b5337cefad5db272f10b6a78..92b228176f7cb05f4be58aabcae02e6ffb0b832d 100644 (file)
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -5,6 +5,7 @@
 #include <linux/kernel.h>
 #include <linux/file.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/writeback.h>
@@ -13,6 +14,7 @@
 #include <linux/pagemap.h>
 #include <linux/quotaops.h>
 #include <linux/buffer_head.h>
+#include <linux/backing-dev.h>
 #include "internal.h"
 
 #define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \
@@ -31,7 +33,7 @@ static int __sync_filesystem(struct super_block *sb, int wait)
         * This should be safe, as we require bdi backing to actually
         * write out data in the first place
         */
-       if (!sb->s_bdi)
+       if (!sb->s_bdi || sb->s_bdi == &noop_backing_dev_info)
                return 0;
 
        if (sb->s_qcop && sb->s_qcop->quota_sync)
index 082daaecac1b44bf2b76e70536a01b703dcee8f3..a4a0a9419711be52782e7afa4f9c81f9cb587658 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/capability.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/xattr.h>
 #include <linux/security.h>
 #include "sysfs.h"
index 0cb10884a2fc26a8ab40726efd810c3f7682d8c8..776137828dcaf6587bed86fb7cf16c7a3c89ffe0 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/magic.h>
+#include <linux/slab.h>
 
 #include "sysfs.h"
 
index 1b9a3a1e8a17a1e3951980b3b4179d06a2b0a916..b93ec51fa7ace3ee4a9931512761ba7dcf0207ed 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <linux/mount.h>
 #include <linux/module.h>
 #include <linux/kobject.h>
index 4e50286a4cc32425c1061c92aba680b265ecaad1..1dabed286b4cf061a34c8521f5b1e44b81147089 100644 (file)
@@ -164,8 +164,8 @@ struct sysv_dir_entry *sysv_find_entry(struct dentry *dentry, struct page **res_
                                                        name, de->name))
                                        goto found;
                        }
+                       dir_put_page(page);
                }
-               dir_put_page(page);
 
                if (++n >= npages)
                        n = 0;
index 1bfc95ad5f716a70dda692a250aee1231b4f608e..98158de91d24a89146b4a0cbe45c0120e511a914 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/time.h>
index 4775af401167d71471c4e6035f4aa4ce1d5f6200..37fa7ed062d8624fdfe6810aaacda6a6503bcd6a 100644 (file)
@@ -45,6 +45,7 @@
 
 #include <linux/freezer.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include "ubifs.h"
 
 /**
index 90492327b3835c476eb52ba0399c20c581e1e19f..c2a68baa782f8d4b4331f689c594a2db640e6d0f 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/moduleparam.h>
 #include <linux/debugfs.h>
 #include <linux/math64.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_UBIFS_FS_DEBUG
 
index e26c02ab6cd5578ae663e777749e74fa2772111a..5692cf72b80737e0b87da9a22c58dbe2e52b371b 100644 (file)
@@ -52,6 +52,7 @@
 #include "ubifs.h"
 #include <linux/mount.h>
 #include <linux/namei.h>
+#include <linux/slab.h>
 
 static int read_block(struct inode *inode, void *addr, unsigned int block,
                      struct ubifs_data_node *dn)
index e5a3d8e96bb706d1d03ab393cb9e84d5855f4e51..918d1582ca05ce4a43f884b75fbf5e2522156275 100644 (file)
@@ -53,6 +53,7 @@
  * good, and GC takes extra care when moving them.
  */
 
+#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/list_sort.h>
 #include "ubifs.h"
index e589fedaf1ef747f7b5fe702065a48007d0fd5db..77d5cf4a75477055117e6f98529a4a7bdeea004b 100644 (file)
@@ -51,6 +51,7 @@
  */
 
 #include <linux/crc32.h>
+#include <linux/slab.h>
 #include "ubifs.h"
 
 /**
index b2792e84d2452fd37e27991b42c1ab5754044de4..ad7f67b827ea3b568d571685c42dfc50fc721920 100644 (file)
@@ -46,6 +46,7 @@
 #include "ubifs.h"
 #include <linux/crc16.h>
 #include <linux/math64.h>
+#include <linux/slab.h>
 
 /**
  * do_calc_lpt_geom - calculate sizes for the LPT area.
index 8cbfb82480252d3f3abebf0d3a14beb3cc2a9b4a..13cb7a4237bf474fa19a9161edd838c214c07c28 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include <linux/crc16.h>
+#include <linux/slab.h>
 #include "ubifs.h"
 
 /**
index 868a55ee080f193a6c8d6743f44d8cff36c57f2d..109c6ea03bb5d0cb86982a42d6ef9030e28b3e55 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <linux/crc32.h>
+#include <linux/slab.h>
 #include "ubifs.h"
 
 /**
index 57085e43320fdaf1925fd293f999978e8373077c..96cb62c8a9ddaa7cbcd432dc15442830632d3995 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include "ubifs.h"
+#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/math64.h>
 
index e5b1a7d00fa018f732bcbd84c336a5ef7eaaeea8..2194915220e56c75bc9894724496dc19c797b908 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <linux/crc32.h>
+#include <linux/slab.h>
 #include "ubifs.h"
 
 /*
index b2d976366a46dcbbceb57a5a8de7183351aebf76..bd2542dad014c947f27c0145b7985bc8fdcee4e1 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/fs.h>
 #include <linux/err.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
index 195830f47569988d1b6ce815c15ce576e5d3cdea..c74400f88fe0eb4882c79586fe09922bf8bd15b4 100644 (file)
@@ -56,6 +56,7 @@
  */
 
 #include "ubifs.h"
+#include <linux/slab.h>
 #include <linux/xattr.h>
 #include <linux/posix_acl_xattr.h>
 
index 19626e2491c4656b56fe672d3a9f3f8a09143c66..9a9378b4eb5ae2c89495b9025d7be8c5aa04ef5b 100644 (file)
@@ -125,9 +125,8 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
 
        mutex_lock(&sbi->s_alloc_mutex);
        partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
-       if (bloc->logicalBlockNum < 0 ||
-           (bloc->logicalBlockNum + count) >
-               partmap->s_partition_len) {
+       if (bloc->logicalBlockNum + count < count ||
+           (bloc->logicalBlockNum + count) > partmap->s_partition_len) {
                udf_debug("%d < %d || %d + %d > %d\n",
                          bloc->logicalBlockNum, 0, bloc->logicalBlockNum,
                          count, partmap->s_partition_len);
@@ -393,9 +392,8 @@ static void udf_table_free_blocks(struct super_block *sb,
 
        mutex_lock(&sbi->s_alloc_mutex);
        partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
-       if (bloc->logicalBlockNum < 0 ||
-           (bloc->logicalBlockNum + count) >
-               partmap->s_partition_len) {
+       if (bloc->logicalBlockNum + count < count ||
+           (bloc->logicalBlockNum + count) > partmap->s_partition_len) {
                udf_debug("%d < %d || %d + %d > %d\n",
                          bloc->logicalBlockNum, 0, bloc->logicalBlockNum, count,
                          partmap->s_partition_len);
index 1eb06774ed903b22db3344db2b56404667e5acca..4b6a46ccbf46771d7b363974c2416b8f63a7b946 100644 (file)
@@ -218,7 +218,7 @@ const struct file_operations udf_file_operations = {
        .llseek                 = generic_file_llseek,
 };
 
-static int udf_setattr(struct dentry *dentry, struct iattr *iattr)
+int udf_setattr(struct dentry *dentry, struct iattr *iattr)
 {
        struct inode *inode = dentry->d_inode;
        int error;
index bb863fe579ac7e7050706bd2331a12b2b23c2ddf..8a3fbd177cab342000164e0a934cc41c5bdec30e 100644 (file)
@@ -1314,7 +1314,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
                break;
        case ICBTAG_FILE_TYPE_SYMLINK:
                inode->i_data.a_ops = &udf_symlink_aops;
-               inode->i_op = &page_symlink_inode_operations;
+               inode->i_op = &udf_symlink_inode_operations;
                inode->i_mode = S_IFLNK | S_IRWXUGO;
                break;
        case ICBTAG_FILE_TYPE_MAIN:
index db423ab078b1beeaf67316050b826928c9651143..75816025f95f5e8e710e92b48cd9751094d45692 100644 (file)
@@ -925,7 +925,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
        iinfo = UDF_I(inode);
        inode->i_mode = S_IFLNK | S_IRWXUGO;
        inode->i_data.a_ops = &udf_symlink_aops;
-       inode->i_op = &page_symlink_inode_operations;
+       inode->i_op = &udf_symlink_inode_operations;
 
        if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
                struct kernel_lb_addr eloc;
@@ -1393,6 +1393,7 @@ const struct export_operations udf_export_ops = {
 const struct inode_operations udf_dir_inode_operations = {
        .lookup                         = udf_lookup,
        .create                         = udf_create,
+       .setattr                        = udf_setattr,
        .link                           = udf_link,
        .unlink                         = udf_unlink,
        .symlink                        = udf_symlink,
@@ -1401,3 +1402,9 @@ const struct inode_operations udf_dir_inode_operations = {
        .mknod                          = udf_mknod,
        .rename                         = udf_rename,
 };
+const struct inode_operations udf_symlink_inode_operations = {
+       .readlink       = generic_readlink,
+       .follow_link    = page_follow_link_light,
+       .put_link       = page_put_link,
+       .setattr        = udf_setattr,
+};
index 4b540ee632d5ba919ee93a5ef2689794c4935bb5..745eb209be0cf97998cd5ccb85be386557ba9075 100644 (file)
@@ -24,7 +24,6 @@
 
 #include <linux/fs.h>
 #include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/buffer_head.h>
 
 uint32_t udf_get_pblock(struct super_block *sb, uint32_t block,
index 852e91845688f24be5b1fa464b70a4d65a044b2a..16064787d2b7e19bfa397ccba348c55cdcc70d86 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/stat.h>
-#include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
index 4223ac855da944d5e10e1e86800ab93c43c20d8d..702a1148e70294e6f35f79ecd0908a3d15f584a9 100644 (file)
@@ -76,6 +76,7 @@ extern const struct inode_operations udf_dir_inode_operations;
 extern const struct file_operations udf_dir_operations;
 extern const struct inode_operations udf_file_inode_operations;
 extern const struct file_operations udf_file_operations;
+extern const struct inode_operations udf_symlink_inode_operations;
 extern const struct address_space_operations udf_aops;
 extern const struct address_space_operations udf_adinicb_aops;
 extern const struct address_space_operations udf_symlink_aops;
@@ -131,7 +132,7 @@ extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *,
 /* file.c */
 extern int udf_ioctl(struct inode *, struct file *, unsigned int,
                     unsigned long);
-
+extern int udf_setattr(struct dentry *dentry, struct iattr *iattr);
 /* inode.c */
 extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *);
 extern int udf_sync_inode(struct inode *);
index cefa8c8913e68a77100d2bdb5cf377b323483ec0..d03a90b6ad69c5850b6e6a3b5ba0b64726df0418 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/string.h>      /* for memset */
 #include <linux/nls.h>
 #include <linux/crc-itu-t.h>
+#include <linux/slab.h>
 
 #include "udf_sb.h"
 
index 05ac0fe9c4d3cb7e62dab0510c398e5e026935eb..8d5a506c82eb0a16978c4b8065011b412dace2a6 100644 (file)
@@ -6,9 +6,9 @@
  */
 
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/posix_acl_xattr.h>
+#include <linux/gfp.h>
 
 
 /*
index bc7405585defce739ac13a6668aadf33856305da..666c9db48eb63893cc3da777c44478ccd4d6942b 100644 (file)
@@ -17,6 +17,7 @@
  */
 #include <linux/mm.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 #include <linux/swap.h>
 #include <linux/blkdev.h>
 #include <linux/backing-dev.h>
index bf85bbe4a9aedd8b43ac57829024fc94095ac91f..a7bc925c4d603e68b1bc0697be51fcd74a6f44f6 100644 (file)
@@ -22,6 +22,7 @@
 #include "xfs_inode.h"
 #include "xfs_vnodeops.h"
 #include "xfs_trace.h"
+#include <linux/slab.h>
 #include <linux/xattr.h>
 #include <linux/posix_acl_xattr.h>
 
index 9083357f9e444170b5b95124e936bb0e0d430c7f..0f8b9968a8036d7574155e22b894ea6717a045ae 100644 (file)
@@ -40,6 +40,7 @@
 #include "xfs_vnodeops.h"
 #include "xfs_trace.h"
 #include "xfs_bmap.h"
+#include <linux/gfp.h>
 #include <linux/mpage.h>
 #include <linux/pagevec.h>
 #include <linux/writeback.h>
@@ -932,6 +933,9 @@ xfs_aops_discard_page(
        if (!xfs_is_delayed_page(page, IOMAP_DELAY))
                goto out_invalidate;
 
+       if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+               goto out_invalidate;
+
        xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
                "page discard on page %p, inode 0x%llx, offset %llu.",
                        page, ip->i_ino, offset);
@@ -964,8 +968,10 @@ xfs_aops_discard_page(
 
                if (error) {
                        /* something screwed, just bail */
-                       xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
-                       "page discard failed delalloc mapping lookup.");
+                       if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+                               xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
+                               "page discard failed delalloc mapping lookup.");
+                       }
                        break;
                }
                if (!nimaps) {
@@ -991,8 +997,10 @@ xfs_aops_discard_page(
                ASSERT(!flist.xbf_count && !flist.xbf_first);
                if (error) {
                        /* something screwed, just bail */
-                       xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
+                       if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+                               xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
                        "page discard unable to remove delalloc mapping.");
+                       }
                        break;
                }
 next_buffer:
index 6f76ba85f193e724e8bba96d5c8cc07e40fb1c50..44c2b0ef9a411e69524d3bbb7beb786f696d4026 100644 (file)
@@ -18,7 +18,7 @@
 #include "xfs.h"
 #include <linux/stddef.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
 #include <linux/vmalloc.h>
@@ -167,75 +167,6 @@ test_page_region(
        return (mask && (page_private(page) & mask) == mask);
 }
 
-/*
- *     Mapping of multi-page buffers into contiguous virtual space
- */
-
-typedef struct a_list {
-       void            *vm_addr;
-       struct a_list   *next;
-} a_list_t;
-
-static a_list_t                *as_free_head;
-static int             as_list_len;
-static DEFINE_SPINLOCK(as_lock);
-
-/*
- *     Try to batch vunmaps because they are costly.
- */
-STATIC void
-free_address(
-       void            *addr)
-{
-       a_list_t        *aentry;
-
-#ifdef CONFIG_XEN
-       /*
-        * Xen needs to be able to make sure it can get an exclusive
-        * RO mapping of pages it wants to turn into a pagetable.  If
-        * a newly allocated page is also still being vmap()ed by xfs,
-        * it will cause pagetable construction to fail.  This is a
-        * quick workaround to always eagerly unmap pages so that Xen
-        * is happy.
-        */
-       vunmap(addr);
-       return;
-#endif
-
-       aentry = kmalloc(sizeof(a_list_t), GFP_NOWAIT);
-       if (likely(aentry)) {
-               spin_lock(&as_lock);
-               aentry->next = as_free_head;
-               aentry->vm_addr = addr;
-               as_free_head = aentry;
-               as_list_len++;
-               spin_unlock(&as_lock);
-       } else {
-               vunmap(addr);
-       }
-}
-
-STATIC void
-purge_addresses(void)
-{
-       a_list_t        *aentry, *old;
-
-       if (as_free_head == NULL)
-               return;
-
-       spin_lock(&as_lock);
-       aentry = as_free_head;
-       as_free_head = NULL;
-       as_list_len = 0;
-       spin_unlock(&as_lock);
-
-       while ((old = aentry) != NULL) {
-               vunmap(aentry->vm_addr);
-               aentry = aentry->next;
-               kfree(old);
-       }
-}
-
 /*
  *     Internal xfs_buf_t object manipulation
  */
@@ -337,7 +268,8 @@ xfs_buf_free(
                uint            i;
 
                if (xfs_buf_is_vmapped(bp))
-                       free_address(bp->b_addr - bp->b_offset);
+                       vm_unmap_ram(bp->b_addr - bp->b_offset,
+                                       bp->b_page_count);
 
                for (i = 0; i < bp->b_page_count; i++) {
                        struct page     *page = bp->b_pages[i];
@@ -457,10 +389,8 @@ _xfs_buf_map_pages(
                bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset;
                bp->b_flags |= XBF_MAPPED;
        } else if (flags & XBF_MAPPED) {
-               if (as_list_len > 64)
-                       purge_addresses();
-               bp->b_addr = vmap(bp->b_pages, bp->b_page_count,
-                                       VM_MAP, PAGE_KERNEL);
+               bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count,
+                                       -1, PAGE_KERNEL);
                if (unlikely(bp->b_addr == NULL))
                        return -ENOMEM;
                bp->b_addr += bp->b_offset;
@@ -1955,9 +1885,6 @@ xfsbufd(
                        xfs_buf_iostrategy(bp);
                        count++;
                }
-
-               if (as_list_len > 0)
-                       purge_addresses();
                if (count)
                        blk_run_address_space(target->bt_mapping);
 
index 4ea1ee18adede8a266504f970c1db3d8b26f5065..7b26cc2fd2844bf1d768e65be90ceeca9eb85e72 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 #include <linux/exportfs.h>
 
 /*
index 0bf6d61f0528510249fe0de99b5ec3053744b83f..593c05b4df8dea614b13c0ee0f13613a9dcbc1e1 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/compat.h>
 #include <linux/ioctl.h>
 #include <linux/mount.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include "xfs.h"
 #include "xfs_fs.h"
index 61a99608731e641fde3aac01c0c38c2fbcb51cea..e65a7937f3a4aaaee198d09f34a7442165a55f18 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/security.h>
 #include <linux/falloc.h>
 #include <linux/fiemap.h>
+#include <linux/slab.h>
 
 /*
  * Bring the timestamps in the XFS inode uptodate.
index 71345a370d9f7ad0f7d6561bf860ed5b08593fbd..29f1edca76de3eca8d6af75ce7a197c6eb82a368 100644 (file)
@@ -61,6 +61,7 @@
 
 #include <linux/namei.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/mount.h>
 #include <linux/mempool.h>
 #include <linux/writeback.h>
@@ -1208,6 +1209,7 @@ xfs_fs_put_super(
 
        xfs_unmountfs(mp);
        xfs_freesb(mp);
+       xfs_inode_shrinker_unregister(mp);
        xfs_icsb_destroy_counters(mp);
        xfs_close_devices(mp);
        xfs_dmops_put(mp);
@@ -1621,6 +1623,8 @@ xfs_fs_fill_super(
        if (error)
                goto fail_vnrele;
 
+       xfs_inode_shrinker_register(mp);
+
        kfree(mtpt);
        return 0;
 
@@ -1866,6 +1870,7 @@ init_xfs_fs(void)
                goto out_cleanup_procfs;
 
        vfs_initquota();
+       xfs_inode_shrinker_init();
 
        error = register_filesystem(&xfs_fs_type);
        if (error)
@@ -1893,6 +1898,7 @@ exit_xfs_fs(void)
 {
        vfs_exitquota();
        unregister_filesystem(&xfs_fs_type);
+       xfs_inode_shrinker_destroy();
        xfs_sysctl_unregister();
        xfs_cleanup_procfs();
        xfs_buf_terminate();
index 05cd85317f6f53b6e0fe77bf0426c890f927b07a..a427c638d9095180e114fe8d64d3f16d66d9201b 100644 (file)
@@ -95,7 +95,8 @@ xfs_inode_ag_walk(
                                           struct xfs_perag *pag, int flags),
        int                     flags,
        int                     tag,
-       int                     exclusive)
+       int                     exclusive,
+       int                     *nr_to_scan)
 {
        uint32_t                first_index;
        int                     last_error = 0;
@@ -134,7 +135,7 @@ restart:
                if (error == EFSCORRUPTED)
                        break;
 
-       } while (1);
+       } while ((*nr_to_scan)--);
 
        if (skipped) {
                delay(1);
@@ -150,12 +151,15 @@ xfs_inode_ag_iterator(
                                           struct xfs_perag *pag, int flags),
        int                     flags,
        int                     tag,
-       int                     exclusive)
+       int                     exclusive,
+       int                     *nr_to_scan)
 {
        int                     error = 0;
        int                     last_error = 0;
        xfs_agnumber_t          ag;
+       int                     nr;
 
+       nr = nr_to_scan ? *nr_to_scan : INT_MAX;
        for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) {
                struct xfs_perag        *pag;
 
@@ -165,14 +169,18 @@ xfs_inode_ag_iterator(
                        continue;
                }
                error = xfs_inode_ag_walk(mp, pag, execute, flags, tag,
-                                               exclusive);
+                                               exclusive, &nr);
                xfs_perag_put(pag);
                if (error) {
                        last_error = error;
                        if (error == EFSCORRUPTED)
                                break;
                }
+               if (nr <= 0)
+                       break;
        }
+       if (nr_to_scan)
+               *nr_to_scan = nr;
        return XFS_ERROR(last_error);
 }
 
@@ -291,7 +299,7 @@ xfs_sync_data(
        ASSERT((flags & ~(SYNC_TRYLOCK|SYNC_WAIT)) == 0);
 
        error = xfs_inode_ag_iterator(mp, xfs_sync_inode_data, flags,
-                                     XFS_ICI_NO_TAG, 0);
+                                     XFS_ICI_NO_TAG, 0, NULL);
        if (error)
                return XFS_ERROR(error);
 
@@ -310,7 +318,7 @@ xfs_sync_attr(
        ASSERT((flags & ~SYNC_WAIT) == 0);
 
        return xfs_inode_ag_iterator(mp, xfs_sync_inode_attr, flags,
-                                    XFS_ICI_NO_TAG, 0);
+                                    XFS_ICI_NO_TAG, 0, NULL);
 }
 
 STATIC int
@@ -673,6 +681,7 @@ __xfs_inode_set_reclaim_tag(
        radix_tree_tag_set(&pag->pag_ici_root,
                           XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino),
                           XFS_ICI_RECLAIM_TAG);
+       pag->pag_ici_reclaimable++;
 }
 
 /*
@@ -705,6 +714,7 @@ __xfs_inode_clear_reclaim_tag(
 {
        radix_tree_tag_clear(&pag->pag_ici_root,
                        XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG);
+       pag->pag_ici_reclaimable--;
 }
 
 /*
@@ -820,10 +830,10 @@ xfs_reclaim_inode(
         * call into reclaim to find it in a clean state instead of waiting for
         * it now. We also don't return errors here - if the error is transient
         * then the next reclaim pass will flush the inode, and if the error
-        * is permanent then the next sync reclaim will relcaim the inode and
+        * is permanent then the next sync reclaim will reclaim the inode and
         * pass on the error.
         */
-       if (error && !XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+       if (error && error != EAGAIN && !XFS_FORCED_SHUTDOWN(ip->i_mount)) {
                xfs_fs_cmn_err(CE_WARN, ip->i_mount,
                        "inode 0x%llx background reclaim flush failed with %d",
                        (long long)ip->i_ino, error);
@@ -854,5 +864,93 @@ xfs_reclaim_inodes(
        int             mode)
 {
        return xfs_inode_ag_iterator(mp, xfs_reclaim_inode, mode,
-                                       XFS_ICI_RECLAIM_TAG, 1);
+                                       XFS_ICI_RECLAIM_TAG, 1, NULL);
+}
+
+/*
+ * Shrinker infrastructure.
+ *
+ * This is all far more complex than it needs to be. It adds a global list of
+ * mounts because the shrinkers can only call a global context. We need to make
+ * the shrinkers pass a context to avoid the need for global state.
+ */
+static LIST_HEAD(xfs_mount_list);
+static struct rw_semaphore xfs_mount_list_lock;
+
+static int
+xfs_reclaim_inode_shrink(
+       int             nr_to_scan,
+       gfp_t           gfp_mask)
+{
+       struct xfs_mount *mp;
+       struct xfs_perag *pag;
+       xfs_agnumber_t  ag;
+       int             reclaimable = 0;
+
+       if (nr_to_scan) {
+               if (!(gfp_mask & __GFP_FS))
+                       return -1;
+
+               down_read(&xfs_mount_list_lock);
+               list_for_each_entry(mp, &xfs_mount_list, m_mplist) {
+                       xfs_inode_ag_iterator(mp, xfs_reclaim_inode, 0,
+                                       XFS_ICI_RECLAIM_TAG, 1, &nr_to_scan);
+                       if (nr_to_scan <= 0)
+                               break;
+               }
+               up_read(&xfs_mount_list_lock);
+       }
+
+       down_read(&xfs_mount_list_lock);
+       list_for_each_entry(mp, &xfs_mount_list, m_mplist) {
+               for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) {
+
+                       pag = xfs_perag_get(mp, ag);
+                       if (!pag->pag_ici_init) {
+                               xfs_perag_put(pag);
+                               continue;
+                       }
+                       reclaimable += pag->pag_ici_reclaimable;
+                       xfs_perag_put(pag);
+               }
+       }
+       up_read(&xfs_mount_list_lock);
+       return reclaimable;
+}
+
+static struct shrinker xfs_inode_shrinker = {
+       .shrink = xfs_reclaim_inode_shrink,
+       .seeks = DEFAULT_SEEKS,
+};
+
+void __init
+xfs_inode_shrinker_init(void)
+{
+       init_rwsem(&xfs_mount_list_lock);
+       register_shrinker(&xfs_inode_shrinker);
+}
+
+void
+xfs_inode_shrinker_destroy(void)
+{
+       ASSERT(list_empty(&xfs_mount_list));
+       unregister_shrinker(&xfs_inode_shrinker);
+}
+
+void
+xfs_inode_shrinker_register(
+       struct xfs_mount        *mp)
+{
+       down_write(&xfs_mount_list_lock);
+       list_add_tail(&mp->m_mplist, &xfs_mount_list);
+       up_write(&xfs_mount_list_lock);
+}
+
+void
+xfs_inode_shrinker_unregister(
+       struct xfs_mount        *mp)
+{
+       down_write(&xfs_mount_list_lock);
+       list_del(&mp->m_mplist);
+       up_write(&xfs_mount_list_lock);
 }
index d480c346cabbb124a0d48ab4e017ef6fefae062e..cdcbaaca9880d04dfa8f2146580b0ef216ed178f 100644 (file)
@@ -53,6 +53,11 @@ void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag,
 int xfs_sync_inode_valid(struct xfs_inode *ip, struct xfs_perag *pag);
 int xfs_inode_ag_iterator(struct xfs_mount *mp,
        int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags),
-       int flags, int tag, int write_lock);
+       int flags, int tag, int write_lock, int *nr_to_scan);
+
+void xfs_inode_shrinker_init(void);
+void xfs_inode_shrinker_destroy(void);
+void xfs_inode_shrinker_register(struct xfs_mount *mp);
+void xfs_inode_shrinker_unregister(struct xfs_mount *mp);
 
 #endif
index 5d0ee8d492dbc21f9e04e9dd661bf3c35862e607..50bee07d6b0ed144544861cadc14a14be9b138b6 100644 (file)
@@ -891,7 +891,8 @@ xfs_qm_dqrele_all_inodes(
        uint             flags)
 {
        ASSERT(mp->m_quotainfo);
-       xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, XFS_ICI_NO_TAG, 0);
+       xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags,
+                               XFS_ICI_NO_TAG, 0, NULL);
 }
 
 /*------------------------------------------------------------------------*/
index b1a5a1ff88eac58f3618a977b1c3ce0e23e10b0b..abb8222b88c9a06e90c00784a60564170ba253da 100644 (file)
@@ -223,6 +223,7 @@ typedef struct xfs_perag {
        int             pag_ici_init;   /* incore inode cache initialised */
        rwlock_t        pag_ici_lock;   /* incore inode lock */
        struct radix_tree_root pag_ici_root;    /* incore inode cache root */
+       int             pag_ici_reclaimable;    /* reclaimable inodes */
 #endif
        int             pagb_count;     /* pagb slots in use */
        xfs_perag_busy_t pagb_list[XFS_PAGB_NUM_SLOTS]; /* unstable blocks */
index cd27c9d6c71f8b9014183fb504bc5183a8785a56..5bba29a07812cb761a9094e2ca1448491e99fc27 100644 (file)
@@ -177,16 +177,26 @@ xfs_swap_extents_check_format(
            XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) > tip->i_df.if_ext_max)
                return EINVAL;
 
-       /* Check root block of temp in btree form to max in target */
+       /*
+        * If we are in a btree format, check that the temp root block will fit
+        * in the target and that it has enough extents to be in btree format
+        * in the target.
+        *
+        * Note that we have to be careful to allow btree->extent conversions
+        * (a common defrag case) which will occur when the temp inode is in
+        * extent format...
+        */
        if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE &&
-           XFS_IFORK_BOFF(ip) &&
-           tip->i_df.if_broot_bytes > XFS_IFORK_BOFF(ip))
+           ((XFS_IFORK_BOFF(ip) &&
+             tip->i_df.if_broot_bytes > XFS_IFORK_BOFF(ip)) ||
+            XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) <= ip->i_df.if_ext_max))
                return EINVAL;
 
-       /* Check root block of target in btree form to max in temp */
+       /* Reciprocal target->temp btree format checks */
        if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE &&
-           XFS_IFORK_BOFF(tip) &&
-           ip->i_df.if_broot_bytes > XFS_IFORK_BOFF(tip))
+           ((XFS_IFORK_BOFF(tip) &&
+             ip->i_df.if_broot_bytes > XFS_IFORK_BOFF(tip)) ||
+            XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) <= tip->i_df.if_ext_max))
                return EINVAL;
 
        return 0;
index e8fba92d7cd9f96b77fc2dc19cef07066ddadc12..2be019136287666ae84e565093924fe0ba8e76a8 100644 (file)
@@ -745,9 +745,16 @@ xfs_log_move_tail(xfs_mount_t      *mp,
 
 /*
  * Determine if we have a transaction that has gone to disk
- * that needs to be covered. Log activity needs to be idle (no AIL and
- * nothing in the iclogs). And, we need to be in the right state indicating
- * something has gone out.
+ * that needs to be covered. To begin the transition to the idle state
+ * firstly the log needs to be idle (no AIL and nothing in the iclogs).
+ * If we are then in a state where covering is needed, the caller is informed
+ * that dummy transactions are required to move the log into the idle state.
+ *
+ * Because this is called as part of the sync process, we should also indicate
+ * that dummy transactions should be issued in anything but the covered or
+ * idle states. This ensures that the log tail is accurately reflected in
+ * the log at the end of the sync, hence if a crash occurrs avoids replay
+ * of transactions where the metadata is already on disk.
  */
 int
 xfs_log_need_covered(xfs_mount_t *mp)
@@ -759,17 +766,24 @@ xfs_log_need_covered(xfs_mount_t *mp)
                return 0;
 
        spin_lock(&log->l_icloglock);
-       if (((log->l_covered_state == XLOG_STATE_COVER_NEED) ||
-               (log->l_covered_state == XLOG_STATE_COVER_NEED2))
-                       && !xfs_trans_ail_tail(log->l_ailp)
-                       && xlog_iclogs_empty(log)) {
-               if (log->l_covered_state == XLOG_STATE_COVER_NEED)
-                       log->l_covered_state = XLOG_STATE_COVER_DONE;
-               else {
-                       ASSERT(log->l_covered_state == XLOG_STATE_COVER_NEED2);
-                       log->l_covered_state = XLOG_STATE_COVER_DONE2;
+       switch (log->l_covered_state) {
+       case XLOG_STATE_COVER_DONE:
+       case XLOG_STATE_COVER_DONE2:
+       case XLOG_STATE_COVER_IDLE:
+               break;
+       case XLOG_STATE_COVER_NEED:
+       case XLOG_STATE_COVER_NEED2:
+               if (!xfs_trans_ail_tail(log->l_ailp) &&
+                   xlog_iclogs_empty(log)) {
+                       if (log->l_covered_state == XLOG_STATE_COVER_NEED)
+                               log->l_covered_state = XLOG_STATE_COVER_DONE;
+                       else
+                               log->l_covered_state = XLOG_STATE_COVER_DONE2;
                }
+               /* FALLTHRU */
+       default:
                needed = 1;
+               break;
        }
        spin_unlock(&log->l_icloglock);
        return needed;
index 4fa0bc7b983ebb0e934b4b877f63c6090fb73afa..9ff48a16a7ee6334a2ab310dee58f5dc5a6ba323 100644 (file)
@@ -259,6 +259,7 @@ typedef struct xfs_mount {
        wait_queue_head_t       m_wait_single_sync_task;
        __int64_t               m_update_flags; /* sb flags we need to update
                                                   on the next remount,rw */
+       struct list_head        m_mplist;       /* inode shrinker mount list */
 } xfs_mount_t;
 
 /*
index 3a4767c01c5fd6ecee67d409fdf4a906bbe5da5f..4f7b44866b762351ca4bfacdbcb65cacec13d010 100644 (file)
@@ -65,6 +65,8 @@
 #define ACPI_VIDEO_HID                 "LNXVIDEO"
 #define ACPI_BAY_HID                   "LNXIOBAY"
 #define ACPI_DOCK_HID                  "LNXDOCK"
+/* Quirk for broken IBM BIOSes */
+#define ACPI_SMBUS_IBM_HID             "SMBUSIBM"
 
 /*
  * For fixed hardware buttons, we fabricate acpi_devices with HID
index c99c64dc5f3dcfe1a9fbf192c44f30bf84a47ea9..c33749f95b325ceca7aa3c3e9fb2803145101356 100644 (file)
@@ -33,7 +33,7 @@
  * Atomically reads the value of @v.  Note that the guaranteed
  * useful range of an atomic_t is only 24 bits.
  */
-#define atomic_read(v) ((v)->counter)
+#define atomic_read(v) (*(volatile int *)&(v)->counter)
 
 /**
  * atomic_set - set atomic variable
diff --git a/include/asm-generic/bitops/arch_hweight.h b/include/asm-generic/bitops/arch_hweight.h
new file mode 100644 (file)
index 0000000..6a211f4
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef _ASM_GENERIC_BITOPS_ARCH_HWEIGHT_H_
+#define _ASM_GENERIC_BITOPS_ARCH_HWEIGHT_H_
+
+#include <asm/types.h>
+
+static inline unsigned int __arch_hweight32(unsigned int w)
+{
+       return __sw_hweight32(w);
+}
+
+static inline unsigned int __arch_hweight16(unsigned int w)
+{
+       return __sw_hweight16(w);
+}
+
+static inline unsigned int __arch_hweight8(unsigned int w)
+{
+       return __sw_hweight8(w);
+}
+
+static inline unsigned long __arch_hweight64(__u64 w)
+{
+       return __sw_hweight64(w);
+}
+#endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */
diff --git a/include/asm-generic/bitops/const_hweight.h b/include/asm-generic/bitops/const_hweight.h
new file mode 100644 (file)
index 0000000..fa2a50b
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef _ASM_GENERIC_BITOPS_CONST_HWEIGHT_H_
+#define _ASM_GENERIC_BITOPS_CONST_HWEIGHT_H_
+
+/*
+ * Compile time versions of __arch_hweightN()
+ */
+#define __const_hweight8(w)            \
+      (        (!!((w) & (1ULL << 0))) +       \
+       (!!((w) & (1ULL << 1))) +       \
+       (!!((w) & (1ULL << 2))) +       \
+       (!!((w) & (1ULL << 3))) +       \
+       (!!((w) & (1ULL << 4))) +       \
+       (!!((w) & (1ULL << 5))) +       \
+       (!!((w) & (1ULL << 6))) +       \
+       (!!((w) & (1ULL << 7))) )
+
+#define __const_hweight16(w) (__const_hweight8(w)  + __const_hweight8((w)  >> 8 ))
+#define __const_hweight32(w) (__const_hweight16(w) + __const_hweight16((w) >> 16))
+#define __const_hweight64(w) (__const_hweight32(w) + __const_hweight32((w) >> 32))
+
+/*
+ * Generic interface.
+ */
+#define hweight8(w)  (__builtin_constant_p(w) ? __const_hweight8(w)  : __arch_hweight8(w))
+#define hweight16(w) (__builtin_constant_p(w) ? __const_hweight16(w) : __arch_hweight16(w))
+#define hweight32(w) (__builtin_constant_p(w) ? __const_hweight32(w) : __arch_hweight32(w))
+#define hweight64(w) (__builtin_constant_p(w) ? __const_hweight64(w) : __arch_hweight64(w))
+
+/*
+ * Interface for known constant arguments
+ */
+#define HWEIGHT8(w)  (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight8(w))
+#define HWEIGHT16(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight16(w))
+#define HWEIGHT32(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight32(w))
+#define HWEIGHT64(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight64(w))
+
+/*
+ * Type invariant interface to the compile time constant hweight functions.
+ */
+#define HWEIGHT(w)   HWEIGHT64((u64)w)
+
+#endif /* _ASM_GENERIC_BITOPS_CONST_HWEIGHT_H_ */
index fbbc383771dae56660cf8ea6ba3c57f21b0a1b9e..a94d6519c7ed1bafbfb1659aa506afbe5d99f752 100644 (file)
@@ -1,11 +1,7 @@
 #ifndef _ASM_GENERIC_BITOPS_HWEIGHT_H_
 #define _ASM_GENERIC_BITOPS_HWEIGHT_H_
 
-#include <asm/types.h>
-
-extern unsigned int hweight32(unsigned int w);
-extern unsigned int hweight16(unsigned int w);
-extern unsigned int hweight8(unsigned int w);
-extern unsigned long hweight64(__u64 w);
+#include <asm-generic/bitops/arch_hweight.h>
+#include <asm-generic/bitops/const_hweight.h>
 
 #endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */
index e694263445f7b5dd48ff294cdd6ec4b76f3769a2..69206957b72c52efe1f9fe7d2479cfc931d7d7b7 100644 (file)
@@ -131,7 +131,7 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev,
                debug_dma_sync_single_range_for_cpu(dev, addr, offset, size, dir);
 
        } else
-               dma_sync_single_for_cpu(dev, addr, size, dir);
+               dma_sync_single_for_cpu(dev, addr + offset, size, dir);
 }
 
 static inline void dma_sync_single_range_for_device(struct device *dev,
@@ -148,7 +148,7 @@ static inline void dma_sync_single_range_for_device(struct device *dev,
                debug_dma_sync_single_range_for_device(dev, addr, offset, size, dir);
 
        } else
-               dma_sync_single_for_device(dev, addr, size, dir);
+               dma_sync_single_for_device(dev, addr + offset, size, dir);
 }
 
 static inline void
index 4a3c4e441027be39da3d37b8a817ff9f918661dd..2f3b3a00b7a39ccf97ff839f0eb9034a1873a6af 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/mm.h>
 #include <linux/cdev.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #if defined(__alpha__) || defined(__powerpc__)
 #include <asm/pgtable.h>       /* For pte_wrprotect */
 #endif
@@ -1545,39 +1546,7 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map)
 {
 }
 
-
-static __inline__ void *drm_calloc_large(size_t nmemb, size_t size)
-{
-       if (size != 0 && nmemb > ULONG_MAX / size)
-               return NULL;
-
-       if (size * nmemb <= PAGE_SIZE)
-           return kcalloc(nmemb, size, GFP_KERNEL);
-
-       return __vmalloc(size * nmemb,
-                        GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
-}
-
-/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */
-static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size)
-{
-       if (size != 0 && nmemb > ULONG_MAX / size)
-               return NULL;
-
-       if (size * nmemb <= PAGE_SIZE)
-           return kmalloc(nmemb * size, GFP_KERNEL);
-
-       return __vmalloc(size * nmemb,
-                        GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
-}
-
-static __inline void drm_free_large(void *ptr)
-{
-       if (!is_vmalloc_addr(ptr))
-               return kfree(ptr);
-
-       vfree(ptr);
-}
+#include "drm_mem_util.h"
 /*@}*/
 
 #endif                         /* __KERNEL__ */
diff --git a/include/drm/drm_mem_util.h b/include/drm/drm_mem_util.h
new file mode 100644 (file)
index 0000000..6bd325f
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright Â© 2008 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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:
+ *     Jesse Barnes <jbarnes@virtuousgeek.org>
+ *
+ */
+#ifndef _DRM_MEM_UTIL_H_
+#define _DRM_MEM_UTIL_H_
+
+#include <linux/vmalloc.h>
+
+static __inline__ void *drm_calloc_large(size_t nmemb, size_t size)
+{
+       if (size != 0 && nmemb > ULONG_MAX / size)
+               return NULL;
+
+       if (size * nmemb <= PAGE_SIZE)
+           return kcalloc(nmemb, size, GFP_KERNEL);
+
+       return __vmalloc(size * nmemb,
+                        GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
+}
+
+/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */
+static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size)
+{
+       if (size != 0 && nmemb > ULONG_MAX / size)
+               return NULL;
+
+       if (size * nmemb <= PAGE_SIZE)
+           return kmalloc(nmemb * size, GFP_KERNEL);
+
+       return __vmalloc(size * nmemb,
+                        GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
+}
+
+static __inline void drm_free_large(void *ptr)
+{
+       if (!is_vmalloc_addr(ptr))
+               return kfree(ptr);
+
+       vfree(ptr);
+}
+
+#endif
index 676104b7818c0d35cc69f6b60105891f29df63ee..2d428b088cc8f7df979d4fb66f332c3fbadf9f1f 100644 (file)
@@ -6,6 +6,7 @@
        {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
        {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x3155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP}, \
        {0x1002, 0x9712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x9713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0x1002, 0x9714, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
+       {0x1002, 0x9715, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
        {0, 0, 0}
 
 #define r128_PCI_IDS \
index e3f1b4a4b601aa5cb909030d733dad50f5c074cc..6b9db917e71777ace07b335b4c1af2e4339f6c62 100644 (file)
@@ -115,7 +115,6 @@ struct ttm_backend {
        struct ttm_backend_func *func;
 };
 
-#define TTM_PAGE_FLAG_VMALLOC         (1 << 0)
 #define TTM_PAGE_FLAG_USER            (1 << 1)
 #define TTM_PAGE_FLAG_USER_DIRTY      (1 << 2)
 #define TTM_PAGE_FLAG_WRITE           (1 << 3)
@@ -790,34 +789,6 @@ extern void ttm_bo_unreserve(struct ttm_buffer_object *bo);
 extern int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo,
                                  bool interruptible);
 
-/**
- * ttm_bo_block_reservation
- *
- * @bo: A pointer to a struct ttm_buffer_object.
- * @interruptible: Use interruptible sleep when waiting.
- * @no_wait: Don't sleep, but rather return -EBUSY.
- *
- * Block reservation for validation by simply reserving the buffer.
- * This is intended for single buffer use only without eviction,
- * and thus needs no deadlock protection.
- *
- * Returns:
- * -EBUSY: If no_wait == 1 and the buffer is already reserved.
- * -ERESTARTSYS: If interruptible == 1 and the process received a signal
- * while sleeping.
- */
-extern int ttm_bo_block_reservation(struct ttm_buffer_object *bo,
-                                   bool interruptible, bool no_wait);
-
-/**
- * ttm_bo_unblock_reservation
- *
- * @bo: A pointer to a struct ttm_buffer_object.
- *
- * Unblocks reservation leaving lru lists untouched.
- */
-extern void ttm_bo_unblock_reservation(struct ttm_buffer_object *bo);
-
 /*
  * ttm_bo_util.c
  */
index b926afe8c03e7f846043ec78e2bbfb0cc021497e..3da73f5f0ae997cb54e820cf8fbe3b73cffb5c06 100644 (file)
@@ -116,11 +116,12 @@ extern unsigned long acpi_realmode_flags;
 
 int acpi_register_gsi (struct device *dev, u32 gsi, int triggering, int polarity);
 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
+int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
 
 #ifdef CONFIG_X86_IO_APIC
-extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity);
+extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity);
 #else
-#define acpi_get_override_irq(bus, trigger, polarity) (-1)
+#define acpi_get_override_irq(gsi, trigger, polarity) (-1)
 #endif
 /*
  * This function undoes the effect of one call to acpi_register_gsi().
index 6816be6c3f7798bd64ec1d05a27d95f4b9e27c80..8b1038607831360ed621ddb5542c9f686338758e 100644 (file)
@@ -14,6 +14,9 @@
 #ifndef ASMARM_AMBA_H
 #define ASMARM_AMBA_H
 
+#include <linux/device.h>
+#include <linux/resource.h>
+
 #define AMBA_NR_IRQS   2
 
 struct amba_device {
index 29c0448265cf7c7e4b9312f3cd684a319fcf8de3..ca16c3801a1e7c26332efd842be95c4299bcd1b4 100644 (file)
 #define CLCD_UBAS              0x00000010
 #define CLCD_LBAS              0x00000014
 
-#if !defined(CONFIG_ARCH_VERSATILE) && !defined(CONFIG_ARCH_REALVIEW)
-#define CLCD_IENB              0x00000018
-#define CLCD_CNTL              0x0000001c
-#else
-/*
- * Someone rearranged these two registers on the Versatile
- * platform...
- */
-#define CLCD_IENB              0x0000001c
-#define CLCD_CNTL              0x00000018
-#endif
-
-#define CLCD_STAT              0x00000020
-#define CLCD_INTR              0x00000024
-#define CLCD_UCUR              0x00000028
-#define CLCD_LCUR              0x0000002C
+#define CLCD_PL110_IENB                0x00000018
+#define CLCD_PL110_CNTL                0x0000001c
+#define CLCD_PL110_STAT                0x00000020
+#define CLCD_PL110_INTR        0x00000024
+#define CLCD_PL110_UCUR                0x00000028
+#define CLCD_PL110_LCUR                0x0000002C
+
+#define CLCD_PL111_CNTL                0x00000018
+#define CLCD_PL111_IENB                0x0000001c
+#define CLCD_PL111_RIS         0x00000020
+#define CLCD_PL111_MIS         0x00000024
+#define CLCD_PL111_ICR         0x00000028
+#define CLCD_PL111_UCUR                0x0000002c
+#define CLCD_PL111_LCUR                0x00000030
+
 #define CLCD_PALL              0x00000200
 #define CLCD_PALETTE           0x00000200
 
@@ -147,6 +146,8 @@ struct clcd_fb {
        struct clcd_board       *board;
        void                    *board_data;
        void __iomem            *regs;
+       u16                     off_ienb;
+       u16                     off_cntl;
        u32                     clcd_cntl;
        u32                     cmap[16];
 };
index b4fbd9862606c76fc8accc05c18d0f2a1d4ab6ec..5ddd9ad4b19c9c381d77ab5c24a01031b4127ba3 100644 (file)
@@ -1,3 +1,5 @@
+#include <linux/types.h>
+
 /* platform data for the PL061 GPIO driver */
 
 struct pl061_platform_data {
index b4c85e2adef5e494d76a1c9a670ad22111e5c85b..700c5b9b358303a721dc1879b0df120f4eeb3176 100644 (file)
@@ -1025,8 +1025,8 @@ static inline int ata_ok(u8 status)
 
 static inline int lba_28_ok(u64 block, u32 n_block)
 {
-       /* check the ending block number */
-       return ((block + n_block) < ((u64)1 << 28)) && (n_block <= 256);
+       /* check the ending block number: must be LESS THAN 0x0fffffff */
+       return ((block + n_block) < ((1 << 28) - 1)) && (n_block <= 256);
 }
 
 static inline int lba_48_ok(u64 block, u32 n_block)
index fcbc26af00e479675db47d8e79d1e31b3e4368bc..bd0e3c6f323f3fd1e5ea8b60ac8f1a4fdd7785d8 100644 (file)
@@ -101,6 +101,7 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent,
                const char *fmt, ...);
 int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev);
 void bdi_unregister(struct backing_dev_info *bdi);
+int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int);
 void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb,
                                long nr_pages);
 int bdi_writeback_task(struct bdi_writeback *wb);
@@ -246,6 +247,7 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio);
 #endif
 
 extern struct backing_dev_info default_backing_dev_info;
+extern struct backing_dev_info noop_backing_dev_info;
 void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page);
 
 int writeback_in_progress(struct backing_dev_info *bdi);
index 8c4f884db6b40044a5934985656551b1dee22d8d..4a3d52e545e186876f2e36d679c9812e4ce1d8a0 100644 (file)
@@ -36,18 +36,18 @@ struct backlight_device;
 struct fb_info;
 
 struct backlight_ops {
-       const unsigned int options;
+       unsigned int options;
 
 #define BL_CORE_SUSPENDRESUME  (1 << 0)
 
        /* Notify the backlight driver some property has changed */
-       int (* const update_status)(struct backlight_device *);
+       int (*update_status)(struct backlight_device *);
        /* Return the current backlight brightness (accounting for power,
           fb_blank etc.) */
-       int (* const get_brightness)(struct backlight_device *);
+       int (*get_brightness)(struct backlight_device *);
        /* Check if given framebuffer device is the one bound to this backlight;
           return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */
-       int (* const check_fb)(struct fb_info *);
+       int (*check_fb)(struct backlight_device *, struct fb_info *);
 };
 
 /* This structure defines all the properties of a backlight */
@@ -103,7 +103,8 @@ static inline void backlight_update_status(struct backlight_device *bd)
 }
 
 extern struct backlight_device *backlight_device_register(const char *name,
-       struct device *dev, void *devdata, const struct backlight_ops *ops);
+       struct device *dev, void *devdata, const struct backlight_ops *ops,
+       const struct backlight_properties *props);
 extern void backlight_device_unregister(struct backlight_device *bd);
 extern void backlight_force_update(struct backlight_device *bd,
                                   enum backlight_update_reason reason);
index b7938987923882e1e8853d63b31560a4aa0b0393..fc68053378ce276d5d2d038115e12dbb6b31c27e 100644 (file)
 #define BITS_TO_LONGS(nr)      DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
 #endif
 
+extern unsigned int __sw_hweight8(unsigned int w);
+extern unsigned int __sw_hweight16(unsigned int w);
+extern unsigned int __sw_hweight32(unsigned int w);
+extern unsigned long __sw_hweight64(__u64 w);
+
 /*
  * Include this here because some architectures need generic_ffs/fls in
  * scope
@@ -21,9 +26,6 @@
             (bit) < (size); \
             (bit) = find_next_bit((addr), (size), (bit) + 1))
 
-/* Temporary */
-#define for_each_bit(bit, addr, size) for_each_set_bit(bit, addr, size)
-
 static __inline__ int get_bitmask_order(unsigned int count)
 {
        int order;
@@ -47,31 +49,6 @@ static inline unsigned long hweight_long(unsigned long w)
        return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
 }
 
-/*
- * Clearly slow versions of the hweightN() functions, their benefit is
- * of course compile time evaluation of constant arguments.
- */
-#define HWEIGHT8(w)                                    \
-      (        BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) +   \
-       (!!((w) & (1ULL << 0))) +                       \
-       (!!((w) & (1ULL << 1))) +                       \
-       (!!((w) & (1ULL << 2))) +                       \
-       (!!((w) & (1ULL << 3))) +                       \
-       (!!((w) & (1ULL << 4))) +                       \
-       (!!((w) & (1ULL << 5))) +                       \
-       (!!((w) & (1ULL << 6))) +                       \
-       (!!((w) & (1ULL << 7))) )
-
-#define HWEIGHT16(w) (HWEIGHT8(w)  + HWEIGHT8((w) >> 8))
-#define HWEIGHT32(w) (HWEIGHT16(w) + HWEIGHT16((w) >> 16))
-#define HWEIGHT64(w) (HWEIGHT32(w) + HWEIGHT32((w) >> 32))
-
-/*
- * Type invariant version that simply casts things to the
- * largest type.
- */
-#define HWEIGHT(w)   HWEIGHT64((u64)(w))
-
 /**
  * rol32 - rotate a 32-bit value left
  * @word: value to rotate
index ebd22dbed861da16481a1f4995dd9460f71caca4..6690e8bae7bb5946396577fcc12a9c85836cb7b5 100644 (file)
@@ -158,7 +158,6 @@ enum rq_flag_bits {
 struct request {
        struct list_head queuelist;
        struct call_single_data csd;
-       int cpu;
 
        struct request_queue *q;
 
@@ -166,9 +165,11 @@ struct request {
        enum rq_cmd_type_bits cmd_type;
        unsigned long atomic_flags;
 
+       int cpu;
+
        /* the following two fields are internal, NEVER access directly */
-       sector_t __sector;              /* sector cursor */
        unsigned int __data_len;        /* total data len */
+       sector_t __sector;              /* sector cursor */
 
        struct bio *bio;
        struct bio *biotail;
@@ -201,20 +202,20 @@ struct request {
 
        unsigned short ioprio;
 
+       int ref_count;
+
        void *special;          /* opaque pointer available for LLD use */
        char *buffer;           /* kaddr of the current segment if available */
 
        int tag;
        int errors;
 
-       int ref_count;
-
        /*
         * when request is used as a packet command carrier
         */
-       unsigned short cmd_len;
        unsigned char __cmd[BLK_MAX_CDB];
        unsigned char *cmd;
+       unsigned short cmd_len;
 
        unsigned int extra_len; /* length of alignment and padding */
        unsigned int sense_len;
@@ -921,26 +922,7 @@ extern void blk_cleanup_queue(struct request_queue *);
 extern void blk_queue_make_request(struct request_queue *, make_request_fn *);
 extern void blk_queue_bounce_limit(struct request_queue *, u64);
 extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int);
-
-/* Temporary compatibility wrapper */
-static inline void blk_queue_max_sectors(struct request_queue *q, unsigned int max)
-{
-       blk_queue_max_hw_sectors(q, max);
-}
-
 extern void blk_queue_max_segments(struct request_queue *, unsigned short);
-
-static inline void blk_queue_max_phys_segments(struct request_queue *q, unsigned short max)
-{
-       blk_queue_max_segments(q, max);
-}
-
-static inline void blk_queue_max_hw_segments(struct request_queue *q, unsigned short max)
-{
-       blk_queue_max_segments(q, max);
-}
-
-
 extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
 extern void blk_queue_max_discard_sectors(struct request_queue *q,
                unsigned int max_discard_sectors);
@@ -1030,11 +1012,6 @@ static inline int sb_issue_discard(struct super_block *sb,
 
 extern int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm);
 
-#define MAX_PHYS_SEGMENTS 128
-#define MAX_HW_SEGMENTS 128
-#define SAFE_MAX_SECTORS 255
-#define MAX_SEGMENT_SIZE       65536
-
 enum blk_default_limits {
        BLK_MAX_SEGMENTS        = 128,
        BLK_SAFE_MAX_SECTORS    = 255,
index b8ad1ea9958608174530f97951fba1a628dc9749..8f78073d7caaa278017232112f0d3da05aa0d4c0 100644 (file)
@@ -530,6 +530,7 @@ static inline struct cgroup_subsys_state *task_subsys_state(
 {
        return rcu_dereference_check(task->cgroups->subsys[subsys_id],
                                     rcu_read_lock_held() ||
+                                    lockdep_is_held(&task->alloc_lock) ||
                                     cgroup_lock_is_held());
 }
 
index a2ed0591fb19c57f5544f74f6233afe7cda60d35..90f2471dc6f2382d9f522d0c80287a09069c9ed8 100644 (file)
@@ -1,3 +1,7 @@
+/*
+ * See Documentation/circular-buffers.txt for more information.
+ */
+
 #ifndef _LINUX_CIRC_BUF_H
 #define _LINUX_CIRC_BUF_H 1
 
index 0cf725bdd2a1a76d2f9da0d6855268cf7a97955d..fc53492b6ad7fb67e904e88d2f02d184771a326e 100644 (file)
@@ -73,6 +73,7 @@ enum clock_event_nofitiers {
  * @list:              list head for the management code
  * @mode:              operating mode assigned by the management code
  * @next_event:                local storage for the next event in oneshot mode
+ * @retries:           number of forced programming retries
  */
 struct clock_event_device {
        const char              *name;
@@ -93,6 +94,7 @@ struct clock_event_device {
        struct list_head        list;
        enum clock_event_mode   mode;
        ktime_t                 next_event;
+       unsigned long           retries;
 };
 
 /*
index 5b5d4731f95654f45da356d5c631bb7758bd3395..8859e2ede9fe3c368b774b560f80a735df6f4777 100644 (file)
@@ -7,6 +7,8 @@
 #define MAX_CODADEVS  5           /* how many do we allow */
 
 #ifdef __KERNEL__
+#include <linux/backing-dev.h>
+
 struct kstatfs;
 
 /* communication pending/processing queues */
@@ -17,6 +19,7 @@ struct venus_comm {
        struct list_head    vc_processing;
        int                 vc_inuse;
        struct super_block *vc_sb;
+       struct backing_dev_info bdi;
 };
 
 
index 4de02b10007ff4258ce6be681687d263239e1c12..9f15150ce8d67d46415de9c009c17607008c213c 100644 (file)
@@ -278,6 +278,27 @@ struct freq_attr {
        ssize_t (*store)(struct cpufreq_policy *, const char *, size_t count);
 };
 
+#define cpufreq_freq_attr_ro(_name)            \
+static struct freq_attr _name =                        \
+__ATTR(_name, 0444, show_##_name, NULL)
+
+#define cpufreq_freq_attr_ro_perm(_name, _perm)        \
+static struct freq_attr _name =                        \
+__ATTR(_name, _perm, show_##_name, NULL)
+
+#define cpufreq_freq_attr_ro_old(_name)                \
+static struct freq_attr _name##_old =          \
+__ATTR(_name, 0444, show_##_name##_old, NULL)
+
+#define cpufreq_freq_attr_rw(_name)            \
+static struct freq_attr _name =                        \
+__ATTR(_name, 0644, show_##_name, store_##_name)
+
+#define cpufreq_freq_attr_rw_old(_name)                \
+static struct freq_attr _name##_old =          \
+__ATTR(_name, 0644, show_##_name##_old, store_##_name##_old)
+
+
 struct global_attr {
        struct attribute attr;
        ssize_t (*show)(struct kobject *kobj,
@@ -286,6 +307,15 @@ struct global_attr {
                         const char *c, size_t count);
 };
 
+#define define_one_global_ro(_name)            \
+static struct global_attr _name =              \
+__ATTR(_name, 0444, show_##_name, NULL)
+
+#define define_one_global_rw(_name)            \
+static struct global_attr _name =              \
+__ATTR(_name, 0644, show_##_name, store_##_name)
+
+
 /*********************************************************************
  *                        CPUFREQ 2.6. INTERFACE                     *
  *********************************************************************/
index a5740fc4d04b9415478f4180dcbdad289f5eb281..a73454aec33312359c4233fa4ec7e0598dbbe345 100644 (file)
@@ -21,8 +21,7 @@ extern int number_of_cpusets; /* How many cpusets are defined in system? */
 extern int cpuset_init(void);
 extern void cpuset_init_smp(void);
 extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask);
-extern void cpuset_cpus_allowed_locked(struct task_struct *p,
-                                      struct cpumask *mask);
+extern int cpuset_cpus_allowed_fallback(struct task_struct *p);
 extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
 #define cpuset_current_mems_allowed (current->mems_allowed)
 void cpuset_init_current_mems_allowed(void);
@@ -69,9 +68,6 @@ struct seq_file;
 extern void cpuset_task_status_allowed(struct seq_file *m,
                                        struct task_struct *task);
 
-extern void cpuset_lock(void);
-extern void cpuset_unlock(void);
-
 extern int cpuset_mem_spread_node(void);
 
 static inline int cpuset_do_page_mem_spread(void)
@@ -105,10 +101,11 @@ static inline void cpuset_cpus_allowed(struct task_struct *p,
 {
        cpumask_copy(mask, cpu_possible_mask);
 }
-static inline void cpuset_cpus_allowed_locked(struct task_struct *p,
-                                             struct cpumask *mask)
+
+static inline int cpuset_cpus_allowed_fallback(struct task_struct *p)
 {
-       cpumask_copy(mask, cpu_possible_mask);
+       cpumask_copy(&p->cpus_allowed, cpu_possible_mask);
+       return cpumask_any(cpu_active_mask);
 }
 
 static inline nodemask_t cpuset_mems_allowed(struct task_struct *p)
@@ -157,9 +154,6 @@ static inline void cpuset_task_status_allowed(struct seq_file *m,
 {
 }
 
-static inline void cpuset_lock(void) {}
-static inline void cpuset_unlock(void) {}
-
 static inline int cpuset_mem_spread_node(void)
 {
        return 0;
index 30b93b2a01a42891c78ae54f6803f0908c544b7f..eebb617c17d89fcb053d9485dd0dc3e59d67c77f 100644 (file)
@@ -186,6 +186,8 @@ d_iput:             no              no              no       yes
 
 #define DCACHE_FSNOTIFY_PARENT_WATCHED 0x0080 /* Parent inode is watched by some fsnotify listener */
 
+#define DCACHE_CANT_MOUNT      0x0100
+
 extern spinlock_t dcache_lock;
 extern seqlock_t rename_lock;
 
@@ -358,6 +360,18 @@ static inline int d_unlinked(struct dentry *dentry)
        return d_unhashed(dentry) && !IS_ROOT(dentry);
 }
 
+static inline int cant_mount(struct dentry *dentry)
+{
+       return (dentry->d_flags & DCACHE_CANT_MOUNT);
+}
+
+static inline void dont_mount(struct dentry *dentry)
+{
+       spin_lock(&dentry->d_lock);
+       dentry->d_flags |= DCACHE_CANT_MOUNT;
+       spin_unlock(&dentry->d_lock);
+}
+
 static inline struct dentry *dget_parent(struct dentry *dentry)
 {
        struct dentry *ret;
index 8c243aaa86a73880d118f3f44374a0835d88503b..597692f1fc8dfb05383914af2b2a254d944fbc48 100644 (file)
@@ -20,12 +20,14 @@ struct debug_obj_descr;
  * struct debug_obj - representaion of an tracked object
  * @node:      hlist node to link the object into the tracker list
  * @state:     tracked object state
+ * @astate:    current active state
  * @object:    pointer to the real object
  * @descr:     pointer to an object type specific debug description structure
  */
 struct debug_obj {
        struct hlist_node       node;
        enum debug_obj_state    state;
+       unsigned int            astate;
        void                    *object;
        struct debug_obj_descr  *descr;
 };
@@ -60,6 +62,15 @@ extern void debug_object_deactivate(void *addr, struct debug_obj_descr *descr);
 extern void debug_object_destroy   (void *addr, struct debug_obj_descr *descr);
 extern void debug_object_free      (void *addr, struct debug_obj_descr *descr);
 
+/*
+ * Active state:
+ * - Set at 0 upon initialization.
+ * - Must return to 0 before deactivation.
+ */
+extern void
+debug_object_active_state(void *addr, struct debug_obj_descr *descr,
+                         unsigned int expect, unsigned int next);
+
 extern void debug_objects_early_init(void);
 extern void debug_objects_mem_init(void);
 #else
index 5076fe0c8a96a0f55b9992a21ff6d11a50ca56d5..6cee17c2231384cdaaad3fac1792cc9ca6e798b7 100644 (file)
@@ -18,6 +18,7 @@
 #define _LINUX_DELAYACCT_H
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 /*
  * Per-task flags relevant to delay accounting
index 78962272338a757b1eb17b2cb167b30e1090b3ed..4341b1a97a344d63d06dace3555ecee71eb59a53 100644 (file)
@@ -56,7 +56,7 @@ extern const char *drbd_buildtag(void);
 #define REL_VERSION "8.3.7"
 #define API_VERSION 88
 #define PRO_VERSION_MIN 86
-#define PRO_VERSION_MAX 91
+#define PRO_VERSION_MAX 92
 
 
 enum drbd_io_error_p {
index a4d82f8959942be17b948f06af29ceb07e58f5d1..f7431a4ca6082b20637b4e01e7dc96d8ffdef984 100644 (file)
@@ -12,7 +12,7 @@
 #endif
 
 NL_PACKET(primary, 1,
-       NL_BIT(         1,      T_MAY_IGNORE,   overwrite_peer)
+       NL_BIT(         1,      T_MAY_IGNORE,   primary_force)
 )
 
 NL_PACKET(secondary, 2, )
@@ -63,6 +63,7 @@ NL_PACKET(net_conf, 5,
        NL_BIT(         41,     T_MAY_IGNORE,   always_asbp)
        NL_BIT(         61,     T_MAY_IGNORE,   no_cork)
        NL_BIT(         62,     T_MANDATORY,    auto_sndbuf_size)
+       NL_BIT(         70,     T_MANDATORY,    dry_run)
 )
 
 NL_PACKET(disconnect, 6, )
index cac84b006667a42ee3296a3301e37f37978ec23f..5f494b4650977fcb9aac65aa7153320fb1c6f487 100644 (file)
@@ -565,17 +565,17 @@ enum {
 
 static inline int ext3_test_inode_state(struct inode *inode, int bit)
 {
-       return test_bit(bit, &EXT3_I(inode)->i_state);
+       return test_bit(bit, &EXT3_I(inode)->i_state_flags);
 }
 
 static inline void ext3_set_inode_state(struct inode *inode, int bit)
 {
-       set_bit(bit, &EXT3_I(inode)->i_state);
+       set_bit(bit, &EXT3_I(inode)->i_state_flags);
 }
 
 static inline void ext3_clear_inode_state(struct inode *inode, int bit)
 {
-       clear_bit(bit, &EXT3_I(inode)->i_state);
+       clear_bit(bit, &EXT3_I(inode)->i_state_flags);
 }
 #else
 /* Assume that user mode programs are passing in an ext3fs superblock, not
index 7679acdb519a14ae540f421a9d664b65914a5cfb..f42c098aed8d8a38c13849d5ef0940f6394b9594 100644 (file)
@@ -87,7 +87,7 @@ struct ext3_inode_info {
         * near to their parent directory's inode.
         */
        __u32   i_block_group;
-       unsigned long   i_state;        /* Dynamic state flags for ext3 */
+       unsigned long   i_state_flags;  /* Dynamic state flags for ext3 */
 
        /* block reservation info */
        struct ext3_block_alloc_info *i_block_alloc_info;
index 40b11013408ee163f4d295b91a51151a469f3ffa..68f883b30a53cd0ee0b5044f0ceb737676872d76 100644 (file)
@@ -1,21 +1,26 @@
 /*
  * Char device interface.
  *
- * Copyright (C) 2005-2006  Kristian Hoegsberg <krh@bitplanet.net>
- *
- * 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) 2005-2007  Kristian Hoegsberg <krh@bitplanet.net>
+ *
+ * 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 (including the next
+ * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
  */
 
 #ifndef _LINUX_FIREWIRE_CDEV_H
@@ -438,7 +443,7 @@ struct fw_cdev_remove_descriptor {
  * @type:      %FW_CDEV_ISO_CONTEXT_TRANSMIT or %FW_CDEV_ISO_CONTEXT_RECEIVE
  * @header_size: Header size to strip for receive contexts
  * @channel:   Channel to bind to
- * @speed:     Speed to transmit at
+ * @speed:     Speed for transmit contexts
  * @closure:   To be returned in &fw_cdev_event_iso_interrupt
  * @handle:    Handle to context, written back by kernel
  *
@@ -451,6 +456,9 @@ struct fw_cdev_remove_descriptor {
  * If a context was successfully created, the kernel writes back a handle to the
  * context, which must be passed in for subsequent operations on that context.
  *
+ * For receive contexts, @header_size must be at least 4 and must be a multiple
+ * of 4.
+ *
  * Note that the effect of a @header_size > 4 depends on
  * &fw_cdev_get_info.version, as documented at &fw_cdev_event_iso_interrupt.
  */
@@ -481,10 +489,34 @@ struct fw_cdev_create_iso_context {
  *
  * &struct fw_cdev_iso_packet is used to describe isochronous packet queues.
  *
- * Use the FW_CDEV_ISO_ macros to fill in @control.  The sy and tag fields are
- * specified by IEEE 1394a and IEC 61883.
- *
- * FIXME - finish this documentation
+ * Use the FW_CDEV_ISO_ macros to fill in @control.
+ *
+ * For transmit packets, the header length must be a multiple of 4 and specifies
+ * the numbers of bytes in @header that will be prepended to the packet's
+ * payload; these bytes are copied into the kernel and will not be accessed
+ * after the ioctl has returned.  The sy and tag fields are copied to the iso
+ * packet header (these fields are specified by IEEE 1394a and IEC 61883-1).
+ * The skip flag specifies that no packet is to be sent in a frame; when using
+ * this, all other fields except the interrupt flag must be zero.
+ *
+ * For receive packets, the header length must be a multiple of the context's
+ * header size; if the header length is larger than the context's header size,
+ * multiple packets are queued for this entry.  The sy and tag fields are
+ * ignored.  If the sync flag is set, the context drops all packets until
+ * a packet with a matching sy field is received (the sync value to wait for is
+ * specified in the &fw_cdev_start_iso structure).  The payload length defines
+ * how many payload bytes can be received for one packet (in addition to payload
+ * quadlets that have been defined as headers and are stripped and returned in
+ * the &fw_cdev_event_iso_interrupt structure).  If more bytes are received, the
+ * additional bytes are dropped.  If less bytes are received, the remaining
+ * bytes in this part of the payload buffer will not be written to, not even by
+ * the next packet, i.e., packets received in consecutive frames will not
+ * necessarily be consecutive in memory.  If an entry has queued multiple
+ * packets, the payload length is divided equally among them.
+ *
+ * When a packet with the interrupt flag set has been completed, the
+ * &fw_cdev_event_iso_interrupt event will be sent.  An entry that has queued
+ * multiple receive packets is completed when its last packet is completed.
  */
 struct fw_cdev_iso_packet {
        __u32 control;
@@ -501,7 +533,7 @@ struct fw_cdev_iso_packet {
  * Queue a number of isochronous packets for reception or transmission.
  * This ioctl takes a pointer to an array of &fw_cdev_iso_packet structs,
  * which describe how to transmit from or receive into a contiguous region
- * of a mmap()'ed payload buffer.  As part of the packet descriptors,
+ * of a mmap()'ed payload buffer.  As part of transmit packet descriptors,
  * a series of headers can be supplied, which will be prepended to the
  * payload during DMA.
  *
@@ -620,8 +652,8 @@ struct fw_cdev_get_cycle_timer2 {
  * instead of allocated.
  * An %FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED event concludes this operation.
  *
- * To summarize, %FW_CDEV_IOC_DEALLOCATE_ISO_RESOURCE allocates iso resources
- * for the lifetime of the fd or handle.
+ * To summarize, %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE allocates iso resources
+ * for the lifetime of the fd or @handle.
  * In contrast, %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE allocates iso resources
  * for the duration of a bus generation.
  *
index b316770a43fdc3a420d86ef24022713b17ab73a8..9b4bb5fbba4b47ba300d95f4143967acb659ad25 100644 (file)
@@ -1,3 +1,28 @@
+/*
+ * IEEE 1394 constants.
+ *
+ * Copyright (C) 2005-2007  Kristian Hoegsberg <krh@bitplanet.net>
+ *
+ * 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 (including the next
+ * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
 #ifndef _LINUX_FIREWIRE_CONSTANTS_H
 #define _LINUX_FIREWIRE_CONSTANTS_H
 
@@ -21,7 +46,7 @@
 #define EXTCODE_WRAP_ADD               0x6
 #define EXTCODE_VENDOR_DEPENDENT       0x7
 
-/* Juju specific tcodes */
+/* Linux firewire-core (Juju) specific tcodes */
 #define TCODE_LOCK_MASK_SWAP           (0x10 | EXTCODE_MASK_SWAP)
 #define TCODE_LOCK_COMPARE_SWAP                (0x10 | EXTCODE_COMPARE_SWAP)
 #define TCODE_LOCK_FETCH_ADD           (0x10 | EXTCODE_FETCH_ADD)
@@ -36,7 +61,7 @@
 #define RCODE_TYPE_ERROR               0x6
 #define RCODE_ADDRESS_ERROR            0x7
 
-/* Juju specific rcodes */
+/* Linux firewire-core (Juju) specific rcodes */
 #define RCODE_SEND_ERROR               0x10
 #define RCODE_CANCELLED                        0x11
 #define RCODE_BUSY                     0x12
index 5a361f85cfec483e0a595dcb2f4c2ee632ac56d9..da7e52b099f3221cf723f008aa2ac627d276e11b 100644 (file)
@@ -64,9 +64,12 @@ extern bool freeze_task(struct task_struct *p, bool sig_only);
 extern void cancel_freezing(struct task_struct *p);
 
 #ifdef CONFIG_CGROUP_FREEZER
-extern int cgroup_frozen(struct task_struct *task);
+extern int cgroup_freezing_or_frozen(struct task_struct *task);
 #else /* !CONFIG_CGROUP_FREEZER */
-static inline int cgroup_frozen(struct task_struct *task) { return 0; }
+static inline int cgroup_freezing_or_frozen(struct task_struct *task)
+{
+       return 0;
+}
 #endif /* !CONFIG_CGROUP_FREEZER */
 
 /*
index 10b8dedcd18b82a82491129a2baaef0f18ca4ce1..44f35aea2f1fe8ea178aaa9428d8826033ca034c 100644 (file)
@@ -2212,6 +2212,7 @@ extern int generic_segment_checks(const struct iovec *iov,
 /* fs/block_dev.c */
 extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
                                unsigned long nr_segs, loff_t pos);
+extern int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync);
 
 /* fs/splice.c */
 extern ssize_t generic_file_splice_read(struct file *, loff_t *,
@@ -2314,8 +2315,9 @@ extern int vfs_fstatat(int , char __user *, struct kstat *, int);
 extern int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
                    unsigned long arg);
 extern int __generic_block_fiemap(struct inode *inode,
-                                 struct fiemap_extent_info *fieinfo, u64 start,
-                                 u64 len, get_block_t *get_block);
+                                 struct fiemap_extent_info *fieinfo,
+                                 loff_t start, loff_t len,
+                                 get_block_t *get_block);
 extern int generic_block_fiemap(struct inode *inode,
                                struct fiemap_extent_info *fieinfo, u64 start,
                                u64 len, get_block_t *get_block);
index 7be0c6fbe8808be086d884939c7c621e3f5d78cf..c57db27ac86140ba13798e1736b31d9254162a82 100644 (file)
@@ -105,7 +105,7 @@ struct fscache_operation {
        /* operation releaser */
        fscache_operation_release_t release;
 
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
        const char *name;               /* operation name */
        const char *state;              /* operation state */
 #define fscache_set_op_name(OP, N)     do { (OP)->name  = (N); } while(0)
index df8fd9a3b214b5afde8a1368b327358117e6fbdb..01755909ce8167fade2220fb503435652bd71c44 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/inotify.h>
 #include <linux/fsnotify_backend.h>
 #include <linux/audit.h>
+#include <linux/slab.h>
 
 /*
  * fsnotify_d_instantiate - instantiate a dentry for inode
index 01e6adea07ecf798a0a45331a297e8ea5b481e42..41e46330d9bedfd16d46a920cbd840dad54afffe 100644 (file)
@@ -82,9 +82,13 @@ void clear_ftrace_function(void);
 extern void ftrace_stub(unsigned long a0, unsigned long a1);
 
 #else /* !CONFIG_FUNCTION_TRACER */
-# define register_ftrace_function(ops) do { } while (0)
-# define unregister_ftrace_function(ops) do { } while (0)
-# define clear_ftrace_function(ops) do { } while (0)
+/*
+ * (un)register_ftrace_function must be a macro since the ops parameter
+ * must not be evaluated.
+ */
+#define register_ftrace_function(ops) ({ 0; })
+#define unregister_ftrace_function(ops) ({ 0; })
+static inline void clear_ftrace_function(void) { }
 static inline void ftrace_kill(void) { }
 static inline void ftrace_stop(void) { }
 static inline void ftrace_start(void) { }
@@ -237,11 +241,13 @@ extern int skip_trace(unsigned long ip);
 extern void ftrace_disable_daemon(void);
 extern void ftrace_enable_daemon(void);
 #else
-# define skip_trace(ip)                                ({ 0; })
-# define ftrace_force_update()                 ({ 0; })
-# define ftrace_set_filter(buf, len, reset)    do { } while (0)
-# define ftrace_disable_daemon()               do { } while (0)
-# define ftrace_enable_daemon()                        do { } while (0)
+static inline int skip_trace(unsigned long ip) { return 0; }
+static inline int ftrace_force_update(void) { return 0; }
+static inline void ftrace_set_filter(unsigned char *buf, int len, int reset)
+{
+}
+static inline void ftrace_disable_daemon(void) { }
+static inline void ftrace_enable_daemon(void) { }
 static inline void ftrace_release_mod(struct module *mod) {}
 static inline int register_ftrace_command(struct ftrace_func_command *cmd)
 {
@@ -314,16 +320,16 @@ static inline void __ftrace_enabled_restore(int enabled)
   extern void time_hardirqs_on(unsigned long a0, unsigned long a1);
   extern void time_hardirqs_off(unsigned long a0, unsigned long a1);
 #else
-# define time_hardirqs_on(a0, a1)              do { } while (0)
-# define time_hardirqs_off(a0, a1)             do { } while (0)
+  static inline void time_hardirqs_on(unsigned long a0, unsigned long a1) { }
+  static inline void time_hardirqs_off(unsigned long a0, unsigned long a1) { }
 #endif
 
 #ifdef CONFIG_PREEMPT_TRACER
   extern void trace_preempt_on(unsigned long a0, unsigned long a1);
   extern void trace_preempt_off(unsigned long a0, unsigned long a1);
 #else
-# define trace_preempt_on(a0, a1)              do { } while (0)
-# define trace_preempt_off(a0, a1)             do { } while (0)
+  static inline void trace_preempt_on(unsigned long a0, unsigned long a1) { }
+  static inline void trace_preempt_off(unsigned long a0, unsigned long a1) { }
 #endif
 
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
@@ -352,6 +358,10 @@ struct ftrace_graph_ret {
        int depth;
 };
 
+/* Type of the callback handlers for tracing function graph*/
+typedef void (*trace_func_graph_ret_t)(struct ftrace_graph_ret *); /* return */
+typedef int (*trace_func_graph_ent_t)(struct ftrace_graph_ent *); /* entry */
+
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 
 /* for init task */
@@ -400,10 +410,6 @@ extern char __irqentry_text_end[];
 
 #define FTRACE_RETFUNC_DEPTH 50
 #define FTRACE_RETSTACK_ALLOC_SIZE 32
-/* Type of the callback handlers for tracing function graph*/
-typedef void (*trace_func_graph_ret_t)(struct ftrace_graph_ret *); /* return */
-typedef int (*trace_func_graph_ent_t)(struct ftrace_graph_ent *); /* entry */
-
 extern int register_ftrace_graph(trace_func_graph_ret_t retfunc,
                                trace_func_graph_ent_t entryfunc);
 
@@ -441,6 +447,13 @@ static inline void unpause_graph_tracing(void)
 static inline void ftrace_graph_init_task(struct task_struct *t) { }
 static inline void ftrace_graph_exit_task(struct task_struct *t) { }
 
+static inline int register_ftrace_graph(trace_func_graph_ret_t retfunc,
+                         trace_func_graph_ent_t entryfunc)
+{
+       return -1;
+}
+static inline void unregister_ftrace_graph(void) { }
+
 static inline int task_curr_ret_stack(struct task_struct *tsk)
 {
        return -1;
@@ -492,7 +505,9 @@ static inline int test_tsk_trace_graph(struct task_struct *tsk)
        return tsk->trace & TSK_TRACE_FL_GRAPH;
 }
 
-extern int ftrace_dump_on_oops;
+enum ftrace_dump_mode;
+
+extern enum ftrace_dump_mode ftrace_dump_on_oops;
 
 #ifdef CONFIG_PREEMPT
 #define INIT_TRACE_RECURSION           .trace_recursion = 0,
@@ -504,18 +519,6 @@ extern int ftrace_dump_on_oops;
 #define INIT_TRACE_RECURSION
 #endif
 
-#ifdef CONFIG_HW_BRANCH_TRACER
-
-void trace_hw_branch(u64 from, u64 to);
-void trace_hw_branch_oops(void);
-
-#else /* CONFIG_HW_BRANCH_TRACER */
-
-static inline void trace_hw_branch(u64 from, u64 to) {}
-static inline void trace_hw_branch_oops(void) {}
-
-#endif /* CONFIG_HW_BRANCH_TRACER */
-
 #ifdef CONFIG_FTRACE_SYSCALLS
 
 unsigned long arch_syscall_addr(int nr);
index 6b7c444ab8f6fcc84b6d7a1194902ab7a72f7ac6..39e71b0a3bfdb0aeaf9b546c111f19726a954136 100644 (file)
@@ -58,6 +58,7 @@ struct trace_iterator {
        /* The below is zeroed out in pipe_read */
        struct trace_seq        seq;
        struct trace_entry      *ent;
+       unsigned long           lost_events;
        int                     leftover;
        int                     cpu;
        u64                     ts;
@@ -131,12 +132,12 @@ struct ftrace_event_call {
        void                    *mod;
        void                    *data;
 
-       int                     profile_count;
-       int                     (*profile_enable)(struct ftrace_event_call *);
-       void                    (*profile_disable)(struct ftrace_event_call *);
+       int                     perf_refcount;
+       int                     (*perf_event_enable)(struct ftrace_event_call *);
+       void                    (*perf_event_disable)(struct ftrace_event_call *);
 };
 
-#define FTRACE_MAX_PROFILE_SIZE        2048
+#define PERF_MAX_TRACE_SIZE    2048
 
 #define MAX_FILTER_PRED                32
 #define MAX_FILTER_STR_VAL     256     /* Should handle KSYM_SYMBOL_LEN */
@@ -187,22 +188,25 @@ do {                                                                      \
 
 #ifdef CONFIG_PERF_EVENTS
 struct perf_event;
-extern int ftrace_profile_enable(int event_id);
-extern void ftrace_profile_disable(int event_id);
+
+DECLARE_PER_CPU(struct pt_regs, perf_trace_regs);
+
+extern int perf_trace_enable(int event_id);
+extern void perf_trace_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);
 extern void *
-ftrace_perf_buf_prepare(int size, unsigned short type, int *rctxp,
+perf_trace_buf_prepare(int size, unsigned short type, int *rctxp,
                         unsigned long *irq_flags);
 
 static inline void
-ftrace_perf_buf_submit(void *raw_data, int size, int rctx, u64 addr,
-                      u64 count, unsigned long irq_flags)
+perf_trace_buf_submit(void *raw_data, int size, int rctx, u64 addr,
+                      u64 count, unsigned long irq_flags, struct pt_regs *regs)
 {
        struct trace_entry *entry = raw_data;
 
-       perf_tp_event(entry->type, addr, count, raw_data, size);
+       perf_tp_event(entry->type, addr, count, raw_data, size, regs);
        perf_swevent_put_recursion_context(rctx);
        local_irq_restore(irq_flags);
 }
index 48e68da097f6f50000b80e8dd10a82581233179b..361d1cc288d03cc690fbac6638d1e865df289556 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mutex.h>
 #include <linux/device.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
 
 struct gameport {
 
index 56b50514ab2582a9ee288f68cfe630ccd846121a..5f2f4c4d8fb0594720bfc1643cec75fbf12aaa36 100644 (file)
@@ -109,7 +109,7 @@ struct hd_struct {
 };
 
 #define GENHD_FL_REMOVABLE                     1
-#define GENHD_FL_DRIVERFS                      2
+/* 2 is unused */
 #define GENHD_FL_MEDIA_CHANGE_NOTIFY           4
 #define GENHD_FL_CD                            8
 #define GENHD_FL_UP                            16
index c70d27af03f9f081c4a434151f7634bb5eceb93a..a2d6ea49ec564e825ebffc3ebb059f57079fc73d 100644 (file)
@@ -9,9 +9,22 @@ enum {
 };
 
 enum {
-       HW_BREAKPOINT_R = 1,
-       HW_BREAKPOINT_W = 2,
-       HW_BREAKPOINT_X = 4,
+       HW_BREAKPOINT_EMPTY     = 0,
+       HW_BREAKPOINT_R         = 1,
+       HW_BREAKPOINT_W         = 2,
+       HW_BREAKPOINT_RW        = HW_BREAKPOINT_R | HW_BREAKPOINT_W,
+       HW_BREAKPOINT_X         = 4,
+       HW_BREAKPOINT_INVALID   = HW_BREAKPOINT_RW | HW_BREAKPOINT_X,
+};
+
+enum bp_type_idx {
+       TYPE_INST       = 0,
+#ifdef CONFIG_HAVE_MIXED_BREAKPOINTS_REGS
+       TYPE_DATA       = 0,
+#else
+       TYPE_DATA       = 1,
+#endif
+       TYPE_MAX
 };
 
 #ifdef __KERNEL__
@@ -34,6 +47,12 @@ static inline void hw_breakpoint_init(struct perf_event_attr *attr)
        attr->sample_period = 1;
 }
 
+static inline void ptrace_breakpoint_init(struct perf_event_attr *attr)
+{
+       hw_breakpoint_init(attr);
+       attr->exclude_kernel = 1;
+}
+
 static inline unsigned long hw_breakpoint_addr(struct perf_event *bp)
 {
        return bp->attr.bp_addr;
index 0a5da639b32725388c8015ce4f4ca121380cf39b..6ed1d59bfb1e642789e25d47af65fb36c6921f2e 100644 (file)
@@ -355,6 +355,8 @@ struct i2c_adapter {
        int nr;
        char name[48];
        struct completion dev_released;
+
+       struct list_head userspace_clients;
 };
 #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
 
index 87018dc5527dac26d9baf1eefd000b56f74509ff..9e7a12d6385d73f4115bc7528aa30926bdc2005b 100644 (file)
@@ -782,7 +782,6 @@ extern int i2o_exec_lct_get(struct i2o_controller *);
 #define to_i2o_driver(drv) container_of(drv,struct i2o_driver, driver)
 #define to_i2o_device(dev) container_of(dev, struct i2o_device, device)
 #define to_i2o_controller(dev) container_of(dev, struct i2o_controller, device)
-#define kobj_to_i2o_device(kobj) to_i2o_device(container_of(kobj, struct device, kobj))
 
 /**
  *     i2o_out_to_virt - Turn an I2O message to a virtual address
index 97e6ab43518469354dcebc3703d2aa7fa9c4ff5f..3239d1c10acb3479a823cbf37651419d1d1a93cf 100644 (file)
@@ -1169,6 +1169,7 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);
 extern void ide_timer_expiry(unsigned long);
 extern irqreturn_t ide_intr(int irq, void *dev_id);
 extern void do_ide_request(struct request_queue *);
+extern void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq);
 
 void ide_init_disk(struct gendisk *, ide_drive_t *);
 
index c9bf92cd7653abf901ea048341149e290448b42c..d94963b379d93133b19947df42ca8d5841aa3b2c 100644 (file)
@@ -79,10 +79,7 @@ enum {
        IFLA_NET_NS_PID,
        IFLA_IFALIAS,
        IFLA_NUM_VF,            /* Number of VFs if device is SR-IOV PF */
-       IFLA_VF_MAC,            /* Hardware queue specific attributes */
-       IFLA_VF_VLAN,
-       IFLA_VF_TX_RATE,        /* TX Bandwidth Allocation */
-       IFLA_VFINFO,
+       IFLA_VFINFO_LIST,
        __IFLA_MAX
 };
 
@@ -203,6 +200,24 @@ enum macvlan_mode {
 
 /* SR-IOV virtual function managment section */
 
+enum {
+       IFLA_VF_INFO_UNSPEC,
+       IFLA_VF_INFO,
+       __IFLA_VF_INFO_MAX,
+};
+
+#define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1)
+
+enum {
+       IFLA_VF_UNSPEC,
+       IFLA_VF_MAC,            /* Hardware queue specific attributes */
+       IFLA_VF_VLAN,
+       IFLA_VF_TX_RATE,        /* TX Bandwidth Allocation */
+       __IFLA_VF_MAX,
+};
+
+#define IFLA_VF_MAX (__IFLA_VF_MAX - 1)
+
 struct ifla_vf_mac {
        __u32 vf;
        __u8 mac[32]; /* MAX_ADDR_LEN */
index 1822d635be6b461124e659cfaa0861474a25e0bf..16b92d008bed842e141f77664e94446cbe652dcf 100644 (file)
@@ -2,6 +2,7 @@
 #define _IF_TUNNEL_H_
 
 #include <linux/types.h>
+#include <asm/byteorder.h>
 
 #ifdef __KERNEL__
 #include <linux/ip.h>
index b1ed1cd8e2a891d96fa2e60cf9e10d4bd1d83b50..7996fc2c9ba9ee4fc0b573e4e07dffcc0c028c9b 100644 (file)
@@ -49,7 +49,6 @@ extern struct group_info init_groups;
                { .first = &init_task.pids[PIDTYPE_PGID].node },        \
                { .first = &init_task.pids[PIDTYPE_SID].node },         \
        },                                                              \
-       .rcu            = RCU_HEAD_INIT,                                \
        .level          = 0,                                            \
        .numbers        = { {                                           \
                .nr             = 0,                                    \
index 3bd018baae2046e8d0041feb883aecd7c4cce992..c964cd7f436a4ecf63d6f2080d280734f5a2a4ca 100644 (file)
@@ -44,6 +44,7 @@ struct matrix_keymap_data {
  * @active_low: gpio polarity
  * @wakeup: controls whether the device should be set up as wakeup
  *     source
+ * @no_autorepeat: disable key autorepeat
  *
  * This structure represents platform-specific data that use used by
  * matrix_keypad driver to perform proper initialization.
@@ -64,6 +65,7 @@ struct matrix_keypad_platform_data {
 
        bool            active_low;
        bool            wakeup;
+       bool            no_autorepeat;
 };
 
 /**
index 97eb928b49243076d89f634b06a1ab4802f49847..25085ddd955fda5516b4b8a73958246ba4044e41 100644 (file)
@@ -19,6 +19,7 @@
 #define _LINUX_IO_MAPPING_H
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/page.h>
 #include <asm/iomap.h>
index 3af4ffd591b978c4f7f815a5952131a0b673aa13..be22ad83689cb96275d0386c5325c4079699dc9c 100644 (file)
@@ -37,9 +37,9 @@ struct iommu_ops {
        int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
        void (*detach_dev)(struct iommu_domain *domain, struct device *dev);
        int (*map)(struct iommu_domain *domain, unsigned long iova,
-                  phys_addr_t paddr, size_t size, int prot);
-       void (*unmap)(struct iommu_domain *domain, unsigned long iova,
-                     size_t size);
+                  phys_addr_t paddr, int gfp_order, int prot);
+       int (*unmap)(struct iommu_domain *domain, unsigned long iova,
+                    int gfp_order);
        phys_addr_t (*iova_to_phys)(struct iommu_domain *domain,
                                    unsigned long iova);
        int (*domain_has_cap)(struct iommu_domain *domain,
@@ -56,10 +56,10 @@ extern int iommu_attach_device(struct iommu_domain *domain,
                               struct device *dev);
 extern void iommu_detach_device(struct iommu_domain *domain,
                                struct device *dev);
-extern int iommu_map_range(struct iommu_domain *domain, unsigned long iova,
-                          phys_addr_t paddr, size_t size, int prot);
-extern void iommu_unmap_range(struct iommu_domain *domain, unsigned long iova,
-                             size_t size);
+extern int iommu_map(struct iommu_domain *domain, unsigned long iova,
+                    phys_addr_t paddr, int gfp_order, int prot);
+extern int iommu_unmap(struct iommu_domain *domain, unsigned long iova,
+                      int gfp_order);
 extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
                                      unsigned long iova);
 extern int iommu_domain_has_cap(struct iommu_domain *domain,
@@ -96,16 +96,16 @@ static inline void iommu_detach_device(struct iommu_domain *domain,
 {
 }
 
-static inline int iommu_map_range(struct iommu_domain *domain,
-                                 unsigned long iova, phys_addr_t paddr,
-                                 size_t size, int prot)
+static inline int iommu_map(struct iommu_domain *domain, unsigned long iova,
+                           phys_addr_t paddr, int gfp_order, int prot)
 {
        return -ENODEV;
 }
 
-static inline void iommu_unmap_range(struct iommu_domain *domain,
-                                    unsigned long iova, size_t size)
+static inline int iommu_unmap(struct iommu_domain *domain, unsigned long iova,
+                             int gfp_order)
 {
+       return -ENODEV;
 }
 
 static inline phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
index 71ab79da7e7f6b3a12019849978e2da58a00b61c..26fad187d6610f3179dc3bf6b4b1b43820e1783a 100644 (file)
@@ -112,12 +112,14 @@ struct resource_list {
 extern struct resource ioport_resource;
 extern struct resource iomem_resource;
 
+extern struct resource *request_resource_conflict(struct resource *root, struct resource *new);
 extern int request_resource(struct resource *root, struct resource *new);
 extern int release_resource(struct resource *new);
 void release_child_resources(struct resource *new);
 extern void reserve_region_with_split(struct resource *root,
                             resource_size_t start, resource_size_t end,
                             const char *name);
+extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new);
 extern int insert_resource(struct resource *parent, struct resource *new);
 extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new);
 extern int allocate_resource(struct resource *root, struct resource *new,
index 6092487e2950695b76614701e47a4cb51175a4fb..d2e4042f8f5ed1492d17eaf57729ed1acba510d2 100644 (file)
@@ -42,9 +42,13 @@ extern struct ibft_table_header *ibft_addr;
  * mapped address is set in the ibft_addr variable.
  */
 #ifdef CONFIG_ISCSI_IBFT_FIND
-extern void __init reserve_ibft_region(void);
+unsigned long find_ibft_region(unsigned long *sizep);
 #else
-static inline void reserve_ibft_region(void) { }
+static inline unsigned long find_ibft_region(unsigned long *sizep)
+{
+       *sizep = 0;
+       return 0;
+}
 #endif
 
 #endif /* ISCSI_IBFT_H */
index f3aa59cb675d84cc92308bf038661826679cf5f0..516a2a27e87a3ce4c7ed3eeeedb12219aa28faec 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/mutex.h>
 #include <linux/timer.h>
 #include <linux/lockdep.h>
+#include <linux/slab.h>
 
 #define journal_oom_retry 1
 
index 1ec876358180ecd72ec00f06de81af9d6e4bba71..a4d2e9f7088ada70d8b1357f418c32cd09a5bf1a 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/bit_spinlock.h>
 #include <linux/mutex.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
 #endif
 
 #define journal_oom_retry 1
index 7f07074633603463af3c80eb9c9334f31789f244..9fb1c1299032ca8a051d969b8ab2bde46ea707b1 100644 (file)
@@ -426,7 +426,7 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
                .burst = DEFAULT_RATELIMIT_BURST,       \
        };                                              \
                                                        \
-       if (!__ratelimit(&_rs))                         \
+       if (__ratelimit(&_rs))                          \
                printk(fmt, ##__VA_ARGS__);             \
 })
 #else
@@ -490,6 +490,13 @@ static inline void tracing_off(void) { }
 static inline void tracing_off_permanent(void) { }
 static inline int tracing_is_on(void) { return 0; }
 #endif
+
+enum ftrace_dump_mode {
+       DUMP_NONE,
+       DUMP_ALL,
+       DUMP_ORIG,
+};
+
 #ifdef CONFIG_TRACING
 extern void tracing_start(void);
 extern void tracing_stop(void);
@@ -571,7 +578,7 @@ __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap);
 extern int
 __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap);
 
-extern void ftrace_dump(void);
+extern void ftrace_dump(enum ftrace_dump_mode oops_dump_mode);
 #else
 static inline void
 ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { }
@@ -592,7 +599,7 @@ ftrace_vprintk(const char *fmt, va_list ap)
 {
        return 0;
 }
-static inline void ftrace_dump(void) { }
+static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
 #endif /* CONFIG_TRACING */
 
 /*
index bc0fc795bd3536c90feb50b0ce4226c6461447e5..e117b1aee69c76eb39a9e66e3e69f8718cf5d49f 100644 (file)
@@ -86,7 +86,8 @@ union { \
  */
 #define INIT_KFIFO(name) \
        name = __kfifo_initializer(sizeof(name##kfifo_buffer) - \
-                               sizeof(struct kfifo), name##kfifo_buffer)
+                               sizeof(struct kfifo), \
+                               name##kfifo_buffer + sizeof(struct kfifo))
 
 /**
  * DEFINE_KFIFO - macro to define and initialize a kfifo
@@ -102,8 +103,6 @@ union { \
        unsigned char name##kfifo_buffer[size]; \
        struct kfifo name = __kfifo_initializer(size, name##kfifo_buffer)
 
-#undef __kfifo_initializer
-
 extern void kfifo_init(struct kfifo *fifo, void *buffer,
                        unsigned int size);
 extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size,
index a3fd0f91d943c8ad2b7264812a554ff6ebfc9a6e..169d07758ee53046c7f6740f3466aa78921e1342 100644 (file)
@@ -54,7 +54,7 @@ extern struct kmem_cache *kvm_vcpu_cache;
  */
 struct kvm_io_bus {
        int                   dev_count;
-#define NR_IOBUS_DEVS 6
+#define NR_IOBUS_DEVS 200
        struct kvm_io_device *devs[NR_IOBUS_DEVS];
 };
 
@@ -119,6 +119,11 @@ struct kvm_memory_slot {
        int user_alloc;
 };
 
+static inline unsigned long kvm_dirty_bitmap_bytes(struct kvm_memory_slot *memslot)
+{
+       return ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+}
+
 struct kvm_kernel_irq_routing_entry {
        u32 gsi;
        u32 type;
diff --git a/include/linux/lcm.h b/include/linux/lcm.h
new file mode 100644 (file)
index 0000000..7bf01d7
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _LCM_H
+#define _LCM_H
+
+#include <linux/compiler.h>
+
+unsigned long lcm(unsigned long a, unsigned long b) __attribute_const__;
+
+#endif /* _LCM_H */
index f8ea71e6d0e2f52c4811d14de18ea7d231b37959..b2f2003b92e5e727f9e5388f100bac66afd99e35 100644 (file)
@@ -146,6 +146,7 @@ enum {
        ATA_DFLAG_SLEEPING      = (1 << 15), /* device is sleeping */
        ATA_DFLAG_DUBIOUS_XFER  = (1 << 16), /* data transfer not verified */
        ATA_DFLAG_NO_UNLOAD     = (1 << 17), /* device doesn't support unload */
+       ATA_DFLAG_UNLOCK_HPA    = (1 << 18), /* unlock HPA */
        ATA_DFLAG_INIT_MASK     = (1 << 24) - 1,
 
        ATA_DFLAG_DETACH        = (1 << 24),
index 1adfe779eb99123a91c4141bd1974654db8d5880..85582e1bcee900bd219c60169a708a2a38dca8e1 100644 (file)
@@ -36,6 +36,8 @@ struct memory_block {
        struct sys_device sysdev;
 };
 
+int arch_get_memory_phys_device(unsigned long start_pfn);
+
 /* These states are exposed to userspace as text strings in sysfs */
 #define        MEM_ONLINE              (1<<0) /* exposed to userspace */
 #define        MEM_GOING_OFFLINE       (1<<1) /* exposed to userspace */
index e70f21beb4b4db9ec2944ca2bf0a9768e42af2b5..fb19bb92b809d81564cf03af26f5a568f2994629 100644 (file)
@@ -19,7 +19,6 @@ struct anon_vma;
 struct file_ra_state;
 struct user_struct;
 struct writeback_control;
-struct rlimit;
 
 #ifndef CONFIG_DISCONTIGMEM          /* Don't use mapnrs, do it properly */
 extern unsigned long max_mapnr;
@@ -783,8 +782,8 @@ struct mm_walk {
        int (*pmd_entry)(pmd_t *, unsigned long, unsigned long, struct mm_walk *);
        int (*pte_entry)(pte_t *, unsigned long, unsigned long, struct mm_walk *);
        int (*pte_hole)(unsigned long, unsigned long, struct mm_walk *);
-       int (*hugetlb_entry)(pte_t *, unsigned long, unsigned long,
-                            struct mm_walk *);
+       int (*hugetlb_entry)(pte_t *, unsigned long,
+                            unsigned long, unsigned long, struct mm_walk *);
        struct mm_struct *mm;
        void *private;
 };
@@ -1449,9 +1448,6 @@ int vmemmap_populate_basepages(struct page *start_page,
 int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
 void vmemmap_populate_print_last(void);
 
-extern int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim,
-                                size_t size);
-extern void refund_locked_memory(struct mm_struct *mm, size_t size);
 
 enum mf_flags {
        MF_COUNT_INCREASED = 1 << 0,
index c02c8db737011c848499c43580b64632980ff404..8a49cbf0376de0f42409ca1a5a1a71dd00104201 100644 (file)
@@ -268,6 +268,7 @@ struct _mmc_csd {
 
 #define EXT_CSD_CARD_TYPE_26   (1<<0)  /* Card can run at 26MHz */
 #define EXT_CSD_CARD_TYPE_52   (1<<1)  /* Card can run at 52MHz */
+#define EXT_CSD_CARD_TYPE_MASK 0x3     /* Mask out reserved and DDR bits */
 
 #define EXT_CSD_BUS_WIDTH_1    0       /* Card is in 1 bit mode */
 #define EXT_CSD_BUS_WIDTH_4    1       /* Card is in 4 bit mode */
index f58e9d836f329f8244b1dbab34f55b51665ad99e..56fde4364e4c062b8ce47f31155dfdc8db087177 100644 (file)
@@ -474,4 +474,13 @@ struct platform_device_id {
                        __attribute__((aligned(sizeof(kernel_ulong_t))));
 };
 
+struct zorro_device_id {
+       __u32 id;                       /* Device ID or ZORRO_WILDCARD */
+       kernel_ulong_t driver_data;     /* Data private to the driver */
+};
+
+#define ZORRO_WILDCARD                 (0xffffffff)    /* not official */
+
+#define ZORRO_DEVICE_MODALIAS_FMT      "zorro:i%08X"
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
index 5e869ffd34aa0203438c7136b681a276140bb48c..6914fcad46733974df83c76c5d7e2d96008793be 100644 (file)
@@ -330,8 +330,11 @@ struct module
        struct module_notes_attrs *notes_attrs;
 #endif
 
+#ifdef CONFIG_SMP
        /* Per-cpu data. */
-       void *percpu;
+       void __percpu *percpu;
+       unsigned int percpu_size;
+#endif
 
        /* The command line arguments (may be mangled).  People like
           keeping pointers to this stuff */
@@ -365,7 +368,8 @@ struct module
        void (*exit)(void);
 
        struct module_ref {
-               int count;
+               unsigned int incs;
+               unsigned int decs;
        } __percpu *refptr;
 #endif
 
@@ -392,6 +396,7 @@ static inline int module_is_live(struct module *mod)
 struct module *__module_text_address(unsigned long addr);
 struct module *__module_address(unsigned long addr);
 bool is_module_address(unsigned long addr);
+bool is_module_percpu_address(unsigned long addr);
 bool is_module_text_address(unsigned long addr);
 
 static inline int within_module_core(unsigned long addr, struct module *mod)
@@ -459,9 +464,8 @@ static inline void __module_get(struct module *module)
 {
        if (module) {
                preempt_disable();
-               __this_cpu_inc(module->refptr->count);
-               trace_module_get(module, _THIS_IP_,
-                                __this_cpu_read(module->refptr->count));
+               __this_cpu_inc(module->refptr->incs);
+               trace_module_get(module, _THIS_IP_);
                preempt_enable();
        }
 }
@@ -474,11 +478,9 @@ static inline int try_module_get(struct module *module)
                preempt_disable();
 
                if (likely(module_is_live(module))) {
-                       __this_cpu_inc(module->refptr->count);
-                       trace_module_get(module, _THIS_IP_,
-                               __this_cpu_read(module->refptr->count));
-               }
-               else
+                       __this_cpu_inc(module->refptr->incs);
+                       trace_module_get(module, _THIS_IP_);
+               } else
                        ret = 0;
 
                preempt_enable();
@@ -563,6 +565,11 @@ static inline bool is_module_address(unsigned long addr)
        return false;
 }
 
+static inline bool is_module_percpu_address(unsigned long addr)
+{
+       return false;
+}
+
 static inline bool is_module_text_address(unsigned long addr)
 {
        return false;
index 6330fc76b00fb481d8580a392425b45a5556d93c..5ec9ca671687e7c174b76b83995f209c0b0eacba 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/ncp_mount.h>
 #include <linux/net.h>
 #include <linux/mutex.h>
+#include <linux/backing-dev.h>
 
 #ifdef __KERNEL__
 
@@ -127,6 +128,7 @@ struct ncp_server {
                size_t len;
                __u8 data[128];
        } unexpected_packet;
+       struct backing_dev_info bdi;
 };
 
 extern void ncp_tcp_rcv_proc(struct work_struct *work);
index c79a88be7c33813c494bc3694229b943f2fc4d9e..fa8b47637997cd4eef3f0e791ce8bf5b48b34a85 100644 (file)
@@ -2059,12 +2059,12 @@ static inline void skb_bond_set_mac_by_master(struct sk_buff *skb,
  * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and
  * ARP on active-backup slaves with arp_validate enabled.
  */
-static inline int skb_bond_should_drop(struct sk_buff *skb)
+static inline int skb_bond_should_drop(struct sk_buff *skb,
+                                      struct net_device *master)
 {
-       struct net_device *dev = skb->dev;
-       struct net_device *master = dev->master;
-
        if (master) {
+               struct net_device *dev = skb->dev;
+
                if (master->priv_flags & IFF_MASTER_ARPMON)
                        dev->last_rx = jiffies;
 
index 53923868c9bddf8ab63a21019056b6858af5dbd9..361d6b5630ee8105e407477308bed1ab6f03ccf0 100644 (file)
@@ -76,7 +76,7 @@ extern int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n);
 extern int nfnetlink_has_listeners(struct net *net, unsigned int group);
 extern int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned group,
                          int echo, gfp_t flags);
-extern void nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error);
+extern int nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error);
 extern int nfnetlink_unicast(struct sk_buff *skb, struct net *net, u_int32_t pid, int flags);
 
 extern void nfnl_lock(void);
index d654873aa25afdaae0fe2ac921b2cd58db16bf04..1f7e300094cd4777ffe98600cc5319bcf5bb406f 100644 (file)
@@ -59,6 +59,7 @@
 enum nf_ip6_hook_priorities {
        NF_IP6_PRI_FIRST = INT_MIN,
        NF_IP6_PRI_CONNTRACK_DEFRAG = -400,
+       NF_IP6_PRI_RAW = -300,
        NF_IP6_PRI_SELINUX_FIRST = -225,
        NF_IP6_PRI_CONNTRACK = -200,
        NF_IP6_PRI_MANGLE = -150,
index fde27c0173266852787c4d15613f7116b10f3d21..6eaca5e1e8ca595fbfa388815c1b69675baaf314 100644 (file)
@@ -188,7 +188,7 @@ extern int netlink_has_listeners(struct sock *sk, unsigned int group);
 extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock);
 extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 pid,
                             __u32 group, gfp_t allocation);
-extern void netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code);
+extern int netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code);
 extern int netlink_register_notifier(struct notifier_block *nb);
 extern int netlink_unregister_notifier(struct notifier_block *nb);
 
index 1a0b85aa151e313e06912895c42a25a2b0c3c55d..07ce4609fe50416fd87e19c592fc8a978aa316bf 100644 (file)
@@ -209,6 +209,7 @@ struct nfs_inode {
 #define NFS_INO_FLUSHING       (4)             /* inode is flushing out data */
 #define NFS_INO_FSCACHE                (5)             /* inode can be cached by FS-Cache */
 #define NFS_INO_FSCACHE_LOCK   (6)             /* FS-Cache cookie management lock */
+#define NFS_INO_COMMIT         (7)             /* inode is committing unstable writes */
 
 static inline struct nfs_inode *NFS_I(const struct inode *inode)
 {
index 717a5e54eb1dcf68cdda886b71601e003fec105a..e82957acea561bfb9e4a73f33bbd7faf888cf671 100644 (file)
@@ -176,6 +176,7 @@ struct nfs_server {
 #define NFS_CAP_ATIME          (1U << 11)
 #define NFS_CAP_CTIME          (1U << 12)
 #define NFS_CAP_MTIME          (1U << 13)
+#define NFS_CAP_POSIX_LOCK     (1U << 14)
 
 
 /* maximum number of slots to use */
index f6d9cbc39c9ca684907940822ead7425c9f2c5da..a367e19bb3afef4b4da81b5f0676a87b7e1911da 100644 (file)
@@ -127,7 +127,7 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
 
 /* Default string compare functions, Allow arch asm/prom.h to override */
 #if !defined(of_compat_cmp)
-#define of_compat_cmp(s1, s2, l)       strncasecmp((s1), (s2), (l))
+#define of_compat_cmp(s1, s2, l)       strcasecmp((s1), (s2))
 #define of_prop_cmp(s1, s2)            strcmp((s1), (s2))
 #define of_node_cmp(s1, s2)            strcasecmp((s1), (s2))
 #endif
index 30b08136fdf3857db44dda40b04c0a5b46d2e622..aef22ae2af473f4113bf19560d1b441395a458da 100644 (file)
@@ -39,6 +39,7 @@ enum {
        PCG_CACHE, /* charged as cache */
        PCG_USED, /* this object is in use. */
        PCG_ACCT_LRU, /* page has been accounted for */
+       PCG_FILE_MAPPED, /* page is accounted as "mapped" */
 };
 
 #define TESTPCGFLAG(uname, lname)                      \
@@ -73,6 +74,11 @@ CLEARPCGFLAG(AcctLRU, ACCT_LRU)
 TESTPCGFLAG(AcctLRU, ACCT_LRU)
 TESTCLEARPCGFLAG(AcctLRU, ACCT_LRU)
 
+
+SETPCGFLAG(FileMapped, FILE_MAPPED)
+CLEARPCGFLAG(FileMapped, FILE_MAPPED)
+TESTPCGFLAG(FileMapped, FILE_MAPPED)
+
 static inline int page_cgroup_nid(struct page_cgroup *pc)
 {
        return page_to_nid(pc->page);
index a93e5bfdccb8e8b825006776f4afb77ebc975e90..d3a38d687104c4cc76700da32f8e97bd6f94dd60 100644 (file)
@@ -2,10 +2,10 @@
 #define __LINUX_PERCPU_H
 
 #include <linux/preempt.h>
-#include <linux/slab.h> /* For kmalloc() */
 #include <linux/smp.h>
 #include <linux/cpumask.h>
 #include <linux/pfn.h>
+#include <linux/init.h>
 
 #include <asm/percpu.h>
 
@@ -135,9 +135,7 @@ extern int __init pcpu_page_first_chunk(size_t reserved_size,
 #define per_cpu_ptr(ptr, cpu)  SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu)))
 
 extern void __percpu *__alloc_reserved_percpu(size_t size, size_t align);
-extern void __percpu *__alloc_percpu(size_t size, size_t align);
-extern void free_percpu(void __percpu *__pdata);
-extern phys_addr_t per_cpu_ptr_to_phys(void *addr);
+extern bool is_kernel_percpu_address(unsigned long addr);
 
 #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
 extern void __init setup_per_cpu_areas(void);
@@ -147,25 +145,10 @@ extern void __init setup_per_cpu_areas(void);
 
 #define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); })
 
-static inline void __percpu *__alloc_percpu(size_t size, size_t align)
+/* can't distinguish from other static vars, always false */
+static inline bool is_kernel_percpu_address(unsigned long addr)
 {
-       /*
-        * Can't easily make larger alignment work with kmalloc.  WARN
-        * on it.  Larger alignment should only be used for module
-        * percpu sections on SMP for which this path isn't used.
-        */
-       WARN_ON_ONCE(align > SMP_CACHE_BYTES);
-       return kzalloc(size, GFP_KERNEL);
-}
-
-static inline void free_percpu(void __percpu *p)
-{
-       kfree(p);
-}
-
-static inline phys_addr_t per_cpu_ptr_to_phys(void *addr)
-{
-       return __pa(addr);
+       return false;
 }
 
 static inline void __init setup_per_cpu_areas(void) { }
@@ -177,6 +160,10 @@ static inline void *pcpu_lpage_remapped(void *kaddr)
 
 #endif /* CONFIG_SMP */
 
+extern void __percpu *__alloc_percpu(size_t size, size_t align);
+extern void free_percpu(void __percpu *__pdata);
+extern phys_addr_t per_cpu_ptr_to_phys(void *addr);
+
 #define alloc_percpu(type)     \
        (typeof(type) __percpu *)__alloc_percpu(sizeof(type), __alignof__(type))
 
index 6f8cd7da1a012da2760e0e251f8d1792a99cfcd7..3fd5c82e0e184c0690d8e62a2a459ad2dea279da 100644 (file)
@@ -203,8 +203,19 @@ struct perf_event_attr {
                                enable_on_exec :  1, /* next exec enables     */
                                task           :  1, /* trace fork/exit       */
                                watermark      :  1, /* wakeup_watermark      */
-
-                               __reserved_1   : 49;
+                               /*
+                                * precise_ip:
+                                *
+                                *  0 - SAMPLE_IP can have arbitrary skid
+                                *  1 - SAMPLE_IP must have constant skid
+                                *  2 - SAMPLE_IP requested to have 0 skid
+                                *  3 - SAMPLE_IP must have 0 skid
+                                *
+                                *  See also PERF_RECORD_MISC_EXACT_IP
+                                */
+                               precise_ip     :  2, /* skid constraint       */
+
+                               __reserved_1   : 47;
 
        union {
                __u32           wakeup_events;    /* wakeup every n events */
@@ -287,11 +298,24 @@ struct perf_event_mmap_page {
        __u64   data_tail;              /* user-space written tail */
 };
 
-#define PERF_RECORD_MISC_CPUMODE_MASK          (3 << 0)
+#define PERF_RECORD_MISC_CPUMODE_MASK          (7 << 0)
 #define PERF_RECORD_MISC_CPUMODE_UNKNOWN       (0 << 0)
 #define PERF_RECORD_MISC_KERNEL                        (1 << 0)
 #define PERF_RECORD_MISC_USER                  (2 << 0)
 #define PERF_RECORD_MISC_HYPERVISOR            (3 << 0)
+#define PERF_RECORD_MISC_GUEST_KERNEL          (4 << 0)
+#define PERF_RECORD_MISC_GUEST_USER            (5 << 0)
+
+/*
+ * Indicates that the content of PERF_SAMPLE_IP points to
+ * the actual instruction that triggered the event. See also
+ * perf_event_attr::precise_ip.
+ */
+#define PERF_RECORD_MISC_EXACT_IP              (1 << 14)
+/*
+ * Reserve the last bit to indicate some extended misc field
+ */
+#define PERF_RECORD_MISC_EXT_RESERVED          (1 << 15)
 
 struct perf_event_header {
        __u32   type;
@@ -439,6 +463,12 @@ enum perf_callchain_context {
 # include <asm/perf_event.h>
 #endif
 
+struct perf_guest_info_callbacks {
+       int (*is_in_guest) (void);
+       int (*is_user_mode) (void);
+       unsigned long (*get_guest_ip) (void);
+};
+
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 #include <asm/hw_breakpoint.h>
 #endif
@@ -452,6 +482,8 @@ enum perf_callchain_context {
 #include <linux/fs.h>
 #include <linux/pid_namespace.h>
 #include <linux/workqueue.h>
+#include <linux/ftrace.h>
+#include <linux/cpu.h>
 #include <asm/atomic.h>
 
 #define PERF_MAX_STACK_DEPTH           255
@@ -466,6 +498,17 @@ struct perf_raw_record {
        void                            *data;
 };
 
+struct perf_branch_entry {
+       __u64                           from;
+       __u64                           to;
+       __u64                           flags;
+};
+
+struct perf_branch_stack {
+       __u64                           nr;
+       struct perf_branch_entry        entries[0];
+};
+
 struct task_struct;
 
 /**
@@ -504,6 +547,8 @@ struct hw_perf_event {
 
 struct perf_event;
 
+#define PERF_EVENT_TXN_STARTED 1
+
 /**
  * struct pmu - generic performance monitoring unit
  */
@@ -514,6 +559,16 @@ struct pmu {
        void (*stop)                    (struct perf_event *event);
        void (*read)                    (struct perf_event *event);
        void (*unthrottle)              (struct perf_event *event);
+
+       /*
+        * group events scheduling is treated as a transaction,
+        * add group events as a whole and perform one schedulability test.
+        * If test fails, roll back the whole group
+        */
+
+       void (*start_txn)       (const struct pmu *pmu);
+       void (*cancel_txn)      (const struct pmu *pmu);
+       int  (*commit_txn)      (const struct pmu *pmu);
 };
 
 /**
@@ -569,6 +624,14 @@ enum perf_group_flag {
        PERF_GROUP_SOFTWARE = 0x1,
 };
 
+#define SWEVENT_HLIST_BITS     8
+#define SWEVENT_HLIST_SIZE     (1 << SWEVENT_HLIST_BITS)
+
+struct swevent_hlist {
+       struct hlist_head       heads[SWEVENT_HLIST_SIZE];
+       struct rcu_head         rcu_head;
+};
+
 /**
  * struct perf_event - performance event kernel representation:
  */
@@ -577,6 +640,7 @@ struct perf_event {
        struct list_head                group_entry;
        struct list_head                event_entry;
        struct list_head                sibling_list;
+       struct hlist_node               hlist_entry;
        int                             nr_siblings;
        int                             group_flags;
        struct perf_event               *group_leader;
@@ -724,6 +788,9 @@ struct perf_cpu_context {
        int                             active_oncpu;
        int                             max_pertask;
        int                             exclusive;
+       struct swevent_hlist            *swevent_hlist;
+       struct mutex                    hlist_mutex;
+       int                             hlist_refcount;
 
        /*
         * Recursion avoidance:
@@ -767,9 +834,6 @@ extern void perf_disable(void);
 extern void perf_enable(void);
 extern int perf_event_task_disable(void);
 extern int perf_event_task_enable(void);
-extern int hw_perf_group_sched_in(struct perf_event *group_leader,
-              struct perf_cpu_context *cpuctx,
-              struct perf_event_context *ctx);
 extern void perf_event_update_userpage(struct perf_event *event);
 extern int perf_event_release_kernel(struct perf_event *event);
 extern struct perf_event *
@@ -840,11 +904,56 @@ extern atomic_t perf_swevent_enabled[PERF_COUNT_SW_MAX];
 
 extern void __perf_sw_event(u32, u64, int, struct pt_regs *, u64);
 
+extern void
+perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip);
+
+/*
+ * Take a snapshot of the regs. Skip ip and frame pointer to
+ * the nth caller. We only need a few of the regs:
+ * - ip for PERF_SAMPLE_IP
+ * - cs for user_mode() tests
+ * - bp for callchains
+ * - eflags, for future purposes, just in case
+ */
+static inline void perf_fetch_caller_regs(struct pt_regs *regs, int skip)
+{
+       unsigned long ip;
+
+       memset(regs, 0, sizeof(*regs));
+
+       switch (skip) {
+       case 1 :
+               ip = CALLER_ADDR0;
+               break;
+       case 2 :
+               ip = CALLER_ADDR1;
+               break;
+       case 3 :
+               ip = CALLER_ADDR2;
+               break;
+       case 4:
+               ip = CALLER_ADDR3;
+               break;
+       /* No need to support further for now */
+       default:
+               ip = 0;
+       }
+
+       return perf_arch_fetch_caller_regs(regs, ip, skip);
+}
+
 static inline void
 perf_sw_event(u32 event_id, u64 nr, int nmi, struct pt_regs *regs, u64 addr)
 {
-       if (atomic_read(&perf_swevent_enabled[event_id]))
+       if (atomic_read(&perf_swevent_enabled[event_id])) {
+               struct pt_regs hot_regs;
+
+               if (!regs) {
+                       perf_fetch_caller_regs(&hot_regs, 1);
+                       regs = &hot_regs;
+               }
                __perf_sw_event(event_id, nr, nmi, regs, addr);
+       }
 }
 
 extern void __perf_event_mmap(struct vm_area_struct *vma);
@@ -855,6 +964,10 @@ static inline void perf_event_mmap(struct vm_area_struct *vma)
                __perf_event_mmap(vma);
 }
 
+extern struct perf_guest_info_callbacks *perf_guest_cbs;
+extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
+extern int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
+
 extern void perf_event_comm(struct task_struct *tsk);
 extern void perf_event_fork(struct task_struct *tsk);
 
@@ -880,7 +993,8 @@ static inline bool perf_paranoid_kernel(void)
 }
 
 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_tp_event(int event_id, u64 addr, u64 count, void *record,
+                         int entry_size, struct pt_regs *regs);
 extern void perf_bp_event(struct perf_event *event, void *data);
 
 #ifndef perf_misc_flags
@@ -923,6 +1037,11 @@ perf_sw_event(u32 event_id, u64 nr, int nmi,
 static inline void
 perf_bp_event(struct perf_event *event, void *data)                    { }
 
+static inline int perf_register_guest_info_callbacks
+(struct perf_guest_info_callbacks *callbacks) { return 0; }
+static inline int perf_unregister_guest_info_callbacks
+(struct perf_guest_info_callbacks *callbacks) { return 0; }
+
 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)            { }
@@ -936,5 +1055,21 @@ static inline void perf_event_disable(struct perf_event *event)           { }
 #define perf_output_put(handle, x) \
        perf_output_copy((handle), &(x), sizeof(x))
 
+/*
+ * This has to have a higher priority than migration_notifier in sched.c.
+ */
+#define perf_cpu_notifier(fn)                                  \
+do {                                                           \
+       static struct notifier_block fn##_nb __cpuinitdata =    \
+               { .notifier_call = fn, .priority = 20 };        \
+       fn(&fn##_nb, (unsigned long)CPU_UP_PREPARE,             \
+               (void *)(unsigned long)smp_processor_id());     \
+       fn(&fn##_nb, (unsigned long)CPU_STARTING,               \
+               (void *)(unsigned long)smp_processor_id());     \
+       fn(&fn##_nb, (unsigned long)CPU_ONLINE,                 \
+               (void *)(unsigned long)smp_processor_id());     \
+       register_cpu_notifier(&fn##_nb);                        \
+} while (0)
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_PERF_EVENT_H */
index 212da17d06afa66fb07749b6498aa4f3d4f6f727..5417944d3687758bdfbb286633457258fd88a913 100644 (file)
@@ -44,12 +44,14 @@ extern int platform_get_irq_byname(struct platform_device *, const char *);
 extern int platform_add_devices(struct platform_device **, int);
 
 extern struct platform_device *platform_device_register_simple(const char *, int id,
-                                       struct resource *, unsigned int);
+                                       const struct resource *, unsigned int);
 extern struct platform_device *platform_device_register_data(struct device *,
                const char *, int, const void *, size_t);
 
 extern struct platform_device *platform_device_alloc(const char *name, int id);
-extern int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num);
+extern int platform_device_add_resources(struct platform_device *pdev,
+                                        const struct resource *res,
+                                        unsigned int num);
 extern int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size);
 extern int platform_device_add(struct platform_device *pdev);
 extern void platform_device_del(struct platform_device *pdev);
index 2110a81c5e2afaab47ec5cb107cf17503d731317..34066ffd893d733b8134da1b57915bec314afb48 100644 (file)
 #define POISON_FREE    0x6b    /* for use-after-free poisoning */
 #define        POISON_END      0xa5    /* end-byte of poisoning */
 
+/********** mm/hugetlb.c **********/
+/*
+ * Private mappings of hugetlb pages use this poisoned value for
+ * page->mapping. The core VM should not be doing anything with this mapping
+ * but futex requires the existence of some page->mapping value even though it
+ * is unused if PAGE_MAPPING_ANON is set.
+ */
+#define HUGETLB_POISON ((void *)(0x00300300 + POISON_POINTER_DELTA + PAGE_MAPPING_ANON))
+
 /********** arch/$ARCH/mm/init.c **********/
 #define POISON_FREE_INITMEM    0xcc
 
index e1fb60729979b12f4c401a4310e6272f6417ef70..4272521e29e9d5e85483a1cf7d14af96940bcb68 100644 (file)
@@ -345,18 +345,6 @@ static inline void user_single_step_siginfo(struct task_struct *tsk,
 #define arch_ptrace_stop(code, info)           do { } while (0)
 #endif
 
-#ifndef arch_ptrace_untrace
-/*
- * Do machine-specific work before untracing child.
- *
- * This is called for a normal detach as well as from ptrace_exit()
- * when the tracing task dies.
- *
- * Called with write_lock(&tasklist_lock) held.
- */
-#define arch_ptrace_untrace(task)              do { } while (0)
-#endif
-
 extern int task_current_syscall(struct task_struct *target, long *callno,
                                unsigned long args[6], unsigned int maxargs,
                                unsigned long *sp, unsigned long *pc);
index c5da7491809655fde7650c0ba65753988b41c4ab..55ca73cf25e5c850217d4dc626e551a2ff0ac0d4 100644 (file)
@@ -121,6 +121,13 @@ do {                                                                       \
  * (Note, rcu_assign_pointer and rcu_dereference are not needed to control
  * access to data items when inserting into or looking up from the radix tree)
  *
+ * Note that the value returned by radix_tree_tag_get() may not be relied upon
+ * if only the RCU read lock is held.  Functions to set/clear tags and to
+ * delete nodes running concurrently with it may affect its result such that
+ * two consecutive reads in the same locked section may return different
+ * values.  If reliability is required, modification functions must also be
+ * excluded from concurrency.
+ *
  * radix_tree_tagged is able to be called without locking or RCU.
  */
 
index 5210a5c60877c2b0d08b831d9f2bdcb8ec1b2b3a..fe1872e5b37e1f8fab4d090f620c2660809d0a6b 100644 (file)
@@ -110,6 +110,7 @@ struct rb_node
 struct rb_root
 {
        struct rb_node *rb_node;
+       void (*augment_cb)(struct rb_node *node);
 };
 
 
@@ -129,7 +130,9 @@ static inline void rb_set_color(struct rb_node *rb, int color)
        rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
 }
 
-#define RB_ROOT        (struct rb_root) { NULL, }
+#define RB_ROOT        (struct rb_root) { NULL, NULL, }
+#define RB_AUGMENT_ROOT(x)     (struct rb_root) { NULL, x}
+
 #define        rb_entry(ptr, type, member) container_of(ptr, type, member)
 
 #define RB_EMPTY_ROOT(root)    ((root)->rb_node == NULL)
index 3024050c82a12610222a1b5e7d1c40d44e339b5a..b653b4aaa8a6332c8d783f2cd9afb7c8882028b4 100644 (file)
@@ -56,8 +56,6 @@ struct rcu_head {
 };
 
 /* Exported common interfaces */
-extern void synchronize_rcu_bh(void);
-extern void synchronize_sched(void);
 extern void rcu_barrier(void);
 extern void rcu_barrier_bh(void);
 extern void rcu_barrier_sched(void);
@@ -66,8 +64,6 @@ extern int sched_expedited_torture_stats(char *page);
 
 /* Internal to kernel */
 extern void rcu_init(void);
-extern int rcu_scheduler_active;
-extern void rcu_scheduler_starting(void);
 
 #if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU)
 #include <linux/rcutree.h>
@@ -83,6 +79,14 @@ extern void rcu_scheduler_starting(void);
        (ptr)->next = NULL; (ptr)->func = NULL; \
 } while (0)
 
+static inline void init_rcu_head_on_stack(struct rcu_head *head)
+{
+}
+
+static inline void destroy_rcu_head_on_stack(struct rcu_head *head)
+{
+}
+
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 
 extern struct lockdep_map rcu_lock_map;
@@ -101,20 +105,18 @@ extern struct lockdep_map rcu_sched_lock_map;
 # define rcu_read_release_sched() \
                lock_release(&rcu_sched_lock_map, 1, _THIS_IP_)
 
-static inline int debug_lockdep_rcu_enabled(void)
-{
-       return likely(rcu_scheduler_active && debug_locks);
-}
+extern int debug_lockdep_rcu_enabled(void);
 
 /**
  * rcu_read_lock_held - might we be in RCU read-side critical section?
  *
- * If CONFIG_PROVE_LOCKING is selected and enabled, returns nonzero iff in
- * an RCU read-side critical section.  In absence of CONFIG_PROVE_LOCKING,
+ * If CONFIG_DEBUG_LOCK_ALLOC is selected, returns nonzero iff in an RCU
+ * read-side critical section.  In absence of CONFIG_DEBUG_LOCK_ALLOC,
  * this assumes we are in an RCU read-side critical section unless it can
  * prove otherwise.
  *
- * Check rcu_scheduler_active to prevent false positives during boot.
+ * Check debug_lockdep_rcu_enabled() to prevent false positives during boot
+ * and while lockdep is disabled.
  */
 static inline int rcu_read_lock_held(void)
 {
@@ -123,33 +125,24 @@ static inline int rcu_read_lock_held(void)
        return lock_is_held(&rcu_lock_map);
 }
 
-/**
- * rcu_read_lock_bh_held - might we be in RCU-bh read-side critical section?
- *
- * If CONFIG_PROVE_LOCKING is selected and enabled, returns nonzero iff in
- * an RCU-bh read-side critical section.  In absence of CONFIG_PROVE_LOCKING,
- * this assumes we are in an RCU-bh read-side critical section unless it can
- * prove otherwise.
- *
- * Check rcu_scheduler_active to prevent false positives during boot.
+/*
+ * rcu_read_lock_bh_held() is defined out of line to avoid #include-file
+ * hell.
  */
-static inline int rcu_read_lock_bh_held(void)
-{
-       if (!debug_lockdep_rcu_enabled())
-               return 1;
-       return lock_is_held(&rcu_bh_lock_map);
-}
+extern int rcu_read_lock_bh_held(void);
 
 /**
  * rcu_read_lock_sched_held - might we be in RCU-sched read-side critical section?
  *
- * If CONFIG_PROVE_LOCKING is selected and enabled, returns nonzero iff in an
- * RCU-sched read-side critical section.  In absence of CONFIG_PROVE_LOCKING,
- * this assumes we are in an RCU-sched read-side critical section unless it
- * can prove otherwise.  Note that disabling of preemption (including
- * disabling irqs) counts as an RCU-sched read-side critical section.
+ * If CONFIG_DEBUG_LOCK_ALLOC is selected, returns nonzero iff in an
+ * RCU-sched read-side critical section.  In absence of
+ * CONFIG_DEBUG_LOCK_ALLOC, this assumes we are in an RCU-sched read-side
+ * critical section unless it can prove otherwise.  Note that disabling
+ * of preemption (including disabling irqs) counts as an RCU-sched
+ * read-side critical section.
  *
- * Check rcu_scheduler_active to prevent false positives during boot.
+ * Check debug_lockdep_rcu_enabled() to prevent false positives during boot
+ * and while lockdep is disabled.
  */
 #ifdef CONFIG_PREEMPT
 static inline int rcu_read_lock_sched_held(void)
@@ -160,7 +153,7 @@ static inline int rcu_read_lock_sched_held(void)
                return 1;
        if (debug_locks)
                lockdep_opinion = lock_is_held(&rcu_sched_lock_map);
-       return lockdep_opinion || preempt_count() != 0;
+       return lockdep_opinion || preempt_count() != 0 || irqs_disabled();
 }
 #else /* #ifdef CONFIG_PREEMPT */
 static inline int rcu_read_lock_sched_held(void)
@@ -191,7 +184,7 @@ static inline int rcu_read_lock_bh_held(void)
 #ifdef CONFIG_PREEMPT
 static inline int rcu_read_lock_sched_held(void)
 {
-       return !rcu_scheduler_active || preempt_count() != 0;
+       return preempt_count() != 0 || irqs_disabled();
 }
 #else /* #ifdef CONFIG_PREEMPT */
 static inline int rcu_read_lock_sched_held(void)
@@ -204,28 +197,87 @@ static inline int rcu_read_lock_sched_held(void)
 
 #ifdef CONFIG_PROVE_RCU
 
+extern int rcu_my_thread_group_empty(void);
+
+#define __do_rcu_dereference_check(c)                                  \
+       do {                                                            \
+               static bool __warned;                                   \
+               if (debug_lockdep_rcu_enabled() && !__warned && !(c)) { \
+                       __warned = true;                                \
+                       lockdep_rcu_dereference(__FILE__, __LINE__);    \
+               }                                                       \
+       } while (0)
+
 /**
  * rcu_dereference_check - rcu_dereference with debug checking
+ * @p: The pointer to read, prior to dereferencing
+ * @c: The conditions under which the dereference will take place
+ *
+ * Do an rcu_dereference(), but check that the conditions under which the
+ * dereference will take place are correct.  Typically the conditions indicate
+ * the various locking conditions that should be held at that point.  The check
+ * should return true if the conditions are satisfied.
+ *
+ * For example:
+ *
+ *     bar = rcu_dereference_check(foo->bar, rcu_read_lock_held() ||
+ *                                           lockdep_is_held(&foo->lock));
+ *
+ * could be used to indicate to lockdep that foo->bar may only be dereferenced
+ * if either the RCU read lock is held, or that the lock required to replace
+ * the bar struct at foo->bar is held.
+ *
+ * Note that the list of conditions may also include indications of when a lock
+ * need not be held, for example during initialisation or destruction of the
+ * target struct:
  *
- * Do an rcu_dereference(), but check that the context is correct.
- * For example, rcu_dereference_check(gp, rcu_read_lock_held()) to
- * ensure that the rcu_dereference_check() executes within an RCU
- * read-side critical section.  It is also possible to check for
- * locks being held, for example, by using lockdep_is_held().
+ *     bar = rcu_dereference_check(foo->bar, rcu_read_lock_held() ||
+ *                                           lockdep_is_held(&foo->lock) ||
+ *                                           atomic_read(&foo->usage) == 0);
  */
 #define rcu_dereference_check(p, c) \
        ({ \
-               if (debug_lockdep_rcu_enabled() && !(c)) \
-                       lockdep_rcu_dereference(__FILE__, __LINE__); \
+               __do_rcu_dereference_check(c); \
                rcu_dereference_raw(p); \
        })
 
+/**
+ * rcu_dereference_protected - fetch RCU pointer when updates prevented
+ *
+ * Return the value of the specified RCU-protected pointer, but omit
+ * both the smp_read_barrier_depends() and the ACCESS_ONCE().  This
+ * is useful in cases where update-side locks prevent the value of the
+ * pointer from changing.  Please note that this primitive does -not-
+ * prevent the compiler from repeating this reference or combining it
+ * with other references, so it should not be used without protection
+ * of appropriate locks.
+ */
+#define rcu_dereference_protected(p, c) \
+       ({ \
+               __do_rcu_dereference_check(c); \
+               (p); \
+       })
+
 #else /* #ifdef CONFIG_PROVE_RCU */
 
 #define rcu_dereference_check(p, c)    rcu_dereference_raw(p)
+#define rcu_dereference_protected(p, c) (p)
 
 #endif /* #else #ifdef CONFIG_PROVE_RCU */
 
+/**
+ * rcu_access_pointer - fetch RCU pointer with no dereferencing
+ *
+ * Return the value of the specified RCU-protected pointer, but omit the
+ * smp_read_barrier_depends() and keep the ACCESS_ONCE().  This is useful
+ * when the value of this pointer is accessed, but the pointer is not
+ * dereferenced, for example, when testing an RCU-protected pointer against
+ * NULL.  This may also be used in cases where update-side locks prevent
+ * the value of the pointer from changing, but rcu_dereference_protected()
+ * is a lighter-weight primitive for this use case.
+ */
+#define rcu_access_pointer(p)  ACCESS_ONCE(p)
+
 /**
  * rcu_read_lock - mark the beginning of an RCU read-side critical section.
  *
index a5195875480aa299d96e0649f524a184cdd88413..e2e893144a8450848cf50f8672368aa79c0a0001 100644 (file)
 
 void rcu_sched_qs(int cpu);
 void rcu_bh_qs(int cpu);
+static inline void rcu_note_context_switch(int cpu)
+{
+       rcu_sched_qs(cpu);
+}
 
 #define __rcu_read_lock()      preempt_disable()
 #define __rcu_read_unlock()    preempt_enable()
@@ -60,8 +64,6 @@ static inline long rcu_batches_completed_bh(void)
        return 0;
 }
 
-extern int rcu_expedited_torture_stats(char *page);
-
 static inline void rcu_force_quiescent_state(void)
 {
 }
@@ -74,7 +76,17 @@ static inline void rcu_sched_force_quiescent_state(void)
 {
 }
 
-#define synchronize_rcu synchronize_sched
+extern void synchronize_sched(void);
+
+static inline void synchronize_rcu(void)
+{
+       synchronize_sched();
+}
+
+static inline void synchronize_rcu_bh(void)
+{
+       synchronize_sched();
+}
 
 static inline void synchronize_rcu_expedited(void)
 {
@@ -114,4 +126,17 @@ static inline int rcu_preempt_depth(void)
        return 0;
 }
 
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+
+extern int rcu_scheduler_active __read_mostly;
+extern void rcu_scheduler_starting(void);
+
+#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+
+static inline void rcu_scheduler_starting(void)
+{
+}
+
+#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+
 #endif /* __LINUX_RCUTINY_H */
index 42cc3a04779ee1376adce84aeb57655df656d06f..c0ed1c056f290701def0e0116b6aad72ada30c91 100644 (file)
@@ -34,8 +34,8 @@ struct notifier_block;
 
 extern void rcu_sched_qs(int cpu);
 extern void rcu_bh_qs(int cpu);
+extern void rcu_note_context_switch(int cpu);
 extern int rcu_needs_cpu(int cpu);
-extern int rcu_expedited_torture_stats(char *page);
 
 #ifdef CONFIG_TREE_PREEMPT_RCU
 
@@ -86,6 +86,8 @@ static inline void __rcu_read_unlock_bh(void)
 
 extern void call_rcu_sched(struct rcu_head *head,
                           void (*func)(struct rcu_head *rcu));
+extern void synchronize_rcu_bh(void);
+extern void synchronize_sched(void);
 extern void synchronize_rcu_expedited(void);
 
 static inline void synchronize_rcu_bh_expedited(void)
@@ -120,4 +122,7 @@ static inline int rcu_blocking_is_gp(void)
        return num_online_cpus() == 1;
 }
 
+extern void rcu_scheduler_starting(void);
+extern int rcu_scheduler_active __read_mostly;
+
 #endif /* __LINUX_RCUTREE_H */
index 28c9fd020d3992669435ed8767e522e2f48b76b1..ebd7472652942c116b66b5e17a8d00a6dd46b894 100644 (file)
@@ -183,9 +183,13 @@ static inline struct regulator *__must_check regulator_get(struct device *dev,
 {
        /* Nothing except the stubbed out regulator API should be
         * looking at the value except to check if it is an error
-        * value so the actual return value doesn't matter.
+        * value. Drivers are free to handle NULL specifically by
+        * skipping all regulator API calls, but they don't have to.
+        * Drivers which don't, should make sure they properly handle
+        * corner cases of the API, such as regulator_get_voltage()
+        * returning 0.
         */
-       return (struct regulator *)id;
+       return NULL;
 }
 static inline void regulator_put(struct regulator *regulator)
 {
index 99928dce37ea927bde2f515df93ad9a2bab2a239..7fa02b4af838513b9a609122db0772654cdc2f91 100644 (file)
@@ -70,6 +70,11 @@ int reiserfs_security_write(struct reiserfs_transaction_handle *th,
 void reiserfs_security_free(struct reiserfs_security_handle *sec);
 #endif
 
+static inline int reiserfs_xattrs_initialized(struct super_block *sb)
+{
+       return REISERFS_SB(sb)->priv_root != NULL;
+}
+
 #define xattr_size(size) ((size) + sizeof(struct reiserfs_xattr_header))
 static inline loff_t reiserfs_xattr_nblocks(struct inode *inode, loff_t size)
 {
index 5fcc31ed5771358b625eb24434e656e28f016cd8..25b4f686d9189242f6e6d817b563101f7ce07262 100644 (file)
@@ -120,12 +120,16 @@ int ring_buffer_write(struct ring_buffer *buffer,
                      unsigned long length, void *data);
 
 struct ring_buffer_event *
-ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts);
+ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts,
+                unsigned long *lost_events);
 struct ring_buffer_event *
-ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts);
+ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts,
+                   unsigned long *lost_events);
 
 struct ring_buffer_iter *
-ring_buffer_read_start(struct ring_buffer *buffer, int cpu);
+ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu);
+void ring_buffer_read_prepare_sync(void);
+void ring_buffer_read_start(struct ring_buffer_iter *iter);
 void ring_buffer_read_finish(struct ring_buffer_iter *iter);
 
 struct ring_buffer_event *
index dad7f668ebf70041f3897102a0ff13a1a456edad..b55e988988b589dca9ead5726e1f3ac52df4f98e 100644 (file)
@@ -99,7 +99,6 @@ struct futex_pi_state;
 struct robust_list_head;
 struct bio_list;
 struct fs_struct;
-struct bts_context;
 struct perf_event_context;
 
 /*
@@ -275,11 +274,17 @@ extern cpumask_var_t nohz_cpu_mask;
 #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ)
 extern int select_nohz_load_balancer(int cpu);
 extern int get_nohz_load_balancer(void);
+extern int nohz_ratelimit(int cpu);
 #else
 static inline int select_nohz_load_balancer(int cpu)
 {
        return 0;
 }
+
+static inline int nohz_ratelimit(int cpu)
+{
+       return 0;
+}
 #endif
 
 /*
@@ -954,6 +959,7 @@ struct sched_domain {
        char *name;
 #endif
 
+       unsigned int span_weight;
        /*
         * Span of all CPUs in this domain.
         *
@@ -1026,12 +1032,17 @@ struct sched_domain;
 #define WF_SYNC                0x01            /* waker goes to sleep after wakup */
 #define WF_FORK                0x02            /* child wakeup after fork */
 
+#define ENQUEUE_WAKEUP         1
+#define ENQUEUE_WAKING         2
+#define ENQUEUE_HEAD           4
+
+#define DEQUEUE_SLEEP          1
+
 struct sched_class {
        const struct sched_class *next;
 
-       void (*enqueue_task) (struct rq *rq, struct task_struct *p, int wakeup,
-                             bool head);
-       void (*dequeue_task) (struct rq *rq, struct task_struct *p, int sleep);
+       void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags);
+       void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags);
        void (*yield_task) (struct rq *rq);
 
        void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int flags);
@@ -1040,7 +1051,8 @@ struct sched_class {
        void (*put_prev_task) (struct rq *rq, struct task_struct *p);
 
 #ifdef CONFIG_SMP
-       int  (*select_task_rq)(struct task_struct *p, int sd_flag, int flags);
+       int  (*select_task_rq)(struct rq *rq, struct task_struct *p,
+                              int sd_flag, int flags);
 
        void (*pre_schedule) (struct rq *this_rq, struct task_struct *task);
        void (*post_schedule) (struct rq *this_rq);
@@ -1077,36 +1089,8 @@ struct load_weight {
        unsigned long weight, inv_weight;
 };
 
-/*
- * CFS stats for a schedulable entity (task, task-group etc)
- *
- * Current field usage histogram:
- *
- *     4 se->block_start
- *     4 se->run_node
- *     4 se->sleep_start
- *     6 se->load.weight
- */
-struct sched_entity {
-       struct load_weight      load;           /* for load-balancing */
-       struct rb_node          run_node;
-       struct list_head        group_node;
-       unsigned int            on_rq;
-
-       u64                     exec_start;
-       u64                     sum_exec_runtime;
-       u64                     vruntime;
-       u64                     prev_sum_exec_runtime;
-
-       u64                     last_wakeup;
-       u64                     avg_overlap;
-
-       u64                     nr_migrations;
-
-       u64                     start_runtime;
-       u64                     avg_wakeup;
-
 #ifdef CONFIG_SCHEDSTATS
+struct sched_statistics {
        u64                     wait_start;
        u64                     wait_max;
        u64                     wait_count;
@@ -1138,6 +1122,24 @@ struct sched_entity {
        u64                     nr_wakeups_affine_attempts;
        u64                     nr_wakeups_passive;
        u64                     nr_wakeups_idle;
+};
+#endif
+
+struct sched_entity {
+       struct load_weight      load;           /* for load-balancing */
+       struct rb_node          run_node;
+       struct list_head        group_node;
+       unsigned int            on_rq;
+
+       u64                     exec_start;
+       u64                     sum_exec_runtime;
+       u64                     vruntime;
+       u64                     prev_sum_exec_runtime;
+
+       u64                     nr_migrations;
+
+#ifdef CONFIG_SCHEDSTATS
+       struct sched_statistics statistics;
 #endif
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
@@ -1272,12 +1274,6 @@ struct task_struct {
        struct list_head ptraced;
        struct list_head ptrace_entry;
 
-       /*
-        * This is the tracer handle for the ptrace BTS extension.
-        * This field actually belongs to the ptracer task.
-        */
-       struct bts_context *bts;
-
        /* PID/PID hash table linkage. */
        struct pid_link pids[PIDTYPE_MAX];
        struct list_head thread_group;
@@ -1497,7 +1493,6 @@ struct task_struct {
        /* bitmask of trace recursion */
        unsigned long trace_recursion;
 #endif /* CONFIG_TRACING */
-       unsigned long stack_start;
 #ifdef CONFIG_CGROUP_MEM_RES_CTLR /* memcg uses this to do batch job */
        struct memcg_batch_info {
                int do_batch;   /* incremented when batch uncharge started */
@@ -1847,6 +1842,7 @@ extern void sched_clock_idle_sleep_event(void);
 extern void sched_clock_idle_wakeup_event(u64 delta_ns);
 
 #ifdef CONFIG_HOTPLUG_CPU
+extern void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p);
 extern void idle_task_exit(void);
 #else
 static inline void idle_task_exit(void) {}
@@ -2123,10 +2119,8 @@ extern void set_task_comm(struct task_struct *tsk, char *from);
 extern char *get_task_comm(char *to, struct task_struct *tsk);
 
 #ifdef CONFIG_SMP
-extern void wait_task_context_switch(struct task_struct *p);
 extern unsigned long wait_task_inactive(struct task_struct *, long match_state);
 #else
-static inline void wait_task_context_switch(struct task_struct *p) {}
 static inline unsigned long wait_task_inactive(struct task_struct *p,
                                               long match_state)
 {
index 233d20b52c1b2506debd5a0585f9a7810329c9fd..3158dd982d2756aaf0ab5cee2f6c166b47575adf 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/sched.h>
 #include <linux/key.h>
 #include <linux/xfrm.h>
-#include <linux/gfp.h>
+#include <linux/slab.h>
 #include <net/flow.h>
 
 /* Maximum number of letters for an LSM name string */
index 1b177d29a7f0fdac7c2483431abb0ec92e3a2a2d..193d4bfe42ffd5ae030bb4357a64de0da00a0ebc 100644 (file)
@@ -2,7 +2,9 @@
 #define __LINUX_SERIAL_SCI_H
 
 #include <linux/serial_core.h>
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
 #include <asm/dmaengine.h>
+#endif
 
 /*
  * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts)
@@ -30,8 +32,10 @@ struct plat_sci_port {
        upf_t           flags;                  /* UPF_* flags */
        char            *clk;                   /* clock string */
        struct device   *dma_dev;
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
        enum sh_dmae_slave_chan_id dma_slave_tx;
        enum sh_dmae_slave_chan_id dma_slave_rx;
+#endif
 };
 
 #endif /* __LINUX_SERIAL_SCI_H */
index 03f816a9b65950ba998b00aaf5f3352f25be0c7f..124f90cd5a38bd39ab88af0563aa0d0ff9aa06d2 100644 (file)
@@ -190,9 +190,6 @@ struct skb_shared_info {
        atomic_t        dataref;
        unsigned short  nr_frags;
        unsigned short  gso_size;
-#ifdef CONFIG_HAS_DMA
-       dma_addr_t      dma_head;
-#endif
        /* Warning: this field is not always filled in (UFO)! */
        unsigned short  gso_segs;
        unsigned short  gso_type;
@@ -201,9 +198,6 @@ struct skb_shared_info {
        struct sk_buff  *frag_list;
        struct skb_shared_hwtstamps hwtstamps;
        skb_frag_t      frags[MAX_SKB_FRAGS];
-#ifdef CONFIG_HAS_DMA
-       dma_addr_t      dma_maps[MAX_SKB_FRAGS];
-#endif
        /* Intermediate layers must ensure that destructor_arg
         * remains valid until skb destructor */
        void *          destructor_arg;
index 488446289cab4839670d8ff507d1cfb508d2fc98..49d1247cd6d904b1bc8cfc38a2193bd179855c35 100644 (file)
@@ -106,6 +106,7 @@ int kmem_cache_shrink(struct kmem_cache *);
 void kmem_cache_free(struct kmem_cache *, void *);
 unsigned int kmem_cache_size(struct kmem_cache *);
 const char *kmem_cache_name(struct kmem_cache *);
+int kern_ptr_validate(const void *ptr, unsigned long size);
 int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr);
 
 /*
index 8a060a7040d818dae9a86af3f350ea3d2635d17b..bb947dd1fba92515170f1a5de745dde34026eb0a 100644 (file)
@@ -10,6 +10,7 @@
 #define _SMB_FS_SB
 
 #include <linux/types.h>
+#include <linux/backing-dev.h>
 #include <linux/smb.h>
 
 /*
@@ -74,6 +75,8 @@ struct smb_sb_info {
        struct smb_ops *ops;
 
        struct super_block *super_block;
+
+       struct backing_dev_info bdi;
 };
 
 static inline int
index 7b3aae2052a6e37340ed04548487333141d925cd..354cc5617f8b87304b97eebeec2c4b3e8a52428a 100644 (file)
@@ -255,6 +255,7 @@ struct ucred {
 #define MSG_ERRQUEUE   0x2000  /* Fetch message from error queue */
 #define MSG_NOSIGNAL   0x4000  /* Do not generate SIGPIPE */
 #define MSG_MORE       0x8000  /* Sender will send more */
+#define MSG_WAITFORONE 0x10000 /* recvmmsg(): block until 1+ packets avail */
 
 #define MSG_EOF         MSG_FIN
 
diff --git a/include/linux/spi/l4f00242t03.h b/include/linux/spi/l4f00242t03.h
new file mode 100644 (file)
index 0000000..aee1dbd
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * l4f00242t03.h -- Platform glue for Epson L4F00242T03 LCD
+ *
+ * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ * Based on Marek Vasut work in lms283gf05.h
+ *
+ * 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 _INCLUDE_LINUX_SPI_L4F00242T03_H_
+#define _INCLUDE_LINUX_SPI_L4F00242T03_H_
+
+struct l4f00242t03_pdata {
+       unsigned int    reset_gpio;
+       unsigned int    data_enable_gpio;
+       const char      *io_supply;     /* will be set to 1.8 V */
+       const char      *core_supply;   /* will be set to 2.8 V */
+};
+
+#endif /* _INCLUDE_LINUX_SPI_L4F00242T03_H_ */
index 97b60b37f445dca6cad09959e5838b2206280149..af56071b06f92ea23368947a4daffad12e03e660 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/device.h>
 #include <linux/mod_devicetable.h>
+#include <linux/slab.h>
 
 /*
  * INTERFACES between SPI master-side drivers and SPI infrastructure.
index 4d5ecb222af9e0f83a377b71aa97f520ba8d1aa2..4d5d2f546dbff11ee6a4abb6ad2cc53770d45aeb 100644 (file)
@@ -27,6 +27,8 @@
 #ifndef _LINUX_SRCU_H
 #define _LINUX_SRCU_H
 
+#include <linux/mutex.h>
+
 struct srcu_struct_array {
        int c[2];
 };
@@ -84,8 +86,8 @@ long srcu_batches_completed(struct srcu_struct *sp);
 /**
  * srcu_read_lock_held - might we be in SRCU read-side critical section?
  *
- * If CONFIG_PROVE_LOCKING is selected and enabled, returns nonzero iff in
- * an SRCU read-side critical section.  In absence of CONFIG_PROVE_LOCKING,
+ * If CONFIG_DEBUG_LOCK_ALLOC is selected, returns nonzero iff in an SRCU
+ * read-side critical section.  In absence of CONFIG_DEBUG_LOCK_ALLOC,
  * this assumes we are in an SRCU read-side critical section unless it can
  * prove otherwise.
  */
index baba3a23a8145c6106177f924dd712b63e7b2f17..6b524a0d02e42b14419c5ae75133360a1f4874a5 100644 (file)
 #ifndef _LINUX_STOP_MACHINE
 #define _LINUX_STOP_MACHINE
-/* "Bogolock": stop the entire machine, disable interrupts.  This is a
-   very heavy lock, which is equivalent to grabbing every spinlock
-   (and more).  So the "read" side to such a lock is anything which
-   disables preeempt. */
+
 #include <linux/cpu.h>
 #include <linux/cpumask.h>
+#include <linux/list.h>
 #include <asm/system.h>
 
+/*
+ * stop_cpu[s]() is simplistic per-cpu maximum priority cpu
+ * monopolization mechanism.  The caller can specify a non-sleeping
+ * function to be executed on a single or multiple cpus preempting all
+ * other processes and monopolizing those cpus until it finishes.
+ *
+ * Resources for this mechanism are preallocated when a cpu is brought
+ * up and requests are guaranteed to be served as long as the target
+ * cpus are online.
+ */
+typedef int (*cpu_stop_fn_t)(void *arg);
+
+#ifdef CONFIG_SMP
+
+struct cpu_stop_work {
+       struct list_head        list;           /* cpu_stopper->works */
+       cpu_stop_fn_t           fn;
+       void                    *arg;
+       struct cpu_stop_done    *done;
+};
+
+int stop_one_cpu(unsigned int cpu, cpu_stop_fn_t fn, void *arg);
+void stop_one_cpu_nowait(unsigned int cpu, cpu_stop_fn_t fn, void *arg,
+                        struct cpu_stop_work *work_buf);
+int stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg);
+int try_stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg);
+
+#else  /* CONFIG_SMP */
+
+#include <linux/workqueue.h>
+
+struct cpu_stop_work {
+       struct work_struct      work;
+       cpu_stop_fn_t           fn;
+       void                    *arg;
+};
+
+static inline int stop_one_cpu(unsigned int cpu, cpu_stop_fn_t fn, void *arg)
+{
+       int ret = -ENOENT;
+       preempt_disable();
+       if (cpu == smp_processor_id())
+               ret = fn(arg);
+       preempt_enable();
+       return ret;
+}
+
+static void stop_one_cpu_nowait_workfn(struct work_struct *work)
+{
+       struct cpu_stop_work *stwork =
+               container_of(work, struct cpu_stop_work, work);
+       preempt_disable();
+       stwork->fn(stwork->arg);
+       preempt_enable();
+}
+
+static inline void stop_one_cpu_nowait(unsigned int cpu,
+                                      cpu_stop_fn_t fn, void *arg,
+                                      struct cpu_stop_work *work_buf)
+{
+       if (cpu == smp_processor_id()) {
+               INIT_WORK(&work_buf->work, stop_one_cpu_nowait_workfn);
+               work_buf->fn = fn;
+               work_buf->arg = arg;
+               schedule_work(&work_buf->work);
+       }
+}
+
+static inline int stop_cpus(const struct cpumask *cpumask,
+                           cpu_stop_fn_t fn, void *arg)
+{
+       if (cpumask_test_cpu(raw_smp_processor_id(), cpumask))
+               return stop_one_cpu(raw_smp_processor_id(), fn, arg);
+       return -ENOENT;
+}
+
+static inline int try_stop_cpus(const struct cpumask *cpumask,
+                               cpu_stop_fn_t fn, void *arg)
+{
+       return stop_cpus(cpumask, fn, arg);
+}
+
+#endif /* CONFIG_SMP */
+
+/*
+ * stop_machine "Bogolock": stop the entire machine, disable
+ * interrupts.  This is a very heavy lock, which is equivalent to
+ * grabbing every spinlock (and more).  So the "read" side to such a
+ * lock is anything which disables preeempt.
+ */
 #if defined(CONFIG_STOP_MACHINE) && defined(CONFIG_SMP)
 
 /**
@@ -36,24 +124,7 @@ int stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus);
  */
 int __stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus);
 
-/**
- * stop_machine_create: create all stop_machine threads
- *
- * Description: This causes all stop_machine threads to be created before
- * stop_machine actually gets called. This can be used by subsystems that
- * need a non failing stop_machine infrastructure.
- */
-int stop_machine_create(void);
-
-/**
- * stop_machine_destroy: destroy all stop_machine threads
- *
- * Description: This causes all stop_machine threads which were created with
- * stop_machine_create to be destroyed again.
- */
-void stop_machine_destroy(void);
-
-#else
+#else   /* CONFIG_STOP_MACHINE && CONFIG_SMP */
 
 static inline int stop_machine(int (*fn)(void *), void *data,
                               const struct cpumask *cpus)
@@ -65,8 +136,5 @@ static inline int stop_machine(int (*fn)(void *), void *data,
        return ret;
 }
 
-static inline int stop_machine_create(void) { return 0; }
-static inline void stop_machine_destroy(void) { }
-
-#endif /* CONFIG_SMP */
-#endif /* _LINUX_STOP_MACHINE */
+#endif /* CONFIG_STOP_MACHINE && CONFIG_SMP */
+#endif /* _LINUX_STOP_MACHINE */
index d7152b451e21d7fb2bb84fcd3ffc33afa8ace8e9..7c91260c44a93ef8870f6c0cd2620cb0619e113f 100644 (file)
@@ -36,7 +36,6 @@ struct rpc_rqst *xprt_alloc_bc_request(struct rpc_xprt *xprt);
 void xprt_free_bc_request(struct rpc_rqst *req);
 int xprt_setup_backchannel(struct rpc_xprt *, unsigned int min_reqs);
 void xprt_destroy_backchannel(struct rpc_xprt *, int max_reqs);
-void bc_release_request(struct rpc_task *);
 int bc_send(struct rpc_rqst *req);
 
 /*
@@ -59,6 +58,10 @@ static inline int svc_is_backchannel(const struct svc_rqst *rqstp)
 {
        return 0;
 }
+
+static inline void xprt_free_bc_request(struct rpc_rqst *req)
+{
+}
 #endif /* CONFIG_NFS_V4_1 */
 #endif /* _LINUX_SUNRPC_BC_XPRT_H */
 
index 44f2ad0e88252de06c20e157a9f1055a1c8d82eb..057929b0a6514963b66098e9f3ff58129937ffa5 100644 (file)
@@ -105,18 +105,18 @@ struct perf_event_attr;
 
 #ifdef CONFIG_PERF_EVENTS
 
-#define TRACE_SYS_ENTER_PROFILE_INIT(sname)                                   \
-       .profile_enable = prof_sysenter_enable,                                \
-       .profile_disable = prof_sysenter_disable,
+#define TRACE_SYS_ENTER_PERF_INIT(sname)                                      \
+       .perf_event_enable = perf_sysenter_enable,                             \
+       .perf_event_disable = perf_sysenter_disable,
 
-#define TRACE_SYS_EXIT_PROFILE_INIT(sname)                                    \
-       .profile_enable = prof_sysexit_enable,                                 \
-       .profile_disable = prof_sysexit_disable,
+#define TRACE_SYS_EXIT_PERF_INIT(sname)                                               \
+       .perf_event_enable = perf_sysexit_enable,                              \
+       .perf_event_disable = perf_sysexit_disable,
 #else
-#define TRACE_SYS_ENTER_PROFILE(sname)
-#define TRACE_SYS_ENTER_PROFILE_INIT(sname)
-#define TRACE_SYS_EXIT_PROFILE(sname)
-#define TRACE_SYS_EXIT_PROFILE_INIT(sname)
+#define TRACE_SYS_ENTER_PERF(sname)
+#define TRACE_SYS_ENTER_PERF_INIT(sname)
+#define TRACE_SYS_EXIT_PERF(sname)
+#define TRACE_SYS_EXIT_PERF_INIT(sname)
 #endif /* CONFIG_PERF_EVENTS */
 
 #ifdef CONFIG_FTRACE_SYSCALLS
@@ -153,7 +153,7 @@ struct perf_event_attr;
                .regfunc                = reg_event_syscall_enter,      \
                .unregfunc              = unreg_event_syscall_enter,    \
                .data                   = (void *)&__syscall_meta_##sname,\
-               TRACE_SYS_ENTER_PROFILE_INIT(sname)                     \
+               TRACE_SYS_ENTER_PERF_INIT(sname)                        \
        }
 
 #define SYSCALL_TRACE_EXIT_EVENT(sname)                                        \
@@ -175,7 +175,7 @@ struct perf_event_attr;
                .regfunc                = reg_event_syscall_exit,       \
                .unregfunc              = unreg_event_syscall_exit,     \
                .data                   = (void *)&__syscall_meta_##sname,\
-               TRACE_SYS_EXIT_PROFILE_INIT(sname)                      \
+               TRACE_SYS_EXIT_PERF_INIT(sname)                 \
        }
 
 #define SYSCALL_METADATA(sname, nb)                            \
@@ -688,7 +688,7 @@ asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg);
 asmlinkage long sys_shmget(key_t key, size_t size, int flag);
 asmlinkage long sys_shmdt(char __user *shmaddr);
 asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf);
-asmlinkage long sys_ipc(unsigned int call, int first, int second,
+asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second,
                unsigned long third, void __user *ptr, long fifth);
 
 asmlinkage long sys_mq_open(const char __user *name, int oflag, mode_t mode, struct mq_attr __user *attr);
index b6523c1427ce09f17b4827072e614ab2e34c64ed..58de6edf751f5e0a6c4c13517785674200d6a9c0 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/taskstats.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_TASKSTATS
 extern struct kmem_cache *taskstats_cache;
index d2ae79e21be3a4aee4fe1cd8dde51d272d7b97dc..b232ccc0ee291d8297d1fd40b07ab999979bc3cb 100644 (file)
@@ -42,6 +42,7 @@ enum tick_nohz_mode {
  * @idle_waketime:     Time when the idle was interrupted
  * @idle_exittime:     Time when the idle state was left
  * @idle_sleeptime:    Sum of the time slept in idle with sched tick stopped
+ * @iowait_sleeptime:  Sum of the time slept in idle with sched tick stopped, with IO outstanding
  * @sleep_length:      Duration of the current idle sleep
  * @do_timer_lst:      CPU was the last one doing do_timer before going idle
  */
@@ -60,7 +61,7 @@ struct tick_sched {
        ktime_t                         idle_waketime;
        ktime_t                         idle_exittime;
        ktime_t                         idle_sleeptime;
-       ktime_t                         idle_lastupdate;
+       ktime_t                         iowait_sleeptime;
        ktime_t                         sleep_length;
        unsigned long                   last_jiffies;
        unsigned long                   next_jiffies;
@@ -124,6 +125,7 @@ extern void tick_nohz_stop_sched_tick(int inidle);
 extern void tick_nohz_restart_sched_tick(void);
 extern ktime_t tick_nohz_get_sleep_length(void);
 extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time);
+extern u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time);
 # else
 static inline void tick_nohz_stop_sched_tick(int inidle) { }
 static inline void tick_nohz_restart_sched_tick(void) { }
@@ -134,6 +136,7 @@ static inline ktime_t tick_nohz_get_sleep_length(void)
        return len;
 }
 static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; }
+static inline u64 get_cpu_iowait_time_us(int cpu, u64 *unused) { return -1; }
 # endif /* !NO_HZ */
 
 #endif
index f59604ed0ec606c75449d6b2cd8416abf6f7f38f..1d85f9a6a19926af57cfe58081822109d99a98f0 100644 (file)
@@ -33,6 +33,65 @@ struct tracepoint {
                                         * Keep in sync with vmlinux.lds.h.
                                         */
 
+/*
+ * Connect a probe to a tracepoint.
+ * Internal API, should not be used directly.
+ */
+extern int tracepoint_probe_register(const char *name, void *probe);
+
+/*
+ * Disconnect a probe from a tracepoint.
+ * Internal API, should not be used directly.
+ */
+extern int tracepoint_probe_unregister(const char *name, void *probe);
+
+extern int tracepoint_probe_register_noupdate(const char *name, void *probe);
+extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe);
+extern void tracepoint_probe_update_all(void);
+
+struct tracepoint_iter {
+       struct module *module;
+       struct tracepoint *tracepoint;
+};
+
+extern void tracepoint_iter_start(struct tracepoint_iter *iter);
+extern void tracepoint_iter_next(struct tracepoint_iter *iter);
+extern void tracepoint_iter_stop(struct tracepoint_iter *iter);
+extern void tracepoint_iter_reset(struct tracepoint_iter *iter);
+extern int tracepoint_get_iter_range(struct tracepoint **tracepoint,
+       struct tracepoint *begin, struct tracepoint *end);
+
+/*
+ * tracepoint_synchronize_unregister must be called between the last tracepoint
+ * probe unregistration and the end of module exit to make sure there is no
+ * caller executing a probe when it is freed.
+ */
+static inline void tracepoint_synchronize_unregister(void)
+{
+       synchronize_sched();
+}
+
+#define PARAMS(args...) args
+
+#ifdef CONFIG_TRACEPOINTS
+extern void tracepoint_update_probe_range(struct tracepoint *begin,
+       struct tracepoint *end);
+#else
+static inline void tracepoint_update_probe_range(struct tracepoint *begin,
+       struct tracepoint *end)
+{ }
+#endif /* CONFIG_TRACEPOINTS */
+
+#endif /* _LINUX_TRACEPOINT_H */
+
+/*
+ * Note: we keep the TRACE_EVENT and DECLARE_TRACE outside the include
+ *  file ifdef protection.
+ *  This is due to the way trace events work. If a file includes two
+ *  trace event headers under one "CREATE_TRACE_POINTS" the first include
+ *  will override the TRACE_EVENT and break the second include.
+ */
+
 #ifndef DECLARE_TRACE
 
 #define TP_PROTO(args...)      args
@@ -49,7 +108,7 @@ struct tracepoint {
                void **it_func;                                         \
                                                                        \
                rcu_read_lock_sched_notrace();                          \
-               it_func = rcu_dereference((tp)->funcs);                 \
+               it_func = rcu_dereference_sched((tp)->funcs);           \
                if (it_func) {                                          \
                        do {                                            \
                                ((void(*)(proto))(*it_func))(args);     \
@@ -96,9 +155,6 @@ struct tracepoint {
 #define EXPORT_TRACEPOINT_SYMBOL(name)                                 \
        EXPORT_SYMBOL(__tracepoint_##name)
 
-extern void tracepoint_update_probe_range(struct tracepoint *begin,
-       struct tracepoint *end);
-
 #else /* !CONFIG_TRACEPOINTS */
 #define DECLARE_TRACE(name, proto, args)                               \
        static inline void _do_trace_##name(struct tracepoint *tp, proto) \
@@ -119,61 +175,9 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin,
 #define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
 #define EXPORT_TRACEPOINT_SYMBOL(name)
 
-static inline void tracepoint_update_probe_range(struct tracepoint *begin,
-       struct tracepoint *end)
-{ }
 #endif /* CONFIG_TRACEPOINTS */
 #endif /* DECLARE_TRACE */
 
-/*
- * Connect a probe to a tracepoint.
- * Internal API, should not be used directly.
- */
-extern int tracepoint_probe_register(const char *name, void *probe);
-
-/*
- * Disconnect a probe from a tracepoint.
- * Internal API, should not be used directly.
- */
-extern int tracepoint_probe_unregister(const char *name, void *probe);
-
-extern int tracepoint_probe_register_noupdate(const char *name, void *probe);
-extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe);
-extern void tracepoint_probe_update_all(void);
-
-struct tracepoint_iter {
-       struct module *module;
-       struct tracepoint *tracepoint;
-};
-
-extern void tracepoint_iter_start(struct tracepoint_iter *iter);
-extern void tracepoint_iter_next(struct tracepoint_iter *iter);
-extern void tracepoint_iter_stop(struct tracepoint_iter *iter);
-extern void tracepoint_iter_reset(struct tracepoint_iter *iter);
-extern int tracepoint_get_iter_range(struct tracepoint **tracepoint,
-       struct tracepoint *begin, struct tracepoint *end);
-
-/*
- * tracepoint_synchronize_unregister must be called between the last tracepoint
- * probe unregistration and the end of module exit to make sure there is no
- * caller executing a probe when it is freed.
- */
-static inline void tracepoint_synchronize_unregister(void)
-{
-       synchronize_sched();
-}
-
-#define PARAMS(args...) args
-
-#endif /* _LINUX_TRACEPOINT_H */
-
-/*
- * Note: we keep the TRACE_EVENT outside the include file ifdef protection.
- *  This is due to the way trace events work. If a file includes two
- *  trace event headers under one "CREATE_TRACE_POINTS" the first include
- *  will override the TRACE_EVENT and break the second include.
- */
-
 #ifndef TRACE_EVENT
 /*
  * For use with the TRACE_EVENT macro:
index 568369a86306e5e80b5db3974db85dce56360f80..4409967db0c45e8e0a5568b5596e4b42bffe659c 100644 (file)
@@ -70,12 +70,13 @@ struct tty_buffer {
 
 /*
  * We default to dicing tty buffer allocations to this many characters
- * in order to avoid multiple page allocations. We assume tty_buffer itself
- * is under 256 bytes. See tty_buffer_find for the allocation logic this
- * must match
+ * in order to avoid multiple page allocations. We know the size of
+ * tty_buffer itself but it must also be taken into account that the
+ * the buffer is 256 byte aligned. See tty_buffer_find for the allocation
+ * logic this must match
  */
 
-#define TTY_BUFFER_PAGE                ((PAGE_SIZE  - 256) / 2)
+#define TTY_BUFFER_PAGE        (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF)
 
 
 struct tty_bufhead {
@@ -223,6 +224,7 @@ struct tty_port {
        wait_queue_head_t       close_wait;     /* Close waiters */
        wait_queue_head_t       delta_msr_wait; /* Modem status change */
        unsigned long           flags;          /* TTY flags ASY_*/
+       unsigned char           console:1;      /* port is a console */
        struct mutex            mutex;          /* Locking */
        struct mutex            buf_mutex;      /* Buffer alloc lock */
        unsigned char           *xmit_buf;      /* Optional buffer */
index c42724f8c80210f6d50708ced60269c1dd3cc703..23d237a075e21ce2635f8ce2b5a15dfd2fcde9a7 100644 (file)
@@ -188,12 +188,12 @@ typedef u32 phys_addr_t;
 typedef phys_addr_t resource_size_t;
 
 typedef struct {
-       volatile int counter;
+       int counter;
 } atomic_t;
 
 #ifdef CONFIG_64BIT
 typedef struct {
-       volatile long counter;
+       long counter;
 } atomic64_t;
 #endif
 
index 8c9f053111bb8002d332749a36403cef7b7bb0a0..739f1fd1cc15187a40868ea0cb6c32e888fe8bea 100644 (file)
@@ -1055,7 +1055,8 @@ typedef void (*usb_complete_t)(struct urb *);
  * @number_of_packets: Lists the number of ISO transfer buffers.
  * @interval: Specifies the polling interval for interrupt or isochronous
  *     transfers.  The units are frames (milliseconds) for full and low
- *     speed devices, and microframes (1/8 millisecond) for highspeed ones.
+ *     speed devices, and microframes (1/8 millisecond) for highspeed
+ *     and SuperSpeed devices.
  * @error_count: Returns the number of ISO transfers that reported errors.
  * @context: For use in completion functions.  This normally points to
  *     request-specific driver context.
@@ -1084,7 +1085,7 @@ typedef void (*usb_complete_t)(struct urb *);
  * Alternatively, drivers may pass the URB_NO_xxx_DMA_MAP transfer flags,
  * which tell the host controller driver that no such mapping is needed since
  * the device driver is DMA-aware.  For example, a device driver might
- * allocate a DMA buffer with usb_buffer_alloc() or call usb_buffer_map().
+ * allocate a DMA buffer with usb_alloc_coherent() or call usb_buffer_map().
  * When these transfer flags are provided, host controller drivers will
  * attempt to use the dma addresses found in the transfer_dma and/or
  * setup_dma fields rather than determining a dma address themselves.
@@ -1286,9 +1287,16 @@ static inline void usb_fill_bulk_urb(struct urb *urb,
  *
  * Initializes a interrupt urb with the proper information needed to submit
  * it to a device.
- * Note that high speed interrupt endpoints use a logarithmic encoding of
- * the endpoint interval, and express polling intervals in microframes
- * (eight per millisecond) rather than in frames (one per millisecond).
+ *
+ * Note that High Speed and SuperSpeed interrupt endpoints use a logarithmic
+ * encoding of the endpoint interval, and express polling intervals in
+ * microframes (eight per millisecond) rather than in frames (one per
+ * millisecond).
+ *
+ * Wireless USB also uses the logarithmic encoding, but specifies it in units of
+ * 128us instead of 125us.  For Wireless USB devices, the interval is passed
+ * through to the host controller, rather than being translated into microframe
+ * units.
  */
 static inline void usb_fill_int_urb(struct urb *urb,
                                    struct usb_device *dev,
@@ -1305,7 +1313,7 @@ static inline void usb_fill_int_urb(struct urb *urb,
        urb->transfer_buffer_length = buffer_length;
        urb->complete = complete_fn;
        urb->context = context;
-       if (dev->speed == USB_SPEED_HIGH)
+       if (dev->speed == USB_SPEED_HIGH || dev->speed == USB_SPEED_SUPER)
                urb->interval = 1 << (interval - 1);
        else
                urb->interval = interval;
@@ -1358,11 +1366,23 @@ static inline int usb_urb_dir_out(struct urb *urb)
        return (urb->transfer_flags & URB_DIR_MASK) == URB_DIR_OUT;
 }
 
-void *usb_buffer_alloc(struct usb_device *dev, size_t size,
+void *usb_alloc_coherent(struct usb_device *dev, size_t size,
        gfp_t mem_flags, dma_addr_t *dma);
-void usb_buffer_free(struct usb_device *dev, size_t size,
+void usb_free_coherent(struct usb_device *dev, size_t size,
        void *addr, dma_addr_t dma);
 
+/* Compatible macros while we switch over */
+static inline void *usb_buffer_alloc(struct usb_device *dev, size_t size,
+                                    gfp_t mem_flags, dma_addr_t *dma)
+{
+       return usb_alloc_coherent(dev, size, mem_flags, dma);
+}
+static inline void usb_buffer_free(struct usb_device *dev, size_t size,
+                                  void *addr, dma_addr_t dma)
+{
+       return usb_free_coherent(dev, size, addr, dma);
+}
+
 #if 0
 struct urb *usb_buffer_map(struct urb *urb);
 void usb_buffer_dmasync(struct urb *urb);
index bbf45d500b6dd547535bd2c6523ac84a0438e110..f4b7ca516cdd76c4b72691a0cdc1d4feb2f70349 100644 (file)
@@ -15,6 +15,8 @@
 #ifndef __LINUX_USB_GADGET_H
 #define __LINUX_USB_GADGET_H
 
+#include <linux/slab.h>
+
 struct usb_ep;
 
 /**
index ae4f039515b441f3407d88da1e2172a78bab2e5b..92228a8fbcbc8f688afa343252fdeb381baf23fc 100644 (file)
 
 /* Feature bits */
 #define VIRTIO_CONSOLE_F_SIZE  0       /* Does host provide console size? */
-#define VIRTIO_CONSOLE_F_MULTIPORT 1   /* Does host provide multiple ports? */
 
 struct virtio_console_config {
        /* colums of the screens */
        __u16 cols;
        /* rows of the screens */
        __u16 rows;
-       /* max. number of ports this device can hold */
-       __u32 max_nr_ports;
-       /* number of ports added so far */
-       __u32 nr_ports;
 } __attribute__((packed));
 
-/*
- * A message that's passed between the Host and the Guest for a
- * particular port.
- */
-struct virtio_console_control {
-       __u32 id;               /* Port number */
-       __u16 event;            /* The kind of control event (see below) */
-       __u16 value;            /* Extra information for the key */
-};
-
-/* Some events for control messages */
-#define VIRTIO_CONSOLE_PORT_READY      0
-#define VIRTIO_CONSOLE_CONSOLE_PORT    1
-#define VIRTIO_CONSOLE_RESIZE          2
-#define VIRTIO_CONSOLE_PORT_OPEN       3
-#define VIRTIO_CONSOLE_PORT_NAME       4
-#define VIRTIO_CONSOLE_PORT_REMOVE     5
-
 #ifdef __KERNEL__
 int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int));
 #endif /* __KERNEL__ */
index 778b7b2a47d4afc36e81c8516124acbc850e2f07..d5dd0bc408fd4e7b1e79ea8326841a8a187f2738 100644 (file)
@@ -27,7 +27,7 @@ struct vt_mode {
 #define VT_SETMODE     0x5602  /* set mode of active vt */
 #define                VT_AUTO         0x00    /* auto vt switching */
 #define                VT_PROCESS      0x01    /* process controls switching */
-#define                VT_PROCESS_AUTO 0x02    /* process is notified of switching */
+#define                VT_ACKACQ       0x02    /* acknowledge switch */
 
 struct vt_stat {
        unsigned short v_active;        /* active vt */
@@ -38,7 +38,6 @@ struct vt_stat {
 #define VT_SENDSIG     0x5604  /* signal to send to bitmask of vts */
 
 #define VT_RELDISP     0x5605  /* release display */
-#define                VT_ACKACQ       0x02    /* acknowledge switch */
 
 #define VT_ACTIVATE    0x5606  /* make vt active */
 #define VT_WAITACTIVE  0x5607  /* wait for vt active */
index a48e16b77d5e2d94c1bb1bfb6b5efa56a82bd7af..76d96d035ea03920ac919a13e2b255e93cc77f35 100644 (file)
@@ -127,12 +127,26 @@ static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
 /*
  * Used for wake-one threads:
  */
+static inline void __add_wait_queue_exclusive(wait_queue_head_t *q,
+                                             wait_queue_t *wait)
+{
+       wait->flags |= WQ_FLAG_EXCLUSIVE;
+       __add_wait_queue(q, wait);
+}
+
 static inline void __add_wait_queue_tail(wait_queue_head_t *head,
-                                               wait_queue_t *new)
+                                        wait_queue_t *new)
 {
        list_add_tail(&new->task_list, &head->task_list);
 }
 
+static inline void __add_wait_queue_tail_exclusive(wait_queue_head_t *q,
+                                             wait_queue_t *wait)
+{
+       wait->flags |= WQ_FLAG_EXCLUSIVE;
+       __add_wait_queue_tail(q, wait);
+}
+
 static inline void __remove_wait_queue(wait_queue_head_t *head,
                                                        wait_queue_t *old)
 {
@@ -403,25 +417,6 @@ do {                                                                       \
        __ret;                                                          \
 })
 
-/*
- * Must be called with the spinlock in the wait_queue_head_t held.
- */
-static inline void add_wait_queue_exclusive_locked(wait_queue_head_t *q,
-                                                  wait_queue_t * wait)
-{
-       wait->flags |= WQ_FLAG_EXCLUSIVE;
-       __add_wait_queue_tail(q,  wait);
-}
-
-/*
- * Must be called with the spinlock in the wait_queue_head_t held.
- */
-static inline void remove_wait_queue_locked(wait_queue_head_t *q,
-                                           wait_queue_t * wait)
-{
-       __remove_wait_queue(q,  wait);
-}
-
 /*
  * These are the old interfaces to sleep waiting for an event.
  * They are racy.  DO NOT use them, use the wait_event* interfaces above.
index db8096e8853331ac7b615fa0f41cd99d7998b791..57031b4d12f2a51f352524ba765f43d41f261415 100644 (file)
 
 #include <linux/types.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 
 
 /* Backend stuff */
index 76e8903cd204d4b2a21a8577a00150532c3dc24f..36520ded3e062701866a5a4941e1cc0a85d19b37 100644 (file)
@@ -34,6 +34,9 @@ struct writeback_control {
        enum writeback_sync_modes sync_mode;
        unsigned long *older_than_this; /* If !NULL, only write back inodes
                                           older than this */
+       unsigned long wb_start;         /* Time writeback_inodes_wb was
+                                          called. This is needed to avoid
+                                          extra jobs and livelock */
        long nr_to_write;               /* Write this many pages, and decrement
                                           this for each page written */
        long pages_skipped;             /* Pages which were not written */
index 913bfc226dda8da65d29f2a1e08a01b5e79861c4..7bf9db525e9ee7e7092959c64059198a60bacc3d 100644 (file)
@@ -38,8 +38,6 @@
 typedef __u32 zorro_id;
 
 
-#define ZORRO_WILDCARD         (0xffffffff)    /* not official */
-
 /* Include the ID list */
 #include <linux/zorro_ids.h>
 
@@ -116,6 +114,7 @@ struct ConfigDev {
 
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/mod_devicetable.h>
 
 #include <asm/zorro.h>
 
@@ -142,28 +141,9 @@ struct zorro_dev {
      *  Zorro bus
      */
 
-struct zorro_bus {
-    struct list_head devices;          /* list of devices on this bus */
-    unsigned int num_resources;                /* number of resources */
-    struct resource resources[4];      /* address space routed to this bus */
-    struct device dev;
-    char name[10];
-};
-
-extern struct zorro_bus zorro_bus;     /* single Zorro bus */
 extern struct bus_type zorro_bus_type;
 
 
-    /*
-     *  Zorro device IDs
-     */
-
-struct zorro_device_id {
-       zorro_id id;                    /* Device ID or ZORRO_WILDCARD */
-       unsigned long driver_data;      /* Data private to the driver */
-};
-
-
     /*
      *  Zorro device drivers
      */
index b9da1f5591e780337b05631a245f9218e65606f0..4aeff96ff7d8105f7bfe5e97b69ec94e1db6d4e8 100644 (file)
@@ -188,7 +188,6 @@ void saa7146_buffer_timeout(unsigned long data);
 void saa7146_dma_free(struct saa7146_dev* dev,struct videobuf_queue *q,
                                                struct saa7146_buf *buf);
 
-int saa7146_vv_devinit(struct saa7146_dev *dev);
 int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv);
 int saa7146_vv_release(struct saa7146_dev* dev);
 
index f076dfa75ae8b28eec5aefc5233a12c55ed459de..4f3760afc20fb52d19a09f679f3e16313fed707d 100644 (file)
@@ -54,6 +54,7 @@ enum p9_proto_versions{
 
 enum p9_trans_status {
        Connected,
+       BeginDisconnect,
        Disconnected,
        Hung,
 };
@@ -198,6 +199,7 @@ int p9_client_version(struct p9_client *);
 struct p9_client *p9_client_create(const char *dev_name, char *options);
 void p9_client_destroy(struct p9_client *clnt);
 void p9_client_disconnect(struct p9_client *clnt);
+void p9_client_begin_disconnect(struct p9_client *clnt);
 struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
                                        char *uname, u32 n_uname, char *aname);
 struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname,
index 717e2192d521ee014ed415ad51d29d296576dba5..206d22297ac36345e5912472cd14ab9c3f51bc10 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/spinlock.h>
 #include <linux/timer.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <asm/atomic.h>
 
 #define        AX25_T1CLAMPLO                  1
index 04a6908e38d2883a136a60c92ddb1405e1d1ff60..ff77e8f882f13fdc8545662b3543685e661de0f4 100644 (file)
@@ -176,6 +176,6 @@ extern void hci_sock_cleanup(void);
 extern int bt_sysfs_init(void);
 extern void bt_sysfs_cleanup(void);
 
-extern struct class *bt_class;
+extern struct dentry *bt_debugfs;
 
 #endif /* __BLUETOOTH_H */
index c07ac9650ebc00219418dcca80abf828e30dbcd8..c49086d2bc7da380c9ef18873e88bc6a709ce9e6 100644 (file)
@@ -2,6 +2,7 @@
 #define __NET_FIB_RULES_H
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/fib_rules.h>
 #include <net/flow.h>
index a14121dd19320365a54f9bb62ee88af23b00b11e..ef51a668ba191b6c2d3d4a62df21a6b47482c363 100644 (file)
@@ -13,6 +13,7 @@
 #include <net/datalink.h>
 #include <linux/ipx.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 
 struct ipx_address {
        __be32  net;
index 5e310c8d8e2f96209913711863abff8e7389f358..205a3360156ed46d43a077e3cfabac1647ce236f 100644 (file)
@@ -28,6 +28,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <asm/debug.h>
 
 /*
index 2d2a1f9a61d868acb94b6e3bd92f47e074ccef8e..32d15bd6efa3c573030e899bb979d98dcc811ee9 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _NF_CONNTRACK_EXTEND_H
 #define _NF_CONNTRACK_EXTEND_H
 
+#include <linux/slab.h>
+
 #include <net/netfilter/nf_conntrack.h>
 
 enum nf_ct_ext_id {
index 60ebbc1fef46a157cdb4393f123b21b07a7e0dc5..9db401a8b4d982db3a97a214b73788d1111d88f7 100644 (file)
@@ -31,6 +31,7 @@
 #define _NETLABEL_H
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/net.h>
 #include <linux/skbuff.h>
 #include <linux/in.h>
index f82e463c875a51600ad0055c86c164d12e3e16ed..4fc05b58503eb4beab8fc20b3ab0b762f9f3d293 100644 (file)
@@ -945,7 +945,11 @@ static inline u64 nla_get_u64(const struct nlattr *nla)
  */
 static inline __be64 nla_get_be64(const struct nlattr *nla)
 {
-       return *(__be64 *) nla_data(nla);
+       __be64 tmp;
+
+       nla_memcpy(&tmp, nla, sizeof(tmp));
+
+       return tmp;
 }
 
 /**
index ab170a60e7d31a6a72b2f88fd7e3696007abb039..f0793c1cb5f8c2d89cd3f5dbb4fe31afbef4c026 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/netrom.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 
 #define        NR_NETWORK_LEN                  15
index 8be5135ff7aa4f9ba46bf2e491fc13350b676828..2c55a7ea20af016ebd6ca1982a0fe5e171b71f83 100644 (file)
@@ -107,6 +107,7 @@ typedef enum {
        SCTP_CMD_T1_RETRAN,      /* Mark for retransmission after T1 timeout  */
        SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */
        SCTP_CMD_SEND_MSG,       /* Send the whole use message */
+       SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */
        SCTP_CMD_LAST
 } sctp_verb_t;
 
index 78740ec57d5db39e7c55b3248c9569e5170e6a17..fa6cde578a1d122a43a0f63e07969a36cf3e27ff 100644 (file)
@@ -128,6 +128,7 @@ extern int sctp_register_pf(struct sctp_pf *, sa_family_t);
 int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb);
 int sctp_inet_listen(struct socket *sock, int backlog);
 void sctp_write_space(struct sock *sk);
+void sctp_data_ready(struct sock *sk, int len);
 unsigned int sctp_poll(struct file *file, struct socket *sock,
                poll_table *wait);
 void sctp_sock_rfree(struct sk_buff *skb);
index 851c813adb3ac2a144cbb0b98582331629a5c385..61d73e37d5436138d743372a48aecad3191526fe 100644 (file)
@@ -279,6 +279,7 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
 /* 2nd level prototypes */
 void sctp_generate_t3_rtx_event(unsigned long peer);
 void sctp_generate_heartbeat_event(unsigned long peer);
+void sctp_generate_proto_unreach_event(unsigned long peer);
 
 void sctp_ootb_pkt_free(struct sctp_packet *);
 
index ff301774471104581f49bbfdebc3d6846f7ae080..219043a67bf7ab6073eba985e80ebb8ca206f2c1 100644 (file)
@@ -778,6 +778,7 @@ int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len,
                          struct iovec *data);
 void sctp_chunk_free(struct sctp_chunk *);
 void  *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data);
+void  *sctp_addto_chunk_fixed(struct sctp_chunk *, int len, const void *data);
 struct sctp_chunk *sctp_chunkify(struct sk_buff *,
                                 const struct sctp_association *,
                                 struct sock *);
@@ -1009,6 +1010,9 @@ struct sctp_transport {
        /* Heartbeat timer is per destination. */
        struct timer_list hb_timer;
 
+       /* Timer to handle ICMP proto unreachable envets */
+       struct timer_list proto_unreach_timer;
+
        /* Since we're using per-destination retransmission timers
         * (see above), we're also using per-destination "transmitted"
         * queues.  This probably ought to be a private struct
index 092b0551e77f28a08387d687592366ee4467a678..1ad6435f252eda64b17e6b4568c58f42a0eed6d0 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/skbuff.h>      /* struct sk_buff */
 #include <linux/mm.h>
 #include <linux/security.h>
+#include <linux/slab.h>
 
 #include <linux/filter.h>
 #include <linux/rculist_nulls.h>
@@ -73,7 +74,7 @@
                                        printk(KERN_DEBUG msg); } while (0)
 #else
 /* Validate arguments and do nothing */
-static void inline int __attribute__ ((format (printf, 2, 3)))
+static inline void __attribute__ ((format (printf, 2, 3)))
 SOCK_DEBUG(struct sock *sk, const char *msg, ...)
 {
 }
index 75be5a28815d5d2759976a003a2f9f8f0ac9a1c9..aa04b9a5093b2ceed25c672cf5abaefa9b75b7fb 100644 (file)
@@ -1197,30 +1197,15 @@ extern int                      tcp_v4_md5_do_del(struct sock *sk,
 extern struct tcp_md5sig_pool * __percpu *tcp_alloc_md5sig_pool(struct sock *);
 extern void                    tcp_free_md5sig_pool(void);
 
-extern struct tcp_md5sig_pool  *__tcp_get_md5sig_pool(int cpu);
-extern void                    __tcp_put_md5sig_pool(void);
+extern struct tcp_md5sig_pool  *tcp_get_md5sig_pool(void);
+extern void                    tcp_put_md5sig_pool(void);
+
 extern int tcp_md5_hash_header(struct tcp_md5sig_pool *, struct tcphdr *);
 extern int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *, struct sk_buff *,
                                 unsigned header_len);
 extern int tcp_md5_hash_key(struct tcp_md5sig_pool *hp,
                            struct tcp_md5sig_key *key);
 
-static inline
-struct tcp_md5sig_pool         *tcp_get_md5sig_pool(void)
-{
-       int cpu = get_cpu();
-       struct tcp_md5sig_pool *ret = __tcp_get_md5sig_pool(cpu);
-       if (!ret)
-               put_cpu();
-       return ret;
-}
-
-static inline void             tcp_put_md5sig_pool(void)
-{
-       __tcp_put_md5sig_pool();
-       put_cpu();
-}
-
 /* write queue abstraction */
 static inline void tcp_write_queue_purge(struct sock *sk)
 {
index 9baa07dc7d17e31546407e91e2875a8960861cd8..468551ea4f1d4248a10a5b7e19c43647c4f013d9 100644 (file)
@@ -10,6 +10,7 @@
 #ifndef _X25_H
 #define _X25_H 
 #include <linux/x25.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 
 #define        X25_ADDR_LEN                    16
@@ -182,6 +183,10 @@ extern int  sysctl_x25_clear_request_timeout;
 extern int  sysctl_x25_ack_holdback_timeout;
 extern int  sysctl_x25_forward;
 
+extern int x25_parse_address_block(struct sk_buff *skb,
+               struct x25_address *called_addr,
+               struct x25_address *calling_addr);
+
 extern int  x25_addr_ntoa(unsigned char *, struct x25_address *,
                          struct x25_address *);
 extern int  x25_addr_aton(unsigned char *, struct x25_address *,
index d74e080ba6c9c0a0ff14be2019eed6aeef659c68..ac52f33f3e4af06113dc060fd4a8282e6f837c94 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/in6.h>
 #include <linux/mutex.h>
 #include <linux/audit.h>
+#include <linux/slab.h>
 
 #include <net/sock.h>
 #include <net/dst.h>
index d57847f2f6c115549d477cf745547550ba1b1bf5..aab3c13dc310759f8038b64c9f60608386a0facd 100644 (file)
@@ -26,6 +26,7 @@
 #ifdef __KERNEL__
 #include <linux/device.h>
 #include <pcmcia/ss.h>
+#include <asm/atomic.h>
 
 /*
  * PCMCIA device drivers (16-bit cards only; 32-bit cards require CardBus
@@ -94,10 +95,8 @@ struct pcmcia_device {
        config_req_t            conf;
        window_handle_t         win;
 
-       /* Is the device suspended, or in the process of
-        * being removed? */
+       /* Is the device suspended? */
        u16                     suspended:1;
-       u16                     _removed:1;
 
        /* Flags whether io, irq, win configurations were
         * requested, and whether the configuration is "locked" */
@@ -115,7 +114,7 @@ struct pcmcia_device {
        u16                     has_card_id:1;
        u16                     has_func_id:1;
 
-       u16                     reserved:3;
+       u16                     reserved:4;
 
        u8                      func_id;
        u16                     manf_id;
index 32896a77391054babaeb60482ad121a4864329af..344705cb42f419478fccefeb8cf5479a8d4d8a9b 100644 (file)
@@ -224,18 +224,16 @@ struct pcmcia_socket {
 
        /* 16-bit state: */
        struct {
-               /* PCMCIA card is present in socket */
-               u8                      present:1;
                /* "master" ioctl is used */
                u8                      busy:1;
-               /* pcmcia module is being unloaded */
-               u8                      dead:1;
                /* the PCMCIA card consists of two pseudo devices */
                u8                      has_pfc:1;
 
-               u8                      reserved:4;
+               u8                      reserved:6;
        } pcmcia_state;
 
+       /* non-zero if PCMCIA card is present */
+       atomic_t                        present;
 
 #ifdef CONFIG_PCMCIA_IOCTL
        struct user_info_t              *user;
@@ -277,12 +275,6 @@ extern struct pccard_resource_ops pccard_nonstatic_ops;
 #endif
 
 
-/* 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 */
 extern void pcmcia_parse_events(struct pcmcia_socket *socket,
                                unsigned int events);
index ff92b46f5153455501d4446648bfeafe712cde10..ae5196aae1a5311421e72ba22d9b9f43cb748500 100644 (file)
@@ -338,7 +338,8 @@ struct iscsi_host {
 extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth,
                                    int reason);
 extern int iscsi_eh_abort(struct scsi_cmnd *sc);
-extern int iscsi_eh_target_reset(struct scsi_cmnd *sc);
+extern int iscsi_eh_recover_target(struct scsi_cmnd *sc);
+extern int iscsi_eh_session_reset(struct scsi_cmnd *sc);
 extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
 extern int iscsi_queuecommand(struct scsi_cmnd *sc,
                              void (*done)(struct scsi_cmnd *));
index 9eaa3f05f9544621463c1c172d71c16f40ed42fb..3b586859669cf4a161166263c4eac2a8e2519400 100644 (file)
@@ -36,6 +36,7 @@
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_transport_sas.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 
 struct block_device;
 
index 8988edae160978f09747e29010fce79be703d56b..2609048c1d442581a2530f79cc2135aa679f8cb1 100644 (file)
@@ -307,7 +307,7 @@ struct ak4113 {
 
 int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
                ak4113_write_t *write,
-               const unsigned char pgm[AK4113_WRITABLE_REGS],
+               const unsigned char *pgm,
                void *private_data, struct ak4113 **r_ak4113);
 void snd_ak4113_reg_write(struct ak4113 *ak4113, unsigned char reg,
                unsigned char mask, unsigned char val);
index 061f16d4c8780b18f15cafaefb760a5e0780af59..0a0b019d41adebf2c10d8505a6d76dbed37a546c 100644 (file)
@@ -219,7 +219,6 @@ struct snd_soc_dai {
        struct snd_soc_codec *codec;
        unsigned int active;
        unsigned char pop_wait:1;
-       void *dma_data;
 
        /* DAI private data */
        void *private_data;
@@ -230,4 +229,21 @@ struct snd_soc_dai {
        struct list_head list;
 };
 
+static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai,
+                                            const struct snd_pcm_substream *ss)
+{
+       return (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+               dai->playback.dma_data : dai->capture.dma_data;
+}
+
+static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai,
+                                           const struct snd_pcm_substream *ss,
+                                           void *data)
+{
+       if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               dai->playback.dma_data = data;
+       else
+               dai->capture.dma_data = data;
+}
+
 #endif
index 5d234a8c2506c74df25d5fbc7f9220c0bdb106ad..a57fbfcd4c8f26877626f34caf122de3216f1da6 100644 (file)
@@ -375,6 +375,7 @@ struct snd_soc_pcm_stream {
        unsigned int channels_min;      /* min channels */
        unsigned int channels_max;      /* max channels */
        unsigned int active:1;          /* stream is in use */
+       void *dma_data;                 /* used by platform code */
 };
 
 /* SoC audio ops */
index 5acfb1eb4df91cd096da3ee728bd636955247b0f..1dfab54015113b83bce9f3302470c3a5ed95b5e7 100644 (file)
 
 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
 
+/* Make all open coded DECLARE_TRACE nops */
+#undef DECLARE_TRACE
+#define DECLARE_TRACE(name, proto, args)
+
 #ifdef CONFIG_EVENT_TRACING
 #include <trace/ftrace.h>
 #endif
@@ -75,6 +79,7 @@
 #undef DEFINE_EVENT
 #undef DEFINE_EVENT_PRINT
 #undef TRACE_HEADER_MULTI_READ
+#undef DECLARE_TRACE
 
 /* Only undef what we defined in this file */
 #ifdef UNDEF_TRACE_INCLUDE_FILE
index 5fb72733331e4e8a16d0144ad97097b174de80a8..d870a918559cde9ef478f3d8935c6361309fc6bb 100644 (file)
@@ -40,6 +40,16 @@ DECLARE_EVENT_CLASS(block_rq_with_error,
                  __entry->nr_sector, __entry->errors)
 );
 
+/**
+ * block_rq_abort - abort block operation request
+ * @q: queue containing the block operation request
+ * @rq: block IO operation request
+ *
+ * Called immediately after pending block IO operation request @rq in
+ * queue @q is aborted. The fields in the operation request @rq
+ * can be examined to determine which device and sectors the pending
+ * operation would access.
+ */
 DEFINE_EVENT(block_rq_with_error, block_rq_abort,
 
        TP_PROTO(struct request_queue *q, struct request *rq),
@@ -47,6 +57,15 @@ DEFINE_EVENT(block_rq_with_error, block_rq_abort,
        TP_ARGS(q, rq)
 );
 
+/**
+ * block_rq_requeue - place block IO request back on a queue
+ * @q: queue holding operation
+ * @rq: block IO operation request
+ *
+ * The block operation request @rq is being placed back into queue
+ * @q.  For some reason the request was not completed and needs to be
+ * put back in the queue.
+ */
 DEFINE_EVENT(block_rq_with_error, block_rq_requeue,
 
        TP_PROTO(struct request_queue *q, struct request *rq),
@@ -54,6 +73,17 @@ DEFINE_EVENT(block_rq_with_error, block_rq_requeue,
        TP_ARGS(q, rq)
 );
 
+/**
+ * block_rq_complete - block IO operation completed by device driver
+ * @q: queue containing the block operation request
+ * @rq: block operations request
+ *
+ * The block_rq_complete tracepoint event indicates that some portion
+ * of operation request has been completed by the device driver.  If
+ * the @rq->bio is %NULL, then there is absolutely no additional work to
+ * do for the request. If @rq->bio is non-NULL then there is
+ * additional work required to complete the request.
+ */
 DEFINE_EVENT(block_rq_with_error, block_rq_complete,
 
        TP_PROTO(struct request_queue *q, struct request *rq),
@@ -95,6 +125,16 @@ DECLARE_EVENT_CLASS(block_rq,
                  __entry->nr_sector, __entry->comm)
 );
 
+/**
+ * block_rq_insert - insert block operation request into queue
+ * @q: target queue
+ * @rq: block IO operation request
+ *
+ * Called immediately before block operation request @rq is inserted
+ * into queue @q.  The fields in the operation request @rq struct can
+ * be examined to determine which device and sectors the pending
+ * operation would access.
+ */
 DEFINE_EVENT(block_rq, block_rq_insert,
 
        TP_PROTO(struct request_queue *q, struct request *rq),
@@ -102,6 +142,14 @@ DEFINE_EVENT(block_rq, block_rq_insert,
        TP_ARGS(q, rq)
 );
 
+/**
+ * block_rq_issue - issue pending block IO request operation to device driver
+ * @q: queue holding operation
+ * @rq: block IO operation operation request
+ *
+ * Called when block operation request @rq from queue @q is sent to a
+ * device driver for processing.
+ */
 DEFINE_EVENT(block_rq, block_rq_issue,
 
        TP_PROTO(struct request_queue *q, struct request *rq),
@@ -109,6 +157,17 @@ DEFINE_EVENT(block_rq, block_rq_issue,
        TP_ARGS(q, rq)
 );
 
+/**
+ * block_bio_bounce - used bounce buffer when processing block operation
+ * @q: queue holding the block operation
+ * @bio: block operation
+ *
+ * A bounce buffer was used to handle the block operation @bio in @q.
+ * This occurs when hardware limitations prevent a direct transfer of
+ * data between the @bio data memory area and the IO device.  Use of a
+ * bounce buffer requires extra copying of data and decreases
+ * performance.
+ */
 TRACE_EVENT(block_bio_bounce,
 
        TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -138,6 +197,14 @@ TRACE_EVENT(block_bio_bounce,
                  __entry->nr_sector, __entry->comm)
 );
 
+/**
+ * block_bio_complete - completed all work on the block operation
+ * @q: queue holding the block operation
+ * @bio: block operation completed
+ *
+ * This tracepoint indicates there is no further work to do on this
+ * block IO operation @bio.
+ */
 TRACE_EVENT(block_bio_complete,
 
        TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -193,6 +260,14 @@ DECLARE_EVENT_CLASS(block_bio,
                  __entry->nr_sector, __entry->comm)
 );
 
+/**
+ * block_bio_backmerge - merging block operation to the end of an existing operation
+ * @q: queue holding operation
+ * @bio: new block operation to merge
+ *
+ * Merging block request @bio to the end of an existing block request
+ * in queue @q.
+ */
 DEFINE_EVENT(block_bio, block_bio_backmerge,
 
        TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -200,6 +275,14 @@ DEFINE_EVENT(block_bio, block_bio_backmerge,
        TP_ARGS(q, bio)
 );
 
+/**
+ * block_bio_frontmerge - merging block operation to the beginning of an existing operation
+ * @q: queue holding operation
+ * @bio: new block operation to merge
+ *
+ * Merging block IO operation @bio to the beginning of an existing block
+ * operation in queue @q.
+ */
 DEFINE_EVENT(block_bio, block_bio_frontmerge,
 
        TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -207,6 +290,13 @@ DEFINE_EVENT(block_bio, block_bio_frontmerge,
        TP_ARGS(q, bio)
 );
 
+/**
+ * block_bio_queue - putting new block IO operation in queue
+ * @q: queue holding operation
+ * @bio: new block operation
+ *
+ * About to place the block IO operation @bio into queue @q.
+ */
 DEFINE_EVENT(block_bio, block_bio_queue,
 
        TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -243,6 +333,15 @@ DECLARE_EVENT_CLASS(block_get_rq,
                  __entry->nr_sector, __entry->comm)
 );
 
+/**
+ * block_getrq - get a free request entry in queue for block IO operations
+ * @q: queue for operations
+ * @bio: pending block IO operation
+ * @rw: low bit indicates a read (%0) or a write (%1)
+ *
+ * A request struct for queue @q has been allocated to handle the
+ * block IO operation @bio.
+ */
 DEFINE_EVENT(block_get_rq, block_getrq,
 
        TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
@@ -250,6 +349,17 @@ DEFINE_EVENT(block_get_rq, block_getrq,
        TP_ARGS(q, bio, rw)
 );
 
+/**
+ * block_sleeprq - waiting to get a free request entry in queue for block IO operation
+ * @q: queue for operation
+ * @bio: pending block IO operation
+ * @rw: low bit indicates a read (%0) or a write (%1)
+ *
+ * In the case where a request struct cannot be provided for queue @q
+ * the process needs to wait for an request struct to become
+ * available.  This tracepoint event is generated each time the
+ * process goes to sleep waiting for request struct become available.
+ */
 DEFINE_EVENT(block_get_rq, block_sleeprq,
 
        TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
@@ -257,6 +367,14 @@ DEFINE_EVENT(block_get_rq, block_sleeprq,
        TP_ARGS(q, bio, rw)
 );
 
+/**
+ * block_plug - keep operations requests in request queue
+ * @q: request queue to plug
+ *
+ * Plug the request queue @q.  Do not allow block operation requests
+ * to be sent to the device driver. Instead, accumulate requests in
+ * the queue to improve throughput performance of the block device.
+ */
 TRACE_EVENT(block_plug,
 
        TP_PROTO(struct request_queue *q),
@@ -293,6 +411,13 @@ DECLARE_EVENT_CLASS(block_unplug,
        TP_printk("[%s] %d", __entry->comm, __entry->nr_rq)
 );
 
+/**
+ * block_unplug_timer - timed release of operations requests in queue to device driver
+ * @q: request queue to unplug
+ *
+ * Unplug the request queue @q because a timer expired and allow block
+ * operation requests to be sent to the device driver.
+ */
 DEFINE_EVENT(block_unplug, block_unplug_timer,
 
        TP_PROTO(struct request_queue *q),
@@ -300,6 +425,13 @@ DEFINE_EVENT(block_unplug, block_unplug_timer,
        TP_ARGS(q)
 );
 
+/**
+ * block_unplug_io - release of operations requests in request queue
+ * @q: request queue to unplug
+ *
+ * Unplug request queue @q because device driver is scheduled to work
+ * on elements in the request queue.
+ */
 DEFINE_EVENT(block_unplug, block_unplug_io,
 
        TP_PROTO(struct request_queue *q),
@@ -307,6 +439,17 @@ DEFINE_EVENT(block_unplug, block_unplug_io,
        TP_ARGS(q)
 );
 
+/**
+ * block_split - split a single bio struct into two bio structs
+ * @q: queue containing the bio
+ * @bio: block operation being split
+ * @new_sector: The starting sector for the new bio
+ *
+ * The bio request @bio in request queue @q needs to be split into two
+ * bio requests. The newly created @bio request starts at
+ * @new_sector. This split may be required due to hardware limitation
+ * such as operation crossing device boundaries in a RAID system.
+ */
 TRACE_EVENT(block_split,
 
        TP_PROTO(struct request_queue *q, struct bio *bio,
@@ -337,6 +480,16 @@ TRACE_EVENT(block_split,
                  __entry->comm)
 );
 
+/**
+ * block_remap - map request for a partition to the raw device
+ * @q: queue holding the operation
+ * @bio: revised operation
+ * @dev: device for the operation
+ * @from: original sector for the operation
+ *
+ * An operation for a partition on a block device has been mapped to the
+ * raw block device.
+ */
 TRACE_EVENT(block_remap,
 
        TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev,
@@ -370,6 +523,17 @@ TRACE_EVENT(block_remap,
                  (unsigned long long)__entry->old_sector)
 );
 
+/**
+ * block_rq_remap - map request for a block operation request
+ * @q: queue holding the operation
+ * @rq: block IO operation request
+ * @dev: device for the operation
+ * @from: original sector for the operation
+ *
+ * The block operation request @rq in @q has been remapped.  The block
+ * operation request @rq holds the current information and @from hold
+ * the original sector.
+ */
 TRACE_EVENT(block_rq_remap,
 
        TP_PROTO(struct request_queue *q, struct request *rq, dev_t dev,
index 5c1dcfc16c6037019d8bcecf4e7c2fa4f3649505..2821b86de63b9674d6ed3a68c7496f022b3cdff6 100644 (file)
@@ -35,15 +35,15 @@ TRACE_EVENT(lock_acquire,
                  __get_str(name))
 );
 
-TRACE_EVENT(lock_release,
+DECLARE_EVENT_CLASS(lock,
 
-       TP_PROTO(struct lockdep_map *lock, int nested, unsigned long ip),
+       TP_PROTO(struct lockdep_map *lock, unsigned long ip),
 
-       TP_ARGS(lock, nested, ip),
+       TP_ARGS(lock, ip),
 
        TP_STRUCT__entry(
-               __string(name, lock->name)
-               __field(void *, lockdep_addr)
+               __string(       name,   lock->name      )
+               __field(        void *, lockdep_addr    )
        ),
 
        TP_fast_assign(
@@ -51,51 +51,30 @@ TRACE_EVENT(lock_release,
                __entry->lockdep_addr = lock;
        ),
 
-       TP_printk("%p %s",
-                 __entry->lockdep_addr, __get_str(name))
+       TP_printk("%p %s",  __entry->lockdep_addr, __get_str(name))
 );
 
-#ifdef CONFIG_LOCK_STAT
-
-TRACE_EVENT(lock_contended,
+DEFINE_EVENT(lock, lock_release,
 
        TP_PROTO(struct lockdep_map *lock, unsigned long ip),
 
-       TP_ARGS(lock, ip),
+       TP_ARGS(lock, ip)
+);
 
-       TP_STRUCT__entry(
-               __string(name, lock->name)
-               __field(void *, lockdep_addr)
-       ),
+#ifdef CONFIG_LOCK_STAT
 
-       TP_fast_assign(
-               __assign_str(name, lock->name);
-               __entry->lockdep_addr = lock;
-       ),
+DEFINE_EVENT(lock, lock_contended,
 
-       TP_printk("%p %s",
-                 __entry->lockdep_addr, __get_str(name))
-);
+       TP_PROTO(struct lockdep_map *lock, unsigned long ip),
 
-TRACE_EVENT(lock_acquired,
-       TP_PROTO(struct lockdep_map *lock, unsigned long ip, s64 waittime),
+       TP_ARGS(lock, ip)
+);
 
-       TP_ARGS(lock, ip, waittime),
+DEFINE_EVENT(lock, lock_acquired,
 
-       TP_STRUCT__entry(
-               __string(name, lock->name)
-               __field(s64, wait_nsec)
-               __field(void *, lockdep_addr)
-       ),
+       TP_PROTO(struct lockdep_map *lock, unsigned long ip),
 
-       TP_fast_assign(
-               __assign_str(name, lock->name);
-               __entry->wait_nsec = waittime;
-               __entry->lockdep_addr = lock;
-       ),
-       TP_printk("%p %s (%llu ns)", __entry->lockdep_addr,
-                 __get_str(name),
-                 __entry->wait_nsec)
+       TP_ARGS(lock, ip)
 );
 
 #endif
index 4b0f48ba16a688da9ead5b901604419c7823ea3b..c7bb2f0482fec377b1f67edd661d6331441fe7c3 100644 (file)
@@ -51,11 +51,14 @@ TRACE_EVENT(module_free,
        TP_printk("%s", __get_str(name))
 );
 
+#ifdef CONFIG_MODULE_UNLOAD
+/* trace_module_get/put are only used if CONFIG_MODULE_UNLOAD is defined */
+
 DECLARE_EVENT_CLASS(module_refcnt,
 
-       TP_PROTO(struct module *mod, unsigned long ip, int refcnt),
+       TP_PROTO(struct module *mod, unsigned long ip),
 
-       TP_ARGS(mod, ip, refcnt),
+       TP_ARGS(mod, ip),
 
        TP_STRUCT__entry(
                __field(        unsigned long,  ip              )
@@ -65,7 +68,7 @@ DECLARE_EVENT_CLASS(module_refcnt,
 
        TP_fast_assign(
                __entry->ip     = ip;
-               __entry->refcnt = refcnt;
+               __entry->refcnt = __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs);
                __assign_str(name, mod->name);
        ),
 
@@ -75,17 +78,18 @@ DECLARE_EVENT_CLASS(module_refcnt,
 
 DEFINE_EVENT(module_refcnt, module_get,
 
-       TP_PROTO(struct module *mod, unsigned long ip, int refcnt),
+       TP_PROTO(struct module *mod, unsigned long ip),
 
-       TP_ARGS(mod, ip, refcnt)
+       TP_ARGS(mod, ip)
 );
 
 DEFINE_EVENT(module_refcnt, module_put,
 
-       TP_PROTO(struct module *mod, unsigned long ip, int refcnt),
+       TP_PROTO(struct module *mod, unsigned long ip),
 
-       TP_ARGS(mod, ip, refcnt)
+       TP_ARGS(mod, ip)
 );
+#endif /* CONFIG_MODULE_UNLOAD */
 
 TRACE_EVENT(module_request,
 
index a8989c4547e7e7b790140957dcaaa3c7917952cd..188deca2f3c7721a1baac60cc07e8d7006442c71 100644 (file)
@@ -1,4 +1,7 @@
-#ifndef _TRACE_NAPI_H_
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM napi
+
+#if !defined(_TRACE_NAPI_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_NAPI_H_
 
 #include <linux/netdevice.h>
@@ -8,4 +11,7 @@ DECLARE_TRACE(napi_poll,
        TP_PROTO(struct napi_struct *napi),
        TP_ARGS(napi));
 
-#endif
+#endif /* _TRACE_NAPI_H_ */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
index cfceb0b73e205bb936a6e3fcfeb34f5515ab0feb..4f733ecea46e8cd464d05c92d5610f57c10a59fc 100644 (file)
@@ -51,15 +51,12 @@ TRACE_EVENT(sched_kthread_stop_ret,
 
 /*
  * Tracepoint for waiting on task to unschedule:
- *
- * (NOTE: the 'rq' argument is not used by generic trace events,
- *        but used by the latency tracer plugin. )
  */
 TRACE_EVENT(sched_wait_task,
 
-       TP_PROTO(struct rq *rq, struct task_struct *p),
+       TP_PROTO(struct task_struct *p),
 
-       TP_ARGS(rq, p),
+       TP_ARGS(p),
 
        TP_STRUCT__entry(
                __array(        char,   comm,   TASK_COMM_LEN   )
@@ -79,15 +76,12 @@ TRACE_EVENT(sched_wait_task,
 
 /*
  * Tracepoint for waking up a task:
- *
- * (NOTE: the 'rq' argument is not used by generic trace events,
- *        but used by the latency tracer plugin. )
  */
 DECLARE_EVENT_CLASS(sched_wakeup_template,
 
-       TP_PROTO(struct rq *rq, struct task_struct *p, int success),
+       TP_PROTO(struct task_struct *p, int success),
 
-       TP_ARGS(rq, p, success),
+       TP_ARGS(p, success),
 
        TP_STRUCT__entry(
                __array(        char,   comm,   TASK_COMM_LEN   )
@@ -111,31 +105,25 @@ DECLARE_EVENT_CLASS(sched_wakeup_template,
 );
 
 DEFINE_EVENT(sched_wakeup_template, sched_wakeup,
-            TP_PROTO(struct rq *rq, struct task_struct *p, int success),
-            TP_ARGS(rq, p, success));
+            TP_PROTO(struct task_struct *p, int success),
+            TP_ARGS(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. )
  */
 DEFINE_EVENT(sched_wakeup_template, sched_wakeup_new,
-            TP_PROTO(struct rq *rq, struct task_struct *p, int success),
-            TP_ARGS(rq, p, success));
+            TP_PROTO(struct task_struct *p, int success),
+            TP_ARGS(p, success));
 
 /*
  * Tracepoint for task switches, performed by the scheduler:
- *
- * (NOTE: the 'rq' argument is not used by generic trace events,
- *        but used by the latency tracer plugin. )
  */
 TRACE_EVENT(sched_switch,
 
-       TP_PROTO(struct rq *rq, struct task_struct *prev,
+       TP_PROTO(struct task_struct *prev,
                 struct task_struct *next),
 
-       TP_ARGS(rq, prev, next),
+       TP_ARGS(prev, next),
 
        TP_STRUCT__entry(
                __array(        char,   prev_comm,      TASK_COMM_LEN   )
index a510b75ac304505dbd8771b2b0ffcd101c397c90..814566c99d29eaf53b0410375c5306c1f6997c58 100644 (file)
@@ -100,18 +100,7 @@ TRACE_EVENT(signal_deliver,
                  __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,
+DECLARE_EVENT_CLASS(signal_queue_overflow,
 
        TP_PROTO(int sig, int group, struct siginfo *info),
 
@@ -134,6 +123,24 @@ TRACE_EVENT(signal_overflow_fail,
                  __entry->sig, __entry->group, __entry->errno, __entry->code)
 );
 
+/**
+ * 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.
+ */
+DEFINE_EVENT(signal_queue_overflow, signal_overflow_fail,
+
+       TP_PROTO(int sig, int group, struct siginfo *info),
+
+       TP_ARGS(sig, group, info)
+);
+
 /**
  * signal_lose_info - called when siginfo is lost
  * @sig: signal number
@@ -145,28 +152,13 @@ TRACE_EVENT(signal_overflow_fail,
  * '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,
+DEFINE_EVENT(signal_queue_overflow, 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)
+       TP_ARGS(sig, group, info)
 );
+
 #endif /* _TRACE_SIGNAL_H */
 
 /* This part must be outside protection */
index 601ad7744247582feeec95555464ce4b8a2bdc0d..16253db38d73274e329a20519023b342db7e7bd1 100644 (file)
  *
  *     field = (typeof(field))entry;
  *
- *     p = get_cpu_var(ftrace_event_seq);
+ *     p = &get_cpu_var(ftrace_event_seq);
  *     trace_seq_init(p);
- *     ret = trace_seq_printf(s, <TP_printk> "\n");
+ *     ret = trace_seq_printf(s, "%s: ", <call>);
+ *     if (ret)
+ *             ret = trace_seq_printf(s, <TP_printk> "\n");
  *     put_cpu();
  *     if (!ret)
  *             return TRACE_TYPE_PARTIAL_LINE;
@@ -401,18 +403,18 @@ static inline notrace int ftrace_get_offsets_##call(                      \
 #undef DEFINE_EVENT
 #define DEFINE_EVENT(template, name, proto, args)                      \
                                                                        \
-static void ftrace_profile_##name(proto);                              \
+static void perf_trace_##name(proto);                                  \
                                                                        \
 static notrace int                                                     \
-ftrace_profile_enable_##name(struct ftrace_event_call *unused)         \
+perf_trace_enable_##name(struct ftrace_event_call *unused)             \
 {                                                                      \
-       return register_trace_##name(ftrace_profile_##name);            \
+       return register_trace_##name(perf_trace_##name);                \
 }                                                                      \
                                                                        \
 static notrace void                                                    \
-ftrace_profile_disable_##name(struct ftrace_event_call *unused)                \
+perf_trace_disable_##name(struct ftrace_event_call *unused)            \
 {                                                                      \
-       unregister_trace_##name(ftrace_profile_##name);                 \
+       unregister_trace_##name(perf_trace_##name);                     \
 }
 
 #undef DEFINE_EVENT_PRINT
@@ -450,38 +452,38 @@ ftrace_profile_disable_##name(struct ftrace_event_call *unused)           \
  *
  * static void ftrace_raw_event_<call>(proto)
  * {
+ *     struct ftrace_data_offsets_<call> __maybe_unused __data_offsets;
  *     struct ring_buffer_event *event;
  *     struct ftrace_raw_<call> *entry; <-- defined in stage 1
  *     struct ring_buffer *buffer;
  *     unsigned long irq_flags;
+ *     int __data_size;
  *     int pc;
  *
  *     local_save_flags(irq_flags);
  *     pc = preempt_count();
  *
+ *     __data_size = ftrace_get_offsets_<call>(&__data_offsets, args);
+ *
  *     event = trace_current_buffer_lock_reserve(&buffer,
  *                               event_<call>.id,
- *                               sizeof(struct ftrace_raw_<call>),
+ *                               sizeof(*entry) + __data_size,
  *                               irq_flags, pc);
  *     if (!event)
  *             return;
  *     entry   = ring_buffer_event_data(event);
  *
- *     <assign>;  <-- Here we assign the entries by the __field and
- *                     __array macros.
+ *     { <assign>; }  <-- Here we assign the entries by the __field and
+ *                        __array macros.
  *
- *     trace_current_buffer_unlock_commit(buffer, event, irq_flags, pc);
+ *     if (!filter_current_check_discard(buffer, event_call, entry, event))
+ *             trace_current_buffer_unlock_commit(buffer,
+ *                                                event, irq_flags, pc);
  * }
  *
  * static int ftrace_raw_reg_event_<call>(struct ftrace_event_call *unused)
  * {
- *     int ret;
- *
- *     ret = register_trace_<call>(ftrace_raw_event_<call>);
- *     if (!ret)
- *             pr_info("event trace: Could not activate trace point "
- *                     "probe to <call>");
- *     return ret;
+ *     return register_trace_<call>(ftrace_raw_event_<call>);
  * }
  *
  * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused)
@@ -493,6 +495,8 @@ ftrace_profile_disable_##name(struct ftrace_event_call *unused)             \
  *     .trace                  = ftrace_raw_output_<call>, <-- stage 2
  * };
  *
+ * static const char print_fmt_<call>[] = <TP_printk>;
+ *
  * static struct ftrace_event_call __used
  * __attribute__((__aligned__(4)))
  * __attribute__((section("_ftrace_events"))) event_<call> = {
@@ -501,18 +505,20 @@ ftrace_profile_disable_##name(struct ftrace_event_call *unused)           \
  *     .raw_init               = trace_event_raw_init,
  *     .regfunc                = ftrace_reg_event_<call>,
  *     .unregfunc              = ftrace_unreg_event_<call>,
+ *     .print_fmt              = print_fmt_<call>,
+ *     .define_fields          = ftrace_define_fields_<call>,
  * }
  *
  */
 
 #ifdef CONFIG_PERF_EVENTS
 
-#define _TRACE_PROFILE_INIT(call)                                      \
-       .profile_enable = ftrace_profile_enable_##call,                 \
-       .profile_disable = ftrace_profile_disable_##call,
+#define _TRACE_PERF_INIT(call)                                         \
+       .perf_event_enable = perf_trace_enable_##call,                  \
+       .perf_event_disable = perf_trace_disable_##call,
 
 #else
-#define _TRACE_PROFILE_INIT(call)
+#define _TRACE_PERF_INIT(call)
 #endif /* CONFIG_PERF_EVENTS */
 
 #undef __entry
@@ -569,7 +575,6 @@ ftrace_raw_event_id_##call(struct ftrace_event_call *event_call,    \
                return;                                                 \
        entry   = ring_buffer_event_data(event);                        \
                                                                        \
-                                                                       \
        tstruct                                                         \
                                                                        \
        { assign; }                                                     \
@@ -638,7 +643,7 @@ __attribute__((section("_ftrace_events"))) event_##call = {         \
        .unregfunc              = ftrace_raw_unreg_event_##call,        \
        .print_fmt              = print_fmt_##template,                 \
        .define_fields          = ftrace_define_fields_##template,      \
-       _TRACE_PROFILE_INIT(call)                                       \
+       _TRACE_PERF_INIT(call)                                  \
 }
 
 #undef DEFINE_EVENT_PRINT
@@ -657,18 +662,18 @@ __attribute__((section("_ftrace_events"))) event_##call = {               \
        .unregfunc              = ftrace_raw_unreg_event_##call,        \
        .print_fmt              = print_fmt_##call,                     \
        .define_fields          = ftrace_define_fields_##template,      \
-       _TRACE_PROFILE_INIT(call)                                       \
+       _TRACE_PERF_INIT(call)                                  \
 }
 
 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
 
 /*
- * Define the insertion callback to profile events
+ * Define the insertion callback to perf events
  *
  * The job is very similar to ftrace_raw_event_<call> except that we don't
  * insert in the ring buffer but in a perf counter.
  *
- * static void ftrace_profile_<call>(proto)
+ * static void ftrace_perf_<call>(proto)
  * {
  *     struct ftrace_data_offsets_<call> __maybe_unused __data_offsets;
  *     struct ftrace_event_call *event_call = &event_<call>;
@@ -757,8 +762,8 @@ __attribute__((section("_ftrace_events"))) event_##call = {         \
 #undef DECLARE_EVENT_CLASS
 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
 static notrace void                                                    \
-ftrace_profile_templ_##call(struct ftrace_event_call *event_call,      \
-                           proto)                                      \
+perf_trace_templ_##call(struct ftrace_event_call *event_call,          \
+                       struct pt_regs *__regs, proto)                  \
 {                                                                      \
        struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
        struct ftrace_raw_##call *entry;                                \
@@ -773,10 +778,10 @@ ftrace_profile_templ_##call(struct ftrace_event_call *event_call, \
                             sizeof(u64));                              \
        __entry_size -= sizeof(u32);                                    \
                                                                        \
-       if (WARN_ONCE(__entry_size > FTRACE_MAX_PROFILE_SIZE,           \
+       if (WARN_ONCE(__entry_size > PERF_MAX_TRACE_SIZE,               \
                      "profile buffer not large enough"))               \
                return;                                                 \
-       entry = (struct ftrace_raw_##call *)ftrace_perf_buf_prepare(    \
+       entry = (struct ftrace_raw_##call *)perf_trace_buf_prepare(     \
                __entry_size, event_call->id, &rctx, &irq_flags);       \
        if (!entry)                                                     \
                return;                                                 \
@@ -784,17 +789,22 @@ ftrace_profile_templ_##call(struct ftrace_event_call *event_call, \
                                                                        \
        { assign; }                                                     \
                                                                        \
-       ftrace_perf_buf_submit(entry, __entry_size, rctx, __addr,       \
-                              __count, irq_flags);                     \
+       perf_trace_buf_submit(entry, __entry_size, rctx, __addr,        \
+                              __count, irq_flags, __regs);             \
 }
 
 #undef DEFINE_EVENT
-#define DEFINE_EVENT(template, call, proto, args)              \
-static notrace void ftrace_profile_##call(proto)               \
-{                                                              \
-       struct ftrace_event_call *event_call = &event_##call;   \
-                                                               \
-       ftrace_profile_templ_##template(event_call, args);      \
+#define DEFINE_EVENT(template, call, proto, args)                      \
+static notrace void perf_trace_##call(proto)                           \
+{                                                                      \
+       struct ftrace_event_call *event_call = &event_##call;           \
+       struct pt_regs *__regs = &get_cpu_var(perf_trace_regs);         \
+                                                                       \
+       perf_fetch_caller_regs(__regs, 1);                              \
+                                                                       \
+       perf_trace_templ_##template(event_call, __regs, args);          \
+                                                                       \
+       put_cpu_var(perf_trace_regs);                                   \
 }
 
 #undef DEFINE_EVENT_PRINT
index 0387100752f06836981f0afa7c761d2b270786e8..e5e5f48dbfb3f0a378cd1cc4dcfdcc15b7eb308e 100644 (file)
@@ -47,10 +47,10 @@ enum print_line_t print_syscall_exit(struct trace_iterator *iter, int flags);
 #endif
 
 #ifdef CONFIG_PERF_EVENTS
-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);
+int perf_sysenter_enable(struct ftrace_event_call *call);
+void perf_sysenter_disable(struct ftrace_event_call *call);
+int perf_sysexit_enable(struct ftrace_event_call *call);
+void perf_sysexit_disable(struct ftrace_event_call *call);
 #endif
 
 #endif /* _TRACE_SYSCALL_H */
index b9763badbd77da07813dae421f20a90a08df2e11..43e2d7d33976dc982364f599f7336d87ee26dbea 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/mutex.h>
 #include <linux/completion.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/grant_table.h>
 #include <xen/interface/io/xenbus.h>
index eb77e8ccde1c47d979cec79ec7c0fd1a12091161..5fe94b82e4c0a7ee5b779b58b8db09c162533f51 100644 (file)
@@ -604,8 +604,7 @@ config RT_GROUP_SCHED
        default n
        help
          This feature lets you explicitly allocate real CPU bandwidth
-         to users or control groups (depending on the "Basis for grouping tasks"
-         setting below. If enabled, it will also make it impossible to
+         to task groups. If enabled, it will also make it impossible to
          schedule realtime tasks for non-root users until you allocate
          realtime bandwidth for them.
          See Documentation/scheduler/sched-rt-group.txt for more information.
index bb008d064c1a53c711bc9c0b7ae21e26797a9b24..02e3ca4fc5271f33c4384d3ba8a77c8c4e5e306e 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/initrd.h>
 #include <linux/async.h>
 #include <linux/fs_struct.h>
+#include <linux/slab.h>
 
 #include <linux/nfs_fs.h>
 #include <linux/nfs_fs_sb.h>
index 027a402708de6c7fa505f989b6151f5ea5bf1935..bf3ef667bf3669d4332fbaa5fdd65784823c0f54 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/cramfs_fs.h>
 #include <linux/initrd.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 
 #include "do_mounts.h"
 #include "../fs/squashfs/squashfs_fs.h"
index 37d3859b1b32eda85e12ef7c0f1a159b32eafe4c..4b9c20205092e1f7de716633c0d51bd8746e74af 100644 (file)
@@ -457,7 +457,8 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len)
                                         compress_name);
                                message = msg_buf;
                        }
-               }
+               } else
+                       error("junk in compressed archive");
                if (state != Reset)
                        error("junk in compressed archive");
                this_header = saved_offset + my_inptr;
index a1ab78ceb4b62abf17551bc990a3298d1c95a320..5c8540271529ba49400037cf5abfae5cc5ec1486 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/bootmem.h>
 #include <linux/acpi.h>
 #include <linux/tty.h>
-#include <linux/gfp.h>
 #include <linux/percpu.h>
 #include <linux/kmod.h>
 #include <linux/vmalloc.h>
@@ -69,6 +68,7 @@
 #include <linux/kmemtrace.h>
 #include <linux/sfi.h>
 #include <linux/shmem_fs.h>
+#include <linux/slab.h>
 #include <trace/boot.h>
 
 #include <asm/io.h>
@@ -858,7 +858,7 @@ static int __init kernel_init(void * unused)
        /*
         * init can allocate pages on any node
         */
-       set_mems_allowed(node_possible_map);
+       set_mems_allowed(node_states[N_HIGH_MEMORY]);
        /*
         * init can run on any cpu.
         */
index ab76fb0ef8443e373c845b4a82510f09d64a1e79..9dc2c7d3c9e6de04732f79e113e73e1e6d52b368 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/init.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
-#include <linux/slab.h>
 #include <linux/syscalls.h>
 
 #include <linux/mutex.h>
index e4e3f04803ca9ec103da18837104042cc303e908..59a009dc54a8ba0ddf0d258d5b077260148abecc 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/nsproxy.h>
 #include <linux/pid.h>
 #include <linux/ipc_namespace.h>
+#include <linux/slab.h>
 
 #include <net/sock.h>
 #include "util.h"
@@ -157,7 +158,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
                            u->mq_bytes + mq_bytes >
                            task_rlimit(p, RLIMIT_MSGQUEUE)) {
                                spin_unlock(&mq_lock);
-                               kfree(info->messages);
+                               /* mqueue_delete_inode() releases info->messages */
                                goto out_inode;
                        }
                        u->mq_bytes += mq_bytes;
index af42ef8900a6418e3dce715316800e1bbb6da4df..9547cb7ac3135b9ba8964d13018f5ab6340552c9 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -23,7 +23,6 @@
  */
 
 #include <linux/capability.h>
-#include <linux/slab.h>
 #include <linux/msg.h>
 #include <linux/spinlock.h>
 #include <linux/init.h>
index 355a3da9ec73dd8bba5f596c1e1d026e53d881ea..1d6f53f6b562441bcf5ef99c85067275eecf6c5a 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/syscalls.h>
 #include <linux/uaccess.h>
 
-SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, int, second,
+SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
                unsigned long, third, void __user *, ptr, long, fifth)
 {
        int version, ret;
index a987aa1676b594b5501efd7213ccf671318c94c9..149e18ef1ab14f1f82c419d5d40e87dcff28fab5 100644 (file)
@@ -68,7 +68,7 @@ obj-$(CONFIG_USER_NS) += user_namespace.o
 obj-$(CONFIG_PID_NS) += pid_namespace.o
 obj-$(CONFIG_IKCONFIG) += configs.o
 obj-$(CONFIG_RESOURCE_COUNTERS) += res_counter.o
-obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
+obj-$(CONFIG_SMP) += stop_machine.o
 obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o
 obj-$(CONFIG_AUDIT) += audit.o auditfilter.o audit_watch.o
 obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
index 24f8c81fc48d8241562aa7c23e011fe525d1da0b..e4c0e1fee9b0022f8c0a15f7ed267e86f9d7d246 100644 (file)
@@ -353,17 +353,18 @@ restart:
 
 void acct_exit_ns(struct pid_namespace *ns)
 {
-       struct bsd_acct_struct *acct;
+       struct bsd_acct_struct *acct = ns->bacct;
 
-       spin_lock(&acct_lock);
-       acct = ns->bacct;
-       if (acct != NULL) {
-               if (acct->file != NULL)
-                       acct_file_reopen(acct, NULL, NULL);
+       if (acct == NULL)
+               return;
 
-               kfree(acct);
-       }
+       del_timer_sync(&acct->timer);
+       spin_lock(&acct_lock);
+       if (acct->file != NULL)
+               acct_file_reopen(acct, NULL, NULL);
        spin_unlock(&acct_lock);
+
+       kfree(acct);
 }
 
 /*
index 27235f5de198997180d4a293adc932d48c6101c7..15319d6c18fe05a3b3bbb8c91e0c654e58356bb2 100644 (file)
@@ -56,6 +56,7 @@ asynchronous and synchronous parts of the kernel.
 #include <linux/init.h>
 #include <linux/kthread.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/atomic.h>
 
 static async_cookie_t next_cookie = 1;
index 78f7f86aa2387a391cdbc2a91c364d1a41932deb..c71bd26631a28ccf3ecb1d90319b7b35f5e6f227 100644 (file)
@@ -46,6 +46,7 @@
 #include <asm/atomic.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/kthread.h>
 
index 028e85663f273d1d1cab2d75cde3ef76b22d3d48..46a57b57a335226d43ed662e1e8ff1fbe33ac7d4 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/namei.h>
 #include <linux/mount.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 struct audit_tree;
 struct audit_chunk;
index cc7e87936cbc57f7a2eebebbd212fe297c530154..8df43696f4ba6edff44f194398dd1baf59f4af92 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/namei.h>
 #include <linux/netlink.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/inotify.h>
 #include <linux/security.h>
 #include "audit.h"
index a70604047f3c9061e81622a3b399b085fe5ac815..ce08041f578d85d0d304fec4f8b28112cd598101 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/namei.h>
 #include <linux/netlink.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/security.h>
 #include "audit.h"
 
index f3a461c0970a32b44fd8db7da5b50778b728ab88..3828ad5fb8f16fad0221209515ee6120e54aaeea 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/namei.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/mount.h>
 #include <linux/socket.h>
 #include <linux/mqueue.h>
@@ -1893,7 +1894,7 @@ static int audit_inc_name_count(struct audit_context *context,
 {
        if (context->name_count >= AUDIT_NAMES) {
                if (inode)
-                       printk(KERN_DEBUG "name_count maxed, losing inode data: "
+                       printk(KERN_DEBUG "audit: name_count maxed, losing inode data: "
                               "dev=%02x:%02x, inode=%lu\n",
                               MAJOR(inode->i_sb->s_dev),
                               MINOR(inode->i_sb->s_dev),
index 9e4697e9b276e7429fed888b76c8e4ee19562e4c..2f05303715a5c4066a04b128251ebeec08d3779b 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/syscalls.h>
 #include <linux/pid_namespace.h>
 #include <asm/uaccess.h>
-#include "cred-internals.h"
 
 /*
  * Leveraged for setting/resetting capabilities
index ef909a32975006eafd43ce7693314eef5c5ffa4d..e9ec642932eee62ec7f6a4c67e2503e921aebbb6 100644 (file)
@@ -27,7 +27,6 @@
  */
 
 #include <linux/cgroup.h>
-#include <linux/module.h>
 #include <linux/ctype.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
@@ -1647,7 +1646,9 @@ static inline struct cftype *__d_cft(struct dentry *dentry)
 int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
 {
        char *start;
-       struct dentry *dentry = rcu_dereference(cgrp->dentry);
+       struct dentry *dentry = rcu_dereference_check(cgrp->dentry,
+                                                     rcu_read_lock_held() ||
+                                                     cgroup_lock_is_held());
 
        if (!dentry || cgrp == dummytop) {
                /*
@@ -1663,13 +1664,17 @@ int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
        *--start = '\0';
        for (;;) {
                int len = dentry->d_name.len;
+
                if ((start -= len) < buf)
                        return -ENAMETOOLONG;
-               memcpy(start, cgrp->dentry->d_name.name, len);
+               memcpy(start, dentry->d_name.name, len);
                cgrp = cgrp->parent;
                if (!cgrp)
                        break;
-               dentry = rcu_dereference(cgrp->dentry);
+
+               dentry = rcu_dereference_check(cgrp->dentry,
+                                              rcu_read_lock_held() ||
+                                              cgroup_lock_is_held());
                if (!cgrp->parent)
                        continue;
                if (--start < buf)
@@ -3011,7 +3016,7 @@ static int cgroup_event_wake(wait_queue_t *wait, unsigned mode,
        unsigned long flags = (unsigned long)key;
 
        if (flags & POLLHUP) {
-               remove_wait_queue_locked(event->wqh, &event->wait);
+               __remove_wait_queue(event->wqh, &event->wait);
                spin_lock(&cgrp->event_list_lock);
                list_del(&event->list);
                spin_unlock(&cgrp->event_list_lock);
@@ -4430,7 +4435,15 @@ __setup("cgroup_disable=", cgroup_disable);
  */
 unsigned short css_id(struct cgroup_subsys_state *css)
 {
-       struct css_id *cssid = rcu_dereference(css->id);
+       struct css_id *cssid;
+
+       /*
+        * This css_id() can return correct value when somone has refcnt
+        * on this or this is under rcu_read_lock(). Once css->id is allocated,
+        * it's unchanged until freed.
+        */
+       cssid = rcu_dereference_check(css->id,
+                       rcu_read_lock_held() || atomic_read(&css->refcnt));
 
        if (cssid)
                return cssid->id;
@@ -4440,7 +4453,10 @@ EXPORT_SYMBOL_GPL(css_id);
 
 unsigned short css_depth(struct cgroup_subsys_state *css)
 {
-       struct css_id *cssid = rcu_dereference(css->id);
+       struct css_id *cssid;
+
+       cssid = rcu_dereference_check(css->id,
+                       rcu_read_lock_held() || atomic_read(&css->refcnt));
 
        if (cssid)
                return cssid->depth;
@@ -4448,15 +4464,36 @@ unsigned short css_depth(struct cgroup_subsys_state *css)
 }
 EXPORT_SYMBOL_GPL(css_depth);
 
+/**
+ *  css_is_ancestor - test "root" css is an ancestor of "child"
+ * @child: the css to be tested.
+ * @root: the css supporsed to be an ancestor of the child.
+ *
+ * Returns true if "root" is an ancestor of "child" in its hierarchy. Because
+ * this function reads css->id, this use rcu_dereference() and rcu_read_lock().
+ * But, considering usual usage, the csses should be valid objects after test.
+ * Assuming that the caller will do some action to the child if this returns
+ * returns true, the caller must take "child";s reference count.
+ * If "child" is valid object and this returns true, "root" is valid, too.
+ */
+
 bool css_is_ancestor(struct cgroup_subsys_state *child,
                    const struct cgroup_subsys_state *root)
 {
-       struct css_id *child_id = rcu_dereference(child->id);
-       struct css_id *root_id = rcu_dereference(root->id);
+       struct css_id *child_id;
+       struct css_id *root_id;
+       bool ret = true;
 
-       if (!child_id || !root_id || (child_id->depth < root_id->depth))
-               return false;
-       return child_id->stack[root_id->depth] == root_id->id;
+       rcu_read_lock();
+       child_id  = rcu_dereference(child->id);
+       root_id = rcu_dereference(root->id);
+       if (!child_id
+           || !root_id
+           || (child_id->depth < root_id->depth)
+           || (child_id->stack[root_id->depth] != root_id->id))
+               ret = false;
+       rcu_read_unlock();
+       return ret;
 }
 
 static void __free_css_id_cb(struct rcu_head *head)
@@ -4556,13 +4593,13 @@ static int alloc_css_id(struct cgroup_subsys *ss, struct cgroup *parent,
 {
        int subsys_id, i, depth = 0;
        struct cgroup_subsys_state *parent_css, *child_css;
-       struct css_id *child_id, *parent_id = NULL;
+       struct css_id *child_id, *parent_id;
 
        subsys_id = ss->subsys_id;
        parent_css = parent->subsys[subsys_id];
        child_css = child->subsys[subsys_id];
-       depth = css_depth(parent_css) + 1;
        parent_id = parent_css->id;
+       depth = parent_id->depth;
 
        child_id = get_new_cssid(ss, depth);
        if (IS_ERR(child_id))
index 59e9ef6aab4002e1d99170f50156e733e8f46343..e5c0244962b020ab3cd4e4d00a0be04e5cc18af5 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/cgroup.h>
 #include <linux/fs.h>
 #include <linux/uaccess.h>
@@ -47,17 +48,20 @@ static inline struct freezer *task_freezer(struct task_struct *task)
                            struct freezer, css);
 }
 
-int cgroup_frozen(struct task_struct *task)
+int cgroup_freezing_or_frozen(struct task_struct *task)
 {
        struct freezer *freezer;
        enum freezer_state state;
 
        task_lock(task);
        freezer = task_freezer(task);
-       state = freezer->state;
+       if (!freezer->css.cgroup->parent)
+               state = CGROUP_THAWED; /* root cgroup can't be frozen */
+       else
+               state = freezer->state;
        task_unlock(task);
 
-       return state == CGROUP_FROZEN;
+       return (state == CGROUP_FREEZING) || (state == CGROUP_FROZEN);
 }
 
 /*
@@ -201,9 +205,12 @@ static void freezer_fork(struct cgroup_subsys *ss, struct task_struct *task)
         * No lock is needed, since the task isn't on tasklist yet,
         * so it can't be moved to another cgroup, which means the
         * freezer won't be removed and will be valid during this
-        * function call.
+        * function call.  Nevertheless, apply RCU read-side critical
+        * section to suppress RCU lockdep false positives.
         */
+       rcu_read_lock();
        freezer = task_freezer(task);
+       rcu_read_unlock();
 
        /*
         * The root cgroup is non-freezable, so we can skip the
index f6c204f07ea6084c4849d52358d6b1b2aab1f0da..7f40e9275fd9602d8fb8c4669227e5dd6156b0ff 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/posix-timers.h>
 #include <linux/times.h>
 #include <linux/ptrace.h>
+#include <linux/gfp.h>
 
 #include <asm/uaccess.h>
 
index f8cced2692b3799e26710ccbde3bc8f0f8b654e9..545777574779da71ef8e3fcc3935e0e41fa266ca 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kthread.h>
 #include <linux/stop_machine.h>
 #include <linux/mutex.h>
+#include <linux/gfp.h>
 
 #ifdef CONFIG_SMP
 /* Serializes the updates to cpu_online_mask, cpu_present_mask */
@@ -163,6 +164,7 @@ static inline void check_for_tasks(int cpu)
 }
 
 struct take_cpu_down_param {
+       struct task_struct *caller;
        unsigned long mod;
        void *hcpu;
 };
@@ -171,6 +173,7 @@ struct take_cpu_down_param {
 static int __ref take_cpu_down(void *_param)
 {
        struct take_cpu_down_param *param = _param;
+       unsigned int cpu = (unsigned long)param->hcpu;
        int err;
 
        /* Ensure this CPU doesn't handle any more interrupts. */
@@ -181,6 +184,8 @@ static int __ref take_cpu_down(void *_param)
        raw_notifier_call_chain(&cpu_chain, CPU_DYING | param->mod,
                                param->hcpu);
 
+       if (task_cpu(param->caller) == cpu)
+               move_task_off_dead_cpu(cpu, param->caller);
        /* Force idle task to run as soon as we yield: it should
           immediately notice cpu is offline and die quickly. */
        sched_idle_next();
@@ -191,10 +196,10 @@ static int __ref take_cpu_down(void *_param)
 static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
 {
        int err, nr_calls = 0;
-       cpumask_var_t old_allowed;
        void *hcpu = (void *)(long)cpu;
        unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;
        struct take_cpu_down_param tcd_param = {
+               .caller = current,
                .mod = mod,
                .hcpu = hcpu,
        };
@@ -205,9 +210,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
        if (!cpu_online(cpu))
                return -EINVAL;
 
-       if (!alloc_cpumask_var(&old_allowed, GFP_KERNEL))
-               return -ENOMEM;
-
        cpu_hotplug_begin();
        set_cpu_active(cpu, false);
        err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,
@@ -224,10 +226,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
                goto out_release;
        }
 
-       /* Ensure that we are not runnable on dying cpu */
-       cpumask_copy(old_allowed, &current->cpus_allowed);
-       set_cpus_allowed_ptr(current, cpu_active_mask);
-
        err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu));
        if (err) {
                set_cpu_active(cpu, true);
@@ -236,7 +234,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
                                            hcpu) == NOTIFY_BAD)
                        BUG();
 
-               goto out_allowed;
+               goto out_release;
        }
        BUG_ON(cpu_online(cpu));
 
@@ -254,8 +252,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
 
        check_for_tasks(cpu);
 
-out_allowed:
-       set_cpus_allowed_ptr(current, old_allowed);
 out_release:
        cpu_hotplug_done();
        if (!err) {
@@ -263,7 +259,6 @@ out_release:
                                            hcpu) == NOTIFY_BAD)
                        BUG();
        }
-       free_cpumask_var(old_allowed);
        return err;
 }
 
@@ -271,9 +266,6 @@ int __ref cpu_down(unsigned int cpu)
 {
        int err;
 
-       err = stop_machine_create();
-       if (err)
-               return err;
        cpu_maps_update_begin();
 
        if (cpu_hotplug_disabled) {
@@ -285,7 +277,6 @@ int __ref cpu_down(unsigned int cpu)
 
 out:
        cpu_maps_update_done();
-       stop_machine_destroy();
        return err;
 }
 EXPORT_SYMBOL(cpu_down);
@@ -366,9 +357,6 @@ int disable_nonboot_cpus(void)
 {
        int cpu, first_cpu, error;
 
-       error = stop_machine_create();
-       if (error)
-               return error;
        cpu_maps_update_begin();
        first_cpu = cpumask_first(cpu_online_mask);
        /*
@@ -399,7 +387,6 @@ int disable_nonboot_cpus(void)
                printk(KERN_ERR "Non-boot CPUs are not disabled\n");
        }
        cpu_maps_update_done();
-       stop_machine_destroy();
        return error;
 }
 
index ba401fab459f94a42010f6175b2b69c490920645..9a50c5f6e727f3f77ec5dcf2d5f993fc62717ce9 100644 (file)
@@ -920,9 +920,6 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
  *    call to guarantee_online_mems(), as we know no one is changing
  *    our task's cpuset.
  *
- *    Hold callback_mutex around the two modifications of our tasks
- *    mems_allowed to synchronize with cpuset_mems_allowed().
- *
  *    While the mm_struct we are migrating is typically from some
  *    other task, the task_struct mems_allowed that we are hacking
  *    is for our current task, which must allocate new pages for that
@@ -973,15 +970,20 @@ static void cpuset_change_nodemask(struct task_struct *p,
        struct cpuset *cs;
        int migrate;
        const nodemask_t *oldmem = scan->data;
-       nodemask_t newmems;
+       NODEMASK_ALLOC(nodemask_t, newmems, GFP_KERNEL);
+
+       if (!newmems)
+               return;
 
        cs = cgroup_cs(scan->cg);
-       guarantee_online_mems(cs, &newmems);
+       guarantee_online_mems(cs, newmems);
 
        task_lock(p);
-       cpuset_change_task_nodemask(p, &newmems);
+       cpuset_change_task_nodemask(p, newmems);
        task_unlock(p);
 
+       NODEMASK_FREE(newmems);
+
        mm = get_task_mm(p);
        if (!mm)
                return;
@@ -1051,16 +1053,21 @@ static void update_tasks_nodemask(struct cpuset *cs, const nodemask_t *oldmem,
 static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs,
                           const char *buf)
 {
-       nodemask_t oldmem;
+       NODEMASK_ALLOC(nodemask_t, oldmem, GFP_KERNEL);
        int retval;
        struct ptr_heap heap;
 
+       if (!oldmem)
+               return -ENOMEM;
+
        /*
         * top_cpuset.mems_allowed tracks node_stats[N_HIGH_MEMORY];
         * it's read-only
         */
-       if (cs == &top_cpuset)
-               return -EACCES;
+       if (cs == &top_cpuset) {
+               retval = -EACCES;
+               goto done;
+       }
 
        /*
         * An empty mems_allowed is ok iff there are no tasks in the cpuset.
@@ -1076,11 +1083,13 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs,
                        goto done;
 
                if (!nodes_subset(trialcs->mems_allowed,
-                               node_states[N_HIGH_MEMORY]))
-                       return -EINVAL;
+                               node_states[N_HIGH_MEMORY])) {
+                       retval =  -EINVAL;
+                       goto done;
+               }
        }
-       oldmem = cs->mems_allowed;
-       if (nodes_equal(oldmem, trialcs->mems_allowed)) {
+       *oldmem = cs->mems_allowed;
+       if (nodes_equal(*oldmem, trialcs->mems_allowed)) {
                retval = 0;             /* Too easy - nothing to do */
                goto done;
        }
@@ -1096,10 +1105,11 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs,
        cs->mems_allowed = trialcs->mems_allowed;
        mutex_unlock(&callback_mutex);
 
-       update_tasks_nodemask(cs, &oldmem, &heap);
+       update_tasks_nodemask(cs, oldmem, &heap);
 
        heap_free(&heap);
 done:
+       NODEMASK_FREE(oldmem);
        return retval;
 }
 
@@ -1384,40 +1394,47 @@ static void cpuset_attach(struct cgroup_subsys *ss, struct cgroup *cont,
                          struct cgroup *oldcont, struct task_struct *tsk,
                          bool threadgroup)
 {
-       nodemask_t from, to;
        struct mm_struct *mm;
        struct cpuset *cs = cgroup_cs(cont);
        struct cpuset *oldcs = cgroup_cs(oldcont);
+       NODEMASK_ALLOC(nodemask_t, from, GFP_KERNEL);
+       NODEMASK_ALLOC(nodemask_t, to, GFP_KERNEL);
+
+       if (from == NULL || to == NULL)
+               goto alloc_fail;
 
        if (cs == &top_cpuset) {
                cpumask_copy(cpus_attach, cpu_possible_mask);
-               to = node_possible_map;
        } else {
                guarantee_online_cpus(cs, cpus_attach);
-               guarantee_online_mems(cs, &to);
        }
+       guarantee_online_mems(cs, to);
 
        /* do per-task migration stuff possibly for each in the threadgroup */
-       cpuset_attach_task(tsk, &to, cs);
+       cpuset_attach_task(tsk, to, cs);
        if (threadgroup) {
                struct task_struct *c;
                rcu_read_lock();
                list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) {
-                       cpuset_attach_task(c, &to, cs);
+                       cpuset_attach_task(c, to, cs);
                }
                rcu_read_unlock();
        }
 
        /* change mm; only needs to be done once even if threadgroup */
-       from = oldcs->mems_allowed;
-       to = cs->mems_allowed;
+       *from = oldcs->mems_allowed;
+       *to = cs->mems_allowed;
        mm = get_task_mm(tsk);
        if (mm) {
-               mpol_rebind_mm(mm, &to);
+               mpol_rebind_mm(mm, to);
                if (is_memory_migrate(cs))
-                       cpuset_migrate_mm(mm, &from, &to);
+                       cpuset_migrate_mm(mm, from, to);
                mmput(mm);
        }
+
+alloc_fail:
+       NODEMASK_FREE(from);
+       NODEMASK_FREE(to);
 }
 
 /* The various types of files and directories in a cpuset file system */
@@ -1562,13 +1579,21 @@ static int cpuset_sprintf_cpulist(char *page, struct cpuset *cs)
 
 static int cpuset_sprintf_memlist(char *page, struct cpuset *cs)
 {
-       nodemask_t mask;
+       NODEMASK_ALLOC(nodemask_t, mask, GFP_KERNEL);
+       int retval;
+
+       if (mask == NULL)
+               return -ENOMEM;
 
        mutex_lock(&callback_mutex);
-       mask = cs->mems_allowed;
+       *mask = cs->mems_allowed;
        mutex_unlock(&callback_mutex);
 
-       return nodelist_scnprintf(page, PAGE_SIZE, mask);
+       retval = nodelist_scnprintf(page, PAGE_SIZE, *mask);
+
+       NODEMASK_FREE(mask);
+
+       return retval;
 }
 
 static ssize_t cpuset_common_file_read(struct cgroup *cont,
@@ -1997,7 +2022,10 @@ static void scan_for_empty_cpusets(struct cpuset *root)
        struct cpuset *cp;      /* scans cpusets being updated */
        struct cpuset *child;   /* scans child cpusets of cp */
        struct cgroup *cont;
-       nodemask_t oldmems;
+       NODEMASK_ALLOC(nodemask_t, oldmems, GFP_KERNEL);
+
+       if (oldmems == NULL)
+               return;
 
        list_add_tail((struct list_head *)&root->stack_list, &queue);
 
@@ -2014,7 +2042,7 @@ static void scan_for_empty_cpusets(struct cpuset *root)
                    nodes_subset(cp->mems_allowed, node_states[N_HIGH_MEMORY]))
                        continue;
 
-               oldmems = cp->mems_allowed;
+               *oldmems = cp->mems_allowed;
 
                /* Remove offline cpus and mems from this cpuset. */
                mutex_lock(&callback_mutex);
@@ -2030,9 +2058,10 @@ static void scan_for_empty_cpusets(struct cpuset *root)
                        remove_tasks_in_empty_cpuset(cp);
                else {
                        update_tasks_cpumask(cp, NULL);
-                       update_tasks_nodemask(cp, &oldmems, NULL);
+                       update_tasks_nodemask(cp, oldmems, NULL);
                }
        }
+       NODEMASK_FREE(oldmems);
 }
 
 /*
@@ -2090,20 +2119,33 @@ static int cpuset_track_online_cpus(struct notifier_block *unused_nb,
 static int cpuset_track_online_nodes(struct notifier_block *self,
                                unsigned long action, void *arg)
 {
+       NODEMASK_ALLOC(nodemask_t, oldmems, GFP_KERNEL);
+
+       if (oldmems == NULL)
+               return NOTIFY_DONE;
+
        cgroup_lock();
        switch (action) {
        case MEM_ONLINE:
-       case MEM_OFFLINE:
+               *oldmems = top_cpuset.mems_allowed;
                mutex_lock(&callback_mutex);
                top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
                mutex_unlock(&callback_mutex);
-               if (action == MEM_OFFLINE)
-                       scan_for_empty_cpusets(&top_cpuset);
+               update_tasks_nodemask(&top_cpuset, oldmems, NULL);
+               break;
+       case MEM_OFFLINE:
+               /*
+                * needn't update top_cpuset.mems_allowed explicitly because
+                * scan_for_empty_cpusets() will update it.
+                */
+               scan_for_empty_cpusets(&top_cpuset);
                break;
        default:
                break;
        }
        cgroup_unlock();
+
+       NODEMASK_FREE(oldmems);
        return NOTIFY_OK;
 }
 #endif
@@ -2140,19 +2182,52 @@ void __init cpuset_init_smp(void)
 void cpuset_cpus_allowed(struct task_struct *tsk, struct cpumask *pmask)
 {
        mutex_lock(&callback_mutex);
-       cpuset_cpus_allowed_locked(tsk, pmask);
+       task_lock(tsk);
+       guarantee_online_cpus(task_cs(tsk), pmask);
+       task_unlock(tsk);
        mutex_unlock(&callback_mutex);
 }
 
-/**
- * cpuset_cpus_allowed_locked - return cpus_allowed mask from a tasks cpuset.
- * Must be called with callback_mutex held.
- **/
-void cpuset_cpus_allowed_locked(struct task_struct *tsk, struct cpumask *pmask)
+int cpuset_cpus_allowed_fallback(struct task_struct *tsk)
 {
-       task_lock(tsk);
-       guarantee_online_cpus(task_cs(tsk), pmask);
-       task_unlock(tsk);
+       const struct cpuset *cs;
+       int cpu;
+
+       rcu_read_lock();
+       cs = task_cs(tsk);
+       if (cs)
+               cpumask_copy(&tsk->cpus_allowed, cs->cpus_allowed);
+       rcu_read_unlock();
+
+       /*
+        * We own tsk->cpus_allowed, nobody can change it under us.
+        *
+        * But we used cs && cs->cpus_allowed lockless and thus can
+        * race with cgroup_attach_task() or update_cpumask() and get
+        * the wrong tsk->cpus_allowed. However, both cases imply the
+        * subsequent cpuset_change_cpumask()->set_cpus_allowed_ptr()
+        * which takes task_rq_lock().
+        *
+        * If we are called after it dropped the lock we must see all
+        * changes in tsk_cs()->cpus_allowed. Otherwise we can temporary
+        * set any mask even if it is not right from task_cs() pov,
+        * the pending set_cpus_allowed_ptr() will fix things.
+        */
+
+       cpu = cpumask_any_and(&tsk->cpus_allowed, cpu_active_mask);
+       if (cpu >= nr_cpu_ids) {
+               /*
+                * Either tsk->cpus_allowed is wrong (see above) or it
+                * is actually empty. The latter case is only possible
+                * if we are racing with remove_tasks_in_empty_cpuset().
+                * Like above we can temporary set any mask and rely on
+                * set_cpus_allowed_ptr() as synchronization point.
+                */
+               cpumask_copy(&tsk->cpus_allowed, cpu_possible_mask);
+               cpu = cpumask_any(cpu_active_mask);
+       }
+
+       return cpu;
 }
 
 void cpuset_init_current_mems_allowed(void)
@@ -2340,22 +2415,6 @@ int __cpuset_node_allowed_hardwall(int node, gfp_t gfp_mask)
        return 0;
 }
 
-/**
- * cpuset_lock - lock out any changes to cpuset structures
- *
- * The out of memory (oom) code needs to mutex_lock cpusets
- * from being changed while it scans the tasklist looking for a
- * task in an overlapping cpuset.  Expose callback_mutex via this
- * cpuset_lock() routine, so the oom code can lock it, before
- * locking the task list.  The tasklist_lock is a spinlock, so
- * must be taken inside callback_mutex.
- */
-
-void cpuset_lock(void)
-{
-       mutex_lock(&callback_mutex);
-}
-
 /**
  * cpuset_unlock - release lock on cpuset changes
  *
diff --git a/kernel/cred-internals.h b/kernel/cred-internals.h
deleted file mode 100644 (file)
index 2dc4fc2..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Internal credentials stuff
- *
- * Copyright (C) 2008 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.
- */
-
-/*
- * user.c
- */
-static inline void sched_switch_user(struct task_struct *p)
-{
-#ifdef CONFIG_USER_SCHED
-       sched_move_task(p);
-#endif /* CONFIG_USER_SCHED */
-}
-
index 1ed8ca18790c1e937208af47bed6695f4218858b..8f3672a58a1e82a39de67ee4f35e7b2f0c12ac2b 100644 (file)
  */
 #include <linux/module.h>
 #include <linux/cred.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/key.h>
 #include <linux/keyctl.h>
 #include <linux/init_task.h>
 #include <linux/security.h>
 #include <linux/cn_proc.h>
-#include "cred-internals.h"
 
 #if 0
 #define kdebug(FMT, ...) \
@@ -364,7 +364,7 @@ struct cred *prepare_usermodehelper_creds(void)
 
        new = kmem_cache_alloc(cred_jar, GFP_ATOMIC);
        if (!new)
-               return NULL;
+               goto free_tgcred;
 
        kdebug("prepare_usermodehelper_creds() alloc %p", new);
 
@@ -398,6 +398,12 @@ struct cred *prepare_usermodehelper_creds(void)
 error:
        put_cred(new);
        return NULL;
+
+free_tgcred:
+#ifdef CONFIG_KEYS
+       kfree(tgcred);
+#endif
+       return NULL;
 }
 
 /*
@@ -553,8 +559,6 @@ int commit_creds(struct cred *new)
                atomic_dec(&old->user->processes);
        alter_cred_subscribers(old, -2);
 
-       sched_switch_user(task);
-
        /* send notifications */
        if (new->uid   != old->uid  ||
            new->euid  != old->euid ||
@@ -786,8 +790,6 @@ bool creds_are_invalid(const struct cred *cred)
 {
        if (cred->magic != CRED_MAGIC)
                return true;
-       if (atomic_read(&cred->usage) < atomic_read(&cred->subscribers))
-               return true;
 #ifdef CONFIG_SECURITY_SELINUX
        if (selinux_is_enabled()) {
                if ((unsigned long) cred->security < PAGE_SIZE)
index 3cb2c661bb781ab5468a54e58a106cdb14269a7b..31aa9332ef3f8d4f5447f72a3989cbfd0dc7c6df 100644 (file)
@@ -333,6 +333,12 @@ void __init free_early_partial(u64 start, u64 end)
        struct early_res *r;
        int i;
 
+       if (start == end)
+               return;
+
+       if (WARN_ONCE(start > end, "  wrong range [%#llx, %#llx]\n", start, end))
+               return;
+
 try_next:
        i = find_overlapped_early(start, end);
        if (i >= max_early_res)
index cce59cb5ee6aececf1b663d39a1de3fb15b4b426..eabca5a73a85b70d8d1d9f2ea95c05ae6c27c1e2 100644 (file)
@@ -55,7 +55,6 @@
 #include <asm/unistd.h>
 #include <asm/pgtable.h>
 #include <asm/mmu_context.h>
-#include "cred-internals.h"
 
 static void exit_mm(struct task_struct * tsk);
 
@@ -953,7 +952,8 @@ NORET_TYPE void do_exit(long code)
 
        acct_update_integrals(tsk);
        /* sync mm's RSS info before statistics gathering */
-       sync_mm_rss(tsk, tsk->mm);
+       if (tsk->mm)
+               sync_mm_rss(tsk, tsk->mm);
        group_dead = atomic_dec_and_test(&tsk->signal->live);
        if (group_dead) {
                hrtimer_cancel(&tsk->signal->real_timer);
index 4799c5f0e6d089a6287b7c7742a34f37146932c1..4d57d9e3a6e992a9d0a3514138008a0d8aefaeff 100644 (file)
@@ -1052,6 +1052,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        p->prev_utime = cputime_zero;
        p->prev_stime = cputime_zero;
 #endif
+#if defined(SPLIT_RSS_COUNTING)
+       memset(&p->rss_stat, 0, sizeof(p->rss_stat));
+#endif
 
        p->default_timer_slack_ns = current->timer_slack_ns;
 
@@ -1109,10 +1112,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        p->memcg_batch.memcg = NULL;
 #endif
 
-       p->bts = NULL;
-
-       p->stack_start = stack_start;
-
        /* Perform scheduler related setup. Assign this task to a CPU. */
        sched_fork(p, clone_flags);
 
index 03808ed342a6733d46d6e123ffc80d91a317c3d4..7a56b22e0602f0b37338c189110d65c07e7cc730 100644 (file)
 #include <linux/percpu.h>
 #include <linux/sched.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/cpu.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);
+static DEFINE_PER_CPU(unsigned int, nr_cpu_bp_pinned[TYPE_MAX]);
 
 /* Number of pinned task breakpoints in a cpu */
-static DEFINE_PER_CPU(unsigned int, nr_task_bp_pinned[HBP_NUM]);
+static DEFINE_PER_CPU(unsigned int *, nr_task_bp_pinned[TYPE_MAX]);
 
 /* Number of non-pinned cpu/task breakpoints in a cpu */
-static DEFINE_PER_CPU(unsigned int, nr_bp_flexible);
+static DEFINE_PER_CPU(unsigned int, nr_bp_flexible[TYPE_MAX]);
+
+static int nr_slots[TYPE_MAX];
+
+static int constraints_initialized;
 
 /* Gather the number of total pinned and un-pinned bp in a cpuset */
 struct bp_busy_slots {
@@ -67,16 +73,29 @@ struct bp_busy_slots {
 /* Serialize accesses to the above constraints */
 static DEFINE_MUTEX(nr_bp_mutex);
 
+__weak int hw_breakpoint_weight(struct perf_event *bp)
+{
+       return 1;
+}
+
+static inline enum bp_type_idx find_slot_idx(struct perf_event *bp)
+{
+       if (bp->attr.bp_type & HW_BREAKPOINT_RW)
+               return TYPE_DATA;
+
+       return TYPE_INST;
+}
+
 /*
  * Report the maximum number of pinned breakpoints a task
  * have in this cpu
  */
-static unsigned int max_task_bp_pinned(int cpu)
+static unsigned int max_task_bp_pinned(int cpu, enum bp_type_idx type)
 {
        int i;
-       unsigned int *tsk_pinned = per_cpu(nr_task_bp_pinned, cpu);
+       unsigned int *tsk_pinned = per_cpu(nr_task_bp_pinned[type], cpu);
 
-       for (i = HBP_NUM -1; i >= 0; i--) {
+       for (i = nr_slots[type] - 1; i >= 0; i--) {
                if (tsk_pinned[i] > 0)
                        return i + 1;
        }
@@ -84,7 +103,7 @@ static unsigned int max_task_bp_pinned(int cpu)
        return 0;
 }
 
-static int task_bp_pinned(struct task_struct *tsk)
+static int task_bp_pinned(struct task_struct *tsk, enum bp_type_idx type)
 {
        struct perf_event_context *ctx = tsk->perf_event_ctxp;
        struct list_head *list;
@@ -105,7 +124,8 @@ static int task_bp_pinned(struct task_struct *tsk)
         */
        list_for_each_entry(bp, list, event_entry) {
                if (bp->attr.type == PERF_TYPE_BREAKPOINT)
-                       count++;
+                       if (find_slot_idx(bp) == type)
+                               count += hw_breakpoint_weight(bp);
        }
 
        raw_spin_unlock_irqrestore(&ctx->lock, flags);
@@ -118,18 +138,19 @@ static int task_bp_pinned(struct task_struct *tsk)
  * a given cpu (cpu > -1) or in all of them (cpu = -1).
  */
 static void
-fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp)
+fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp,
+                   enum bp_type_idx type)
 {
        int cpu = bp->cpu;
        struct task_struct *tsk = bp->ctx->task;
 
        if (cpu >= 0) {
-               slots->pinned = per_cpu(nr_cpu_bp_pinned, cpu);
+               slots->pinned = per_cpu(nr_cpu_bp_pinned[type], cpu);
                if (!tsk)
-                       slots->pinned += max_task_bp_pinned(cpu);
+                       slots->pinned += max_task_bp_pinned(cpu, type);
                else
-                       slots->pinned += task_bp_pinned(tsk);
-               slots->flexible = per_cpu(nr_bp_flexible, cpu);
+                       slots->pinned += task_bp_pinned(tsk, type);
+               slots->flexible = per_cpu(nr_bp_flexible[type], cpu);
 
                return;
        }
@@ -137,48 +158,66 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp)
        for_each_online_cpu(cpu) {
                unsigned int nr;
 
-               nr = per_cpu(nr_cpu_bp_pinned, cpu);
+               nr = per_cpu(nr_cpu_bp_pinned[type], cpu);
                if (!tsk)
-                       nr += max_task_bp_pinned(cpu);
+                       nr += max_task_bp_pinned(cpu, type);
                else
-                       nr += task_bp_pinned(tsk);
+                       nr += task_bp_pinned(tsk, type);
 
                if (nr > slots->pinned)
                        slots->pinned = nr;
 
-               nr = per_cpu(nr_bp_flexible, cpu);
+               nr = per_cpu(nr_bp_flexible[type], cpu);
 
                if (nr > slots->flexible)
                        slots->flexible = nr;
        }
 }
 
+/*
+ * For now, continue to consider flexible as pinned, until we can
+ * ensure no flexible event can ever be scheduled before a pinned event
+ * in a same cpu.
+ */
+static void
+fetch_this_slot(struct bp_busy_slots *slots, int weight)
+{
+       slots->pinned += weight;
+}
+
 /*
  * 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)
+static void toggle_bp_task_slot(struct task_struct *tsk, int cpu, bool enable,
+                               enum bp_type_idx type, int weight)
 {
        unsigned int *tsk_pinned;
-       int count = 0;
+       int old_count = 0;
+       int old_idx = 0;
+       int idx = 0;
 
-       count = task_bp_pinned(tsk);
+       old_count = task_bp_pinned(tsk, type);
+       old_idx = old_count - 1;
+       idx = old_idx + weight;
 
-       tsk_pinned = per_cpu(nr_task_bp_pinned, cpu);
+       tsk_pinned = per_cpu(nr_task_bp_pinned[type], cpu);
        if (enable) {
-               tsk_pinned[count]++;
-               if (count > 0)
-                       tsk_pinned[count-1]--;
+               tsk_pinned[idx]++;
+               if (old_count > 0)
+                       tsk_pinned[old_idx]--;
        } else {
-               tsk_pinned[count]--;
-               if (count > 0)
-                       tsk_pinned[count-1]++;
+               tsk_pinned[idx]--;
+               if (old_count > 0)
+                       tsk_pinned[old_idx]++;
        }
 }
 
 /*
  * Add/remove the given breakpoint in our constraint table
  */
-static void toggle_bp_slot(struct perf_event *bp, bool enable)
+static void
+toggle_bp_slot(struct perf_event *bp, bool enable, enum bp_type_idx type,
+              int weight)
 {
        int cpu = bp->cpu;
        struct task_struct *tsk = bp->ctx->task;
@@ -186,20 +225,20 @@ static void toggle_bp_slot(struct perf_event *bp, bool enable)
        /* Pinned counter task profiling */
        if (tsk) {
                if (cpu >= 0) {
-                       toggle_bp_task_slot(tsk, cpu, enable);
+                       toggle_bp_task_slot(tsk, cpu, enable, type, weight);
                        return;
                }
 
                for_each_online_cpu(cpu)
-                       toggle_bp_task_slot(tsk, cpu, enable);
+                       toggle_bp_task_slot(tsk, cpu, enable, type, weight);
                return;
        }
 
        /* Pinned counter cpu profiling */
        if (enable)
-               per_cpu(nr_cpu_bp_pinned, bp->cpu)++;
+               per_cpu(nr_cpu_bp_pinned[type], bp->cpu) += weight;
        else
-               per_cpu(nr_cpu_bp_pinned, bp->cpu)--;
+               per_cpu(nr_cpu_bp_pinned[type], bp->cpu) -= weight;
 }
 
 /*
@@ -246,14 +285,29 @@ static void toggle_bp_slot(struct perf_event *bp, bool enable)
 static int __reserve_bp_slot(struct perf_event *bp)
 {
        struct bp_busy_slots slots = {0};
+       enum bp_type_idx type;
+       int weight;
 
-       fetch_bp_busy_slots(&slots, bp);
+       /* We couldn't initialize breakpoint constraints on boot */
+       if (!constraints_initialized)
+               return -ENOMEM;
+
+       /* Basic checks */
+       if (bp->attr.bp_type == HW_BREAKPOINT_EMPTY ||
+           bp->attr.bp_type == HW_BREAKPOINT_INVALID)
+               return -EINVAL;
+
+       type = find_slot_idx(bp);
+       weight = hw_breakpoint_weight(bp);
+
+       fetch_bp_busy_slots(&slots, bp, type);
+       fetch_this_slot(&slots, weight);
 
        /* Flexible counters need to keep at least one slot */
-       if (slots.pinned + (!!slots.flexible) == HBP_NUM)
+       if (slots.pinned + (!!slots.flexible) > nr_slots[type])
                return -ENOSPC;
 
-       toggle_bp_slot(bp, true);
+       toggle_bp_slot(bp, true, type, weight);
 
        return 0;
 }
@@ -273,7 +327,12 @@ int reserve_bp_slot(struct perf_event *bp)
 
 static void __release_bp_slot(struct perf_event *bp)
 {
-       toggle_bp_slot(bp, false);
+       enum bp_type_idx type;
+       int weight;
+
+       type = find_slot_idx(bp);
+       weight = hw_breakpoint_weight(bp);
+       toggle_bp_slot(bp, false, type, weight);
 }
 
 void release_bp_slot(struct perf_event *bp)
@@ -308,6 +367,28 @@ int dbg_release_bp_slot(struct perf_event *bp)
        return 0;
 }
 
+static int validate_hw_breakpoint(struct perf_event *bp)
+{
+       int ret;
+
+       ret = arch_validate_hwbkpt_settings(bp);
+       if (ret)
+               return ret;
+
+       if (arch_check_bp_in_kernelspace(bp)) {
+               if (bp->attr.exclude_kernel)
+                       return -EINVAL;
+               /*
+                * Don't let unprivileged users set a breakpoint in the trap
+                * path to avoid trap recursion attacks.
+                */
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+       }
+
+       return 0;
+}
+
 int register_perf_hw_breakpoint(struct perf_event *bp)
 {
        int ret;
@@ -316,17 +397,7 @@ int register_perf_hw_breakpoint(struct perf_event *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->overflow_handler)
-               ret = arch_validate_hwbkpt_settings(bp, bp->ctx->task);
+       ret = validate_hw_breakpoint(bp);
 
        /* if arch_validate_hwbkpt_settings() fails then release bp slot */
        if (ret)
@@ -373,7 +444,7 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att
        if (attr->disabled)
                goto end;
 
-       err = arch_validate_hwbkpt_settings(bp, bp->ctx->task);
+       err = validate_hw_breakpoint(bp);
        if (!err)
                perf_event_enable(bp);
 
@@ -480,7 +551,36 @@ static struct notifier_block hw_breakpoint_exceptions_nb = {
 
 static int __init init_hw_breakpoint(void)
 {
+       unsigned int **task_bp_pinned;
+       int cpu, err_cpu;
+       int i;
+
+       for (i = 0; i < TYPE_MAX; i++)
+               nr_slots[i] = hw_breakpoint_slots(i);
+
+       for_each_possible_cpu(cpu) {
+               for (i = 0; i < TYPE_MAX; i++) {
+                       task_bp_pinned = &per_cpu(nr_task_bp_pinned[i], cpu);
+                       *task_bp_pinned = kzalloc(sizeof(int) * nr_slots[i],
+                                                 GFP_KERNEL);
+                       if (!*task_bp_pinned)
+                               goto err_alloc;
+               }
+       }
+
+       constraints_initialized = 1;
+
        return register_die_notifier(&hw_breakpoint_exceptions_nb);
+
+ err_alloc:
+       for_each_possible_cpu(err_cpu) {
+               if (err_cpu == cpu)
+                       break;
+               for (i = 0; i < TYPE_MAX; i++)
+                       kfree(per_cpu(nr_task_bp_pinned[i], cpu));
+       }
+
+       return -ENOMEM;
 }
 core_initcall(init_hw_breakpoint);
 
index 42ec11b2af8af5205c09523a9b18b3bf6fdd98ef..b7091d5ca2f829ae61f0140ae6b1901213bfab62 100644 (file)
@@ -359,6 +359,23 @@ static inline void mask_ack_irq(struct irq_desc *desc, int irq)
                if (desc->chip->ack)
                        desc->chip->ack(irq);
        }
+       desc->status |= IRQ_MASKED;
+}
+
+static inline void mask_irq(struct irq_desc *desc, int irq)
+{
+       if (desc->chip->mask) {
+               desc->chip->mask(irq);
+               desc->status |= IRQ_MASKED;
+       }
+}
+
+static inline void unmask_irq(struct irq_desc *desc, int irq)
+{
+       if (desc->chip->unmask) {
+               desc->chip->unmask(irq);
+               desc->status &= ~IRQ_MASKED;
+       }
 }
 
 /*
@@ -484,10 +501,8 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
        raw_spin_lock(&desc->lock);
        desc->status &= ~IRQ_INPROGRESS;
 
-       if (unlikely(desc->status & IRQ_ONESHOT))
-               desc->status |= IRQ_MASKED;
-       else if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
-               desc->chip->unmask(irq);
+       if (!(desc->status & (IRQ_DISABLED | IRQ_ONESHOT)))
+               unmask_irq(desc, irq);
 out_unlock:
        raw_spin_unlock(&desc->lock);
 }
@@ -524,8 +539,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
        action = desc->action;
        if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
                desc->status |= IRQ_PENDING;
-               if (desc->chip->mask)
-                       desc->chip->mask(irq);
+               mask_irq(desc, irq);
                goto out;
        }
 
@@ -593,7 +607,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
                irqreturn_t action_ret;
 
                if (unlikely(!action)) {
-                       desc->chip->mask(irq);
+                       mask_irq(desc, irq);
                        goto out_unlock;
                }
 
@@ -605,8 +619,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
                if (unlikely((desc->status &
                               (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) ==
                              (IRQ_PENDING | IRQ_MASKED))) {
-                       desc->chip->unmask(irq);
-                       desc->status &= ~IRQ_MASKED;
+                       unmask_irq(desc, irq);
                }
 
                desc->status &= ~IRQ_PENDING;
@@ -716,7 +729,7 @@ set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
        __set_irq_handler(irq, handle, 0, name);
 }
 
-void __init set_irq_noprobe(unsigned int irq)
+void set_irq_noprobe(unsigned int irq)
 {
        struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
@@ -731,7 +744,7 @@ void __init set_irq_noprobe(unsigned int irq)
        raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
 
-void __init set_irq_probe(unsigned int irq)
+void set_irq_probe(unsigned int irq)
 {
        struct irq_desc *desc = irq_to_desc(irq);
        unsigned long flags;
index eb6078ca60c7f548a052aa42c247dbb8b24d9620..704e488730a517e12a138bba8286bb856c99f369 100644 (file)
@@ -382,6 +382,7 @@ int can_request_irq(unsigned int irq, unsigned long irqflags)
 {
        struct irq_desc *desc = irq_to_desc(irq);
        struct irqaction *action;
+       unsigned long flags;
 
        if (!desc)
                return 0;
@@ -389,11 +390,14 @@ int can_request_irq(unsigned int irq, unsigned long irqflags)
        if (desc->status & IRQ_NOREQUEST)
                return 0;
 
+       raw_spin_lock_irqsave(&desc->lock, flags);
        action = desc->action;
        if (action)
                if (irqflags & action->flags & IRQF_SHARED)
                        action = NULL;
 
+       raw_spin_unlock_irqrestore(&desc->lock, flags);
+
        return !action;
 }
 
@@ -483,8 +487,26 @@ static int irq_wait_for_interrupt(struct irqaction *action)
  */
 static void irq_finalize_oneshot(unsigned int irq, struct irq_desc *desc)
 {
+again:
        chip_bus_lock(irq, desc);
        raw_spin_lock_irq(&desc->lock);
+
+       /*
+        * Implausible though it may be we need to protect us against
+        * the following scenario:
+        *
+        * The thread is faster done than the hard interrupt handler
+        * on the other CPU. If we unmask the irq line then the
+        * interrupt can come in again and masks the line, leaves due
+        * to IRQ_INPROGRESS and the irq line is masked forever.
+        */
+       if (unlikely(desc->status & IRQ_INPROGRESS)) {
+               raw_spin_unlock_irq(&desc->lock);
+               chip_bus_sync_unlock(irq, desc);
+               cpu_relax();
+               goto again;
+       }
+
        if (!(desc->status & IRQ_DISABLED) && (desc->status & IRQ_MASKED)) {
                desc->status &= ~IRQ_MASKED;
                desc->chip->unmask(irq);
@@ -735,6 +757,16 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
                if (new->flags & IRQF_ONESHOT)
                        desc->status |= IRQ_ONESHOT;
 
+               /*
+                * Force MSI interrupts to run with interrupts
+                * disabled. The multi vector cards can cause stack
+                * overflows due to nested interrupts when enough of
+                * them are directed to a core and fire at the same
+                * time.
+                */
+               if (desc->msi_desc)
+                       new->flags |= IRQF_DISABLED;
+
                if (!(desc->status & IRQ_NOAUTOEN)) {
                        desc->depth = 0;
                        desc->status &= ~IRQ_DISABLED;
index 963559dbd858a4968913ea8d5790867630714668..65d3845665acad7ac0ad540c6f6f08805abf88eb 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/random.h>
 #include <linux/interrupt.h>
index 6f50eccc79c01e4f7b80a0a107d9a1adb183328d..7a6eb04ef6b587b37ca97a127186adfcc812886d 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/irq.h>
+#include <linux/gfp.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
index 8e5288a8a3555c419f477e0925f3210e3863cef6..13aff293f4def468c250a5215a0314162fa7deee 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/sched.h>       /* for cond_resched */
 #include <linux/mm.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 
 #include <asm/sections.h>
 
index 87ebe8adc474de72ec0db5882acda8b35c44cac4..474a84715eaca2936b51ad5a6c46fb4774751c5b 100644 (file)
@@ -1134,11 +1134,9 @@ int crash_shrink_memory(unsigned long new_size)
 
        free_reserved_phys_range(end, crashk_res.end);
 
-       if (start == end) {
-               crashk_res.end = end;
+       if (start == end)
                release_resource(&crashk_res);
-       } else
-               crashk_res.end = end - 1;
+       crashk_res.end = end - 1;
 
 unlock:
        mutex_unlock(&kexec_mutex);
index 761fdd2b3034ae87272578fe1314680af5c0d71f..11f3515ca83f6af2b4614d11ac429c2fdf56bb4f 100644 (file)
@@ -69,9 +69,16 @@ struct kgdb_state {
        struct pt_regs          *linux_regs;
 };
 
+/* Exception state values */
+#define DCPU_WANT_MASTER 0x1 /* Waiting to become a master kgdb cpu */
+#define DCPU_NEXT_MASTER 0x2 /* Transition from one master cpu to another */
+#define DCPU_IS_SLAVE    0x4 /* Slave cpu enter exception */
+#define DCPU_SSTEP       0x8 /* CPU is single stepping */
+
 static struct debuggerinfo_struct {
        void                    *debuggerinfo;
        struct task_struct      *task;
+       int                     exception_state;
 } kgdb_info[NR_CPUS];
 
 /**
@@ -391,27 +398,22 @@ int kgdb_mem2hex(char *mem, char *buf, int count)
 
 /*
  * Copy the binary array pointed to by buf into mem.  Fix $, #, and
- * 0x7d escaped with 0x7d.  Return a pointer to the character after
- * the last byte written.
+ * 0x7d escaped with 0x7d. Return -EFAULT on failure or 0 on success.
+ * The input buf is overwitten with the result to write to mem.
  */
 static int kgdb_ebin2mem(char *buf, char *mem, int count)
 {
-       int err = 0;
-       char c;
+       int size = 0;
+       char *c = buf;
 
        while (count-- > 0) {
-               c = *buf++;
-               if (c == 0x7d)
-                       c = *buf++ ^ 0x20;
-
-               err = probe_kernel_write(mem, &c, 1);
-               if (err)
-                       break;
-
-               mem++;
+               c[size] = *buf++;
+               if (c[size] == 0x7d)
+                       c[size] = *buf++ ^ 0x20;
+               size++;
        }
 
-       return err;
+       return probe_kernel_write(mem, c, size);
 }
 
 /*
@@ -562,49 +564,6 @@ static struct task_struct *getthread(struct pt_regs *regs, int tid)
        return find_task_by_pid_ns(tid, &init_pid_ns);
 }
 
-/*
- * CPU debug state control:
- */
-
-#ifdef CONFIG_SMP
-static void kgdb_wait(struct pt_regs *regs)
-{
-       unsigned long flags;
-       int cpu;
-
-       local_irq_save(flags);
-       cpu = raw_smp_processor_id();
-       kgdb_info[cpu].debuggerinfo = regs;
-       kgdb_info[cpu].task = current;
-       /*
-        * Make sure the above info reaches the primary CPU before
-        * our cpu_in_kgdb[] flag setting does:
-        */
-       smp_wmb();
-       atomic_set(&cpu_in_kgdb[cpu], 1);
-
-       /* Disable any cpu specific hw breakpoints */
-       kgdb_disable_hw_debug(regs);
-
-       /* Wait till primary CPU is done with debugging */
-       while (atomic_read(&passive_cpu_wait[cpu]))
-               cpu_relax();
-
-       kgdb_info[cpu].debuggerinfo = NULL;
-       kgdb_info[cpu].task = NULL;
-
-       /* fix up hardware debug registers on local cpu */
-       if (arch_kgdb_ops.correct_hw_break)
-               arch_kgdb_ops.correct_hw_break();
-
-       /* Signal the primary CPU that we are done: */
-       atomic_set(&cpu_in_kgdb[cpu], 0);
-       touch_softlockup_watchdog_sync();
-       clocksource_touch_watchdog();
-       local_irq_restore(flags);
-}
-#endif
-
 /*
  * Some architectures need cache flushes when we set/clear a
  * breakpoint:
@@ -1400,34 +1359,13 @@ static int kgdb_reenter_check(struct kgdb_state *ks)
        return 1;
 }
 
-/*
- * kgdb_handle_exception() - main entry point from a kernel exception
- *
- * Locking hierarchy:
- *     interface locks, if any (begin_session)
- *     kgdb lock (kgdb_active)
- */
-int
-kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs)
+static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs)
 {
-       struct kgdb_state kgdb_var;
-       struct kgdb_state *ks = &kgdb_var;
        unsigned long flags;
        int sstep_tries = 100;
        int error = 0;
        int i, cpu;
-
-       ks->cpu                 = raw_smp_processor_id();
-       ks->ex_vector           = evector;
-       ks->signo               = signo;
-       ks->ex_vector           = evector;
-       ks->err_code            = ecode;
-       ks->kgdb_usethreadid    = 0;
-       ks->linux_regs          = regs;
-
-       if (kgdb_reenter_check(ks))
-               return 0; /* Ouch, double exception ! */
-
+       int trace_on = 0;
 acquirelock:
        /*
         * Interrupts will be restored by the 'trap return' code, except when
@@ -1435,13 +1373,43 @@ acquirelock:
         */
        local_irq_save(flags);
 
-       cpu = raw_smp_processor_id();
+       cpu = ks->cpu;
+       kgdb_info[cpu].debuggerinfo = regs;
+       kgdb_info[cpu].task = current;
+       /*
+        * Make sure the above info reaches the primary CPU before
+        * our cpu_in_kgdb[] flag setting does:
+        */
+       atomic_inc(&cpu_in_kgdb[cpu]);
 
        /*
-        * Acquire the kgdb_active lock:
+        * CPU will loop if it is a slave or request to become a kgdb
+        * master cpu and acquire the kgdb_active lock:
         */
-       while (atomic_cmpxchg(&kgdb_active, -1, cpu) != -1)
+       while (1) {
+               if (kgdb_info[cpu].exception_state & DCPU_WANT_MASTER) {
+                       if (atomic_cmpxchg(&kgdb_active, -1, cpu) == cpu)
+                               break;
+               } else if (kgdb_info[cpu].exception_state & DCPU_IS_SLAVE) {
+                       if (!atomic_read(&passive_cpu_wait[cpu]))
+                               goto return_normal;
+               } else {
+return_normal:
+                       /* Return to normal operation by executing any
+                        * hw breakpoint fixup.
+                        */
+                       if (arch_kgdb_ops.correct_hw_break)
+                               arch_kgdb_ops.correct_hw_break();
+                       if (trace_on)
+                               tracing_on();
+                       atomic_dec(&cpu_in_kgdb[cpu]);
+                       touch_softlockup_watchdog_sync();
+                       clocksource_touch_watchdog();
+                       local_irq_restore(flags);
+                       return 0;
+               }
                cpu_relax();
+       }
 
        /*
         * For single stepping, try to only enter on the processor
@@ -1475,9 +1443,6 @@ acquirelock:
        if (kgdb_io_ops->pre_exception)
                kgdb_io_ops->pre_exception();
 
-       kgdb_info[ks->cpu].debuggerinfo = ks->linux_regs;
-       kgdb_info[ks->cpu].task = current;
-
        kgdb_disable_hw_debug(ks->linux_regs);
 
        /*
@@ -1486,15 +1451,9 @@ acquirelock:
         */
        if (!kgdb_single_step) {
                for (i = 0; i < NR_CPUS; i++)
-                       atomic_set(&passive_cpu_wait[i], 1);
+                       atomic_inc(&passive_cpu_wait[i]);
        }
 
-       /*
-        * spin_lock code is good enough as a barrier so we don't
-        * need one here:
-        */
-       atomic_set(&cpu_in_kgdb[ks->cpu], 1);
-
 #ifdef CONFIG_SMP
        /* Signal the other CPUs to enter kgdb_wait() */
        if ((!kgdb_single_step) && kgdb_do_roundup)
@@ -1518,6 +1477,9 @@ acquirelock:
        kgdb_single_step = 0;
        kgdb_contthread = current;
        exception_level = 0;
+       trace_on = tracing_is_on();
+       if (trace_on)
+               tracing_off();
 
        /* Talk to debugger with gdbserial protocol */
        error = gdb_serial_stub(ks);
@@ -1526,13 +1488,11 @@ acquirelock:
        if (kgdb_io_ops->post_exception)
                kgdb_io_ops->post_exception();
 
-       kgdb_info[ks->cpu].debuggerinfo = NULL;
-       kgdb_info[ks->cpu].task = NULL;
-       atomic_set(&cpu_in_kgdb[ks->cpu], 0);
+       atomic_dec(&cpu_in_kgdb[ks->cpu]);
 
        if (!kgdb_single_step) {
                for (i = NR_CPUS-1; i >= 0; i--)
-                       atomic_set(&passive_cpu_wait[i], 0);
+                       atomic_dec(&passive_cpu_wait[i]);
                /*
                 * Wait till all the CPUs have quit
                 * from the debugger.
@@ -1551,6 +1511,8 @@ kgdb_restore:
                else
                        kgdb_sstep_pid = 0;
        }
+       if (trace_on)
+               tracing_on();
        /* Free kgdb_active */
        atomic_set(&kgdb_active, -1);
        touch_softlockup_watchdog_sync();
@@ -1560,13 +1522,52 @@ kgdb_restore:
        return error;
 }
 
+/*
+ * kgdb_handle_exception() - main entry point from a kernel exception
+ *
+ * Locking hierarchy:
+ *     interface locks, if any (begin_session)
+ *     kgdb lock (kgdb_active)
+ */
+int
+kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs)
+{
+       struct kgdb_state kgdb_var;
+       struct kgdb_state *ks = &kgdb_var;
+       int ret;
+
+       ks->cpu                 = raw_smp_processor_id();
+       ks->ex_vector           = evector;
+       ks->signo               = signo;
+       ks->ex_vector           = evector;
+       ks->err_code            = ecode;
+       ks->kgdb_usethreadid    = 0;
+       ks->linux_regs          = regs;
+
+       if (kgdb_reenter_check(ks))
+               return 0; /* Ouch, double exception ! */
+       kgdb_info[ks->cpu].exception_state |= DCPU_WANT_MASTER;
+       ret = kgdb_cpu_enter(ks, regs);
+       kgdb_info[ks->cpu].exception_state &= ~DCPU_WANT_MASTER;
+       return ret;
+}
+
 int kgdb_nmicallback(int cpu, void *regs)
 {
 #ifdef CONFIG_SMP
+       struct kgdb_state kgdb_var;
+       struct kgdb_state *ks = &kgdb_var;
+
+       memset(ks, 0, sizeof(struct kgdb_state));
+       ks->cpu                 = cpu;
+       ks->linux_regs          = regs;
+
        if (!atomic_read(&cpu_in_kgdb[cpu]) &&
-                       atomic_read(&kgdb_active) != cpu &&
-                       atomic_read(&cpu_in_kgdb[atomic_read(&kgdb_active)])) {
-               kgdb_wait((struct pt_regs *)regs);
+           atomic_read(&kgdb_active) != -1 &&
+           atomic_read(&kgdb_active) != cpu) {
+               kgdb_info[cpu].exception_state |= DCPU_IS_SLAVE;
+               kgdb_cpu_enter(ks, regs);
+               kgdb_info[cpu].exception_state &= ~DCPU_IS_SLAVE;
                return 0;
        }
 #endif
@@ -1742,11 +1743,11 @@ EXPORT_SYMBOL_GPL(kgdb_unregister_io_module);
  */
 void kgdb_breakpoint(void)
 {
-       atomic_set(&kgdb_setting_breakpoint, 1);
+       atomic_inc(&kgdb_setting_breakpoint);
        wmb(); /* Sync point before breakpoint */
        arch_kgdb_breakpoint();
        wmb(); /* Sync point after breakpoint */
-       atomic_set(&kgdb_setting_breakpoint, 0);
+       atomic_dec(&kgdb_setting_breakpoint);
 }
 EXPORT_SYMBOL_GPL(kgdb_breakpoint);
 
index fa034d29cf73d5730f531b7bfd98682278d077b4..282035f3ae964e1e288f352c370be8edd11d3078 100644 (file)
@@ -259,7 +259,8 @@ static void __kprobes __free_insn_slot(struct kprobe_insn_cache *c,
        struct kprobe_insn_page *kip;
 
        list_for_each_entry(kip, &c->pages, list) {
-               long idx = ((long)slot - (long)kip->insns) / c->insn_size;
+               long idx = ((long)slot - (long)kip->insns) /
+                               (c->insn_size * sizeof(kprobe_opcode_t));
                if (idx >= 0 && idx < slots_per_page(c)) {
                        WARN_ON(kip->slot_used[idx] != SLOT_USED);
                        if (dirty) {
@@ -1587,6 +1588,72 @@ static void __kprobes kill_kprobe(struct kprobe *p)
        arch_remove_kprobe(p);
 }
 
+/* Disable one kprobe */
+int __kprobes disable_kprobe(struct kprobe *kp)
+{
+       int ret = 0;
+       struct kprobe *p;
+
+       mutex_lock(&kprobe_mutex);
+
+       /* Check whether specified probe is valid. */
+       p = __get_valid_kprobe(kp);
+       if (unlikely(p == NULL)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       /* If the probe is already disabled (or gone), just return */
+       if (kprobe_disabled(kp))
+               goto out;
+
+       kp->flags |= KPROBE_FLAG_DISABLED;
+       if (p != kp)
+               /* When kp != p, p is always enabled. */
+               try_to_disable_aggr_kprobe(p);
+
+       if (!kprobes_all_disarmed && kprobe_disabled(p))
+               disarm_kprobe(p);
+out:
+       mutex_unlock(&kprobe_mutex);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(disable_kprobe);
+
+/* Enable one kprobe */
+int __kprobes enable_kprobe(struct kprobe *kp)
+{
+       int ret = 0;
+       struct kprobe *p;
+
+       mutex_lock(&kprobe_mutex);
+
+       /* Check whether specified probe is valid. */
+       p = __get_valid_kprobe(kp);
+       if (unlikely(p == NULL)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (kprobe_gone(kp)) {
+               /* This kprobe has gone, we couldn't enable it. */
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (p != kp)
+               kp->flags &= ~KPROBE_FLAG_DISABLED;
+
+       if (!kprobes_all_disarmed && kprobe_disabled(p)) {
+               p->flags &= ~KPROBE_FLAG_DISABLED;
+               arm_kprobe(p);
+       }
+out:
+       mutex_unlock(&kprobe_mutex);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(enable_kprobe);
+
 void __kprobes dump_kprobe(struct kprobe *kp)
 {
        printk(KERN_WARNING "Dumping kprobe:\n");
@@ -1804,72 +1871,6 @@ static const struct file_operations debugfs_kprobes_operations = {
        .release        = seq_release,
 };
 
-/* Disable one kprobe */
-int __kprobes disable_kprobe(struct kprobe *kp)
-{
-       int ret = 0;
-       struct kprobe *p;
-
-       mutex_lock(&kprobe_mutex);
-
-       /* Check whether specified probe is valid. */
-       p = __get_valid_kprobe(kp);
-       if (unlikely(p == NULL)) {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       /* If the probe is already disabled (or gone), just return */
-       if (kprobe_disabled(kp))
-               goto out;
-
-       kp->flags |= KPROBE_FLAG_DISABLED;
-       if (p != kp)
-               /* When kp != p, p is always enabled. */
-               try_to_disable_aggr_kprobe(p);
-
-       if (!kprobes_all_disarmed && kprobe_disabled(p))
-               disarm_kprobe(p);
-out:
-       mutex_unlock(&kprobe_mutex);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(disable_kprobe);
-
-/* Enable one kprobe */
-int __kprobes enable_kprobe(struct kprobe *kp)
-{
-       int ret = 0;
-       struct kprobe *p;
-
-       mutex_lock(&kprobe_mutex);
-
-       /* Check whether specified probe is valid. */
-       p = __get_valid_kprobe(kp);
-       if (unlikely(p == NULL)) {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       if (kprobe_gone(kp)) {
-               /* This kprobe has gone, we couldn't enable it. */
-               ret = -EINVAL;
-               goto out;
-       }
-
-       if (p != kp)
-               kp->flags &= ~KPROBE_FLAG_DISABLED;
-
-       if (!kprobes_all_disarmed && kprobe_disabled(p)) {
-               p->flags &= ~KPROBE_FLAG_DISABLED;
-               arm_kprobe(p);
-       }
-out:
-       mutex_unlock(&kprobe_mutex);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(enable_kprobe);
-
 static void __kprobes arm_all_kprobes(void)
 {
        struct hlist_head *head;
index 82ed0ea15194caf27c72dd3a40d459731eb718df..83911c7801751dd847348145db20f4e3e40e33b6 100644 (file)
@@ -219,7 +219,7 @@ int kthreadd(void *unused)
        set_task_comm(tsk, "kthreadd");
        ignore_signals(tsk);
        set_cpus_allowed_ptr(tsk, cpu_all_mask);
-       set_mems_allowed(node_possible_map);
+       set_mems_allowed(node_states[N_HIGH_MEMORY]);
 
        current->flags |= PF_NOFREEZE | PF_FREEZER_NOSIG;
 
index ca07c5c0c914186de89fb26e7323193375051178..877fb306d4154465e184e19b73ca1984a179aece 100644 (file)
@@ -56,7 +56,6 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/list.h>
-#include <linux/slab.h>
 #include <linux/stacktrace.h>
 
 static DEFINE_SPINLOCK(latency_lock);
index 681bc2e1e1871209f36cd54baf7e80b29117d479..ec21304856d102814a796ef511f02d728f58a380 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/ftrace.h>
 #include <linux/stringify.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 
 #include <asm/sections.h>
 
@@ -430,20 +431,7 @@ static struct stack_trace lockdep_init_trace = {
 /*
  * Various lockdep statistics:
  */
-atomic_t chain_lookup_hits;
-atomic_t chain_lookup_misses;
-atomic_t hardirqs_on_events;
-atomic_t hardirqs_off_events;
-atomic_t redundant_hardirqs_on;
-atomic_t redundant_hardirqs_off;
-atomic_t softirqs_on_events;
-atomic_t softirqs_off_events;
-atomic_t redundant_softirqs_on;
-atomic_t redundant_softirqs_off;
-atomic_t nr_unused_locks;
-atomic_t nr_cyclic_checks;
-atomic_t nr_find_usage_forwards_checks;
-atomic_t nr_find_usage_backwards_checks;
+DEFINE_PER_CPU(struct lockdep_stats, lockdep_stats);
 #endif
 
 /*
@@ -582,9 +570,6 @@ static int static_obj(void *obj)
        unsigned long start = (unsigned long) &_stext,
                      end   = (unsigned long) &_end,
                      addr  = (unsigned long) obj;
-#ifdef CONFIG_SMP
-       int i;
-#endif
 
        /*
         * static variable?
@@ -595,24 +580,16 @@ static int static_obj(void *obj)
        if (arch_is_kernel_data(addr))
                return 1;
 
-#ifdef CONFIG_SMP
        /*
-        * percpu var?
+        * in-kernel percpu var?
         */
-       for_each_possible_cpu(i) {
-               start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
-               end   = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
-                                       + per_cpu_offset(i);
-
-               if ((addr >= start) && (addr < end))
-                       return 1;
-       }
-#endif
+       if (is_kernel_percpu_address(addr))
+               return 1;
 
        /*
-        * module var?
+        * module static or percpu var?
         */
-       return is_module_address(addr);
+       return is_module_address(addr) || is_module_percpu_address(addr);
 }
 
 /*
@@ -758,7 +735,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
                return NULL;
        }
        class = lock_classes + nr_lock_classes++;
-       debug_atomic_inc(&nr_unused_locks);
+       debug_atomic_inc(nr_unused_locks);
        class->key = key;
        class->name = lock->name;
        class->subclass = subclass;
@@ -828,7 +805,8 @@ static struct lock_list *alloc_list_entry(void)
  * Add a new dependency to the head of the list:
  */
 static int add_lock_to_list(struct lock_class *class, struct lock_class *this,
-                           struct list_head *head, unsigned long ip, int distance)
+                           struct list_head *head, unsigned long ip,
+                           int distance, struct stack_trace *trace)
 {
        struct lock_list *entry;
        /*
@@ -839,11 +817,9 @@ static int add_lock_to_list(struct lock_class *class, struct lock_class *this,
        if (!entry)
                return 0;
 
-       if (!save_trace(&entry->trace))
-               return 0;
-
        entry->class = this;
        entry->distance = distance;
+       entry->trace = *trace;
        /*
         * Since we never remove from the dependency list, the list can
         * be walked lockless by other CPUs, it's only allocation
@@ -1215,7 +1191,7 @@ check_noncircular(struct lock_list *root, struct lock_class *target,
 {
        int result;
 
-       debug_atomic_inc(&nr_cyclic_checks);
+       debug_atomic_inc(nr_cyclic_checks);
 
        result = __bfs_forwards(root, target, class_equal, target_entry);
 
@@ -1252,7 +1228,7 @@ find_usage_forwards(struct lock_list *root, enum lock_usage_bit bit,
 {
        int result;
 
-       debug_atomic_inc(&nr_find_usage_forwards_checks);
+       debug_atomic_inc(nr_find_usage_forwards_checks);
 
        result = __bfs_forwards(root, (void *)bit, usage_match, target_entry);
 
@@ -1275,7 +1251,7 @@ find_usage_backwards(struct lock_list *root, enum lock_usage_bit bit,
 {
        int result;
 
-       debug_atomic_inc(&nr_find_usage_backwards_checks);
+       debug_atomic_inc(nr_find_usage_backwards_checks);
 
        result = __bfs_backwards(root, (void *)bit, usage_match, target_entry);
 
@@ -1645,12 +1621,20 @@ check_deadlock(struct task_struct *curr, struct held_lock *next,
  */
 static int
 check_prev_add(struct task_struct *curr, struct held_lock *prev,
-              struct held_lock *next, int distance)
+              struct held_lock *next, int distance, int trylock_loop)
 {
        struct lock_list *entry;
        int ret;
        struct lock_list this;
        struct lock_list *uninitialized_var(target_entry);
+       /*
+        * Static variable, serialized by the graph_lock().
+        *
+        * We use this static variable to save the stack trace in case
+        * we call into this function multiple times due to encountering
+        * trylocks in the held lock stack.
+        */
+       static struct stack_trace trace;
 
        /*
         * Prove that the new <prev> -> <next> dependency would not
@@ -1698,20 +1682,23 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
                }
        }
 
+       if (!trylock_loop && !save_trace(&trace))
+               return 0;
+
        /*
         * Ok, all validations passed, add the new lock
         * to the previous lock's dependency list:
         */
        ret = add_lock_to_list(hlock_class(prev), hlock_class(next),
                               &hlock_class(prev)->locks_after,
-                              next->acquire_ip, distance);
+                              next->acquire_ip, distance, &trace);
 
        if (!ret)
                return 0;
 
        ret = add_lock_to_list(hlock_class(next), hlock_class(prev),
                               &hlock_class(next)->locks_before,
-                              next->acquire_ip, distance);
+                              next->acquire_ip, distance, &trace);
        if (!ret)
                return 0;
 
@@ -1741,6 +1728,7 @@ static int
 check_prevs_add(struct task_struct *curr, struct held_lock *next)
 {
        int depth = curr->lockdep_depth;
+       int trylock_loop = 0;
        struct held_lock *hlock;
 
        /*
@@ -1766,7 +1754,8 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)
                 * added:
                 */
                if (hlock->read != 2) {
-                       if (!check_prev_add(curr, hlock, next, distance))
+                       if (!check_prev_add(curr, hlock, next,
+                                               distance, trylock_loop))
                                return 0;
                        /*
                         * Stop after the first non-trylock entry,
@@ -1789,6 +1778,7 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)
                if (curr->held_locks[depth].irq_context !=
                                curr->held_locks[depth-1].irq_context)
                        break;
+               trylock_loop = 1;
        }
        return 1;
 out_bug:
@@ -1835,7 +1825,7 @@ static inline int lookup_chain_cache(struct task_struct *curr,
        list_for_each_entry(chain, hash_head, entry) {
                if (chain->chain_key == chain_key) {
 cache_hit:
-                       debug_atomic_inc(&chain_lookup_hits);
+                       debug_atomic_inc(chain_lookup_hits);
                        if (very_verbose(class))
                                printk("\nhash chain already cached, key: "
                                        "%016Lx tail class: [%p] %s\n",
@@ -1900,7 +1890,7 @@ cache_hit:
                chain_hlocks[chain->base + j] = class - lock_classes;
        }
        list_add_tail_rcu(&chain->entry, hash_head);
-       debug_atomic_inc(&chain_lookup_misses);
+       debug_atomic_inc(chain_lookup_misses);
        inc_chains();
 
        return 1;
@@ -2321,7 +2311,12 @@ void trace_hardirqs_on_caller(unsigned long ip)
                return;
 
        if (unlikely(curr->hardirqs_enabled)) {
-               debug_atomic_inc(&redundant_hardirqs_on);
+               /*
+                * Neither irq nor preemption are disabled here
+                * so this is racy by nature but loosing one hit
+                * in a stat is not a big deal.
+                */
+               __debug_atomic_inc(redundant_hardirqs_on);
                return;
        }
        /* we'll do an OFF -> ON transition: */
@@ -2348,7 +2343,7 @@ void trace_hardirqs_on_caller(unsigned long ip)
 
        curr->hardirq_enable_ip = ip;
        curr->hardirq_enable_event = ++curr->irq_events;
-       debug_atomic_inc(&hardirqs_on_events);
+       debug_atomic_inc(hardirqs_on_events);
 }
 EXPORT_SYMBOL(trace_hardirqs_on_caller);
 
@@ -2380,9 +2375,9 @@ void trace_hardirqs_off_caller(unsigned long ip)
                curr->hardirqs_enabled = 0;
                curr->hardirq_disable_ip = ip;
                curr->hardirq_disable_event = ++curr->irq_events;
-               debug_atomic_inc(&hardirqs_off_events);
+               debug_atomic_inc(hardirqs_off_events);
        } else
-               debug_atomic_inc(&redundant_hardirqs_off);
+               debug_atomic_inc(redundant_hardirqs_off);
 }
 EXPORT_SYMBOL(trace_hardirqs_off_caller);
 
@@ -2406,7 +2401,7 @@ void trace_softirqs_on(unsigned long ip)
                return;
 
        if (curr->softirqs_enabled) {
-               debug_atomic_inc(&redundant_softirqs_on);
+               debug_atomic_inc(redundant_softirqs_on);
                return;
        }
 
@@ -2416,7 +2411,7 @@ void trace_softirqs_on(unsigned long ip)
        curr->softirqs_enabled = 1;
        curr->softirq_enable_ip = ip;
        curr->softirq_enable_event = ++curr->irq_events;
-       debug_atomic_inc(&softirqs_on_events);
+       debug_atomic_inc(softirqs_on_events);
        /*
         * We are going to turn softirqs on, so set the
         * usage bit for all held locks, if hardirqs are
@@ -2446,10 +2441,10 @@ void trace_softirqs_off(unsigned long ip)
                curr->softirqs_enabled = 0;
                curr->softirq_disable_ip = ip;
                curr->softirq_disable_event = ++curr->irq_events;
-               debug_atomic_inc(&softirqs_off_events);
+               debug_atomic_inc(softirqs_off_events);
                DEBUG_LOCKS_WARN_ON(!softirq_count());
        } else
-               debug_atomic_inc(&redundant_softirqs_off);
+               debug_atomic_inc(redundant_softirqs_off);
 }
 
 static void __lockdep_trace_alloc(gfp_t gfp_mask, unsigned long flags)
@@ -2654,7 +2649,7 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this,
                        return 0;
                break;
        case LOCK_USED:
-               debug_atomic_dec(&nr_unused_locks);
+               debug_atomic_dec(nr_unused_locks);
                break;
        default:
                if (!debug_locks_off_graph_unlock())
@@ -2760,7 +2755,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
                if (!class)
                        return 0;
        }
-       debug_atomic_inc((atomic_t *)&class->ops);
+       atomic_inc((atomic_t *)&class->ops);
        if (very_verbose(class)) {
                printk("\nacquire class [%p] %s", class->key, class->name);
                if (class->name_version > 1)
@@ -3211,8 +3206,6 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
 {
        unsigned long flags;
 
-       trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip);
-
        if (unlikely(current->lockdep_recursion))
                return;
 
@@ -3220,6 +3213,7 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
        check_flags(flags);
 
        current->lockdep_recursion = 1;
+       trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip);
        __lock_acquire(lock, subclass, trylock, read, check,
                       irqs_disabled_flags(flags), nest_lock, ip, 0);
        current->lockdep_recursion = 0;
@@ -3232,14 +3226,13 @@ void lock_release(struct lockdep_map *lock, int nested,
 {
        unsigned long flags;
 
-       trace_lock_release(lock, nested, ip);
-
        if (unlikely(current->lockdep_recursion))
                return;
 
        raw_local_irq_save(flags);
        check_flags(flags);
        current->lockdep_recursion = 1;
+       trace_lock_release(lock, ip);
        __lock_release(lock, nested, ip);
        current->lockdep_recursion = 0;
        raw_local_irq_restore(flags);
@@ -3392,7 +3385,7 @@ found_it:
                hlock->holdtime_stamp = now;
        }
 
-       trace_lock_acquired(lock, ip, waittime);
+       trace_lock_acquired(lock, ip);
 
        stats = get_lock_stats(hlock_class(hlock));
        if (waittime) {
@@ -3413,8 +3406,6 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip)
 {
        unsigned long flags;
 
-       trace_lock_contended(lock, ip);
-
        if (unlikely(!lock_stat))
                return;
 
@@ -3424,6 +3415,7 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip)
        raw_local_irq_save(flags);
        check_flags(flags);
        current->lockdep_recursion = 1;
+       trace_lock_contended(lock, ip);
        __lock_contended(lock, ip);
        current->lockdep_recursion = 0;
        raw_local_irq_restore(flags);
@@ -3814,8 +3806,11 @@ void lockdep_rcu_dereference(const char *file, const int line)
 {
        struct task_struct *curr = current;
 
+#ifndef CONFIG_PROVE_RCU_REPEATEDLY
        if (!debug_locks_off())
                return;
+#endif /* #ifdef CONFIG_PROVE_RCU_REPEATEDLY */
+       /* Note: the following can be executed concurrently, so be careful. */
        printk("\n===================================================\n");
        printk(  "[ INFO: suspicious rcu_dereference_check() usage. ]\n");
        printk(  "---------------------------------------------------\n");
index a2ee95ad13139d3361596e413834db43ec819dab..4f560cfedc8fd038c4dd09bfb590a9932fbd1193 100644 (file)
@@ -110,30 +110,60 @@ lockdep_count_backward_deps(struct lock_class *class)
 #endif
 
 #ifdef CONFIG_DEBUG_LOCKDEP
+
+#include <asm/local.h>
 /*
- * Various lockdep statistics:
+ * Various lockdep statistics.
+ * We want them per cpu as they are often accessed in fast path
+ * and we want to avoid too much cache bouncing.
  */
-extern atomic_t chain_lookup_hits;
-extern atomic_t chain_lookup_misses;
-extern atomic_t hardirqs_on_events;
-extern atomic_t hardirqs_off_events;
-extern atomic_t redundant_hardirqs_on;
-extern atomic_t redundant_hardirqs_off;
-extern atomic_t softirqs_on_events;
-extern atomic_t softirqs_off_events;
-extern atomic_t redundant_softirqs_on;
-extern atomic_t redundant_softirqs_off;
-extern atomic_t nr_unused_locks;
-extern atomic_t nr_cyclic_checks;
-extern atomic_t nr_cyclic_check_recursions;
-extern atomic_t nr_find_usage_forwards_checks;
-extern atomic_t nr_find_usage_forwards_recursions;
-extern atomic_t nr_find_usage_backwards_checks;
-extern atomic_t nr_find_usage_backwards_recursions;
-# define debug_atomic_inc(ptr)         atomic_inc(ptr)
-# define debug_atomic_dec(ptr)         atomic_dec(ptr)
-# define debug_atomic_read(ptr)                atomic_read(ptr)
+struct lockdep_stats {
+       int     chain_lookup_hits;
+       int     chain_lookup_misses;
+       int     hardirqs_on_events;
+       int     hardirqs_off_events;
+       int     redundant_hardirqs_on;
+       int     redundant_hardirqs_off;
+       int     softirqs_on_events;
+       int     softirqs_off_events;
+       int     redundant_softirqs_on;
+       int     redundant_softirqs_off;
+       int     nr_unused_locks;
+       int     nr_cyclic_checks;
+       int     nr_cyclic_check_recursions;
+       int     nr_find_usage_forwards_checks;
+       int     nr_find_usage_forwards_recursions;
+       int     nr_find_usage_backwards_checks;
+       int     nr_find_usage_backwards_recursions;
+};
+
+DECLARE_PER_CPU(struct lockdep_stats, lockdep_stats);
+
+#define __debug_atomic_inc(ptr)                                        \
+       this_cpu_inc(lockdep_stats.ptr);
+
+#define debug_atomic_inc(ptr)                  {               \
+       WARN_ON_ONCE(!irqs_disabled());                         \
+       __this_cpu_inc(lockdep_stats.ptr);                      \
+}
+
+#define debug_atomic_dec(ptr)                  {               \
+       WARN_ON_ONCE(!irqs_disabled());                         \
+       __this_cpu_dec(lockdep_stats.ptr);                      \
+}
+
+#define debug_atomic_read(ptr)         ({                              \
+       struct lockdep_stats *__cpu_lockdep_stats;                      \
+       unsigned long long __total = 0;                                 \
+       int __cpu;                                                      \
+       for_each_possible_cpu(__cpu) {                                  \
+               __cpu_lockdep_stats = &per_cpu(lockdep_stats, __cpu);   \
+               __total += __cpu_lockdep_stats->ptr;                    \
+       }                                                               \
+       __total;                                                        \
+})
 #else
+# define __debug_atomic_inc(ptr)       do { } while (0)
 # define debug_atomic_inc(ptr)         do { } while (0)
 # define debug_atomic_dec(ptr)         do { } while (0)
 # define debug_atomic_read(ptr)                0
index d4aba4f3584c73c3faff6ff5a0b73e27f6a7c5fb..59b76c8ce9d7172e8176f355da9719495077a133 100644 (file)
@@ -184,34 +184,34 @@ static const struct file_operations proc_lockdep_chains_operations = {
 static void lockdep_stats_debug_show(struct seq_file *m)
 {
 #ifdef CONFIG_DEBUG_LOCKDEP
-       unsigned int hi1 = debug_atomic_read(&hardirqs_on_events),
-                    hi2 = debug_atomic_read(&hardirqs_off_events),
-                    hr1 = debug_atomic_read(&redundant_hardirqs_on),
-                    hr2 = debug_atomic_read(&redundant_hardirqs_off),
-                    si1 = debug_atomic_read(&softirqs_on_events),
-                    si2 = debug_atomic_read(&softirqs_off_events),
-                    sr1 = debug_atomic_read(&redundant_softirqs_on),
-                    sr2 = debug_atomic_read(&redundant_softirqs_off);
-
-       seq_printf(m, " chain lookup misses:           %11u\n",
-               debug_atomic_read(&chain_lookup_misses));
-       seq_printf(m, " chain lookup hits:             %11u\n",
-               debug_atomic_read(&chain_lookup_hits));
-       seq_printf(m, " cyclic checks:                 %11u\n",
-               debug_atomic_read(&nr_cyclic_checks));
-       seq_printf(m, " find-mask forwards checks:     %11u\n",
-               debug_atomic_read(&nr_find_usage_forwards_checks));
-       seq_printf(m, " find-mask backwards checks:    %11u\n",
-               debug_atomic_read(&nr_find_usage_backwards_checks));
-
-       seq_printf(m, " hardirq on events:             %11u\n", hi1);
-       seq_printf(m, " hardirq off events:            %11u\n", hi2);
-       seq_printf(m, " redundant hardirq ons:         %11u\n", hr1);
-       seq_printf(m, " redundant hardirq offs:        %11u\n", hr2);
-       seq_printf(m, " softirq on events:             %11u\n", si1);
-       seq_printf(m, " softirq off events:            %11u\n", si2);
-       seq_printf(m, " redundant softirq ons:         %11u\n", sr1);
-       seq_printf(m, " redundant softirq offs:        %11u\n", sr2);
+       unsigned long long hi1 = debug_atomic_read(hardirqs_on_events),
+                          hi2 = debug_atomic_read(hardirqs_off_events),
+                          hr1 = debug_atomic_read(redundant_hardirqs_on),
+                          hr2 = debug_atomic_read(redundant_hardirqs_off),
+                          si1 = debug_atomic_read(softirqs_on_events),
+                          si2 = debug_atomic_read(softirqs_off_events),
+                          sr1 = debug_atomic_read(redundant_softirqs_on),
+                          sr2 = debug_atomic_read(redundant_softirqs_off);
+
+       seq_printf(m, " chain lookup misses:           %11llu\n",
+               debug_atomic_read(chain_lookup_misses));
+       seq_printf(m, " chain lookup hits:             %11llu\n",
+               debug_atomic_read(chain_lookup_hits));
+       seq_printf(m, " cyclic checks:                 %11llu\n",
+               debug_atomic_read(nr_cyclic_checks));
+       seq_printf(m, " find-mask forwards checks:     %11llu\n",
+               debug_atomic_read(nr_find_usage_forwards_checks));
+       seq_printf(m, " find-mask backwards checks:    %11llu\n",
+               debug_atomic_read(nr_find_usage_backwards_checks));
+
+       seq_printf(m, " hardirq on events:             %11llu\n", hi1);
+       seq_printf(m, " hardirq off events:            %11llu\n", hi2);
+       seq_printf(m, " redundant hardirq ons:         %11llu\n", hr1);
+       seq_printf(m, " redundant hardirq offs:        %11llu\n", hr2);
+       seq_printf(m, " softirq on events:             %11llu\n", si1);
+       seq_printf(m, " softirq off events:            %11llu\n", si2);
+       seq_printf(m, " redundant softirq ons:         %11llu\n", sr1);
+       seq_printf(m, " redundant softirq offs:        %11llu\n", sr2);
 #endif
 }
 
@@ -263,7 +263,7 @@ static int lockdep_stats_show(struct seq_file *m, void *v)
 #endif
        }
 #ifdef CONFIG_DEBUG_LOCKDEP
-       DEBUG_LOCKS_WARN_ON(debug_atomic_read(&nr_unused_locks) != nr_unused);
+       DEBUG_LOCKS_WARN_ON(debug_atomic_read(nr_unused_locks) != nr_unused);
 #endif
        seq_printf(m, " lock-classes:                  %11lu [max: %lu]\n",
                        nr_lock_classes, MAX_LOCKDEP_KEYS);
index c968d3606dca8cbf9d4e3ba04bcb0a48091024e9..e2564580f3f113ec9d391a7ad45beea842d39620 100644 (file)
@@ -59,8 +59,6 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/module.h>
 
-EXPORT_TRACEPOINT_SYMBOL(module_get);
-
 #if 0
 #define DEBUGP printk
 #else
@@ -370,27 +368,33 @@ EXPORT_SYMBOL_GPL(find_module);
 
 #ifdef CONFIG_SMP
 
-static void *percpu_modalloc(unsigned long size, unsigned long align,
-                            const char *name)
+static inline void __percpu *mod_percpu(struct module *mod)
 {
-       void *ptr;
+       return mod->percpu;
+}
 
+static int percpu_modalloc(struct module *mod,
+                          unsigned long size, unsigned long align)
+{
        if (align > PAGE_SIZE) {
                printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
-                      name, align, PAGE_SIZE);
+                      mod->name, align, PAGE_SIZE);
                align = PAGE_SIZE;
        }
 
-       ptr = __alloc_reserved_percpu(size, align);
-       if (!ptr)
+       mod->percpu = __alloc_reserved_percpu(size, align);
+       if (!mod->percpu) {
                printk(KERN_WARNING
                       "Could not allocate %lu bytes percpu data\n", size);
-       return ptr;
+               return -ENOMEM;
+       }
+       mod->percpu_size = size;
+       return 0;
 }
 
-static void percpu_modfree(void *freeme)
+static void percpu_modfree(struct module *mod)
 {
-       free_percpu(freeme);
+       free_percpu(mod->percpu);
 }
 
 static unsigned int find_pcpusec(Elf_Ehdr *hdr,
@@ -400,24 +404,62 @@ static unsigned int find_pcpusec(Elf_Ehdr *hdr,
        return find_sec(hdr, sechdrs, secstrings, ".data.percpu");
 }
 
-static void percpu_modcopy(void *pcpudest, const void *from, unsigned long size)
+static void percpu_modcopy(struct module *mod,
+                          const void *from, unsigned long size)
 {
        int cpu;
 
        for_each_possible_cpu(cpu)
-               memcpy(pcpudest + per_cpu_offset(cpu), from, size);
+               memcpy(per_cpu_ptr(mod->percpu, cpu), from, size);
+}
+
+/**
+ * is_module_percpu_address - test whether address is from module static percpu
+ * @addr: address to test
+ *
+ * Test whether @addr belongs to module static percpu area.
+ *
+ * RETURNS:
+ * %true if @addr is from module static percpu area
+ */
+bool is_module_percpu_address(unsigned long addr)
+{
+       struct module *mod;
+       unsigned int cpu;
+
+       preempt_disable();
+
+       list_for_each_entry_rcu(mod, &modules, list) {
+               if (!mod->percpu_size)
+                       continue;
+               for_each_possible_cpu(cpu) {
+                       void *start = per_cpu_ptr(mod->percpu, cpu);
+
+                       if ((void *)addr >= start &&
+                           (void *)addr < start + mod->percpu_size) {
+                               preempt_enable();
+                               return true;
+                       }
+               }
+       }
+
+       preempt_enable();
+       return false;
 }
 
 #else /* ... !CONFIG_SMP */
 
-static inline void *percpu_modalloc(unsigned long size, unsigned long align,
-                                   const char *name)
+static inline void __percpu *mod_percpu(struct module *mod)
 {
        return NULL;
 }
-static inline void percpu_modfree(void *pcpuptr)
+static inline int percpu_modalloc(struct module *mod,
+                                 unsigned long size, unsigned long align)
+{
+       return -ENOMEM;
+}
+static inline void percpu_modfree(struct module *mod)
 {
-       BUG();
 }
 static inline unsigned int find_pcpusec(Elf_Ehdr *hdr,
                                        Elf_Shdr *sechdrs,
@@ -425,12 +467,16 @@ static inline unsigned int find_pcpusec(Elf_Ehdr *hdr,
 {
        return 0;
 }
-static inline void percpu_modcopy(void *pcpudst, const void *src,
-                                 unsigned long size)
+static inline void percpu_modcopy(struct module *mod,
+                                 const void *from, unsigned long size)
 {
        /* pcpusec should be 0, and size of that section should be 0. */
        BUG_ON(size != 0);
 }
+bool is_module_percpu_address(unsigned long addr)
+{
+       return false;
+}
 
 #endif /* CONFIG_SMP */
 
@@ -467,17 +513,22 @@ MODINFO_ATTR(srcversion);
 static char last_unloaded_module[MODULE_NAME_LEN+1];
 
 #ifdef CONFIG_MODULE_UNLOAD
+
+EXPORT_TRACEPOINT_SYMBOL(module_get);
+
 /* Init the unload section of the module. */
 static void module_unload_init(struct module *mod)
 {
        int cpu;
 
        INIT_LIST_HEAD(&mod->modules_which_use_me);
-       for_each_possible_cpu(cpu)
-               per_cpu_ptr(mod->refptr, cpu)->count = 0;
+       for_each_possible_cpu(cpu) {
+               per_cpu_ptr(mod->refptr, cpu)->incs = 0;
+               per_cpu_ptr(mod->refptr, cpu)->decs = 0;
+       }
 
        /* Hold reference count during initialization. */
-       __this_cpu_write(mod->refptr->count, 1);
+       __this_cpu_write(mod->refptr->incs, 1);
        /* Backwards compatibility macros put refcount during init. */
        mod->waiter = current;
 }
@@ -616,12 +667,28 @@ static int try_stop_module(struct module *mod, int flags, int *forced)
 
 unsigned int module_refcount(struct module *mod)
 {
-       unsigned int total = 0;
+       unsigned int incs = 0, decs = 0;
        int cpu;
 
        for_each_possible_cpu(cpu)
-               total += per_cpu_ptr(mod->refptr, cpu)->count;
-       return total;
+               decs += per_cpu_ptr(mod->refptr, cpu)->decs;
+       /*
+        * ensure the incs are added up after the decs.
+        * module_put ensures incs are visible before decs with smp_wmb.
+        *
+        * This 2-count scheme avoids the situation where the refcount
+        * for CPU0 is read, then CPU0 increments the module refcount,
+        * then CPU1 drops that refcount, then the refcount for CPU1 is
+        * read. We would record a decrement but not its corresponding
+        * increment so we would see a low count (disaster).
+        *
+        * Rare situation? But module_refcount can be preempted, and we
+        * might be tallying up 4096+ CPUs. So it is not impossible.
+        */
+       smp_rmb();
+       for_each_possible_cpu(cpu)
+               incs += per_cpu_ptr(mod->refptr, cpu)->incs;
+       return incs - decs;
 }
 EXPORT_SYMBOL(module_refcount);
 
@@ -657,16 +724,8 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
                return -EFAULT;
        name[MODULE_NAME_LEN-1] = '\0';
 
-       /* Create stop_machine threads since free_module relies on
-        * a non-failing stop_machine call. */
-       ret = stop_machine_create();
-       if (ret)
-               return ret;
-
-       if (mutex_lock_interruptible(&module_mutex) != 0) {
-               ret = -EINTR;
-               goto out_stop;
-       }
+       if (mutex_lock_interruptible(&module_mutex) != 0)
+               return -EINTR;
 
        mod = find_module(name);
        if (!mod) {
@@ -726,8 +785,6 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
 
  out:
        mutex_unlock(&module_mutex);
-out_stop:
-       stop_machine_destroy();
        return ret;
 }
 
@@ -798,10 +855,10 @@ void module_put(struct module *module)
 {
        if (module) {
                preempt_disable();
-               __this_cpu_dec(module->refptr->count);
+               smp_wmb(); /* see comment in module_refcount */
+               __this_cpu_inc(module->refptr->decs);
 
-               trace_module_put(module, _RET_IP_,
-                                __this_cpu_read(module->refptr->count));
+               trace_module_put(module, _RET_IP_);
                /* Maybe they're waiting for us to drop reference? */
                if (unlikely(!module_is_live(module)))
                        wake_up_process(module->waiter);
@@ -1400,8 +1457,7 @@ static void free_module(struct module *mod)
        /* This may be NULL, but that's OK */
        module_free(mod, mod->module_init);
        kfree(mod->args);
-       if (mod->percpu)
-               percpu_modfree(mod->percpu);
+       percpu_modfree(mod);
 #if defined(CONFIG_MODULE_UNLOAD)
        if (mod->refptr)
                free_percpu(mod->refptr);
@@ -1520,7 +1576,7 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
                default:
                        /* Divert to percpu allocation if a percpu var. */
                        if (sym[i].st_shndx == pcpuindex)
-                               secbase = (unsigned long)mod->percpu;
+                               secbase = (unsigned long)mod_percpu(mod);
                        else
                                secbase = sechdrs[sym[i].st_shndx].sh_addr;
                        sym[i].st_value += secbase;
@@ -1954,7 +2010,7 @@ static noinline struct module *load_module(void __user *umod,
        unsigned int modindex, versindex, infoindex, pcpuindex;
        struct module *mod;
        long err = 0;
-       void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
+       void *ptr = NULL; /* Stops spurious gcc warning */
        unsigned long symoffs, stroffs, *strmap;
 
        mm_segment_t old_fs;
@@ -2094,15 +2150,11 @@ static noinline struct module *load_module(void __user *umod,
 
        if (pcpuindex) {
                /* We have a special allocation for this section. */
-               percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size,
-                                        sechdrs[pcpuindex].sh_addralign,
-                                        mod->name);
-               if (!percpu) {
-                       err = -ENOMEM;
+               err = percpu_modalloc(mod, sechdrs[pcpuindex].sh_size,
+                                     sechdrs[pcpuindex].sh_addralign);
+               if (err)
                        goto free_mod;
-               }
                sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
-               mod->percpu = percpu;
        }
 
        /* Determine total sizes, and put offsets in sh_entsize.  For now
@@ -2317,7 +2369,7 @@ static noinline struct module *load_module(void __user *umod,
        sort_extable(mod->extable, mod->extable + mod->num_exentries);
 
        /* Finally, copy percpu area over. */
-       percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
+       percpu_modcopy(mod, (void *)sechdrs[pcpuindex].sh_addr,
                       sechdrs[pcpuindex].sh_size);
 
        add_kallsyms(mod, sechdrs, hdr->e_shnum, symindex, strindex,
@@ -2409,8 +2461,7 @@ static noinline struct module *load_module(void __user *umod,
        module_free(mod, mod->module_core);
        /* mod will be freed with core. Don't access it beyond this line! */
  free_percpu:
-       if (percpu)
-               percpu_modfree(percpu);
+       percpu_modfree(mod);
  free_mod:
        kfree(args);
        kfree(strmap);
index 2ab67233ee8f71bf43fd7f746438c652c891419f..f74e6c00e26d1f50fb1c404b2a6e5505354882bf 100644 (file)
@@ -13,6 +13,7 @@
  *             Pavel Emelianov <xemul@openvz.org>
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/nsproxy.h>
 #include <linux/init_task.h>
index 93caf65ff57c80cf52ce215e51c65694060d95af..fd03513c7327f548c9eb990bfa94e78196fbefe8 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/padata.h>
 #include <linux/mutex.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/rcupdate.h>
 
 #define MAX_SEQ_NR INT_MAX - NR_CPUS
index 4393b9e73740b6bf76aebd59d94e1d8e51ed01d4..a4fa381db3c2de81b93d1f57708706d18d9702d3 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/smp.h>
 #include <linux/file.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/hash.h>
 #include <linux/sysfs.h>
 #include <linux/dcache.h>
 #include <linux/percpu.h>
@@ -81,41 +83,19 @@ extern __weak const struct pmu *hw_perf_event_init(struct perf_event *event)
 void __weak hw_perf_disable(void)              { barrier(); }
 void __weak hw_perf_enable(void)               { barrier(); }
 
-void __weak hw_perf_event_setup(int cpu)       { barrier(); }
-void __weak hw_perf_event_setup_online(int cpu)        { barrier(); }
-void __weak hw_perf_event_setup_offline(int cpu)       { barrier(); }
-
-int __weak
-hw_perf_group_sched_in(struct perf_event *group_leader,
-              struct perf_cpu_context *cpuctx,
-              struct perf_event_context *ctx)
-{
-       return 0;
-}
-
 void __weak perf_event_print_debug(void)       { }
 
 static DEFINE_PER_CPU(int, perf_disable_count);
 
-void __perf_disable(void)
-{
-       __get_cpu_var(perf_disable_count)++;
-}
-
-bool __perf_enable(void)
-{
-       return !--__get_cpu_var(perf_disable_count);
-}
-
 void perf_disable(void)
 {
-       __perf_disable();
-       hw_perf_disable();
+       if (!__get_cpu_var(perf_disable_count)++)
+               hw_perf_disable();
 }
 
 void perf_enable(void)
 {
-       if (__perf_enable())
+       if (!--__get_cpu_var(perf_disable_count))
                hw_perf_enable();
 }
 
@@ -275,6 +255,18 @@ static void update_event_times(struct perf_event *event)
        event->total_time_running = run_end - event->tstamp_running;
 }
 
+/*
+ * Update total_time_enabled and total_time_running for all events in a group.
+ */
+static void update_group_times(struct perf_event *leader)
+{
+       struct perf_event *event;
+
+       update_event_times(leader);
+       list_for_each_entry(event, &leader->sibling_list, group_entry)
+               update_event_times(event);
+}
+
 static struct list_head *
 ctx_group_list(struct perf_event *event, struct perf_event_context *ctx)
 {
@@ -328,8 +320,6 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx)
 static void
 list_del_event(struct perf_event *event, struct perf_event_context *ctx)
 {
-       struct perf_event *sibling, *tmp;
-
        if (list_empty(&event->group_entry))
                return;
        ctx->nr_events--;
@@ -342,7 +332,7 @@ 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);
+       update_group_times(event);
 
        /*
         * If event was in error state, then keep it
@@ -353,6 +343,12 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx)
         */
        if (event->state > PERF_EVENT_STATE_OFF)
                event->state = PERF_EVENT_STATE_OFF;
+}
+
+static void
+perf_destroy_group(struct perf_event *event, struct perf_event_context *ctx)
+{
+       struct perf_event *sibling, *tmp;
 
        /*
         * If this was a group event with sibling events then
@@ -517,18 +513,6 @@ retry:
        raw_spin_unlock_irq(&ctx->lock);
 }
 
-/*
- * Update total_time_enabled and total_time_running for all events in a group.
- */
-static void update_group_times(struct perf_event *leader)
-{
-       struct perf_event *event;
-
-       update_event_times(leader);
-       list_for_each_entry(event, &leader->sibling_list, group_entry)
-               update_event_times(event);
-}
-
 /*
  * Cross CPU call to disable a performance event
  */
@@ -653,15 +637,20 @@ group_sched_in(struct perf_event *group_event,
               struct perf_cpu_context *cpuctx,
               struct perf_event_context *ctx)
 {
-       struct perf_event *event, *partial_group;
+       struct perf_event *event, *partial_group = NULL;
+       const struct pmu *pmu = group_event->pmu;
+       bool txn = false;
        int ret;
 
        if (group_event->state == PERF_EVENT_STATE_OFF)
                return 0;
 
-       ret = hw_perf_group_sched_in(group_event, cpuctx, ctx);
-       if (ret)
-               return ret < 0 ? ret : 0;
+       /* Check if group transaction availabe */
+       if (pmu->start_txn)
+               txn = true;
+
+       if (txn)
+               pmu->start_txn(pmu);
 
        if (event_sched_in(group_event, cpuctx, ctx))
                return -EAGAIN;
@@ -676,9 +665,19 @@ group_sched_in(struct perf_event *group_event,
                }
        }
 
-       return 0;
+       if (!txn)
+               return 0;
+
+       ret = pmu->commit_txn(pmu);
+       if (!ret) {
+               pmu->cancel_txn(pmu);
+               return 0;
+       }
 
 group_error:
+       if (txn)
+               pmu->cancel_txn(pmu);
+
        /*
         * Groups can be scheduled in as one unit only, so undo any
         * partial group before returning:
@@ -1178,11 +1177,9 @@ void perf_event_task_sched_out(struct task_struct *task,
        struct perf_event_context *ctx = task->perf_event_ctxp;
        struct perf_event_context *next_ctx;
        struct perf_event_context *parent;
-       struct pt_regs *regs;
        int do_switch = 1;
 
-       regs = task_pt_regs(task);
-       perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, regs, 0);
+       perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0);
 
        if (likely(!ctx || !cpuctx->task_ctx))
                return;
@@ -1382,6 +1379,8 @@ void perf_event_task_sched_in(struct task_struct *task)
        if (cpuctx->task_ctx == ctx)
                return;
 
+       perf_disable();
+
        /*
         * We want to keep the following priority order:
         * cpu pinned (that don't need to move), task pinned,
@@ -1394,6 +1393,8 @@ void perf_event_task_sched_in(struct task_struct *task)
        ctx_sched_in(ctx, cpuctx, EVENT_FLEXIBLE);
 
        cpuctx->task_ctx = ctx;
+
+       perf_enable();
 }
 
 #define MAX_INTERRUPTS (~0ULL)
@@ -1538,12 +1539,15 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx)
                 */
                if (interrupts == MAX_INTERRUPTS) {
                        perf_log_throttle(event, 1);
+                       perf_disable();
                        event->pmu->unthrottle(event);
+                       perf_enable();
                }
 
                if (!event->attr.freq || !event->attr.sample_freq)
                        continue;
 
+               perf_disable();
                event->pmu->read(event);
                now = atomic64_read(&event->count);
                delta = now - hwc->freq_count_stamp;
@@ -1551,6 +1555,7 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx)
 
                if (delta > 0)
                        perf_adjust_period(event, TICK_NSEC, delta);
+               perf_enable();
        }
        raw_spin_unlock(&ctx->lock);
 }
@@ -1560,9 +1565,6 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx)
  */
 static void rotate_ctx(struct perf_event_context *ctx)
 {
-       if (!ctx->nr_events)
-               return;
-
        raw_spin_lock(&ctx->lock);
 
        /* Rotate the first entry last of non-pinned groups */
@@ -1575,19 +1577,28 @@ void perf_event_task_tick(struct task_struct *curr)
 {
        struct perf_cpu_context *cpuctx;
        struct perf_event_context *ctx;
+       int rotate = 0;
 
        if (!atomic_read(&nr_events))
                return;
 
        cpuctx = &__get_cpu_var(perf_cpu_context);
-       ctx = curr->perf_event_ctxp;
+       if (cpuctx->ctx.nr_events &&
+           cpuctx->ctx.nr_events != cpuctx->ctx.nr_active)
+               rotate = 1;
 
-       perf_disable();
+       ctx = curr->perf_event_ctxp;
+       if (ctx && ctx->nr_events && ctx->nr_events != ctx->nr_active)
+               rotate = 1;
 
        perf_ctx_adjust_freq(&cpuctx->ctx);
        if (ctx)
                perf_ctx_adjust_freq(ctx);
 
+       if (!rotate)
+               return;
+
+       perf_disable();
        cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE);
        if (ctx)
                task_ctx_sched_out(ctx, EVENT_FLEXIBLE);
@@ -1599,7 +1610,6 @@ void perf_event_task_tick(struct task_struct *curr)
        cpu_ctx_sched_in(cpuctx, EVENT_FLEXIBLE);
        if (ctx)
                task_ctx_sched_in(curr, EVENT_FLEXIBLE);
-
        perf_enable();
 }
 
@@ -1862,9 +1872,30 @@ int perf_event_release_kernel(struct perf_event *event)
 {
        struct perf_event_context *ctx = event->ctx;
 
+       /*
+        * Remove from the PMU, can't get re-enabled since we got
+        * here because the last ref went.
+        */
+       perf_event_disable(event);
+
        WARN_ON_ONCE(ctx->parent_ctx);
-       mutex_lock(&ctx->mutex);
-       perf_event_remove_from_context(event);
+       /*
+        * There are two ways this annotation is useful:
+        *
+        *  1) there is a lock recursion from perf_event_exit_task
+        *     see the comment there.
+        *
+        *  2) there is a lock-inversion with mmap_sem through
+        *     perf_event_read_group(), which takes faults while
+        *     holding ctx->mutex, however this is called after
+        *     the last filedesc died, so there is no possibility
+        *     to trigger the AB-BA case.
+        */
+       mutex_lock_nested(&ctx->mutex, SINGLE_DEPTH_NESTING);
+       raw_spin_lock_irq(&ctx->lock);
+       list_del_event(event, ctx);
+       perf_destroy_group(event, ctx);
+       raw_spin_unlock_irq(&ctx->lock);
        mutex_unlock(&ctx->mutex);
 
        mutex_lock(&event->owner->perf_event_mutex);
@@ -2648,6 +2679,7 @@ static int perf_fasync(int fd, struct file *filp, int on)
 }
 
 static const struct file_operations perf_fops = {
+       .llseek                 = no_llseek,
        .release                = perf_release,
        .read                   = perf_read,
        .poll                   = perf_poll,
@@ -2791,6 +2823,33 @@ __weak struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
        return NULL;
 }
 
+__weak
+void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip)
+{
+}
+
+
+/*
+ * We assume there is only KVM supporting the callbacks.
+ * Later on, we might change it to a list if there is
+ * another virtualization implementation supporting the callbacks.
+ */
+struct perf_guest_info_callbacks *perf_guest_cbs;
+
+int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
+{
+       perf_guest_cbs = cbs;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(perf_register_guest_info_callbacks);
+
+int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
+{
+       perf_guest_cbs = NULL;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks);
+
 /*
  * Output
  */
@@ -3376,15 +3435,23 @@ static void perf_event_task_output(struct perf_event *event,
                                     struct perf_task_event *task_event)
 {
        struct perf_output_handle handle;
-       int size;
        struct task_struct *task = task_event->task;
-       int ret;
+       unsigned long flags;
+       int size, ret;
+
+       /*
+        * If this CPU attempts to acquire an rq lock held by a CPU spinning
+        * in perf_output_lock() from interrupt context, it's game over.
+        */
+       local_irq_save(flags);
 
        size  = task_event->event_id.header.size;
        ret = perf_output_begin(&handle, event, size, 0, 0);
 
-       if (ret)
+       if (ret) {
+               local_irq_restore(flags);
                return;
+       }
 
        task_event->event_id.pid = perf_event_pid(event, task);
        task_event->event_id.ppid = perf_event_pid(event, current);
@@ -3395,6 +3462,7 @@ static void perf_event_task_output(struct perf_event *event,
        perf_output_put(&handle, task_event->event_id);
 
        perf_output_end(&handle);
+       local_irq_restore(flags);
 }
 
 static int perf_event_task_match(struct perf_event *event)
@@ -3734,7 +3802,7 @@ void __perf_event_mmap(struct vm_area_struct *vma)
                .event_id  = {
                        .header = {
                                .type = PERF_RECORD_MMAP,
-                               .misc = 0,
+                               .misc = PERF_RECORD_MISC_USER,
                                /* .size */
                        },
                        /* .pid */
@@ -3952,36 +4020,6 @@ static void perf_swevent_add(struct perf_event *event, u64 nr,
        perf_swevent_overflow(event, 0, nmi, data, regs);
 }
 
-static int perf_swevent_is_counting(struct perf_event *event)
-{
-       /*
-        * The event is active, we're good!
-        */
-       if (event->state == PERF_EVENT_STATE_ACTIVE)
-               return 1;
-
-       /*
-        * The event is off/error, not counting.
-        */
-       if (event->state != PERF_EVENT_STATE_INACTIVE)
-               return 0;
-
-       /*
-        * The event is inactive, if the context is active
-        * we're part of a group that didn't make it on the 'pmu',
-        * not counting.
-        */
-       if (event->ctx->is_active)
-               return 0;
-
-       /*
-        * We're inactive and the context is too, this means the
-        * task is scheduled out, we're counting events that happen
-        * to us, like migration events.
-        */
-       return 1;
-}
-
 static int perf_tp_event_match(struct perf_event *event,
                                struct perf_sample_data *data);
 
@@ -4005,12 +4043,6 @@ static int perf_swevent_match(struct perf_event *event,
                                struct perf_sample_data *data,
                                struct pt_regs *regs)
 {
-       if (event->cpu != -1 && event->cpu != smp_processor_id())
-               return 0;
-
-       if (!perf_swevent_is_counting(event))
-               return 0;
-
        if (event->attr.type != type)
                return 0;
 
@@ -4027,18 +4059,53 @@ static int perf_swevent_match(struct perf_event *event,
        return 1;
 }
 
-static void perf_swevent_ctx_event(struct perf_event_context *ctx,
-                                    enum perf_type_id type,
-                                    u32 event_id, u64 nr, int nmi,
-                                    struct perf_sample_data *data,
-                                    struct pt_regs *regs)
+static inline u64 swevent_hash(u64 type, u32 event_id)
+{
+       u64 val = event_id | (type << 32);
+
+       return hash_64(val, SWEVENT_HLIST_BITS);
+}
+
+static struct hlist_head *
+find_swevent_head(struct perf_cpu_context *ctx, u64 type, u32 event_id)
+{
+       u64 hash;
+       struct swevent_hlist *hlist;
+
+       hash = swevent_hash(type, event_id);
+
+       hlist = rcu_dereference(ctx->swevent_hlist);
+       if (!hlist)
+               return NULL;
+
+       return &hlist->heads[hash];
+}
+
+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;
        struct perf_event *event;
+       struct hlist_node *node;
+       struct hlist_head *head;
 
-       list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
+       cpuctx = &__get_cpu_var(perf_cpu_context);
+
+       rcu_read_lock();
+
+       head = find_swevent_head(cpuctx, type, event_id);
+
+       if (!head)
+               goto end;
+
+       hlist_for_each_entry_rcu(event, node, head, hlist_entry) {
                if (perf_swevent_match(event, type, event_id, data, regs))
                        perf_swevent_add(event, nr, nmi, data, regs);
        }
+end:
+       rcu_read_unlock();
 }
 
 int perf_swevent_get_recursion_context(void)
@@ -4076,27 +4143,6 @@ void perf_swevent_put_recursion_context(int rctx)
 }
 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;
-       struct perf_event_context *ctx;
-
-       cpuctx = &__get_cpu_var(perf_cpu_context);
-       rcu_read_lock();
-       perf_swevent_ctx_event(&cpuctx->ctx, type, event_id,
-                                nr, nmi, data, regs);
-       /*
-        * doesn't really matter which of the child contexts the
-        * events ends up in.
-        */
-       ctx = rcu_dereference(current->perf_event_ctxp);
-       if (ctx)
-               perf_swevent_ctx_event(ctx, type, event_id, nr, nmi, data, regs);
-       rcu_read_unlock();
-}
 
 void __perf_sw_event(u32 event_id, u64 nr, int nmi,
                            struct pt_regs *regs, u64 addr)
@@ -4122,16 +4168,28 @@ static void perf_swevent_read(struct perf_event *event)
 static int perf_swevent_enable(struct perf_event *event)
 {
        struct hw_perf_event *hwc = &event->hw;
+       struct perf_cpu_context *cpuctx;
+       struct hlist_head *head;
+
+       cpuctx = &__get_cpu_var(perf_cpu_context);
 
        if (hwc->sample_period) {
                hwc->last_period = hwc->sample_period;
                perf_swevent_set_period(event);
        }
+
+       head = find_swevent_head(cpuctx, event->attr.type, event->attr.config);
+       if (WARN_ON_ONCE(!head))
+               return -EINVAL;
+
+       hlist_add_head_rcu(&event->hlist_entry, head);
+
        return 0;
 }
 
 static void perf_swevent_disable(struct perf_event *event)
 {
+       hlist_del_rcu(&event->hlist_entry);
 }
 
 static const struct pmu perf_ops_generic = {
@@ -4159,15 +4217,8 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer)
        perf_sample_data_init(&data, 0);
        data.period = event->hw.last_period;
        regs = get_irq_regs();
-       /*
-        * In case we exclude kernel IPs or are somehow not in interrupt
-        * context, provide the next best thing, the user IP.
-        */
-       if ((event->attr.exclude_kernel || !regs) &&
-                       !event->attr.exclude_user)
-               regs = task_pt_regs(current);
 
-       if (regs) {
+       if (regs && !perf_exclude_event(event, regs)) {
                if (!(event->attr.exclude_idle && current->pid == 0))
                        if (perf_event_overflow(event, 0, &data, regs))
                                ret = HRTIMER_NORESTART;
@@ -4315,12 +4366,110 @@ static const struct pmu perf_ops_task_clock = {
        .read           = task_clock_perf_event_read,
 };
 
+static void swevent_hlist_release_rcu(struct rcu_head *rcu_head)
+{
+       struct swevent_hlist *hlist;
+
+       hlist = container_of(rcu_head, struct swevent_hlist, rcu_head);
+       kfree(hlist);
+}
+
+static void swevent_hlist_release(struct perf_cpu_context *cpuctx)
+{
+       struct swevent_hlist *hlist;
+
+       if (!cpuctx->swevent_hlist)
+               return;
+
+       hlist = cpuctx->swevent_hlist;
+       rcu_assign_pointer(cpuctx->swevent_hlist, NULL);
+       call_rcu(&hlist->rcu_head, swevent_hlist_release_rcu);
+}
+
+static void swevent_hlist_put_cpu(struct perf_event *event, int cpu)
+{
+       struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu);
+
+       mutex_lock(&cpuctx->hlist_mutex);
+
+       if (!--cpuctx->hlist_refcount)
+               swevent_hlist_release(cpuctx);
+
+       mutex_unlock(&cpuctx->hlist_mutex);
+}
+
+static void swevent_hlist_put(struct perf_event *event)
+{
+       int cpu;
+
+       if (event->cpu != -1) {
+               swevent_hlist_put_cpu(event, event->cpu);
+               return;
+       }
+
+       for_each_possible_cpu(cpu)
+               swevent_hlist_put_cpu(event, cpu);
+}
+
+static int swevent_hlist_get_cpu(struct perf_event *event, int cpu)
+{
+       struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu);
+       int err = 0;
+
+       mutex_lock(&cpuctx->hlist_mutex);
+
+       if (!cpuctx->swevent_hlist && cpu_online(cpu)) {
+               struct swevent_hlist *hlist;
+
+               hlist = kzalloc(sizeof(*hlist), GFP_KERNEL);
+               if (!hlist) {
+                       err = -ENOMEM;
+                       goto exit;
+               }
+               rcu_assign_pointer(cpuctx->swevent_hlist, hlist);
+       }
+       cpuctx->hlist_refcount++;
+ exit:
+       mutex_unlock(&cpuctx->hlist_mutex);
+
+       return err;
+}
+
+static int swevent_hlist_get(struct perf_event *event)
+{
+       int err;
+       int cpu, failed_cpu;
+
+       if (event->cpu != -1)
+               return swevent_hlist_get_cpu(event, event->cpu);
+
+       get_online_cpus();
+       for_each_possible_cpu(cpu) {
+               err = swevent_hlist_get_cpu(event, cpu);
+               if (err) {
+                       failed_cpu = cpu;
+                       goto fail;
+               }
+       }
+       put_online_cpus();
+
+       return 0;
+ fail:
+       for_each_possible_cpu(cpu) {
+               if (cpu == failed_cpu)
+                       break;
+               swevent_hlist_put_cpu(event, cpu);
+       }
+
+       put_online_cpus();
+       return err;
+}
+
 #ifdef CONFIG_EVENT_TRACING
 
 void perf_tp_event(int event_id, u64 addr, u64 count, void *record,
-                         int entry_size)
+                  int entry_size, struct pt_regs *regs)
 {
-       struct pt_regs *regs = get_irq_regs();
        struct perf_sample_data data;
        struct perf_raw_record raw = {
                .size = entry_size,
@@ -4330,12 +4479,9 @@ void perf_tp_event(int event_id, u64 addr, u64 count, void *record,
        perf_sample_data_init(&data, addr);
        data.raw = &raw;
 
-       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);
+                        &data, regs);
 }
 EXPORT_SYMBOL_GPL(perf_tp_event);
 
@@ -4351,11 +4497,14 @@ static int perf_tp_event_match(struct perf_event *event,
 
 static void tp_perf_event_destroy(struct perf_event *event)
 {
-       ftrace_profile_disable(event->attr.config);
+       perf_trace_disable(event->attr.config);
+       swevent_hlist_put(event);
 }
 
 static const struct pmu *tp_perf_event_init(struct perf_event *event)
 {
+       int err;
+
        /*
         * Raw tracepoint data is a severe data leak, only allow root to
         * have these.
@@ -4365,10 +4514,15 @@ static const struct pmu *tp_perf_event_init(struct perf_event *event)
                        !capable(CAP_SYS_ADMIN))
                return ERR_PTR(-EPERM);
 
-       if (ftrace_profile_enable(event->attr.config))
+       if (perf_trace_enable(event->attr.config))
                return NULL;
 
        event->destroy = tp_perf_event_destroy;
+       err = swevent_hlist_get(event);
+       if (err) {
+               perf_trace_disable(event->attr.config);
+               return ERR_PTR(err);
+       }
 
        return &perf_ops_generic;
 }
@@ -4469,6 +4623,7 @@ static void sw_perf_event_destroy(struct perf_event *event)
        WARN_ON(event->parent);
 
        atomic_dec(&perf_swevent_enabled[event_id]);
+       swevent_hlist_put(event);
 }
 
 static const struct pmu *sw_perf_event_init(struct perf_event *event)
@@ -4507,6 +4662,12 @@ static const struct pmu *sw_perf_event_init(struct perf_event *event)
        case PERF_COUNT_SW_ALIGNMENT_FAULTS:
        case PERF_COUNT_SW_EMULATION_FAULTS:
                if (!event->parent) {
+                       int err;
+
+                       err = swevent_hlist_get(event);
+                       if (err)
+                               return ERR_PTR(err);
+
                        atomic_inc(&perf_swevent_enabled[event_id]);
                        event->destroy = sw_perf_event_destroy;
                }
@@ -4892,7 +5053,7 @@ err_fput_free_put_context:
 
 err_free_put_context:
        if (err < 0)
-               kfree(event);
+               free_event(event);
 
 err_put_context:
        if (err < 0)
@@ -5171,7 +5332,7 @@ void perf_event_exit_task(struct task_struct *child)
         *
         * But since its the parent context it won't be the same instance.
         */
-       mutex_lock_nested(&child_ctx->mutex, SINGLE_DEPTH_NESTING);
+       mutex_lock(&child_ctx->mutex);
 
 again:
        list_for_each_entry_safe(child_event, tmp, &child_ctx->pinned_groups,
@@ -5372,18 +5533,37 @@ int perf_event_init_task(struct task_struct *child)
        return ret;
 }
 
+static void __init perf_event_init_all_cpus(void)
+{
+       int cpu;
+       struct perf_cpu_context *cpuctx;
+
+       for_each_possible_cpu(cpu) {
+               cpuctx = &per_cpu(perf_cpu_context, cpu);
+               mutex_init(&cpuctx->hlist_mutex);
+               __perf_event_init_context(&cpuctx->ctx, NULL);
+       }
+}
+
 static void __cpuinit perf_event_init_cpu(int cpu)
 {
        struct perf_cpu_context *cpuctx;
 
        cpuctx = &per_cpu(perf_cpu_context, cpu);
-       __perf_event_init_context(&cpuctx->ctx, NULL);
 
        spin_lock(&perf_resource_lock);
        cpuctx->max_pertask = perf_max_events - perf_reserved_percpu;
        spin_unlock(&perf_resource_lock);
 
-       hw_perf_event_setup(cpu);
+       mutex_lock(&cpuctx->hlist_mutex);
+       if (cpuctx->hlist_refcount > 0) {
+               struct swevent_hlist *hlist;
+
+               hlist = kzalloc(sizeof(*hlist), GFP_KERNEL);
+               WARN_ON_ONCE(!hlist);
+               rcu_assign_pointer(cpuctx->swevent_hlist, hlist);
+       }
+       mutex_unlock(&cpuctx->hlist_mutex);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -5403,6 +5583,10 @@ static void perf_event_exit_cpu(int cpu)
        struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu);
        struct perf_event_context *ctx = &cpuctx->ctx;
 
+       mutex_lock(&cpuctx->hlist_mutex);
+       swevent_hlist_release(cpuctx);
+       mutex_unlock(&cpuctx->hlist_mutex);
+
        mutex_lock(&ctx->mutex);
        smp_call_function_single(cpu, __perf_event_exit_cpu, NULL, 1);
        mutex_unlock(&ctx->mutex);
@@ -5423,20 +5607,11 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
                perf_event_init_cpu(cpu);
                break;
 
-       case CPU_ONLINE:
-       case CPU_ONLINE_FROZEN:
-               hw_perf_event_setup_online(cpu);
-               break;
-
        case CPU_DOWN_PREPARE:
        case CPU_DOWN_PREPARE_FROZEN:
                perf_event_exit_cpu(cpu);
                break;
 
-       case CPU_DEAD:
-               hw_perf_event_setup_offline(cpu);
-               break;
-
        default:
                break;
        }
@@ -5454,6 +5629,7 @@ static struct notifier_block __cpuinitdata perf_cpu_nb = {
 
 void __init perf_event_init(void)
 {
+       perf_event_init_all_cpus();
        perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE,
                        (void *)(long)smp_processor_id());
        perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_ONLINE,
index 79aac93acf99813d3abf89967089832cc272572c..a5aff94e1f0b49d30eb77ff056dd6712d5687e5e 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/syscalls.h>
 #include <linux/err.h>
 #include <linux/acct.h>
+#include <linux/slab.h>
 
 #define BITS_PER_PAGE          (PAGE_SIZE*8)
 
index 1a22dfd42df9b4089e9630f2635a425a26d4959b..bc7704b3a4431434e15bacb3127cfb9a5e1517a9 100644 (file)
@@ -1061,9 +1061,9 @@ static void check_thread_timers(struct task_struct *tsk,
        }
 }
 
-static void stop_process_timers(struct task_struct *tsk)
+static void stop_process_timers(struct signal_struct *sig)
 {
-       struct thread_group_cputimer *cputimer = &tsk->signal->cputimer;
+       struct thread_group_cputimer *cputimer = &sig->cputimer;
        unsigned long flags;
 
        if (!cputimer->running)
@@ -1072,6 +1072,10 @@ static void stop_process_timers(struct task_struct *tsk)
        spin_lock_irqsave(&cputimer->lock, flags);
        cputimer->running = 0;
        spin_unlock_irqrestore(&cputimer->lock, flags);
+
+       sig->cputime_expires.prof_exp = cputime_zero;
+       sig->cputime_expires.virt_exp = cputime_zero;
+       sig->cputime_expires.sched_exp = 0;
 }
 
 static u32 onecputick;
@@ -1133,7 +1137,7 @@ static void check_process_timers(struct task_struct *tsk,
            list_empty(&timers[CPUCLOCK_VIRT]) &&
            cputime_eq(sig->it[CPUCLOCK_VIRT].expires, cputime_zero) &&
            list_empty(&timers[CPUCLOCK_SCHED])) {
-               stop_process_timers(tsk);
+               stop_process_timers(sig);
                return;
        }
 
index da5288ec239286d9c2ae3f62b75a32ff3ed60f8b..aa9e916da4d53051eed6e7d12e9ddd37baaab3cd 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/console.h>
 #include <linux/cpu.h>
 #include <linux/freezer.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_scan.h>
 #include <asm/suspend.h>
 
index 39ac698ef8361e43b769aa7b1b6256370b7018d3..fdcad9ed5a7b00bc0de3ca4a54b1cdd0b6759a1b 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/suspend.h>
 
 /*
index 5ade1bdcf366a9e93789097ea99ba8aba9dceccc..71ae29052ab6c2275c6f48239b56cdd4be4cba33 100644 (file)
@@ -88,12 +88,11 @@ static int try_to_freeze_tasks(bool sig_only)
                printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
                                "(%d tasks refusing to freeze):\n",
                                elapsed_csecs / 100, elapsed_csecs % 100, todo);
-               show_state();
                read_lock(&tasklist_lock);
                do_each_thread(g, p) {
                        task_lock(p);
                        if (freezing(p) && !freezer_should_skip(p))
-                               printk(KERN_ERR " %s\n", p->comm);
+                               sched_show_task(p);
                        cancel_freezing(p);
                        task_unlock(p);
                } while_each_thread(g, p);
@@ -145,7 +144,7 @@ static void thaw_tasks(bool nosig_only)
                if (nosig_only && should_send_signal(p))
                        continue;
 
-               if (cgroup_frozen(p))
+               if (cgroup_freezing_or_frozen(p))
                        continue;
 
                thaw_process(p);
index 830cadecbdfcf2c9f7adedeca5cb6e1f169f8e87..be861c26dda7c70a35e775b5cb93756c7077754b 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/console.h>
 #include <linux/highmem.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
index 44cce10b582dc06c4d0d326b95fe25631e49f251..56e7dbb8b996db295b4fc7cdf1b5f11a0409cb0c 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/console.h>
 #include <linux/cpu.h>
 #include <linux/syscalls.h>
+#include <linux/gfp.h>
 
 #include "power.h"
 
index 1d575733d4e142f68ee3a43ea033ccb1882111c7..66824d71983a6f9cbf56c3e5c4ac77dc981070e8 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/swap.h>
 #include <linux/swapops.h>
 #include <linux/pm.h>
+#include <linux/slab.h>
 
 #include "power.h"
 
index 4d2289626a84e6d03dbc618db13fbb8af4bd6092..a8c96212bc1b4fdfb9f0c212066ff9bd9812690a 100644 (file)
@@ -420,7 +420,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
                         * User space encodes device types as two-byte values,
                         * so we need to recode them
                         */
-                       swdev = old_decode_dev(swap_area.dev);
+                       swdev = new_decode_dev(swap_area.dev);
                        if (swdev) {
                                offset = swap_area.offset;
                                data->swap = swap_type_of(swdev, offset, NULL);
index a55d3a367ae86a95e3788e6162717188bb05ad90..dfadc5b729f194905ded52faef8b2d2564dfd2ce 100644 (file)
@@ -127,8 +127,10 @@ int __ref profile_init(void)
                return 0;
 
        prof_buffer = vmalloc(buffer_bytes);
-       if (prof_buffer)
+       if (prof_buffer) {
+               memset(prof_buffer, 0, buffer_bytes);
                return 0;
+       }
 
        free_cpumask_var(prof_cpu_mask);
        return -ENOMEM;
index 42ad8ae729a0b9d594a9c28afb2a22cb9c20197d..6af9cdd558b7b28b5d7e44cc78e3e7cced8582d5 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
-#include <linux/smp_lock.h>
 #include <linux/ptrace.h>
 #include <linux/security.h>
 #include <linux/signal.h>
@@ -76,7 +75,6 @@ void __ptrace_unlink(struct task_struct *child)
        child->parent = child->real_parent;
        list_del_init(&child->ptrace_entry);
 
-       arch_ptrace_untrace(child);
        if (task_is_traced(child))
                ptrace_untrace(child);
 }
@@ -666,10 +664,6 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data)
        struct task_struct *child;
        long ret;
 
-       /*
-        * This lock_kernel fixes a subtle race with suid exec
-        */
-       lock_kernel();
        if (request == PTRACE_TRACEME) {
                ret = ptrace_traceme();
                if (!ret)
@@ -703,7 +697,6 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data)
  out_put_task_struct:
        put_task_struct(child);
  out:
-       unlock_kernel();
        return ret;
 }
 
@@ -813,10 +806,6 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
        struct task_struct *child;
        long ret;
 
-       /*
-        * This lock_kernel fixes a subtle race with suid exec
-        */
-       lock_kernel();
        if (request == PTRACE_TRACEME) {
                ret = ptrace_traceme();
                goto out;
@@ -846,7 +835,6 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
  out_put_task_struct:
        put_task_struct(child);
  out:
-       unlock_kernel();
        return ret;
 }
 #endif /* CONFIG_COMPAT */
index f1125c1a6321950030c42e8e5e2df2689d068a94..72a8dc9567f5825ee24bb52174b67953ca372b63 100644 (file)
@@ -44,7 +44,7 @@
 #include <linux/cpu.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
-#include <linux/kernel_stat.h>
+#include <linux/hardirq.h>
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 static struct lock_class_key rcu_lock_key;
@@ -63,23 +63,34 @@ struct lockdep_map rcu_sched_lock_map =
 EXPORT_SYMBOL_GPL(rcu_sched_lock_map);
 #endif
 
-int rcu_scheduler_active __read_mostly;
-EXPORT_SYMBOL_GPL(rcu_scheduler_active);
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
 
-/*
- * 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.
+int debug_lockdep_rcu_enabled(void)
+{
+       return rcu_scheduler_active && debug_locks &&
+              current->lockdep_recursion == 0;
+}
+EXPORT_SYMBOL_GPL(debug_lockdep_rcu_enabled);
+
+/**
+ * rcu_read_lock_bh_held - might we be in RCU-bh read-side critical section?
+ *
+ * Check for bottom half being disabled, which covers both the
+ * CONFIG_PROVE_RCU and not cases.  Note that if someone uses
+ * rcu_read_lock_bh(), but then later enables BH, lockdep (if enabled)
+ * will show the situation.
+ *
+ * Check debug_lockdep_rcu_enabled() to prevent false positives during boot.
  */
-void rcu_scheduler_starting(void)
+int rcu_read_lock_bh_held(void)
 {
-       WARN_ON(num_online_cpus() != 1);
-       WARN_ON(nr_context_switches() > 0);
-       rcu_scheduler_active = 1;
+       if (!debug_lockdep_rcu_enabled())
+               return 1;
+       return in_softirq();
 }
+EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held);
+
+#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
 
 /*
  * Awaken the corresponding synchronize_rcu() instance now that a
@@ -92,3 +103,14 @@ void wakeme_after_rcu(struct rcu_head  *head)
        rcu = container_of(head, struct rcu_synchronize, head);
        complete(&rcu->completion);
 }
+
+#ifdef CONFIG_PROVE_RCU
+/*
+ * wrapper function to avoid #include problems.
+ */
+int rcu_my_thread_group_empty(void)
+{
+       return thread_group_empty(current);
+}
+EXPORT_SYMBOL_GPL(rcu_my_thread_group_empty);
+#endif /* #ifdef CONFIG_PROVE_RCU */
index 9f6d9ff2572cddf3067a3a4434f5a86612a94a44..38729d3cd23692887afac015b442c052a150f38c 100644 (file)
@@ -44,9 +44,9 @@ struct rcu_ctrlblk {
 };
 
 /* Definition for rcupdate control block. */
-static struct rcu_ctrlblk rcu_ctrlblk = {
-       .donetail       = &rcu_ctrlblk.rcucblist,
-       .curtail        = &rcu_ctrlblk.rcucblist,
+static struct rcu_ctrlblk rcu_sched_ctrlblk = {
+       .donetail       = &rcu_sched_ctrlblk.rcucblist,
+       .curtail        = &rcu_sched_ctrlblk.rcucblist,
 };
 
 static struct rcu_ctrlblk rcu_bh_ctrlblk = {
@@ -54,6 +54,11 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk = {
        .curtail        = &rcu_bh_ctrlblk.rcucblist,
 };
 
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+int rcu_scheduler_active __read_mostly;
+EXPORT_SYMBOL_GPL(rcu_scheduler_active);
+#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+
 #ifdef CONFIG_NO_HZ
 
 static long rcu_dynticks_nesting = 1;
@@ -108,7 +113,8 @@ static int rcu_qsctr_help(struct rcu_ctrlblk *rcp)
  */
 void rcu_sched_qs(int cpu)
 {
-       if (rcu_qsctr_help(&rcu_ctrlblk) + rcu_qsctr_help(&rcu_bh_ctrlblk))
+       if (rcu_qsctr_help(&rcu_sched_ctrlblk) +
+           rcu_qsctr_help(&rcu_bh_ctrlblk))
                raise_softirq(RCU_SOFTIRQ);
 }
 
@@ -173,7 +179,7 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
  */
 static void rcu_process_callbacks(struct softirq_action *unused)
 {
-       __rcu_process_callbacks(&rcu_ctrlblk);
+       __rcu_process_callbacks(&rcu_sched_ctrlblk);
        __rcu_process_callbacks(&rcu_bh_ctrlblk);
 }
 
@@ -187,7 +193,8 @@ static void rcu_process_callbacks(struct softirq_action *unused)
  *
  * Cool, huh?  (Due to Josh Triplett.)
  *
- * But we want to make this a static inline later.
+ * But we want to make this a static inline later.  The cond_resched()
+ * currently makes this problematic.
  */
 void synchronize_sched(void)
 {
@@ -195,12 +202,6 @@ void synchronize_sched(void)
 }
 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().
  */
@@ -226,7 +227,7 @@ static void __call_rcu(struct rcu_head *head,
  */
 void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
 {
-       __call_rcu(head, func, &rcu_ctrlblk);
+       __call_rcu(head, func, &rcu_sched_ctrlblk);
 }
 EXPORT_SYMBOL_GPL(call_rcu);
 
@@ -244,11 +245,13 @@ void rcu_barrier(void)
 {
        struct rcu_synchronize rcu;
 
+       init_rcu_head_on_stack(&rcu.head);
        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);
+       destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(rcu_barrier);
 
@@ -256,11 +259,13 @@ void rcu_barrier_bh(void)
 {
        struct rcu_synchronize rcu;
 
+       init_rcu_head_on_stack(&rcu.head);
        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);
+       destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(rcu_barrier_bh);
 
@@ -268,11 +273,13 @@ void rcu_barrier_sched(void)
 {
        struct rcu_synchronize rcu;
 
+       init_rcu_head_on_stack(&rcu.head);
        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);
+       destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(rcu_barrier_sched);
 
@@ -280,3 +287,5 @@ void __init rcu_init(void)
 {
        open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
 }
+
+#include "rcutiny_plugin.h"
diff --git a/kernel/rcutiny_plugin.h b/kernel/rcutiny_plugin.h
new file mode 100644 (file)
index 0000000..d223a92
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Read-Copy Update mechanism for mutual exclusion (tree-based version)
+ * Internal non-public definitions that provide either classic
+ * or preemptable semantics.
+ *
+ * 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, 2009
+ *
+ * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+ */
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+
+#include <linux/kernel_stat.h>
+
+/*
+ * During boot, we forgive RCU lockdep issues.  After this function is
+ * invoked, we start taking RCU lockdep issues seriously.
+ */
+void rcu_scheduler_starting(void)
+{
+       WARN_ON(nr_context_switches() > 0);
+       rcu_scheduler_active = 1;
+}
+
+#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
index 58df55bf83ed919ae4d6372ef4769c0768310a03..6535ac8bc6a5935ceebd05ea24390e25b13fba41 100644 (file)
@@ -464,9 +464,11 @@ static void rcu_bh_torture_synchronize(void)
 {
        struct rcu_bh_torture_synchronize rcu;
 
+       init_rcu_head_on_stack(&rcu.head);
        init_completion(&rcu.completion);
        call_rcu_bh(&rcu.head, rcu_bh_torture_wakeme_after_cb);
        wait_for_completion(&rcu.completion);
+       destroy_rcu_head_on_stack(&rcu.head);
 }
 
 static struct rcu_torture_ops rcu_bh_ops = {
@@ -669,7 +671,7 @@ static struct rcu_torture_ops sched_expedited_ops = {
        .sync           = synchronize_sched_expedited,
        .cb_barrier     = NULL,
        .fqs            = rcu_sched_force_quiescent_state,
-       .stats          = rcu_expedited_torture_stats,
+       .stats          = NULL,
        .irq_capable    = 1,
        .name           = "sched_expedited"
 };
index 3ec8160fc75ffa76121cb5d04c948b0f16f3e317..d4437345706f8a539eee6dba201662fd791978ef 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/cpu.h>
 #include <linux/mutex.h>
 #include <linux/time.h>
+#include <linux/kernel_stat.h>
 
 #include "rcutree.h"
 
@@ -53,8 +54,8 @@
 
 static struct lock_class_key rcu_node_class[NUM_RCU_LVLS];
 
-#define RCU_STATE_INITIALIZER(name) { \
-       .level = { &name.node[0] }, \
+#define RCU_STATE_INITIALIZER(structname) { \
+       .level = { &structname.node[0] }, \
        .levelcnt = { \
                NUM_RCU_LVL_0,  /* root of hierarchy. */ \
                NUM_RCU_LVL_1, \
@@ -65,13 +66,14 @@ static struct lock_class_key rcu_node_class[NUM_RCU_LVLS];
        .signaled = RCU_GP_IDLE, \
        .gpnum = -300, \
        .completed = -300, \
-       .onofflock = __RAW_SPIN_LOCK_UNLOCKED(&name.onofflock), \
+       .onofflock = __RAW_SPIN_LOCK_UNLOCKED(&structname.onofflock), \
        .orphan_cbs_list = NULL, \
-       .orphan_cbs_tail = &name.orphan_cbs_list, \
+       .orphan_cbs_tail = &structname.orphan_cbs_list, \
        .orphan_qlen = 0, \
-       .fqslock = __RAW_SPIN_LOCK_UNLOCKED(&name.fqslock), \
+       .fqslock = __RAW_SPIN_LOCK_UNLOCKED(&structname.fqslock), \
        .n_force_qs = 0, \
        .n_force_qs_ngp = 0, \
+       .name = #structname, \
 }
 
 struct rcu_state rcu_sched_state = RCU_STATE_INITIALIZER(rcu_sched_state);
@@ -80,6 +82,9 @@ 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);
 
+int rcu_scheduler_active __read_mostly;
+EXPORT_SYMBOL_GPL(rcu_scheduler_active);
+
 /*
  * Return true if an RCU grace period is in progress.  The ACCESS_ONCE()s
  * permit this function to be invoked without holding the root rcu_node
@@ -97,25 +102,32 @@ static int rcu_gp_in_progress(struct rcu_state *rsp)
  */
 void rcu_sched_qs(int cpu)
 {
-       struct rcu_data *rdp;
+       struct rcu_data *rdp = &per_cpu(rcu_sched_data, cpu);
 
-       rdp = &per_cpu(rcu_sched_data, cpu);
        rdp->passed_quiesc_completed = rdp->gpnum - 1;
        barrier();
        rdp->passed_quiesc = 1;
-       rcu_preempt_note_context_switch(cpu);
 }
 
 void rcu_bh_qs(int cpu)
 {
-       struct rcu_data *rdp;
+       struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu);
 
-       rdp = &per_cpu(rcu_bh_data, cpu);
        rdp->passed_quiesc_completed = rdp->gpnum - 1;
        barrier();
        rdp->passed_quiesc = 1;
 }
 
+/*
+ * Note a context switch.  This is a quiescent state for RCU-sched,
+ * and requires special handling for preemptible RCU.
+ */
+void rcu_note_context_switch(int cpu)
+{
+       rcu_sched_qs(cpu);
+       rcu_preempt_note_context_switch(cpu);
+}
+
 #ifdef CONFIG_NO_HZ
 DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = {
        .dynticks_nesting = 1,
@@ -438,6 +450,8 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
 
 #ifdef CONFIG_RCU_CPU_STALL_DETECTOR
 
+int rcu_cpu_stall_panicking __read_mostly;
+
 static void record_gp_stall_check_time(struct rcu_state *rsp)
 {
        rsp->gp_start = jiffies;
@@ -470,7 +484,8 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
 
        /* OK, time to rat on our buddy... */
 
-       printk(KERN_ERR "INFO: RCU detected CPU stalls:");
+       printk(KERN_ERR "INFO: %s detected stalls on CPUs/tasks: {",
+              rsp->name);
        rcu_for_each_leaf_node(rsp, rnp) {
                raw_spin_lock_irqsave(&rnp->lock, flags);
                rcu_print_task_stall(rnp);
@@ -481,7 +496,7 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
                        if (rnp->qsmask & (1UL << cpu))
                                printk(" %d", rnp->grplo + cpu);
        }
-       printk(" (detected by %d, t=%ld jiffies)\n",
+       printk("} (detected by %d, t=%ld jiffies)\n",
               smp_processor_id(), (long)(jiffies - rsp->gp_start));
        trigger_all_cpu_backtrace();
 
@@ -497,8 +512,8 @@ static void print_cpu_stall(struct rcu_state *rsp)
        unsigned long flags;
        struct rcu_node *rnp = rcu_get_root(rsp);
 
-       printk(KERN_ERR "INFO: RCU detected CPU %d stall (t=%lu jiffies)\n",
-                       smp_processor_id(), jiffies - rsp->gp_start);
+       printk(KERN_ERR "INFO: %s detected stall on CPU %d (t=%lu jiffies)\n",
+              rsp->name, smp_processor_id(), jiffies - rsp->gp_start);
        trigger_all_cpu_backtrace();
 
        raw_spin_lock_irqsave(&rnp->lock, flags);
@@ -515,6 +530,8 @@ static void check_cpu_stall(struct rcu_state *rsp, struct rcu_data *rdp)
        long delta;
        struct rcu_node *rnp;
 
+       if (rcu_cpu_stall_panicking)
+               return;
        delta = jiffies - rsp->jiffies_stall;
        rnp = rdp->mynode;
        if ((rnp->qsmask & rdp->grpmask) && delta >= 0) {
@@ -529,6 +546,21 @@ static void check_cpu_stall(struct rcu_state *rsp, struct rcu_data *rdp)
        }
 }
 
+static int rcu_panic(struct notifier_block *this, unsigned long ev, void *ptr)
+{
+       rcu_cpu_stall_panicking = 1;
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block rcu_panic_block = {
+       .notifier_call = rcu_panic,
+};
+
+static void __init check_cpu_stall_init(void)
+{
+       atomic_notifier_chain_register(&panic_notifier_list, &rcu_panic_block);
+}
+
 #else /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
 
 static void record_gp_stall_check_time(struct rcu_state *rsp)
@@ -539,6 +571,10 @@ static void check_cpu_stall(struct rcu_state *rsp, struct rcu_data *rdp)
 {
 }
 
+static void __init check_cpu_stall_init(void)
+{
+}
+
 #endif /* #else #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
 
 /*
@@ -1125,8 +1161,6 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
  */
 void rcu_check_callbacks(int cpu, int user)
 {
-       if (!rcu_pending(cpu))
-               return; /* if nothing for RCU to do. */
        if (user ||
            (idle_cpu(cpu) && rcu_scheduler_active &&
             !in_softirq() && hardirq_count() <= (1 << HARDIRQ_SHIFT))) {
@@ -1158,7 +1192,8 @@ void rcu_check_callbacks(int cpu, int user)
                rcu_bh_qs(cpu);
        }
        rcu_preempt_check_callbacks(cpu);
-       raise_softirq(RCU_SOFTIRQ);
+       if (rcu_pending(cpu))
+               raise_softirq(RCU_SOFTIRQ);
 }
 
 #ifdef CONFIG_SMP
@@ -1236,11 +1271,11 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
                break; /* grace period idle or initializing, ignore. */
 
        case RCU_SAVE_DYNTICK:
-
-               raw_spin_unlock(&rnp->lock);  /* irqs remain disabled */
                if (RCU_SIGNAL_INIT != RCU_SAVE_DYNTICK)
                        break; /* So gcc recognizes the dead code. */
 
+               raw_spin_unlock(&rnp->lock);  /* irqs remain disabled */
+
                /* Record dyntick-idle state. */
                force_qs_rnp(rsp, dyntick_save_progress_counter);
                raw_spin_lock(&rnp->lock);  /* irqs already disabled */
@@ -1449,11 +1484,13 @@ void synchronize_sched(void)
        if (rcu_blocking_is_gp())
                return;
 
+       init_rcu_head_on_stack(&rcu.head);
        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);
+       destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(synchronize_sched);
 
@@ -1473,11 +1510,13 @@ void synchronize_rcu_bh(void)
        if (rcu_blocking_is_gp())
                return;
 
+       init_rcu_head_on_stack(&rcu.head);
        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);
+       destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
 
@@ -1498,8 +1537,20 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
        check_cpu_stall(rsp, rdp);
 
        /* Is the RCU core waiting for a quiescent state from this CPU? */
-       if (rdp->qs_pending) {
+       if (rdp->qs_pending && !rdp->passed_quiesc) {
+
+               /*
+                * If force_quiescent_state() coming soon and this CPU
+                * needs a quiescent state, and this is either RCU-sched
+                * or RCU-bh, force a local reschedule.
+                */
                rdp->n_rp_qs_pending++;
+               if (!rdp->preemptable &&
+                   ULONG_CMP_LT(ACCESS_ONCE(rsp->jiffies_force_qs) - 1,
+                                jiffies))
+                       set_need_resched();
+       } else if (rdp->qs_pending && rdp->passed_quiesc) {
+               rdp->n_rp_report_qs++;
                return 1;
        }
 
@@ -1766,6 +1817,21 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
        return NOTIFY_OK;
 }
 
+/*
+ * 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.  This function also enables RCU lockdep checking.
+ */
+void rcu_scheduler_starting(void)
+{
+       WARN_ON(num_online_cpus() != 1);
+       WARN_ON(nr_context_switches() > 0);
+       rcu_scheduler_active = 1;
+}
+
 /*
  * Compute the per-level fanout, either using the exact fanout specified
  * or balancing the tree, depending on CONFIG_RCU_FANOUT_EXACT.
@@ -1849,6 +1915,14 @@ static void __init rcu_init_one(struct rcu_state *rsp)
                        INIT_LIST_HEAD(&rnp->blocked_tasks[3]);
                }
        }
+
+       rnp = rsp->level[NUM_RCU_LVLS - 1];
+       for_each_possible_cpu(i) {
+               while (i > rnp->grphi)
+                       rnp++;
+               rsp->rda[i]->mynode = rnp;
+               rcu_boot_init_percpu_data(i, rsp);
+       }
 }
 
 /*
@@ -1859,19 +1933,11 @@ static void __init rcu_init_one(struct rcu_state *rsp)
 #define RCU_INIT_FLAVOR(rsp, rcu_data) \
 do { \
        int i; \
-       int j; \
-       struct rcu_node *rnp; \
        \
-       rcu_init_one(rsp); \
-       rnp = (rsp)->level[NUM_RCU_LVLS - 1]; \
-       j = 0; \
        for_each_possible_cpu(i) { \
-               if (i > rnp[j].grphi) \
-                       j++; \
-               per_cpu(rcu_data, i).mynode = &rnp[j]; \
                (rsp)->rda[i] = &per_cpu(rcu_data, i); \
-               rcu_boot_init_percpu_data(i, rsp); \
        } \
+       rcu_init_one(rsp); \
 } while (0)
 
 void __init rcu_init(void)
@@ -1879,12 +1945,6 @@ void __init rcu_init(void)
        int cpu;
 
        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();
@@ -1898,6 +1958,7 @@ void __init rcu_init(void)
        cpu_notifier(rcu_cpu_notify, 0);
        for_each_online_cpu(cpu)
                rcu_cpu_notify(NULL, CPU_UP_PREPARE, (void *)(long)cpu);
+       check_cpu_stall_init();
 }
 
 #include "rcutree_plugin.h"
index 4a525a30e08e9e08f2cb7827b1d68412901d09a5..14c040b18ed04a23f34448d9278d9ad55e5ab0c1 100644 (file)
@@ -223,6 +223,7 @@ struct rcu_data {
        /* 5) __rcu_pending() statistics. */
        unsigned long n_rcu_pending;    /* rcu_pending() calls since boot. */
        unsigned long n_rp_qs_pending;
+       unsigned long n_rp_report_qs;
        unsigned long n_rp_cb_ready;
        unsigned long n_rp_cpu_needs_gp;
        unsigned long n_rp_gp_completed;
@@ -326,6 +327,7 @@ struct rcu_state {
        unsigned long jiffies_stall;            /* Time at which to check */
                                                /*  for CPU stalls. */
 #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
+       char *name;                             /* Name of structure. */
 };
 
 /* Return values for rcu_preempt_offline_tasks(). */
index 79b53bda894326838c200575c7f87e0b5f70b678..0e4f420245d97369b7fdf6bb99815789ffe13233 100644 (file)
 
 #include <linux/delay.h>
 
+/*
+ * Check the RCU kernel configuration parameters and print informative
+ * messages about anything out of the ordinary.  If you like #ifdef, you
+ * will love this function.
+ */
+static void __init rcu_bootup_announce_oddness(void)
+{
+#ifdef CONFIG_RCU_TRACE
+       printk(KERN_INFO "\tRCU debugfs-based tracing is enabled.\n");
+#endif
+#if (defined(CONFIG_64BIT) && CONFIG_RCU_FANOUT != 64) || (!defined(CONFIG_64BIT) && CONFIG_RCU_FANOUT != 32)
+       printk(KERN_INFO "\tCONFIG_RCU_FANOUT set to non-default value of %d\n",
+              CONFIG_RCU_FANOUT);
+#endif
+#ifdef CONFIG_RCU_FANOUT_EXACT
+       printk(KERN_INFO "\tHierarchical RCU autobalancing is disabled.\n");
+#endif
+#ifdef CONFIG_RCU_FAST_NO_HZ
+       printk(KERN_INFO
+              "\tRCU dyntick-idle grace-period acceleration is enabled.\n");
+#endif
+#ifdef CONFIG_PROVE_RCU
+       printk(KERN_INFO "\tRCU lockdep checking is enabled.\n");
+#endif
+#ifdef CONFIG_RCU_TORTURE_TEST_RUNNABLE
+       printk(KERN_INFO "\tRCU torture testing starts during boot.\n");
+#endif
+#ifndef CONFIG_RCU_CPU_STALL_DETECTOR
+       printk(KERN_INFO
+              "\tRCU-based detection of stalled CPUs is disabled.\n");
+#endif
+#ifndef CONFIG_RCU_CPU_STALL_VERBOSE
+       printk(KERN_INFO "\tVerbose stalled-CPUs detection is disabled.\n");
+#endif
+#if NUM_RCU_LVL_4 != 0
+       printk(KERN_INFO "\tExperimental four-level hierarchy is enabled.\n");
+#endif
+}
+
 #ifdef CONFIG_TREE_PREEMPT_RCU
 
 struct rcu_state rcu_preempt_state = RCU_STATE_INITIALIZER(rcu_preempt_state);
@@ -38,8 +77,8 @@ static int rcu_preempted_readers_exp(struct rcu_node *rnp);
  */
 static void __init rcu_bootup_announce(void)
 {
-       printk(KERN_INFO
-              "Experimental preemptable hierarchical RCU implementation.\n");
+       printk(KERN_INFO "Preemptable hierarchical RCU implementation.\n");
+       rcu_bootup_announce_oddness();
 }
 
 /*
@@ -75,13 +114,19 @@ EXPORT_SYMBOL_GPL(rcu_force_quiescent_state);
  * that this just means that the task currently running on the CPU is
  * not in a quiescent state.  There might be any number of tasks blocked
  * while in an RCU read-side critical section.
+ *
+ * Unlike the other rcu_*_qs() functions, callers to this function
+ * must disable irqs in order to protect the assignment to
+ * ->rcu_read_unlock_special.
  */
 static void rcu_preempt_qs(int cpu)
 {
        struct rcu_data *rdp = &per_cpu(rcu_preempt_data, cpu);
+
        rdp->passed_quiesc_completed = rdp->gpnum - 1;
        barrier();
        rdp->passed_quiesc = 1;
+       current->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_NEED_QS;
 }
 
 /*
@@ -144,9 +189,8 @@ static void rcu_preempt_note_context_switch(int cpu)
         * grace period, then the fact that the task has been enqueued
         * means that we continue to block the current grace period.
         */
-       rcu_preempt_qs(cpu);
        local_irq_save(flags);
-       t->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_NEED_QS;
+       rcu_preempt_qs(cpu);
        local_irq_restore(flags);
 }
 
@@ -236,7 +280,6 @@ static void rcu_read_unlock_special(struct task_struct *t)
         */
        special = t->rcu_read_unlock_special;
        if (special & RCU_READ_UNLOCK_NEED_QS) {
-               t->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_NEED_QS;
                rcu_preempt_qs(smp_processor_id());
        }
 
@@ -473,7 +516,6 @@ static void rcu_preempt_check_callbacks(int cpu)
        struct task_struct *t = current;
 
        if (t->rcu_read_lock_nesting == 0) {
-               t->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_NEED_QS;
                rcu_preempt_qs(cpu);
                return;
        }
@@ -515,11 +557,13 @@ void synchronize_rcu(void)
        if (!rcu_scheduler_active)
                return;
 
+       init_rcu_head_on_stack(&rcu.head);
        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);
+       destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(synchronize_rcu);
 
@@ -754,6 +798,7 @@ void exit_rcu(void)
 static void __init rcu_bootup_announce(void)
 {
        printk(KERN_INFO "Hierarchical RCU implementation.\n");
+       rcu_bootup_announce_oddness();
 }
 
 /*
@@ -1008,6 +1053,8 @@ static DEFINE_PER_CPU(unsigned long, rcu_dyntick_holdoff);
 int rcu_needs_cpu(int cpu)
 {
        int c = 0;
+       int snap;
+       int snap_nmi;
        int thatcpu;
 
        /* Check for being in the holdoff period. */
@@ -1015,12 +1062,18 @@ int rcu_needs_cpu(int cpu)
                return rcu_needs_cpu_quick_check(cpu);
 
        /* Don't bother unless we are the last non-dyntick-idle CPU. */
-       for_each_cpu_not(thatcpu, nohz_cpu_mask)
-               if (thatcpu != cpu) {
+       for_each_online_cpu(thatcpu) {
+               if (thatcpu == cpu)
+                       continue;
+               snap = per_cpu(rcu_dynticks, thatcpu).dynticks;
+               snap_nmi = per_cpu(rcu_dynticks, thatcpu).dynticks_nmi;
+               smp_mb(); /* Order sampling of snap with end of grace period. */
+               if (((snap & 0x1) != 0) || ((snap_nmi & 0x1) != 0)) {
                        per_cpu(rcu_dyntick_drain, cpu) = 0;
                        per_cpu(rcu_dyntick_holdoff, cpu) = jiffies - 1;
                        return rcu_needs_cpu_quick_check(cpu);
                }
+       }
 
        /* Check and update the rcu_dyntick_drain sequencing. */
        if (per_cpu(rcu_dyntick_drain, cpu) <= 0) {
index d45db2e35d27a1c3aea36ad6ff299fdf73cb7e74..36c95b45738ed7f74fb78b901ddcff7fc1488498 100644 (file)
@@ -241,11 +241,13 @@ static const struct file_operations rcugp_fops = {
 static void print_one_rcu_pending(struct seq_file *m, struct rcu_data *rdp)
 {
        seq_printf(m, "%3d%cnp=%ld "
-                  "qsp=%ld cbr=%ld cng=%ld gpc=%ld gps=%ld nf=%ld nn=%ld\n",
+                  "qsp=%ld rpq=%ld cbr=%ld cng=%ld "
+                  "gpc=%ld gps=%ld nf=%ld nn=%ld\n",
                   rdp->cpu,
                   cpu_is_offline(rdp->cpu) ? '!' : ' ',
                   rdp->n_rcu_pending,
                   rdp->n_rp_qs_pending,
+                  rdp->n_rp_report_qs,
                   rdp->n_rp_cb_ready,
                   rdp->n_rp_cpu_needs_gp,
                   rdp->n_rp_gp_completed,
index bcdabf37c40b58165d29a2e7dc33b41ef9a6d547..c7eaa37a768b785cf69cd2eb64ab3fb75c052124 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/types.h>
 #include <linux/parser.h>
 #include <linux/fs.h>
-#include <linux/slab.h>
 #include <linux/res_counter.h>
 #include <linux/uaccess.h>
 #include <linux/mm.h>
index 2d5be5d9bf5f2937fecaf881236cd48f13078fab..9c358e26353427b5a553e900014359c80c4eced2 100644 (file)
@@ -219,19 +219,34 @@ void release_child_resources(struct resource *r)
 }
 
 /**
- * request_resource - request and reserve an I/O or memory resource
+ * request_resource_conflict - request and reserve an I/O or memory resource
  * @root: root resource descriptor
  * @new: resource descriptor desired by caller
  *
- * Returns 0 for success, negative error code on error.
+ * Returns 0 for success, conflict resource on error.
  */
-int request_resource(struct resource *root, struct resource *new)
+struct resource *request_resource_conflict(struct resource *root, struct resource *new)
 {
        struct resource *conflict;
 
        write_lock(&resource_lock);
        conflict = __request_resource(root, new);
        write_unlock(&resource_lock);
+       return conflict;
+}
+
+/**
+ * request_resource - request and reserve an I/O or memory resource
+ * @root: root resource descriptor
+ * @new: resource descriptor desired by caller
+ *
+ * Returns 0 for success, negative error code on error.
+ */
+int request_resource(struct resource *root, struct resource *new)
+{
+       struct resource *conflict;
+
+       conflict = request_resource_conflict(root, new);
        return conflict ? -EBUSY : 0;
 }
 
@@ -474,25 +489,40 @@ static struct resource * __insert_resource(struct resource *parent, struct resou
 }
 
 /**
- * insert_resource - Inserts a resource in the resource tree
+ * insert_resource_conflict - Inserts resource in the resource tree
  * @parent: parent of the new resource
  * @new: new resource to insert
  *
- * Returns 0 on success, -EBUSY if the resource can't be inserted.
+ * Returns 0 on success, conflict resource if the resource can't be inserted.
  *
- * This function is equivalent to request_resource when no conflict
+ * This function is equivalent to request_resource_conflict when no conflict
  * happens. If a conflict happens, and the conflicting resources
  * entirely fit within the range of the new resource, then the new
  * resource is inserted and the conflicting resources become children of
  * the new resource.
  */
-int insert_resource(struct resource *parent, struct resource *new)
+struct resource *insert_resource_conflict(struct resource *parent, struct resource *new)
 {
        struct resource *conflict;
 
        write_lock(&resource_lock);
        conflict = __insert_resource(parent, new);
        write_unlock(&resource_lock);
+       return conflict;
+}
+
+/**
+ * insert_resource - Inserts a resource in the resource tree
+ * @parent: parent of the new resource
+ * @new: new resource to insert
+ *
+ * Returns 0 on success, -EBUSY if the resource can't be inserted.
+ */
+int insert_resource(struct resource *parent, struct resource *new)
+{
+       struct resource *conflict;
+
+       conflict = insert_resource_conflict(parent, new);
        return conflict ? -EBUSY : 0;
 }
 
index 9ab3cd7858d38001cc4ed0586bf187438e685cd7..1d93cd0ae4d36a8c3cc4af5ff8e195dd1d9fcfda 100644 (file)
@@ -55,9 +55,9 @@
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
 #include <linux/percpu.h>
-#include <linux/kthread.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/stop_machine.h>
 #include <linux/sysctl.h>
 #include <linux/syscalls.h>
 #include <linux/times.h>
@@ -71,6 +71,7 @@
 #include <linux/debugfs.h>
 #include <linux/ctype.h>
 #include <linux/ftrace.h>
+#include <linux/slab.h>
 
 #include <asm/tlb.h>
 #include <asm/irq_regs.h>
@@ -322,6 +323,15 @@ static inline struct task_group *task_group(struct task_struct *p)
 /* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */
 static inline void set_task_rq(struct task_struct *p, unsigned int cpu)
 {
+       /*
+        * Strictly speaking this rcu_read_lock() is not needed since the
+        * task_group is tied to the cgroup, which in turn can never go away
+        * as long as there are tasks attached to it.
+        *
+        * However since task_group() uses task_subsys_state() which is an
+        * rcu_dereference() user, this quiets CONFIG_PROVE_RCU.
+        */
+       rcu_read_lock();
 #ifdef CONFIG_FAIR_GROUP_SCHED
        p->se.cfs_rq = task_group(p)->cfs_rq[cpu];
        p->se.parent = task_group(p)->se[cpu];
@@ -331,6 +341,7 @@ static inline void set_task_rq(struct task_struct *p, unsigned int cpu)
        p->rt.rt_rq  = task_group(p)->rt_rq[cpu];
        p->rt.parent = task_group(p)->rt_se[cpu];
 #endif
+       rcu_read_unlock();
 }
 
 #else
@@ -492,8 +503,11 @@ struct rq {
        #define CPU_LOAD_IDX_MAX 5
        unsigned long cpu_load[CPU_LOAD_IDX_MAX];
 #ifdef CONFIG_NO_HZ
+       u64 nohz_stamp;
        unsigned char in_nohz_recently;
 #endif
+       unsigned int skip_clock_update;
+
        /* capture load from *all* tasks on this cpu: */
        struct load_weight load;
        unsigned long nr_load_updates;
@@ -535,15 +549,13 @@ struct rq {
        int post_schedule;
        int active_balance;
        int push_cpu;
+       struct cpu_stop_work active_balance_work;
        /* cpu of this runqueue: */
        int cpu;
        int online;
 
        unsigned long avg_load_per_task;
 
-       struct task_struct *migration_thread;
-       struct list_head migration_queue;
-
        u64 rt_avg;
        u64 age_stamp;
        u64 idle_stamp;
@@ -591,6 +603,13 @@ static inline
 void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
 {
        rq->curr->sched_class->check_preempt_curr(rq, p, flags);
+
+       /*
+        * A queue event has occurred, and we're going to schedule.  In
+        * this case, we can save a useless back to back clock update.
+        */
+       if (test_tsk_need_resched(p))
+               rq->skip_clock_update = 1;
 }
 
 static inline int cpu_of(struct rq *rq)
@@ -625,7 +644,8 @@ static inline int cpu_of(struct rq *rq)
 
 inline void update_rq_clock(struct rq *rq)
 {
-       rq->clock = sched_clock_cpu(cpu_of(rq));
+       if (!rq->skip_clock_update)
+               rq->clock = sched_clock_cpu(cpu_of(rq));
 }
 
 /*
@@ -903,16 +923,12 @@ static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev)
 #endif /* __ARCH_WANT_UNLOCKED_CTXSW */
 
 /*
- * Check whether the task is waking, we use this to synchronize against
- * ttwu() so that task_cpu() reports a stable number.
- *
- * We need to make an exception for PF_STARTING tasks because the fork
- * path might require task_rq_lock() to work, eg. it can call
- * set_cpus_allowed_ptr() from the cpuset clone_ns code.
+ * Check whether the task is waking, we use this to synchronize ->cpus_allowed
+ * against ttwu().
  */
 static inline int task_is_waking(struct task_struct *p)
 {
-       return unlikely((p->state == TASK_WAKING) && !(p->flags & PF_STARTING));
+       return unlikely(p->state == TASK_WAKING);
 }
 
 /*
@@ -925,11 +941,9 @@ static inline struct rq *__task_rq_lock(struct task_struct *p)
        struct rq *rq;
 
        for (;;) {
-               while (task_is_waking(p))
-                       cpu_relax();
                rq = task_rq(p);
                raw_spin_lock(&rq->lock);
-               if (likely(rq == task_rq(p) && !task_is_waking(p)))
+               if (likely(rq == task_rq(p)))
                        return rq;
                raw_spin_unlock(&rq->lock);
        }
@@ -946,12 +960,10 @@ static struct rq *task_rq_lock(struct task_struct *p, unsigned long *flags)
        struct rq *rq;
 
        for (;;) {
-               while (task_is_waking(p))
-                       cpu_relax();
                local_irq_save(*flags);
                rq = task_rq(p);
                raw_spin_lock(&rq->lock);
-               if (likely(rq == task_rq(p) && !task_is_waking(p)))
+               if (likely(rq == task_rq(p)))
                        return rq;
                raw_spin_unlock_irqrestore(&rq->lock, *flags);
        }
@@ -1228,6 +1240,17 @@ void wake_up_idle_cpu(int cpu)
        if (!tsk_is_polling(rq->idle))
                smp_send_reschedule(cpu);
 }
+
+int nohz_ratelimit(int cpu)
+{
+       struct rq *rq = cpu_rq(cpu);
+       u64 diff = rq->clock - rq->nohz_stamp;
+
+       rq->nohz_stamp = rq->clock;
+
+       return diff < (NSEC_PER_SEC / HZ) >> 1;
+}
+
 #endif /* CONFIG_NO_HZ */
 
 static u64 sched_avg_period(void)
@@ -1770,8 +1793,6 @@ static void double_rq_lock(struct rq *rq1, struct rq *rq2)
                        raw_spin_lock_nested(&rq1->lock, SINGLE_DEPTH_NESTING);
                }
        }
-       update_rq_clock(rq1);
-       update_rq_clock(rq2);
 }
 
 /*
@@ -1802,7 +1823,7 @@ static void cfs_rq_set_shares(struct cfs_rq *cfs_rq, unsigned long shares)
 }
 #endif
 
-static void calc_load_account_active(struct rq *this_rq);
+static void calc_load_account_idle(struct rq *this_rq);
 static void update_sysctl(void);
 static int get_update_sysctl_factor(void);
 
@@ -1859,62 +1880,43 @@ static void set_load_weight(struct task_struct *p)
        p->se.load.inv_weight = prio_to_wmult[p->static_prio - MAX_RT_PRIO];
 }
 
-static void update_avg(u64 *avg, u64 sample)
-{
-       s64 diff = sample - *avg;
-       *avg += diff >> 3;
-}
-
-static void
-enqueue_task(struct rq *rq, struct task_struct *p, int wakeup, bool head)
+static void enqueue_task(struct rq *rq, struct task_struct *p, int flags)
 {
-       if (wakeup)
-               p->se.start_runtime = p->se.sum_exec_runtime;
-
+       update_rq_clock(rq);
        sched_info_queued(p);
-       p->sched_class->enqueue_task(rq, p, wakeup, head);
+       p->sched_class->enqueue_task(rq, p, flags);
        p->se.on_rq = 1;
 }
 
-static void dequeue_task(struct rq *rq, struct task_struct *p, int sleep)
+static void dequeue_task(struct rq *rq, struct task_struct *p, int flags)
 {
-       if (sleep) {
-               if (p->se.last_wakeup) {
-                       update_avg(&p->se.avg_overlap,
-                               p->se.sum_exec_runtime - p->se.last_wakeup);
-                       p->se.last_wakeup = 0;
-               } else {
-                       update_avg(&p->se.avg_wakeup,
-                               sysctl_sched_wakeup_granularity);
-               }
-       }
-
+       update_rq_clock(rq);
        sched_info_dequeued(p);
-       p->sched_class->dequeue_task(rq, p, sleep);
+       p->sched_class->dequeue_task(rq, p, flags);
        p->se.on_rq = 0;
 }
 
 /*
  * activate_task - move a task to the runqueue.
  */
-static void activate_task(struct rq *rq, struct task_struct *p, int wakeup)
+static void activate_task(struct rq *rq, struct task_struct *p, int flags)
 {
        if (task_contributes_to_load(p))
                rq->nr_uninterruptible--;
 
-       enqueue_task(rq, p, wakeup, false);
+       enqueue_task(rq, p, flags);
        inc_nr_running(rq);
 }
 
 /*
  * deactivate_task - remove a task from the runqueue.
  */
-static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep)
+static void deactivate_task(struct rq *rq, struct task_struct *p, int flags)
 {
        if (task_contributes_to_load(p))
                rq->nr_uninterruptible++;
 
-       dequeue_task(rq, p, sleep);
+       dequeue_task(rq, p, flags);
        dec_nr_running(rq);
 }
 
@@ -2043,21 +2045,18 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
        __set_task_cpu(p, new_cpu);
 }
 
-struct migration_req {
-       struct list_head list;
-
+struct migration_arg {
        struct task_struct *task;
        int dest_cpu;
-
-       struct completion done;
 };
 
+static int migration_cpu_stop(void *data);
+
 /*
  * The task's runqueue lock must be held.
  * Returns true if you have to wait for migration thread.
  */
-static int
-migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req)
+static bool migrate_task(struct task_struct *p, int dest_cpu)
 {
        struct rq *rq = task_rq(p);
 
@@ -2065,58 +2064,7 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req)
         * If the task is not on a runqueue (and not running), then
         * the next wake-up will properly place the task.
         */
-       if (!p->se.on_rq && !task_running(rq, p))
-               return 0;
-
-       init_completion(&req->done);
-       req->task = p;
-       req->dest_cpu = dest_cpu;
-       list_add(&req->list, &rq->migration_queue);
-
-       return 1;
-}
-
-/*
- * wait_task_context_switch -  wait for a thread to complete at least one
- *                             context switch.
- *
- * @p must not be current.
- */
-void wait_task_context_switch(struct task_struct *p)
-{
-       unsigned long nvcsw, nivcsw, flags;
-       int running;
-       struct rq *rq;
-
-       nvcsw   = p->nvcsw;
-       nivcsw  = p->nivcsw;
-       for (;;) {
-               /*
-                * The runqueue is assigned before the actual context
-                * switch. We need to take the runqueue lock.
-                *
-                * We could check initially without the lock but it is
-                * very likely that we need to take the lock in every
-                * iteration.
-                */
-               rq = task_rq_lock(p, &flags);
-               running = task_running(rq, p);
-               task_rq_unlock(rq, &flags);
-
-               if (likely(!running))
-                       break;
-               /*
-                * The switch count is incremented before the actual
-                * context switch. We thus wait for two switches to be
-                * sure at least one completed.
-                */
-               if ((p->nvcsw - nvcsw) > 1)
-                       break;
-               if ((p->nivcsw - nivcsw) > 1)
-                       break;
-
-               cpu_relax();
-       }
+       return p->se.on_rq || task_running(rq, p);
 }
 
 /*
@@ -2174,7 +2122,7 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state)
                 * just go back and repeat.
                 */
                rq = task_rq_lock(p, &flags);
-               trace_sched_wait_task(rq, p);
+               trace_sched_wait_task(p);
                running = task_running(rq, p);
                on_rq = p->se.on_rq;
                ncsw = 0;
@@ -2272,6 +2220,9 @@ void task_oncpu_function_call(struct task_struct *p,
 }
 
 #ifdef CONFIG_SMP
+/*
+ * ->cpus_allowed is protected by either TASK_WAKING or rq->lock held.
+ */
 static int select_fallback_rq(int cpu, struct task_struct *p)
 {
        int dest_cpu;
@@ -2288,12 +2239,8 @@ static int select_fallback_rq(int cpu, struct task_struct *p)
                return dest_cpu;
 
        /* No more Mr. Nice Guy. */
-       if (dest_cpu >= nr_cpu_ids) {
-               rcu_read_lock();
-               cpuset_cpus_allowed_locked(p, &p->cpus_allowed);
-               rcu_read_unlock();
-               dest_cpu = cpumask_any_and(cpu_active_mask, &p->cpus_allowed);
-
+       if (unlikely(dest_cpu >= nr_cpu_ids)) {
+               dest_cpu = cpuset_cpus_allowed_fallback(p);
                /*
                 * Don't tell them about moving exiting tasks or
                 * kernel threads (both mm NULL), since they never
@@ -2310,17 +2257,12 @@ static int select_fallback_rq(int cpu, struct task_struct *p)
 }
 
 /*
- * Gets called from 3 sites (exec, fork, wakeup), since it is called without
- * holding rq->lock we need to ensure ->cpus_allowed is stable, this is done
- * by:
- *
- *  exec:           is unstable, retry loop
- *  fork & wake-up: serialize ->cpus_allowed against TASK_WAKING
+ * The caller (fork, wakeup) owns TASK_WAKING, ->cpus_allowed is stable.
  */
 static inline
-int select_task_rq(struct task_struct *p, int sd_flags, int wake_flags)
+int select_task_rq(struct rq *rq, struct task_struct *p, int sd_flags, int wake_flags)
 {
-       int cpu = p->sched_class->select_task_rq(p, sd_flags, wake_flags);
+       int cpu = p->sched_class->select_task_rq(rq, p, sd_flags, wake_flags);
 
        /*
         * In order not to call set_task_cpu() on a blocking task we need
@@ -2338,6 +2280,12 @@ int select_task_rq(struct task_struct *p, int sd_flags, int wake_flags)
 
        return cpu;
 }
+
+static void update_avg(u64 *avg, u64 sample)
+{
+       s64 diff = sample - *avg;
+       *avg += diff >> 3;
+}
 #endif
 
 /***
@@ -2359,16 +2307,13 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
 {
        int cpu, orig_cpu, this_cpu, success = 0;
        unsigned long flags;
+       unsigned long en_flags = ENQUEUE_WAKEUP;
        struct rq *rq;
 
-       if (!sched_feat(SYNC_WAKEUPS))
-               wake_flags &= ~WF_SYNC;
-
        this_cpu = get_cpu();
 
        smp_wmb();
        rq = task_rq_lock(p, &flags);
-       update_rq_clock(rq);
        if (!(p->state & state))
                goto out;
 
@@ -2388,28 +2333,26 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
         *
         * First fix up the nr_uninterruptible count:
         */
-       if (task_contributes_to_load(p))
-               rq->nr_uninterruptible--;
+       if (task_contributes_to_load(p)) {
+               if (likely(cpu_online(orig_cpu)))
+                       rq->nr_uninterruptible--;
+               else
+                       this_rq()->nr_uninterruptible--;
+       }
        p->state = TASK_WAKING;
 
-       if (p->sched_class->task_waking)
+       if (p->sched_class->task_waking) {
                p->sched_class->task_waking(rq, p);
+               en_flags |= ENQUEUE_WAKING;
+       }
 
-       __task_rq_unlock(rq);
-
-       cpu = select_task_rq(p, SD_BALANCE_WAKE, wake_flags);
-       if (cpu != orig_cpu) {
-               /*
-                * Since we migrate the task without holding any rq->lock,
-                * we need to be careful with task_rq_lock(), since that
-                * might end up locking an invalid rq.
-                */
+       cpu = select_task_rq(rq, p, SD_BALANCE_WAKE, wake_flags);
+       if (cpu != orig_cpu)
                set_task_cpu(p, cpu);
-       }
+       __task_rq_unlock(rq);
 
        rq = cpu_rq(cpu);
        raw_spin_lock(&rq->lock);
-       update_rq_clock(rq);
 
        /*
         * We migrated the task without holding either rq->lock, however
@@ -2437,36 +2380,20 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
 
 out_activate:
 #endif /* CONFIG_SMP */
-       schedstat_inc(p, se.nr_wakeups);
+       schedstat_inc(p, se.statistics.nr_wakeups);
        if (wake_flags & WF_SYNC)
-               schedstat_inc(p, se.nr_wakeups_sync);
+               schedstat_inc(p, se.statistics.nr_wakeups_sync);
        if (orig_cpu != cpu)
-               schedstat_inc(p, se.nr_wakeups_migrate);
+               schedstat_inc(p, se.statistics.nr_wakeups_migrate);
        if (cpu == this_cpu)
-               schedstat_inc(p, se.nr_wakeups_local);
+               schedstat_inc(p, se.statistics.nr_wakeups_local);
        else
-               schedstat_inc(p, se.nr_wakeups_remote);
-       activate_task(rq, p, 1);
+               schedstat_inc(p, se.statistics.nr_wakeups_remote);
+       activate_task(rq, p, en_flags);
        success = 1;
 
-       /*
-        * Only attribute actual wakeups done by this task.
-        */
-       if (!in_interrupt()) {
-               struct sched_entity *se = &current->se;
-               u64 sample = se->sum_exec_runtime;
-
-               if (se->last_wakeup)
-                       sample -= se->last_wakeup;
-               else
-                       sample -= se->start_runtime;
-               update_avg(&se->avg_wakeup, sample);
-
-               se->last_wakeup = se->sum_exec_runtime;
-       }
-
 out_running:
-       trace_sched_wakeup(rq, p, success);
+       trace_sched_wakeup(p, success);
        check_preempt_curr(rq, p, wake_flags);
 
        p->state = TASK_RUNNING;
@@ -2526,42 +2453,9 @@ static void __sched_fork(struct task_struct *p)
        p->se.sum_exec_runtime          = 0;
        p->se.prev_sum_exec_runtime     = 0;
        p->se.nr_migrations             = 0;
-       p->se.last_wakeup               = 0;
-       p->se.avg_overlap               = 0;
-       p->se.start_runtime             = 0;
-       p->se.avg_wakeup                = sysctl_sched_wakeup_granularity;
 
 #ifdef CONFIG_SCHEDSTATS
-       p->se.wait_start                        = 0;
-       p->se.wait_max                          = 0;
-       p->se.wait_count                        = 0;
-       p->se.wait_sum                          = 0;
-
-       p->se.sleep_start                       = 0;
-       p->se.sleep_max                         = 0;
-       p->se.sum_sleep_runtime                 = 0;
-
-       p->se.block_start                       = 0;
-       p->se.block_max                         = 0;
-       p->se.exec_max                          = 0;
-       p->se.slice_max                         = 0;
-
-       p->se.nr_migrations_cold                = 0;
-       p->se.nr_failed_migrations_affine       = 0;
-       p->se.nr_failed_migrations_running      = 0;
-       p->se.nr_failed_migrations_hot          = 0;
-       p->se.nr_forced_migrations              = 0;
-
-       p->se.nr_wakeups                        = 0;
-       p->se.nr_wakeups_sync                   = 0;
-       p->se.nr_wakeups_migrate                = 0;
-       p->se.nr_wakeups_local                  = 0;
-       p->se.nr_wakeups_remote                 = 0;
-       p->se.nr_wakeups_affine                 = 0;
-       p->se.nr_wakeups_affine_attempts        = 0;
-       p->se.nr_wakeups_passive                = 0;
-       p->se.nr_wakeups_idle                   = 0;
-
+       memset(&p->se.statistics, 0, sizeof(p->se.statistics));
 #endif
 
        INIT_LIST_HEAD(&p->rt.run_list);
@@ -2582,11 +2476,11 @@ void sched_fork(struct task_struct *p, int clone_flags)
 
        __sched_fork(p);
        /*
-        * We mark the process as waking here. This guarantees that
+        * We mark the process as running here. This guarantees that
         * nobody will actually run it, and a signal or other external
         * event cannot wake it up and insert it on the runqueue either.
         */
-       p->state = TASK_WAKING;
+       p->state = TASK_RUNNING;
 
        /*
         * Revert to default priority/policy on fork if requested.
@@ -2650,34 +2544,30 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
 {
        unsigned long flags;
        struct rq *rq;
-       int cpu = get_cpu();
+       int cpu __maybe_unused = get_cpu();
 
 #ifdef CONFIG_SMP
+       rq = task_rq_lock(p, &flags);
+       p->state = TASK_WAKING;
+
        /*
         * Fork balancing, do it here and not earlier because:
         *  - cpus_allowed can change in the fork path
         *  - any previously selected cpu might disappear through hotplug
         *
-        * We still have TASK_WAKING but PF_STARTING is gone now, meaning
-        * ->cpus_allowed is stable, we have preemption disabled, meaning
-        * cpu_online_mask is stable.
+        * We set TASK_WAKING so that select_task_rq() can drop rq->lock
+        * without people poking at ->cpus_allowed.
         */
-       cpu = select_task_rq(p, SD_BALANCE_FORK, 0);
+       cpu = select_task_rq(rq, p, SD_BALANCE_FORK, 0);
        set_task_cpu(p, cpu);
-#endif
 
-       /*
-        * Since the task is not on the rq and we still have TASK_WAKING set
-        * nobody else will migrate this task.
-        */
-       rq = cpu_rq(cpu);
-       raw_spin_lock_irqsave(&rq->lock, flags);
-
-       BUG_ON(p->state != TASK_WAKING);
        p->state = TASK_RUNNING;
-       update_rq_clock(rq);
+       task_rq_unlock(rq, &flags);
+#endif
+
+       rq = task_rq_lock(p, &flags);
        activate_task(rq, p, 0);
-       trace_sched_wakeup_new(rq, p, 1);
+       trace_sched_wakeup_new(p, 1);
        check_preempt_curr(rq, p, WF_FORK);
 #ifdef CONFIG_SMP
        if (p->sched_class->task_woken)
@@ -2897,7 +2787,7 @@ context_switch(struct rq *rq, struct task_struct *prev,
        struct mm_struct *mm, *oldmm;
 
        prepare_task_switch(rq, prev, next);
-       trace_sched_switch(rq, prev, next);
+       trace_sched_switch(prev, next);
        mm = next->mm;
        oldmm = prev->active_mm;
        /*
@@ -3014,6 +2904,61 @@ static unsigned long calc_load_update;
 unsigned long avenrun[3];
 EXPORT_SYMBOL(avenrun);
 
+static long calc_load_fold_active(struct rq *this_rq)
+{
+       long nr_active, delta = 0;
+
+       nr_active = this_rq->nr_running;
+       nr_active += (long) this_rq->nr_uninterruptible;
+
+       if (nr_active != this_rq->calc_load_active) {
+               delta = nr_active - this_rq->calc_load_active;
+               this_rq->calc_load_active = nr_active;
+       }
+
+       return delta;
+}
+
+#ifdef CONFIG_NO_HZ
+/*
+ * For NO_HZ we delay the active fold to the next LOAD_FREQ update.
+ *
+ * When making the ILB scale, we should try to pull this in as well.
+ */
+static atomic_long_t calc_load_tasks_idle;
+
+static void calc_load_account_idle(struct rq *this_rq)
+{
+       long delta;
+
+       delta = calc_load_fold_active(this_rq);
+       if (delta)
+               atomic_long_add(delta, &calc_load_tasks_idle);
+}
+
+static long calc_load_fold_idle(void)
+{
+       long delta = 0;
+
+       /*
+        * Its got a race, we don't care...
+        */
+       if (atomic_long_read(&calc_load_tasks_idle))
+               delta = atomic_long_xchg(&calc_load_tasks_idle, 0);
+
+       return delta;
+}
+#else
+static void calc_load_account_idle(struct rq *this_rq)
+{
+}
+
+static inline long calc_load_fold_idle(void)
+{
+       return 0;
+}
+#endif
+
 /**
  * get_avenrun - get the load average array
  * @loads:     pointer to dest load array
@@ -3060,20 +3005,22 @@ void calc_global_load(void)
 }
 
 /*
- * Either called from update_cpu_load() or from a cpu going idle
+ * Called from update_cpu_load() to periodically update this CPU's
+ * active count.
  */
 static void calc_load_account_active(struct rq *this_rq)
 {
-       long nr_active, delta;
+       long delta;
 
-       nr_active = this_rq->nr_running;
-       nr_active += (long) this_rq->nr_uninterruptible;
+       if (time_before(jiffies, this_rq->calc_load_update))
+               return;
 
-       if (nr_active != this_rq->calc_load_active) {
-               delta = nr_active - this_rq->calc_load_active;
-               this_rq->calc_load_active = nr_active;
+       delta  = calc_load_fold_active(this_rq);
+       delta += calc_load_fold_idle();
+       if (delta)
                atomic_long_add(delta, &calc_load_tasks);
-       }
+
+       this_rq->calc_load_update += LOAD_FREQ;
 }
 
 /*
@@ -3105,10 +3052,7 @@ static void update_cpu_load(struct rq *this_rq)
                this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) >> i;
        }
 
-       if (time_after_eq(jiffies, this_rq->calc_load_update)) {
-               this_rq->calc_load_update += LOAD_FREQ;
-               calc_load_account_active(this_rq);
-       }
+       calc_load_account_active(this_rq);
 }
 
 #ifdef CONFIG_SMP
@@ -3120,44 +3064,27 @@ static void update_cpu_load(struct rq *this_rq)
 void sched_exec(void)
 {
        struct task_struct *p = current;
-       struct migration_req req;
-       int dest_cpu, this_cpu;
        unsigned long flags;
        struct rq *rq;
-
-again:
-       this_cpu = get_cpu();
-       dest_cpu = select_task_rq(p, SD_BALANCE_EXEC, 0);
-       if (dest_cpu == this_cpu) {
-               put_cpu();
-               return;
-       }
+       int dest_cpu;
 
        rq = task_rq_lock(p, &flags);
-       put_cpu();
+       dest_cpu = p->sched_class->select_task_rq(rq, p, SD_BALANCE_EXEC, 0);
+       if (dest_cpu == smp_processor_id())
+               goto unlock;
 
        /*
         * select_task_rq() can race against ->cpus_allowed
         */
-       if (!cpumask_test_cpu(dest_cpu, &p->cpus_allowed)
-           || unlikely(!cpu_active(dest_cpu))) {
-               task_rq_unlock(rq, &flags);
-               goto again;
-       }
+       if (cpumask_test_cpu(dest_cpu, &p->cpus_allowed) &&
+           likely(cpu_active(dest_cpu)) && migrate_task(p, dest_cpu)) {
+               struct migration_arg arg = { p, dest_cpu };
 
-       /* force the process onto the specified CPU */
-       if (migrate_task(p, dest_cpu, &req)) {
-               /* Need to wait for migration thread (might exit: take ref). */
-               struct task_struct *mt = rq->migration_thread;
-
-               get_task_struct(mt);
                task_rq_unlock(rq, &flags);
-               wake_up_process(mt);
-               put_task_struct(mt);
-               wait_for_completion(&req.done);
-
+               stop_one_cpu(cpu_of(rq), migration_cpu_stop, &arg);
                return;
        }
+unlock:
        task_rq_unlock(rq, &flags);
 }
 
@@ -3629,23 +3556,9 @@ static inline void schedule_debug(struct task_struct *prev)
 
 static void put_prev_task(struct rq *rq, struct task_struct *prev)
 {
-       if (prev->state == TASK_RUNNING) {
-               u64 runtime = prev->se.sum_exec_runtime;
-
-               runtime -= prev->se.prev_sum_exec_runtime;
-               runtime = min_t(u64, runtime, 2*sysctl_sched_migration_cost);
-
-               /*
-                * In order to avoid avg_overlap growing stale when we are
-                * indeed overlapping and hence not getting put to sleep, grow
-                * the avg_overlap on preemption.
-                *
-                * We use the average preemption runtime because that
-                * correlates to the amount of cache footprint a task can
-                * build up.
-                */
-               update_avg(&prev->se.avg_overlap, runtime);
-       }
+       if (prev->se.on_rq)
+               update_rq_clock(rq);
+       rq->skip_clock_update = 0;
        prev->sched_class->put_prev_task(rq, prev);
 }
 
@@ -3695,7 +3608,7 @@ need_resched:
        preempt_disable();
        cpu = smp_processor_id();
        rq = cpu_rq(cpu);
-       rcu_sched_qs(cpu);
+       rcu_note_context_switch(cpu);
        prev = rq->curr;
        switch_count = &prev->nivcsw;
 
@@ -3708,14 +3621,13 @@ need_resched_nonpreemptible:
                hrtick_clear(rq);
 
        raw_spin_lock_irq(&rq->lock);
-       update_rq_clock(rq);
        clear_tsk_need_resched(prev);
 
        if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
                if (unlikely(signal_pending_state(prev->state, prev)))
                        prev->state = TASK_RUNNING;
                else
-                       deactivate_task(rq, prev, 1);
+                       deactivate_task(rq, prev, DEQUEUE_SLEEP);
                switch_count = &prev->nvcsw;
        }
 
@@ -3779,7 +3691,7 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner)
         * the mutex owner just released it and exited.
         */
        if (probe_kernel_address(&owner->cpu, cpu))
-               goto out;
+               return 0;
 #else
        cpu = owner->cpu;
 #endif
@@ -3789,14 +3701,14 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner)
         * the cpu field may no longer be valid.
         */
        if (cpu >= nr_cpumask_bits)
-               goto out;
+               return 0;
 
        /*
         * We need to validate that we can do a
         * get_cpu() and that we have the percpu area.
         */
        if (!cpu_online(cpu))
-               goto out;
+               return 0;
 
        rq = cpu_rq(cpu);
 
@@ -3815,7 +3727,7 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner)
 
                cpu_relax();
        }
-out:
+
        return 1;
 }
 #endif
@@ -4038,8 +3950,7 @@ do_wait_for_common(struct completion *x, long timeout, int state)
        if (!x->done) {
                DECLARE_WAITQUEUE(wait, current);
 
-               wait.flags |= WQ_FLAG_EXCLUSIVE;
-               __add_wait_queue_tail(&x->wait, &wait);
+               __add_wait_queue_tail_exclusive(&x->wait, &wait);
                do {
                        if (signal_pending_state(state, current)) {
                                timeout = -ERESTARTSYS;
@@ -4265,7 +4176,6 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
        BUG_ON(prio < 0 || prio > MAX_PRIO);
 
        rq = task_rq_lock(p, &flags);
-       update_rq_clock(rq);
 
        oldprio = p->prio;
        prev_class = p->sched_class;
@@ -4286,7 +4196,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
        if (running)
                p->sched_class->set_curr_task(rq);
        if (on_rq) {
-               enqueue_task(rq, p, 0, oldprio < prio);
+               enqueue_task(rq, p, oldprio < prio ? ENQUEUE_HEAD : 0);
 
                check_class_changed(rq, p, prev_class, oldprio, running);
        }
@@ -4308,7 +4218,6 @@ void set_user_nice(struct task_struct *p, long nice)
         * the task might be in the middle of scheduling on another CPU.
         */
        rq = task_rq_lock(p, &flags);
-       update_rq_clock(rq);
        /*
         * The RT priorities are set via sched_setscheduler(), but we still
         * allow the 'normal' nice value to be set - but as expected
@@ -4330,7 +4239,7 @@ void set_user_nice(struct task_struct *p, long nice)
        delta = p->prio - old_prio;
 
        if (on_rq) {
-               enqueue_task(rq, p, 0, false);
+               enqueue_task(rq, p, 0);
                /*
                 * If the task increased its priority or is running and
                 * lowered its priority, then reschedule its CPU:
@@ -4591,7 +4500,6 @@ recheck:
                raw_spin_unlock_irqrestore(&p->pi_lock, flags);
                goto recheck;
        }
-       update_rq_clock(rq);
        on_rq = p->se.on_rq;
        running = task_current(rq, p);
        if (on_rq)
@@ -4902,7 +4810,9 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len,
        int ret;
        cpumask_var_t mask;
 
-       if (len < cpumask_size())
+       if ((len * BITS_PER_BYTE) < nr_cpu_ids)
+               return -EINVAL;
+       if (len & (sizeof(unsigned long)-1))
                return -EINVAL;
 
        if (!alloc_cpumask_var(&mask, GFP_KERNEL))
@@ -4910,10 +4820,12 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len,
 
        ret = sched_getaffinity(pid, mask);
        if (ret == 0) {
-               if (copy_to_user(user_mask_ptr, mask, cpumask_size()))
+               size_t retlen = min_t(size_t, len, cpumask_size());
+
+               if (copy_to_user(user_mask_ptr, mask, retlen))
                        ret = -EFAULT;
                else
-                       ret = cpumask_size();
+                       ret = retlen;
        }
        free_cpumask_var(mask);
 
@@ -5324,17 +5236,15 @@ static inline void sched_init_granularity(void)
 /*
  * This is how migration works:
  *
- * 1) we queue a struct migration_req structure in the source CPU's
- *    runqueue and wake up that CPU's migration thread.
- * 2) we down() the locked semaphore => thread blocks.
- * 3) migration thread wakes up (implicitly it forces the migrated
- *    thread off the CPU)
- * 4) it gets the migration request and checks whether the migrated
- *    task is still in the wrong runqueue.
- * 5) if it's in the wrong runqueue then the migration thread removes
+ * 1) we invoke migration_cpu_stop() on the target CPU using
+ *    stop_one_cpu().
+ * 2) stopper starts to run (implicitly forcing the migrated thread
+ *    off the CPU)
+ * 3) it checks whether the migrated task is still in the wrong runqueue.
+ * 4) if it's in the wrong runqueue then the migration thread removes
  *    it and puts it into the right queue.
- * 6) migration thread up()s the semaphore.
- * 7) we wake up and the migration is done.
+ * 5) stopper completes and stop_one_cpu() returns and the migration
+ *    is done.
  */
 
 /*
@@ -5348,12 +5258,23 @@ static inline void sched_init_granularity(void)
  */
 int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask)
 {
-       struct migration_req req;
        unsigned long flags;
        struct rq *rq;
+       unsigned int dest_cpu;
        int ret = 0;
 
+       /*
+        * Serialize against TASK_WAKING so that ttwu() and wunt() can
+        * drop the rq->lock and still rely on ->cpus_allowed.
+        */
+again:
+       while (task_is_waking(p))
+               cpu_relax();
        rq = task_rq_lock(p, &flags);
+       if (task_is_waking(p)) {
+               task_rq_unlock(rq, &flags);
+               goto again;
+       }
 
        if (!cpumask_intersects(new_mask, cpu_active_mask)) {
                ret = -EINVAL;
@@ -5377,15 +5298,12 @@ int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask)
        if (cpumask_test_cpu(task_cpu(p), new_mask))
                goto out;
 
-       if (migrate_task(p, cpumask_any_and(cpu_active_mask, new_mask), &req)) {
+       dest_cpu = cpumask_any_and(cpu_active_mask, new_mask);
+       if (migrate_task(p, dest_cpu)) {
+               struct migration_arg arg = { p, dest_cpu };
                /* Need help from migration thread: drop lock and wait. */
-               struct task_struct *mt = rq->migration_thread;
-
-               get_task_struct(mt);
                task_rq_unlock(rq, &flags);
-               wake_up_process(rq->migration_thread);
-               put_task_struct(mt);
-               wait_for_completion(&req.done);
+               stop_one_cpu(cpu_of(rq), migration_cpu_stop, &arg);
                tlb_migrate_finish(p->mm);
                return 0;
        }
@@ -5443,98 +5361,49 @@ fail:
        return ret;
 }
 
-#define RCU_MIGRATION_IDLE     0
-#define RCU_MIGRATION_NEED_QS  1
-#define RCU_MIGRATION_GOT_QS   2
-#define RCU_MIGRATION_MUST_SYNC        3
-
 /*
- * migration_thread - this is a highprio system thread that performs
- * thread migration by bumping thread off CPU then 'pushing' onto
- * another runqueue.
+ * migration_cpu_stop - this will be executed by a highprio stopper thread
+ * and performs thread migration by bumping thread off CPU then
+ * 'pushing' onto another runqueue.
  */
-static int migration_thread(void *data)
-{
-       int badcpu;
-       int cpu = (long)data;
-       struct rq *rq;
-
-       rq = cpu_rq(cpu);
-       BUG_ON(rq->migration_thread != current);
-
-       set_current_state(TASK_INTERRUPTIBLE);
-       while (!kthread_should_stop()) {
-               struct migration_req *req;
-               struct list_head *head;
-
-               raw_spin_lock_irq(&rq->lock);
-
-               if (cpu_is_offline(cpu)) {
-                       raw_spin_unlock_irq(&rq->lock);
-                       break;
-               }
-
-               if (rq->active_balance) {
-                       active_load_balance(rq, cpu);
-                       rq->active_balance = 0;
-               }
-
-               head = &rq->migration_queue;
-
-               if (list_empty(head)) {
-                       raw_spin_unlock_irq(&rq->lock);
-                       schedule();
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       continue;
-               }
-               req = list_entry(head->next, struct migration_req, list);
-               list_del_init(head->next);
-
-               if (req->task != NULL) {
-                       raw_spin_unlock(&rq->lock);
-                       __migrate_task(req->task, cpu, req->dest_cpu);
-               } else if (likely(cpu == (badcpu = smp_processor_id()))) {
-                       req->dest_cpu = RCU_MIGRATION_GOT_QS;
-                       raw_spin_unlock(&rq->lock);
-               } else {
-                       req->dest_cpu = RCU_MIGRATION_MUST_SYNC;
-                       raw_spin_unlock(&rq->lock);
-                       WARN_ONCE(1, "migration_thread() on CPU %d, expected %d\n", badcpu, cpu);
-               }
-               local_irq_enable();
-
-               complete(&req->done);
-       }
-       __set_current_state(TASK_RUNNING);
-
-       return 0;
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-
-static int __migrate_task_irq(struct task_struct *p, int src_cpu, int dest_cpu)
+static int migration_cpu_stop(void *data)
 {
-       int ret;
+       struct migration_arg *arg = data;
 
+       /*
+        * The original target cpu might have gone down and we might
+        * be on another cpu but it doesn't matter.
+        */
        local_irq_disable();
-       ret = __migrate_task(p, src_cpu, dest_cpu);
+       __migrate_task(arg->task, raw_smp_processor_id(), arg->dest_cpu);
        local_irq_enable();
-       return ret;
+       return 0;
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
 /*
  * Figure out where task on dead CPU should go, use force if necessary.
  */
-static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
+void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
 {
-       int dest_cpu;
+       struct rq *rq = cpu_rq(dead_cpu);
+       int needs_cpu, uninitialized_var(dest_cpu);
+       unsigned long flags;
 
-again:
-       dest_cpu = select_fallback_rq(dead_cpu, p);
+       local_irq_save(flags);
 
-       /* It can have affinity changed while we were choosing. */
-       if (unlikely(!__migrate_task_irq(p, dead_cpu, dest_cpu)))
-               goto again;
+       raw_spin_lock(&rq->lock);
+       needs_cpu = (task_cpu(p) == dead_cpu) && (p->state != TASK_WAKING);
+       if (needs_cpu)
+               dest_cpu = select_fallback_rq(dead_cpu, p);
+       raw_spin_unlock(&rq->lock);
+       /*
+        * It can only fail if we race with set_cpus_allowed(),
+        * in the racer should migrate the task anyway.
+        */
+       if (needs_cpu)
+               __migrate_task(p, dead_cpu, dest_cpu);
+       local_irq_restore(flags);
 }
 
 /*
@@ -5598,7 +5467,6 @@ void sched_idle_next(void)
 
        __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1);
 
-       update_rq_clock(rq);
        activate_task(rq, p, 0);
 
        raw_spin_unlock_irqrestore(&rq->lock, flags);
@@ -5653,7 +5521,6 @@ static void migrate_dead_tasks(unsigned int dead_cpu)
        for ( ; ; ) {
                if (!rq->nr_running)
                        break;
-               update_rq_clock(rq);
                next = pick_next_task(rq);
                if (!next)
                        break;
@@ -5876,35 +5743,20 @@ static void set_rq_offline(struct rq *rq)
 static int __cpuinit
 migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
-       struct task_struct *p;
        int cpu = (long)hcpu;
        unsigned long flags;
-       struct rq *rq;
+       struct rq *rq = cpu_rq(cpu);
 
        switch (action) {
 
        case CPU_UP_PREPARE:
        case CPU_UP_PREPARE_FROZEN:
-               p = kthread_create(migration_thread, hcpu, "migration/%d", cpu);
-               if (IS_ERR(p))
-                       return NOTIFY_BAD;
-               kthread_bind(p, cpu);
-               /* Must be high prio: stop_machine expects to yield to it. */
-               rq = task_rq_lock(p, &flags);
-               __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1);
-               task_rq_unlock(rq, &flags);
-               get_task_struct(p);
-               cpu_rq(cpu)->migration_thread = p;
                rq->calc_load_update = calc_load_update;
                break;
 
        case CPU_ONLINE:
        case CPU_ONLINE_FROZEN:
-               /* Strictly unnecessary, as first user will wake it. */
-               wake_up_process(cpu_rq(cpu)->migration_thread);
-
                /* Update our root-domain */
-               rq = cpu_rq(cpu);
                raw_spin_lock_irqsave(&rq->lock, flags);
                if (rq->rd) {
                        BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span));
@@ -5915,61 +5767,24 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
                break;
 
 #ifdef CONFIG_HOTPLUG_CPU
-       case CPU_UP_CANCELED:
-       case CPU_UP_CANCELED_FROZEN:
-               if (!cpu_rq(cpu)->migration_thread)
-                       break;
-               /* Unbind it from offline cpu so it can run. Fall thru. */
-               kthread_bind(cpu_rq(cpu)->migration_thread,
-                            cpumask_any(cpu_online_mask));
-               kthread_stop(cpu_rq(cpu)->migration_thread);
-               put_task_struct(cpu_rq(cpu)->migration_thread);
-               cpu_rq(cpu)->migration_thread = NULL;
-               break;
-
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
-               cpuset_lock(); /* around calls to cpuset_cpus_allowed_lock() */
                migrate_live_tasks(cpu);
-               rq = cpu_rq(cpu);
-               kthread_stop(rq->migration_thread);
-               put_task_struct(rq->migration_thread);
-               rq->migration_thread = NULL;
                /* Idle task back to normal (off runqueue, low prio) */
                raw_spin_lock_irq(&rq->lock);
-               update_rq_clock(rq);
                deactivate_task(rq, rq->idle, 0);
                __setscheduler(rq, rq->idle, SCHED_NORMAL, 0);
                rq->idle->sched_class = &idle_sched_class;
                migrate_dead_tasks(cpu);
                raw_spin_unlock_irq(&rq->lock);
-               cpuset_unlock();
                migrate_nr_uninterruptible(rq);
                BUG_ON(rq->nr_running != 0);
                calc_global_load_remove(rq);
-               /*
-                * No need to migrate the tasks: it was best-effort if
-                * they didn't take sched_hotcpu_mutex. Just wake up
-                * the requestors.
-                */
-               raw_spin_lock_irq(&rq->lock);
-               while (!list_empty(&rq->migration_queue)) {
-                       struct migration_req *req;
-
-                       req = list_entry(rq->migration_queue.next,
-                                        struct migration_req, list);
-                       list_del_init(&req->list);
-                       raw_spin_unlock_irq(&rq->lock);
-                       complete(&req->done);
-                       raw_spin_lock_irq(&rq->lock);
-               }
-               raw_spin_unlock_irq(&rq->lock);
                break;
 
        case CPU_DYING:
        case CPU_DYING_FROZEN:
                /* Update our root-domain */
-               rq = cpu_rq(cpu);
                raw_spin_lock_irqsave(&rq->lock, flags);
                if (rq->rd) {
                        BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span));
@@ -6300,6 +6115,9 @@ cpu_attach_domain(struct sched_domain *sd, struct root_domain *rd, int cpu)
        struct rq *rq = cpu_rq(cpu);
        struct sched_domain *tmp;
 
+       for (tmp = sd; tmp; tmp = tmp->parent)
+               tmp->span_weight = cpumask_weight(sched_domain_span(tmp));
+
        /* Remove the sched domains which do not contribute to scheduling. */
        for (tmp = sd; tmp; ) {
                struct sched_domain *parent = tmp->parent;
@@ -7783,10 +7601,8 @@ void __init sched_init(void)
                rq->push_cpu = 0;
                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
                init_rq_hrtick(rq);
@@ -7887,7 +7703,6 @@ static void normalize_task(struct rq *rq, struct task_struct *p)
 {
        int on_rq;
 
-       update_rq_clock(rq);
        on_rq = p->se.on_rq;
        if (on_rq)
                deactivate_task(rq, p, 0);
@@ -7914,9 +7729,9 @@ void normalize_rt_tasks(void)
 
                p->se.exec_start                = 0;
 #ifdef CONFIG_SCHEDSTATS
-               p->se.wait_start                = 0;
-               p->se.sleep_start               = 0;
-               p->se.block_start               = 0;
+               p->se.statistics.wait_start     = 0;
+               p->se.statistics.sleep_start    = 0;
+               p->se.statistics.block_start    = 0;
 #endif
 
                if (!rt_task(p)) {
@@ -8249,8 +8064,6 @@ void sched_move_task(struct task_struct *tsk)
 
        rq = task_rq_lock(tsk, &flags);
 
-       update_rq_clock(rq);
-
        running = task_current(rq, tsk);
        on_rq = tsk->se.on_rq;
 
@@ -8269,7 +8082,7 @@ void sched_move_task(struct task_struct *tsk)
        if (unlikely(running))
                tsk->sched_class->set_curr_task(rq);
        if (on_rq)
-               enqueue_task(rq, tsk, 0, false);
+               enqueue_task(rq, tsk, 0);
 
        task_rq_unlock(rq, &flags);
 }
@@ -9083,43 +8896,32 @@ struct cgroup_subsys cpuacct_subsys = {
 
 #ifndef CONFIG_SMP
 
-int rcu_expedited_torture_stats(char *page)
-{
-       return 0;
-}
-EXPORT_SYMBOL_GPL(rcu_expedited_torture_stats);
-
 void synchronize_sched_expedited(void)
 {
+       barrier();
 }
 EXPORT_SYMBOL_GPL(synchronize_sched_expedited);
 
 #else /* #ifndef CONFIG_SMP */
 
-static DEFINE_PER_CPU(struct migration_req, rcu_migration_req);
-static DEFINE_MUTEX(rcu_sched_expedited_mutex);
-
-#define RCU_EXPEDITED_STATE_POST -2
-#define RCU_EXPEDITED_STATE_IDLE -1
+static atomic_t synchronize_sched_expedited_count = ATOMIC_INIT(0);
 
-static int rcu_expedited_state = RCU_EXPEDITED_STATE_IDLE;
-
-int rcu_expedited_torture_stats(char *page)
+static int synchronize_sched_expedited_cpu_stop(void *data)
 {
-       int cnt = 0;
-       int cpu;
-
-       cnt += sprintf(&page[cnt], "state: %d /", rcu_expedited_state);
-       for_each_online_cpu(cpu) {
-                cnt += sprintf(&page[cnt], " %d:%d",
-                               cpu, per_cpu(rcu_migration_req, cpu).dest_cpu);
-       }
-       cnt += sprintf(&page[cnt], "\n");
-       return cnt;
+       /*
+        * There must be a full memory barrier on each affected CPU
+        * between the time that try_stop_cpus() is called and the
+        * time that it returns.
+        *
+        * In the current initial implementation of cpu_stop, the
+        * above condition is already met when the control reaches
+        * this point and the following smp_mb() is not strictly
+        * necessary.  Do smp_mb() anyway for documentation and
+        * robustness against future implementation changes.
+        */
+       smp_mb(); /* See above comment block. */
+       return 0;
 }
-EXPORT_SYMBOL_GPL(rcu_expedited_torture_stats);
-
-static long synchronize_sched_expedited_count;
 
 /*
  * Wait for an rcu-sched grace period to elapse, but use "big hammer"
@@ -9133,18 +8935,14 @@ static long synchronize_sched_expedited_count;
  */
 void synchronize_sched_expedited(void)
 {
-       int cpu;
-       unsigned long flags;
-       bool need_full_sync = 0;
-       struct rq *rq;
-       struct migration_req *req;
-       long snap;
-       int trycount = 0;
+       int snap, trycount = 0;
 
        smp_mb();  /* ensure prior mod happens before capturing snap. */
-       snap = ACCESS_ONCE(synchronize_sched_expedited_count) + 1;
+       snap = atomic_read(&synchronize_sched_expedited_count) + 1;
        get_online_cpus();
-       while (!mutex_trylock(&rcu_sched_expedited_mutex)) {
+       while (try_stop_cpus(cpu_online_mask,
+                            synchronize_sched_expedited_cpu_stop,
+                            NULL) == -EAGAIN) {
                put_online_cpus();
                if (trycount++ < 10)
                        udelay(trycount * num_online_cpus());
@@ -9152,41 +8950,15 @@ void synchronize_sched_expedited(void)
                        synchronize_sched();
                        return;
                }
-               if (ACCESS_ONCE(synchronize_sched_expedited_count) - snap > 0) {
+               if (atomic_read(&synchronize_sched_expedited_count) - snap > 0) {
                        smp_mb(); /* ensure test happens before caller kfree */
                        return;
                }
                get_online_cpus();
        }
-       rcu_expedited_state = RCU_EXPEDITED_STATE_POST;
-       for_each_online_cpu(cpu) {
-               rq = cpu_rq(cpu);
-               req = &per_cpu(rcu_migration_req, cpu);
-               init_completion(&req->done);
-               req->task = NULL;
-               req->dest_cpu = RCU_MIGRATION_NEED_QS;
-               raw_spin_lock_irqsave(&rq->lock, flags);
-               list_add(&req->list, &rq->migration_queue);
-               raw_spin_unlock_irqrestore(&rq->lock, flags);
-               wake_up_process(rq->migration_thread);
-       }
-       for_each_online_cpu(cpu) {
-               rcu_expedited_state = cpu;
-               req = &per_cpu(rcu_migration_req, cpu);
-               rq = cpu_rq(cpu);
-               wait_for_completion(&req->done);
-               raw_spin_lock_irqsave(&rq->lock, flags);
-               if (unlikely(req->dest_cpu == RCU_MIGRATION_MUST_SYNC))
-                       need_full_sync = 1;
-               req->dest_cpu = RCU_MIGRATION_IDLE;
-               raw_spin_unlock_irqrestore(&rq->lock, flags);
-       }
-       rcu_expedited_state = RCU_EXPEDITED_STATE_IDLE;
-       synchronize_sched_expedited_count++;
-       mutex_unlock(&rcu_sched_expedited_mutex);
+       atomic_inc(&synchronize_sched_expedited_count);
+       smp_mb__after_atomic_inc(); /* ensure post-GP actions seen after GP. */
        put_online_cpus();
-       if (need_full_sync)
-               synchronize_sched();
 }
 EXPORT_SYMBOL_GPL(synchronize_sched_expedited);
 
index fccf9fbb0d7bc9bd6c2ca6dceadd8560d2dbc492..e6871cb3fc83dde1901b62c6355edc30ea55a64e 100644 (file)
@@ -27,6 +27,7 @@
  *  of the License.
  */
 
+#include <linux/gfp.h>
 #include "sched_cpupri.h"
 
 /* Convert between a 140 based task->prio, and our 102 based cpupri */
index 67f95aada4b95637b75432278b9d7391401a62d6..87a330a7185fd7c145a341e2d417c5778c4538f6 100644 (file)
@@ -70,16 +70,16 @@ static void print_cfs_group_stats(struct seq_file *m, int cpu,
        PN(se->vruntime);
        PN(se->sum_exec_runtime);
 #ifdef CONFIG_SCHEDSTATS
-       PN(se->wait_start);
-       PN(se->sleep_start);
-       PN(se->block_start);
-       PN(se->sleep_max);
-       PN(se->block_max);
-       PN(se->exec_max);
-       PN(se->slice_max);
-       PN(se->wait_max);
-       PN(se->wait_sum);
-       P(se->wait_count);
+       PN(se->statistics.wait_start);
+       PN(se->statistics.sleep_start);
+       PN(se->statistics.block_start);
+       PN(se->statistics.sleep_max);
+       PN(se->statistics.block_max);
+       PN(se->statistics.exec_max);
+       PN(se->statistics.slice_max);
+       PN(se->statistics.wait_max);
+       PN(se->statistics.wait_sum);
+       P(se->statistics.wait_count);
 #endif
        P(se->load.weight);
 #undef PN
@@ -104,7 +104,7 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
        SEQ_printf(m, "%9Ld.%06ld %9Ld.%06ld %9Ld.%06ld",
                SPLIT_NS(p->se.vruntime),
                SPLIT_NS(p->se.sum_exec_runtime),
-               SPLIT_NS(p->se.sum_sleep_runtime));
+               SPLIT_NS(p->se.statistics.sum_sleep_runtime));
 #else
        SEQ_printf(m, "%15Ld %15Ld %15Ld.%06ld %15Ld.%06ld %15Ld.%06ld",
                0LL, 0LL, 0LL, 0L, 0LL, 0L, 0LL, 0L);
@@ -114,7 +114,9 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
        {
                char path[64];
 
+               rcu_read_lock();
                cgroup_path(task_group(p)->css.cgroup, path, sizeof(path));
+               rcu_read_unlock();
                SEQ_printf(m, " %s", path);
        }
 #endif
@@ -173,11 +175,6 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
        task_group_path(tg, path, sizeof(path));
 
        SEQ_printf(m, "\ncfs_rq[%d]:%s\n", cpu, path);
-#elif defined(CONFIG_USER_SCHED) && defined(CONFIG_FAIR_GROUP_SCHED)
-       {
-               uid_t uid = cfs_rq->tg->uid;
-               SEQ_printf(m, "\ncfs_rq[%d] for UID: %u\n", cpu, uid);
-       }
 #else
        SEQ_printf(m, "\ncfs_rq[%d]:\n", cpu);
 #endif
@@ -407,40 +404,38 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m)
        PN(se.exec_start);
        PN(se.vruntime);
        PN(se.sum_exec_runtime);
-       PN(se.avg_overlap);
-       PN(se.avg_wakeup);
 
        nr_switches = p->nvcsw + p->nivcsw;
 
 #ifdef CONFIG_SCHEDSTATS
-       PN(se.wait_start);
-       PN(se.sleep_start);
-       PN(se.block_start);
-       PN(se.sleep_max);
-       PN(se.block_max);
-       PN(se.exec_max);
-       PN(se.slice_max);
-       PN(se.wait_max);
-       PN(se.wait_sum);
-       P(se.wait_count);
-       PN(se.iowait_sum);
-       P(se.iowait_count);
+       PN(se.statistics.wait_start);
+       PN(se.statistics.sleep_start);
+       PN(se.statistics.block_start);
+       PN(se.statistics.sleep_max);
+       PN(se.statistics.block_max);
+       PN(se.statistics.exec_max);
+       PN(se.statistics.slice_max);
+       PN(se.statistics.wait_max);
+       PN(se.statistics.wait_sum);
+       P(se.statistics.wait_count);
+       PN(se.statistics.iowait_sum);
+       P(se.statistics.iowait_count);
        P(sched_info.bkl_count);
        P(se.nr_migrations);
-       P(se.nr_migrations_cold);
-       P(se.nr_failed_migrations_affine);
-       P(se.nr_failed_migrations_running);
-       P(se.nr_failed_migrations_hot);
-       P(se.nr_forced_migrations);
-       P(se.nr_wakeups);
-       P(se.nr_wakeups_sync);
-       P(se.nr_wakeups_migrate);
-       P(se.nr_wakeups_local);
-       P(se.nr_wakeups_remote);
-       P(se.nr_wakeups_affine);
-       P(se.nr_wakeups_affine_attempts);
-       P(se.nr_wakeups_passive);
-       P(se.nr_wakeups_idle);
+       P(se.statistics.nr_migrations_cold);
+       P(se.statistics.nr_failed_migrations_affine);
+       P(se.statistics.nr_failed_migrations_running);
+       P(se.statistics.nr_failed_migrations_hot);
+       P(se.statistics.nr_forced_migrations);
+       P(se.statistics.nr_wakeups);
+       P(se.statistics.nr_wakeups_sync);
+       P(se.statistics.nr_wakeups_migrate);
+       P(se.statistics.nr_wakeups_local);
+       P(se.statistics.nr_wakeups_remote);
+       P(se.statistics.nr_wakeups_affine);
+       P(se.statistics.nr_wakeups_affine_attempts);
+       P(se.statistics.nr_wakeups_passive);
+       P(se.statistics.nr_wakeups_idle);
 
        {
                u64 avg_atom, avg_per_cpu;
@@ -491,35 +486,6 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m)
 void proc_sched_set_task(struct task_struct *p)
 {
 #ifdef CONFIG_SCHEDSTATS
-       p->se.wait_max                          = 0;
-       p->se.wait_sum                          = 0;
-       p->se.wait_count                        = 0;
-       p->se.iowait_sum                        = 0;
-       p->se.iowait_count                      = 0;
-       p->se.sleep_max                         = 0;
-       p->se.sum_sleep_runtime                 = 0;
-       p->se.block_max                         = 0;
-       p->se.exec_max                          = 0;
-       p->se.slice_max                         = 0;
-       p->se.nr_migrations                     = 0;
-       p->se.nr_migrations_cold                = 0;
-       p->se.nr_failed_migrations_affine       = 0;
-       p->se.nr_failed_migrations_running      = 0;
-       p->se.nr_failed_migrations_hot          = 0;
-       p->se.nr_forced_migrations              = 0;
-       p->se.nr_wakeups                        = 0;
-       p->se.nr_wakeups_sync                   = 0;
-       p->se.nr_wakeups_migrate                = 0;
-       p->se.nr_wakeups_local                  = 0;
-       p->se.nr_wakeups_remote                 = 0;
-       p->se.nr_wakeups_affine                 = 0;
-       p->se.nr_wakeups_affine_attempts        = 0;
-       p->se.nr_wakeups_passive                = 0;
-       p->se.nr_wakeups_idle                   = 0;
-       p->sched_info.bkl_count                 = 0;
+       memset(&p->se.statistics, 0, sizeof(p->se.statistics));
 #endif
-       p->se.sum_exec_runtime                  = 0;
-       p->se.prev_sum_exec_runtime             = 0;
-       p->nvcsw                                = 0;
-       p->nivcsw                               = 0;
 }
index 5a5ea2cd924fa8494abfa21f8203f919f40ff1ca..217e4a9393e42c2f5dfdfae058625601c15e235b 100644 (file)
@@ -35,8 +35,8 @@
  * (to see the precise effective timeslice length of your workload,
  *  run vmstat and monitor the context-switches (cs) field)
  */
-unsigned int sysctl_sched_latency = 5000000ULL;
-unsigned int normalized_sysctl_sched_latency = 5000000ULL;
+unsigned int sysctl_sched_latency = 6000000ULL;
+unsigned int normalized_sysctl_sched_latency = 6000000ULL;
 
 /*
  * The initial- and re-scaling of tunables is configurable
@@ -52,15 +52,15 @@ enum sched_tunable_scaling sysctl_sched_tunable_scaling
 
 /*
  * Minimal preemption granularity for CPU-bound tasks:
- * (default: 1 msec * (1 + ilog(ncpus)), units: nanoseconds)
+ * (default: 2 msec * (1 + ilog(ncpus)), units: nanoseconds)
  */
-unsigned int sysctl_sched_min_granularity = 1000000ULL;
-unsigned int normalized_sysctl_sched_min_granularity = 1000000ULL;
+unsigned int sysctl_sched_min_granularity = 2000000ULL;
+unsigned int normalized_sysctl_sched_min_granularity = 2000000ULL;
 
 /*
  * is kept at sysctl_sched_latency / sysctl_sched_min_granularity
  */
-static unsigned int sched_nr_latency = 5;
+static unsigned int sched_nr_latency = 3;
 
 /*
  * After fork, child runs first. If set to 0 (default) then
@@ -505,7 +505,8 @@ __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr,
 {
        unsigned long delta_exec_weighted;
 
-       schedstat_set(curr->exec_max, max((u64)delta_exec, curr->exec_max));
+       schedstat_set(curr->statistics.exec_max,
+                     max((u64)delta_exec, curr->statistics.exec_max));
 
        curr->sum_exec_runtime += delta_exec;
        schedstat_add(cfs_rq, exec_clock, delta_exec);
@@ -548,7 +549,7 @@ static void update_curr(struct cfs_rq *cfs_rq)
 static inline void
 update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
-       schedstat_set(se->wait_start, rq_of(cfs_rq)->clock);
+       schedstat_set(se->statistics.wait_start, rq_of(cfs_rq)->clock);
 }
 
 /*
@@ -567,18 +568,18 @@ static void update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se)
 static void
 update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
-       schedstat_set(se->wait_max, max(se->wait_max,
-                       rq_of(cfs_rq)->clock - se->wait_start));
-       schedstat_set(se->wait_count, se->wait_count + 1);
-       schedstat_set(se->wait_sum, se->wait_sum +
-                       rq_of(cfs_rq)->clock - se->wait_start);
+       schedstat_set(se->statistics.wait_max, max(se->statistics.wait_max,
+                       rq_of(cfs_rq)->clock - se->statistics.wait_start));
+       schedstat_set(se->statistics.wait_count, se->statistics.wait_count + 1);
+       schedstat_set(se->statistics.wait_sum, se->statistics.wait_sum +
+                       rq_of(cfs_rq)->clock - se->statistics.wait_start);
 #ifdef CONFIG_SCHEDSTATS
        if (entity_is_task(se)) {
                trace_sched_stat_wait(task_of(se),
-                       rq_of(cfs_rq)->clock - se->wait_start);
+                       rq_of(cfs_rq)->clock - se->statistics.wait_start);
        }
 #endif
-       schedstat_set(se->wait_start, 0);
+       schedstat_set(se->statistics.wait_start, 0);
 }
 
 static inline void
@@ -657,39 +658,39 @@ static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
        if (entity_is_task(se))
                tsk = task_of(se);
 
-       if (se->sleep_start) {
-               u64 delta = rq_of(cfs_rq)->clock - se->sleep_start;
+       if (se->statistics.sleep_start) {
+               u64 delta = rq_of(cfs_rq)->clock - se->statistics.sleep_start;
 
                if ((s64)delta < 0)
                        delta = 0;
 
-               if (unlikely(delta > se->sleep_max))
-                       se->sleep_max = delta;
+               if (unlikely(delta > se->statistics.sleep_max))
+                       se->statistics.sleep_max = delta;
 
-               se->sleep_start = 0;
-               se->sum_sleep_runtime += delta;
+               se->statistics.sleep_start = 0;
+               se->statistics.sum_sleep_runtime += delta;
 
                if (tsk) {
                        account_scheduler_latency(tsk, delta >> 10, 1);
                        trace_sched_stat_sleep(tsk, delta);
                }
        }
-       if (se->block_start) {
-               u64 delta = rq_of(cfs_rq)->clock - se->block_start;
+       if (se->statistics.block_start) {
+               u64 delta = rq_of(cfs_rq)->clock - se->statistics.block_start;
 
                if ((s64)delta < 0)
                        delta = 0;
 
-               if (unlikely(delta > se->block_max))
-                       se->block_max = delta;
+               if (unlikely(delta > se->statistics.block_max))
+                       se->statistics.block_max = delta;
 
-               se->block_start = 0;
-               se->sum_sleep_runtime += delta;
+               se->statistics.block_start = 0;
+               se->statistics.sum_sleep_runtime += delta;
 
                if (tsk) {
                        if (tsk->in_iowait) {
-                               se->iowait_sum += delta;
-                               se->iowait_count++;
+                               se->statistics.iowait_sum += delta;
+                               se->statistics.iowait_count++;
                                trace_sched_stat_iowait(tsk, delta);
                        }
 
@@ -737,19 +738,9 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
                vruntime += sched_vslice(cfs_rq, se);
 
        /* sleeps up to a single latency don't count. */
-       if (!initial && sched_feat(FAIR_SLEEPERS)) {
+       if (!initial) {
                unsigned long thresh = sysctl_sched_latency;
 
-               /*
-                * Convert the sleeper threshold into virtual time.
-                * SCHED_IDLE is a special sub-class.  We care about
-                * fairness only relative to other SCHED_IDLE tasks,
-                * all of which have the same weight.
-                */
-               if (sched_feat(NORMALIZED_SLEEPER) && (!entity_is_task(se) ||
-                                task_of(se)->policy != SCHED_IDLE))
-                       thresh = calc_delta_fair(thresh, se);
-
                /*
                 * Halve their sleep time's effect, to allow
                 * for a gentler effect of sleepers:
@@ -766,9 +757,6 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
        se->vruntime = vruntime;
 }
 
-#define ENQUEUE_WAKEUP 1
-#define ENQUEUE_MIGRATE 2
-
 static void
 enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
 {
@@ -776,7 +764,7 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
         * Update the normalized vruntime before updating min_vruntime
         * through callig update_curr().
         */
-       if (!(flags & ENQUEUE_WAKEUP) || (flags & ENQUEUE_MIGRATE))
+       if (!(flags & ENQUEUE_WAKEUP) || (flags & ENQUEUE_WAKING))
                se->vruntime += cfs_rq->min_vruntime;
 
        /*
@@ -812,7 +800,7 @@ static void clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se)
 }
 
 static void
-dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep)
+dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
 {
        /*
         * Update run-time statistics of the 'current'.
@@ -820,15 +808,15 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep)
        update_curr(cfs_rq);
 
        update_stats_dequeue(cfs_rq, se);
-       if (sleep) {
+       if (flags & DEQUEUE_SLEEP) {
 #ifdef CONFIG_SCHEDSTATS
                if (entity_is_task(se)) {
                        struct task_struct *tsk = task_of(se);
 
                        if (tsk->state & TASK_INTERRUPTIBLE)
-                               se->sleep_start = rq_of(cfs_rq)->clock;
+                               se->statistics.sleep_start = rq_of(cfs_rq)->clock;
                        if (tsk->state & TASK_UNINTERRUPTIBLE)
-                               se->block_start = rq_of(cfs_rq)->clock;
+                               se->statistics.block_start = rq_of(cfs_rq)->clock;
                }
 #endif
        }
@@ -845,7 +833,7 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep)
         * update can refer to the ->curr item and we need to reflect this
         * movement in our normalized position.
         */
-       if (!sleep)
+       if (!(flags & DEQUEUE_SLEEP))
                se->vruntime -= cfs_rq->min_vruntime;
 }
 
@@ -912,7 +900,7 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
         * when there are only lesser-weight tasks around):
         */
        if (rq_of(cfs_rq)->load.weight >= 2*se->load.weight) {
-               se->slice_max = max(se->slice_max,
+               se->statistics.slice_max = max(se->statistics.slice_max,
                        se->sum_exec_runtime - se->prev_sum_exec_runtime);
        }
 #endif
@@ -1054,16 +1042,10 @@ static inline void hrtick_update(struct rq *rq)
  * then put the task into the rbtree:
  */
 static void
-enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup, bool head)
+enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
 {
        struct cfs_rq *cfs_rq;
        struct sched_entity *se = &p->se;
-       int flags = 0;
-
-       if (wakeup)
-               flags |= ENQUEUE_WAKEUP;
-       if (p->state == TASK_WAKING)
-               flags |= ENQUEUE_MIGRATE;
 
        for_each_sched_entity(se) {
                if (se->on_rq)
@@ -1081,18 +1063,18 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup, bool head)
  * decreased. We remove the task from the rbtree and
  * update the fair scheduling stats:
  */
-static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep)
+static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags)
 {
        struct cfs_rq *cfs_rq;
        struct sched_entity *se = &p->se;
 
        for_each_sched_entity(se) {
                cfs_rq = cfs_rq_of(se);
-               dequeue_entity(cfs_rq, se, sleep);
+               dequeue_entity(cfs_rq, se, flags);
                /* Don't dequeue parent if it has other entities besides us */
                if (cfs_rq->load.weight)
                        break;
-               sleep = 1;
+               flags |= DEQUEUE_SLEEP;
        }
 
        hrtick_update(rq);
@@ -1240,7 +1222,6 @@ static inline unsigned long effective_load(struct task_group *tg, int cpu,
 
 static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
 {
-       struct task_struct *curr = current;
        unsigned long this_load, load;
        int idx, this_cpu, prev_cpu;
        unsigned long tl_per_task;
@@ -1255,18 +1236,6 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
        load      = source_load(prev_cpu, idx);
        this_load = target_load(this_cpu, idx);
 
-       if (sync) {
-              if (sched_feat(SYNC_LESS) &&
-                  (curr->se.avg_overlap > sysctl_sched_migration_cost ||
-                   p->se.avg_overlap > sysctl_sched_migration_cost))
-                      sync = 0;
-       } else {
-               if (sched_feat(SYNC_MORE) &&
-                   (curr->se.avg_overlap < sysctl_sched_migration_cost &&
-                    p->se.avg_overlap < sysctl_sched_migration_cost))
-                       sync = 1;
-       }
-
        /*
         * If sync wakeup then subtract the (maximum possible)
         * effect of the currently running task from the load
@@ -1306,7 +1275,7 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
        if (sync && balanced)
                return 1;
 
-       schedstat_inc(p, se.nr_wakeups_affine_attempts);
+       schedstat_inc(p, se.statistics.nr_wakeups_affine_attempts);
        tl_per_task = cpu_avg_load_per_task(this_cpu);
 
        if (balanced ||
@@ -1318,7 +1287,7 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
                 * there is no bad imbalance.
                 */
                schedstat_inc(sd, ttwu_move_affine);
-               schedstat_inc(p, se.nr_wakeups_affine);
+               schedstat_inc(p, se.statistics.nr_wakeups_affine);
 
                return 1;
        }
@@ -1406,29 +1375,48 @@ 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)
+static int select_idle_sibling(struct task_struct *p, int target)
 {
        int cpu = smp_processor_id();
        int prev_cpu = task_cpu(p);
+       struct sched_domain *sd;
        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 the task is going to be woken-up on this cpu and if it is
+        * already idle, then it is the right target.
         */
-       if (target == cpu && !cpu_rq(prev_cpu)->cfs.nr_running)
+       if (target == cpu && idle_cpu(cpu))
+               return cpu;
+
+       /*
+        * If the task is going to be woken-up on the cpu where it previously
+        * ran and if it is currently idle, then it the right target.
+        */
+       if (target == prev_cpu && idle_cpu(prev_cpu))
                return prev_cpu;
 
        /*
-        * Otherwise, iterate the domain and find an elegible idle cpu.
+        * Otherwise, iterate the domains 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;
+       for_each_domain(target, sd) {
+               if (!(sd->flags & SD_SHARE_PKG_RESOURCES))
                        break;
+
+               for_each_cpu_and(i, sched_domain_span(sd), &p->cpus_allowed) {
+                       if (idle_cpu(i)) {
+                               target = i;
+                               break;
+                       }
                }
+
+               /*
+                * Lets stop looking for an idle sibling when we reached
+                * the domain that spans the current cpu and prev_cpu.
+                */
+               if (cpumask_test_cpu(cpu, sched_domain_span(sd)) &&
+                   cpumask_test_cpu(prev_cpu, sched_domain_span(sd)))
+                       break;
        }
 
        return target;
@@ -1445,7 +1433,8 @@ select_idle_sibling(struct task_struct *p, struct sched_domain *sd, int target)
  *
  * preempt must be disabled.
  */
-static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flags)
+static int
+select_task_rq_fair(struct rq *rq, struct task_struct *p, int sd_flag, int wake_flags)
 {
        struct sched_domain *tmp, *affine_sd = NULL, *sd = NULL;
        int cpu = smp_processor_id();
@@ -1456,8 +1445,7 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag
        int sync = wake_flags & WF_SYNC;
 
        if (sd_flag & SD_BALANCE_WAKE) {
-               if (sched_feat(AFFINE_WAKEUPS) &&
-                   cpumask_test_cpu(cpu, &p->cpus_allowed))
+               if (cpumask_test_cpu(cpu, &p->cpus_allowed))
                        want_affine = 1;
                new_cpu = prev_cpu;
        }
@@ -1491,34 +1479,13 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag
                }
 
                /*
-                * 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 both cpu and prev_cpu are part of this domain,
+                * cpu is a valid SD_WAKE_AFFINE target.
                 */
-               if (want_affine) {
-                       int target = -1;
-
-                       /*
-                        * 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_SHARE_PKG_RESOURCES)
-                               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_affine && (tmp->flags & SD_WAKE_AFFINE) &&
+                   cpumask_test_cpu(prev_cpu, sched_domain_span(tmp))) {
+                       affine_sd = tmp;
+                       want_affine = 0;
                }
 
                if (!want_sd && !want_affine)
@@ -1531,22 +1498,29 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag
                        sd = tmp;
        }
 
+#ifdef CONFIG_FAIR_GROUP_SCHED
        if (sched_feat(LB_SHARES_UPDATE)) {
                /*
                 * Pick the largest domain to update shares over
                 */
                tmp = sd;
-               if (affine_sd && (!tmp ||
-                                 cpumask_weight(sched_domain_span(affine_sd)) >
-                                 cpumask_weight(sched_domain_span(sd))))
+               if (affine_sd && (!tmp || affine_sd->span_weight > sd->span_weight))
                        tmp = affine_sd;
 
-               if (tmp)
+               if (tmp) {
+                       raw_spin_unlock(&rq->lock);
                        update_shares(tmp);
+                       raw_spin_lock(&rq->lock);
+               }
        }
+#endif
 
-       if (affine_sd && wake_affine(affine_sd, p, sync))
-               return cpu;
+       if (affine_sd) {
+               if (cpu == prev_cpu || wake_affine(affine_sd, p, sync))
+                       return select_idle_sibling(p, cpu);
+               else
+                       return select_idle_sibling(p, prev_cpu);
+       }
 
        while (sd) {
                int load_idx = sd->forkexec_idx;
@@ -1576,10 +1550,10 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag
 
                /* Now try balancing at a lower domain level of new_cpu */
                cpu = new_cpu;
-               weight = cpumask_weight(sched_domain_span(sd));
+               weight = sd->span_weight;
                sd = NULL;
                for_each_domain(cpu, tmp) {
-                       if (weight <= cpumask_weight(sched_domain_span(tmp)))
+                       if (weight <= tmp->span_weight)
                                break;
                        if (tmp->flags & sd_flag)
                                sd = tmp;
@@ -1591,63 +1565,26 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag
 }
 #endif /* CONFIG_SMP */
 
-/*
- * Adaptive granularity
- *
- * se->avg_wakeup gives the average time a task runs until it does a wakeup,
- * with the limit of wakeup_gran -- when it never does a wakeup.
- *
- * So the smaller avg_wakeup is the faster we want this task to preempt,
- * but we don't want to treat the preemptee unfairly and therefore allow it
- * to run for at least the amount of time we'd like to run.
- *
- * NOTE: we use 2*avg_wakeup to increase the probability of actually doing one
- *
- * NOTE: we use *nr_running to scale with load, this nicely matches the
- *       degrading latency on load.
- */
-static unsigned long
-adaptive_gran(struct sched_entity *curr, struct sched_entity *se)
-{
-       u64 this_run = curr->sum_exec_runtime - curr->prev_sum_exec_runtime;
-       u64 expected_wakeup = 2*se->avg_wakeup * cfs_rq_of(se)->nr_running;
-       u64 gran = 0;
-
-       if (this_run < expected_wakeup)
-               gran = expected_wakeup - this_run;
-
-       return min_t(s64, gran, sysctl_sched_wakeup_granularity);
-}
-
 static unsigned long
 wakeup_gran(struct sched_entity *curr, struct sched_entity *se)
 {
        unsigned long gran = sysctl_sched_wakeup_granularity;
 
-       if (cfs_rq_of(curr)->curr && sched_feat(ADAPTIVE_GRAN))
-               gran = adaptive_gran(curr, se);
-
        /*
         * Since its curr running now, convert the gran from real-time
         * to virtual-time in his units.
+        *
+        * By using 'se' instead of 'curr' we penalize light tasks, so
+        * they get preempted easier. That is, if 'se' < 'curr' then
+        * the resulting gran will be larger, therefore penalizing the
+        * lighter, if otoh 'se' > 'curr' then the resulting gran will
+        * be smaller, again penalizing the lighter task.
+        *
+        * This is especially important for buddies when the leftmost
+        * task is higher priority than the buddy.
         */
-       if (sched_feat(ASYM_GRAN)) {
-               /*
-                * By using 'se' instead of 'curr' we penalize light tasks, so
-                * they get preempted easier. That is, if 'se' < 'curr' then
-                * the resulting gran will be larger, therefore penalizing the
-                * lighter, if otoh 'se' > 'curr' then the resulting gran will
-                * be smaller, again penalizing the lighter task.
-                *
-                * This is especially important for buddies when the leftmost
-                * task is higher priority than the buddy.
-                */
-               if (unlikely(se->load.weight != NICE_0_LOAD))
-                       gran = calc_delta_fair(gran, se);
-       } else {
-               if (unlikely(curr->load.weight != NICE_0_LOAD))
-                       gran = calc_delta_fair(gran, curr);
-       }
+       if (unlikely(se->load.weight != NICE_0_LOAD))
+               gran = calc_delta_fair(gran, se);
 
        return gran;
 }
@@ -1705,7 +1642,6 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
        struct task_struct *curr = rq->curr;
        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;
 
        if (unlikely(rt_prio(p->prio)))
@@ -1738,14 +1674,6 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
        if (unlikely(curr->policy == SCHED_IDLE))
                goto preempt;
 
-       if (sched_feat(WAKEUP_SYNC) && sync)
-               goto preempt;
-
-       if (sched_feat(WAKEUP_OVERLAP) &&
-                       se->avg_overlap < sysctl_sched_migration_cost &&
-                       pse->avg_overlap < sysctl_sched_migration_cost)
-               goto preempt;
-
        if (!sched_feat(WAKEUP_PREEMPT))
                return;
 
@@ -1844,13 +1772,13 @@ int can_migrate_task(struct task_struct *p, struct rq *rq, int this_cpu,
         * 3) are cache-hot on their current CPU.
         */
        if (!cpumask_test_cpu(this_cpu, &p->cpus_allowed)) {
-               schedstat_inc(p, se.nr_failed_migrations_affine);
+               schedstat_inc(p, se.statistics.nr_failed_migrations_affine);
                return 0;
        }
        *all_pinned = 0;
 
        if (task_running(rq, p)) {
-               schedstat_inc(p, se.nr_failed_migrations_running);
+               schedstat_inc(p, se.statistics.nr_failed_migrations_running);
                return 0;
        }
 
@@ -1866,14 +1794,14 @@ int can_migrate_task(struct task_struct *p, struct rq *rq, int this_cpu,
 #ifdef CONFIG_SCHEDSTATS
                if (tsk_cache_hot) {
                        schedstat_inc(sd, lb_hot_gained[idle]);
-                       schedstat_inc(p, se.nr_forced_migrations);
+                       schedstat_inc(p, se.statistics.nr_forced_migrations);
                }
 #endif
                return 1;
        }
 
        if (tsk_cache_hot) {
-               schedstat_inc(p, se.nr_failed_migrations_hot);
+               schedstat_inc(p, se.statistics.nr_failed_migrations_hot);
                return 0;
        }
        return 1;
@@ -2311,7 +2239,7 @@ unsigned long __weak arch_scale_freq_power(struct sched_domain *sd, int cpu)
 
 unsigned long default_scale_smt_power(struct sched_domain *sd, int cpu)
 {
-       unsigned long weight = cpumask_weight(sched_domain_span(sd));
+       unsigned long weight = sd->span_weight;
        unsigned long smt_gain = sd->smt_gain;
 
        smt_gain /= weight;
@@ -2344,7 +2272,7 @@ unsigned long scale_rt_power(int cpu)
 
 static void update_cpu_power(struct sched_domain *sd, int cpu)
 {
-       unsigned long weight = cpumask_weight(sched_domain_span(sd));
+       unsigned long weight = sd->span_weight;
        unsigned long power = SCHED_LOAD_SCALE;
        struct sched_group *sdg = sd->groups;
 
@@ -2870,6 +2798,8 @@ static int need_active_balance(struct sched_domain *sd, int sd_idle, int idle)
        return unlikely(sd->nr_balance_failed > sd->cache_nice_tries+2);
 }
 
+static int active_load_balance_cpu_stop(void *data);
+
 /*
  * Check this_cpu to ensure it is balanced within domain. Attempt to move
  * tasks if there is an imbalance.
@@ -2959,8 +2889,9 @@ redo:
                if (need_active_balance(sd, sd_idle, idle)) {
                        raw_spin_lock_irqsave(&busiest->lock, flags);
 
-                       /* don't kick the migration_thread, if the curr
-                        * task on busiest cpu can't be moved to this_cpu
+                       /* don't kick the active_load_balance_cpu_stop,
+                        * if the curr task on busiest cpu can't be
+                        * moved to this_cpu
                         */
                        if (!cpumask_test_cpu(this_cpu,
                                              &busiest->curr->cpus_allowed)) {
@@ -2970,14 +2901,22 @@ redo:
                                goto out_one_pinned;
                        }
 
+                       /*
+                        * ->active_balance synchronizes accesses to
+                        * ->active_balance_work.  Once set, it's cleared
+                        * only after active load balance is finished.
+                        */
                        if (!busiest->active_balance) {
                                busiest->active_balance = 1;
                                busiest->push_cpu = this_cpu;
                                active_balance = 1;
                        }
                        raw_spin_unlock_irqrestore(&busiest->lock, flags);
+
                        if (active_balance)
-                               wake_up_process(busiest->migration_thread);
+                               stop_one_cpu_nowait(cpu_of(busiest),
+                                       active_load_balance_cpu_stop, busiest,
+                                       &busiest->active_balance_work);
 
                        /*
                         * We've kicked active balancing, reset the failure
@@ -3084,24 +3023,29 @@ static void idle_balance(int this_cpu, struct rq *this_rq)
 }
 
 /*
- * active_load_balance is run by migration threads. It pushes running tasks
- * off the busiest CPU onto idle CPUs. It requires at least 1 task to be
- * running on each physical CPU where possible, and avoids physical /
- * logical imbalances.
- *
- * Called with busiest_rq locked.
+ * active_load_balance_cpu_stop is run by cpu stopper. It pushes
+ * running tasks off the busiest CPU onto idle CPUs. It requires at
+ * least 1 task to be running on each physical CPU where possible, and
+ * avoids physical / logical imbalances.
  */
-static void active_load_balance(struct rq *busiest_rq, int busiest_cpu)
+static int active_load_balance_cpu_stop(void *data)
 {
+       struct rq *busiest_rq = data;
+       int busiest_cpu = cpu_of(busiest_rq);
        int target_cpu = busiest_rq->push_cpu;
+       struct rq *target_rq = cpu_rq(target_cpu);
        struct sched_domain *sd;
-       struct rq *target_rq;
+
+       raw_spin_lock_irq(&busiest_rq->lock);
+
+       /* make sure the requested cpu hasn't gone down in the meantime */
+       if (unlikely(busiest_cpu != smp_processor_id() ||
+                    !busiest_rq->active_balance))
+               goto out_unlock;
 
        /* Is there any task to move? */
        if (busiest_rq->nr_running <= 1)
-               return;
-
-       target_rq = cpu_rq(target_cpu);
+               goto out_unlock;
 
        /*
         * This condition is "impossible", if it occurs
@@ -3112,8 +3056,6 @@ static void active_load_balance(struct rq *busiest_rq, int busiest_cpu)
 
        /* move a task from busiest_rq to target_rq */
        double_lock_balance(busiest_rq, target_rq);
-       update_rq_clock(busiest_rq);
-       update_rq_clock(target_rq);
 
        /* Search for an sd spanning us and the target CPU. */
        for_each_domain(target_cpu, sd) {
@@ -3132,6 +3074,10 @@ static void active_load_balance(struct rq *busiest_rq, int busiest_cpu)
                        schedstat_inc(sd, alb_failed);
        }
        double_unlock_balance(busiest_rq, target_rq);
+out_unlock:
+       busiest_rq->active_balance = 0;
+       raw_spin_unlock_irq(&busiest_rq->lock);
+       return 0;
 }
 
 #ifdef CONFIG_NO_HZ
index d5059fd761d9bf49aca78e830a4fe9330bd464c9..83c66e8ad3ee314704456e14dfc23607d00c5f0d 100644 (file)
@@ -1,10 +1,3 @@
-/*
- * Disregards a certain amount of sleep time (sched_latency_ns) and
- * considers the task to be running during that period. This gives it
- * a service deficit on wakeup, allowing it to run sooner.
- */
-SCHED_FEAT(FAIR_SLEEPERS, 1)
-
 /*
  * Only give sleepers 50% of their service deficit. This allows
  * them to run sooner, but does not allow tons of sleepers to
@@ -12,13 +5,6 @@ SCHED_FEAT(FAIR_SLEEPERS, 1)
  */
 SCHED_FEAT(GENTLE_FAIR_SLEEPERS, 1)
 
-/*
- * By not normalizing the sleep time, heavy tasks get an effective
- * longer period, and lighter task an effective shorter period they
- * are considered running.
- */
-SCHED_FEAT(NORMALIZED_SLEEPER, 0)
-
 /*
  * Place new tasks ahead so that they do not starve already running
  * tasks
@@ -30,37 +16,6 @@ SCHED_FEAT(START_DEBIT, 1)
  */
 SCHED_FEAT(WAKEUP_PREEMPT, 1)
 
-/*
- * Compute wakeup_gran based on task behaviour, clipped to
- *  [0, sched_wakeup_gran_ns]
- */
-SCHED_FEAT(ADAPTIVE_GRAN, 1)
-
-/*
- * When converting the wakeup granularity to virtual time, do it such
- * that heavier tasks preempting a lighter task have an edge.
- */
-SCHED_FEAT(ASYM_GRAN, 1)
-
-/*
- * Always wakeup-preempt SYNC wakeups, see SYNC_WAKEUPS.
- */
-SCHED_FEAT(WAKEUP_SYNC, 0)
-
-/*
- * Wakeup preempt based on task behaviour. Tasks that do not overlap
- * don't get preempted.
- */
-SCHED_FEAT(WAKEUP_OVERLAP, 0)
-
-/*
- * Use the SYNC wakeup hint, pipes and the likes use this to indicate
- * the remote end is likely to consume the data we just wrote, and
- * therefore has cache benefit from being placed on the same cpu, see
- * also AFFINE_WAKEUPS.
- */
-SCHED_FEAT(SYNC_WAKEUPS, 1)
-
 /*
  * Based on load and program behaviour, see if it makes sense to place
  * a newly woken task on the same cpu as the task that woke it --
@@ -69,16 +24,6 @@ SCHED_FEAT(SYNC_WAKEUPS, 1)
  */
 SCHED_FEAT(AFFINE_WAKEUPS, 1)
 
-/*
- * Weaken SYNC hint based on overlap
- */
-SCHED_FEAT(SYNC_LESS, 1)
-
-/*
- * Add SYNC hint based on overlap
- */
-SCHED_FEAT(SYNC_MORE, 0)
-
 /*
  * Prefer to schedule the task we woke last (assuming it failed
  * wakeup-preemption), since its likely going to consume data we
index a8a6d8a50947f11e9bb1f8a9e782effffe4468f7..9fa0f402c87c2aa2bf8be7f404c6cfc27b64a865 100644 (file)
@@ -6,7 +6,8 @@
  */
 
 #ifdef CONFIG_SMP
-static int select_task_rq_idle(struct task_struct *p, int sd_flag, int flags)
+static int
+select_task_rq_idle(struct rq *rq, struct task_struct *p, int sd_flag, int flags)
 {
        return task_cpu(p); /* IDLE tasks as never migrated */
 }
@@ -22,8 +23,7 @@ static void check_preempt_curr_idle(struct rq *rq, struct task_struct *p, int fl
 static struct task_struct *pick_next_task_idle(struct rq *rq)
 {
        schedstat_inc(rq, sched_goidle);
-       /* adjust the active tasks as we might go into a long sleep */
-       calc_load_account_active(rq);
+       calc_load_account_idle(rq);
        return rq->idle;
 }
 
@@ -32,7 +32,7 @@ static struct task_struct *pick_next_task_idle(struct rq *rq)
  * message if some code attempts to do it:
  */
 static void
-dequeue_task_idle(struct rq *rq, struct task_struct *p, int sleep)
+dequeue_task_idle(struct rq *rq, struct task_struct *p, int flags)
 {
        raw_spin_unlock_irq(&rq->lock);
        printk(KERN_ERR "bad: scheduling from the idle thread!\n");
index b5b920ae2ea7fe83ca17d2c94d0a7b638574144c..8afb953e31c6c1ba9a263a78929a04a0d82ff2c7 100644 (file)
@@ -613,7 +613,7 @@ static void update_curr_rt(struct rq *rq)
        if (unlikely((s64)delta_exec < 0))
                delta_exec = 0;
 
-       schedstat_set(curr->se.exec_max, max(curr->se.exec_max, delta_exec));
+       schedstat_set(curr->se.statistics.exec_max, max(curr->se.statistics.exec_max, delta_exec));
 
        curr->se.sum_exec_runtime += delta_exec;
        account_group_exec_runtime(curr, delta_exec);
@@ -888,20 +888,20 @@ static void dequeue_rt_entity(struct sched_rt_entity *rt_se)
  * Adding/removing a task to/from a priority array:
  */
 static void
-enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup, bool head)
+enqueue_task_rt(struct rq *rq, struct task_struct *p, int flags)
 {
        struct sched_rt_entity *rt_se = &p->rt;
 
-       if (wakeup)
+       if (flags & ENQUEUE_WAKEUP)
                rt_se->timeout = 0;
 
-       enqueue_rt_entity(rt_se, head);
+       enqueue_rt_entity(rt_se, flags & ENQUEUE_HEAD);
 
        if (!task_current(rq, p) && p->rt.nr_cpus_allowed > 1)
                enqueue_pushable_task(rq, p);
 }
 
-static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep)
+static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int flags)
 {
        struct sched_rt_entity *rt_se = &p->rt;
 
@@ -948,10 +948,9 @@ static void yield_task_rt(struct rq *rq)
 #ifdef CONFIG_SMP
 static int find_lowest_rq(struct task_struct *task);
 
-static int select_task_rq_rt(struct task_struct *p, int sd_flag, int flags)
+static int
+select_task_rq_rt(struct rq *rq, struct task_struct *p, int sd_flag, int flags)
 {
-       struct rq *rq = task_rq(p);
-
        if (sd_flag != SD_BALANCE_WAKE)
                return smp_processor_id();
 
index 7494bbf5a27035fcd80cb7b9bf4814452e37e9a8..7d3f4fa9ef4f3b15eeee03b4ed3f3684819c8cf8 100644 (file)
@@ -637,7 +637,7 @@ int delayed_slow_work_enqueue(struct delayed_slow_work *dwork,
                        goto cancelled;
 
                /* the timer holds a reference whilst it is pending */
-               ret = work->ops->get_ref(work);
+               ret = slow_work_get_ref(work);
                if (ret < 0)
                        goto cant_get_ref;
 
index 321f3c59d7324f4100629b55111bb02b05c70161..a29ebd1ef41df7a4295e3173848e5239c05caa60 100644 (file)
@@ -43,28 +43,28 @@ extern void slow_work_new_thread_desc(struct slow_work *, struct seq_file *);
  */
 static inline void slow_work_set_thread_pid(int id, pid_t pid)
 {
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
        slow_work_pids[id] = pid;
 #endif
 }
 
 static inline void slow_work_mark_time(struct slow_work *work)
 {
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
        work->mark = CURRENT_TIME;
 #endif
 }
 
 static inline void slow_work_begin_exec(int id, struct slow_work *work)
 {
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
        slow_work_execs[id] = work;
 #endif
 }
 
 static inline void slow_work_end_exec(int id, struct slow_work *work)
 {
-#ifdef CONFIG_SLOW_WORK_PROC
+#ifdef CONFIG_SLOW_WORK_DEBUG
        write_lock(&slow_work_execs_lock);
        slow_work_execs[id] = NULL;
        write_unlock(&slow_work_execs_lock);
index 9867b6bfefce7f1d20d342149984ca40e0dbd3ab..3fc697336183a79bffd175efdd98a7663ecf3691 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/module.h>
 #include <linux/percpu.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/smp.h>
 #include <linux/cpu.h>
 
index 7c1a67ef027431e8f82d341ed7e729b9c0eec044..0db913a5c60f4751067e668a80cb8d5c054957f0 100644 (file)
@@ -716,7 +716,7 @@ static int run_ksoftirqd(void * __bind_cpu)
                        preempt_enable_no_resched();
                        cond_resched();
                        preempt_disable();
-                       rcu_sched_qs((long)__bind_cpu);
+                       rcu_note_context_switch((long)__bind_cpu);
                }
                preempt_enable();
                set_current_state(TASK_INTERRUPTIBLE);
index 0d4c7898ab805dd868880e7deca2d0d69d88fc67..4b493f67dcb562c183258115619539f3a68cd62a 100644 (file)
@@ -155,11 +155,11 @@ void softlockup_tick(void)
         * Wake up the high-prio watchdog task twice per
         * threshold timespan.
         */
-       if (now > touch_ts + softlockup_thresh/2)
+       if (time_after(now - softlockup_thresh/2, touch_ts))
                wake_up_process(per_cpu(softlockup_watchdog, this_cpu));
 
        /* Warn about unreasonable delays: */
-       if (now <= (touch_ts + softlockup_thresh))
+       if (time_before_eq(now - softlockup_thresh, touch_ts))
                return;
 
        per_cpu(softlockup_print_ts, this_cpu) = touch_ts;
index bde4295774c8f921f235fd4d2efebbd726132b38..2980da3fd50925f7902a5ba42e64934f6c4b0650 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/preempt.h>
 #include <linux/rcupdate.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/srcu.h>
 
index 9bb9fb1bd79c8b07da0dba482244d90e61aa7b76..b4e7431e7c78996607ef0495d7cb50bc34621d2c 100644 (file)
-/* Copyright 2008, 2005 Rusty Russell rusty@rustcorp.com.au IBM Corporation.
- * GPL v2 and any later version.
+/*
+ * kernel/stop_machine.c
+ *
+ * Copyright (C) 2008, 2005    IBM Corporation.
+ * Copyright (C) 2008, 2005    Rusty Russell rusty@rustcorp.com.au
+ * Copyright (C) 2010          SUSE Linux Products GmbH
+ * Copyright (C) 2010          Tejun Heo <tj@kernel.org>
+ *
+ * This file is released under the GPLv2 and any later version.
  */
+#include <linux/completion.h>
 #include <linux/cpu.h>
-#include <linux/err.h>
+#include <linux/init.h>
 #include <linux/kthread.h>
 #include <linux/module.h>
+#include <linux/percpu.h>
 #include <linux/sched.h>
 #include <linux/stop_machine.h>
-#include <linux/syscalls.h>
 #include <linux/interrupt.h>
+#include <linux/kallsyms.h>
 
 #include <asm/atomic.h>
-#include <asm/uaccess.h>
+
+/*
+ * Structure to determine completion condition and record errors.  May
+ * be shared by works on different cpus.
+ */
+struct cpu_stop_done {
+       atomic_t                nr_todo;        /* nr left to execute */
+       bool                    executed;       /* actually executed? */
+       int                     ret;            /* collected return value */
+       struct completion       completion;     /* fired if nr_todo reaches 0 */
+};
+
+/* the actual stopper, one per every possible cpu, enabled on online cpus */
+struct cpu_stopper {
+       spinlock_t              lock;
+       struct list_head        works;          /* list of pending works */
+       struct task_struct      *thread;        /* stopper thread */
+       bool                    enabled;        /* is this stopper enabled? */
+};
+
+static DEFINE_PER_CPU(struct cpu_stopper, cpu_stopper);
+
+static void cpu_stop_init_done(struct cpu_stop_done *done, unsigned int nr_todo)
+{
+       memset(done, 0, sizeof(*done));
+       atomic_set(&done->nr_todo, nr_todo);
+       init_completion(&done->completion);
+}
+
+/* signal completion unless @done is NULL */
+static void cpu_stop_signal_done(struct cpu_stop_done *done, bool executed)
+{
+       if (done) {
+               if (executed)
+                       done->executed = true;
+               if (atomic_dec_and_test(&done->nr_todo))
+                       complete(&done->completion);
+       }
+}
+
+/* queue @work to @stopper.  if offline, @work is completed immediately */
+static void cpu_stop_queue_work(struct cpu_stopper *stopper,
+                               struct cpu_stop_work *work)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&stopper->lock, flags);
+
+       if (stopper->enabled) {
+               list_add_tail(&work->list, &stopper->works);
+               wake_up_process(stopper->thread);
+       } else
+               cpu_stop_signal_done(work->done, false);
+
+       spin_unlock_irqrestore(&stopper->lock, flags);
+}
+
+/**
+ * stop_one_cpu - stop a cpu
+ * @cpu: cpu to stop
+ * @fn: function to execute
+ * @arg: argument to @fn
+ *
+ * Execute @fn(@arg) on @cpu.  @fn is run in a process context with
+ * the highest priority preempting any task on the cpu and
+ * monopolizing it.  This function returns after the execution is
+ * complete.
+ *
+ * This function doesn't guarantee @cpu stays online till @fn
+ * completes.  If @cpu goes down in the middle, execution may happen
+ * partially or fully on different cpus.  @fn should either be ready
+ * for that or the caller should ensure that @cpu stays online until
+ * this function completes.
+ *
+ * CONTEXT:
+ * Might sleep.
+ *
+ * RETURNS:
+ * -ENOENT if @fn(@arg) was not executed because @cpu was offline;
+ * otherwise, the return value of @fn.
+ */
+int stop_one_cpu(unsigned int cpu, cpu_stop_fn_t fn, void *arg)
+{
+       struct cpu_stop_done done;
+       struct cpu_stop_work work = { .fn = fn, .arg = arg, .done = &done };
+
+       cpu_stop_init_done(&done, 1);
+       cpu_stop_queue_work(&per_cpu(cpu_stopper, cpu), &work);
+       wait_for_completion(&done.completion);
+       return done.executed ? done.ret : -ENOENT;
+}
+
+/**
+ * stop_one_cpu_nowait - stop a cpu but don't wait for completion
+ * @cpu: cpu to stop
+ * @fn: function to execute
+ * @arg: argument to @fn
+ *
+ * Similar to stop_one_cpu() but doesn't wait for completion.  The
+ * caller is responsible for ensuring @work_buf is currently unused
+ * and will remain untouched until stopper starts executing @fn.
+ *
+ * CONTEXT:
+ * Don't care.
+ */
+void stop_one_cpu_nowait(unsigned int cpu, cpu_stop_fn_t fn, void *arg,
+                       struct cpu_stop_work *work_buf)
+{
+       *work_buf = (struct cpu_stop_work){ .fn = fn, .arg = arg, };
+       cpu_stop_queue_work(&per_cpu(cpu_stopper, cpu), work_buf);
+}
+
+/* static data for stop_cpus */
+static DEFINE_MUTEX(stop_cpus_mutex);
+static DEFINE_PER_CPU(struct cpu_stop_work, stop_cpus_work);
+
+int __stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg)
+{
+       struct cpu_stop_work *work;
+       struct cpu_stop_done done;
+       unsigned int cpu;
+
+       /* initialize works and done */
+       for_each_cpu(cpu, cpumask) {
+               work = &per_cpu(stop_cpus_work, cpu);
+               work->fn = fn;
+               work->arg = arg;
+               work->done = &done;
+       }
+       cpu_stop_init_done(&done, cpumask_weight(cpumask));
+
+       /*
+        * Disable preemption while queueing to avoid getting
+        * preempted by a stopper which might wait for other stoppers
+        * to enter @fn which can lead to deadlock.
+        */
+       preempt_disable();
+       for_each_cpu(cpu, cpumask)
+               cpu_stop_queue_work(&per_cpu(cpu_stopper, cpu),
+                                   &per_cpu(stop_cpus_work, cpu));
+       preempt_enable();
+
+       wait_for_completion(&done.completion);
+       return done.executed ? done.ret : -ENOENT;
+}
+
+/**
+ * stop_cpus - stop multiple cpus
+ * @cpumask: cpus to stop
+ * @fn: function to execute
+ * @arg: argument to @fn
+ *
+ * Execute @fn(@arg) on online cpus in @cpumask.  On each target cpu,
+ * @fn is run in a process context with the highest priority
+ * preempting any task on the cpu and monopolizing it.  This function
+ * returns after all executions are complete.
+ *
+ * This function doesn't guarantee the cpus in @cpumask stay online
+ * till @fn completes.  If some cpus go down in the middle, execution
+ * on the cpu may happen partially or fully on different cpus.  @fn
+ * should either be ready for that or the caller should ensure that
+ * the cpus stay online until this function completes.
+ *
+ * All stop_cpus() calls are serialized making it safe for @fn to wait
+ * for all cpus to start executing it.
+ *
+ * CONTEXT:
+ * Might sleep.
+ *
+ * RETURNS:
+ * -ENOENT if @fn(@arg) was not executed at all because all cpus in
+ * @cpumask were offline; otherwise, 0 if all executions of @fn
+ * returned 0, any non zero return value if any returned non zero.
+ */
+int stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg)
+{
+       int ret;
+
+       /* static works are used, process one request at a time */
+       mutex_lock(&stop_cpus_mutex);
+       ret = __stop_cpus(cpumask, fn, arg);
+       mutex_unlock(&stop_cpus_mutex);
+       return ret;
+}
+
+/**
+ * try_stop_cpus - try to stop multiple cpus
+ * @cpumask: cpus to stop
+ * @fn: function to execute
+ * @arg: argument to @fn
+ *
+ * Identical to stop_cpus() except that it fails with -EAGAIN if
+ * someone else is already using the facility.
+ *
+ * CONTEXT:
+ * Might sleep.
+ *
+ * RETURNS:
+ * -EAGAIN if someone else is already stopping cpus, -ENOENT if
+ * @fn(@arg) was not executed at all because all cpus in @cpumask were
+ * offline; otherwise, 0 if all executions of @fn returned 0, any non
+ * zero return value if any returned non zero.
+ */
+int try_stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg)
+{
+       int ret;
+
+       /* static works are used, process one request at a time */
+       if (!mutex_trylock(&stop_cpus_mutex))
+               return -EAGAIN;
+       ret = __stop_cpus(cpumask, fn, arg);
+       mutex_unlock(&stop_cpus_mutex);
+       return ret;
+}
+
+static int cpu_stopper_thread(void *data)
+{
+       struct cpu_stopper *stopper = data;
+       struct cpu_stop_work *work;
+       int ret;
+
+repeat:
+       set_current_state(TASK_INTERRUPTIBLE);  /* mb paired w/ kthread_stop */
+
+       if (kthread_should_stop()) {
+               __set_current_state(TASK_RUNNING);
+               return 0;
+       }
+
+       work = NULL;
+       spin_lock_irq(&stopper->lock);
+       if (!list_empty(&stopper->works)) {
+               work = list_first_entry(&stopper->works,
+                                       struct cpu_stop_work, list);
+               list_del_init(&work->list);
+       }
+       spin_unlock_irq(&stopper->lock);
+
+       if (work) {
+               cpu_stop_fn_t fn = work->fn;
+               void *arg = work->arg;
+               struct cpu_stop_done *done = work->done;
+               char ksym_buf[KSYM_NAME_LEN];
+
+               __set_current_state(TASK_RUNNING);
+
+               /* cpu stop callbacks are not allowed to sleep */
+               preempt_disable();
+
+               ret = fn(arg);
+               if (ret)
+                       done->ret = ret;
+
+               /* restore preemption and check it's still balanced */
+               preempt_enable();
+               WARN_ONCE(preempt_count(),
+                         "cpu_stop: %s(%p) leaked preempt count\n",
+                         kallsyms_lookup((unsigned long)fn, NULL, NULL, NULL,
+                                         ksym_buf), arg);
+
+               cpu_stop_signal_done(done, true);
+       } else
+               schedule();
+
+       goto repeat;
+}
+
+/* manage stopper for a cpu, mostly lifted from sched migration thread mgmt */
+static int __cpuinit cpu_stop_cpu_callback(struct notifier_block *nfb,
+                                          unsigned long action, void *hcpu)
+{
+       struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
+       unsigned int cpu = (unsigned long)hcpu;
+       struct cpu_stopper *stopper = &per_cpu(cpu_stopper, cpu);
+       struct task_struct *p;
+
+       switch (action & ~CPU_TASKS_FROZEN) {
+       case CPU_UP_PREPARE:
+               BUG_ON(stopper->thread || stopper->enabled ||
+                      !list_empty(&stopper->works));
+               p = kthread_create(cpu_stopper_thread, stopper, "migration/%d",
+                                  cpu);
+               if (IS_ERR(p))
+                       return NOTIFY_BAD;
+               sched_setscheduler_nocheck(p, SCHED_FIFO, &param);
+               get_task_struct(p);
+               stopper->thread = p;
+               break;
+
+       case CPU_ONLINE:
+               kthread_bind(stopper->thread, cpu);
+               /* strictly unnecessary, as first user will wake it */
+               wake_up_process(stopper->thread);
+               /* mark enabled */
+               spin_lock_irq(&stopper->lock);
+               stopper->enabled = true;
+               spin_unlock_irq(&stopper->lock);
+               break;
+
+#ifdef CONFIG_HOTPLUG_CPU
+       case CPU_UP_CANCELED:
+       case CPU_DEAD:
+       {
+               struct cpu_stop_work *work;
+
+               /* kill the stopper */
+               kthread_stop(stopper->thread);
+               /* drain remaining works */
+               spin_lock_irq(&stopper->lock);
+               list_for_each_entry(work, &stopper->works, list)
+                       cpu_stop_signal_done(work->done, false);
+               stopper->enabled = false;
+               spin_unlock_irq(&stopper->lock);
+               /* release the stopper */
+               put_task_struct(stopper->thread);
+               stopper->thread = NULL;
+               break;
+       }
+#endif
+       }
+
+       return NOTIFY_OK;
+}
+
+/*
+ * Give it a higher priority so that cpu stopper is available to other
+ * cpu notifiers.  It currently shares the same priority as sched
+ * migration_notifier.
+ */
+static struct notifier_block __cpuinitdata cpu_stop_cpu_notifier = {
+       .notifier_call  = cpu_stop_cpu_callback,
+       .priority       = 10,
+};
+
+static int __init cpu_stop_init(void)
+{
+       void *bcpu = (void *)(long)smp_processor_id();
+       unsigned int cpu;
+       int err;
+
+       for_each_possible_cpu(cpu) {
+               struct cpu_stopper *stopper = &per_cpu(cpu_stopper, cpu);
+
+               spin_lock_init(&stopper->lock);
+               INIT_LIST_HEAD(&stopper->works);
+       }
+
+       /* start one for the boot cpu */
+       err = cpu_stop_cpu_callback(&cpu_stop_cpu_notifier, CPU_UP_PREPARE,
+                                   bcpu);
+       BUG_ON(err == NOTIFY_BAD);
+       cpu_stop_cpu_callback(&cpu_stop_cpu_notifier, CPU_ONLINE, bcpu);
+       register_cpu_notifier(&cpu_stop_cpu_notifier);
+
+       return 0;
+}
+early_initcall(cpu_stop_init);
+
+#ifdef CONFIG_STOP_MACHINE
 
 /* This controls the threads on each CPU. */
 enum stopmachine_state {
@@ -26,174 +393,94 @@ enum stopmachine_state {
        /* Exit */
        STOPMACHINE_EXIT,
 };
-static enum stopmachine_state state;
 
 struct stop_machine_data {
-       int (*fn)(void *);
-       void *data;
-       int fnret;
+       int                     (*fn)(void *);
+       void                    *data;
+       /* Like num_online_cpus(), but hotplug cpu uses us, so we need this. */
+       unsigned int            num_threads;
+       const struct cpumask    *active_cpus;
+
+       enum stopmachine_state  state;
+       atomic_t                thread_ack;
 };
 
-/* Like num_online_cpus(), but hotplug cpu uses us, so we need this. */
-static unsigned int num_threads;
-static atomic_t thread_ack;
-static DEFINE_MUTEX(lock);
-/* setup_lock protects refcount, stop_machine_wq and stop_machine_work. */
-static DEFINE_MUTEX(setup_lock);
-/* Users of stop_machine. */
-static int refcount;
-static struct workqueue_struct *stop_machine_wq;
-static struct stop_machine_data active, idle;
-static const struct cpumask *active_cpus;
-static void __percpu *stop_machine_work;
-
-static void set_state(enum stopmachine_state newstate)
+static void set_state(struct stop_machine_data *smdata,
+                     enum stopmachine_state newstate)
 {
        /* Reset ack counter. */
-       atomic_set(&thread_ack, num_threads);
+       atomic_set(&smdata->thread_ack, smdata->num_threads);
        smp_wmb();
-       state = newstate;
+       smdata->state = newstate;
 }
 
 /* Last one to ack a state moves to the next state. */
-static void ack_state(void)
+static void ack_state(struct stop_machine_data *smdata)
 {
-       if (atomic_dec_and_test(&thread_ack))
-               set_state(state + 1);
+       if (atomic_dec_and_test(&smdata->thread_ack))
+               set_state(smdata, smdata->state + 1);
 }
 
-/* This is the actual function which stops the CPU. It runs
- * in the context of a dedicated stopmachine workqueue. */
-static void stop_cpu(struct work_struct *unused)
+/* This is the cpu_stop function which stops the CPU. */
+static int stop_machine_cpu_stop(void *data)
 {
+       struct stop_machine_data *smdata = data;
        enum stopmachine_state curstate = STOPMACHINE_NONE;
-       struct stop_machine_data *smdata = &idle;
-       int cpu = smp_processor_id();
-       int err;
+       int cpu = smp_processor_id(), err = 0;
+       bool is_active;
+
+       if (!smdata->active_cpus)
+               is_active = cpu == cpumask_first(cpu_online_mask);
+       else
+               is_active = cpumask_test_cpu(cpu, smdata->active_cpus);
 
-       if (!active_cpus) {
-               if (cpu == cpumask_first(cpu_online_mask))
-                       smdata = &active;
-       } else {
-               if (cpumask_test_cpu(cpu, active_cpus))
-                       smdata = &active;
-       }
        /* Simple state machine */
        do {
                /* Chill out and ensure we re-read stopmachine_state. */
                cpu_relax();
-               if (state != curstate) {
-                       curstate = state;
+               if (smdata->state != curstate) {
+                       curstate = smdata->state;
                        switch (curstate) {
                        case STOPMACHINE_DISABLE_IRQ:
                                local_irq_disable();
                                hard_irq_disable();
                                break;
                        case STOPMACHINE_RUN:
-                               /* On multiple CPUs only a single error code
-                                * is needed to tell that something failed. */
-                               err = smdata->fn(smdata->data);
-                               if (err)
-                                       smdata->fnret = err;
+                               if (is_active)
+                                       err = smdata->fn(smdata->data);
                                break;
                        default:
                                break;
                        }
-                       ack_state();
+                       ack_state(smdata);
                }
        } while (curstate != STOPMACHINE_EXIT);
 
        local_irq_enable();
+       return err;
 }
 
-/* Callback for CPUs which aren't supposed to do anything. */
-static int chill(void *unused)
-{
-       return 0;
-}
-
-int stop_machine_create(void)
-{
-       mutex_lock(&setup_lock);
-       if (refcount)
-               goto done;
-       stop_machine_wq = create_rt_workqueue("kstop");
-       if (!stop_machine_wq)
-               goto err_out;
-       stop_machine_work = alloc_percpu(struct work_struct);
-       if (!stop_machine_work)
-               goto err_out;
-done:
-       refcount++;
-       mutex_unlock(&setup_lock);
-       return 0;
-
-err_out:
-       if (stop_machine_wq)
-               destroy_workqueue(stop_machine_wq);
-       mutex_unlock(&setup_lock);
-       return -ENOMEM;
-}
-EXPORT_SYMBOL_GPL(stop_machine_create);
-
-void stop_machine_destroy(void)
-{
-       mutex_lock(&setup_lock);
-       refcount--;
-       if (refcount)
-               goto done;
-       destroy_workqueue(stop_machine_wq);
-       free_percpu(stop_machine_work);
-done:
-       mutex_unlock(&setup_lock);
-}
-EXPORT_SYMBOL_GPL(stop_machine_destroy);
-
 int __stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus)
 {
-       struct work_struct *sm_work;
-       int i, ret;
-
-       /* Set up initial state. */
-       mutex_lock(&lock);
-       num_threads = num_online_cpus();
-       active_cpus = cpus;
-       active.fn = fn;
-       active.data = data;
-       active.fnret = 0;
-       idle.fn = chill;
-       idle.data = NULL;
-
-       set_state(STOPMACHINE_PREPARE);
-
-       /* Schedule the stop_cpu work on all cpus: hold this CPU so one
-        * doesn't hit this CPU until we're ready. */
-       get_cpu();
-       for_each_online_cpu(i) {
-               sm_work = per_cpu_ptr(stop_machine_work, i);
-               INIT_WORK(sm_work, stop_cpu);
-               queue_work_on(i, stop_machine_wq, sm_work);
-       }
-       /* This will release the thread on our CPU. */
-       put_cpu();
-       flush_workqueue(stop_machine_wq);
-       ret = active.fnret;
-       mutex_unlock(&lock);
-       return ret;
+       struct stop_machine_data smdata = { .fn = fn, .data = data,
+                                           .num_threads = num_online_cpus(),
+                                           .active_cpus = cpus };
+
+       /* Set the initial state and stop all online cpus. */
+       set_state(&smdata, STOPMACHINE_PREPARE);
+       return stop_cpus(cpu_online_mask, stop_machine_cpu_stop, &smdata);
 }
 
 int stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus)
 {
        int ret;
 
-       ret = stop_machine_create();
-       if (ret)
-               return ret;
        /* No CPUs can come up or down during this. */
        get_online_cpus();
        ret = __stop_machine(fn, data, cpus);
        put_online_cpus();
-       stop_machine_destroy();
        return ret;
 }
 EXPORT_SYMBOL_GPL(stop_machine);
+
+#endif /* CONFIG_STOP_MACHINE */
index 8298878f4f7116ec8b04d6babbd016cfa2edb026..7cb426a58965d5063dbf0d115646e32b4a082ac6 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/personality.h>
 #include <linux/ptrace.h>
 #include <linux/fs_struct.h>
+#include <linux/gfp.h>
 
 #include <linux/compat.h>
 #include <linux/syscalls.h>
@@ -1117,7 +1118,7 @@ DECLARE_RWSEM(uts_sem);
 
 #ifdef COMPAT_UTS_MACHINE
 #define override_architecture(name) \
-       (current->personality == PER_LINUX32 && \
+       (personality(current->personality) == PER_LINUX32 && \
         copy_to_user(name->machine, COMPAT_UTS_MACHINE, \
                      sizeof(COMPAT_UTS_MACHINE)))
 #else
index 8cd50d8f9bde4c2d2ce403736aa33c9b769f35c9..59030570f5ca4970283d24aea52f4e06fa849b4f 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/file.h>
 #include <linux/ctype.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_SYSCTL_SYSCALL
 
index 899ca51be5e87849dee68145e59d86f4cc9077b7..11281d5792bd5b4d0eb7d5b86034ca4b2a4d256a 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/delayacct.h>
 #include <linux/cpumask.h>
 #include <linux/percpu.h>
+#include <linux/slab.h>
 #include <linux/cgroupstats.h>
 #include <linux/cgroup.h>
 #include <linux/fs.h>
index 804798005d19846d449fcb5b2b81439135c6c62a..656dccfe1cbbc322ab44b0b398618297186bf118 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/syscalls.h>
 #include <linux/security.h>
 #include <linux/fs.h>
-#include <linux/slab.h>
 #include <linux/math64.h>
 #include <linux/ptrace.h>
 
index 0a8a213016f005bfc51632b22b668f037a75c3f2..aada0e52680ace6cc7d5e09a111a3879c1c6bda3 100644 (file)
 
 #include "tick-internal.h"
 
+/* Limit min_delta to a jiffie */
+#define MIN_DELTA_LIMIT                (NSEC_PER_SEC / HZ)
+
+static int tick_increase_min_delta(struct clock_event_device *dev)
+{
+       /* Nothing to do if we already reached the limit */
+       if (dev->min_delta_ns >= MIN_DELTA_LIMIT)
+               return -ETIME;
+
+       if (dev->min_delta_ns < 5000)
+               dev->min_delta_ns = 5000;
+       else
+               dev->min_delta_ns += dev->min_delta_ns >> 1;
+
+       if (dev->min_delta_ns > MIN_DELTA_LIMIT)
+               dev->min_delta_ns = MIN_DELTA_LIMIT;
+
+       printk(KERN_WARNING "CE: %s increased min_delta_ns to %llu nsec\n",
+              dev->name ? dev->name : "?",
+              (unsigned long long) dev->min_delta_ns);
+       return 0;
+}
+
 /**
  * tick_program_event internal worker function
  */
@@ -37,23 +60,28 @@ int tick_dev_program_event(struct clock_event_device *dev, ktime_t expires,
                if (!ret || !force)
                        return ret;
 
+               dev->retries++;
                /*
-                * We tried 2 times to program the device with the given
-                * min_delta_ns. If that's not working then we double it
+                * We tried 3 times to program the device with the given
+                * min_delta_ns. If that's not working then we increase it
                 * and emit a warning.
                 */
                if (++i > 2) {
                        /* Increase the min. delta and try again */
-                       if (!dev->min_delta_ns)
-                               dev->min_delta_ns = 5000;
-                       else
-                               dev->min_delta_ns += dev->min_delta_ns >> 1;
-
-                       printk(KERN_WARNING
-                              "CE: %s increasing min_delta_ns to %llu nsec\n",
-                              dev->name ? dev->name : "?",
-                              (unsigned long long) dev->min_delta_ns << 1);
-
+                       if (tick_increase_min_delta(dev)) {
+                               /*
+                                * Get out of the loop if min_delta_ns
+                                * hit the limit already. That's
+                                * better than staying here forever.
+                                *
+                                * We clear next_event so we have a
+                                * chance that the box survives.
+                                */
+                               printk(KERN_WARNING
+                                      "CE: Reprogramming failure. Giving up\n");
+                               dev->next_event.tv64 = KTIME_MAX;
+                               return -ETIME;
+                       }
                        i = 0;
                }
 
index f992762d7f51c9e187160f8ee78543a5933cf679..1d7b9bc1c0340e8deccbc5df1418fd71889d837d 100644 (file)
@@ -150,14 +150,32 @@ static void tick_nohz_update_jiffies(ktime_t now)
        touch_softlockup_watchdog();
 }
 
+/*
+ * Updates the per cpu time idle statistics counters
+ */
+static void
+update_ts_time_stats(struct tick_sched *ts, ktime_t now, u64 *last_update_time)
+{
+       ktime_t delta;
+
+       if (ts->idle_active) {
+               delta = ktime_sub(now, ts->idle_entrytime);
+               ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta);
+               if (nr_iowait_cpu() > 0)
+                       ts->iowait_sleeptime = ktime_add(ts->iowait_sleeptime, delta);
+               ts->idle_entrytime = now;
+       }
+
+       if (last_update_time)
+               *last_update_time = ktime_to_us(now);
+
+}
+
 static void tick_nohz_stop_idle(int cpu, ktime_t now)
 {
        struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
-       ktime_t delta;
 
-       delta = ktime_sub(now, ts->idle_entrytime);
-       ts->idle_lastupdate = now;
-       ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta);
+       update_ts_time_stats(ts, now, NULL);
        ts->idle_active = 0;
 
        sched_clock_idle_wakeup_event(0);
@@ -165,20 +183,32 @@ static void tick_nohz_stop_idle(int cpu, ktime_t now)
 
 static ktime_t tick_nohz_start_idle(struct tick_sched *ts)
 {
-       ktime_t now, delta;
+       ktime_t now;
 
        now = ktime_get();
-       if (ts->idle_active) {
-               delta = ktime_sub(now, ts->idle_entrytime);
-               ts->idle_lastupdate = now;
-               ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta);
-       }
+
+       update_ts_time_stats(ts, now, NULL);
+
        ts->idle_entrytime = now;
        ts->idle_active = 1;
        sched_clock_idle_sleep_event();
        return now;
 }
 
+/**
+ * get_cpu_idle_time_us - get the total idle time of a cpu
+ * @cpu: CPU number to query
+ * @last_update_time: variable to store update time in
+ *
+ * Return the cummulative idle time (since boot) for a given
+ * CPU, in microseconds. The idle time returned includes
+ * the iowait time (unlike what "top" and co report).
+ *
+ * This time is measured via accounting rather than sampling,
+ * and is as accurate as ktime_get() is.
+ *
+ * This function returns -1 if NOHZ is not enabled.
+ */
 u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time)
 {
        struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
@@ -186,15 +216,38 @@ u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time)
        if (!tick_nohz_enabled)
                return -1;
 
-       if (ts->idle_active)
-               *last_update_time = ktime_to_us(ts->idle_lastupdate);
-       else
-               *last_update_time = ktime_to_us(ktime_get());
+       update_ts_time_stats(ts, ktime_get(), last_update_time);
 
        return ktime_to_us(ts->idle_sleeptime);
 }
 EXPORT_SYMBOL_GPL(get_cpu_idle_time_us);
 
+/*
+ * get_cpu_iowait_time_us - get the total iowait time of a cpu
+ * @cpu: CPU number to query
+ * @last_update_time: variable to store update time in
+ *
+ * Return the cummulative iowait time (since boot) for a given
+ * CPU, in microseconds.
+ *
+ * This time is measured via accounting rather than sampling,
+ * and is as accurate as ktime_get() is.
+ *
+ * This function returns -1 if NOHZ is not enabled.
+ */
+u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time)
+{
+       struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
+
+       if (!tick_nohz_enabled)
+               return -1;
+
+       update_ts_time_stats(ts, ktime_get(), last_update_time);
+
+       return ktime_to_us(ts->iowait_sleeptime);
+}
+EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us);
+
 /**
  * tick_nohz_stop_sched_tick - stop the idle tick from the idle task
  *
@@ -262,6 +315,9 @@ void tick_nohz_stop_sched_tick(int inidle)
                goto end;
        }
 
+       if (nohz_ratelimit(cpu))
+               goto end;
+
        ts->idle_calls++;
        /* Read jiffies and the time when jiffies were updated last */
        do {
index 12f5c55090bea159652c299d0db1a0a2969a3424..ac38fbb176ccd0bb598b1eaaa7f2a703b17ec565 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/timecompare.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/math64.h>
 
 /*
index 16736379a9caaba6320f32f3df6e94cb5a9abbda..39f6177fafac110d342d2cedcd093b7a736bfdc8 100644 (file)
@@ -818,7 +818,8 @@ void update_wall_time(void)
        shift = min(shift, maxshift);
        while (offset >= timekeeper.cycle_interval) {
                offset = logarithmic_accumulation(offset, shift);
-               shift--;
+               if(offset < timekeeper.cycle_interval<<shift)
+                       shift--;
        }
 
        /* correct the clock when NTP error is too big */
index bdfb8dd1050cfb64f4cca35f22b749b06a294dd1..ab8f5e33fa92c76db813d1419e6a339f3a7aca52 100644 (file)
@@ -176,6 +176,7 @@ static void print_cpu(struct seq_file *m, int cpu, u64 now)
                P_ns(idle_waketime);
                P_ns(idle_exittime);
                P_ns(idle_sleeptime);
+               P_ns(iowait_sleeptime);
                P(last_jiffies);
                P(next_jiffies);
                P_ns(idle_expires);
@@ -228,6 +229,7 @@ print_tickdevice(struct seq_file *m, struct tick_device *td, int cpu)
        SEQ_printf(m, " event_handler:  ");
        print_name_offset(m, dev->event_handler);
        SEQ_printf(m, "\n");
+       SEQ_printf(m, " retries:        %lu\n", dev->retries);
 }
 
 static void timer_list_show_tickdevices(struct seq_file *m)
@@ -257,7 +259,7 @@ static int timer_list_show(struct seq_file *m, void *v)
        u64 now = ktime_to_ns(ktime_get());
        int cpu;
 
-       SEQ_printf(m, "Timer List Version: v0.5\n");
+       SEQ_printf(m, "Timer List Version: v0.6\n");
        SEQ_printf(m, "HRTIMER_MAX_CLOCK_BASES: %d\n", HRTIMER_MAX_CLOCK_BASES);
        SEQ_printf(m, "now at %Ld nsecs\n", (unsigned long long)now);
 
index c61a7949387f93e69b1a4979eff1a03c7e7131b4..aeb6a54f2771691499ab474c3bf57d8e3e7d092f 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/kallsyms.h>
 #include <linux/perf_event.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -880,6 +881,7 @@ int try_to_del_timer_sync(struct timer_list *timer)
        if (base->running_timer == timer)
                goto out;
 
+       timer_stats_timer_clear_start_info(timer);
        ret = 0;
        if (timer_pending(timer)) {
                detach_timer(timer, 1);
index 13e13d428cd37b96ca144b733c4c98fa4c7f257d..8b1797c4545b41c00cca7b3e5e268cf8b8f0e164 100644 (file)
@@ -44,9 +44,6 @@ config HAVE_FTRACE_MCOUNT_RECORD
        help
          See Documentation/trace/ftrace-design.txt
 
-config HAVE_HW_BRANCH_TRACER
-       bool
-
 config HAVE_SYSCALL_TRACEPOINTS
        bool
        help
@@ -374,14 +371,6 @@ config STACK_TRACER
 
          Say N if unsure.
 
-config HW_BRANCH_TRACER
-       depends on HAVE_HW_BRANCH_TRACER
-       bool "Trace hw branches"
-       select GENERIC_TRACER
-       help
-         This tracer records all branches on the system in a circular
-         buffer, giving access to the last N branches for each cpu.
-
 config KMEMTRACE
        bool "Trace SLAB allocations"
        select GENERIC_TRACER
index d00c6fe23f54aec4176db3139deee574ed42557b..ffb1a5b0550e3f071c568695a386a10ea84290b8 100644 (file)
@@ -41,7 +41,6 @@ obj-$(CONFIG_MMIOTRACE) += trace_mmiotrace.o
 obj-$(CONFIG_BOOT_TRACER) += trace_boot.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += trace_functions_graph.o
 obj-$(CONFIG_TRACE_BRANCH_PROFILING) += trace_branch.o
-obj-$(CONFIG_HW_BRANCH_TRACER) += trace_hw_branches.o
 obj-$(CONFIG_KMEMTRACE) += kmemtrace.o
 obj-$(CONFIG_WORKQUEUE_TRACER) += trace_workqueue.o
 obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o
@@ -52,7 +51,7 @@ obj-$(CONFIG_EVENT_TRACING) += trace_events.o
 obj-$(CONFIG_EVENT_TRACING) += trace_export.o
 obj-$(CONFIG_FTRACE_SYSCALLS) += trace_syscalls.o
 ifeq ($(CONFIG_PERF_EVENTS),y)
-obj-$(CONFIG_EVENT_TRACING) += trace_event_profile.o
+obj-$(CONFIG_EVENT_TRACING) += trace_event_perf.o
 endif
 obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o
 obj-$(CONFIG_KPROBE_EVENT) += trace_kprobe.o
index 07f945a99430bfe58fd1dde80365a7e6e663147d..b3bc91a3f510d089d7ce69ad4b294655dce53ac7 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/percpu.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/debugfs.h>
 #include <linux/smp_lock.h>
 #include <linux/time.h>
index d9062f5cc0c01e598670d651fba80b87ccb68a57..32837e19e3bdb66535650af0ba8e3597d48a11e8 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/uaccess.h>
 #include <linux/ftrace.h>
 #include <linux/sysctl.h>
+#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/list.h>
 #include <linux/hash.h>
@@ -263,6 +264,7 @@ struct ftrace_profile {
        unsigned long                   counter;
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
        unsigned long long              time;
+       unsigned long long              time_squared;
 #endif
 };
 
@@ -365,9 +367,9 @@ static int function_stat_headers(struct seq_file *m)
 {
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
        seq_printf(m, "  Function                               "
-                  "Hit    Time            Avg\n"
+                  "Hit    Time            Avg             s^2\n"
                      "  --------                               "
-                  "---    ----            ---\n");
+                  "---    ----            ---             ---\n");
 #else
        seq_printf(m, "  Function                               Hit\n"
                      "  --------                               ---\n");
@@ -383,6 +385,7 @@ static int function_stat_show(struct seq_file *m, void *v)
        static DEFINE_MUTEX(mutex);
        static struct trace_seq s;
        unsigned long long avg;
+       unsigned long long stddev;
 #endif
 
        kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
@@ -393,11 +396,25 @@ static int function_stat_show(struct seq_file *m, void *v)
        avg = rec->time;
        do_div(avg, rec->counter);
 
+       /* Sample standard deviation (s^2) */
+       if (rec->counter <= 1)
+               stddev = 0;
+       else {
+               stddev = rec->time_squared - rec->counter * avg * avg;
+               /*
+                * Divide only 1000 for ns^2 -> us^2 conversion.
+                * trace_print_graph_duration will divide 1000 again.
+                */
+               do_div(stddev, (rec->counter - 1) * 1000);
+       }
+
        mutex_lock(&mutex);
        trace_seq_init(&s);
        trace_print_graph_duration(rec->time, &s);
        trace_seq_puts(&s, "    ");
        trace_print_graph_duration(avg, &s);
+       trace_seq_puts(&s, "    ");
+       trace_print_graph_duration(stddev, &s);
        trace_print_seq(m, &s);
        mutex_unlock(&mutex);
 #endif
@@ -649,6 +666,10 @@ static void profile_graph_return(struct ftrace_graph_ret *trace)
        if (!stat->hash || !ftrace_profile_enabled)
                goto out;
 
+       /* If the calltime was zero'd ignore it */
+       if (!trace->calltime)
+               goto out;
+
        calltime = trace->rettime - trace->calltime;
 
        if (!(trace_flags & TRACE_ITER_GRAPH_TIME)) {
@@ -667,8 +688,10 @@ static void profile_graph_return(struct ftrace_graph_ret *trace)
        }
 
        rec = ftrace_find_profiled_func(stat, trace->func);
-       if (rec)
+       if (rec) {
                rec->time += calltime;
+               rec->time_squared += calltime * calltime;
+       }
 
  out:
        local_irq_restore(flags);
@@ -3211,8 +3234,7 @@ free:
 }
 
 static void
-ftrace_graph_probe_sched_switch(struct rq *__rq, struct task_struct *prev,
-                               struct task_struct *next)
+ftrace_graph_probe_sched_switch(struct task_struct *prev, struct task_struct *next)
 {
        unsigned long long timestamp;
        int index;
@@ -3338,11 +3360,11 @@ void unregister_ftrace_graph(void)
                goto out;
 
        ftrace_graph_active--;
-       unregister_trace_sched_switch(ftrace_graph_probe_sched_switch);
        ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub;
        ftrace_graph_entry = ftrace_graph_entry_stub;
        ftrace_shutdown(FTRACE_STOP_FUNC_RET);
        unregister_pm_notifier(&ftrace_suspend_notifier);
+       unregister_trace_sched_switch(ftrace_graph_probe_sched_switch);
 
  out:
        mutex_unlock(&ftrace_lock);
index 9f4f565b01e67e59bfd906f950ebea9f863252a6..a22582a061618cea52acee544d9e783ef1d9868e 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/workqueue.h>
 #include <linux/sched.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/power.h>
index 05a9f83b8819c39dcc03c76f737eaaf5ae7bbfe7..7f6059c5aa94c772ba6ad9785c40838f96bbc77f 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/percpu.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/hash.h>
 #include <linux/list.h>
@@ -207,6 +208,14 @@ EXPORT_SYMBOL_GPL(tracing_is_on);
 #define RB_MAX_SMALL_DATA      (RB_ALIGNMENT * RINGBUF_TYPE_DATA_TYPE_LEN_MAX)
 #define RB_EVNT_MIN_SIZE       8U      /* two 32bit words */
 
+#if !defined(CONFIG_64BIT) || defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+# define RB_FORCE_8BYTE_ALIGNMENT      0
+# define RB_ARCH_ALIGNMENT             RB_ALIGNMENT
+#else
+# define RB_FORCE_8BYTE_ALIGNMENT      1
+# define RB_ARCH_ALIGNMENT             8U
+#endif
+
 /* define RINGBUF_TYPE_DATA for 'case RINGBUF_TYPE_DATA:' */
 #define RINGBUF_TYPE_DATA 0 ... RINGBUF_TYPE_DATA_TYPE_LEN_MAX
 
@@ -310,6 +319,11 @@ EXPORT_SYMBOL_GPL(ring_buffer_event_data);
 #define TS_MASK                ((1ULL << TS_SHIFT) - 1)
 #define TS_DELTA_TEST  (~TS_MASK)
 
+/* Flag when events were overwritten */
+#define RB_MISSED_EVENTS       (1 << 31)
+/* Missed count stored at end */
+#define RB_MISSED_STORED       (1 << 30)
+
 struct buffer_data_page {
        u64              time_stamp;    /* page time stamp */
        local_t          commit;        /* write committed index */
@@ -329,6 +343,7 @@ struct buffer_page {
        local_t          write;         /* index for next write */
        unsigned         read;          /* index for next read */
        local_t          entries;       /* entries on this page */
+       unsigned long    real_end;      /* real end of data */
        struct buffer_data_page *page;  /* Actual data page */
 };
 
@@ -408,6 +423,12 @@ int ring_buffer_print_page_header(struct trace_seq *s)
                               (unsigned int)sizeof(field.commit),
                               (unsigned int)is_signed_type(long));
 
+       ret = trace_seq_printf(s, "\tfield: int overwrite;\t"
+                              "offset:%u;\tsize:%u;\tsigned:%u;\n",
+                              (unsigned int)offsetof(typeof(field), commit),
+                              1,
+                              (unsigned int)is_signed_type(long));
+
        ret = trace_seq_printf(s, "\tfield: char data;\t"
                               "offset:%u;\tsize:%u;\tsigned:%u;\n",
                               (unsigned int)offsetof(typeof(field), data),
@@ -431,6 +452,8 @@ struct ring_buffer_per_cpu {
        struct buffer_page              *tail_page;     /* write to tail */
        struct buffer_page              *commit_page;   /* committed pages */
        struct buffer_page              *reader_page;
+       unsigned long                   lost_events;
+       unsigned long                   last_overrun;
        local_t                         commit_overrun;
        local_t                         overrun;
        local_t                         entries;
@@ -1201,18 +1224,19 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages)
 
        for (i = 0; i < nr_pages; i++) {
                if (RB_WARN_ON(cpu_buffer, list_empty(cpu_buffer->pages)))
-                       return;
+                       goto out;
                p = cpu_buffer->pages->next;
                bpage = list_entry(p, struct buffer_page, list);
                list_del_init(&bpage->list);
                free_buffer_page(bpage);
        }
        if (RB_WARN_ON(cpu_buffer, list_empty(cpu_buffer->pages)))
-               return;
+               goto out;
 
        rb_reset_cpu(cpu_buffer);
        rb_check_pages(cpu_buffer);
 
+out:
        spin_unlock_irq(&cpu_buffer->reader_lock);
 }
 
@@ -1229,7 +1253,7 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer,
 
        for (i = 0; i < nr_pages; i++) {
                if (RB_WARN_ON(cpu_buffer, list_empty(pages)))
-                       return;
+                       goto out;
                p = pages->next;
                bpage = list_entry(p, struct buffer_page, list);
                list_del_init(&bpage->list);
@@ -1238,6 +1262,7 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer,
        rb_reset_cpu(cpu_buffer);
        rb_check_pages(cpu_buffer);
 
+out:
        spin_unlock_irq(&cpu_buffer->reader_lock);
 }
 
@@ -1547,7 +1572,7 @@ rb_update_event(struct ring_buffer_event *event,
 
        case 0:
                length -= RB_EVNT_HDR_SIZE;
-               if (length > RB_MAX_SMALL_DATA)
+               if (length > RB_MAX_SMALL_DATA || RB_FORCE_8BYTE_ALIGNMENT)
                        event->array[0] = length;
                else
                        event->type_len = DIV_ROUND_UP(length, RB_ALIGNMENT);
@@ -1722,11 +1747,11 @@ static unsigned rb_calculate_event_length(unsigned length)
        if (!length)
                length = 1;
 
-       if (length > RB_MAX_SMALL_DATA)
+       if (length > RB_MAX_SMALL_DATA || RB_FORCE_8BYTE_ALIGNMENT)
                length += sizeof(event.array[0]);
 
        length += RB_EVNT_HDR_SIZE;
-       length = ALIGN(length, RB_ALIGNMENT);
+       length = ALIGN(length, RB_ARCH_ALIGNMENT);
 
        return length;
 }
@@ -1750,6 +1775,13 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer,
        event = __rb_page_index(tail_page, tail);
        kmemcheck_annotate_bitfield(event, bitfield);
 
+       /*
+        * Save the original length to the meta data.
+        * This will be used by the reader to add lost event
+        * counter.
+        */
+       tail_page->real_end = tail;
+
        /*
         * If this event is bigger than the minimum size, then
         * we need to be careful that we don't subtract the
@@ -1968,17 +2000,13 @@ rb_add_time_stamp(struct ring_buffer_per_cpu *cpu_buffer,
                  u64 *ts, u64 *delta)
 {
        struct ring_buffer_event *event;
-       static int once;
        int ret;
 
-       if (unlikely(*delta > (1ULL << 59) && !once++)) {
-               printk(KERN_WARNING "Delta way too big! %llu"
-                      " ts=%llu write stamp = %llu\n",
-                      (unsigned long long)*delta,
-                      (unsigned long long)*ts,
-                      (unsigned long long)cpu_buffer->write_stamp);
-               WARN_ON(1);
-       }
+       WARN_ONCE(*delta > (1ULL << 59),
+                 KERN_WARNING "Delta way too big! %llu ts=%llu write stamp = %llu\n",
+                 (unsigned long long)*delta,
+                 (unsigned long long)*ts,
+                 (unsigned long long)cpu_buffer->write_stamp);
 
        /*
         * The delta is too big, we to add a
@@ -2827,6 +2855,7 @@ static struct buffer_page *
 rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
 {
        struct buffer_page *reader = NULL;
+       unsigned long overwrite;
        unsigned long flags;
        int nr_loops = 0;
        int ret;
@@ -2868,6 +2897,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
        local_set(&cpu_buffer->reader_page->write, 0);
        local_set(&cpu_buffer->reader_page->entries, 0);
        local_set(&cpu_buffer->reader_page->page->commit, 0);
+       cpu_buffer->reader_page->real_end = 0;
 
  spin:
        /*
@@ -2887,6 +2917,18 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
        /* The reader page will be pointing to the new head */
        rb_set_list_to_head(cpu_buffer, &cpu_buffer->reader_page->list);
 
+       /*
+        * We want to make sure we read the overruns after we set up our
+        * pointers to the next object. The writer side does a
+        * cmpxchg to cross pages which acts as the mb on the writer
+        * side. Note, the reader will constantly fail the swap
+        * while the writer is updating the pointers, so this
+        * guarantees that the overwrite recorded here is the one we
+        * want to compare with the last_overrun.
+        */
+       smp_mb();
+       overwrite = local_read(&(cpu_buffer->overrun));
+
        /*
         * Here's the tricky part.
         *
@@ -2918,6 +2960,11 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
        cpu_buffer->reader_page = reader;
        rb_reset_reader_page(cpu_buffer);
 
+       if (overwrite != cpu_buffer->last_overrun) {
+               cpu_buffer->lost_events = overwrite - cpu_buffer->last_overrun;
+               cpu_buffer->last_overrun = overwrite;
+       }
+
        goto again;
 
  out:
@@ -2994,8 +3041,14 @@ static void rb_advance_iter(struct ring_buffer_iter *iter)
                rb_advance_iter(iter);
 }
 
+static int rb_lost_events(struct ring_buffer_per_cpu *cpu_buffer)
+{
+       return cpu_buffer->lost_events;
+}
+
 static struct ring_buffer_event *
-rb_buffer_peek(struct ring_buffer_per_cpu *cpu_buffer, u64 *ts)
+rb_buffer_peek(struct ring_buffer_per_cpu *cpu_buffer, u64 *ts,
+              unsigned long *lost_events)
 {
        struct ring_buffer_event *event;
        struct buffer_page *reader;
@@ -3047,6 +3100,8 @@ rb_buffer_peek(struct ring_buffer_per_cpu *cpu_buffer, u64 *ts)
                        ring_buffer_normalize_time_stamp(cpu_buffer->buffer,
                                                         cpu_buffer->cpu, ts);
                }
+               if (lost_events)
+                       *lost_events = rb_lost_events(cpu_buffer);
                return event;
 
        default:
@@ -3157,12 +3212,14 @@ static inline int rb_ok_to_lock(void)
  * @buffer: The ring buffer to read
  * @cpu: The cpu to peak at
  * @ts: The timestamp counter of this event.
+ * @lost_events: a variable to store if events were lost (may be NULL)
  *
  * This will return the event that will be read next, but does
  * not consume the data.
  */
 struct ring_buffer_event *
-ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
+ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts,
+                unsigned long *lost_events)
 {
        struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
        struct ring_buffer_event *event;
@@ -3177,7 +3234,7 @@ ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
        local_irq_save(flags);
        if (dolock)
                spin_lock(&cpu_buffer->reader_lock);
-       event = rb_buffer_peek(cpu_buffer, ts);
+       event = rb_buffer_peek(cpu_buffer, ts, lost_events);
        if (event && event->type_len == RINGBUF_TYPE_PADDING)
                rb_advance_reader(cpu_buffer);
        if (dolock)
@@ -3219,13 +3276,17 @@ ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
 /**
  * ring_buffer_consume - return an event and consume it
  * @buffer: The ring buffer to get the next event from
+ * @cpu: the cpu to read the buffer from
+ * @ts: a variable to store the timestamp (may be NULL)
+ * @lost_events: a variable to store if events were lost (may be NULL)
  *
  * Returns the next event in the ring buffer, and that event is consumed.
  * Meaning, that sequential reads will keep returning a different event,
  * and eventually empty the ring buffer if the producer is slower.
  */
 struct ring_buffer_event *
-ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts)
+ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts,
+                   unsigned long *lost_events)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        struct ring_buffer_event *event = NULL;
@@ -3246,9 +3307,11 @@ ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts)
        if (dolock)
                spin_lock(&cpu_buffer->reader_lock);
 
-       event = rb_buffer_peek(cpu_buffer, ts);
-       if (event)
+       event = rb_buffer_peek(cpu_buffer, ts, lost_events);
+       if (event) {
+               cpu_buffer->lost_events = 0;
                rb_advance_reader(cpu_buffer);
+       }
 
        if (dolock)
                spin_unlock(&cpu_buffer->reader_lock);
@@ -3265,23 +3328,30 @@ ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts)
 EXPORT_SYMBOL_GPL(ring_buffer_consume);
 
 /**
- * ring_buffer_read_start - start a non consuming read of the buffer
+ * ring_buffer_read_prepare - Prepare for a non consuming read of the buffer
  * @buffer: The ring buffer to read from
  * @cpu: The cpu buffer to iterate over
  *
- * This starts up an iteration through the buffer. It also disables
- * the recording to the buffer until the reading is finished.
- * This prevents the reading from being corrupted. This is not
- * a consuming read, so a producer is not expected.
+ * This performs the initial preparations necessary to iterate
+ * through the buffer.  Memory is allocated, buffer recording
+ * is disabled, and the iterator pointer is returned to the caller.
  *
- * Must be paired with ring_buffer_finish.
+ * Disabling buffer recordng prevents the reading from being
+ * corrupted. This is not a consuming read, so a producer is not
+ * expected.
+ *
+ * After a sequence of ring_buffer_read_prepare calls, the user is
+ * expected to make at least one call to ring_buffer_prepare_sync.
+ * Afterwards, ring_buffer_read_start is invoked to get things going
+ * for real.
+ *
+ * This overall must be paired with ring_buffer_finish.
  */
 struct ring_buffer_iter *
-ring_buffer_read_start(struct ring_buffer *buffer, int cpu)
+ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        struct ring_buffer_iter *iter;
-       unsigned long flags;
 
        if (!cpumask_test_cpu(cpu, buffer->cpumask))
                return NULL;
@@ -3295,15 +3365,52 @@ ring_buffer_read_start(struct ring_buffer *buffer, int cpu)
        iter->cpu_buffer = cpu_buffer;
 
        atomic_inc(&cpu_buffer->record_disabled);
+
+       return iter;
+}
+EXPORT_SYMBOL_GPL(ring_buffer_read_prepare);
+
+/**
+ * ring_buffer_read_prepare_sync - Synchronize a set of prepare calls
+ *
+ * All previously invoked ring_buffer_read_prepare calls to prepare
+ * iterators will be synchronized.  Afterwards, read_buffer_read_start
+ * calls on those iterators are allowed.
+ */
+void
+ring_buffer_read_prepare_sync(void)
+{
        synchronize_sched();
+}
+EXPORT_SYMBOL_GPL(ring_buffer_read_prepare_sync);
+
+/**
+ * ring_buffer_read_start - start a non consuming read of the buffer
+ * @iter: The iterator returned by ring_buffer_read_prepare
+ *
+ * This finalizes the startup of an iteration through the buffer.
+ * The iterator comes from a call to ring_buffer_read_prepare and
+ * an intervening ring_buffer_read_prepare_sync must have been
+ * performed.
+ *
+ * Must be paired with ring_buffer_finish.
+ */
+void
+ring_buffer_read_start(struct ring_buffer_iter *iter)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+       unsigned long flags;
+
+       if (!iter)
+               return;
+
+       cpu_buffer = iter->cpu_buffer;
 
        spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
        arch_spin_lock(&cpu_buffer->lock);
        rb_iter_reset(iter);
        arch_spin_unlock(&cpu_buffer->lock);
        spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
-
-       return iter;
 }
 EXPORT_SYMBOL_GPL(ring_buffer_read_start);
 
@@ -3397,6 +3504,9 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
        cpu_buffer->write_stamp = 0;
        cpu_buffer->read_stamp = 0;
 
+       cpu_buffer->lost_events = 0;
+       cpu_buffer->last_overrun = 0;
+
        rb_head_page_activate(cpu_buffer);
 }
 
@@ -3672,6 +3782,7 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
        struct ring_buffer_event *event;
        struct buffer_data_page *bpage;
        struct buffer_page *reader;
+       unsigned long missed_events;
        unsigned long flags;
        unsigned int commit;
        unsigned int read;
@@ -3708,6 +3819,9 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
        read = reader->read;
        commit = rb_page_commit(reader);
 
+       /* Check if any events were dropped */
+       missed_events = cpu_buffer->lost_events;
+
        /*
         * If this page has been partially read or
         * if len is not big enough to read the rest of the page or
@@ -3768,9 +3882,35 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
                local_set(&reader->entries, 0);
                reader->read = 0;
                *data_page = bpage;
+
+               /*
+                * Use the real_end for the data size,
+                * This gives us a chance to store the lost events
+                * on the page.
+                */
+               if (reader->real_end)
+                       local_set(&bpage->commit, reader->real_end);
        }
        ret = read;
 
+       cpu_buffer->lost_events = 0;
+       /*
+        * Set a flag in the commit field if we lost events
+        */
+       if (missed_events) {
+               commit = local_read(&bpage->commit);
+
+               /* If there is room at the end of the page to save the
+                * missed events, then record it there.
+                */
+               if (BUF_PAGE_SIZE - commit >= sizeof(missed_events)) {
+                       memcpy(&bpage->data[commit], &missed_events,
+                              sizeof(missed_events));
+                       local_add(RB_MISSED_STORED, &bpage->commit);
+               }
+               local_add(RB_MISSED_EVENTS, &bpage->commit);
+       }
+
  out_unlock:
        spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
 
index df74c7982255ba1c5095371e1ca3fd5369d3f3c2..302f8a6146352a998f2730923598346196e84856 100644 (file)
@@ -81,7 +81,7 @@ static enum event_status read_event(int cpu)
        int *entry;
        u64 ts;
 
-       event = ring_buffer_consume(buffer, cpu, &ts);
+       event = ring_buffer_consume(buffer, cpu, &ts, NULL);
        if (!event)
                return EVENT_DROPPED;
 
@@ -113,7 +113,8 @@ static enum event_status read_page(int cpu)
        ret = ring_buffer_read_page(buffer, &bpage, PAGE_SIZE, cpu, 1);
        if (ret >= 0) {
                rpage = bpage;
-               commit = local_read(&rpage->commit);
+               /* The commit may have missed event flags set, clear them */
+               commit = local_read(&rpage->commit) & 0xfffff;
                for (i = 0; i < commit && !kill_test; i += inc) {
 
                        if (i >= (PAGE_SIZE - offsetof(struct rb_page, data))) {
index 3ec2ee6f65602fde8cf701432a18b8c7b2fef11e..756d7283318bd24e4998ca93d72d1edf62f8bef1 100644 (file)
 #include <linux/kdebug.h>
 #include <linux/string.h>
 #include <linux/rwsem.h>
+#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/poll.h>
-#include <linux/gfp.h>
 #include <linux/fs.h>
 
 #include "trace.h"
@@ -117,9 +117,12 @@ static cpumask_var_t __read_mostly tracing_buffer_mask;
  *
  * It is default off, but you can enable it with either specifying
  * "ftrace_dump_on_oops" in the kernel command line, or setting
- * /proc/sys/kernel/ftrace_dump_on_oops to true.
+ * /proc/sys/kernel/ftrace_dump_on_oops
+ * Set 1 if you want to dump buffers of all CPUs
+ * Set 2 if you want to dump the buffer of the CPU that triggered oops
  */
-int ftrace_dump_on_oops;
+
+enum ftrace_dump_mode ftrace_dump_on_oops;
 
 static int tracing_set_tracer(const char *buf);
 
@@ -139,8 +142,17 @@ __setup("ftrace=", set_cmdline_ftrace);
 
 static int __init set_ftrace_dump_on_oops(char *str)
 {
-       ftrace_dump_on_oops = 1;
-       return 1;
+       if (*str++ != '=' || !*str) {
+               ftrace_dump_on_oops = DUMP_ALL;
+               return 1;
+       }
+
+       if (!strcmp("orig_cpu", str)) {
+               ftrace_dump_on_oops = DUMP_ORIG;
+                return 1;
+        }
+
+        return 0;
 }
 __setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops);
 
@@ -1545,7 +1557,8 @@ static void trace_iterator_increment(struct trace_iterator *iter)
 }
 
 static struct trace_entry *
-peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts)
+peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts,
+               unsigned long *lost_events)
 {
        struct ring_buffer_event *event;
        struct ring_buffer_iter *buf_iter = iter->buffer_iter[cpu];
@@ -1556,7 +1569,8 @@ peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts)
        if (buf_iter)
                event = ring_buffer_iter_peek(buf_iter, ts);
        else
-               event = ring_buffer_peek(iter->tr->buffer, cpu, ts);
+               event = ring_buffer_peek(iter->tr->buffer, cpu, ts,
+                                        lost_events);
 
        ftrace_enable_cpu();
 
@@ -1564,10 +1578,12 @@ peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts)
 }
 
 static struct trace_entry *
-__find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
+__find_next_entry(struct trace_iterator *iter, int *ent_cpu,
+                 unsigned long *missing_events, u64 *ent_ts)
 {
        struct ring_buffer *buffer = iter->tr->buffer;
        struct trace_entry *ent, *next = NULL;
+       unsigned long lost_events = 0, next_lost = 0;
        int cpu_file = iter->cpu_file;
        u64 next_ts = 0, ts;
        int next_cpu = -1;
@@ -1580,7 +1596,7 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
        if (cpu_file > TRACE_PIPE_ALL_CPU) {
                if (ring_buffer_empty_cpu(buffer, cpu_file))
                        return NULL;
-               ent = peek_next_entry(iter, cpu_file, ent_ts);
+               ent = peek_next_entry(iter, cpu_file, ent_ts, missing_events);
                if (ent_cpu)
                        *ent_cpu = cpu_file;
 
@@ -1592,7 +1608,7 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
                if (ring_buffer_empty_cpu(buffer, cpu))
                        continue;
 
-               ent = peek_next_entry(iter, cpu, &ts);
+               ent = peek_next_entry(iter, cpu, &ts, &lost_events);
 
                /*
                 * Pick the entry with the smallest timestamp:
@@ -1601,6 +1617,7 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
                        next = ent;
                        next_cpu = cpu;
                        next_ts = ts;
+                       next_lost = lost_events;
                }
        }
 
@@ -1610,6 +1627,9 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
        if (ent_ts)
                *ent_ts = next_ts;
 
+       if (missing_events)
+               *missing_events = next_lost;
+
        return next;
 }
 
@@ -1617,13 +1637,14 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
 struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
                                          int *ent_cpu, u64 *ent_ts)
 {
-       return __find_next_entry(iter, ent_cpu, ent_ts);
+       return __find_next_entry(iter, ent_cpu, NULL, ent_ts);
 }
 
 /* Find the next real entry, and increment the iterator to the next entry */
 static void *find_next_entry_inc(struct trace_iterator *iter)
 {
-       iter->ent = __find_next_entry(iter, &iter->cpu, &iter->ts);
+       iter->ent = __find_next_entry(iter, &iter->cpu,
+                                     &iter->lost_events, &iter->ts);
 
        if (iter->ent)
                trace_iterator_increment(iter);
@@ -1635,7 +1656,8 @@ static void trace_consume(struct trace_iterator *iter)
 {
        /* Don't allow ftrace to trace into the ring buffers */
        ftrace_disable_cpu();
-       ring_buffer_consume(iter->tr->buffer, iter->cpu, &iter->ts);
+       ring_buffer_consume(iter->tr->buffer, iter->cpu, &iter->ts,
+                           &iter->lost_events);
        ftrace_enable_cpu();
 }
 
@@ -1786,7 +1808,7 @@ static void print_func_help_header(struct seq_file *m)
 }
 
 
-static void
+void
 print_trace_header(struct seq_file *m, struct trace_iterator *iter)
 {
        unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
@@ -1995,7 +2017,7 @@ static enum print_line_t print_bin_fmt(struct trace_iterator *iter)
        return event ? event->binary(iter, 0) : TRACE_TYPE_HANDLED;
 }
 
-static int trace_empty(struct trace_iterator *iter)
+int trace_empty(struct trace_iterator *iter)
 {
        int cpu;
 
@@ -2030,6 +2052,10 @@ static enum print_line_t print_trace_line(struct trace_iterator *iter)
 {
        enum print_line_t ret;
 
+       if (iter->lost_events)
+               trace_seq_printf(&iter->seq, "CPU:%d [LOST %lu EVENTS]\n",
+                                iter->cpu, iter->lost_events);
+
        if (iter->trace && iter->trace->print_line) {
                ret = iter->trace->print_line(iter);
                if (ret != TRACE_TYPE_UNHANDLED)
@@ -2058,6 +2084,23 @@ static enum print_line_t print_trace_line(struct trace_iterator *iter)
        return print_trace_fmt(iter);
 }
 
+void trace_default_header(struct seq_file *m)
+{
+       struct trace_iterator *iter = m->private;
+
+       if (iter->iter_flags & TRACE_FILE_LAT_FMT) {
+               /* print nothing if the buffers are empty */
+               if (trace_empty(iter))
+                       return;
+               print_trace_header(m, iter);
+               if (!(trace_flags & TRACE_ITER_VERBOSE))
+                       print_lat_help_header(m);
+       } else {
+               if (!(trace_flags & TRACE_ITER_VERBOSE))
+                       print_func_help_header(m);
+       }
+}
+
 static int s_show(struct seq_file *m, void *v)
 {
        struct trace_iterator *iter = v;
@@ -2070,17 +2113,9 @@ static int s_show(struct seq_file *m, void *v)
                }
                if (iter->trace && iter->trace->print_header)
                        iter->trace->print_header(m);
-               else if (iter->iter_flags & TRACE_FILE_LAT_FMT) {
-                       /* print nothing if the buffers are empty */
-                       if (trace_empty(iter))
-                               return 0;
-                       print_trace_header(m, iter);
-                       if (!(trace_flags & TRACE_ITER_VERBOSE))
-                               print_lat_help_header(m);
-               } else {
-                       if (!(trace_flags & TRACE_ITER_VERBOSE))
-                               print_func_help_header(m);
-               }
+               else
+                       trace_default_header(m);
+
        } else if (iter->leftover) {
                /*
                 * If we filled the seq_file buffer earlier, we
@@ -2166,15 +2201,20 @@ __tracing_open(struct inode *inode, struct file *file)
 
        if (iter->cpu_file == TRACE_PIPE_ALL_CPU) {
                for_each_tracing_cpu(cpu) {
-
                        iter->buffer_iter[cpu] =
-                               ring_buffer_read_start(iter->tr->buffer, cpu);
+                               ring_buffer_read_prepare(iter->tr->buffer, cpu);
+               }
+               ring_buffer_read_prepare_sync();
+               for_each_tracing_cpu(cpu) {
+                       ring_buffer_read_start(iter->buffer_iter[cpu]);
                        tracing_iter_reset(iter, cpu);
                }
        } else {
                cpu = iter->cpu_file;
                iter->buffer_iter[cpu] =
-                               ring_buffer_read_start(iter->tr->buffer, cpu);
+                       ring_buffer_read_prepare(iter->tr->buffer, cpu);
+               ring_buffer_read_prepare_sync();
+               ring_buffer_read_start(iter->buffer_iter[cpu]);
                tracing_iter_reset(iter, cpu);
        }
 
@@ -4324,7 +4364,7 @@ static int trace_panic_handler(struct notifier_block *this,
                               unsigned long event, void *unused)
 {
        if (ftrace_dump_on_oops)
-               ftrace_dump();
+               ftrace_dump(ftrace_dump_on_oops);
        return NOTIFY_OK;
 }
 
@@ -4341,7 +4381,7 @@ static int trace_die_handler(struct notifier_block *self,
        switch (val) {
        case DIE_OOPS:
                if (ftrace_dump_on_oops)
-                       ftrace_dump();
+                       ftrace_dump(ftrace_dump_on_oops);
                break;
        default:
                break;
@@ -4382,7 +4422,8 @@ trace_printk_seq(struct trace_seq *s)
        trace_seq_init(s);
 }
 
-static void __ftrace_dump(bool disable_tracing)
+static void
+__ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode)
 {
        static arch_spinlock_t ftrace_dump_lock =
                (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;
@@ -4415,12 +4456,25 @@ static void __ftrace_dump(bool disable_tracing)
        /* don't look at user memory in panic mode */
        trace_flags &= ~TRACE_ITER_SYM_USEROBJ;
 
-       printk(KERN_TRACE "Dumping ftrace buffer:\n");
-
        /* Simulate the iterator */
        iter.tr = &global_trace;
        iter.trace = current_trace;
-       iter.cpu_file = TRACE_PIPE_ALL_CPU;
+
+       switch (oops_dump_mode) {
+       case DUMP_ALL:
+               iter.cpu_file = TRACE_PIPE_ALL_CPU;
+               break;
+       case DUMP_ORIG:
+               iter.cpu_file = raw_smp_processor_id();
+               break;
+       case DUMP_NONE:
+               goto out_enable;
+       default:
+               printk(KERN_TRACE "Bad dumping mode, switching to all CPUs dump\n");
+               iter.cpu_file = TRACE_PIPE_ALL_CPU;
+       }
+
+       printk(KERN_TRACE "Dumping ftrace buffer:\n");
 
        /*
         * We need to stop all tracing on all CPUS to read the
@@ -4459,6 +4513,7 @@ static void __ftrace_dump(bool disable_tracing)
        else
                printk(KERN_TRACE "---------------------------------\n");
 
+ out_enable:
        /* Re-enable tracing if requested */
        if (!disable_tracing) {
                trace_flags |= old_userobj;
@@ -4475,9 +4530,9 @@ static void __ftrace_dump(bool disable_tracing)
 }
 
 /* By default: disable tracing after the dump */
-void ftrace_dump(void)
+void ftrace_dump(enum ftrace_dump_mode oops_dump_mode)
 {
-       __ftrace_dump(true);
+       __ftrace_dump(true, oops_dump_mode);
 }
 
 __init static int tracer_alloc_buffers(void)
index 2825ef2c0b155ae1968997e3efd5e4fd8fdd8570..d1ce0bec1b3fb625dc8bc9b50ba22bec891ec01f 100644 (file)
@@ -34,7 +34,6 @@ enum trace_type {
        TRACE_GRAPH_RET,
        TRACE_GRAPH_ENT,
        TRACE_USER_STACK,
-       TRACE_HW_BRANCHES,
        TRACE_KMEM_ALLOC,
        TRACE_KMEM_FREE,
        TRACE_BLK,
@@ -103,29 +102,17 @@ struct syscall_trace_exit {
        long                    ret;
 };
 
-struct kprobe_trace_entry {
+struct kprobe_trace_entry_head {
        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 kretprobe_trace_entry_head {
        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:
@@ -229,7 +216,6 @@ extern void __ftrace_bad_type(void);
                          TRACE_GRAPH_ENT);             \
                IF_ASSIGN(var, ent, struct ftrace_graph_ret_entry,      \
                          TRACE_GRAPH_RET);             \
-               IF_ASSIGN(var, ent, struct hw_branch_entry, TRACE_HW_BRANCHES);\
                IF_ASSIGN(var, ent, struct kmemtrace_alloc_entry,       \
                          TRACE_KMEM_ALLOC);    \
                IF_ASSIGN(var, ent, struct kmemtrace_free_entry,        \
@@ -378,6 +364,9 @@ void trace_function(struct trace_array *tr,
                    unsigned long ip,
                    unsigned long parent_ip,
                    unsigned long flags, int pc);
+void trace_default_header(struct seq_file *m);
+void print_trace_header(struct seq_file *m, struct trace_iterator *iter);
+int trace_empty(struct trace_iterator *iter);
 
 void trace_graph_return(struct ftrace_graph_ret *trace);
 int trace_graph_entry(struct ftrace_graph_ent *trace);
@@ -467,8 +456,6 @@ extern int trace_selftest_startup_sysprof(struct tracer *trace,
                                               struct trace_array *tr);
 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 */
@@ -491,9 +478,29 @@ extern int trace_clock_id;
 
 /* Standard output formatting function used for function return traces */
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
-extern enum print_line_t print_graph_function(struct trace_iterator *iter);
+
+/* Flag options */
+#define TRACE_GRAPH_PRINT_OVERRUN       0x1
+#define TRACE_GRAPH_PRINT_CPU           0x2
+#define TRACE_GRAPH_PRINT_OVERHEAD      0x4
+#define TRACE_GRAPH_PRINT_PROC          0x8
+#define TRACE_GRAPH_PRINT_DURATION      0x10
+#define TRACE_GRAPH_PRINT_ABS_TIME      0x20
+
+extern enum print_line_t
+print_graph_function_flags(struct trace_iterator *iter, u32 flags);
+extern void print_graph_headers_flags(struct seq_file *s, u32 flags);
 extern enum print_line_t
 trace_print_graph_duration(unsigned long long duration, struct trace_seq *s);
+extern void graph_trace_open(struct trace_iterator *iter);
+extern void graph_trace_close(struct trace_iterator *iter);
+extern int __trace_graph_entry(struct trace_array *tr,
+                              struct ftrace_graph_ent *trace,
+                              unsigned long flags, int pc);
+extern void __trace_graph_return(struct trace_array *tr,
+                                struct ftrace_graph_ret *trace,
+                                unsigned long flags, int pc);
+
 
 #ifdef CONFIG_DYNAMIC_FTRACE
 /* TODO: make this variable */
@@ -524,7 +531,7 @@ static inline int ftrace_graph_addr(unsigned long addr)
 #endif /* CONFIG_DYNAMIC_FTRACE */
 #else /* CONFIG_FUNCTION_GRAPH_TRACER */
 static inline enum print_line_t
-print_graph_function(struct trace_iterator *iter)
+print_graph_function_flags(struct trace_iterator *iter, u32 flags)
 {
        return TRACE_TYPE_UNHANDLED;
 }
index 6fbfb8f417b9cd9d60d72ff6b6a0c9c54c520ce1..9d589d8dcd1aa7e9470b6868980a20c4aeaf6160 100644 (file)
@@ -84,7 +84,7 @@ u64 notrace trace_clock_global(void)
        int this_cpu;
        u64 now;
 
-       raw_local_irq_save(flags);
+       local_irq_save(flags);
 
        this_cpu = raw_smp_processor_id();
        now = cpu_clock(this_cpu);
@@ -110,7 +110,7 @@ u64 notrace trace_clock_global(void)
        arch_spin_unlock(&trace_clock_struct.lock);
 
  out:
-       raw_local_irq_restore(flags);
+       local_irq_restore(flags);
 
        return now;
 }
index c16a08f399df53e9d9728d11e039f485b72e4986..dc008c1240da54ae8ebc6fcccb204ad205897e96 100644 (file)
@@ -318,18 +318,6 @@ FTRACE_ENTRY(branch, trace_branch,
                 __entry->func, __entry->file, __entry->correct)
 );
 
-FTRACE_ENTRY(hw_branch, hw_branch_entry,
-
-       TRACE_HW_BRANCHES,
-
-       F_STRUCT(
-               __field(        u64,    from    )
-               __field(        u64,    to      )
-       ),
-
-       F_printk("from: %llx to: %llx", __entry->from, __entry->to)
-);
-
 FTRACE_ENTRY(kmem_alloc, kmemtrace_alloc_entry,
 
        TRACE_KMEM_ALLOC,
similarity index 63%
rename from kernel/trace/trace_event_profile.c
rename to kernel/trace/trace_event_perf.c
index c1cc3ab633de6cab14b87463d4f70669feb8904b..0565bb42566f6982d6d197857e0b7e07511ab8a7 100644 (file)
@@ -1,32 +1,41 @@
 /*
- * trace event based perf counter profiling
+ * trace event based perf event profiling/tracing
  *
  * Copyright (C) 2009 Red Hat Inc, Peter Zijlstra <pzijlstr@redhat.com>
- *
+ * Copyright (C) 2009-2010 Frederic Weisbecker <fweisbec@gmail.com>
  */
 
 #include <linux/module.h>
 #include <linux/kprobes.h>
 #include "trace.h"
 
+DEFINE_PER_CPU(struct pt_regs, perf_trace_regs);
+EXPORT_PER_CPU_SYMBOL_GPL(perf_trace_regs);
+
+EXPORT_SYMBOL_GPL(perf_arch_fetch_caller_regs);
 
 static char *perf_trace_buf;
 static char *perf_trace_buf_nmi;
 
-typedef typeof(char [FTRACE_MAX_PROFILE_SIZE]) perf_trace_t ;
+/*
+ * Force it to be aligned to unsigned long to avoid misaligned accesses
+ * suprises
+ */
+typedef typeof(unsigned long [PERF_MAX_TRACE_SIZE / sizeof(unsigned long)])
+       perf_trace_t;
 
 /* Count the events in use (per event id, not per instance) */
-static int     total_profile_count;
+static int     total_ref_count;
 
-static int ftrace_profile_enable_event(struct ftrace_event_call *event)
+static int perf_trace_event_enable(struct ftrace_event_call *event)
 {
        char *buf;
        int ret = -ENOMEM;
 
-       if (event->profile_count++ > 0)
+       if (event->perf_refcount++ > 0)
                return 0;
 
-       if (!total_profile_count) {
+       if (!total_ref_count) {
                buf = (char *)alloc_percpu(perf_trace_t);
                if (!buf)
                        goto fail_buf;
@@ -40,35 +49,35 @@ static int ftrace_profile_enable_event(struct ftrace_event_call *event)
                rcu_assign_pointer(perf_trace_buf_nmi, buf);
        }
 
-       ret = event->profile_enable(event);
+       ret = event->perf_event_enable(event);
        if (!ret) {
-               total_profile_count++;
+               total_ref_count++;
                return 0;
        }
 
 fail_buf_nmi:
-       if (!total_profile_count) {
+       if (!total_ref_count) {
                free_percpu(perf_trace_buf_nmi);
                free_percpu(perf_trace_buf);
                perf_trace_buf_nmi = NULL;
                perf_trace_buf = NULL;
        }
 fail_buf:
-       event->profile_count--;
+       event->perf_refcount--;
 
        return ret;
 }
 
-int ftrace_profile_enable(int event_id)
+int perf_trace_enable(int event_id)
 {
        struct ftrace_event_call *event;
        int ret = -EINVAL;
 
        mutex_lock(&event_mutex);
        list_for_each_entry(event, &ftrace_events, list) {
-               if (event->id == event_id && event->profile_enable &&
+               if (event->id == event_id && event->perf_event_enable &&
                    try_module_get(event->mod)) {
-                       ret = ftrace_profile_enable_event(event);
+                       ret = perf_trace_event_enable(event);
                        break;
                }
        }
@@ -77,16 +86,16 @@ int ftrace_profile_enable(int event_id)
        return ret;
 }
 
-static void ftrace_profile_disable_event(struct ftrace_event_call *event)
+static void perf_trace_event_disable(struct ftrace_event_call *event)
 {
        char *buf, *nmi_buf;
 
-       if (--event->profile_count > 0)
+       if (--event->perf_refcount > 0)
                return;
 
-       event->profile_disable(event);
+       event->perf_event_disable(event);
 
-       if (!--total_profile_count) {
+       if (!--total_ref_count) {
                buf = perf_trace_buf;
                rcu_assign_pointer(perf_trace_buf, NULL);
 
@@ -104,14 +113,14 @@ static void ftrace_profile_disable_event(struct ftrace_event_call *event)
        }
 }
 
-void ftrace_profile_disable(int event_id)
+void perf_trace_disable(int event_id)
 {
        struct ftrace_event_call *event;
 
        mutex_lock(&event_mutex);
        list_for_each_entry(event, &ftrace_events, list) {
                if (event->id == event_id) {
-                       ftrace_profile_disable_event(event);
+                       perf_trace_event_disable(event);
                        module_put(event->mod);
                        break;
                }
@@ -119,13 +128,15 @@ void ftrace_profile_disable(int event_id)
        mutex_unlock(&event_mutex);
 }
 
-__kprobes void *ftrace_perf_buf_prepare(int size, unsigned short type,
-                                       int *rctxp, unsigned long *irq_flags)
+__kprobes void *perf_trace_buf_prepare(int size, unsigned short type,
+                                      int *rctxp, unsigned long *irq_flags)
 {
        struct trace_entry *entry;
        char *trace_buf, *raw_data;
        int pc, cpu;
 
+       BUILD_BUG_ON(PERF_MAX_TRACE_SIZE % sizeof(unsigned long));
+
        pc = preempt_count();
 
        /* Protect the per cpu buffer, begin the rcu read side */
@@ -148,7 +159,7 @@ __kprobes void *ftrace_perf_buf_prepare(int size, unsigned short type,
        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;
+       memset(&raw_data[size - sizeof(u64)], 0, sizeof(u64));
 
        entry = (struct trace_entry *)raw_data;
        tracing_generic_entry_update(entry, *irq_flags, pc);
@@ -161,4 +172,4 @@ err_recursion:
        local_irq_restore(*irq_flags);
        return NULL;
 }
-EXPORT_SYMBOL_GPL(ftrace_perf_buf_prepare);
+EXPORT_SYMBOL_GPL(perf_trace_buf_prepare);
index 3f972ad98d04f48926edaf6953ea74d22bd32eab..c697c70433494d6e41e51656a767c9f575cdccba 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/uaccess.h>
 #include <linux/module.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 
 #include <asm/setup.h>
@@ -938,7 +939,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
                trace_create_file("enable", 0644, call->dir, call,
                                  enable);
 
-       if (call->id && call->profile_enable)
+       if (call->id && call->perf_event_enable)
                trace_create_file("id", 0444, call->dir, call,
                                  id);
 
index 4615f62a04f185bf5d38b89162ca223884954385..58092d844a1fce94b36ecb3763ccfc0fded5d1a4 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/ctype.h>
 #include <linux/mutex.h>
 #include <linux/perf_event.h>
+#include <linux/slab.h>
 
 #include "trace.h"
 #include "trace_output.h"
@@ -1397,7 +1398,7 @@ int ftrace_profile_set_filter(struct perf_event *event, int event_id,
        }
 
        err = -EINVAL;
-       if (!call)
+       if (&call->list == &ftrace_events)
                goto out_unlock;
 
        err = -EEXIST;
index e6989d9b44dae8a23a60bcdb669f226329ef1025..dd11c830eb84f06419c08fff07f4b7252c197eb9 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
 #include <linux/ftrace.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 
 #include "trace.h"
@@ -39,7 +40,7 @@ struct fgraph_data {
 #define TRACE_GRAPH_PRINT_OVERHEAD     0x4
 #define TRACE_GRAPH_PRINT_PROC         0x8
 #define TRACE_GRAPH_PRINT_DURATION     0x10
-#define TRACE_GRAPH_PRINT_ABS_TIME     0X20
+#define TRACE_GRAPH_PRINT_ABS_TIME     0x20
 
 static struct tracer_opt trace_opts[] = {
        /* Display overruns? (for self-debug purpose) */
@@ -178,7 +179,7 @@ unsigned long ftrace_return_to_handler(unsigned long frame_pointer)
        return ret;
 }
 
-static int __trace_graph_entry(struct trace_array *tr,
+int __trace_graph_entry(struct trace_array *tr,
                                struct ftrace_graph_ent *trace,
                                unsigned long flags,
                                int pc)
@@ -245,7 +246,7 @@ int trace_graph_thresh_entry(struct ftrace_graph_ent *trace)
                return trace_graph_entry(trace);
 }
 
-static void __trace_graph_return(struct trace_array *tr,
+void __trace_graph_return(struct trace_array *tr,
                                struct ftrace_graph_ret *trace,
                                unsigned long flags,
                                int pc)
@@ -489,9 +490,10 @@ get_return_for_leaf(struct trace_iterator *iter,
                         * We need to consume the current entry to see
                         * the next one.
                         */
-                       ring_buffer_consume(iter->tr->buffer, iter->cpu, NULL);
+                       ring_buffer_consume(iter->tr->buffer, iter->cpu,
+                                           NULL, NULL);
                        event = ring_buffer_peek(iter->tr->buffer, iter->cpu,
-                                                NULL);
+                                                NULL, NULL);
                }
 
                if (!event)
@@ -525,17 +527,18 @@ get_return_for_leaf(struct trace_iterator *iter,
 
 /* Signal a overhead of time execution to the output */
 static int
-print_graph_overhead(unsigned long long duration, struct trace_seq *s)
+print_graph_overhead(unsigned long long duration, struct trace_seq *s,
+                    u32 flags)
 {
        /* If duration disappear, we don't need anything */
-       if (!(tracer_flags.val & TRACE_GRAPH_PRINT_DURATION))
+       if (!(flags & TRACE_GRAPH_PRINT_DURATION))
                return 1;
 
        /* Non nested entry or return */
        if (duration == -1)
                return trace_seq_printf(s, "  ");
 
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
+       if (flags & TRACE_GRAPH_PRINT_OVERHEAD) {
                /* Duration exceeded 100 msecs */
                if (duration > 100000ULL)
                        return trace_seq_printf(s, "! ");
@@ -561,7 +564,7 @@ static int print_graph_abs_time(u64 t, struct trace_seq *s)
 
 static enum print_line_t
 print_graph_irq(struct trace_iterator *iter, unsigned long addr,
-               enum trace_type type, int cpu, pid_t pid)
+               enum trace_type type, int cpu, pid_t pid, u32 flags)
 {
        int ret;
        struct trace_seq *s = &iter->seq;
@@ -571,21 +574,21 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
                return TRACE_TYPE_UNHANDLED;
 
        /* Absolute time */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) {
+       if (flags & TRACE_GRAPH_PRINT_ABS_TIME) {
                ret = print_graph_abs_time(iter->ts, s);
                if (!ret)
                        return TRACE_TYPE_PARTIAL_LINE;
        }
 
        /* Cpu */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
+       if (flags & TRACE_GRAPH_PRINT_CPU) {
                ret = print_graph_cpu(s, cpu);
                if (ret == TRACE_TYPE_PARTIAL_LINE)
                        return TRACE_TYPE_PARTIAL_LINE;
        }
 
        /* Proc */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
+       if (flags & TRACE_GRAPH_PRINT_PROC) {
                ret = print_graph_proc(s, pid);
                if (ret == TRACE_TYPE_PARTIAL_LINE)
                        return TRACE_TYPE_PARTIAL_LINE;
@@ -595,7 +598,7 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
        }
 
        /* No overhead */
-       ret = print_graph_overhead(-1, s);
+       ret = print_graph_overhead(-1, s, flags);
        if (!ret)
                return TRACE_TYPE_PARTIAL_LINE;
 
@@ -608,7 +611,7 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
                return TRACE_TYPE_PARTIAL_LINE;
 
        /* Don't close the duration column if haven't one */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
+       if (flags & TRACE_GRAPH_PRINT_DURATION)
                trace_seq_printf(s, " |");
        ret = trace_seq_printf(s, "\n");
 
@@ -678,7 +681,8 @@ print_graph_duration(unsigned long long duration, struct trace_seq *s)
 static enum print_line_t
 print_graph_entry_leaf(struct trace_iterator *iter,
                struct ftrace_graph_ent_entry *entry,
-               struct ftrace_graph_ret_entry *ret_entry, struct trace_seq *s)
+               struct ftrace_graph_ret_entry *ret_entry,
+               struct trace_seq *s, u32 flags)
 {
        struct fgraph_data *data = iter->private;
        struct ftrace_graph_ret *graph_ret;
@@ -710,12 +714,12 @@ print_graph_entry_leaf(struct trace_iterator *iter,
        }
 
        /* Overhead */
-       ret = print_graph_overhead(duration, s);
+       ret = print_graph_overhead(duration, s, flags);
        if (!ret)
                return TRACE_TYPE_PARTIAL_LINE;
 
        /* Duration */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
+       if (flags & TRACE_GRAPH_PRINT_DURATION) {
                ret = print_graph_duration(duration, s);
                if (ret == TRACE_TYPE_PARTIAL_LINE)
                        return TRACE_TYPE_PARTIAL_LINE;
@@ -738,7 +742,7 @@ print_graph_entry_leaf(struct trace_iterator *iter,
 static enum print_line_t
 print_graph_entry_nested(struct trace_iterator *iter,
                         struct ftrace_graph_ent_entry *entry,
-                        struct trace_seq *s, int cpu)
+                        struct trace_seq *s, int cpu, u32 flags)
 {
        struct ftrace_graph_ent *call = &entry->graph_ent;
        struct fgraph_data *data = iter->private;
@@ -758,12 +762,12 @@ print_graph_entry_nested(struct trace_iterator *iter,
        }
 
        /* No overhead */
-       ret = print_graph_overhead(-1, s);
+       ret = print_graph_overhead(-1, s, flags);
        if (!ret)
                return TRACE_TYPE_PARTIAL_LINE;
 
        /* No time */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
+       if (flags & TRACE_GRAPH_PRINT_DURATION) {
                ret = trace_seq_printf(s, "            |  ");
                if (!ret)
                        return TRACE_TYPE_PARTIAL_LINE;
@@ -789,7 +793,7 @@ print_graph_entry_nested(struct trace_iterator *iter,
 
 static enum print_line_t
 print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
-                    int type, unsigned long addr)
+                    int type, unsigned long addr, u32 flags)
 {
        struct fgraph_data *data = iter->private;
        struct trace_entry *ent = iter->ent;
@@ -802,27 +806,27 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
 
        if (type) {
                /* Interrupt */
-               ret = print_graph_irq(iter, addr, type, cpu, ent->pid);
+               ret = print_graph_irq(iter, addr, type, cpu, ent->pid, flags);
                if (ret == TRACE_TYPE_PARTIAL_LINE)
                        return TRACE_TYPE_PARTIAL_LINE;
        }
 
        /* Absolute time */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) {
+       if (flags & TRACE_GRAPH_PRINT_ABS_TIME) {
                ret = print_graph_abs_time(iter->ts, s);
                if (!ret)
                        return TRACE_TYPE_PARTIAL_LINE;
        }
 
        /* Cpu */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
+       if (flags & TRACE_GRAPH_PRINT_CPU) {
                ret = print_graph_cpu(s, cpu);
                if (ret == TRACE_TYPE_PARTIAL_LINE)
                        return TRACE_TYPE_PARTIAL_LINE;
        }
 
        /* Proc */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
+       if (flags & TRACE_GRAPH_PRINT_PROC) {
                ret = print_graph_proc(s, ent->pid);
                if (ret == TRACE_TYPE_PARTIAL_LINE)
                        return TRACE_TYPE_PARTIAL_LINE;
@@ -844,7 +848,7 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
 
 static enum print_line_t
 print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
-                       struct trace_iterator *iter)
+                       struct trace_iterator *iter, u32 flags)
 {
        struct fgraph_data *data = iter->private;
        struct ftrace_graph_ent *call = &field->graph_ent;
@@ -852,14 +856,14 @@ print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
        static enum print_line_t ret;
        int cpu = iter->cpu;
 
-       if (print_graph_prologue(iter, s, TRACE_GRAPH_ENT, call->func))
+       if (print_graph_prologue(iter, s, TRACE_GRAPH_ENT, call->func, flags))
                return TRACE_TYPE_PARTIAL_LINE;
 
        leaf_ret = get_return_for_leaf(iter, field);
        if (leaf_ret)
-               ret = print_graph_entry_leaf(iter, field, leaf_ret, s);
+               ret = print_graph_entry_leaf(iter, field, leaf_ret, s, flags);
        else
-               ret = print_graph_entry_nested(iter, field, s, cpu);
+               ret = print_graph_entry_nested(iter, field, s, cpu, flags);
 
        if (data) {
                /*
@@ -878,7 +882,8 @@ print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
 
 static enum print_line_t
 print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
-                  struct trace_entry *ent, struct trace_iterator *iter)
+                  struct trace_entry *ent, struct trace_iterator *iter,
+                  u32 flags)
 {
        unsigned long long duration = trace->rettime - trace->calltime;
        struct fgraph_data *data = iter->private;
@@ -908,16 +913,16 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
                }
        }
 
-       if (print_graph_prologue(iter, s, 0, 0))
+       if (print_graph_prologue(iter, s, 0, 0, flags))
                return TRACE_TYPE_PARTIAL_LINE;
 
        /* Overhead */
-       ret = print_graph_overhead(duration, s);
+       ret = print_graph_overhead(duration, s, flags);
        if (!ret)
                return TRACE_TYPE_PARTIAL_LINE;
 
        /* Duration */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
+       if (flags & TRACE_GRAPH_PRINT_DURATION) {
                ret = print_graph_duration(duration, s);
                if (ret == TRACE_TYPE_PARTIAL_LINE)
                        return TRACE_TYPE_PARTIAL_LINE;
@@ -947,14 +952,15 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
        }
 
        /* Overrun */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERRUN) {
+       if (flags & TRACE_GRAPH_PRINT_OVERRUN) {
                ret = trace_seq_printf(s, " (Overruns: %lu)\n",
                                        trace->overrun);
                if (!ret)
                        return TRACE_TYPE_PARTIAL_LINE;
        }
 
-       ret = print_graph_irq(iter, trace->func, TRACE_GRAPH_RET, cpu, pid);
+       ret = print_graph_irq(iter, trace->func, TRACE_GRAPH_RET,
+                             cpu, pid, flags);
        if (ret == TRACE_TYPE_PARTIAL_LINE)
                return TRACE_TYPE_PARTIAL_LINE;
 
@@ -962,8 +968,8 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
 }
 
 static enum print_line_t
-print_graph_comment(struct trace_seq *s,  struct trace_entry *ent,
-                   struct trace_iterator *iter)
+print_graph_comment(struct trace_seq *s, struct trace_entry *ent,
+                   struct trace_iterator *iter, u32 flags)
 {
        unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
        struct fgraph_data *data = iter->private;
@@ -975,16 +981,16 @@ print_graph_comment(struct trace_seq *s,  struct trace_entry *ent,
        if (data)
                depth = per_cpu_ptr(data->cpu_data, iter->cpu)->depth;
 
-       if (print_graph_prologue(iter, s, 0, 0))
+       if (print_graph_prologue(iter, s, 0, 0, flags))
                return TRACE_TYPE_PARTIAL_LINE;
 
        /* No overhead */
-       ret = print_graph_overhead(-1, s);
+       ret = print_graph_overhead(-1, s, flags);
        if (!ret)
                return TRACE_TYPE_PARTIAL_LINE;
 
        /* No time */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
+       if (flags & TRACE_GRAPH_PRINT_DURATION) {
                ret = trace_seq_printf(s, "            |  ");
                if (!ret)
                        return TRACE_TYPE_PARTIAL_LINE;
@@ -1039,7 +1045,7 @@ print_graph_comment(struct trace_seq *s,  struct trace_entry *ent,
 
 
 enum print_line_t
-print_graph_function(struct trace_iterator *iter)
+print_graph_function_flags(struct trace_iterator *iter, u32 flags)
 {
        struct ftrace_graph_ent_entry *field;
        struct fgraph_data *data = iter->private;
@@ -1060,7 +1066,7 @@ print_graph_function(struct trace_iterator *iter)
        if (data && data->failed) {
                field = &data->ent;
                iter->cpu = data->cpu;
-               ret = print_graph_entry(field, s, iter);
+               ret = print_graph_entry(field, s, iter, flags);
                if (ret == TRACE_TYPE_HANDLED && iter->cpu != cpu) {
                        per_cpu_ptr(data->cpu_data, iter->cpu)->ignore = 1;
                        ret = TRACE_TYPE_NO_CONSUME;
@@ -1080,32 +1086,49 @@ print_graph_function(struct trace_iterator *iter)
                struct ftrace_graph_ent_entry saved;
                trace_assign_type(field, entry);
                saved = *field;
-               return print_graph_entry(&saved, s, iter);
+               return print_graph_entry(&saved, s, iter, flags);
        }
        case TRACE_GRAPH_RET: {
                struct ftrace_graph_ret_entry *field;
                trace_assign_type(field, entry);
-               return print_graph_return(&field->ret, s, entry, iter);
+               return print_graph_return(&field->ret, s, entry, iter, flags);
        }
+       case TRACE_STACK:
+       case TRACE_FN:
+               /* dont trace stack and functions as comments */
+               return TRACE_TYPE_UNHANDLED;
+
        default:
-               return print_graph_comment(s, entry, iter);
+               return print_graph_comment(s, entry, iter, flags);
        }
 
        return TRACE_TYPE_HANDLED;
 }
 
-static void print_lat_header(struct seq_file *s)
+static enum print_line_t
+print_graph_function(struct trace_iterator *iter)
+{
+       return print_graph_function_flags(iter, tracer_flags.val);
+}
+
+static enum print_line_t
+print_graph_function_event(struct trace_iterator *iter, int flags)
+{
+       return print_graph_function(iter);
+}
+
+static void print_lat_header(struct seq_file *s, u32 flags)
 {
        static const char spaces[] = "                " /* 16 spaces */
                "    "                                  /* 4 spaces */
                "                 ";                    /* 17 spaces */
        int size = 0;
 
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
+       if (flags & TRACE_GRAPH_PRINT_ABS_TIME)
                size += 16;
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
+       if (flags & TRACE_GRAPH_PRINT_CPU)
                size += 4;
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
+       if (flags & TRACE_GRAPH_PRINT_PROC)
                size += 17;
 
        seq_printf(s, "#%.*s  _-----=> irqs-off        \n", size, spaces);
@@ -1116,43 +1139,48 @@ static void print_lat_header(struct seq_file *s)
        seq_printf(s, "#%.*s|||| /                     \n", size, spaces);
 }
 
-static void print_graph_headers(struct seq_file *s)
+void print_graph_headers_flags(struct seq_file *s, u32 flags)
 {
        int lat = trace_flags & TRACE_ITER_LATENCY_FMT;
 
        if (lat)
-               print_lat_header(s);
+               print_lat_header(s, flags);
 
        /* 1st line */
        seq_printf(s, "#");
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
+       if (flags & TRACE_GRAPH_PRINT_ABS_TIME)
                seq_printf(s, "     TIME       ");
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
+       if (flags & TRACE_GRAPH_PRINT_CPU)
                seq_printf(s, " CPU");
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
+       if (flags & TRACE_GRAPH_PRINT_PROC)
                seq_printf(s, "  TASK/PID       ");
        if (lat)
                seq_printf(s, "|||||");
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
+       if (flags & TRACE_GRAPH_PRINT_DURATION)
                seq_printf(s, "  DURATION   ");
        seq_printf(s, "               FUNCTION CALLS\n");
 
        /* 2nd line */
        seq_printf(s, "#");
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
+       if (flags & TRACE_GRAPH_PRINT_ABS_TIME)
                seq_printf(s, "      |         ");
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
+       if (flags & TRACE_GRAPH_PRINT_CPU)
                seq_printf(s, " |  ");
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
+       if (flags & TRACE_GRAPH_PRINT_PROC)
                seq_printf(s, "   |    |        ");
        if (lat)
                seq_printf(s, "|||||");
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
+       if (flags & TRACE_GRAPH_PRINT_DURATION)
                seq_printf(s, "   |   |      ");
        seq_printf(s, "               |   |   |   |\n");
 }
 
-static void graph_trace_open(struct trace_iterator *iter)
+void print_graph_headers(struct seq_file *s)
+{
+       print_graph_headers_flags(s, tracer_flags.val);
+}
+
+void graph_trace_open(struct trace_iterator *iter)
 {
        /* pid and depth on the last trace processed */
        struct fgraph_data *data;
@@ -1187,7 +1215,7 @@ static void graph_trace_open(struct trace_iterator *iter)
        pr_warning("function graph tracer: not enough memory\n");
 }
 
-static void graph_trace_close(struct trace_iterator *iter)
+void graph_trace_close(struct trace_iterator *iter)
 {
        struct fgraph_data *data = iter->private;
 
@@ -1197,6 +1225,16 @@ static void graph_trace_close(struct trace_iterator *iter)
        }
 }
 
+static struct trace_event graph_trace_entry_event = {
+       .type           = TRACE_GRAPH_ENT,
+       .trace          = print_graph_function_event,
+};
+
+static struct trace_event graph_trace_ret_event = {
+       .type           = TRACE_GRAPH_RET,
+       .trace          = print_graph_function_event,
+};
+
 static struct tracer graph_trace __read_mostly = {
        .name           = "function_graph",
        .open           = graph_trace_open,
@@ -1218,6 +1256,16 @@ static __init int init_graph_trace(void)
 {
        max_bytes_for_cpu = snprintf(NULL, 0, "%d", nr_cpu_ids - 1);
 
+       if (!register_ftrace_event(&graph_trace_entry_event)) {
+               pr_warning("Warning: could not register graph trace events\n");
+               return 1;
+       }
+
+       if (!register_ftrace_event(&graph_trace_ret_event)) {
+               pr_warning("Warning: could not register graph trace events\n");
+               return 1;
+       }
+
        return register_tracer(&graph_trace);
 }
 
diff --git a/kernel/trace/trace_hw_branches.c b/kernel/trace/trace_hw_branches.c
deleted file mode 100644 (file)
index 7b97000..0000000
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * h/w branch tracer for x86 based on BTS
- *
- * Copyright (C) 2008-2009 Intel Corporation.
- * Markus Metzger <markus.t.metzger@gmail.com>, 2008-2009
- */
-#include <linux/kallsyms.h>
-#include <linux/debugfs.h>
-#include <linux/ftrace.h>
-#include <linux/module.h>
-#include <linux/cpu.h>
-#include <linux/smp.h>
-#include <linux/fs.h>
-
-#include <asm/ds.h>
-
-#include "trace_output.h"
-#include "trace.h"
-
-
-#define BTS_BUFFER_SIZE (1 << 13)
-
-static DEFINE_PER_CPU(struct bts_tracer *, hwb_tracer);
-static DEFINE_PER_CPU(unsigned char[BTS_BUFFER_SIZE], hwb_buffer);
-
-#define this_tracer per_cpu(hwb_tracer, smp_processor_id())
-
-static int trace_hw_branches_enabled __read_mostly;
-static int trace_hw_branches_suspended __read_mostly;
-static struct trace_array *hw_branch_trace __read_mostly;
-
-
-static void bts_trace_init_cpu(int cpu)
-{
-       per_cpu(hwb_tracer, cpu) =
-               ds_request_bts_cpu(cpu, per_cpu(hwb_buffer, cpu),
-                                  BTS_BUFFER_SIZE, NULL, (size_t)-1,
-                                  BTS_KERNEL);
-
-       if (IS_ERR(per_cpu(hwb_tracer, cpu)))
-               per_cpu(hwb_tracer, cpu) = NULL;
-}
-
-static int bts_trace_init(struct trace_array *tr)
-{
-       int cpu;
-
-       hw_branch_trace = tr;
-       trace_hw_branches_enabled = 0;
-
-       get_online_cpus();
-       for_each_online_cpu(cpu) {
-               bts_trace_init_cpu(cpu);
-
-               if (likely(per_cpu(hwb_tracer, cpu)))
-                       trace_hw_branches_enabled = 1;
-       }
-       trace_hw_branches_suspended = 0;
-       put_online_cpus();
-
-       /* If we could not enable tracing on a single cpu, we fail. */
-       return trace_hw_branches_enabled ? 0 : -EOPNOTSUPP;
-}
-
-static void bts_trace_reset(struct trace_array *tr)
-{
-       int cpu;
-
-       get_online_cpus();
-       for_each_online_cpu(cpu) {
-               if (likely(per_cpu(hwb_tracer, cpu))) {
-                       ds_release_bts(per_cpu(hwb_tracer, cpu));
-                       per_cpu(hwb_tracer, cpu) = NULL;
-               }
-       }
-       trace_hw_branches_enabled = 0;
-       trace_hw_branches_suspended = 0;
-       put_online_cpus();
-}
-
-static void bts_trace_start(struct trace_array *tr)
-{
-       int cpu;
-
-       get_online_cpus();
-       for_each_online_cpu(cpu)
-               if (likely(per_cpu(hwb_tracer, cpu)))
-                       ds_resume_bts(per_cpu(hwb_tracer, cpu));
-       trace_hw_branches_suspended = 0;
-       put_online_cpus();
-}
-
-static void bts_trace_stop(struct trace_array *tr)
-{
-       int cpu;
-
-       get_online_cpus();
-       for_each_online_cpu(cpu)
-               if (likely(per_cpu(hwb_tracer, cpu)))
-                       ds_suspend_bts(per_cpu(hwb_tracer, cpu));
-       trace_hw_branches_suspended = 1;
-       put_online_cpus();
-}
-
-static int __cpuinit bts_hotcpu_handler(struct notifier_block *nfb,
-                                    unsigned long action, void *hcpu)
-{
-       int cpu = (long)hcpu;
-
-       switch (action) {
-       case CPU_ONLINE:
-       case CPU_DOWN_FAILED:
-               /* The notification is sent with interrupts enabled. */
-               if (trace_hw_branches_enabled) {
-                       bts_trace_init_cpu(cpu);
-
-                       if (trace_hw_branches_suspended &&
-                           likely(per_cpu(hwb_tracer, cpu)))
-                               ds_suspend_bts(per_cpu(hwb_tracer, cpu));
-               }
-               break;
-
-       case CPU_DOWN_PREPARE:
-               /* The notification is sent with interrupts enabled. */
-               if (likely(per_cpu(hwb_tracer, cpu))) {
-                       ds_release_bts(per_cpu(hwb_tracer, cpu));
-                       per_cpu(hwb_tracer, cpu) = NULL;
-               }
-       }
-
-       return NOTIFY_DONE;
-}
-
-static struct notifier_block bts_hotcpu_notifier __cpuinitdata = {
-       .notifier_call = bts_hotcpu_handler
-};
-
-static void bts_trace_print_header(struct seq_file *m)
-{
-       seq_puts(m, "# CPU#        TO  <-  FROM\n");
-}
-
-static enum print_line_t bts_trace_print_line(struct trace_iterator *iter)
-{
-       unsigned long symflags = TRACE_ITER_SYM_OFFSET;
-       struct trace_entry *entry = iter->ent;
-       struct trace_seq *seq = &iter->seq;
-       struct hw_branch_entry *it;
-
-       trace_assign_type(it, entry);
-
-       if (entry->type == TRACE_HW_BRANCHES) {
-               if (trace_seq_printf(seq, "%4d  ", iter->cpu) &&
-                   seq_print_ip_sym(seq, it->to, symflags) &&
-                   trace_seq_printf(seq, "\t  <-  ") &&
-                   seq_print_ip_sym(seq, it->from, symflags) &&
-                   trace_seq_printf(seq, "\n"))
-                       return TRACE_TYPE_HANDLED;
-               return TRACE_TYPE_PARTIAL_LINE;
-       }
-       return TRACE_TYPE_UNHANDLED;
-}
-
-void trace_hw_branch(u64 from, u64 to)
-{
-       struct ftrace_event_call *call = &event_hw_branch;
-       struct trace_array *tr = hw_branch_trace;
-       struct ring_buffer_event *event;
-       struct ring_buffer *buf;
-       struct hw_branch_entry *entry;
-       unsigned long irq1;
-       int cpu;
-
-       if (unlikely(!tr))
-               return;
-
-       if (unlikely(!trace_hw_branches_enabled))
-               return;
-
-       local_irq_save(irq1);
-       cpu = raw_smp_processor_id();
-       if (atomic_inc_return(&tr->data[cpu]->disabled) != 1)
-               goto out;
-
-       buf = tr->buffer;
-       event = trace_buffer_lock_reserve(buf, TRACE_HW_BRANCHES,
-                                         sizeof(*entry), 0, 0);
-       if (!event)
-               goto out;
-       entry   = ring_buffer_event_data(event);
-       tracing_generic_entry_update(&entry->ent, 0, from);
-       entry->ent.type = TRACE_HW_BRANCHES;
-       entry->from = from;
-       entry->to   = to;
-       if (!filter_check_discard(call, entry, buf, event))
-               trace_buffer_unlock_commit(buf, event, 0, 0);
-
- out:
-       atomic_dec(&tr->data[cpu]->disabled);
-       local_irq_restore(irq1);
-}
-
-static void trace_bts_at(const struct bts_trace *trace, void *at)
-{
-       struct bts_struct bts;
-       int err = 0;
-
-       WARN_ON_ONCE(!trace->read);
-       if (!trace->read)
-               return;
-
-       err = trace->read(this_tracer, at, &bts);
-       if (err < 0)
-               return;
-
-       switch (bts.qualifier) {
-       case BTS_BRANCH:
-               trace_hw_branch(bts.variant.lbr.from, bts.variant.lbr.to);
-               break;
-       }
-}
-
-/*
- * Collect the trace on the current cpu and write it into the ftrace buffer.
- *
- * pre: tracing must be suspended on the current cpu
- */
-static void trace_bts_cpu(void *arg)
-{
-       struct trace_array *tr = (struct trace_array *)arg;
-       const struct bts_trace *trace;
-       unsigned char *at;
-
-       if (unlikely(!tr))
-               return;
-
-       if (unlikely(atomic_read(&tr->data[raw_smp_processor_id()]->disabled)))
-               return;
-
-       if (unlikely(!this_tracer))
-               return;
-
-       trace = ds_read_bts(this_tracer);
-       if (!trace)
-               return;
-
-       for (at = trace->ds.top; (void *)at < trace->ds.end;
-            at += trace->ds.size)
-               trace_bts_at(trace, at);
-
-       for (at = trace->ds.begin; (void *)at < trace->ds.top;
-            at += trace->ds.size)
-               trace_bts_at(trace, at);
-}
-
-static void trace_bts_prepare(struct trace_iterator *iter)
-{
-       int cpu;
-
-       get_online_cpus();
-       for_each_online_cpu(cpu)
-               if (likely(per_cpu(hwb_tracer, cpu)))
-                       ds_suspend_bts(per_cpu(hwb_tracer, cpu));
-       /*
-        * We need to collect the trace on the respective cpu since ftrace
-        * implicitly adds the record for the current cpu.
-        * Once that is more flexible, we could collect the data from any cpu.
-        */
-       on_each_cpu(trace_bts_cpu, iter->tr, 1);
-
-       for_each_online_cpu(cpu)
-               if (likely(per_cpu(hwb_tracer, cpu)))
-                       ds_resume_bts(per_cpu(hwb_tracer, cpu));
-       put_online_cpus();
-}
-
-static void trace_bts_close(struct trace_iterator *iter)
-{
-       tracing_reset_online_cpus(iter->tr);
-}
-
-void trace_hw_branch_oops(void)
-{
-       if (this_tracer) {
-               ds_suspend_bts_noirq(this_tracer);
-               trace_bts_cpu(hw_branch_trace);
-               ds_resume_bts_noirq(this_tracer);
-       }
-}
-
-struct tracer bts_tracer __read_mostly =
-{
-       .name           = "hw-branch-tracer",
-       .init           = bts_trace_init,
-       .reset          = bts_trace_reset,
-       .print_header   = bts_trace_print_header,
-       .print_line     = bts_trace_print_line,
-       .start          = bts_trace_start,
-       .stop           = bts_trace_stop,
-       .open           = trace_bts_prepare,
-       .close          = trace_bts_close,
-#ifdef CONFIG_FTRACE_SELFTEST
-       .selftest       = trace_selftest_startup_hw_branches,
-#endif /* CONFIG_FTRACE_SELFTEST */
-};
-
-__init static int init_bts_trace(void)
-{
-       register_hotcpu_notifier(&bts_hotcpu_notifier);
-       return register_tracer(&bts_tracer);
-}
-device_initcall(init_bts_trace);
index 2974bc7538c74603b15f85b75a62f74e70f7bb4d..6fd486e0cef407b1cf3c416d15c31be14bf8dd6a 100644 (file)
@@ -34,6 +34,9 @@ static int trace_type __read_mostly;
 
 static int save_lat_flag;
 
+static void stop_irqsoff_tracer(struct trace_array *tr, int graph);
+static int start_irqsoff_tracer(struct trace_array *tr, int graph);
+
 #ifdef CONFIG_PREEMPT_TRACER
 static inline int
 preempt_trace(void)
@@ -55,6 +58,23 @@ irq_trace(void)
 # define irq_trace() (0)
 #endif
 
+#define TRACE_DISPLAY_GRAPH    1
+
+static struct tracer_opt trace_opts[] = {
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       /* display latency trace as call graph */
+       { TRACER_OPT(display-graph, TRACE_DISPLAY_GRAPH) },
+#endif
+       { } /* Empty entry */
+};
+
+static struct tracer_flags tracer_flags = {
+       .val  = 0,
+       .opts = trace_opts,
+};
+
+#define is_graph() (tracer_flags.val & TRACE_DISPLAY_GRAPH)
+
 /*
  * Sequence count - we record it when starting a measurement and
  * skip the latency if the sequence has changed - some other section
@@ -108,6 +128,202 @@ static struct ftrace_ops trace_ops __read_mostly =
 };
 #endif /* CONFIG_FUNCTION_TRACER */
 
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+static int irqsoff_set_flag(u32 old_flags, u32 bit, int set)
+{
+       int cpu;
+
+       if (!(bit & TRACE_DISPLAY_GRAPH))
+               return -EINVAL;
+
+       if (!(is_graph() ^ set))
+               return 0;
+
+       stop_irqsoff_tracer(irqsoff_trace, !set);
+
+       for_each_possible_cpu(cpu)
+               per_cpu(tracing_cpu, cpu) = 0;
+
+       tracing_max_latency = 0;
+       tracing_reset_online_cpus(irqsoff_trace);
+
+       return start_irqsoff_tracer(irqsoff_trace, set);
+}
+
+static int irqsoff_graph_entry(struct ftrace_graph_ent *trace)
+{
+       struct trace_array *tr = irqsoff_trace;
+       struct trace_array_cpu *data;
+       unsigned long flags;
+       long disabled;
+       int ret;
+       int cpu;
+       int pc;
+
+       cpu = raw_smp_processor_id();
+       if (likely(!per_cpu(tracing_cpu, cpu)))
+               return 0;
+
+       local_save_flags(flags);
+       /* slight chance to get a false positive on tracing_cpu */
+       if (!irqs_disabled_flags(flags))
+               return 0;
+
+       data = tr->data[cpu];
+       disabled = atomic_inc_return(&data->disabled);
+
+       if (likely(disabled == 1)) {
+               pc = preempt_count();
+               ret = __trace_graph_entry(tr, trace, flags, pc);
+       } else
+               ret = 0;
+
+       atomic_dec(&data->disabled);
+       return ret;
+}
+
+static void irqsoff_graph_return(struct ftrace_graph_ret *trace)
+{
+       struct trace_array *tr = irqsoff_trace;
+       struct trace_array_cpu *data;
+       unsigned long flags;
+       long disabled;
+       int cpu;
+       int pc;
+
+       cpu = raw_smp_processor_id();
+       if (likely(!per_cpu(tracing_cpu, cpu)))
+               return;
+
+       local_save_flags(flags);
+       /* slight chance to get a false positive on tracing_cpu */
+       if (!irqs_disabled_flags(flags))
+               return;
+
+       data = tr->data[cpu];
+       disabled = atomic_inc_return(&data->disabled);
+
+       if (likely(disabled == 1)) {
+               pc = preempt_count();
+               __trace_graph_return(tr, trace, flags, pc);
+       }
+
+       atomic_dec(&data->disabled);
+}
+
+static void irqsoff_trace_open(struct trace_iterator *iter)
+{
+       if (is_graph())
+               graph_trace_open(iter);
+
+}
+
+static void irqsoff_trace_close(struct trace_iterator *iter)
+{
+       if (iter->private)
+               graph_trace_close(iter);
+}
+
+#define GRAPH_TRACER_FLAGS (TRACE_GRAPH_PRINT_CPU | \
+                           TRACE_GRAPH_PRINT_PROC)
+
+static enum print_line_t irqsoff_print_line(struct trace_iterator *iter)
+{
+       u32 flags = GRAPH_TRACER_FLAGS;
+
+       if (trace_flags & TRACE_ITER_LATENCY_FMT)
+               flags |= TRACE_GRAPH_PRINT_DURATION;
+       else
+               flags |= TRACE_GRAPH_PRINT_ABS_TIME;
+
+       /*
+        * In graph mode call the graph tracer output function,
+        * otherwise go with the TRACE_FN event handler
+        */
+       if (is_graph())
+               return print_graph_function_flags(iter, flags);
+
+       return TRACE_TYPE_UNHANDLED;
+}
+
+static void irqsoff_print_header(struct seq_file *s)
+{
+       if (is_graph()) {
+               struct trace_iterator *iter = s->private;
+               u32 flags = GRAPH_TRACER_FLAGS;
+
+               if (trace_flags & TRACE_ITER_LATENCY_FMT) {
+                       /* print nothing if the buffers are empty */
+                       if (trace_empty(iter))
+                               return;
+
+                       print_trace_header(s, iter);
+                       flags |= TRACE_GRAPH_PRINT_DURATION;
+               } else
+                       flags |= TRACE_GRAPH_PRINT_ABS_TIME;
+
+               print_graph_headers_flags(s, flags);
+       } else
+               trace_default_header(s);
+}
+
+static void
+trace_graph_function(struct trace_array *tr,
+                unsigned long ip, unsigned long flags, int pc)
+{
+       u64 time = trace_clock_local();
+       struct ftrace_graph_ent ent = {
+               .func  = ip,
+               .depth = 0,
+       };
+       struct ftrace_graph_ret ret = {
+               .func     = ip,
+               .depth    = 0,
+               .calltime = time,
+               .rettime  = time,
+       };
+
+       __trace_graph_entry(tr, &ent, flags, pc);
+       __trace_graph_return(tr, &ret, flags, pc);
+}
+
+static void
+__trace_function(struct trace_array *tr,
+                unsigned long ip, unsigned long parent_ip,
+                unsigned long flags, int pc)
+{
+       if (!is_graph())
+               trace_function(tr, ip, parent_ip, flags, pc);
+       else {
+               trace_graph_function(tr, parent_ip, flags, pc);
+               trace_graph_function(tr, ip, flags, pc);
+       }
+}
+
+#else
+#define __trace_function trace_function
+
+static int irqsoff_set_flag(u32 old_flags, u32 bit, int set)
+{
+       return -EINVAL;
+}
+
+static int irqsoff_graph_entry(struct ftrace_graph_ent *trace)
+{
+       return -1;
+}
+
+static enum print_line_t irqsoff_print_line(struct trace_iterator *iter)
+{
+       return TRACE_TYPE_UNHANDLED;
+}
+
+static void irqsoff_graph_return(struct ftrace_graph_ret *trace) { }
+static void irqsoff_print_header(struct seq_file *s) { }
+static void irqsoff_trace_open(struct trace_iterator *iter) { }
+static void irqsoff_trace_close(struct trace_iterator *iter) { }
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
 /*
  * Should this new latency be reported/recorded?
  */
@@ -150,7 +366,7 @@ check_critical_timing(struct trace_array *tr,
        if (!report_latency(delta))
                goto out_unlock;
 
-       trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
+       __trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
        /* Skip 5 functions to get to the irq/preempt enable function */
        __trace_stack(tr, flags, 5, pc);
 
@@ -172,7 +388,7 @@ out_unlock:
 out:
        data->critical_sequence = max_sequence;
        data->preempt_timestamp = ftrace_now(cpu);
-       trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
+       __trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
 }
 
 static inline void
@@ -204,7 +420,7 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip)
 
        local_save_flags(flags);
 
-       trace_function(tr, ip, parent_ip, flags, preempt_count());
+       __trace_function(tr, ip, parent_ip, flags, preempt_count());
 
        per_cpu(tracing_cpu, cpu) = 1;
 
@@ -238,7 +454,7 @@ stop_critical_timing(unsigned long ip, unsigned long parent_ip)
        atomic_inc(&data->disabled);
 
        local_save_flags(flags);
-       trace_function(tr, ip, parent_ip, flags, preempt_count());
+       __trace_function(tr, ip, parent_ip, flags, preempt_count());
        check_critical_timing(tr, data, parent_ip ? : ip, cpu);
        data->critical_start = 0;
        atomic_dec(&data->disabled);
@@ -347,19 +563,32 @@ void trace_preempt_off(unsigned long a0, unsigned long a1)
 }
 #endif /* CONFIG_PREEMPT_TRACER */
 
-static void start_irqsoff_tracer(struct trace_array *tr)
+static int start_irqsoff_tracer(struct trace_array *tr, int graph)
 {
-       register_ftrace_function(&trace_ops);
-       if (tracing_is_enabled())
+       int ret = 0;
+
+       if (!graph)
+               ret = register_ftrace_function(&trace_ops);
+       else
+               ret = register_ftrace_graph(&irqsoff_graph_return,
+                                           &irqsoff_graph_entry);
+
+       if (!ret && tracing_is_enabled())
                tracer_enabled = 1;
        else
                tracer_enabled = 0;
+
+       return ret;
 }
 
-static void stop_irqsoff_tracer(struct trace_array *tr)
+static void stop_irqsoff_tracer(struct trace_array *tr, int graph)
 {
        tracer_enabled = 0;
-       unregister_ftrace_function(&trace_ops);
+
+       if (!graph)
+               unregister_ftrace_function(&trace_ops);
+       else
+               unregister_ftrace_graph();
 }
 
 static void __irqsoff_tracer_init(struct trace_array *tr)
@@ -372,12 +601,14 @@ static void __irqsoff_tracer_init(struct trace_array *tr)
        /* make sure that the tracer is visible */
        smp_wmb();
        tracing_reset_online_cpus(tr);
-       start_irqsoff_tracer(tr);
+
+       if (start_irqsoff_tracer(tr, is_graph()))
+               printk(KERN_ERR "failed to start irqsoff tracer\n");
 }
 
 static void irqsoff_tracer_reset(struct trace_array *tr)
 {
-       stop_irqsoff_tracer(tr);
+       stop_irqsoff_tracer(tr, is_graph());
 
        if (!save_lat_flag)
                trace_flags &= ~TRACE_ITER_LATENCY_FMT;
@@ -409,9 +640,15 @@ static struct tracer irqsoff_tracer __read_mostly =
        .start          = irqsoff_tracer_start,
        .stop           = irqsoff_tracer_stop,
        .print_max      = 1,
+       .print_header   = irqsoff_print_header,
+       .print_line     = irqsoff_print_line,
+       .flags          = &tracer_flags,
+       .set_flag       = irqsoff_set_flag,
 #ifdef CONFIG_FTRACE_SELFTEST
        .selftest    = trace_selftest_startup_irqsoff,
 #endif
+       .open           = irqsoff_trace_open,
+       .close          = irqsoff_trace_close,
 };
 # define register_irqsoff(trace) register_tracer(&trace)
 #else
@@ -435,9 +672,15 @@ static struct tracer preemptoff_tracer __read_mostly =
        .start          = irqsoff_tracer_start,
        .stop           = irqsoff_tracer_stop,
        .print_max      = 1,
+       .print_header   = irqsoff_print_header,
+       .print_line     = irqsoff_print_line,
+       .flags          = &tracer_flags,
+       .set_flag       = irqsoff_set_flag,
 #ifdef CONFIG_FTRACE_SELFTEST
        .selftest    = trace_selftest_startup_preemptoff,
 #endif
+       .open           = irqsoff_trace_open,
+       .close          = irqsoff_trace_close,
 };
 # define register_preemptoff(trace) register_tracer(&trace)
 #else
@@ -463,9 +706,15 @@ static struct tracer preemptirqsoff_tracer __read_mostly =
        .start          = irqsoff_tracer_start,
        .stop           = irqsoff_tracer_stop,
        .print_max      = 1,
+       .print_header   = irqsoff_print_header,
+       .print_line     = irqsoff_print_line,
+       .flags          = &tracer_flags,
+       .set_flag       = irqsoff_set_flag,
 #ifdef CONFIG_FTRACE_SELFTEST
        .selftest    = trace_selftest_startup_preemptirqsoff,
 #endif
+       .open           = irqsoff_trace_open,
+       .close          = irqsoff_trace_close,
 };
 
 # define register_preemptirqsoff(trace) register_tracer(&trace)
index 505c92273b1a51b98370221dcd30cd9234d36d06..a7514326052b658b88e69029a7754e197b7c2f56 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/ctype.h>
 #include <linux/ptrace.h>
 #include <linux/perf_event.h>
+#include <linux/stringify.h>
+#include <asm/bitsperlong.h>
 
 #include "trace.h"
 #include "trace_output.h"
@@ -40,7 +42,6 @@
 
 /* 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"
 
@@ -52,56 +53,102 @@ const char *reserved_field_names[] = {
        "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 *);
+/* Printing function type */
+typedef int (*print_type_func_t)(struct trace_seq *, const char *, void *);
+#define PRINT_TYPE_FUNC_NAME(type)     print_type_##type
+#define PRINT_TYPE_FMT_NAME(type)      print_type_format_##type
+
+/* Printing  in basic type function template */
+#define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt, cast)                  \
+static __kprobes int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s,   \
+                                               const char *name, void *data)\
+{                                                                      \
+       return trace_seq_printf(s, " %s=" fmt, name, (cast)*(type *)data);\
+}                                                                      \
+static const char PRINT_TYPE_FMT_NAME(type)[] = fmt;
+
+DEFINE_BASIC_PRINT_TYPE_FUNC(u8, "%x", unsigned int)
+DEFINE_BASIC_PRINT_TYPE_FUNC(u16, "%x", unsigned int)
+DEFINE_BASIC_PRINT_TYPE_FUNC(u32, "%lx", unsigned long)
+DEFINE_BASIC_PRINT_TYPE_FUNC(u64, "%llx", unsigned long long)
+DEFINE_BASIC_PRINT_TYPE_FUNC(s8, "%d", int)
+DEFINE_BASIC_PRINT_TYPE_FUNC(s16, "%d", int)
+DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%ld", long)
+DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%lld", long long)
+
+/* Data fetch function type */
+typedef        void (*fetch_func_t)(struct pt_regs *, void *, void *);
+
+struct fetch_param {
+       fetch_func_t    fn;
        void *data;
 };
 
-static __kprobes unsigned long call_fetch(struct fetch_func *f,
-                                         struct pt_regs *regs)
+static __kprobes void call_fetch(struct fetch_param *fprm,
+                                struct pt_regs *regs, void *dest)
 {
-       return f->func(regs, f->data);
+       return fprm->fn(regs, fprm->data, dest);
 }
 
-/* fetch handlers */
-static __kprobes unsigned long fetch_register(struct pt_regs *regs,
-                                             void *offset)
-{
-       return regs_get_register(regs, (unsigned int)((unsigned long)offset));
+#define FETCH_FUNC_NAME(kind, type)    fetch_##kind##_##type
+/*
+ * Define macro for basic types - we don't need to define s* types, because
+ * we have to care only about bitwidth at recording time.
+ */
+#define DEFINE_BASIC_FETCH_FUNCS(kind)  \
+DEFINE_FETCH_##kind(u8)                        \
+DEFINE_FETCH_##kind(u16)               \
+DEFINE_FETCH_##kind(u32)               \
+DEFINE_FETCH_##kind(u64)
+
+#define CHECK_BASIC_FETCH_FUNCS(kind, fn)      \
+       ((FETCH_FUNC_NAME(kind, u8) == fn) ||   \
+        (FETCH_FUNC_NAME(kind, u16) == fn) ||  \
+        (FETCH_FUNC_NAME(kind, u32) == fn) ||  \
+        (FETCH_FUNC_NAME(kind, u64) == fn))
+
+/* Data fetch function templates */
+#define DEFINE_FETCH_reg(type)                                         \
+static __kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs, \
+                                         void *offset, void *dest)     \
+{                                                                      \
+       *(type *)dest = (type)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));
+DEFINE_BASIC_FETCH_FUNCS(reg)
+
+#define DEFINE_FETCH_stack(type)                                       \
+static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\
+                                         void *offset, void *dest)     \
+{                                                                      \
+       *(type *)dest = (type)regs_get_kernel_stack_nth(regs,           \
+                               (unsigned int)((unsigned long)offset)); \
 }
+DEFINE_BASIC_FETCH_FUNCS(stack)
 
-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;
+#define DEFINE_FETCH_retval(type)                                      \
+static __kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs,\
+                                         void *dummy, void *dest)      \
+{                                                                      \
+       *(type *)dest = (type)regs_return_value(regs);                  \
 }
-
-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);
+DEFINE_BASIC_FETCH_FUNCS(retval)
+
+#define DEFINE_FETCH_memory(type)                                      \
+static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\
+                                         void *addr, void *dest)       \
+{                                                                      \
+       type retval;                                                    \
+       if (probe_kernel_address(addr, retval))                         \
+               *(type *)dest = 0;                                      \
+       else                                                            \
+               *(type *)dest = retval;                                 \
 }
+DEFINE_BASIC_FETCH_FUNCS(memory)
 
 /* Memory fetching by symbol */
 struct symbol_cache {
@@ -145,51 +192,126 @@ static struct symbol_cache *alloc_symbol_cache(const char *sym, long offset)
        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;
+#define DEFINE_FETCH_symbol(type)                                      \
+static __kprobes void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs,\
+                                         void *data, void *dest)       \
+{                                                                      \
+       struct symbol_cache *sc = data;                                 \
+       if (sc->addr)                                                   \
+               fetch_memory_##type(regs, (void *)sc->addr, dest);      \
+       else                                                            \
+               *(type *)dest = 0;                                      \
 }
+DEFINE_BASIC_FETCH_FUNCS(symbol)
 
-/* Special indirect memory access interface */
-struct indirect_fetch_data {
-       struct fetch_func orig;
+/* Dereference memory access function */
+struct deref_fetch_param {
+       struct fetch_param 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;
+#define DEFINE_FETCH_deref(type)                                       \
+static __kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs,\
+                                           void *data, void *dest)     \
+{                                                                      \
+       struct deref_fetch_param *dprm = data;                          \
+       unsigned long addr;                                             \
+       call_fetch(&dprm->orig, regs, &addr);                           \
+       if (addr) {                                                     \
+               addr += dprm->offset;                                   \
+               fetch_memory_##type(regs, (void *)addr, dest);          \
+       } else                                                          \
+               *(type *)dest = 0;                                      \
 }
+DEFINE_BASIC_FETCH_FUNCS(deref)
 
-static __kprobes void free_indirect_fetch_data(struct indirect_fetch_data *data)
+static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data)
 {
-       if (data->orig.func == fetch_indirect)
-               free_indirect_fetch_data(data->orig.data);
-       else if (data->orig.func == fetch_symbol)
+       if (CHECK_BASIC_FETCH_FUNCS(deref, data->orig.fn))
+               free_deref_fetch_param(data->orig.data);
+       else if (CHECK_BASIC_FETCH_FUNCS(symbol, data->orig.fn))
                free_symbol_cache(data->orig.data);
        kfree(data);
 }
 
+/* Default (unsigned long) fetch type */
+#define __DEFAULT_FETCH_TYPE(t) u##t
+#define _DEFAULT_FETCH_TYPE(t) __DEFAULT_FETCH_TYPE(t)
+#define DEFAULT_FETCH_TYPE _DEFAULT_FETCH_TYPE(BITS_PER_LONG)
+#define DEFAULT_FETCH_TYPE_STR __stringify(DEFAULT_FETCH_TYPE)
+
+#define ASSIGN_FETCH_FUNC(kind, type)  \
+       .kind = FETCH_FUNC_NAME(kind, type)
+
+#define ASSIGN_FETCH_TYPE(ptype, ftype, sign)  \
+       {.name = #ptype,                        \
+        .size = sizeof(ftype),                 \
+        .is_signed = sign,                     \
+        .print = PRINT_TYPE_FUNC_NAME(ptype),  \
+        .fmt = PRINT_TYPE_FMT_NAME(ptype),     \
+ASSIGN_FETCH_FUNC(reg, ftype),                 \
+ASSIGN_FETCH_FUNC(stack, ftype),               \
+ASSIGN_FETCH_FUNC(retval, ftype),              \
+ASSIGN_FETCH_FUNC(memory, ftype),              \
+ASSIGN_FETCH_FUNC(symbol, ftype),              \
+ASSIGN_FETCH_FUNC(deref, ftype),               \
+       }
+
+/* Fetch type information table */
+static const struct fetch_type {
+       const char      *name;          /* Name of type */
+       size_t          size;           /* Byte size of type */
+       int             is_signed;      /* Signed flag */
+       print_type_func_t       print;  /* Print functions */
+       const char      *fmt;           /* Fromat string */
+       /* Fetch functions */
+       fetch_func_t    reg;
+       fetch_func_t    stack;
+       fetch_func_t    retval;
+       fetch_func_t    memory;
+       fetch_func_t    symbol;
+       fetch_func_t    deref;
+} fetch_type_table[] = {
+       ASSIGN_FETCH_TYPE(u8,  u8,  0),
+       ASSIGN_FETCH_TYPE(u16, u16, 0),
+       ASSIGN_FETCH_TYPE(u32, u32, 0),
+       ASSIGN_FETCH_TYPE(u64, u64, 0),
+       ASSIGN_FETCH_TYPE(s8,  u8,  1),
+       ASSIGN_FETCH_TYPE(s16, u16, 1),
+       ASSIGN_FETCH_TYPE(s32, u32, 1),
+       ASSIGN_FETCH_TYPE(s64, u64, 1),
+};
+
+static const struct fetch_type *find_fetch_type(const char *type)
+{
+       int i;
+
+       if (!type)
+               type = DEFAULT_FETCH_TYPE_STR;
+
+       for (i = 0; i < ARRAY_SIZE(fetch_type_table); i++)
+               if (strcmp(type, fetch_type_table[i].name) == 0)
+                       return &fetch_type_table[i];
+       return NULL;
+}
+
+/* Special function : only accept unsigned long */
+static __kprobes void fetch_stack_address(struct pt_regs *regs,
+                                         void *dummy, void *dest)
+{
+       *(unsigned long *)dest = kernel_stack_pointer(regs);
+}
+
 /**
  * Kprobe event core functions
  */
 
 struct probe_arg {
-       struct fetch_func       fetch;
-       const char              *name;
+       struct fetch_param      fetch;
+       unsigned int            offset; /* Offset from argument entry */
+       const char              *name;  /* Name of this argument */
+       const char              *comm;  /* Command of this argument */
+       const struct fetch_type *type;  /* Type of this argument */
 };
 
 /* Flags for trace_probe */
@@ -204,6 +326,7 @@ struct trace_probe {
        const char              *symbol;        /* symbol name */
        struct ftrace_event_call        call;
        struct trace_event              event;
+       ssize_t                 size;           /* trace entry size */
        unsigned int            nr_args;
        struct probe_arg        args[];
 };
@@ -212,6 +335,7 @@ struct trace_probe {
        (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;
@@ -222,49 +346,6 @@ 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_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);
 
@@ -347,11 +428,12 @@ error:
 
 static void free_probe_arg(struct probe_arg *arg)
 {
-       if (arg->fetch.func == fetch_symbol)
+       if (CHECK_BASIC_FETCH_FUNCS(deref, arg->fetch.fn))
+               free_deref_fetch_param(arg->fetch.data);
+       else if (CHECK_BASIC_FETCH_FUNCS(symbol, arg->fetch.fn))
                free_symbol_cache(arg->fetch.data);
-       else if (arg->fetch.func == fetch_indirect)
-               free_indirect_fetch_data(arg->fetch.data);
        kfree(arg->name);
+       kfree(arg->comm);
 }
 
 static void free_trace_probe(struct trace_probe *tp)
@@ -457,28 +539,30 @@ static int split_symbol_offset(char *symbol, unsigned long *offset)
 #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)
+static int parse_probe_vars(char *arg, const struct fetch_type *t,
+                           struct fetch_param *f, 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
+               if (is_return)
+                       f->fn = t->retval;
+               else
                        ret = -EINVAL;
        } else if (strncmp(arg, "stack", 5) == 0) {
                if (arg[5] == '\0') {
-                       ff->func = fetch_stack_address;
-                       ff->data = NULL;
+                       if (strcmp(t->name, DEFAULT_FETCH_TYPE_STR) == 0)
+                               f->fn = fetch_stack_address;
+                       else
+                               ret = -EINVAL;
                } 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;
+                               f->fn = t->stack;
+                               f->data = (void *)param;
                        }
                } else
                        ret = -EINVAL;
@@ -488,7 +572,8 @@ static int parse_probe_vars(char *arg, struct fetch_func *ff, int is_return)
 }
 
 /* Recursive argument parser */
-static int __parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
+static int __parse_probe_arg(char *arg, const struct fetch_type *t,
+                            struct fetch_param *f, int is_return)
 {
        int ret = 0;
        unsigned long param;
@@ -497,13 +582,13 @@ static int __parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
 
        switch (arg[0]) {
        case '$':
-               ret = parse_probe_vars(arg + 1, ff, is_return);
+               ret = parse_probe_vars(arg + 1, t, f, 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;
+                       f->fn = t->reg;
+                       f->data = (void *)(unsigned long)ret;
                        ret = 0;
                }
                break;
@@ -512,26 +597,22 @@ static int __parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
                        ret = strict_strtoul(arg + 1, 0, &param);
                        if (ret)
                                break;
-                       ff->func = fetch_memory;
-                       ff->data = (void *)param;
+                       f->fn = t->memory;
+                       f->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;
+                       f->data = alloc_symbol_cache(arg + 1, offset);
+                       if (f->data)
+                               f->fn = t->symbol;
                }
                break;
-       case '+':       /* indirect memory */
+       case '+':       /* deref memory */
        case '-':
                tmp = strchr(arg, '(');
-               if (!tmp) {
-                       ret = -EINVAL;
+               if (!tmp)
                        break;
-               }
                *tmp = '\0';
                ret = strict_strtol(arg + 1, 0, &offset);
                if (ret)
@@ -541,38 +622,58 @@ static int __parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
                arg = tmp + 1;
                tmp = strrchr(arg, ')');
                if (tmp) {
-                       struct indirect_fetch_data *id;
+                       struct deref_fetch_param *dprm;
+                       const struct fetch_type *t2 = find_fetch_type(NULL);
                        *tmp = '\0';
-                       id = kzalloc(sizeof(struct indirect_fetch_data),
-                                    GFP_KERNEL);
-                       if (!id)
+                       dprm = kzalloc(sizeof(struct deref_fetch_param),
+                                      GFP_KERNEL);
+                       if (!dprm)
                                return -ENOMEM;
-                       id->offset = offset;
-                       ret = __parse_probe_arg(arg, &id->orig, is_return);
+                       dprm->offset = offset;
+                       ret = __parse_probe_arg(arg, t2, &dprm->orig,
+                                               is_return);
                        if (ret)
-                               kfree(id);
+                               kfree(dprm);
                        else {
-                               ff->func = fetch_indirect;
-                               ff->data = (void *)id;
+                               f->fn = t->deref;
+                               f->data = (void *)dprm;
                        }
-               } else
-                       ret = -EINVAL;
+               }
                break;
-       default:
-               /* TODO: support custom handler */
-               ret = -EINVAL;
        }
+       if (!ret && !f->fn)
+               ret = -EINVAL;
        return ret;
 }
 
 /* String length checking wrapper */
-static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
+static int parse_probe_arg(char *arg, struct trace_probe *tp,
+                          struct probe_arg *parg, int is_return)
 {
+       const char *t;
+
        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);
+       parg->comm = kstrdup(arg, GFP_KERNEL);
+       if (!parg->comm) {
+               pr_info("Failed to allocate memory for command '%s'.\n", arg);
+               return -ENOMEM;
+       }
+       t = strchr(parg->comm, ':');
+       if (t) {
+               arg[t - parg->comm] = '\0';
+               t++;
+       }
+       parg->type = find_fetch_type(t);
+       if (!parg->type) {
+               pr_info("Unsupported type: %s\n", t);
+               return -EINVAL;
+       }
+       parg->offset = tp->size;
+       tp->size += parg->type->size;
+       return __parse_probe_arg(arg, parg->type, &parg->fetch, is_return);
 }
 
 /* Return 1 if name is reserved or already used by another argument */
@@ -602,15 +703,18 @@ static int create_trace_probe(int argc, char **argv)
         *  @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:
+        * Dereferencing memory fetch:
         *  +|-offs(ARG) : fetch memory at ARG +|- offs address.
         * Alias name of args:
         *  NAME=FETCHARG : set NAME as alias of FETCHARG.
+        * Type of args:
+        *  FETCHARG:TYPE : use TYPE instead of unsigned long.
         */
        struct trace_probe *tp;
        int i, ret = 0;
        int is_return = 0, is_delete = 0;
-       char *symbol = NULL, *event = NULL, *arg = NULL, *group = NULL;
+       char *symbol = NULL, *event = NULL, *group = NULL;
+       char *arg, *tmp;
        unsigned long offset = 0;
        void *addr = NULL;
        char buf[MAX_EVENT_NAME_LEN];
@@ -723,13 +827,6 @@ static int create_trace_probe(int argc, char **argv)
                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",
@@ -737,9 +834,19 @@ static int create_trace_probe(int argc, char **argv)
                        ret = -ENOMEM;
                        goto error;
                }
+               tmp = strchr(tp->args[i].name, ':');
+               if (tmp)
+                       *tmp = '_';     /* convert : to _ */
+
+               if (conflict_field_name(tp->args[i].name, tp->args, i)) {
+                       pr_info("Argument%d name '%s' conflicts with "
+                               "another field.\n", i, argv[i]);
+                       ret = -EINVAL;
+                       goto error;
+               }
 
                /* Parse fetch argument */
-               ret = parse_probe_arg(arg, &tp->args[i].fetch, is_return);
+               ret = parse_probe_arg(arg, tp, &tp->args[i], is_return);
                if (ret) {
                        pr_info("Parse error at argument%d. (%d)\n", i, ret);
                        kfree(tp->args[i].name);
@@ -794,8 +901,7 @@ static void probes_seq_stop(struct seq_file *m, void *v)
 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];
+       int i;
 
        seq_printf(m, "%c", probe_is_return(tp) ? 'r' : 'p');
        seq_printf(m, ":%s/%s", tp->call.system, tp->call.name);
@@ -807,15 +913,10 @@ static int probes_seq_show(struct seq_file *m, void *v)
        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);
-       }
+       for (i = 0; i < tp->nr_args; i++)
+               seq_printf(m, " %s=%s", tp->args[i].name, tp->args[i].comm);
        seq_printf(m, "\n");
+
        return 0;
 }
 
@@ -945,9 +1046,10 @@ static const struct file_operations kprobe_profile_ops = {
 static __kprobes void 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 kprobe_trace_entry_head *entry;
        struct ring_buffer_event *event;
        struct ring_buffer *buffer;
+       u8 *data;
        int size, i, pc;
        unsigned long irq_flags;
        struct ftrace_event_call *call = &tp->call;
@@ -957,7 +1059,7 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
        local_save_flags(irq_flags);
        pc = preempt_count();
 
-       size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args);
+       size = sizeof(*entry) + tp->size;
 
        event = trace_current_buffer_lock_reserve(&buffer, call->id, size,
                                                  irq_flags, pc);
@@ -965,10 +1067,10 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
                return;
 
        entry = ring_buffer_event_data(event);
-       entry->nargs = tp->nr_args;
        entry->ip = (unsigned long)kp->addr;
+       data = (u8 *)&entry[1];
        for (i = 0; i < tp->nr_args; i++)
-               entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
+               call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
 
        if (!filter_current_check_discard(buffer, call, entry, event))
                trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc);
@@ -979,9 +1081,10 @@ static __kprobes void 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 kretprobe_trace_entry_head *entry;
        struct ring_buffer_event *event;
        struct ring_buffer *buffer;
+       u8 *data;
        int size, i, pc;
        unsigned long irq_flags;
        struct ftrace_event_call *call = &tp->call;
@@ -989,7 +1092,7 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,
        local_save_flags(irq_flags);
        pc = preempt_count();
 
-       size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args);
+       size = sizeof(*entry) + tp->size;
 
        event = trace_current_buffer_lock_reserve(&buffer, call->id, size,
                                                  irq_flags, pc);
@@ -997,11 +1100,11 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,
                return;
 
        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;
+       data = (u8 *)&entry[1];
        for (i = 0; i < tp->nr_args; i++)
-               entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
+               call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
 
        if (!filter_current_check_discard(buffer, call, entry, event))
                trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc);
@@ -1011,13 +1114,14 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,
 enum print_line_t
 print_kprobe_event(struct trace_iterator *iter, int flags)
 {
-       struct kprobe_trace_entry *field;
+       struct kprobe_trace_entry_head *field;
        struct trace_seq *s = &iter->seq;
        struct trace_event *event;
        struct trace_probe *tp;
+       u8 *data;
        int i;
 
-       field = (struct kprobe_trace_entry *)iter->ent;
+       field = (struct kprobe_trace_entry_head *)iter->ent;
        event = ftrace_find_event(field->ent.type);
        tp = container_of(event, struct trace_probe, event);
 
@@ -1030,9 +1134,10 @@ print_kprobe_event(struct trace_iterator *iter, int flags)
        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]))
+       data = (u8 *)&field[1];
+       for (i = 0; i < tp->nr_args; i++)
+               if (!tp->args[i].type->print(s, tp->args[i].name,
+                                            data + tp->args[i].offset))
                        goto partial;
 
        if (!trace_seq_puts(s, "\n"))
@@ -1046,13 +1151,14 @@ partial:
 enum print_line_t
 print_kretprobe_event(struct trace_iterator *iter, int flags)
 {
-       struct kretprobe_trace_entry *field;
+       struct kretprobe_trace_entry_head *field;
        struct trace_seq *s = &iter->seq;
        struct trace_event *event;
        struct trace_probe *tp;
+       u8 *data;
        int i;
 
-       field = (struct kretprobe_trace_entry *)iter->ent;
+       field = (struct kretprobe_trace_entry_head *)iter->ent;
        event = ftrace_find_event(field->ent.type);
        tp = container_of(event, struct trace_probe, event);
 
@@ -1071,9 +1177,10 @@ print_kretprobe_event(struct trace_iterator *iter, int flags)
        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]))
+       data = (u8 *)&field[1];
+       for (i = 0; i < tp->nr_args; i++)
+               if (!tp->args[i].type->print(s, tp->args[i].name,
+                                            data + tp->args[i].offset))
                        goto partial;
 
        if (!trace_seq_puts(s, "\n"))
@@ -1129,29 +1236,43 @@ static int probe_event_raw_init(struct ftrace_event_call *event_call)
 static int kprobe_event_define_fields(struct ftrace_event_call *event_call)
 {
        int ret, i;
-       struct kprobe_trace_entry field;
+       struct kprobe_trace_entry_head field;
        struct trace_probe *tp = (struct trace_probe *)event_call->data;
 
        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);
+       for (i = 0; i < tp->nr_args; i++) {
+               ret = trace_define_field(event_call, tp->args[i].type->name,
+                                        tp->args[i].name,
+                                        sizeof(field) + tp->args[i].offset,
+                                        tp->args[i].type->size,
+                                        tp->args[i].type->is_signed,
+                                        FILTER_OTHER);
+               if (ret)
+                       return ret;
+       }
        return 0;
 }
 
 static int kretprobe_event_define_fields(struct ftrace_event_call *event_call)
 {
        int ret, i;
-       struct kretprobe_trace_entry field;
+       struct kretprobe_trace_entry_head field;
        struct trace_probe *tp = (struct trace_probe *)event_call->data;
 
        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);
+       for (i = 0; i < tp->nr_args; i++) {
+               ret = trace_define_field(event_call, tp->args[i].type->name,
+                                        tp->args[i].name,
+                                        sizeof(field) + tp->args[i].offset,
+                                        tp->args[i].type->size,
+                                        tp->args[i].type->is_signed,
+                                        FILTER_OTHER);
+               if (ret)
+                       return ret;
+       }
        return 0;
 }
 
@@ -1176,8 +1297,8 @@ static int __set_print_fmt(struct trace_probe *tp, char *buf, int len)
        pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", fmt);
 
        for (i = 0; i < tp->nr_args; i++) {
-               pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=%%lx",
-                               tp->args[i].name);
+               pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=%s",
+                               tp->args[i].name, tp->args[i].type->fmt);
        }
 
        pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg);
@@ -1214,67 +1335,70 @@ static int set_print_fmt(struct trace_probe *tp)
 #ifdef CONFIG_PERF_EVENTS
 
 /* Kprobe profile handler */
-static __kprobes void kprobe_profile_func(struct kprobe *kp,
+static __kprobes void kprobe_perf_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 kprobe_trace_entry_head *entry;
+       u8 *data;
        int size, __size, i;
        unsigned long irq_flags;
        int rctx;
 
-       __size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args);
+       __size = sizeof(*entry) + tp->size;
        size = ALIGN(__size + sizeof(u32), sizeof(u64));
        size -= sizeof(u32);
-       if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE,
+       if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
                     "profile buffer not large enough"))
                return;
 
-       entry = ftrace_perf_buf_prepare(size, call->id, &rctx, &irq_flags);
+       entry = perf_trace_buf_prepare(size, call->id, &rctx, &irq_flags);
        if (!entry)
                return;
 
-       entry->nargs = tp->nr_args;
        entry->ip = (unsigned long)kp->addr;
+       data = (u8 *)&entry[1];
        for (i = 0; i < tp->nr_args; i++)
-               entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
+               call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
 
-       ftrace_perf_buf_submit(entry, size, rctx, entry->ip, 1, irq_flags);
+       perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, irq_flags, regs);
 }
 
 /* Kretprobe profile handler */
-static __kprobes void kretprobe_profile_func(struct kretprobe_instance *ri,
+static __kprobes void kretprobe_perf_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 kretprobe_trace_entry_head *entry;
+       u8 *data;
        int size, __size, i;
        unsigned long irq_flags;
        int rctx;
 
-       __size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args);
+       __size = sizeof(*entry) + tp->size;
        size = ALIGN(__size + sizeof(u32), sizeof(u64));
        size -= sizeof(u32);
-       if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE,
+       if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
                     "profile buffer not large enough"))
                return;
 
-       entry = ftrace_perf_buf_prepare(size, call->id, &rctx, &irq_flags);
+       entry = perf_trace_buf_prepare(size, call->id, &rctx, &irq_flags);
        if (!entry)
                return;
 
-       entry->nargs = tp->nr_args;
        entry->func = (unsigned long)tp->rp.kp.addr;
        entry->ret_ip = (unsigned long)ri->ret_addr;
+       data = (u8 *)&entry[1];
        for (i = 0; i < tp->nr_args; i++)
-               entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
+               call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
 
-       ftrace_perf_buf_submit(entry, size, rctx, entry->ret_ip, 1, irq_flags);
+       perf_trace_buf_submit(entry, size, rctx, entry->ret_ip, 1,
+                              irq_flags, regs);
 }
 
-static int probe_profile_enable(struct ftrace_event_call *call)
+static int probe_perf_enable(struct ftrace_event_call *call)
 {
        struct trace_probe *tp = (struct trace_probe *)call->data;
 
@@ -1286,7 +1410,7 @@ static int probe_profile_enable(struct ftrace_event_call *call)
                return enable_kprobe(&tp->rp.kp);
 }
 
-static void probe_profile_disable(struct ftrace_event_call *call)
+static void probe_perf_disable(struct ftrace_event_call *call)
 {
        struct trace_probe *tp = (struct trace_probe *)call->data;
 
@@ -1311,7 +1435,7 @@ int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs)
                kprobe_trace_func(kp, regs);
 #ifdef CONFIG_PERF_EVENTS
        if (tp->flags & TP_FLAG_PROFILE)
-               kprobe_profile_func(kp, regs);
+               kprobe_perf_func(kp, regs);
 #endif
        return 0;       /* We don't tweek kernel, so just return 0 */
 }
@@ -1325,7 +1449,7 @@ int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs)
                kretprobe_trace_func(ri, regs);
 #ifdef CONFIG_PERF_EVENTS
        if (tp->flags & TP_FLAG_PROFILE)
-               kretprobe_profile_func(ri, regs);
+               kretprobe_perf_func(ri, regs);
 #endif
        return 0;       /* We don't tweek kernel, so just return 0 */
 }
@@ -1358,8 +1482,8 @@ static int register_probe_event(struct trace_probe *tp)
        call->unregfunc = probe_event_disable;
 
 #ifdef CONFIG_PERF_EVENTS
-       call->profile_enable = probe_profile_enable;
-       call->profile_disable = probe_profile_disable;
+       call->perf_event_enable = probe_perf_enable;
+       call->perf_event_disable = probe_perf_disable;
 #endif
        call->data = tp;
        ret = trace_add_event_call(call);
index 94103cdcf9d86aa5f48c1f50c46c4b4366aaf770..8eaf00749b6532bb86d7580e8c8390838ff81da8 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/debugfs.h>
 #include <linux/ftrace.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 
 #include "trace_output.h"
 
 #include <asm/atomic.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 {
@@ -52,7 +47,6 @@ struct trace_ksym {
 
 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);
@@ -180,13 +174,6 @@ 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;
@@ -202,13 +189,17 @@ int process_new_ksym_entry(char *ksymname, int op, unsigned long addr)
 
        if (IS_ERR(entry->ksym_hbp)) {
                ret = PTR_ERR(entry->ksym_hbp);
-               printk(KERN_INFO "ksym_tracer request failed. Try again"
-                                       " later!!\n");
+               if (ret == -ENOSPC) {
+                       printk(KERN_ERR "ksym_tracer: Maximum limit reached."
+                       " No new requests for tracing can be accepted now.\n");
+               } else {
+                       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;
 
@@ -264,7 +255,6 @@ static void __ksym_trace_reset(void)
        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);
@@ -337,7 +327,6 @@ static ssize_t ksym_trace_filter_write(struct file *file,
                                goto out_unlock;
                }
                /* Error or "symbol:---" case: drop it */
-               ksym_filter_entry_count--;
                hlist_del_rcu(&(entry->ksym_hlist));
                synchronize_rcu();
                kfree(entry);
index 0acd834659ed9f9306165d40b81d34a563604095..017fa376505d29a43fe1d69103047fe0365accb4 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/mmiotrace.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/time.h>
 
 #include <asm/atomic.h>
index 8e46b3323cdcdd91ad9833aa1eb8d0f1bf82f3af..2404c129a8c95cf006c83354ac26879ff40dc18c 100644 (file)
@@ -253,7 +253,7 @@ void *trace_seq_reserve(struct trace_seq *s, size_t len)
        void *ret;
 
        if (s->full)
-               return 0;
+               return NULL;
 
        if (len > ((PAGE_SIZE - 1) - s->len)) {
                s->full = 1;
index 5fca0f51fde4ac27df4c733c6ebd827c34d661b2..a55fccfede5d34b92b1d25d43b0080d8d45583bf 100644 (file)
@@ -50,8 +50,7 @@ tracing_sched_switch_trace(struct trace_array *tr,
 }
 
 static void
-probe_sched_switch(struct rq *__rq, struct task_struct *prev,
-                       struct task_struct *next)
+probe_sched_switch(struct task_struct *prev, struct task_struct *next)
 {
        struct trace_array_cpu *data;
        unsigned long flags;
@@ -109,7 +108,7 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
 }
 
 static void
-probe_sched_wakeup(struct rq *__rq, struct task_struct *wakee, int success)
+probe_sched_wakeup(struct task_struct *wakee, int success)
 {
        struct trace_array_cpu *data;
        unsigned long flags;
index 0271742abb8d1188e34c19905c89a4cc169843e0..8052446ceeaa9333ae575edf6f762b665c76ac09 100644 (file)
@@ -107,8 +107,7 @@ static void probe_wakeup_migrate_task(struct task_struct *task, int cpu)
 }
 
 static void notrace
-probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev,
-       struct task_struct *next)
+probe_wakeup_sched_switch(struct task_struct *prev, struct task_struct *next)
 {
        struct trace_array_cpu *data;
        cycle_t T0, T1, delta;
@@ -200,7 +199,7 @@ static void wakeup_reset(struct trace_array *tr)
 }
 
 static void
-probe_wakeup(struct rq *rq, struct task_struct *p, int success)
+probe_wakeup(struct task_struct *p, int success)
 {
        struct trace_array_cpu *data;
        int cpu = smp_processor_id();
index 280fea470d67ea603f230d8bfc7868d5d48e62b2..250e7f9bd2f0114c998d26c239fb3bfb535ebde2 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/stringify.h>
 #include <linux/kthread.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 static inline int trace_valid_entry(struct trace_entry *entry)
 {
@@ -16,7 +17,6 @@ static inline int trace_valid_entry(struct trace_entry *entry)
        case TRACE_BRANCH:
        case TRACE_GRAPH_ENT:
        case TRACE_GRAPH_RET:
-       case TRACE_HW_BRANCHES:
        case TRACE_KSYM:
                return 1;
        }
@@ -29,7 +29,7 @@ static int trace_test_buffer_cpu(struct trace_array *tr, int cpu)
        struct trace_entry *entry;
        unsigned int loops = 0;
 
-       while ((event = ring_buffer_consume(tr->buffer, cpu, NULL))) {
+       while ((event = ring_buffer_consume(tr->buffer, cpu, NULL, NULL))) {
                entry = ring_buffer_event_data(event);
 
                /*
@@ -255,7 +255,8 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr)
 /* Maximum number of functions to trace before diagnosing a hang */
 #define GRAPH_MAX_FUNC_TEST    100000000
 
-static void __ftrace_dump(bool disable_tracing);
+static void
+__ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode);
 static unsigned int graph_hang_thresh;
 
 /* Wrap the real function entry probe to avoid possible hanging */
@@ -266,7 +267,7 @@ static int trace_graph_entry_watchdog(struct ftrace_graph_ent *trace)
                ftrace_graph_stop();
                printk(KERN_WARNING "BUG: Function graph tracer hang!\n");
                if (ftrace_dump_on_oops)
-                       __ftrace_dump(false);
+                       __ftrace_dump(false, DUMP_ALL);
                return 0;
        }
 
@@ -754,62 +755,6 @@ trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr)
 }
 #endif /* CONFIG_BRANCH_TRACER */
 
-#ifdef CONFIG_HW_BRANCH_TRACER
-int
-trace_selftest_startup_hw_branches(struct tracer *trace,
-                                  struct trace_array *tr)
-{
-       struct trace_iterator *iter;
-       struct tracer tracer;
-       unsigned long count;
-       int ret;
-
-       if (!trace->open) {
-               printk(KERN_CONT "missing open function...");
-               return -1;
-       }
-
-       ret = tracer_init(trace, tr);
-       if (ret) {
-               warn_failed_init_tracer(trace, ret);
-               return ret;
-       }
-
-       /*
-        * The hw-branch tracer needs to collect the trace from the various
-        * cpu trace buffers - before tracing is stopped.
-        */
-       iter = kzalloc(sizeof(*iter), GFP_KERNEL);
-       if (!iter)
-               return -ENOMEM;
-
-       memcpy(&tracer, trace, sizeof(tracer));
-
-       iter->trace = &tracer;
-       iter->tr = tr;
-       iter->pos = -1;
-       mutex_init(&iter->mutex);
-
-       trace->open(iter);
-
-       mutex_destroy(&iter->mutex);
-       kfree(iter);
-
-       tracing_stop();
-
-       ret = trace_test_buffer(tr, &count);
-       trace->reset(tr);
-       tracing_start();
-
-       if (!ret && !count) {
-               printk(KERN_CONT "no entries found..");
-               ret = -1;
-       }
-
-       return ret;
-}
-#endif /* CONFIG_HW_BRANCH_TRACER */
-
 #ifdef CONFIG_KSYM_TRACER
 static int ksym_selftest_dummy;
 
index a4bb239eb9874a1a6efe7703a303a7e103c4c977..96cffb269e7360e131e445c8c0013c90419f0921 100644 (file)
@@ -10,6 +10,7 @@
 
 
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/rbtree.h>
 #include <linux/debugfs.h>
 #include "trace_stat.h"
index cba47d7935cc96fb8d27ea7015afdbcf7eded882..4d6d711717f2958a9c502f0e53bbb8a89ee41ff7 100644 (file)
@@ -1,5 +1,6 @@
 #include <trace/syscall.h>
 #include <trace/events/syscalls.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/ftrace.h>
 #include <linux/perf_event.h>
@@ -428,12 +429,12 @@ core_initcall(init_ftrace_syscalls);
 
 #ifdef CONFIG_PERF_EVENTS
 
-static DECLARE_BITMAP(enabled_prof_enter_syscalls, NR_syscalls);
-static DECLARE_BITMAP(enabled_prof_exit_syscalls, NR_syscalls);
-static int sys_prof_refcount_enter;
-static int sys_prof_refcount_exit;
+static DECLARE_BITMAP(enabled_perf_enter_syscalls, NR_syscalls);
+static DECLARE_BITMAP(enabled_perf_exit_syscalls, NR_syscalls);
+static int sys_perf_refcount_enter;
+static int sys_perf_refcount_exit;
 
-static void prof_syscall_enter(struct pt_regs *regs, long id)
+static void perf_syscall_enter(struct pt_regs *regs, long id)
 {
        struct syscall_metadata *sys_data;
        struct syscall_trace_enter *rec;
@@ -443,7 +444,7 @@ static void prof_syscall_enter(struct pt_regs *regs, long id)
        int size;
 
        syscall_nr = syscall_get_nr(current, regs);
-       if (!test_bit(syscall_nr, enabled_prof_enter_syscalls))
+       if (!test_bit(syscall_nr, enabled_perf_enter_syscalls))
                return;
 
        sys_data = syscall_nr_to_meta(syscall_nr);
@@ -455,11 +456,11 @@ static void prof_syscall_enter(struct pt_regs *regs, long id)
        size = ALIGN(size + sizeof(u32), sizeof(u64));
        size -= sizeof(u32);
 
-       if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE,
-                     "profile buffer not large enough"))
+       if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
+                     "perf buffer not large enough"))
                return;
 
-       rec = (struct syscall_trace_enter *)ftrace_perf_buf_prepare(size,
+       rec = (struct syscall_trace_enter *)perf_trace_buf_prepare(size,
                                sys_data->enter_event->id, &rctx, &flags);
        if (!rec)
                return;
@@ -467,10 +468,10 @@ static void prof_syscall_enter(struct pt_regs *regs, long id)
        rec->nr = syscall_nr;
        syscall_get_arguments(current, regs, 0, sys_data->nb_args,
                               (unsigned long *)&rec->args);
-       ftrace_perf_buf_submit(rec, size, rctx, 0, 1, flags);
+       perf_trace_buf_submit(rec, size, rctx, 0, 1, flags, regs);
 }
 
-int prof_sysenter_enable(struct ftrace_event_call *call)
+int perf_sysenter_enable(struct ftrace_event_call *call)
 {
        int ret = 0;
        int num;
@@ -478,34 +479,34 @@ int prof_sysenter_enable(struct ftrace_event_call *call)
        num = ((struct syscall_metadata *)call->data)->syscall_nr;
 
        mutex_lock(&syscall_trace_lock);
-       if (!sys_prof_refcount_enter)
-               ret = register_trace_sys_enter(prof_syscall_enter);
+       if (!sys_perf_refcount_enter)
+               ret = register_trace_sys_enter(perf_syscall_enter);
        if (ret) {
                pr_info("event trace: Could not activate"
                                "syscall entry trace point");
        } else {
-               set_bit(num, enabled_prof_enter_syscalls);
-               sys_prof_refcount_enter++;
+               set_bit(num, enabled_perf_enter_syscalls);
+               sys_perf_refcount_enter++;
        }
        mutex_unlock(&syscall_trace_lock);
        return ret;
 }
 
-void prof_sysenter_disable(struct ftrace_event_call *call)
+void perf_sysenter_disable(struct ftrace_event_call *call)
 {
        int num;
 
        num = ((struct syscall_metadata *)call->data)->syscall_nr;
 
        mutex_lock(&syscall_trace_lock);
-       sys_prof_refcount_enter--;
-       clear_bit(num, enabled_prof_enter_syscalls);
-       if (!sys_prof_refcount_enter)
-               unregister_trace_sys_enter(prof_syscall_enter);
+       sys_perf_refcount_enter--;
+       clear_bit(num, enabled_perf_enter_syscalls);
+       if (!sys_perf_refcount_enter)
+               unregister_trace_sys_enter(perf_syscall_enter);
        mutex_unlock(&syscall_trace_lock);
 }
 
-static void prof_syscall_exit(struct pt_regs *regs, long ret)
+static void perf_syscall_exit(struct pt_regs *regs, long ret)
 {
        struct syscall_metadata *sys_data;
        struct syscall_trace_exit *rec;
@@ -515,7 +516,7 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)
        int size;
 
        syscall_nr = syscall_get_nr(current, regs);
-       if (!test_bit(syscall_nr, enabled_prof_exit_syscalls))
+       if (!test_bit(syscall_nr, enabled_perf_exit_syscalls))
                return;
 
        sys_data = syscall_nr_to_meta(syscall_nr);
@@ -530,11 +531,11 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)
         * Impossible, but be paranoid with the future
         * How to put this check outside runtime?
         */
-       if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE,
-               "exit event has grown above profile buffer size"))
+       if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
+               "exit event has grown above perf buffer size"))
                return;
 
-       rec = (struct syscall_trace_exit *)ftrace_perf_buf_prepare(size,
+       rec = (struct syscall_trace_exit *)perf_trace_buf_prepare(size,
                                sys_data->exit_event->id, &rctx, &flags);
        if (!rec)
                return;
@@ -542,10 +543,10 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)
        rec->nr = syscall_nr;
        rec->ret = syscall_get_return_value(current, regs);
 
-       ftrace_perf_buf_submit(rec, size, rctx, 0, 1, flags);
+       perf_trace_buf_submit(rec, size, rctx, 0, 1, flags, regs);
 }
 
-int prof_sysexit_enable(struct ftrace_event_call *call)
+int perf_sysexit_enable(struct ftrace_event_call *call)
 {
        int ret = 0;
        int num;
@@ -553,30 +554,30 @@ int prof_sysexit_enable(struct ftrace_event_call *call)
        num = ((struct syscall_metadata *)call->data)->syscall_nr;
 
        mutex_lock(&syscall_trace_lock);
-       if (!sys_prof_refcount_exit)
-               ret = register_trace_sys_exit(prof_syscall_exit);
+       if (!sys_perf_refcount_exit)
+               ret = register_trace_sys_exit(perf_syscall_exit);
        if (ret) {
                pr_info("event trace: Could not activate"
                                "syscall exit trace point");
        } else {
-               set_bit(num, enabled_prof_exit_syscalls);
-               sys_prof_refcount_exit++;
+               set_bit(num, enabled_perf_exit_syscalls);
+               sys_perf_refcount_exit++;
        }
        mutex_unlock(&syscall_trace_lock);
        return ret;
 }
 
-void prof_sysexit_disable(struct ftrace_event_call *call)
+void perf_sysexit_disable(struct ftrace_event_call *call)
 {
        int num;
 
        num = ((struct syscall_metadata *)call->data)->syscall_nr;
 
        mutex_lock(&syscall_trace_lock);
-       sys_prof_refcount_exit--;
-       clear_bit(num, enabled_prof_exit_syscalls);
-       if (!sys_prof_refcount_exit)
-               unregister_trace_sys_exit(prof_syscall_exit);
+       sys_perf_refcount_exit--;
+       clear_bit(num, enabled_perf_exit_syscalls);
+       if (!sys_perf_refcount_exit)
+               unregister_trace_sys_exit(perf_syscall_exit);
        mutex_unlock(&syscall_trace_lock);
 }
 
index 40cafb07dffd11e533b17ef5c7fcf6546aef00f5..cc2d2faa7d9e037734f1e4c11e87418c4a3a5400 100644 (file)
@@ -9,6 +9,7 @@
 #include <trace/events/workqueue.h>
 #include <linux/list.h>
 #include <linux/percpu.h>
+#include <linux/slab.h>
 #include <linux/kref.h>
 #include "trace_stat.h"
 #include "trace.h"
index 766467b3bcb7f1e42da792bece602ec8404135a2..7e72614b736d82dd108d99ab79daefa55e6cdfe3 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/user_namespace.h>
-#include "cred-internals.h"
 
 struct user_namespace init_user_ns = {
        .kref = {
@@ -137,9 +136,6 @@ struct user_struct *alloc_uid(struct user_namespace *ns, uid_t uid)
        struct hlist_head *hashent = uidhashentry(ns, uid);
        struct user_struct *up, *new;
 
-       /* Make uid_hash_find() + uids_user_create() + uid_hash_insert()
-        * atomic.
-        */
        spin_lock_irq(&uidhash_lock);
        up = uid_hash_find(uid, hashent);
        spin_unlock_irq(&uidhash_lock);
@@ -161,11 +157,6 @@ struct user_struct *alloc_uid(struct user_namespace *ns, uid_t uid)
                spin_lock_irq(&uidhash_lock);
                up = uid_hash_find(uid, hashent);
                if (up) {
-                       /* This case is not possible when CONFIG_USER_SCHED
-                        * is defined, since we serialize alloc_uid() using
-                        * uids_mutex. Hence no need to call
-                        * sched_destroy_user() or remove_user_sysfs_dir().
-                        */
                        key_put(new->uid_keyring);
                        key_put(new->session_keyring);
                        kmem_cache_free(uid_cachep, new);
@@ -178,8 +169,6 @@ struct user_struct *alloc_uid(struct user_namespace *ns, uid_t uid)
 
        return up;
 
-       put_user_ns(new->user_ns);
-       kmem_cache_free(uid_cachep, new);
 out_unlock:
        return NULL;
 }
index dee48658805c4e58d1b4fc5776a165cc18e8c464..5bfb213984b2b2b740fb46bfbe945b6eaf6110ce 100644 (file)
@@ -774,7 +774,7 @@ 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());
+               cwq = wq_per_cpu(get_wq_data(&dwork->work)->wq, get_cpu());
                __queue_work(cwq, &dwork->work);
                put_cpu();
        }
index 8e5ec5e1ab91f11505ac1a7589bb196ff10e1147..d85be90d5888cb8df619039fb4282e77c9a120ff 100644 (file)
@@ -103,7 +103,8 @@ config HEADERS_CHECK
 
 config DEBUG_SECTION_MISMATCH
        bool "Enable full Section mismatch analysis"
-       depends on UNDEFINED
+       depends on UNDEFINED || (BLACKFIN)
+       default y
        # This option is on purpose disabled for now.
        # It will be enabled when we are down to a reasonable number
        # of section mismatch warnings (< 10 for an allyesconfig build)
@@ -355,7 +356,7 @@ config SLUB_STATS
 config DEBUG_KMEMLEAK
        bool "Kernel memory leak detector"
        depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \
-               (X86 || ARM || PPC || S390 || SUPERH)
+               (X86 || ARM || PPC || S390 || SPARC64 || SUPERH || MICROBLAZE)
 
        select DEBUG_FS if SYSFS
        select STACKTRACE if STACKTRACE_SUPPORT
@@ -511,6 +512,18 @@ config PROVE_RCU
 
         Say N if you are unsure.
 
+config PROVE_RCU_REPEATEDLY
+       bool "RCU debugging: don't disable PROVE_RCU on first splat"
+       depends on PROVE_RCU
+       default n
+       help
+        By itself, PROVE_RCU will disable checking upon issuing the
+        first warning (or "splat").  This feature prevents such
+        disabling, allowing multiple RCU-lockdep warnings to be printed
+        on a single reboot.
+
+        Say N if you are unsure.
+
 config LOCKDEP
        bool
        depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
@@ -792,7 +805,7 @@ config RCU_CPU_STALL_DETECTOR
 config RCU_CPU_STALL_VERBOSE
        bool "Print additional per-task information for RCU_CPU_STALL_DETECTOR"
        depends on RCU_CPU_STALL_DETECTOR && TREE_PREEMPT_RCU
-       default n
+       default y
        help
          This option causes RCU to printk detailed per-task information
          for any tasks that are stalling the current RCU grace period.
@@ -1085,6 +1098,13 @@ config DMA_API_DEBUG
          This option causes a performance degredation.  Use only if you want
          to debug device drivers. If unsure, say N.
 
+config ATOMIC64_SELFTEST
+       bool "Perform an atomic64_t self-test at boot"
+       help
+         Enable this option to test the atomic64_t functions at boot.
+
+         If unsure, say N.
+
 source "samples/Kconfig"
 
 source "lib/Kconfig.kgdb"
index 2e152aed71980852a4a682a6e98082a01d7048be..9e6d3c29d73a15a7db63728928e234361d48977f 100644 (file)
@@ -21,7 +21,7 @@ lib-y += kobject.o kref.o klist.o
 
 obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
         bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
-        string_helpers.o gcd.o list_sort.o
+        string_helpers.o gcd.o lcm.o list_sort.o
 
 ifeq ($(CONFIG_DEBUG_KOBJECT),y)
 CFLAGS_kobject.o += -DDEBUG
@@ -39,7 +39,10 @@ lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
 lib-$(CONFIG_GENERIC_FIND_FIRST_BIT) += find_next_bit.o
 lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
 obj-$(CONFIG_GENERIC_FIND_LAST_BIT) += find_last_bit.o
+
+CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS))
 obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
+
 obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
 obj-$(CONFIG_BTREE) += btree.o
 obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
@@ -101,6 +104,8 @@ obj-$(CONFIG_GENERIC_CSUM) += checksum.o
 
 obj-$(CONFIG_GENERIC_ATOMIC64) += atomic64.o
 
+obj-$(CONFIG_ATOMIC64_SELFTEST) += atomic64_test.o
+
 hostprogs-y    := gen_crc32table
 clean-files    := crc32table.h
 
index 8bee16ec75242d756e19dd67a2173520468474db..a21c12bc727ca973908e34e7ddbbdfab62eeb5ed 100644 (file)
@@ -162,12 +162,12 @@ int atomic64_add_unless(atomic64_t *v, long long a, long long u)
 {
        unsigned long flags;
        spinlock_t *lock = lock_addr(v);
-       int ret = 1;
+       int ret = 0;
 
        spin_lock_irqsave(lock, flags);
        if (v->counter != u) {
                v->counter += a;
-               ret = 0;
+               ret = 1;
        }
        spin_unlock_irqrestore(lock, flags);
        return ret;
diff --git a/lib/atomic64_test.c b/lib/atomic64_test.c
new file mode 100644 (file)
index 0000000..65e482c
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Testsuite for atomic64_t functions
+ *
+ * Copyright Â© 2010  Luca Barbieri
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/init.h>
+#include <asm/atomic.h>
+
+#define INIT(c) do { atomic64_set(&v, c); r = c; } while (0)
+static __init int test_atomic64(void)
+{
+       long long v0 = 0xaaa31337c001d00dLL;
+       long long v1 = 0xdeadbeefdeafcafeLL;
+       long long v2 = 0xfaceabadf00df001LL;
+       long long onestwos = 0x1111111122222222LL;
+       long long one = 1LL;
+
+       atomic64_t v = ATOMIC64_INIT(v0);
+       long long r = v0;
+       BUG_ON(v.counter != r);
+
+       atomic64_set(&v, v1);
+       r = v1;
+       BUG_ON(v.counter != r);
+       BUG_ON(atomic64_read(&v) != r);
+
+       INIT(v0);
+       atomic64_add(onestwos, &v);
+       r += onestwos;
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       atomic64_add(-one, &v);
+       r += -one;
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       r += onestwos;
+       BUG_ON(atomic64_add_return(onestwos, &v) != r);
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       r += -one;
+       BUG_ON(atomic64_add_return(-one, &v) != r);
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       atomic64_sub(onestwos, &v);
+       r -= onestwos;
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       atomic64_sub(-one, &v);
+       r -= -one;
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       r -= onestwos;
+       BUG_ON(atomic64_sub_return(onestwos, &v) != r);
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       r -= -one;
+       BUG_ON(atomic64_sub_return(-one, &v) != r);
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       atomic64_inc(&v);
+       r += one;
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       r += one;
+       BUG_ON(atomic64_inc_return(&v) != r);
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       atomic64_dec(&v);
+       r -= one;
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       r -= one;
+       BUG_ON(atomic64_dec_return(&v) != r);
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       BUG_ON(atomic64_xchg(&v, v1) != v0);
+       r = v1;
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       BUG_ON(atomic64_cmpxchg(&v, v0, v1) != v0);
+       r = v1;
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       BUG_ON(atomic64_cmpxchg(&v, v2, v1) != v0);
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       BUG_ON(atomic64_add_unless(&v, one, v0));
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       BUG_ON(!atomic64_add_unless(&v, one, v1));
+       r += one;
+       BUG_ON(v.counter != r);
+
+#if defined(CONFIG_X86) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(_ASM_GENERIC_ATOMIC64_H)
+       INIT(onestwos);
+       BUG_ON(atomic64_dec_if_positive(&v) != (onestwos - 1));
+       r -= one;
+       BUG_ON(v.counter != r);
+
+       INIT(0);
+       BUG_ON(atomic64_dec_if_positive(&v) != -one);
+       BUG_ON(v.counter != r);
+
+       INIT(-one);
+       BUG_ON(atomic64_dec_if_positive(&v) != (-one - one));
+       BUG_ON(v.counter != r);
+#else
+#warning Please implement atomic64_dec_if_positive for your architecture, and add it to the IF above
+#endif
+
+       INIT(onestwos);
+       BUG_ON(!atomic64_inc_not_zero(&v));
+       r += one;
+       BUG_ON(v.counter != r);
+
+       INIT(0);
+       BUG_ON(atomic64_inc_not_zero(&v));
+       BUG_ON(v.counter != r);
+
+       INIT(-one);
+       BUG_ON(!atomic64_inc_not_zero(&v));
+       r += one;
+       BUG_ON(v.counter != r);
+
+#ifdef CONFIG_X86
+       printk(KERN_INFO "atomic64 test passed for %s platform %s CX8 and %s SSE\n",
+#ifdef CONFIG_X86_64
+              "x86-64",
+#elif defined(CONFIG_X86_CMPXCHG64)
+              "i586+",
+#else
+              "i386+",
+#endif
+              boot_cpu_has(X86_FEATURE_CX8) ? "with" : "without",
+              boot_cpu_has(X86_FEATURE_XMM) ? "with" : "without");
+#else
+       printk(KERN_INFO "atomic64 test passed\n");
+#endif
+
+       return 0;
+}
+
+core_initcall(test_atomic64);
index 41859a8202184e1006a53be2bf794ccc6420c755..c9c6f03515269aa78baad42ecf86f4d649a45a5c 100644 (file)
@@ -95,7 +95,8 @@ static unsigned long *btree_node_alloc(struct btree_head *head, gfp_t gfp)
        unsigned long *node;
 
        node = mempool_alloc(head->mempool, gfp);
-       memset(node, 0, NODESIZE);
+       if (likely(node))
+               memset(node, 0, NODESIZE);
        return node;
 }
 
index 7bb4142a502f3a8ceb57fb9e24d24d8bfe81332d..05d6aca7fc1905defed315f2f14df86d231741b6 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/bitops.h>
 #include <linux/cpumask.h>
index 0f45fbff34cb970b68dd4642eb30b67d3857a31e..bc5b936e9142c51eb7c3be5bef8a2e2f7fa3e09b 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/module.h>
 #include <linux/compiler.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <asm/atomic.h>
 #include "crc32defs.h"
index a9a8996d286a8e64f5ac23aec220b7645356cfac..deebcc57d4e6a77e334dacb3b46c703e5c673515 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include <linux/hash.h>
 
 #define ODEBUG_HASH_BITS       14
@@ -140,6 +141,7 @@ alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr)
                obj->object = addr;
                obj->descr  = descr;
                obj->state  = ODEBUG_STATE_NONE;
+               obj->astate = 0;
                hlist_del(&obj->node);
 
                hlist_add_head(&obj->node, &b->list);
@@ -251,8 +253,10 @@ static void debug_print_object(struct debug_obj *obj, char *msg)
 
        if (limit < 5 && obj->descr != descr_test) {
                limit++;
-               WARN(1, KERN_ERR "ODEBUG: %s %s object type: %s\n", msg,
-                      obj_states[obj->state], obj->descr->name);
+               WARN(1, KERN_ERR "ODEBUG: %s %s (active state %u) "
+                                "object type: %s\n",
+                       msg, obj_states[obj->state], obj->astate,
+                       obj->descr->name);
        }
        debug_objects_warnings++;
 }
@@ -446,7 +450,10 @@ void debug_object_deactivate(void *addr, struct debug_obj_descr *descr)
                case ODEBUG_STATE_INIT:
                case ODEBUG_STATE_INACTIVE:
                case ODEBUG_STATE_ACTIVE:
-                       obj->state = ODEBUG_STATE_INACTIVE;
+                       if (!obj->astate)
+                               obj->state = ODEBUG_STATE_INACTIVE;
+                       else
+                               debug_print_object(obj, "deactivate");
                        break;
 
                case ODEBUG_STATE_DESTROYED:
@@ -552,6 +559,53 @@ out_unlock:
        raw_spin_unlock_irqrestore(&db->lock, flags);
 }
 
+/**
+ * debug_object_active_state - debug checks object usage state machine
+ * @addr:      address of the object
+ * @descr:     pointer to an object specific debug description structure
+ * @expect:    expected state
+ * @next:      state to move to if expected state is found
+ */
+void
+debug_object_active_state(void *addr, struct debug_obj_descr *descr,
+                         unsigned int expect, unsigned int next)
+{
+       struct debug_bucket *db;
+       struct debug_obj *obj;
+       unsigned long flags;
+
+       if (!debug_objects_enabled)
+               return;
+
+       db = get_bucket((unsigned long) addr);
+
+       raw_spin_lock_irqsave(&db->lock, flags);
+
+       obj = lookup_object(addr, db);
+       if (obj) {
+               switch (obj->state) {
+               case ODEBUG_STATE_ACTIVE:
+                       if (obj->astate == expect)
+                               obj->astate = next;
+                       else
+                               debug_print_object(obj, "active_state");
+                       break;
+
+               default:
+                       debug_print_object(obj, "active_state");
+                       break;
+               }
+       } else {
+               struct debug_obj o = { .object = addr,
+                                      .state = ODEBUG_STATE_NOTAVAILABLE,
+                                      .descr = descr };
+
+               debug_print_object(&o, "active_state");
+       }
+
+       raw_spin_unlock_irqrestore(&db->lock, flags);
+}
+
 #ifdef CONFIG_DEBUG_OBJECTS_FREE
 static void __debug_check_no_obj_freed(const void *address, unsigned long size)
 {
@@ -773,7 +827,7 @@ static int __init fixup_free(void *addr, enum debug_obj_state state)
        }
 }
 
-static int
+static int __init
 check_results(void *addr, enum debug_obj_state state, int fixups, int warnings)
 {
        struct debug_bucket *db;
@@ -916,7 +970,7 @@ void __init debug_objects_early_init(void)
 /*
  * Convert the statically allocated objects to dynamic ones:
  */
-static int debug_objects_replace_static_objects(void)
+static int __init debug_objects_replace_static_objects(void)
 {
        struct debug_bucket *db = obj_hash;
        struct hlist_node *node, *tmp;
index db521f45626e000ff48b08b364a868c7f847c9b5..bcb3a4bd68ff92b22811254e8335a8c67f1abc7c 100644 (file)
@@ -97,7 +97,7 @@ STATIC inline int INIT unlzo(u8 *input, int in_len,
        u32 src_len, dst_len;
        size_t tmp;
        u8 *in_buf, *in_buf_save, *out_buf;
-       int obytes_processed = 0;
+       int ret = -1;
 
        set_error_fn(error_fn);
 
@@ -174,15 +174,22 @@ STATIC inline int INIT unlzo(u8 *input, int in_len,
 
                /* decompress */
                tmp = dst_len;
-               r = lzo1x_decompress_safe((u8 *) in_buf, src_len,
+
+               /* When the input data is not compressed at all,
+                * lzo1x_decompress_safe will fail, so call memcpy()
+                * instead */
+               if (unlikely(dst_len == src_len))
+                       memcpy(out_buf, in_buf, src_len);
+               else {
+                       r = lzo1x_decompress_safe((u8 *) in_buf, src_len,
                                                out_buf, &tmp);
 
-               if (r != LZO_E_OK || dst_len != tmp) {
-                       error("Compressed data violation");
-                       goto exit_2;
+                       if (r != LZO_E_OK || dst_len != tmp) {
+                               error("Compressed data violation");
+                               goto exit_2;
+                       }
                }
 
-               obytes_processed += dst_len;
                if (flush)
                        flush(out_buf, dst_len);
                if (output)
@@ -196,6 +203,7 @@ STATIC inline int INIT unlzo(u8 *input, int in_len,
                        in_buf += src_len;
        }
 
+       ret = 0;
 exit_2:
        if (!input)
                free(in_buf);
@@ -203,7 +211,7 @@ exit_1:
        if (!output)
                free(out_buf);
 exit:
-       return obytes_processed;
+       return ret;
 }
 
 #define decompress unlzo
index 72c8909006da156a41c4a70a1de2562198b45103..49368608f988872da20525722d1406ef3a94a520 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/pci.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 #include <linux/module.h>
 
 void devm_ioremap_release(struct device *dev, void *res)
index ba8b67039d13eac2a81835a92d3241375fb43d3d..01e64270e246bef1070c9e68a3603051b02bf919 100644 (file)
@@ -570,7 +570,7 @@ static ssize_t filter_write(struct file *file, const char __user *userbuf,
         * Now parse out the first token and use it as the name for the
         * driver to filter for.
         */
-       for (i = 0; i < NAME_MAX_LEN; ++i) {
+       for (i = 0; i < NAME_MAX_LEN - 1; ++i) {
                current_driver_name[i] = buf[i];
                if (isspace(buf[i]) || buf[i] == ' ' || buf[i] == 0)
                        break;
index f9350291598825a214068eb338e41f07edffb8c8..d6b8b9b1abfedf5ca023164b76d81ca06d0622a2 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/uaccess.h>
 #include <linux/dynamic_debug.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 
 extern struct _ddebug __start___verbose[];
 extern struct _ddebug __stop___verbose[];
index 66eef2e4483ea50caaecd2afd1e8ca652e5e28d0..41b1804fa728a6cb6d38abd66ce1e71bb05eb1b6 100644 (file)
@@ -99,7 +99,7 @@ struct flex_array *flex_array_alloc(int element_size, unsigned int total,
        ret->element_size = element_size;
        ret->total_nr_elements = total;
        if (elements_fit_in_base(ret) && !(flags & __GFP_ZERO))
-               memset(ret->parts[0], FLEX_ARRAY_FREE,
+               memset(&ret->parts[0], FLEX_ARRAY_FREE,
                                                FLEX_ARRAY_BASE_BYTES_LEFT);
        return ret;
 }
index e67f97495dd53c6a479f0a7a0ac3f2f68814f2e1..736c3b06398e522a7ad3d0ee846d77163436a334 100644 (file)
@@ -10,6 +10,7 @@
  * Version 2.  See the file COPYING for more details.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/bitmap.h>
 #include <linux/genalloc.h>
index 63ee4eb1228d13ff4b712cb8f1dd8385bf9c1bcb..3c79d50814cf1d2af2d1148f067ac03328d7f974 100644 (file)
@@ -9,7 +9,7 @@
  * The Hamming Weight of a number is the total number of bits set in it.
  */
 
-unsigned int hweight32(unsigned int w)
+unsigned int __sw_hweight32(unsigned int w)
 {
 #ifdef ARCH_HAS_FAST_MULTIPLIER
        w -= (w >> 1) & 0x55555555;
@@ -24,29 +24,30 @@ unsigned int hweight32(unsigned int w)
        return (res + (res >> 16)) & 0x000000FF;
 #endif
 }
-EXPORT_SYMBOL(hweight32);
+EXPORT_SYMBOL(__sw_hweight32);
 
-unsigned int hweight16(unsigned int w)
+unsigned int __sw_hweight16(unsigned int w)
 {
        unsigned int res = w - ((w >> 1) & 0x5555);
        res = (res & 0x3333) + ((res >> 2) & 0x3333);
        res = (res + (res >> 4)) & 0x0F0F;
        return (res + (res >> 8)) & 0x00FF;
 }
-EXPORT_SYMBOL(hweight16);
+EXPORT_SYMBOL(__sw_hweight16);
 
-unsigned int hweight8(unsigned int w)
+unsigned int __sw_hweight8(unsigned int w)
 {
        unsigned int res = w - ((w >> 1) & 0x55);
        res = (res & 0x33) + ((res >> 2) & 0x33);
        return (res + (res >> 4)) & 0x0F;
 }
-EXPORT_SYMBOL(hweight8);
+EXPORT_SYMBOL(__sw_hweight8);
 
-unsigned long hweight64(__u64 w)
+unsigned long __sw_hweight64(__u64 w)
 {
 #if BITS_PER_LONG == 32
-       return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
+       return __sw_hweight32((unsigned int)(w >> 32)) +
+              __sw_hweight32((unsigned int)w);
 #elif BITS_PER_LONG == 64
 #ifdef ARCH_HAS_FAST_MULTIPLIER
        w -= (w >> 1) & 0x5555555555555555ul;
@@ -63,4 +64,4 @@ unsigned long hweight64(__u64 w)
 #endif
 #endif
 }
-EXPORT_SYMBOL(hweight64);
+EXPORT_SYMBOL(__sw_hweight64);
index d10255973a9fc8b79df675c684a6532da26694a8..677b738c220458827f2765525739021b9219770d 100644 (file)
       the two sets of lengths.
  */
 #include <linux/compiler.h>
+#include <linux/slab.h>
 
 #ifdef RCSID
 static char rcsid[] = "#Id: inflate.c,v 0.14 1993/06/10 13:27:04 jloup Exp #";
index c5ff1fd1003025a64ce1ce25ef901c7185d2c6c5..9c4233b23783db47322abd1ff7235c764e0cb7f4 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <stdarg.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/string.h>
 
index c9d3a3e8405d884c80eeb6e15a7379f48fd333f6..7b48d44ced6ec2972fdd45cbc2c0d084dcf22f82 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/string.h>
 #include <linux/kobject.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <linux/socket.h>
 #include <linux/skbuff.h>
index 9ecd6e86561034f2a097bcc027765704e124f7df..6d19f690380b8e3020b3a74e8fac3d2713055d0e 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/kref.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 /**
  * kref_set - initialize object and set refcount to requested number.
diff --git a/lib/lcm.c b/lib/lcm.c
new file mode 100644 (file)
index 0000000..157cd88
--- /dev/null
+++ b/lib/lcm.c
@@ -0,0 +1,15 @@
+#include <linux/kernel.h>
+#include <linux/gcd.h>
+#include <linux/module.h>
+
+/* Lowest common multiple */
+unsigned long lcm(unsigned long a, unsigned long b)
+{
+       if (a && b)
+               return (a * b) / gcd(a, b);
+       else if (b)
+               return b;
+
+       return a;
+}
+EXPORT_SYMBOL_GPL(lcm);
index 6b9670d6bbf9e669c5e833514ccb41cb83f014da..2a087e0f98633cf00724ef0ef7b411d9f60b609e 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/slab.h>
 #include <linux/notifier.h>
 #include <linux/cpu.h>
-#include <linux/gfp.h>
 #include <linux/string.h>
 #include <linux/bitops.h>
 #include <linux/rcupdate.h>
@@ -556,6 +555,10 @@ EXPORT_SYMBOL(radix_tree_tag_clear);
  *
  *  0: tag not present or not set
  *  1: tag set
+ *
+ * Note that the return value of this function may not be relied on, even if
+ * the RCU lock is held, unless tag modification and node deletion are excluded
+ * from concurrency.
  */
 int radix_tree_tag_get(struct radix_tree_root *root,
                        unsigned long index, unsigned int tag)
@@ -596,12 +599,8 @@ int radix_tree_tag_get(struct radix_tree_root *root,
                 */
                if (!tag_get(node, tag, offset))
                        saw_unset_tag = 1;
-               if (height == 1) {
-                       int ret = tag_get(node, tag, offset);
-
-                       BUG_ON(ret && saw_unset_tag);
-                       return !!ret;
-               }
+               if (height == 1)
+                       return !!tag_get(node, tag, offset);
                node = rcu_dereference_raw(node->slots[offset]);
                shift -= RADIX_TREE_MAP_SHIFT;
                height--;
index 09f5ce1810dcc02ddb99696d255ed3ad6436f30b..027a03f4c56d4059b23560c984f5699e44e069d8 100644 (file)
 /*
  * __ratelimit - rate limiting
  * @rs: ratelimit_state data
+ * @func: name of calling function
  *
- * This enforces a rate limit: not more than @rs->ratelimit_burst callbacks
- * in every @rs->ratelimit_jiffies
+ * This enforces a rate limit: not more than @rs->burst callbacks
+ * in every @rs->interval
+ *
+ * RETURNS:
+ * 0 means callbacks will be suppressed.
+ * 1 means go ahead and do it.
  */
 int ___ratelimit(struct ratelimit_state *rs, const char *func)
 {
@@ -35,7 +40,7 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func)
         * the entity that is holding the lock already:
         */
        if (!spin_trylock_irqsave(&rs->lock, flags))
-               return 1;
+               return 0;
 
        if (!rs->begin)
                rs->begin = jiffies;
index e2aa3be29858cdcdd69bf4a43a67813db84079ee..15e10b1afdd279aad26ebbf869a5fd824831fe5f 100644 (file)
@@ -44,6 +44,11 @@ static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
        else
                root->rb_node = right;
        rb_set_parent(node, right);
+
+       if (root->augment_cb) {
+               root->augment_cb(node);
+               root->augment_cb(right);
+       }
 }
 
 static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
@@ -67,12 +72,20 @@ static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
        else
                root->rb_node = left;
        rb_set_parent(node, left);
+
+       if (root->augment_cb) {
+               root->augment_cb(node);
+               root->augment_cb(left);
+       }
 }
 
 void rb_insert_color(struct rb_node *node, struct rb_root *root)
 {
        struct rb_node *parent, *gparent;
 
+       if (root->augment_cb)
+               root->augment_cb(node);
+
        while ((parent = rb_parent(node)) && rb_is_red(parent))
        {
                gparent = rb_parent(parent);
@@ -227,12 +240,15 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
        else
        {
                struct rb_node *old = node, *left;
+               int old_parent_cb = 0;
+               int successor_parent_cb = 0;
 
                node = node->rb_right;
                while ((left = node->rb_left) != NULL)
                        node = left;
 
                if (rb_parent(old)) {
+                       old_parent_cb = 1;
                        if (rb_parent(old)->rb_left == old)
                                rb_parent(old)->rb_left = node;
                        else
@@ -247,8 +263,10 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
                if (parent == old) {
                        parent = node;
                } else {
+                       successor_parent_cb = 1;
                        if (child)
                                rb_set_parent(child, parent);
+
                        parent->rb_left = child;
 
                        node->rb_right = old->rb_right;
@@ -259,6 +277,24 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
                node->rb_left = old->rb_left;
                rb_set_parent(old->rb_left, node);
 
+               if (root->augment_cb) {
+                       /*
+                        * Here, three different nodes can have new children.
+                        * The parent of the successor node that was selected
+                        * to replace the node to be erased.
+                        * The node that is getting erased and is now replaced
+                        * by its successor.
+                        * The parent of the node getting erased-replaced.
+                        */
+                       if (successor_parent_cb)
+                               root->augment_cb(parent);
+
+                       root->augment_cb(node);
+
+                       if (old_parent_cb)
+                               root->augment_cb(rb_parent(old));
+               }
+
                goto color;
        }
 
@@ -267,15 +303,19 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 
        if (child)
                rb_set_parent(child, parent);
-       if (parent)
-       {
+
+       if (parent) {
                if (parent->rb_left == node)
                        parent->rb_left = child;
                else
                        parent->rb_right = child;
-       }
-       else
+
+               if (root->augment_cb)
+                       root->augment_cb(parent);
+
+       } else {
                root->rb_node = child;
+       }
 
  color:
        if (color == RB_BLACK)
index ccf95bff798439c7afead0834370864ff41a735c..ffc9fc7f3b051a8f2c9efd6099f930043b22396a 100644 (file)
@@ -143,13 +143,14 @@ void __sched __down_read(struct rw_semaphore *sem)
 {
        struct rwsem_waiter waiter;
        struct task_struct *tsk;
+       unsigned long flags;
 
-       spin_lock_irq(&sem->wait_lock);
+       spin_lock_irqsave(&sem->wait_lock, flags);
 
        if (sem->activity >= 0 && list_empty(&sem->wait_list)) {
                /* granted */
                sem->activity++;
-               spin_unlock_irq(&sem->wait_lock);
+               spin_unlock_irqrestore(&sem->wait_lock, flags);
                goto out;
        }
 
@@ -164,7 +165,7 @@ void __sched __down_read(struct rw_semaphore *sem)
        list_add_tail(&waiter.list, &sem->wait_list);
 
        /* we don't need to touch the semaphore struct anymore */
-       spin_unlock_irq(&sem->wait_lock);
+       spin_unlock_irqrestore(&sem->wait_lock, flags);
 
        /* wait to be given the lock */
        for (;;) {
@@ -209,13 +210,14 @@ void __sched __down_write_nested(struct rw_semaphore *sem, int subclass)
 {
        struct rwsem_waiter waiter;
        struct task_struct *tsk;
+       unsigned long flags;
 
-       spin_lock_irq(&sem->wait_lock);
+       spin_lock_irqsave(&sem->wait_lock, flags);
 
        if (sem->activity == 0 && list_empty(&sem->wait_list)) {
                /* granted */
                sem->activity = -1;
-               spin_unlock_irq(&sem->wait_lock);
+               spin_unlock_irqrestore(&sem->wait_lock, flags);
                goto out;
        }
 
@@ -230,7 +232,7 @@ void __sched __down_write_nested(struct rw_semaphore *sem, int subclass)
        list_add_tail(&waiter.list, &sem->wait_list);
 
        /* we don't need to touch the semaphore struct anymore */
-       spin_unlock_irq(&sem->wait_lock);
+       spin_unlock_irqrestore(&sem->wait_lock, flags);
 
        /* wait to be given the lock */
        for (;;) {
index 3e3365e5665eebf950803b34411f386681157533..ceba8e28807a81c09c551e4f782091efa9bebccf 100644 (file)
@@ -136,9 +136,10 @@ __rwsem_do_wake(struct rw_semaphore *sem, int downgrading)
  out:
        return sem;
 
-       /* undo the change to count, but check for a transition 1->0 */
+       /* undo the change to the active count, but check for a transition
+        * 1->0 */
  undo:
-       if (rwsem_atomic_update(-RWSEM_ACTIVE_BIAS, sem) != 0)
+       if (rwsem_atomic_update(-RWSEM_ACTIVE_BIAS, sem) & RWSEM_ACTIVE_MASK)
                goto out;
        goto try_again;
 }
index 0d475d8167bfd7f4f9909424ea29a72653b581fe..9afa25b52a83f33f0685d94306f1df4def372db4 100644 (file)
@@ -7,6 +7,7 @@
  * Version 2. See the file COPYING for more details.
  */
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/scatterlist.h>
 #include <linux/highmem.h>
 
index 437eedb5a53ba1feae04f98b5def86798462f920..5fddf720da73e42b6568b80f64234e47033bc142 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/types.h>
 #include <linux/ctype.h>
 #include <linux/highmem.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
index 9fbcb44c554f9edbb2b2b439c20d5e18362cdc6d..d608331b3e4798c23607471dea52bbc483c69760 100644 (file)
 #include <linux/rcupdate.h>
 #include <linux/err.h>
 #include <linux/textsearch.h>
+#include <linux/slab.h>
 
 static LIST_HEAD(ts_ops);
 static DEFINE_SPINLOCK(ts_mod_lock);
index 24112e5a5780608eed4855e1ceb3f18c7b371df9..46d34b0b74a873290b0cd9fcfff6c19561c91de4 100644 (file)
@@ -118,6 +118,7 @@ long long simple_strtoll(const char *cp, char **endp, unsigned int base)
 
        return simple_strtoull(cp, endp, base);
 }
+EXPORT_SYMBOL(simple_strtoll);
 
 /**
  * strict_strtoul - convert a string to an unsigned long strictly
@@ -408,12 +409,12 @@ enum format_type {
 };
 
 struct printf_spec {
-       u16     type;
-       s16     field_width;    /* width of output field */
+       u8      type;           /* format_type enum */
        u8      flags;          /* flags to number() */
-       u8      base;
-       s8      precision;      /* # of digits/chars */
-       u8      qualifier;
+       u8      base;           /* number base, 8, 10 or 16 only */
+       u8      qualifier;      /* number qualifier, one of 'hHlLtzZ' */
+       s16     field_width;    /* width of output field */
+       s16     precision;      /* # of digits/chars */
 };
 
 static char *number(char *buf, char *end, unsigned long long num,
index 7a68d2ab556093ab3398cbb95d8386c65357e07a..6c2a73a54a43c2bb6b412ebf7af56d622315a329 100644 (file)
@@ -33,7 +33,11 @@ obj-$(CONFIG_FAILSLAB) += failslab.o
 obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
 obj-$(CONFIG_FS_XIP) += filemap_xip.o
 obj-$(CONFIG_MIGRATION) += migrate.o
-obj-$(CONFIG_SMP) += percpu.o
+ifdef CONFIG_SMP
+obj-y += percpu.o
+else
+obj-y += percpu_up.o
+endif
 obj-$(CONFIG_QUICKLIST) += quicklist.o
 obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o page_cgroup.o
 obj-$(CONFIG_MEMORY_FAILURE) += memory-failure.o
index 0e8ca0347707b62d9cfb35a3fb353f2bf6f79e6a..707d0dc6da0f59a5730f613e2980fefc154c807a 100644 (file)
@@ -11,6 +11,8 @@
 #include <linux/writeback.h>
 #include <linux/device.h>
 
+static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0);
+
 void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
 {
 }
@@ -25,6 +27,11 @@ struct backing_dev_info default_backing_dev_info = {
 };
 EXPORT_SYMBOL_GPL(default_backing_dev_info);
 
+struct backing_dev_info noop_backing_dev_info = {
+       .name           = "noop",
+};
+EXPORT_SYMBOL_GPL(noop_backing_dev_info);
+
 static struct class *bdi_class;
 
 /*
@@ -227,6 +234,9 @@ static struct device_attribute bdi_dev_attrs[] = {
 static __init int bdi_class_init(void)
 {
        bdi_class = class_create(THIS_MODULE, "bdi");
+       if (IS_ERR(bdi_class))
+               return PTR_ERR(bdi_class);
+
        bdi_class->dev_attrs = bdi_dev_attrs;
        bdi_debug_init();
        return 0;
@@ -712,6 +722,33 @@ void bdi_destroy(struct backing_dev_info *bdi)
 }
 EXPORT_SYMBOL(bdi_destroy);
 
+/*
+ * For use from filesystems to quickly init and register a bdi associated
+ * with dirty writeback
+ */
+int bdi_setup_and_register(struct backing_dev_info *bdi, char *name,
+                          unsigned int cap)
+{
+       char tmp[32];
+       int err;
+
+       bdi->name = name;
+       bdi->capabilities = cap;
+       err = bdi_init(bdi);
+       if (err)
+               return err;
+
+       sprintf(tmp, "%.28s%s", name, "-%d");
+       err = bdi_register(bdi, NULL, tmp, atomic_long_inc_return(&bdi_seq));
+       if (err) {
+               bdi_destroy(bdi);
+               return err;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(bdi_setup_and_register);
+
 static wait_queue_head_t congestion_wqh[2] = {
                __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]),
                __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1])
index d7c791ef00367e27ac65f4a51da946abbd45d271..58c66cc5056a7073aabf880116548a9572c2894b 100644 (file)
@@ -10,6 +10,7 @@
  */
 #include <linux/init.h>
 #include <linux/pfn.h>
+#include <linux/slab.h>
 #include <linux/bootmem.h>
 #include <linux/module.h>
 #include <linux/kmemleak.h>
@@ -180,19 +181,12 @@ static void __init __free_pages_memory(unsigned long start, unsigned long end)
        end_aligned = end & ~(BITS_PER_LONG - 1);
 
        if (end_aligned <= start_aligned) {
-#if 1
-               printk(KERN_DEBUG " %lx - %lx\n", start, end);
-#endif
                for (i = start; i < end; i++)
                        __free_pages_bootmem(pfn_to_page(i), 0);
 
                return;
        }
 
-#if 1
-       printk(KERN_DEBUG " %lx %lx - %lx %lx\n",
-                start, start_aligned, end_aligned, end);
-#endif
        for (i = start; i < start_aligned; i++)
                __free_pages_bootmem(pfn_to_page(i), 0);
 
@@ -310,9 +304,22 @@ unsigned long __init free_all_bootmem_node(pg_data_t *pgdat)
 unsigned long __init free_all_bootmem(void)
 {
 #ifdef CONFIG_NO_BOOTMEM
-       return free_all_memory_core_early(NODE_DATA(0)->node_id);
+       /*
+        * We need to use MAX_NUMNODES instead of NODE_DATA(0)->node_id
+        *  because in some case like Node0 doesnt have RAM installed
+        *  low ram will be on Node1
+        * Use MAX_NUMNODES will make sure all ranges in early_node_map[]
+        *  will be used instead of only Node0 related
+        */
+       return free_all_memory_core_early(MAX_NUMNODES);
 #else
-       return free_all_bootmem_core(NODE_DATA(0)->bdata);
+       unsigned long total_pages = 0;
+       bootmem_data_t *bdata;
+
+       list_for_each_entry(bdata, &bdata_list, list)
+               total_pages += free_all_bootmem_core(bdata);
+
+       return total_pages;
 #endif
 }
 
@@ -428,9 +435,6 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
 {
 #ifdef CONFIG_NO_BOOTMEM
        free_early(physaddr, physaddr + size);
-#if 0
-       printk(KERN_DEBUG "free %lx %lx\n", physaddr, size);
-#endif
 #else
        unsigned long start, end;
 
@@ -456,9 +460,6 @@ void __init free_bootmem(unsigned long addr, unsigned long size)
 {
 #ifdef CONFIG_NO_BOOTMEM
        free_early(addr, addr + size);
-#if 0
-       printk(KERN_DEBUG "free %lx %lx\n", addr, size);
-#endif
 #else
        unsigned long start, end;
 
index a2b76a588e348e0d46f2bfed4131af6ac3eea86b..13b6dad1eed272bec61a388d17f116be62cb1bb5 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/swap.h>
+#include <linux/gfp.h>
 #include <linux/bio.h>
 #include <linux/pagemap.h>
 #include <linux/mempool.h>
index bb41f98dd8b700d7ecf1765aa7e76e6cbd6ad97a..c5f88f240ddcfc26a8cb2b2fadf66a3345102a5f 100644 (file)
@@ -1,5 +1,4 @@
 #include <linux/fault-inject.h>
-#include <linux/gfp.h>
 #include <linux/slab.h>
 
 static struct {
index 045b31c37653d133394146c8b49db671ea016591..140ebda9640f64a7f05b58a5d31156cb874a6eb9 100644 (file)
  * the NFS filesystem used to do this differently, for example)
  */
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/compiler.h>
 #include <linux/fs.h>
 #include <linux/uaccess.h>
 #include <linux/aio.h>
 #include <linux/capability.h>
 #include <linux/kernel_stat.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
 #include <linux/mman.h>
index 78b94f0b6d5dbd6e95ac1c5cb44937fc45d13e45..83364df74a33811ea7aea971412bfe91d4fe9c17 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/sched.h>
 #include <linux/seqlock.h>
 #include <linux/mutex.h>
+#include <linux/gfp.h>
 #include <asm/tlbflush.h>
 #include <asm/io.h>
 
index 3a5aeb37c1107ed9735b2e0e943db3212bacaf3c..4c9e6bbf3772c771775057404a1e0f314b90045c 100644 (file)
@@ -2,7 +2,6 @@
  * Generic hugetlb support.
  * (C) William Irwin, April 2004
  */
-#include <linux/gfp.h>
 #include <linux/list.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -18,6 +17,7 @@
 #include <linux/mutex.h>
 #include <linux/bootmem.h>
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -546,6 +546,7 @@ static void free_huge_page(struct page *page)
 
        mapping = (struct address_space *) page_private(page);
        set_page_private(page, 0);
+       page->mapping = NULL;
        BUG_ON(page_count(page));
        INIT_LIST_HEAD(&page->lru);
 
@@ -1038,7 +1039,7 @@ static struct page *alloc_huge_page(struct vm_area_struct *vma,
                page = alloc_buddy_huge_page(h, vma, addr);
                if (!page) {
                        hugetlb_put_quota(inode->i_mapping, chg);
-                       return ERR_PTR(-VM_FAULT_OOM);
+                       return ERR_PTR(-VM_FAULT_SIGBUS);
                }
        }
 
@@ -2447,8 +2448,10 @@ retry:
                        spin_lock(&inode->i_lock);
                        inode->i_blocks += blocks_per_huge_page(h);
                        spin_unlock(&inode->i_lock);
-               } else
+               } else {
                        lock_page(page);
+                       page->mapping = HUGETLB_POISON;
+               }
        }
 
        /*
index 5b069e4f5e485ac8f5906c4a0cad7dbdeef75f7e..2c0d032ac8983b8e59919019e07a97d9f25adad9 100644 (file)
@@ -72,7 +72,6 @@
 #include <linux/module.h>
 #include <linux/kthread.h>
 #include <linux/prio_tree.h>
-#include <linux/gfp.h>
 #include <linux/fs.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
index a93f1b7f508cde17cb0b41f7183641dcfdb7a26f..956880f2ff4927a3f0a124ce6ecab4bd2d380696 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -365,7 +365,7 @@ static int break_ksm(struct vm_area_struct *vma, unsigned long addr)
        do {
                cond_resched();
                page = follow_page(vma, addr, FOLL_GET);
-               if (!page)
+               if (IS_ERR_OR_NULL(page))
                        break;
                if (PageKsm(page))
                        ret = handle_mm_fault(vma->vm_mm, vma, addr,
@@ -447,7 +447,7 @@ static struct page *get_mergeable_page(struct rmap_item *rmap_item)
                goto out;
 
        page = follow_page(vma, addr, FOLL_GET);
-       if (!page)
+       if (IS_ERR_OR_NULL(page))
                goto out;
        if (PageAnon(page)) {
                flush_anon_page(vma, page, addr);
@@ -751,7 +751,7 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page,
                 * page
                 */
                if (page_mapcount(page) + 1 + swapped != page_count(page)) {
-                       set_pte_at_notify(mm, addr, ptep, entry);
+                       set_pte_at(mm, addr, ptep, entry);
                        goto out_unlock;
                }
                entry = pte_wrprotect(entry);
@@ -1086,7 +1086,7 @@ struct rmap_item *unstable_tree_search_insert(struct rmap_item *rmap_item,
                cond_resched();
                tree_rmap_item = rb_entry(*new, struct rmap_item, node);
                tree_page = get_mergeable_page(tree_rmap_item);
-               if (!tree_page)
+               if (IS_ERR_OR_NULL(tree_page))
                        return NULL;
 
                /*
@@ -1294,7 +1294,7 @@ next_mm:
                        if (ksm_test_exit(mm))
                                break;
                        *page = follow_page(vma, ksm_scan.address, FOLL_GET);
-                       if (*page && PageAnon(*page)) {
+                       if (!IS_ERR_OR_NULL(*page) && PageAnon(*page)) {
                                flush_anon_page(vma, *page, ksm_scan.address);
                                flush_dcache_page(*page);
                                rmap_item = get_next_rmap_item(slot,
@@ -1308,7 +1308,7 @@ next_mm:
                                up_read(&mm->mmap_sem);
                                return rmap_item;
                        }
-                       if (*page)
+                       if (!IS_ERR_OR_NULL(*page))
                                put_page(*page);
                        ksm_scan.address += PAGE_SIZE;
                        cond_resched();
@@ -1367,7 +1367,7 @@ next_mm:
 static void ksm_do_scan(unsigned int scan_npages)
 {
        struct rmap_item *rmap_item;
-       struct page *page;
+       struct page *uninitialized_var(page);
 
        while (scan_npages--) {
                cond_resched();
index 7973b5221fb8e86b816c8e9667aff5f6c5fa7e21..8a79a6f0f029842860fae7cd9b15c8c90600d56c 100644 (file)
@@ -1359,16 +1359,19 @@ void mem_cgroup_update_file_mapped(struct page *page, int val)
 
        lock_page_cgroup(pc);
        mem = pc->mem_cgroup;
-       if (!mem)
-               goto done;
-
-       if (!PageCgroupUsed(pc))
+       if (!mem || !PageCgroupUsed(pc))
                goto done;
 
        /*
         * Preemption is already disabled. We can use __this_cpu_xxx
         */
-       __this_cpu_add(mem->stat->count[MEM_CGROUP_STAT_FILE_MAPPED], val);
+       if (val > 0) {
+               __this_cpu_inc(mem->stat->count[MEM_CGROUP_STAT_FILE_MAPPED]);
+               SetPageCgroupFileMapped(pc);
+       } else {
+               __this_cpu_dec(mem->stat->count[MEM_CGROUP_STAT_FILE_MAPPED]);
+               ClearPageCgroupFileMapped(pc);
+       }
 
 done:
        unlock_page_cgroup(pc);
@@ -1598,7 +1601,6 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
                         * There is a small race that "from" or "to" can be
                         * freed by rmdir, so we use css_tryget().
                         */
-                       rcu_read_lock();
                        from = mc.from;
                        to = mc.to;
                        if (from && css_tryget(&from->css)) {
@@ -1619,7 +1621,6 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
                                        do_continue = (to == mem_over_limit);
                                css_put(&to->css);
                        }
-                       rcu_read_unlock();
                        if (do_continue) {
                                DEFINE_WAIT(wait);
                                prepare_to_wait(&mc.waitq, &wait,
@@ -1801,16 +1802,13 @@ static void __mem_cgroup_commit_charge(struct mem_cgroup *mem,
 static void __mem_cgroup_move_account(struct page_cgroup *pc,
        struct mem_cgroup *from, struct mem_cgroup *to, bool uncharge)
 {
-       struct page *page;
-
        VM_BUG_ON(from == to);
        VM_BUG_ON(PageLRU(pc->page));
        VM_BUG_ON(!PageCgroupLocked(pc));
        VM_BUG_ON(!PageCgroupUsed(pc));
        VM_BUG_ON(pc->mem_cgroup != from);
 
-       page = pc->page;
-       if (page_mapped(page) && !PageAnon(page)) {
+       if (PageCgroupFileMapped(pc)) {
                /* Update mapped_file data for mem_cgroup */
                preempt_disable();
                __this_cpu_dec(from->stat->count[MEM_CGROUP_STAT_FILE_MAPPED]);
@@ -2429,11 +2427,11 @@ int mem_cgroup_prepare_migration(struct page *page, struct mem_cgroup **ptr)
        }
        unlock_page_cgroup(pc);
 
+       *ptr = mem;
        if (mem) {
-               ret = __mem_cgroup_try_charge(NULL, GFP_KERNEL, &mem, false);
+               ret = __mem_cgroup_try_charge(NULL, GFP_KERNEL, ptr, false);
                css_put(&mem->css);
        }
-       *ptr = mem;
        return ret;
 }
 
@@ -3691,8 +3689,10 @@ static struct mem_cgroup *mem_cgroup_alloc(void)
        else
                mem = vmalloc(size);
 
-       if (mem)
-               memset(mem, 0, size);
+       if (!mem)
+               return NULL;
+
+       memset(mem, 0, size);
        mem->stat = alloc_percpu(struct mem_cgroup_stat_cpu);
        if (!mem->stat) {
                if (size < PAGE_SIZE)
@@ -3946,28 +3946,6 @@ one_by_one:
        }
        return ret;
 }
-#else  /* !CONFIG_MMU */
-static int mem_cgroup_can_attach(struct cgroup_subsys *ss,
-                               struct cgroup *cgroup,
-                               struct task_struct *p,
-                               bool threadgroup)
-{
-       return 0;
-}
-static void mem_cgroup_cancel_attach(struct cgroup_subsys *ss,
-                               struct cgroup *cgroup,
-                               struct task_struct *p,
-                               bool threadgroup)
-{
-}
-static void mem_cgroup_move_task(struct cgroup_subsys *ss,
-                               struct cgroup *cont,
-                               struct cgroup *old_cont,
-                               struct task_struct *p,
-                               bool threadgroup)
-{
-}
-#endif
 
 /**
  * is_target_pte_for_mc - check a pte whether it is valid for move charge
@@ -4330,6 +4308,28 @@ static void mem_cgroup_move_task(struct cgroup_subsys *ss,
        }
        mem_cgroup_clear_mc();
 }
+#else  /* !CONFIG_MMU */
+static int mem_cgroup_can_attach(struct cgroup_subsys *ss,
+                               struct cgroup *cgroup,
+                               struct task_struct *p,
+                               bool threadgroup)
+{
+       return 0;
+}
+static void mem_cgroup_cancel_attach(struct cgroup_subsys *ss,
+                               struct cgroup *cgroup,
+                               struct task_struct *p,
+                               bool threadgroup)
+{
+}
+static void mem_cgroup_move_task(struct cgroup_subsys *ss,
+                               struct cgroup *cont,
+                               struct cgroup *old_cont,
+                               struct task_struct *p,
+                               bool threadgroup)
+{
+}
+#endif
 
 struct cgroup_subsys mem_cgroup_subsys = {
        .name = "memory",
index d1f3351629766ffe112e3f904565ed3035412774..620b0b461593afb124fc3174508b55993fe1f782 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/migrate.h>
 #include <linux/page-isolation.h>
 #include <linux/suspend.h>
+#include <linux/slab.h>
 #include "internal.h"
 
 int sysctl_memory_failure_early_kill __read_mostly = 0;
index 5b7f2002e54b17e8d9b67e75cff0aaa06c9296b4..833952d8b74d3a8ec8a3750bf664dba2d02671ed 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/kallsyms.h>
 #include <linux/swapops.h>
 #include <linux/elf.h>
+#include <linux/gfp.h>
 
 #include <asm/io.h>
 #include <asm/pgalloc.h>
@@ -124,7 +125,7 @@ core_initcall(init_zero_pfn);
 
 #if defined(SPLIT_RSS_COUNTING)
 
-void __sync_task_rss_stat(struct task_struct *task, struct mm_struct *mm)
+static void __sync_task_rss_stat(struct task_struct *task, struct mm_struct *mm)
 {
        int i;
 
index 643f66e101878015cbea8b3dc9ac1eb948d2d702..08f40a2f3fe0aef1819636d5983b3242758463e9 100644 (file)
@@ -73,7 +73,6 @@
 #include <linux/sched.h>
 #include <linux/nodemask.h>
 #include <linux/cpuset.h>
-#include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/module.h>
@@ -806,9 +805,13 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask,
 
        err = 0;
        if (nmask) {
-               task_lock(current);
-               get_policy_nodemask(pol, nmask);
-               task_unlock(current);
+               if (mpol_store_user_nodemask(pol)) {
+                       *nmask = pol->w.user_nodemask;
+               } else {
+                       task_lock(current);
+                       get_policy_nodemask(pol, nmask);
+                       task_unlock(current);
+               }
        }
 
  out:
@@ -2195,8 +2198,8 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
                        char *rest = nodelist;
                        while (isdigit(*rest))
                                rest++;
-                       if (!*rest)
-                               err = 0;
+                       if (*rest)
+                               goto out;
                }
                break;
        case MPOL_INTERLEAVE:
@@ -2205,7 +2208,6 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
                 */
                if (!nodelist)
                        nodes = node_states[N_HIGH_MEMORY];
-               err = 0;
                break;
        case MPOL_LOCAL:
                /*
@@ -2215,11 +2217,19 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
                        goto out;
                mode = MPOL_PREFERRED;
                break;
-
-       /*
-        * case MPOL_BIND:    mpol_new() enforces non-empty nodemask.
-        * case MPOL_DEFAULT: mpol_new() enforces empty nodemask, ignores flags.
-        */
+       case MPOL_DEFAULT:
+               /*
+                * Insist on a empty nodelist
+                */
+               if (!nodelist)
+                       err = 0;
+               goto out;
+       case MPOL_BIND:
+               /*
+                * Insist on a nodelist
+                */
+               if (!nodelist)
+                       goto out;
        }
 
        mode_flags = 0;
@@ -2233,13 +2243,14 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
                else if (!strcmp(flags, "relative"))
                        mode_flags |= MPOL_F_RELATIVE_NODES;
                else
-                       err = 1;
+                       goto out;
        }
 
        new = mpol_new(mode, mode_flags, &nodes);
        if (IS_ERR(new))
-               err = 1;
-       else {
+               goto out;
+
+       {
                int ret;
                NODEMASK_SCRATCH(scratch);
                if (scratch) {
@@ -2250,13 +2261,15 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context)
                        ret = -ENOMEM;
                NODEMASK_SCRATCH_FREE(scratch);
                if (ret) {
-                       err = 1;
                        mpol_put(new);
-               } else if (no_context) {
-                       /* save for contextualization */
-                       new->w.user_nodemask = nodes;
+                       goto out;
                }
        }
+       err = 0;
+       if (no_context) {
+               /* save for contextualization */
+               new->w.user_nodemask = nodes;
+       }
 
 out:
        /* Restore string for error message */
index 88000b89fc9a567768509926b7baf5dc44d2d7d7..d3f3f7f81075eb1eb2e7f5dbe2c0f292a489dacf 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/security.h>
 #include <linux/memcontrol.h>
 #include <linux/syscalls.h>
+#include <linux/gfp.h>
 
 #include "internal.h"
 
index 7a3436ef39eba1ace01efca158e93599aaea5bb7..f77433c20279d95c2a87ce7117888e63580c8922 100644 (file)
@@ -7,8 +7,8 @@
 /*
  * The mincore() system call.
  */
-#include <linux/slab.h>
 #include <linux/pagemap.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/syscalls.h>
index 8f4e2dfceec1c88e796a6bafb78e7422f06bdb72..3f82720e05153a59e2fbb566942121763fc9a44d 100644 (file)
@@ -607,44 +607,3 @@ void user_shm_unlock(size_t size, struct user_struct *user)
        spin_unlock(&shmlock_user_lock);
        free_uid(user);
 }
-
-int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim,
-                         size_t size)
-{
-       unsigned long lim, vm, pgsz;
-       int error = -ENOMEM;
-
-       pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT;
-
-       down_write(&mm->mmap_sem);
-
-       lim = ACCESS_ONCE(rlim[RLIMIT_AS].rlim_cur) >> PAGE_SHIFT;
-       vm   = mm->total_vm + pgsz;
-       if (lim < vm)
-               goto out;
-
-       lim = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur) >> PAGE_SHIFT;
-       vm   = mm->locked_vm + pgsz;
-       if (lim < vm)
-               goto out;
-
-       mm->total_vm  += pgsz;
-       mm->locked_vm += pgsz;
-
-       error = 0;
- out:
-       up_write(&mm->mmap_sem);
-       return error;
-}
-
-void refund_locked_memory(struct mm_struct *mm, size_t size)
-{
-       unsigned long pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT;
-
-       down_write(&mm->mmap_sem);
-
-       mm->total_vm  -= pgsz;
-       mm->locked_vm -= pgsz;
-
-       up_write(&mm->mmap_sem);
-}
index 75557c639ad419c49aff37f1a57de548077f702d..456ec6f278897a560bd915e6d84297ac3de7ddef 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -507,11 +507,12 @@ int vma_adjust(struct vm_area_struct *vma, unsigned long start,
        struct address_space *mapping = NULL;
        struct prio_tree_root *root = NULL;
        struct file *file = vma->vm_file;
-       struct anon_vma *anon_vma = NULL;
        long adjust_next = 0;
        int remove_next = 0;
 
        if (next && !insert) {
+               struct vm_area_struct *exporter = NULL;
+
                if (end >= next->vm_end) {
                        /*
                         * vma expands, overlapping all the next, and
@@ -519,7 +520,7 @@ int vma_adjust(struct vm_area_struct *vma, unsigned long start,
                         */
 again:                 remove_next = 1 + (end > next->vm_end);
                        end = next->vm_end;
-                       anon_vma = next->anon_vma;
+                       exporter = next;
                        importer = vma;
                } else if (end > next->vm_start) {
                        /*
@@ -527,7 +528,7 @@ again:                      remove_next = 1 + (end > next->vm_end);
                         * mprotect case 5 shifting the boundary up.
                         */
                        adjust_next = (end - next->vm_start) >> PAGE_SHIFT;
-                       anon_vma = next->anon_vma;
+                       exporter = next;
                        importer = vma;
                } else if (end < vma->vm_end) {
                        /*
@@ -536,28 +537,19 @@ again:                    remove_next = 1 + (end > next->vm_end);
                         * mprotect case 4 shifting the boundary down.
                         */
                        adjust_next = - ((vma->vm_end - end) >> PAGE_SHIFT);
-                       anon_vma = next->anon_vma;
+                       exporter = vma;
                        importer = next;
                }
-       }
 
-       /*
-        * When changing only vma->vm_end, we don't really need anon_vma lock.
-        */
-       if (vma->anon_vma && (insert || importer || start != vma->vm_start))
-               anon_vma = vma->anon_vma;
-       if (anon_vma) {
                /*
                 * Easily overlooked: when mprotect shifts the boundary,
                 * make sure the expanding vma has anon_vma set if the
                 * shrinking vma had, to cover any anon pages imported.
                 */
-               if (importer && !importer->anon_vma) {
-                       /* Block reverse map lookups until things are set up. */
-                       if (anon_vma_clone(importer, vma)) {
+               if (exporter && exporter->anon_vma && !importer->anon_vma) {
+                       if (anon_vma_clone(importer, exporter))
                                return -ENOMEM;
-                       }
-                       importer->anon_vma = anon_vma;
+                       importer->anon_vma = exporter->anon_vma;
                }
        }
 
@@ -824,6 +816,61 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
        return NULL;
 }
 
+/*
+ * Rough compatbility check to quickly see if it's even worth looking
+ * at sharing an anon_vma.
+ *
+ * They need to have the same vm_file, and the flags can only differ
+ * in things that mprotect may change.
+ *
+ * NOTE! The fact that we share an anon_vma doesn't _have_ to mean that
+ * we can merge the two vma's. For example, we refuse to merge a vma if
+ * there is a vm_ops->close() function, because that indicates that the
+ * driver is doing some kind of reference counting. But that doesn't
+ * really matter for the anon_vma sharing case.
+ */
+static int anon_vma_compatible(struct vm_area_struct *a, struct vm_area_struct *b)
+{
+       return a->vm_end == b->vm_start &&
+               mpol_equal(vma_policy(a), vma_policy(b)) &&
+               a->vm_file == b->vm_file &&
+               !((a->vm_flags ^ b->vm_flags) & ~(VM_READ|VM_WRITE|VM_EXEC)) &&
+               b->vm_pgoff == a->vm_pgoff + ((b->vm_start - a->vm_start) >> PAGE_SHIFT);
+}
+
+/*
+ * Do some basic sanity checking to see if we can re-use the anon_vma
+ * from 'old'. The 'a'/'b' vma's are in VM order - one of them will be
+ * the same as 'old', the other will be the new one that is trying
+ * to share the anon_vma.
+ *
+ * NOTE! This runs with mm_sem held for reading, so it is possible that
+ * the anon_vma of 'old' is concurrently in the process of being set up
+ * by another page fault trying to merge _that_. But that's ok: if it
+ * is being set up, that automatically means that it will be a singleton
+ * acceptable for merging, so we can do all of this optimistically. But
+ * we do that ACCESS_ONCE() to make sure that we never re-load the pointer.
+ *
+ * IOW: that the "list_is_singular()" test on the anon_vma_chain only
+ * matters for the 'stable anon_vma' case (ie the thing we want to avoid
+ * is to return an anon_vma that is "complex" due to having gone through
+ * a fork).
+ *
+ * We also make sure that the two vma's are compatible (adjacent,
+ * and with the same memory policies). That's all stable, even with just
+ * a read lock on the mm_sem.
+ */
+static struct anon_vma *reusable_anon_vma(struct vm_area_struct *old, struct vm_area_struct *a, struct vm_area_struct *b)
+{
+       if (anon_vma_compatible(a, b)) {
+               struct anon_vma *anon_vma = ACCESS_ONCE(old->anon_vma);
+
+               if (anon_vma && list_is_singular(&old->anon_vma_chain))
+                       return anon_vma;
+       }
+       return NULL;
+}
+
 /*
  * find_mergeable_anon_vma is used by anon_vma_prepare, to check
  * neighbouring vmas for a suitable anon_vma, before it goes off
@@ -834,28 +881,16 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
  */
 struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *vma)
 {
+       struct anon_vma *anon_vma;
        struct vm_area_struct *near;
-       unsigned long vm_flags;
 
        near = vma->vm_next;
        if (!near)
                goto try_prev;
 
-       /*
-        * Since only mprotect tries to remerge vmas, match flags
-        * which might be mprotected into each other later on.
-        * Neither mlock nor madvise tries to remerge at present,
-        * so leave their flags as obstructing a merge.
-        */
-       vm_flags = vma->vm_flags & ~(VM_READ|VM_WRITE|VM_EXEC);
-       vm_flags |= near->vm_flags & (VM_READ|VM_WRITE|VM_EXEC);
-
-       if (near->anon_vma && vma->vm_end == near->vm_start &&
-                       mpol_equal(vma_policy(vma), vma_policy(near)) &&
-                       can_vma_merge_before(near, vm_flags,
-                               NULL, vma->vm_file, vma->vm_pgoff +
-                               ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT)))
-               return near->anon_vma;
+       anon_vma = reusable_anon_vma(near, vma, near);
+       if (anon_vma)
+               return anon_vma;
 try_prev:
        /*
         * It is potentially slow to have to call find_vma_prev here.
@@ -868,14 +903,9 @@ try_prev:
        if (!near)
                goto none;
 
-       vm_flags = vma->vm_flags & ~(VM_READ|VM_WRITE|VM_EXEC);
-       vm_flags |= near->vm_flags & (VM_READ|VM_WRITE|VM_EXEC);
-
-       if (near->anon_vma && near->vm_end == vma->vm_start &&
-                       mpol_equal(vma_policy(near), vma_policy(vma)) &&
-                       can_vma_merge_after(near, vm_flags,
-                               NULL, vma->vm_file, vma->vm_pgoff))
-               return near->anon_vma;
+       anon_vma = reusable_anon_vma(near, near, vma);
+       if (anon_vma)
+               return anon_vma;
 none:
        /*
         * There's no absolute need to look only at touching neighbours:
@@ -1947,7 +1977,8 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
                return 0;
 
        /* Clean everything up if vma_adjust failed. */
-       new->vm_ops->close(new);
+       if (new->vm_ops && new->vm_ops->close)
+               new->vm_ops->close(new);
        if (new->vm_file) {
                if (vma->vm_flags & VM_EXECUTABLE)
                        removed_exe_file_vma(mm);
index 0777654147c9d0e3fd0b676771dc5052bcab9455..9e82e937000e19f8210b10886457a3d82ee0870b 100644 (file)
@@ -53,6 +53,7 @@ void unuse_mm(struct mm_struct *mm)
        struct task_struct *tsk = current;
 
        task_lock(tsk);
+       sync_mm_rss(tsk, mm);
        tsk->mm = NULL;
        /* active_mm is still 'mm' */
        enter_lazy_tlb(mm, tsk);
index 7e33f2cb3c774ee960630032c4797c872f598ba8..438951d366f27cb449d7872f40ced3f791186f07 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/rcupdate.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 /*
  * This function can't run concurrently against mmu_notifier_register
index 8bc969d8112d28adb32b3754d339820739e2ba8c..2d1bf7cf885179af5144f41998d95dc2d2b72981 100644 (file)
@@ -10,7 +10,6 @@
 
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
-#include <linux/slab.h>
 #include <linux/shm.h>
 #include <linux/mman.h>
 #include <linux/fs.h>
index e9c75efce60938a82821d24dedf0702ea5d0a50b..cde56ee51ef7a6b10e18f860bd7be08df07f2407 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
-#include <linux/slab.h>
 #include <linux/shm.h>
 #include <linux/ksm.h>
 #include <linux/mman.h>
index 605ace8982a8dcbc14ac061ab824166a16220180..63fa17d121f027ca5c75f09eab994db346316d2b 100644 (file)
@@ -146,7 +146,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                        (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
 
        for (i = 0; i < nr_pages; i++) {
-               vma = find_extend_vma(mm, start);
+               vma = find_vma(mm, start);
                if (!vma)
                        goto finish_or_fault;
 
@@ -162,7 +162,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                }
                if (vmas)
                        vmas[i] = vma;
-               start += PAGE_SIZE;
+               start = (start + PAGE_SIZE) & PAGE_MASK;
        }
 
        return i;
@@ -764,7 +764,7 @@ EXPORT_SYMBOL(find_vma);
  */
 struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
 {
-       return find_vma(mm, addr & PAGE_MASK);
+       return find_vma(mm, addr);
 }
 
 /*
@@ -1040,10 +1040,9 @@ static int do_mmap_shared_file(struct vm_area_struct *vma)
        if (ret != -ENOSYS)
                return ret;
 
-       /* getting an ENOSYS error indicates that direct mmap isn't
-        * possible (as opposed to tried but failed) so we'll fall
-        * through to making a private copy of the data and mapping
-        * that if we can */
+       /* getting -ENOSYS indicates that direct mmap isn't possible (as
+        * opposed to tried but failed) so we can only give a suitable error as
+        * it's not possible to make a private copy if MAP_SHARED was given */
        return -ENODEV;
 }
 
index 9b223af6a147f6fc82b22c58d1d878f09fb80053..b68e802a7a7d6961a0c1f7709a9cc606d022371c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/oom.h>
 #include <linux/mm.h>
 #include <linux/err.h>
+#include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/swap.h>
 #include <linux/timex.h>
index 3dd88539a0e6b47876ec87a91ee093533e1392c9..6c0081441a326a174f83ebd66485bd9cb961f88d 100644 (file)
@@ -284,6 +284,7 @@ static DEFINE_MUTEX(swap_cgroup_mutex);
 struct swap_cgroup_ctrl {
        struct page **map;
        unsigned long length;
+       spinlock_t      lock;
 };
 
 struct swap_cgroup_ctrl swap_cgroup_ctrl[MAX_SWAPFILES];
@@ -353,16 +354,22 @@ unsigned short swap_cgroup_cmpxchg(swp_entry_t ent,
        struct swap_cgroup_ctrl *ctrl;
        struct page *mappage;
        struct swap_cgroup *sc;
+       unsigned long flags;
+       unsigned short retval;
 
        ctrl = &swap_cgroup_ctrl[type];
 
        mappage = ctrl->map[idx];
        sc = page_address(mappage);
        sc += pos;
-       if (cmpxchg(&sc->id, old, new) == old)
-               return old;
+       spin_lock_irqsave(&ctrl->lock, flags);
+       retval = sc->id;
+       if (retval == old)
+               sc->id = new;
        else
-               return 0;
+               retval = 0;
+       spin_unlock_irqrestore(&ctrl->lock, flags);
+       return retval;
 }
 
 /**
@@ -383,13 +390,17 @@ unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id)
        struct page *mappage;
        struct swap_cgroup *sc;
        unsigned short old;
+       unsigned long flags;
 
        ctrl = &swap_cgroup_ctrl[type];
 
        mappage = ctrl->map[idx];
        sc = page_address(mappage);
        sc += pos;
-       old = xchg(&sc->id, id);
+       spin_lock_irqsave(&ctrl->lock, flags);
+       old = sc->id;
+       sc->id = id;
+       spin_unlock_irqrestore(&ctrl->lock, flags);
 
        return old;
 }
@@ -441,6 +452,7 @@ int swap_cgroup_swapon(int type, unsigned long max_pages)
        mutex_lock(&swap_cgroup_mutex);
        ctrl->length = length;
        ctrl->map = array;
+       spin_lock_init(&ctrl->lock);
        if (swap_cgroup_prepare(type)) {
                /* memory shortage */
                ctrl->map = NULL;
index a19af956ee1bb6f55d87df3a3905a486820a49a7..31a3b962230a930cecab5d223f43d6d790f2610a 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/mm.h>
 #include <linux/kernel_stat.h>
+#include <linux/gfp.h>
 #include <linux/pagemap.h>
 #include <linux/swap.h>
 #include <linux/bio.h>
index 7b47a57b66462dae3d9ae42929a1bba543d2c290..8b1a2ce21ee53f3a6ea598759faf02c21c4c5dd2 100644 (file)
@@ -80,6 +80,37 @@ static int walk_pud_range(pgd_t *pgd, unsigned long addr, unsigned long end,
        return err;
 }
 
+#ifdef CONFIG_HUGETLB_PAGE
+static unsigned long hugetlb_entry_end(struct hstate *h, unsigned long addr,
+                                      unsigned long end)
+{
+       unsigned long boundary = (addr & huge_page_mask(h)) + huge_page_size(h);
+       return boundary < end ? boundary : end;
+}
+
+static int walk_hugetlb_range(struct vm_area_struct *vma,
+                             unsigned long addr, unsigned long end,
+                             struct mm_walk *walk)
+{
+       struct hstate *h = hstate_vma(vma);
+       unsigned long next;
+       unsigned long hmask = huge_page_mask(h);
+       pte_t *pte;
+       int err = 0;
+
+       do {
+               next = hugetlb_entry_end(h, addr, end);
+               pte = huge_pte_offset(walk->mm, addr & hmask);
+               if (pte && walk->hugetlb_entry)
+                       err = walk->hugetlb_entry(pte, hmask, addr, next, walk);
+               if (err)
+                       return err;
+       } while (addr = next, addr != end);
+
+       return 0;
+}
+#endif
+
 /**
  * walk_page_range - walk a memory map's page tables with a callback
  * @mm: memory map to walk
@@ -128,20 +159,16 @@ int walk_page_range(unsigned long addr, unsigned long end,
                vma = find_vma(walk->mm, addr);
 #ifdef CONFIG_HUGETLB_PAGE
                if (vma && is_vm_hugetlb_page(vma)) {
-                       pte_t *pte;
-                       struct hstate *hs;
-
                        if (vma->vm_end < next)
                                next = vma->vm_end;
-                       hs = hstate_vma(vma);
-                       pte = huge_pte_offset(walk->mm,
-                                             addr & huge_page_mask(hs));
-                       if (pte && !huge_pte_none(huge_ptep_get(pte))
-                           && walk->hugetlb_entry)
-                               err = walk->hugetlb_entry(pte, addr,
-                                                         next, walk);
+                       /*
+                        * Hugepage is very tightly coupled with vma, so
+                        * walk through hugetlb entries within a given vma.
+                        */
+                       err = walk_hugetlb_range(vma, addr, next, walk);
                        if (err)
                                break;
+                       pgd = pgd_offset(walk->mm, next);
                        continue;
                }
 #endif
index 768419d44ad7b2b80e38b49927965b191a2f7704..6e09741ddc628bf53f4efc338fb4d2636b1b473e 100644 (file)
@@ -1303,6 +1303,32 @@ void free_percpu(void __percpu *ptr)
 }
 EXPORT_SYMBOL_GPL(free_percpu);
 
+/**
+ * is_kernel_percpu_address - test whether address is from static percpu area
+ * @addr: address to test
+ *
+ * Test whether @addr belongs to in-kernel static percpu area.  Module
+ * static percpu areas are not considered.  For those, use
+ * is_module_percpu_address().
+ *
+ * RETURNS:
+ * %true if @addr is from in-kernel static percpu area, %false otherwise.
+ */
+bool is_kernel_percpu_address(unsigned long addr)
+{
+       const size_t static_size = __per_cpu_end - __per_cpu_start;
+       void __percpu *base = __addr_to_pcpu_ptr(pcpu_base_addr);
+       unsigned int cpu;
+
+       for_each_possible_cpu(cpu) {
+               void *start = per_cpu_ptr(base, cpu);
+
+               if ((void *)addr >= start && (void *)addr < start + static_size)
+                       return true;
+        }
+       return false;
+}
+
 /**
  * per_cpu_ptr_to_phys - convert translated percpu address to physical address
  * @addr: the address to be converted to physical address
diff --git a/mm/percpu_up.c b/mm/percpu_up.c
new file mode 100644 (file)
index 0000000..c4351c7
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * mm/percpu_up.c - dummy percpu memory allocator implementation for UP
+ */
+
+#include <linux/module.h>
+#include <linux/percpu.h>
+#include <linux/slab.h>
+
+void __percpu *__alloc_percpu(size_t size, size_t align)
+{
+       /*
+        * Can't easily make larger alignment work with kmalloc.  WARN
+        * on it.  Larger alignment should only be used for module
+        * percpu sections on SMP for which this path isn't used.
+        */
+       WARN_ON_ONCE(align > SMP_CACHE_BYTES);
+       return kzalloc(size, GFP_KERNEL);
+}
+EXPORT_SYMBOL_GPL(__alloc_percpu);
+
+void free_percpu(void __percpu *p)
+{
+       kfree(p);
+}
+EXPORT_SYMBOL_GPL(free_percpu);
+
+phys_addr_t per_cpu_ptr_to_phys(void *addr)
+{
+       return __pa(addr);
+}
index 6633965bb27bcb609be4578dcb8bcd30cd3e39c8..2876349339a7c275a940ea16c688885d13caa29d 100644 (file)
@@ -14,6 +14,7 @@
  */
 #include <linux/kernel.h>
 
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/mmzone.h>
 #include <linux/module.h>
index 337b20e946f6891ed9ae322d22c8e24a1b27f40e..dfa9a1a03a116c7659d0d71134a3450a8d69026f 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/kernel.h>
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/blkdev.h>
@@ -502,7 +503,7 @@ void page_cache_sync_readahead(struct address_space *mapping,
                return;
 
        /* be dumb */
-       if (filp->f_mode & FMODE_RANDOM) {
+       if (filp && (filp->f_mode & FMODE_RANDOM)) {
                force_page_cache_readahead(mapping, filp, offset, req_size);
                return;
        }
index fcd593c9c997153e78737fc9243d84499205590a..0feeef860a8f5b5d61081234f40e8e149e2696f5 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -133,8 +133,8 @@ int anon_vma_prepare(struct vm_area_struct *vma)
                                goto out_enomem_free_avc;
                        allocated = anon_vma;
                }
-               spin_lock(&anon_vma->lock);
 
+               spin_lock(&anon_vma->lock);
                /* page_table_lock to protect against threads */
                spin_lock(&mm->page_table_lock);
                if (likely(!vma->anon_vma)) {
@@ -144,14 +144,15 @@ int anon_vma_prepare(struct vm_area_struct *vma)
                        list_add(&avc->same_vma, &vma->anon_vma_chain);
                        list_add(&avc->same_anon_vma, &anon_vma->head);
                        allocated = NULL;
+                       avc = NULL;
                }
                spin_unlock(&mm->page_table_lock);
-
                spin_unlock(&anon_vma->lock);
-               if (unlikely(allocated)) {
+
+               if (unlikely(allocated))
                        anon_vma_free(allocated);
+               if (unlikely(avc))
                        anon_vma_chain_free(avc);
-               }
        }
        return 0;
 
@@ -182,7 +183,7 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
 {
        struct anon_vma_chain *avc, *pavc;
 
-       list_for_each_entry(pavc, &src->anon_vma_chain, same_vma) {
+       list_for_each_entry_reverse(pavc, &src->anon_vma_chain, same_vma) {
                avc = anon_vma_chain_alloc();
                if (!avc)
                        goto enomem_failure;
@@ -232,6 +233,7 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma)
  out_error_free_anon_vma:
        anon_vma_free(anon_vma);
  out_error:
+       unlink_anon_vmas(vma);
        return -ENOMEM;
 }
 
@@ -334,14 +336,13 @@ vma_address(struct page *page, struct vm_area_struct *vma)
 
 /*
  * At what user virtual address is page expected in vma?
- * checking that the page matches the vma.
+ * Caller should check the page is actually part of the vma.
  */
 unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
 {
-       if (PageAnon(page)) {
-               if (vma->anon_vma != page_anon_vma(page))
-                       return -EFAULT;
-       } else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) {
+       if (PageAnon(page))
+               ;
+       else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) {
                if (!vma->vm_file ||
                    vma->vm_file->f_mapping != page->mapping)
                        return -EFAULT;
@@ -729,13 +730,29 @@ void page_move_anon_rmap(struct page *page,
  * @page:      the page to add the mapping to
  * @vma:       the vm area in which the mapping is added
  * @address:   the user virtual address mapped
+ * @exclusive: the page is exclusively owned by the current process
  */
 static void __page_set_anon_rmap(struct page *page,
-       struct vm_area_struct *vma, unsigned long address)
+       struct vm_area_struct *vma, unsigned long address, int exclusive)
 {
        struct anon_vma *anon_vma = vma->anon_vma;
 
        BUG_ON(!anon_vma);
+
+       /*
+        * If the page isn't exclusively mapped into this vma,
+        * we must use the _oldest_ possible anon_vma for the
+        * page mapping!
+        *
+        * So take the last AVC chain entry in the vma, which is
+        * the deepest ancestor, and use the anon_vma from that.
+        */
+       if (!exclusive) {
+               struct anon_vma_chain *avc;
+               avc = list_entry(vma->anon_vma_chain.prev, struct anon_vma_chain, same_vma);
+               anon_vma = avc->anon_vma;
+       }
+
        anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
        page->mapping = (struct address_space *) anon_vma;
        page->index = linear_page_index(vma, address);
@@ -790,7 +807,7 @@ void page_add_anon_rmap(struct page *page,
        VM_BUG_ON(!PageLocked(page));
        VM_BUG_ON(address < vma->vm_start || address >= vma->vm_end);
        if (first)
-               __page_set_anon_rmap(page, vma, address);
+               __page_set_anon_rmap(page, vma, address, 0);
        else
                __page_check_anon_rmap(page, vma, address);
 }
@@ -812,7 +829,7 @@ void page_add_new_anon_rmap(struct page *page,
        SetPageSwapBacked(page);
        atomic_set(&page->_mapcount, 0); /* increment count (starts at -1) */
        __inc_zone_page_state(page, NR_ANON_PAGES);
-       __page_set_anon_rmap(page, vma, address);
+       __page_set_anon_rmap(page, vma, address, 1);
        if (page_evictable(page, vma))
                lru_cache_add_lru(page, LRU_ACTIVE_ANON);
        else
index a9f325b28bed145a4aab6ff8414b074d3b233280..bac0f4fcc216548fae98d352b0787cf509c0f262 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3602,21 +3602,10 @@ EXPORT_SYMBOL(kmem_cache_alloc_notrace);
  */
 int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr)
 {
-       unsigned long addr = (unsigned long)ptr;
-       unsigned long min_addr = PAGE_OFFSET;
-       unsigned long align_mask = BYTES_PER_WORD - 1;
        unsigned long size = cachep->buffer_size;
        struct page *page;
 
-       if (unlikely(addr < min_addr))
-               goto out;
-       if (unlikely(addr > (unsigned long)high_memory - size))
-               goto out;
-       if (unlikely(addr & align_mask))
-               goto out;
-       if (unlikely(!kern_addr_valid(addr)))
-               goto out;
-       if (unlikely(!kern_addr_valid(addr + size - 1)))
+       if (unlikely(!kern_ptr_validate(ptr, size)))
                goto out;
        page = virt_to_page(ptr);
        if (unlikely(!PageSlab(page)))
index b364844a1068be41e1419fa02746060af67e92bb..d2a54fe71ea22519feada61f181e874685c0a51b 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2153,7 +2153,7 @@ static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags)
        int local_node;
 
        if (slab_state >= UP && (s < kmalloc_caches ||
-                       s > kmalloc_caches + KMALLOC_CACHES))
+                       s >= kmalloc_caches + KMALLOC_CACHES))
                local_node = page_to_nid(virt_to_page(s));
        else
                local_node = 0;
@@ -2386,6 +2386,9 @@ int kmem_ptr_validate(struct kmem_cache *s, const void *object)
 {
        struct page *page;
 
+       if (!kern_ptr_validate(object, s->size))
+               return 0;
+
        page = get_object_page(object);
 
        if (!page || s != page->slab)
index 392b9bb5bc015edfb1a2ce538a1cecbc39c3af94..aa33fd67fa412bee2cef32e18c163d626e88bd00 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/bootmem.h>
 #include <linux/highmem.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/vmalloc.h>
 #include <linux/sched.h>
index 22896d5891330ea7d9756a8e5a28f25eefbd9a81..dc0cc4d43ff3ee37f36d70fbde28feef9d56d62e 100644 (file)
@@ -2,6 +2,7 @@
  * sparse memory mappings.
  */
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/mmzone.h>
 #include <linux/bootmem.h>
 #include <linux/highmem.h>
index 9036b89813aca85fabc8df912760747d14b40ad5..7cd60bf0a972a2f8371774135eb204b7692821cf 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -30,6 +30,7 @@
 #include <linux/notifier.h>
 #include <linux/backing-dev.h>
 #include <linux/memcontrol.h>
+#include <linux/gfp.h>
 
 #include "internal.h"
 
index 6d1daeb1cb4a3dfbcf522919312a67f861085b74..e10f5833167f6d5b564a534484985dc3c7dee745 100644 (file)
@@ -8,6 +8,7 @@
  */
 #include <linux/module.h>
 #include <linux/mm.h>
+#include <linux/gfp.h>
 #include <linux/kernel_stat.h>
 #include <linux/swap.h>
 #include <linux/swapops.h>
index e87e37244829ce03abc22673cda7eeb37f6fff0a..f42675a3615d81ab59e722cc3e3d18b1e1e0525f 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/kernel.h>
 #include <linux/backing-dev.h>
+#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
 #include <linux/module.h>
index 834db7be240f3e10769166396fdec9b2620eeb82..f5712e8964be8a8da2c521361dee71c123689428 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -186,6 +186,27 @@ void kzfree(const void *p)
 }
 EXPORT_SYMBOL(kzfree);
 
+int kern_ptr_validate(const void *ptr, unsigned long size)
+{
+       unsigned long addr = (unsigned long)ptr;
+       unsigned long min_addr = PAGE_OFFSET;
+       unsigned long align_mask = sizeof(void *) - 1;
+
+       if (unlikely(addr < min_addr))
+               goto out;
+       if (unlikely(addr > (unsigned long)high_memory - size))
+               goto out;
+       if (unlikely(addr & align_mask))
+               goto out;
+       if (unlikely(!kern_addr_valid(addr)))
+               goto out;
+       if (unlikely(!kern_addr_valid(addr + size - 1)))
+               goto out;
+       return 1;
+out:
+       return 0;
+}
+
 /*
  * strndup_user - duplicate an existing string from user space
  * @s: The string to duplicate
index 79c809895fba777d6069ae3778046def74a29b81..3ff3311447f58c2122a5154a85b6cd034d6c7e0e 100644 (file)
@@ -13,7 +13,7 @@
 
 #include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
 #include <linux/kernel_stat.h>
 #include <linux/swap.h>
 #include <linux/pagemap.h>
@@ -1535,13 +1535,6 @@ static void get_scan_ratio(struct zone *zone, struct scan_control *sc,
        unsigned long ap, fp;
        struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc);
 
-       /* If we have no swap space, do not bother scanning anon pages. */
-       if (!sc->may_swap || (nr_swap_pages <= 0)) {
-               percent[0] = 0;
-               percent[1] = 100;
-               return;
-       }
-
        anon  = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_ANON) +
                zone_nr_lru_pages(zone, sc, LRU_INACTIVE_ANON);
        file  = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_FILE) +
@@ -1639,20 +1632,22 @@ static void shrink_zone(int priority, struct zone *zone,
        unsigned long nr_reclaimed = sc->nr_reclaimed;
        unsigned long nr_to_reclaim = sc->nr_to_reclaim;
        struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc);
+       int noswap = 0;
 
-       get_scan_ratio(zone, sc, percent);
+       /* If we have no swap space, do not bother scanning anon pages. */
+       if (!sc->may_swap || (nr_swap_pages <= 0)) {
+               noswap = 1;
+               percent[0] = 0;
+               percent[1] = 100;
+       } else
+               get_scan_ratio(zone, sc, percent);
 
        for_each_evictable_lru(l) {
                int file = is_file_lru(l);
                unsigned long scan;
 
-               if (percent[file] == 0) {
-                       nr[l] = 0;
-                       continue;
-               }
-
                scan = zone_nr_lru_pages(zone, sc, l);
-               if (priority) {
+               if (priority || noswap) {
                        scan >>= priority;
                        scan = (scan * percent[file]) / 100;
                }
index 7f760cbc73f35a7b49944fe86f046e5269850b31..fa12ea3051fb109c18f66ee41da49fd2f7ff4fdb 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/mm.h>
 #include <linux/err.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/cpu.h>
 #include <linux/vmstat.h>
 #include <linux/sched.h>
index 1dcb0660c49dea6bc2b7ec7402eed68629d2e896..9ed7c0e7dc1759972f6c323085a0f10f1d38d31d 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/llc.h>
+#include <linux/slab.h>
 #include <net/llc.h>
 #include <net/llc_pdu.h>
 #include <net/garp.h>
index 2530f35241cde096a08a748790d74b75f8b22884..7f353c4f437ac1bcf0f3ec3646a134fc6e425038 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/datalink.h>
 #include <linux/mm.h>
 #include <linux/in.h>
index 6ab1835041a7485f1d4e23cadb7e3b35f6fcc631..1256a40da43cbcb9ff45a748b7945a016ac0ff95 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 
 #include <net/datalink.h>
 #include <net/p8022.h>
index 6fea0750662b847d048587e423618b8e4fa8b8b8..21cde8fd5795310a823367783cc3f4cd9eb92d0c 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/datalink.h>
 #include <net/llc.h>
 #include <net/psnap.h>
index 0b7a24452d111accb3da25c95806025a32a07f61..53c8f77f0ccd1025a7061568b551a1d9631c0dd1 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/skbuff.h>
 #include <linux/etherdevice.h>
 #include <linux/llc.h>
+#include <linux/slab.h>
 #include <net/llc.h>
 #include <net/llc_pdu.h>
 #include <net/stp.h>
index 44acce47fcdc9a581deb37942c9a89fefecd48c3..1c6e596074dff99fe4571ff4df1d40c081186f01 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/seq_file.h>
 #include <linux/init.h>
 #include <linux/sysctl.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 #include <net/net_namespace.h>
 
index 453512266ea1dd783dbc68f5e6b511dd64ec5ac5..97da977c2a23338e57fb8b8a11db3f2a4d47965d 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/rculist.h>
 #include <net/p8022.h>
@@ -378,6 +379,8 @@ static void vlan_transfer_features(struct net_device *dev,
 #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
        vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid;
 #endif
+       vlandev->real_num_tx_queues = dev->real_num_tx_queues;
+       BUG_ON(vlandev->real_num_tx_queues > vlandev->num_tx_queues);
 
        if (old_features != vlandev->features)
                netdev_features_change(vlandev);
index c0316e0ca6e854724ccb6dc07e1441dd697e7277..c584a0af77d3efaf436a1cc07413fcfa31f442e1 100644 (file)
@@ -11,7 +11,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
        if (netpoll_rx(skb))
                return NET_RX_DROP;
 
-       if (skb_bond_should_drop(skb))
+       if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master)))
                goto drop;
 
        skb->skb_iif = skb->dev->ifindex;
@@ -83,7 +83,7 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,
 {
        struct sk_buff *p;
 
-       if (skb_bond_should_drop(skb))
+       if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master)))
                goto drop;
 
        skb->skb_iif = skb->dev->ifindex;
index 9e83272fc5b022e6a4b765888f06647ce0d92f67..29b6348c8d4d6f280c3e349a6518c6b5ce3d75c1 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -361,6 +362,14 @@ static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb,
        return ret;
 }
 
+static u16 vlan_dev_select_queue(struct net_device *dev, struct sk_buff *skb)
+{
+       struct net_device *rdev = vlan_dev_info(dev)->real_dev;
+       const struct net_device_ops *ops = rdev->netdev_ops;
+
+       return ops->ndo_select_queue(rdev, skb);
+}
+
 static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
 {
        /* TODO: gotta make sure the underlying layer can handle it,
@@ -688,7 +697,8 @@ static const struct header_ops vlan_header_ops = {
        .parse   = eth_header_parse,
 };
 
-static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops;
+static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops,
+                   vlan_netdev_ops_sq, vlan_netdev_accel_ops_sq;
 
 static int vlan_dev_init(struct net_device *dev)
 {
@@ -722,11 +732,17 @@ static int vlan_dev_init(struct net_device *dev)
        if (real_dev->features & NETIF_F_HW_VLAN_TX) {
                dev->header_ops      = real_dev->header_ops;
                dev->hard_header_len = real_dev->hard_header_len;
-               dev->netdev_ops         = &vlan_netdev_accel_ops;
+               if (real_dev->netdev_ops->ndo_select_queue)
+                       dev->netdev_ops = &vlan_netdev_accel_ops_sq;
+               else
+                       dev->netdev_ops = &vlan_netdev_accel_ops;
        } else {
                dev->header_ops      = &vlan_header_ops;
                dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN;
-               dev->netdev_ops         = &vlan_netdev_ops;
+               if (real_dev->netdev_ops->ndo_select_queue)
+                       dev->netdev_ops = &vlan_netdev_ops_sq;
+               else
+                       dev->netdev_ops = &vlan_netdev_ops;
        }
 
        if (is_vlan_dev(real_dev))
@@ -865,6 +881,56 @@ static const struct net_device_ops vlan_netdev_accel_ops = {
 #endif
 };
 
+static const struct net_device_ops vlan_netdev_ops_sq = {
+       .ndo_select_queue       = vlan_dev_select_queue,
+       .ndo_change_mtu         = vlan_dev_change_mtu,
+       .ndo_init               = vlan_dev_init,
+       .ndo_uninit             = vlan_dev_uninit,
+       .ndo_open               = vlan_dev_open,
+       .ndo_stop               = vlan_dev_stop,
+       .ndo_start_xmit =  vlan_dev_hard_start_xmit,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = vlan_dev_set_mac_address,
+       .ndo_set_rx_mode        = vlan_dev_set_rx_mode,
+       .ndo_set_multicast_list = vlan_dev_set_rx_mode,
+       .ndo_change_rx_flags    = vlan_dev_change_rx_flags,
+       .ndo_do_ioctl           = vlan_dev_ioctl,
+       .ndo_neigh_setup        = vlan_dev_neigh_setup,
+       .ndo_get_stats          = vlan_dev_get_stats,
+#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
+       .ndo_fcoe_ddp_setup     = vlan_dev_fcoe_ddp_setup,
+       .ndo_fcoe_ddp_done      = vlan_dev_fcoe_ddp_done,
+       .ndo_fcoe_enable        = vlan_dev_fcoe_enable,
+       .ndo_fcoe_disable       = vlan_dev_fcoe_disable,
+       .ndo_fcoe_get_wwn       = vlan_dev_fcoe_get_wwn,
+#endif
+};
+
+static const struct net_device_ops vlan_netdev_accel_ops_sq = {
+       .ndo_select_queue       = vlan_dev_select_queue,
+       .ndo_change_mtu         = vlan_dev_change_mtu,
+       .ndo_init               = vlan_dev_init,
+       .ndo_uninit             = vlan_dev_uninit,
+       .ndo_open               = vlan_dev_open,
+       .ndo_stop               = vlan_dev_stop,
+       .ndo_start_xmit =  vlan_dev_hwaccel_hard_start_xmit,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = vlan_dev_set_mac_address,
+       .ndo_set_rx_mode        = vlan_dev_set_rx_mode,
+       .ndo_set_multicast_list = vlan_dev_set_rx_mode,
+       .ndo_change_rx_flags    = vlan_dev_change_rx_flags,
+       .ndo_do_ioctl           = vlan_dev_ioctl,
+       .ndo_neigh_setup        = vlan_dev_neigh_setup,
+       .ndo_get_stats          = vlan_dev_get_stats,
+#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
+       .ndo_fcoe_ddp_setup     = vlan_dev_fcoe_ddp_setup,
+       .ndo_fcoe_ddp_done      = vlan_dev_fcoe_ddp_done,
+       .ndo_fcoe_enable        = vlan_dev_fcoe_enable,
+       .ndo_fcoe_disable       = vlan_dev_fcoe_disable,
+       .ndo_fcoe_get_wwn       = vlan_dev_fcoe_get_wwn,
+#endif
+};
+
 void vlan_setup(struct net_device *dev)
 {
        ether_setup(dev);
index e3e5bf4469ced27351e467b9d3bde3b11291c894..0aa79faa98509a1d91f71cec5c307f3522c2a58d 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/poll.h>
 #include <linux/idr.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/uaccess.h>
 #include <net/9p/9p.h>
@@ -71,9 +72,10 @@ inline int p9_is_proto_dotu(struct p9_client *clnt)
 EXPORT_SYMBOL(p9_is_proto_dotu);
 
 /* Interpret mount option for protocol version */
-static unsigned char get_protocol_version(const substring_t *name)
+static int get_protocol_version(const substring_t *name)
 {
-       unsigned char version = -EINVAL;
+       int version = -EINVAL;
+
        if (!strncmp("9p2000", name->from, name->to-name->from)) {
                version = p9_proto_legacy;
                P9_DPRINTK(P9_DEBUG_9P, "Protocol version: Legacy\n");
@@ -533,7 +535,12 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
 
        P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type);
 
-       if (c->status != Connected)
+       /* we allow for any status other than disconnected */
+       if (c->status == Disconnected)
+               return ERR_PTR(-EIO);
+
+       /* if status is begin_disconnected we allow only clunk request */
+       if ((c->status == BeginDisconnect) && (type != P9_TCLUNK))
                return ERR_PTR(-EIO);
 
        if (signal_pending(current)) {
@@ -799,8 +806,10 @@ void p9_client_destroy(struct p9_client *clnt)
 
        v9fs_put_trans(clnt->trans_mod);
 
-       list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist)
+       list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) {
+               printk(KERN_INFO "Found fid %d not clunked\n", fid->fid);
                p9_fid_destroy(fid);
+       }
 
        if (clnt->fidpool)
                p9_idpool_destroy(clnt->fidpool);
@@ -818,6 +827,13 @@ void p9_client_disconnect(struct p9_client *clnt)
 }
 EXPORT_SYMBOL(p9_client_disconnect);
 
+void p9_client_begin_disconnect(struct p9_client *clnt)
+{
+       P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);
+       clnt->status = BeginDisconnect;
+}
+EXPORT_SYMBOL(p9_client_begin_disconnect);
+
 struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
        char *uname, u32 n_uname, char *aname)
 {
index 94f5a8f65e9c3649c8417a62c0c87b1e1ef708cd..e7541d5b011831e6c945d9cfb9163c90f9b1d1fd 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/types.h>
 #include <net/9p/9p.h>
index 31d0b05582a970e9c35b5e01e7d90d36ac25fd6b..98ce9bcb0e15da4443ce08cd654576c2b235b69f 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/idr.h>
 #include <linux/file.h>
 #include <linux/parser.h>
+#include <linux/slab.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 #include <net/9p/transport.h>
index 2c95a89c0f46464e379bb15ca79622149e9f051e..041101ab4aa55b6ceec057e40c007ae57ff409ba 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/file.h>
 #include <linux/parser.h>
 #include <linux/semaphore.h>
+#include <linux/slab.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 #include <net/9p/transport.h>
index afde1a89fbb328d1dbda695c6824e205c7997e1a..7eb78ecc16181cb6d6fc697ac50812882d0c9c8d 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/inet.h>
 #include <linux/idr.h>
 #include <linux/file.h>
+#include <linux/slab.h>
 #include <net/9p/9p.h>
 #include <linux/parser.h>
 #include <net/9p/client.h>
index dc4ec05ad93d5324b3a7d6b81c63ae1c7815af39..e048701a72d230821f6e23eeddd89f5a14fc2f9b 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/sched.h>
 #include <linux/parser.h>
 #include <linux/idr.h>
+#include <linux/slab.h>
 #include <net/9p/9p.h>
 
 /**
index f2b3b56aa779305623fc4c919bae37a7a24c0b41..50dce7981321709e5aa095c233234ca83e69d034 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/datalink.h>
 #include <net/psnap.h>
index 9fc4da56fb1dbcc8cfca2e0714059355e0630c92..7b02967fbbe7dcf0a2138059b44967c4f0cc9375 100644 (file)
@@ -57,6 +57,7 @@
 #include <linux/smp_lock.h>
 #include <linux/termios.h>     /* For TIOCOUTQ/INQ */
 #include <linux/compat.h>
+#include <linux/slab.h>
 #include <net/datalink.h>
 #include <net/psnap.h>
 #include <net/sock.h>
index cf3ae8b475728df8668ce90ce14f5622e65c2388..dcda35c66f152015d99e916e4c869637c2ecd08a 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/atm.h>
 #include <linux/atmdev.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 
 #include "signaling.h"
index f693b78eb4678d79b8a4f4786a4fffba47461ade..799c631f0fed0c1e8210d2d61e3fdf3afd27aea9 100644 (file)
@@ -1,6 +1,7 @@
 /* ATM driver model support. */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/kobject.h>
 #include <linux/atmdev.h>
index 4d64d87e7578a26aa6bd89bfa425dea14fb13f77..d6c7ceaf13e969171eb96fb54e5a7ea2ed03844e 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/ip.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <net/arp.h>
 #include <linux/atm.h>
 #include <linux/atmdev.h>
index ebfa022008f79aff20202c2c13ae0b04ee117d81..313aba11316b5764e759fa7356f5f8286d69ceb5 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/seq_file.h>
 #include <linux/rcupdate.h>
 #include <linux/jhash.h>
+#include <linux/slab.h>
 #include <net/route.h> /* for struct rtable and routing */
 #include <net/icmp.h> /* icmp_send */
 #include <linux/param.h> /* for HZ */
index 74d095a081e3ed0a667ab6805b2c361d51cf81d3..97ed94aa0cbceb3623b91e918fd886f353793aab 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <net/sock.h>          /* struct sock */
 #include <linux/uaccess.h>
 #include <linux/poll.h>
index 5da5753157f9d8da1799e93649e52e9f258d85dd..feeaf5718472ec076bfd01c866f04f0e9e3b83ea 100644 (file)
@@ -6,6 +6,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/bitops.h>
 #include <linux/capability.h>
index a6521c8aa88b58b9ceedb410d5807cdff1cd9127..436f2e177657e7b184c7afe5c467f97cbcc420cd 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
index 4c141810eb6dc210935f9c12cba875e0912f318d..e773d8336918b021eeeea82e409fba657f564ab1 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/types.h>
 #include <linux/atmmpc.h>
+#include <linux/slab.h>
 #include <linux/time.h>
 
 #include "mpoa_caches.h"
index b9bdb98427e4475151685c016c395f92bfd66240..53e500292271803ade21c6f0bfac00dcce7ab3ac 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/uaccess.h>
 #include <linux/atmmpc.h>
 #include <linux/atm.h>
+#include <linux/gfp.h>
 #include "mpc.h"
 #include "mpoa_caches.h"
 
index 400839273c67503e6fa4207c2d2949a5f99e351f..e49bb6d948a1b1ec1a195f9952a2f0063640c7ce 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/atm.h>
 #include <linux/atmdev.h>
 #include <linux/capability.h>
index 7a96b2376bd7223ad951e66a4ad441fccbb32d0d..696e218436e5ec3de66b9bb63e06d70c31ab427d 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/netdevice.h>
 #include <linux/atmclip.h>
 #include <linux/init.h> /* for __init */
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/atmclip.h>
 #include <linux/uaccess.h>
index d0c4bd047dc453990d45cead53fcdbb57b27fc25..b4f7b9ff3c741880e1f587f8f27a939ab62c25dd 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 
 #include "common.h"
 #include "protocols.h"
index 90082904f20d55df42fc83903f569d08db3e6e93..d29e582615116a68e1f476091c6475d589401878 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/capability.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <net/sock.h>   /* for struct sock */
 
index ad1d28ae512bcfc66a89f693c4e855ad0580783f..6ba6e466ee545af605264c45eea340cb9b27e1cd 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/atmsvc.h>
 #include <linux/atmdev.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 
 #include "resources.h"
 #include "signaling.h"
index a5beedf43e2df8738f9f3ce35fb00636ca2f471a..65c5801261f949b206d242e65f0c36ff7265cb54 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index a7a0e0c9698b0c59de7b553fdda73e947864a027..c1cb982f6e86954018c7311d17016cb2189f9bf1 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/socket.h>
+#include <linux/slab.h>
 #include <linux/in.h>
 #include <linux/kernel.h>
 #include <linux/timer.h>
index b5e59787be2f145084dfe15a6189e2f0923222b2..85816e612dc0a83cd76b56a5d81448d90cd28b20 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/sockios.h>
 #include <linux/spinlock.h>
 #include <linux/net.h>
+#include <linux/gfp.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index 71338f112108a06ee9b3734d19c7146c54fea7a9..5a0dda8df492424b4e0c24255a625373b5cacf09 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index de56d3983de098b11d64f8971d85b8ded8187bf2..9bb7765412036dc19001ea412c346e12990148c3 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index f047a57aa95c151be44c41a92d9e834a8c35cfb5..cf0c47a265304bc94cc391c7c92a10be16de14ed 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index 14912600ec57e6e961ee7de20dc2eebbb9a4013c..37507d806f65f64d6b1740dc055fea80845ff644 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/sockios.h>
 #include <linux/spinlock.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index c833ba4c45a585514eee55835c5ce61880594c6d..7805945a5fd6d311f54f26a66dc5ad9c0e83ece1 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index 034aa10a5198bd6dd88ba9eb431f9f3088600d98..c6715ee4ab8f6099e25a58421998127df1a96dda 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index 9f13f6eefcba68cdf779121b9749b66044c26b41..d349be9578f5bce47be0d42243ca1c7ea34dbcdb 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/sockios.h>
 #include <linux/net.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index 5159be6b2625a91894a1c388e1cae3e1ade7e725..ebe0ef3f1d839c1715dcf3784e8d9148b62820e2 100644 (file)
@@ -7,6 +7,7 @@
  * Copyright (C) 1996 Mike Shaver (shaver@zeroknowledge.com)
  */
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/spinlock.h>
 #include <net/ax25.h>
index 087cc51f592733fba6557d5456801dc75a6b69a0..404a8500fd031b254b0049a6c97b8ff6f7805675 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/poll.h>
index ef09c7b3a8585451a9a1f1ec4ec29b5650988019..8062dad6d10d0c83afd345d1f4c0ea8532d41b9a 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/freezer.h>
 #include <linux/errno.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 
 #include <linux/socket.h>
index b6234b73c4cfb6fc5a752917baf75f0f1c53f883..5643a2391e76979e6de26e589debb2580555612f 100644 (file)
@@ -26,6 +26,7 @@
 */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <linux/socket.h>
 #include <linux/netdevice.h>
index 2ff6ac7b2ed494b8ffcac277d0e067b92d408734..2862f53b66b15b8b680322b32c5196f502adc7f0 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/capability.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/poll.h>
 #include <linux/fcntl.h>
 #include <linux/skbuff.h>
@@ -39,6 +38,7 @@
 #include <linux/file.h>
 #include <linux/init.h>
 #include <linux/compat.h>
+#include <linux/gfp.h>
 #include <net/sock.h>
 
 #include <asm/system.h>
index 978cc3a718ad1726de639fd93762b5d926a1592f..7ea1979a8e4f1aab1ef895eb61ffc06cab848536 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/capability.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/poll.h>
 #include <linux/fcntl.h>
 #include <linux/skbuff.h>
@@ -34,6 +33,7 @@
 #include <linux/ioctl.h>
 #include <linux/file.h>
 #include <linux/compat.h>
+#include <linux/gfp.h>
 #include <net/sock.h>
 
 #include <linux/isdn/capilli.h>
index cafb55b0cea5ca290f0a2ac4fc5e73eac200ba5e..0e8e1a59856c40ffe5b1cde05d6bd6321febc24a 100644 (file)
@@ -1,6 +1,7 @@
 /* Bluetooth HCI driver model support. */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
@@ -8,8 +9,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
-struct class *bt_class = NULL;
-EXPORT_SYMBOL_GPL(bt_class);
+static struct class *bt_class;
 
 struct dentry *bt_debugfs = NULL;
 EXPORT_SYMBOL_GPL(bt_debugfs);
index 9cfef68b9feceaacf6165faafcc120fe99c9bfa1..250dfd46237d284a0c587ad7e3da35e9dcb81f80 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/capability.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/poll.h>
 #include <linux/fcntl.h>
 #include <linux/skbuff.h>
@@ -35,6 +34,7 @@
 #include <linux/file.h>
 #include <linux/init.h>
 #include <linux/compat.h>
+#include <linux/gfp.h>
 #include <net/sock.h>
 
 #include "hidp.h"
index 4db7ae2fe07dea0fcc12d142f072b8ebef5c6a58..9753b690a8b356b9bd24e88efb45d8d6e2b5ca56 100644 (file)
@@ -40,6 +40,8 @@
 #include <linux/skbuff.h>
 #include <linux/list.h>
 #include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 #include <linux/uaccess.h>
 #include <linux/crc16.h>
 #include <net/sock.h>
@@ -1000,7 +1002,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
 
        BT_DBG("sk %p", sk);
 
-       if (!addr || addr->sa_family != AF_BLUETOOTH)
+       if (!addr || alen < sizeof(addr->sa_family) ||
+           addr->sa_family != AF_BLUETOOTH)
                return -EINVAL;
 
        memset(&la, 0, sizeof(la));
@@ -1623,7 +1626,10 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
        /* Connectionless channel */
        if (sk->sk_type == SOCK_DGRAM) {
                skb = l2cap_create_connless_pdu(sk, msg, len);
-               err = l2cap_do_send(sk, skb);
+               if (IS_ERR(skb))
+                       err = PTR_ERR(skb);
+               else
+                       err = l2cap_do_send(sk, skb);
                goto done;
        }
 
@@ -2830,6 +2836,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
                        int len = cmd->len - sizeof(*rsp);
                        char req[64];
 
+                       if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
+                               l2cap_send_disconn_req(conn, sk);
+                               goto done;
+                       }
+
                        /* throw out any old stored conf requests */
                        result = L2CAP_CONF_SUCCESS;
                        len = l2cap_parse_conf_rsp(sk, rsp->data,
@@ -3937,31 +3948,42 @@ drop:
        return 0;
 }
 
-static ssize_t l2cap_sysfs_show(struct class *dev,
-                               struct class_attribute *attr,
-                               char *buf)
+static int l2cap_debugfs_show(struct seq_file *f, void *p)
 {
        struct sock *sk;
        struct hlist_node *node;
-       char *str = buf;
 
        read_lock_bh(&l2cap_sk_list.lock);
 
        sk_for_each(sk, node, &l2cap_sk_list.head) {
                struct l2cap_pinfo *pi = l2cap_pi(sk);
 
-               str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
-                               batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
-                               sk->sk_state, __le16_to_cpu(pi->psm), pi->scid,
-                               pi->dcid, pi->imtu, pi->omtu, pi->sec_level);
+               seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
+                                       batostr(&bt_sk(sk)->src),
+                                       batostr(&bt_sk(sk)->dst),
+                                       sk->sk_state, __le16_to_cpu(pi->psm),
+                                       pi->scid, pi->dcid,
+                                       pi->imtu, pi->omtu, pi->sec_level);
        }
 
        read_unlock_bh(&l2cap_sk_list.lock);
 
-       return str - buf;
+       return 0;
 }
 
-static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
+static int l2cap_debugfs_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, l2cap_debugfs_show, inode->i_private);
+}
+
+static const struct file_operations l2cap_debugfs_fops = {
+       .open           = l2cap_debugfs_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static struct dentry *l2cap_debugfs;
 
 static const struct proto_ops l2cap_sock_ops = {
        .family         = PF_BLUETOOTH,
@@ -4021,8 +4043,12 @@ static int __init l2cap_init(void)
                goto error;
        }
 
-       if (class_create_file(bt_class, &class_attr_l2cap) < 0)
-               BT_ERR("Failed to create L2CAP info file");
+       if (bt_debugfs) {
+               l2cap_debugfs = debugfs_create_file("l2cap", 0444,
+                                       bt_debugfs, NULL, &l2cap_debugfs_fops);
+               if (!l2cap_debugfs)
+                       BT_ERR("Failed to create L2CAP debug file");
+       }
 
        BT_INFO("L2CAP ver %s", VERSION);
        BT_INFO("L2CAP socket layer initialized");
@@ -4036,7 +4062,7 @@ error:
 
 static void __exit l2cap_exit(void)
 {
-       class_remove_file(bt_class, &class_attr_l2cap);
+       debugfs_remove(l2cap_debugfs);
 
        if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
                BT_ERR("L2CAP socket unregistration failed");
index db8a68e1a5ba835c11eff1f4d1f0525642e9ab41..7dca91bb8c576397e571994655efbe9d1832d7b6 100644 (file)
 #include <linux/init.h>
 #include <linux/wait.h>
 #include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 #include <linux/net.h>
 #include <linux/mutex.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 #include <net/sock.h>
 #include <asm/uaccess.h>
@@ -2098,13 +2101,10 @@ static struct hci_cb rfcomm_cb = {
        .security_cfm   = rfcomm_security_cfm
 };
 
-static ssize_t rfcomm_dlc_sysfs_show(struct class *dev,
-                                    struct class_attribute *attr,
-                                    char *buf)
+static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x)
 {
        struct rfcomm_session *s;
        struct list_head *pp, *p;
-       char *str = buf;
 
        rfcomm_lock();
 
@@ -2114,18 +2114,32 @@ static ssize_t rfcomm_dlc_sysfs_show(struct class *dev,
                        struct sock *sk = s->sock->sk;
                        struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list);
 
-                       str += sprintf(str, "%s %s %ld %d %d %d %d\n",
-                                       batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
-                                       d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
+                       seq_printf(f, "%s %s %ld %d %d %d %d\n",
+                                               batostr(&bt_sk(sk)->src),
+                                               batostr(&bt_sk(sk)->dst),
+                                               d->state, d->dlci, d->mtu,
+                                               d->rx_credits, d->tx_credits);
                }
        }
 
        rfcomm_unlock();
 
-       return (str - buf);
+       return 0;
 }
 
-static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL);
+static int rfcomm_dlc_debugfs_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, rfcomm_dlc_debugfs_show, inode->i_private);
+}
+
+static const struct file_operations rfcomm_dlc_debugfs_fops = {
+       .open           = rfcomm_dlc_debugfs_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static struct dentry *rfcomm_dlc_debugfs;
 
 /* ---- Initialization ---- */
 static int __init rfcomm_init(void)
@@ -2142,8 +2156,12 @@ static int __init rfcomm_init(void)
                goto unregister;
        }
 
-       if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0)
-               BT_ERR("Failed to create RFCOMM info file");
+       if (bt_debugfs) {
+               rfcomm_dlc_debugfs = debugfs_create_file("rfcomm_dlc", 0444,
+                               bt_debugfs, NULL, &rfcomm_dlc_debugfs_fops);
+               if (!rfcomm_dlc_debugfs)
+                       BT_ERR("Failed to create RFCOMM debug file");
+       }
 
        err = rfcomm_init_ttys();
        if (err < 0)
@@ -2171,7 +2189,7 @@ unregister:
 
 static void __exit rfcomm_exit(void)
 {
-       class_remove_file(bt_class, &class_attr_rfcomm_dlc);
+       debugfs_remove(rfcomm_dlc_debugfs);
 
        hci_unregister_cb(&rfcomm_cb);
 
index ca87d6ac6a2036dd7030c334c133e4326edcda62..8ed3c37684fa345326366239d719a1b1a100458b 100644 (file)
@@ -40,6 +40,8 @@
 #include <linux/skbuff.h>
 #include <linux/list.h>
 #include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 #include <net/sock.h>
 
 #include <asm/system.h>
@@ -395,7 +397,8 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
 
        BT_DBG("sk %p", sk);
 
-       if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc))
+       if (alen < sizeof(struct sockaddr_rc) ||
+           addr->sa_family != AF_BLUETOOTH)
                return -EINVAL;
 
        lock_sock(sk);
@@ -1061,28 +1064,38 @@ done:
        return result;
 }
 
-static ssize_t rfcomm_sock_sysfs_show(struct class *dev,
-                                     struct class_attribute *attr,
-                                     char *buf)
+static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p)
 {
        struct sock *sk;
        struct hlist_node *node;
-       char *str = buf;
 
        read_lock_bh(&rfcomm_sk_list.lock);
 
        sk_for_each(sk, node, &rfcomm_sk_list.head) {
-               str += sprintf(str, "%s %s %d %d\n",
-                               batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
+               seq_printf(f, "%s %s %d %d\n",
+                               batostr(&bt_sk(sk)->src),
+                               batostr(&bt_sk(sk)->dst),
                                sk->sk_state, rfcomm_pi(sk)->channel);
        }
 
        read_unlock_bh(&rfcomm_sk_list.lock);
 
-       return (str - buf);
+       return 0;
 }
 
-static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL);
+static int rfcomm_sock_debugfs_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, rfcomm_sock_debugfs_show, inode->i_private);
+}
+
+static const struct file_operations rfcomm_sock_debugfs_fops = {
+       .open           = rfcomm_sock_debugfs_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static struct dentry *rfcomm_sock_debugfs;
 
 static const struct proto_ops rfcomm_sock_ops = {
        .family         = PF_BLUETOOTH,
@@ -1122,8 +1135,12 @@ int __init rfcomm_init_sockets(void)
        if (err < 0)
                goto error;
 
-       if (class_create_file(bt_class, &class_attr_rfcomm) < 0)
-               BT_ERR("Failed to create RFCOMM info file");
+       if (bt_debugfs) {
+               rfcomm_sock_debugfs = debugfs_create_file("rfcomm", 0444,
+                               bt_debugfs, NULL, &rfcomm_sock_debugfs_fops);
+               if (!rfcomm_sock_debugfs)
+                       BT_ERR("Failed to create RFCOMM debug file");
+       }
 
        BT_INFO("RFCOMM socket layer initialized");
 
@@ -1137,7 +1154,7 @@ error:
 
 void rfcomm_cleanup_sockets(void)
 {
-       class_remove_file(bt_class, &class_attr_rfcomm);
+       debugfs_remove(rfcomm_sock_debugfs);
 
        if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
                BT_ERR("RFCOMM socket layer unregistration failed");
index f93b939539bc121da4448ce68e0e785b55b08416..ca6b2ad1c3fc02a6bcbf16a034aa253e05b1a456 100644 (file)
@@ -38,6 +38,8 @@
 #include <linux/socket.h>
 #include <linux/skbuff.h>
 #include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 #include <linux/list.h>
 #include <net/sock.h>
 
@@ -497,7 +499,8 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
 
        BT_DBG("sk %p", sk);
 
-       if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_sco))
+       if (alen < sizeof(struct sockaddr_sco) ||
+           addr->sa_family != AF_BLUETOOTH)
                return -EINVAL;
 
        if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
@@ -953,28 +956,36 @@ drop:
        return 0;
 }
 
-static ssize_t sco_sysfs_show(struct class *dev,
-                               struct class_attribute *attr,
-                               char *buf)
+static int sco_debugfs_show(struct seq_file *f, void *p)
 {
        struct sock *sk;
        struct hlist_node *node;
-       char *str = buf;
 
        read_lock_bh(&sco_sk_list.lock);
 
        sk_for_each(sk, node, &sco_sk_list.head) {
-               str += sprintf(str, "%s %s %d\n",
-                               batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
-                               sk->sk_state);
+               seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src),
+                               batostr(&bt_sk(sk)->dst), sk->sk_state);
        }
 
        read_unlock_bh(&sco_sk_list.lock);
 
-       return (str - buf);
+       return 0;
 }
 
-static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL);
+static int sco_debugfs_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, sco_debugfs_show, inode->i_private);
+}
+
+static const struct file_operations sco_debugfs_fops = {
+       .open           = sco_debugfs_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static struct dentry *sco_debugfs;
 
 static const struct proto_ops sco_sock_ops = {
        .family         = PF_BLUETOOTH,
@@ -1032,8 +1043,12 @@ static int __init sco_init(void)
                goto error;
        }
 
-       if (class_create_file(bt_class, &class_attr_sco) < 0)
-               BT_ERR("Failed to create SCO info file");
+       if (bt_debugfs) {
+               sco_debugfs = debugfs_create_file("sco", 0444,
+                                       bt_debugfs, NULL, &sco_debugfs_fops);
+               if (!sco_debugfs)
+                       BT_ERR("Failed to create SCO debug file");
+       }
 
        BT_INFO("SCO (Voice Link) ver %s", VERSION);
        BT_INFO("SCO socket layer initialized");
@@ -1047,7 +1062,7 @@ error:
 
 static void __exit sco_exit(void)
 {
-       class_remove_file(bt_class, &class_attr_sco);
+       debugfs_remove(sco_debugfs);
 
        if (bt_sock_unregister(BTPROTO_SCO) < 0)
                BT_ERR("SCO socket unregistration failed");
index eb7062d2e9e5d28168fe2dcbdc3ec2f44bc9f4c9..90a9024e5c1eaf30713258c4d32151a89cc87c06 100644 (file)
@@ -40,7 +40,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
                        goto out;
 
                mdst = br_mdb_get(br, skb);
-               if (mdst || BR_INPUT_SKB_CB(skb)->mrouters_only)
+               if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb))
                        br_multicast_deliver(mdst, skb);
                else
                        br_flood_deliver(br, skb);
index 3b8e038ab32c537cd36657edd39d506a1891118b..9101a4e5620129fa4d29df1a7e2cbde264cf88f2 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/etherdevice.h>
 #include <linux/jhash.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <asm/atomic.h>
 #include <asm/unaligned.h>
 #include "br_private.h"
index d61e6f741125bbd510d20237a8e76e4292802b77..7a241c396981eebb9ee1357daf88e7d18f3f8db8 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter_bridge.h>
 #include "br_private.h"
 
+static int deliver_clone(const struct net_bridge_port *prev,
+                        struct sk_buff *skb,
+                        void (*__packet_hook)(const struct net_bridge_port *p,
+                                              struct sk_buff *skb));
+
 /* Don't forward packets to originating port or forwarding diasabled */
 static inline int should_deliver(const struct net_bridge_port *p,
                                 const struct sk_buff *skb)
@@ -94,17 +100,22 @@ void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
 }
 
 /* called with rcu_read_lock */
-void br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
+void br_forward(const struct net_bridge_port *to, struct sk_buff *skb, struct sk_buff *skb0)
 {
        if (should_deliver(to, skb)) {
-               __br_forward(to, skb);
+               if (skb0)
+                       deliver_clone(to, skb, __br_forward);
+               else
+                       __br_forward(to, skb);
                return;
        }
 
-       kfree_skb(skb);
+       if (!skb0)
+               kfree_skb(skb);
 }
 
-static int deliver_clone(struct net_bridge_port *prev, struct sk_buff *skb,
+static int deliver_clone(const struct net_bridge_port *prev,
+                        struct sk_buff *skb,
                         void (*__packet_hook)(const struct net_bridge_port *p,
                                               struct sk_buff *skb))
 {
index b6a3872f5681de09a8d67a8fe0ec99cf4ad4dbd1..0b6b1f2ff7acb4000892dd08e1e9834844d188e7 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/if_ether.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 
 #include "br_private.h"
index 53b39851d87d475ecdbfbf9b94fa6eb8072d5f40..a82dde2d2ead34d32af8ecd3829ee5563d8cf710 100644 (file)
@@ -11,6 +11,7 @@
  *     2 of the License, or (at your option) any later version.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -70,7 +71,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
 
        if (is_multicast_ether_addr(dest)) {
                mdst = br_mdb_get(br, skb);
-               if (mdst || BR_INPUT_SKB_CB(skb)->mrouters_only) {
+               if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) {
                        if ((mdst && !hlist_unhashed(&mdst->mglist)) ||
                            br_multicast_is_router(br))
                                skb2 = skb;
@@ -90,7 +91,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
 
        if (skb) {
                if (dst)
-                       br_forward(dst->dst, skb);
+                       br_forward(dst->dst, skb, skb2);
                else
                        br_flood_forward(br, skb, skb2);
        }
index 2af6e4a902628ca8e1132e51bdeeee971f078a1d..995afc4b04dc58bf46d0ca4b5b7d650247b37282 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/if_bridge.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <linux/times.h>
 #include <net/net_namespace.h>
 #include <asm/uaccess.h>
index fd96a8dc97f4b8c03bbeb67141d12669d817feb6..eaa0e1bae49bcf28dff4f10e648dbd5ee418554f 100644 (file)
@@ -49,22 +49,23 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get(
 static struct net_bridge_mdb_entry *br_mdb_ip_get(
        struct net_bridge_mdb_htable *mdb, __be32 dst)
 {
+       if (!mdb)
+               return NULL;
+
        return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst));
 }
 
 struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
                                        struct sk_buff *skb)
 {
-       struct net_bridge_mdb_htable *mdb = br->mdb;
-
-       if (!mdb || br->multicast_disabled)
+       if (br->multicast_disabled)
                return NULL;
 
        switch (skb->protocol) {
        case htons(ETH_P_IP):
                if (BR_INPUT_SKB_CB(skb)->igmp)
                        break;
-               return br_mdb_ip_get(mdb, ip_hdr(skb)->daddr);
+               return br_mdb_ip_get(br->mdb, ip_hdr(skb)->daddr);
        }
 
        return NULL;
@@ -722,11 +723,11 @@ static int br_multicast_igmp3_report(struct net_bridge *br,
                if (!pskb_may_pull(skb, len))
                        return -EINVAL;
 
-               grec = (void *)(skb->data + len);
+               grec = (void *)(skb->data + len - sizeof(*grec));
                group = grec->grec_mca;
                type = grec->grec_type;
 
-               len += grec->grec_nsrcs * 4;
+               len += ntohs(grec->grec_nsrcs) * 4;
                if (!pskb_may_pull(skb, len))
                        return -EINVAL;
 
@@ -851,8 +852,8 @@ static int br_multicast_query(struct net_bridge *br,
                if (ih3->nsrcs)
                        goto out;
 
-               max_delay = ih3->code ? 1 :
-                           IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE);
+               max_delay = ih3->code ?
+                           IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1;
        }
 
        if (!group)
@@ -956,9 +957,6 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
        unsigned offset;
        int err;
 
-       BR_INPUT_SKB_CB(skb)->igmp = 0;
-       BR_INPUT_SKB_CB(skb)->mrouters_only = 0;
-
        /* We treat OOM as packet loss for now. */
        if (!pskb_may_pull(skb, sizeof(*iph)))
                return -EINVAL;
@@ -990,7 +988,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
 
                err = pskb_trim_rcsum(skb2, len);
                if (err)
-                       return err;
+                       goto err_out;
        }
 
        len -= ip_hdrlen(skb2);
@@ -1012,7 +1010,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
        case CHECKSUM_NONE:
                skb2->csum = 0;
                if (skb_checksum_complete(skb2))
-                       return -EINVAL;
+                       goto out;
        }
 
        err = 0;
@@ -1039,6 +1037,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
 
 out:
        __skb_push(skb2, offset);
+err_out:
        if (skb2 != skb)
                kfree_skb(skb2);
        return err;
@@ -1047,6 +1046,9 @@ out:
 int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port,
                     struct sk_buff *skb)
 {
+       BR_INPUT_SKB_CB(skb)->igmp = 0;
+       BR_INPUT_SKB_CB(skb)->mrouters_only = 0;
+
        if (br->multicast_disabled)
                return 0;
 
index 268e2e7258881addf26214bb4418382ba3228c97..4c4977d12fd64d81a0c0281cd166346b81e65da1 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/ip.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
index fcffb3fb1177aa57352f4fdbcc0247944d1959ac..aa56ac2c88293ad7717c62c256eaea185a638cd1 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <net/rtnetlink.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
index fef0384e3c0b78ad09074487200cb08747fc46b4..846d7d1e2075d1ffb7821c3244441203b0a8d726 100644 (file)
@@ -206,12 +206,20 @@ struct net_bridge
 
 struct br_input_skb_cb {
        struct net_device *brdev;
+#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
        int igmp;
        int mrouters_only;
+#endif
 };
 
 #define BR_INPUT_SKB_CB(__skb) ((struct br_input_skb_cb *)(__skb)->cb)
 
+#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
+# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb)  (BR_INPUT_SKB_CB(__skb)->mrouters_only)
+#else
+# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb)  (0)
+#endif
+
 extern struct notifier_block br_device_notifier;
 extern const u8 br_group_address[ETH_ALEN];
 
@@ -252,7 +260,7 @@ extern void br_deliver(const struct net_bridge_port *to,
                struct sk_buff *skb);
 extern int br_dev_queue_push_xmit(struct sk_buff *skb);
 extern void br_forward(const struct net_bridge_port *to,
-               struct sk_buff *skb);
+               struct sk_buff *skb, struct sk_buff *skb0);
 extern int br_forward_finish(struct sk_buff *skb);
 extern void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb);
 extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb,
index 81ae40b3f6550c70b01b8d88a5266e14647a2d11..d66cce11f3bf93475b85d827dbf6b11de8897886 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/netfilter_bridge.h>
 #include <linux/etherdevice.h>
 #include <linux/llc.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/llc.h>
 #include <net/llc_pdu.h>
index c6ac657074a6b6471a1bb554fe7bb123ed676944..f9560f3dbdc7c9ba538a12b1b637766ecf981db8 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/socket.h>
 #include <linux/skbuff.h>
index dfb58056a89ae7f6e3538124197ba3d175c77edd..f0865fd1e3eca770f2218e576093a139b9676243 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/smp.h>
 #include <linux/cpumask.h>
index e32af52238a2a437787b4adaa7a7616e195b0e57..907dc871fac8bcf5e6d3cbce2c79f9a53706ccfa 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/can.h>
 #include <linux/can/core.h>
 #include <linux/can/bcm.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/net_namespace.h>
 
@@ -1478,6 +1479,9 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
        struct sock *sk = sock->sk;
        struct bcm_sock *bo = bcm_sk(sk);
 
+       if (len < sizeof(*addr))
+               return -EINVAL;
+
        if (bo->bound)
                return -EISCONN;
 
index abca920440b50cdf51e539fc18c6ea15f7ef698b..da99cf153b33737ce45a06e71fc89037b96096b3 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/init.h>
 #include <linux/uio.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/socket.h>
 #include <linux/if_arp.h>
@@ -444,7 +445,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
                                return -EFAULT;
                        }
                } else if (count == 1) {
-                       if (copy_from_user(&sfilter, optval, optlen))
+                       if (copy_from_user(&sfilter, optval, sizeof(sfilter)))
                                return -EFAULT;
                }
 
index a1fb1b079a82b00bd269fa208984de34010bf7f4..ec24d9edb0258ecda760deaf80eaa211f844feef 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/fs.h>
 #include <linux/types.h>
 #include <linux/file.h>
index 95c2e0840d0d7571ed799a1d17006db05c4bd6eb..2dccd4ee591b3a755242c05b8889489a380dc8bd 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/poll.h>
 #include <linux/highmem.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 
 #include <net/protocol.h>
 #include <linux/skbuff.h>
index bcc490cc9452f3e87273836ef406c54608c49084..264137fce3a25496c349b141b8276d6900f80412 100644 (file)
@@ -80,6 +80,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/hash.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/mutex.h>
 #include <linux/string.h>
@@ -1450,7 +1451,7 @@ static inline void net_timestamp(struct sk_buff *skb)
  *
  * return values:
  *     NET_RX_SUCCESS  (no congestion)
- *     NET_RX_DROP     (packet was dropped)
+ *     NET_RX_DROP     (packet was dropped, but freed)
  *
  * dev_forward_skb can be used for injecting an skb from the
  * start_xmit function of one device into the receive queue
@@ -1464,12 +1465,11 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
 {
        skb_orphan(skb);
 
-       if (!(dev->flags & IFF_UP))
-               return NET_RX_DROP;
-
-       if (skb->len > (dev->mtu + dev->hard_header_len))
+       if (!(dev->flags & IFF_UP) ||
+           (skb->len > (dev->mtu + dev->hard_header_len))) {
+               kfree_skb(skb);
                return NET_RX_DROP;
-
+       }
        skb_set_dev(skb, dev);
        skb->tstamp.tv64 = 0;
        skb->pkt_type = PACKET_HOST;
@@ -1988,8 +1988,12 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev,
                        if (dev->real_num_tx_queues > 1)
                                queue_index = skb_tx_hash(dev, skb);
 
-                       if (sk && sk->sk_dst_cache)
-                               sk_tx_queue_set(sk, queue_index);
+                       if (sk) {
+                               struct dst_entry *dst = rcu_dereference_bh(sk->sk_dst_cache);
+
+                               if (dst && skb_dst(skb) == dst)
+                                       sk_tx_queue_set(sk, queue_index);
+                       }
                }
        }
 
@@ -2483,6 +2487,7 @@ int netif_receive_skb(struct sk_buff *skb)
 {
        struct packet_type *ptype, *pt_prev;
        struct net_device *orig_dev;
+       struct net_device *master;
        struct net_device *null_or_orig;
        struct net_device *null_or_bond;
        int ret = NET_RX_DROP;
@@ -2503,11 +2508,12 @@ int netif_receive_skb(struct sk_buff *skb)
 
        null_or_orig = NULL;
        orig_dev = skb->dev;
-       if (orig_dev->master) {
-               if (skb_bond_should_drop(skb))
+       master = ACCESS_ONCE(orig_dev->master);
+       if (master) {
+               if (skb_bond_should_drop(skb, master))
                        null_or_orig = orig_dev; /* deliver only exact match */
                else
-                       skb->dev = orig_dev->master;
+                       skb->dev = master;
        }
 
        __get_cpu_var(netdev_rx_stat).total++;
index f8c8749753506c00f8a843679c7522de255302b5..cf208d8042b198d962a8ccfbd81c0b70acca28c2 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/percpu.h>
 #include <linux/timer.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include <net/genetlink.h>
 #include <net/netevent.h>
 
index cb1b3488b739837fcff71c10d36694f2ea3ab393..f307bc18f6a0002a0a1f7d1c2268a8cc260e0805 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/workqueue.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/string.h>
index f4cb6b6299d9ad833c442455944133c5c55868dd..9d55c57f318a7ac93f9362ee5245f07c473c906c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/ethtool.h>
 #include <linux/netdevice.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 /*
index 9a24377146bf0dc25163e96bfb3c9b6c0701ab40..d2c3e7dc2e5f17baedd875cdd805186a7678b2aa 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
index d38ef7fd50f0c70397e487f254c81ff1248782bd..ff943bed21afe0b90cc797628ff76795c79981f4 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/inet.h>
 #include <linux/netdevice.h>
 #include <linux/if_packet.h>
+#include <linux/gfp.h>
 #include <net/ip.h>
 #include <net/protocol.h>
 #include <net/netlink.h>
index 493775f4f2f1d7c19b618640e186aae7195ded53..cf8e70392fe0938acb4b8b88fa8bc74dbeaed584 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/init.h>
 #include <linux/rbtree.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/gen_stats.h>
 
index 16ad45d4882b56a2c531a0a944bc31c690ff5a4b..1e7f4e91a935f65b8fbb1ff60efd1663a39686cc 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/net.h>
 #include <linux/in6.h>
 #include <asm/uaccess.h>
index 5910b555a54afbe603322756d39d9fb9898d4830..bdbce2f5875be574cf367a2493bf290e9b99bcd8 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/rtnetlink.h>
 #include <linux/jiffies.h>
 #include <linux/spinlock.h>
-#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/bitops.h>
 #include <asm/types.h>
index 6cee6434da677a393d218a4c50e069d80932a594..bff37908bd55683012353bde62015722f8c515e9 100644 (file)
@@ -15,6 +15,7 @@
  *     Harald Welte            Add neighbour cache statistics like rtstat
  */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index 099c753c4213ae814b51bf4e149eeb4f79836224..59cfc7d8fc450c26a17b094280dec7a2842461e9 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <linux/rtnetlink.h>
 #include <linux/wireless.h>
index f1e982c508bb16df812024014d953c184e777247..afa6380ed88ac2ee0b5cd8c8a731dcb9f3dcb809 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/workqueue.h>
 #include <linux/netlink.h>
 #include <linux/net_dropmon.h>
+#include <linux/slab.h>
 
 #include <asm/unaligned.h>
 #include <asm/bitops.h>
index 7aa6972537658375031c81dd41e31171b0f69084..a58f59b975974ec6d0daf13bbe71aecc1d2e0bd2 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/delay.h>
 #include <linux/rcupdate.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 #include <net/tcp.h>
 #include <net/udp.h>
 #include <asm/unaligned.h>
@@ -614,7 +615,7 @@ void netpoll_print_options(struct netpoll *np)
                         np->name, np->local_port);
        printk(KERN_INFO "%s: local IP %pI4\n",
                         np->name, &np->local_ip);
-       printk(KERN_INFO "%s: interface %s\n",
+       printk(KERN_INFO "%s: interface '%s'\n",
                         np->name, np->dev_name);
        printk(KERN_INFO "%s: remote port %d\n",
                         np->name, np->remote_port);
@@ -661,6 +662,9 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
                if ((delim = strchr(cur, '@')) == NULL)
                        goto parse_failed;
                *delim = 0;
+               if (*cur == ' ' || *cur == '\t')
+                       printk(KERN_INFO "%s: warning: whitespace"
+                                       "is not allowed\n", np->name);
                np->remote_port = simple_strtol(cur, NULL, 10);
                cur = delim;
        }
@@ -708,7 +712,7 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
        return 0;
 
  parse_failed:
-       printk(KERN_INFO "%s: couldn't parse config at %s!\n",
+       printk(KERN_INFO "%s: couldn't parse config at '%s'!\n",
               np->name, cur);
        return -1;
 }
@@ -735,7 +739,7 @@ int netpoll_setup(struct netpoll *np)
                npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL);
                if (!npinfo) {
                        err = -ENOMEM;
-                       goto release;
+                       goto put;
                }
 
                npinfo->rx_flags = 0;
@@ -845,7 +849,7 @@ int netpoll_setup(struct netpoll *np)
 
                kfree(npinfo);
        }
-
+put:
        dev_put(ndev);
        return err;
 }
index 4568120d8533f557c3211f627aac69b41ce3abc5..31e85d327aa2ccd7e4ec6e9ae8699ada83bbb879 100644 (file)
@@ -602,12 +602,19 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
        a->tx_compressed = b->tx_compressed;
 };
 
+/* All VF info */
 static inline int rtnl_vfinfo_size(const struct net_device *dev)
 {
-       if (dev->dev.parent && dev_is_pci(dev->dev.parent))
-               return dev_num_vf(dev->dev.parent) *
-                       sizeof(struct ifla_vf_info);
-       else
+       if (dev->dev.parent && dev_is_pci(dev->dev.parent)) {
+
+               int num_vfs = dev_num_vf(dev->dev.parent);
+               size_t size = nlmsg_total_size(sizeof(struct nlattr));
+               size += nlmsg_total_size(num_vfs * sizeof(struct nlattr));
+               size += num_vfs * (sizeof(struct ifla_vf_mac) +
+                                 sizeof(struct ifla_vf_vlan) +
+                                 sizeof(struct ifla_vf_tx_rate));
+               return size;
+       } else
                return 0;
 }
 
@@ -629,7 +636,7 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
               + nla_total_size(1) /* IFLA_OPERSTATE */
               + nla_total_size(1) /* IFLA_LINKMODE */
               + nla_total_size(4) /* IFLA_NUM_VF */
-              + nla_total_size(rtnl_vfinfo_size(dev)) /* IFLA_VFINFO */
+              + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */
               + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
 }
 
@@ -700,14 +707,37 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 
        if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) {
                int i;
-               struct ifla_vf_info ivi;
 
-               NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent));
-               for (i = 0; i < dev_num_vf(dev->dev.parent); i++) {
+               struct nlattr *vfinfo, *vf;
+               int num_vfs = dev_num_vf(dev->dev.parent);
+
+               NLA_PUT_U32(skb, IFLA_NUM_VF, num_vfs);
+               vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST);
+               if (!vfinfo)
+                       goto nla_put_failure;
+               for (i = 0; i < num_vfs; i++) {
+                       struct ifla_vf_info ivi;
+                       struct ifla_vf_mac vf_mac;
+                       struct ifla_vf_vlan vf_vlan;
+                       struct ifla_vf_tx_rate vf_tx_rate;
                        if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
                                break;
-                       NLA_PUT(skb, IFLA_VFINFO, sizeof(ivi), &ivi);
+                       vf_mac.vf = vf_vlan.vf = vf_tx_rate.vf = ivi.vf;
+                       memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
+                       vf_vlan.vlan = ivi.vlan;
+                       vf_vlan.qos = ivi.qos;
+                       vf_tx_rate.rate = ivi.tx_rate;
+                       vf = nla_nest_start(skb, IFLA_VF_INFO);
+                       if (!vf) {
+                               nla_nest_cancel(skb, vfinfo);
+                               goto nla_put_failure;
+                       }
+                       NLA_PUT(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac);
+                       NLA_PUT(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan);
+                       NLA_PUT(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate), &vf_tx_rate);
+                       nla_nest_end(skb, vf);
                }
+               nla_nest_end(skb, vfinfo);
        }
        if (dev->rtnl_link_ops) {
                if (rtnl_link_fill(skb, dev) < 0)
@@ -769,12 +799,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
        [IFLA_LINKINFO]         = { .type = NLA_NESTED },
        [IFLA_NET_NS_PID]       = { .type = NLA_U32 },
        [IFLA_IFALIAS]          = { .type = NLA_STRING, .len = IFALIASZ-1 },
-       [IFLA_VF_MAC]           = { .type = NLA_BINARY,
-                                   .len = sizeof(struct ifla_vf_mac) },
-       [IFLA_VF_VLAN]          = { .type = NLA_BINARY,
-                                   .len = sizeof(struct ifla_vf_vlan) },
-       [IFLA_VF_TX_RATE]       = { .type = NLA_BINARY,
-                                   .len = sizeof(struct ifla_vf_tx_rate) },
+       [IFLA_VFINFO_LIST]      = {. type = NLA_NESTED },
 };
 EXPORT_SYMBOL(ifla_policy);
 
@@ -783,6 +808,19 @@ static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
        [IFLA_INFO_DATA]        = { .type = NLA_NESTED },
 };
 
+static const struct nla_policy ifla_vfinfo_policy[IFLA_VF_INFO_MAX+1] = {
+       [IFLA_VF_INFO]          = { .type = NLA_NESTED },
+};
+
+static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
+       [IFLA_VF_MAC]           = { .type = NLA_BINARY,
+                                   .len = sizeof(struct ifla_vf_mac) },
+       [IFLA_VF_VLAN]          = { .type = NLA_BINARY,
+                                   .len = sizeof(struct ifla_vf_vlan) },
+       [IFLA_VF_TX_RATE]       = { .type = NLA_BINARY,
+                                   .len = sizeof(struct ifla_vf_tx_rate) },
+};
+
 struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
 {
        struct net *net;
@@ -812,6 +850,52 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
        return 0;
 }
 
+static int do_setvfinfo(struct net_device *dev, struct nlattr *attr)
+{
+       int rem, err = -EINVAL;
+       struct nlattr *vf;
+       const struct net_device_ops *ops = dev->netdev_ops;
+
+       nla_for_each_nested(vf, attr, rem) {
+               switch (nla_type(vf)) {
+               case IFLA_VF_MAC: {
+                       struct ifla_vf_mac *ivm;
+                       ivm = nla_data(vf);
+                       err = -EOPNOTSUPP;
+                       if (ops->ndo_set_vf_mac)
+                               err = ops->ndo_set_vf_mac(dev, ivm->vf,
+                                                         ivm->mac);
+                       break;
+               }
+               case IFLA_VF_VLAN: {
+                       struct ifla_vf_vlan *ivv;
+                       ivv = nla_data(vf);
+                       err = -EOPNOTSUPP;
+                       if (ops->ndo_set_vf_vlan)
+                               err = ops->ndo_set_vf_vlan(dev, ivv->vf,
+                                                          ivv->vlan,
+                                                          ivv->qos);
+                       break;
+               }
+               case IFLA_VF_TX_RATE: {
+                       struct ifla_vf_tx_rate *ivt;
+                       ivt = nla_data(vf);
+                       err = -EOPNOTSUPP;
+                       if (ops->ndo_set_vf_tx_rate)
+                               err = ops->ndo_set_vf_tx_rate(dev, ivt->vf,
+                                                             ivt->rate);
+                       break;
+               }
+               default:
+                       err = -EINVAL;
+                       break;
+               }
+               if (err)
+                       break;
+       }
+       return err;
+}
+
 static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
                      struct nlattr **tb, char *ifname, int modified)
 {
@@ -942,40 +1026,17 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
                write_unlock_bh(&dev_base_lock);
        }
 
-       if (tb[IFLA_VF_MAC]) {
-               struct ifla_vf_mac *ivm;
-               ivm = nla_data(tb[IFLA_VF_MAC]);
-               err = -EOPNOTSUPP;
-               if (ops->ndo_set_vf_mac)
-                       err = ops->ndo_set_vf_mac(dev, ivm->vf, ivm->mac);
-               if (err < 0)
-                       goto errout;
-               modified = 1;
-       }
-
-       if (tb[IFLA_VF_VLAN]) {
-               struct ifla_vf_vlan *ivv;
-               ivv = nla_data(tb[IFLA_VF_VLAN]);
-               err = -EOPNOTSUPP;
-               if (ops->ndo_set_vf_vlan)
-                       err = ops->ndo_set_vf_vlan(dev, ivv->vf,
-                                                  ivv->vlan,
-                                                  ivv->qos);
-               if (err < 0)
-                       goto errout;
-               modified = 1;
-       }
-       err = 0;
-
-       if (tb[IFLA_VF_TX_RATE]) {
-               struct ifla_vf_tx_rate *ivt;
-               ivt = nla_data(tb[IFLA_VF_TX_RATE]);
-               err = -EOPNOTSUPP;
-               if (ops->ndo_set_vf_tx_rate)
-                       err = ops->ndo_set_vf_tx_rate(dev, ivt->vf, ivt->rate);
-               if (err < 0)
-                       goto errout;
-               modified = 1;
+       if (tb[IFLA_VFINFO_LIST]) {
+               struct nlattr *attr;
+               int rem;
+               nla_for_each_nested(attr, tb[IFLA_VFINFO_LIST], rem) {
+                       if (nla_type(attr) != IFLA_VF_INFO)
+                               goto errout;
+                       err = do_setvfinfo(dev, attr);
+                       if (err < 0)
+                               goto errout;
+                       modified = 1;
+               }
        }
        err = 0;
 
@@ -1270,10 +1331,11 @@ replay:
                        err = ops->newlink(net, dev, tb, data);
                else
                        err = register_netdevice(dev);
-               if (err < 0 && !IS_ERR(dev)) {
+
+               if (err < 0 && !IS_ERR(dev))
                        free_netdev(dev);
+               if (err < 0)
                        goto out;
-               }
 
                err = rtnl_configure_link(dev, ifm);
                if (err < 0)
index 9b264634acfd6233ebfa7369cc4537638377d06d..b88f6f9d0b97503ddd353e163e73680704cde79a 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/security.h>
 #include <linux/pid.h>
 #include <linux/nsproxy.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
index 06124872af5ba017d71e6817c9e0f4c9d8ac21ea..b7b6b8208f755ceb6f64c0f7a90a0673e172410a 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/netdevice.h>
 #include <linux/ratelimit.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #include <net/ip.h>
 #include <net/sock.h>
index 813e399220a746701c1da057bbbe61d32d2d0f93..19ac2b985485f0e7ef4b408197ffb10434143c78 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/netlink.h>
+#include <linux/slab.h>
 #include <net/netlink.h>
 #include <net/rtnetlink.h>
 #include <linux/dcbnl.h>
index 49d27c556becbb3423fcff11a1561a2b864319cc..36479ca61e0392572ef46a5a39d14c9091b387b4 100644 (file)
@@ -11,6 +11,8 @@
  *     published by the Free Software Foundation.
  */
 
+#include <linux/slab.h>
+
 #include "ccid.h"
 #include "ccids/lib/tfrc.h"
 
index a47a8c918ee89e0ea2402b76f7133afd2c2eb69f..9b3ae9922be1aa446f8b57973356d216de9f82ee 100644 (file)
@@ -23,6 +23,7 @@
 /*
  * This implementation should follow RFC 4341
  */
+#include <linux/slab.h>
 #include "../feat.h"
 #include "../ccid.h"
 #include "../dccp.h"
index 972b8dc918d6ab90d5d11f55f2e2e7c585def32a..df7dd26cf07eb8c5fa131f2ce7aee8eb87f065e9 100644 (file)
@@ -22,6 +22,7 @@
  *  2 of the License, or (at your option) any later version.
  */
 #include <linux/module.h>
+#include <linux/slab.h>
 #include "ccid.h"
 #include "feat.h"
 
index 7648f316310fbe668342915d82995d833eb71a91..9ec717426024d0ab01a927653e4dd85134b72ef0 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/dccp.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 
 #include <net/sock.h>
 
index b195c4feaa0ae3390fefad4d06e50d43f08acf83..52ffa1cde15a07f597470a15d7fd5ad25bd1e695 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/dccp.h>
 #include <linux/icmp.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/random.h>
@@ -998,11 +999,11 @@ static struct inet_protosw dccp_v4_protosw = {
 
 static int __net_init dccp_v4_init_net(struct net *net)
 {
-       int err;
+       if (dccp_hashinfo.bhash == NULL)
+               return -ESOCKTNOSUPPORT;
 
-       err = inet_ctl_sock_create(&net->dccp.v4_ctl_sk, PF_INET,
-                                  SOCK_DCCP, IPPROTO_DCCP, net);
-       return err;
+       return inet_ctl_sock_create(&net->dccp.v4_ctl_sk, PF_INET,
+                                   SOCK_DCCP, IPPROTO_DCCP, net);
 }
 
 static void __net_exit dccp_v4_exit_net(struct net *net)
index 1aec6349e8582e5f0d7e7110ec0f857419575e4e..3b11e41a2929e717ded1865c864a6f7b1b5fb7e0 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/module.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <linux/xfrm.h>
 
 #include <net/addrconf.h>
@@ -1191,11 +1192,11 @@ static struct inet_protosw dccp_v6_protosw = {
 
 static int __net_init dccp_v6_init_net(struct net *net)
 {
-       int err;
+       if (dccp_hashinfo.bhash == NULL)
+               return -ESOCKTNOSUPPORT;
 
-       err = inet_ctl_sock_create(&net->dccp.v6_ctl_sk, PF_INET6,
-                                  SOCK_DCCP, IPPROTO_DCCP, net);
-       return err;
+       return inet_ctl_sock_create(&net->dccp.v6_ctl_sk, PF_INET6,
+                                   SOCK_DCCP, IPPROTO_DCCP, net);
 }
 
 static void __net_exit dccp_v6_exit_net(struct net *net)
index 0d508c359fa97f053831f15a76ea764236ca9887..128b089d3aefb0d05f7899a240ad3ced0a708d33 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/dccp.h>
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 #include <linux/timer.h>
index d6bb753bf6ad8485552bea39107a59afa0eb971a..fc3f436440b48980f01a05cb97f80960e4f5fd5a 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/dccp.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 
 #include <net/inet_sock.h>
 #include <net/sock.h>
index f5b3464f124292ef26dcbaf7562355e7ab5d5a63..078e48d442fd2df6c5e500b2db4958df7a82a534 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/kfifo.h>
 #include <linux/vmalloc.h>
+#include <linux/gfp.h>
 #include <net/net_namespace.h>
 
 #include "dccp.h"
index 0ef7061920c02ba08a124641322019a35cdaa195..a0e38d8018f55f9c7387136a3889d568d2bdfa92 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/if_arp.h>
 #include <linux/init.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <net/checksum.h>
 
 #include <net/inet_sock.h>
@@ -1036,7 +1037,7 @@ static int __init dccp_init(void)
                     FIELD_SIZEOF(struct sk_buff, cb));
        rc = percpu_counter_init(&dccp_orphan_count, 0);
        if (rc)
-               goto out;
+               goto out_fail;
        rc = -ENOBUFS;
        inet_hashinfo_init(&dccp_hashinfo);
        dccp_hashinfo.bind_bucket_cachep =
@@ -1125,8 +1126,9 @@ static int __init dccp_init(void)
                goto out_sysctl_exit;
 
        dccp_timestamping_init();
-out:
-       return rc;
+
+       return 0;
+
 out_sysctl_exit:
        dccp_sysctl_exit();
 out_ackvec_exit:
@@ -1135,18 +1137,19 @@ out_free_dccp_mib:
        dccp_mib_exit();
 out_free_dccp_bhash:
        free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order);
-       dccp_hashinfo.bhash = NULL;
 out_free_dccp_locks:
        inet_ehash_locks_free(&dccp_hashinfo);
 out_free_dccp_ehash:
        free_pages((unsigned long)dccp_hashinfo.ehash, ehash_order);
-       dccp_hashinfo.ehash = NULL;
 out_free_bind_bucket_cachep:
        kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
-       dccp_hashinfo.bind_bucket_cachep = NULL;
 out_free_percpu:
        percpu_counter_destroy(&dccp_orphan_count);
-       goto out;
+out_fail:
+       dccp_hashinfo.bhash = NULL;
+       dccp_hashinfo.ehash = NULL;
+       dccp_hashinfo.bind_bucket_cachep = NULL;
+       return rc;
 }
 
 static void __exit dccp_fini(void)
index 238af093495b2448e140fbf3366c0ad45ef8d1f0..cead68eb254c1370928ae37078a4df8b36fcd5a7 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/skbuff.h>
 #include <linux/sysctl.h>
 #include <linux/notifier.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <net/net_namespace.h>
index e9d48700e83a3a5d5bdc3dcd2c80f7fe9aea45d1..4ab96c15166d4930dd49772e41734f3eca3968f5 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/string.h>
 #include <linux/net.h>
 #include <linux/socket.h>
+#include <linux/slab.h>
 #include <linux/sockios.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
index 794b5bf95af1af0512ee10f2b4884a056ddae9ab..deb723dba44b62d8aca89aa15d9ea332001f004a 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/module.h>
 #include <linux/socket.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 #include <linux/if_ether.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
index 932408dca86da3de19a371469f1ea4d54dac1403..25a37299bc65c0fd8652c886758a372c1bdcf66a 100644 (file)
@@ -57,6 +57,7 @@
 #include <linux/netdevice.h>
 #include <linux/inet.h>
 #include <linux/route.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/tcp_states.h>
 #include <asm/system.h>
index a65e929ce76cc67b01b35642584fbf7b80b37355..baeb1eaf011be83a0dff59717f54e30241e4f0ad 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/netdevice.h>
 #include <linux/inet.h>
 #include <linux/route.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <asm/system.h>
 #include <linux/fcntl.h>
index a7bf03ca0a36a7566c3e3c8c934f819131b34ea0..70ebe74027d558750218c8bc9974d0a02f2de3c8 100644 (file)
@@ -66,6 +66,7 @@
 #include <linux/inet.h>
 #include <linux/route.h>
 #include <linux/in_route.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <linux/mm.h>
 #include <linux/proc_fs.h>
index b9a33bb5e9cce34cc82bd897e959d9c395ec4ac8..f2abd37556905923097b0f203358a785b6f722ba 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/string.h>
 #include <linux/net.h>
 #include <linux/socket.h>
+#include <linux/slab.h>
 #include <linux/sockios.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
index 6d2bd3202048a8c8b36e17ef707278cc806d89e4..64a7f39e069fbc82e7e4a1bf2a50981e92d30949 100644 (file)
@@ -14,6 +14,7 @@
  */
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/netfilter.h>
index 71489f69a42c1e38f59b5c61dfe6c2d2b557242d..6112a12578b26441c69038aaffa1cf90bd2f9b91 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/list.h>
 #include <linux/netdevice.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <net/dsa.h>
 #include "dsa_priv.h"
 
index cdf2d28a0297e84e7582301d56902573965b983e..98dfe80b45381f1c5b4bea6459f8d1b5e932c870 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/etherdevice.h>
 #include <linux/list.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include "dsa_priv.h"
 
 #define DSA_HLEN       4
index 8f53948cff4fcabe1577a805ec8af8125f8acf85..6f383322ad2508570d793f3c6bd8078c4152c0b4 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/etherdevice.h>
 #include <linux/list.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include "dsa_priv.h"
 
 #define DSA_HLEN       4
index a85c829853c00ec9e1ec4aeee2f05013d5c73c0b..d6d7d0add3cb4634fd00d61fb983973a4e5a4551 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/etherdevice.h>
 #include <linux/list.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include "dsa_priv.h"
 
 netdev_tx_t trailer_xmit(struct sk_buff *skb, struct net_device *dev)
index 29b4931aae520e254e61e655f6d71b9ba76730be..2a5a8053e0004fb1523bb7d21436eefd618a907a 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/wireless.h>
 #include <linux/skbuff.h>
 #include <linux/udp.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/inet_common.h>
 #include <linux/stat.h>
index d60e15d9365e720b56f823c1842170d12de8a218..eb00796758c312a8eb6be570977c508e3dbb48ec 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 
 #include <net/datalink.h>
 
index bad1c49fd9607ab5e70ee95a3134a28aa6a7bdbd..93c91b633a566729bc48acedc766ae3db20f3bc2 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/if.h>
 #include <linux/termios.h>     /* For TIOCOUTQ/INQ */
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <net/datalink.h>
 #include <net/psnap.h>
 #include <net/sock.h>
@@ -126,6 +127,9 @@ static int ieee802154_sock_connect(struct socket *sock, struct sockaddr *uaddr,
 {
        struct sock *sk = sock->sk;
 
+       if (addr_len < sizeof(uaddr->sa_family))
+               return -EINVAL;
+
        if (uaddr->sa_family == AF_UNSPEC)
                return sk->sk_prot->disconnect(sk, flags);
 
@@ -147,6 +151,9 @@ static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg,
        dev_load(sock_net(sk), ifr.ifr_name);
        dev = dev_get_by_name(sock_net(sk), ifr.ifr_name);
 
+       if (!dev)
+               return -ENODEV;
+
        if (dev->type == ARPHRD_IEEE802154 && dev->netdev_ops->ndo_do_ioctl)
                ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd);
 
index 9aac5aee157548d663114661d945a3188611f0d4..1a3334c2609a194015eec5b6b85c943fccc1ca92 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/if_arp.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/af_ieee802154.h>
 #include <net/ieee802154.h>
index 33137b99e47137b8b589c8efbcf6d6912e4573f1..c8097ae2482fc83c71ecf8ecced5e5657406f890 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <net/genetlink.h>
 #include <linux/nl802154.h>
 
index 135c1678fb11cea06d69d705255332a41137b9fb..71ee1108d4f86d9509a8f3ba011d066d1a41ef7c 100644 (file)
@@ -22,6 +22,7 @@
  * Maxim Osipov <maxim.osipov@siemens.com>
  */
 
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
index 199a2d9d12f9ec7f526c981789f096f2292df33e..ed0eab39f531f028e96deaa5f61755c46c4e5855 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <net/netlink.h>
 #include <net/genetlink.h>
 #include <net/wpan-phy.h>
index 9c9b85c00033718a5a4f7bf8e879869631f2b08b..10970ca85748a2a0835b2a9ac17bf26c66c1e9e2 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/if_arp.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/af_ieee802154.h>
 
index 268691256a6d2b915caeb7a951cce97aed98ecdf..3d803a1b9fb69a046205a57be9dcbe2bfb141e72 100644 (file)
@@ -16,6 +16,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/device.h>
index 33b7dffa773240a1d017a03a2f606988f4ef4e30..f71357422380b640153b004968e7cf2b0d9a5444 100644 (file)
@@ -86,6 +86,7 @@
 #include <linux/poll.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -530,6 +531,8 @@ int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr,
 {
        struct sock *sk = sock->sk;
 
+       if (addr_len < sizeof(uaddr->sa_family))
+               return -EINVAL;
        if (uaddr->sa_family == AF_UNSPEC)
                return sk->sk_prot->disconnect(sk, flags);
 
@@ -573,6 +576,9 @@ int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
        int err;
        long timeo;
 
+       if (addr_len < sizeof(uaddr->sa_family))
+               return -EINVAL;
+
        lock_sock(sk);
 
        if (uaddr->sa_family == AF_UNSPEC) {
index 987b47dc69ade1dc1b5e768fc92da16b1674be11..880a5ec6dce0e35805aa5abfb4a4cc4809698579 100644 (file)
@@ -1,6 +1,7 @@
 #include <crypto/hash.h>
 #include <linux/err.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 #include <net/ah.h>
index c4dd135428021e92e9023ac7379ac59b371fe6a5..80769f1f9fab8d529bf5de1d1141a9108fe8f256 100644 (file)
@@ -98,6 +98,7 @@
 #include <linux/net.h>
 #include <linux/rcupdate.h>
 #include <linux/jhash.h>
+#include <linux/slab.h>
 #ifdef CONFIG_SYSCTL
 #include <linux/sysctl.h>
 #endif
@@ -660,13 +661,13 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
 #endif
 #endif
 
-#ifdef CONFIG_FDDI
+#if defined(CONFIG_FDDI) || defined(CONFIG_FDDI_MODULE)
        case ARPHRD_FDDI:
                arp->ar_hrd = htons(ARPHRD_ETHER);
                arp->ar_pro = htons(ETH_P_IP);
                break;
 #endif
-#ifdef CONFIG_TR
+#if defined(CONFIG_TR) || defined(CONFIG_TR_MODULE)
        case ARPHRD_IEEE802_TR:
                arp->ar_hrd = htons(ARPHRD_IEEE802);
                arp->ar_pro = htons(ETH_P_IP);
@@ -1050,7 +1051,7 @@ static int arp_req_set(struct net *net, struct arpreq *r,
                        return -EINVAL;
        }
        switch (dev->type) {
-#ifdef CONFIG_FDDI
+#if defined(CONFIG_FDDI) || defined(CONFIG_FDDI_MODULE)
        case ARPHRD_FDDI:
                /*
                 * According to RFC 1390, FDDI devices should accept ARP
index 1e029dc754550b76576521331170bcd069fbd8c2..c97cd9ff697ee1cba4f373333190126c57970f28 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/string.h>
 #include <linux/jhash.h>
 #include <linux/audit.h>
+#include <linux/slab.h>
 #include <net/ip.h>
 #include <net/icmp.h>
 #include <net/tcp.h>
index 51ca946e339268b58181870695906e1f29257d85..90e3d6379a42ae369ceeba06c783978858e96e71 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/notifier.h>
 #include <linux/inetdevice.h>
 #include <linux/igmp.h>
+#include <linux/slab.h>
 #ifdef CONFIG_SYSCTL
 #include <linux/sysctl.h>
 #endif
@@ -1194,7 +1195,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
                hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
                        if (idx < s_idx)
                                goto cont;
-                       if (idx > s_idx)
+                       if (h > s_h || idx > s_idx)
                                s_ip_idx = 0;
                        in_dev = __in_dev_get_rcu(dev);
                        if (!in_dev)
index 9b3e28ed524077860c8925894646163fe241f608..4f0ed458c883658c37265fe6537bde2ac8b88429 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 
 #include <net/ip.h>
 #include <net/protocol.h>
index 14972017b9c2ad727369a124f95116ff95af430d..4ed7e0dea1bc0e8b33bb1f094e712b59fb6715ad 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/skbuff.h>
 #include <linux/netlink.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #include <net/net_namespace.h>
 #include <net/ip.h>
index 1af0ea0fb6a20227c941e8ad910d3634ff2a1319..20f09c5b31e8bba5e3580255fe5f8d541c14d374 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/proc_fs.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #include <net/arp.h>
 #include <net/ip.h>
index af5d897928606df52c3f97483f860c934d2bf6fd..c98f115fb0fde6d97136695075fa45c04976c4be 100644 (file)
@@ -71,6 +71,7 @@
 #include <linux/netlink.h>
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/ip.h>
 #include <net/protocol.h>
@@ -208,7 +209,9 @@ static inline struct node *tnode_get_child_rcu(struct tnode *tn, unsigned int i)
 {
        struct node *ret = tnode_get_child(tn, i);
 
-       return rcu_dereference(ret);
+       return rcu_dereference_check(ret,
+                                    rcu_read_lock_held() ||
+                                    lockdep_rtnl_is_held());
 }
 
 static inline int tnode_child_length(const struct tnode *tn)
@@ -961,7 +964,9 @@ fib_find_node(struct trie *t, u32 key)
        struct node *n;
 
        pos = 0;
-       n = rcu_dereference(t->trie);
+       n = rcu_dereference_check(t->trie,
+                                 rcu_read_lock_held() ||
+                                 lockdep_rtnl_is_held());
 
        while (n != NULL &&  NODE_TYPE(n) == T_TNODE) {
                tn = (struct tnode *) n;
index 4b4c2bcd15db4b4464be428a954ee8686769b68b..ac4dec1327354020b35f7404f5f47f4d463aba3f 100644 (file)
@@ -74,6 +74,7 @@
 #include <linux/netdevice.h>
 #include <linux/string.h>
 #include <linux/netfilter_ipv4.h>
+#include <linux/slab.h>
 #include <net/snmp.h>
 #include <net/ip.h>
 #include <net/route.h>
index 63bf298ca109f6bffba83bc8ba835d2d96e52cf8..15d3eeda92f5c7876698dac44048ff1c4bbc09b7 100644 (file)
@@ -71,6 +71,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <linux/types.h>
index 1aaa8110d84be07d51d0bff955056e33db34e001..e5fa2ddce320adafac68cdbf19bfefdae534cf2c 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <linux/cache.h>
 #include <linux/init.h>
 #include <linux/time.h>
index eaf3e2c8646a438a938f341151c04920746a3c5f..a2ca6aed763bad1e0c449d32e79786512b553ef7 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/random.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
+#include <linux/slab.h>
 
 #include <net/inet_frag.h>
 
index cc94cc2d8b2d8825d909266b501afb1c6ea03cab..c5af909cf701c37dfb2afecf078de854349c2950 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/kernel.h>
 #include <linux/kmemcheck.h>
+#include <linux/slab.h>
 #include <net/inet_hashtables.h>
 #include <net/inet_timewait_sock.h>
 #include <net/ip.h>
index a2991bc8e32e5e0b89727086fb1484dfe65ffdc4..af10942b326c4f51cdd49c61411a009e2d80a026 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/ip.h>
 #include <linux/icmp.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/ip.h>
 #include <net/tcp.h>
index b59430bc041ca99d4d653e5a1791bd279392ffc5..75347ea70ea071d6fef5223535b6bb83973b602b 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/netdevice.h>
 #include <linux/jhash.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <net/route.h>
 #include <net/dst.h>
 #include <net/sock.h>
index f47c9f76754b2f03d900bf2cabe9907f93907bd3..fe381d12ecdd4227e785ff54f6e0b97162914f55 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
@@ -810,11 +811,13 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
                        tunnel->err_count = 0;
        }
 
-       max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen;
+       max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen + rt->u.dst.header_len;
 
        if (skb_headroom(skb) < max_headroom || skb_shared(skb)||
            (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
                struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
+               if (max_headroom > dev->needed_headroom)
+                       dev->needed_headroom = max_headroom;
                if (!new_skb) {
                        ip_rt_put(rt);
                        txq->tx_dropped++;
index c29de9879fdae1e56d1ac2a2572159aab1b31854..f8ab7a380d4a64b12696eeab5c5f23ab5ca332db 100644 (file)
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 
 #include <linux/net.h>
 #include <linux/socket.h>
index 94bf105ef3c9b7e593df4b8aee0a016d0a9022e7..4c09a31fd140c115a6f9cb4469d3f62aa10e56ae 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/capability.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <asm/uaccess.h>
 #include <linux/skbuff.h>
index 3451799e3dbf78253d70995d37697a1b546f143d..d1bcc9f21d4fb57fc53670f046bcedfe3a98bef0 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 
 #include <linux/socket.h>
 #include <linux/sockios.h>
@@ -119,7 +120,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb)
        newskb->pkt_type = PACKET_LOOPBACK;
        newskb->ip_summed = CHECKSUM_UNNECESSARY;
        WARN_ON(!skb_dst(newskb));
-       netif_rx(newskb);
+       netif_rx_ni(newskb);
        return 0;
 }
 
index 644dc43a55dec954dc7232b3edb58c3412951540..1e64dabbd232ea41bdbf6825b9358dc18b741931 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/icmp.h>
 #include <linux/inetdevice.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/ip.h>
 #include <net/icmp.h>
index 6789092816487ee51220502282371d7939e9a6e5..067ce9e043dc2e6d5013681815e6da46ef8cc060 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/root_dev.h>
 #include <linux/delay.h>
 #include <linux/nfs_fs.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/arp.h>
 #include <net/ip.h>
index 2f302d3ac9a3c27e4f29dd1f1c71811353db73d5..0b27b14dcc9d65e6545327ef98a3ece61419214f 100644 (file)
@@ -95,6 +95,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
index 8582e12e4a62a8b11ec53d129aabbf16842fcc8e..ec19a890c9a0eb02ba9deec1b099422690e621c0 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/mroute.h>
 #include <linux/init.h>
 #include <linux/if_ether.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/ip.h>
 #include <net/protocol.h>
@@ -753,7 +754,8 @@ ipmr_cache_unresolved(struct net *net, vifi_t vifi, struct sk_buff *skb)
                c->next = mfc_unres_queue;
                mfc_unres_queue = c;
 
-               mod_timer(&ipmr_expire_timer, c->mfc_un.unres.expires);
+               if (atomic_read(&net->ipv4.cache_resolve_queue_len) == 1)
+                       mod_timer(&ipmr_expire_timer, c->mfc_un.unres.expires);
        }
 
        /*
@@ -802,6 +804,9 @@ static int ipmr_mfc_add(struct net *net, struct mfcctl *mfc, int mrtsock)
        int line;
        struct mfc_cache *uc, *c, **cp;
 
+       if (mfc->mfcc_parent >= MAXVIFS)
+               return -ENFILE;
+
        line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr);
 
        for (cp = &net->ipv4.mfc_cache_array[line];
@@ -1613,17 +1618,20 @@ ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm)
        int ct;
        struct rtnexthop *nhp;
        struct net *net = mfc_net(c);
-       struct net_device *dev = net->ipv4.vif_table[c->mfc_parent].dev;
        u8 *b = skb_tail_pointer(skb);
        struct rtattr *mp_head;
 
-       if (dev)
-               RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex);
+       /* If cache is unresolved, don't try to parse IIF and OIF */
+       if (c->mfc_parent > MAXVIFS)
+               return -ENOENT;
+
+       if (VIF_EXISTS(net, c->mfc_parent))
+               RTA_PUT(skb, RTA_IIF, 4, &net->ipv4.vif_table[c->mfc_parent].dev->ifindex);
 
        mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0));
 
        for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) {
-               if (c->mfc_un.res.ttls[ct] < 255) {
+               if (VIF_EXISTS(net, ct) && c->mfc_un.res.ttls[ct] < 255) {
                        if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4))
                                goto rtattr_failure;
                        nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp)));
index c14623fc4d5eab4f9203580e67a29161583358fa..82fb43c5c59ef9cf058646516521406437b70b87 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/netfilter_ipv4.h>
 #include <linux/ip.h>
 #include <linux/skbuff.h>
+#include <linux/gfp.h>
 #include <net/route.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
index bfe26f32b93069fc478cc559973b0b2cf743154f..79ca5e70d49774e074613fe2c55cee941386542a 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/module.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_arp/arp_tables.h>
+#include <linux/slab.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
index 2855f1f38cbc2b2278197c3d6522db7883f8a076..e2787048aa0a4f9008cb8389e89baaaa45717fce 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/security.h>
 #include <linux/net.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
 #include <net/route.h>
index 0886f96c736b12b1ddcc50bbb365a3d4e68d1a0d..ab828400ed7160c146f8dc058edf9b17dc81ab96 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/jhash.h>
 #include <linux/bitops.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
index 5113b8f1a379e5210ca7358aa74b77671e3225b1..a0e8bcf041592cac88b9a623cb001e22cd0b55cd 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/ip.h>
 #include <linux/udp.h>
 #include <linux/icmp.h>
index 09a5d3f7cc41e5588febe4fbc6be1e085ce35212..0dbe697f164fd38487a6a8a09e56d83cc00a2352 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/socket.h>
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/kernel.h>
 #include <linux/timer.h>
index c8dc9800d62066d593a4392ccb30fa1d9bbbd0cf..55392466daa49fd455a4c28d6b168c388db2eff2 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/slab.h>
 #include <net/ip.h>
 
 MODULE_LICENSE("GPL");
index b9b83464cbf4bf91d745c01e25b1d45bbc12546d..294a2a32f29345e1ceb39f13afbcc605e586bc4f 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/route.h>
 #include <linux/ip.h>
index 06fb9d11953cadbcf76b6d6ccbf0edaaf78d425a..07fb710cd722f329ea297b764f50cfeb0ad8175e 100644 (file)
@@ -5,6 +5,7 @@
  */
 #include <linux/module.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/slab.h>
 #include <net/ip.h>
 
 #define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
index cce2f64e6f21ee61822adf28f0fcc988dffe4239..be45bdc4c60251a0936e8e5f7d0c6ea56d0e6eec 100644 (file)
@@ -17,6 +17,7 @@
  */
 #include <linux/module.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/slab.h>
 #include <net/ip.h>
 
 MODULE_LICENSE("GPL");
index 4595281c28635b30d4522d75aafdc57e82828b4a..4f8bddb760c9cb47d6931647d8b03ece5fef5fc0 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/types.h>
 #include <linux/timer.h>
 #include <linux/skbuff.h>
+#include <linux/gfp.h>
 #include <net/checksum.h>
 #include <net/icmp.h>
 #include <net/ip.h>
index 4b6af4bb1f500f4e1ed309c305b94111088d12f4..4a0c6b548eee22f1dfc0e6d01187f209319f10d7 100644 (file)
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/kmod.h>
 #include <linux/types.h>
 #include <linux/timer.h>
index ab74cc0535e26843d1c50a9e050f841ce4cd40bc..26de2c1f7fabd1a0e1b135fd487595311aa1793a 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kmod.h>
 #include <linux/skbuff.h>
 #include <linux/proc_fs.h>
+#include <linux/slab.h>
 #include <net/checksum.h>
 #include <net/route.h>
 #include <linux/bitops.h>
index 0b9c7ce3d6c584a90fa012a96e9baa7a6deab317..4d85b6e55f2978f31cbe2aa85d2fbbf95d9bbdb4 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/in.h>
 #include <linux/ip.h>
 #include <linux/udp.h>
index 5678e9562c15b706f930799419ae76297c4a4775..c39c9cf6bee67f9f853f7a8f7c3faa00a440fbba 100644 (file)
@@ -7,6 +7,7 @@
  */
 #include <linux/types.h>
 #include <linux/icmp.h>
+#include <linux/gfp.h>
 #include <linux/ip.h>
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv4.h>
index ce154b47f1da08fd5c0ef874920bbb70aa1e90bb..cc6f097fbd5fb9a24ce0b80737f6973ee48e3b7a 100644 (file)
@@ -60,7 +60,6 @@
 #include <net/net_namespace.h>
 #include <net/dst.h>
 #include <net/sock.h>
-#include <linux/gfp.h>
 #include <linux/ip.h>
 #include <linux/net.h>
 #include <net/ip.h>
index d9b40248b97feb4a1e3e4dd01c9ec789b4494842..cb562fdd9b9a5342cee41f2cc642a8b4af9e30ce 100644 (file)
@@ -90,6 +90,7 @@
 #include <linux/jhash.h>
 #include <linux/rcupdate.h>
 #include <linux/times.h>
+#include <linux/slab.h>
 #include <net/dst.h>
 #include <net/net_namespace.h>
 #include <net/protocol.h>
@@ -932,10 +933,8 @@ static void rt_secret_rebuild_oneshot(struct net *net)
 {
        del_timer_sync(&net->ipv4.rt_secret_timer);
        rt_cache_invalidate(net);
-       if (ip_rt_secret_interval) {
-               net->ipv4.rt_secret_timer.expires += ip_rt_secret_interval;
-               add_timer(&net->ipv4.rt_secret_timer);
-       }
+       if (ip_rt_secret_interval)
+               mod_timer(&net->ipv4.rt_secret_timer, jiffies + ip_rt_secret_interval);
 }
 
 static void rt_emergency_hash_rebuild(struct net *net)
@@ -1099,7 +1098,7 @@ static int slow_chain_length(const struct rtable *head)
 }
 
 static int rt_intern_hash(unsigned hash, struct rtable *rt,
-                         struct rtable **rp, struct sk_buff *skb)
+                         struct rtable **rp, struct sk_buff *skb, int ifindex)
 {
        struct rtable   *rth, **rthp;
        unsigned long   now;
@@ -1214,11 +1213,16 @@ restart:
                    slow_chain_length(rt_hash_table[hash].chain) > rt_chain_length_max) {
                        struct net *net = dev_net(rt->u.dst.dev);
                        int num = ++net->ipv4.current_rt_cache_rebuild_count;
-                       if (!rt_caching(dev_net(rt->u.dst.dev))) {
+                       if (!rt_caching(net)) {
                                printk(KERN_WARNING "%s: %d rebuilds is over limit, route caching disabled\n",
                                        rt->u.dst.dev->name, num);
                        }
-                       rt_emergency_hash_rebuild(dev_net(rt->u.dst.dev));
+                       rt_emergency_hash_rebuild(net);
+                       spin_unlock_bh(rt_hash_lock_addr(hash));
+
+                       hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src,
+                                       ifindex, rt_genid(net));
+                       goto restart;
                }
        }
 
@@ -1443,7 +1447,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
                                        dev_hold(rt->u.dst.dev);
                                if (rt->idev)
                                        in_dev_hold(rt->idev);
-                               rt->u.dst.obsolete      = 0;
+                               rt->u.dst.obsolete      = -1;
                                rt->u.dst.lastuse       = jiffies;
                                rt->u.dst.path          = &rt->u.dst;
                                rt->u.dst.neighbour     = NULL;
@@ -1479,7 +1483,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
                                                        &netevent);
 
                                rt_del(hash, rth);
-                               if (!rt_intern_hash(hash, rt, &rt, NULL))
+                               if (!rt_intern_hash(hash, rt, &rt, NULL, rt->fl.oif))
                                        ip_rt_put(rt);
                                goto do_next;
                        }
@@ -1508,11 +1512,12 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
        struct dst_entry *ret = dst;
 
        if (rt) {
-               if (dst->obsolete) {
+               if (dst->obsolete > 0) {
                        ip_rt_put(rt);
                        ret = NULL;
                } else if ((rt->rt_flags & RTCF_REDIRECTED) ||
-                          rt->u.dst.expires) {
+                          (rt->u.dst.expires &&
+                           time_after_eq(jiffies, rt->u.dst.expires))) {
                        unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src,
                                                rt->fl.oif,
                                                rt_genid(dev_net(dst->dev)));
@@ -1728,7 +1733,9 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
 
 static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
 {
-       return NULL;
+       if (rt_is_expired((struct rtable *)dst))
+               return NULL;
+       return dst;
 }
 
 static void ipv4_dst_destroy(struct dst_entry *dst)
@@ -1890,7 +1897,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        if (!rth)
                goto e_nobufs;
 
-       rth->u.dst.output= ip_rt_bug;
+       rth->u.dst.output = ip_rt_bug;
+       rth->u.dst.obsolete = -1;
 
        atomic_set(&rth->u.dst.__refcnt, 1);
        rth->u.dst.flags= DST_HOST;
@@ -1929,7 +1937,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 
        in_dev_put(in_dev);
        hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev)));
-       return rt_intern_hash(hash, rth, NULL, skb);
+       return rt_intern_hash(hash, rth, NULL, skb, dev->ifindex);
 
 e_nobufs:
        in_dev_put(in_dev);
@@ -2056,6 +2064,7 @@ static int __mkroute_input(struct sk_buff *skb,
        rth->fl.oif     = 0;
        rth->rt_spec_dst= spec_dst;
 
+       rth->u.dst.obsolete = -1;
        rth->u.dst.input = ip_forward;
        rth->u.dst.output = ip_output;
        rth->rt_genid = rt_genid(dev_net(rth->u.dst.dev));
@@ -2095,7 +2104,7 @@ static int ip_mkroute_input(struct sk_buff *skb,
        /* put it into the cache */
        hash = rt_hash(daddr, saddr, fl->iif,
                       rt_genid(dev_net(rth->u.dst.dev)));
-       return rt_intern_hash(hash, rth, NULL, skb);
+       return rt_intern_hash(hash, rth, NULL, skb, fl->iif);
 }
 
 /*
@@ -2220,6 +2229,7 @@ local_input:
                goto e_nobufs;
 
        rth->u.dst.output= ip_rt_bug;
+       rth->u.dst.obsolete = -1;
        rth->rt_genid = rt_genid(net);
 
        atomic_set(&rth->u.dst.__refcnt, 1);
@@ -2251,7 +2261,7 @@ local_input:
        }
        rth->rt_type    = res.type;
        hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net));
-       err = rt_intern_hash(hash, rth, NULL, skb);
+       err = rt_intern_hash(hash, rth, NULL, skb, fl.iif);
        goto done;
 
 no_route:
@@ -2446,6 +2456,7 @@ static int __mkroute_output(struct rtable **result,
        rth->rt_spec_dst= fl->fl4_src;
 
        rth->u.dst.output=ip_output;
+       rth->u.dst.obsolete = -1;
        rth->rt_genid = rt_genid(dev_net(dev_out));
 
        RT_CACHE_STAT_INC(out_slow_tot);
@@ -2497,7 +2508,7 @@ static int ip_mkroute_output(struct rtable **rp,
        if (err == 0) {
                hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif,
                               rt_genid(dev_net(dev_out)));
-               err = rt_intern_hash(hash, rth, rp, NULL);
+               err = rt_intern_hash(hash, rth, rp, NULL, oldflp->oif);
        }
 
        return err;
@@ -3103,22 +3114,20 @@ static void rt_secret_reschedule(int old)
        rtnl_lock();
        for_each_net(net) {
                int deleted = del_timer_sync(&net->ipv4.rt_secret_timer);
+               long time;
 
                if (!new)
                        continue;
 
                if (deleted) {
-                       long time = net->ipv4.rt_secret_timer.expires - jiffies;
+                       time = net->ipv4.rt_secret_timer.expires - jiffies;
 
                        if (time <= 0 || (time += diff) <= 0)
                                time = 0;
-
-                       net->ipv4.rt_secret_timer.expires = time;
                } else
-                       net->ipv4.rt_secret_timer.expires = new;
+                       time = new;
 
-               net->ipv4.rt_secret_timer.expires += jiffies;
-               add_timer(&net->ipv4.rt_secret_timer);
+               mod_timer(&net->ipv4.rt_secret_timer, jiffies + time);
        }
        rtnl_unlock();
 }
index c1bc074f61b7dd53181fe3952ffdce7bf71ce2a5..1cd5c15174b8a0f286fd9d7a92100841dd341ecd 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/inetdevice.h>
 #include <linux/seqlock.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <net/snmp.h>
 #include <net/icmp.h>
 #include <net/ip.h>
index 5901010fad55bc969fe509ae8d3fde0aef443b2d..296150b2a62f11ac127177b6cdfaf73d1dfc4c6a 100644 (file)
 #include <linux/err.h>
 #include <linux/crypto.h>
 #include <linux/time.h>
+#include <linux/slab.h>
 
 #include <net/icmp.h>
 #include <net/tcp.h>
@@ -429,7 +430,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
                if (tp->urg_seq == tp->copied_seq &&
                    !sock_flag(sk, SOCK_URGINLINE) &&
                    tp->urg_data)
-                       target--;
+                       target++;
 
                /* Potential race condition. If read of tp below will
                 * escape above sk->sk_state, we can be illegally awaken
@@ -1254,6 +1255,39 @@ static void tcp_prequeue_process(struct sock *sk)
        tp->ucopy.memory = 0;
 }
 
+#ifdef CONFIG_NET_DMA
+static void tcp_service_net_dma(struct sock *sk, bool wait)
+{
+       dma_cookie_t done, used;
+       dma_cookie_t last_issued;
+       struct tcp_sock *tp = tcp_sk(sk);
+
+       if (!tp->ucopy.dma_chan)
+               return;
+
+       last_issued = tp->ucopy.dma_cookie;
+       dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+
+       do {
+               if (dma_async_memcpy_complete(tp->ucopy.dma_chan,
+                                             last_issued, &done,
+                                             &used) == DMA_SUCCESS) {
+                       /* Safe to free early-copied skbs now */
+                       __skb_queue_purge(&sk->sk_async_wait_queue);
+                       break;
+               } else {
+                       struct sk_buff *skb;
+                       while ((skb = skb_peek(&sk->sk_async_wait_queue)) &&
+                              (dma_async_is_complete(skb->dma_cookie, done,
+                                                     used) == DMA_SUCCESS)) {
+                               __skb_dequeue(&sk->sk_async_wait_queue);
+                               kfree_skb(skb);
+                       }
+               }
+       } while (wait);
+}
+#endif
+
 static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off)
 {
        struct sk_buff *skb;
@@ -1335,6 +1369,7 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
                sk_eat_skb(sk, skb, 0);
                if (!desc->count)
                        break;
+               tp->copied_seq = seq;
        }
        tp->copied_seq = seq;
 
@@ -1546,6 +1581,10 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                        /* __ Set realtime policy in scheduler __ */
                }
 
+#ifdef CONFIG_NET_DMA
+               if (tp->ucopy.dma_chan)
+                       dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+#endif
                if (copied >= target) {
                        /* Do not sleep, just process backlog. */
                        release_sock(sk);
@@ -1554,6 +1593,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                        sk_wait_data(sk, &timeo);
 
 #ifdef CONFIG_NET_DMA
+               tcp_service_net_dma(sk, false);  /* Don't block */
                tp->ucopy.wakeup = 0;
 #endif
 
@@ -1633,6 +1673,9 @@ do_prequeue:
                                                copied = -EFAULT;
                                        break;
                                }
+
+                               dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+
                                if ((offset + used) == skb->len)
                                        copied_early = 1;
 
@@ -1702,27 +1745,9 @@ skip_copy:
        }
 
 #ifdef CONFIG_NET_DMA
-       if (tp->ucopy.dma_chan) {
-               dma_cookie_t done, used;
-
-               dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
-
-               while (dma_async_memcpy_complete(tp->ucopy.dma_chan,
-                                                tp->ucopy.dma_cookie, &done,
-                                                &used) == DMA_IN_PROGRESS) {
-                       /* do partial cleanup of sk_async_wait_queue */
-                       while ((skb = skb_peek(&sk->sk_async_wait_queue)) &&
-                              (dma_async_is_complete(skb->dma_cookie, done,
-                                                     used) == DMA_SUCCESS)) {
-                               __skb_dequeue(&sk->sk_async_wait_queue);
-                               kfree_skb(skb);
-                       }
-               }
+       tcp_service_net_dma(sk, true);  /* Wait for queue to drain */
+       tp->ucopy.dma_chan = NULL;
 
-               /* Safe to free early-copied skbs now */
-               __skb_queue_purge(&sk->sk_async_wait_queue);
-               tp->ucopy.dma_chan = NULL;
-       }
        if (tp->ucopy.pinned_list) {
                dma_unpin_iovec_pages(tp->ucopy.pinned_list);
                tp->ucopy.pinned_list = NULL;
@@ -2814,7 +2839,6 @@ static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool * __percpu *pool)
                        if (p->md5_desc.tfm)
                                crypto_free_hash(p->md5_desc.tfm);
                        kfree(p);
-                       p = NULL;
                }
        }
        free_percpu(pool);
@@ -2912,25 +2936,40 @@ retry:
 
 EXPORT_SYMBOL(tcp_alloc_md5sig_pool);
 
-struct tcp_md5sig_pool *__tcp_get_md5sig_pool(int cpu)
+
+/**
+ *     tcp_get_md5sig_pool - get md5sig_pool for this user
+ *
+ *     We use percpu structure, so if we succeed, we exit with preemption
+ *     and BH disabled, to make sure another thread or softirq handling
+ *     wont try to get same context.
+ */
+struct tcp_md5sig_pool *tcp_get_md5sig_pool(void)
 {
        struct tcp_md5sig_pool * __percpu *p;
-       spin_lock_bh(&tcp_md5sig_pool_lock);
+
+       local_bh_disable();
+
+       spin_lock(&tcp_md5sig_pool_lock);
        p = tcp_md5sig_pool;
        if (p)
                tcp_md5sig_users++;
-       spin_unlock_bh(&tcp_md5sig_pool_lock);
-       return (p ? *per_cpu_ptr(p, cpu) : NULL);
-}
+       spin_unlock(&tcp_md5sig_pool_lock);
 
-EXPORT_SYMBOL(__tcp_get_md5sig_pool);
+       if (p)
+               return *per_cpu_ptr(p, smp_processor_id());
 
-void __tcp_put_md5sig_pool(void)
+       local_bh_enable();
+       return NULL;
+}
+EXPORT_SYMBOL(tcp_get_md5sig_pool);
+
+void tcp_put_md5sig_pool(void)
 {
+       local_bh_enable();
        tcp_free_md5sig_pool();
 }
-
-EXPORT_SYMBOL(__tcp_put_md5sig_pool);
+EXPORT_SYMBOL(tcp_put_md5sig_pool);
 
 int tcp_md5_hash_header(struct tcp_md5sig_pool *hp,
                        struct tcphdr *th)
index 6428b342b16442d48864c53ee7d4f8b25fc6a42c..0ec9bd0ae94f2ef37024ac11c5e411f0179c816a 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/mm.h>
 #include <linux/types.h>
 #include <linux/list.h>
+#include <linux/gfp.h>
 #include <net/tcp.h>
 
 int sysctl_tcp_max_ssthresh = 0;
index 788851ca8c5d10578afceb8be921638f1ed8254d..f240f57b2199e0e7e801212742b152dae2060608 100644 (file)
@@ -62,6 +62,7 @@
  */
 
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/sysctl.h>
 #include <linux/kernel.h>
@@ -2511,6 +2512,9 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
        int err;
        unsigned int mss;
 
+       if (packets == 0)
+               return;
+
        WARN_ON(packets > tp->packets_out);
        if (tp->lost_skb_hint) {
                skb = tp->lost_skb_hint;
index 70df40980a87a201e79f036aebabcfcc9dbb68c4..3c23e70885f41b2eb486731b708867b2000c408e 100644 (file)
@@ -60,6 +60,7 @@
 #include <linux/jhash.h>
 #include <linux/init.h>
 #include <linux/times.h>
+#include <linux/slab.h>
 
 #include <net/net_namespace.h>
 #include <net/icmp.h>
@@ -370,6 +371,11 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
        if (sk->sk_state == TCP_CLOSE)
                goto out;
 
+       if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) {
+               NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP);
+               goto out;
+       }
+
        icsk = inet_csk(sk);
        tp = tcp_sk(sk);
        seq = ntohl(th->seq);
index 4199bc6915c549231f481aeef9f3f7fd1f435464..5fabff9ac6d6b42596fcc96727598e087b455ceb 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/workqueue.h>
 #include <net/tcp.h>
index f181b78f2385b962588f262befeb8d597570faa4..0dda86e72ad8b6d60e24d62128ccadf7ae65a0fe 100644 (file)
@@ -37,6 +37,7 @@
 #include <net/tcp.h>
 
 #include <linux/compiler.h>
+#include <linux/gfp.h>
 #include <linux/module.h>
 
 /* People can turn this off for buggy TCP's found in printers etc. */
index 9bc805df95d2374369e7dd3d2f1f526f581996f5..f8efada580e8fed87b33ea52f27f415034a4d62e 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kprobes.h>
 #include <linux/socket.h>
 #include <linux/tcp.h>
+#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/module.h>
 #include <linux/ktime.h>
index b2e6bbccaee17eef52a3aca0466db51f89ea0d48..8a0ab2977f1fd8be8c4bf9f27d21efa9c214418e 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <net/tcp.h>
 
 int sysctl_tcp_syn_retries __read_mostly = TCP_SYN_RETRIES;
index 3959e0ca456a09ce2457e120e2244358629ee428..3b3813cc80b9cb7e1c5afcf2f7acfb9dce32f50b 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/mutex.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/icmp.h>
 #include <net/ip.h>
 #include <net/protocol.h>
index 7af756d0f93174416a341d4fb1717adbda9b6794..c36522a0f1130005f96bd11fc385c42d949c6e80 100644 (file)
@@ -95,6 +95,7 @@
 #include <linux/mm.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <net/tcp_states.h>
 #include <linux/skbuff.h>
 #include <linux/proc_fs.h>
@@ -471,8 +472,8 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
                        if (hslot->count < hslot2->count)
                                goto begin;
 
-                       result = udp4_lib_lookup2(net, INADDR_ANY, sport,
-                                                 daddr, hnum, dif,
+                       result = udp4_lib_lookup2(net, saddr, sport,
+                                                 INADDR_ANY, hnum, dif,
                                                  hslot2, slot2);
                }
                rcu_read_unlock();
@@ -1526,6 +1527,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 
        uh   = udp_hdr(skb);
        ulen = ntohs(uh->len);
+       saddr = ip_hdr(skb)->saddr;
+       daddr = ip_hdr(skb)->daddr;
+
        if (ulen > skb->len)
                goto short_packet;
 
@@ -1539,9 +1543,6 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
        if (udp4_csum_init(skb, uh, proto))
                goto csum_error;
 
-       saddr = ip_hdr(skb)->saddr;
-       daddr = ip_hdr(skb)->daddr;
-
        if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
                return __udp4_lib_mcast_deliver(net, skb, uh,
                                saddr, daddr, udptable);
index f9f922a0ba88754d86d920b8417b4098d47d082a..c791bb63203f2895a629d26b4734e152d17295cd 100644 (file)
@@ -9,6 +9,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/netfilter.h>
index 3444f3b34ecae4cb964f0fa84b1627bed1573b06..6f368413eb0e6b35bdb4500f175372809f43a18d 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au>
  */
 
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index 3381b4317c270230a7c44ee7d57daf6ac4345897..413054f02aab3dbfe5773f9a81b1589cd21d5027 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/route.h>
 #include <linux/inetdevice.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #ifdef CONFIG_SYSCTL
 #include <linux/sysctl.h>
 #endif
@@ -3610,7 +3611,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
                hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
                        if (idx < s_idx)
                                goto cont;
-                       if (idx > s_idx)
+                       if (h > s_h || idx > s_idx)
                                s_ip_idx = 0;
                        ip_idx = 0;
                        if ((idev = __in6_dev_get(dev)) == NULL)
index 6ff73c4c126aeabc14e102df05d879f4463825e9..ae404c9a746c3fe088144b16aca92b84108a5b37 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/list.h>
 #include <linux/rcupdate.h>
 #include <linux/in6.h>
+#include <linux/slab.h>
 #include <net/addrconf.h>
 #include <linux/if_addrlabel.h>
 #include <linux/netlink.h>
index 37d14e735c273438bdd6a3361f551be7b82c4de8..3f9e86b15e0d867e1b85125b4521edbc0092054d 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #include <linux/inet.h>
 #include <linux/netdevice.h>
@@ -199,7 +200,7 @@ lookup_protocol:
 
        inet_sk(sk)->pinet6 = np = inet6_sk_generic(sk);
        np->hop_limit   = -1;
-       np->mcast_hops  = -1;
+       np->mcast_hops  = IPV6_DEFAULT_MCASTHOPS;
        np->mc_loop     = 1;
        np->pmtudisc    = IPV6_PMTUDISC_WANT;
        np->ipv6only    = net->ipv6.sysctl.bindv6only;
index 5ac89025f9de15f20e8a9a3b2639df31897cd234..ee82d4ef26ce8d81146bf769572dbf4d728a9bf3 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <crypto/hash.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <net/ip.h>
 #include <net/ah.h>
 #include <linux/crypto.h>
index c4f6ca32fa749f74d8e327488911113f9d0b9084..b5b07054508a5154315c99f0da67b903e9ce46ee 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <net/net_namespace.h>
 #include <net/sock.h>
index e6f9cdf780fe4083dca668d25b495ab80fc34d66..61573885e4517abca63a36ae1f30999470ef2a32 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/in6.h>
 #include <linux/ipv6.h>
 #include <linux/route.h>
+#include <linux/slab.h>
 
 #include <net/ipv6.h>
 #include <net/ndisc.h>
@@ -221,6 +222,8 @@ void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
        if (!skb)
                return;
 
+       skb->protocol = htons(ETH_P_IPV6);
+
        serr = SKB_EXT_ERR(skb);
        serr->ee.ee_errno = err;
        serr->ee.ee_origin = SO_EE_ORIGIN_ICMP6;
@@ -254,6 +257,8 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info)
        if (!skb)
                return;
 
+       skb->protocol = htons(ETH_P_IPV6);
+
        skb_put(skb, sizeof(struct ipv6hdr));
        skb_reset_network_header(skb);
        iph = ipv6_hdr(skb);
@@ -318,7 +323,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
                sin->sin6_flowinfo = 0;
                sin->sin6_port = serr->port;
                sin->sin6_scope_id = 0;
-               if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) {
+               if (skb->protocol == htons(ETH_P_IPV6)) {
                        ipv6_addr_copy(&sin->sin6_addr,
                                  (struct in6_addr *)(nh + serr->addr_offset));
                        if (np->sndflow)
@@ -340,7 +345,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
                sin->sin6_family = AF_INET6;
                sin->sin6_flowinfo = 0;
                sin->sin6_scope_id = 0;
-               if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) {
+               if (skb->protocol == htons(ETH_P_IPV6)) {
                        ipv6_addr_copy(&sin->sin6_addr, &ipv6_hdr(skb)->saddr);
                        if (np->rxopt.all)
                                datagram_recv_ctl(sk, msg, skb);
index 074f2c084f9fdf536212298e3864d20b8f3ca1a2..8a659f92d17af2a271f1c4a0ba6e72af6f6bbea1 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/netdevice.h>
 #include <linux/in6.h>
 #include <linux/icmpv6.h>
+#include <linux/slab.h>
 
 #include <net/dst.h>
 #include <net/sock.h>
index eb9abe24bdf0b1e277724958cfd113280936048e..3330a4bd6157e86d9e951f0d7833531fd10b0872 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/netfilter.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_SYSCTL
 #include <linux/sysctl.h>
index 3516e6fe2e560894ae87ee06f4040f52e18069d6..628db24bcf22bceff783384ea7779a87c4cb0ab7 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/in6.h>
 #include <linux/ipv6.h>
 #include <linux/jhash.h>
+#include <linux/slab.h>
 
 #include <net/addrconf.h>
 #include <net/inet_connection_sock.h>
index 2f9847924fa51c95a342ab7bff4c54ea60552342..6b82e02158c6d9c80b2e26dce09497441eed92f3 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/in6.h>
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 
 #ifdef         CONFIG_PROC_FS
 #include <linux/proc_fs.h>
index e41eba8aacf15ce25eb3c7cca1d3baac1f1c884d..14e23216eb28c7332fc67afe6a855ee9a98936a4 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/route.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <net/net_namespace.h>
 #include <net/sock.h>
index e28f9203deca46ecaf03958ea3c0483c79f54849..6aa7ee1295c2f5d7f467a71dcb74a0a8e029cef2 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/in6.h>
 #include <linux/icmpv6.h>
 #include <linux/mroute6.h>
+#include <linux/slab.h>
 
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv6.h>
index dabf108ad81131138a5923268231809ebdb51494..75d5ef830097fc99cbd7e0ccd36452ff45a6f806 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/tcp.h>
 #include <linux/route.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv6.h>
@@ -107,7 +108,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
        newskb->ip_summed = CHECKSUM_UNNECESSARY;
        WARN_ON(!skb_dst(newskb));
 
-       netif_rx(newskb);
+       netif_rx_ni(newskb);
        return 0;
 }
 
@@ -628,7 +629,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
        /* We must not fragment if the socket is set to force MTU discovery
         * or if the skb it not generated by a local socket.
         */
-       if (!skb->local_df) {
+       if (!skb->local_df && skb->len > mtu) {
                skb->dev = skb_dst(skb)->dev;
                icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
                IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
index 138980eec214df5aca51a2933a9b901f6606e231..2599870747ec88e82101fde1c1d42eb393c01898 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/route.h>
 #include <linux/rtnetlink.h>
 #include <linux/netfilter_ipv6.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
index 52e0f74fdfe0cdfa2c8b8dc515244a64f0dc1010..3e333268db897eeeee23895e3dc764f82f401391 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <net/protocol.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
@@ -1113,6 +1114,9 @@ static int ip6mr_mfc_add(struct net *net, struct mf6cctl *mfc, int mrtsock)
        unsigned char ttls[MAXMIFS];
        int i;
 
+       if (mfc->mf6cc_parent >= MAXMIFS)
+               return -ENFILE;
+
        memset(ttls, 255, MAXMIFS);
        for (i = 0; i < MAXMIFS; i++) {
                if (IF_ISSET(i, &mfc->mf6cc_ifset))
@@ -1692,17 +1696,20 @@ ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm)
        int ct;
        struct rtnexthop *nhp;
        struct net *net = mfc6_net(c);
-       struct net_device *dev = net->ipv6.vif6_table[c->mf6c_parent].dev;
        u8 *b = skb_tail_pointer(skb);
        struct rtattr *mp_head;
 
-       if (dev)
-               RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex);
+       /* If cache is unresolved, don't try to parse IIF and OIF */
+       if (c->mf6c_parent > MAXMIFS)
+               return -ENOENT;
+
+       if (MIF_EXISTS(net, c->mf6c_parent))
+               RTA_PUT(skb, RTA_IIF, 4, &net->ipv6.vif6_table[c->mf6c_parent].dev->ifindex);
 
        mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0));
 
        for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) {
-               if (c->mfc_un.res.ttls[ct] < 255) {
+               if (MIF_EXISTS(net, ct) && c->mfc_un.res.ttls[ct] < 255) {
                        if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4))
                                goto rtattr_failure;
                        nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp)));
index 430454ee5ead4413de26d5607606d86ad11ecd94..33f60fca7aa775e36082c65171a10e10a4ec49bb 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/init.h>
 #include <linux/sysctl.h>
 #include <linux/netfilter.h>
+#include <linux/slab.h>
 
 #include <net/sock.h>
 #include <net/snmp.h>
index bcd971915969f1eea6672925dbba349da01bc7e8..c483ab9fd67b494286f2dfd7574fed4fa91792a3 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv6.h>
index 8bcc4b7db3bf8593d74b491d869a48f4d9fcc9a0..da0a4d2adc69ac531eba98783de78f8b570d4717 100644 (file)
@@ -59,6 +59,7 @@
 #include <linux/route.h>
 #include <linux/init.h>
 #include <linux/rcupdate.h>
+#include <linux/slab.h>
 #ifdef CONFIG_SYSCTL
 #include <linux/sysctl.h>
 #endif
index 7854052be60be862833541c8cfd624ac2b4f53ba..6a68a74d14a3a451775ae2f046518b5d119d8f3e 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
 #include <net/ipv6.h>
index dd8afbaf00a8fe84ee317087e1c4e7dc3703ee34..39b50c3768e8b5c22f293e72c465d4b2aeea2bf2 100644 (file)
@@ -15,6 +15,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/gfp.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/icmpv6.h>
index 36b72cafc2276899d5a296236a9c9dba34f9fc08..d6fc9aff3163eb417c6aeadffe481e643d55566d 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/slab.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
index 7844e557c0ec717731f2fcfa4b932ae7ae6349b2..6a102b57f35623c055c1eca22fd80995427ff428 100644 (file)
@@ -10,6 +10,7 @@
  */
 #include <linux/module.h>
 #include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/slab.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
index aef31a29de9ed37f3cf48ab12b738ddf9856882b..5b9926a011bd99faff714042746f161ee58a152a 100644 (file)
@@ -5,6 +5,7 @@
  */
 #include <linux/module.h>
 #include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/slab.h>
 
 #define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
 
@@ -13,7 +14,7 @@ static const struct xt_table packet_raw = {
        .valid_hooks = RAW_VALID_HOOKS,
        .me = THIS_MODULE,
        .af = NFPROTO_IPV6,
-       .priority = NF_IP6_PRI_FIRST,
+       .priority = NF_IP6_PRI_RAW,
 };
 
 /* The work comes in here from netfilter.c. */
index 0824d865aa9bb76314ea61a66a340b7d66cbb271..91aa2b4d83c9c1571d4538ad380dfae5296a180b 100644 (file)
@@ -17,6 +17,7 @@
  */
 #include <linux/module.h>
 #include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/slab.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("James Morris <jmorris <at> redhat.com>");
index f1171b744650e07f1e979a9575e5792ebaa10a9b..dd5b9bd61c6298474af25539617809428ed45418 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 
 #include <net/sock.h>
 #include <net/snmp.h>
index ed31c37c6e3906a817e751bfd86115f2246c7ca3..8763b1a0814a44b150e4c7f9e075f6e684f09243 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/socket.h>
+#include <linux/slab.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
 #include <linux/in6.h>
index a555156e9779edd2b3ea89314689d5c2e54de1af..6d4292ff585463178885153cdd2fe6e044b962a9 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/random.h>
 #include <linux/jhash.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 
 #include <net/sock.h>
 #include <net/snmp.h>
index 52cd3eff31dcccf7f79abed6d2860ceb73b09780..05ebd7833043c687010382fb2d1534ef1bd45b8a 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/nsproxy.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/snmp.h>
 #include <net/ipv6.h>
@@ -814,7 +815,7 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk,
 {
        int flags = 0;
 
-       if (rt6_need_strict(&fl->fl6_dst))
+       if (fl->oif || rt6_need_strict(&fl->fl6_dst))
                flags |= RT6_LOOKUP_F_IFACE;
 
        if (!ipv6_addr_any(&fl->fl6_src))
@@ -879,7 +880,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
 
        rt = (struct rt6_info *) dst;
 
-       if (rt && rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie))
+       if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie))
                return dst;
 
        return NULL;
@@ -890,12 +891,17 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst)
        struct rt6_info *rt = (struct rt6_info *) dst;
 
        if (rt) {
-               if (rt->rt6i_flags & RTF_CACHE)
-                       ip6_del_rt(rt);
-               else
+               if (rt->rt6i_flags & RTF_CACHE) {
+                       if (rt6_check_expired(rt)) {
+                               ip6_del_rt(rt);
+                               dst = NULL;
+                       }
+               } else {
                        dst_release(dst);
+                       dst = NULL;
+               }
        }
-       return NULL;
+       return dst;
 }
 
 static void ip6_link_failure(struct sk_buff *skb)
index b1eea811be48c1f73b3a6e727193a3a04435245e..5abae10cd8844c8d2acb30ceced10055dbdf3856 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/icmp.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <linux/init.h>
 #include <linux/netfilter_ipv4.h>
index f841d93bf987eb07ce03864be359be91b656583a..fa1d8f4e0051a3210b8bfb760ca1a99d0ac1ead5 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/sysctl.h>
 #include <linux/in6.h>
 #include <linux/ipv6.h>
+#include <linux/slab.h>
 #include <net/ndisc.h>
 #include <net/ipv6.h>
 #include <net/addrconf.h>
index 9b6dbba80d312913278f50e059b1d19b4a554cfe..075f540ec1975cdce6148e75661219cfe5decb6e 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/jhash.h>
 #include <linux/ipsec.h>
 #include <linux/times.h>
+#include <linux/slab.h>
 
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
@@ -1014,7 +1015,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
        skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
 
        t1 = (struct tcphdr *) skb_push(buff, tot_len);
-       skb_reset_transport_header(skb);
+       skb_reset_transport_header(buff);
 
        /* Swap the send and the receive. */
        memset(t1, 0, sizeof(*t1));
index e17bc1dfc1a4c7597dc15886a8d285f362066e22..fc3c86a474526ee1c3b9c3f644fbe1d14c458f0e 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/mutex.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/ipv6.h>
 #include <net/protocol.h>
 #include <net/xfrm.h>
index 3c0c9c755c928f74b84b6cfb72332c96c8fbf53d..90824852f598d34f4c544392e247a6f93a7bd0b0 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 #include <net/ndisc.h>
@@ -258,8 +259,8 @@ static struct sock *__udp6_lib_lookup(struct net *net,
                        if (hslot->count < hslot2->count)
                                goto begin;
 
-                       result = udp6_lib_lookup2(net, &in6addr_any, sport,
-                                                 daddr, hnum, dif,
+                       result = udp6_lib_lookup2(net, saddr, sport,
+                                                 &in6addr_any, hnum, dif,
                                                  hslot2, slot2);
                }
                rcu_read_unlock();
index 3927832227b933d3fd55218e0bdb15c6369a7e0f..b809812c8d30a85b13732fd2071d524da6a81807 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au>
  */
 
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index ae181651c75a82d32fdb6596068e3bb5c7839740..00bf7c962b7e84134734d74bac80482da87bdcd6 100644 (file)
@@ -124,7 +124,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
        xdst->u.dst.dev = dev;
        dev_hold(dev);
 
-       xdst->u.rt6.rt6i_idev = in6_dev_get(rt->u.dst.dev);
+       xdst->u.rt6.rt6i_idev = in6_dev_get(dev);
        if (!xdst->u.rt6.rt6i_idev)
                return -ENODEV;
 
index fa85a7d22dc495d005047a0c7a78bd7f96a25f97..2ce3a8278f26576668ffafd178891451e2b5fc87 100644 (file)
@@ -23,6 +23,7 @@
  */
 #include <linux/module.h>
 #include <linux/xfrm.h>
+#include <linux/slab.h>
 #include <linux/rculist.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
index f9759b54a6debfca3d86830bb223fd250f7426ba..da3d21c41d9064cb691342dfe23df37460766b84 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/net.h>
 #include <linux/netdevice.h>
 #include <linux/uio.h>
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/smp_lock.h>
 #include <linux/socket.h>
index e16c11423527df9832485de4479eb019d51d9c1b..30f4519b092f546aad806520280bec883165a9c2 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/list.h>
 #include <linux/route.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 
 #include <net/ipx.h>
index 10093aab6173e48a0a69faf775d1fa78f3367fdc..2a4efcea342389ef054f1c3f42558448e8fa22bf 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/smp_lock.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/net.h>
 #include <linux/irda.h>
index a6f99b5a14995ff62e5620f042ca0821f3552cc3..c1c8ae939126027c5d3ddb6192d2da88677da419 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/socket.h>
 #include <linux/fs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irlmp.h>
index 018c92941aba4ef3f8a1fd31866f32f499e03504..e97082017f4fabfd05ed2c3823f31c5e9fa1ee7e 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irmod.h>
index 7ba96618660e349de2253473d6701ab8bbad9613..08fb54dc8c412cbcb04721ca7df9f034ff06dcbf 100644 (file)
@@ -31,6 +31,7 @@
  ********************************************************************/
 
 #include <linux/init.h>
+#include <linux/gfp.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irlmp.h>
index d57aefd9fe7780c53a2ae4e0698d135e963e6261..e2e893b474e92b356454e8b7c674196ac465e7ee 100644 (file)
@@ -28,6 +28,7 @@
  *
  ********************************************************************/
 
+#include <linux/gfp.h>
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 
index 8b85d774e47fe5dbe2d526eaff6bdf7215a2057b..faa82ca2dfdcf9c8cff71b486434997d832c87cf 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/termios.h>
index bf92e147344736bd39a4fce6b3977bc5c8ee1739..25cc2e6951589b3bced6d14118ec6414d27eb947 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/tty.h>
 #include <linux/kmod.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 
 #include <asm/ioctls.h>
 #include <asm/uaccess.h>
index 294e34d3517cb87cc191c1cfec9d7b39de30245d..79a1e5a23e10e6e0aa1b14837bdfbe29cf7d7000 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
index a301cbd9378511a9b947d3c38b4f40b100c7dd83..703774e29e322966ec4de6cf990bbc427c3ff221 100644 (file)
@@ -24,6 +24,8 @@
  *
  ********************************************************************/
 
+#include <linux/slab.h>
+
 #include <net/irda/irda.h>
 #include <net/irda/irlmp.h>
 #include <net/irda/iriap.h>
index 99ebb96f13869868bba080779354390c3284f5a9..f07ed9fd5792fabe7e1cffc1016330ee01a0fab8 100644 (file)
@@ -22,6 +22,7 @@
  *
  ********************************************************************/
 
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/socket.h>
 #include <linux/module.h>
index 42f7d960d055ca7d8ab0784ddde43ad183943dd2..7ed3af95793548c4941313f7ce195d286252f601 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
index e486dc89ea595e94d9973e5a0ef18c6f1b410099..a788f9e9427d2c1c127d411adc8b06eb9d19ba87 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/proc_fs.h>
index 3f81f81b2dfaba760a93f70bd6492f3ab32d4c27..5cf5e6c872bb361a1be8a919e5092c68135fa009 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/init.h>
 #include <linux/random.h>
 #include <linux/bitops.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/byteorder.h>
index 94a9884d7146137b56665f20cc8ea078a86596b7..d434c888074509f37d414bb93c30664f1d678cc3 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irlap_event.h>
index 7af2e74deda823bf587d298d1f7bab58d8484dd3..688222cbf55be317ecf187cc15d6a4144bded236 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/if_ether.h>
 #include <linux/netdevice.h>
 #include <linux/irda.h>
+#include <linux/slab.h>
 
 #include <net/pkt_sched.h>
 #include <net/sock.h>
index b26dee784aba87be8eb2688567dfc31652173055..df18ab4b6c5e8dffd4ec2532851a88cd3d6eb9f2 100644 (file)
@@ -11,6 +11,7 @@
 #include "irnet_irda.h"                /* Private header */
 #include <linux/sched.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 /*
index 6b3602de359ae556761ec10effa42151c0a92817..6a1a202710c51203597fc291244d1a5d9b5df1d6 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include "irnet_ppp.h"         /* Private header */
 /* Please put other headers in irnet.h - Thanks */
index 69b5b75f5431c85f81312edf9b66fde090085231..6c7c4b92e4f8ec0e5a2aad62b33a6ada0d813c0e 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/socket.h>
 #include <linux/irda.h>
+#include <linux/gfp.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
 #include <net/irda/irda.h>
index ba01938becb5b08bf5c258df54f513392e8cd2ce..849aaf0dabb5ec8a1be02ab471a84d6d736b5f06 100644 (file)
  * Jean II
  */
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irqueue.h>
index 9cb79f95bf63953c9bcdf2b379b4ccbb37089ff5..47db1d8a0d92088a5982b2db471c9fce05001de2 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
index 368707882647bb83293a5be6536b00d6ccca2982..ba9a3fcc2fedff60c23b3cae9e394dca5890bdf0 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/in6.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 #include <net/xfrm.h>
@@ -2129,10 +2130,9 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c
        int err;
 
        out_skb = pfkey_xfrm_policy2msg_prep(xp);
-       if (IS_ERR(out_skb)) {
-               err = PTR_ERR(out_skb);
-               goto out;
-       }
+       if (IS_ERR(out_skb))
+               return PTR_ERR(out_skb);
+
        err = pfkey_xfrm_policy2msg(out_skb, xp, dir);
        if (err < 0)
                return err;
@@ -2148,7 +2148,6 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c
        out_hdr->sadb_msg_seq = c->seq;
        out_hdr->sadb_msg_pid = c->pid;
        pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xp_net(xp));
-out:
        return 0;
 
 }
index bda96d18fd98388e87e8aef8a61bbcbeb7ff9798..d5d8d555c410dbe68b2b05a6a21284e1c2a44b1a 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/inet.h>
 #include <linux/if_arp.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
index 6762e7c751ebe7342fb96cdaca6ee0f8f629d2e1..21904a002449ca797fb02bf9603d92a73cbfd331 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/inet.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
index 339cc5f2684f1008d930c0c2ecf943d537d9294f..c75a79540f9f476b2247a4c96d6004625f528201 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/net.h>
 #include <linux/inet.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
index b827f47ac133c64f71e9934b5acc086505a88a79..43a2a7fb327b3888dd726dc3325408c24255a16a 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/net.h>
 #include <linux/inet.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
index e35d907fba2c20e5b931751584ecacd68f0c4c9e..2db6a9f759130f4277739619018713c521b4522f 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/rtnetlink.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <net/llc.h>
 #include <net/llc_sap.h>
 #include <net/llc_pdu.h>
index 86d6985b9d49790e9e4ec5302602b0ef8c025130..ea225bd2672c03947dcc01b581a14e1a2b792e68 100644 (file)
@@ -18,6 +18,7 @@
  * See the GNU General Public License for more details.
  */
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <net/llc_conn.h>
 #include <net/llc_sap.h>
 #include <net/sock.h>
index a12144da7974df50ae457dcda84d028f26965f85..ba137a6a224de73f2dc671ff93de11ab291520ee 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <net/llc_sap.h>
 #include <net/llc_conn.h>
 #include <net/sock.h>
index a89917130a7bd76e4aa9e64c4b2c8a1b78b6723a..25c31c0a3fdbeab3bbf2e2cb6604594bfa758298 100644 (file)
@@ -11,6 +11,7 @@
  *
  * See the GNU General Public License for more details.
  */
+#include <linux/gfp.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
index 57ad974e4d9490b84cca490e2a42d4150f30c81d..f99687439139faf68f2464a39bd48d6100481dca 100644 (file)
@@ -12,6 +12,7 @@
  * See the GNU General Public License for more details.
  */
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/llc.h>
 #include <net/llc_pdu.h>
index ad6e6e1cf22fce1eefa43d1726537d3b5bf644dc..94e7fca75b851762623a5e536abfc233810f8920 100644 (file)
@@ -23,6 +23,7 @@
 #include <net/sock.h>
 #include <net/tcp_states.h>
 #include <linux/llc.h>
+#include <linux/slab.h>
 
 static int llc_mac_header_len(unsigned short devtype)
 {
@@ -30,7 +31,7 @@ static int llc_mac_header_len(unsigned short devtype)
        case ARPHRD_ETHER:
        case ARPHRD_LOOPBACK:
                return sizeof(struct ethhdr);
-#ifdef CONFIG_TR
+#if defined(CONFIG_TR) || defined(CONFIG_TR_MODULE)
        case ARPHRD_IEEE802_TR:
                return sizeof(struct trh_hdr);
 #endif
index 83da1333949011d8ae4ac877181365795e6d67fa..e4dae0244d76b677ee89ef0b35dd51ccf7807e06 100644 (file)
@@ -13,6 +13,7 @@
  */
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <net/llc.h>
 #include <net/llc_sap.h>
 #include <net/llc_conn.h>
index a978e666ed6f06a79fa4b7529feec540a7ab2908..f9516a27e233ba09ebf1d69a81968552d47902ee 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/ieee80211.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
 #include "driver-ops.h"
index 5538e1b4a697740535b0be966a90719cec3dafc5..87782a4bb541251714236dc1218104e71cd3c315 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/ieee80211.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
 #include "driver-ops.h"
@@ -183,7 +184,6 @@ static void sta_addba_resp_timer_expired(unsigned long data)
                       HT_AGG_STATE_REQ_STOP_BA_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 "
                                "(or no longer) expecting addBA response there",
index b7116ef84a3b019898ddbe6bc5a64cac3e34bcae..edc872e22c9b6211fcd32342296462d871e64f88 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/ieee80211.h>
 #include <linux/nl80211.h>
 #include <linux/rtnetlink.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <linux/rcupdate.h>
 #include <net/cfg80211.h>
index d12e743cb4e1b7716ddd5beeed9954d43e75c9cb..97c9e46e859e9dbd081d5964437c9db73440441a 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/kobject.h>
+#include <linux/slab.h>
 #include "ieee80211_i.h"
 #include "key.h"
 #include "debugfs.h"
index b4ddb2f839146a2b48a62a5e3df2b9f6c44dc1df..83d4289d954bfacd1db317ec71b709623b44fa82 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
+#include <linux/slab.h>
 #include <linux/notifier.h>
 #include <net/mac80211.h>
 #include <net/cfg80211.h>
index f3e94248674948afc3c1b29be81c9b1ce1f234f3..e2976da4e0d9c7e86b21557c1571e2dd7e449db6 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/if_ether.h>
 #include <linux/skbuff.h>
 #include <linux/if_arp.h>
index 0793d7a8d74323f348abce62003471cdb8ac6e59..e08fa8eda1b36aabfda2b591b31ac4f2fe641817 100644 (file)
@@ -10,6 +10,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
index 8160d9c5372ea09e8fbc6c01b54c3e00703d3188..e8f6e3b252d8b8ee3ef4210695dfc44283534bc4 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/list.h>
 #include <linux/rcupdate.h>
 #include <linux/rtnetlink.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
 #include "driver-ops.h"
index 162a643f16b69b92d039c9216d9147c0194ca735..063aad944246678d7ebaa4392b42abbb07a4a055 100644 (file)
@@ -8,6 +8,7 @@
 
 /* just for IFNAMSIZ */
 #include <linux/if.h>
+#include <linux/slab.h>
 #include "led.h"
 
 void ieee80211_led_rx(struct ieee80211_local *local)
index 06c33b68d8e545fdc78625b121594dbcfaf10a03..b887e484ae04427d3ec2118c13e9238c5fc650e9 100644 (file)
@@ -225,11 +225,11 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
                        switch (sdata->vif.type) {
                        case NL80211_IFTYPE_AP:
                                sdata->vif.bss_conf.enable_beacon =
-                                       !!rcu_dereference(sdata->u.ap.beacon);
+                                       !!sdata->u.ap.beacon;
                                break;
                        case NL80211_IFTYPE_ADHOC:
                                sdata->vif.bss_conf.enable_beacon =
-                                       !!rcu_dereference(sdata->u.ibss.presp);
+                                       !!sdata->u.ibss.presp;
                                break;
                        case NL80211_IFTYPE_MESH_POINT:
                                sdata->vif.bss_conf.enable_beacon = true;
index 61080c5fad50f2ef859ac6461d6168d69cddaaa6..859ee5f3d94146a5103b5c2188847da3a302d12d 100644 (file)
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include "ieee80211_i.h"
 #include "mesh.h"
@@ -749,9 +750,6 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
 
        switch (fc & IEEE80211_FCTL_STYPE) {
        case IEEE80211_STYPE_ACTION:
-               if (skb->len < IEEE80211_MIN_ACTION_SIZE)
-                       return RX_DROP_MONITOR;
-               /* fall through */
        case IEEE80211_STYPE_PROBE_RESP:
        case IEEE80211_STYPE_BEACON:
                skb_queue_tail(&ifmsh->skb_queue, skb);
index ce84237ebad3b493d5c5d8dc3ea18662395dbfb7..fefc45c4b4e8cad4a792d9f6787284270f3510bd 100644 (file)
@@ -7,6 +7,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/slab.h>
 #include "mesh.h"
 
 #ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG
@@ -391,7 +392,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
                                if (SN_GT(mpath->sn, orig_sn) ||
                                    (mpath->sn == orig_sn &&
                                     action == MPATH_PREQ &&
-                                    new_metric > mpath->metric)) {
+                                    new_metric >= mpath->metric)) {
                                        process = false;
                                        fresh_info = false;
                                }
@@ -611,7 +612,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
 
        mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr,
                cpu_to_le32(orig_sn), 0, target_addr,
-               cpu_to_le32(target_sn), mpath->next_hop->sta.addr, hopcount,
+               cpu_to_le32(target_sn), next_hop, hopcount,
                ttl, cpu_to_le32(lifetime), cpu_to_le32(metric),
                0, sdata);
        rcu_read_unlock();
index 2312efe04c62ea7116ca6de8302fa76f47b3e56a..181ffd6efd816e859d92274d459da41ab749c1b3 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/etherdevice.h>
 #include <linux/list.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <net/mac80211.h>
index 1a29c4a8139e0ce7d3338a887e5d50836004ae1d..7b7080e2b49f47a1dcac316432341b89b3a9a5cb 100644 (file)
@@ -6,6 +6,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/random.h>
 #include "ieee80211_i.h"
index be5f723d643acbb4146edd3bc7fbbcdd7f943b6d..875c8dec940aad157ee545964dd57e5a6531689f 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/pm_qos_params.h>
 #include <linux/crc32.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 #include <asm/unaligned.h>
 
@@ -167,6 +168,8 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
        ht_changed = conf_is_ht(&local->hw.conf) != enable_ht ||
                     channel_type != local->hw.conf.channel_type;
 
+       if (local->tmp_channel)
+               local->tmp_channel_type = channel_type;
        local->oper_channel_type = channel_type;
 
        if (ht_changed) {
@@ -2027,7 +2030,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
                                continue;
 
                        if (wk->type != IEEE80211_WORK_DIRECT_PROBE &&
-                           wk->type != IEEE80211_WORK_AUTH)
+                           wk->type != IEEE80211_WORK_AUTH &&
+                           wk->type != IEEE80211_WORK_ASSOC)
                                continue;
 
                        if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
index 0b299d236fa1a3bbd74256e7386ecc2d92e7e940..6d0bd198af19d949841eaa94489c301e75f4cfa8 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/kernel.h>
 #include <linux/rtnetlink.h>
+#include <linux/slab.h>
 #include "rate.h"
 #include "ieee80211_i.h"
 #include "debugfs.h"
index 6e5d68b4e427a232dfeebcfe98f666bb2618bb1c..818abfae900773f27f39045a8163469bc8fed82f 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/debugfs.h>
 #include <linux/random.h>
 #include <linux/ieee80211.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 #include "rate.h"
 #include "rc80211_minstrel.h"
index a715d9454f640846ccb24cc055d89eb448267840..0e1f12b1b6dd1ee9971df741cbc8855e6bf05e16 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/skbuff.h>
 #include <linux/debugfs.h>
 #include <linux/ieee80211.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 #include "rc80211_minstrel.h"
 
index 2652a374974eb786cb80cd90ae42e5293840e054..aeda65466f3eb60a4dcb37cd8a2cae152ffe794c 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/types.h>
 #include <linux/skbuff.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 #include "rate.h"
 #include "mesh.h"
index 45667054a5f305308a8bf1faff8b9def3b8b0749..47438b4a9af52d33589e9cc1a695f77a8461d987 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/netdevice.h>
 #include <linux/types.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 
 #include <net/mac80211.h>
 #include "rate.h"
index b5c48de81d8b89009b4cb0fa427e165431221958..04ea07f0e78acd0fd30ee92a525897e64c49f5bc 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/jiffies.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
@@ -1973,6 +1974,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
                        goto handled;
                }
                break;
+       case MESH_PLINK_CATEGORY:
+       case MESH_PATH_SEL_CATEGORY:
+               if (ieee80211_vif_is_mesh(&sdata->vif))
+                       return ieee80211_mesh_rx_mgmt(sdata, rx->skb);
+               break;
        }
 
        /*
index b822dce9786706e65a30480aa97b1cfd031211e6..85507bd9e34109d3f06bb9248322b3b1ad7f615a 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/if_arp.h>
 #include <linux/rtnetlink.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 
 #include "ieee80211_i.h"
index 56422d8943511d7d2744f349342a21bcb75067c5..fb12cec4d333a25d98c13dba1994d6bcbeb001ee 100644 (file)
@@ -93,12 +93,18 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
 
-       sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
+       sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
+                                   rcu_read_lock_held() ||
+                                   lockdep_is_held(&local->sta_lock) ||
+                                   lockdep_is_held(&local->sta_mtx));
        while (sta) {
                if (sta->sdata == sdata &&
                    memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
                        break;
-               sta = rcu_dereference(sta->hnext);
+               sta = rcu_dereference_check(sta->hnext,
+                                           rcu_read_lock_held() ||
+                                           lockdep_is_held(&local->sta_lock) ||
+                                           lockdep_is_held(&local->sta_mtx));
        }
        return sta;
 }
@@ -113,13 +119,19 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
 
-       sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
+       sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
+                                   rcu_read_lock_held() ||
+                                   lockdep_is_held(&local->sta_lock) ||
+                                   lockdep_is_held(&local->sta_mtx));
        while (sta) {
                if ((sta->sdata == sdata ||
                     sta->sdata->bss == sdata->bss) &&
                    memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
                        break;
-               sta = rcu_dereference(sta->hnext);
+               sta = rcu_dereference_check(sta->hnext,
+                                           rcu_read_lock_held() ||
+                                           lockdep_is_held(&local->sta_lock) ||
+                                           lockdep_is_held(&local->sta_mtx));
        }
        return sta;
 }
index cbe53ed4fb0b14b9f95a8db5b21e73d673d9b09a..cfc473e1b0509ca1850d61a49b5dd59b23ecee55 100644 (file)
@@ -1991,6 +1991,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
 void ieee80211_tx_pending(unsigned long data)
 {
        struct ieee80211_local *local = (struct ieee80211_local *)data;
+       struct ieee80211_sub_if_data *sdata;
        unsigned long flags;
        int i;
        bool txok;
@@ -2029,6 +2030,11 @@ void ieee80211_tx_pending(unsigned long data)
                        if (!txok)
                                break;
                }
+
+               if (skb_queue_empty(&local->pending[i]))
+                       list_for_each_entry_rcu(sdata, &local->interfaces, list)
+                               netif_tx_wake_queue(
+                                       netdev_get_tx_queue(sdata->dev, i));
        }
        spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 
index c453226f06b2758377132ddb83e179c4c61ff921..53af570474351d69bbe7e18f15d60be377f4b159 100644 (file)
@@ -279,13 +279,13 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
                /* someone still has this queue stopped */
                return;
 
-       if (!skb_queue_empty(&local->pending[queue]))
+       if (skb_queue_empty(&local->pending[queue])) {
+               rcu_read_lock();
+               list_for_each_entry_rcu(sdata, &local->interfaces, list)
+                       netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue));
+               rcu_read_unlock();
+       } else
                tasklet_schedule(&local->tx_pending_tasklet);
-
-       rcu_read_lock();
-       list_for_each_entry_rcu(sdata, &local->interfaces, list)
-               netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue));
-       rcu_read_unlock();
 }
 
 void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
@@ -1097,9 +1097,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                 */
                res = drv_start(local);
                if (res) {
-                       WARN(local->suspended, "Harware became unavailable "
-                            "upon resume. This is could be a software issue"
-                            "prior to suspend or a hardware issue\n");
+                       WARN(local->suspended, "Hardware became unavailable "
+                            "upon resume. This could be a software issue "
+                            "prior to suspend or a hardware issue.\n");
                        return res;
                }
 
index 5d745f2d72364fcc8289cd104856c2150d7ec61d..5f3a4113bda1682bb0d30f0eaebd6f153037e3b5 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/err.h>
 #include <linux/mm.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 
 #include <net/mac80211.h>
index 1e1ea3007b06d8939cebd9992d266f463a07555b..15e1ba931b87616ab1303ff50eb13f2b3c120fc2 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/crc32.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 #include <asm/unaligned.h>
 
index f4971cd45c64f53eaa248680ca965a471abb7564..0adbcc941ac917952d9eb7ed9308e23c4644c720 100644 (file)
@@ -9,10 +9,10 @@
 
 #include <linux/netdevice.h>
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/compiler.h>
 #include <linux/ieee80211.h>
+#include <linux/gfp.h>
 #include <asm/unaligned.h>
 #include <net/mac80211.h>
 
index 60ec4e4badaa3b48bb680b215f8795925225e5f3..78b505d33bfb42cdf1033be323c2fdb1a359a833 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/inetdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
 
index 3c7e42735b60006584ab8748fc224662f954fbff..1cb0e834f8ff36c784e735eab7c3aae36ea7329f 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/in.h>
 #include <linux/ip.h>
 #include <linux/netfilter.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/protocol.h>
 #include <net/tcp.h>
index 60bb41a8d8d456829ae5b50d33c88a348aef97e5..d8f7e8ef67b41e2bedb7b47cf81070d9cd5cb390 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/proc_fs.h>             /* for proc_net_* */
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/jhash.h>
 #include <linux/random.h>
index 44590887a92cfdfb7ed662d47b532456d68ceb3d..1cd6e3fd058b71b6f49a51589a52451944e177e0 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/tcp.h>
 #include <linux/sctp.h>
 #include <linux/icmp.h>
+#include <linux/slab.h>
 
 #include <net/ip.h>
 #include <net/tcp.h>
index 7ee9c3426f44a24b141492b266223b319e8a3f95..36dc1d88c2fa56cff3f29566965de8c80e9e9d99 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/workqueue.h>
 #include <linux/swap.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv4.h>
index fe3e18834b911c1b388d253d76eeaa68dfa464d7..95fd0d14200b338a41e0a580e890e85ea5ec5e1e 100644 (file)
@@ -39,6 +39,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/ip.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
index 702b53ca937ccc4277c8dfee736616bb018772f3..ff28801962e05883d1a469ac3b2848b51e4429fd 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <linux/kernel.h>
 #include <linux/jiffies.h>
-#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/sysctl.h>
index 73f38ea98f254734aa9da2931d4d93713f45fd38..2c7f185dfae464c09bf4c2146dda87063ad00314 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/in.h>
 #include <linux/ip.h>
 #include <linux/netfilter.h>
+#include <linux/gfp.h>
 #include <net/protocol.h>
 #include <net/tcp.h>
 #include <asm/unaligned.h>
index 1b9370db23054b963d5c97555005a818efb6812f..94a45213faa6853a87b75d6143bdb99a3c5521f4 100644 (file)
@@ -43,6 +43,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/ip.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
index caa58fa1438a4d081257367782c9860f7b3514f3..535dc2b419d81f33f18fd7eea98d80bae07ba9cb 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/skbuff.h>
 #include <linux/jiffies.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 
 /* for sysctl */
 #include <linux/fs.h>
index 0e584553819da8ce77e888369b0912a6b1ba0780..7fc49f4cf5ad63905f4cb0a175b3e5124765002e 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
+#include <linux/gfp.h>
 #include <linux/in.h>
 #include <linux/ip.h>
 #include <net/protocol.h>
index 8e6cfd36e6f0d7370ef817b7da8ffae070bc201e..e6cc174fbc06d4410a54c1e09021811e5773e81c 100644 (file)
@@ -36,6 +36,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/ip.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
index 3c115fc197843287d9bf0dff379e6fbdc4f37c02..30db633f88f10c948e3e15c01ffb2b37bd0c4d13 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/net.h>
 #include <linux/gcd.h>
 
index 223b5018c7dc658d876f4b3c749d1377b57931b4..e450cd6f4eb5794c385bc0f63fbe76cf61393fa3 100644 (file)
@@ -17,6 +17,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/tcp.h>                  /* for tcphdr */
 #include <net/ip.h>
 #include <net/tcp.h>                    /* for csum_tcpudp_magic */
index 018f90db511c673fa633eff0023e888be049d2f3..ab81b380eae6814934de4318c67e6cd4d886ca1f 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/netfilter.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/moduleparam.h>
 
index 07d9d8857e5db50b2d80bca709e137c4472b8724..372e80f07a8160636a9f8530bbd6e05a0ec5664f 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/in.h>
 #include <linux/udp.h>
 #include <linux/netfilter.h>
+#include <linux/gfp.h>
 
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_expect.h>
index d5a9bcd7d61b9695569bddd5a62b1874978da493..f516961a83b44f9a2795dae259be5af3cf399abf 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/percpu.h>
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_core.h>
index f0732aa18e4fdd7e68fe7f791e12f9790a8fc7bd..2ae3169e76330d6565d9f21e8a99f452e07ea8e8 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/moduleparam.h>
 #include <linux/netfilter.h>
 #include <linux/ip.h>
+#include <linux/slab.h>
 #include <linux/ipv6.h>
 #include <linux/ctype.h>
 #include <linux/inet.h>
index a1c8dd917e1202b375f1a6d4f788880035b78a41..a487c80380445a1c718c0f89cb984d62f987abaa 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/inet.h>
 #include <linux/in.h>
 #include <linux/ip.h>
+#include <linux/slab.h>
 #include <linux/udp.h>
 #include <linux/tcp.h>
 #include <linux/skbuff.h>
index 4509fa6726f8739f642f6127c2fd8ba59c6e896e..59e1a4cd4e8b8b115c77e788fe2b821d50f32f65 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/skbuff.h>
 #include <linux/vmalloc.h>
 #include <linux/stddef.h>
-#include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
index 8bd98c84f77e7962c55dee04084c8ee05128f1bd..7673930ca3423fadd838d4f17d26aceda27061e7 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/netfilter.h>
+#include <linux/slab.h>
 
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_expect.h>
index 2b2af631d2b870d3c9f4f81146833fd4a93f2cf9..afc52f2ee4ac1f906b1daf2166faf9cff9256399 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/netlink.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #include <linux/netfilter.h>
 #include <net/netlink.h>
@@ -582,7 +583,9 @@ nla_put_failure:
 nlmsg_failure:
        kfree_skb(skb);
 errout:
-       nfnetlink_set_err(net, 0, group, -ENOBUFS);
+       if (nfnetlink_set_err(net, 0, group, -ENOBUFS) > 0)
+               return -ENOBUFS;
+
        return 0;
 }
 #endif /* CONFIG_NF_CONNTRACK_EVENTS */
index 1a4568bf7ea515ee790b700dfe85a31c38b8bdc6..a44fa75b51783beefa9c44c93b70fba619df5d78 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/types.h>
 #include <linux/netfilter.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/skbuff.h>
 #include <linux/vmalloc.h>
index 9a281554937530d2b2b7817472c95c32586ad18f..5292560d6d4aedbfa33c1369a66fc2d72657df8f 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/spinlock.h>
 #include <linux/skbuff.h>
 #include <linux/dccp.h>
+#include <linux/slab.h>
 
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
index d899b1a699403f300ee895f359f51b901d84c7bf..cf616e55ca4193a54c6f949755428649306cfa5f 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/in.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/dst.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
index dcfecbb81c4617784178009bc02de37b9a32cb00..d9e27734b2a223adab2f73b199431df97e022b70 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/netfilter.h>
+#include <linux/slab.h>
 #include <linux/in.h>
 #include <linux/tcp.h>
 #include <net/netfilter/nf_conntrack.h>
index 24a42efe62ef630ba48496b20a3a2bdfdb482d9e..faa8eb3722b96572edfd82298e275f10053e697d 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 #include <linux/netfilter.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/proc_fs.h>
index ba095fd014e571f554567766a034df237a1bdbe1..c49ef219899edd130cad88524bf7efdf73efe916 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/proc_fs.h>
index 8eb0cc23ada3760a79a0eaefa76ada8745acd4f2..6afa3d52ea5f1d7af8d2be47db8ece008429eeb6 100644 (file)
@@ -113,9 +113,9 @@ int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 pid,
 }
 EXPORT_SYMBOL_GPL(nfnetlink_send);
 
-void nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error)
+int nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error)
 {
-       netlink_set_err(net->nfnl, pid, group, error);
+       return netlink_set_err(net->nfnl, pid, group, error);
 }
 EXPORT_SYMBOL_GPL(nfnetlink_set_err);
 
index d9b8fb8ab340b5a97e57073abdfe611f7b0c1c74..203643fb2c524ade67aedd22bc5f3ee8221ee884 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/list.h>
 #include <linux/jhash.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/netfilter/nf_log.h>
 #include <net/netfilter/nfnetlink_log.h>
index 7ba4abc405c9d342ce7cd4bd76bd294e554ae6dc..e70a6ef1f4f2dfa81cc6e4121d429771933f4bc5 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/notifier.h>
 #include <linux/netdevice.h>
 #include <linux/netfilter.h>
index 0a12cedfe9e3da547981cb6b5251a72a663ece2a..665f5beef6ad73d2caee6cd882611b4ce5dfee61 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/vmalloc.h>
 #include <linux/mutex.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 
 #include <linux/netfilter/x_tables.h>
index 61c50fa8470374c9b76580e3dfbee045ee090837..ee18b231b9508826af1fd70e6003c4b22d695ec9 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/skbuff.h>
 #include <linux/selinux.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
index 8ff7843bb92169b9fa2f9dbb65c90074c329c2f6..3271c8e52153c929f0d1da15dcff7d6ba6f70f87 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter/x_tables.h>
+#include <linux/slab.h>
 #include <linux/leds.h>
 #include <linux/mutex.h>
 
index 87ae97e5516f91413c7ca7decdffc976263787b1..d16d55df4f616444b3fb7368cf0c91a1a2021459 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/jhash.h>
 #include <linux/rtnetlink.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 #include <net/gen_stats.h>
 #include <net/netlink.h>
 
index 0e357ac9a2a831b85fee911847b4c2427d8255d6..c5f4b9919e9a016ef3f3428440e2446571293920 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
+#include <linux/gfp.h>
 #include <linux/ipv6.h>
 #include <linux/tcp.h>
 #include <net/dst.h>
index 26997ce90e48bf861b1cf3fcac712b6889b9f8e7..388ca459609846e9f0f92b84771331c1e58bd206 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <linux/jhash.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/random.h>
index 0989f29ade2ea0e559b53e7afac854a2bb09d54a..395af5943ffdef6c888bbe5e87fb225e60ec02cd 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <net/ip.h>
 #include <linux/dccp.h>
index 9e9c48963942ad39b722be5790c8a4b01750b1d4..215a64835de82748af7db9682ba69aa3104fde39 100644 (file)
@@ -493,6 +493,7 @@ static void hashlimit_ipv6_mask(__be32 *i, unsigned int p)
        case 64 ... 95:
                i[2] = maskl(i[2], p - 64);
                i[3] = 0;
+               break;
        case 96 ... 127:
                i[3] = maskl(i[3], p - 96);
                break;
@@ -879,7 +880,8 @@ static void dl_seq_stop(struct seq_file *s, void *v)
        struct xt_hashlimit_htable *htable = s->private;
        unsigned int *bucket = (unsigned int *)v;
 
-       kfree(bucket);
+       if (!IS_ERR(bucket))
+               kfree(bucket);
        spin_unlock_bh(&htable->lock);
 }
 
index a0ca5339af41523a174f117a7307e46833711c42..e5d7e1ffb1a46be8b7a0a21897f4da1a3e1df6cd 100644 (file)
@@ -6,6 +6,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
index 390b7d09fe512f2957769ace3b8a579b64f64086..2d5562498c435007efec01d0bc8fd82fe074d63b 100644 (file)
@@ -4,6 +4,7 @@
  * Sam Johnston <samj@samj.net>
  */
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 
 #include <linux/netfilter/x_tables.h>
index 7073dbb8100c83fb163498453d814beed8fd2dbe..834b736857cb2160b54951234b7f62609903f6fc 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/bitops.h>
 #include <linux/skbuff.h>
 #include <linux/inet.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 
@@ -267,7 +268,7 @@ recent_mt(const struct sk_buff *skb, const struct xt_match_param *par)
                for (i = 0; i < e->nstamps; i++) {
                        if (info->seconds && time_after(time, e->stamps[i]))
                                continue;
-                       if (info->hit_count && ++hits >= info->hit_count) {
+                       if (!info->hit_count || ++hits >= info->hit_count) {
                                ret = !ret;
                                break;
                        }
index d8c0f8f1a78e3a2c5c6ae96edb94f76258a410cf..937ce0633e99c7c926144a882fea550d2b232a3a 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/spinlock.h>
 #include <linux/skbuff.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 
 #include <linux/netfilter/xt_statistic.h>
 #include <linux/netfilter/x_tables.h>
index b4d7741113115330bc4ae6d5a6df35d6ae14f4cd..96801ffd8af8d79c33e2d30fdd62c39ade795265 100644 (file)
@@ -7,6 +7,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
index e639298bc9c810a77961113b67a5078fee9bbd6f..5f14c8462e30182a8fd5ad7577d5e3e37d9b31d9 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/string.h>
 #include <linux/skbuff.h>
 #include <linux/audit.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/netlink.h>
 #include <net/genetlink.h>
index 0bfeaab88ef556852766c2c355f28233bff47bef..d37b7f80fa374a648e20a50d83b95f033dd9aebe 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/audit.h>
+#include <linux/slab.h>
 #include <net/netlabel.h>
 #include <net/cipso_ipv4.h>
 #include <asm/bug.h>
@@ -50,9 +51,12 @@ struct netlbl_domhsh_tbl {
 };
 
 /* Domain hash table */
-/* XXX - updates should be so rare that having one spinlock for the entire
- * hash table should be okay */
+/* updates should be so rare that having one spinlock for the entire hash table
+ * should be okay */
 static DEFINE_SPINLOCK(netlbl_domhsh_lock);
+#define netlbl_domhsh_rcu_deref(p) \
+       rcu_dereference_check(p, rcu_read_lock_held() || \
+                                lockdep_is_held(&netlbl_domhsh_lock))
 static struct netlbl_domhsh_tbl *netlbl_domhsh = NULL;
 static struct netlbl_dom_map *netlbl_domhsh_def = NULL;
 
@@ -106,7 +110,8 @@ static void netlbl_domhsh_free_entry(struct rcu_head *entry)
  * Description:
  * This is the hashing function for the domain hash table, it returns the
  * correct bucket number for the domain.  The caller is responsibile for
- * calling the rcu_read_[un]lock() functions.
+ * ensuring that the hash table is protected with either a RCU read lock or the
+ * hash table lock.
  *
  */
 static u32 netlbl_domhsh_hash(const char *key)
@@ -120,7 +125,7 @@ static u32 netlbl_domhsh_hash(const char *key)
 
        for (iter = 0, val = 0, len = strlen(key); iter < len; iter++)
                val = (val << 4 | (val >> (8 * sizeof(u32) - 4))) ^ key[iter];
-       return val & (rcu_dereference(netlbl_domhsh)->size - 1);
+       return val & (netlbl_domhsh_rcu_deref(netlbl_domhsh)->size - 1);
 }
 
 /**
@@ -130,7 +135,8 @@ static u32 netlbl_domhsh_hash(const char *key)
  * Description:
  * Searches the domain hash table and returns a pointer to the hash table
  * entry if found, otherwise NULL is returned.  The caller is responsibile for
- * the rcu hash table locks (i.e. the caller much call rcu_read_[un]lock()).
+ * ensuring that the hash table is protected with either a RCU read lock or the
+ * hash table lock.
  *
  */
 static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
@@ -141,7 +147,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
 
        if (domain != NULL) {
                bkt = netlbl_domhsh_hash(domain);
-               bkt_list = &rcu_dereference(netlbl_domhsh)->tbl[bkt];
+               bkt_list = &netlbl_domhsh_rcu_deref(netlbl_domhsh)->tbl[bkt];
                list_for_each_entry_rcu(iter, bkt_list, list)
                        if (iter->valid && strcmp(iter->domain, domain) == 0)
                                return iter;
@@ -159,8 +165,8 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
  * Searches the domain hash table and returns a pointer to the hash table
  * entry if an exact match is found, if an exact match is not present in the
  * hash table then the default entry is returned if valid otherwise NULL is
- * returned.  The caller is responsibile for the rcu hash table locks
- * (i.e. the caller much call rcu_read_[un]lock()).
+ * returned.  The caller is responsibile ensuring that the hash table is
+ * protected with either a RCU read lock or the hash table lock.
  *
  */
 static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
@@ -169,7 +175,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
 
        entry = netlbl_domhsh_search(domain);
        if (entry == NULL) {
-               entry = rcu_dereference(netlbl_domhsh_def);
+               entry = netlbl_domhsh_rcu_deref(netlbl_domhsh_def);
                if (entry != NULL && !entry->valid)
                        entry = NULL;
        }
@@ -306,8 +312,11 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
        struct netlbl_af6list *tmp6;
 #endif /* IPv6 */
 
+       /* XXX - we can remove this RCU read lock as the spinlock protects the
+        *       entire function, but before we do we need to fixup the
+        *       netlbl_af[4,6]list RCU functions to do "the right thing" with
+        *       respect to rcu_dereference() when only a spinlock is held. */
        rcu_read_lock();
-
        spin_lock(&netlbl_domhsh_lock);
        if (entry->domain != NULL)
                entry_old = netlbl_domhsh_search(entry->domain);
index 6ce00205f3425cd079b7a64526db259f9ae58d47..1b83e0009d8d4b7fa965dc21552699b905a2ca04 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/audit.h>
 #include <linux/in.h>
 #include <linux/in6.h>
index 8203623e65ad3c09f94869d6c8b9358d7f04c4bf..998e85e895d04e1fc2b26cc856d09fb141cd35a0 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/skbuff.h>
 #include <linux/in.h>
 #include <linux/in6.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/netlink.h>
 #include <net/genetlink.h>
index 852d9d7976b9553073973bbba983807e52d1bdf6..a3d64aabe2f73d6bbd90b12fbbdb6ae908d34447 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/notifier.h>
 #include <linux/netdevice.h>
 #include <linux/security.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/netlink.h>
 #include <net/genetlink.h>
@@ -114,6 +115,9 @@ struct netlbl_unlhsh_walk_arg {
 /* updates should be so rare that having one spinlock for the entire
  * hash table should be okay */
 static DEFINE_SPINLOCK(netlbl_unlhsh_lock);
+#define netlbl_unlhsh_rcu_deref(p) \
+       rcu_dereference_check(p, rcu_read_lock_held() || \
+                                lockdep_is_held(&netlbl_unlhsh_lock))
 static struct netlbl_unlhsh_tbl *netlbl_unlhsh = NULL;
 static struct netlbl_unlhsh_iface *netlbl_unlhsh_def = NULL;
 
@@ -235,15 +239,13 @@ static void netlbl_unlhsh_free_iface(struct rcu_head *entry)
  * Description:
  * This is the hashing function for the unlabeled hash table, it returns the
  * bucket number for the given device/interface.  The caller is responsible for
- * calling the rcu_read_[un]lock() functions.
+ * ensuring that the hash table is protected with either a RCU read lock or
+ * the hash table lock.
  *
  */
 static u32 netlbl_unlhsh_hash(int ifindex)
 {
-       /* this is taken _almost_ directly from
-        * security/selinux/netif.c:sel_netif_hasfn() as they do pretty much
-        * the same thing */
-       return ifindex & (rcu_dereference(netlbl_unlhsh)->size - 1);
+       return ifindex & (netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->size - 1);
 }
 
 /**
@@ -253,7 +255,8 @@ static u32 netlbl_unlhsh_hash(int ifindex)
  * Description:
  * Searches the unlabeled connection hash table and returns a pointer to the
  * interface entry which matches @ifindex, otherwise NULL is returned.  The
- * caller is responsible for calling the rcu_read_[un]lock() functions.
+ * caller is responsible for ensuring that the hash table is protected with
+ * either a RCU read lock or the hash table lock.
  *
  */
 static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
@@ -263,7 +266,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
        struct netlbl_unlhsh_iface *iter;
 
        bkt = netlbl_unlhsh_hash(ifindex);
-       bkt_list = &rcu_dereference(netlbl_unlhsh)->tbl[bkt];
+       bkt_list = &netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->tbl[bkt];
        list_for_each_entry_rcu(iter, bkt_list, list)
                if (iter->valid && iter->ifindex == ifindex)
                        return iter;
@@ -271,33 +274,6 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
        return NULL;
 }
 
-/**
- * netlbl_unlhsh_search_iface_def - Search for a matching interface entry
- * @ifindex: the network interface
- *
- * Description:
- * Searches the unlabeled connection hash table and returns a pointer to the
- * interface entry which matches @ifindex.  If an exact match can not be found
- * and there is a valid default entry, the default entry is returned, otherwise
- * NULL is returned.  The caller is responsible for calling the
- * rcu_read_[un]lock() functions.
- *
- */
-static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface_def(int ifindex)
-{
-       struct netlbl_unlhsh_iface *entry;
-
-       entry = netlbl_unlhsh_search_iface(ifindex);
-       if (entry != NULL)
-               return entry;
-
-       entry = rcu_dereference(netlbl_unlhsh_def);
-       if (entry != NULL && entry->valid)
-               return entry;
-
-       return NULL;
-}
-
 /**
  * netlbl_unlhsh_add_addr4 - Add a new IPv4 address entry to the hash table
  * @iface: the associated interface entry
@@ -308,8 +284,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface_def(int ifindex)
  * Description:
  * Add a new address entry into the unlabeled connection hash table using the
  * interface entry specified by @iface.  On success zero is returned, otherwise
- * a negative value is returned.  The caller is responsible for calling the
- * rcu_read_[un]lock() functions.
+ * a negative value is returned.
  *
  */
 static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
@@ -349,8 +324,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
  * Description:
  * Add a new address entry into the unlabeled connection hash table using the
  * interface entry specified by @iface.  On success zero is returned, otherwise
- * a negative value is returned.  The caller is responsible for calling the
- * rcu_read_[un]lock() functions.
+ * a negative value is returned.
  *
  */
 static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
@@ -391,8 +365,7 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
  * Description:
  * Add a new, empty, interface entry into the unlabeled connection hash table.
  * On success a pointer to the new interface entry is returned, on failure NULL
- * is returned.  The caller is responsible for calling the rcu_read_[un]lock()
- * functions.
+ * is returned.
  *
  */
 static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex)
@@ -415,10 +388,10 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex)
                if (netlbl_unlhsh_search_iface(ifindex) != NULL)
                        goto add_iface_failure;
                list_add_tail_rcu(&iface->list,
-                                 &rcu_dereference(netlbl_unlhsh)->tbl[bkt]);
+                            &netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->tbl[bkt]);
        } else {
                INIT_LIST_HEAD(&iface->list);
-               if (rcu_dereference(netlbl_unlhsh_def) != NULL)
+               if (netlbl_unlhsh_rcu_deref(netlbl_unlhsh_def) != NULL)
                        goto add_iface_failure;
                rcu_assign_pointer(netlbl_unlhsh_def, iface);
        }
@@ -548,8 +521,7 @@ unlhsh_add_return:
  *
  * Description:
  * Remove an IP address entry from the unlabeled connection hash table.
- * Returns zero on success, negative values on failure.  The caller is
- * responsible for calling the rcu_read_[un]lock() functions.
+ * Returns zero on success, negative values on failure.
  *
  */
 static int netlbl_unlhsh_remove_addr4(struct net *net,
@@ -611,8 +583,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
  *
  * Description:
  * Remove an IP address entry from the unlabeled connection hash table.
- * Returns zero on success, negative values on failure.  The caller is
- * responsible for calling the rcu_read_[un]lock() functions.
+ * Returns zero on success, negative values on failure.
  *
  */
 static int netlbl_unlhsh_remove_addr6(struct net *net,
@@ -1547,8 +1518,10 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb,
        struct netlbl_unlhsh_iface *iface;
 
        rcu_read_lock();
-       iface = netlbl_unlhsh_search_iface_def(skb->skb_iif);
+       iface = netlbl_unlhsh_search_iface(skb->skb_iif);
        if (iface == NULL)
+               iface = rcu_dereference(netlbl_unlhsh_def);
+       if (iface == NULL || !iface->valid)
                goto unlabel_getattr_nolabel;
        switch (family) {
        case PF_INET: {
index 68706b4e3bf8a5d800510854a074537c762cf73d..a3fd75ac3fa50187bd7ff6924700569b2b1cebc4 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/audit.h>
 #include <linux/tty.h>
 #include <linux/security.h>
+#include <linux/gfp.h>
 #include <net/sock.h>
 #include <net/netlink.h>
 #include <net/genetlink.h>
index 320d0423a24062fd58aaf6340b021f7be587f581..795424396aff62fba6971aaff0eb6631965ce481 100644 (file)
@@ -683,6 +683,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
        struct netlink_sock *nlk = nlk_sk(sk);
        struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
 
+       if (alen < sizeof(addr->sa_family))
+               return -EINVAL;
+
        if (addr->sa_family == AF_UNSPEC) {
                sk->sk_state    = NETLINK_UNCONNECTED;
                nlk->dst_pid    = 0;
@@ -1093,6 +1096,7 @@ static inline int do_one_set_err(struct sock *sk,
                                 struct netlink_set_err_data *p)
 {
        struct netlink_sock *nlk = nlk_sk(sk);
+       int ret = 0;
 
        if (sk == p->exclude_sk)
                goto out;
@@ -1104,10 +1108,15 @@ static inline int do_one_set_err(struct sock *sk,
            !test_bit(p->group - 1, nlk->groups))
                goto out;
 
+       if (p->code == ENOBUFS && nlk->flags & NETLINK_RECV_NO_ENOBUFS) {
+               ret = 1;
+               goto out;
+       }
+
        sk->sk_err = p->code;
        sk->sk_error_report(sk);
 out:
-       return 0;
+       return ret;
 }
 
 /**
@@ -1116,12 +1125,16 @@ out:
  * @pid: the PID of a process that we want to skip (if any)
  * @groups: the broadcast group that will notice the error
  * @code: error code, must be negative (as usual in kernelspace)
+ *
+ * This function returns the number of broadcast listeners that have set the
+ * NETLINK_RECV_NO_ENOBUFS socket option.
  */
-void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
+int netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
 {
        struct netlink_set_err_data info;
        struct hlist_node *node;
        struct sock *sk;
+       int ret = 0;
 
        info.exclude_sk = ssk;
        info.pid = pid;
@@ -1132,9 +1145,10 @@ void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
        read_lock(&nl_table_lock);
 
        sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list)
-               do_one_set_err(sk, &info);
+               ret += do_one_set_err(sk, &info);
 
        read_unlock(&nl_table_lock);
+       return ret;
 }
 EXPORT_SYMBOL(netlink_set_err);
 
index a4b6e148c5dec4ceba8a4aa5ef964353433e2d6a..06438fa2b1e5d1bfcef02b274941e0553a533bd2 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/socket.h>
index a249127020a50eea96aba8dd0cb594ca86e73e15..fa07f044b59977af946049b8a03fe64be5994966 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/socket.h>
 #include <linux/in.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
index 7aa11b01b2e240890fef4d8503142011d8d3f33b..64e6dde9749d5e713d15ac23914e3928211aa395 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/fcntl.h>
 #include <linux/in.h>
 #include <linux/if_ether.h>    /* For the statistics structure. */
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
index 68176483617f36c6c83df1bf5978753c4ab2755f..6d4ef6d65b3df789d3eb4b3449df1fd1f2a5ced3 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index f324d5df4186f2c69cae6e39aeb1941dd167d421..94d4e922af53c0fb5e1c34508dbad6a76f46d96f 100644 (file)
@@ -7,6 +7,7 @@
  * Copyright Tomi Manninen OH2BNS (oh2bns@sral.fi)
  */
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/socket.h>
 #include <linux/timer.h>
 #include <net/ax25.h>
index e3e6c44e1890cee8246a6d94dfae7181a2e75c19..607fddb4fdbbd944b1dad88400061455f03909a4 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index 5cc648012f50bc8923d4d8dd29a93d7750777518..44059d0c8dd1dceb831a60a71447aa6e8aacb6df 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index 04e7d0d2fd8f1c4aa2f6ba249d3b68ea73b16910..6a947ae50dbdd9865e2607041a4b12f2a7e13fcc 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index 1612d417d10c5b631c4aeea78207cd8e34a0a305..243946d4809d04584a8388c8183aaa4cb608d049 100644 (file)
@@ -60,6 +60,7 @@
 #include <linux/wireless.h>
 #include <linux/kernel.h>
 #include <linux/kmod.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/ip.h>
 #include <net/protocol.h>
@@ -2168,8 +2169,6 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd,
        case SIOCGIFDSTADDR:
        case SIOCSIFDSTADDR:
        case SIOCSIFFLAGS:
-               if (!net_eq(sock_net(sk), &init_net))
-                       return -ENOIOCTLCMD;
                return inet_dgram_ops.ioctl(sock, cmd, arg);
 #endif
 
index 526d0273991a5c99ee2bb2e664bf394640f7a25f..73aee7f2fcdccd56b77f19f818d95085b89e2843 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <asm/unaligned.h>
 #include <net/sock.h>
 
index 387197b579b1c430bd511b695740c7724fb4c9c7..1bd38db4fe1e996df47396d43acd296e9811fa1b 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/socket.h>
 #include <asm/ioctls.h>
 #include <net/sock.h>
index 360cf377693eeee42008d6f0e5f1e34f12259b25..e2a95762abd37685c6b10a63795df539ffe0b295 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/socket.h>
 #include <net/sock.h>
 #include <net/tcp_states.h>
index c597cc53a6fb2d3433c70beea0f05fdc982d5a21..9b4ced6e0968dc99ecf198bbdfba1b4201aed0a4 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/kernel.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/phonet.h>
 #include <linux/proc_fs.h>
@@ -107,8 +108,7 @@ static void phonet_device_destroy(struct net_device *dev)
        if (pnd) {
                u8 addr;
 
-               for (addr = find_first_bit(pnd->addrs, 64); addr < 64;
-                       addr = find_next_bit(pnd->addrs, 64, 1+addr))
+               for_each_set_bit(addr, pnd->addrs, 64)
                        phonet_address_notify(RTM_DELADDR, dev, addr);
                kfree(pnd);
        }
index 2e6c7eb8e76add27fabc042825e8bda8f9886d06..58b3b1f991ed2db16d78d2d192eefb4b4d3ad80e 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/netlink.h>
 #include <linux/phonet.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/phonet/pn_dev.h>
 
@@ -141,8 +142,7 @@ static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
                        continue;
 
                addr_idx = 0;
-               for (addr = find_first_bit(pnd->addrs, 64); addr < 64;
-                       addr = find_next_bit(pnd->addrs, 64, 1+addr)) {
+               for_each_set_bit(addr, pnd->addrs, 64) {
                        if (addr_idx++ < addr_start_idx)
                                continue;
 
index 69c8b826a0cef427e3c1e00c1216af5a014f4c32..c785bfd0744f149b753506f8f2f754329410f8ad 100644 (file)
@@ -23,6 +23,7 @@
  * 02110-1301 USA
  */
 
+#include <linux/gfp.h>
 #include <linux/kernel.h>
 #include <linux/net.h>
 #include <linux/poll.h>
index 853c52be781f7992a850ef2229b6c61b6a3e6f74..f81862baf4d080be3aa507e21e96fba2edd90a7a 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/in.h>
 #include <linux/poll.h>
 #include <net/sock.h>
index 6d06cac2649cd6bc62cdbb71975612c338185e08..f1da27ceb064e5a2d4095414c65e1fbf547d063e 100644 (file)
@@ -30,6 +30,7 @@
  * SOFTWARE.
  *
  */
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/rbtree.h>
 
index 278f607ab603ff90d243472c1efc0a1735742558..7619b671ca2829f0e197a93f6abd06df2f108229 100644 (file)
@@ -32,6 +32,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <net/inet_hashtables.h>
 
 #include "rds.h"
index 3b8992361042f62c0deca22b542e458670667782..8f2d6dd7700a8a0e20192b521c30dc7bc2df553b 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/inetdevice.h>
 #include <linux/if_arp.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "rds.h"
 #include "ib.h"
index 647cb8ffc39bfe96c6953185518844ec1d7a1983..88d0856cb797d3bd41ffc0fc29f0b51618424d6d 100644 (file)
@@ -32,6 +32,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/in.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include "rds.h"
index 4b0da865a72c2ee323999b1810a3a19a3a07709d..059989fdb7d784592eef3f873b808d1b88a16afa 100644 (file)
@@ -31,6 +31,7 @@
  *
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include "rds.h"
 #include "rdma.h"
index 04dc0d3f3c955c00449d67a17951b86ac0f08573..c7dd11b835f04447cb2e63d013e0b49fd9a384b2 100644 (file)
@@ -31,6 +31,7 @@
  *
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <rdma/rdma_cm.h>
index 814a91a6f4a79dd97422bded809a0e67778a4bd5..c45c4173a44d44eb9ceee633e0cec271f2182411 100644 (file)
@@ -32,6 +32,7 @@
  */
 #include <linux/percpu.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/proc_fs.h>
 
 #include "rds.h"
index b28fa8525b24029ffdfb026ee19a76d3597fc668..c8f3d3525cb9b187daeca402f71cb5b88356ce41 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/inetdevice.h>
 #include <linux/if_arp.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "rds.h"
 #include "iw.h"
index 394cf6b4d0aad63c4dbb7bb51ecdd4b0b69b2dbc..3e9460f935d84f6ebafca6d5592b8f8527185fb7 100644 (file)
@@ -32,6 +32,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/in.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 #include "rds.h"
index 9eda11cca9566fbeb96e56e6f3ae9566fa152d99..13dc1862d86264288eb0455056d289008d072234 100644 (file)
@@ -31,6 +31,7 @@
  *
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include "rds.h"
 #include "rdma.h"
index 54af7d6b92da073ad9305d67eb04a48acb0b6e7e..da43ee840ca3bb89d44d5031b5acf5887fcf1069 100644 (file)
@@ -31,6 +31,7 @@
  *
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <rdma/rdma_cm.h>
index 4a61997f554db1108c69cd619662526d80079f0a..0d7a159158b81c0b18af5df5f37a7c2356f9a6eb 100644 (file)
@@ -31,6 +31,7 @@
  *
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/in.h>
 
 #include "rds.h"
index 73e600ffd87ff533d5091b866ab7f5bff586663b..9a1d67e001ba60a79608275ecfa3ed452f373b19 100644 (file)
@@ -31,6 +31,7 @@
  *
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include "rds.h"
 #include "rdma.h"
index 36790122dfd4c3cb869960ddb2141cd235973e16..595a952d4b17f069c60a457701d6e207f68e621b 100644 (file)
@@ -31,6 +31,7 @@
  *
  */
 #include <linux/highmem.h>
+#include <linux/gfp.h>
 
 #include "rds.h"
 
index 4c64daa1f5d52b0eb72b6920bd7f4a39a3a756b9..5ce9437cad672168825e78f43fb1fe38e8ce2b20 100644 (file)
@@ -31,6 +31,7 @@
  *
  */
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 #include <linux/rbtree.h>
 #include <linux/dma-mapping.h> /* for DMA_*_DEVICE */
 
index 9ece910ea394317a7b8dc9fd80e6a7c540e5f9b3..7b155081b4dc59ba8a8565396ff01e78cb7cde21 100644 (file)
@@ -134,7 +134,7 @@ static int __init rds_rdma_listen_init(void)
                ret = PTR_ERR(cm_id);
                printk(KERN_ERR "RDS/RDMA: failed to setup listener, "
                       "rdma_create_id() returned %d\n", ret);
-               goto out;
+               return ret;
        }
 
        sin.sin_family = AF_INET,
index b426d67f760c61f77717a40057d71fd0090da46e..e2a2b9344f7b576be4d06ca02f23c072acd9f904 100644 (file)
@@ -31,6 +31,7 @@
  *
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <linux/in.h>
 
index b2fccfc207690f5bfa231af389031a7dce8a218b..f04b929ded926d48b0fd326f5c5d916895b3f9b5 100644 (file)
@@ -31,6 +31,7 @@
  *
  */
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <net/sock.h>
 #include <linux/in.h>
 #include <linux/list.h>
index b5198aee45d3a3469100f44bfed4fef9dddac56b..babf4577ff7d3f06835e073e48733edeceb97db3 100644 (file)
@@ -31,6 +31,7 @@
  *
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/in.h>
 #include <net/tcp.h>
 
index 53cb1b54165d81f0145dbef5b3bc173058383963..975183fe6950a34b242ef55db011e6f04c1c6772 100644 (file)
@@ -31,6 +31,7 @@
  *
  */
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/in.h>
 #include <net/tcp.h>
 
index c00dafffbb5acf3d844716b49d5fe434e710d006..e08ec912d8b0f3f3181e32365a567abb2d916ebe 100644 (file)
@@ -31,6 +31,7 @@
  *
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <net/tcp.h>
 
 #include "rds.h"
index c218e07e5cafe80bb65ef86dfec1b27a9cdfb986..a9fa86f65983a65ebbcc9a04e65f053df2f70afc 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/wait.h>
 #include <linux/poll.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 
 #include "rfkill.h"
 
index e90b9b6c16ae8130b1f9993b6b5991743663dd61..4fb711a035f43f34ee5490fb5ab9ed17e93a98af 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/socket.h>
 #include <linux/in.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
index 424b893d14502b95d8f61aecf74fd9df3c14ac7f..178ff4f73c85102518025fa3d4e20f647a389743 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/fcntl.h>
 #include <linux/in.h>
 #include <linux/if_ether.h>
+#include <linux/slab.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
index 5ef5f6988a2e1aa892539e0c7c53364d7f796808..a750a28e02219770539fcfe08b0010fe9cca0cdd 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index 968e8bac1b5dfd8f33578633c1f4338a5fe66624..ae4a9d99aec70da821722a4e204ee6eacf1df872 100644 (file)
@@ -7,6 +7,7 @@
  * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
  */
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/socket.h>
 #include <linux/timer.h>
 #include <net/ax25.h>
index 69820f93414b1ca7f98fb62b5570d8d0bfbca0aa..4ebf33afbe473c31098ab6e80674ef3d6198892e 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
+#include <linux/gfp.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index 70a0b3b4b4d2903b7bd74d1e783e819a561c32ce..cbc244a128bd1611829f6e943ae7a669cc81f2d3 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index b05108f382da4a757b0381a106bfcbc3598dd51e..1734abba26a29bf1a9d156747b97d0d8c5f1fe84 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <net/ax25.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
index 287b1415cee93fae57a830fdd74ef9144b00c7d7..c060095b27ce9c6b1f565461345836d38a154f6c 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 #include <linux/net.h>
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/poll.h>
 #include <linux/proc_fs.h>
index 77228f28fa363240fce7da4e32d0b81bd8ea3951..6d79310fcaaeead0d6d0953f791e18385c794c03 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <linux/icmp.h>
+#include <linux/gfp.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
 #include <net/ip.h>
@@ -88,6 +89,11 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local,
 
        /* get a notification message to send to the server app */
        notification = alloc_skb(0, GFP_NOFS);
+       if (!notification) {
+               _debug("no memory");
+               ret = -ENOMEM;
+               goto error_nofree;
+       }
        rxrpc_new_skb(notification);
        notification->mark = RXRPC_SKB_MARK_NEW_CALL;
 
@@ -189,6 +195,7 @@ invalid_service:
        ret = -ECONNREFUSED;
 error:
        rxrpc_free_skb(notification);
+error_nofree:
        _leave(" = %d", ret);
        return ret;
 }
index b4a2209770311a4fdce0757c9857bbdd6fdf2f39..2714da167fb8980fd7a43f3485e25e2bdcfc7feb 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/circ_buf.h>
 #include <linux/net.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/udp.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
index bc0019f704fecb433b369798a064aaf7230a6a6c..909d092de9f43c9e4320e465711d2d1a36fb692a 100644 (file)
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/circ_buf.h>
 #include <net/sock.h>
index 9f1ce841a0bbcd348e83c7ad518649079e95c357..4106ca95ec86f43b8c235dd5d94e9fc016ea06f5 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/net.h>
 #include <linux/skbuff.h>
 #include <linux/crypto.h>
index f98c8027e5c12970f959144309d5d44f4677ee9a..89315009bab11f2f6c32db1bd50d0505d8210c46 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <linux/icmp.h>
+#include <linux/gfp.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
 #include <net/ip.h>
index 74697b2004962059857c6b42e84a5490befce23d..5ee16f0353febe4d195daaa6ca29ace62a79c06a 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/key-type.h>
 #include <linux/crypto.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
 #include <keys/rxrpc-type.h>
index 807535ff29b52d0ebdb85ac6ba4fa5e4c5d18805..87f7135d238b498f9208543cf4608c1cb78a59d3 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/net.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
 #include "ar-internal.h"
index cc9102c5b588319e09b9769302bd5704e9bfb8e3..5f22e263eda748ffdbe06f802626588a70776004 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/net.h>
+#include <linux/gfp.h>
 #include <linux/skbuff.h>
 #include <linux/circ_buf.h>
 #include <net/sock.h>
index edc026c1eb763aeaf837d27ab9692374a4a7653b..f0f85b0123f7b58f3d9e34048af2bcf49fcf4fa5 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <linux/icmp.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
 #include <net/ip.h>
index 0936e1acc30ece6110313c01fb0ee78c0e5dd91e..5e0226fe587e738157d58471f6a603d003780484 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/net.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
 #include "ar-internal.h"
index 713ac593e2e96d5a21b43958ff3ebb67816a8a3c..7635107726ce76b66be2e28877bec91f9286ae96 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/crypto.h>
 #include <linux/scatterlist.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
 #include <keys/rxrpc-type.h>
index 21f9c7678aa3ea903a9741305c22b6157e8637c3..2f691fb180d127751877003af00e624334da474c 100644 (file)
@@ -328,13 +328,16 @@ config NET_CLS_FLOW
          module will be called cls_flow.
 
 config NET_CLS_CGROUP
-       bool "Control Group Classifier"
+       tristate "Control Group Classifier"
        select NET_CLS
        depends on CGROUPS
        ---help---
          Say Y here if you want to classify packets based on the control
          cgroup of their process.
 
+         To compile this code as a module, choose M here: the
+         module will be called cls_cgroup.
+
 config NET_EMATCH
        bool "Extended Matches"
        select NET_CLS
index 64f5e328cee99025d58b477902bcdb78fc7a8d46..d8e0171d9a4b8a14cd2c7241c173d3647164430e 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/kmod.h>
index 082c520b0def5d85f8ca8dc830d3ec20250cd758..da27a170b6b7bcd42372a651668cba3f72034ab0 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
 #include <linux/tc_act/tc_ipt.h>
index d329170243cb858de314d018ce085728b28e638a..c046682054ebdffbba3f71e439d140ac5c3155c1 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <net/net_namespace.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
index 6b0359a500e603510cf30f1a66767dcb3f62b42c..b7dcfedc802ea5c54a096efe3921f1fe4dd30aa5 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
 #include <linux/tc_act/tc_pedit.h>
index 723964c3ee4ff78c4e442db790d960b261fd04df..654f73dff7c1c8d7f9d5fb6541174299c4b32f05 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <net/act_api.h>
 #include <net/netlink.h>
 
index 8daa1ebc7413b971dafde75606af039d52a7e83e..622ca809c15ca3cf595e0d721e1d70171c3c2fbe 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
index 3725d8fa29db7c02185636336bba3cd59922d124..f082b27ff46d90fe80d85ab051511e43acb915c1 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/kmod.h>
 #include <linux/netlink.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
 #include <net/netlink.h>
index 4e2bda854119bf87391dc89a3cda8ce44810c5a0..efd4f95fd0507d1d114db3683805cf08a61762f7 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
index e4877ca6727c4b098ef1b6f08163fd7702d3eea2..221180384fd7d466bc0864ae6eca5aee9a6f0e95 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/errno.h>
@@ -24,6 +25,25 @@ struct cgroup_cls_state
        u32 classid;
 };
 
+static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss,
+                                              struct cgroup *cgrp);
+static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp);
+static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp);
+
+struct cgroup_subsys net_cls_subsys = {
+       .name           = "net_cls",
+       .create         = cgrp_create,
+       .destroy        = cgrp_destroy,
+       .populate       = cgrp_populate,
+#ifdef CONFIG_NET_CLS_CGROUP
+       .subsys_id      = net_cls_subsys_id,
+#else
+#define net_cls_subsys_id net_cls_subsys.subsys_id
+#endif
+       .module         = THIS_MODULE,
+};
+
+
 static inline struct cgroup_cls_state *cgrp_cls_state(struct cgroup *cgrp)
 {
        return container_of(cgroup_subsys_state(cgrp, net_cls_subsys_id),
@@ -79,14 +99,6 @@ static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp)
        return cgroup_add_files(cgrp, ss, ss_files, ARRAY_SIZE(ss_files));
 }
 
-struct cgroup_subsys net_cls_subsys = {
-       .name           = "net_cls",
-       .create         = cgrp_create,
-       .destroy        = cgrp_destroy,
-       .populate       = cgrp_populate,
-       .subsys_id      = net_cls_subsys_id,
-};
-
 struct cls_cgroup_head
 {
        u32                     handle;
@@ -277,12 +289,19 @@ static struct tcf_proto_ops cls_cgroup_ops __read_mostly = {
 
 static int __init init_cgroup_cls(void)
 {
-       return register_tcf_proto_ops(&cls_cgroup_ops);
+       int ret = register_tcf_proto_ops(&cls_cgroup_ops);
+       if (ret)
+               return ret;
+       ret = cgroup_load_subsys(&net_cls_subsys);
+       if (ret)
+               unregister_tcf_proto_ops(&cls_cgroup_ops);
+       return ret;
 }
 
 static void __exit exit_cgroup_cls(void)
 {
        unregister_tcf_proto_ops(&cls_cgroup_ops);
+       cgroup_unload_subsys(&net_cls_subsys);
 }
 
 module_init(init_cgroup_cls);
index e054c62857e19ef29826857aabad4d5a5fcf8ac4..6ed61b10e0020d657c4531d501adf155292c486a 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <linux/if_vlan.h>
+#include <linux/slab.h>
 
 #include <net/pkt_cls.h>
 #include <net/ip.h>
index 6d6e87585fb1a5028285210cd404ebc67547daa3..93b0a7b6f9b474641595d4f093b79330bd0d05f9 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
index dd872d5383efe371fa4333dcc1af724039b047b5..694dcd85dec83bda586f8a96843a1f8fac6a4259 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
index e806f2314b5e24281dd4bfbe3f442d1c1ee51d41..20ef330bb918b552f91c3795d67a2c6f9d407c3b 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 #include <linux/errno.h>
+#include <linux/slab.h>
 #include <net/act_api.h>
 #include <net/netlink.h>
 #include <net/pkt_cls.h>
index 07372f60bee3364588cb94fcfcad1cc7bee514e5..17c5dfc673209d68670aee8bfb5cbf099a4f0a51 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
index 24dce8b648a425b39f877bfe4935b0602ee16c9b..3bcac8aa333c2a322fb7283ce0803480e893d5d4 100644 (file)
@@ -58,6 +58,7 @@
  *           only available if that subsystem is enabled in the kernel.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
index 370a1b2ea31770b4ce08196f146d43da12f31f4e..1a4176aee6e5c181749d522ebd2a258dbbf59762 100644 (file)
@@ -9,6 +9,7 @@
  * Authors:    Thomas Graf <tgraf@suug.ch>
  */
 
+#include <linux/gfp.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
index 853c5ead87fd3691c4e699eebb9c6b34bc64f9aa..763253257411af1db91b3e25a78af8e687523342 100644 (file)
@@ -9,6 +9,7 @@
  * Authors:    Thomas Graf <tgraf@suug.ch>
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
index aab59409728b4c50c4c45bc233570c10b8844980..e782bdeedc584254ecf8b544d85a449039016a92 100644 (file)
@@ -82,6 +82,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
index 6cd491013b503f264fe210545a118f45cb8df0d0..145268ca57cfeffdfea5751e19c738964b2637db 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/list.h>
 #include <linux/hrtimer.h>
 #include <linux/lockdep.h>
+#include <linux/slab.h>
 
 #include <net/net_namespace.h>
 #include <net/sock.h>
index ab82f145f68937a9c722322517fd2dd479550db0..fcbb86a486a21ab3c9a51a63bd248f809817dbd0 100644 (file)
@@ -3,6 +3,7 @@
 /* Written 1998-2000 by Werner Almesberger, EPFL ICA */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/errno.h>
index 3846d65bc03ec7a7de7e6ca674dc6c2b255dc570..28c01ef5abc815ae5429e29c34bba8b97b7d50f6 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
index a65604f8f2b8f8aaa6dce6a2a13ee76e73b295be..b74046a95397c6d2e3d9a90e648c3414dd18c50f 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
index d303daa45d49e54f34bc11d698d309253c5e77b2..63d41f86679c0653951090c81f189665c5deaa00 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/errno.h>
index 4b0a6cc44c77b6c50e02247333f8b9ed42ae4e3c..5948bafa8ce29de97bf4a824139ee2f033579810 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
index 5173c1e1b19c3c0756310dae69785b6b1456c25f..ff4dd53eeff013f875330d8fbeb24e3a6e299e5a 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/rcupdate.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <net/pkt_sched.h>
 
 /* Main transmission queue. */
index 40408d595c08da0163e9a2c4c358e0293d4cebce..51dcc2aa5c926b735fa683135bddaf3c66114355 100644 (file)
@@ -18,6 +18,7 @@
  *  For all the glorious comments look at include/net/red.h
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
index 508cf5f3a6d5c4a2b0555e08273555590b97957f..0b52b8de562c40db1bd4541a08389885af621cb2 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/compiler.h>
 #include <linux/rbtree.h>
 #include <linux/workqueue.h>
+#include <linux/slab.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
 
index d1dea3d5dc929f1dc2051b2ed42f65168c88aa09..b2aba3f5e6fa5cd8bdf127c86d96fd7ab21ebf32 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/errno.h>
index 7db2c88ce585f04a7361b87dec3aa2760d65f1f3..c50876cd87047bace522be68375d193687108ade 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
index d8b10e054627a8aea17fe2818833587e11ef63af..4714ff162bbd2cdf42eb77c7b629e0331391bfeb 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
index 93285cecb246942b5640809d34e7d17d9ee1d63a..81672e0c1b253558a77f6ead32dfd6bfbb995c4e 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
index cb21380c0605fe813b4a4ff0f489d9fdc08c2428..c5a9ac5660079581ad81b61bef4039da621cf2ad 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/ipv6.h>
 #include <linux/skbuff.h>
 #include <linux/jhash.h>
+#include <linux/slab.h>
 #include <net/ip.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
index db69637069c458443793f5d4d08a17c7225ff87e..3415b6ce1c0a5b1116a4e23cc710c0b8f5b0f8d5 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/if_arp.h>
index df5abbff63e22b5de97b3579173adf37519a8df3..99c93ee98ad9dd0317c236e561e25fef069297d0 100644 (file)
@@ -1194,8 +1194,10 @@ void sctp_assoc_update(struct sctp_association *asoc,
        /* Remove any peer addresses not present in the new association. */
        list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
                trans = list_entry(pos, struct sctp_transport, transports);
-               if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr))
-                       sctp_assoc_del_peer(asoc, &trans->ipaddr);
+               if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) {
+                       sctp_assoc_rm_peer(asoc, trans);
+                       continue;
+               }
 
                if (asoc->state >= SCTP_STATE_ESTABLISHED)
                        sctp_transport_reset(trans);
index 56935bbc1496f535e646d2e8ef03c9bddb3a2634..86366390038a1cae0b536874fd037464f2a1678f 100644 (file)
@@ -34,6 +34,7 @@
  * be incorporated into the next SCTP release.
  */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/crypto.h>
 #include <linux/scatterlist.h>
index bef1337316837c8dce7b97bdd89560ecee23cbdd..faf71d179e4641137f8d8d477e4a9773321d4bdd 100644 (file)
@@ -43,6 +43,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/in.h>
 #include <net/sock.h>
 #include <net/ipv6.h>
index 8e4320040f058ebbd0f7d7ca64b1749f9ec9df12..3eab6db59a37e5e5a9d40b6afabac39d421af2e3 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/net.h>
 #include <linux/inet.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
index 905fda582b92b652aebd8108feaa12f9cf92fb79..7ec09ba03a1cec9e82d6251d9becccf8a8a42a1b 100644 (file)
@@ -144,6 +144,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
        /* Use SCTP specific send buffer space queues.  */
        ep->sndbuf_policy = sctp_sndbuf_policy;
 
+       sk->sk_data_ready = sctp_data_ready;
        sk->sk_write_space = sctp_write_space;
        sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
 
index 3d74b264ea2256442eb336e1e333269b8cdbe128..ea2192444ce66413261d20ce8ec236279496d141 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/socket.h>
 #include <linux/ip.h>
 #include <linux/time.h> /* For struct timeval */
+#include <linux/slab.h>
 #include <net/ip.h>
 #include <net/icmp.h>
 #include <net/snmp.h>
@@ -439,11 +440,25 @@ void sctp_icmp_proto_unreachable(struct sock *sk,
 {
        SCTP_DEBUG_PRINTK("%s\n",  __func__);
 
-       sctp_do_sm(SCTP_EVENT_T_OTHER,
-                  SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
-                  asoc->state, asoc->ep, asoc, t,
-                  GFP_ATOMIC);
+       if (sock_owned_by_user(sk)) {
+               if (timer_pending(&t->proto_unreach_timer))
+                       return;
+               else {
+                       if (!mod_timer(&t->proto_unreach_timer,
+                                               jiffies + (HZ/20)))
+                               sctp_association_hold(asoc);
+               }
+                       
+       } else {
+               if (timer_pending(&t->proto_unreach_timer) &&
+                   del_timer(&t->proto_unreach_timer))
+                       sctp_association_put(asoc);
 
+               sctp_do_sm(SCTP_EVENT_T_OTHER,
+                          SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
+                          asoc->state, asoc->ep, asoc, t,
+                          GFP_ATOMIC);
+       }
 }
 
 /* Common lookup code for icmp/icmpv6 error handler. */
index bbf5dd2a97c42d0ac49d7ad0f1e0fd6b0955f63a..ccb6dc48d15b6ecf123887cd23d00ffec1ec3c4a 100644 (file)
@@ -46,6 +46,7 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 /* Initialize an SCTP inqueue.  */
 void sctp_inq_init(struct sctp_inq *queue)
index 1d7ac70ba39f611dae6fa8e932369705c81d47be..9fb5d37c37ad0785fcd2e56b3912baa1a9087de3 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/netdevice.h>
 #include <linux/init.h>
 #include <linux/ipsec.h>
+#include <linux/slab.h>
 
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
index 7c5589363433c38d6c63a344f36d5e9d61befc45..fad261d41ec2f6fdbb1eb3d323b1a0445f29305a 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <net/inet_ecn.h>
 #include <net/ip.h>
 #include <net/icmp.h>
index 229690f02a1da7131811114f47b7cf3e7c35e5ca..abfc0b8dee74ea171c9f974e7a10fe4b9c66b2b9 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/list.h>   /* For struct list_head */
 #include <linux/socket.h>
 #include <linux/ip.h>
+#include <linux/slab.h>
 #include <net/sock.h>    /* For skb_set_owner_w */
 
 #include <net/sctp/sctp.h>
index 8cb4f060bce68298d2f3d59ff67bf97fab276dbc..534c7eae9d15f9b0371b7cd2963f74e7cbf18e7c 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/socket.h>
 #include <linux/ip.h>
 #include <linux/time.h> /* For struct timeval */
+#include <linux/gfp.h>
 #include <net/sock.h>
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
index e771690f6d5d90d05111d981d55404cef66d737f..a56f98e82f92f0a0dbd53d2045ab7d8053ab1454 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/bootmem.h>
 #include <linux/highmem.h>
 #include <linux/swap.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/protocol.h>
 #include <net/ip.h>
index 9e732916b671bde5893681f2e6690244260f0da2..30c1767186b8af2d6091eaab4e9b77ee1f831215 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/inet.h>
 #include <linux/scatterlist.h>
 #include <linux/crypto.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 
 #include <linux/skbuff.h>
@@ -107,7 +108,7 @@ static const struct sctp_paramhdr prsctp_param = {
        cpu_to_be16(sizeof(struct sctp_paramhdr)),
 };
 
-/* A helper to initialize to initialize an op error inside a
+/* A helper to initialize an op error inside a
  * provided chunk, as most cause codes will be embedded inside an
  * abort chunk.
  */
@@ -124,6 +125,29 @@ void  sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code,
        chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err);
 }
 
+/* A helper to initialize an op error inside a
+ * provided chunk, as most cause codes will be embedded inside an
+ * abort chunk.  Differs from sctp_init_cause in that it won't oops
+ * if there isn't enough space in the op error chunk
+ */
+int sctp_init_cause_fixed(struct sctp_chunk *chunk, __be16 cause_code,
+                     size_t paylen)
+{
+       sctp_errhdr_t err;
+       __u16 len;
+
+       /* Cause code constants are now defined in network order.  */
+       err.cause = cause_code;
+       len = sizeof(sctp_errhdr_t) + paylen;
+       err.length  = htons(len);
+
+       if (skb_tailroom(chunk->skb) >  len)
+               return -ENOSPC;
+       chunk->subh.err_hdr = sctp_addto_chunk_fixed(chunk,
+                                                    sizeof(sctp_errhdr_t),
+                                                    &err);
+       return 0;
+}
 /* 3.3.2 Initiation (INIT) (1)
  *
  * This chunk is used to initiate a SCTP association between two
@@ -207,7 +231,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
        sp = sctp_sk(asoc->base.sk);
        num_types = sp->pf->supported_addrs(sp, types);
 
-       chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types);
+       chunksize = sizeof(init) + addrs_len;
+       chunksize += WORD_ROUND(SCTP_SAT_LEN(num_types));
        chunksize += sizeof(ecap_param);
 
        if (sctp_prsctp_enable)
@@ -237,14 +262,14 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
                /* Add HMACS parameter length if any were defined */
                auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs;
                if (auth_hmacs->length)
-                       chunksize += ntohs(auth_hmacs->length);
+                       chunksize += WORD_ROUND(ntohs(auth_hmacs->length));
                else
                        auth_hmacs = NULL;
 
                /* Add CHUNKS parameter length */
                auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks;
                if (auth_chunks->length)
-                       chunksize += ntohs(auth_chunks->length);
+                       chunksize += WORD_ROUND(ntohs(auth_chunks->length));
                else
                        auth_chunks = NULL;
 
@@ -254,7 +279,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
 
        /* If we have any extensions to report, account for that */
        if (num_ext)
-               chunksize += sizeof(sctp_supported_ext_param_t) + num_ext;
+               chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) +
+                                       num_ext);
 
        /* RFC 2960 3.3.2 Initiation (INIT) (1)
         *
@@ -396,13 +422,13 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
 
                auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs;
                if (auth_hmacs->length)
-                       chunksize += ntohs(auth_hmacs->length);
+                       chunksize += WORD_ROUND(ntohs(auth_hmacs->length));
                else
                        auth_hmacs = NULL;
 
                auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks;
                if (auth_chunks->length)
-                       chunksize += ntohs(auth_chunks->length);
+                       chunksize += WORD_ROUND(ntohs(auth_chunks->length));
                else
                        auth_chunks = NULL;
 
@@ -411,7 +437,8 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
        }
 
        if (num_ext)
-               chunksize += sizeof(sctp_supported_ext_param_t) + num_ext;
+               chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) +
+                                       num_ext);
 
        /* Now allocate and fill out the chunk.  */
        retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize);
@@ -1128,6 +1155,24 @@ nodata:
        return retval;
 }
 
+/* Create an Operation Error chunk of a fixed size,
+ * specifically, max(asoc->pathmtu, SCTP_DEFAULT_MAXSEGMENT)
+ * This is a helper function to allocate an error chunk for
+ * for those invalid parameter codes in which we may not want
+ * to report all the errors, if the incomming chunk is large
+ */
+static inline struct sctp_chunk *sctp_make_op_error_fixed(
+       const struct sctp_association *asoc,
+       const struct sctp_chunk *chunk)
+{
+       size_t size = asoc ? asoc->pathmtu : 0;
+
+       if (!size)
+               size = SCTP_DEFAULT_MAXSEGMENT;
+
+       return sctp_make_op_error_space(asoc, chunk, size);
+}
+
 /* Create an Operation Error chunk.  */
 struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc,
                                 const struct sctp_chunk *chunk,
@@ -1370,6 +1415,18 @@ void *sctp_addto_chunk(struct sctp_chunk *chunk, int len, const void *data)
        return target;
 }
 
+/* Append bytes to the end of a chunk. Returns NULL if there isn't sufficient
+ * space in the chunk
+ */
+void *sctp_addto_chunk_fixed(struct sctp_chunk *chunk,
+                            int len, const void *data)
+{
+       if (skb_tailroom(chunk->skb) > len)
+               return sctp_addto_chunk(chunk, len, data);
+       else
+               return NULL;
+}
+
 /* Append bytes from user space to the end of a chunk.  Will panic if
  * chunk is not big enough.
  * Returns a kernel err value.
@@ -1973,13 +2030,12 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc,
                 * returning multiple unknown parameters.
                 */
                if (NULL == *errp)
-                       *errp = sctp_make_op_error_space(asoc, chunk,
-                                       ntohs(chunk->chunk_hdr->length));
+                       *errp = sctp_make_op_error_fixed(asoc, chunk);
 
                if (*errp) {
-                       sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM,
+                       sctp_init_cause_fixed(*errp, SCTP_ERROR_UNKNOWN_PARAM,
                                        WORD_ROUND(ntohs(param.p->length)));
-                       sctp_addto_chunk(*errp,
+                       sctp_addto_chunk_fixed(*errp,
                                        WORD_ROUND(ntohs(param.p->length)),
                                        param.v);
                } else {
@@ -3314,21 +3370,6 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
        sctp_chunk_free(asconf);
        asoc->addip_last_asconf = NULL;
 
-       /* Send the next asconf chunk from the addip chunk queue. */
-       if (!list_empty(&asoc->addip_chunk_list)) {
-               struct list_head *entry = asoc->addip_chunk_list.next;
-               asconf = list_entry(entry, struct sctp_chunk, list);
-
-               list_del_init(entry);
-
-               /* Hold the chunk until an ASCONF_ACK is received. */
-               sctp_chunk_hold(asconf);
-               if (sctp_primitive_ASCONF(asoc, asconf))
-                       sctp_chunk_free(asconf);
-               else
-                       asoc->addip_last_asconf = asconf;
-       }
-
        return retval;
 }
 
index 500886bda9b4acb8d600b5ce622923dab68b9486..eb1f42f45fdde604512f1eefcced4041843e51f8 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/types.h>
 #include <linux/socket.h>
 #include <linux/ip.h>
+#include <linux/gfp.h>
 #include <net/sock.h>
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
@@ -396,6 +397,41 @@ out_unlock:
        sctp_transport_put(transport);
 }
 
+/* Handle the timeout of the ICMP protocol unreachable timer.  Trigger
+ * the correct state machine transition that will close the association.
+ */
+void sctp_generate_proto_unreach_event(unsigned long data)
+{
+       struct sctp_transport *transport = (struct sctp_transport *) data;
+       struct sctp_association *asoc = transport->asoc;
+       
+       sctp_bh_lock_sock(asoc->base.sk);
+       if (sock_owned_by_user(asoc->base.sk)) {
+               SCTP_DEBUG_PRINTK("%s:Sock is busy.\n", __func__);
+
+               /* Try again later.  */
+               if (!mod_timer(&transport->proto_unreach_timer,
+                               jiffies + (HZ/20)))
+                       sctp_association_hold(asoc);
+               goto out_unlock;
+       }
+
+       /* Is this structure just waiting around for us to actually
+        * get destroyed?
+        */
+       if (asoc->base.dead)
+               goto out_unlock;
+
+       sctp_do_sm(SCTP_EVENT_T_OTHER,
+                  SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
+                  asoc->state, asoc->ep, asoc, transport, GFP_ATOMIC);
+
+out_unlock:
+       sctp_bh_unlock_sock(asoc->base.sk);
+       sctp_association_put(asoc);
+}
+
+
 /* Inject a SACK Timeout event into the state machine.  */
 static void sctp_generate_sack_event(unsigned long data)
 {
@@ -961,6 +997,29 @@ static int sctp_cmd_send_msg(struct sctp_association *asoc,
 }
 
 
+/* Sent the next ASCONF packet currently stored in the association.
+ * This happens after the ASCONF_ACK was succeffully processed.
+ */
+static void sctp_cmd_send_asconf(struct sctp_association *asoc)
+{
+       /* Send the next asconf chunk from the addip chunk
+        * queue.
+        */
+       if (!list_empty(&asoc->addip_chunk_list)) {
+               struct list_head *entry = asoc->addip_chunk_list.next;
+               struct sctp_chunk *asconf = list_entry(entry,
+                                               struct sctp_chunk, list);
+               list_del_init(entry);
+
+               /* Hold the chunk until an ASCONF_ACK is received. */
+               sctp_chunk_hold(asconf);
+               if (sctp_primitive_ASCONF(asoc, asconf))
+                       sctp_chunk_free(asconf);
+               else
+                       asoc->addip_last_asconf = asconf;
+       }
+}
+
 
 /* These three macros allow us to pull the debugging code out of the
  * main flow of sctp_do_sm() to keep attention focused on the real
@@ -1616,6 +1675,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        }
                        error = sctp_cmd_send_msg(asoc, cmd->obj.msg);
                        break;
+               case SCTP_CMD_SEND_NEXT_ASCONF:
+                       sctp_cmd_send_asconf(asoc);
+                       break;
                default:
                        printk(KERN_WARNING "Impossible command: %u, %p\n",
                               cmd->verb, cmd->obj.ptr);
index 47bc20d3a85b714f2d4d5730b4effccbc4f4c080..24b2cd55563726e8cd24be5dfbfafe8eb2892886 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/ipv6.h>
 #include <linux/net.h>
 #include <linux/inet.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/inet_ecn.h>
 #include <linux/skbuff.h>
@@ -3675,8 +3676,14 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
 
                if (!sctp_process_asconf_ack((struct sctp_association *)asoc,
-                                            asconf_ack))
+                                            asconf_ack)) {
+                       /* Successfully processed ASCONF_ACK.  We can
+                        * release the next asconf if we have one.
+                        */
+                       sctp_add_cmd_sf(commands, SCTP_CMD_SEND_NEXT_ASCONF,
+                                       SCTP_NULL());
                        return SCTP_DISPOSITION_CONSUME;
+               }
 
                abort = sctp_make_abort(asoc, asconf_ack,
                                        sizeof(sctp_errhdr_t));
index dfc5c127efd47d5cfca1a5541d3e91dff898c1b3..44a1ab03a3f0124ac33c63aa62f54b5663b52914 100644 (file)
@@ -67,6 +67,7 @@
 #include <linux/poll.h>
 #include <linux/init.h>
 #include <linux/crypto.h>
+#include <linux/slab.h>
 
 #include <net/ip.h>
 #include <net/icmp.h>
@@ -3718,12 +3719,12 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
        sp->hmac = NULL;
 
        SCTP_DBG_OBJCNT_INC(sock);
-       percpu_counter_inc(&sctp_sockets_allocated);
 
        /* Set socket backlog limit. */
        sk->sk_backlog.limit = sysctl_sctp_rmem[1];
 
        local_bh_disable();
+       percpu_counter_inc(&sctp_sockets_allocated);
        sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
        local_bh_enable();
 
@@ -3740,8 +3741,8 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk)
        /* Release our hold on the endpoint. */
        ep = sctp_sk(sk)->ep;
        sctp_endpoint_free(ep);
-       percpu_counter_dec(&sctp_sockets_allocated);
        local_bh_disable();
+       percpu_counter_dec(&sctp_sockets_allocated);
        sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
        local_bh_enable();
 }
@@ -6188,6 +6189,16 @@ do_nonblock:
        goto out;
 }
 
+void sctp_data_ready(struct sock *sk, int len)
+{
+       read_lock_bh(&sk->sk_callback_lock);
+       if (sk_has_sleeper(sk))
+               wake_up_interruptible_sync_poll(sk->sk_sleep, POLLIN |
+                                               POLLRDNORM | POLLRDBAND);
+       sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
+       read_unlock_bh(&sk->sk_callback_lock);
+}
+
 /* If socket sndbuf has changed, wake up all per association waiters.  */
 void sctp_write_space(struct sock *sk)
 {
index 737d330e5ffc6a4fdeb4d8b64cccc53e34b619f0..442ad4ed6315fab99ec5b78d012e65a8236e2fae 100644 (file)
@@ -37,6 +37,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
index b827d21dbe54451582c61a4758b7063e794cfd7d..165d54e07fcd4bc571642fff9ad020411e417c00 100644 (file)
@@ -48,6 +48,7 @@
  * be incorporated into the next SCTP release.
  */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/random.h>
 #include <net/sctp/sctp.h>
@@ -107,6 +108,8 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
                        (unsigned long)peer);
        setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event,
                        (unsigned long)peer);
+       setup_timer(&peer->proto_unreach_timer,
+                   sctp_generate_proto_unreach_event, (unsigned long)peer);
 
        /* Initialize the 64-bit random nonce sent with heartbeat. */
        get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce));
@@ -170,6 +173,10 @@ void sctp_transport_free(struct sctp_transport *transport)
            del_timer(&transport->T3_rtx_timer))
                sctp_transport_put(transport);
 
+       /* Delete the ICMP proto unreachable timer if it's active. */
+       if (timer_pending(&transport->proto_unreach_timer) &&
+           del_timer(&transport->proto_unreach_timer))
+               sctp_association_put(transport->asoc);
 
        sctp_transport_put(transport);
 }
index 9bd64565021a91ed890e27313c7ce364f474c749..747d5412c463ee1492f37485bb7bf4e4181e1b4e 100644 (file)
@@ -42,6 +42,7 @@
  * be incorporated into the next SCTP release.
  */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/bitmap.h>
 #include <net/sctp/sctp.h>
index 8b3560fd876d2b95b361460b16fa3d92291a3160..aa72e89c3ee1685ad6d4096c76072daf80937f16 100644 (file)
@@ -43,6 +43,7 @@
  * be incorporated into the next SCTP release.
  */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/skbuff.h>
 #include <net/sctp/structs.h>
index 7b23803343cc66e39c6b6214d9b96ff2a0d4877a..3a448536f0b6b4c98d3ae2966c51f686ee068760 100644 (file)
@@ -41,6 +41,7 @@
  * be incorporated into the next SCTP release.
  */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
index 769c386bd4288758635acde6ca77c401a49c61a8..5e8d0af3c0e73b3537c1852eee2c15a917e4a605 100644 (file)
@@ -87,6 +87,7 @@
 #include <linux/wireless.h>
 #include <linux/nsproxy.h>
 #include <linux/magic.h>
+#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -2135,6 +2136,10 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
                        break;
                ++datagrams;
 
+               /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
+               if (flags & MSG_WAITFORONE)
+                       flags |= MSG_DONTWAIT;
+
                if (timeout) {
                        ktime_get_ts(timeout);
                        *timeout = timespec_sub(end_time, *timeout);
index f845d9d72f7307e3910fe39d0b32fbb95491114f..1419d0cdbbaccd494051caada325112320a657ec 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <net/ipv6.h>
 #include <linux/sunrpc/clnt.h>
+#include <linux/slab.h>
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 
index f394fc190a496f81125a467ec4723862da12c5f2..95afe79dd9d74ea14568f63a73a082ac31f9b887 100644 (file)
@@ -237,7 +237,7 @@ rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
        list_for_each_entry_safe(cred, next, &cred_unused, cr_lru) {
 
                /* Enforce a 60 second garbage collection moratorium */
-               if (time_in_range_open(cred->cr_expire, expired, jiffies) &&
+               if (time_in_range(cred->cr_expire, expired, jiffies) &&
                    test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0)
                        continue;
 
index bf88bf8e9365a0746eda3d0153135280b759bd3e..8f623b0f03dd3880bb57a96fce0b7951b572294c 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/sched.h>
index 0cfccc2a02979c4844c63dffbbdd47312a0139e6..c389ccf6437d5870868ec49f489b3f07f131ed46 100644 (file)
@@ -1280,9 +1280,8 @@ alloc_enc_pages(struct rpc_rqst *rqstp)
        rqstp->rq_release_snd_buf = priv_release_snd_buf;
        return 0;
 out_free:
-       for (i--; i >= 0; i--) {
-               __free_page(rqstp->rq_enc_pages[i]);
-       }
+       rqstp->rq_enc_pages_num = i;
+       priv_release_snd_buf(rqstp);
 out:
        return -EAGAIN;
 }
index c0ba39c4f5f220de70711e92e350c6aa64002e9a..310b78e994567e961984debbe99b0092b551cc94 100644 (file)
@@ -33,7 +33,6 @@
 
 #include <linux/types.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/sunrpc/sched.h>
 #include <linux/sunrpc/gss_asn1.h>
index c93fca204558cbca50b54fcc7cf7de6542a7b7be..e9b63617668763c6162df5152dc72b6f84c049f5 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/err.h>
 #include <linux/types.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/scatterlist.h>
 #include <linux/crypto.h>
 #include <linux/highmem.h>
index b8f42ef7178e89b4dc62b587888db4f1479788a4..88fe6e75ed7e4166ef8991a3e435a1a4553a956c 100644 (file)
@@ -59,7 +59,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/jiffies.h>
 #include <linux/sunrpc/gss_krb5.h>
 #include <linux/random.h>
index 17562b4c35f65e03ab7e7115ef8ce543c086b651..6331cd6866ec9f6ddb807153644b28a4bde19fc7 100644 (file)
@@ -32,7 +32,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/sunrpc/gss_krb5.h>
 #include <linux/crypto.h>
 
index 066ec73c84d682e2caa83ab4f44f61e5497a7649..ce6c247edad02d54f29a11a851fc677f269a4ec0 100644 (file)
@@ -58,7 +58,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/jiffies.h>
 #include <linux/sunrpc/gss_krb5.h>
 #include <linux/crypto.h>
index ae8e69b59c4c35c1eb23f2501174f3ba4d26b85e..a6e905637e035f54a3414321825ad97a2582b000 100644 (file)
@@ -1,5 +1,4 @@
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/jiffies.h>
 #include <linux/sunrpc/gss_krb5.h>
 #include <linux/random.h>
index c832712f8d55484c30144c2232730a3c60dc339b..5a3a65a0e2b4b41c7b0558b1b5a33807d5e53564 100644 (file)
@@ -34,7 +34,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/slab.h>
 #include <linux/jiffies.h>
 #include <linux/sunrpc/gss_spkm3.h>
 #include <linux/random.h>
index e34bc531fcb9c3d8754046df05aefe253f15542a..b81e790ef9f4197477c6eef889e1f315afd2c8a1 100644 (file)
@@ -37,6 +37,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/pagemap.h>
index 46b2647c5bd28bb253394e96c39823d401d6d473..aac2f8b4ee214290796bf76c97aae6051b4fed47 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
  */
 
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/module.h>
index 553621fb2c41f2063630b83fd74d03cd71d9b7ab..cf06af3b63c676068343b46941bc1dd59380440a 100644 (file)
@@ -22,6 +22,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ******************************************************************************/
 
 #include <linux/tcp.h>
+#include <linux/slab.h>
 #include <linux/sunrpc/xprt.h>
 
 #ifdef RPC_DEBUG
index 13f214f531208603a0e8f2b7cfe8ff0cfbc79bea..f0c05d3311c1a1ac3dca0d19ab701cd5e00a9559 100644 (file)
@@ -37,21 +37,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #define RPCDBG_FACILITY        RPCDBG_SVCDSP
 
-void bc_release_request(struct rpc_task *task)
-{
-       struct rpc_rqst *req = task->tk_rqstp;
-
-       dprintk("RPC:       bc_release_request: task= %p\n", task);
-
-       /*
-        * Release this request only if it's a backchannel
-        * preallocated request
-        */
-       if (!bc_prealloc(req))
-               return;
-       xprt_free_bc_request(req);
-}
-
 /* Empty callback ops */
 static const struct rpc_call_ops nfs41_callback_ops = {
 };
index 154034b675bd90de493d1438ff46a2b230178742..19c9983d53607483cce29654b8e589dca6da539d 100644 (file)
@@ -659,6 +659,7 @@ struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req,
        task = rpc_new_task(&task_setup_data);
        if (!task) {
                xprt_free_bc_request(req);
+               task = ERR_PTR(-ENOMEM);
                goto out;
        }
        task->tk_rqstp = req;
index 8d63f8fd29b7e3ff0e940d7457d45203f99c56b1..20e30c6f8355dc0bc612bffb44abefee7c3536df 100644 (file)
@@ -587,6 +587,8 @@ static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent,
        struct dentry *dentry;
 
        dentry = __rpc_lookup_create(parent, name);
+       if (IS_ERR(dentry))
+               return dentry;
        if (dentry->d_inode == NULL)
                return dentry;
        dput(dentry);
index 3e3772d8eb921ce00af629ad11627ad3677ea613..121105355f60e4a90dcb9906e878ea255499358d 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <net/ipv6.h>
 
 #include <linux/sunrpc/clnt.h>
index a661a3acb37e682dba442b98ec1c9729a75f7f5f..10b4319ebbca5816f02b4719f923852ea0301025 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/compiler.h>
 #include <linux/netdevice.h>
+#include <linux/gfp.h>
 #include <linux/skbuff.h>
 #include <linux/types.h>
 #include <linux/pagemap.h>
index 1b4e6791ecf3d3a036347150708fb0e345c26198..5785d2037f45ea72bd065c1b93a0f22e16ec5526 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include <linux/init.h>
 #include <linux/kernel.h>
index 8420a4205b76bc9278e247ee299d10314c68558a..d9017d64597e2beabb7f2edb9147018613d7c412 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/xdr.h>
index 8f0f1fb3dc5259419a1e823f522d9e5792538831..061b2e0f9118833bcc93facef2cb8bc40f655a01 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/errno.h>
 #include <linux/freezer.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <linux/sunrpc/stats.h>
 #include <linux/sunrpc/svc_xprt.h>
index afdcb0459a8319660443b0130dc000d65e0f5449..207311610988a3c3f29a2bf3ce2ea37320d237f1 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/seq_file.h>
 #include <linux/hash.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/ipv6.h>
 #include <linux/kernel.h>
index 8bd690c48b69d55862b49a35bd53ffa324a8061b..2763fde88499866084bf4782e597ce78d1086be4 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
index 469de292c23c34b8ba9a0f9ea24e07d4b77d5e09..42f09ade00445289c22a51f88550af7b7dadb85a 100644 (file)
@@ -46,6 +46,7 @@
 
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/metrics.h>
+#include <linux/sunrpc/bc_xprt.h>
 
 #include "sunrpc.h"
 
@@ -1032,21 +1033,16 @@ void xprt_release(struct rpc_task *task)
        if (req->rq_release_snd_buf)
                req->rq_release_snd_buf(req);
 
-       /*
-        * Early exit if this is a backchannel preallocated request.
-        * There is no need to have it added to the RPC slot list.
-        */
-       if (is_bc_request)
-               return;
-
-       memset(req, 0, sizeof(*req));   /* mark unused */
-
        dprintk("RPC: %5u release request %p\n", task->tk_pid, req);
+       if (likely(!is_bc_request)) {
+               memset(req, 0, sizeof(*req));   /* mark unused */
 
-       spin_lock(&xprt->reserve_lock);
-       list_add(&req->rq_list, &xprt->free);
-       rpc_wake_up_next(&xprt->backlog);
-       spin_unlock(&xprt->reserve_lock);
+               spin_lock(&xprt->reserve_lock);
+               list_add(&req->rq_list, &xprt->free);
+               rpc_wake_up_next(&xprt->backlog);
+               spin_unlock(&xprt->reserve_lock);
+       } else
+               xprt_free_bc_request(req);
 }
 
 /**
index 5b8a8ff93a2591b3b3b162a7e5ca60f7cdf89f94..d718b8fa95253c61d0e0adedd0bccf5cd84d89ed 100644 (file)
@@ -40,6 +40,7 @@
  */
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/sysctl.h>
 #include <linux/sunrpc/clnt.h>
index 3fa5751af0ecca4b03002d19a804f969b7011096..edea15a54e51d90d03b0149e6602f38017743758 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/sunrpc/debug.h>
 #include <linux/sunrpc/rpc_rdma.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <rdma/ib_verbs.h>
 #include <rdma/rdma_cm.h>
@@ -678,7 +679,10 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv,
        int ret;
 
        dprintk("svcrdma: Creating RDMA socket\n");
-
+       if (sa->sa_family != AF_INET) {
+               dprintk("svcrdma: Address family %d is not supported.\n", sa->sa_family);
+               return ERR_PTR(-EAFNOSUPPORT);
+       }
        cma_xprt = rdma_create_xprt(serv, 1);
        if (!cma_xprt)
                return ERR_PTR(-ENOMEM);
index f96c2fe6137b87f11d7155d96441600012c984a3..187257b1d88070d5adba6f03074c56b044cd0f37 100644 (file)
@@ -49,6 +49,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 
 #include "xprt_rdma.h"
index 2209aa87d899819152572e9ae87957d2b223d29d..27015c6d8eb58311ed88264e86313fc3879ad0c2 100644 (file)
@@ -48,6 +48,7 @@
  */
 
 #include <linux/pci.h> /* for Tavor hack below */
+#include <linux/slab.h>
 
 #include "xprt_rdma.h"
 
index 75ab08eac66b2166cc54c9e30237544b4c9a4a4d..9847c30b5001ce5d4e3cd9e1b5828e80cdd7ef24 100644 (file)
@@ -548,8 +548,6 @@ static int xs_udp_send_request(struct rpc_task *task)
                /* Still some bytes left; set up for a retry later. */
                status = -EAGAIN;
        }
-       if (!transport->sock)
-               goto out;
 
        switch (status) {
        case -ENOTSOCK:
@@ -569,7 +567,7 @@ static int xs_udp_send_request(struct rpc_task *task)
                 * prompts ECONNREFUSED. */
                clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
        }
-out:
+
        return status;
 }
 
@@ -651,8 +649,6 @@ static int xs_tcp_send_request(struct rpc_task *task)
                status = -EAGAIN;
                break;
        }
-       if (!transport->sock)
-               goto out;
 
        switch (status) {
        case -ENOTSOCK:
@@ -672,7 +668,7 @@ static int xs_tcp_send_request(struct rpc_task *task)
        case -ENOTCONN:
                clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
        }
-out:
+
        return status;
 }
 
@@ -2255,9 +2251,6 @@ static struct rpc_xprt_ops xs_tcp_ops = {
        .buf_free               = rpc_free,
        .send_request           = xs_tcp_send_request,
        .set_retrans_timeout    = xprt_set_retrans_timeout_def,
-#if defined(CONFIG_NFS_V4_1)
-       .release_request        = bc_release_request,
-#endif /* CONFIG_NFS_V4_1 */
        .close                  = xs_tcp_close,
        .destroy                = xs_destroy,
        .print_stats            = xs_tcp_print_stats,
index a881f92a8537c71531ca7eda1421c3766c7601db..c58a1d16563a6ab3bd9b51740a8520cef997bf45 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/netdevice.h>
 #include <linux/in.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 
 /*
index 524ba5696d4d6530c1cf7cea80832cb8158cfaa9..6230d16020c49917f5f28e06b514d379f698205d 100644 (file)
@@ -38,6 +38,7 @@
 #include <net/tipc/tipc_bearer.h>
 #include <net/tipc/tipc_msg.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 
 #define MAX_ETH_BEARERS                2
index 414fc34b8bea5550198a01036f68191f06d2f475..8dea66500cf5ce65d6427aad77152f437e0c92ac 100644 (file)
@@ -153,11 +153,11 @@ void tipc_ref_table_stop(void)
 
 u32 tipc_ref_acquire(void *object, spinlock_t **lock)
 {
-       struct reference *entry;
        u32 index;
        u32 index_mask;
        u32 next_plus_upper;
        u32 ref;
+       struct reference *entry = NULL;
 
        if (!object) {
                err("Attempt to acquire reference to non-existent object\n");
@@ -175,30 +175,36 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock)
                index = tipc_ref_table.first_free;
                entry = &(tipc_ref_table.entries[index]);
                index_mask = tipc_ref_table.index_mask;
-               /* take lock in case a previous user of entry still holds it */
-               spin_lock_bh(&entry->lock);
                next_plus_upper = entry->ref;
                tipc_ref_table.first_free = next_plus_upper & index_mask;
                ref = (next_plus_upper & ~index_mask) + index;
-               entry->ref = ref;
-               entry->object = object;
-               *lock = &entry->lock;
        }
        else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
                index = tipc_ref_table.init_point++;
                entry = &(tipc_ref_table.entries[index]);
                spin_lock_init(&entry->lock);
-               spin_lock_bh(&entry->lock);
                ref = tipc_ref_table.start_mask + index;
-               entry->ref = ref;
-               entry->object = object;
-               *lock = &entry->lock;
        }
        else {
                ref = 0;
        }
        write_unlock_bh(&ref_table_lock);
 
+       /*
+        * Grab the lock so no one else can modify this entry
+        * While we assign its ref value & object pointer
+        */
+       if (entry) {
+               spin_lock_bh(&entry->lock);
+               entry->ref = ref;
+               entry->object = object;
+               *lock = &entry->lock;
+               /*
+                * keep it locked, the caller is responsible
+                * for unlocking this when they're done with it
+                */
+       }
+
        return ref;
 }
 
index 4b235fc1c70ff7948c372a6c0d36e7ca9b5ad39a..cfb20b80b3a1758061d446e60fa92de17299559c 100644 (file)
@@ -40,9 +40,9 @@
 #include <linux/socket.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/poll.h>
 #include <linux/fcntl.h>
+#include <linux/gfp.h>
 #include <asm/string.h>
 #include <asm/atomic.h>
 #include <net/sock.h>
index 19c17e4a0c8b96d0468a7652661f8b5ff34b9b86..14c22c3768da8875955e72836830057eb5f7db13 100644 (file)
@@ -74,7 +74,6 @@
 #include <linux/un.h>
 #include <linux/net.h>
 #include <linux/fs.h>
-#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/file.h>
index d095c7be10d03bd1514e8fae584a3b31cc30d5ce..397cffebb3b655546043a540067ac81be99fa42c 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/sysctl.h>
 
 #include <net/af_unix.h>
index 7718657e93dcea7951abaeecaaeb3a91d484b734..d5b7c3779c431b66520d7584ac5a31faa34b765b 100644 (file)
@@ -72,6 +72,7 @@
  *   wimax_msg_send()
  */
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <net/genetlink.h>
 #include <linux/netdevice.h>
 #include <linux/wimax.h>
index 813e1eaea29bb2ef71b2e6b4292248837fcef93a..1ed65dbdab03df1bab0a008a7ca0277ce143bfdb 100644 (file)
@@ -51,6 +51,7 @@
  *   wimax_rfkill_rm()
  */
 #include <linux/device.h>
+#include <linux/gfp.h>
 #include <net/genetlink.h>
 #include <linux/netdevice.h>
 #include <linux/wimax.h>
index 7fdb9409ad2ab251cefe2699f3abbc6bb4c8bee5..6ac70c1015235448fe79ebd3b25664b5f47479e3 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/module.h>
 #include <linux/err.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/nl80211.h>
 #include <linux/debugfs.h>
 #include <linux/notifier.h>
index 2e4895615037c18a8b6360d17947e5c4a7096194..a4991a3efec0249ac5dea20424628388652072fa 100644 (file)
@@ -9,6 +9,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/slab.h>
 #include "core.h"
 #include "debugfs.h"
 
index 6ef5a491fb4b018b866ff22f19b6e717fb90d4f7..6a5acf7501740a1da95520f8f867cd2187b46c18 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 #include <net/cfg80211.h>
 #include "wext-compat.h"
 #include "nl80211.h"
index 62bc8855e1237db6b7d83f7a19c79e5c3976a0f7..22139fa4611598810ae0d4c4a462996aeaa61583 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/nl80211.h>
+#include <linux/slab.h>
 #include <linux/wireless.h>
 #include <net/cfg80211.h>
 #include <net/iw_handler.h>
index e447db04cf76dee4f178c3f8b98ac7c2be8393cb..030cf153bea252e28893e7d976f776faa355aa14 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/if.h>
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/if_ether.h>
 #include <linux/ieee80211.h>
index ed89c59bb431ab9c320c5f300123b501628f6c64..422da20d1e5b8a0bad63c8677b2631612905be9e 100644 (file)
@@ -33,6 +33,7 @@
  *
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/random.h>
 #include <linux/nl80211.h>
@@ -324,7 +325,7 @@ struct reg_regdb_search_request {
 };
 
 static LIST_HEAD(reg_regdb_search_list);
-static DEFINE_SPINLOCK(reg_regdb_search_lock);
+static DEFINE_MUTEX(reg_regdb_search_mutex);
 
 static void reg_regdb_search(struct work_struct *work)
 {
@@ -332,7 +333,7 @@ static void reg_regdb_search(struct work_struct *work)
        const struct ieee80211_regdomain *curdom, *regdom;
        int i, r;
 
-       spin_lock(&reg_regdb_search_lock);
+       mutex_lock(&reg_regdb_search_mutex);
        while (!list_empty(&reg_regdb_search_list)) {
                request = list_first_entry(&reg_regdb_search_list,
                                           struct reg_regdb_search_request,
@@ -346,18 +347,16 @@ static void reg_regdb_search(struct work_struct *work)
                                r = reg_copy_regd(&regdom, curdom);
                                if (r)
                                        break;
-                               spin_unlock(&reg_regdb_search_lock);
                                mutex_lock(&cfg80211_mutex);
                                set_regdom(regdom);
                                mutex_unlock(&cfg80211_mutex);
-                               spin_lock(&reg_regdb_search_lock);
                                break;
                        }
                }
 
                kfree(request);
        }
-       spin_unlock(&reg_regdb_search_lock);
+       mutex_unlock(&reg_regdb_search_mutex);
 }
 
 static DECLARE_WORK(reg_regdb_work, reg_regdb_search);
@@ -375,9 +374,9 @@ static void reg_regdb_query(const char *alpha2)
 
        memcpy(request->alpha2, alpha2, 2);
 
-       spin_lock(&reg_regdb_search_lock);
+       mutex_lock(&reg_regdb_search_mutex);
        list_add_tail(&request->list, &reg_regdb_search_list);
-       spin_unlock(&reg_regdb_search_lock);
+       mutex_unlock(&reg_regdb_search_mutex);
 
        schedule_work(&reg_regdb_work);
 }
index 978cac3414b558fd80bc41e3c87aa56510584beb..a026c6d56bd3347898cb1486301aedba37119b03 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
index 17fde0da1b08658db9882f000a51928dbd9ad339..f4dfd5f5f2ea429cb3a6e1d541f419813063ef45 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
index be2ab8c59e3a9806425b2b958d87dfe50d80111d..d3574a4eb3ba1ab837d564c819c50c328aaf2f7e 100644 (file)
@@ -5,6 +5,7 @@
  */
 #include <linux/bitops.h>
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <net/cfg80211.h>
 #include <net/ip.h>
 #include "core.h"
index 9ab51838849eee380faeceb52772aa128420fd02..a60a2773b49726b01fc86b58a74a432a8f54fc26 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/nl80211.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
+#include <linux/slab.h>
 #include <net/iw_handler.h>
 #include <net/cfg80211.h>
 #include "wext-compat.h"
index 5e1656bdf23b21779214088ca16b9efaa88d252c..4f5a47091fde623abc20e9ad8abfaea0fc224da3 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
+#include <linux/slab.h>
 #include <linux/wireless.h>
 #include <linux/uaccess.h>
 #include <net/cfg80211.h>
index a3c2277de9e5d6eb54397e74dd45fad789052fcc..3feb28e41c5347b85175f57daf223918620723b2 100644 (file)
@@ -7,6 +7,7 @@
  *
  * (As all part of the Linux kernel, this file is GPL)
  */
+#include <linux/slab.h>
 #include <linux/wireless.h>
 #include <linux/netdevice.h>
 #include <net/iw_handler.h>
index 5615a88025367f5beaee4e90e9040d5e4deb9f15..d5c6140f4cb8ee25b80da910b4884b351c0b87c5 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
+#include <linux/slab.h>
 #include <net/cfg80211.h>
 #include "wext-compat.h"
 #include "nl80211.h"
index 9796f3ed1edbc5dce941f449aa235276628a3d86..36e84e13c6aa9f6167d9b6ba2cf48b72829c2d58 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <net/tcp_states.h>
 #include <asm/uaccess.h>
@@ -82,6 +83,41 @@ struct compat_x25_subscrip_struct {
 };
 #endif
 
+
+int x25_parse_address_block(struct sk_buff *skb,
+               struct x25_address *called_addr,
+               struct x25_address *calling_addr)
+{
+       unsigned char len;
+       int needed;
+       int rc;
+
+       if (skb->len < 1) {
+               /* packet has no address block */
+               rc = 0;
+               goto empty;
+       }
+
+       len = *skb->data;
+       needed = 1 + (len >> 4) + (len & 0x0f);
+
+       if (skb->len < needed) {
+               /* packet is too short to hold the addresses it claims
+                  to hold */
+               rc = -1;
+               goto empty;
+       }
+
+       return x25_addr_ntoa(skb->data, called_addr, calling_addr);
+
+empty:
+       *called_addr->x25_addr = 0;
+       *calling_addr->x25_addr = 0;
+
+       return rc;
+}
+
+
 int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr,
                  struct x25_address *calling_addr)
 {
@@ -366,6 +402,7 @@ static void __x25_destroy_socket(struct sock *sk)
                        /*
                         * Queue the unaccepted socket for death
                         */
+                       skb->sk->sk_state = TCP_LISTEN;
                        sock_set_flag(skb->sk, SOCK_DEAD);
                        x25_start_heartbeat(skb->sk);
                        x25_sk(skb->sk)->state = X25_STATE_0;
@@ -553,7 +590,8 @@ static int x25_create(struct net *net, struct socket *sock, int protocol,
        x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE;
        x25->facilities.pacsize_in  = X25_DEFAULT_PACKET_SIZE;
        x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
-       x25->facilities.throughput  = X25_DEFAULT_THROUGHPUT;
+       x25->facilities.throughput  = 0;        /* by default don't negotiate
+                                                  throughput */
        x25->facilities.reverse     = X25_DEFAULT_REVERSE;
        x25->dte_facilities.calling_len = 0;
        x25->dte_facilities.called_len = 0;
@@ -921,16 +959,26 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
        /*
         *      Extract the X.25 addresses and convert them to ASCII strings,
         *      and remove them.
+        *
+        *      Address block is mandatory in call request packets
         */
-       addr_len = x25_addr_ntoa(skb->data, &source_addr, &dest_addr);
+       addr_len = x25_parse_address_block(skb, &source_addr, &dest_addr);
+       if (addr_len <= 0)
+               goto out_clear_request;
        skb_pull(skb, addr_len);
 
        /*
         *      Get the length of the facilities, skip past them for the moment
         *      get the call user data because this is needed to determine
         *      the correct listener
+        *
+        *      Facilities length is mandatory in call request packets
         */
+       if (skb->len < 1)
+               goto out_clear_request;
        len = skb->data[0] + 1;
+       if (skb->len < len)
+               goto out_clear_request;
        skb_pull(skb,len);
 
        /*
@@ -1414,9 +1462,20 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        if (facilities.winsize_in < 1 ||
                            facilities.winsize_in > 127)
                                break;
-                       if (facilities.throughput < 0x03 ||
-                           facilities.throughput > 0xDD)
-                               break;
+                       if (facilities.throughput) {
+                               int out = facilities.throughput & 0xf0;
+                               int in  = facilities.throughput & 0x0f;
+                               if (!out)
+                                       facilities.throughput |=
+                                               X25_DEFAULT_THROUGHPUT << 4;
+                               else if (out < 0x30 || out > 0xD0)
+                                       break;
+                               if (!in)
+                                       facilities.throughput |=
+                                               X25_DEFAULT_THROUGHPUT;
+                               else if (in < 0x03 || in > 0x0D)
+                                       break;
+                       }
                        if (facilities.reverse &&
                                (facilities.reverse & 0x81) != 0x81)
                                break;
index 52e304212241055b32bf382960308afd5fea8079..b9ef682230a0cbe675cf42367608ac88ee050a6f 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/sock.h>
 #include <linux/if_arp.h>
 #include <net/x25.h>
index a21f6646eb3a85cd1275708ba53960ed085402da..771bab00754b0baff1a5c7a95892028857c8b84d 100644 (file)
@@ -35,7 +35,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
                struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask)
 {
        unsigned char *p = skb->data;
-       unsigned int len = *p++;
+       unsigned int len;
 
        *vc_fac_mask = 0;
 
@@ -50,6 +50,14 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
        memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae));
        memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae));
 
+       if (skb->len < 1)
+               return 0;
+
+       len = *p++;
+
+       if (len >= skb->len)
+               return -1;
+
        while (len > 0) {
                switch (*p & X25_FAC_CLASS_MASK) {
                case X25_FAC_CLASS_A:
@@ -247,6 +255,8 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
        memcpy(new, ours, sizeof(*new));
 
        len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask);
+       if (len < 0)
+               return len;
 
        /*
         *      They want reverse charging, we won't accept it.
@@ -259,9 +269,18 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
        new->reverse = theirs.reverse;
 
        if (theirs.throughput) {
-               if (theirs.throughput < ours->throughput) {
-                       SOCK_DEBUG(sk, "X.25: throughput negotiated down\n");
-                       new->throughput = theirs.throughput;
+               int theirs_in =  theirs.throughput & 0x0f;
+               int theirs_out = theirs.throughput & 0xf0;
+               int ours_in  = ours->throughput & 0x0f;
+               int ours_out = ours->throughput & 0xf0;
+               if (!ours_in || theirs_in < ours_in) {
+                       SOCK_DEBUG(sk, "X.25: inbound throughput negotiated\n");
+                       new->throughput = (new->throughput & 0xf0) | theirs_in;
+               }
+               if (!ours_out || theirs_out < ours_out) {
+                       SOCK_DEBUG(sk,
+                               "X.25: outbound throughput negotiated\n");
+                       new->throughput = (new->throughput & 0x0f) | theirs_out;
                }
        }
 
index 056a55f3a8719f9bc6e7ff2336b16cc5e6994292..25a81079396863af36ac7e2eedb27c1d43c00b1d 100644 (file)
@@ -10,6 +10,7 @@
  */
 #include <linux/if_arp.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <net/x25.h>
 
 LIST_HEAD(x25_forward_list);
index 96d9227835479474e6cedaeef6704f619c1683e8..372ac226e648445057f82786e95a7ee64c11cd2d 100644 (file)
@@ -23,6 +23,7 @@
  *                                       i-frames.
  */
 
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -89,6 +90,7 @@ static int x25_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
 static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype)
 {
        struct x25_address source_addr, dest_addr;
+       int len;
 
        switch (frametype) {
                case X25_CALL_ACCEPTED: {
@@ -106,11 +108,17 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
                         *      Parse the data in the frame.
                         */
                        skb_pull(skb, X25_STD_MIN_LEN);
-                       skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr));
-                       skb_pull(skb,
-                                x25_parse_facilities(skb, &x25->facilities,
+
+                       len = x25_parse_address_block(skb, &source_addr,
+                                               &dest_addr);
+                       if (len > 0)
+                               skb_pull(skb, len);
+
+                       len = x25_parse_facilities(skb, &x25->facilities,
                                                &x25->dte_facilities,
-                                               &x25->vc_facil_mask));
+                                               &x25->vc_facil_mask);
+                       if (len > 0)
+                               skb_pull(skb, len);
                        /*
                         *      Copy any Call User Data.
                         */
index e4e1b6e495386c6cb1673a9e29143e1681bea6f6..73e7b954ad288229df4d03bc164f07da183444cc 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/jiffies.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <asm/uaccess.h>
index 2b96b52114d6235980325df17ef92f8adb6c8dfd..52351a26b6fc4b713f034e9b2d7a1990247ca419 100644 (file)
@@ -22,6 +22,7 @@
  *                                     needed cleaned seq-number fields.
  */
 
+#include <linux/slab.h>
 #include <linux/socket.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
index b95fae9ab393976e682b245b537e8b9b6251e2d5..97d77c532d8c95550711c915cb2b02d65d99828f 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/if_arp.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <net/x25.h>
 
 LIST_HEAD(x25_route_list);
index 352b32d216fc1ed2876fb51356f2af393fb19f8b..dc20cf12f39b59a16794ea49a3a11a01168c13d3 100644 (file)
@@ -23,6 +23,7 @@
  *                                             restriction on response.
  */
 
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/skbuff.h>
index 0fc5ff66d1faad83f205ac34884d882582d48260..fc91ad7ee26e7e8baa9b3f9f3b332425c55e5427 100644 (file)
 
 #include <linux/crypto.h>
 #include <linux/err.h>
-#include <linux/gfp.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/percpu.h>
+#include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/vmalloc.h>
 #include <net/ip.h>
index b9fe13138c070858980f8fa60334ca9b5990073f..6a329158bdfaa14de3891194e0c98ae70f4f1834 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/netdevice.h>
 #include <linux/netfilter.h>
 #include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <net/dst.h>
 #include <net/xfrm.h>
index 17d5b96f2fc8b6d8b7f290abbd67906526393a53..add77ecb8ac43cd85e6ebb1f57de839434dbb389 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/audit.h>
 #include <asm/uaccess.h>
 #include <linux/ktime.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 
index 2c4d6cdcba492cd2f70ac32a3e71b5b0abd17691..05640bc9594b7b5dc61b6e0dcd3b850e993af582 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/sysctl.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/xfrm.h>
 
index 3b126d1f8599198e6930ff7bd3c5690fb52ec138..d0c687fd9802220bd558303f54ccd683e77a3803 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kobject.h>
 #include <linux/string.h>
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
 
index f9bdf264473db421f4a720eaca0d4c5456e4d7e6..cbcd654215e68c2c0cc111737c94ae00074b9f3a 100644 (file)
@@ -245,3 +245,7 @@ quiet_cmd_lzo = LZO    $@
 cmd_lzo = (cat $(filter-out FORCE,$^) | \
        lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
        (rm -f $@ ; false)
+
+# misc stuff
+# ---------------------------------------------------------------------------
+quote:="
index f76f3d13276dd114c880e13ec45cad7452f992b9..6f97a13bcee4131aedbbf97a4f9db49c50e519e5 100755 (executable)
@@ -284,7 +284,7 @@ foreach my $file (@ARGV) {
        my $file_cnt = @files;
        my $lastfile;
 
-       open(my $patch, '<', $file)
+       open(my $patch, "< $file")
            or die "$P: Can't open $file: $!\n";
        while (<$patch>) {
            my $patch_line = $_;
index c7865c362d28fdbe160c94bfdd54e40bf34f8dd5..fcdfb245a5755d3bc534ac25d35728c214e8d03d 100755 (executable)
@@ -1424,6 +1424,8 @@ sub dump_struct($$) {
        $nested =~ s/\/\*.*?\*\///gos;
        # strip kmemcheck_bitfield_{begin,end}.*;
        $members =~ s/kmemcheck_bitfield_.*?;//gos;
+       # strip attributes
+       $members =~ s/__aligned\s*\(\d+\)//gos;
 
        create_parameterlist($members, ';', $file);
        check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested);
@@ -1728,6 +1730,7 @@ sub dump_function($$) {
     $prototype =~ s/^noinline +//;
     $prototype =~ s/__devinit +//;
     $prototype =~ s/__init +//;
+    $prototype =~ s/__init_or_module +//;
     $prototype =~ s/^#\s*define\s+//; #ak added
     $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//;
 
index 220213e603db4320e8c1ea88d8c557652085bfe5..df90f31d14bf3430aa6e56581cc47bb4f2b65bcf 100644 (file)
@@ -796,6 +796,16 @@ static int do_platform_entry(const char *filename,
        return 1;
 }
 
+/* Looks like: zorro:iN. */
+static int do_zorro_entry(const char *filename, struct zorro_device_id *id,
+                         char *alias)
+{
+       id->id = TO_NATIVE(id->id);
+       strcpy(alias, "zorro:");
+       ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id);
+       return 1;
+}
+
 /* Ignore any prefix, eg. some architectures prepend _ */
 static inline int sym_is(const char *symbol, const char *name)
 {
@@ -943,6 +953,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
                do_table(symval, sym->st_size,
                         sizeof(struct platform_device_id), "platform",
                         do_platform_entry, mod);
+       else if (sym_is(symname, "__mod_zorro_device_table"))
+               do_table(symval, sym->st_size,
+                        sizeof(struct zorro_device_id), "zorro",
+                        do_zorro_entry, mod);
        free(zeros);
 }
 
index 6cf8fd2b79e80df26e142aa94e6fed9d4c3e7015..f77c604239926d464fb2d309675a5e6771ed53a6 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/list.h>
 #include <linux/uaccess.h>
 #include <linux/seq_file.h>
+#include <linux/slab.h>
 #include <linux/rcupdate.h>
 #include <linux/mutex.h>
 
index c3a793881d04f0c578049f986ce98cb778d71895..1c812e874504ef90e1b8748e28d6d9e73d6a5912 100644 (file)
@@ -161,13 +161,13 @@ static int create_by_name(const char *name, mode_t mode,
 
        mutex_lock(&parent->d_inode->i_mutex);
        *dentry = lookup_one_len(name, parent, strlen(name));
-       if (!IS_ERR(dentry)) {
+       if (!IS_ERR(*dentry)) {
                if ((mode & S_IFMT) == S_IFDIR)
                        error = mkdir(parent->d_inode, *dentry, mode);
                else
                        error = create(parent->d_inode, *dentry, mode);
        } else
-               error = PTR_ERR(dentry);
+               error = PTR_ERR(*dentry);
        mutex_unlock(&parent->d_inode->i_mutex);
 
        return error;
index 2a5e0bcf38873f85188b75c75252e343cf2db12c..52015d098fdfd6d1823cf44ccfef1e754605884f 100644 (file)
@@ -13,6 +13,7 @@
  *     and store_template.
  */
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "ima.h"
 static const char *IMA_TEMPLATE_NAME = "ima";
index ff513ff737f5c62861ff20e181567c195d126357..5af76340470c387401889530298c619ddcb0ec6c 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/gfp.h>
 #include <linux/audit.h>
 #include "ima.h"
 
index 46642a19bc78928759aaf753429c10c07e1bcb54..952e51373f5810ac43aef5615c0e6ee166e4eb04 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/crypto.h>
 #include <linux/scatterlist.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include "ima.h"
 
 static int init_desc(struct hash_desc *desc)
index 0c72c9c38956f1ac949f049db87fc17a3d8eed39..07cb9c338cc43a27c794efab3a565415901539c8 100644 (file)
@@ -16,6 +16,7 @@
  *     current measurement list and IMA statistics
  */
 #include <linux/fcntl.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/seq_file.h>
 #include <linux/rculist.h>
index 2d4d05d92fdacf01048ac9857541e8d17a3f0855..2c744d4880148605b13f5a9f5ed8a5d300581afc 100644 (file)
@@ -14,6 +14,7 @@
  *     - cache integrity information associated with an inode
  *       using a radix tree.
  */
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/radix-tree.h>
index a40da7ae590021933bbb2d5982fc7a61494947ff..b1bcb702a27c7a6db1a5360fafee0bedc5bda5a1 100644 (file)
@@ -16,6 +16,7 @@
  */
 #include <linux/module.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include "ima.h"
 
index 294b005d65206edb7219989c033c4bbe34eb3cbd..b2c89d9de2a475b790dbc1b804deca430714813a 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/binfmts.h>
 #include <linux/mount.h>
 #include <linux/mman.h>
+#include <linux/slab.h>
 
 #include "ima.h"
 
index 4759d0f99335c5d8e06d44fa4993f4b65f061bb8..8643a93c5963b174853140ef9e90d23e145141cc 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/security.h>
 #include <linux/magic.h>
 #include <linux/parser.h>
+#include <linux/slab.h>
 
 #include "ima.h"
 
index a0880e9c8e054695c757818b7991b2c37daf38ab..46ba62b1adf5813f341a317f4fbd982392076ac5 100644 (file)
@@ -20,6 +20,7 @@
  */
 #include <linux/module.h>
 #include <linux/rculist.h>
+#include <linux/slab.h>
 #include "ima.h"
 
 LIST_HEAD(ima_measurements);   /* list of all measurements */
index 19902319d097acc75ef6246d6981e33b43a8c69f..a46e825cbf0265311288115453ee25227baa28e4 100644 (file)
@@ -77,10 +77,10 @@ static bool key_gc_keyring(struct key *keyring, time_t limit)
                goto dont_gc;
 
        /* scan the keyring looking for dead keys */
-       klist = rcu_dereference_check(keyring->payload.subscriptions,
-                                     lockdep_is_held(&key_serial_lock));
+       rcu_read_lock();
+       klist = rcu_dereference(keyring->payload.subscriptions);
        if (!klist)
-               goto dont_gc;
+               goto unlock_dont_gc;
 
        for (loop = klist->nkeys - 1; loop >= 0; loop--) {
                key = klist->keys[loop];
@@ -89,11 +89,14 @@ static bool key_gc_keyring(struct key *keyring, time_t limit)
                        goto do_gc;
        }
 
+unlock_dont_gc:
+       rcu_read_unlock();
 dont_gc:
        kleave(" = false");
        return false;
 
 do_gc:
+       rcu_read_unlock();
        key_gc_cursor = keyring->serial;
        key_get(keyring);
        spin_unlock(&key_serial_lock);
index e814d2109f8ef170ea60043fa83b1f37c3e35de1..1e4b0037935c8ff56434e70d5786b02e6e7be33d 100644 (file)
 #include <asm/uaccess.h>
 #include "internal.h"
 
+#define rcu_dereference_locked_keyring(keyring)                                \
+       (rcu_dereference_protected(                                     \
+               (keyring)->payload.subscriptions,                       \
+               rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem)))
+
 /*
  * when plumbing the depths of the key tree, this sets a hard limit set on how
  * deep we're willing to go
@@ -201,8 +206,7 @@ static long keyring_read(const struct key *keyring,
        int loop, ret;
 
        ret = 0;
-       klist = rcu_dereference(keyring->payload.subscriptions);
-
+       klist = rcu_dereference_locked_keyring(keyring);
        if (klist) {
                /* calculate how much data we could return */
                qty = klist->nkeys * sizeof(key_serial_t);
@@ -526,9 +530,8 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
        struct key *keyring;
        int bucket;
 
-       keyring = ERR_PTR(-EINVAL);
        if (!name)
-               goto error;
+               return ERR_PTR(-EINVAL);
 
        bucket = keyring_hash(name);
 
@@ -555,17 +558,18 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
                                           KEY_SEARCH) < 0)
                                continue;
 
-                       /* we've got a match */
-                       atomic_inc(&keyring->usage);
-                       read_unlock(&keyring_name_lock);
-                       goto error;
+                       /* we've got a match but we might end up racing with
+                        * key_cleanup() if the keyring is currently 'dead'
+                        * (ie. it has a zero usage count) */
+                       if (!atomic_inc_not_zero(&keyring->usage))
+                               continue;
+                       goto out;
                }
        }
 
-       read_unlock(&keyring_name_lock);
        keyring = ERR_PTR(-ENOKEY);
-
- error:
+out:
+       read_unlock(&keyring_name_lock);
        return keyring;
 
 } /* end find_keyring_by_name() */
@@ -720,8 +724,7 @@ int __key_link(struct key *keyring, struct key *key)
        }
 
        /* see if there's a matching key we can displace */
-       klist = keyring->payload.subscriptions;
-
+       klist = rcu_dereference_locked_keyring(keyring);
        if (klist && klist->nkeys > 0) {
                struct key_type *type = key->type;
 
@@ -765,8 +768,6 @@ int __key_link(struct key *keyring, struct key *key)
        if (ret < 0)
                goto error2;
 
-       klist = keyring->payload.subscriptions;
-
        if (klist && klist->nkeys < klist->maxkeys) {
                /* there's sufficient slack space to add directly */
                atomic_inc(&key->usage);
@@ -868,7 +869,7 @@ int key_unlink(struct key *keyring, struct key *key)
 
        down_write(&keyring->sem);
 
-       klist = keyring->payload.subscriptions;
+       klist = rcu_dereference_locked_keyring(keyring);
        if (klist) {
                /* search the keyring for the key */
                for (loop = 0; loop < klist->nkeys; loop++)
@@ -959,7 +960,7 @@ int keyring_clear(struct key *keyring)
                /* detach the pointer block with the locks held */
                down_write(&keyring->sem);
 
-               klist = keyring->payload.subscriptions;
+               klist = rcu_dereference_locked_keyring(keyring);
                if (klist) {
                        /* adjust the quota */
                        key_payload_reserve(keyring,
@@ -991,7 +992,9 @@ EXPORT_SYMBOL(keyring_clear);
  */
 static void keyring_revoke(struct key *keyring)
 {
-       struct keyring_list *klist = keyring->payload.subscriptions;
+       struct keyring_list *klist;
+
+       klist = rcu_dereference_locked_keyring(keyring);
 
        /* adjust the quota */
        key_payload_reserve(keyring, 0);
@@ -1025,7 +1028,7 @@ void keyring_gc(struct key *keyring, time_t limit)
 
        down_write(&keyring->sem);
 
-       klist = keyring->payload.subscriptions;
+       klist = rcu_dereference_locked_keyring(keyring);
        if (!klist)
                goto no_klist;
 
index 9d01021ca0c8cdd9c25c8292daff990204ecf466..706d63f4f1855c89ed2df4d369d98cf3bb0a722c 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
index 5c23afb31ece464ad0165e1a3fb052a8969244c5..06c2ccf26ed3e36158b1e594192e9e06b376617d 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/keyctl.h>
 #include <linux/fs.h>
 #include <linux/err.h>
index 03fe63ed55bda1a1cfacc95138e409e8ef53f0d2..d8c1a6a0fb08e7e86a24be12c64ff6ee13f0a266 100644 (file)
@@ -68,7 +68,8 @@ static int call_sbin_request_key(struct key_construction *cons,
 {
        const struct cred *cred = current_cred();
        key_serial_t prkey, sskey;
-       struct key *key = cons->key, *authkey = cons->authkey, *keyring;
+       struct key *key = cons->key, *authkey = cons->authkey, *keyring,
+               *session;
        char *argv[9], *envp[3], uid_str[12], gid_str[12];
        char key_str[12], keyring_str[3][12];
        char desc[20];
@@ -93,7 +94,7 @@ static int call_sbin_request_key(struct key_construction *cons,
        }
 
        /* attach the auth key to the session keyring */
-       ret = __key_link(keyring, authkey);
+       ret = key_link(keyring, authkey);
        if (ret < 0)
                goto error_link;
 
@@ -112,10 +113,12 @@ static int call_sbin_request_key(struct key_construction *cons,
        if (cred->tgcred->process_keyring)
                prkey = cred->tgcred->process_keyring->serial;
 
-       if (cred->tgcred->session_keyring)
-               sskey = rcu_dereference(cred->tgcred->session_keyring)->serial;
-       else
-               sskey = cred->user->session_keyring->serial;
+       rcu_read_lock();
+       session = rcu_dereference(cred->tgcred->session_keyring);
+       if (!session)
+               session = cred->user->session_keyring;
+       sskey = session->serial;
+       rcu_read_unlock();
 
        sprintf(keyring_str[2], "%d", sskey);
 
@@ -336,8 +339,10 @@ static int construct_alloc_key(struct key_type *type,
 
 key_already_present:
        mutex_unlock(&key_construction_mutex);
-       if (dest_keyring)
+       if (dest_keyring) {
+               __key_link(dest_keyring, key_ref_to_ptr(key_ref));
                up_write(&dest_keyring->sem);
+       }
        mutex_unlock(&user->cons_lock);
        key_put(key);
        *_key = key = key_ref_to_ptr(key_ref);
@@ -428,6 +433,11 @@ struct key *request_key_and_link(struct key_type *type,
 
        if (!IS_ERR(key_ref)) {
                key = key_ref_to_ptr(key_ref);
+               if (dest_keyring) {
+                       construct_get_dest_keyring(&dest_keyring);
+                       key_link(dest_keyring, key);
+                       key_put(dest_keyring);
+               }
        } else if (PTR_ERR(key_ref) != -EAGAIN) {
                key = ERR_CAST(key_ref);
        } else  {
index 7c687d568221cd71a3e863b9c9c50f5cd9352005..e9aa079296561507835e0e349a55f07b11bec5bb 100644 (file)
@@ -199,7 +199,8 @@ long user_read(const struct key *key, char __user *buffer, size_t buflen)
        struct user_key_payload *upayload;
        long ret;
 
-       upayload = rcu_dereference(key->payload.data);
+       upayload = rcu_dereference_protected(
+               key->payload.data, rwsem_is_locked(&((struct key *)key)->sem));
        ret = upayload->datalen;
 
        /* we can return the data as is */
index acba3dfc8d297dfcd7a787839dac3cfff11663c6..893365b79a292dac685f344100460d057265be86 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/stddef.h>
 #include <linux/kernel.h>
+#include <linux/gfp.h>
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <net/sock.h>
index e86f297522bfb9ea91de0ad929034bcccd59d57f..f728728f193bdc0b1a3d578c0f1fa69b016dfabb 100644 (file)
@@ -33,7 +33,7 @@ int mmap_min_addr_handler(struct ctl_table *table, int write,
 {
        int ret;
 
-       if (!capable(CAP_SYS_RAWIO))
+       if (write && !capable(CAP_SYS_RAWIO))
                return -EPERM;
 
        ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
index b4e14bc0bf32bf6d0a9ae948d697912ca11e8769..d6095d63d831a63999f1921fbed460a94140fc39 100644 (file)
@@ -16,6 +16,7 @@
  */
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
index 2534400317c5554dff0fcc2b4bb68be3f61dc9fd..628da72ee76353f347e55b22c1162b0b2cda0441 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <linux/spinlock.h>
 #include <linux/rcupdate.h>
+#include <linux/gfp.h>
 #include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <net/sock.h>
index 1ae556446e65a745f9caf670ea591f1ea3613ea5..0e147b6914ad1c9d1f7bb66967e8cabc39f2f94c 100644 (file)
@@ -11,6 +11,7 @@
  */
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
index 7100072bb1b0c88f56f4b9e50a48fa675338e297..dc92792271f1d8e59e01e9f4e9000d4f0090b2c0 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/types.h>
 #include <linux/rcupdate.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/in.h>
 #include <linux/in6.h>
index fe7fba67f19f0dd2c0b2c96c5a736ecb15bd362d..cfe2d72d3fb76b0f36a61471244dc1c8ec84b729 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/types.h>
 #include <linux/rcupdate.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/in.h>
 #include <linux/in6.h>
index 8da6a842808623f2ffe6f0244aaba80d9d4df111..cd4f734e27499cf2f9e203f0edb2557cf02bc24c 100644 (file)
@@ -82,7 +82,7 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified
 void avtab_cache_init(void);
 void avtab_cache_destroy(void);
 
-#define MAX_AVTAB_HASH_BITS 13
+#define MAX_AVTAB_HASH_BITS 11
 #define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
 #define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1)
 #define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS
index 837658a98a5418080d9e7264c450e780ee939b7c..bcf9f620426e04dfd102895bcf89b7f5d6b761bc 100644 (file)
@@ -4,7 +4,6 @@
  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
  */
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include "symtab.h"
index f3cb9ed731a9d927319c37bfc3a2e0d63f330db9..fff78d3b51a2ecddd1f18dd959ad99c80c090742 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv6.h>
+#include <linux/slab.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/skbuff.h>
index 0f9ac81469001d30d91a05af27974b116823d330..f4fac64c4da8b153aef2d4cb817d31348bab4110 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include "smack.h"
index 5225e668dbf046fbe17ea105b23eb18cd11590d4..fdfeaa2f28ec641bc5b86f24c765d6ff49d2d702 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
+#include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/pipe_fs_i.h>
 #include <net/netlabel.h>
index aeead7585093a301c20826b9f316776fc295f4ce..a2b72d77f9265f7553c4bffb225644baf4bd44d0 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/vmalloc.h>
 #include <linux/security.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 #include <net/netlabel.h>
 #include <net/cipso_ipv4.h>
index ef89947a774bbf419aadc0ba6b942985b75b5b50..975c45d88baad581d77dbc88be9048854c44ad83 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 #include <linux/security.h>
 #include <linux/hardirq.h>
 #include "common.h"
index 66caaa1b842a2a7e102313a2dcc199bd69debec2..acb8c397d5cfc93909087fbb2354aa4b7dc7f328 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "common.h"
 #include <linux/binfmts.h>
+#include <linux/slab.h>
 
 /* Variables definitions.*/
 
index 1b24304edb7de3135a2febcd0b15f35d66582dd9..6f3fe76a1fde6aabdd84a7998258e6b9e539aaa0 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include "common.h"
+#include <linux/slab.h>
 
 /* Keyword array for single path operations. */
 static const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = {
index 9645525ccdd45cdc50ef9d915dd27642aa4a233f..d9ad35bc7fa823b7d2078cfa76ba6d7fa6736fb9 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "common.h"
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 enum tomoyo_gc_id {
        TOMOYO_ID_DOMAIN_INITIALIZER,
index cf7d61f781b9768cc8691cd3b4fc4c234a313b55..c225c65ce426a682b587b9e0b96b25cfa4e09cf8 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/fs_struct.h>
 #include <linux/hash.h>
 #include <linux/magic.h>
+#include <linux/slab.h>
 #include "common.h"
 
 /**
index 84bb07d39a7fc29766fb1d0d019e0d08e392e664..91852e49910e24d9bee395e7dea36277edd08922 100644 (file)
@@ -33,6 +33,7 @@
  */
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa");
index 1dd66ddffcaf6b97cf46ef2fe2f055a7ca317d37..fd2188c3df2b4c436c9a6112cbc577c309d2898e 100644 (file)
@@ -66,6 +66,7 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
 MODULE_LICENSE("GPL");
index f13827e17562959d178d92edd76db44e545b84bc..69d2cb601f2a4daa7d32d6abda14c5095b56de01 100644 (file)
@@ -11,6 +11,7 @@
  */
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("toonie codec driver for snd-aoa");
index 1dd0c28d1fb72c6bfb85858afc1f665917b94f86..6776d1c12b63a30fafa4b16b52ddc638c1e0dcb2 100644 (file)
@@ -6,6 +6,7 @@
  * GPL v2, can be found in COPYING.
  */
 
+#include <linux/slab.h>
 #include <asm/pmac_feature.h>
 #include <asm/pmac_pfunc.h>
 #include "../aoa.h"
index 7a437da056465dc189619231d63dc1d0b6fb79dc..1cd9b301df0357dd7802626c93731d22c5efc73b 100644 (file)
@@ -12,6 +12,7 @@
 #include <asm/prom.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include "../aoa.h"
 #include "../soundbus/soundbus.h"
 
index 87beb4ad4d63a3b7f2521b8820941a6a44631c91..47f854c2001facf5f19f2df68686007972bb7d3f 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/prom.h>
index 4e3b819d49930f07b7ce641c1de0a32b878f8bcd..9d6f3b176ed1ac73f20c4e8427403a9970ca0156 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
index 59bacd365733f869513df9cdb81797ad7389cfba..be838993926d74d0f1682ffdeda183ac8e8acd6e 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <asm/io.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <asm/macio.h>
 #include <linux/pci.h>
index 656e474dca47f1a20d0ed473ebdfc1e8eb0c1a7f..91acc9a243ec47dec8aabb6a67bcdd9b4f4aa671 100644 (file)
@@ -863,7 +863,6 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci)
        struct snd_ac97 *ac97;
        int ret;
 
-       writel(0, aaci->base + AC97_POWERDOWN);
        /*
         * Assert AACIRESET for 2us
         */
@@ -1047,7 +1046,11 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id)
 
        writel(0x1fff, aaci->base + AACI_INTCLR);
        writel(aaci->maincr, aaci->base + AACI_MAINCR);
-
+       /*
+        * Fix: ac97 read back fail errors by reading
+        * from any arbitrary aaci register.
+        */
+       readl(aaci->base + AACI_CSCH1);
        ret = aaci_probe_ac97(aaci);
        if (ret)
                goto out;
index 743ac6a2906598fdbd70a04f6a3c6910fd86fdfe..8808b82311b1eb207a2fb3306548666ad6dd6a8b 100644 (file)
@@ -4,6 +4,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/dma-mapping.h>
 
@@ -205,6 +206,7 @@ int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
        if (!rtd->dma_desc_array)
                goto err1;
 
+       rtd->dma_ch = -1;
        runtime->private_data = rtd;
        return 0;
 
index 368dc9c4aef8d905eff9eb4fb780abedf53fca04..426874429a5e088cf50414f6ab1f76dd7f8d1fd2 100644 (file)
@@ -21,6 +21,7 @@
 /* this file included from control.c */
 
 #include <linux/compat.h>
+#include <linux/slab.h>
 
 struct snd_ctl_elem_list32 {
        u32 offset;
index 7f4d744ae40ae7ce8102e1c6439fc306a5abb174..7730575bfadd93bc12d6d441c63098aa1238477d 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/hrtimer.h>
index d749a0d394a7fb5d2327e4e659dc42d194edd9b5..cc4a53d4b7f87155386697318d037671e75dab55 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/time.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <sound/core.h>
index f705eec7372a32aad6187651cc393c69c2ce7e78..14b8a4ee690dfb4b5b8df9c5159f396c1677a171 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/input.h>
+#include <linux/slab.h>
 #include <sound/jack.h>
 #include <sound/core.h>
 
index 3da4f92427d8acc129bfba67d2ca29ea0fe56fb1..2c41825c836ec028c4725c2e038eb3937723c543 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/init.h>
 #include <linux/time.h>
+#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <sound/core.h>
 
index 0dcc2870d537752c98de1014df65330f051e9dfe..bbe25d8c450ad5e9e3d653b94215fc050fab521c 100644 (file)
@@ -19,7 +19,6 @@
  *
  */
 
-#include <linux/slab.h>
 #include <linux/time.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
index 08bfed594a83bfcf323472edbde17003f6fdeb28..5fb2e28e796f6a2766146dbdc5234a1de9a71680 100644 (file)
@@ -21,6 +21,7 @@
 /* This file included from pcm_native.c */
 
 #include <linux/compat.h>
+#include <linux/slab.h>
 
 static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream,
                                      s32 __user *src)
index b546ac2660f9f64b8436e3efe836cfa0f298afee..a2ff86189d2a583ad208c8e61beed816d3f23a67 100644 (file)
@@ -148,6 +148,9 @@ static void pcm_debug_name(struct snd_pcm_substream *substream,
 
 #define xrun_debug(substream, mask) \
                        ((substream)->pstr->xrun_debug & (mask))
+#else
+#define xrun_debug(substream, mask)    0
+#endif
 
 #define dump_stack_on_xrun(substream) do {                     \
                if (xrun_debug(substream, XRUN_DEBUG_STACK))    \
@@ -169,6 +172,7 @@ static void xrun(struct snd_pcm_substream *substream)
        }
 }
 
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
 #define hw_ptr_error(substream, fmt, args...)                          \
        do {                                                            \
                if (xrun_debug(substream, XRUN_DEBUG_BASIC)) {          \
@@ -255,8 +259,6 @@ static void xrun_log_show(struct snd_pcm_substream *substream)
 
 #else /* ! CONFIG_SND_PCM_XRUN_DEBUG */
 
-#define xrun_debug(substream, mask)    0
-#define xrun(substream)                        do { } while (0)
 #define hw_ptr_error(substream, fmt, args...) do { } while (0)
 #define xrun_log(substream, pos)       do { } while (0)
 #define xrun_log_show(substream)       do { } while (0)
index d6d49d6651f9122a389572db10d4f2ff078bbec2..917e4055ee30fdc37d6726e8af2f8d4d07506410 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/io.h>
 #include <linux/time.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/vmalloc.h>
 #include <sound/core.h>
index 87288762403055a3f6f842c70b9e99794956a1cd..20b5982c996b9a2aeef8ad200f62fe79cca41767 100644 (file)
@@ -36,6 +36,9 @@
 #include <sound/timer.h>
 #include <sound/minors.h>
 #include <asm/io.h>
+#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
+#include <dma-coherence.h>
+#endif
 
 /*
  *  Compatibility
@@ -3184,6 +3187,10 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
                                         substream->runtime->dma_area,
                                         substream->runtime->dma_addr,
                                         area->vm_end - area->vm_start);
+#elif defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
+       if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV &&
+           !plat_device_is_coherent(substream->dma_buffer.dev.dev))
+               area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
 #endif /* ARCH_HAS_DMA_MMAP_COHERENT */
        /* mmap with fault handler */
        area->vm_ops = &snd_pcm_vm_ops_data_fault;
index d0d721c22eacca6d4379dab12f9fc4dd57238eaa..685712276ac95ab0d57985489b86f4f840bcf9b1 100644 (file)
@@ -29,6 +29,7 @@
 #include "seq_oss_event.h"
 #include <linux/init.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 
 /*
  * common variables
index 9dfb2f77be608368ff897c948742dbf806fa52cd..677dc84590c79ae49dca0fb569fe4c98a44c068c 100644 (file)
@@ -28,6 +28,7 @@
 #include <sound/seq_midi_event.h>
 #include "../seq_lock.h"
 #include <linux/init.h>
+#include <linux/slab.h>
 
 
 /*
index f5de79f29f1e1a2aae91ede5d1bec3a65675fbdd..73661c4ab82aabefc2f26382db55854c704c8534 100644 (file)
@@ -25,6 +25,7 @@
 #include <sound/seq_oss_legacy.h>
 #include "../seq_lock.h"
 #include <linux/wait.h>
+#include <linux/slab.h>
 
 /*
  * constants
index 945a27c34a9d1b2e5a9ed993930c26357fca2c60..ee44ab9593c01819cc5f7fd0278801ca2cab0343 100644 (file)
@@ -24,6 +24,7 @@
 #include "seq_oss_midi.h"
 #include "../seq_lock.h"
 #include <linux/init.h>
+#include <linux/slab.h>
 
 /*
  * constants
index c440fdacec93dc752caff10a0c312f343e0e98b2..ab59cbfbcaf20b4263faebb55d092ef93c2a4923 100644 (file)
@@ -23,6 +23,7 @@
 #include "seq_oss_timer.h"
 #include "seq_oss_event.h"
 #include <sound/seq_oss_legacy.h>
+#include <linux/slab.h>
 
 /*
  */
index 217424858191e63bcd16b49e0f4d98c34192e6f5..d50338bbc21f1dbc2637ae9b2938716679b919c9 100644 (file)
@@ -27,6 +27,7 @@
 #include "../seq_lock.h"
 #include "../seq_clientmgr.h"
 #include <linux/wait.h>
+#include <linux/slab.h>
 
 
 /*
index c956fe462569238e1a396e69a86f73eb65200d45..81f7c109dc46e1b8ef9b4a2a67477fdf72940ef6 100644 (file)
@@ -21,6 +21,7 @@
 /* This file included from seq.c */
 
 #include <linux/compat.h>
+#include <linux/slab.h>
 
 struct snd_seq_port_info32 {
        struct snd_seq_addr addr;       /* client/port numbers */
index 77884e62b6483216981c0d2a9da553ac86b9f138..c38b90cf3cb07ac6c74514cfa807590dd6c92bcf 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include "seq_system.h"
 #include "seq_timer.h"
index 73943651caed9e4376f8694ffa90835cd1d9832e..5040c7b862fe6f571fb9a231e00819758ca2a632 100644 (file)
@@ -1160,6 +1160,7 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
 {
        struct snd_timer_user *tu = timeri->callback_data;
        struct snd_timer_tread r1;
+       unsigned long flags;
 
        if (event >= SNDRV_TIMER_EVENT_START &&
            event <= SNDRV_TIMER_EVENT_PAUSE)
@@ -1169,9 +1170,9 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
        r1.event = event;
        r1.tstamp = *tstamp;
        r1.val = resolution;
-       spin_lock(&tu->qlock);
+       spin_lock_irqsave(&tu->qlock, flags);
        snd_timer_user_append_to_tqueue(tu, &r1);
-       spin_unlock(&tu->qlock);
+       spin_unlock_irqrestore(&tu->qlock, flags);
        kill_fasync(&tu->fasync, SIGIO, POLL_IN);
        wake_up(&tu->qchange_sleep);
 }
index 1950ffce2b545cdff262daae280128134259fa20..a1282c1c059130f0cae4c48473e9376c11227d11 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/platform_device.h>
 
 #include <linux/ioport.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/interrupt.h>
 
index 2f8f295d6b0cc731885c82d6907172a1a577788d..da03597fc893d0393869415f607f6ddbcaad31cb 100644 (file)
@@ -54,7 +54,6 @@
 #include <linux/interrupt.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
index 9284829bf9275e9c2afabbbe8e2026c35c2dfb60..8539ab0a0893db2933e39732f7073be3d2c1f166 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/parport.h>
 #include <linux/spinlock.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/rawmidi.h>
index a54b1dc5cc7859f7b10316aed9fce1af5b9c391f..ade3ca52422ef81ca639698c739dee6863185670 100644 (file)
@@ -19,7 +19,6 @@
  */
 
 #include "opl3_voice.h"
-#include <linux/slab.h>
 
 static int snd_opl3_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure);
 static int snd_opl3_close_seq_oss(struct snd_seq_oss_arg *arg);
index 6d57b6441dec53312de691a6caeb835ae2ef607d..301acb6b9cf9af792ddc33160989dcb8dbcc8769 100644 (file)
@@ -19,6 +19,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <sound/opl3.h>
 #include <sound/asound_fm.h>
 
index 01997f24c895708f19a4851061b42bce57c88b1d..f07e38da59b852748d31e3dfaf91140e943d57d6 100644 (file)
@@ -20,6 +20,7 @@
 #include "opl4_local.h"
 #include <sound/initval.h>
 #include <linux/ioport.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <asm/io.h>
 
index 1e123077923d79edc59a98524c00e0516bd91b98..4ff6c8cc5077e9fb35d092984986154c31984b54 100644 (file)
@@ -16,7 +16,7 @@
 #include <asm/i8253.h>
 #else
 #include <asm/8253pit.h>
-static DEFINE_SPINLOCK(i8253_lock);
+static DEFINE_RAW_SPINLOCK(i8253_lock);
 #endif
 
 #define PCSP_SOUND_VERSION 0x400       /* read 4.00 */
index 0444cdeb4becd93a35f8fe20ad6699e2c0a8e9f7..b5e2b54c2604ecb398e5fcaae6c5a873a2dc1cad 100644 (file)
@@ -21,7 +21,7 @@ static void pcspkr_do_sound(unsigned int count)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&i8253_lock, flags);
+       raw_spin_lock_irqsave(&i8253_lock, flags);
 
        if (count) {
                /* set command for counter 2, 2 byte write */
@@ -36,7 +36,7 @@ static void pcspkr_do_sound(unsigned int count)
                outb(inb_p(0x61) & 0xFC, 0x61);
        }
 
-       spin_unlock_irqrestore(&i8253_lock, flags);
+       raw_spin_unlock_irqrestore(&i8253_lock, flags);
 }
 
 void pcspkr_stop_sound(void)
index e1145ac6e9086d15ee14179b4b53493bec21ad91..ce9e7d170c0dc09b6f1274ff9e91cd7ab5ea2826 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/moduleparam.h>
 #include <linux/interrupt.h>
 #include <sound/pcm.h>
@@ -65,7 +66,7 @@ static u64 pcsp_timer_update(struct snd_pcsp *chip)
        timer_cnt = val * CUR_DIV() / 256;
 
        if (timer_cnt && chip->enable) {
-               spin_lock_irqsave(&i8253_lock, flags);
+               raw_spin_lock_irqsave(&i8253_lock, flags);
                if (!nforce_wa) {
                        outb_p(chip->val61, 0x61);
                        outb_p(timer_cnt, 0x42);
@@ -74,7 +75,7 @@ static u64 pcsp_timer_update(struct snd_pcsp *chip)
                        outb(chip->val61 ^ 2, 0x61);
                        chip->thalf = 1;
                }
-               spin_unlock_irqrestore(&i8253_lock, flags);
+               raw_spin_unlock_irqrestore(&i8253_lock, flags);
        }
 
        chip->ns_rem = PCSP_PERIOD_NS();
@@ -158,10 +159,10 @@ static int pcsp_start_playing(struct snd_pcsp *chip)
                return -EIO;
        }
 
-       spin_lock(&i8253_lock);
+       raw_spin_lock(&i8253_lock);
        chip->val61 = inb(0x61) | 0x03;
        outb_p(0x92, 0x43);     /* binary, mode 1, LSB only, ch 2 */
-       spin_unlock(&i8253_lock);
+       raw_spin_unlock(&i8253_lock);
        atomic_set(&chip->timer_active, 1);
        chip->thalf = 0;
 
@@ -178,11 +179,11 @@ static void pcsp_stop_playing(struct snd_pcsp *chip)
                return;
 
        atomic_set(&chip->timer_active, 0);
-       spin_lock(&i8253_lock);
+       raw_spin_lock(&i8253_lock);
        /* restore the timer */
        outb_p(0xb6, 0x43);     /* binary, mode 3, LSB/MSB, ch 2 */
        outb(chip->val61 & 0xFC, 0x61);
-       spin_unlock(&i8253_lock);
+       raw_spin_unlock(&i8253_lock);
 }
 
 /*
index 60158e2e0eafb529e00013b4a9997d325b1b7fa2..f2b0ba22d9cec1b2de13c0b184e30f0f035e610f 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/parport.h>
 #include <linux/spinlock.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/rawmidi.h>
index 46df8817c18f7b79faa466eb01fbb12af3149921..f7a6fbd313e31aa9059570d3b6c64a8471b97fe6 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/device.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <sound/core.h>
 #include <sound/hwdep.h>
index fff62cc8607c49bb08daa62a132c0c2d03d1824d..971a84a4fa77692336ab6e520adc651afe721b32 100644 (file)
@@ -70,7 +70,7 @@ static int snd_ak4113_dev_free(struct snd_device *device)
 }
 
 int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
-               ak4113_write_t *write, const unsigned char pgm[5],
+               ak4113_write_t *write, const unsigned char *pgm,
                void *private_data, struct ak4113 **r_ak4113)
 {
        struct ak4113 *chip;
index c4c6ef73f9bf5ee32ee1f97ee62251b51d6339a1..ee538f1ae8462f0de200d66fa861009fae537a43 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/version.h>
 #include <sound/core.h>
 #include <sound/tea575x-tuner.h>
index 8246aae32ab436b8967f986753b955de747d1e0c..fe79a169acb52e794e9e33b74c5851b84659da70 100644 (file)
@@ -46,7 +46,6 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/isa.h>
-#include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
index cc15d1d65a22396276000862f28970eb6c5e8263..999dc1e0fdbd5fb95546ef0403a85b5715162c05 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/isa.h>
-#include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
index 9a43baae72503598e19eb483991aafa18d29cb8b..fb4d6b34bbca5c3e9dce8caeb7c885efd3f6e256 100644 (file)
@@ -80,7 +80,6 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/isa.h>
-#include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/isapnp.h>
 #include <linux/moduleparam.h>
index 534a6eced2b810882a4676834926b3703fddf1d4..c7b80e4730fc280f7b3a24698bba5b1b59e503a2 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/err.h>
 #include <linux/isa.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
 #include <asm/dma.h>
index 4be562b2cf219bd12402ddb7778fd50f4f684abe..787495674235ecf2e5b9708d2b98d585282b0a77 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/errno.h>
index 0481a55334b9aca8cc8717a9c5161502d80a16ad..265abcce9dba24ec1953101cfc721f5ad51c3241 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/isa.h>
 #include <linux/interrupt.h>
 #include <linux/pm.h>
-#include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
index 5913717c1be6e9768e3492cca53682682c64d23d..8c24102d0d9389aeca007de307f38fe836e38b53 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/isa.h>
 #include <linux/pnp.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/moduleparam.h>
 #include <asm/io.h>
index 4d2d0405bdc7bda05f0eb6a23a58d8d37e6da372..c35dc68930dc52ddd3ca0990aa2870995f84e753 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/err.h>
 #include <linux/isa.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
 #include <asm/io.h>
index 91dc3d83e2cf8e9d1f01a4a92c20ad1865ccc2c7..ccedbfed061a3b290a92cba575868a18ae37462a 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "emu8000_local.h"
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <sound/initval.h>
 #include <sound/pcm.h>
 
index cafc3a7316a89c4948deaf4d51e7b53fa3cce1c7..ff18286fef9d588c5e34f602506c131733da5bf1 100644 (file)
@@ -93,7 +93,7 @@ static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard,
                return err;
        }
        port[dev] = pnp_port_start(pdev, 0);
-       dma8[dev] = pnp_dma(pdev, 1);
+       dma8[dev] = pnp_dma(pdev, 0);
        irq[dev] = pnp_irq(pdev, 0);
 
        return 0;
index 519c36346dec5e232ed162bb7a9552a777acc068..4d1c5a300ff84de4e75854dcfd17d2540ed4b453 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <asm/dma.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/err.h>
 #include <linux/isa.h>
index 3cd57ee54660716a8182d9c33e2771b4263500f6..81284a8fa0ceb56db3fc246638a792fffadba88f 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/isa.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
index a34ae7b1f7d0b71c2db484bccfb2294ee6e7d578..711670e4a4251e9cdc91a3b48350ec81a6c03a5c 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/isa.h>
 #include <linux/pnp.h>
index 2bb1cee092555df10d6f445a288b554ddbdfc0f1..657e2d6c01ac55fcf56f047b71632139304aad22 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/time.h>
 #include <linux/wait.h>
+#include <linux/slab.h>
 #include <linux/firmware.h>
 #include <sound/core.h>
 #include <sound/snd_wavefront.h>
index 5d4ff48c4345418a4a2fb4fe4d8f782472484143..4fb7b19ff393292480da357a845f8420919bd161 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/wait.h>
 #include <linux/firmware.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/snd_wavefront.h>
 #include <sound/initval.h>
index 9a88cdfd952a0c609847442b24da8746d8aee51e..453d343550a880ae2480337a3ab7c055e001959a 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/sgi/hpc3.h>
 #include <asm/sgi/ip22.h>
index 6aff217379d910d2a333bec3c4c950a8ffe593d3..717604c00f0add6bcab218e9b17e4de9dc6efcf7 100644 (file)
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
-#include <linux/gfp.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/ip32/ip32_ints.h>
 #include <asm/ip32/mace.h>
index d12bd98a37ba6f207190df984ae113be1e5e8dcd..24793c5b65ac186ab7b54815a5696f564881b99b 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/stddef.h>
+#include <linux/slab.h>
 #include <linux/isapnp.h>
 #include <linux/pnp.h>
 #include <linux/spinlock.h>
index 1bfcf7e8854632a7b395f9143b9fb3c3d0408545..bcc3e8e071229db29775632dc6a7380aeda0f6f5 100644 (file)
@@ -26,6 +26,7 @@
 #define SAMPLE_ROUNDUP 0
 
 #include <linux/mm.h>
+#include <linux/gfp.h>
 #include "sound_config.h"
 
 #define DMAP_FREE_ON_CLOSE      0
index bb14e4c67e8905273072ad211298e68fd5e7cf19..87910e9921332d770e5cd07d60434dd670b891fa 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/ioport.h>
 #include <linux/soundcard.h>
 #include <linux/interrupt.h>
+#include <linux/platform_device.h>
 
 #include <asm/uaccess.h>
 #include <asm/setup.h>
@@ -710,31 +711,41 @@ static MACHINE machAmiga = {
 /*** Config & Setup **********************************************************/
 
 
-static int __init dmasound_paula_init(void)
+static int __init amiga_audio_probe(struct platform_device *pdev)
 {
-       int err;
-
-       if (MACH_IS_AMIGA && AMIGAHW_PRESENT(AMI_AUDIO)) {
-           if (!request_mem_region(CUSTOM_PHYSADDR+0xa0, 0x40,
-                                   "dmasound [Paula]"))
-               return -EBUSY;
-           dmasound.mach = machAmiga;
-           dmasound.mach.default_hard = def_hard ;
-           dmasound.mach.default_soft = def_soft ;
-           err = dmasound_init();
-           if (err)
-               release_mem_region(CUSTOM_PHYSADDR+0xa0, 0x40);
-           return err;
-       } else
-           return -ENODEV;
+       dmasound.mach = machAmiga;
+       dmasound.mach.default_hard = def_hard ;
+       dmasound.mach.default_soft = def_soft ;
+       return dmasound_init();
 }
 
-static void __exit dmasound_paula_cleanup(void)
+static int __exit amiga_audio_remove(struct platform_device *pdev)
 {
        dmasound_deinit();
-       release_mem_region(CUSTOM_PHYSADDR+0xa0, 0x40);
+       return 0;
+}
+
+static struct platform_driver amiga_audio_driver = {
+       .remove = __exit_p(amiga_audio_remove),
+       .driver   = {
+               .name   = "amiga-audio",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init amiga_audio_init(void)
+{
+       return platform_driver_probe(&amiga_audio_driver, amiga_audio_probe);
 }
 
-module_init(dmasound_paula_init);
-module_exit(dmasound_paula_cleanup);
+module_init(amiga_audio_init);
+
+static void __exit amiga_audio_exit(void)
+{
+       platform_driver_unregister(&amiga_audio_driver);
+}
+
+module_exit(amiga_audio_exit);
+
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:amiga-audio");
index 24d152ccf80d21ac6b751a85839bcaa8bedaa651..52d06a334e8f1a20ca43da9cc7dd8a347680b646 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include "sound_config.h"
 
index 0af9d24feb8fbbb47e8cfa41312a0aeff6f3ac4c..25e4609f83398128986537de66dd87fb1646006f 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
index 21eb6dce46df28bf17d2aa160244ac29db911425..c0cc951ba97d99d52fb0a067754380ba44ed905c 100644 (file)
@@ -24,7 +24,6 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/types.h>
 #include <linux/delay.h>
index bf27e008f465f29aed345549b583c3e7dcb75213..a1e3f9671beaffa9ff315f86d6af839102875e27 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/smp_lock.h>
+#include <linux/gfp.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 #include "sound_config.h"
index 7781c13c147635b53b06756e31b0daae50b583c0..938c48c43585ea88fa0be036b0765e24f3221ff0 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/delay.h>
 
index 7de18b58f2cd8b3e05895ff33bd27aba607102db..84ef4d06c1c287e5ee77b641291c229d244cc0f0 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include "sound_config.h"
 #include "sb_mixer.h"
index ce4db49291f7862427fc74902970d8f78174049e..7d42c5418d1bb42ea6407ca284a6a0b498e7ec61 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 
 #include "sound_config.h"
 #include "sound_firmware.h"
index 8b796704e1120a15caaed0c96edffa67a34e8006..f139028e85c0dda9f30f9b3406f0e945f5d1bc70 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 
 #include "sound_config.h"
 
index fad1a4f25ad6db0402de24f24f0c21e1be301c54..2039d31b7e2248f25fdf3b38c81f264e1669ed4e 100644 (file)
@@ -16,6 +16,8 @@
  * Stanislav Voronyi <stas@esc.kharkov.com>    : Support for AWE 3DSE device (Jun 7 1999)
  */
 
+#include <linux/slab.h>
+
 #include "sound_config.h"
 
 #define __SB_MIXER_C__
index c79874696becfdf81c4f42793ff44eee35bd103e..e85789e53816640f8e7e7224fdd0199787e5f4de 100644 (file)
@@ -1631,8 +1631,6 @@ unsigned long compute_finetune(unsigned long base_freq, int bend, int range,
        }
 
        semitones = bend / 100;
-       if (semitones > 99)
-               semitones = 99;
        cents = bend % 100;
 
        amount = (int) (semitone_tuning[semitones] * multiplier * cent_tuning[cents]) / 10000;
index fde7c12fe5da9eac43384068c7c761b14cee193c..2d9c51312622fe4a10ea0bf202f24fb092a895ac 100644 (file)
@@ -36,7 +36,6 @@
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <linux/wait.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/major.h>
 #include <linux/delay.h>
index a446b826d5fc87645738dacae9fbe3b31378b4ce..8e514a676a0d00df1dcff0ce71a57119b456b254 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include "sound_config.h"
 
index 103940fd5b4f46e9e2ae7c8435acf64938679faa..f0b4151d9b17c4abfe0dfff99bbce86759aea939 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include "sound_config.h"
 
index 725fef0f59a379d5dd8e2a71e1993dcf151046fb..ac39a531df19ef697eeb1e904d5677273d3f87c8 100644 (file)
@@ -17,6 +17,7 @@
  * We currently support a mixer device, but it is currently non-functional.
  */
 
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -363,13 +364,13 @@ static void vidc_audio_trigger(int dev, int enable_bits)
        struct audio_operations *adev = audio_devs[dev];
 
        if (enable_bits & PCM_ENABLE_OUTPUT) {
-               if (!(adev->flags & DMA_ACTIVE)) {
+               if (!(adev->dmap_out->flags & DMA_ACTIVE)) {
                        unsigned long flags;
 
                        local_irq_save(flags);
 
                        /* prevent recusion */
-                       adev->flags |= DMA_ACTIVE;
+                       adev->dmap_out->flags |= DMA_ACTIVE;
 
                        dma_interrupt = vidc_audio_dma_interrupt;
                        vidc_sound_dma_irq(0, NULL);
index 6713110bdc7506ed3b05a0259d626936c440a51b..20b3b325aa800d2e015799a093a53d7038a067cb 100644 (file)
 #include <linux/wait.h>
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <asm/visws/cobalt.h>
 
index 2c63bb9da74a019a5df655e7960aa0c4b893b670..e688dde6bbdeb0b54ae26c761eaba38b1ede5a95 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
index 1caf5e3c1f6ad481064ea70cced23293333de96a..e68c98ef4041508c2f9a2361172ab592be3ec90c 100644 (file)
@@ -1852,12 +1852,14 @@ static unsigned int ad1981_jacks_blacklist[] = {
        0x10140523, /* Thinkpad R40 */
        0x10140534, /* Thinkpad X31 */
        0x10140537, /* Thinkpad T41p */
+       0x1014053e, /* Thinkpad R40e */
        0x10140554, /* Thinkpad T42p/R50p */
        0x10140567, /* Thinkpad T43p 2668-G7U */
        0x10140581, /* Thinkpad X41-2527 */
        0x10280160, /* Dell Dimension 2400 */
        0x104380b0, /* Asus A7V8X-MX */
        0x11790241, /* Toshiba Satellite A-15 S127 */
+       0x1179ff10, /* Toshiba P500 */
        0x144dc01a, /* Samsung NP-X20C004/SEG */
        0 /* end */
 };
index 73b17d526c8bb2cce8420d6f79f4ac88aae402b6..6320bf084e476a48d1a0bac92542337f3173f411 100644 (file)
@@ -22,7 +22,6 @@
  *
  */
 
-#include <linux/slab.h>
 #include <linux/mutex.h>
 
 #include <sound/core.h>
index d75cf7b0642684a8d2f7a6ebde3ee1296ece0ea4..6cf1de8042e80c400eebdc88691b5c16a86eb1d1 100644 (file)
@@ -68,7 +68,6 @@
 #include <asm/io.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/gameport.h>
 #include <linux/moduleparam.h>
 #include <linux/dma-mapping.h>
index 296123ab74f7e94b6c911fc52eb852a760e26b6b..8afd8b5d1ac73420e408427fb8536f96d0384db7 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <asm/system.h>
index 8f443a9d61ec92628dc17316719e447cab8f1c1b..85fd315d99990d6cba86001840d5cd7389975e2a 100644 (file)
@@ -63,7 +63,6 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/initval.h>
index 0470461cc03eb8887e9f79459e206cad99b9b5e2..ba96428c9f4cfc8dfa468b37b6098cd171fc6ec8 100644 (file)
@@ -63,7 +63,6 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/initval.h>
index 1ded64e056433e22f8e96d8b0fbeb6dbf2c557d4..329968edca9b840fc622602535b0088cdb73bd6c 100644 (file)
@@ -941,13 +941,21 @@ static snd_pcm_uframes_t snd_cmipci_pcm_pointer(struct cmipci *cm, struct cmipci
                                                struct snd_pcm_substream *substream)
 {
        size_t ptr;
-       unsigned int reg;
+       unsigned int reg, rem, tries;
+
        if (!rec->running)
                return 0;
 #if 1 // this seems better..
        reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2;
-       ptr = rec->dma_size - (snd_cmipci_read_w(cm, reg) + 1);
-       ptr >>= rec->shift;
+       for (tries = 0; tries < 3; tries++) {
+               rem = snd_cmipci_read_w(cm, reg);
+               if (rem < rec->dma_size)
+                       goto ok;
+       } 
+       printk(KERN_ERR "cmipci: invalid PCM pointer: %#x\n", rem);
+       return SNDRV_PCM_POS_XRUN;
+ok:
+       ptr = (rec->dma_size - (rem + 1)) >> rec->shift;
 #else
        reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1;
        ptr = snd_cmipci_read(cm, reg) - rec->offset;
index 207479a641cff3fb115ff75f0cd861ec56227fe4..bc07e275d4d4237879f03cbb80eaa78ff233b087 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/delay.h>
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/sb.h>
 #include <sound/initval.h>
index 0f48a871f17bf756ac05cde5d408ed8cae36b37d..f16bc8aad6ed205a7f7b983e9486e4437090c875 100644 (file)
@@ -23,7 +23,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/pci.h>
 #include <sound/core.h>
 #include <sound/control.h>
index 564c33b60953964129619309e4a39090ca47fb97..a3301cc4ab822e640a30d80dee10e9222adb66a3 100644 (file)
@@ -19,7 +19,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <sound/core.h>
index 480cb1e905b61af9a5c3c12aaed35da17376ecd5..1bff80cde0a2f88000eaa1711867b882adcae433 100644 (file)
@@ -24,6 +24,7 @@
 #include "ctdaio.h"
 #include "cttimer.h"
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <sound/pcm.h>
 #include <sound/control.h>
 #include <sound/asoundef.h>
index d0dc227fbdd3ceaeccc72cbcb6b7191ff037e662..85ab43e89212c6724c1e70f3cad3de33e9816935 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "ctpcm.h"
 #include "cttimer.h"
+#include <linux/slab.h>
 #include <sound/pcm.h>
 
 /* Hardware descriptions for playback */
index a65bafe0800f8c727569024e699f395231d4a46a..fe7ad64dccd7361a2a4f88df437d7a84de4a0743 100644 (file)
@@ -40,9 +40,9 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
index 0a6c50bcd758073c0a7ba0de4043c886c71a2351..d1fd34b1a8e35971a06fe943247d23aa96de12f1 100644 (file)
@@ -44,9 +44,9 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
index f5142796989b074480949b61a39c73c55f4ce7a3..1dffdc54416d3e1fbe33c3d876e9d0fb4a1d1c0e 100644 (file)
@@ -51,9 +51,9 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
index 8dab82d7d19d1368abdcb26dd25b7ae581a058b2..668a5ec044992f227f0f7cf37a61325ea5078549 100644 (file)
@@ -2184,10 +2184,9 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
                        goto ctl_error;
 #endif
 
-       if ((err = snd_card_register(card)) < 0) {
-               snd_card_free(card);
+       err = snd_card_register(card);
+       if (err < 0)
                goto ctl_error;
-       }
        snd_printk(KERN_INFO "Card registered: %s\n", card->longname);
 
        pci_set_drvdata(pci, chip);
index 2364f8a1bc21509e678c6d09eab207f2efa0e0c7..050e54aa693f5e90f6b0b87ffb61b1f994a37a02 100644 (file)
@@ -44,9 +44,9 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
index 616b55825a194af53d8bee426987422bd07ba0f1..5748fc6d29d627b2a3dd6c9c03548aa1a74b109e 100644 (file)
@@ -50,9 +50,9 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
index 776175c0bdad10c4bb86b014274dc349aac5db02..4ae5e35cb5f17e76f64d329760ae2db5f0fd43ce 100644 (file)
@@ -42,9 +42,9 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
index 8816b0bd2ba61102ea2b922d88f61efcccfb56c2..3550715bab1c101b7a78e8923fba782d7cfb6b23 100644 (file)
@@ -42,9 +42,9 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
index b1e3652f2f485669874130be56287e97080133f7..19b191fd0120d62dfca64fa9559c5adc0dd86177 100644 (file)
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
index 1035125336d6f89a0f36bc63d1bd5c8e67fae735..a9fcedf317a4007a18249e9882244165bcbc98dc 100644 (file)
@@ -43,9 +43,9 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
index 60b7cb2753cfd2fd1968bc6f978e95b542f62cfc..bcdfac63212c78a8ee2017e8f9406eba31237e24 100644 (file)
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
index 8c3f5c5b53013a879b5848663d7aadab209e2023..d3a98c5dac86e32261c9d47101f8f9633942e800 100644 (file)
@@ -49,9 +49,9 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
index ed1cc0abc2b82cf2a8523ad4711c3b8cfce90f0b..2a1dca6dce17832d5a6d3c30607e1591fd395ac1 100644 (file)
@@ -51,9 +51,9 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
index cc2bbfc65327f23284a3000257aa261e497f2189..9cdf14cfdd741d2147acb9a47e9986f54a523df6 100644 (file)
@@ -50,9 +50,9 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
index 3e7e01824b4073febd740144f906a460d77670c9..1047be405ebe03dcd2df3eb4a6be1e4e90db6621 100644 (file)
@@ -48,9 +48,9 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
index 6a47672f930aedfe67163ce56a0e5a726470e734..ffb1ddb8dc28ea1d3fbdf574d0c4efbef9772c98 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/gfp.h>
 #include <linux/time.h>
 #include <linux/mutex.h>
 
index e4581a42ace56e62ba0e530f5a6cbd360f43b2d3..29714c818b53b9387609b67b409e7b15bf9ea2ef 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/input.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <sound/core.h>
 #include "hda_beep.h"
index 5bd7cf45f3a586ef31fc09859b348eebec2508bc..0e76ac2b2aceefe24ac0037331124c9e8d87eb65 100644 (file)
@@ -1806,6 +1806,8 @@ int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
                item->nid = nid;
                return 0;
        }
+       printk(KERN_ERR "hda-codec: no NID for mapping control %s:%d:%d\n",
+              kctl->id.name, kctl->id.index, index);
        return -EINVAL;
 }
 EXPORT_SYMBOL_HDA(snd_hda_add_nid);
@@ -2884,7 +2886,7 @@ int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus)
        list_for_each_entry(codec, &bus->codec_list, list) {
                int err = snd_hda_codec_build_controls(codec);
                if (err < 0) {
-                       printk(KERN_ERR "hda_codec: cannot build controls"
+                       printk(KERN_ERR "hda_codec: cannot build controls "
                               "for #%d (error %d)\n", codec->addr, err);
                        err = snd_hda_codec_reset(codec);
                        if (err < 0) {
index dcd22446cfc7103bba5339097adae355b8a33b2c..d8da18a9e98b9051a05c15d426f964c29fcf9b21 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <asm/unaligned.h>
 #include "hda_codec.h"
index da1ac9068aac0dd3a27e9ce4e4db490bb2459997..cec68152dcb1b9ae343b0fe0911256491e73996d 100644 (file)
@@ -2269,8 +2269,12 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
        SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB),
        {}
 };
 
@@ -2360,6 +2364,7 @@ static struct snd_pci_quirk msi_black_list[] __devinitdata = {
        SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
        SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
        SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */
+       SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */
        {}
 };
 
@@ -2378,6 +2383,13 @@ static void __devinit check_msi(struct azx *chip)
                       "hda_intel: msi for device %04x:%04x set to %d\n",
                       q->subvendor, q->subdevice, q->value);
                chip->msi = q->value;
+               return;
+       }
+
+       /* NVidia chipsets seem to cause troubles with MSI */
+       if (chip->driver_type == AZX_DRIVER_NVIDIA) {
+               printk(KERN_INFO "hda_intel: Disable MSI for Nvidia chipset\n");
+               chip->msi = 0;
        }
 }
 
@@ -2706,6 +2718,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
        { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH },
        /* PCH */
        { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH },
+       { PCI_DEVICE(0x8086, 0x3b57), .driver_data = AZX_DRIVER_ICH },
        /* CPT */
        { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH },
        /* SCH */
index e6d1bdff1b6e56f53778ace479d682eaf385d915..e9fdfc4b1c57bd92a6cffd77abc9d0577a361a4a 100644 (file)
@@ -519,14 +519,6 @@ static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
        ad198x_power_eapd(codec);
        return 0;
 }
-
-static int ad198x_resume(struct hda_codec *codec)
-{
-       ad198x_init(codec);
-       snd_hda_codec_resume_amp(codec);
-       snd_hda_codec_resume_cache(codec);
-       return 0;
-}
 #endif
 
 static struct hda_codec_ops ad198x_patch_ops = {
@@ -539,7 +531,6 @@ static struct hda_codec_ops ad198x_patch_ops = {
 #endif
 #ifdef SND_HDA_NEEDS_RESUME
        .suspend = ad198x_suspend,
-       .resume = ad198x_resume,
 #endif
        .reboot_notify = ad198x_shutup,
 };
@@ -1896,6 +1887,14 @@ static int patch_ad1981(struct hda_codec *codec)
        case AD1981_THINKPAD:
                spec->mixers[0] = ad1981_thinkpad_mixers;
                spec->input_mux = &ad1981_thinkpad_capture_source;
+               /* set the upper-limit for mixer amp to 0dB for avoiding the
+                * possible damage by overloading
+                */
+               snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
+                                         (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
+                                         (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
+                                         (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+                                         (1 << AC_AMPCAP_MUTE_SHIFT));
                break;
        case AD1981_TOSHIBA:
                spec->mixers[0] = ad1981_hp_mixers;
index 7de782a5b8f4ccb784707e4027f111c12538b27b..350ee8ac415382b5f53a536a61f2422f44ac0ec3 100644 (file)
@@ -766,7 +766,7 @@ static int build_input(struct hda_codec *codec)
                for (n = 0; n < AUTO_PIN_LAST; n++) {
                        if (!spec->adc_nid[n])
                                continue;
-                       err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[i]);
+                       err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[n]);
                        if (err < 0)
                                return err;
                }
index 194a28c5499219b99d3b10ed2ae357cde7707679..feabb44c7ca47d1f7297f01bcb02af206c2af31f 100644 (file)
@@ -1195,10 +1195,12 @@ static int patch_cxt5045(struct hda_codec *codec)
 
        switch (codec->subsystem_id >> 16) {
        case 0x103c:
+       case 0x1631:
        case 0x1734:
-               /* HP & Fujitsu-Siemens laptops have really bad sound over 0dB
-                * on NID 0x17. Fix max PCM level to 0 dB
-                * (originally it has 0x2b steps with 0dB offset 0x14)
+       case 0x17aa:
+               /* HP, Packard Bell, Fujitsu-Siemens & Lenovo laptops have
+                * really bad sound over 0dB on NID 0x17. Fix max PCM level to
+                * 0 dB (originally it has 0x2b steps with 0dB offset 0x14)
                 */
                snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
                                          (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
@@ -1591,6 +1593,21 @@ static int patch_cxt5047(struct hda_codec *codec)
 #endif 
        }
        spec->vmaster_nid = 0x13;
+
+       switch (codec->subsystem_id >> 16) {
+       case 0x103c:
+               /* HP laptops have really bad sound over 0 dB on NID 0x10.
+                * Fix max PCM level to 0 dB (originally it has 0x1e steps
+                * with 0 dB offset 0x17)
+                */
+               snd_hda_override_amp_caps(codec, 0x10, HDA_INPUT,
+                                         (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
+                                         (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
+                                         (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+                                         (1 << AC_AMPCAP_MUTE_SHIFT));
+               break;
+       }
+
        return 0;
 }
 
@@ -2827,6 +2844,10 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
                      CXT5066_DELL_LAPTOP),
        SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
        SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO),
+       SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
+       SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
+       SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5),
+       SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD),
        {}
 };
index 70669a246902570de791822919fecba4fc0d5f19..3c10c0b149f4c682d683a6ae21ae837b3fe18f4d 100644 (file)
@@ -538,8 +538,6 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
  * patch entries
  */
 static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
-       { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
-       { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
        { .id = 0x10de0002, .name = "MCP77/78 HDMI",
          .patch = patch_nvhdmi_8ch_7x },
        { .id = 0x10de0003, .name = "MCP77/78 HDMI",
@@ -550,12 +548,16 @@ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
          .patch = patch_nvhdmi_8ch_7x },
        { .id = 0x10de0007, .name = "MCP79/7A HDMI",
          .patch = patch_nvhdmi_8ch_7x },
-       { .id = 0x10de000c, .name = "MCP89 HDMI",
+       { .id = 0x10de000a, .name = "GT220 HDMI",
          .patch = patch_nvhdmi_8ch_89 },
        { .id = 0x10de000b, .name = "GT21x HDMI",
          .patch = patch_nvhdmi_8ch_89 },
+       { .id = 0x10de000c, .name = "MCP89 HDMI",
+         .patch = patch_nvhdmi_8ch_89 },
        { .id = 0x10de000d, .name = "GT240 HDMI",
          .patch = patch_nvhdmi_8ch_89 },
+       { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
+       { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
        {} /* terminator */
 };
 
@@ -564,11 +566,12 @@ 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");
-MODULE_ALIAS("snd-hda-codec-id:10de8001");
-MODULE_ALIAS("snd-hda-codec-id:10de000c");
+MODULE_ALIAS("snd-hda-codec-id:10de000a");
 MODULE_ALIAS("snd-hda-codec-id:10de000b");
+MODULE_ALIAS("snd-hda-codec-id:10de000c");
 MODULE_ALIAS("snd-hda-codec-id:10de000d");
+MODULE_ALIAS("snd-hda-codec-id:10de0067");
+MODULE_ALIAS("snd-hda-codec-id:10de8001");
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("NVIDIA HDMI HD-audio codec");
index 3a8371990d751d4b2b8aeccf014d3fc3b33d6b3f..886d8e46bb37109d0bf5b0a445a2a6281092c297 100644 (file)
@@ -230,6 +230,7 @@ enum {
        ALC888_ACER_ASPIRE_7730G,
        ALC883_MEDION,
        ALC883_MEDION_MD2,
+       ALC883_MEDION_WIM2160,
        ALC883_LAPTOP_EAPD,
        ALC883_LENOVO_101E_2ch,
        ALC883_LENOVO_NB0763,
@@ -1389,22 +1390,31 @@ struct alc_fixup {
 
 static void alc_pick_fixup(struct hda_codec *codec,
                           const struct snd_pci_quirk *quirk,
-                          const struct alc_fixup *fix)
+                          const struct alc_fixup *fix,
+                          int pre_init)
 {
        const struct alc_pincfg *cfg;
 
        quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
        if (!quirk)
                return;
-
        fix += quirk->value;
        cfg = fix->pins;
-       if (cfg) {
+       if (pre_init && cfg) {
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+               snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
+                           codec->chip_name, quirk->name);
+#endif
                for (; cfg->nid; cfg++)
                        snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
        }
-       if (fix->verbs)
+       if (!pre_init && fix->verbs) {
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+               snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
+                           codec->chip_name, quirk->name);
+#endif
                add_verb(codec->spec, fix->verbs);
+       }
 }
 
 static int alc_read_coef_idx(struct hda_codec *codec,
@@ -1621,6 +1631,11 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
  */
 
 static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
+/* Route to built-in subwoofer as well as speakers */
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 /* Bias voltage on for external mic port */
        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
 /* Front Mic: set to PIN_IN (empty by default) */
@@ -1632,10 +1647,12 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
 /* Enable speaker output */
        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
 /* Enable headphone output */
        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
        { }
 };
 
@@ -2532,8 +2549,6 @@ static int alc_build_controls(struct hda_codec *codec)
                        return err;
        }
 
-       alc_free_kctls(codec); /* no longer needed */
-
        /* assign Capture Source enums to NID */
        kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
        if (!kctl)
@@ -2602,6 +2617,9 @@ static int alc_build_controls(struct hda_codec *codec)
                        }
                }
        }
+
+       alc_free_kctls(codec); /* no longer needed */
+
        return 0;
 }
 
@@ -4125,7 +4143,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
        SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
        SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
-       SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
+       SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
        SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
        SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
        SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
@@ -4800,6 +4818,25 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec)
        }
 }
 
+static void alc880_auto_init_input_src(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       int c;
+
+       for (c = 0; c < spec->num_adc_nids; c++) {
+               unsigned int mux_idx;
+               const struct hda_input_mux *imux;
+               mux_idx = c >= spec->num_mux_defs ? 0 : c;
+               imux = &spec->input_mux[mux_idx];
+               if (!imux->num_items && mux_idx > 0)
+                       imux = &spec->input_mux[0];
+               if (imux)
+                       snd_hda_codec_write(codec, spec->adc_nids[c], 0,
+                                           AC_VERB_SET_CONNECT_SEL,
+                                           imux->items[0].index);
+       }
+}
+
 /* parse the BIOS configuration and set up the alc_spec */
 /* return 1 if successful, 0 if the proper config is not found,
  * or a negative error code
@@ -4878,6 +4915,7 @@ static void alc880_auto_init(struct hda_codec *codec)
        alc880_auto_init_multi_out(codec);
        alc880_auto_init_extra_out(codec);
        alc880_auto_init_analog_input(codec);
+       alc880_auto_init_input_src(codec);
        if (spec->unsol_event)
                alc_inithook(codec);
 }
@@ -4983,6 +5021,70 @@ static void set_capture_mixer(struct hda_codec *codec)
        }
 }
 
+/* fill adc_nids (and capsrc_nids) containing all active input pins */
+static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
+                                int num_nids)
+{
+       struct alc_spec *spec = codec->spec;
+       int n;
+       hda_nid_t fallback_adc = 0, fallback_cap = 0;
+
+       for (n = 0; n < num_nids; n++) {
+               hda_nid_t adc, cap;
+               hda_nid_t conn[HDA_MAX_NUM_INPUTS];
+               int nconns, i, j;
+
+               adc = nids[n];
+               if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
+                       continue;
+               cap = adc;
+               nconns = snd_hda_get_connections(codec, cap, conn,
+                                                ARRAY_SIZE(conn));
+               if (nconns == 1) {
+                       cap = conn[0];
+                       nconns = snd_hda_get_connections(codec, cap, conn,
+                                                        ARRAY_SIZE(conn));
+               }
+               if (nconns <= 0)
+                       continue;
+               if (!fallback_adc) {
+                       fallback_adc = adc;
+                       fallback_cap = cap;
+               }
+               for (i = 0; i < AUTO_PIN_LAST; i++) {
+                       hda_nid_t nid = spec->autocfg.input_pins[i];
+                       if (!nid)
+                               continue;
+                       for (j = 0; j < nconns; j++) {
+                               if (conn[j] == nid)
+                                       break;
+                       }
+                       if (j >= nconns)
+                               break;
+               }
+               if (i >= AUTO_PIN_LAST) {
+                       int num_adcs = spec->num_adc_nids;
+                       spec->private_adc_nids[num_adcs] = adc;
+                       spec->private_capsrc_nids[num_adcs] = cap;
+                       spec->num_adc_nids++;
+                       spec->adc_nids = spec->private_adc_nids;
+                       if (adc != cap)
+                               spec->capsrc_nids = spec->private_capsrc_nids;
+               }
+       }
+       if (!spec->num_adc_nids) {
+               printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
+                      " using fallback 0x%x\n",
+                      codec->chip_name, fallback_adc);
+               spec->private_adc_nids[0] = fallback_adc;
+               spec->adc_nids = spec->private_adc_nids;
+               if (fallback_adc != fallback_cap) {
+                       spec->private_capsrc_nids[0] = fallback_cap;
+                       spec->capsrc_nids = spec->private_adc_nids;
+               }
+       }
+}
+
 #ifdef CONFIG_SND_HDA_INPUT_BEEP
 #define set_beep_amp(spec, nid, idx, dir) \
        ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
@@ -6325,6 +6427,8 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec)
        }
 }
 
+#define alc260_auto_init_input_src     alc880_auto_init_input_src
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -6411,6 +6515,7 @@ static void alc260_auto_init(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
        alc260_auto_init_multi_out(codec);
        alc260_auto_init_analog_input(codec);
+       alc260_auto_init_input_src(codec);
        if (spec->unsol_event)
                alc_inithook(codec);
 }
@@ -6477,7 +6582,7 @@ static struct alc_config_preset alc260_presets[] = {
                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
                .dac_nids = alc260_dac_nids,
                .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
-               .adc_nids = alc260_adc_nids,
+               .adc_nids = alc260_dual_adc_nids,
                .num_channel_mode = ARRAY_SIZE(alc260_modes),
                .channel_mode = alc260_modes,
                .input_mux = &alc260_capture_source,
@@ -8383,6 +8488,42 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
        { } /* end */
 };
 
+static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+       HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
+       { } /* end */
+};
+
+static struct hda_verb alc883_medion_wim2160_verbs[] = {
+       /* Unmute front mixer */
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+       /* Set speaker pin to front mixer */
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+       /* Init headphone pin */
+       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+
+       { } /* end */
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc883_medion_wim2160_setup(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+
+       spec->autocfg.hp_pins[0] = 0x1a;
+       spec->autocfg.speaker_pins[0] = 0x15;
+}
+
 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -8397,9 +8538,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
 
 static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
        HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-       HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -9094,6 +9233,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
        [ALC888_ACER_ASPIRE_7730G]      = "acer-aspire-7730g",
        [ALC883_MEDION]         = "medion",
        [ALC883_MEDION_MD2]     = "medion-md2",
+       [ALC883_MEDION_WIM2160] = "medion-wim2160",
        [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
        [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
        [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
@@ -9195,6 +9335,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
+       SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
        SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
@@ -9204,10 +9345,12 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
+       SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
        SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
 
        SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
+       SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
        SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
        SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
        SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
@@ -9235,7 +9378,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
        SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
        SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
        SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
-       SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
+       SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
 
        {}
 };
@@ -9746,6 +9889,21 @@ static struct alc_config_preset alc882_presets[] = {
                .setup = alc883_medion_md2_setup,
                .init_hook = alc_automute_amp,
        },
+       [ALC883_MEDION_WIM2160] = {
+               .mixers = { alc883_medion_wim2160_mixer },
+               .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
+               .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+               .dac_nids = alc883_dac_nids,
+               .dig_out_nid = ALC883_DIGOUT_NID,
+               .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+               .adc_nids = alc883_adc_nids,
+               .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+               .channel_mode = alc883_3ST_2ch_modes,
+               .input_mux = &alc883_capture_source,
+               .unsol_event = alc_automute_amp_unsol_event,
+               .setup = alc883_medion_wim2160_setup,
+               .init_hook = alc_automute_amp,
+       },
        [ALC883_LAPTOP_EAPD] = {
                .mixers = { alc883_base_mixer },
                .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
@@ -10038,6 +10196,8 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
        int idx;
 
        alc_set_pin_output(codec, nid, pin_type);
+       if (dac_idx >= spec->multiout.num_dacs)
+               return;
        if (spec->multiout.dac_nids[dac_idx] == 0x25)
                idx = 4;
        else
@@ -10289,7 +10449,8 @@ static int patch_alc882(struct hda_codec *codec)
                board_config = ALC882_AUTO;
        }
 
-       alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
+       if (board_config == ALC882_AUTO)
+               alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
 
        if (board_config == ALC882_AUTO) {
                /* automatic parse from the BIOS config */
@@ -10362,6 +10523,9 @@ static int patch_alc882(struct hda_codec *codec)
        set_capture_mixer(codec);
        set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
 
+       if (board_config == ALC882_AUTO)
+               alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
+
        spec->vmaster_nid = 0x0c;
 
        codec->patch_ops = alc_patch_ops;
@@ -12453,11 +12617,11 @@ static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
        unsigned char bits;
 
        present = snd_hda_jack_detect(codec, 0x15);
-       bits = present ? AMP_IN_MUTE(0) : 0;
+       bits = present ? HDA_AMP_MUTE : 0;
        snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
-                               AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
        snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
-                               AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
 }
 
 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
@@ -12742,6 +12906,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
                dac = 0x02;
                break;
        case 0x15:
+       case 0x21: /* ALC269vb has this pin, too */
                dac = 0x03;
                break;
        default:
@@ -13327,9 +13492,9 @@ static hda_nid_t alc269vb_capsrc_nids[1] = {
        0x22,
 };
 
-/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
- *       not a mux!
- */
+static hda_nid_t alc269_adc_candidates[] = {
+       0x08, 0x09, 0x07,
+};
 
 #define alc269_modes           alc260_modes
 #define alc269_capture_source  alc880_lg_lw_capture_source
@@ -13476,11 +13641,11 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
        unsigned char bits;
 
        present = snd_hda_jack_detect(codec, 0x15);
-       bits = present ? AMP_IN_MUTE(0) : 0;
+       bits = present ? HDA_AMP_MUTE : 0;
        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
-                       AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
-                       AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
 
        snd_hda_codec_write(codec, 0x20, 0,
                        AC_VERB_SET_COEF_INDEX, 0x0c);
@@ -13505,11 +13670,11 @@ static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
        /* Check port replicator headphone socket */
        present |= snd_hda_jack_detect(codec, 0x1a);
 
-       bits = present ? AMP_IN_MUTE(0) : 0;
+       bits = present ? HDA_AMP_MUTE : 0;
        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
-                       AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
-                       AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
 
        snd_hda_codec_write(codec, 0x20, 0,
                        AC_VERB_SET_COEF_INDEX, 0x0c);
@@ -13640,11 +13805,11 @@ static void alc269_speaker_automute(struct hda_codec *codec)
        unsigned char bits;
 
        present = snd_hda_jack_detect(codec, nid);
-       bits = present ? AMP_IN_MUTE(0) : 0;
+       bits = present ? HDA_AMP_MUTE : 0;
        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
-                               AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
-                               AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
 }
 
 /* unsolicited event for HP jack sensing */
@@ -13661,19 +13826,19 @@ static void alc269_laptop_unsol_event(struct hda_codec *codec,
        }
 }
 
-static void alc269_laptop_dmic_setup(struct hda_codec *codec)
+static void alc269_laptop_amic_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
        spec->autocfg.hp_pins[0] = 0x15;
        spec->autocfg.speaker_pins[0] = 0x14;
        spec->ext_mic.pin = 0x18;
        spec->ext_mic.mux_idx = 0;
-       spec->int_mic.pin = 0x12;
-       spec->int_mic.mux_idx = 5;
+       spec->int_mic.pin = 0x19;
+       spec->int_mic.mux_idx = 1;
        spec->auto_mic = 1;
 }
 
-static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
+static void alc269_laptop_dmic_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
        spec->autocfg.hp_pins[0] = 0x15;
@@ -13681,14 +13846,14 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
        spec->ext_mic.pin = 0x18;
        spec->ext_mic.mux_idx = 0;
        spec->int_mic.pin = 0x12;
-       spec->int_mic.mux_idx = 6;
+       spec->int_mic.mux_idx = 5;
        spec->auto_mic = 1;
 }
 
-static void alc269_laptop_amic_setup(struct hda_codec *codec)
+static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x15;
+       spec->autocfg.hp_pins[0] = 0x21;
        spec->autocfg.speaker_pins[0] = 0x14;
        spec->ext_mic.pin = 0x18;
        spec->ext_mic.mux_idx = 0;
@@ -13697,6 +13862,18 @@ static void alc269_laptop_amic_setup(struct hda_codec *codec)
        spec->auto_mic = 1;
 }
 
+static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       spec->autocfg.hp_pins[0] = 0x21;
+       spec->autocfg.speaker_pins[0] = 0x14;
+       spec->ext_mic.pin = 0x18;
+       spec->ext_mic.mux_idx = 0;
+       spec->int_mic.pin = 0x12;
+       spec->int_mic.mux_idx = 6;
+       spec->auto_mic = 1;
+}
+
 static void alc269_laptop_inithook(struct hda_codec *codec)
 {
        alc269_speaker_automute(codec);
@@ -13836,7 +14013,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
        int err;
        static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
-       hda_nid_t real_capsrc_nids;
 
        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
                                           alc269_ignore);
@@ -13860,18 +14036,19 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
 
        if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
                add_verb(spec, alc269vb_init_verbs);
-               real_capsrc_nids = alc269vb_capsrc_nids[0];
                alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
        } else {
                add_verb(spec, alc269_init_verbs);
-               real_capsrc_nids = alc269_capsrc_nids[0];
                alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
        }
 
        spec->num_mux_defs = 1;
        spec->input_mux = &spec->private_imux[0];
+       fillup_priv_adc_nids(codec, alc269_adc_candidates,
+                            sizeof(alc269_adc_candidates));
+
        /* set default input source */
-       snd_hda_codec_write_cache(codec, real_capsrc_nids,
+       snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],
                                  0, AC_VERB_SET_CONNECT_SEL,
                                  spec->input_mux->items[0].index);
 
@@ -13901,6 +14078,27 @@ static void alc269_auto_init(struct hda_codec *codec)
                alc_inithook(codec);
 }
 
+enum {
+       ALC269_FIXUP_SONY_VAIO,
+};
+
+const static struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
+       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
+       {}
+};
+
+static const struct alc_fixup alc269_fixups[] = {
+       [ALC269_FIXUP_SONY_VAIO] = {
+               .verbs = alc269_sony_vaio_fixup_verbs
+       },
+};
+
+static struct snd_pci_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
+       {}
+};
+
+
 /*
  * configuration and preset
  */
@@ -13960,7 +14158,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = {
                      ALC269_DMIC),
        SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
        SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
-       SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC),
+       SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
        SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
        SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
        SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
@@ -14034,7 +14232,7 @@ static struct alc_config_preset alc269_presets[] = {
                .num_channel_mode = ARRAY_SIZE(alc269_modes),
                .channel_mode = alc269_modes,
                .unsol_event = alc269_laptop_unsol_event,
-               .setup = alc269_laptop_amic_setup,
+               .setup = alc269vb_laptop_amic_setup,
                .init_hook = alc269_laptop_inithook,
        },
        [ALC269VB_DMIC] = {
@@ -14114,6 +14312,9 @@ static int patch_alc269(struct hda_codec *codec)
                board_config = ALC269_AUTO;
        }
 
+       if (board_config == ALC269_AUTO)
+               alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
+
        if (board_config == ALC269_AUTO) {
                /* automatic parse from the BIOS config */
                err = alc269_parse_auto_config(codec);
@@ -14150,20 +14351,25 @@ static int patch_alc269(struct hda_codec *codec)
        spec->stream_digital_playback = &alc269_pcm_digital_playback;
        spec->stream_digital_capture = &alc269_pcm_digital_capture;
 
-       if (!is_alc269vb) {
-               spec->adc_nids = alc269_adc_nids;
-               spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
-               spec->capsrc_nids = alc269_capsrc_nids;
-       } else {
-               spec->adc_nids = alc269vb_adc_nids;
-               spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
-               spec->capsrc_nids = alc269vb_capsrc_nids;
+       if (!spec->adc_nids) { /* wasn't filled automatically? use default */
+               if (!is_alc269vb) {
+                       spec->adc_nids = alc269_adc_nids;
+                       spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
+                       spec->capsrc_nids = alc269_capsrc_nids;
+               } else {
+                       spec->adc_nids = alc269vb_adc_nids;
+                       spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
+                       spec->capsrc_nids = alc269vb_capsrc_nids;
+               }
        }
 
        if (!spec->cap_mixer)
                set_capture_mixer(codec);
        set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
 
+       if (board_config == ALC269_AUTO)
+               alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
+
        spec->vmaster_nid = 0x02;
 
        codec->patch_ops = alc_patch_ops;
@@ -15252,7 +15458,8 @@ static int patch_alc861(struct hda_codec *codec)
                board_config = ALC861_AUTO;
        }
 
-       alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups);
+       if (board_config == ALC861_AUTO)
+               alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
 
        if (board_config == ALC861_AUTO) {
                /* automatic parse from the BIOS config */
@@ -15289,6 +15496,9 @@ static int patch_alc861(struct hda_codec *codec)
 
        spec->vmaster_nid = 0x03;
 
+       if (board_config == ALC861_AUTO)
+               alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
+
        codec->patch_ops = alc_patch_ops;
        if (board_config == ALC861_AUTO) {
                spec->init_hook = alc861_auto_init;
@@ -16223,7 +16433,8 @@ static int patch_alc861vd(struct hda_codec *codec)
                board_config = ALC861VD_AUTO;
        }
 
-       alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
+       if (board_config == ALC861VD_AUTO)
+               alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
 
        if (board_config == ALC861VD_AUTO) {
                /* automatic parse from the BIOS config */
@@ -16271,6 +16482,9 @@ static int patch_alc861vd(struct hda_codec *codec)
 
        spec->vmaster_nid = 0x02;
 
+       if (board_config == ALC861VD_AUTO)
+               alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
+
        codec->patch_ops = alc_patch_ops;
 
        if (board_config == ALC861VD_AUTO)
@@ -17109,9 +17323,9 @@ static void alc663_m51va_speaker_automute(struct hda_codec *codec)
        present = snd_hda_jack_detect(codec, 0x21);
        bits = present ? HDA_AMP_MUTE : 0;
        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
-                               AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
-                               AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
 }
 
 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
@@ -17122,13 +17336,13 @@ static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
        present = snd_hda_jack_detect(codec, 0x21);
        bits = present ? HDA_AMP_MUTE : 0;
        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
-                               AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
-                               AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
        snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
-                               AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
        snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
-                               AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
 }
 
 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
@@ -17139,13 +17353,13 @@ static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
        present = snd_hda_jack_detect(codec, 0x15);
        bits = present ? HDA_AMP_MUTE : 0;
        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
-                               AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
-                               AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
        snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
-                               AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
        snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
-                               AMP_IN_MUTE(0), bits);
+                                HDA_AMP_MUTE, bits);
 }
 
 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
@@ -17184,14 +17398,14 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
 
        if (present1 || present2) {
                snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
-                               AMP_IN_MUTE(0), AMP_IN_MUTE(0));
+                                        HDA_AMP_MUTE, HDA_AMP_MUTE);
                snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
-                               AMP_IN_MUTE(0), AMP_IN_MUTE(0));
+                                        HDA_AMP_MUTE, HDA_AMP_MUTE);
        } else {
                snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
-                               AMP_IN_MUTE(0), 0);
+                                        HDA_AMP_MUTE, 0);
                snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
-                               AMP_IN_MUTE(0), 0);
+                                        HDA_AMP_MUTE, 0);
        }
 }
 
@@ -17657,7 +17871,6 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
                                        ALC662_3ST_6ch_DIG),
        SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
                           ALC663_ASUS_H13),
-       SND_PCI_QUIRK(0x8086, 0xd604, "Intel mobo", ALC662_3ST_2ch_DIG),
        {}
 };
 
index 8c416bb18a57cef781249611bdbae060212b924d..a0e06d82da1f8c27d50d8a2b1fd5d75927db4ca9 100644 (file)
@@ -104,6 +104,7 @@ enum {
        STAC_DELL_M4_2,
        STAC_DELL_M4_3,
        STAC_HP_M4,
+       STAC_HP_DV4,
        STAC_HP_DV5,
        STAC_HP_HDX,
        STAC_HP_DV4_1222NR,
@@ -1544,11 +1545,9 @@ static unsigned int alienware_m17x_pin_configs[13] = {
        0x904601b0,
 };
 
-static unsigned int intel_dg45id_pin_configs[14] = {
+static unsigned int intel_dg45id_pin_configs[13] = {
        0x02214230, 0x02A19240, 0x01013214, 0x01014210,
-       0x01A19250, 0x01011212, 0x01016211, 0x40f000f0,
-       0x40f000f0, 0x40f000f0, 0x40f000f0, 0x014510A0,
-       0x074510B0, 0x40f000f0
+       0x01A19250, 0x01011212, 0x01016211
 };
 
 static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
@@ -1607,6 +1606,10 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
                                "Dell Studio 1555", STAC_DELL_M6_DMIC),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
                                "Dell Studio 1557", STAC_DELL_M6_DMIC),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe,
+                               "Dell Studio XPS 1645", STAC_DELL_M6_BOTH),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413,
+                               "Dell Studio 1558", STAC_DELL_M6_BOTH),
        {} /* terminator */
 };
 
@@ -1689,6 +1692,7 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
        [STAC_DELL_M4_2]        = dell_m4_2_pin_configs,
        [STAC_DELL_M4_3]        = dell_m4_3_pin_configs,
        [STAC_HP_M4]            = NULL,
+       [STAC_HP_DV4]           = NULL,
        [STAC_HP_DV5]           = NULL,
        [STAC_HP_HDX]           = NULL,
        [STAC_HP_DV4_1222NR]    = NULL,
@@ -1701,6 +1705,7 @@ static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
        [STAC_DELL_M4_2] = "dell-m4-2",
        [STAC_DELL_M4_3] = "dell-m4-3",
        [STAC_HP_M4] = "hp-m4",
+       [STAC_HP_DV4] = "hp-dv4",
        [STAC_HP_DV5] = "hp-dv5",
        [STAC_HP_HDX] = "hp-hdx",
        [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr",
@@ -1719,7 +1724,7 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
        SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
                      "HP", STAC_HP_DV5),
        SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
-                     "HP dv4-7", STAC_HP_DV5),
+                     "HP dv4-7", STAC_HP_DV4),
        SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600,
                      "HP dv4-7", STAC_HP_DV5),
        SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610,
@@ -1730,6 +1735,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
                      "HP HDX", STAC_HP_HDX),  /* HDX16 */
        SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620,
                      "HP dv6", STAC_HP_DV5),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061,
+                     "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */
        SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
                      "HP", STAC_HP_DV5),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
@@ -4762,6 +4769,9 @@ static void set_hp_led_gpio(struct hda_codec *codec)
        struct sigmatel_spec *spec = codec->spec;
        unsigned int gpio;
 
+       if (spec->gpio_led)
+               return;
+
        gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP);
        gpio &= AC_GPIO_IO_COUNT;
        if (gpio > 3)
@@ -5671,6 +5681,9 @@ again:
                spec->num_smuxes = 1;
                spec->num_dmuxes = 1;
                /* fallthrough */
+       case STAC_HP_DV4:
+               spec->gpio_led = 0x01;
+               /* fallthrough */
        case STAC_HP_DV5:
                snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
                stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN);
@@ -5684,6 +5697,7 @@ again:
                spec->num_dmics = 1;
                spec->num_dmuxes = 1;
                spec->num_smuxes = 1;
+               spec->gpio_led = 0x08;
                break;
        }
 
@@ -5740,7 +5754,8 @@ again:
        }
 
        /* enable bass on HP dv7 */
-       if (spec->board_config == STAC_HP_DV5) {
+       if (spec->board_config == STAC_HP_DV4 ||
+           spec->board_config == STAC_HP_DV5) {
                unsigned int cap;
                cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
                cap &= AC_GPIO_IO_COUNT;
index 9ddc37300f6b5cd88420ff885823e486e0cd3dd5..73453814e09877a35e5f165d2dfbff3b776592b6 100644 (file)
@@ -476,7 +476,7 @@ static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
        knew->name = kstrdup(tmpl->name, GFP_KERNEL);
        if (!knew->name)
                return NULL;
-       return 0;
+       return knew;
 }
 
 static void via_free_kctls(struct hda_codec *codec)
@@ -1215,14 +1215,13 @@ static struct snd_kcontrol_new via_hp_mixer[2] = {
        },
 };
 
-static int via_hp_build(struct via_spec *spec)
+static int via_hp_build(struct hda_codec *codec)
 {
+       struct via_spec *spec = codec->spec;
        struct snd_kcontrol_new *knew;
        hda_nid_t nid;
-
-       knew = via_clone_control(spec, &via_hp_mixer[0]);
-       if (knew == NULL)
-               return -ENOMEM;
+       int nums;
+       hda_nid_t conn[HDA_MAX_CONNECTIONS];
 
        switch (spec->codec_type) {
        case VT1718S:
@@ -1239,6 +1238,14 @@ static int via_hp_build(struct via_spec *spec)
                break;
        }
 
+       nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS);
+       if (nums <= 1)
+               return 0;
+
+       knew = via_clone_control(spec, &via_hp_mixer[0]);
+       if (knew == NULL)
+               return -ENOMEM;
+
        knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
        knew->private_value = nid;
 
@@ -2561,7 +2568,7 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
        return 1;
@@ -3087,7 +3094,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
        return 1;
@@ -3654,7 +3661,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
        return 1;
@@ -4140,7 +4147,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
        return 1;
@@ -4510,7 +4517,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        return 1;
 }
@@ -4930,7 +4937,7 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
 
@@ -5425,7 +5432,7 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
 
@@ -5781,7 +5788,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        return 1;
 }
@@ -6000,12 +6007,12 @@ static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec,
 
        /* Line-Out: PortE */
        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
-                             "Master Front Playback Volume",
+                             "Front Playback Volume",
                              HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
        if (err < 0)
                return err;
        err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
-                             "Master Front Playback Switch",
+                             "Front Playback Switch",
                              HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT));
        if (err < 0)
                return err;
@@ -6130,7 +6137,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        return 1;
 }
index 03391da8c8c7741304fff11f4e8ccc044393e984..90d560c3df13c4a3e92268809d5435177fdfebb3 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <sound/core.h>
 #include <sound/initval.h>
index 6da21a2bcade940c9104bdcbd5ad85972d5eb468..e328cfb7620c77bd80d1c3788c373f6ababfc520 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <sound/core.h>
 
 #include "ice1712.h"
index 3e1c20ae2f1c2c42c115c293bc26fdd6c660124f..726fd4b92e19e8d564adef229c9c5201a0785963 100644 (file)
@@ -347,7 +347,7 @@ static int maya_gpio_sw_put(struct snd_kcontrol *kcontrol,
 
 /* known working input slots (0-4) */
 #define MAYA_LINE_IN   1       /* in-2 */
-#define MAYA_MIC_IN    4       /* in-5 */
+#define MAYA_MIC_IN    3       /* in-4 */
 
 static void wm8776_select_input(struct snd_maya44 *chip, int idx, int line)
 {
@@ -393,8 +393,8 @@ static int maya_rec_src_put(struct snd_kcontrol *kcontrol,
        int changed;
 
        mutex_lock(&chip->mutex);
-       changed = maya_set_gpio_bits(chip->ice, GPIO_MIC_RELAY,
-                                    sel ? GPIO_MIC_RELAY : 0);
+       changed = maya_set_gpio_bits(chip->ice, 1 << GPIO_MIC_RELAY,
+                                    sel ? (1 << GPIO_MIC_RELAY) : 0);
        wm8776_select_input(chip, 0, sel ? MAYA_MIC_IN : MAYA_LINE_IN);
        mutex_unlock(&chip->mutex);
        return changed;
index 7f9674b641c0c8e98e171c6bfcc5e80bd370d213..4c551e147c089d8186db424d6bc630ddeead58b1 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <sound/core.h>
 
 #include "ice1712.h"
index 5af9e84456d1c801be959f1053d01c4a6a57b3cc..e618f789026ea7dc4ff2ddddf4fc46a3e1328a39 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <sound/core.h>
 
 #include "ice1712.h"
index 0cca56038cd94d406fc4150f5494855916677afc..ef9af3f4ace2f6fda837a89e4ea46ff8821fd86c 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <sound/initval.h>
 #include <sound/control.h>
index b64e78139d632c2be13178981efb1b80069df73a..b56e336767809b250cd508a04d96fd526c130d45 100644 (file)
@@ -849,6 +849,7 @@ struct snd_m3 {
        struct snd_kcontrol *master_switch;
        struct snd_kcontrol *master_volume;
        struct tasklet_struct hwvol_tq;
+       unsigned int in_suspend;
 
 #ifdef CONFIG_PM
        u16 *suspend_mem;
@@ -884,6 +885,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_m3_ids) = {
 MODULE_DEVICE_TABLE(pci, snd_m3_ids);
 
 static struct snd_pci_quirk m3_amp_quirk_list[] __devinitdata = {
+       SND_PCI_QUIRK(0x0E11, 0x0094, "Compaq Evo N600c", 0x0c),
        SND_PCI_QUIRK(0x10f7, 0x833e, "Panasonic CF-28", 0x0d),
        SND_PCI_QUIRK(0x10f7, 0x833d, "Panasonic CF-72", 0x0d),
        SND_PCI_QUIRK(0x1033, 0x80f1, "NEC LM800J/7", 0x03),
@@ -1613,6 +1615,11 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
        outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER);
        outb(0x88, chip->iobase + HW_VOL_COUNTER_MASTER);
 
+       /* Ignore spurious HV interrupts during suspend / resume, this avoids
+          mistaking them for a mute button press. */
+       if (chip->in_suspend)
+               return;
+
        if (!chip->master_switch || !chip->master_volume)
                return;
 
@@ -2424,6 +2431,7 @@ static int m3_suspend(struct pci_dev *pci, pm_message_t state)
        if (chip->suspend_mem == NULL)
                return 0;
 
+       chip->in_suspend = 1;
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
        snd_pcm_suspend_all(chip->pcm);
        snd_ac97_suspend(chip->ac97);
@@ -2497,6 +2505,7 @@ static int m3_resume(struct pci_dev *pci)
        snd_m3_hv_init(chip);
 
        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+       chip->in_suspend = 0;
        return 0;
 }
 #endif /* CONFIG_PM */
index 7e8e7da592a98e01faf4804e6983dba9fc07878c..3be8f97c8bc089e9f2b4e266a13306b443163629 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/moduleparam.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 
 #include <sound/core.h>
 #include <sound/initval.h>
@@ -1161,13 +1162,15 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private
                                unsigned long count, unsigned long pos)
 {
        struct mixart_mgr *mgr = entry->private_data;
+       unsigned long maxsize;
 
-       count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
-       if(count <= 0)
+       if (pos >= MIXART_BA0_SIZE)
                return 0;
-       if(pos + count > MIXART_BA0_SIZE)
-               count = (long)(MIXART_BA0_SIZE - pos);
-       if(copy_to_user_fromio(buf, MIXART_MEM( mgr, pos ), count))
+       maxsize = MIXART_BA0_SIZE - pos;
+       if (count > maxsize)
+               count = maxsize;
+       count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
+       if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count))
                return -EFAULT;
        return count;
 }
@@ -1180,13 +1183,15 @@ static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private
                                unsigned long count, unsigned long pos)
 {
        struct mixart_mgr *mgr = entry->private_data;
+       unsigned long maxsize;
 
-       count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
-       if(count <= 0)
+       if (pos > MIXART_BA1_SIZE)
                return 0;
-       if(pos + count > MIXART_BA1_SIZE)
-               count = (long)(MIXART_BA1_SIZE - pos);
-       if(copy_to_user_fromio(buf, MIXART_REG( mgr, pos ), count))
+       maxsize = MIXART_BA1_SIZE - pos;
+       if (count > maxsize)
+               count = maxsize;
+       count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
+       if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count))
                return -EFAULT;
        return count;
 }
index 4cf4cd8c939c518629200903123ede9d7eec94d2..bf2696aa5d49021db7c1b37bdbf5a7968c16ae93 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/pci.h>
 #include <linux/firmware.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include <sound/core.h>
 #include "mixart.h"
index 9c5e6450eebbec3c1d11deef24053193f75ceb41..fad03d64e3ad0c936aca79a257f6c484b067f657 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 #include <sound/ac97_codec.h>
 #include <sound/asoundef.h>
 #include <sound/core.h>
index 16c226bfcd2bc945e795c7bab877cfeb71f9b055..7c4986b27f2b07bd8faa7d824a0056d1db821308 100644 (file)
@@ -56,6 +56,7 @@
 #include <sound/pcm_params.h>
 #include <sound/tlv.h>
 #include "xonar.h"
+#include "cm9780.h"
 #include "cs4398.h"
 #include "cs4362a.h"
 
@@ -172,6 +173,8 @@ static void xonar_d1_init(struct oxygen *chip)
        oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
                            GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE);
 
+       oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
+
        xonar_init_cs53x1(chip);
        xonar_enable_output(chip);
 
index d5e1c6eb7b7bba56f7a57e4b34229290d466a529..3c04524de37c06afbc341809a67e14659edfa975 100644 (file)
 
 
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 
 #include <sound/core.h>
index 9d5252bc870c15e2d86a4558a5ffb24124eda574..d19dc052c3912f0aa235f8fae0344b5f241833fa 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 
 #include <sound/core.h>
index 52c6eb57cc3f51fafa7f39c165543e046dd52016..b92adef8e81e7ae61eef5681925610b87f03a502 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/firmware.h>
 #include <linux/moduleparam.h>
index 44a3e2d8c5563e757fe437c569a45658ce471b41..c492af5b25f3e43a9530b69e5c6f7fc591ea30be 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/slab.h>
 #include <linux/moduleparam.h>
 
 #include <sound/core.h>
index 7e3e8fbc90fefca268bde1a8ec27361b8889ac78..9cc1b5aa0148f92445986601b6399ca1eb9a8306 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/time.h>
+#include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
index 5d2afa0b0ce430012f48d0c038b455a6dce41a04..9dce0bde5c05b078ba32ffb5e18b775353c9a7d3 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include "pdaudiocf.h"
index 0d668f471620cc81283142cc16cc0d1159cb84f9..43f995a3f96033c081499dd41002541279252b95 100644 (file)
@@ -20,7 +20,6 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <sound/core.h>
 #include <sound/asoundef.h>
index 7be3b335704597d0a7808e8cc4eae1356ded7f73..cfd1438bcc644a2658845d38cd015d207e023eca 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/init.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include "vxpocket.h"
 #include <pcmcia/ciscode.h>
index 1f72e1c786bf2f389e18788bd3b304287312617a..00e2d5166d0a2fc277da60e02bebb1206608a5d3 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <asm/io.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <sound/core.h>
 #include "pmac.h"
index d06f780bd7e84ad088163eb52e134c8c57188956..8f064c7ce74569348d0af6a035f97c353af9ac71 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <sound/core.h>
 #include "pmac.h"
 
index 53c81a547613ee0482c8dd64b9c3bb0a7b88f2e6..2f12da4da561f6eeec98a028d7163c68e112b5dd 100644 (file)
 
 #include <linux/dma-mapping.h>
 #include <linux/dmapool.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
-#include <linux/slab.h>
 
 #include <sound/asound.h>
 #include <sound/control.h>
index 76d9ad27d91cd73d76a3a3b2d75d56594162409a..68e0dee4ff0593a0ad56fc4f2583c2c13c4312de 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/pcm.h>
index 9ef6b96373f598cbb2bf670953a6a85a96bf710c..3e6628c8e6659b943b09ece126afe76f11421e97 100644 (file)
@@ -180,7 +180,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
        snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
        runtime->dma_bytes = params_buffer_bytes(params);
 
-       prtd->params = rtd->dai->cpu_dai->dma_data;
+       prtd->params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
        prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
 
        prtd->dma_buffer = runtime->dma_addr;
index e588e63f18d205e6e7f1d118b4982711f867cd51..0b59806905d1d815a62acfbf395abbf0bebdec3f 100644 (file)
@@ -363,12 +363,12 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
        ssc_p->dma_params[dir] = dma_params;
 
        /*
-        * The cpu_dai->dma_data field is only used to communicate the
-        * appropriate DMA parameters to the pcm driver hw_params()
+        * The snd_soc_pcm_stream->dma_data field is only used to communicate
+        * the appropriate DMA parameters to the pcm driver hw_params()
         * function.  It should not be used for other purposes
         * as it is common to all substreams.
         */
-       rtd->dai->cpu_dai->dma_data = dma_params;
+       snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_params);
 
        channels = params_channels(params);
 
index 340311d7fed55055c44fa58520878920ffba3dfe..a61ccd2d505f010fd9720a29c8ce318e7d27819e 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
index 0cf2ca61c7764bf38a2df63f088a675fee317265..495be6e7193169fcdf22400a682915d4966c3cc9 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/suspend.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
index 67cbfe7283da1c481cbaafad4c731de17b670a76..5e7aacf3bb5a2027c2decfe98e3b49919c04a207 100644 (file)
@@ -29,8 +29,8 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/slab.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
index e69322978739d760e27bf47aaf61021cbf958deb..523b7fc33f4e7f94b5d1f6f6ffd89f9e904479c5 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/wait.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
index c6c6a4a7d948feb34402bd0d332d84f738a529bd..1d2a1adf25759070cfa96a3cab81c89c31630b30 100644 (file)
@@ -29,8 +29,8 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/slab.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
index 5e03bb2f3cd7db4ddc9f72337709b4f56d07c8a4..6bac1ac1a315b72ee8b9fe134f4b94665a2cb47b 100644 (file)
@@ -29,8 +29,8 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/slab.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
index a1bbe16b7f9613e3129ebdb8819125c2b7c7463a..1f5e57a4bb7accdfdad3eefdd209b9b056b7351c 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <sound/core.h>
@@ -80,9 +81,11 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
 static int ac97_soc_probe(struct platform_device *pdev)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_card *card = socdev->card;
        struct snd_soc_codec *codec;
        struct snd_ac97_bus *ac97_bus;
        struct snd_ac97_template ac97_template;
+       int i;
        int ret = 0;
 
        printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION);
@@ -102,12 +105,6 @@ static int ac97_soc_probe(struct platform_device *pdev)
        INIT_LIST_HEAD(&codec->dapm_widgets);
        INIT_LIST_HEAD(&codec->dapm_paths);
 
-       ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
-       if (ret < 0) {
-               printk(KERN_ERR "ASoC: failed to init gen ac97 glue\n");
-               goto err;
-       }
-
        /* register pcms */
        ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
        if (ret < 0)
@@ -123,6 +120,13 @@ static int ac97_soc_probe(struct platform_device *pdev)
        if (ret < 0)
                goto bus_err;
 
+       for (i = 0; i < card->num_links; i++) {
+               if (card->dai_link[i].codec_dai->ac97_control) {
+                       snd_ac97_dev_add_pdata(codec->ac97,
+                               card->dai_link[i].cpu_dai->ac97_pdata);
+               }
+       }
+
        return 0;
 
 bus_err:
index 3c80137d59382198138af20ef2050338a6b9a73d..11b62dee842cecd84c57cb94642fff41e2e091d2 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
index c233810d463df1c4e50c866dd277b94d3b9bd81a..240cd155b313315fe4fbd9b03cf51fcb6402f7f1 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
index 39c0f7584e656ab78f71d6d70e28abac9ec6d131..042072738cdcf6d3edf051b097d6ab13b1a64a0a 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
index d2fcc601722c17b23d24d144a502009063d7d728..475807bea2c229d04e4e3ed91dd8647ffa26d259 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
index cc96411ca3e6ec0547202f06a0db55dab6e885a0..f8e75edb27b7ec793f21f32e10200db2d734148c 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <sound/core.h>
index b68d99fb6af0a41ce8b3f55781c82cda336f07ae..bdeb10dfd88728bb17ad68f45353d15e290a2ef8 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/soc.h>
 #include <sound/initval.h>
index ff966567e2bad1e2f5a3ae39b782205cb7122399..352d1d08dbd95ae10bb47e571392e641245c9db3 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 3ef16bbc8c8397a3e808f63901c12fddd3135ad8..729859cf6ca8696b0c4f6218d167c9e04fcdbfef 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 82fca284d00761c67ed920c000236b4e9fbd5bf8..926797a014c75716f069db87d03a1f7dbd3e43ba 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
 #include <sound/initval.h>
index dfbeb2db61b3e25011c24276cab47a58425aa788..81a62d198b7002b92f9df5d82c7cdd30b625b7c0 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/soc.h>
 #include <sound/initval.h>
index e000cdfec1ec20550abe154c2939bad4365e0e7b..9f169c4771080c43a06f509771619339589dedad 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/tty.h>
+#include <linux/slab.h>
 
 #include <sound/core.h>
 #include <sound/initval.h>
index cf2975a7294af95ec306851c92785d64d0e8199c..366daf1d044e04959489c71f161c5aad376b17b7 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 2afcd0a8669d308a1ab658cbbfa7f823961fdf8a..5a5f187a265738283cb4f05049f78d12430d9789 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/initval.h>
index d2ff1cde6883c31412559540c7f3a37dcc2d06f8..29d0906a924a89e4da8c3ffbe65830acbcdf7ce6 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 81b8c9dfe7fc3253034c034afd288d500cd26848..3293629dcb3b65bc862b4ab008cffb3d6c90437f 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/device.h>
 #include <sound/core.h>
index da589d8664d0d52ce44d6cc0efc7f57981cfdd69..776b79cde90402bbbde5784fec34f415e7637ecc 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 357b609196e35aecf223be365a383591bec5cd7a..b5b7d6a03844d2834cca44c9fb5f54c364f3faa7 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/device.h>
 #include <linux/sysfs.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index e4b946a19ea3e958b46969be2561e03764c1096d..4a6d56c3fed9f6fa740dc63dbe1ece1201f5bfd4 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index f9f367d29a9095e8bc5a44be2da0da9b45f4ba7e..d1e0e81ef30c6bf0da79e8fb3a6354a0c78cf81a 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -778,7 +779,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
        if (dac33->fifo_mode) {
                /* Generic for all FIFO modes */
                /* 50-51 : ASRC Control registers */
-               dac33_write(codec, DAC33_ASRC_CTRL_A, (1 << 4)); /* div=2 */
+               dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCLKDIV(1));
                dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */
 
                /* Write registers 0x34 and 0x35 (MSB, LSB) */
@@ -1038,11 +1039,7 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
        case SND_SOC_DAIFMT_DSP_A:
                aictrl_a |= DAC33_AFMT_DSP;
                aictrl_b &= ~DAC33_DATA_DELAY_MASK;
-               aictrl_b |= DAC33_DATA_DELAY(1); /* 1 bit delay */
-               break;
-       case SND_SOC_DAIFMT_DSP_B:
-               aictrl_a |= DAC33_AFMT_DSP;
-               aictrl_b &= ~DAC33_DATA_DELAY_MASK; /* No delay */
+               aictrl_b |= DAC33_DATA_DELAY(0);
                break;
        case SND_SOC_DAIFMT_RIGHT_J:
                aictrl_a |= DAC33_AFMT_RIGHT_J;
@@ -1066,7 +1063,7 @@ static void dac33_init_chip(struct snd_soc_codec *codec)
 {
        /* 44-46: DAC Control Registers */
        /* A : DAC sample rate Fsref/1.5 */
-       dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(1));
+       dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
        /* B : DAC src=normal, not muted */
        dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
                                             DAC33_DACSRCL_LEFT);
index 958d49c969ac3d78696f2276f131d9b13ba71d9f..569ad8758a84bcbe0f02dd3b27bdd28d959b8285 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/i2c.h>
 #include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 #include <sound/tpa6130a2-plat.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
index 6f5d4af200526ed5477f1870b9c48a048aa2865b..520ffd6536c3c44a46fcff4cc811d4408f234fc2 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/i2c/twl.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 3e99fe5131ddff15fe308968412c7da8977b2ba6..a8dcd5a5bbcb2e0ac743e95a731ecb4c7e1c123f 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/module.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
index 217b02680597ef14b7eabd2771e17e528c84345b..002e289d1255f5044afb6c697edd7923effb352f 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/firmware.h>
@@ -32,6 +31,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index df2c6d9617fb78d07b2bc3b4edec741f8b808339..2e0772f9c456fe63d6cb8c5ae0f17bffbb6a1cf4 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/platform_device.h>
index b432f4d4a3247bb4df2763bcc5c00a97779a7ed1..6acc885cf9b7489741a354f3f83ccdfb93dd5e78 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
index af8cb6995a1f5d053ffda2e348c6cf489270d5f2..9000b1d19afbc2ab18f03ca6dab0227cdd472d49 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index d3a61d7ea0c509414e4a113def31b547fba33d6b..19cd47293424b19965a50ff4ca7388ed30e81585 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index d077df6f5e7515a6cb98ab727bf83d4529b05274..8cc9042965eb070afeba101cdd3e578e31519bff 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
index 24a35603bcf732d563034f4cd2491a78a76a0d20..8ca3812f2f2f1e77eb6e4872d3e7ad4c39e43d93 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 63a254e293cae381d3f9c6c2d27ec985fd1d35ad..1072621e93fdee9de08476cfcd915fed2c792999 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
index 3fb653ba363a1da03ab8d702ab6add9b45e4cb34..07adc375a706f4c14cee3ca4effbe74944ccc00b 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 5a2619dbf283b8a6195eb912dae6fb2c9ae96149..e7c6bf163185e3810425cf42c723d499f2e02bf6 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
index 475c67ac7818e39e417d21c9a43fb96ab0833841..2916ed4d384449a55da18a294ec2259cb9845683 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index c2444e7c848025524ada66f2ef8631112d15f908..613199a0f799e60bc8327017c9c7aaf09558b2dc 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 44e7d9d82f87d7b7e658272fc7fcedd67129c832..60b1b3e1094b55aca16f04d474e3dc072a0a7d32 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index dbc368c08263adab922dfbbd62570cb73409926f..b7fd96adac643043a3e4bfe0b45c984112bdbc77 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 3595bd57c4eb8911bf7a63a8122028a746aaf931..fa5f99fde68bfcc7ca19b62e874589742acd0c2b 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 593e47d0e0eb87e8e97d384eb434a456242e842c..c6f0abcc57113449228f6a4ac7c754f96c3d0a23 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 31e39ffd1d8e84f27ae1f0daf5ca17e22c14331a..0c04b476487f40f85cb1358ad7ba829c8b89b772 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 615dab2b62ef46a09841b0f5cf5edea2f379fa72..c8d7a809af4d157ba9711362aa86160db8033ead 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index d07bcc1e1c603ed9a86e06c2e293bdb51358d271..f1e63e01b04d3621ef2124946b954d92cac7f525 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index d2342c5e0425f2e861d8861d80cffd2a3b81ef1a..50634ab76a5cde6be72d09070415d1a329c3698e 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index d9540d55fc89b6b96ec108f896cc7572f8c74176..a65b781af512b1d1c794fdd2c5a5ac22c2f442ca 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index ee637af4737a039c252c82c287f5c37e22b4ee37..69708c4cc004c9de2abb1f6bdd781c0634307d93 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 28bb59ea6ea1597cae32396fd18e65f8bcbe2338..526f56b0906663fe681ec970bcd3d24a44a4b7a6 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 2862e4dced27fc2ff20a338c3f4461674a4dcf21..bb18c3ecfeb931f314262ea77945810f13a3d09c 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/spi/spi.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 056b787b6ee09d1f9948c67d0d7acb2d9abbf887..831f4730bfd5bff798ee60e63d54e8f0b0b5f9ff 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index bf022f68b84f114ccc44835910df1315bca3fe70..03e8b1a6a56ca48645b0986ac5afbfd4dc16565b 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/i2c.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 29f3771c33a4448838b3934b9f7a430be737e142..9da0724cd47aff5c26457e4ee9b6ef27a1c12c8d 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -3007,34 +3008,39 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_OFF:
-               /* Switch over to startup biases */
-               snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
-                                   WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
-                                   WM8994_VMID_BUF_ENA |
-                                   WM8994_VMID_RAMP_MASK,
-                                   WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
-                                   WM8994_VMID_BUF_ENA |
-                                   (1 << WM8994_VMID_RAMP_SHIFT));
-
-               /* Disable main biases */
-               snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
-                                   WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0);
+               if (codec->bias_level == SND_SOC_BIAS_STANDBY) {
+                       /* Switch over to startup biases */
+                       snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+                                           WM8994_BIAS_SRC |
+                                           WM8994_STARTUP_BIAS_ENA |
+                                           WM8994_VMID_BUF_ENA |
+                                           WM8994_VMID_RAMP_MASK,
+                                           WM8994_BIAS_SRC |
+                                           WM8994_STARTUP_BIAS_ENA |
+                                           WM8994_VMID_BUF_ENA |
+                                           (1 << WM8994_VMID_RAMP_SHIFT));
 
-               /* Discharge line */
-               snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
-                                   WM8994_LINEOUT1_DISCH |
-                                   WM8994_LINEOUT2_DISCH,
-                                   WM8994_LINEOUT1_DISCH |
-                                   WM8994_LINEOUT2_DISCH);
+                       /* Disable main biases */
+                       snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+                                           WM8994_BIAS_ENA |
+                                           WM8994_VMID_SEL_MASK, 0);
 
-               msleep(5);
+                       /* Discharge line */
+                       snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
+                                           WM8994_LINEOUT1_DISCH |
+                                           WM8994_LINEOUT2_DISCH,
+                                           WM8994_LINEOUT1_DISCH |
+                                           WM8994_LINEOUT2_DISCH);
 
-               /* Switch off startup biases */
-               snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
-                                   WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
-                                   WM8994_VMID_BUF_ENA |
-                                   WM8994_VMID_RAMP_MASK, 0);
+                       msleep(5);
 
+                       /* Switch off startup biases */
+                       snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+                                           WM8994_BIAS_SRC |
+                                           WM8994_STARTUP_BIAS_ENA |
+                                           WM8994_VMID_BUF_ENA |
+                                           WM8994_VMID_RAMP_MASK, 0);
+               }
                break;
        }
        codec->bias_level = level;
@@ -3401,7 +3407,7 @@ struct snd_soc_dai wm8994_dai[] = {
                        .rates = WM8994_RATES,
                        .formats = WM8994_FORMATS,
                },
-               .playback = {
+               .capture = {
                        .stream_name = "AIF3 Capture",
                        .channels_min = 2,
                        .channels_max = 2,
@@ -3730,11 +3736,12 @@ static int wm8994_codec_probe(struct platform_device *pdev)
        case 3:
                wm8994->hubs.dcs_codes = -5;
                wm8994->hubs.hp_startup_mode = 1;
+               wm8994->hubs.dcs_readback_mode = 1;
                break;
        default:
+               wm8994->hubs.dcs_readback_mode = 1;
                break;
        }
-                          
 
        /* Remember if AIFnLRCLK is configured as a GPIO.  This should be
         * configured on init - if a system wants to do this dynamically
index c468497314ba4291314e856e26d3bb50c9c9b5b7..3a184fcb702b513cadc18969cc0387f2b246da2d 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index ec54c6da9856e58dab9d34163f0d57565b9d511f..8793341849d1bafdc2e13f1c7564bd655cf440fe 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
index e237bf615129cb7e32799f85762842bd683898a4..2f48a8aae22c0c5f72410a20f691b07345fb678b 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
index ceb86b4ddb25286076d00fb5fc7aeffce9e234bc..2fca514fde5851ea5d7462962b41ef7776ea40e8 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/device.h>
 #include <sound/core.h>
index 0ad9f5d536c67bf89afe1172ef863cff2fdfd6d0..e1f225a3ac46fbd2869378b273dcc32fa9319aca 100644 (file)
@@ -62,21 +62,27 @@ static const char *speaker_mode_text[] = {
 static const struct soc_enum speaker_mode =
        SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text);
 
-static void wait_for_dc_servo(struct snd_soc_codec *codec)
+static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
 {
        unsigned int reg;
        int count = 0;
+       unsigned int val;
+
+       val = op | WM8993_DCS_ENA_CHAN_0 | WM8993_DCS_ENA_CHAN_1;
+
+       /* Trigger the command */
+       snd_soc_write(codec, WM8993_DC_SERVO_0, val);
 
        dev_dbg(codec->dev, "Waiting for DC servo...\n");
 
        do {
                count++;
                msleep(1);
-               reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0);
+               reg = snd_soc_read(codec, WM8993_DC_SERVO_0);
                dev_dbg(codec->dev, "DC servo: %x\n", reg);
-       } while (reg & WM8993_DCS_DATAPATH_BUSY);
+       } while (reg & op && count < 400);
 
-       if (reg & WM8993_DCS_DATAPATH_BUSY)
+       if (reg & op)
                dev_err(codec->dev, "Timed out waiting for DC Servo\n");
 }
 
@@ -86,51 +92,58 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec)
 static void calibrate_dc_servo(struct snd_soc_codec *codec)
 {
        struct wm_hubs_data *hubs = codec->private_data;
-       u16 reg, dcs_cfg;
+       u16 reg, reg_l, reg_r, dcs_cfg;
 
        /* Set for 32 series updates */
        snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
                            WM8993_DCS_SERIES_NO_01_MASK,
                            32 << WM8993_DCS_SERIES_NO_01_SHIFT);
-
-       /* Enable the DC servo.  Write all bits to avoid triggering startup
-        * or write calibration.
-        */
-       snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
-                           0xFFFF,
-                           WM8993_DCS_ENA_CHAN_0 |
-                           WM8993_DCS_ENA_CHAN_1 |
-                           WM8993_DCS_TRIG_SERIES_1 |
-                           WM8993_DCS_TRIG_SERIES_0);
-
-       wait_for_dc_servo(codec);
+       wait_for_dc_servo(codec,
+                         WM8993_DCS_TRIG_SERIES_0 | WM8993_DCS_TRIG_SERIES_1);
 
        /* Apply correction to DC servo result */
        if (hubs->dcs_codes) {
                dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
                        hubs->dcs_codes);
 
+               /* Different chips in the family support different
+                * readback methods.
+                */
+               switch (hubs->dcs_readback_mode) {
+               case 0:
+                       reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
+                               & WM8993_DCS_INTEG_CHAN_0_MASK;;
+                       reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
+                               & WM8993_DCS_INTEG_CHAN_1_MASK;
+                       break;
+               case 1:
+                       reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
+                       reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
+                               >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
+                       reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
+                       break;
+               default:
+                       WARN(1, "Unknown DCS readback method");
+                       break;
+               }
+
                /* HPOUT1L */
-               reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) &
-                       WM8993_DCS_INTEG_CHAN_0_MASK;;
-               reg += hubs->dcs_codes;
-               dcs_cfg = reg << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
+               if (reg_l + hubs->dcs_codes > 0 &&
+                   reg_l + hubs->dcs_codes < 0xff)
+                       reg_l += hubs->dcs_codes;
+               dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
 
                /* HPOUT1R */
-               reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) &
-                       WM8993_DCS_INTEG_CHAN_1_MASK;
-               reg += hubs->dcs_codes;
-               dcs_cfg |= reg;
+               if (reg_r + hubs->dcs_codes > 0 &&
+                   reg_r + hubs->dcs_codes < 0xff)
+                       reg_r += hubs->dcs_codes;
+               dcs_cfg |= reg_r;
 
                /* Do it */
                snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg);
-               snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
-                                   WM8993_DCS_TRIG_DAC_WR_0 |
-                                   WM8993_DCS_TRIG_DAC_WR_1,
-                                   WM8993_DCS_TRIG_DAC_WR_0 |
-                                   WM8993_DCS_TRIG_DAC_WR_1);
-
-               wait_for_dc_servo(codec);
+               wait_for_dc_servo(codec,
+                                 WM8993_DCS_TRIG_DAC_WR_0 |
+                                 WM8993_DCS_TRIG_DAC_WR_1);
        }
 }
 
@@ -141,10 +154,16 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
                               struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct wm_hubs_data *hubs = codec->private_data;
        int ret;
 
        ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
 
+       /* If we're applying an offset correction then updating the
+        * callibration would be likely to introduce further offsets. */
+       if (hubs->dcs_codes)
+               return ret;
+
        /* Only need to do this if the outputs are active */
        if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1)
            & (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA))
index 420104fe9c90467a1c9027c3e9bc234cab28ecc8..e51c16683589ffb612f3ec58761f01ea24c7223e 100644 (file)
@@ -21,6 +21,7 @@ extern const unsigned int wm_hubs_spkmix_tlv[];
 /* This *must* be the first element of the codec->private_data struct */
 struct wm_hubs_data {
        int dcs_codes;
+       int dcs_readback_mode;
        int hp_startup_mode;
 };
 
index 6362ca05506e0e011312ff023446b2eb0a7da440..adadcd3aa1b1b20a2a2b50c84965deeff8fdf2f7 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/clk.h>
@@ -585,7 +586,8 @@ static int davinci_i2s_probe(struct platform_device *pdev)
        dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
 
        davinci_i2s_dai.private_data = dev;
-       davinci_i2s_dai.dma_data = dev->dma_params;
+       davinci_i2s_dai.capture.dma_data = dev->dma_params;
+       davinci_i2s_dai.playback.dma_data = dev->dma_params;
        ret = snd_soc_register_dai(&davinci_i2s_dai);
        if (ret != 0)
                goto err_free_mem;
index ab6518d86f1886c14b18fe4c436cba2a9d6c2f07..79f0f4ad242c1be8bfb00694ff1e011016942f90 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/clk.h>
@@ -917,7 +918,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
 
        dma_data->channel = res->start;
        davinci_mcasp_dai[pdata->op_mode].private_data = dev;
-       davinci_mcasp_dai[pdata->op_mode].dma_data = dev->dma_params;
+       davinci_mcasp_dai[pdata->op_mode].capture.dma_data = dev->dma_params;
+       davinci_mcasp_dai[pdata->op_mode].playback.dma_data = dev->dma_params;
        davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
        ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
 
index 80c7fdf2f521542d83babc9855d3a362de545a19..2dc406f42fe7f5ca5f92a86649b23a439fba18cc 100644 (file)
@@ -649,8 +649,10 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
        struct snd_pcm_hardware *ppcm;
        int ret = 0;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->dma_data;
+       struct davinci_pcm_dma_params *pa;
        struct davinci_pcm_dma_params *params;
+
+       pa = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
        if (!pa)
                return -ENODEV;
        params = &pa[substream->stream];
index b1a3a278819fe6fa16a1a14d38b02221a05517e2..410c7496a18dd295cec46770176ba960ca46686b 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/gfp.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
index 93f0f38a32c99fb26299c288d3ce0ca442f55914..762c1b8e8e4e078e48efede6dfc52b5a81eb4fc4 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/interrupt.h>
 #include <linux/device.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
index 30ed568afb2ef5c24316e1fe1ae24c34a795adac..d639e55c51241dad15eb984815c69f9461a26797 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/slab.h>
 
 #include <sound/soc.h>
 
index ef67d1cdffe7e4409c28f889a660351c8bfc2da9..83de1c81c8c410e580ae9b2b286cf8a99faca4b0 100644 (file)
@@ -9,6 +9,7 @@
  * express or implied.
  */
 
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/of_device.h>
index 8bc5cd9e972fc89a2223dc32f01c42cbffd15fea..3bc13fd890969efda650ada0d28a68d72b934b3e 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/bitops.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index c7d0fd9b7de884522ee02f1ef838dccd8ed53269..7174b4c710de4451f974214558af0dc27516457d 100644 (file)
@@ -1,6 +1,6 @@
 config SND_IMX_SOC
        tristate "SoC Audio for Freescale i.MX CPUs"
-       depends on ARCH_MXC && BROKEN
+       depends on ARCH_MXC
        select SND_PCM
        select FIQ
        select SND_SOC_AC97_BUS
index 19452e44afdc7190c4ba7995d4a3c802f6d35bde..2b31ac673ea4d95a05b986d7f6b5059d4e5cd615 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <sound/core.h>
 #include <sound/initval.h>
@@ -70,7 +71,12 @@ static void imx_ssi_dma_callback(int channel, void *data)
 
 static void snd_imx_dma_err_callback(int channel, void *data, int err)
 {
-       pr_err("DMA error callback called\n");
+       struct snd_pcm_substream *substream = data;
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
+       int ret;
 
        pr_err("DMA timeout on channel %d -%s%s%s%s\n",
                 channel,
@@ -78,16 +84,26 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err)
                 err & IMX_DMA_ERR_REQUEST ?  " request" : "",
                 err & IMX_DMA_ERR_TRANSFER ? " transfer" : "",
                 err & IMX_DMA_ERR_BUFFER ?   " buffer" : "");
+
+       imx_dma_disable(iprtd->dma);
+       ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
+                       IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
+                       substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+                       DMA_MODE_WRITE : DMA_MODE_READ);
+       if (!ret)
+               imx_dma_enable(iprtd->dma);
 }
 
 static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
+       struct imx_pcm_dma_params *dma_params;
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct imx_pcm_runtime_data *iprtd = runtime->private_data;
        int ret;
 
+       dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream);
+
        iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH);
        if (iprtd->dma < 0) {
                pr_err("Failed to claim the audio DMA\n");
@@ -192,10 +208,12 @@ static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
+       struct imx_pcm_dma_params *dma_params;
        struct imx_pcm_runtime_data *iprtd = runtime->private_data;
        int err;
 
+       dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream);
+
        iprtd->substream = substream;
        iprtd->buf = (unsigned int *)substream->dma_buffer.area;
        iprtd->period_cnt = 0;
index d9cb9849b033e04100125c50b47fa3ebb2362feb..6b518e07eea9ce46d4f74a092e11bff816d9754b 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <sound/core.h>
 #include <sound/initval.h>
@@ -38,23 +39,24 @@ struct imx_pcm_runtime_data {
        unsigned long offset;
        unsigned long last_offset;
        unsigned long size;
-       struct timer_list timer;
-       int poll_time;
+       struct hrtimer hrt;
+       int poll_time_ns;
+       struct snd_pcm_substream *substream;
+       atomic_t running;
 };
 
-static inline void imx_ssi_set_next_poll(struct imx_pcm_runtime_data *iprtd)
+static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
 {
-       iprtd->timer.expires = jiffies + iprtd->poll_time;
-}
-
-static void imx_ssi_timer_callback(unsigned long data)
-{
-       struct snd_pcm_substream *substream = (void *)data;
+       struct imx_pcm_runtime_data *iprtd =
+               container_of(hrt, struct imx_pcm_runtime_data, hrt);
+       struct snd_pcm_substream *substream = iprtd->substream;
        struct snd_pcm_runtime *runtime = substream->runtime;
-       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
        struct pt_regs regs;
        unsigned long delta;
 
+       if (!atomic_read(&iprtd->running))
+               return HRTIMER_NORESTART;
+
        get_fiq_regs(&regs);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -71,16 +73,14 @@ static void imx_ssi_timer_callback(unsigned long data)
 
        /* If we've transferred at least a period then report it and
         * reset our poll time */
-       if (delta >= runtime->period_size) {
+       if (delta >= iprtd->period) {
                snd_pcm_period_elapsed(substream);
                iprtd->last_offset = iprtd->offset;
-
-               imx_ssi_set_next_poll(iprtd);
        }
 
-       /* Restart the timer; if we didn't report we'll run on the next tick */
-       add_timer(&iprtd->timer);
+       hrtimer_forward_now(hrt, ns_to_ktime(iprtd->poll_time_ns));
 
+       return HRTIMER_RESTART;
 }
 
 static struct fiq_handler fh = {
@@ -98,8 +98,8 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
        iprtd->period = params_period_bytes(params) ;
        iprtd->offset = 0;
        iprtd->last_offset = 0;
-       iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params));
-
+       iprtd->poll_time_ns = 1000000000 / params_rate(params) *
+                               params_period_size(params);
        snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
 
        return 0;
@@ -134,8 +134,9 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               imx_ssi_set_next_poll(iprtd);
-               add_timer(&iprtd->timer);
+               atomic_set(&iprtd->running, 1);
+               hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns),
+                     HRTIMER_MODE_REL);
                if (++fiq_enable == 1)
                        enable_fiq(imx_pcm_fiq);
 
@@ -144,11 +145,11 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_SUSPEND:
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               del_timer(&iprtd->timer);
+               atomic_set(&iprtd->running, 0);
+
                if (--fiq_enable == 0)
                        disable_fiq(imx_pcm_fiq);
 
-
                break;
        default:
                return -EINVAL;
@@ -179,7 +180,7 @@ static struct snd_pcm_hardware snd_imx_hardware = {
        .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
        .period_bytes_min = 128,
        .period_bytes_max = 16 * 1024,
-       .periods_min = 2,
+       .periods_min = 4,
        .periods_max = 255,
        .fifo_size = 0,
 };
@@ -193,9 +194,11 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
        iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
        runtime->private_data = iprtd;
 
-       init_timer(&iprtd->timer);
-       iprtd->timer.data = (unsigned long)substream;
-       iprtd->timer.function = imx_ssi_timer_callback;
+       iprtd->substream = substream;
+
+       atomic_set(&iprtd->running, 0);
+       hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       iprtd->hrt.function = snd_hrtimer_callback;
 
        ret = snd_pcm_hw_constraint_integer(substream->runtime,
                        SNDRV_PCM_HW_PARAM_PERIODS);
@@ -211,7 +214,8 @@ static int snd_imx_close(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct imx_pcm_runtime_data *iprtd = runtime->private_data;
 
-       del_timer_sync(&iprtd->timer);
+       hrtimer_cancel(&iprtd->hrt);
+
        kfree(iprtd);
 
        return 0;
index 56f46a75d2972515f19e3bb89c8bf6f50960375d..80b4fee2442b8ac0d4b1eb7306f6304062c09e4d 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <sound/core.h>
 #include <sound/initval.h>
@@ -234,17 +235,20 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
                             struct snd_soc_dai *cpu_dai)
 {
        struct imx_ssi *ssi = cpu_dai->private_data;
+       struct imx_pcm_dma_params *dma_data;
        u32 reg, sccr;
 
        /* Tx/Rx config */
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                reg = SSI_STCCR;
-               cpu_dai->dma_data = &ssi->dma_params_tx;
+               dma_data = &ssi->dma_params_tx;
        } else {
                reg = SSI_SRCCR;
-               cpu_dai->dma_data = &ssi->dma_params_rx;
+               dma_data = &ssi->dma_params_rx;
        }
 
+       snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
+
        sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK;
 
        /* DAI data (word) size */
@@ -652,7 +656,8 @@ static int imx_ssi_probe(struct platform_device *pdev)
        dai->private_data = ssi;
 
        if ((cpu_is_mx27() || cpu_is_mx21()) &&
-                       !(ssi->flags & IMX_SSI_USE_AC97)) {
+                       !(ssi->flags & IMX_SSI_USE_AC97) &&
+                       (ssi->flags & IMX_SSI_DMA)) {
                ssi->flags |= IMX_SSI_DMA;
                platform = imx_ssi_dma_mx2_init(pdev, ssi);
        } else
index ad8df6cfae883120daa6c2b7389aec22ccd72e0b..1dab4c14874d45289b2a601a001f9c5fbb2ebf5a 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/wait.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/err.h>
 #include <linux/clk.h>
index e814a9591f78057553e877549a40e31f3522de66..8ad9dc9010078f3b07d744a04030ad31bab7bf8b 100644 (file)
@@ -297,7 +297,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
        omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode;
        omap_mcbsp_dai_dma_params[id][substream->stream].data_type =
                                                        OMAP_DMA_DATA_TYPE_S16;
-       cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream];
+
+       snd_soc_dai_set_dma_data(cpu_dai, substream,
+               &omap_mcbsp_dai_dma_params[id][substream->stream]);
 
        if (mcbsp_data->configured) {
                /* McBSP already configured by another stream */
index 25f19e4728bf50df3616075ba28d7666ed455fd6..b7f4f7e015f3f4ef4c0dc91f46e1e4573ce39259 100644 (file)
@@ -150,7 +150,8 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
        int stream = substream->stream;
        int channels, err, link_mask = 0;
 
-       cpu_dai->dma_data = &omap_mcpdm_dai_dma_params[stream];
+       snd_soc_dai_set_dma_data(cpu_dai, substream,
+                                &omap_mcpdm_dai_dma_params[stream]);
 
        channels = params_channels(params);
        switch (channels) {
index 825db385f01f16d3b0f64a21fbfc3238c801e873..1e521904ea64efabd199c1d334adb2c5a247c799 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -60,12 +61,11 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data)
        struct omap_runtime_data *prtd = runtime->private_data;
        unsigned long flags;
 
-       if ((cpu_is_omap1510()) &&
-                       (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) {
+       if ((cpu_is_omap1510())) {
                /*
                 * OMAP1510 doesn't fully support DMA progress counter
                 * and there is no software emulation implemented yet,
-                * so have to maintain our own playback progress counter
+                * so have to maintain our own progress counters
                 * that can be used by omap_pcm_pointer() instead.
                 */
                spin_lock_irqsave(&prtd->lock, flags);
@@ -100,9 +100,11 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct omap_runtime_data *prtd = runtime->private_data;
-       struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data;
+       struct omap_pcm_dma_data *dma_data;
        int err = 0;
 
+       dma_data = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
+
        /* return if this is a bufferless transfer e.g.
         * codec <--> BT codec or GSM modem -- lg FIXME */
        if (!dma_data)
@@ -189,8 +191,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
        dma_params.frame_count  = runtime->periods;
        omap_set_dma_params(prtd->dma_ch, &dma_params);
 
-       if ((cpu_is_omap1510()) &&
-                       (substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
+       if ((cpu_is_omap1510()))
                omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ |
                              OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
        else
@@ -248,14 +249,15 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
        dma_addr_t ptr;
        snd_pcm_uframes_t offset;
 
-       if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+       if (cpu_is_omap1510()) {
+               offset = prtd->period_index * runtime->period_size;
+       } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
                ptr = omap_get_dma_dst_pos(prtd->dma_ch);
                offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
-       } else if (!(cpu_is_omap1510())) {
+       } else {
                ptr = omap_get_dma_src_pos(prtd->dma_ch);
                offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
-       } else
-               offset = prtd->period_index * runtime->period_size;
+       }
 
        if (offset >= runtime->buffer_size)
                offset = 0;
index 9e95e5117c88f8c6a95cbfe25e60cd66f22c92e2..544fd9566f4d11e4ffc764271554eae3e0f606d0 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/io.h>
@@ -121,10 +122,9 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
                ssp_disable(ssp);
        }
 
-       if (cpu_dai->dma_data) {
-               kfree(cpu_dai->dma_data);
-               cpu_dai->dma_data = NULL;
-       }
+       kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
+       snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
+
        return ret;
 }
 
@@ -141,10 +141,8 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
                clk_disable(ssp->clk);
        }
 
-       if (cpu_dai->dma_data) {
-               kfree(cpu_dai->dma_data);
-               cpu_dai->dma_data = NULL;
-       }
+       kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
+       snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
 }
 
 #ifdef CONFIG_PM
@@ -569,19 +567,23 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
        u32 sspsp;
        int width = snd_pcm_format_physical_width(params_format(params));
        int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf;
+       struct pxa2xx_pcm_dma_params *dma_data;
+
+       dma_data = snd_soc_dai_get_dma_data(dai, substream);
 
        /* generate correct DMA params */
-       if (cpu_dai->dma_data)
-               kfree(cpu_dai->dma_data);
+       kfree(dma_data);
 
        /* Network mode with one active slot (ttsa == 1) can be used
         * to force 16-bit frame width on the wire (for S16_LE), even
         * with two channels. Use 16-bit DMA transfers for this case.
         */
-       cpu_dai->dma_data = ssp_get_dma_params(ssp,
+       dma_data = ssp_get_dma_params(ssp,
                        ((chn == 2) && (ttsa != 1)) || (width == 32),
                        substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
 
+       snd_soc_dai_set_dma_data(dai, substream, dma_data);
+
        /* we can only change the settings if the port is not in use */
        if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
                return 0;
index e9ae7b3a7e006cc33cc74e128f9f1429f3ebc9ac..d314115e3dd726750afbb8706b72cc51fbb3104b 100644 (file)
@@ -122,11 +122,14 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       struct pxa2xx_pcm_dma_params *dma_data;
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_out;
+               dma_data = &pxa2xx_ac97_pcm_stereo_out;
        else
-               cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_in;
+               dma_data = &pxa2xx_ac97_pcm_stereo_in;
+
+       snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
 
        return 0;
 }
@@ -137,11 +140,14 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       struct pxa2xx_pcm_dma_params *dma_data;
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
+               dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
        else
-               cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_in;
+               dma_data = &pxa2xx_ac97_pcm_aux_mono_in;
+
+       snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
 
        return 0;
 }
@@ -156,7 +162,8 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                return -ENODEV;
        else
-               cpu_dai->dma_data = &pxa2xx_ac97_pcm_mic_mono_in;
+               snd_soc_dai_set_dma_data(cpu_dai, substream,
+                                        &pxa2xx_ac97_pcm_mic_mono_in);
 
        return 0;
 }
index 6b8f655d1ad826d7556317b17e1f1074fa7e49f3..c1a5275721e4f0eb2812842d31555c84b16f206c 100644 (file)
@@ -164,6 +164,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       struct pxa2xx_pcm_dma_params *dma_data;
 
        BUG_ON(IS_ERR(clk_i2s));
        clk_enable(clk_i2s);
@@ -171,9 +172,11 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
        pxa_i2s_wait();
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_out;
+               dma_data = &pxa2xx_i2s_pcm_stereo_out;
        else
-               cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_in;
+               dma_data = &pxa2xx_i2s_pcm_stereo_in;
+
+       snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
 
        /* is port used by another stream */
        if (!(SACR0 & SACR0_ENB)) {
index d38e39575f510a6519b0b115189848012dc7a73a..adc7e6f15f9367b5acbf16c02f633af3583a16da 100644 (file)
@@ -25,9 +25,11 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct pxa2xx_runtime_data *prtd = runtime->private_data;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data;
+       struct pxa2xx_pcm_dma_params *dma;
        int ret;
 
+       dma = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
+
        /* return if this is a bufferless transfer e.g.
         * codec <--> BT codec or GSM modem -- lg FIXME */
        if (!dma)
index ee8ed9d7e7033318ae563fcc7cf827c65d08d427..ecf4fd04ae9651c2a264c9428fcf6d1caae6777f 100644 (file)
@@ -224,11 +224,14 @@ static int s3c_ac97_hw_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       struct s3c_dma_params *dma_data;
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               cpu_dai->dma_data = &s3c_ac97_pcm_out;
+               dma_data = &s3c_ac97_pcm_out;
        else
-               cpu_dai->dma_data = &s3c_ac97_pcm_in;
+               dma_data = &s3c_ac97_pcm_in;
+
+       snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
 
        return 0;
 }
@@ -238,8 +241,8 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
 {
        u32 ac_glbctrl;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       int channel = ((struct s3c_dma_params *)
-                 rtd->dai->cpu_dai->dma_data)->channel;
+       struct s3c_dma_params *dma_data =
+               snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
 
        ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
        if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
@@ -265,7 +268,7 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
 
        writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
 
-       s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+       s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
 
        return 0;
 }
@@ -280,7 +283,7 @@ static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream,
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                return -ENODEV;
        else
-               cpu_dai->dma_data = &s3c_ac97_mic_in;
+               snd_soc_dai_set_dma_data(cpu_dai, substream, &s3c_ac97_mic_in);
 
        return 0;
 }
@@ -290,8 +293,8 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
 {
        u32 ac_glbctrl;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       int channel = ((struct s3c_dma_params *)
-                 rtd->dai->cpu_dai->dma_data)->channel;
+       struct s3c_dma_params *dma_data =
+               snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
 
        ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
        ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK;
@@ -311,7 +314,7 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
 
        writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
 
-       s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+       s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
 
        return 0;
 }
index 7725e26d6c914c99ad84ce89864320c944abbd00..1b61c23ff300be0ef2c593cf5e813e20aeb2cb5d 100644 (file)
@@ -145,10 +145,12 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct s3c24xx_runtime_data *prtd = runtime->private_data;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct s3c_dma_params *dma = rtd->dai->cpu_dai->dma_data;
        unsigned long totbytes = params_buffer_bytes(params);
+       struct s3c_dma_params *dma =
+               snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
        int ret = 0;
 
+
        pr_debug("Entered %s\n", __func__);
 
        /* return if this is a bufferless transfer e.g.
index e994d8374fe62dc313aca6077e8bed20c5fb186f..88515946b6c06560810fabf8bcabd8ea560cafc2 100644 (file)
@@ -339,14 +339,17 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai_link *dai = rtd->dai;
        struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai);
+       struct s3c_dma_params *dma_data;
        u32 iismod;
 
        pr_debug("Entered %s\n", __func__);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               dai->cpu_dai->dma_data = i2s->dma_playback;
+               dma_data = i2s->dma_playback;
        else
-               dai->cpu_dai->dma_data = i2s->dma_capture;
+               dma_data = i2s->dma_capture;
+
+       snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data);
 
        /* Working copies of register */
        iismod = readl(i2s->regs + S3C2412_IISMOD);
@@ -394,8 +397,8 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
        int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
        unsigned long irqs;
        int ret = 0;
-       int channel = ((struct s3c_dma_params *)
-                 rtd->dai->cpu_dai->dma_data)->channel;
+       struct s3c_dma_params *dma_data =
+               snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
 
        pr_debug("Entered %s\n", __func__);
 
@@ -431,7 +434,7 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
                 * of the auto reload mechanism of S3C24XX.
                 * This call won't bother S3C64XX.
                 */
-               s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+               s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
 
                break;
 
index a98f40c3cd291eea98e9a4b9778d5cc5a910c401..326f0a9e7e3076ebbce6af2500c86cb56fce5f60 100644 (file)
@@ -178,6 +178,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai_link *dai = rtd->dai;
        struct s3c_pcm_info *pcm = to_info(dai->cpu_dai);
+       struct s3c_dma_params *dma_data;
        void __iomem *regs = pcm->regs;
        struct clk *clk;
        int sclk_div, sync_div;
@@ -187,9 +188,11 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
        dev_dbg(pcm->dev, "Entered %s\n", __func__);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               dai->cpu_dai->dma_data = pcm->dma_playback;
+               dma_data = pcm->dma_playback;
        else
-               dai->cpu_dai->dma_data = pcm->dma_capture;
+               dma_data = pcm->dma_capture;
+
+       snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data);
 
        /* Strictly check for sample size */
        switch (params_format(params)) {
index 0bc5950b9f0299d1dd6d7c6bdf830e2f12380747..c3ac890a3986184f86ed00a1dc300fdb10d7d258 100644 (file)
@@ -242,14 +242,17 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct s3c_dma_params *dma_data;
        u32 iismod;
 
        pr_debug("Entered %s\n", __func__);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out;
+               dma_data = &s3c24xx_i2s_pcm_stereo_out;
        else
-               rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_in;
+               dma_data = &s3c24xx_i2s_pcm_stereo_in;
+
+       snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_data);
 
        /* Working copies of register */
        iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
@@ -258,13 +261,11 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
        switch (params_format(params)) {
        case SNDRV_PCM_FORMAT_S8:
                iismod &= ~S3C2410_IISMOD_16BIT;
-               ((struct s3c_dma_params *)
-                 rtd->dai->cpu_dai->dma_data)->dma_size = 1;
+               dma_data->dma_size = 1;
                break;
        case SNDRV_PCM_FORMAT_S16_LE:
                iismod |= S3C2410_IISMOD_16BIT;
-               ((struct s3c_dma_params *)
-                 rtd->dai->cpu_dai->dma_data)->dma_size = 2;
+               dma_data->dma_size = 2;
                break;
        default:
                return -EINVAL;
@@ -280,8 +281,8 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 {
        int ret = 0;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       int channel = ((struct s3c_dma_params *)
-                 rtd->dai->cpu_dai->dma_data)->channel;
+       struct s3c_dma_params *dma_data =
+               snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
 
        pr_debug("Entered %s\n", __func__);
 
@@ -300,7 +301,7 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
                else
                        s3c24xx_snd_txctrl(1);
 
-               s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+               s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
                break;
        case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_SUSPEND:
index c5cda187ecab6d5f72285959e39e525d34f3ffb9..5b9ac1759bd26021eb8570381a5dfd2eb5d7842c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/clk.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -518,7 +519,8 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev)
 
        s6000_i2s_dai.dev = &pdev->dev;
        s6000_i2s_dai.private_data = dev;
-       s6000_i2s_dai.dma_data = &dev->dma_params;
+       s6000_i2s_dai.capture.dma_data = &dev->dma_params;
+       s6000_i2s_dai.playback.dma_data = &dev->dma_params;
 
        dev->sifbase = sifmem->start;
        dev->scbbase = mmio;
index 1d61109e09fa272e3b7e6855e8f2ba303f2e8a95..9c7f7f00cebb45706aa6c8f7302b4a371d469ceb 100644 (file)
@@ -58,13 +58,15 @@ static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct s6000_runtime_data *prtd = runtime->private_data;
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *par;
        int channel;
        unsigned int period_size;
        unsigned int dma_offset;
        dma_addr_t dma_pos;
        dma_addr_t src, dst;
 
+       par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
        period_size = snd_pcm_lib_period_bytes(substream);
        dma_offset = prtd->period * period_size;
        dma_pos = runtime->dma_addr + dma_offset;
@@ -101,7 +103,8 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data)
 {
        struct snd_pcm *pcm = data;
        struct snd_soc_pcm_runtime *runtime = pcm->private_data;
-       struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *params =
+               snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
        struct s6000_runtime_data *prtd;
        unsigned int has_xrun;
        int i, ret = IRQ_NONE;
@@ -172,11 +175,13 @@ static int s6000_pcm_start(struct snd_pcm_substream *substream)
 {
        struct s6000_runtime_data *prtd = substream->runtime->private_data;
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *par;
        unsigned long flags;
        int srcinc;
        u32 dma;
 
+       par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
        spin_lock_irqsave(&prtd->lock, flags);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -212,10 +217,12 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream)
 {
        struct s6000_runtime_data *prtd = substream->runtime->private_data;
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *par;
        unsigned long flags;
        u32 channel;
 
+       par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                channel = par->dma_out;
        else
@@ -236,9 +243,11 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream)
 static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *par;
        int ret;
 
+       par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
        ret = par->trigger(substream, cmd, 0);
        if (ret < 0)
                return ret;
@@ -275,13 +284,15 @@ static int s6000_pcm_prepare(struct snd_pcm_substream *substream)
 static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *par;
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct s6000_runtime_data *prtd = runtime->private_data;
        unsigned long flags;
        unsigned int offset;
        dma_addr_t count;
 
+       par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
        spin_lock_irqsave(&prtd->lock, flags);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -305,11 +316,12 @@ static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
 static int s6000_pcm_open(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *par;
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct s6000_runtime_data *prtd;
        int ret;
 
+       par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
        snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware);
 
        ret = snd_pcm_hw_constraint_step(runtime, 0,
@@ -364,7 +376,7 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *hw_params)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *par;
        int ret;
        ret = snd_pcm_lib_malloc_pages(substream,
                                       params_buffer_bytes(hw_params));
@@ -373,6 +385,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
                return ret;
        }
 
+       par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
        if (par->same_rate) {
                spin_lock(&par->lock);
                if (par->rate == -1 ||
@@ -392,7 +406,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
 static int s6000_pcm_hw_free(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *par =
+               snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
 
        spin_lock(&par->lock);
        par->in_use &= ~(1 << substream->stream);
@@ -417,7 +432,8 @@ static struct snd_pcm_ops s6000_pcm_ops = {
 static void s6000_pcm_free(struct snd_pcm *pcm)
 {
        struct snd_soc_pcm_runtime *runtime = pcm->private_data;
-       struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *params =
+               snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
 
        free_irq(params->irq, pcm);
        snd_pcm_lib_preallocate_free_for_all(pcm);
@@ -429,9 +445,11 @@ static int s6000_pcm_new(struct snd_card *card,
                         struct snd_soc_dai *dai, struct snd_pcm *pcm)
 {
        struct snd_soc_pcm_runtime *runtime = pcm->private_data;
-       struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+       struct s6000_pcm_dma_params *params;
        int res;
 
+       params = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
        if (!card->dev->dma_mask)
                card->dev->dma_mask = &s6000_pcm_dmamask;
        if (!card->dev->coherent_dma_mask)
index 106674979b535a54110ba0b1a0e47048178bb9e9..f07f6d8b93e14cf8f038416154361bc7b8038aee 100644 (file)
@@ -32,6 +32,7 @@ config SND_SOC_SH4_SIU
        select DMA_ENGINE
        select DMADEVICES
        select SH_DMAE
+       select FW_LOADER
 
 ##
 ## Boards
index baddb1242c715d26dfdfe08aeec0557a6f22fe7e..0d8bdf07729c559daaf7bc861f379c7b3bbddf0d 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
index 993abb730dfaf92c9d9546045eafcf448148de3c..8dc966f45c36ac3786c1506d1041a98532221425 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/list.h>
 #include <linux/pm_runtime.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/initval.h>
index 5452d19607e11adf0fe3c6361ee1769600a29656..d86ee1bfc03ae2bc4fbc5843f359c7901591d7bf 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/delay.h>
 #include <linux/firmware.h>
 #include <linux/pm_runtime.h>
+#include <linux/slab.h>
 
 #include <asm/clock.h>
 #include <asm/siu.h>
index ba7f8d05d9775b8427381220dc33a3f3292e026e..8f85719212f96283351a9381a2419afc8adf2d96 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/slab.h>
 
 #include <sound/control.h>
 #include <sound/core.h>
index c8b0556ef4316a0030a4b392226fc733dbf48877..ad7f9528d751a95e93eca755d225d92ba9cea701 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/bitops.h>
 #include <linux/debugfs.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/ac97_codec.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -1548,7 +1549,8 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
                        mutex_unlock(&codec->mutex);
                        return ret;
                }
-               if (card->dai_link[i].codec_dai->ac97_control) {
+               /* Check for codec->ac97 to handle the ac97.c fun */
+               if (card->dai_link[i].codec_dai->ac97_control && codec->ac97) {
                        snd_ac97_dev_add_pdata(codec->ac97,
                                card->dai_link[i].cpu_dai->ac97_pdata);
                }
index 6c3351095786f224448f62277d61aa583dfe000a..7c28f401f436a8a6fb499c6f788c1488b5c91512 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/platform_device.h>
 #include <linux/jiffies.h>
 #include <linux/debugfs.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 0f83bdb9b16fdf96270b6c8c3b936d2538cae260..0ec20b68e8cbbe6089c7c8b453fdf9d4d5a41507 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/gfp.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
@@ -253,3 +254,4 @@ module_exit(txx9aclc_ac97_exit);
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_DESCRIPTION("TXx9 ACLC AC97 driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:txx9aclc-ac97");
index 3175de9a92cbddc82fbbe9a1f3554159ca9a868c..95b17f731aec3a298e2f8c38638201e8eeb63ac2 100644 (file)
@@ -96,3 +96,4 @@ module_exit(txx9aclc_generic_exit);
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_DESCRIPTION("Generic TXx9 ACLC ALSA SoC audio driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:txx9aclc-generic");
index efed64b8b026c18117b6b58a49d8cfb1dd467955..49cc7ea9a51891ee5cc0de690ae368de00d030e2 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/scatterlist.h>
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 96deaefaa89756058eb68ac38ca89d9224f12f60..340a0bc5303e9264622a50e3d9d6dcf40d984310 100644 (file)
@@ -2,7 +2,6 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/sched.h>
 #include <asm/uaccess.h>
 #include "oss/sound_firmware.h"
index 8d13d933087dee455186d568e2ba4364988225ba..7dcc06512e8684c60c738f6eb7fe9eeeff499070 100644 (file)
@@ -10,7 +10,6 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
index 1d2e51b3f9184cc66881e370d73b8452ae42266c..2eab6ce48852233dbf58a44b227e7e522d8bd352 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
+#include <linux/gfp.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
index 687e6a13689e7cd912ac99ca79b9a14883931a56..58a32a10d115863661dea284024fae49102c889a 100644 (file)
@@ -19,7 +19,6 @@
  */
 
 #include <linux/wait.h>
-#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/emux_synth.h>
 #include <sound/info.h>
index 86b2c3b92df53abafa8188560c4e034ce987ea97..4328cad6c3a24cd7f5887eb6d825d52f0ad6091b 100644 (file)
@@ -17,6 +17,7 @@
 */
 
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/usb.h>
 #include <sound/core.h>
index a3f02dd974406bb60b2f10f9d7bd4108b80b589e..afc5aeb680059b6d69681bb6d5f3951d23c64102 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/gfp.h>
 #include <linux/usb.h>
 #include <sound/initval.h>
 #include <sound/core.h>
index 538e8c00d31aadac2c8555df958c1312051265b5..2f218c77fff2dd2249811a9d99141468e885dbce 100644 (file)
@@ -17,6 +17,7 @@
 */
 
 #include <linux/usb.h>
+#include <linux/gfp.h>
 #include <sound/rawmidi.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
index 2c59afd99611b363651d77afe0e0f2ef26be0ebb..9e28b20cb2ce30262ea5962890ed55cd365492f8 100644 (file)
@@ -986,6 +986,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
        DEFINE_WAIT(wait);
        long timeout = msecs_to_jiffies(50);
 
+       if (ep->umidi->disconnected)
+               return;
        /*
         * The substream buffer is empty, but some data might still be in the
         * currently active URBs, so we have to wait for those to complete.
@@ -1123,14 +1125,21 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
  * Frees an output endpoint.
  * May be called when ep hasn't been initialized completely.
  */
-static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep)
+static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep)
 {
        unsigned int i;
 
        for (i = 0; i < OUTPUT_URBS; ++i)
-               if (ep->urbs[i].urb)
+               if (ep->urbs[i].urb) {
                        free_urb_and_buffer(ep->umidi, ep->urbs[i].urb,
                                            ep->max_transfer);
+                       ep->urbs[i].urb = NULL;
+               }
+}
+
+static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep)
+{
+       snd_usbmidi_out_endpoint_clear(ep);
        kfree(ep);
 }
 
@@ -1262,15 +1271,18 @@ void snd_usbmidi_disconnect(struct list_head* p)
                                usb_kill_urb(ep->out->urbs[j].urb);
                        if (umidi->usb_protocol_ops->finish_out_endpoint)
                                umidi->usb_protocol_ops->finish_out_endpoint(ep->out);
+                       ep->out->active_urbs = 0;
+                       if (ep->out->drain_urbs) {
+                               ep->out->drain_urbs = 0;
+                               wake_up(&ep->out->drain_wait);
+                       }
                }
                if (ep->in)
                        for (j = 0; j < INPUT_URBS; ++j)
                                usb_kill_urb(ep->in->urbs[j]);
                /* free endpoints here; later call can result in Oops */
-               if (ep->out) {
-                       snd_usbmidi_out_endpoint_delete(ep->out);
-                       ep->out = NULL;
-               }
+               if (ep->out)
+                       snd_usbmidi_out_endpoint_clear(ep->out);
                if (ep->in) {
                        snd_usbmidi_in_endpoint_delete(ep->in);
                        ep->in = NULL;
index 44deb21b17770b8d063793c979fdab72a5b0ecd1..9ca9a13a78da196f62acaae7010623b14045809b 100644 (file)
@@ -16,6 +16,7 @@
  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/audio.h>
 #include <sound/core.h>
index 1879b72c40f8d0695bd98883021a84be5477f050..04aafb43a13c9fbdc5eca982cdc6d13718d5245d 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <sound/core.h>
 #include <sound/memalloc.h>
index 12ae0340adc0b37d826661bff498ed5ab954b766..c400ade3ff08b8c18d8225a9688b38f9e1c487cc 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/usb.h>
+#include <linux/gfp.h>
 
 #include "usb_stream.h"
 
index c42350eed2eb48f9963dc053a60594895f953c85..cbd37f2c76d0c6e301854dbdcdc7e00df224b1dc 100644 (file)
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/usb.h>
 #include <sound/core.h>
index 74a67a85aa81382e4f113f9ce557dbc5121ab327..5d37d1ccf813c3ff25206f0517eb87cfa4d7bf72 100644 (file)
@@ -32,6 +32,7 @@
 
 
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/usb.h>
 #include <sound/core.h>
 #include <sound/info.h>
index 9ed6c3956ca790e7afe83a5a8cb4d7cff56993d1..2a528e56afd50db1c7f7cb309e1734c826cef3c2 100644 (file)
@@ -51,6 +51,7 @@
 */
 
 #include <linux/delay.h>
+#include <linux/gfp.h>
 #include "usbusx2yaudio.c"
 
 #if defined(USX2Y_NRPACKS_VARIABLE) || (!defined(USX2Y_NRPACKS_VARIABLE) &&  USX2Y_NRPACKS == 1)
index bdd3b7ecad0a6dedbf6fc673f7daf3e40c9c49ce..bd498d496952a6f78973b0e6b8422552009770d0 100644 (file)
@@ -24,7 +24,10 @@ DOC_MAN1=$(patsubst %.txt,%.1,$(MAN1_TXT))
 DOC_MAN5=$(patsubst %.txt,%.5,$(MAN5_TXT))
 DOC_MAN7=$(patsubst %.txt,%.7,$(MAN7_TXT))
 
+# Make the path relative to DESTDIR, not prefix
+ifndef DESTDIR
 prefix?=$(HOME)
+endif
 bindir?=$(prefix)/bin
 htmldir?=$(prefix)/share/doc/perf-doc
 pdfdir?=$(prefix)/share/doc/perf-doc
@@ -32,7 +35,6 @@ mandir?=$(prefix)/share/man
 man1dir=$(mandir)/man1
 man5dir=$(mandir)/man5
 man7dir=$(mandir)/man7
-# DESTDIR=
 
 ASCIIDOC=asciidoc
 ASCIIDOC_EXTRA = --unsafe
index c9dcade068312d843904107d51beb9d9497f2c4a..5164a655c39f60b578c8642f2caabe8af66fa016 100644 (file)
@@ -1,5 +1,5 @@
 perf-annotate(1)
-==============
+================
 
 NAME
 ----
index ae525ac5a2ceabdc5612e0ecd631e475619205f5..a3dbadb26ef596d29f6e2e9c3a5326bff4dfdad7 100644 (file)
@@ -1,5 +1,5 @@
 perf-bench(1)
-============
+=============
 
 NAME
 ----
@@ -19,12 +19,12 @@ COMMON OPTIONS
 -f::
 --format=::
 Specify format style.
-Current available format styles are,
+Current available format styles are:
 
 'default'::
 Default style. This is mainly for human reading.
 ---------------------
-% perf bench sched pipe                      # with no style specify
+% perf bench sched pipe                      # with no style specified
 (executing 1000000 pipe operations between two tasks)
         Total time:5.855 sec
                 5.855061 usecs/op
@@ -79,7 +79,7 @@ options (20 sender and receiver processes per group)
 
       Total time:0.308 sec
 
-% perf bench sched messaging -t -g 20        # be multi-thread,with 20 groups
+% 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)
 
index 88bc3b5197461a099ad2a424f2a64f79abf388d7..5d1a9500277f32535fc8f95ffa12907a3720e6d5 100644 (file)
@@ -8,7 +8,7 @@ perf-buildid-cache - Manage build-id cache.
 SYNOPSIS
 --------
 [verse]
-'perf buildid-list <options>'
+'perf buildid-cache <options>'
 
 DESCRIPTION
 -----------
@@ -30,4 +30,4 @@ OPTIONS
 
 SEE ALSO
 --------
-linkperf:perf-record[1], linkperf:perf-report[1]
+linkperf:perf-record[1], linkperf:perf-report[1], linkperf:perf-buildid-list[1]
index 8974e208cba6a72e67f1c78ed0754741c23d1e52..20d97d84ea1c37164005a4f38b8af5e23104ef93 100644 (file)
@@ -1,5 +1,5 @@
 perf-diff(1)
-==============
+============
 
 NAME
 ----
diff --git a/tools/perf/Documentation/perf-inject.txt b/tools/perf/Documentation/perf-inject.txt
new file mode 100644 (file)
index 0000000..025630d
--- /dev/null
@@ -0,0 +1,35 @@
+perf-inject(1)
+==============
+
+NAME
+----
+perf-inject - Filter to augment the events stream with additional information
+
+SYNOPSIS
+--------
+[verse]
+'perf inject <options>'
+
+DESCRIPTION
+-----------
+perf-inject reads a perf-record event stream and repipes it to stdout.  At any
+point the processing code can inject other events into the event stream - in
+this case build-ids (-b option) are read and injected as needed into the event
+stream.
+
+Build-ids are just the first user of perf-inject - potentially anything that
+needs userspace processing to augment the events stream with additional
+information could make use of this facility.
+
+OPTIONS
+-------
+-b::
+--build-ids=::
+        Inject build-ids into the output stream
+-v::
+--verbose::
+       Be more verbose.
+
+SEE ALSO
+--------
+linkperf:perf-record[1], linkperf:perf-report[1], linkperf:perf-archive[1]
index eac4d852e7cdc8074d2c885c27744a99c147d9ec..a52fcde894c75ed2ab2a25cb3e8757f819b22e49 100644 (file)
@@ -1,5 +1,5 @@
 perf-kmem(1)
-==============
+============
 
 NAME
 ----
diff --git a/tools/perf/Documentation/perf-kvm.txt b/tools/perf/Documentation/perf-kvm.txt
new file mode 100644 (file)
index 0000000..d004e19
--- /dev/null
@@ -0,0 +1,68 @@
+perf-kvm(1)
+===========
+
+NAME
+----
+perf-kvm - Tool to trace/measure kvm guest os
+
+SYNOPSIS
+--------
+[verse]
+'perf kvm' [--host] [--guest] [--guestmount=<path>
+       [--guestkallsyms=<path> --guestmodules=<path> | --guestvmlinux=<path>]]
+       {top|record|report|diff|buildid-list}
+'perf kvm' [--host] [--guest] [--guestkallsyms=<path> --guestmodules=<path>
+       | --guestvmlinux=<path>] {top|record|report|diff|buildid-list}
+
+DESCRIPTION
+-----------
+There are a couple of variants of perf kvm:
+
+  'perf kvm [options] top <command>' to generates and displays
+  a performance counter profile of guest os in realtime
+  of an arbitrary workload.
+
+  'perf kvm record <command>' to record the performance couinter profile
+  of an arbitrary workload and save it into a perf data file. If both
+  --host and --guest are input, the perf data file name is perf.data.kvm.
+  If there is  no --host but --guest, the file name is perf.data.guest.
+  If there is no --guest but --host, the file name is perf.data.host.
+
+  'perf kvm report' to display the performance counter profile information
+  recorded via perf kvm record.
+
+  'perf kvm diff' to displays the performance difference amongst two perf.data
+  files captured via perf record.
+
+  'perf kvm buildid-list' to  display 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
+-------
+--host=::
+        Collect host side performance profile.
+--guest=::
+        Collect guest side performance profile.
+--guestmount=<path>::
+       Guest os root file system mount directory. Users mounts guest os
+        root directories under <path> by a specific filesystem access method,
+       typically, sshfs. For example, start 2 guest os. The one's pid is 8888
+       and the other's is 9999.
+        #mkdir ~/guestmount; cd ~/guestmount
+        #sshfs -o allow_other,direct_io -p 5551 localhost:/ 8888/
+        #sshfs -o allow_other,direct_io -p 5552 localhost:/ 9999/
+        #perf kvm --host --guest --guestmount=~/guestmount top
+--guestkallsyms=<path>::
+        Guest os /proc/kallsyms file copy. 'perf' kvm' reads it to get guest
+       kernel symbols. Users copy it out from guest os.
+--guestmodules=<path>::
+       Guest os /proc/modules file copy. 'perf' kvm' reads it to get guest
+       kernel module information. Users copy it out from guest os.
+--guestvmlinux=<path>::
+       Guest os kernel vmlinux.
+
+SEE ALSO
+--------
+linkperf:perf-top[1], linkperf:perf-record[1], linkperf:perf-report[1],
+linkperf:perf-diff[1], linkperf:perf-buildid-list[1]
index 8290b94226687f8f3d4b8700419519879bedbd78..43e3dd284b90f73bc76d28e6fa738ff295482f41 100644 (file)
@@ -15,6 +15,35 @@ DESCRIPTION
 This command displays the symbolic event types which can be selected in the
 various perf commands with the -e option.
 
+RAW HARDWARE EVENT DESCRIPTOR
+-----------------------------
+Even when an event is not available in a symbolic form within perf right now,
+it can be encoded in a per processor specific way.
+
+For instance For x86 CPUs NNN represents the raw register encoding with the
+layout of IA32_PERFEVTSELx MSRs (see [Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3B: System Programming Guide] Figure 30-1 Layout
+of IA32_PERFEVTSELx MSRs) or AMD's PerfEvtSeln (see [AMD64 Architecture Programmer’s Manual Volume 2: System Programming], Page 344,
+Figure 13-7 Performance Event-Select Register (PerfEvtSeln)).
+
+Example:
+
+If the Intel docs for a QM720 Core i7 describe an event as:
+
+  Event  Umask  Event Mask
+  Num.   Value  Mnemonic    Description                        Comment
+
+  A8H      01H  LSD.UOPS    Counts the number of micro-ops     Use cmask=1 and
+                            delivered by loop stream detector  invert to count
+                                                               cycles
+
+raw encoding of 0x1A8 can be used:
+
+ perf stat -e r1a8 -a sleep 1
+ perf record -e r1a8 ...
+
+You should refer to the processor specific documentation for getting these
+details. Some of them are referenced in the SEE ALSO section below.
+
 OPTIONS
 -------
 None
@@ -22,4 +51,6 @@ None
 SEE ALSO
 --------
 linkperf:perf-stat[1], linkperf:perf-top[1],
-linkperf:perf-record[1]
+linkperf:perf-record[1],
+http://www.intel.com/Assets/PDF/manual/253669.pdf[Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3B: System Programming Guide],
+http://support.amd.com/us/Processor_TechDocs/24593.pdf[AMD64 Architecture Programmer’s Manual Volume 2: System Programming]
index 34202b1be0bb8ffd149755b4c3091922fc77dac5..94a258c96a440b091616264fb2a7d0fd8b515967 100644 (file)
@@ -57,6 +57,14 @@ OPTIONS
 --force::
        Forcibly add events with existing name.
 
+-n::
+--dry-run::
+       Dry run. With this option, --add and --del doesn't execute actual
+       adding and removal operations.
+
+--max-probes::
+       Set the maximum number of probe points for an event. Default is 128.
+
 PROBE SYNTAX
 ------------
 Probe points are defined by following syntax.
@@ -74,13 +82,22 @@ Probe points are defined by following syntax.
 'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. Currently, event group name is set as 'probe'.
 '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. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition.  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 or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
-'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).
+'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT).
+
+PROBE ARGUMENT
+--------------
+Each probe argument follows below syntax.
+
+ [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE]
+
+'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.)
+'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo.
 
 LINE SYNTAX
 -----------
 Line range is descripted by following syntax.
 
- "FUNC[:RLN[+NUM|:RLN2]]|SRC:ALN[+NUM|:ALN2]"
+ "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]"
 
 FUNC specifies the function name of showing lines. 'RLN' is the start line
 number from function entry line, and 'RLN2' is the end line number. As same as
index fc46c0b40f6e431bd5124885544b5827a96234c8..34e255fc3e2f14d0a559efd207b6def3abfdea9e 100644 (file)
@@ -58,7 +58,7 @@ OPTIONS
 
 -f::
 --force::
-       Overwrite existing data file.
+       Overwrite existing data file. (deprecated)
 
 -c::
 --count=::
@@ -69,8 +69,8 @@ OPTIONS
        Output file name.
 
 -i::
---inherit::
-       Child tasks inherit counters.
+--no-inherit::
+       Child tasks do not inherit counters.
 -F::
 --freq=::
        Profile at this frequency.
@@ -101,7 +101,7 @@ OPTIONS
 
 -R::
 --raw-samples::
-Collect raw sample records from all opened counters (typically for tracepoint counters).
+Collect raw sample records from all opened counters (default for tracepoint counters).
 
 SEE ALSO
 --------
index 1ce79198997b00248c077a5ac46af22a0ab461fb..8417644a6166b9fcd071b88eebb9dd46f00b8a1f 100644 (file)
@@ -12,7 +12,7 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-There's four variants of perf sched:
+There are four variants of perf sched:
 
   'perf sched record <command>' to record the scheduling events
   of an arbitrary workload.
@@ -27,7 +27,7 @@ There's four variants of perf sched:
   via perf sched record. (this is done by starting up mockup threads
   that mimic the workload based on the events in the trace. These
   threads can then replay the timings (CPU runtime and sleep patterns)
-  of the workload as it occured when it was recorded - and can repeat
+  of the workload as it occurred when it was recorded - and can repeat
   it a number of times, measuring its performance.)
 
 OPTIONS
index 484080dd5b6faea6397949065f989248b9574604..2cab8e8c33d00df44dd9b215257a856751fefea9 100644 (file)
@@ -31,8 +31,8 @@ OPTIONS
         hexadecimal event descriptor.
 
 -i::
---inherit::
-        child tasks inherit counters
+--no-inherit::
+        child tasks do not inherit counters
 -p::
 --pid=<pid>::
         stat events on existing pid
diff --git a/tools/perf/Documentation/perf-test.txt b/tools/perf/Documentation/perf-test.txt
new file mode 100644 (file)
index 0000000..1c4b5f5
--- /dev/null
@@ -0,0 +1,22 @@
+perf-test(1)
+============
+
+NAME
+----
+perf-test - Runs sanity tests.
+
+SYNOPSIS
+--------
+[verse]
+'perf test <options>'
+
+DESCRIPTION
+-----------
+This command does assorted sanity tests, initially thru linked routines but
+also will look for a directory with more tests in the form of scripts.
+
+OPTIONS
+-------
+-v::
+--verbose::
+       Be more verbose.
index d729cee8d987cf1b7c025811cbb697e3fad471c6..ee6525ee6d69ada5c5cae3eb928b6626d9cfae49 100644 (file)
@@ -49,12 +49,10 @@ 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
+ # perf record -a -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 above option: -a to enable system-wide collection.
 
 The format file for the sched_wakep event defines the following fields
 (see /sys/kernel/debug/tracing/events/sched/sched_wakeup/format):
index a241aca771846dc13eaa6f72c8f285bbb2c9a8db..693be804dd3d88a167b8d3cdaf3023f5fa2cd5c2 100644 (file)
@@ -1,5 +1,5 @@
 perf-trace-python(1)
-==================
+====================
 
 NAME
 ----
@@ -93,7 +93,7 @@ don't care how it exited, so we'll use 'perf record' to record only
 the sys_enter events:
 
 ----
-# perf record -c 1 -f -a -M -R -e raw_syscalls:sys_enter
+# perf record -a -e raw_syscalls:sys_enter
 
 ^C[ perf record: Woken up 1 times to write data ]
 [ perf record: Captured and wrote 56.545 MB perf.data (~2470503 samples) ]
@@ -182,7 +182,7 @@ mean either that the record step recorded event types that it wasn't
 really interested in, or the script was run against a trace file that
 doesn't correspond to the script.
 
-The script generated by -g option option simply prints a line for each
+The script generated by -g option simply prints a line for each
 event found in the trace stream i.e. it basically just dumps the event
 and its parameter values to stdout.  The print_header() function is
 simply a utility function used for that purpose.  Let's rename the
@@ -359,7 +359,7 @@ your script:
 # cat kernel-source/tools/perf/scripts/python/bin/syscall-counts-record
 
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e raw_syscalls:sys_enter
+perf record -a -e raw_syscalls:sys_enter
 ----
 
 The 'report' script is also a shell script with the same base name as
@@ -449,12 +449,10 @@ 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
+ # perf record -a -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 above option: -a to enable system-wide collection.
 
 The format file for the sched_wakep event defines the following fields
 (see /sys/kernel/debug/tracing/events/sched/sched_wakeup/format):
@@ -584,7 +582,7 @@ 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
 
-The *autodict* function returns a special special kind of Python
+The *autodict* function returns a special kind of Python
 dictionary that implements Perl's 'autovivifying' hashes in Python
 i.e. with autovivifying hashes, you can assign nested hash values
 without having to go to the trouble of creating intermediate levels if
index 8879299cd9dfe7e274a475eb1042c63ba875b42a..122ec9dc4853d079903d566a219a9e48d8a6a465 100644 (file)
@@ -1,5 +1,5 @@
 perf-trace(1)
-==============
+=============
 
 NAME
 ----
index 2d537382c68602fa72e4b9dec7f30c20a208aec2..3d8f31ed771df18770b1e31361485d39400b5476 100644 (file)
@@ -1,3 +1,7 @@
+ifeq ("$(origin O)", "command line")
+       OUTPUT := $(O)/
+endif
+
 # The default target of this Makefile is...
 all::
 
@@ -150,10 +154,17 @@ all::
 # Define LDFLAGS=-static to build a static binary.
 #
 # Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds.
+#
+# Define NO_DWARF if you do not want debug-info analysis feature at all.
 
-PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
-       @$(SHELL_PATH) util/PERF-VERSION-GEN
--include PERF-VERSION-FILE
+$(shell sh -c 'mkdir -p $(OUTPUT)scripts/python/Perf-Trace-Util/' 2> /dev/null)
+$(shell sh -c 'mkdir -p $(OUTPUT)scripts/perl/Perf-Trace-Util/' 2> /dev/null)
+$(shell sh -c 'mkdir -p $(OUTPUT)util/scripting-engines/' 2> /dev/null)
+$(shell sh -c 'mkdir $(OUTPUT)bench' 2> /dev/null)
+
+$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
+       @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
+-include $(OUTPUT)PERF-VERSION-FILE
 
 uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
 uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not')
@@ -162,6 +173,22 @@ 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')
 
+ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
+                                 -e s/arm.*/arm/ -e s/sa110/arm/ \
+                                 -e s/s390x/s390/ -e s/parisc64/parisc/ \
+                                 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
+                                 -e s/sh[234].*/sh/ )
+
+# Additional ARCH settings for x86
+ifeq ($(ARCH),i386)
+        ARCH := x86
+endif
+ifeq ($(ARCH),x86_64)
+        ARCH := x86
+endif
+
+$(shell sh -c 'mkdir -p $(OUTPUT)arch/$(ARCH)/util/' 2> /dev/null)
+
 # CFLAGS and LDFLAGS are for the users to override from the command line.
 
 #
@@ -200,7 +227,7 @@ 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_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
 ALL_LDFLAGS = $(LDFLAGS)
 STRIP ?= strip
 
@@ -216,7 +243,10 @@ STRIP ?= strip
 # runtime figures out where they are based on the path to the executable.
 # This can help installing the suite in a relocatable way.
 
+# Make the path relative to DESTDIR, not to prefix
+ifndef DESTDIR
 prefix = $(HOME)
+endif
 bindir_relative = bin
 bindir = $(prefix)/$(bindir_relative)
 mandir = share/man
@@ -233,7 +263,6 @@ sysconfdir = $(prefix)/etc
 ETC_PERFCONFIG = etc/perfconfig
 endif
 lib = lib
-# DESTDIR=
 
 export prefix bindir sharedir sysconfdir
 
@@ -272,7 +301,7 @@ endif
 # Those must not be GNU-specific; they are shared with perl/ which may
 # be built by a different compiler. (Note that this is an artifact now
 # but it still might be nice to keep that distinction.)
-BASIC_CFLAGS = -Iutil/include
+BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include
 BASIC_LDFLAGS =
 
 # Guard against environment variables
@@ -306,7 +335,7 @@ PROGRAMS += $(EXTRA_PROGRAMS)
 #
 # Single 'perf' binary right now:
 #
-PROGRAMS += perf
+PROGRAMS += $(OUTPUT)perf
 
 # List built-in command $C whose implementation cmd_$C() is not in
 # builtin-$C.o but is linked in as part of some other command.
@@ -316,7 +345,7 @@ PROGRAMS += perf
 ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
 
 # what 'all' will build but not install in perfexecdir
-OTHER_PROGRAMS = perf$X
+OTHER_PROGRAMS = $(OUTPUT)perf$X
 
 # Set paths to tools early so that they can be used for version tests.
 ifndef SHELL_PATH
@@ -328,7 +357,7 @@ endif
 
 export PERL_PATH
 
-LIB_FILE=libperf.a
+LIB_FILE=$(OUTPUT)libperf.a
 
 LIB_H += ../../include/linux/perf_event.h
 LIB_H += ../../include/linux/rbtree.h
@@ -348,12 +377,13 @@ 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/bug.h
 LIB_H += util/include/asm/byteorder.h
+LIB_H += util/include/asm/hweight.h
 LIB_H += util/include/asm/swab.h
 LIB_H += util/include/asm/system.h
 LIB_H += util/include/asm/uaccess.h
+LIB_H += util/include/dwarf-regs.h
 LIB_H += perf.h
 LIB_H += util/cache.h
 LIB_H += util/callchain.h
@@ -373,7 +403,6 @@ LIB_H += util/header.h
 LIB_H += util/help.h
 LIB_H += util/session.h
 LIB_H += util/strbuf.h
-LIB_H += util/string.h
 LIB_H += util/strlist.h
 LIB_H += util/svghelper.h
 LIB_H += util/run-command.h
@@ -387,77 +416,83 @@ LIB_H += util/thread.h
 LIB_H += util/trace-event.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/build-id.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
-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
-LIB_OBJS += util/string.o
-LIB_OBJS += util/strlist.o
-LIB_OBJS += util/usage.o
-LIB_OBJS += util/wrapper.o
-LIB_OBJS += util/sigchain.o
-LIB_OBJS += util/symbol.o
-LIB_OBJS += util/color.o
-LIB_OBJS += util/pager.o
-LIB_OBJS += util/header.o
-LIB_OBJS += util/callchain.o
-LIB_OBJS += util/values.o
-LIB_OBJS += util/debug.o
-LIB_OBJS += util/map.o
-LIB_OBJS += util/session.o
-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-scripting.o
-LIB_OBJS += util/svghelper.o
-LIB_OBJS += util/sort.o
-LIB_OBJS += util/hist.o
-LIB_OBJS += util/probe-event.o
-LIB_OBJS += util/util.o
-
-BUILTIN_OBJS += builtin-annotate.o
-
-BUILTIN_OBJS += builtin-bench.o
+LIB_H += util/pstack.h
+LIB_H += util/cpumap.h
+
+LIB_OBJS += $(OUTPUT)util/abspath.o
+LIB_OBJS += $(OUTPUT)util/alias.o
+LIB_OBJS += $(OUTPUT)util/build-id.o
+LIB_OBJS += $(OUTPUT)util/config.o
+LIB_OBJS += $(OUTPUT)util/ctype.o
+LIB_OBJS += $(OUTPUT)util/debugfs.o
+LIB_OBJS += $(OUTPUT)util/environment.o
+LIB_OBJS += $(OUTPUT)util/event.o
+LIB_OBJS += $(OUTPUT)util/exec_cmd.o
+LIB_OBJS += $(OUTPUT)util/help.o
+LIB_OBJS += $(OUTPUT)util/levenshtein.o
+LIB_OBJS += $(OUTPUT)util/parse-options.o
+LIB_OBJS += $(OUTPUT)util/parse-events.o
+LIB_OBJS += $(OUTPUT)util/path.o
+LIB_OBJS += $(OUTPUT)util/rbtree.o
+LIB_OBJS += $(OUTPUT)util/bitmap.o
+LIB_OBJS += $(OUTPUT)util/hweight.o
+LIB_OBJS += $(OUTPUT)util/run-command.o
+LIB_OBJS += $(OUTPUT)util/quote.o
+LIB_OBJS += $(OUTPUT)util/strbuf.o
+LIB_OBJS += $(OUTPUT)util/string.o
+LIB_OBJS += $(OUTPUT)util/strlist.o
+LIB_OBJS += $(OUTPUT)util/usage.o
+LIB_OBJS += $(OUTPUT)util/wrapper.o
+LIB_OBJS += $(OUTPUT)util/sigchain.o
+LIB_OBJS += $(OUTPUT)util/symbol.o
+LIB_OBJS += $(OUTPUT)util/color.o
+LIB_OBJS += $(OUTPUT)util/pager.o
+LIB_OBJS += $(OUTPUT)util/header.o
+LIB_OBJS += $(OUTPUT)util/callchain.o
+LIB_OBJS += $(OUTPUT)util/values.o
+LIB_OBJS += $(OUTPUT)util/debug.o
+LIB_OBJS += $(OUTPUT)util/map.o
+LIB_OBJS += $(OUTPUT)util/pstack.o
+LIB_OBJS += $(OUTPUT)util/session.o
+LIB_OBJS += $(OUTPUT)util/thread.o
+LIB_OBJS += $(OUTPUT)util/trace-event-parse.o
+LIB_OBJS += $(OUTPUT)util/trace-event-read.o
+LIB_OBJS += $(OUTPUT)util/trace-event-info.o
+LIB_OBJS += $(OUTPUT)util/trace-event-scripting.o
+LIB_OBJS += $(OUTPUT)util/svghelper.o
+LIB_OBJS += $(OUTPUT)util/sort.o
+LIB_OBJS += $(OUTPUT)util/hist.o
+LIB_OBJS += $(OUTPUT)util/probe-event.o
+LIB_OBJS += $(OUTPUT)util/util.o
+LIB_OBJS += $(OUTPUT)util/cpumap.o
+
+BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
+
+BUILTIN_OBJS += $(OUTPUT)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-diff.o
-BUILTIN_OBJS += builtin-help.o
-BUILTIN_OBJS += builtin-sched.o
-BUILTIN_OBJS += builtin-buildid-list.o
-BUILTIN_OBJS += builtin-buildid-cache.o
-BUILTIN_OBJS += builtin-list.o
-BUILTIN_OBJS += builtin-record.o
-BUILTIN_OBJS += builtin-report.o
-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
-BUILTIN_OBJS += builtin-lock.o
+BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
+BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
+BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o
+
+BUILTIN_OBJS += $(OUTPUT)builtin-diff.o
+BUILTIN_OBJS += $(OUTPUT)builtin-help.o
+BUILTIN_OBJS += $(OUTPUT)builtin-sched.o
+BUILTIN_OBJS += $(OUTPUT)builtin-buildid-list.o
+BUILTIN_OBJS += $(OUTPUT)builtin-buildid-cache.o
+BUILTIN_OBJS += $(OUTPUT)builtin-list.o
+BUILTIN_OBJS += $(OUTPUT)builtin-record.o
+BUILTIN_OBJS += $(OUTPUT)builtin-report.o
+BUILTIN_OBJS += $(OUTPUT)builtin-stat.o
+BUILTIN_OBJS += $(OUTPUT)builtin-timechart.o
+BUILTIN_OBJS += $(OUTPUT)builtin-top.o
+BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
+BUILTIN_OBJS += $(OUTPUT)builtin-probe.o
+BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o
+BUILTIN_OBJS += $(OUTPUT)builtin-lock.o
+BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o
+BUILTIN_OBJS += $(OUTPUT)builtin-test.o
+BUILTIN_OBJS += $(OUTPUT)builtin-inject.o
 
 PERFLIBS = $(LIB_FILE)
 
@@ -472,6 +507,15 @@ PERFLIBS = $(LIB_FILE)
 -include config.mak.autogen
 -include config.mak
 
+ifndef NO_DWARF
+ifneq ($(shell sh -c "(echo '\#include <dwarf.h>'; echo '\#include <libdw.h>'; echo '\#include <version.h>'; echo '\#ifndef _ELFUTILS_PREREQ'; echo '\#error'; echo '\#endif'; echo 'int main(void) { Dwarf *dbg; dbg = dwarf_begin(0, DWARF_C_READ); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -I/usr/include/elfutils -ldw -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
+       msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
+       NO_DWARF := 1
+endif # Dwarf support
+endif # NO_DWARF
+
+-include arch/$(ARCH)/Makefile
+
 ifeq ($(uname_S),Darwin)
        ifndef NO_FINK
                ifeq ($(shell test -d /sw/lib && echo y),y)
@@ -488,26 +532,45 @@ ifeq ($(uname_S),Darwin)
        PTHREAD_LIBS =
 endif
 
-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 $(BITBUCKET) $(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 $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
+ifneq ($(OUTPUT),)
+       BASIC_CFLAGS += -I$(OUTPUT)
+endif
+
+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) -o $(BITBUCKET) $(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) -o $(BITBUCKET) $(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 $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
+       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) -o $(BITBUCKET) $(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 <dwarf.h>'; echo '\#include <libdw.h>'; echo 'int main(void) { Dwarf *dbg; dbg = dwarf_begin(0, DWARF_C_READ); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/elfutils -ldw -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
-       msg := $(warning No libdw.h found or old libdw.h found, disables dwarf support. Please install elfutils-devel/elfutils-dev);
-       BASIC_CFLAGS += -DNO_DWARF_SUPPORT
+ifndef NO_DWARF
+ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
+       msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
 else
-       BASIC_CFLAGS += -I/usr/include/elfutils
+       BASIC_CFLAGS += -I/usr/include/elfutils -DDWARF_SUPPORT
        EXTLIBS += -lelf -ldw
-       LIB_OBJS += util/probe-finder.o
+       LIB_OBJS += $(OUTPUT)util/probe-finder.o
+endif # PERF_HAVE_DWARF_REGS
+endif # NO_DWARF
+
+ifdef NO_NEWT
+       BASIC_CFLAGS += -DNO_NEWT_SUPPORT
+else
+ifneq ($(shell sh -c "(echo '\#include <newt.h>'; echo 'int main(void) { newtInit(); newtCls(); return newtFinished(); }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -lnewt -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
+       msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev);
+       BASIC_CFLAGS += -DNO_NEWT_SUPPORT
+else
+       # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
+       BASIC_CFLAGS += -I/usr/include/slang
+       EXTLIBS += -lnewt -lslang
+       LIB_OBJS += $(OUTPUT)util/newt.o
 endif
+endif # NO_NEWT
 
 ifndef NO_LIBPERL
 PERL_EMBED_LDOPTS = `perl -MExtUtils::Embed -e ldopts 2>/dev/null`
@@ -518,8 +581,8 @@ ifneq ($(shell sh -c "(echo '\#include <EXTERN.h>'; echo '\#include <perl.h>'; e
        BASIC_CFLAGS += -DNO_LIBPERL
 else
        ALL_LDFLAGS += $(PERL_EMBED_LDOPTS)
-       LIB_OBJS += util/scripting-engines/trace-event-perl.o
-       LIB_OBJS += scripts/perl/Perf-Trace-Util/Context.o
+       LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
+       LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
 endif
 
 ifndef NO_LIBPYTHON
@@ -527,16 +590,19 @@ PYTHON_EMBED_LDOPTS = `python-config --ldflags 2>/dev/null`
 PYTHON_EMBED_CCOPTS = `python-config --cflags 2>/dev/null`
 endif
 
-ifneq ($(shell sh -c "(echo '\#include <Python.h>'; echo 'int main(void) { Py_Initialize(); return 0; }') | $(CC) -x c - $(PYTHON_EMBED_CCOPTS) -o /dev/null $(PYTHON_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y)
+ifneq ($(shell sh -c "(echo '\#include <Python.h>'; echo 'int main(void) { Py_Initialize(); return 0; }') | $(CC) -x c - $(PYTHON_EMBED_CCOPTS) -o $(BITBUCKET) $(PYTHON_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y)
        BASIC_CFLAGS += -DNO_LIBPYTHON
 else
        ALL_LDFLAGS += $(PYTHON_EMBED_LDOPTS)
-       LIB_OBJS += util/scripting-engines/trace-event-python.o
-       LIB_OBJS += scripts/python/Perf-Trace-Util/Context.o
+       LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
+       LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
 endif
 
 ifdef NO_DEMANGLE
        BASIC_CFLAGS += -DNO_DEMANGLE
+else ifdef HAVE_CPLUS_DEMANGLE
+       EXTLIBS += -liberty
+       BASIC_CFLAGS += -DHAVE_CPLUS_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 $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd "$(QUIET_STDERR)" && echo y")
 
@@ -603,53 +669,53 @@ ifdef NO_C99_FORMAT
 endif
 ifdef SNPRINTF_RETURNS_BOGUS
        COMPAT_CFLAGS += -DSNPRINTF_RETURNS_BOGUS
-       COMPAT_OBJS += compat/snprintf.o
+       COMPAT_OBJS += $(OUTPUT)compat/snprintf.o
 endif
 ifdef FREAD_READS_DIRECTORIES
        COMPAT_CFLAGS += -DFREAD_READS_DIRECTORIES
-       COMPAT_OBJS += compat/fopen.o
+       COMPAT_OBJS += $(OUTPUT)compat/fopen.o
 endif
 ifdef NO_SYMLINK_HEAD
        BASIC_CFLAGS += -DNO_SYMLINK_HEAD
 endif
 ifdef NO_STRCASESTR
        COMPAT_CFLAGS += -DNO_STRCASESTR
-       COMPAT_OBJS += compat/strcasestr.o
+       COMPAT_OBJS += $(OUTPUT)compat/strcasestr.o
 endif
 ifdef NO_STRTOUMAX
        COMPAT_CFLAGS += -DNO_STRTOUMAX
-       COMPAT_OBJS += compat/strtoumax.o
+       COMPAT_OBJS += $(OUTPUT)compat/strtoumax.o
 endif
 ifdef NO_STRTOULL
        COMPAT_CFLAGS += -DNO_STRTOULL
 endif
 ifdef NO_SETENV
        COMPAT_CFLAGS += -DNO_SETENV
-       COMPAT_OBJS += compat/setenv.o
+       COMPAT_OBJS += $(OUTPUT)compat/setenv.o
 endif
 ifdef NO_MKDTEMP
        COMPAT_CFLAGS += -DNO_MKDTEMP
-       COMPAT_OBJS += compat/mkdtemp.o
+       COMPAT_OBJS += $(OUTPUT)compat/mkdtemp.o
 endif
 ifdef NO_UNSETENV
        COMPAT_CFLAGS += -DNO_UNSETENV
-       COMPAT_OBJS += compat/unsetenv.o
+       COMPAT_OBJS += $(OUTPUT)compat/unsetenv.o
 endif
 ifdef NO_SYS_SELECT_H
        BASIC_CFLAGS += -DNO_SYS_SELECT_H
 endif
 ifdef NO_MMAP
        COMPAT_CFLAGS += -DNO_MMAP
-       COMPAT_OBJS += compat/mmap.o
+       COMPAT_OBJS += $(OUTPUT)compat/mmap.o
 else
        ifdef USE_WIN32_MMAP
                COMPAT_CFLAGS += -DUSE_WIN32_MMAP
-               COMPAT_OBJS += compat/win32mmap.o
+               COMPAT_OBJS += $(OUTPUT)compat/win32mmap.o
        endif
 endif
 ifdef NO_PREAD
        COMPAT_CFLAGS += -DNO_PREAD
-       COMPAT_OBJS += compat/pread.o
+       COMPAT_OBJS += $(OUTPUT)compat/pread.o
 endif
 ifdef NO_FAST_WORKING_DIRECTORY
        BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY
@@ -671,10 +737,10 @@ else
 endif
 endif
 ifdef NO_INET_NTOP
-       LIB_OBJS += compat/inet_ntop.o
+       LIB_OBJS += $(OUTPUT)compat/inet_ntop.o
 endif
 ifdef NO_INET_PTON
-       LIB_OBJS += compat/inet_pton.o
+       LIB_OBJS += $(OUTPUT)compat/inet_pton.o
 endif
 
 ifdef NO_ICONV
@@ -691,15 +757,15 @@ endif
 
 ifdef PPC_SHA1
        SHA1_HEADER = "ppc/sha1.h"
-       LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o
+       LIB_OBJS += $(OUTPUT)ppc/sha1.o ppc/sha1ppc.o
 else
 ifdef ARM_SHA1
        SHA1_HEADER = "arm/sha1.h"
-       LIB_OBJS += arm/sha1.o arm/sha1_arm.o
+       LIB_OBJS += $(OUTPUT)arm/sha1.o $(OUTPUT)arm/sha1_arm.o
 else
 ifdef MOZILLA_SHA1
        SHA1_HEADER = "mozilla-sha1/sha1.h"
-       LIB_OBJS += mozilla-sha1/sha1.o
+       LIB_OBJS += $(OUTPUT)mozilla-sha1/sha1.o
 else
        SHA1_HEADER = <openssl/sha.h>
        EXTLIBS += $(LIB_4_CRYPTO)
@@ -711,15 +777,15 @@ ifdef NO_PERL_MAKEMAKER
 endif
 ifdef NO_HSTRERROR
        COMPAT_CFLAGS += -DNO_HSTRERROR
-       COMPAT_OBJS += compat/hstrerror.o
+       COMPAT_OBJS += $(OUTPUT)compat/hstrerror.o
 endif
 ifdef NO_MEMMEM
        COMPAT_CFLAGS += -DNO_MEMMEM
-       COMPAT_OBJS += compat/memmem.o
+       COMPAT_OBJS += $(OUTPUT)compat/memmem.o
 endif
 ifdef INTERNAL_QSORT
        COMPAT_CFLAGS += -DINTERNAL_QSORT
-       COMPAT_OBJS += compat/qsort.o
+       COMPAT_OBJS += $(OUTPUT)compat/qsort.o
 endif
 ifdef RUNTIME_PREFIX
        COMPAT_CFLAGS += -DRUNTIME_PREFIX
@@ -799,7 +865,7 @@ export TAR INSTALL DESTDIR SHELL_PATH
 
 SHELL = $(SHELL_PATH)
 
-all:: .perf.dev.null shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) PERF-BUILD-OPTIONS
+all:: .perf.dev.null shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) $(OUTPUT)PERF-BUILD-OPTIONS
 ifneq (,$X)
        $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), test '$p' -ef '$p$X' || $(RM) '$p';)
 endif
@@ -811,39 +877,39 @@ please_set_SHELL_PATH_to_a_more_modern_shell:
 
 shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell
 
-strip: $(PROGRAMS) perf$X
-       $(STRIP) $(STRIP_OPTS) $(PROGRAMS) perf$X
+strip: $(PROGRAMS) $(OUTPUT)perf$X
+       $(STRIP) $(STRIP_OPTS) $(PROGRAMS) $(OUTPUT)perf$X
 
-perf.o: perf.c common-cmds.h PERF-CFLAGS
+$(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
        $(QUIET_CC)$(CC) -DPERF_VERSION='"$(PERF_VERSION)"' \
                '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
-               $(ALL_CFLAGS) -c $(filter %.c,$^)
+               $(ALL_CFLAGS) -c $(filter %.c,$^) -o $@
 
-perf$X: perf.o $(BUILTIN_OBJS) $(PERFLIBS)
-       $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ perf.o \
+$(OUTPUT)perf$X: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
+       $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(OUTPUT)perf.o \
                $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
 
-builtin-help.o: builtin-help.c common-cmds.h PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \
+$(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
                '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
                '-DPERF_MAN_PATH="$(mandir_SQ)"' \
                '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
 
-builtin-timechart.o: builtin-timechart.c common-cmds.h PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \
+$(OUTPUT)builtin-timechart.o: builtin-timechart.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
                '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
                '-DPERF_MAN_PATH="$(mandir_SQ)"' \
                '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
 
-$(BUILT_INS): perf$X
+$(BUILT_INS): $(OUTPUT)perf$X
        $(QUIET_BUILT_IN)$(RM) $@ && \
        ln perf$X $@ 2>/dev/null || \
        ln -s perf$X $@ 2>/dev/null || \
        cp perf$X $@
 
-common-cmds.h: util/generate-cmdlist.sh command-list.txt
+$(OUTPUT)common-cmds.h: util/generate-cmdlist.sh command-list.txt
 
-common-cmds.h: $(wildcard Documentation/perf-*.txt)
+$(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt)
        $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@
 
 $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
@@ -855,7 +921,7 @@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
            -e 's/@@NO_CURL@@/$(NO_CURL)/g' \
            $@.sh >$@+ && \
        chmod +x $@+ && \
-       mv $@+ $@
+       mv $@+ $(OUTPUT)$@
 
 configure: configure.ac
        $(QUIET_GEN)$(RM) $@ $<+ && \
@@ -865,60 +931,50 @@ configure: configure.ac
        $(RM) $<+
 
 # These can record PERF_VERSION
-perf.o perf.spec \
+$(OUTPUT)perf.o perf.spec \
        $(patsubst %.sh,%,$(SCRIPT_SH)) \
        $(patsubst %.perl,%,$(SCRIPT_PERL)) \
-       : PERF-VERSION-FILE
+       : $(OUTPUT)PERF-VERSION-FILE
 
-%.o: %.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $<
-%.s: %.c PERF-CFLAGS
+$(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
+$(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS
        $(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $<
-%.o: %.S
-       $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $<
+$(OUTPUT)%.o: %.S
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
 
-util/exec_cmd.o: util/exec_cmd.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \
+$(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
                '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \
                '-DBINDIR="$(bindir_relative_SQ)"' \
                '-DPREFIX="$(prefix_SQ)"' \
                $<
 
-builtin-init-db.o: builtin-init-db.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DDEFAULT_PERF_TEMPLATE_DIR='"$(template_dir_SQ)"' $<
-
-util/config.o: util/config.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
-
-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//`
+$(OUTPUT)builtin-init-db.o: builtin-init-db.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DDEFAULT_PERF_TEMPLATE_DIR='"$(template_dir_SQ)"' $<
 
-util/bitmap.o: ../../lib/bitmap.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o util/bitmap.o -c $(KBITMAP_FLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+$(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -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)"' $<
+$(OUTPUT)util/newt.o: util/newt.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
 
-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)"' $<
+$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
 
-util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o util/scripting-engines/trace-event-perl.o -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
+$(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -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 $<
+$(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
 
-util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o util/scripting-engines/trace-event-python.o -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
+$(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
 
-scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o scripts/python/Perf-Trace-Util/Context.o -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
+$(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
 
-perf-%$X: %.o $(PERFLIBS)
+$(OUTPUT)perf-%$X: %.o $(PERFLIBS)
        $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
 
 $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
@@ -959,17 +1015,17 @@ cscope:
 TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\
              $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
 
-PERF-CFLAGS: .FORCE-PERF-CFLAGS
+$(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS
        @FLAGS='$(TRACK_CFLAGS)'; \
-           if test x"$$FLAGS" != x"`cat PERF-CFLAGS 2>/dev/null`" ; then \
+           if test x"$$FLAGS" != x"`cat $(OUTPUT)PERF-CFLAGS 2>/dev/null`" ; then \
                echo 1>&2 "    * new build flags or prefix"; \
-               echo "$$FLAGS" >PERF-CFLAGS; \
+               echo "$$FLAGS" >$(OUTPUT)PERF-CFLAGS; \
             fi
 
 # We need to apply sq twice, once to protect from the shell
-# that runs PERF-BUILD-OPTIONS, and then again to protect it
+# that runs $(OUTPUT)PERF-BUILD-OPTIONS, and then again to protect it
 # and the first level quoting from the shell that runs "echo".
-PERF-BUILD-OPTIONS: .FORCE-PERF-BUILD-OPTIONS
+$(OUTPUT)PERF-BUILD-OPTIONS: .FORCE-PERF-BUILD-OPTIONS
        @echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@
        @echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@
        @echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@
@@ -990,7 +1046,7 @@ all:: $(TEST_PROGRAMS)
 
 export NO_SVN_TESTS
 
-check: common-cmds.h
+check: $(OUTPUT)common-cmds.h
        if sparse; \
        then \
                for i in *.c */*.c; \
@@ -1024,10 +1080,10 @@ export perfexec_instdir
 
 install: all
        $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
-       $(INSTALL) perf$X '$(DESTDIR_SQ)$(bindir_SQ)'
+       $(INSTALL) $(OUTPUT)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) perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
+       $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
        $(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'
@@ -1041,7 +1097,7 @@ ifdef BUILT_INS
        $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
        $(INSTALL) $(BUILT_INS) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
 ifneq (,$X)
-       $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), $(RM) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$p';)
+       $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) $(OUTPUT)perf$X)), $(RM) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$p';)
 endif
 endif
 
@@ -1125,14 +1181,14 @@ clean:
        $(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*
+       $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
        $(RM) -r autom4te.cache
        $(RM) config.log config.mak.autogen config.mak.append config.status config.cache
        $(RM) -r $(PERF_TARNAME) .doc-tmp-dir
        $(RM) $(PERF_TARNAME).tar.gz perf-core_$(PERF_VERSION)-*.tar.gz
        $(RM) $(htmldocs).tar.gz $(manpages).tar.gz
        $(MAKE) -C Documentation/ clean
-       $(RM) PERF-VERSION-FILE PERF-CFLAGS PERF-BUILD-OPTIONS
+       $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS $(OUTPUT)PERF-BUILD-OPTIONS
 
 .PHONY: all install clean strip
 .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile
new file mode 100644 (file)
index 0000000..15130b5
--- /dev/null
@@ -0,0 +1,4 @@
+ifndef NO_DWARF
+PERF_HAVE_DWARF_REGS := 1
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
+endif
diff --git a/tools/perf/arch/powerpc/util/dwarf-regs.c b/tools/perf/arch/powerpc/util/dwarf-regs.c
new file mode 100644 (file)
index 0000000..48ae0c5
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Mapping of DWARF debug register numbers into register names.
+ *
+ * Copyright (C) 2010 Ian Munsie, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <libio.h>
+#include <dwarf-regs.h>
+
+
+struct pt_regs_dwarfnum {
+       const char *name;
+       unsigned int dwarfnum;
+};
+
+#define STR(s) #s
+#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
+#define GPR_DWARFNUM_NAME(num) \
+       {.name = STR(%gpr##num), .dwarfnum = num}
+#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
+
+/*
+ * Reference:
+ * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html
+ */
+static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
+       GPR_DWARFNUM_NAME(0),
+       GPR_DWARFNUM_NAME(1),
+       GPR_DWARFNUM_NAME(2),
+       GPR_DWARFNUM_NAME(3),
+       GPR_DWARFNUM_NAME(4),
+       GPR_DWARFNUM_NAME(5),
+       GPR_DWARFNUM_NAME(6),
+       GPR_DWARFNUM_NAME(7),
+       GPR_DWARFNUM_NAME(8),
+       GPR_DWARFNUM_NAME(9),
+       GPR_DWARFNUM_NAME(10),
+       GPR_DWARFNUM_NAME(11),
+       GPR_DWARFNUM_NAME(12),
+       GPR_DWARFNUM_NAME(13),
+       GPR_DWARFNUM_NAME(14),
+       GPR_DWARFNUM_NAME(15),
+       GPR_DWARFNUM_NAME(16),
+       GPR_DWARFNUM_NAME(17),
+       GPR_DWARFNUM_NAME(18),
+       GPR_DWARFNUM_NAME(19),
+       GPR_DWARFNUM_NAME(20),
+       GPR_DWARFNUM_NAME(21),
+       GPR_DWARFNUM_NAME(22),
+       GPR_DWARFNUM_NAME(23),
+       GPR_DWARFNUM_NAME(24),
+       GPR_DWARFNUM_NAME(25),
+       GPR_DWARFNUM_NAME(26),
+       GPR_DWARFNUM_NAME(27),
+       GPR_DWARFNUM_NAME(28),
+       GPR_DWARFNUM_NAME(29),
+       GPR_DWARFNUM_NAME(30),
+       GPR_DWARFNUM_NAME(31),
+       REG_DWARFNUM_NAME("%msr",   66),
+       REG_DWARFNUM_NAME("%ctr",   109),
+       REG_DWARFNUM_NAME("%link",  108),
+       REG_DWARFNUM_NAME("%xer",   101),
+       REG_DWARFNUM_NAME("%dar",   119),
+       REG_DWARFNUM_NAME("%dsisr", 118),
+       REG_DWARFNUM_END,
+};
+
+/**
+ * get_arch_regstr() - lookup register name from it's DWARF register number
+ * @n: the DWARF register number
+ *
+ * get_arch_regstr() returns the name of the register in struct
+ * regdwarfnum_table from it's DWARF register number. If the register is not
+ * found in the table, this returns NULL;
+ */
+const char *get_arch_regstr(unsigned int n)
+{
+       const struct pt_regs_dwarfnum *roff;
+       for (roff = regdwarfnum_table; roff->name != NULL; roff++)
+               if (roff->dwarfnum == n)
+                       return roff->name;
+       return NULL;
+}
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
new file mode 100644 (file)
index 0000000..15130b5
--- /dev/null
@@ -0,0 +1,4 @@
+ifndef NO_DWARF
+PERF_HAVE_DWARF_REGS := 1
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
+endif
diff --git a/tools/perf/arch/x86/util/dwarf-regs.c b/tools/perf/arch/x86/util/dwarf-regs.c
new file mode 100644 (file)
index 0000000..a794d30
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
+ * Extracted from probe-finder.c
+ *
+ * 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 <libio.h>
+#include <dwarf-regs.h>
+
+/*
+ * 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) */
+const char *get_arch_regstr(unsigned int n)
+{
+       return (n <= ARCH_MAX_REGS) ? arch_regs_table[n] : NULL;
+}
index 89773178e89408f9df1c235d355f5a4f3aebe27e..38dae7465142fdb86037cbae95a85a3ede9e24ed 100644 (file)
@@ -10,7 +10,6 @@
 #include "../perf.h"
 #include "../util/util.h"
 #include "../util/parse-options.h"
-#include "../util/string.h"
 #include "../util/header.h"
 #include "bench.h"
 
@@ -24,7 +23,7 @@
 
 static const char      *length_str     = "1MB";
 static const char      *routine        = "default";
-static int             use_clock       = 0;
+static bool            use_clock       = false;
 static int             clock_fd;
 
 static const struct option options[] = {
index 81cee78181fa28fd2f382144c061e409c439fb3f..d1d1b30f99c1c26121a5191a9d332b4cb23dfae3 100644 (file)
@@ -31,9 +31,9 @@
 
 #define DATASIZE 100
 
-static int use_pipes = 0;
+static bool use_pipes = false;
 static unsigned int loops = 100;
-static unsigned int thread_mode = 0;
+static bool thread_mode = false;
 static unsigned int num_groups = 10;
 
 struct sender_context {
@@ -256,10 +256,8 @@ static const struct option options[] = {
                    "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_UINTEGER('g', "group", &num_groups, "Specify number of groups"),
+       OPT_UINTEGER('l', "loop", &loops, "Specify number of loops"),
        OPT_END()
 };
 
index 4f77c7c27640791e357a130d71639d688c892641..d9ab3ce446acf88a4c86238dd3ea01e3c498b169 100644 (file)
@@ -93,7 +93,7 @@ int bench_sched_pipe(int argc, const char **argv,
 
        switch (bench_format) {
        case BENCH_FORMAT_DEFAULT:
-               printf("# Extecuted %d pipe operations between two tasks\n\n",
+               printf("# Executed %d pipe operations between two tasks\n\n",
                        loops);
 
                result_usec = diff.tv_sec * 1000000;
index 5ec5de995872a262e398b20da5440921fb3e51f2..77bcc9b130f5b3d6120f8c458b70f3c384ff2672 100644 (file)
@@ -14,7 +14,6 @@
 #include "util/cache.h"
 #include <linux/rbtree.h>
 #include "util/symbol.h"
-#include "util/string.h"
 
 #include "perf.h"
 #include "util/debug.h"
 
 static char            const *input_name = "perf.data";
 
-static int             force;
+static bool            force;
 
-static int             full_paths;
+static bool            full_paths;
 
-static int             print_line;
-
-struct sym_hist {
-       u64             sum;
-       u64             ip[0];
-};
-
-struct sym_ext {
-       struct rb_node  node;
-       double          percent;
-       char            *path;
-};
-
-struct sym_priv {
-       struct sym_hist *hist;
-       struct sym_ext  *ext;
-};
+static bool            print_line;
 
 static const char *sym_hist_filter;
 
-static int sym__alloc_hist(struct symbol *self)
-{
-       struct sym_priv *priv = symbol__priv(self);
-       const int size = (sizeof(*priv->hist) +
-                         (self->end - self->start) * sizeof(u64));
-
-       priv->hist = zalloc(size);
-       return priv->hist == NULL ? -1 : 0;
-}
-
-/*
- * collect histogram counts
- */
-static int annotate__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 || !he->map)
-               return 0;
-
-       priv = symbol__priv(sym);
-       if (priv->hist == NULL && sym__alloc_hist(sym) < 0)
-               return -ENOMEM;
-
-       sym_size = sym->end - sym->start;
-       offset = ip - sym->start;
-
-       pr_debug3("%s: ip=%#Lx\n", __func__, he->map->unmap_ip(he->map, ip));
-
-       if (offset >= sym_size)
-               return 0;
-
-       h = priv->hist;
-       h->sum++;
-       h->ip[offset]++;
-
-       pr_debug3("%#Lx %s: count++ [ip: %#Lx, %#Lx] => %Ld\n", he->sym->start,
-                 he->sym->name, ip, ip - he->sym->start, h->ip[offset]);
-       return 0;
-}
-
-static int perf_session__add_hist_entry(struct perf_session *self,
-                                       struct addr_location *al, u64 count)
+static int hists__add_entry(struct hists *self, struct addr_location *al)
 {
-       bool hit;
        struct hist_entry *he;
 
        if (sym_hist_filter != NULL &&
@@ -116,11 +51,11 @@ static int perf_session__add_hist_entry(struct perf_session *self,
                return 0;
        }
 
-       he = __perf_session__add_hist_entry(self, al, NULL, count, &hit);
+       he = __hists__add_entry(self, al, NULL, 1);
        if (he == NULL)
                return -ENOMEM;
 
-       return annotate__hist_hit(he, al->addr);
+       return hist_entry__inc_addr_samples(he, al->addr);
 }
 
 static int process_sample_event(event_t *event, struct perf_session *session)
@@ -136,7 +71,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
                return -1;
        }
 
-       if (!al.filtered && perf_session__add_hist_entry(session, &al, 1)) {
+       if (!al.filtered && hists__add_entry(&session->hists, &al)) {
                pr_warning("problem incrementing symbol count, "
                           "skipping event\n");
                return -1;
@@ -145,106 +80,11 @@ static int process_sample_event(event_t *event, struct perf_session *session)
        return 0;
 }
 
-struct objdump_line {
-       struct list_head node;
-       s64              offset;
-       char             *line;
-};
-
-static struct objdump_line *objdump_line__new(s64 offset, char *line)
-{
-       struct objdump_line *self = malloc(sizeof(*self));
-
-       if (self != NULL) {
-               self->offset = offset;
-               self->line = line;
-       }
-
-       return self;
-}
-
-static void objdump_line__free(struct objdump_line *self)
-{
-       free(self->line);
-       free(self);
-}
-
-static void objdump__add_line(struct list_head *head, struct objdump_line *line)
-{
-       list_add_tail(&line->node, head);
-}
-
-static struct objdump_line *objdump__get_next_ip_line(struct list_head *head,
-                                                     struct objdump_line *pos)
-{
-       list_for_each_entry_continue(pos, head, node)
-               if (pos->offset >= 0)
-                       return pos;
-
-       return NULL;
-}
-
-static int parse_line(FILE *file, struct hist_entry *he,
-                     struct list_head *head)
-{
-       struct symbol *sym = he->sym;
-       struct objdump_line *objdump_line;
-       char *line = NULL, *tmp, *tmp2;
-       size_t line_len;
-       s64 line_ip, offset = -1;
-       char *c;
-
-       if (getline(&line, &line_len, file) < 0)
-               return -1;
-
-       if (!line)
-               return -1;
-
-       c = strchr(line, '\n');
-       if (c)
-               *c = 0;
-
-       line_ip = -1;
-
-       /*
-        * Strip leading spaces:
-        */
-       tmp = line;
-       while (*tmp) {
-               if (*tmp != ' ')
-                       break;
-               tmp++;
-       }
-
-       if (*tmp) {
-               /*
-                * Parse hexa addresses followed by ':'
-                */
-               line_ip = strtoull(tmp, &tmp2, 16);
-               if (*tmp2 != ':')
-                       line_ip = -1;
-       }
-
-       if (line_ip != -1) {
-               u64 start = map__rip_2objdump(he->map, sym->start);
-               offset = line_ip - start;
-       }
-
-       objdump_line = objdump_line__new(offset, line);
-       if (objdump_line == NULL) {
-               free(line);
-               return -1;
-       }
-       objdump__add_line(head, objdump_line);
-
-       return 0;
-}
-
 static int objdump_line__print(struct objdump_line *self,
                               struct list_head *head,
                               struct hist_entry *he, u64 len)
 {
-       struct symbol *sym = he->sym;
+       struct symbol *sym = he->ms.sym;
        static const char *prev_line;
        static const char *prev_color;
 
@@ -327,7 +167,7 @@ static void insert_source_line(struct sym_ext *sym_ext)
 
 static void free_source_line(struct hist_entry *he, int len)
 {
-       struct sym_priv *priv = symbol__priv(he->sym);
+       struct sym_priv *priv = symbol__priv(he->ms.sym);
        struct sym_ext *sym_ext = priv->ext;
        int i;
 
@@ -346,7 +186,7 @@ static void free_source_line(struct hist_entry *he, int len)
 static void
 get_source_line(struct hist_entry *he, int len, const char *filename)
 {
-       struct symbol *sym = he->sym;
+       struct symbol *sym = he->ms.sym;
        u64 start;
        int i;
        char cmd[PATH_MAX * 2];
@@ -361,7 +201,7 @@ get_source_line(struct hist_entry *he, int len, const char *filename)
        if (!priv->ext)
                return;
 
-       start = he->map->unmap_ip(he->map, sym->start);
+       start = he->ms.map->unmap_ip(he->ms.map, sym->start);
 
        for (i = 0; i < len; i++) {
                char *path = NULL;
@@ -425,7 +265,7 @@ static void print_summary(const char *filename)
 
 static void hist_entry__print_hits(struct hist_entry *self)
 {
-       struct symbol *sym = self->sym;
+       struct symbol *sym = self->ms.sym;
        struct sym_priv *priv = symbol__priv(sym);
        struct sym_hist *h = priv->hist;
        u64 len = sym->end - sym->start, offset;
@@ -439,23 +279,17 @@ static void hist_entry__print_hits(struct hist_entry *self)
 
 static void annotate_sym(struct hist_entry *he)
 {
-       struct map *map = he->map;
+       struct map *map = he->ms.map;
        struct dso *dso = map->dso;
-       struct symbol *sym = he->sym;
+       struct symbol *sym = he->ms.sym;
        const char *filename = dso->long_name, *d_filename;
        u64 len;
-       char command[PATH_MAX*2];
-       FILE *file;
        LIST_HEAD(head);
        struct objdump_line *pos, *n;
 
-       if (!filename)
+       if (hist_entry__annotate(he, &head) < 0)
                return;
 
-       pr_debug("%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
@@ -472,29 +306,6 @@ static void annotate_sym(struct hist_entry *he)
        printf(" Percent |      Source code & Disassembly of %s\n", d_filename);
        printf("------------------------------------------------\n");
 
-       if (verbose >= 2)
-               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",
-               map__rip_2objdump(map, sym->start),
-               map__rip_2objdump(map, sym->end),
-               filename, filename);
-
-       if (verbose >= 3)
-               printf("doing: %s\n", command);
-
-       file = popen(command, "r");
-       if (!file)
-               return;
-
-       while (!feof(file)) {
-               if (parse_line(file, he, &head) < 0)
-                       break;
-       }
-
-       pclose(file);
-
        if (verbose)
                hist_entry__print_hits(he);
 
@@ -508,25 +319,25 @@ static void annotate_sym(struct hist_entry *he)
                free_source_line(he, len);
 }
 
-static void perf_session__find_annotations(struct perf_session *self)
+static void hists__find_annotations(struct hists *self)
 {
        struct rb_node *nd;
 
-       for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) {
+       for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
                struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
                struct sym_priv *priv;
 
-               if (he->sym == NULL)
+               if (he->ms.sym == NULL)
                        continue;
 
-               priv = symbol__priv(he->sym);
+               priv = symbol__priv(he->ms.sym);
                if (priv->hist == NULL)
                        continue;
 
                annotate_sym(he);
                /*
                 * Since we have a hist_entry per IP for the same symbol, free
-                * he->sym->hist to signal we already processed this symbol.
+                * he->ms.sym->hist to signal we already processed this symbol.
                 */
                free(priv->hist);
                priv->hist = NULL;
@@ -545,7 +356,7 @@ static int __cmd_annotate(void)
        int ret;
        struct perf_session *session;
 
-       session = perf_session__new(input_name, O_RDONLY, force);
+       session = perf_session__new(input_name, O_RDONLY, force, false);
        if (session == NULL)
                return -ENOMEM;
 
@@ -554,7 +365,7 @@ static int __cmd_annotate(void)
                goto out_delete;
 
        if (dump_trace) {
-               event__print_totals();
+               perf_session__fprintf_nr_events(session, stdout);
                goto out_delete;
        }
 
@@ -562,11 +373,11 @@ static int __cmd_annotate(void)
                perf_session__fprintf(session, stdout);
 
        if (verbose > 2)
-               dsos__fprintf(stdout);
+               perf_session__fprintf_dsos(session, stdout);
 
-       perf_session__collapse_resort(session);
-       perf_session__output_resort(session, session->event_total[0]);
-       perf_session__find_annotations(session);
+       hists__collapse_resort(&session->hists);
+       hists__output_resort(&session->hists);
+       hists__find_annotations(&session->hists);
 out_delete:
        perf_session__delete(session);
 
@@ -581,10 +392,12 @@ static const char * const annotate_usage[] = {
 static const struct option options[] = {
        OPT_STRING('i', "input", &input_name, "file",
                    "input file name"),
+       OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
+                  "only consider symbols in these dsos"),
        OPT_STRING('s', "symbol", &sym_hist_filter, "symbol",
                    "symbol to annotate"),
        OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show symbol address, etc)"),
        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
                    "dump raw trace in ASCII"),
index 46996774e55967dc1351f9bf731ebc2f0c36cc59..fcb96269852a3929d376c8560c79f2b2add9b943 100644 (file)
@@ -95,7 +95,7 @@ static void dump_suites(int subsys_index)
        return;
 }
 
-static char *bench_format_str;
+static const char *bench_format_str;
 int bench_format = BENCH_FORMAT_DEFAULT;
 
 static const struct option bench_options[] = {
@@ -126,7 +126,7 @@ static void print_usage(void)
        printf("\n");
 }
 
-static int bench_str2int(char *str)
+static int bench_str2int(const char *str)
 {
        if (!str)
                return BENCH_FORMAT_DEFAULT;
index 30a05f552c96dfaac6de44a8268f5cb5ccd49061..f8e3d1852029b65c9c2efbdf5b6315f6f9e9d492 100644 (file)
@@ -27,7 +27,7 @@ static const struct option buildid_cache_options[] = {
                   "file list", "file(s) to add"),
        OPT_STRING('r', "remove", &remove_name_list_str, "file list",
                    "file(s) to remove"),
-       OPT_BOOLEAN('v', "verbose", &verbose, "be more verbose"),
+       OPT_INCR('v', "verbose", &verbose, "be more verbose"),
        OPT_END()
 };
 
index d0675c02f81eb0a45f5d2b8185dc6b26a15f98fd..44a47e13bd673eb362f956b80bd02adbec367d45 100644 (file)
@@ -16,7 +16,7 @@
 #include "util/symbol.h"
 
 static char const *input_name = "perf.data";
-static int force;
+static bool force;
 static bool with_hits;
 
 static const char * const buildid_list_usage[] = {
@@ -29,7 +29,7 @@ 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,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose"),
        OPT_END()
 };
@@ -39,14 +39,14 @@ static int __cmd_buildid_list(void)
        int err = -1;
        struct perf_session *session;
 
-       session = perf_session__new(input_name, O_RDONLY, force);
+       session = perf_session__new(input_name, O_RDONLY, force, false);
        if (session == NULL)
                return -1;
 
        if (with_hits)
                perf_session__process_events(session, &build_id__mark_dso_hit_ops);
 
-       dsos__fprintf_buildid(stdout, with_hits);
+       perf_session__fprintf_dsos_buildid(session, stdout, with_hits);
 
        perf_session__delete(session);
        return err;
index 18b3f505f9db947012bfb247791f6c0edc13082c..a6e2fdc7a04e16613087a4c65e70d832ab903505 100644 (file)
 static char const *input_old = "perf.data.old",
                  *input_new = "perf.data";
 static char      diff__default_sort_order[] = "dso,symbol";
-static int  force;
+static bool  force;
 static bool show_displacement;
 
-static int perf_session__add_hist_entry(struct perf_session *self,
-                                       struct addr_location *al, u64 count)
+static int hists__add_entry(struct hists *self,
+                           struct addr_location *al, u64 period)
 {
-       bool hit;
-       struct hist_entry *he = __perf_session__add_hist_entry(self, al, NULL,
-                                                              count, &hit);
-       if (he == NULL)
-               return -ENOMEM;
-
-       if (hit)
-               he->count += count;
-
-       return 0;
+       if (__hists__add_entry(self, al, NULL, period) != NULL)
+               return 0;
+       return -ENOMEM;
 }
 
 static int diff__process_sample_event(event_t *event, struct perf_session *session)
@@ -56,12 +49,12 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi
 
        event__parse_sample(event, session->sample_type, &data);
 
-       if (perf_session__add_hist_entry(session, &al, data.period)) {
-               pr_warning("problem incrementing symbol count, skipping event\n");
+       if (hists__add_entry(&session->hists, &al, data.period)) {
+               pr_warning("problem incrementing symbol period, skipping event\n");
                return -1;
        }
 
-       session->events_stats.total += data.period;
+       session->hists.stats.total_period += data.period;
        return 0;
 }
 
@@ -94,35 +87,34 @@ static void perf_session__insert_hist_entry_by_name(struct rb_root *root,
        rb_insert_color(&he->rb_node, root);
 }
 
-static void perf_session__resort_hist_entries(struct perf_session *self)
+static void hists__resort_entries(struct hists *self)
 {
        unsigned long position = 1;
        struct rb_root tmp = RB_ROOT;
-       struct rb_node *next = rb_first(&self->hists);
+       struct rb_node *next = rb_first(&self->entries);
 
        while (next != NULL) {
                struct hist_entry *n = rb_entry(next, struct hist_entry, rb_node);
 
                next = rb_next(&n->rb_node);
-               rb_erase(&n->rb_node, &self->hists);
+               rb_erase(&n->rb_node, &self->entries);
                n->position = position++;
                perf_session__insert_hist_entry_by_name(&tmp, n);
        }
 
-       self->hists = tmp;
+       self->entries = tmp;
 }
 
-static void perf_session__set_hist_entries_positions(struct perf_session *self)
+static void hists__set_positions(struct hists *self)
 {
-       perf_session__output_resort(self, self->events_stats.total);
-       perf_session__resort_hist_entries(self);
+       hists__output_resort(self);
+       hists__resort_entries(self);
 }
 
-static struct hist_entry *
-perf_session__find_hist_entry(struct perf_session *self,
-                             struct hist_entry *he)
+static struct hist_entry *hists__find_entry(struct hists *self,
+                                           struct hist_entry *he)
 {
-       struct rb_node *n = self->hists.rb_node;
+       struct rb_node *n = self->entries.rb_node;
 
        while (n) {
                struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node);
@@ -139,14 +131,13 @@ perf_session__find_hist_entry(struct perf_session *self,
        return NULL;
 }
 
-static void perf_session__match_hists(struct perf_session *old_session,
-                                     struct perf_session *new_session)
+static void hists__match(struct hists *older, struct hists *newer)
 {
        struct rb_node *nd;
 
-       for (nd = rb_first(&new_session->hists); nd; nd = rb_next(nd)) {
+       for (nd = rb_first(&newer->entries); nd; nd = rb_next(nd)) {
                struct hist_entry *pos = rb_entry(nd, struct hist_entry, rb_node);
-               pos->pair = perf_session__find_hist_entry(old_session, pos);
+               pos->pair = hists__find_entry(older, pos);
        }
 }
 
@@ -155,8 +146,8 @@ static int __cmd_diff(void)
        int ret, i;
        struct perf_session *session[2];
 
-       session[0] = perf_session__new(input_old, O_RDONLY, force);
-       session[1] = perf_session__new(input_new, O_RDONLY, force);
+       session[0] = perf_session__new(input_old, O_RDONLY, force, false);
+       session[1] = perf_session__new(input_new, O_RDONLY, force, false);
        if (session[0] == NULL || session[1] == NULL)
                return -ENOMEM;
 
@@ -166,13 +157,13 @@ static int __cmd_diff(void)
                        goto out_delete;
        }
 
-       perf_session__output_resort(session[1], session[1]->events_stats.total);
+       hists__output_resort(&session[1]->hists);
        if (show_displacement)
-               perf_session__set_hist_entries_positions(session[0]);
+               hists__set_positions(&session[0]->hists);
 
-       perf_session__match_hists(session[0], session[1]);
-       perf_session__fprintf_hists(session[1], session[0],
-                                   show_displacement, stdout);
+       hists__match(&session[0]->hists, &session[1]->hists);
+       hists__fprintf(&session[1]->hists, &session[0]->hists,
+                      show_displacement, stdout);
 out_delete:
        for (i = 0; i < 2; ++i)
                perf_session__delete(session[i]);
@@ -185,7 +176,7 @@ static const char * const diff_usage[] = {
 };
 
 static const struct option options[] = {
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show symbol address, etc)"),
        OPT_BOOLEAN('m', "displacement", &show_displacement,
                    "Show position displacement relative to baseline"),
@@ -222,6 +213,10 @@ int cmd_diff(int argc, const char **argv, const char *prefix __used)
                        input_new = argv[1];
                } else
                        input_new = argv[0];
+       } else if (symbol_conf.default_guest_vmlinux_name ||
+                  symbol_conf.default_guest_kallsyms) {
+               input_old = "perf.data.host";
+               input_new = "perf.data.guest";
        }
 
        symbol_conf.exclude_other = false;
index 215b584007b19f8ccccc7951c5ee9eebabda3bf7..6d5a8a7faf488454056f23eaab8c4f42af1819ee 100644 (file)
@@ -29,14 +29,14 @@ enum help_format {
        HELP_FORMAT_WEB,
 };
 
-static int show_all = 0;
+static bool show_all = false;
 static enum help_format help_format = HELP_FORMAT_MAN;
 static struct option builtin_help_options[] = {
        OPT_BOOLEAN('a', "all", &show_all, "print all available commands"),
-       OPT_SET_INT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN),
-       OPT_SET_INT('w', "web", &help_format, "show manual in web browser",
+       OPT_SET_UINT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN),
+       OPT_SET_UINT('w', "web", &help_format, "show manual in web browser",
                        HELP_FORMAT_WEB),
-       OPT_SET_INT('i', "info", &help_format, "show info page",
+       OPT_SET_UINT('i', "info", &help_format, "show info page",
                        HELP_FORMAT_INFO),
        OPT_END(),
 };
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
new file mode 100644 (file)
index 0000000..8e3e47b
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * builtin-inject.c
+ *
+ * Builtin inject command: Examine the live mode (stdin) event stream
+ * and repipe it to stdout while optionally injecting additional
+ * events into it.
+ */
+#include "builtin.h"
+
+#include "perf.h"
+#include "util/session.h"
+#include "util/debug.h"
+
+#include "util/parse-options.h"
+
+static char            const *input_name = "-";
+static bool            inject_build_ids;
+
+static int event__repipe(event_t *event __used,
+                        struct perf_session *session __used)
+{
+       uint32_t size;
+       void *buf = event;
+
+       size = event->header.size;
+
+       while (size) {
+               int ret = write(STDOUT_FILENO, buf, size);
+               if (ret < 0)
+                       return -errno;
+
+               size -= ret;
+               buf += ret;
+       }
+
+       return 0;
+}
+
+static int event__repipe_mmap(event_t *self, struct perf_session *session)
+{
+       int err;
+
+       err = event__process_mmap(self, session);
+       event__repipe(self, session);
+
+       return err;
+}
+
+static int event__repipe_task(event_t *self, struct perf_session *session)
+{
+       int err;
+
+       err = event__process_task(self, session);
+       event__repipe(self, session);
+
+       return err;
+}
+
+static int event__repipe_tracing_data(event_t *self,
+                                     struct perf_session *session)
+{
+       int err;
+
+       event__repipe(self, session);
+       err = event__process_tracing_data(self, session);
+
+       return err;
+}
+
+static int dso__read_build_id(struct dso *self)
+{
+       if (self->has_build_id)
+               return 0;
+
+       if (filename__read_build_id(self->long_name, self->build_id,
+                                   sizeof(self->build_id)) > 0) {
+               self->has_build_id = true;
+               return 0;
+       }
+
+       return -1;
+}
+
+static int dso__inject_build_id(struct dso *self, struct perf_session *session)
+{
+       u16 misc = PERF_RECORD_MISC_USER;
+       struct machine *machine;
+       int err;
+
+       if (dso__read_build_id(self) < 0) {
+               pr_debug("no build_id found for %s\n", self->long_name);
+               return -1;
+       }
+
+       machine = perf_session__find_host_machine(session);
+       if (machine == NULL) {
+               pr_err("Can't find machine for session\n");
+               return -1;
+       }
+
+       if (self->kernel)
+               misc = PERF_RECORD_MISC_KERNEL;
+
+       err = event__synthesize_build_id(self, misc, event__repipe,
+                                        machine, session);
+       if (err) {
+               pr_err("Can't synthesize build_id event for %s\n", self->long_name);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int event__inject_buildid(event_t *event, struct perf_session *session)
+{
+       struct addr_location al;
+       struct thread *thread;
+       u8 cpumode;
+
+       cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+
+       thread = perf_session__findnew(session, event->ip.pid);
+       if (thread == NULL) {
+               pr_err("problem processing %d event, skipping it.\n",
+                      event->header.type);
+               goto repipe;
+       }
+
+       thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
+                             event->ip.pid, event->ip.ip, &al);
+
+       if (al.map != NULL) {
+               if (!al.map->dso->hit) {
+                       al.map->dso->hit = 1;
+                       if (map__load(al.map, NULL) >= 0) {
+                               dso__inject_build_id(al.map->dso, session);
+                               /*
+                                * If this fails, too bad, let the other side
+                                * account this as unresolved.
+                                */
+                       } else
+                               pr_warning("no symbols found in %s, maybe "
+                                          "install a debug package?\n",
+                                          al.map->dso->long_name);
+               }
+       }
+
+repipe:
+       event__repipe(event, session);
+       return 0;
+}
+
+struct perf_event_ops inject_ops = {
+       .sample         = event__repipe,
+       .mmap           = event__repipe,
+       .comm           = event__repipe,
+       .fork           = event__repipe,
+       .exit           = event__repipe,
+       .lost           = event__repipe,
+       .read           = event__repipe,
+       .throttle       = event__repipe,
+       .unthrottle     = event__repipe,
+       .attr           = event__repipe,
+       .event_type     = event__repipe,
+       .tracing_data   = event__repipe,
+       .build_id       = event__repipe,
+};
+
+extern volatile int session_done;
+
+static void sig_handler(int sig __attribute__((__unused__)))
+{
+       session_done = 1;
+}
+
+static int __cmd_inject(void)
+{
+       struct perf_session *session;
+       int ret = -EINVAL;
+
+       signal(SIGINT, sig_handler);
+
+       if (inject_build_ids) {
+               inject_ops.sample       = event__inject_buildid;
+               inject_ops.mmap         = event__repipe_mmap;
+               inject_ops.fork         = event__repipe_task;
+               inject_ops.tracing_data = event__repipe_tracing_data;
+       }
+
+       session = perf_session__new(input_name, O_RDONLY, false, true);
+       if (session == NULL)
+               return -ENOMEM;
+
+       ret = perf_session__process_events(session, &inject_ops);
+
+       perf_session__delete(session);
+
+       return ret;
+}
+
+static const char * const report_usage[] = {
+       "perf inject [<options>]",
+       NULL
+};
+
+static const struct option options[] = {
+       OPT_BOOLEAN('b', "build-ids", &inject_build_ids,
+                   "Inject build-ids into the output stream"),
+       OPT_INCR('v', "verbose", &verbose,
+                "be more verbose (show build ids, etc)"),
+       OPT_END()
+};
+
+int cmd_inject(int argc, const char **argv, const char *prefix __used)
+{
+       argc = parse_options(argc, argv, options, report_usage, 0);
+
+       /*
+        * Any (unrecognized) arguments left?
+        */
+       if (argc)
+               usage_with_options(report_usage, options);
+
+       if (symbol__init() < 0)
+               return -1;
+
+       return __cmd_inject();
+}
index 924a9518931ade8eb51e17eb36fc38024c556c79..31f60a2535e0ec95b60e6b90e3e24818fa0dd972 100644 (file)
@@ -335,8 +335,9 @@ static int process_sample_event(event_t *event, struct perf_session *session)
 }
 
 static struct perf_event_ops event_ops = {
-       .sample = process_sample_event,
-       .comm   = event__process_comm,
+       .sample                 = process_sample_event,
+       .comm                   = event__process_comm,
+       .ordered_samples        = true,
 };
 
 static double fragmentation(unsigned long n_req, unsigned long n_alloc)
@@ -351,6 +352,7 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
                           int n_lines, int is_caller)
 {
        struct rb_node *next;
+       struct machine *machine;
 
        printf("%.102s\n", graph_dotted_line);
        printf(" %-34s |",  is_caller ? "Callsite": "Alloc Ptr");
@@ -359,23 +361,29 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
 
        next = rb_first(root);
 
+       machine = perf_session__find_host_machine(session);
+       if (!machine) {
+               pr_err("__print_result: couldn't find kernel information\n");
+               return;
+       }
        while (next && n_lines--) {
                struct alloc_stat *data = rb_entry(next, struct alloc_stat,
                                                   node);
                struct symbol *sym = NULL;
+               struct map *map;
                char buf[BUFSIZ];
                u64 addr;
 
                if (is_caller) {
                        addr = data->call_site;
                        if (!raw_ip)
-                               sym = map_groups__find_function(&session->kmaps, addr, NULL);
+                               sym = machine__find_kernel_function(machine, addr, &map, NULL);
                } else
                        addr = data->ptr;
 
                if (sym != NULL)
                        snprintf(buf, sizeof(buf), "%s+%Lx", sym->name,
-                                addr - sym->start);
+                                addr - map->unmap_ip(map, sym->start));
                else
                        snprintf(buf, sizeof(buf), "%#Lx", addr);
                printf(" %-34s |", buf);
@@ -484,10 +492,13 @@ static void sort_result(void)
 static int __cmd_kmem(void)
 {
        int err = -EINVAL;
-       struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
+       struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0, false);
        if (session == NULL)
                return -ENOMEM;
 
+       if (perf_session__create_kernel_maps(session) < 0)
+               goto out_delete;
+
        if (!perf_session__has_traces(session, "kmem record"))
                goto out_delete;
 
@@ -718,7 +729,6 @@ static const char *record_args[] = {
        "record",
        "-a",
        "-R",
-       "-M",
        "-f",
        "-c", "1",
        "-e", "kmem:kmalloc",
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
new file mode 100644 (file)
index 0000000..34d1e85
--- /dev/null
@@ -0,0 +1,144 @@
+#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/session.h"
+
+#include "util/parse-options.h"
+#include "util/trace-event.h"
+
+#include "util/debug.h"
+
+#include <sys/prctl.h>
+
+#include <semaphore.h>
+#include <pthread.h>
+#include <math.h>
+
+static const char              *file_name;
+static char                    name_buffer[256];
+
+bool                           perf_host = 1;
+bool                           perf_guest;
+
+static const char * const kvm_usage[] = {
+       "perf kvm [<options>] {top|record|report|diff|buildid-list}",
+       NULL
+};
+
+static const struct option kvm_options[] = {
+       OPT_STRING('i', "input", &file_name, "file",
+                  "Input file name"),
+       OPT_STRING('o', "output", &file_name, "file",
+                  "Output file name"),
+       OPT_BOOLEAN(0, "guest", &perf_guest,
+                   "Collect guest os data"),
+       OPT_BOOLEAN(0, "host", &perf_host,
+                   "Collect guest os data"),
+       OPT_STRING(0, "guestmount", &symbol_conf.guestmount, "directory",
+                  "guest mount directory under which every guest os"
+                  " instance has a subdir"),
+       OPT_STRING(0, "guestvmlinux", &symbol_conf.default_guest_vmlinux_name,
+                  "file", "file saving guest os vmlinux"),
+       OPT_STRING(0, "guestkallsyms", &symbol_conf.default_guest_kallsyms,
+                  "file", "file saving guest os /proc/kallsyms"),
+       OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules,
+                  "file", "file saving guest os /proc/modules"),
+       OPT_END()
+};
+
+static int __cmd_record(int argc, const char **argv)
+{
+       int rec_argc, i = 0, j;
+       const char **rec_argv;
+
+       rec_argc = argc + 2;
+       rec_argv = calloc(rec_argc + 1, sizeof(char *));
+       rec_argv[i++] = strdup("record");
+       rec_argv[i++] = strdup("-o");
+       rec_argv[i++] = strdup(file_name);
+       for (j = 1; j < argc; j++, i++)
+               rec_argv[i] = argv[j];
+
+       BUG_ON(i != rec_argc);
+
+       return cmd_record(i, rec_argv, NULL);
+}
+
+static int __cmd_report(int argc, const char **argv)
+{
+       int rec_argc, i = 0, j;
+       const char **rec_argv;
+
+       rec_argc = argc + 2;
+       rec_argv = calloc(rec_argc + 1, sizeof(char *));
+       rec_argv[i++] = strdup("report");
+       rec_argv[i++] = strdup("-i");
+       rec_argv[i++] = strdup(file_name);
+       for (j = 1; j < argc; j++, i++)
+               rec_argv[i] = argv[j];
+
+       BUG_ON(i != rec_argc);
+
+       return cmd_report(i, rec_argv, NULL);
+}
+
+static int __cmd_buildid_list(int argc, const char **argv)
+{
+       int rec_argc, i = 0, j;
+       const char **rec_argv;
+
+       rec_argc = argc + 2;
+       rec_argv = calloc(rec_argc + 1, sizeof(char *));
+       rec_argv[i++] = strdup("buildid-list");
+       rec_argv[i++] = strdup("-i");
+       rec_argv[i++] = strdup(file_name);
+       for (j = 1; j < argc; j++, i++)
+               rec_argv[i] = argv[j];
+
+       BUG_ON(i != rec_argc);
+
+       return cmd_buildid_list(i, rec_argv, NULL);
+}
+
+int cmd_kvm(int argc, const char **argv, const char *prefix __used)
+{
+       perf_host = perf_guest = 0;
+
+       argc = parse_options(argc, argv, kvm_options, kvm_usage,
+                       PARSE_OPT_STOP_AT_NON_OPTION);
+       if (!argc)
+               usage_with_options(kvm_usage, kvm_options);
+
+       if (!perf_host)
+               perf_guest = 1;
+
+       if (!file_name) {
+               if (perf_host && !perf_guest)
+                       sprintf(name_buffer, "perf.data.host");
+               else if (!perf_host && perf_guest)
+                       sprintf(name_buffer, "perf.data.guest");
+               else
+                       sprintf(name_buffer, "perf.data.kvm");
+               file_name = name_buffer;
+       }
+
+       if (!strncmp(argv[0], "rec", 3))
+               return __cmd_record(argc, argv);
+       else if (!strncmp(argv[0], "rep", 3))
+               return __cmd_report(argc, argv);
+       else if (!strncmp(argv[0], "diff", 4))
+               return cmd_diff(argc, argv, NULL);
+       else if (!strncmp(argv[0], "top", 3))
+               return cmd_top(argc, argv, NULL);
+       else if (!strncmp(argv[0], "buildid-list", 12))
+               return __cmd_buildid_list(argc, argv);
+       else
+               usage_with_options(kvm_usage, kvm_options);
+
+       return 0;
+}
index e12c844df1e27a0366ec2491f8ad7df3f817307d..821c1586a22b7da92cd732ad1a4ee4e05b037085 100644 (file)
@@ -23,6 +23,8 @@
 #include <linux/list.h>
 #include <linux/hash.h>
 
+static struct perf_session *session;
+
 /* based on kernel/lockdep.c */
 #define LOCKHASH_BITS          12
 #define LOCKHASH_SIZE          (1UL << LOCKHASH_BITS)
@@ -32,9 +34,6 @@ static struct list_head lockhash_table[LOCKHASH_SIZE];
 #define __lockhashfn(key)      hash_long((unsigned long)key, LOCKHASH_BITS)
 #define lockhashentry(key)     (lockhash_table + __lockhashfn((key)))
 
-#define LOCK_STATE_UNLOCKED    0              /* initial state */
-#define LOCK_STATE_LOCKED      1
-
 struct lock_stat {
        struct list_head        hash_entry;
        struct rb_node          rb;             /* used for sorting */
@@ -47,20 +46,151 @@ struct lock_stat {
        void                    *addr;          /* address of lockdep_map, used as ID */
        char                    *name;          /* for strcpy(), we cannot use const */
 
-       int                     state;
-       u64                     prev_event_time; /* timestamp of previous event */
-
-       unsigned int            nr_acquired;
        unsigned int            nr_acquire;
+       unsigned int            nr_acquired;
        unsigned int            nr_contended;
        unsigned int            nr_release;
 
+       unsigned int            nr_readlock;
+       unsigned int            nr_trylock;
        /* these times are in nano sec. */
        u64                     wait_time_total;
        u64                     wait_time_min;
        u64                     wait_time_max;
+
+       int                     discard; /* flag of blacklist */
 };
 
+/*
+ * States of lock_seq_stat
+ *
+ * UNINITIALIZED is required for detecting first event of acquire.
+ * As the nature of lock events, there is no guarantee
+ * that the first event for the locks are acquire,
+ * it can be acquired, contended or release.
+ */
+#define SEQ_STATE_UNINITIALIZED      0        /* initial state */
+#define SEQ_STATE_RELEASED     1
+#define SEQ_STATE_ACQUIRING    2
+#define SEQ_STATE_ACQUIRED     3
+#define SEQ_STATE_READ_ACQUIRED        4
+#define SEQ_STATE_CONTENDED    5
+
+/*
+ * MAX_LOCK_DEPTH
+ * Imported from include/linux/sched.h.
+ * Should this be synchronized?
+ */
+#define MAX_LOCK_DEPTH 48
+
+/*
+ * struct lock_seq_stat:
+ * Place to put on state of one lock sequence
+ * 1) acquire -> acquired -> release
+ * 2) acquire -> contended -> acquired -> release
+ * 3) acquire (with read or try) -> release
+ * 4) Are there other patterns?
+ */
+struct lock_seq_stat {
+       struct list_head        list;
+       int                     state;
+       u64                     prev_event_time;
+       void                    *addr;
+
+       int                     read_count;
+};
+
+struct thread_stat {
+       struct rb_node          rb;
+
+       u32                     tid;
+       struct list_head        seq_list;
+};
+
+static struct rb_root          thread_stats;
+
+static struct thread_stat *thread_stat_find(u32 tid)
+{
+       struct rb_node *node;
+       struct thread_stat *st;
+
+       node = thread_stats.rb_node;
+       while (node) {
+               st = container_of(node, struct thread_stat, rb);
+               if (st->tid == tid)
+                       return st;
+               else if (tid < st->tid)
+                       node = node->rb_left;
+               else
+                       node = node->rb_right;
+       }
+
+       return NULL;
+}
+
+static void thread_stat_insert(struct thread_stat *new)
+{
+       struct rb_node **rb = &thread_stats.rb_node;
+       struct rb_node *parent = NULL;
+       struct thread_stat *p;
+
+       while (*rb) {
+               p = container_of(*rb, struct thread_stat, rb);
+               parent = *rb;
+
+               if (new->tid < p->tid)
+                       rb = &(*rb)->rb_left;
+               else if (new->tid > p->tid)
+                       rb = &(*rb)->rb_right;
+               else
+                       BUG_ON("inserting invalid thread_stat\n");
+       }
+
+       rb_link_node(&new->rb, parent, rb);
+       rb_insert_color(&new->rb, &thread_stats);
+}
+
+static struct thread_stat *thread_stat_findnew_after_first(u32 tid)
+{
+       struct thread_stat *st;
+
+       st = thread_stat_find(tid);
+       if (st)
+               return st;
+
+       st = zalloc(sizeof(struct thread_stat));
+       if (!st)
+               die("memory allocation failed\n");
+
+       st->tid = tid;
+       INIT_LIST_HEAD(&st->seq_list);
+
+       thread_stat_insert(st);
+
+       return st;
+}
+
+static struct thread_stat *thread_stat_findnew_first(u32 tid);
+static struct thread_stat *(*thread_stat_findnew)(u32 tid) =
+       thread_stat_findnew_first;
+
+static struct thread_stat *thread_stat_findnew_first(u32 tid)
+{
+       struct thread_stat *st;
+
+       st = zalloc(sizeof(struct thread_stat));
+       if (!st)
+               die("memory allocation failed\n");
+       st->tid = tid;
+       INIT_LIST_HEAD(&st->seq_list);
+
+       rb_link_node(&st->rb, NULL, &thread_stats.rb_node);
+       rb_insert_color(&st->rb, &thread_stats);
+
+       thread_stat_findnew = thread_stat_findnew_after_first;
+       return st;
+}
+
 /* build simple key function one is bigger than two */
 #define SINGLE_KEY(member)                                             \
        static int lock_stat_key_ ## member(struct lock_stat *one,      \
@@ -175,8 +305,6 @@ static struct lock_stat *lock_stat_findnew(void *addr, const char *name)
                goto alloc_failed;
        strcpy(new->name, name);
 
-       /* LOCK_STATE_UNLOCKED == 0 isn't guaranteed forever */
-       new->state = LOCK_STATE_UNLOCKED;
        new->wait_time_min = ULLONG_MAX;
 
        list_add(&new->hash_entry, entry);
@@ -188,8 +316,6 @@ alloc_failed:
 
 static char                    const *input_name = "perf.data";
 
-static int                     profile_cpu = -1;
-
 struct raw_event_sample {
        u32                     size;
        char                    data[0];
@@ -198,6 +324,7 @@ struct raw_event_sample {
 struct trace_acquire_event {
        void                    *addr;
        const char              *name;
+       int                     flag;
 };
 
 struct trace_acquired_event {
@@ -241,120 +368,258 @@ struct trace_lock_handler {
                              struct thread *thread);
 };
 
+static struct lock_seq_stat *get_seq(struct thread_stat *ts, void *addr)
+{
+       struct lock_seq_stat *seq;
+
+       list_for_each_entry(seq, &ts->seq_list, list) {
+               if (seq->addr == addr)
+                       return seq;
+       }
+
+       seq = zalloc(sizeof(struct lock_seq_stat));
+       if (!seq)
+               die("Not enough memory\n");
+       seq->state = SEQ_STATE_UNINITIALIZED;
+       seq->addr = addr;
+
+       list_add(&seq->list, &ts->seq_list);
+       return seq;
+}
+
+enum broken_state {
+       BROKEN_ACQUIRE,
+       BROKEN_ACQUIRED,
+       BROKEN_CONTENDED,
+       BROKEN_RELEASE,
+       BROKEN_MAX,
+};
+
+static int bad_hist[BROKEN_MAX];
+
+enum acquire_flags {
+       TRY_LOCK = 1,
+       READ_LOCK = 2,
+};
+
 static void
 report_lock_acquire_event(struct trace_acquire_event *acquire_event,
                        struct event *__event __used,
                        int cpu __used,
-                       u64 timestamp,
+                       u64 timestamp __used,
                        struct thread *thread __used)
 {
-       struct lock_stat *st;
+       struct lock_stat *ls;
+       struct thread_stat *ts;
+       struct lock_seq_stat *seq;
+
+       ls = lock_stat_findnew(acquire_event->addr, acquire_event->name);
+       if (ls->discard)
+               return;
 
-       st = lock_stat_findnew(acquire_event->addr, acquire_event->name);
+       ts = thread_stat_findnew(thread->pid);
+       seq = get_seq(ts, acquire_event->addr);
 
-       switch (st->state) {
-       case LOCK_STATE_UNLOCKED:
+       switch (seq->state) {
+       case SEQ_STATE_UNINITIALIZED:
+       case SEQ_STATE_RELEASED:
+               if (!acquire_event->flag) {
+                       seq->state = SEQ_STATE_ACQUIRING;
+               } else {
+                       if (acquire_event->flag & TRY_LOCK)
+                               ls->nr_trylock++;
+                       if (acquire_event->flag & READ_LOCK)
+                               ls->nr_readlock++;
+                       seq->state = SEQ_STATE_READ_ACQUIRED;
+                       seq->read_count = 1;
+                       ls->nr_acquired++;
+               }
+               break;
+       case SEQ_STATE_READ_ACQUIRED:
+               if (acquire_event->flag & READ_LOCK) {
+                       seq->read_count++;
+                       ls->nr_acquired++;
+                       goto end;
+               } else {
+                       goto broken;
+               }
                break;
-       case LOCK_STATE_LOCKED:
+       case SEQ_STATE_ACQUIRED:
+       case SEQ_STATE_ACQUIRING:
+       case SEQ_STATE_CONTENDED:
+broken:
+               /* broken lock sequence, discard it */
+               ls->discard = 1;
+               bad_hist[BROKEN_ACQUIRE]++;
+               list_del(&seq->list);
+               free(seq);
+               goto end;
                break;
        default:
-               BUG_ON(1);
+               BUG_ON("Unknown state of lock sequence found!\n");
                break;
        }
 
-       st->prev_event_time = timestamp;
+       ls->nr_acquire++;
+       seq->prev_event_time = timestamp;
+end:
+       return;
 }
 
 static void
 report_lock_acquired_event(struct trace_acquired_event *acquired_event,
                         struct event *__event __used,
                         int cpu __used,
-                        u64 timestamp,
+                        u64 timestamp __used,
                         struct thread *thread __used)
 {
-       struct lock_stat *st;
+       struct lock_stat *ls;
+       struct thread_stat *ts;
+       struct lock_seq_stat *seq;
+       u64 contended_term;
+
+       ls = lock_stat_findnew(acquired_event->addr, acquired_event->name);
+       if (ls->discard)
+               return;
 
-       st = lock_stat_findnew(acquired_event->addr, acquired_event->name);
+       ts = thread_stat_findnew(thread->pid);
+       seq = get_seq(ts, acquired_event->addr);
 
-       switch (st->state) {
-       case LOCK_STATE_UNLOCKED:
-               st->state = LOCK_STATE_LOCKED;
-               st->nr_acquired++;
+       switch (seq->state) {
+       case SEQ_STATE_UNINITIALIZED:
+               /* orphan event, do nothing */
+               return;
+       case SEQ_STATE_ACQUIRING:
+               break;
+       case SEQ_STATE_CONTENDED:
+               contended_term = timestamp - seq->prev_event_time;
+               ls->wait_time_total += contended_term;
+               if (contended_term < ls->wait_time_min)
+                       ls->wait_time_min = contended_term;
+               if (ls->wait_time_max < contended_term)
+                       ls->wait_time_max = contended_term;
                break;
-       case LOCK_STATE_LOCKED:
+       case SEQ_STATE_RELEASED:
+       case SEQ_STATE_ACQUIRED:
+       case SEQ_STATE_READ_ACQUIRED:
+               /* broken lock sequence, discard it */
+               ls->discard = 1;
+               bad_hist[BROKEN_ACQUIRED]++;
+               list_del(&seq->list);
+               free(seq);
+               goto end;
                break;
+
        default:
-               BUG_ON(1);
+               BUG_ON("Unknown state of lock sequence found!\n");
                break;
        }
 
-       st->prev_event_time = timestamp;
+       seq->state = SEQ_STATE_ACQUIRED;
+       ls->nr_acquired++;
+       seq->prev_event_time = timestamp;
+end:
+       return;
 }
 
 static void
 report_lock_contended_event(struct trace_contended_event *contended_event,
                          struct event *__event __used,
                          int cpu __used,
-                         u64 timestamp,
+                         u64 timestamp __used,
                          struct thread *thread __used)
 {
-       struct lock_stat *st;
+       struct lock_stat *ls;
+       struct thread_stat *ts;
+       struct lock_seq_stat *seq;
 
-       st = lock_stat_findnew(contended_event->addr, contended_event->name);
+       ls = lock_stat_findnew(contended_event->addr, contended_event->name);
+       if (ls->discard)
+               return;
 
-       switch (st->state) {
-       case LOCK_STATE_UNLOCKED:
+       ts = thread_stat_findnew(thread->pid);
+       seq = get_seq(ts, contended_event->addr);
+
+       switch (seq->state) {
+       case SEQ_STATE_UNINITIALIZED:
+               /* orphan event, do nothing */
+               return;
+       case SEQ_STATE_ACQUIRING:
                break;
-       case LOCK_STATE_LOCKED:
-               st->nr_contended++;
+       case SEQ_STATE_RELEASED:
+       case SEQ_STATE_ACQUIRED:
+       case SEQ_STATE_READ_ACQUIRED:
+       case SEQ_STATE_CONTENDED:
+               /* broken lock sequence, discard it */
+               ls->discard = 1;
+               bad_hist[BROKEN_CONTENDED]++;
+               list_del(&seq->list);
+               free(seq);
+               goto end;
                break;
        default:
-               BUG_ON(1);
+               BUG_ON("Unknown state of lock sequence found!\n");
                break;
        }
 
-       st->prev_event_time = timestamp;
+       seq->state = SEQ_STATE_CONTENDED;
+       ls->nr_contended++;
+       seq->prev_event_time = timestamp;
+end:
+       return;
 }
 
 static void
 report_lock_release_event(struct trace_release_event *release_event,
                        struct event *__event __used,
                        int cpu __used,
-                       u64 timestamp,
+                       u64 timestamp __used,
                        struct thread *thread __used)
 {
-       struct lock_stat *st;
-       u64 hold_time;
+       struct lock_stat *ls;
+       struct thread_stat *ts;
+       struct lock_seq_stat *seq;
 
-       st = lock_stat_findnew(release_event->addr, release_event->name);
+       ls = lock_stat_findnew(release_event->addr, release_event->name);
+       if (ls->discard)
+               return;
 
-       switch (st->state) {
-       case LOCK_STATE_UNLOCKED:
-               break;
-       case LOCK_STATE_LOCKED:
-               st->state = LOCK_STATE_UNLOCKED;
-               hold_time = timestamp - st->prev_event_time;
+       ts = thread_stat_findnew(thread->pid);
+       seq = get_seq(ts, release_event->addr);
 
-               if (timestamp < st->prev_event_time) {
-                       /* terribly, this can happen... */
+       switch (seq->state) {
+       case SEQ_STATE_UNINITIALIZED:
+               goto end;
+               break;
+       case SEQ_STATE_ACQUIRED:
+               break;
+       case SEQ_STATE_READ_ACQUIRED:
+               seq->read_count--;
+               BUG_ON(seq->read_count < 0);
+               if (!seq->read_count) {
+                       ls->nr_release++;
                        goto end;
                }
-
-               if (st->wait_time_min > hold_time)
-                       st->wait_time_min = hold_time;
-               if (st->wait_time_max < hold_time)
-                       st->wait_time_max = hold_time;
-               st->wait_time_total += hold_time;
-
-               st->nr_release++;
+               break;
+       case SEQ_STATE_ACQUIRING:
+       case SEQ_STATE_CONTENDED:
+       case SEQ_STATE_RELEASED:
+               /* broken lock sequence, discard it */
+               ls->discard = 1;
+               bad_hist[BROKEN_RELEASE]++;
+               goto free_seq;
                break;
        default:
-               BUG_ON(1);
+               BUG_ON("Unknown state of lock sequence found!\n");
                break;
        }
 
+       ls->nr_release++;
+free_seq:
+       list_del(&seq->list);
+       free(seq);
 end:
-       st->prev_event_time = timestamp;
+       return;
 }
 
 /* lock oriented handlers */
@@ -381,6 +646,7 @@ process_lock_acquire_event(void *data,
        tmp = raw_field_value(event, "lockdep_addr", data);
        memcpy(&acquire_event.addr, &tmp, sizeof(void *));
        acquire_event.name = (char *)raw_field_ptr(event, "name", data);
+       acquire_event.flag = (int)raw_field_value(event, "flag", data);
 
        if (trace_handler->acquire_event)
                trace_handler->acquire_event(&acquire_event, event, cpu, timestamp, thread);
@@ -441,8 +707,7 @@ process_lock_release_event(void *data,
 }
 
 static void
-process_raw_event(void *data, int cpu,
-                 u64 timestamp, struct thread *thread)
+process_raw_event(void *data, int cpu, u64 timestamp, struct thread *thread)
 {
        struct event *event;
        int type;
@@ -460,173 +725,19 @@ process_raw_event(void *data, int cpu,
                process_lock_release_event(data, event, cpu, timestamp, thread);
 }
 
-struct raw_event_queue {
-       u64                     timestamp;
-       int                     cpu;
-       void                    *data;
-       struct thread           *thread;
-       struct list_head        list;
-};
-
-static LIST_HEAD(raw_event_head);
-
-#define FLUSH_PERIOD   (5 * NSEC_PER_SEC)
-
-static u64 flush_limit = ULLONG_MAX;
-static u64 last_flush = 0;
-struct raw_event_queue *last_inserted;
-
-static void flush_raw_event_queue(u64 limit)
-{
-       struct raw_event_queue *tmp, *iter;
-
-       list_for_each_entry_safe(iter, tmp, &raw_event_head, list) {
-               if (iter->timestamp > limit)
-                       return;
-
-               if (iter == last_inserted)
-                       last_inserted = NULL;
-
-               process_raw_event(iter->data, iter->cpu, iter->timestamp,
-                                 iter->thread);
-
-               last_flush = iter->timestamp;
-               list_del(&iter->list);
-               free(iter->data);
-               free(iter);
-       }
-}
-
-static void __queue_raw_event_end(struct raw_event_queue *new)
-{
-       struct raw_event_queue *iter;
-
-       list_for_each_entry_reverse(iter, &raw_event_head, list) {
-               if (iter->timestamp < new->timestamp) {
-                       list_add(&new->list, &iter->list);
-                       return;
-               }
-       }
-
-       list_add(&new->list, &raw_event_head);
-}
-
-static void __queue_raw_event_before(struct raw_event_queue *new,
-                                    struct raw_event_queue *iter)
+static void print_bad_events(int bad, int total)
 {
-       list_for_each_entry_continue_reverse(iter, &raw_event_head, list) {
-               if (iter->timestamp < new->timestamp) {
-                       list_add(&new->list, &iter->list);
-                       return;
-               }
-       }
-
-       list_add(&new->list, &raw_event_head);
-}
-
-static void __queue_raw_event_after(struct raw_event_queue *new,
-                                    struct raw_event_queue *iter)
-{
-       list_for_each_entry_continue(iter, &raw_event_head, list) {
-               if (iter->timestamp > new->timestamp) {
-                       list_add_tail(&new->list, &iter->list);
-                       return;
-               }
-       }
-       list_add_tail(&new->list, &raw_event_head);
-}
-
-/* The queue is ordered by time */
-static void __queue_raw_event(struct raw_event_queue *new)
-{
-       if (!last_inserted) {
-               __queue_raw_event_end(new);
-               return;
-       }
-
-       /*
-        * Most of the time the current event has a timestamp
-        * very close to the last event inserted, unless we just switched
-        * to another event buffer. Having a sorting based on a list and
-        * on the last inserted event that is close to the current one is
-        * probably more efficient than an rbtree based sorting.
-        */
-       if (last_inserted->timestamp >= new->timestamp)
-               __queue_raw_event_before(new, last_inserted);
-       else
-               __queue_raw_event_after(new, last_inserted);
-}
-
-static void queue_raw_event(void *data, int raw_size, int cpu,
-                           u64 timestamp, struct thread *thread)
-{
-       struct raw_event_queue *new;
-
-       if (flush_limit == ULLONG_MAX)
-               flush_limit = timestamp + FLUSH_PERIOD;
-
-       if (timestamp < last_flush) {
-               printf("Warning: Timestamp below last timeslice flush\n");
-               return;
-       }
-
-       new = malloc(sizeof(*new));
-       if (!new)
-               die("Not enough memory\n");
-
-       new->timestamp = timestamp;
-       new->cpu = cpu;
-       new->thread = thread;
-
-       new->data = malloc(raw_size);
-       if (!new->data)
-               die("Not enough memory\n");
-
-       memcpy(new->data, data, raw_size);
-
-       __queue_raw_event(new);
-       last_inserted = new;
-
-       /*
-        * We want to have a slice of events covering 2 * FLUSH_PERIOD
-        * If FLUSH_PERIOD is big enough, it ensures every events that occured
-        * in the first half of the timeslice have all been buffered and there
-        * are none remaining (we need that because of the weakly ordered
-        * event recording we have). Then once we reach the 2 * FLUSH_PERIOD
-        * timeslice, we flush the first half to be gentle with the memory
-        * (the second half can still get new events in the middle, so wait
-        * another period to flush it)
-        */
-       if (new->timestamp > flush_limit &&
-               new->timestamp - flush_limit > FLUSH_PERIOD) {
-               flush_limit += FLUSH_PERIOD;
-               flush_raw_event_queue(flush_limit);
-       }
-}
-
-static int process_sample_event(event_t *event, struct perf_session *session)
-{
-       struct thread *thread;
-       struct sample_data data;
-
-       bzero(&data, sizeof(struct sample_data));
-       event__parse_sample(event, session->sample_type, &data);
-       thread = perf_session__findnew(session, data.pid);
-
-       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);
-
-       if (profile_cpu != -1 && profile_cpu != (int) data.cpu)
-               return 0;
-
-       queue_raw_event(data.raw_data, data.raw_size, data.cpu, data.time, thread);
-
-       return 0;
+       /* Output for debug, this have to be removed */
+       int i;
+       const char *name[4] =
+               { "acquire", "acquired", "contended", "release" };
+
+       pr_info("\n=== output for debug===\n\n");
+       pr_info("bad: %d, total: %d\n", bad, total);
+       pr_info("bad rate: %f %%\n", (double)bad / (double)total * 100);
+       pr_info("histogram of events caused bad sequence\n");
+       for (i = 0; i < BROKEN_MAX; i++)
+               pr_info(" %10s: %d\n", name[i], bad_hist[i]);
 }
 
 /* TODO: various way to print, coloring, nano or milli sec */
@@ -634,26 +745,30 @@ static void print_result(void)
 {
        struct lock_stat *st;
        char cut_name[20];
+       int bad, total;
 
-       printf("%18s ", "ID");
-       printf("%20s ", "Name");
-       printf("%10s ", "acquired");
-       printf("%10s ", "contended");
+       pr_info("%20s ", "Name");
+       pr_info("%10s ", "acquired");
+       pr_info("%10s ", "contended");
 
-       printf("%15s ", "total wait (ns)");
-       printf("%15s ", "max wait (ns)");
-       printf("%15s ", "min wait (ns)");
+       pr_info("%15s ", "total wait (ns)");
+       pr_info("%15s ", "max wait (ns)");
+       pr_info("%15s ", "min wait (ns)");
 
-       printf("\n\n");
+       pr_info("\n\n");
 
+       bad = total = 0;
        while ((st = pop_from_result())) {
+               total++;
+               if (st->discard) {
+                       bad++;
+                       continue;
+               }
                bzero(cut_name, 20);
 
-               printf("%p ", st->addr);
-
                if (strlen(st->name) < 16) {
                        /* output raw name */
-                       printf("%20s ", st->name);
+                       pr_info("%20s ", st->name);
                } else {
                        strncpy(cut_name, st->name, 16);
                        cut_name[16] = '.';
@@ -661,18 +776,39 @@ static void print_result(void)
                        cut_name[18] = '.';
                        cut_name[19] = '\0';
                        /* cut off name for saving output style */
-                       printf("%20s ", cut_name);
+                       pr_info("%20s ", cut_name);
                }
 
-               printf("%10u ", st->nr_acquired);
-               printf("%10u ", st->nr_contended);
+               pr_info("%10u ", st->nr_acquired);
+               pr_info("%10u ", st->nr_contended);
 
-               printf("%15llu ", st->wait_time_total);
-               printf("%15llu ", st->wait_time_max);
-               printf("%15llu ", st->wait_time_min == ULLONG_MAX ?
+               pr_info("%15llu ", st->wait_time_total);
+               pr_info("%15llu ", st->wait_time_max);
+               pr_info("%15llu ", st->wait_time_min == ULLONG_MAX ?
                       0 : st->wait_time_min);
-               printf("\n");
+               pr_info("\n");
        }
+
+       print_bad_events(bad, total);
+}
+
+static bool info_threads, info_map;
+
+static void dump_threads(void)
+{
+       struct thread_stat *st;
+       struct rb_node *node;
+       struct thread *t;
+
+       pr_info("%10s: comm\n", "Thread ID");
+
+       node = rb_first(&thread_stats);
+       while (node) {
+               st = container_of(node, struct thread_stat, rb);
+               t = perf_session__findnew(session, st->tid);
+               pr_info("%10d: %s\n", st->tid, t->comm);
+               node = rb_next(node);
+       };
 }
 
 static void dump_map(void)
@@ -680,23 +816,53 @@ static void dump_map(void)
        unsigned int i;
        struct lock_stat *st;
 
+       pr_info("Address of instance: name of class\n");
        for (i = 0; i < LOCKHASH_SIZE; i++) {
                list_for_each_entry(st, &lockhash_table[i], hash_entry) {
-                       printf("%p: %s\n", st->addr, st->name);
+                       pr_info(" %p: %s\n", st->addr, st->name);
                }
        }
 }
 
+static void dump_info(void)
+{
+       if (info_threads)
+               dump_threads();
+       else if (info_map)
+               dump_map();
+       else
+               die("Unknown type of information\n");
+}
+
+static int process_sample_event(event_t *self, struct perf_session *s)
+{
+       struct sample_data data;
+       struct thread *thread;
+
+       bzero(&data, sizeof(data));
+       event__parse_sample(self, s->sample_type, &data);
+
+       thread = perf_session__findnew(s, data.tid);
+       if (thread == NULL) {
+               pr_debug("problem processing %d event, skipping it.\n",
+                       self->header.type);
+               return -1;
+       }
+
+       process_raw_event(data.raw_data, data.cpu, data.time, thread);
+
+       return 0;
+}
+
 static struct perf_event_ops eops = {
        .sample                 = process_sample_event,
        .comm                   = event__process_comm,
+       .ordered_samples        = true,
 };
 
-static struct perf_session *session;
-
 static int read_events(void)
 {
-       session = perf_session__new(input_name, O_RDONLY, 0);
+       session = perf_session__new(input_name, O_RDONLY, 0, false);
        if (!session)
                die("Initializing perf session failed\n");
 
@@ -720,7 +886,6 @@ static void __cmd_report(void)
        setup_pager();
        select_key();
        read_events();
-       flush_raw_event_queue(ULLONG_MAX);
        sort_result();
        print_result();
 }
@@ -737,6 +902,19 @@ static const struct option report_options[] = {
        OPT_END()
 };
 
+static const char * const info_usage[] = {
+       "perf lock info [<options>]",
+       NULL
+};
+
+static const struct option info_options[] = {
+       OPT_BOOLEAN('t', "threads", &info_threads,
+                   "dump thread list in perf.data"),
+       OPT_BOOLEAN('m', "map", &info_map,
+                   "map of lock instances (name:address table)"),
+       OPT_END()
+};
+
 static const char * const lock_usage[] = {
        "perf lock [<options>] {record|trace|report}",
        NULL
@@ -744,14 +922,13 @@ static const char * const lock_usage[] = {
 
 static const struct option lock_options[] = {
        OPT_STRING('i', "input", &input_name, "file", "input file name"),
-       OPT_BOOLEAN('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"),
+       OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"),
        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"),
        OPT_END()
 };
 
 static const char *record_args[] = {
        "record",
-       "-a",
        "-R",
        "-f",
        "-m", "1024",
@@ -808,12 +985,18 @@ int cmd_lock(int argc, const char **argv, const char *prefix __used)
        } else if (!strcmp(argv[0], "trace")) {
                /* Aliased to 'perf trace' */
                return cmd_trace(argc, argv, prefix);
-       } else if (!strcmp(argv[0], "map")) {
+       } else if (!strcmp(argv[0], "info")) {
+               if (argc) {
+                       argc = parse_options(argc, argv,
+                                            info_options, info_usage, 0);
+                       if (argc)
+                               usage_with_options(info_usage, info_options);
+               }
                /* recycling report_lock_ops */
                trace_handler = &report_lock_ops;
                setup_pager();
                read_events();
-               dump_map();
+               dump_info();
        } else {
                usage_with_options(lock_usage, lock_options);
        }
index c30a33592340e4977c4d82cfb7dabd618370be2c..61c6d70732c9888dac776a07731e892723addfbb 100644 (file)
 #include "builtin.h"
 #include "util/util.h"
 #include "util/strlist.h"
-#include "util/event.h"
+#include "util/symbol.h"
 #include "util/debug.h"
 #include "util/debugfs.h"
-#include "util/symbol.h"
-#include "util/thread.h"
 #include "util/parse-options.h"
-#include "util/parse-events.h" /* For debugfs_path */
 #include "util/probe-finder.h"
 #include "util/probe-event.h"
 
 #define MAX_PATH_LEN 256
-#define MAX_PROBES 128
 
 /* Session management structure */
 static struct {
-       bool need_dwarf;
        bool list_events;
        bool force_add;
        bool show_lines;
-       int nr_probe;
-       struct probe_point probes[MAX_PROBES];
+       int nevents;
+       struct perf_probe_event events[MAX_PROBES];
        struct strlist *dellist;
-       struct map_groups kmap_groups;
-       struct map *kmaps[MAP__NR_TYPES];
        struct line_range line_range;
-} session;
+       int max_probe_points;
+} params;
 
 
 /* Parse an event definition. Note that any error must die. */
-static void parse_probe_event(const char *str)
+static int parse_probe_event(const char *str)
 {
-       struct probe_point *pp = &session.probes[session.nr_probe];
+       struct perf_probe_event *pev = &params.events[params.nevents];
+       int ret;
 
-       pr_debug("probe-definition(%d): %s\n", session.nr_probe, str);
-       if (++session.nr_probe == MAX_PROBES)
+       pr_debug("probe-definition(%d): %s\n", params.nevents, str);
+       if (++params.nevents == MAX_PROBES)
                die("Too many probes (> %d) are specified.", MAX_PROBES);
 
-       /* Parse perf-probe event into probe_point */
-       parse_perf_probe_event(str, pp, &session.need_dwarf);
+       /* Parse a perf-probe command into event */
+       ret = parse_perf_probe_command(str, pev);
+       pr_debug("%d arguments\n", pev->nargs);
 
-       pr_debug("%d arguments\n", pp->nr_args);
+       return ret;
 }
 
-static void parse_probe_event_argv(int argc, const char **argv)
+static int parse_probe_event_argv(int argc, const char **argv)
 {
-       int i, len;
+       int i, len, ret;
        char *buf;
 
        /* Bind up rest arguments */
        len = 0;
        for (i = 0; i < argc; i++)
                len += strlen(argv[i]) + 1;
-       buf = zalloc(len + 1);
-       if (!buf)
-               die("Failed to allocate memory for binding arguments.");
+       buf = xzalloc(len + 1);
        len = 0;
        for (i = 0; i < argc; i++)
                len += sprintf(&buf[len], "%s ", argv[i]);
-       parse_probe_event(buf);
+       ret = parse_probe_event(buf);
        free(buf);
+       return ret;
 }
 
 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;
+               return parse_probe_event(str);
+       else
+               return 0;
 }
 
 static int opt_del_probe_event(const struct option *opt __used,
                               const char *str, int unset __used)
 {
        if (str) {
-               if (!session.dellist)
-                       session.dellist = strlist__new(true, NULL);
-               strlist__add(session.dellist, str);
+               if (!params.dellist)
+                       params.dellist = strlist__new(true, NULL);
+               strlist__add(params.dellist, str);
        }
        return 0;
 }
 
-/* Currently just checking function name from symbol map */
-static void evaluate_probe_point(struct probe_point *pp)
-{
-       struct symbol *sym;
-       sym = map__find_symbol_by_name(session.kmaps[MAP__FUNCTION],
-                                      pp->function, NULL);
-       if (!sym)
-               die("Kernel symbol \'%s\' not found - probe not added.",
-                   pp->function);
-}
-
-#ifndef NO_DWARF_SUPPORT
-static int open_vmlinux(void)
-{
-       if (map__load(session.kmaps[MAP__FUNCTION], NULL) < 0) {
-               pr_debug("Failed to load kernel map.\n");
-               return -EINVAL;
-       }
-       pr_debug("Try to open %s\n",
-                session.kmaps[MAP__FUNCTION]->dso->long_name);
-       return open(session.kmaps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
-}
-
+#ifdef DWARF_SUPPORT
 static int opt_show_lines(const struct option *opt __used,
                          const char *str, int unset __used)
 {
+       int ret = 0;
+
        if (str)
-               parse_line_range_desc(str, &session.line_range);
-       INIT_LIST_HEAD(&session.line_range.line_list);
-       session.show_lines = true;
-       return 0;
+               ret = parse_line_range_desc(str, &params.line_range);
+       INIT_LIST_HEAD(&params.line_range.line_list);
+       params.show_lines = true;
+
+       return ret;
 }
 #endif
 
@@ -156,29 +133,25 @@ static const char * const probe_usage[] = {
        "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
        "perf probe [<options>] --del '[GROUP:]EVENT' ...",
        "perf probe --list",
-#ifndef NO_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
        "perf probe --line 'LINEDESC'",
 #endif
        NULL
 };
 
 static const struct option options[] = {
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show parsed arguments, etc)"),
-#ifndef NO_DWARF_SUPPORT
-       OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
-                  "file", "vmlinux pathname"),
-#endif
-       OPT_BOOLEAN('l', "list", &session.list_events,
+       OPT_BOOLEAN('l', "list", &params.list_events,
                    "list up current probe events"),
        OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.",
                opt_del_probe_event),
        OPT_CALLBACK('a', "add", NULL,
-#ifdef NO_DWARF_SUPPORT
-               "[EVENT=]FUNC[+OFF|%return] [ARG ...]",
-#else
+#ifdef DWARF_SUPPORT
                "[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT"
-               " [ARG ...]",
+               " [[NAME=]ARG ...]",
+#else
+               "[EVENT=]FUNC[+OFF|%return] [[NAME=]ARG ...]",
 #endif
                "probe point definition, where\n"
                "\t\tGROUP:\tGroup name (optional)\n"
@@ -186,51 +159,35 @@ static const struct option options[] = {
                "\t\tFUNC:\tFunction name\n"
                "\t\tOFF:\tOffset from function entry (in byte)\n"
                "\t\t%return:\tPut the probe at function return\n"
-#ifdef NO_DWARF_SUPPORT
-               "\t\tARG:\tProbe argument (only \n"
-#else
+#ifdef DWARF_SUPPORT
                "\t\tSRC:\tSource code path\n"
                "\t\tRL:\tRelative line number from function entry.\n"
                "\t\tAL:\tAbsolute line number in file.\n"
                "\t\tPT:\tLazy expression of line code.\n"
                "\t\tARG:\tProbe argument (local variable name or\n"
-#endif
                "\t\t\tkprobe-tracer argument format.)\n",
+#else
+               "\t\tARG:\tProbe argument (kprobe-tracer argument format.)\n",
+#endif
                opt_add_probe_event),
-       OPT_BOOLEAN('f', "force", &session.force_add, "forcibly add events"
+       OPT_BOOLEAN('f', "force", &params.force_add, "forcibly add events"
                    " with existing name"),
-#ifndef NO_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
        OPT_CALLBACK('L', "line", NULL,
-                    "FUNC[:RLN[+NUM|:RLN2]]|SRC:ALN[+NUM|:ALN2]",
+                    "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]",
                     "Show source code lines.", opt_show_lines),
+       OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
+                  "file", "vmlinux pathname"),
 #endif
+       OPT__DRY_RUN(&probe_event_dry_run),
+       OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
+                "Set how many probe points can be found for a probe."),
        OPT_END()
 };
 
-/* Initialize symbol maps for vmlinux */
-static void init_vmlinux(void)
-{
-       symbol_conf.sort_by_name = true;
-       if (symbol_conf.vmlinux_name == NULL)
-               symbol_conf.try_vmlinux_path = true;
-       else
-               pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
-       if (symbol__init() < 0)
-               die("Failed to init symbol map.");
-
-       map_groups__init(&session.kmap_groups);
-       if (map_groups__create_kernel_maps(&session.kmap_groups,
-                                          session.kmaps) < 0)
-               die("Failed to create kernel maps.");
-}
-
 int cmd_probe(int argc, const char **argv, const char *prefix __used)
 {
-       int i, ret;
-#ifndef NO_DWARF_SUPPORT
-       int fd;
-#endif
-       struct probe_point *pp;
+       int ret;
 
        argc = parse_options(argc, argv, options, probe_usage,
                             PARSE_OPT_STOP_AT_NON_OPTION);
@@ -239,123 +196,69 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
                        pr_warning("  Error: '-' is not supported.\n");
                        usage_with_options(probe_usage, options);
                }
-               parse_probe_event_argv(argc, argv);
+               ret = parse_probe_event_argv(argc, argv);
+               if (ret < 0) {
+                       pr_err("  Error: Parse Error.  (%d)\n", ret);
+                       return ret;
+               }
        }
 
-       if ((!session.nr_probe && !session.dellist && !session.list_events &&
-            !session.show_lines))
-               usage_with_options(probe_usage, options);
+       if (params.max_probe_points == 0)
+               params.max_probe_points = MAX_PROBES;
 
-       if (debugfs_valid_mountpoint(debugfs_path) < 0)
-               die("Failed to find debugfs path.");
+       if ((!params.nevents && !params.dellist && !params.list_events &&
+            !params.show_lines))
+               usage_with_options(probe_usage, options);
 
-       if (session.list_events) {
-               if (session.nr_probe != 0 || session.dellist) {
-                       pr_warning("  Error: Don't use --list with"
-                                  " --add/--del.\n");
+       if (params.list_events) {
+               if (params.nevents != 0 || params.dellist) {
+                       pr_err("  Error: Don't use --list with --add/--del.\n");
                        usage_with_options(probe_usage, options);
                }
-               if (session.show_lines) {
-                       pr_warning("  Error: Don't use --list with --line.\n");
+               if (params.show_lines) {
+                       pr_err("  Error: Don't use --list with --line.\n");
                        usage_with_options(probe_usage, options);
                }
-               show_perf_probe_events();
-               return 0;
+               ret = show_perf_probe_events();
+               if (ret < 0)
+                       pr_err("  Error: Failed to show event list. (%d)\n",
+                              ret);
+               return ret;
        }
 
-#ifndef NO_DWARF_SUPPORT
-       if (session.show_lines) {
-               if (session.nr_probe != 0 || session.dellist) {
+#ifdef DWARF_SUPPORT
+       if (params.show_lines) {
+               if (params.nevents != 0 || params.dellist) {
                        pr_warning("  Error: Don't use --line with"
                                   " --add/--del.\n");
                        usage_with_options(probe_usage, options);
                }
-               init_vmlinux();
-               fd = open_vmlinux();
-               if (fd < 0)
-                       die("Could not open debuginfo file.");
-               ret = find_line_range(fd, &session.line_range);
-               if (ret <= 0)
-                       die("Source line is not found.\n");
-               close(fd);
-               show_line_range(&session.line_range);
-               return 0;
-       }
-#endif
 
-       if (session.dellist) {
-               del_trace_kprobe_events(session.dellist);
-               strlist__delete(session.dellist);
-               if (session.nr_probe == 0)
-                       return 0;
+               ret = show_line_range(&params.line_range);
+               if (ret < 0)
+                       pr_err("  Error: Failed to show lines. (%d)\n", ret);
+               return ret;
        }
+#endif
 
-       /* Add probes */
-       init_vmlinux();
-
-       if (session.need_dwarf)
-#ifdef NO_DWARF_SUPPORT
-               die("Debuginfo-analysis is not supported");
-#else  /* !NO_DWARF_SUPPORT */
-               pr_debug("Some probes require debuginfo.\n");
-
-       fd = open_vmlinux();
-       if (fd < 0) {
-               if (session.need_dwarf)
-                       die("Could not open debuginfo file.");
-
-               pr_debug("Could not open vmlinux/module file."
-                        " Try to use symbols.\n");
-               goto end_dwarf;
-       }
-
-       /* Searching probe points */
-       for (i = 0; i < session.nr_probe; i++) {
-               pp = &session.probes[i];
-               if (pp->found)
-                       continue;
-
-               lseek(fd, SEEK_SET, 0);
-               ret = find_probe_point(fd, pp);
-               if (ret > 0)
-                       continue;
-               if (ret == 0) { /* No error but failed to find probe point. */
-                       synthesize_perf_probe_point(pp);
-                       die("Probe point '%s' not found. - probe not added.",
-                           pp->probes[0]);
-               }
-               /* Error path */
-               if (session.need_dwarf) {
-                       if (ret == -ENOENT)
-                               pr_warning("No dwarf info found in the vmlinux - please rebuild with CONFIG_DEBUG_INFO=y.\n");
-                       die("Could not analyze debuginfo.");
+       if (params.dellist) {
+               ret = del_perf_probe_events(params.dellist);
+               strlist__delete(params.dellist);
+               if (ret < 0) {
+                       pr_err("  Error: Failed to delete events. (%d)\n", ret);
+                       return ret;
                }
-               pr_debug("An error occurred in debuginfo analysis."
-                        " Try to use symbols.\n");
-               break;
        }
-       close(fd);
-
-end_dwarf:
-#endif /* !NO_DWARF_SUPPORT */
 
-       /* Synthesize probes without dwarf */
-       for (i = 0; i < session.nr_probe; i++) {
-               pp = &session.probes[i];
-               if (pp->found)  /* This probe is already found. */
-                       continue;
-
-               evaluate_probe_point(pp);
-               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.");
+       if (params.nevents) {
+               ret = add_perf_probe_events(params.events, params.nevents,
+                                           params.force_add,
+                                           params.max_probe_points);
+               if (ret < 0) {
+                       pr_err("  Error: Failed to add events. (%d)\n", ret);
+                       return ret;
+               }
        }
-
-       /* Settng up probe points */
-       add_trace_kprobe_events(session.probes, session.nr_probe,
-                               session.force_add);
        return 0;
 }
 
index 771533ced6a803d23886214d5551df1f0db440b1..cb46c7d0ea99436863cbfed0c6e9a67f8618e9fe 100644 (file)
 #include "util/util.h"
 #include "util/parse-options.h"
 #include "util/parse-events.h"
-#include "util/string.h"
 
 #include "util/header.h"
 #include "util/event.h"
 #include "util/debug.h"
 #include "util/session.h"
 #include "util/symbol.h"
+#include "util/cpumap.h"
 
 #include <unistd.h>
 #include <sched.h>
 
-static int                     fd[MAX_NR_CPUS][MAX_COUNTERS];
+enum write_mode_t {
+       WRITE_FORCE,
+       WRITE_APPEND
+};
+
+static int                     *fd[MAX_NR_CPUS][MAX_COUNTERS];
 
-static long                    default_interval                =      0;
+static u64                     user_interval                   = ULLONG_MAX;
+static u64                     default_interval                =      0;
 
 static int                     nr_cpus                         =      0;
 static unsigned int            page_size;
 static unsigned int            mmap_pages                      =    128;
+static unsigned int            user_freq                       = UINT_MAX;
 static int                     freq                            =   1000;
 static int                     output;
+static int                     pipe_output                     =      0;
 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                     realtime_prio                   =      0;
+static bool                    raw_samples                     =  false;
+static bool                    system_wide                     =  false;
 static int                     profile_cpu                     =     -1;
 static pid_t                   target_pid                      =     -1;
+static pid_t                   target_tid                      =     -1;
+static pid_t                   *all_tids                       =      NULL;
+static int                     thread_num                      =      0;
 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 bool                    no_inherit                      =  false;
+static enum write_mode_t       write_mode                      = WRITE_FORCE;
+static bool                    call_graph                      =  false;
+static bool                    inherit_stat                    =  false;
+static bool                    no_samples                      =  false;
+static bool                    sample_address                  =  false;
+static bool                    multiplex                       =  false;
 static int                     multiplex_fd                    =     -1;
 
 static long                    samples                         =      0;
@@ -59,7 +69,7 @@ static struct timeval         this_read;
 
 static u64                     bytes_written                   =      0;
 
-static struct pollfd           event_array[MAX_NR_CPUS * MAX_COUNTERS];
+static struct pollfd           *event_array;
 
 static int                     nr_poll                         =      0;
 static int                     nr_cpu                          =      0;
@@ -76,7 +86,7 @@ struct mmap_data {
        unsigned int            prev;
 };
 
-static struct mmap_data                mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
+static struct mmap_data                *mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
 
 static unsigned long mmap_read_head(struct mmap_data *md)
 {
@@ -100,6 +110,11 @@ static void mmap_write_tail(struct mmap_data *md, unsigned long tail)
        pc->data_tail = tail;
 }
 
+static void advance_output(size_t size)
+{
+       bytes_written += size;
+}
+
 static void write_output(void *buf, size_t size)
 {
        while (size) {
@@ -224,12 +239,13 @@ static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int n
        return h_attr;
 }
 
-static void create_counter(int counter, int cpu, pid_t pid)
+static void create_counter(int counter, int cpu)
 {
        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 thread_index;
        int ret;
        struct {
                u64 count;
@@ -244,10 +260,22 @@ static void create_counter(int counter, int cpu, pid_t pid)
 
        attr->sample_type       |= PERF_SAMPLE_IP | PERF_SAMPLE_TID;
 
-       if (freq) {
-               attr->sample_type       |= PERF_SAMPLE_PERIOD;
-               attr->freq              = 1;
-               attr->sample_freq       = freq;
+       if (nr_counters > 1)
+               attr->sample_type |= PERF_SAMPLE_ID;
+
+       /*
+        * We default some events to a 1 default interval. But keep
+        * it a weak assumption overridable by the user.
+        */
+       if (!attr->sample_period || (user_freq != UINT_MAX &&
+                                    user_interval != ULLONG_MAX)) {
+               if (freq) {
+                       attr->sample_type       |= PERF_SAMPLE_PERIOD;
+                       attr->freq              = 1;
+                       attr->sample_freq       = freq;
+               } else {
+                       attr->sample_period = default_interval;
+               }
        }
 
        if (no_samples)
@@ -270,119 +298,130 @@ static void create_counter(int counter, int cpu, pid_t pid)
 
        attr->mmap              = track;
        attr->comm              = track;
-       attr->inherit           = inherit;
-       attr->disabled          = 1;
+       attr->inherit           = !no_inherit;
+       if (target_pid == -1 && target_tid == -1 && !system_wide) {
+               attr->disabled = 1;
+               attr->enable_on_exec = 1;
+       }
 
+       for (thread_index = 0; thread_index < thread_num; thread_index++) {
 try_again:
-       fd[nr_cpu][counter] = sys_perf_event_open(attr, pid, cpu, group_fd, 0);
-
-       if (fd[nr_cpu][counter] < 0) {
-               int err = errno;
-
-               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");
+               fd[nr_cpu][counter][thread_index] = sys_perf_event_open(attr,
+                               all_tids[thread_index], cpu, group_fd, 0);
+
+               if (fd[nr_cpu][counter][thread_index] < 0) {
+                       int err = errno;
+
+                       if (err == EPERM || err == EACCES)
+                               die("Permission error - are you root?\n"
+                                       "\t Consider tweaking"
+                                       " /proc/sys/kernel/perf_event_paranoid.\n");
+                       else if (err ==  ENODEV && profile_cpu != -1) {
+                               die("No such device - did you specify"
+                                       " an out-of-range profile CPU?\n");
+                       }
 
-               /*
-                * If it's cycles then fall back to hrtimer
-                * based cpu-clock-tick sw counter, which
-                * is always available even if no PMU support:
-                */
-               if (attr->type == PERF_TYPE_HARDWARE
-                       && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
-
-                       if (verbose)
-                               warning(" ... trying to fall back to cpu-clock-ticks\n");
-                       attr->type = PERF_TYPE_SOFTWARE;
-                       attr->config = PERF_COUNT_SW_CPU_CLOCK;
-                       goto try_again;
-               }
-               printf("\n");
-               error("perfcounter syscall returned with %d (%s)\n",
-                       fd[nr_cpu][counter], strerror(err));
+                       /*
+                        * If it's cycles then fall back to hrtimer
+                        * based cpu-clock-tick sw counter, which
+                        * is always available even if no PMU support:
+                        */
+                       if (attr->type == PERF_TYPE_HARDWARE
+                                       && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
+
+                               if (verbose)
+                                       warning(" ... trying to fall back to cpu-clock-ticks\n");
+                               attr->type = PERF_TYPE_SOFTWARE;
+                               attr->config = PERF_COUNT_SW_CPU_CLOCK;
+                               goto try_again;
+                       }
+                       printf("\n");
+                       error("perfcounter syscall returned with %d (%s)\n",
+                                       fd[nr_cpu][counter][thread_index], 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");
+                       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);
-       }
+                       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");
+               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))) {
-                       fprintf(stderr, "incompatible append\n");
-                       exit(-1);
+               if (!file_new) {
+                       if (memcmp(&h_attr->attr, attr, sizeof(*attr))) {
+                               fprintf(stderr, "incompatible append\n");
+                               exit(-1);
+                       }
                }
-       }
 
-       if (read(fd[nr_cpu][counter], &read_data, sizeof(read_data)) == -1) {
-               perror("Unable to read perf file descriptor\n");
-               exit(-1);
-       }
+               if (read(fd[nr_cpu][counter][thread_index], &read_data, sizeof(read_data)) == -1) {
+                       perror("Unable to read perf file descriptor\n");
+                       exit(-1);
+               }
 
-       if (perf_header_attr__add_id(h_attr, read_data.id) < 0) {
-               pr_warning("Not enough memory to add id\n");
-               exit(-1);
-       }
+               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);
+               assert(fd[nr_cpu][counter][thread_index] >= 0);
+               fcntl(fd[nr_cpu][counter][thread_index], F_SETFL, O_NONBLOCK);
 
-       /*
-        * First counter acts as the group leader:
-        */
-       if (group && group_fd == -1)
-               group_fd = fd[nr_cpu][counter];
-       if (multiplex && multiplex_fd == -1)
-               multiplex_fd = fd[nr_cpu][counter];
+               /*
+                * First counter acts as the group leader:
+                */
+               if (group && group_fd == -1)
+                       group_fd = fd[nr_cpu][counter][thread_index];
+               if (multiplex && multiplex_fd == -1)
+                       multiplex_fd = fd[nr_cpu][counter][thread_index];
 
-       if (multiplex && fd[nr_cpu][counter] != multiplex_fd) {
+               if (multiplex && fd[nr_cpu][counter][thread_index] != multiplex_fd) {
 
-               ret = ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_SET_OUTPUT, multiplex_fd);
-               assert(ret != -1);
-       } else {
-               event_array[nr_poll].fd = fd[nr_cpu][counter];
-               event_array[nr_poll].events = POLLIN;
-               nr_poll++;
-
-               mmap_array[nr_cpu][counter].counter = counter;
-               mmap_array[nr_cpu][counter].prev = 0;
-               mmap_array[nr_cpu][counter].mask = mmap_pages*page_size - 1;
-               mmap_array[nr_cpu][counter].base = mmap(NULL, (mmap_pages+1)*page_size,
-                               PROT_READ|PROT_WRITE, MAP_SHARED, fd[nr_cpu][counter], 0);
-               if (mmap_array[nr_cpu][counter].base == MAP_FAILED) {
-                       error("failed to mmap with %d (%s)\n", errno, strerror(errno));
-                       exit(-1);
+                       ret = ioctl(fd[nr_cpu][counter][thread_index], PERF_EVENT_IOC_SET_OUTPUT, multiplex_fd);
+                       assert(ret != -1);
+               } else {
+                       event_array[nr_poll].fd = fd[nr_cpu][counter][thread_index];
+                       event_array[nr_poll].events = POLLIN;
+                       nr_poll++;
+
+                       mmap_array[nr_cpu][counter][thread_index].counter = counter;
+                       mmap_array[nr_cpu][counter][thread_index].prev = 0;
+                       mmap_array[nr_cpu][counter][thread_index].mask = mmap_pages*page_size - 1;
+                       mmap_array[nr_cpu][counter][thread_index].base = mmap(NULL, (mmap_pages+1)*page_size,
+                               PROT_READ|PROT_WRITE, MAP_SHARED, fd[nr_cpu][counter][thread_index], 0);
+                       if (mmap_array[nr_cpu][counter][thread_index].base == MAP_FAILED) {
+                               error("failed to mmap with %d (%s)\n", errno, strerror(errno));
+                               exit(-1);
+                       }
                }
-       }
 
-       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);
+               if (filter != NULL) {
+                       ret = ioctl(fd[nr_cpu][counter][thread_index],
+                                       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);
 }
 
-static void open_counters(int cpu, pid_t pid)
+static void open_counters(int cpu)
 {
        int counter;
 
        group_fd = -1;
        for (counter = 0; counter < nr_counters; counter++)
-               create_counter(counter, cpu, pid);
+               create_counter(counter, cpu);
 
        nr_cpu++;
 }
@@ -391,6 +430,9 @@ static int process_buildids(void)
 {
        u64 size = lseek(output, 0, SEEK_CUR);
 
+       if (size == 0)
+               return 0;
+
        session->fd = output;
        return __perf_session__process_events(session, post_processing_offset,
                                              size - post_processing_offset,
@@ -399,10 +441,80 @@ static int process_buildids(void)
 
 static void atexit_header(void)
 {
-       session->header.data_size += bytes_written;
+       if (!pipe_output) {
+               session->header.data_size += bytes_written;
+
+               process_buildids();
+               perf_header__write(&session->header, output, true);
+       }
+}
+
+static void event__synthesize_guest_os(struct machine *machine, void *data)
+{
+       int err;
+       char *guest_kallsyms;
+       char path[PATH_MAX];
+       struct perf_session *psession = data;
+
+       if (machine__is_host(machine))
+               return;
+
+       /*
+        *As for guest kernel when processing subcommand record&report,
+        *we arrange module mmap prior to guest kernel mmap and trigger
+        *a preload dso because default guest module symbols are loaded
+        *from guest kallsyms instead of /lib/modules/XXX/XXX. This
+        *method is used to avoid symbol missing when the first addr is
+        *in module instead of in guest kernel.
+        */
+       err = event__synthesize_modules(process_synthesized_event,
+                                       psession, machine);
+       if (err < 0)
+               pr_err("Couldn't record guest kernel [%d]'s reference"
+                      " relocation symbol.\n", machine->pid);
+
+       if (machine__is_default_guest(machine))
+               guest_kallsyms = (char *) symbol_conf.default_guest_kallsyms;
+       else {
+               sprintf(path, "%s/proc/kallsyms", machine->root_dir);
+               guest_kallsyms = path;
+       }
+
+       /*
+        * We use _stext for guest kernel because guest kernel's /proc/kallsyms
+        * have no _text sometimes.
+        */
+       err = event__synthesize_kernel_mmap(process_synthesized_event,
+                                           psession, machine, "_text");
+       if (err < 0)
+               err = event__synthesize_kernel_mmap(process_synthesized_event,
+                                                   psession, machine, "_stext");
+       if (err < 0)
+               pr_err("Couldn't record guest kernel [%d]'s reference"
+                      " relocation symbol.\n", machine->pid);
+}
+
+static struct perf_event_header finished_round_event = {
+       .size = sizeof(struct perf_event_header),
+       .type = PERF_RECORD_FINISHED_ROUND,
+};
+
+static void mmap_read_all(void)
+{
+       int i, counter, thread;
+
+       for (i = 0; i < nr_cpu; i++) {
+               for (counter = 0; counter < nr_counters; counter++) {
+                       for (thread = 0; thread < thread_num; thread++) {
+                               if (mmap_array[i][counter][thread].base)
+                                       mmap_read(&mmap_array[i][counter][thread]);
+                       }
+
+               }
+       }
 
-       process_buildids();
-       perf_header__write(&session->header, output, true);
+       if (perf_header__has_feat(&session->header, HEADER_TRACE_INFO))
+               write_output(&finished_round_event, sizeof(finished_round_event));
 }
 
 static int __cmd_record(int argc, const char **argv)
@@ -414,13 +526,11 @@ static int __cmd_record(int argc, const char **argv)
        int err;
        unsigned long waking = 0;
        int child_ready_pipe[2], go_pipe[2];
-       const bool forks = target_pid == -1 && argc > 0;
+       const bool forks = argc > 0;
        char buf;
+       struct machine *machine;
 
        page_size = sysconf(_SC_PAGE_SIZE);
-       nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
-       assert(nr_cpus <= MAX_NR_CPUS);
-       assert(nr_cpus >= 0);
 
        atexit(sig_atexit);
        signal(SIGCHLD, sig_handler);
@@ -431,70 +541,63 @@ static int __cmd_record(int argc, const char **argv)
                exit(-1);
        }
 
-       if (!stat(output_name, &st) && st.st_size) {
-               if (!force) {
-                       if (!append_file) {
-                               pr_err("Error, output file %s exists, use -A "
-                                      "to append or -f to overwrite.\n",
-                                      output_name);
-                               exit(-1);
-                       }
-               } else {
+       if (!strcmp(output_name, "-"))
+               pipe_output = 1;
+       else if (!stat(output_name, &st) && st.st_size) {
+               if (write_mode == WRITE_FORCE) {
                        char oldname[PATH_MAX];
                        snprintf(oldname, sizeof(oldname), "%s.old",
                                 output_name);
                        unlink(oldname);
                        rename(output_name, oldname);
                }
-       } else {
-               append_file = 0;
+       } else if (write_mode == WRITE_APPEND) {
+               write_mode = WRITE_FORCE;
        }
 
        flags = O_CREAT|O_RDWR;
-       if (append_file)
+       if (write_mode == WRITE_APPEND)
                file_new = 0;
        else
                flags |= O_TRUNC;
 
-       output = open(output_name, flags, S_IRUSR|S_IWUSR);
+       if (pipe_output)
+               output = STDOUT_FILENO;
+       else
+               output = open(output_name, flags, S_IRUSR | S_IWUSR);
        if (output < 0) {
                perror("failed to create output file");
                exit(-1);
        }
 
-       session = perf_session__new(output_name, O_WRONLY, force);
+       session = perf_session__new(output_name, O_WRONLY,
+                                   write_mode == WRITE_FORCE, false);
        if (session == NULL) {
                pr_err("Not enough memory for reading perf file header\n");
                return -1;
        }
 
        if (!file_new) {
-               err = perf_header__read(&session->header, output);
+               err = perf_header__read(session, output);
                if (err < 0)
                        return err;
        }
 
-       if (raw_samples) {
+       if (have_tracepoints(attrs, nr_counters))
                perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
-       } else {
-               for (i = 0; i < nr_counters; i++) {
-                       if (attrs[i].sample_type & PERF_SAMPLE_RAW) {
-                               perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
-                               break;
-                       }
-               }
-       }
 
        atexit(atexit_header);
 
        if (forks) {
-               pid = fork();
+               child_pid = fork();
                if (pid < 0) {
                        perror("failed to fork");
                        exit(-1);
                }
 
-               if (!pid) {
+               if (!child_pid) {
+                       if (pipe_output)
+                               dup2(2, 1);
                        close(child_ready_pipe[0]);
                        close(go_pipe[1]);
                        fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
@@ -523,10 +626,8 @@ static int __cmd_record(int argc, const char **argv)
                        exit(-1);
                }
 
-               child_pid = pid;
-
-               if (!system_wide)
-                       target_pid = pid;
+               if (!system_wide && target_tid == -1 && target_pid == -1)
+                       all_tids[0] = child_pid;
 
                close(child_ready_pipe[1]);
                close(go_pipe[0]);
@@ -540,15 +641,19 @@ static int __cmd_record(int argc, const char **argv)
                close(child_ready_pipe[0]);
        }
 
-
-       if ((!system_wide && !inherit) || profile_cpu != -1) {
-               open_counters(profile_cpu, target_pid);
+       if ((!system_wide && no_inherit) || profile_cpu != -1) {
+               open_counters(profile_cpu);
        } else {
+               nr_cpus = read_cpu_map();
                for (i = 0; i < nr_cpus; i++)
-                       open_counters(i, target_pid);
+                       open_counters(cpumap[i]);
        }
 
-       if (file_new) {
+       if (pipe_output) {
+               err = perf_header__write_pipe(output);
+               if (err < 0)
+                       return err;
+       } else if (file_new) {
                err = perf_header__write(&session->header, output, false);
                if (err < 0)
                        return err;
@@ -556,21 +661,70 @@ static int __cmd_record(int argc, const char **argv)
 
        post_processing_offset = lseek(output, 0, SEEK_CUR);
 
+       if (pipe_output) {
+               err = event__synthesize_attrs(&session->header,
+                                             process_synthesized_event,
+                                             session);
+               if (err < 0) {
+                       pr_err("Couldn't synthesize attrs.\n");
+                       return err;
+               }
+
+               err = event__synthesize_event_types(process_synthesized_event,
+                                                   session);
+               if (err < 0) {
+                       pr_err("Couldn't synthesize event_types.\n");
+                       return err;
+               }
+
+               if (have_tracepoints(attrs, nr_counters)) {
+                       /*
+                        * FIXME err <= 0 here actually means that
+                        * there were no tracepoints so its not really
+                        * an error, just that we don't need to
+                        * synthesize anything.  We really have to
+                        * return this more properly and also
+                        * propagate errors that now are calling die()
+                        */
+                       err = event__synthesize_tracing_data(output, attrs,
+                                                            nr_counters,
+                                                            process_synthesized_event,
+                                                            session);
+                       if (err <= 0) {
+                               pr_err("Couldn't record tracing data.\n");
+                               return err;
+                       }
+                       advance_output(err);
+               }
+       }
+
+       machine = perf_session__find_host_machine(session);
+       if (!machine) {
+               pr_err("Couldn't find native kernel information.\n");
+               return -1;
+       }
+
        err = event__synthesize_kernel_mmap(process_synthesized_event,
-                                           session, "_text");
+                                           session, machine, "_text");
+       if (err < 0)
+               err = event__synthesize_kernel_mmap(process_synthesized_event,
+                                                   session, machine, "_stext");
        if (err < 0) {
                pr_err("Couldn't record kernel reference relocation symbol.\n");
                return err;
        }
 
-       err = event__synthesize_modules(process_synthesized_event, session);
+       err = event__synthesize_modules(process_synthesized_event,
+                                       session, machine);
        if (err < 0) {
                pr_err("Couldn't record kernel reference relocation symbol.\n");
                return err;
        }
+       if (perf_guest)
+               perf_session__process_machines(session, event__synthesize_guest_os);
 
        if (!system_wide && profile_cpu == -1)
-               event__synthesize_thread(target_pid, process_synthesized_event,
+               event__synthesize_thread(target_tid, process_synthesized_event,
                                         session);
        else
                event__synthesize_threads(process_synthesized_event, session);
@@ -593,13 +747,9 @@ static int __cmd_record(int argc, const char **argv)
 
        for (;;) {
                int hits = samples;
+               int thread;
 
-               for (i = 0; i < nr_cpu; i++) {
-                       for (counter = 0; counter < nr_counters; counter++) {
-                               if (mmap_array[i][counter].base)
-                                       mmap_read(&mmap_array[i][counter]);
-                       }
-               }
+               mmap_read_all();
 
                if (hits == samples) {
                        if (done)
@@ -610,8 +760,15 @@ static int __cmd_record(int argc, const char **argv)
 
                if (done) {
                        for (i = 0; i < nr_cpu; i++) {
-                               for (counter = 0; counter < nr_counters; counter++)
-                                       ioctl(fd[i][counter], PERF_EVENT_IOC_DISABLE);
+                               for (counter = 0;
+                                       counter < nr_counters;
+                                       counter++) {
+                                       for (thread = 0;
+                                               thread < thread_num;
+                                               thread++)
+                                               ioctl(fd[i][counter][thread],
+                                                       PERF_EVENT_IOC_DISABLE);
+                               }
                        }
                }
        }
@@ -636,6 +793,8 @@ static const char * const record_usage[] = {
        NULL
 };
 
+static bool force, append_file;
+
 static const struct option options[] = {
        OPT_CALLBACK('e', "event", NULL, "event",
                     "event selector. use 'perf list' to list available events",
@@ -643,7 +802,9 @@ static const struct option options[] = {
        OPT_CALLBACK(0, "filter", NULL, "filter",
                     "event filter", parse_filter),
        OPT_INTEGER('p', "pid", &target_pid,
-                   "record events on existing pid"),
+                   "record events on existing process id"),
+       OPT_INTEGER('t', "tid", &target_tid,
+                   "record events on existing thread id"),
        OPT_INTEGER('r', "realtime", &realtime_prio,
                    "collect data with this RT SCHED_FIFO priority"),
        OPT_BOOLEAN('R', "raw-samples", &raw_samples,
@@ -655,20 +816,17 @@ static const struct option options[] = {
        OPT_INTEGER('C', "profile_cpu", &profile_cpu,
                            "CPU to profile on"),
        OPT_BOOLEAN('f', "force", &force,
-                       "overwrite existing data file"),
-       OPT_LONG('c', "count", &default_interval,
-                   "event period to sample"),
+                       "overwrite existing data file (deprecated)"),
+       OPT_U64('c', "count", &user_interval, "event period to sample"),
        OPT_STRING('o', "output", &output_name, "file",
                    "output file name"),
-       OPT_BOOLEAN('i', "inherit", &inherit,
-                   "child tasks inherit counters"),
-       OPT_INTEGER('F', "freq", &freq,
-                   "profile at this frequency"),
-       OPT_INTEGER('m', "mmap-pages", &mmap_pages,
-                   "number of mmap data pages"),
+       OPT_BOOLEAN('i', "no-inherit", &no_inherit,
+                   "child tasks do not inherit counters"),
+       OPT_UINTEGER('F', "freq", &user_freq, "profile at this frequency"),
+       OPT_UINTEGER('m', "mmap-pages", &mmap_pages, "number of mmap data pages"),
        OPT_BOOLEAN('g', "call-graph", &call_graph,
                    "do call-graph (stack chain/backtrace) recording"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show counter open errors, etc)"),
        OPT_BOOLEAN('s', "stat", &inherit_stat,
                    "per thread counts"),
@@ -683,13 +841,24 @@ static const struct option options[] = {
 
 int cmd_record(int argc, const char **argv, const char *prefix __used)
 {
-       int counter;
+       int i,j;
 
        argc = parse_options(argc, argv, options, record_usage,
                            PARSE_OPT_STOP_AT_NON_OPTION);
-       if (!argc && target_pid == -1 && !system_wide && profile_cpu == -1)
+       if (!argc && target_pid == -1 && target_tid == -1 &&
+               !system_wide && profile_cpu == -1)
                usage_with_options(record_usage, options);
 
+       if (force && append_file) {
+               fprintf(stderr, "Can't overwrite and append at the same time."
+                               " You need to choose between -f and -A");
+               usage_with_options(record_usage, options);
+       } else if (append_file) {
+               write_mode = WRITE_APPEND;
+       } else {
+               write_mode = WRITE_FORCE;
+       }
+
        symbol__init();
 
        if (!nr_counters) {
@@ -698,6 +867,42 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
                attrs[0].config = PERF_COUNT_HW_CPU_CYCLES;
        }
 
+       if (target_pid != -1) {
+               target_tid = target_pid;
+               thread_num = find_all_tid(target_pid, &all_tids);
+               if (thread_num <= 0) {
+                       fprintf(stderr, "Can't find all threads of pid %d\n",
+                                       target_pid);
+                       usage_with_options(record_usage, options);
+               }
+       } else {
+               all_tids=malloc(sizeof(pid_t));
+               if (!all_tids)
+                       return -ENOMEM;
+
+               all_tids[0] = target_tid;
+               thread_num = 1;
+       }
+
+       for (i = 0; i < MAX_NR_CPUS; i++) {
+               for (j = 0; j < MAX_COUNTERS; j++) {
+                       fd[i][j] = malloc(sizeof(int)*thread_num);
+                       mmap_array[i][j] = zalloc(
+                               sizeof(struct mmap_data)*thread_num);
+                       if (!fd[i][j] || !mmap_array[i][j])
+                               return -ENOMEM;
+               }
+       }
+       event_array = malloc(
+               sizeof(struct pollfd)*MAX_NR_CPUS*MAX_COUNTERS*thread_num);
+       if (!event_array)
+               return -ENOMEM;
+
+       if (user_interval != ULLONG_MAX)
+               default_interval = user_interval;
+       if (user_freq != UINT_MAX)
+               freq = user_freq;
+
        /*
         * User specified count overrides default frequency.
         */
@@ -710,12 +915,5 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
                exit(EXIT_FAILURE);
        }
 
-       for (counter = 0; counter < nr_counters; counter++) {
-               if (attrs[counter].sample_period)
-                       continue;
-
-               attrs[counter].sample_period = default_interval;
-       }
-
        return __cmd_record(argc, argv);
 }
index cfc655d40bb7b4a88f37c068aef908e76e408a4c..1d3c1003b43a2f083e94a0926a0000e159379352 100644 (file)
@@ -14,7 +14,6 @@
 #include "util/cache.h"
 #include <linux/rbtree.h>
 #include "util/symbol.h"
-#include "util/string.h"
 #include "util/callchain.h"
 #include "util/strlist.h"
 #include "util/values.h"
 
 static char            const *input_name = "perf.data";
 
-static int             force;
+static bool            force;
 static bool            hide_unresolved;
 static bool            dont_use_callchains;
 
-static int             show_threads;
+static bool            show_threads;
 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 const char      default_pretty_printing_style[] = "normal";
+static const char      *pretty_printing_style = default_pretty_printing_style;
 
 static char            callchain_default_opt[] = "fractal,0.5";
 
+static struct hists *perf_session__hists_findnew(struct perf_session *self,
+                                                u64 event_stream, u32 type,
+                                                u64 config)
+{
+       struct rb_node **p = &self->hists_tree.rb_node;
+       struct rb_node *parent = NULL;
+       struct hists *iter, *new;
+
+       while (*p != NULL) {
+               parent = *p;
+               iter = rb_entry(parent, struct hists, rb_node);
+               if (iter->config == config)
+                       return iter;
+
+
+               if (config > iter->config)
+                       p = &(*p)->rb_right;
+               else
+                       p = &(*p)->rb_left;
+       }
+
+       new = malloc(sizeof(struct hists));
+       if (new == NULL)
+               return NULL;
+       memset(new, 0, sizeof(struct hists));
+       new->event_stream = event_stream;
+       new->config = config;
+       new->type = type;
+       rb_link_node(&new->rb_node, parent, p);
+       rb_insert_color(&new->rb_node, &self->hists_tree);
+       return new;
+}
+
 static int perf_session__add_hist_entry(struct perf_session *self,
                                        struct addr_location *al,
-                                       struct ip_callchain *chain, u64 count)
+                                       struct sample_data *data)
 {
-       struct symbol **syms = NULL, *parent = NULL;
-       bool hit;
+       struct map_symbol *syms = NULL;
+       struct symbol *parent = NULL;
+       int err = -ENOMEM;
        struct hist_entry *he;
+       struct hists *hists;
+       struct perf_event_attr *attr;
 
-       if ((sort__has_parent || symbol_conf.use_callchain) && chain)
+       if ((sort__has_parent || symbol_conf.use_callchain) && data->callchain) {
                syms = perf_session__resolve_callchain(self, al->thread,
-                                                      chain, &parent);
-       he = __perf_session__add_hist_entry(self, al, parent, count, &hit);
-       if (he == NULL)
-               return -ENOMEM;
-
-       if (hit)
-               he->count += count;
+                                                      data->callchain, &parent);
+               if (syms == NULL)
+                       return -ENOMEM;
+       }
 
+       attr = perf_header__find_attr(data->id, &self->header);
+       if (attr)
+               hists = perf_session__hists_findnew(self, data->id, attr->type, attr->config);
+       else
+               hists = perf_session__hists_findnew(self, data->id, 0, 0);
+       if (hists == NULL)
+               goto out_free_syms;
+       he = __hists__add_entry(hists, al, parent, data->period);
+       if (he == NULL)
+               goto out_free_syms;
+       err = 0;
        if (symbol_conf.use_callchain) {
-               if (!hit)
-                       callchain_init(&he->callchain);
-               append_chain(&he->callchain, chain, syms);
-               free(syms);
+               err = append_chain(he->callchain, data->callchain, syms);
+               if (err)
+                       goto out_free_syms;
        }
-
-       return 0;
+       /*
+        * Only in the newt browser we are doing integrated annotation,
+        * so we don't allocated the extra space needed because the stdio
+        * code will not use it.
+        */
+       if (use_browser)
+               err = hist_entry__inc_addr_samples(he, al->addr);
+out_free_syms:
+       free(syms);
+       return err;
 }
 
-static int validate_chain(struct ip_callchain *chain, event_t *event)
+static int add_event_total(struct perf_session *session,
+                          struct sample_data *data,
+                          struct perf_event_attr *attr)
 {
-       unsigned int chain_size;
+       struct hists *hists;
 
-       chain_size = event->header.size;
-       chain_size -= (unsigned long)&event->ip.__more_data - (unsigned long)event;
+       if (attr)
+               hists = perf_session__hists_findnew(session, data->id,
+                                                   attr->type, attr->config);
+       else
+               hists = perf_session__hists_findnew(session, data->id, 0, 0);
 
-       if (chain->nr*sizeof(u64) > chain_size)
-               return -1;
+       if (!hists)
+               return -ENOMEM;
 
+       hists->stats.total_period += data->period;
+       /*
+        * FIXME: add_event_total should be moved from here to
+        * perf_session__process_event so that the proper hist is passed to
+        * the event_op methods.
+        */
+       hists__inc_nr_events(hists, PERF_RECORD_SAMPLE);
+       session->hists.stats.total_period += data->period;
        return 0;
 }
 
@@ -90,6 +153,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
 {
        struct sample_data data = { .period = 1, };
        struct addr_location al;
+       struct perf_event_attr *attr;
 
        event__parse_sample(event, session->sample_type, &data);
 
@@ -101,7 +165,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
 
                dump_printf("... chain: nr:%Lu\n", data.callchain->nr);
 
-               if (validate_chain(data.callchain, event) < 0) {
+               if (!ip_callchain__valid(data.callchain, event)) {
                        pr_debug("call-chain problem with event, "
                                 "skipping it.\n");
                        return 0;
@@ -123,12 +187,18 @@ static int process_sample_event(event_t *event, struct perf_session *session)
        if (al.filtered || (hide_unresolved && al.sym == NULL))
                return 0;
 
-       if (perf_session__add_hist_entry(session, &al, data.callchain, data.period)) {
-               pr_debug("problem incrementing symbol count, skipping event\n");
+       if (perf_session__add_hist_entry(session, &al, &data)) {
+               pr_debug("problem incrementing symbol period, skipping event\n");
+               return -1;
+       }
+
+       attr = perf_header__find_attr(data.id, &session->header);
+
+       if (add_event_total(session, &data, attr)) {
+               pr_debug("problem adding event period\n");
                return -1;
        }
 
-       session->events_stats.total += data.period;
        return 0;
 }
 
@@ -191,14 +261,43 @@ static struct perf_event_ops event_ops = {
        .fork   = event__process_task,
        .lost   = event__process_lost,
        .read   = process_read_event,
+       .attr   = event__process_attr,
+       .event_type = event__process_event_type,
+       .tracing_data = event__process_tracing_data,
+       .build_id = event__process_build_id,
 };
 
+extern volatile int session_done;
+
+static void sig_handler(int sig __used)
+{
+       session_done = 1;
+}
+
+static size_t hists__fprintf_nr_sample_events(struct hists *self,
+                                             const char *evname, FILE *fp)
+{
+       size_t ret;
+       char unit;
+       unsigned long nr_events = self->stats.nr_events[PERF_RECORD_SAMPLE];
+
+       nr_events = convert_unit(nr_events, &unit);
+       ret = fprintf(fp, "# Events: %lu%c", nr_events, unit);
+       if (evname != NULL)
+               ret += fprintf(fp, " %s", evname);
+       return ret + fprintf(fp, "\n#\n");
+}
+
 static int __cmd_report(void)
 {
        int ret = -EINVAL;
        struct perf_session *session;
+       struct rb_node *next;
+       const char *help = "For a higher level overview, try: perf report --sort comm,dso";
+
+       signal(SIGINT, sig_handler);
 
-       session = perf_session__new(input_name, O_RDONLY, force);
+       session = perf_session__new(input_name, O_RDONLY, force, false);
        if (session == NULL)
                return -ENOMEM;
 
@@ -214,7 +313,7 @@ static int __cmd_report(void)
                goto out_delete;
 
        if (dump_trace) {
-               event__print_totals();
+               perf_session__fprintf_nr_events(session, stdout);
                goto out_delete;
        }
 
@@ -222,21 +321,42 @@ static int __cmd_report(void)
                perf_session__fprintf(session, stdout);
 
        if (verbose > 2)
-               dsos__fprintf(stdout);
+               perf_session__fprintf_dsos(session, stdout);
+
+       next = rb_first(&session->hists_tree);
+       while (next) {
+               struct hists *hists;
+
+               hists = rb_entry(next, struct hists, rb_node);
+               hists__collapse_resort(hists);
+               hists__output_resort(hists);
+               if (use_browser)
+                       hists__browse(hists, help, input_name);
+               else {
+                       const char *evname = NULL;
+                       if (rb_first(&session->hists.entries) !=
+                           rb_last(&session->hists.entries))
+                               evname = __event_name(hists->type, hists->config);
+
+                       hists__fprintf_nr_sample_events(hists, evname, stdout);
+
+                       hists__fprintf(hists, NULL, false, stdout);
+                       fprintf(stdout, "\n\n");
+               }
 
-       perf_session__collapse_resort(session);
-       perf_session__output_resort(session, session->events_stats.total);
-       fprintf(stdout, "# Samples: %Ld\n#\n", session->events_stats.total);
-       perf_session__fprintf_hists(session, NULL, false, stdout);
-       if (sort_order == default_sort_order &&
-           parent_pattern == default_parent_pattern)
-               fprintf(stdout, "#\n# (For a higher level overview, try: perf report --sort comm,dso)\n#\n");
+               next = rb_next(&hists->rb_node);
+       }
 
-       if (show_threads) {
-               bool raw_printing_style = !strcmp(pretty_printing_style, "raw");
-               perf_read_values_display(stdout, &show_threads_values,
-                                        raw_printing_style);
-               perf_read_values_destroy(&show_threads_values);
+       if (!use_browser && sort_order == default_sort_order &&
+           parent_pattern == default_parent_pattern) {
+               fprintf(stdout, "#\n# (%s)\n#\n", help);
+
+               if (show_threads) {
+                       bool style = !strcmp(pretty_printing_style, "raw");
+                       perf_read_values_display(stdout, &show_threads_values,
+                                                style);
+                       perf_read_values_destroy(&show_threads_values);
+               }
        }
 out_delete:
        perf_session__delete(session);
@@ -247,7 +367,7 @@ static int
 parse_callchain_opt(const struct option *opt __used, const char *arg,
                    int unset)
 {
-       char *tok;
+       char *tok, *tok2;
        char *endptr;
 
        /*
@@ -292,10 +412,13 @@ parse_callchain_opt(const struct option *opt __used, const char *arg,
        if (!tok)
                goto setup;
 
+       tok2 = strtok(NULL, ",");
        callchain_param.min_percent = strtod(tok, &endptr);
        if (tok == endptr)
                return -1;
 
+       if (tok2)
+               callchain_param.print_limit = strtod(tok2, &endptr);
 setup:
        if (register_callchain_param(&callchain_param) < 0) {
                fprintf(stderr, "Can't register callchain params\n");
@@ -312,7 +435,7 @@ static const char * const report_usage[] = {
 static const struct option options[] = {
        OPT_STRING('i', "input", &input_name, "file",
                    "input file name"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show symbol address, etc)"),
        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
                    "dump raw trace in ASCII"),
@@ -331,12 +454,14 @@ static const struct option options[] = {
                   "sort by key(s): pid, comm, dso, symbol, parent"),
        OPT_BOOLEAN('P', "full-paths", &symbol_conf.full_paths,
                    "Don't shorten the pathnames taking into account the cwd"),
+       OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
+                   "Show sample percentage for different cpu modes"),
        OPT_STRING('p', "parent", &parent_pattern, "regex",
                   "regex filter to identify parent, see: '--sort parent'"),
        OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
                    "Only display entries with parent-match"),
        OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent",
-                    "Display callchains using output_type and min percent threshold. "
+                    "Display callchains using output_type (graph, flat, fractal, or none) and min percent threshold. "
                     "Default: fractal,0.5", &parse_callchain_opt, callchain_default_opt),
        OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
                   "only consider symbols in these dsos"),
@@ -359,7 +484,15 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
 {
        argc = parse_options(argc, argv, options, report_usage, 0);
 
-       setup_pager();
+       if (strcmp(input_name, "-") != 0)
+               setup_browser();
+       /*
+        * Only in the newt browser we are doing integrated annotation,
+        * so don't allocate extra space that won't be used in the stdio
+        * implementation.
+        */
+       if (use_browser)
+               symbol_conf.priv_size = sizeof(struct sym_priv);
 
        if (symbol__init() < 0)
                return -1;
@@ -367,7 +500,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
        setup_sorting(report_usage, options);
 
        if (parent_pattern != default_parent_pattern) {
-               sort_dimension__add("parent");
+               if (sort_dimension__add("parent") < 0)
+                       return -1;
                sort_parent.elide = 1;
        } else
                symbol_conf.exclude_other = false;
index 4f5a03e43444ef2b9f02551557aae18dddf9ace7..f67bce2a83b4e090d86a0ecc2dd5a1240521db0a 100644 (file)
@@ -22,7 +22,7 @@
 static char                    const *input_name = "perf.data";
 
 static char                    default_sort_order[] = "avg, max, switch, runtime";
-static char                    *sort_order = default_sort_order;
+static const char              *sort_order = default_sort_order;
 
 static int                     profile_cpu = -1;
 
@@ -68,10 +68,10 @@ enum sched_event_type {
 
 struct sched_atom {
        enum sched_event_type   type;
+       int                     specific_wait;
        u64                     timestamp;
        u64                     duration;
        unsigned long           nr;
-       int                     specific_wait;
        sem_t                   *wait_sem;
        struct task_desc        *wakee;
 };
@@ -105,7 +105,7 @@ static u64                  sum_runtime;
 static u64                     sum_fluct;
 static u64                     run_avg;
 
-static unsigned long           replay_repeat = 10;
+static unsigned int            replay_repeat = 10;
 static unsigned long           nr_timestamps;
 static unsigned long           nr_unordered_timestamps;
 static unsigned long           nr_state_machine_bugs;
@@ -1641,30 +1641,26 @@ static int process_sample_event(event_t *event, struct perf_session *session)
        return 0;
 }
 
-static int process_lost_event(event_t *event __used,
-                             struct perf_session *session __used)
-{
-       nr_lost_chunks++;
-       nr_lost_events += event->lost.lost;
-
-       return 0;
-}
-
 static struct perf_event_ops event_ops = {
-       .sample = process_sample_event,
-       .comm   = event__process_comm,
-       .lost   = process_lost_event,
+       .sample                 = process_sample_event,
+       .comm                   = event__process_comm,
+       .lost                   = event__process_lost,
+       .ordered_samples        = true,
 };
 
 static int read_events(void)
 {
        int err = -EINVAL;
-       struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
+       struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0, false);
        if (session == NULL)
                return -ENOMEM;
 
-       if (perf_session__has_traces(session, "record -R"))
+       if (perf_session__has_traces(session, "record -R")) {
                err = perf_session__process_events(session, &event_ops);
+               nr_events      = session->hists.stats.nr_events[0];
+               nr_lost_events = session->hists.stats.total_lost;
+               nr_lost_chunks = session->hists.stats.nr_events[PERF_RECORD_LOST];
+       }
 
        perf_session__delete(session);
        return err;
@@ -1790,7 +1786,7 @@ static const char * const sched_usage[] = {
 static const struct option sched_options[] = {
        OPT_STRING('i', "input", &input_name, "file",
                    "input file name"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show symbol address, etc)"),
        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
                    "dump raw trace in ASCII"),
@@ -1805,7 +1801,7 @@ static const char * const latency_usage[] = {
 static const struct option latency_options[] = {
        OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
                   "sort by key(s): runtime, switch, avg, max"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show symbol address, etc)"),
        OPT_INTEGER('C', "CPU", &profile_cpu,
                    "CPU to profile on"),
@@ -1820,9 +1816,9 @@ static const char * const replay_usage[] = {
 };
 
 static const struct option replay_options[] = {
-       OPT_INTEGER('r', "repeat", &replay_repeat,
-                   "repeat the workload replay N times (-1: infinite)"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_UINTEGER('r', "repeat", &replay_repeat,
+                    "repeat the workload replay N times (-1: infinite)"),
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show symbol address, etc)"),
        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
                    "dump raw trace in ASCII"),
@@ -1850,7 +1846,6 @@ static const char *record_args[] = {
        "record",
        "-a",
        "-R",
-       "-M",
        "-f",
        "-m", "1024",
        "-c", "1",
index e8c85d5aec4151fc965f2b16063c60da456d6e67..ff8c413b7e734008a667b093e4ffc41f2f5bf7b5 100644 (file)
@@ -45,6 +45,8 @@
 #include "util/event.h"
 #include "util/debug.h"
 #include "util/header.h"
+#include "util/cpumap.h"
+#include "util/thread.h"
 
 #include <sys/prctl.h>
 #include <math.h>
@@ -65,18 +67,21 @@ static struct perf_event_attr default_attrs[] = {
 
 };
 
-static int                     system_wide                     =  0;
+static bool                    system_wide                     =  false;
 static unsigned int            nr_cpus                         =  0;
 static int                     run_idx                         =  0;
 
 static int                     run_count                       =  1;
-static int                     inherit                         =  1;
-static int                     scale                           =  1;
+static bool                    no_inherit                      = false;
+static bool                    scale                           =  true;
 static pid_t                   target_pid                      = -1;
+static pid_t                   target_tid                      = -1;
+static pid_t                   *all_tids                       =  NULL;
+static int                     thread_num                      =  0;
 static pid_t                   child_pid                       = -1;
-static int                     null_run                        =  0;
+static bool                    null_run                        =  false;
 
-static int                     fd[MAX_NR_CPUS][MAX_COUNTERS];
+static int                     *fd[MAX_NR_CPUS][MAX_COUNTERS];
 
 static int                     event_scaled[MAX_COUNTERS];
 
@@ -139,9 +144,11 @@ struct stats                       runtime_branches_stats;
 #define ERR_PERF_OPEN \
 "Error: counter %d, sys_perf_event_open() syscall returned with %d (%s)\n"
 
-static void create_perf_stat_counter(int counter, int pid)
+static int create_perf_stat_counter(int counter)
 {
        struct perf_event_attr *attr = attrs + counter;
+       int thread;
+       int ncreated = 0;
 
        if (scale)
                attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
@@ -151,21 +158,33 @@ static void create_perf_stat_counter(int counter, int pid)
                unsigned int cpu;
 
                for (cpu = 0; cpu < nr_cpus; cpu++) {
-                       fd[cpu][counter] = sys_perf_event_open(attr, -1, cpu, -1, 0);
-                       if (fd[cpu][counter] < 0 && verbose)
-                               fprintf(stderr, ERR_PERF_OPEN, counter,
-                                       fd[cpu][counter], strerror(errno));
+                       fd[cpu][counter][0] = sys_perf_event_open(attr,
+                                       -1, cpumap[cpu], -1, 0);
+                       if (fd[cpu][counter][0] < 0)
+                               pr_debug(ERR_PERF_OPEN, counter,
+                                        fd[cpu][counter][0], strerror(errno));
+                       else
+                               ++ncreated;
                }
        } else {
-               attr->inherit        = inherit;
-               attr->disabled       = 1;
-               attr->enable_on_exec = 1;
-
-               fd[0][counter] = sys_perf_event_open(attr, pid, -1, -1, 0);
-               if (fd[0][counter] < 0 && verbose)
-                       fprintf(stderr, ERR_PERF_OPEN, counter,
-                               fd[0][counter], strerror(errno));
+               attr->inherit = !no_inherit;
+               if (target_pid == -1 && target_tid == -1) {
+                       attr->disabled = 1;
+                       attr->enable_on_exec = 1;
+               }
+               for (thread = 0; thread < thread_num; thread++) {
+                       fd[0][counter][thread] = sys_perf_event_open(attr,
+                               all_tids[thread], -1, -1, 0);
+                       if (fd[0][counter][thread] < 0)
+                               pr_debug(ERR_PERF_OPEN, counter,
+                                        fd[0][counter][thread],
+                                        strerror(errno));
+                       else
+                               ++ncreated;
+               }
        }
+
+       return ncreated;
 }
 
 /*
@@ -189,25 +208,28 @@ static void read_counter(int counter)
        unsigned int cpu;
        size_t res, nv;
        int scaled;
-       int i;
+       int i, thread;
 
        count[0] = count[1] = count[2] = 0;
 
        nv = scale ? 3 : 1;
        for (cpu = 0; cpu < nr_cpus; cpu++) {
-               if (fd[cpu][counter] < 0)
-                       continue;
-
-               res = read(fd[cpu][counter], single_count, nv * sizeof(u64));
-               assert(res == nv * sizeof(u64));
-
-               close(fd[cpu][counter]);
-               fd[cpu][counter] = -1;
-
-               count[0] += single_count[0];
-               if (scale) {
-                       count[1] += single_count[1];
-                       count[2] += single_count[2];
+               for (thread = 0; thread < thread_num; thread++) {
+                       if (fd[cpu][counter][thread] < 0)
+                               continue;
+
+                       res = read(fd[cpu][counter][thread],
+                                       single_count, nv * sizeof(u64));
+                       assert(res == nv * sizeof(u64));
+
+                       close(fd[cpu][counter][thread]);
+                       fd[cpu][counter][thread] = -1;
+
+                       count[0] += single_count[0];
+                       if (scale) {
+                               count[1] += single_count[1];
+                               count[2] += single_count[2];
+                       }
                }
        }
 
@@ -249,10 +271,9 @@ static int run_perf_stat(int argc __used, const char **argv)
 {
        unsigned long long t0, t1;
        int status = 0;
-       int counter;
-       int pid = target_pid;
+       int counter, ncreated = 0;
        int child_ready_pipe[2], go_pipe[2];
-       const bool forks = (target_pid == -1 && argc > 0);
+       const bool forks = (argc > 0);
        char buf;
 
        if (!system_wide)
@@ -264,10 +285,10 @@ static int run_perf_stat(int argc __used, const char **argv)
        }
 
        if (forks) {
-               if ((pid = fork()) < 0)
+               if ((child_pid = fork()) < 0)
                        perror("failed to fork");
 
-               if (!pid) {
+               if (!child_pid) {
                        close(child_ready_pipe[0]);
                        close(go_pipe[1]);
                        fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
@@ -296,7 +317,8 @@ static int run_perf_stat(int argc __used, const char **argv)
                        exit(-1);
                }
 
-               child_pid = pid;
+               if (target_tid == -1 && target_pid == -1 && !system_wide)
+                       all_tids[0] = child_pid;
 
                /*
                 * Wait for the child to be ready to exec.
@@ -309,7 +331,16 @@ static int run_perf_stat(int argc __used, const char **argv)
        }
 
        for (counter = 0; counter < nr_counters; counter++)
-               create_perf_stat_counter(counter, pid);
+               ncreated += create_perf_stat_counter(counter);
+
+       if (ncreated == 0) {
+               pr_err("No permission to collect %sstats.\n"
+                      "Consider tweaking /proc/sys/kernel/perf_event_paranoid.\n",
+                      system_wide ? "system-wide " : "");
+               if (child_pid != -1)
+                       kill(child_pid, SIGTERM);
+               return -1;
+       }
 
        /*
         * Enable counters and exec the command:
@@ -320,7 +351,7 @@ static int run_perf_stat(int argc __used, const char **argv)
                close(go_pipe[1]);
                wait(&status);
        } else {
-               while(!done);
+               while(!done) sleep(1);
        }
 
        t1 = rdclock();
@@ -428,12 +459,14 @@ static void print_stat(int argc, const char **argv)
 
        fprintf(stderr, "\n");
        fprintf(stderr, " Performance counter stats for ");
-       if(target_pid == -1) {
+       if(target_pid == -1 && target_tid == -1) {
                fprintf(stderr, "\'%s", argv[0]);
                for (i = 1; i < argc; i++)
                        fprintf(stderr, " %s", argv[i]);
-       }else
-               fprintf(stderr, "task pid \'%d", target_pid);
+       } else if (target_pid != -1)
+               fprintf(stderr, "process id \'%d", target_pid);
+       else
+               fprintf(stderr, "thread id \'%d", target_tid);
 
        fprintf(stderr, "\'");
        if (run_count > 1)
@@ -458,7 +491,7 @@ static volatile int signr = -1;
 
 static void skip_signal(int signo)
 {
-       if(target_pid != -1)
+       if(child_pid == -1)
                done = 1;
 
        signr = signo;
@@ -485,15 +518,17 @@ static const struct option options[] = {
        OPT_CALLBACK('e', "event", NULL, "event",
                     "event selector. use 'perf list' to list available events",
                     parse_events),
-       OPT_BOOLEAN('i', "inherit", &inherit,
-                   "child tasks inherit counters"),
+       OPT_BOOLEAN('i', "no-inherit", &no_inherit,
+                   "child tasks do not inherit counters"),
        OPT_INTEGER('p', "pid", &target_pid,
-                   "stat events on existing pid"),
+                   "stat events on existing process id"),
+       OPT_INTEGER('t', "tid", &target_tid,
+                   "stat events on existing thread id"),
        OPT_BOOLEAN('a', "all-cpus", &system_wide,
                    "system-wide collection from all CPUs"),
        OPT_BOOLEAN('c', "scale", &scale,
                    "scale/normalize counters"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show counter open errors, etc)"),
        OPT_INTEGER('r', "repeat", &run_count,
                    "repeat command and print average + stddev (max: 100)"),
@@ -505,10 +540,11 @@ static const struct option options[] = {
 int cmd_stat(int argc, const char **argv, const char *prefix __used)
 {
        int status;
+       int i,j;
 
        argc = parse_options(argc, argv, options, stat_usage,
                PARSE_OPT_STOP_AT_NON_OPTION);
-       if (!argc && target_pid == -1)
+       if (!argc && target_pid == -1 && target_tid == -1)
                usage_with_options(stat_usage, options);
        if (run_count <= 0)
                usage_with_options(stat_usage, options);
@@ -519,9 +555,35 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
                nr_counters = ARRAY_SIZE(default_attrs);
        }
 
-       nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
-       assert(nr_cpus <= MAX_NR_CPUS);
-       assert((int)nr_cpus >= 0);
+       if (system_wide)
+               nr_cpus = read_cpu_map();
+       else
+               nr_cpus = 1;
+
+       if (target_pid != -1) {
+               target_tid = target_pid;
+               thread_num = find_all_tid(target_pid, &all_tids);
+               if (thread_num <= 0) {
+                       fprintf(stderr, "Can't find all threads of pid %d\n",
+                                       target_pid);
+                       usage_with_options(stat_usage, options);
+               }
+       } else {
+               all_tids=malloc(sizeof(pid_t));
+               if (!all_tids)
+                       return -ENOMEM;
+
+               all_tids[0] = target_tid;
+               thread_num = 1;
+       }
+
+       for (i = 0; i < MAX_NR_CPUS; i++) {
+               for (j = 0; j < MAX_COUNTERS; j++) {
+                       fd[i][j] = malloc(sizeof(int)*thread_num);
+                       if (!fd[i][j])
+                               return -ENOMEM;
+               }
+       }
 
        /*
         * We dont want to block the signals - that would cause
@@ -541,7 +603,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
                status = run_perf_stat(argc, argv);
        }
 
-       print_stat(argc, argv);
+       if (status != -1)
+               print_stat(argc, argv);
 
        return status;
 }
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
new file mode 100644 (file)
index 0000000..035b9fa
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ * builtin-test.c
+ *
+ * Builtin regression testing command: ever growing number of sanity tests
+ */
+#include "builtin.h"
+
+#include "util/cache.h"
+#include "util/debug.h"
+#include "util/parse-options.h"
+#include "util/session.h"
+#include "util/symbol.h"
+#include "util/thread.h"
+
+static long page_size;
+
+static int vmlinux_matches_kallsyms_filter(struct map *map __used, struct symbol *sym)
+{
+       bool *visited = symbol__priv(sym);
+       *visited = true;
+       return 0;
+}
+
+static int test__vmlinux_matches_kallsyms(void)
+{
+       int err = -1;
+       struct rb_node *nd;
+       struct symbol *sym;
+       struct map *kallsyms_map, *vmlinux_map;
+       struct machine kallsyms, vmlinux;
+       enum map_type type = MAP__FUNCTION;
+       struct ref_reloc_sym ref_reloc_sym = { .name = "_stext", };
+
+       /*
+        * Step 1:
+        *
+        * Init the machines that will hold kernel, modules obtained from
+        * both vmlinux + .ko files and from /proc/kallsyms split by modules.
+        */
+       machine__init(&kallsyms, "", HOST_KERNEL_ID);
+       machine__init(&vmlinux, "", HOST_KERNEL_ID);
+
+       /*
+        * Step 2:
+        *
+        * Create the kernel maps for kallsyms and the DSO where we will then
+        * load /proc/kallsyms. Also create the modules maps from /proc/modules
+        * and find the .ko files that match them in /lib/modules/`uname -r`/.
+        */
+       if (machine__create_kernel_maps(&kallsyms) < 0) {
+               pr_debug("machine__create_kernel_maps ");
+               return -1;
+       }
+
+       /*
+        * Step 3:
+        *
+        * Load and split /proc/kallsyms into multiple maps, one per module.
+        */
+       if (machine__load_kallsyms(&kallsyms, "/proc/kallsyms", type, NULL) <= 0) {
+               pr_debug("dso__load_kallsyms ");
+               goto out;
+       }
+
+       /*
+        * Step 4:
+        *
+        * kallsyms will be internally on demand sorted by name so that we can
+        * find the reference relocation * symbol, i.e. the symbol we will use
+        * to see if the running kernel was relocated by checking if it has the
+        * same value in the vmlinux file we load.
+        */
+       kallsyms_map = machine__kernel_map(&kallsyms, type);
+
+       sym = map__find_symbol_by_name(kallsyms_map, ref_reloc_sym.name, NULL);
+       if (sym == NULL) {
+               pr_debug("dso__find_symbol_by_name ");
+               goto out;
+       }
+
+       ref_reloc_sym.addr = sym->start;
+
+       /*
+        * Step 5:
+        *
+        * Now repeat step 2, this time for the vmlinux file we'll auto-locate.
+        */
+       if (machine__create_kernel_maps(&vmlinux) < 0) {
+               pr_debug("machine__create_kernel_maps ");
+               goto out;
+       }
+
+       vmlinux_map = machine__kernel_map(&vmlinux, type);
+       map__kmap(vmlinux_map)->ref_reloc_sym = &ref_reloc_sym;
+
+       /*
+        * Step 6:
+        *
+        * Locate a vmlinux file in the vmlinux path that has a buildid that
+        * matches the one of the running kernel.
+        *
+        * While doing that look if we find the ref reloc symbol, if we find it
+        * we'll have its ref_reloc_symbol.unrelocated_addr and then
+        * maps__reloc_vmlinux will notice and set proper ->[un]map_ip routines
+        * to fixup the symbols.
+        */
+       if (machine__load_vmlinux_path(&vmlinux, type,
+                                      vmlinux_matches_kallsyms_filter) <= 0) {
+               pr_debug("machine__load_vmlinux_path ");
+               goto out;
+       }
+
+       err = 0;
+       /*
+        * Step 7:
+        *
+        * Now look at the symbols in the vmlinux DSO and check if we find all of them
+        * in the kallsyms dso. For the ones that are in both, check its names and
+        * end addresses too.
+        */
+       for (nd = rb_first(&vmlinux_map->dso->symbols[type]); nd; nd = rb_next(nd)) {
+               struct symbol *pair;
+
+               sym  = rb_entry(nd, struct symbol, rb_node);
+               pair = machine__find_kernel_symbol(&kallsyms, type, sym->start, NULL, NULL);
+
+               if (pair && pair->start == sym->start) {
+next_pair:
+                       if (strcmp(sym->name, pair->name) == 0) {
+                               /*
+                                * kallsyms don't have the symbol end, so we
+                                * set that by using the next symbol start - 1,
+                                * in some cases we get this up to a page
+                                * wrong, trace_kmalloc when I was developing
+                                * this code was one such example, 2106 bytes
+                                * off the real size. More than that and we
+                                * _really_ have a problem.
+                                */
+                               s64 skew = sym->end - pair->end;
+                               if (llabs(skew) < page_size)
+                                       continue;
+
+                               pr_debug("%#Lx: diff end addr for %s v: %#Lx k: %#Lx\n",
+                                        sym->start, sym->name, sym->end, pair->end);
+                       } else {
+                               struct rb_node *nnd = rb_prev(&pair->rb_node);
+
+                               if (nnd) {
+                                       struct symbol *next = rb_entry(nnd, struct symbol, rb_node);
+
+                                       if (next->start == sym->start) {
+                                               pair = next;
+                                               goto next_pair;
+                                       }
+                               }
+                               pr_debug("%#Lx: diff name v: %s k: %s\n",
+                                        sym->start, sym->name, pair->name);
+                       }
+               } else
+                       pr_debug("%#Lx: %s not on kallsyms\n", sym->start, sym->name);
+
+               err = -1;
+       }
+
+       if (!verbose)
+               goto out;
+
+       pr_info("Maps only in vmlinux:\n");
+
+       for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) {
+               struct map *pos = rb_entry(nd, struct map, rb_node), *pair;
+               /*
+                * If it is the kernel, kallsyms is always "[kernel.kallsyms]", while
+                * the kernel will have the path for the vmlinux file being used,
+                * so use the short name, less descriptive but the same ("[kernel]" in
+                * both cases.
+                */
+               pair = map_groups__find_by_name(&kallsyms.kmaps, type,
+                                               (pos->dso->kernel ?
+                                                       pos->dso->short_name :
+                                                       pos->dso->name));
+               if (pair)
+                       pair->priv = 1;
+               else
+                       map__fprintf(pos, stderr);
+       }
+
+       pr_info("Maps in vmlinux with a different name in kallsyms:\n");
+
+       for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) {
+               struct map *pos = rb_entry(nd, struct map, rb_node), *pair;
+
+               pair = map_groups__find(&kallsyms.kmaps, type, pos->start);
+               if (pair == NULL || pair->priv)
+                       continue;
+
+               if (pair->start == pos->start) {
+                       pair->priv = 1;
+                       pr_info(" %Lx-%Lx %Lx %s in kallsyms as",
+                               pos->start, pos->end, pos->pgoff, pos->dso->name);
+                       if (pos->pgoff != pair->pgoff || pos->end != pair->end)
+                               pr_info(": \n*%Lx-%Lx %Lx",
+                                       pair->start, pair->end, pair->pgoff);
+                       pr_info(" %s\n", pair->dso->name);
+                       pair->priv = 1;
+               }
+       }
+
+       pr_info("Maps only in kallsyms:\n");
+
+       for (nd = rb_first(&kallsyms.kmaps.maps[type]);
+            nd; nd = rb_next(nd)) {
+               struct map *pos = rb_entry(nd, struct map, rb_node);
+
+               if (!pos->priv)
+                       map__fprintf(pos, stderr);
+       }
+out:
+       return err;
+}
+
+static struct test {
+       const char *desc;
+       int (*func)(void);
+} tests[] = {
+       {
+               .desc = "vmlinux symtab matches kallsyms",
+               .func = test__vmlinux_matches_kallsyms,
+       },
+       {
+               .func = NULL,
+       },
+};
+
+static int __cmd_test(void)
+{
+       int i = 0;
+
+       page_size = sysconf(_SC_PAGE_SIZE);
+
+       while (tests[i].func) {
+               int err;
+               pr_info("%2d: %s:", i + 1, tests[i].desc);
+               pr_debug("\n--- start ---\n");
+               err = tests[i].func();
+               pr_debug("---- end ----\n%s:", tests[i].desc);
+               pr_info(" %s\n", err ? "FAILED!\n" : "Ok");
+               ++i;
+       }
+
+       return 0;
+}
+
+static const char * const test_usage[] = {
+       "perf test [<options>]",
+       NULL,
+};
+
+static const struct option test_options[] = {
+       OPT_INTEGER('v', "verbose", &verbose,
+                   "be more verbose (show symbol address, etc)"),
+       OPT_END()
+};
+
+int cmd_test(int argc, const char **argv, const char *prefix __used)
+{
+       argc = parse_options(argc, argv, test_options, test_usage, 0);
+       if (argc)
+               usage_with_options(test_usage, test_options);
+
+       symbol_conf.priv_size = sizeof(int);
+       symbol_conf.sort_by_name = true;
+       symbol_conf.try_vmlinux_path = true;
+
+       if (symbol__init() < 0)
+               return -1;
+
+       setup_pager();
+
+       return __cmd_test();
+}
index 0d4d8ff7914b029423dba4e742c7343925519043..5a52ed9fc10baf5e0a2080853899847187530f32 100644 (file)
@@ -21,7 +21,6 @@
 #include "util/cache.h"
 #include <linux/rbtree.h>
 #include "util/symbol.h"
-#include "util/string.h"
 #include "util/callchain.h"
 #include "util/strlist.h"
 
@@ -43,7 +42,7 @@ static u64            turbo_frequency;
 
 static u64             first_time, last_time;
 
-static int             power_only;
+static bool            power_only;
 
 
 struct per_pid;
@@ -78,8 +77,6 @@ struct per_pid {
 
        struct per_pidcomm *all;
        struct per_pidcomm *current;
-
-       int painted;
 };
 
 
@@ -146,9 +143,6 @@ struct wake_event {
 static struct power_event    *power_events;
 static struct wake_event     *wake_events;
 
-struct sample_wrapper *all_samples;
-
-
 struct process_filter;
 struct process_filter {
        char                    *name;
@@ -569,88 +563,6 @@ static void end_sample_processing(void)
        }
 }
 
-static u64 sample_time(event_t *event, const struct perf_session *session)
-{
-       int cursor;
-
-       cursor = 0;
-       if (session->sample_type & PERF_SAMPLE_IP)
-               cursor++;
-       if (session->sample_type & PERF_SAMPLE_TID)
-               cursor++;
-       if (session->sample_type & PERF_SAMPLE_TIME)
-               return event->sample.array[cursor];
-       return 0;
-}
-
-
-/*
- * We first queue all events, sorted backwards by insertion.
- * The order will get flipped later.
- */
-static int queue_sample_event(event_t *event, struct perf_session *session)
-{
-       struct sample_wrapper *copy, *prev;
-       int size;
-
-       size = event->sample.header.size + sizeof(struct sample_wrapper) + 8;
-
-       copy = malloc(size);
-       if (!copy)
-               return 1;
-
-       memset(copy, 0, size);
-
-       copy->next = NULL;
-       copy->timestamp = sample_time(event, session);
-
-       memcpy(&copy->data, event, event->sample.header.size);
-
-       /* insert in the right place in the list */
-
-       if (!all_samples) {
-               /* first sample ever */
-               all_samples = copy;
-               return 0;
-       }
-
-       if (all_samples->timestamp < copy->timestamp) {
-               /* insert at the head of the list */
-               copy->next = all_samples;
-               all_samples = copy;
-               return 0;
-       }
-
-       prev = all_samples;
-       while (prev->next) {
-               if (prev->next->timestamp < copy->timestamp) {
-                       copy->next = prev->next;
-                       prev->next = copy;
-                       return 0;
-               }
-               prev = prev->next;
-       }
-       /* insert at the end of the list */
-       prev->next = copy;
-
-       return 0;
-}
-
-static void sort_queued_samples(void)
-{
-       struct sample_wrapper *cursor, *next;
-
-       cursor = all_samples;
-       all_samples = NULL;
-
-       while (cursor) {
-               next = cursor->next;
-               cursor->next = all_samples;
-               all_samples = cursor;
-               cursor = next;
-       }
-}
-
 /*
  * Sort the pid datastructure
  */
@@ -1014,31 +926,17 @@ static void write_svg_file(const char *filename)
        svg_close();
 }
 
-static void process_samples(struct perf_session *session)
-{
-       struct sample_wrapper *cursor;
-       event_t *event;
-
-       sort_queued_samples();
-
-       cursor = all_samples;
-       while (cursor) {
-               event = (void *)&cursor->data;
-               cursor = cursor->next;
-               process_sample_event(event, session);
-       }
-}
-
 static struct perf_event_ops event_ops = {
-       .comm   = process_comm_event,
-       .fork   = process_fork_event,
-       .exit   = process_exit_event,
-       .sample = queue_sample_event,
+       .comm                   = process_comm_event,
+       .fork                   = process_fork_event,
+       .exit                   = process_exit_event,
+       .sample                 = process_sample_event,
+       .ordered_samples        = true,
 };
 
 static int __cmd_timechart(void)
 {
-       struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
+       struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0, false);
        int ret = -EINVAL;
 
        if (session == NULL)
@@ -1051,8 +949,6 @@ static int __cmd_timechart(void)
        if (ret)
                goto out_delete;
 
-       process_samples(session);
-
        end_sample_processing();
 
        sort_pids();
@@ -1075,7 +971,6 @@ static const char *record_args[] = {
        "record",
        "-a",
        "-R",
-       "-M",
        "-f",
        "-c", "1",
        "-e", "power:power_start",
index 31f2e597800c7f4331a9aa97ec9045f04a52306b..397290a0a76e8eef264a87db3ec9e926f379821b 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/rbtree.h>
 #include "util/parse-options.h"
 #include "util/parse-events.h"
+#include "util/cpumap.h"
 
 #include "util/debug.h"
 
@@ -54,9 +55,9 @@
 #include <linux/unistd.h>
 #include <linux/types.h>
 
-static int                     fd[MAX_NR_CPUS][MAX_COUNTERS];
+static int                     *fd[MAX_NR_CPUS][MAX_COUNTERS];
 
-static int                     system_wide                     =      0;
+static bool                    system_wide                     =  false;
 
 static int                     default_interval                =      0;
 
@@ -64,18 +65,21 @@ static int                  count_filter                    =      5;
 static int                     print_entries;
 
 static int                     target_pid                      =     -1;
-static int                     inherit                         =      0;
+static int                     target_tid                      =     -1;
+static pid_t                   *all_tids                       =      NULL;
+static int                     thread_num                      =      0;
+static bool                    inherit                         =  false;
 static int                     profile_cpu                     =     -1;
 static int                     nr_cpus                         =      0;
-static unsigned int            realtime_prio                   =      0;
-static int                     group                           =      0;
+static int                     realtime_prio                   =      0;
+static bool                    group                           =  false;
 static unsigned int            page_size;
 static unsigned int            mmap_pages                      =     16;
 static int                     freq                            =   1000; /* 1 KHz */
 
 static int                     delay_secs                      =      2;
-static int                     zero                            =      0;
-static int                     dump_symtab                     =      0;
+static bool                    zero                            =  false;
+static bool                    dump_symtab                     =  false;
 
 static bool                    hide_kernel_symbols             =  false;
 static bool                    hide_user_symbols               =  false;
@@ -92,7 +96,7 @@ struct source_line {
        struct source_line      *next;
 };
 
-static char                    *sym_filter                     =   NULL;
+static const char              *sym_filter                     =   NULL;
 struct sym_entry               *sym_filter_entry               =   NULL;
 struct sym_entry               *sym_filter_entry_sched         =   NULL;
 static int                     sym_pcnt_filter                 =      5;
@@ -132,7 +136,7 @@ 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)
+void get_term_dimensions(struct winsize *ws)
 {
        char *s = getenv("LINES");
 
@@ -168,7 +172,7 @@ static void sig_winch_handler(int sig __used)
        update_print_entries(&winsize);
 }
 
-static void parse_source(struct sym_entry *syme)
+static int parse_source(struct sym_entry *syme)
 {
        struct symbol *sym;
        struct sym_entry_source *source;
@@ -179,12 +183,21 @@ static void parse_source(struct sym_entry *syme)
        u64 len;
 
        if (!syme)
-               return;
+               return -1;
+
+       sym = sym_entry__symbol(syme);
+       map = syme->map;
+
+       /*
+        * We can't annotate with just /proc/kallsyms
+        */
+       if (map->dso->origin == DSO__ORIG_KERNEL)
+               return -1;
 
        if (syme->src == NULL) {
                syme->src = zalloc(sizeof(*source));
                if (syme->src == NULL)
-                       return;
+                       return -1;
                pthread_mutex_init(&syme->src->lock, NULL);
        }
 
@@ -194,9 +207,6 @@ static void parse_source(struct sym_entry *syme)
                pthread_mutex_lock(&source->lock);
                goto out_assign;
        }
-
-       sym = sym_entry__symbol(syme);
-       map = syme->map;
        path = map->dso->long_name;
 
        len = sym->end - sym->start;
@@ -208,7 +218,7 @@ static void parse_source(struct sym_entry *syme)
 
        file = popen(command, "r");
        if (!file)
-               return;
+               return -1;
 
        pthread_mutex_lock(&source->lock);
        source->lines_tail = &source->lines;
@@ -244,6 +254,7 @@ static void parse_source(struct sym_entry *syme)
 out_assign:
        sym_filter_entry = syme;
        pthread_mutex_unlock(&source->lock);
+       return 0;
 }
 
 static void __zero_source_counters(struct sym_entry *syme)
@@ -409,7 +420,9 @@ static double sym_weight(const struct sym_entry *sym)
 }
 
 static long                    samples;
-static long                    userspace_samples;
+static long                    kernel_samples, us_samples;
+static long                    exact_samples;
+static long                    guest_us_samples, guest_kernel_samples;
 static const char              CONSOLE_CLEAR[] = "\e[H\e[2J";
 
 static void __list_insert_active_sym(struct sym_entry *syme)
@@ -449,15 +462,20 @@ static void print_sym_table(void)
        int printed = 0, j;
        int counter, snap = !display_weighted ? sym_counter : 0;
        float samples_per_sec = samples/delay_secs;
-       float ksamples_per_sec = (samples-userspace_samples)/delay_secs;
+       float ksamples_per_sec = kernel_samples/delay_secs;
+       float us_samples_per_sec = (us_samples)/delay_secs;
+       float guest_kernel_samples_per_sec = (guest_kernel_samples)/delay_secs;
+       float guest_us_samples_per_sec = (guest_us_samples)/delay_secs;
+       float esamples_percent = (100.0*exact_samples)/samples;
        float sum_ksamples = 0.0;
        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;
+       int sym_width = 0, dso_width = 0, dso_short_width = 0;
        const int win_width = winsize.ws_col - 1;
 
-       samples = userspace_samples = 0;
+       samples = us_samples = kernel_samples = exact_samples = 0;
+       guest_kernel_samples = guest_us_samples = 0;
 
        /* Sort the active symbols */
        pthread_mutex_lock(&active_symbols_lock);
@@ -488,9 +506,30 @@ static void print_sym_table(void)
        puts(CONSOLE_CLEAR);
 
        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)));
+       if (!perf_guest) {
+               printf("   PerfTop:%8.0f irqs/sec  kernel:%4.1f%%"
+                       "  exact: %4.1f%% [",
+                       samples_per_sec,
+                       100.0 - (100.0 * ((samples_per_sec - ksamples_per_sec) /
+                                        samples_per_sec)),
+                       esamples_percent);
+       } else {
+               printf("   PerfTop:%8.0f irqs/sec  kernel:%4.1f%% us:%4.1f%%"
+                       " guest kernel:%4.1f%% guest us:%4.1f%%"
+                       " exact: %4.1f%% [",
+                       samples_per_sec,
+                       100.0 - (100.0 * ((samples_per_sec-ksamples_per_sec) /
+                                         samples_per_sec)),
+                       100.0 - (100.0 * ((samples_per_sec-us_samples_per_sec) /
+                                         samples_per_sec)),
+                       100.0 - (100.0 * ((samples_per_sec -
+                                               guest_kernel_samples_per_sec) /
+                                         samples_per_sec)),
+                       100.0 - (100.0 * ((samples_per_sec -
+                                          guest_us_samples_per_sec) /
+                                         samples_per_sec)),
+                       esamples_percent);
+       }
 
        if (nr_counters == 1 || !display_weighted) {
                printf("%Ld", (u64)attrs[0].sample_period);
@@ -513,13 +552,15 @@ static void print_sym_table(void)
 
        if (target_pid != -1)
                printf(" (target_pid: %d", target_pid);
+       else if (target_tid != -1)
+               printf(" (target_tid: %d", target_tid);
        else
                printf(" (all");
 
        if (profile_cpu != -1)
                printf(", cpu: %d)\n", profile_cpu);
        else {
-               if (target_pid != -1)
+               if (target_tid != -1)
                        printf(")\n");
                else
                        printf(", %d CPUs)\n", nr_cpus);
@@ -544,15 +585,20 @@ static void print_sym_table(void)
                if (syme->map->dso->long_name_len > dso_width)
                        dso_width = syme->map->dso->long_name_len;
 
+               if (syme->map->dso->short_name_len > dso_short_width)
+                       dso_short_width = syme->map->dso->short_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;
+       if (sym_width + dso_width > winsize.ws_col - 29) {
+               dso_width = dso_short_width;
+               if (sym_width + dso_width > winsize.ws_col - 29)
+                       sym_width = winsize.ws_col - dso_width - 29;
+       }
        putchar('\n');
        if (nr_counters == 1)
                printf("             samples  pcnt");
@@ -576,7 +622,6 @@ static void print_sym_table(void)
 
                syme = rb_entry(nd, struct sym_entry, rb_node);
                sym = sym_entry__symbol(syme);
-
                if (++printed > print_entries || (int)syme->snap_count < count_filter)
                        continue;
 
@@ -740,7 +785,7 @@ static int key_mapped(int c)
        return 0;
 }
 
-static void handle_keypress(int c)
+static void handle_keypress(struct perf_session *session, int c)
 {
        if (!key_mapped(c)) {
                struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
@@ -809,7 +854,7 @@ static void handle_keypress(int c)
                case 'Q':
                        printf("exiting.\n");
                        if (dump_symtab)
-                               dsos__fprintf(stderr);
+                               perf_session__fprintf_dsos(session, stderr);
                        exit(0);
                case 's':
                        prompt_symbol(&sym_filter_entry, "Enter details symbol");
@@ -833,7 +878,7 @@ static void handle_keypress(int c)
                        display_weighted = ~display_weighted;
                        break;
                case 'z':
-                       zero = ~zero;
+                       zero = !zero;
                        break;
                default:
                        break;
@@ -845,6 +890,7 @@ static void *display_thread(void *arg __used)
        struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
        struct termios tc, save;
        int delay_msecs, c;
+       struct perf_session *session = (struct perf_session *) arg;
 
        tcgetattr(0, &save);
        tc = save;
@@ -865,7 +911,7 @@ repeat:
        c = getc(stdin);
        tcsetattr(0, TCSAFLUSH, &save);
 
-       handle_keypress(c);
+       handle_keypress(session, c);
        goto repeat;
 
        return NULL;
@@ -936,24 +982,48 @@ static void event__process_sample(const event_t *self,
        u64 ip = self->ip.ip;
        struct sym_entry *syme;
        struct addr_location al;
+       struct machine *machine;
        u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
 
        ++samples;
 
        switch (origin) {
        case PERF_RECORD_MISC_USER:
-               ++userspace_samples;
+               ++us_samples;
                if (hide_user_symbols)
                        return;
+               machine = perf_session__find_host_machine(session);
                break;
        case PERF_RECORD_MISC_KERNEL:
+               ++kernel_samples;
                if (hide_kernel_symbols)
                        return;
+               machine = perf_session__find_host_machine(session);
+               break;
+       case PERF_RECORD_MISC_GUEST_KERNEL:
+               ++guest_kernel_samples;
+               machine = perf_session__find_machine(session, self->ip.pid);
                break;
+       case PERF_RECORD_MISC_GUEST_USER:
+               ++guest_us_samples;
+               /*
+                * TODO: we don't process guest user from host side
+                * except simple counting.
+                */
+               return;
        default:
                return;
        }
 
+       if (!machine && perf_guest) {
+               pr_err("Can't find guest [%d]'s kernel information\n",
+                       self->ip.pid);
+               return;
+       }
+
+       if (self->header.misc & PERF_RECORD_MISC_EXACT_IP)
+               exact_samples++;
+
        if (event__preprocess_sample(self, session, &al, symbol_filter) < 0 ||
            al.filtered)
                return;
@@ -970,7 +1040,7 @@ static void event__process_sample(const event_t *self,
                 * --hide-kernel-symbols, even if the user specifies an
                 * invalid --vmlinux ;-)
                 */
-               if (al.map == session->vmlinux_maps[MAP__FUNCTION] &&
+               if (al.map == machine->vmlinux_maps[MAP__FUNCTION] &&
                    RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) {
                        pr_err("The %s file can't be used\n",
                               symbol_conf.vmlinux_name);
@@ -984,7 +1054,17 @@ static void event__process_sample(const event_t *self,
        if (sym_filter_entry_sched) {
                sym_filter_entry = sym_filter_entry_sched;
                sym_filter_entry_sched = NULL;
-               parse_source(sym_filter_entry);
+               if (parse_source(sym_filter_entry) < 0) {
+                       struct symbol *sym = sym_entry__symbol(sym_filter_entry);
+
+                       pr_err("Can't annotate %s", sym->name);
+                       if (sym_filter_entry->map->dso->origin == DSO__ORIG_KERNEL) {
+                               pr_err(": No vmlinux file was found in the path:\n");
+                               vmlinux_path__fprintf(stderr);
+                       } else
+                               pr_err(".\n");
+                       exit(1);
+               }
        }
 
        syme = symbol__priv(al.sym);
@@ -1100,16 +1180,21 @@ static void perf_session__mmap_read_counter(struct perf_session *self,
        md->prev = old;
 }
 
-static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS];
-static struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
+static struct pollfd *event_array;
+static struct mmap_data *mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
 
 static void perf_session__mmap_read(struct perf_session *self)
 {
-       int i, counter;
+       int i, counter, thread_index;
 
        for (i = 0; i < nr_cpus; i++) {
                for (counter = 0; counter < nr_counters; counter++)
-                       perf_session__mmap_read_counter(self, &mmap_array[i][counter]);
+                       for (thread_index = 0;
+                               thread_index < thread_num;
+                               thread_index++) {
+                               perf_session__mmap_read_counter(self,
+                                       &mmap_array[i][counter][thread_index]);
+                       }
        }
 }
 
@@ -1120,10 +1205,11 @@ static void start_counter(int i, int counter)
 {
        struct perf_event_attr *attr;
        int cpu;
+       int thread_index;
 
        cpu = profile_cpu;
-       if (target_pid == -1 && profile_cpu == -1)
-               cpu = i;
+       if (target_tid == -1 && profile_cpu == -1)
+               cpu = cpumap[i];
 
        attr = attrs + counter;
 
@@ -1138,55 +1224,58 @@ static void start_counter(int i, int counter)
        attr->inherit           = (cpu < 0) && inherit;
        attr->mmap              = 1;
 
+       for (thread_index = 0; thread_index < thread_num; thread_index++) {
 try_again:
-       fd[i][counter] = sys_perf_event_open(attr, target_pid, cpu, group_fd, 0);
-
-       if (fd[i][counter] < 0) {
-               int err = errno;
+               fd[i][counter][thread_index] = sys_perf_event_open(attr,
+                               all_tids[thread_index], cpu, group_fd, 0);
+
+               if (fd[i][counter][thread_index] < 0) {
+                       int err = errno;
+
+                       if (err == EPERM || err == EACCES)
+                               die("No permission - are you root?\n");
+                       /*
+                        * If it's cycles then fall back to hrtimer
+                        * based cpu-clock-tick sw counter, which
+                        * is always available even if no PMU support:
+                        */
+                       if (attr->type == PERF_TYPE_HARDWARE
+                                       && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
+
+                               if (verbose)
+                                       warning(" ... trying to fall back to cpu-clock-ticks\n");
+
+                               attr->type = PERF_TYPE_SOFTWARE;
+                               attr->config = PERF_COUNT_SW_CPU_CLOCK;
+                               goto try_again;
+                       }
+                       printf("\n");
+                       error("perfcounter syscall returned with %d (%s)\n",
+                                       fd[i][counter][thread_index], strerror(err));
+                       die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
+                       exit(-1);
+               }
+               assert(fd[i][counter][thread_index] >= 0);
+               fcntl(fd[i][counter][thread_index], F_SETFL, O_NONBLOCK);
 
-               if (err == EPERM || err == EACCES)
-                       die("No permission - are you root?\n");
                /*
-                * If it's cycles then fall back to hrtimer
-                * based cpu-clock-tick sw counter, which
-                * is always available even if no PMU support:
+                * First counter acts as the group leader:
                 */
-               if (attr->type == PERF_TYPE_HARDWARE
-                       && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
-
-                       if (verbose)
-                               warning(" ... trying to fall back to cpu-clock-ticks\n");
-
-                       attr->type = PERF_TYPE_SOFTWARE;
-                       attr->config = PERF_COUNT_SW_CPU_CLOCK;
-                       goto try_again;
-               }
-               printf("\n");
-               error("perfcounter syscall returned with %d (%s)\n",
-                       fd[i][counter], strerror(err));
-               die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
-               exit(-1);
+               if (group && group_fd == -1)
+                       group_fd = fd[i][counter][thread_index];
+
+               event_array[nr_poll].fd = fd[i][counter][thread_index];
+               event_array[nr_poll].events = POLLIN;
+               nr_poll++;
+
+               mmap_array[i][counter][thread_index].counter = counter;
+               mmap_array[i][counter][thread_index].prev = 0;
+               mmap_array[i][counter][thread_index].mask = mmap_pages*page_size - 1;
+               mmap_array[i][counter][thread_index].base = mmap(NULL, (mmap_pages+1)*page_size,
+                               PROT_READ, MAP_SHARED, fd[i][counter][thread_index], 0);
+               if (mmap_array[i][counter][thread_index].base == MAP_FAILED)
+                       die("failed to mmap with %d (%s)\n", errno, strerror(errno));
        }
-       assert(fd[i][counter] >= 0);
-       fcntl(fd[i][counter], F_SETFL, O_NONBLOCK);
-
-       /*
-        * First counter acts as the group leader:
-        */
-       if (group && group_fd == -1)
-               group_fd = fd[i][counter];
-
-       event_array[nr_poll].fd = fd[i][counter];
-       event_array[nr_poll].events = POLLIN;
-       nr_poll++;
-
-       mmap_array[i][counter].counter = counter;
-       mmap_array[i][counter].prev = 0;
-       mmap_array[i][counter].mask = mmap_pages*page_size - 1;
-       mmap_array[i][counter].base = mmap(NULL, (mmap_pages+1)*page_size,
-                       PROT_READ, MAP_SHARED, fd[i][counter], 0);
-       if (mmap_array[i][counter].base == MAP_FAILED)
-               die("failed to mmap with %d (%s)\n", errno, strerror(errno));
 }
 
 static int __cmd_top(void)
@@ -1198,12 +1287,12 @@ static int __cmd_top(void)
         * FIXME: perf_session__new should allow passing a O_MMAP, so that all this
         * mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
         */
-       struct perf_session *session = perf_session__new(NULL, O_WRONLY, false);
+       struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, false);
        if (session == NULL)
                return -ENOMEM;
 
-       if (target_pid != -1)
-               event__synthesize_thread(target_pid, event__process, session);
+       if (target_tid != -1)
+               event__synthesize_thread(target_tid, event__process, session);
        else
                event__synthesize_threads(event__process, session);
 
@@ -1214,11 +1303,11 @@ static int __cmd_top(void)
        }
 
        /* Wait for a minimal set of events before starting the snapshot */
-       poll(event_array, nr_poll, 100);
+       poll(&event_array[0], nr_poll, 100);
 
        perf_session__mmap_read(session);
 
-       if (pthread_create(&thread, NULL, display_thread, NULL)) {
+       if (pthread_create(&thread, NULL, display_thread, session)) {
                printf("Could not create display thread.\n");
                exit(-1);
        }
@@ -1257,7 +1346,9 @@ static const struct option options[] = {
        OPT_INTEGER('c', "count", &default_interval,
                    "event period to sample"),
        OPT_INTEGER('p', "pid", &target_pid,
-                   "profile events on existing pid"),
+                   "profile events on existing process id"),
+       OPT_INTEGER('t', "tid", &target_tid,
+                   "profile events on existing thread id"),
        OPT_BOOLEAN('a', "all-cpus", &system_wide,
                            "system-wide collection from all CPUs"),
        OPT_INTEGER('C', "CPU", &profile_cpu,
@@ -1266,8 +1357,7 @@ static const struct option options[] = {
                   "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_UINTEGER('m', "mmap-pages", &mmap_pages, "number of mmap data pages"),
        OPT_INTEGER('r', "realtime", &realtime_prio,
                    "collect data with this RT SCHED_FIFO priority"),
        OPT_INTEGER('d', "delay", &delay_secs,
@@ -1290,7 +1380,7 @@ static const struct option options[] = {
                    "display this many functions"),
        OPT_BOOLEAN('U', "hide_user_symbols", &hide_user_symbols,
                    "hide user symbols"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show counter open errors, etc)"),
        OPT_END()
 };
@@ -1298,6 +1388,7 @@ static const struct option options[] = {
 int cmd_top(int argc, const char **argv, const char *prefix __used)
 {
        int counter;
+       int i,j;
 
        page_size = sysconf(_SC_PAGE_SIZE);
 
@@ -1305,8 +1396,39 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
        if (argc)
                usage_with_options(top_usage, options);
 
+       if (target_pid != -1) {
+               target_tid = target_pid;
+               thread_num = find_all_tid(target_pid, &all_tids);
+               if (thread_num <= 0) {
+                       fprintf(stderr, "Can't find all threads of pid %d\n",
+                               target_pid);
+                       usage_with_options(top_usage, options);
+               }
+       } else {
+               all_tids=malloc(sizeof(pid_t));
+               if (!all_tids)
+                       return -ENOMEM;
+
+               all_tids[0] = target_tid;
+               thread_num = 1;
+       }
+
+       for (i = 0; i < MAX_NR_CPUS; i++) {
+               for (j = 0; j < MAX_COUNTERS; j++) {
+                       fd[i][j] = malloc(sizeof(int)*thread_num);
+                       mmap_array[i][j] = zalloc(
+                               sizeof(struct mmap_data)*thread_num);
+                       if (!fd[i][j] || !mmap_array[i][j])
+                               return -ENOMEM;
+               }
+       }
+       event_array = malloc(
+               sizeof(struct pollfd)*MAX_NR_CPUS*MAX_COUNTERS*thread_num);
+       if (!event_array)
+               return -ENOMEM;
+
        /* CPU and PID are mutually exclusive */
-       if (target_pid != -1 && profile_cpu != -1) {
+       if (target_tid > 0 && profile_cpu != -1) {
                printf("WARNING: PID switch overriding CPU\n");
                sleep(1);
                profile_cpu = -1;
@@ -1347,12 +1469,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
                attrs[counter].sample_period = default_interval;
        }
 
-       nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
-       assert(nr_cpus <= MAX_NR_CPUS);
-       assert(nr_cpus >= 0);
-
-       if (target_pid != -1 || profile_cpu != -1)
+       if (target_tid != -1 || profile_cpu != -1)
                nr_cpus = 1;
+       else
+               nr_cpus = read_cpu_map();
 
        get_term_dimensions(&winsize);
        if (print_entries == 0) {
index 407041d20de065027e9f2a32eff7b5e6a078419c..dddf3f01b5ab3c91db25611ac4a2ed6c5adcf064 100644 (file)
@@ -11,6 +11,8 @@
 
 static char const              *script_name;
 static char const              *generate_script_lang;
+static bool                    debug_ordering;
+static u64                     last_timestamp;
 
 static int default_start_script(const char *script __unused,
                                int argc __unused,
@@ -51,6 +53,8 @@ static void setup_scripting(void)
 
 static int cleanup_scripting(void)
 {
+       pr_debug("\nperf trace script stopped\n");
+
        return scripting_ops->stop_script();
 }
 
@@ -87,6 +91,14 @@ static int process_sample_event(event_t *event, struct perf_session *session)
        }
 
        if (session->sample_type & PERF_SAMPLE_RAW) {
+               if (debug_ordering) {
+                       if (data.time < last_timestamp) {
+                               pr_err("Samples misordered, previous: %llu "
+                                       "this: %llu\n", last_timestamp,
+                                       data.time);
+                       }
+                       last_timestamp = data.time;
+               }
                /*
                 * FIXME: better resolve from pid from the struct trace_entry
                 * field, although it should be the same than this perf
@@ -97,17 +109,31 @@ static int process_sample_event(event_t *event, struct perf_session *session)
                                             data.time, thread->comm);
        }
 
-       session->events_stats.total += data.period;
+       session->hists.stats.total_period += data.period;
        return 0;
 }
 
 static struct perf_event_ops event_ops = {
        .sample = process_sample_event,
        .comm   = event__process_comm,
+       .attr   = event__process_attr,
+       .event_type = event__process_event_type,
+       .tracing_data = event__process_tracing_data,
+       .build_id = event__process_build_id,
+       .ordered_samples = true,
 };
 
+extern volatile int session_done;
+
+static void sig_handler(int sig __unused)
+{
+       session_done = 1;
+}
+
 static int __cmd_trace(struct perf_session *session)
 {
+       signal(SIGINT, sig_handler);
+
        return perf_session__process_events(session, &event_ops);
 }
 
@@ -505,7 +531,7 @@ static const char * const trace_usage[] = {
 static const struct option options[] = {
        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
                    "dump raw trace in ASCII"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show symbol address, etc)"),
        OPT_BOOLEAN('L', "Latency", &latency_format,
                    "show latency attributes (irqs/preemption disabled, etc)"),
@@ -518,6 +544,8 @@ static const struct option options[] = {
                   "generate perf-trace.xx script in specified language"),
        OPT_STRING('i', "input", &input_name, "file",
                    "input file name"),
+       OPT_BOOLEAN('d', "debug-ordering", &debug_ordering,
+                  "check that samples time ordering is monotonic"),
 
        OPT_END()
 };
@@ -548,6 +576,65 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
                suffix = REPORT_SUFFIX;
        }
 
+       if (!suffix && argc >= 2 && strncmp(argv[1], "-", strlen("-")) != 0) {
+               char *record_script_path, *report_script_path;
+               int live_pipe[2];
+               pid_t pid;
+
+               record_script_path = get_script_path(argv[1], RECORD_SUFFIX);
+               if (!record_script_path) {
+                       fprintf(stderr, "record script not found\n");
+                       return -1;
+               }
+
+               report_script_path = get_script_path(argv[1], REPORT_SUFFIX);
+               if (!report_script_path) {
+                       fprintf(stderr, "report script not found\n");
+                       return -1;
+               }
+
+               if (pipe(live_pipe) < 0) {
+                       perror("failed to create pipe");
+                       exit(-1);
+               }
+
+               pid = fork();
+               if (pid < 0) {
+                       perror("failed to fork");
+                       exit(-1);
+               }
+
+               if (!pid) {
+                       dup2(live_pipe[1], 1);
+                       close(live_pipe[0]);
+
+                       __argv = malloc(5 * sizeof(const char *));
+                       __argv[0] = "/bin/sh";
+                       __argv[1] = record_script_path;
+                       __argv[2] = "-o";
+                       __argv[3] = "-";
+                       __argv[4] = NULL;
+
+                       execvp("/bin/sh", (char **)__argv);
+                       exit(-1);
+               }
+
+               dup2(live_pipe[0], 0);
+               close(live_pipe[1]);
+
+               __argv = malloc((argc + 3) * sizeof(const char *));
+               __argv[0] = "/bin/sh";
+               __argv[1] = report_script_path;
+               for (i = 2; i < argc; i++)
+                       __argv[i] = argv[i];
+               __argv[i++] = "-i";
+               __argv[i++] = "-";
+               __argv[i++] = NULL;
+
+               execvp("/bin/sh", (char **)__argv);
+               exit(-1);
+       }
+
        if (suffix) {
                script_path = get_script_path(argv[2], suffix);
                if (!script_path) {
@@ -576,11 +663,12 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
        if (!script_name)
                setup_pager();
 
-       session = perf_session__new(input_name, O_RDONLY, 0);
+       session = perf_session__new(input_name, O_RDONLY, 0, false);
        if (session == NULL)
                return -ENOMEM;
 
-       if (!perf_session__has_traces(session, "record -R"))
+       if (strcmp(input_name, "-") &&
+           !perf_session__has_traces(session, "record -R"))
                return -EINVAL;
 
        if (generate_script_lang) {
@@ -617,6 +705,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
                err = scripting_ops->start_script(script_name, argc, argv);
                if (err)
                        goto out;
+               pr_debug("perf trace started with script %s\n\n", script_name);
        }
 
        err = __cmd_trace(session);
index 10fe49e7048a986888f56830a5562e206c967331..921245b28583e448cce49008b2482e0f59193454 100644 (file)
@@ -32,5 +32,8 @@ 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);
 extern int cmd_lock(int argc, const char **argv, const char *prefix);
+extern int cmd_kvm(int argc, const char **argv, const char *prefix);
+extern int cmd_test(int argc, const char **argv, const char *prefix);
+extern int cmd_inject(int argc, const char **argv, const char *prefix);
 
 #endif
index db6ee94d4a8e4fcef7277cbd69384e2b291611da..949d77fc0b9718d812a8906883b7a89ef99c49f0 100644 (file)
@@ -8,6 +8,7 @@ perf-bench                      mainporcelain common
 perf-buildid-cache             mainporcelain common
 perf-buildid-list              mainporcelain common
 perf-diff                      mainporcelain common
+perf-inject                    mainporcelain common
 perf-list                      mainporcelain common
 perf-sched                     mainporcelain common
 perf-record                    mainporcelain common
@@ -19,3 +20,5 @@ perf-trace                    mainporcelain common
 perf-probe                     mainporcelain common
 perf-kmem                      mainporcelain common
 perf-lock                      mainporcelain common
+perf-kvm                       mainporcelain common
+perf-test                      mainporcelain common
index 910468e6e01cfbcbfffb1619904e307253d8d6b7..2e7a4f417e2065c336614f853554357146bb73ce 100644 (file)
@@ -30,4 +30,7 @@ done
 
 tar cfj $PERF_DATA.tar.bz2 -C $DEBUGDIR -T $MANIFEST
 rm -f $MANIFEST $BUILDIDS
+echo -e "Now please run:\n"
+echo -e "$ tar xvf $PERF_DATA.tar.bz2 -C ~/.debug\n"
+echo "wherever you need to run 'perf report' on."
 exit 0
index cd32c200cdb32169c03369e0f505b8e974822306..08e0e5d2b50eb30be37b609c7e3a3f00bd0c8f12 100644 (file)
 #include "util/quote.h"
 #include "util/run-command.h"
 #include "util/parse-events.h"
-#include "util/string.h"
 #include "util/debugfs.h"
 
+bool use_browser;
+
 const char perf_usage_string[] =
        "perf [--version] [--help] COMMAND [ARGS]";
 
@@ -262,6 +263,8 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
        set_debugfs_path();
 
        status = p->fn(argc, argv, prefix);
+       exit_browser(status);
+
        if (status)
                return status & 0xff;
 
@@ -304,6 +307,9 @@ static void handle_internal_command(int argc, const char **argv)
                { "probe",      cmd_probe,      0 },
                { "kmem",       cmd_kmem,       0 },
                { "lock",       cmd_lock,       0 },
+               { "kvm",        cmd_kvm,        0 },
+               { "test",       cmd_test,       0 },
+               { "inject",     cmd_inject,     0 },
        };
        unsigned int i;
        static const char ext[] = STRIP_EXTENSION;
index 6fb379bc1d1fec0c4c9384fdf2e301d4445a8a01..ef7aa0a0c5265191e8120e76f9f134b5e241fa53 100644 (file)
@@ -1,6 +1,10 @@
 #ifndef _PERF_PERF_H
 #define _PERF_PERF_H
 
+struct winsize;
+
+void get_term_dimensions(struct winsize *ws);
+
 #if defined(__i386__)
 #include "../../arch/x86/include/asm/unistd.h"
 #define rmb()          asm volatile("lock; addl $0,0(%%esp)" ::: "memory")
@@ -76,6 +80,7 @@
 
 #include "../../include/linux/perf_event.h"
 #include "util/types.h"
+#include <stdbool.h>
 
 /*
  * prctl(PR_TASK_PERF_EVENTS_DISABLE) will (cheaply) disable all
@@ -102,8 +107,6 @@ static inline unsigned long long rdclock(void)
 #define __user
 #define asmlinkage
 
-#define __used         __attribute__((__unused__))
-
 #define unlikely(x)    __builtin_expect(!!(x), 0)
 #define min(x, y) ({                           \
        typeof(x) _min1 = (x);                  \
@@ -129,4 +132,6 @@ struct ip_callchain {
        u64 ips[0];
 };
 
+extern bool perf_host, perf_guest;
+
 #endif
index f869c48dc9b0ae920a250832d8804f97303ea8df..d94b40c8ac857227516b6f408bf5b13a9fea03cd 100644 (file)
@@ -15,6 +15,7 @@ our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
 
 our @EXPORT = qw(
 avg nsecs nsecs_secs nsecs_nsecs nsecs_usecs print_nsecs
+clear_term
 );
 
 our $VERSION = '0.01';
@@ -55,6 +56,11 @@ sub nsecs_str {
     return $str;
 }
 
+sub clear_term
+{
+    print "\x1b[H\x1b[2J";
+}
+
 1;
 __END__
 =head1 NAME
index e6cb1474f8e88525c0d9f7cbe742dc91bea2cf2d..423ad6aed05646c16af21150310d0796d52a77c6 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e kmem:kmalloc -e irq:softirq_entry -e kmem:kfree
+perf record -a -e kmem:kmalloc -e irq:softirq_entry -e kmem:kfree
index f8885d389e6fab8c87237f42277df5ddc2ea5865..eb5846bcb565fe3c53599adf4fbe5d1bdb9bed8d 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e raw_syscalls:sys_exit
+perf record -a -e raw_syscalls:sys_exit $@
index 8bfc660e5056207c76f9d5effe117604ca0b52c7..e3a5e55d54ff6706f620e9517d1a33f4b991364c 100644 (file)
@@ -1,4 +1,10 @@
 #!/bin/bash
 # description: system-wide failed syscalls
 # args: [comm]
-perf trace -s ~/libexec/perf-core/scripts/perl/failed-syscalls.pl $1
+if [ $# -gt 0 ] ; then
+    if ! expr match "$1" "-" > /dev/null ; then
+       comm=$1
+       shift
+    fi
+fi
+perf trace $@ -s ~/libexec/perf-core/scripts/perl/failed-syscalls.pl $comm
index b25056ebf963abd69b484d831928a0ff744e8819..5bfaae5a6cbae1b8a63283e9ba32f18269677dc7 100644 (file)
@@ -1,2 +1,3 @@
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e syscalls:sys_enter_read -e syscalls:sys_enter_write
+perf record -a -e syscalls:sys_enter_read -e syscalls:sys_enter_write $@
+
index eddb9ccce6a59111a2a1a61a566b45774b111536..d83070b7eeb536d2afa455601d6e8533bbd5694a 100644 (file)
@@ -1,7 +1,13 @@
 #!/bin/bash
 # description: r/w activity for a program, by file
 # args: <comm>
-perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-file.pl $1
+if [ $# -lt 1 ] ; then
+    echo "usage: rw-by-file <comm>"
+    exit
+fi
+comm=$1
+shift
+perf trace $@ -s ~/libexec/perf-core/scripts/perl/rw-by-file.pl $comm
 
 
 
index 8903979c5b6c91ef42464a8cff40042429a98c3a..6e0b2f7755ac218098479958150f06129cc60ec4 100644 (file)
@@ -1,2 +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
+perf record -a -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write $@
index 7f44c25cc857ca6fbb1a4f8f220c9767b64c2468..7ef46983f62f471145f924a6901b5c1e75a68572 100644 (file)
@@ -1,6 +1,6 @@
 #!/bin/bash
 # description: system-wide r/w activity
-perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-pid.pl
+perf trace $@ -s ~/libexec/perf-core/scripts/perl/rw-by-pid.pl
 
 
 
diff --git a/tools/perf/scripts/perl/bin/rwtop-record b/tools/perf/scripts/perl/bin/rwtop-record
new file mode 100644 (file)
index 0000000..6e0b2f7
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/bash
+perf record -a -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/rwtop-report b/tools/perf/scripts/perl/bin/rwtop-report
new file mode 100644 (file)
index 0000000..93e698c
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/bash
+# description: system-wide r/w top
+# args: [interval]
+n_args=0
+for i in "$@"
+do
+    if expr match "$i" "-" > /dev/null ; then
+       break
+    fi
+    n_args=$(( $n_args + 1 ))
+done
+if [ "$n_args" -gt 1 ] ; then
+    echo "usage: rwtop-report [interval]"
+    exit
+fi
+if [ "$n_args" -gt 0 ] ; then
+    interval=$1
+    shift
+fi
+perf trace $@ -s ~/libexec/perf-core/scripts/perl/rwtop.pl $interval
+
+
+
index 6abedda911a44acfc3e561b4c5bf0d1aabb0ad3e..9f2acaaae9f0538fbdea692bbadd015965b48ae2 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e sched:sched_switch -e sched:sched_wakeup
+perf record -a -e sched:sched_switch -e sched:sched_wakeup $@
 
 
 
index fce3adcb3249a4c2971a53ad8286ffb83736cbe8..a0d898f9ca1d2c87c0a46e475483dc58101f4305 100644 (file)
@@ -1,6 +1,6 @@
 #!/bin/bash
 # description: system-wide min/max/avg wakeup latency
-perf trace -s ~/libexec/perf-core/scripts/perl/wakeup-latency.pl
+perf trace $@ -s ~/libexec/perf-core/scripts/perl/wakeup-latency.pl
 
 
 
index fce6637b19ba03a63cbf0fe86938945936e04322..85301f2471ff59b774573142a4d4c3db5e40604d 100644 (file)
@@ -1,2 +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
+perf record -a -e workqueue:workqueue_creation -e workqueue:workqueue_destruction -e workqueue:workqueue_execution -e workqueue:workqueue_insertion $@
index 71cfbd182fb99946185562cb8809f9ce53d309a8..35081132ef97551f7bc352180a75037ccb927dab 100644 (file)
@@ -1,6 +1,6 @@
 #!/bin/bash
 # description: workqueue stats (ins/exe/create/destroy)
-perf trace -s ~/libexec/perf-core/scripts/perl/workqueue-stats.pl
+perf trace $@ -s ~/libexec/perf-core/scripts/perl/workqueue-stats.pl
 
 
 
index c18e7e27a84b6b801c845afffb6f143f4af19113..94bc25a347ebf7b4688f8cdda37499868d21ddf9 100644 (file)
@@ -11,6 +11,8 @@ use Perf::Trace::Core;
 use Perf::Trace::Context;
 use Perf::Trace::Util;
 
+my $for_comm = shift;
+
 my %failed_syscalls;
 
 sub raw_syscalls::sys_exit
@@ -33,6 +35,8 @@ sub trace_end
 
     foreach my $comm (sort {$failed_syscalls{$b} <=> $failed_syscalls{$a}}
                      keys %failed_syscalls) {
-           printf("%-20s  %10s\n", $comm, $failed_syscalls{$comm});
+       next if ($for_comm && $comm ne $for_comm);
+
+       printf("%-20s  %10s\n", $comm, $failed_syscalls{$comm});
     }
 }
index da601fae1a007b8744c6984f0dac385dc234eb29..9db23c9daf5552d9159a093bf14381750cb71ac7 100644 (file)
@@ -79,12 +79,12 @@ sub trace_end
     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};
+    foreach my $pid (sort { ($reads{$b}{bytes_read} || 0) <=>
+                               ($reads{$a}{bytes_read} || 0) } keys %reads) {
+       my $comm = $reads{$pid}{comm} || "";
+       my $total_reads = $reads{$pid}{total_reads} || 0;
+       my $bytes_requested = $reads{$pid}{bytes_requested} || 0;
+       my $bytes_read = $reads{$pid}{bytes_read} || 0;
 
        printf("%6s  %-20s  %10s  %10s  %10s\n", $pid, $comm,
               $total_reads, $bytes_requested, $bytes_read);
@@ -96,16 +96,23 @@ sub trace_end
     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};
+    my @errcounts = ();
 
-           printf("%6d  %-20s  %6d  %10s\n", $pid, $comm, $err, $errors);
+    foreach my $pid (keys %reads) {
+       foreach my $error (keys %{$reads{$pid}{errors}}) {
+           my $comm = $reads{$pid}{comm} || "";
+           my $errcount = $reads{$pid}{errors}{$error} || 0;
+           push @errcounts, [$pid, $comm, $error, $errcount];
        }
     }
 
+    @errcounts = sort { $b->[3] <=> $a->[3] } @errcounts;
+
+    for my $i (0 .. $#errcounts) {
+       printf("%6d  %-20s  %6d  %10s\n", $errcounts[$i][0],
+              $errcounts[$i][1], $errcounts[$i][2], $errcounts[$i][3]);
+    }
+
     printf("\nwrite counts by pid:\n\n");
 
     printf("%6s  %20s  %10s  %10s\n", "pid", "comm",
@@ -113,11 +120,11 @@ sub trace_end
     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};
+    foreach my $pid (sort { ($writes{$b}{bytes_written} || 0) <=>
+                       ($writes{$a}{bytes_written} || 0)} keys %writes) {
+       my $comm = $writes{$pid}{comm} || "";
+       my $total_writes = $writes{$pid}{total_writes} || 0;
+       my $bytes_written = $writes{$pid}{bytes_written} || 0;
 
        printf("%6s  %-20s  %10s  %10s\n", $pid, $comm,
               $total_writes, $bytes_written);
@@ -129,16 +136,23 @@ sub trace_end
     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};
+    @errcounts = ();
 
-           printf("%6d  %-20s  %6d  %10s\n", $pid, $comm, $err, $errors);
+    foreach my $pid (keys %writes) {
+       foreach my $error (keys %{$writes{$pid}{errors}}) {
+           my $comm = $writes{$pid}{comm} || "";
+           my $errcount = $writes{$pid}{errors}{$error} || 0;
+           push @errcounts, [$pid, $comm, $error, $errcount];
        }
     }
 
+    @errcounts = sort { $b->[3] <=> $a->[3] } @errcounts;
+
+    for my $i (0 .. $#errcounts) {
+       printf("%6d  %-20s  %6d  %10s\n", $errcounts[$i][0],
+              $errcounts[$i][1], $errcounts[$i][2], $errcounts[$i][3]);
+    }
+
     print_unhandled();
 }
 
diff --git a/tools/perf/scripts/perl/rwtop.pl b/tools/perf/scripts/perl/rwtop.pl
new file mode 100644 (file)
index 0000000..4bb3ecd
--- /dev/null
@@ -0,0 +1,199 @@
+#!/usr/bin/perl -w
+# (c) 2010, Tom Zanussi <tzanussi@gmail.com>
+# Licensed under the terms of the GNU GPL License version 2
+
+# read/write top
+#
+# Periodically displays system-wide r/w call activity, broken down by
+# pid.  If an [interval] arg is specified, the display will be
+# refreshed every [interval] seconds.  The default interval is 3
+# seconds.
+
+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 $default_interval = 3;
+my $nlines = 20;
+my $print_thread;
+my $print_pending = 0;
+
+my %reads;
+my %writes;
+
+my $interval = shift;
+if (!$interval) {
+    $interval = $default_interval;
+}
+
+sub syscalls::sys_exit_read
+{
+    my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+       $common_pid, $common_comm,
+       $nr, $ret) = @_;
+
+    print_check();
+
+    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) = @_;
+
+    print_check();
+
+    $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) = @_;
+
+    print_check();
+
+    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) = @_;
+
+    print_check();
+
+    $writes{$common_pid}{bytes_written} += $count;
+    $writes{$common_pid}{total_writes}++;
+    $writes{$common_pid}{comm} = $common_comm;
+}
+
+sub trace_begin
+{
+    $SIG{ALRM} = \&set_print_pending;
+    alarm 1;
+}
+
+sub trace_end
+{
+    print_unhandled();
+    print_totals();
+}
+
+sub print_check()
+{
+    if ($print_pending == 1) {
+       $print_pending = 0;
+       print_totals();
+    }
+}
+
+sub set_print_pending()
+{
+    $print_pending = 1;
+    alarm $interval;
+}
+
+sub print_totals
+{
+    my $count;
+
+    $count = 0;
+
+    clear_term();
+
+    printf("\nread counts by pid:\n\n");
+
+    printf("%6s  %20s  %10s  %10s  %10s\n", "pid", "comm",
+          "# reads", "bytes_req", "bytes_read");
+    printf("%6s  %-20s  %10s  %10s  %10s\n", "------", "--------------------",
+          "----------", "----------", "----------");
+
+    foreach my $pid (sort { ($reads{$b}{bytes_read} || 0) <=>
+                              ($reads{$a}{bytes_read} || 0) } keys %reads) {
+       my $comm = $reads{$pid}{comm} || "";
+       my $total_reads = $reads{$pid}{total_reads} || 0;
+       my $bytes_requested = $reads{$pid}{bytes_requested} || 0;
+       my $bytes_read = $reads{$pid}{bytes_read} || 0;
+
+       printf("%6s  %-20s  %10s  %10s  %10s\n", $pid, $comm,
+              $total_reads, $bytes_requested, $bytes_read);
+
+       if (++$count == $nlines) {
+           last;
+       }
+    }
+
+    $count = 0;
+
+    printf("\nwrite counts by pid:\n\n");
+
+    printf("%6s  %20s  %10s  %13s\n", "pid", "comm",
+          "# writes", "bytes_written");
+    printf("%6s  %-20s  %10s  %13s\n", "------", "--------------------",
+          "----------", "-------------");
+
+    foreach my $pid (sort { ($writes{$b}{bytes_written} || 0) <=>
+                       ($writes{$a}{bytes_written} || 0)} keys %writes) {
+       my $comm = $writes{$pid}{comm} || "";
+       my $total_writes = $writes{$pid}{total_writes} || 0;
+       my $bytes_written = $writes{$pid}{bytes_written} || 0;
+
+       printf("%6s  %-20s  %10s  %13s\n", $pid, $comm,
+              $total_writes, $bytes_written);
+
+       if (++$count == $nlines) {
+           last;
+       }
+    }
+
+    %reads = ();
+    %writes = ();
+}
+
+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}++;
+}
index ed58ef284e235a31ac7e4731418ec34eb9cba4d0..d9143dcec6c601c3b544fbc3a87fe7c1f29d4e70 100644 (file)
@@ -22,8 +22,8 @@ my %last_wakeup;
 
 my $max_wakeup_latency;
 my $min_wakeup_latency;
-my $total_wakeup_latency;
-my $total_wakeups;
+my $total_wakeup_latency = 0;
+my $total_wakeups = 0;
 
 sub sched::sched_switch
 {
@@ -67,8 +67,12 @@ 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));
+    if ($total_wakeups) {
+       printf("avg_wakeup_latency (ns): %u\n",
+              avg($total_wakeup_latency, $total_wakeups));
+    } else {
+       printf("avg_wakeup_latency (ns): N/A\n");
+    }
     printf("min_wakeup_latency (ns): %u\n", $min_wakeup_latency);
     printf("max_wakeup_latency (ns): %u\n", $max_wakeup_latency);
 
index 511302c8a4945f100e5e3c947df56d34976f621b..b84b12699b70ba0731bdbfdd4115d62558990184 100644 (file)
@@ -71,9 +71,9 @@ sub trace_end
     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'};
+           my $ins = $$wqhash{'inserted'} || 0;
+           my $exe = $$wqhash{'executed'} || 0;
+           my $comm = $$wqhash{'comm'} || "";
            if ($ins || $exe) {
                printf("%3u %6u %6u\t%-20s\n", $cpu, $ins, $exe, $comm);
            }
@@ -87,9 +87,9 @@ sub trace_end
     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'};
+           my $created = $$wqhash{'created'} || 0;
+           my $destroyed = $$wqhash{'destroyed'} || 0;
+           my $comm = $$wqhash{'comm'} || "";
            if ($created || $destroyed) {
                printf("%3u %6u %6u\t%-20s\n", $cpu, $created, $destroyed,
                       $comm);
index 83e91435ed096d63e368e3c5674fa9a98427e996..9689bc0acd9f2d934050c71231c3d4635a2af7b2 100644 (file)
@@ -23,3 +23,6 @@ def nsecs_nsecs(nsecs):
 def nsecs_str(nsecs):
     str = "%5u.%09u" % (nsecs_secs(nsecs), nsecs_nsecs(nsecs)),
     return str
+
+def clear_term():
+    print("\x1b[H\x1b[2J")
index f8885d389e6fab8c87237f42277df5ddc2ea5865..eb5846bcb565fe3c53599adf4fbe5d1bdb9bed8d 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e raw_syscalls:sys_exit
+perf record -a -e raw_syscalls:sys_exit $@
index 1e0c0a860c87702b7432fe073a699546d60d4491..30293545fcc2864f0f577669ed88a40353c1f4a9 100644 (file)
@@ -1,4 +1,10 @@
 #!/bin/bash
 # description: system-wide failed syscalls, by pid
 # args: [comm]
-perf trace -s ~/libexec/perf-core/scripts/python/failed-syscalls-by-pid.py $1
+if [ $# -gt 0 ] ; then
+    if ! expr match "$1" "-" > /dev/null ; then
+       comm=$1
+       shift
+    fi
+fi
+perf trace $@ -s ~/libexec/perf-core/scripts/python/failed-syscalls-by-pid.py $comm
diff --git a/tools/perf/scripts/python/bin/sctop-record b/tools/perf/scripts/python/bin/sctop-record
new file mode 100644 (file)
index 0000000..1fc5998
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/bash
+perf record -a -e raw_syscalls:sys_enter $@
diff --git a/tools/perf/scripts/python/bin/sctop-report b/tools/perf/scripts/python/bin/sctop-report
new file mode 100644 (file)
index 0000000..b01c842
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/bash
+# description: syscall top
+# args: [comm] [interval]
+n_args=0
+for i in "$@"
+do
+    if expr match "$i" "-" > /dev/null ; then
+       break
+    fi
+    n_args=$(( $n_args + 1 ))
+done
+if [ "$n_args" -gt 2 ] ; then
+    echo "usage: sctop-report [comm] [interval]"
+    exit
+fi
+if [ "$n_args" -gt 1 ] ; then
+    comm=$1
+    interval=$2
+    shift 2
+elif [ "$n_args" -gt 0 ] ; then
+    interval=$1
+    shift
+fi
+perf trace $@ -s ~/libexec/perf-core/scripts/python/sctop.py $comm $interval
index 45a8c50359daf8092024b0d997c1b4d63a1a727a..1fc5998b721d5f2a5f2a89e83ad90559f18439dd 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e raw_syscalls:sys_enter
+perf record -a -e raw_syscalls:sys_enter $@
index f8044d192271898ea48265aea76bb141bfd285b8..9e9d8ddd72ced9d6b652c5c130070b86ecdc1cfe 100644 (file)
@@ -1,4 +1,10 @@
 #!/bin/bash
 # description: system-wide syscall counts, by pid
 # args: [comm]
-perf trace -s ~/libexec/perf-core/scripts/python/syscall-counts-by-pid.py $1
+if [ $# -gt 0 ] ; then
+    if ! expr match "$1" "-" > /dev/null ; then
+       comm=$1
+       shift
+    fi
+fi
+perf trace $@ -s ~/libexec/perf-core/scripts/python/syscall-counts-by-pid.py $comm
index 45a8c50359daf8092024b0d997c1b4d63a1a727a..1fc5998b721d5f2a5f2a89e83ad90559f18439dd 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e raw_syscalls:sys_enter
+perf record -a -e raw_syscalls:sys_enter $@
index a366aa61612fba6795609b9b0c0dc56a9d9f9ed2..dc076b618796fa999b3024540c9c747a2da4553a 100644 (file)
@@ -1,4 +1,10 @@
 #!/bin/bash
 # description: system-wide syscall counts
 # args: [comm]
-perf trace -s ~/libexec/perf-core/scripts/python/syscall-counts.py $1
+if [ $# -gt 0 ] ; then
+    if ! expr match "$1" "-" > /dev/null ; then
+       comm=$1
+       shift
+    fi
+fi
+perf trace $@ -s ~/libexec/perf-core/scripts/python/syscall-counts.py $comm
diff --git a/tools/perf/scripts/python/sctop.py b/tools/perf/scripts/python/sctop.py
new file mode 100644 (file)
index 0000000..6cafad4
--- /dev/null
@@ -0,0 +1,78 @@
+# system call top
+# (c) 2010, Tom Zanussi <tzanussi@gmail.com>
+# Licensed under the terms of the GNU GPL License version 2
+#
+# Periodically displays system-wide system call totals, broken down by
+# syscall.  If a [comm] arg is specified, only syscalls called by
+# [comm] are displayed. If an [interval] arg is specified, the display
+# will be refreshed every [interval] seconds.  The default interval is
+# 3 seconds.
+
+import thread
+import time
+import os
+import sys
+
+sys.path.append(os.environ['PERF_EXEC_PATH'] + \
+       '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
+
+from perf_trace_context import *
+from Core import *
+from Util import *
+
+usage = "perf trace -s syscall-counts.py [comm] [interval]\n";
+
+for_comm = None
+default_interval = 3
+interval = default_interval
+
+if len(sys.argv) > 3:
+       sys.exit(usage)
+
+if len(sys.argv) > 2:
+       for_comm = sys.argv[1]
+       interval = int(sys.argv[2])
+elif len(sys.argv) > 1:
+       try:
+               interval = int(sys.argv[1])
+       except ValueError:
+               for_comm = sys.argv[1]
+               interval = default_interval
+
+syscalls = autodict()
+
+def trace_begin():
+       thread.start_new_thread(print_syscall_totals, (interval,))
+       pass
+
+def raw_syscalls__sys_enter(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       id, args):
+       if for_comm is not None:
+               if common_comm != for_comm:
+                       return
+       try:
+               syscalls[id] += 1
+       except TypeError:
+               syscalls[id] = 1
+
+def print_syscall_totals(interval):
+       while 1:
+               clear_term()
+               if for_comm is not None:
+                       print "\nsyscall events for %s:\n\n" % (for_comm),
+               else:
+                       print "\nsyscall events:\n\n",
+
+               print "%-40s  %10s\n" % ("event", "count"),
+               print "%-40s  %10s\n" % ("----------------------------------------", \
+                                                "----------"),
+
+               for id, val in sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \
+                                             reverse = True):
+                       try:
+                               print "%-40d  %10d\n" % (id, val),
+                       except TypeError:
+                               pass
+               syscalls.clear()
+               time.sleep(interval)
index 54552a00a1177098e77e0cd76d2ccc9c02858378..49ece7921914a3fdc20ea02d56af193ab61a73f9 100755 (executable)
@@ -1,6 +1,10 @@
 #!/bin/sh
 
-GVF=PERF-VERSION-FILE
+if [ $# -eq 1 ]  ; then
+       OUTPUT=$1
+fi
+
+GVF=${OUTPUT}PERF-VERSION-FILE
 DEF_VER=v0.0.2.PERF
 
 LF='
diff --git a/tools/perf/util/bitmap.c b/tools/perf/util/bitmap.c
new file mode 100644 (file)
index 0000000..5e230ac
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * From lib/bitmap.c
+ * Helper functions for bitmap.h.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+#include <linux/bitmap.h>
+
+int __bitmap_weight(const unsigned long *bitmap, int bits)
+{
+       int k, w = 0, lim = bits/BITS_PER_LONG;
+
+       for (k = 0; k < lim; k++)
+               w += hweight_long(bitmap[k]);
+
+       if (bits % BITS_PER_LONG)
+               w += hweight_long(bitmap[k] & BITMAP_LAST_WORD_MASK(bits));
+
+       return w;
+}
index 04904b35ba8118c39474f015fcf72bb8919537b6..0f60a39068086b9949ee4aa03b94de2bdc5ea439 100644 (file)
@@ -24,7 +24,7 @@ static int build_id__mark_dso_hit(event_t *event, struct perf_session *session)
        }
 
        thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
-                             event->ip.ip, &al);
+                             event->ip.pid, event->ip.ip, &al);
 
        if (al.map != NULL)
                al.map->dso->hit = 1;
index 918eb376abe3943375cf1ea1843d4f724ac0f621..4b9aab7f04056ef6d599ba9e2eb8d7d3333d579b 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __PERF_CACHE_H
 #define __PERF_CACHE_H
 
+#include <stdbool.h>
 #include "util.h"
 #include "strbuf.h"
 #include "../perf.h"
@@ -69,6 +70,19 @@ extern const char *pager_program;
 extern int pager_in_use(void);
 extern int pager_use_color;
 
+extern bool use_browser;
+
+#ifdef NO_NEWT_SUPPORT
+static inline void setup_browser(void)
+{
+       setup_pager();
+}
+static inline void exit_browser(bool wait_for_ok __used) {}
+#else
+void setup_browser(void);
+void exit_browser(bool wait_for_ok);
+#endif
+
 extern const char *editor_program;
 extern const char *excludes_file;
 
index b3b71258272a902f2e349bd74b3c610260d31c96..21a52e0a44359aaa582d0745717f388f24fc058c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009, Frederic Weisbecker <fweisbec@gmail.com>
+ * Copyright (C) 2009-2010, Frederic Weisbecker <fweisbec@gmail.com>
  *
  * Handle the callchains from the stream in an ad-hoc radix tree and then
  * sort them in an rbtree.
 
 #include "callchain.h"
 
+bool ip_callchain__valid(struct ip_callchain *chain, event_t *event)
+{
+       unsigned int chain_size = event->header.size;
+       chain_size -= (unsigned long)&event->ip.__more_data - (unsigned long)event;
+       return chain->nr * sizeof(u64) <= chain_size;
+}
+
 #define chain_for_each_child(child, parent)    \
        list_for_each_entry(child, &parent->children, brothers)
 
@@ -160,7 +167,7 @@ create_child(struct callchain_node *parent, bool inherit_children)
 {
        struct callchain_node *new;
 
-       new = malloc(sizeof(*new));
+       new = zalloc(sizeof(*new));
        if (!new) {
                perror("not enough memory to create child for code path tree");
                return NULL;
@@ -183,25 +190,36 @@ create_child(struct callchain_node *parent, bool inherit_children)
        return new;
 }
 
+
+struct resolved_ip {
+       u64               ip;
+       struct map_symbol ms;
+};
+
+struct resolved_chain {
+       u64                     nr;
+       struct resolved_ip      ips[0];
+};
+
+
 /*
  * Fill the node with callchain values
  */
 static void
-fill_node(struct callchain_node *node, struct ip_callchain *chain,
-         int start, struct symbol **syms)
+fill_node(struct callchain_node *node, struct resolved_chain *chain, int start)
 {
        unsigned int i;
 
        for (i = start; i < chain->nr; i++) {
                struct callchain_list *call;
 
-               call = malloc(sizeof(*call));
+               call = zalloc(sizeof(*call));
                if (!call) {
                        perror("not enough memory for the code path tree");
                        return;
                }
-               call->ip = chain->ips[i];
-               call->sym = syms[i];
+               call->ip = chain->ips[i].ip;
+               call->ms = chain->ips[i].ms;
                list_add_tail(&call->list, &node->val);
        }
        node->val_nr = chain->nr - start;
@@ -210,13 +228,13 @@ fill_node(struct callchain_node *node, struct ip_callchain *chain,
 }
 
 static void
-add_child(struct callchain_node *parent, struct ip_callchain *chain,
-         int start, struct symbol **syms)
+add_child(struct callchain_node *parent, struct resolved_chain *chain,
+         int start)
 {
        struct callchain_node *new;
 
        new = create_child(parent, false);
-       fill_node(new, chain, start, syms);
+       fill_node(new, chain, start);
 
        new->children_hit = 0;
        new->hit = 1;
@@ -228,9 +246,8 @@ add_child(struct callchain_node *parent, struct ip_callchain *chain,
  * Then create another child to host the given callchain of new branch
  */
 static void
-split_add_child(struct callchain_node *parent, struct ip_callchain *chain,
-               struct callchain_list *to_split, int idx_parents, int idx_local,
-               struct symbol **syms)
+split_add_child(struct callchain_node *parent, struct resolved_chain *chain,
+               struct callchain_list *to_split, int idx_parents, int idx_local)
 {
        struct callchain_node *new;
        struct list_head *old_tail;
@@ -257,7 +274,7 @@ split_add_child(struct callchain_node *parent, struct ip_callchain *chain,
        /* create a new child for the new branch if any */
        if (idx_total < chain->nr) {
                parent->hit = 0;
-               add_child(parent, chain, idx_total, syms);
+               add_child(parent, chain, idx_total);
                parent->children_hit++;
        } else {
                parent->hit = 1;
@@ -265,32 +282,33 @@ split_add_child(struct callchain_node *parent, struct ip_callchain *chain,
 }
 
 static int
-__append_chain(struct callchain_node *root, struct ip_callchain *chain,
-              unsigned int start, struct symbol **syms);
+__append_chain(struct callchain_node *root, struct resolved_chain *chain,
+              unsigned int start);
 
 static void
-__append_chain_children(struct callchain_node *root, struct ip_callchain *chain,
-                       struct symbol **syms, unsigned int start)
+__append_chain_children(struct callchain_node *root,
+                       struct resolved_chain *chain,
+                       unsigned int start)
 {
        struct callchain_node *rnode;
 
        /* lookup in childrens */
        chain_for_each_child(rnode, root) {
-               unsigned int ret = __append_chain(rnode, chain, start, syms);
+               unsigned int ret = __append_chain(rnode, chain, start);
 
                if (!ret)
                        goto inc_children_hit;
        }
        /* nothing in children, add to the current node */
-       add_child(root, chain, start, syms);
+       add_child(root, chain, start);
 
 inc_children_hit:
        root->children_hit++;
 }
 
 static int
-__append_chain(struct callchain_node *root, struct ip_callchain *chain,
-              unsigned int start, struct symbol **syms)
+__append_chain(struct callchain_node *root, struct resolved_chain *chain,
+              unsigned int start)
 {
        struct callchain_list *cnode;
        unsigned int i = start;
@@ -302,13 +320,19 @@ __append_chain(struct callchain_node *root, struct ip_callchain *chain,
         * anywhere inside a function.
         */
        list_for_each_entry(cnode, &root->val, list) {
+               struct symbol *sym;
+
                if (i == chain->nr)
                        break;
-               if (cnode->sym && syms[i]) {
-                       if (cnode->sym->start != syms[i]->start)
+
+               sym = chain->ips[i].ms.sym;
+
+               if (cnode->ms.sym && sym) {
+                       if (cnode->ms.sym->start != sym->start)
                                break;
-               } else if (cnode->ip != chain->ips[i])
+               } else if (cnode->ip != chain->ips[i].ip)
                        break;
+
                if (!found)
                        found = true;
                i++;
@@ -320,7 +344,7 @@ __append_chain(struct callchain_node *root, struct ip_callchain *chain,
 
        /* we match only a part of the node. Split it and add the new chain */
        if (i - start < root->val_nr) {
-               split_add_child(root, chain, cnode, start, i - start, syms);
+               split_add_child(root, chain, cnode, start, i - start);
                return 0;
        }
 
@@ -331,15 +355,50 @@ __append_chain(struct callchain_node *root, struct ip_callchain *chain,
        }
 
        /* We match the node and still have a part remaining */
-       __append_chain_children(root, chain, syms, i);
+       __append_chain_children(root, chain, i);
 
        return 0;
 }
 
-void append_chain(struct callchain_node *root, struct ip_callchain *chain,
-                 struct symbol **syms)
+static void filter_context(struct ip_callchain *old, struct resolved_chain *new,
+                          struct map_symbol *syms)
 {
+       int i, j = 0;
+
+       for (i = 0; i < (int)old->nr; i++) {
+               if (old->ips[i] >= PERF_CONTEXT_MAX)
+                       continue;
+
+               new->ips[j].ip = old->ips[i];
+               new->ips[j].ms = syms[i];
+               j++;
+       }
+
+       new->nr = j;
+}
+
+
+int append_chain(struct callchain_node *root, struct ip_callchain *chain,
+                struct map_symbol *syms)
+{
+       struct resolved_chain *filtered;
+
        if (!chain->nr)
-               return;
-       __append_chain_children(root, chain, syms, 0);
+               return 0;
+
+       filtered = zalloc(sizeof(*filtered) +
+                         chain->nr * sizeof(struct resolved_ip));
+       if (!filtered)
+               return -ENOMEM;
+
+       filter_context(chain, filtered, syms);
+
+       if (!filtered->nr)
+               goto end;
+
+       __append_chain_children(root, filtered, 0);
+end:
+       free(filtered);
+
+       return 0;
 }
index ad4626de4c2b9cfa8deb5c5b49b42c644a95a761..1cba1f5504e71ed7747e0263072503643983b1f7 100644 (file)
@@ -4,6 +4,7 @@
 #include "../perf.h"
 #include <linux/list.h>
 #include <linux/rbtree.h>
+#include "event.h"
 #include "util.h"
 #include "symbol.h"
 
@@ -33,13 +34,14 @@ typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_node *,
 
 struct callchain_param {
        enum chain_mode         mode;
+       u32                     print_limit;
        double                  min_percent;
        sort_chain_func_t       sort;
 };
 
 struct callchain_list {
        u64                     ip;
-       struct symbol           *sym;
+       struct map_symbol       ms;
        struct list_head        list;
 };
 
@@ -56,6 +58,8 @@ 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);
+int append_chain(struct callchain_node *root, struct ip_callchain *chain,
+                struct map_symbol *syms);
+
+bool ip_callchain__valid(struct ip_callchain *chain, event_t *event);
 #endif /* __PERF_CALLCHAIN_H */
index e88bca55a5993c82212c6307d35bab9824d9358f..e191eb9a667f601f7dc52872e8e0258ae39af119 100644 (file)
@@ -166,6 +166,31 @@ int perf_color_default_config(const char *var, const char *value, void *cb)
        return perf_default_config(var, value, cb);
 }
 
+static int __color_vsnprintf(char *bf, size_t size, const char *color,
+                            const char *fmt, va_list args, const char *trail)
+{
+       int r = 0;
+
+       /*
+        * Auto-detect:
+        */
+       if (perf_use_color_default < 0) {
+               if (isatty(1) || pager_in_use())
+                       perf_use_color_default = 1;
+               else
+                       perf_use_color_default = 0;
+       }
+
+       if (perf_use_color_default && *color)
+               r += snprintf(bf, size, "%s", color);
+       r += vsnprintf(bf + r, size - r, fmt, args);
+       if (perf_use_color_default && *color)
+               r += snprintf(bf + r, size - r, "%s", PERF_COLOR_RESET);
+       if (trail)
+               r += snprintf(bf + r, size - r, "%s", trail);
+       return r;
+}
+
 static int __color_vfprintf(FILE *fp, const char *color, const char *fmt,
                va_list args, const char *trail)
 {
@@ -191,11 +216,28 @@ static int __color_vfprintf(FILE *fp, const char *color, const char *fmt,
        return r;
 }
 
+int color_vsnprintf(char *bf, size_t size, const char *color,
+                   const char *fmt, va_list args)
+{
+       return __color_vsnprintf(bf, size, color, fmt, args, NULL);
+}
+
 int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args)
 {
        return __color_vfprintf(fp, color, fmt, args, NULL);
 }
 
+int color_snprintf(char *bf, size_t size, const char *color,
+                  const char *fmt, ...)
+{
+       va_list args;
+       int r;
+
+       va_start(args, fmt);
+       r = color_vsnprintf(bf, size, color, fmt, args);
+       va_end(args);
+       return r;
+}
 
 int color_fprintf(FILE *fp, const char *color, const char *fmt, ...)
 {
@@ -274,3 +316,9 @@ int percent_color_fprintf(FILE *fp, const char *fmt, double percent)
 
        return r;
 }
+
+int percent_color_snprintf(char *bf, size_t size, const char *fmt, double percent)
+{
+       const char *color = get_percent_color(percent);
+       return color_snprintf(bf, size, color, fmt, percent);
+}
index 24e8809210bbbc8af8e46c8f137b6e1032d199d7..dea082b7960210a17ccd2ee12d71a61a6192a503 100644 (file)
@@ -32,10 +32,14 @@ int perf_color_default_config(const char *var, const char *value, void *cb);
 int perf_config_colorbool(const char *var, const char *value, int stdout_is_tty);
 void color_parse(const char *value, const char *var, char *dst);
 void color_parse_mem(const char *value, int len, const char *var, char *dst);
+int color_vsnprintf(char *bf, size_t size, const char *color,
+                   const char *fmt, va_list args);
 int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args);
 int color_fprintf(FILE *fp, const char *color, const char *fmt, ...);
+int color_snprintf(char *bf, size_t size, const char *color, const char *fmt, ...);
 int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...);
 int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf);
+int percent_color_snprintf(char *bf, size_t size, const char *fmt, double percent);
 int percent_color_fprintf(FILE *fp, const char *fmt, double percent);
 const char *get_percent_color(double percent);
 
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
new file mode 100644 (file)
index 0000000..4e01490
--- /dev/null
@@ -0,0 +1,59 @@
+#include "util.h"
+#include "../perf.h"
+#include "cpumap.h"
+#include <assert.h>
+#include <stdio.h>
+
+int cpumap[MAX_NR_CPUS];
+
+static int default_cpu_map(void)
+{
+       int nr_cpus, i;
+
+       nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+       assert(nr_cpus <= MAX_NR_CPUS);
+       assert((int)nr_cpus >= 0);
+
+       for (i = 0; i < nr_cpus; ++i)
+               cpumap[i] = i;
+
+       return nr_cpus;
+}
+
+int read_cpu_map(void)
+{
+       FILE *onlnf;
+       int nr_cpus = 0;
+       int n, cpu, prev;
+       char sep;
+
+       onlnf = fopen("/sys/devices/system/cpu/online", "r");
+       if (!onlnf)
+               return default_cpu_map();
+
+       sep = 0;
+       prev = -1;
+       for (;;) {
+               n = fscanf(onlnf, "%u%c", &cpu, &sep);
+               if (n <= 0)
+                       break;
+               if (prev >= 0) {
+                       assert(nr_cpus + cpu - prev - 1 < MAX_NR_CPUS);
+                       while (++prev < cpu)
+                               cpumap[nr_cpus++] = prev;
+               }
+               assert (nr_cpus < MAX_NR_CPUS);
+               cpumap[nr_cpus++] = cpu;
+               if (n == 2 && sep == '-')
+                       prev = cpu;
+               else
+                       prev = -1;
+               if (n == 1 || sep == '\n')
+                       break;
+       }
+       fclose(onlnf);
+       if (nr_cpus > 0)
+               return nr_cpus;
+
+       return default_cpu_map();
+}
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
new file mode 100644 (file)
index 0000000..86c78bb
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __PERF_CPUMAP_H
+#define __PERF_CPUMAP_H
+
+extern int read_cpu_map(void);
+extern int cpumap[];
+
+#endif /* __PERF_CPUMAP_H */
index 0905600c3851b51ec6b52f716e33f797c1da1032..dd824cf3b6282d620784f234eb58bbcdda643667 100644 (file)
@@ -6,13 +6,14 @@
 #include <stdarg.h>
 #include <stdio.h>
 
+#include "cache.h"
 #include "color.h"
 #include "event.h"
 #include "debug.h"
 #include "util.h"
 
 int verbose = 0;
-int dump_trace = 0;
+bool dump_trace = false;
 
 int eprintf(int level, const char *fmt, ...)
 {
@@ -21,7 +22,10 @@ int eprintf(int level, const char *fmt, ...)
 
        if (verbose >= level) {
                va_start(args, fmt);
-               ret = vfprintf(stderr, fmt, args);
+               if (use_browser)
+                       ret = browser__show_help(fmt, args);
+               else
+                       ret = vfprintf(stderr, fmt, args);
                va_end(args);
        }
 
index c6c24c522deaf0cbbef6af3ffd95de706525412d..047ac3324ebe0948aefddac341f6994f1f896cce 100644 (file)
@@ -2,14 +2,38 @@
 #ifndef __PERF_DEBUG_H
 #define __PERF_DEBUG_H
 
+#include <stdbool.h>
 #include "event.h"
 
 extern int verbose;
-extern int dump_trace;
+extern bool dump_trace;
 
-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);
 
+struct ui_progress;
+
+#ifdef NO_NEWT_SUPPORT
+static inline int browser__show_help(const char *format __used, va_list ap __used)
+{
+       return 0;
+}
+
+static inline struct ui_progress *ui_progress__new(const char *title __used,
+                                                  u64 total __used)
+{
+       return (struct ui_progress *)1;
+}
+
+static inline void ui_progress__update(struct ui_progress *self __used,
+                                      u64 curr __used) {}
+
+static inline void ui_progress__delete(struct ui_progress *self __used) {}
+#else
+int browser__show_help(const char *format, va_list ap);
+struct ui_progress *ui_progress__new(const char *title, u64 total);
+void ui_progress__update(struct ui_progress *self, u64 curr);
+void ui_progress__delete(struct ui_progress *self);
+#endif
+
 #endif /* __PERF_DEBUG_H */
index 705ec63548b4e66d6502eecf7b3a24a38ec81f8c..50771b5813ee6e15a6843a232b108415f77a4a29 100644 (file)
@@ -7,6 +7,23 @@
 #include "strlist.h"
 #include "thread.h"
 
+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",
+       [PERF_RECORD_HEADER_ATTR]        = "ATTR",
+       [PERF_RECORD_HEADER_EVENT_TYPE]  = "EVENT_TYPE",
+       [PERF_RECORD_HEADER_TRACING_DATA]        = "TRACING_DATA",
+       [PERF_RECORD_HEADER_BUILD_ID]    = "BUILD_ID",
+};
+
 static pid_t event__synthesize_comm(pid_t pid, int full,
                                    event__handler_t process,
                                    struct perf_session *session)
@@ -112,7 +129,11 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
                event_t ev = {
                        .header = {
                                .type = PERF_RECORD_MMAP,
-                               .misc = 0, /* Just like the kernel, see kernel/perf_event.c __perf_event_mmap */
+                               /*
+                                * Just like the kernel, see __perf_event_mmap
+                                * in kernel/perf_event.c
+                                */
+                               .misc = PERF_RECORD_MISC_USER,
                         },
                };
                int n;
@@ -130,6 +151,7 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
                        continue;
                pbf += n + 3;
                if (*pbf == 'x') { /* vm_exec */
+                       u64 vm_pgoff;
                        char *execname = strchr(bf, '/');
 
                        /* Catch VDSO */
@@ -139,6 +161,14 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
                        if (execname == NULL)
                                continue;
 
+                       pbf += 3;
+                       n = hex2u64(pbf, &vm_pgoff);
+                       /* pgoff is in bytes, not pages */
+                       if (n >= 0)
+                               ev.mmap.pgoff = vm_pgoff << getpagesize();
+                       else
+                               ev.mmap.pgoff = 0;
+
                        size = strlen(execname);
                        execname[size - 1] = '\0'; /* Remove \n */
                        memcpy(ev.mmap.filename, execname, size);
@@ -158,11 +188,23 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
 }
 
 int event__synthesize_modules(event__handler_t process,
-                             struct perf_session *session)
+                             struct perf_session *session,
+                             struct machine *machine)
 {
        struct rb_node *nd;
+       struct map_groups *kmaps = &machine->kmaps;
+       u16 misc;
+
+       /*
+        * kernel uses 0 for user space maps, see kernel/perf_event.c
+        * __perf_event_mmap
+        */
+       if (machine__is_host(machine))
+               misc = PERF_RECORD_MISC_KERNEL;
+       else
+               misc = PERF_RECORD_MISC_GUEST_KERNEL;
 
-       for (nd = rb_first(&session->kmaps.maps[MAP__FUNCTION]);
+       for (nd = rb_first(&kmaps->maps[MAP__FUNCTION]);
             nd; nd = rb_next(nd)) {
                event_t ev;
                size_t size;
@@ -173,12 +215,13 @@ int event__synthesize_modules(event__handler_t process,
 
                size = ALIGN(pos->dso->long_name_len + 1, sizeof(u64));
                memset(&ev, 0, sizeof(ev));
-               ev.mmap.header.misc = 1; /* kernel uses 0 for user space maps, see kernel/perf_event.c __perf_event_mmap */
+               ev.mmap.header.misc = misc;
                ev.mmap.header.type = PERF_RECORD_MMAP;
                ev.mmap.header.size = (sizeof(ev.mmap) -
                                        (sizeof(ev.mmap.filename) - size));
                ev.mmap.start = pos->start;
                ev.mmap.len   = pos->end - pos->start;
+               ev.mmap.pid   = machine->pid;
 
                memcpy(ev.mmap.filename, pos->dso->long_name,
                       pos->dso->long_name_len + 1);
@@ -241,13 +284,18 @@ static int find_symbol_cb(void *arg, const char *name, char type, u64 start)
 
 int event__synthesize_kernel_mmap(event__handler_t process,
                                  struct perf_session *session,
+                                 struct machine *machine,
                                  const char *symbol_name)
 {
        size_t size;
+       const char *filename, *mmap_name;
+       char path[PATH_MAX];
+       char name_buff[PATH_MAX];
+       struct map *map;
+
        event_t ev = {
                .header = {
                        .type = PERF_RECORD_MMAP,
-                       .misc = 1, /* kernel uses 0 for user space maps, see kernel/perf_event.c __perf_event_mmap */
                },
        };
        /*
@@ -257,16 +305,37 @@ int event__synthesize_kernel_mmap(event__handler_t process,
         */
        struct process_symbol_args args = { .name = symbol_name, };
 
-       if (kallsyms__parse("/proc/kallsyms", &args, find_symbol_cb) <= 0)
+       mmap_name = machine__mmap_name(machine, name_buff, sizeof(name_buff));
+       if (machine__is_host(machine)) {
+               /*
+                * kernel uses PERF_RECORD_MISC_USER for user space maps,
+                * see kernel/perf_event.c __perf_event_mmap
+                */
+               ev.header.misc = PERF_RECORD_MISC_KERNEL;
+               filename = "/proc/kallsyms";
+       } else {
+               ev.header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
+               if (machine__is_default_guest(machine))
+                       filename = (char *) symbol_conf.default_guest_kallsyms;
+               else {
+                       sprintf(path, "%s/proc/kallsyms", machine->root_dir);
+                       filename = path;
+               }
+       }
+
+       if (kallsyms__parse(filename, &args, find_symbol_cb) <= 0)
                return -ENOENT;
 
+       map = machine->vmlinux_maps[MAP__FUNCTION];
        size = snprintf(ev.mmap.filename, sizeof(ev.mmap.filename),
-                       "[kernel.kallsyms.%s]", symbol_name) + 1;
+                       "%s%s", mmap_name, symbol_name) + 1;
        size = ALIGN(size, sizeof(u64));
-       ev.mmap.header.size = (sizeof(ev.mmap) - (sizeof(ev.mmap.filename) - size));
+       ev.mmap.header.size = (sizeof(ev.mmap) -
+                       (sizeof(ev.mmap.filename) - size));
        ev.mmap.pgoff = args.start;
-       ev.mmap.start = session->vmlinux_maps[MAP__FUNCTION]->start;
-       ev.mmap.len   = session->vmlinux_maps[MAP__FUNCTION]->end - ev.mmap.start ;
+       ev.mmap.start = map->start;
+       ev.mmap.len   = map->end - ev.mmap.start;
+       ev.mmap.pid   = machine->pid;
 
        return process(&ev, session);
 }
@@ -316,26 +385,54 @@ int event__process_comm(event_t *self, struct perf_session *session)
 int event__process_lost(event_t *self, struct perf_session *session)
 {
        dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost);
-       session->events_stats.lost += self->lost.lost;
+       session->hists.stats.total_lost += self->lost.lost;
        return 0;
 }
 
-int event__process_mmap(event_t *self, struct perf_session *session)
+static void event_set_kernel_mmap_len(struct map **maps, event_t *self)
+{
+       maps[MAP__FUNCTION]->start = self->mmap.start;
+       maps[MAP__FUNCTION]->end   = self->mmap.start + self->mmap.len;
+       /*
+        * Be a bit paranoid here, some perf.data file came with
+        * a zero sized synthesized MMAP event for the kernel.
+        */
+       if (maps[MAP__FUNCTION]->end == 0)
+               maps[MAP__FUNCTION]->end = ~0UL;
+}
+
+static int event__process_kernel_mmap(event_t *self,
+                       struct perf_session *session)
 {
-       struct thread *thread;
        struct map *map;
+       char kmmap_prefix[PATH_MAX];
+       struct machine *machine;
+       enum dso_kernel_type kernel_type;
+       bool is_kernel_mmap;
+
+       machine = perf_session__findnew_machine(session, self->mmap.pid);
+       if (!machine) {
+               pr_err("Can't find id %d's machine\n", self->mmap.pid);
+               goto out_problem;
+       }
 
-       dump_printf(" %d/%d: [%#Lx(%#Lx) @ %#Lx]: %s\n",
-                   self->mmap.pid, self->mmap.tid, self->mmap.start,
-                   self->mmap.len, self->mmap.pgoff, self->mmap.filename);
+       machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix));
+       if (machine__is_host(machine))
+               kernel_type = DSO_TYPE_KERNEL;
+       else
+               kernel_type = DSO_TYPE_GUEST_KERNEL;
 
-       if (self->mmap.pid == 0) {
-               static const char kmmap_prefix[] = "[kernel.kallsyms.";
+       is_kernel_mmap = memcmp(self->mmap.filename,
+                               kmmap_prefix,
+                               strlen(kmmap_prefix)) == 0;
+       if (self->mmap.filename[0] == '/' ||
+           (!is_kernel_mmap && self->mmap.filename[0] == '[')) {
 
-               if (self->mmap.filename[0] == '/') {
-                       char short_module_name[1024];
-                       char *name = strrchr(self->mmap.filename, '/'), *dot;
+               char short_module_name[1024];
+               char *name, *dot;
 
+               if (self->mmap.filename[0] == '/') {
+                       name = strrchr(self->mmap.filename, '/');
                        if (name == NULL)
                                goto out_problem;
 
@@ -343,58 +440,84 @@ int event__process_mmap(event_t *self, struct perf_session *session)
                        dot = strrchr(name, '.');
                        if (dot == NULL)
                                goto out_problem;
-
                        snprintf(short_module_name, sizeof(short_module_name),
-                                "[%.*s]", (int)(dot - name), name);
+                                       "[%.*s]", (int)(dot - name), name);
                        strxfrchar(short_module_name, '-', '_');
-
-                       map = perf_session__new_module_map(session,
-                                                          self->mmap.start,
-                                                          self->mmap.filename);
-                       if (map == NULL)
-                               goto out_problem;
-
-                       name = strdup(short_module_name);
-                       if (name == NULL)
-                               goto out_problem;
-
-                       map->dso->short_name = name;
-                       map->end = map->start + self->mmap.len;
-               } else if (memcmp(self->mmap.filename, kmmap_prefix,
-                               sizeof(kmmap_prefix) - 1) == 0) {
-                       const char *symbol_name = (self->mmap.filename +
-                                                  sizeof(kmmap_prefix) - 1);
+               } else
+                       strcpy(short_module_name, self->mmap.filename);
+
+               map = machine__new_module(machine, self->mmap.start,
+                                         self->mmap.filename);
+               if (map == NULL)
+                       goto out_problem;
+
+               name = strdup(short_module_name);
+               if (name == NULL)
+                       goto out_problem;
+
+               map->dso->short_name = name;
+               map->end = map->start + self->mmap.len;
+       } else if (is_kernel_mmap) {
+               const char *symbol_name = (self->mmap.filename +
+                               strlen(kmmap_prefix));
+               /*
+                * Should be there already, from the build-id table in
+                * the header.
+                */
+               struct dso *kernel = __dsos__findnew(&machine->kernel_dsos,
+                                                    kmmap_prefix);
+               if (kernel == NULL)
+                       goto out_problem;
+
+               kernel->kernel = kernel_type;
+               if (__machine__create_kernel_maps(machine, kernel) < 0)
+                       goto out_problem;
+
+               event_set_kernel_mmap_len(machine->vmlinux_maps, self);
+               perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps,
+                                                        symbol_name,
+                                                        self->mmap.pgoff);
+               if (machine__is_default_guest(machine)) {
                        /*
-                        * Should be there already, from the build-id table in
-                        * the header.
+                        * preload dso of guest kernel and modules
                         */
-                       struct dso *kernel = __dsos__findnew(&dsos__kernel,
-                                                            "[kernel.kallsyms]");
-                       if (kernel == NULL)
-                               goto out_problem;
-
-                       kernel->kernel = 1;
-                       if (__perf_session__create_kernel_maps(session, kernel) < 0)
-                               goto out_problem;
+                       dso__load(kernel, machine->vmlinux_maps[MAP__FUNCTION],
+                                 NULL);
+               }
+       }
+       return 0;
+out_problem:
+       return -1;
+}
 
-                       session->vmlinux_maps[MAP__FUNCTION]->start = self->mmap.start;
-                       session->vmlinux_maps[MAP__FUNCTION]->end   = self->mmap.start + self->mmap.len;
-                       /*
-                        * Be a bit paranoid here, some perf.data file came with
-                        * a zero sized synthesized MMAP event for the kernel.
-                        */
-                       if (session->vmlinux_maps[MAP__FUNCTION]->end == 0)
-                               session->vmlinux_maps[MAP__FUNCTION]->end = ~0UL;
+int event__process_mmap(event_t *self, struct perf_session *session)
+{
+       struct machine *machine;
+       struct thread *thread;
+       struct map *map;
+       u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+       int ret = 0;
 
-                       perf_session__set_kallsyms_ref_reloc_sym(session, symbol_name,
-                                                                self->mmap.pgoff);
-               }
+       dump_printf(" %d/%d: [%#Lx(%#Lx) @ %#Lx]: %s\n",
+                       self->mmap.pid, self->mmap.tid, self->mmap.start,
+                       self->mmap.len, self->mmap.pgoff, self->mmap.filename);
+
+       if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL ||
+           cpumode == PERF_RECORD_MISC_KERNEL) {
+               ret = event__process_kernel_mmap(self, session);
+               if (ret < 0)
+                       goto out_problem;
                return 0;
        }
 
+       machine = perf_session__find_host_machine(session);
+       if (machine == NULL)
+               goto out_problem;
        thread = perf_session__findnew(session, self->mmap.pid);
-       map = map__new(&self->mmap, MAP__FUNCTION,
-                      session->cwd, session->cwdlen);
+       map = map__new(&machine->user_dsos, self->mmap.start,
+                       self->mmap.len, self->mmap.pgoff,
+                       self->mmap.pid, self->mmap.filename,
+                       MAP__FUNCTION, session->cwd, session->cwdlen);
 
        if (thread == NULL || map == NULL)
                goto out_problem;
@@ -434,22 +557,56 @@ int event__process_task(event_t *self, struct perf_session *session)
 
 void thread__find_addr_map(struct thread *self,
                           struct perf_session *session, u8 cpumode,
-                          enum map_type type, u64 addr,
+                          enum map_type type, pid_t pid, u64 addr,
                           struct addr_location *al)
 {
        struct map_groups *mg = &self->mg;
+       struct machine *machine = NULL;
 
        al->thread = self;
        al->addr = addr;
+       al->cpumode = cpumode;
+       al->filtered = false;
 
-       if (cpumode == PERF_RECORD_MISC_KERNEL) {
+       if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) {
                al->level = 'k';
-               mg = &session->kmaps;
-       } else if (cpumode == PERF_RECORD_MISC_USER)
+               machine = perf_session__find_host_machine(session);
+               if (machine == NULL) {
+                       al->map = NULL;
+                       return;
+               }
+               mg = &machine->kmaps;
+       } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) {
                al->level = '.';
-       else {
-               al->level = 'H';
+               machine = perf_session__find_host_machine(session);
+       } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) {
+               al->level = 'g';
+               machine = perf_session__find_machine(session, pid);
+               if (machine == NULL) {
+                       al->map = NULL;
+                       return;
+               }
+               mg = &machine->kmaps;
+       } else {
+               /*
+                * 'u' means guest os user space.
+                * TODO: We don't support guest user space. Might support late.
+                */
+               if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest)
+                       al->level = 'u';
+               else
+                       al->level = 'H';
                al->map = NULL;
+
+               if ((cpumode == PERF_RECORD_MISC_GUEST_USER ||
+                       cpumode == PERF_RECORD_MISC_GUEST_KERNEL) &&
+                       !perf_guest)
+                       al->filtered = true;
+               if ((cpumode == PERF_RECORD_MISC_USER ||
+                       cpumode == PERF_RECORD_MISC_KERNEL) &&
+                       !perf_host)
+                       al->filtered = true;
+
                return;
        }
 try_again:
@@ -464,8 +621,10 @@ try_again:
                 * "[vdso]" dso, but for now lets use the old trick of looking
                 * in the whole kernel symbol list.
                 */
-               if ((long long)al->addr < 0 && mg != &session->kmaps) {
-                       mg = &session->kmaps;
+               if ((long long)al->addr < 0 &&
+                   cpumode == PERF_RECORD_MISC_KERNEL &&
+                   machine && mg != &machine->kmaps) {
+                       mg = &machine->kmaps;
                        goto try_again;
                }
        } else
@@ -474,11 +633,11 @@ try_again:
 
 void thread__find_addr_location(struct thread *self,
                                struct perf_session *session, u8 cpumode,
-                               enum map_type type, u64 addr,
+                               enum map_type type, pid_t pid, u64 addr,
                                struct addr_location *al,
                                symbol_filter_t filter)
 {
-       thread__find_addr_map(self, session, cpumode, type, addr, al);
+       thread__find_addr_map(self, session, cpumode, type, pid, addr, al);
        if (al->map != NULL)
                al->sym = map__find_symbol(al->map, al->addr, filter);
        else
@@ -490,8 +649,10 @@ static void dso__calc_col_width(struct dso *self)
        if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
            (!symbol_conf.dso_list ||
             strlist__has_entry(symbol_conf.dso_list, self->name))) {
-               unsigned int slen = strlen(self->name);
-               if (slen > dsos__col_width)
+               u16 slen = self->short_name_len;
+               if (verbose)
+                       slen = self->long_name_len;
+               if (dsos__col_width < slen)
                        dsos__col_width = slen;
        }
 
@@ -512,31 +673,55 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
                goto out_filtered;
 
        dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
+       /*
+        * Have we already created the kernel maps for the host machine?
+        *
+        * This should have happened earlier, when we processed the kernel MMAP
+        * events, but for older perf.data files there was no such thing, so do
+        * it now.
+        */
+       if (cpumode == PERF_RECORD_MISC_KERNEL &&
+           session->host_machine.vmlinux_maps[MAP__FUNCTION] == NULL)
+               machine__create_kernel_maps(&session->host_machine);
 
-       thread__find_addr_location(thread, session, cpumode, MAP__FUNCTION,
-                                  self->ip.ip, al, filter);
+       thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
+                             self->ip.pid, self->ip.ip, al);
        dump_printf(" ...... dso: %s\n",
                    al->map ? al->map->dso->long_name :
                        al->level == 'H' ? "[hypervisor]" : "<not found>");
-       /*
-        * 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 (symbol_conf.dso_list &&
-           (!al->map || !al->map->dso ||
-            !(strlist__has_entry(symbol_conf.dso_list, al->map->dso->short_name) ||
-              (al->map->dso->short_name != al->map->dso->long_name &&
-               strlist__has_entry(symbol_conf.dso_list, al->map->dso->long_name)))))
-               goto out_filtered;
+       al->sym = NULL;
+
+       if (al->map) {
+               if (symbol_conf.dso_list &&
+                   (!al->map || !al->map->dso ||
+                    !(strlist__has_entry(symbol_conf.dso_list,
+                                         al->map->dso->short_name) ||
+                      (al->map->dso->short_name != al->map->dso->long_name &&
+                       strlist__has_entry(symbol_conf.dso_list,
+                                          al->map->dso->long_name)))))
+                       goto out_filtered;
+               /*
+                * 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 && !al->map->dso->slen_calculated)
+                       dso__calc_col_width(al->map->dso);
+
+               al->sym = map__find_symbol(al->map, al->addr, filter);
+       } else {
+               const unsigned int unresolved_col_width = BITS_PER_LONG / 4;
+
+               if (dsos__col_width < unresolved_col_width &&
+                   !symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
+                   !symbol_conf.dso_list)
+                       dsos__col_width = unresolved_col_width;
+       }
 
        if (symbol_conf.sym_list && al->sym &&
            !strlist__has_entry(symbol_conf.sym_list, al->sym->name))
                goto out_filtered;
 
-       al->filtered = false;
        return 0;
 
 out_filtered:
@@ -570,6 +755,7 @@ int event__parse_sample(event_t *event, u64 type, struct sample_data *data)
                array++;
        }
 
+       data->id = -1ULL;
        if (type & PERF_SAMPLE_ID) {
                data->id = *array;
                array++;
index 50a7132887f57eab20c6e57b70fb1258cd8f259b..8577085db067bb3d7b6a7530fab877b3e28afe96 100644 (file)
@@ -68,21 +68,54 @@ struct sample_data {
        u64 addr;
        u64 id;
        u64 stream_id;
-       u32 cpu;
        u64 period;
-       struct ip_callchain *callchain;
+       u32 cpu;
        u32 raw_size;
        void *raw_data;
+       struct ip_callchain *callchain;
 };
 
 #define BUILD_ID_SIZE 20
 
 struct build_id_event {
        struct perf_event_header header;
+       pid_t                    pid;
        u8                       build_id[ALIGN(BUILD_ID_SIZE, sizeof(u64))];
        char                     filename[];
 };
 
+enum perf_user_event_type { /* above any possible kernel type */
+       PERF_RECORD_HEADER_ATTR                 = 64,
+       PERF_RECORD_HEADER_EVENT_TYPE           = 65,
+       PERF_RECORD_HEADER_TRACING_DATA         = 66,
+       PERF_RECORD_HEADER_BUILD_ID             = 67,
+       PERF_RECORD_FINISHED_ROUND              = 68,
+       PERF_RECORD_HEADER_MAX
+};
+
+struct attr_event {
+       struct perf_event_header header;
+       struct perf_event_attr attr;
+       u64 id[];
+};
+
+#define MAX_EVENT_NAME 64
+
+struct perf_trace_event_type {
+       u64     event_id;
+       char    name[MAX_EVENT_NAME];
+};
+
+struct event_type_event {
+       struct perf_event_header header;
+       struct perf_trace_event_type event_type;
+};
+
+struct tracing_data_event {
+       struct perf_event_header header;
+       u32 size;
+};
+
 typedef union event_union {
        struct perf_event_header        header;
        struct ip_event                 ip;
@@ -92,13 +125,12 @@ typedef union event_union {
        struct lost_event               lost;
        struct read_event               read;
        struct sample_event             sample;
+       struct attr_event               attr;
+       struct event_type_event         event_type;
+       struct tracing_data_event       tracing_data;
+       struct build_id_event           build_id;
 } event_t;
 
-struct events_stats {
-       u64 total;
-       u64 lost;
-};
-
 void event__print_totals(void);
 
 struct perf_session;
@@ -110,10 +142,13 @@ int event__synthesize_thread(pid_t pid, event__handler_t process,
 void event__synthesize_threads(event__handler_t process,
                               struct perf_session *session);
 int event__synthesize_kernel_mmap(event__handler_t process,
-                                 struct perf_session *session,
-                                 const char *symbol_name);
+                               struct perf_session *session,
+                               struct machine *machine,
+                               const char *symbol_name);
+
 int event__synthesize_modules(event__handler_t process,
-                             struct perf_session *session);
+                             struct perf_session *session,
+                             struct machine *machine);
 
 int event__process_comm(event_t *self, struct perf_session *session);
 int event__process_lost(event_t *self, struct perf_session *session);
@@ -125,4 +160,6 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
                             struct addr_location *al, symbol_filter_t filter);
 int event__parse_sample(event_t *event, u64 type, struct sample_data *data);
 
+extern const char *event__name[];
+
 #endif /* __PERF_RECORD_H */
index 6c9aa16ee51fce97747cb9c9ea493e717b45b953..8847bec64c54119fc0e006dbd6350b231203dbd9 100644 (file)
@@ -99,13 +99,6 @@ int perf_header__add_attr(struct perf_header *self,
        return 0;
 }
 
-#define MAX_EVENT_NAME 64
-
-struct perf_trace_event_type {
-       u64     event_id;
-       char    name[MAX_EVENT_NAME];
-};
-
 static int event_count;
 static struct perf_trace_event_type *events;
 
@@ -197,7 +190,8 @@ static int write_padded(int fd, const void *bf, size_t count,
                        continue;               \
                else
 
-static int __dsos__write_buildid_table(struct list_head *head, u16 misc, int fd)
+static int __dsos__write_buildid_table(struct list_head *head, pid_t pid,
+                               u16 misc, int fd)
 {
        struct dso *pos;
 
@@ -212,6 +206,7 @@ static int __dsos__write_buildid_table(struct list_head *head, u16 misc, int fd)
                len = ALIGN(len, NAME_ALIGN);
                memset(&b, 0, sizeof(b));
                memcpy(&b.build_id, pos->build_id, sizeof(pos->build_id));
+               b.pid = pid;
                b.header.misc = misc;
                b.header.size = sizeof(b) + len;
                err = do_write(fd, &b, sizeof(b));
@@ -226,13 +221,32 @@ static int __dsos__write_buildid_table(struct list_head *head, u16 misc, int fd)
        return 0;
 }
 
-static int dsos__write_buildid_table(int fd)
+static int dsos__write_buildid_table(struct perf_header *header, int fd)
 {
-       int err = __dsos__write_buildid_table(&dsos__kernel,
-                                             PERF_RECORD_MISC_KERNEL, fd);
-       if (err == 0)
-               err = __dsos__write_buildid_table(&dsos__user,
-                                                 PERF_RECORD_MISC_USER, fd);
+       struct perf_session *session = container_of(header,
+                       struct perf_session, header);
+       struct rb_node *nd;
+       int err = 0;
+       u16 kmisc, umisc;
+
+       for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
+               struct machine *pos = rb_entry(nd, struct machine, rb_node);
+               if (machine__is_host(pos)) {
+                       kmisc = PERF_RECORD_MISC_KERNEL;
+                       umisc = PERF_RECORD_MISC_USER;
+               } else {
+                       kmisc = PERF_RECORD_MISC_GUEST_KERNEL;
+                       umisc = PERF_RECORD_MISC_GUEST_USER;
+               }
+
+               err = __dsos__write_buildid_table(&pos->kernel_dsos, pos->pid,
+                                                 kmisc, fd);
+               if (err == 0)
+                       err = __dsos__write_buildid_table(&pos->user_dsos,
+                                                         pos->pid, umisc, fd);
+               if (err)
+                       break;
+       }
        return err;
 }
 
@@ -349,9 +363,12 @@ static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir)
        return err;
 }
 
-static int dsos__cache_build_ids(void)
+static int dsos__cache_build_ids(struct perf_header *self)
 {
-       int err_kernel, err_user;
+       struct perf_session *session = container_of(self,
+                       struct perf_session, header);
+       struct rb_node *nd;
+       int ret = 0;
        char debugdir[PATH_MAX];
 
        snprintf(debugdir, sizeof(debugdir), "%s/%s", getenv("HOME"),
@@ -360,9 +377,28 @@ static int dsos__cache_build_ids(void)
        if (mkdir(debugdir, 0755) != 0 && errno != EEXIST)
                return -1;
 
-       err_kernel = __dsos__cache_build_ids(&dsos__kernel, debugdir);
-       err_user   = __dsos__cache_build_ids(&dsos__user, debugdir);
-       return err_kernel || err_user ? -1 : 0;
+       for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
+               struct machine *pos = rb_entry(nd, struct machine, rb_node);
+               ret |= __dsos__cache_build_ids(&pos->kernel_dsos, debugdir);
+               ret |= __dsos__cache_build_ids(&pos->user_dsos, debugdir);
+       }
+       return ret ? -1 : 0;
+}
+
+static bool dsos__read_build_ids(struct perf_header *self, bool with_hits)
+{
+       bool ret = false;
+       struct perf_session *session = container_of(self,
+                       struct perf_session, header);
+       struct rb_node *nd;
+
+       for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
+               struct machine *pos = rb_entry(nd, struct machine, rb_node);
+               ret |= __dsos__read_build_ids(&pos->kernel_dsos, with_hits);
+               ret |= __dsos__read_build_ids(&pos->user_dsos, with_hits);
+       }
+
+       return ret;
 }
 
 static int perf_header__adds_write(struct perf_header *self, int fd)
@@ -373,7 +409,7 @@ static int perf_header__adds_write(struct perf_header *self, int fd)
        u64 sec_start;
        int idx = 0, err;
 
-       if (dsos__read_build_ids(true))
+       if (dsos__read_build_ids(self, true))
                perf_header__set_feat(self, HEADER_BUILD_ID);
 
        nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS);
@@ -400,7 +436,6 @@ static int perf_header__adds_write(struct perf_header *self, int fd)
                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;
 
@@ -408,14 +443,14 @@ static int perf_header__adds_write(struct perf_header *self, int fd)
 
                /* Write build-ids */
                buildid_sec->offset = lseek(fd, 0, SEEK_CUR);
-               err = dsos__write_buildid_table(fd);
+               err = dsos__write_buildid_table(self, 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;
-               dsos__cache_build_ids();
+               dsos__cache_build_ids(self);
        }
 
        lseek(fd, sec_start, SEEK_SET);
@@ -427,6 +462,25 @@ out_free:
        return err;
 }
 
+int perf_header__write_pipe(int fd)
+{
+       struct perf_pipe_file_header f_header;
+       int err;
+
+       f_header = (struct perf_pipe_file_header){
+               .magic     = PERF_MAGIC,
+               .size      = sizeof(f_header),
+       };
+
+       err = do_write(fd, &f_header, sizeof(f_header));
+       if (err < 0) {
+               pr_debug("failed to write perf pipe header\n");
+               return err;
+       }
+
+       return 0;
+}
+
 int perf_header__write(struct perf_header *self, int fd, bool at_exit)
 {
        struct perf_file_header f_header;
@@ -518,25 +572,10 @@ int perf_header__write(struct perf_header *self, int fd, bool at_exit)
        return 0;
 }
 
-static int do_read(int fd, void *buf, size_t size)
-{
-       while (size) {
-               int ret = read(fd, buf, size);
-
-               if (ret <= 0)
-                       return -1;
-
-               size -= ret;
-               buf += ret;
-       }
-
-       return 0;
-}
-
 static int perf_header__getbuffer64(struct perf_header *self,
                                    int fd, void *buf, size_t size)
 {
-       if (do_read(fd, buf, size))
+       if (do_read(fd, buf, size) <= 0)
                return -1;
 
        if (self->needs_swap)
@@ -592,7 +631,7 @@ int perf_file_header__read(struct perf_file_header *self,
 {
        lseek(fd, 0, SEEK_SET);
 
-       if (do_read(fd, self, sizeof(*self)) ||
+       if (do_read(fd, self, sizeof(*self)) <= 0 ||
            memcmp(&self->magic, __perf_magic, sizeof(self->magic)))
                return -1;
 
@@ -636,6 +675,93 @@ int perf_file_header__read(struct perf_file_header *self,
        return 0;
 }
 
+static int __event_process_build_id(struct build_id_event *bev,
+                                   char *filename,
+                                   struct perf_session *session)
+{
+       int err = -1;
+       struct list_head *head;
+       struct machine *machine;
+       u16 misc;
+       struct dso *dso;
+       enum dso_kernel_type dso_type;
+
+       machine = perf_session__findnew_machine(session, bev->pid);
+       if (!machine)
+               goto out;
+
+       misc = bev->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+
+       switch (misc) {
+       case PERF_RECORD_MISC_KERNEL:
+               dso_type = DSO_TYPE_KERNEL;
+               head = &machine->kernel_dsos;
+               break;
+       case PERF_RECORD_MISC_GUEST_KERNEL:
+               dso_type = DSO_TYPE_GUEST_KERNEL;
+               head = &machine->kernel_dsos;
+               break;
+       case PERF_RECORD_MISC_USER:
+       case PERF_RECORD_MISC_GUEST_USER:
+               dso_type = DSO_TYPE_USER;
+               head = &machine->user_dsos;
+               break;
+       default:
+               goto out;
+       }
+
+       dso = __dsos__findnew(head, filename);
+       if (dso != NULL) {
+               char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+
+               dso__set_build_id(dso, &bev->build_id);
+
+               if (filename[0] == '[')
+                       dso->kernel = dso_type;
+
+               build_id__sprintf(dso->build_id, sizeof(dso->build_id),
+                                 sbuild_id);
+               pr_debug("build id event received for %s: %s\n",
+                        dso->long_name, sbuild_id);
+       }
+
+       err = 0;
+out:
+       return err;
+}
+
+static int perf_header__read_build_ids(struct perf_header *self,
+                       int input, u64 offset, u64 size)
+{
+       struct perf_session *session = container_of(self,
+                       struct perf_session, header);
+       struct build_id_event bev;
+       char filename[PATH_MAX];
+       u64 limit = offset + size;
+       int err = -1;
+
+       while (offset < limit) {
+               ssize_t len;
+
+               if (read(input, &bev, sizeof(bev)) != sizeof(bev))
+                       goto out;
+
+               if (self->needs_swap)
+                       perf_event_header__bswap(&bev.header);
+
+               len = bev.header.size - sizeof(bev);
+               if (read(input, filename, len) != len)
+                       goto out;
+
+               __event_process_build_id(&bev, filename, session);
+
+               offset += bev.header.size;
+       }
+       err = 0;
+out:
+       return err;
+}
+
 static int perf_file_section__process(struct perf_file_section *self,
                                      struct perf_header *ph,
                                      int feat, int fd)
@@ -648,7 +774,7 @@ static int perf_file_section__process(struct perf_file_section *self,
 
        switch (feat) {
        case HEADER_TRACE_INFO:
-               trace_report(fd);
+               trace_report(fd, false);
                break;
 
        case HEADER_BUILD_ID:
@@ -662,13 +788,56 @@ static int perf_file_section__process(struct perf_file_section *self,
        return 0;
 }
 
-int perf_header__read(struct perf_header *self, int fd)
+static int perf_file_header__read_pipe(struct perf_pipe_file_header *self,
+                                      struct perf_header *ph, int fd,
+                                      bool repipe)
+{
+       if (do_read(fd, self, sizeof(*self)) <= 0 ||
+           memcmp(&self->magic, __perf_magic, sizeof(self->magic)))
+               return -1;
+
+       if (repipe && do_write(STDOUT_FILENO, self, sizeof(*self)) < 0)
+               return -1;
+
+       if (self->size != sizeof(*self)) {
+               u64 size = bswap_64(self->size);
+
+               if (size != sizeof(*self))
+                       return -1;
+
+               ph->needs_swap = true;
+       }
+
+       return 0;
+}
+
+static int perf_header__read_pipe(struct perf_session *session, int fd)
 {
+       struct perf_header *self = &session->header;
+       struct perf_pipe_file_header f_header;
+
+       if (perf_file_header__read_pipe(&f_header, self, fd,
+                                       session->repipe) < 0) {
+               pr_debug("incompatible file format\n");
+               return -EINVAL;
+       }
+
+       session->fd = fd;
+
+       return 0;
+}
+
+int perf_header__read(struct perf_session *session, int fd)
+{
+       struct perf_header *self = &session->header;
        struct perf_file_header f_header;
        struct perf_file_attr   f_attr;
        u64                     f_id;
        int nr_attrs, nr_ids, i, j;
 
+       if (session->fd_pipe)
+               return perf_header__read_pipe(session, fd);
+
        if (perf_file_header__read(&f_header, self, fd) < 0) {
                pr_debug("incompatible file format\n");
                return -EINVAL;
@@ -753,6 +922,14 @@ perf_header__find_attr(u64 id, struct perf_header *header)
 {
        int i;
 
+       /*
+        * We set id to -1 if the data file doesn't contain sample
+        * ids. Check for this and avoid walking through the entire
+        * list of ids which may be large.
+        */
+       if (id == -1ULL)
+               return NULL;
+
        for (i = 0; i < header->attrs; i++) {
                struct perf_header_attr *attr = header->attr[i];
                int j;
@@ -765,3 +942,231 @@ perf_header__find_attr(u64 id, struct perf_header *header)
 
        return NULL;
 }
+
+int event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id,
+                          event__handler_t process,
+                          struct perf_session *session)
+{
+       event_t *ev;
+       size_t size;
+       int err;
+
+       size = sizeof(struct perf_event_attr);
+       size = ALIGN(size, sizeof(u64));
+       size += sizeof(struct perf_event_header);
+       size += ids * sizeof(u64);
+
+       ev = malloc(size);
+
+       ev->attr.attr = *attr;
+       memcpy(ev->attr.id, id, ids * sizeof(u64));
+
+       ev->attr.header.type = PERF_RECORD_HEADER_ATTR;
+       ev->attr.header.size = size;
+
+       err = process(ev, session);
+
+       free(ev);
+
+       return err;
+}
+
+int event__synthesize_attrs(struct perf_header *self,
+                           event__handler_t process,
+                           struct perf_session *session)
+{
+       struct perf_header_attr *attr;
+       int i, err = 0;
+
+       for (i = 0; i < self->attrs; i++) {
+               attr = self->attr[i];
+
+               err = event__synthesize_attr(&attr->attr, attr->ids, attr->id,
+                                            process, session);
+               if (err) {
+                       pr_debug("failed to create perf header attribute\n");
+                       return err;
+               }
+       }
+
+       return err;
+}
+
+int event__process_attr(event_t *self, struct perf_session *session)
+{
+       struct perf_header_attr *attr;
+       unsigned int i, ids, n_ids;
+
+       attr = perf_header_attr__new(&self->attr.attr);
+       if (attr == NULL)
+               return -ENOMEM;
+
+       ids = self->header.size;
+       ids -= (void *)&self->attr.id - (void *)self;
+       n_ids = ids / sizeof(u64);
+
+       for (i = 0; i < n_ids; i++) {
+               if (perf_header_attr__add_id(attr, self->attr.id[i]) < 0) {
+                       perf_header_attr__delete(attr);
+                       return -ENOMEM;
+               }
+       }
+
+       if (perf_header__add_attr(&session->header, attr) < 0) {
+               perf_header_attr__delete(attr);
+               return -ENOMEM;
+       }
+
+       perf_session__update_sample_type(session);
+
+       return 0;
+}
+
+int event__synthesize_event_type(u64 event_id, char *name,
+                                event__handler_t process,
+                                struct perf_session *session)
+{
+       event_t ev;
+       size_t size = 0;
+       int err = 0;
+
+       memset(&ev, 0, sizeof(ev));
+
+       ev.event_type.event_type.event_id = event_id;
+       memset(ev.event_type.event_type.name, 0, MAX_EVENT_NAME);
+       strncpy(ev.event_type.event_type.name, name, MAX_EVENT_NAME - 1);
+
+       ev.event_type.header.type = PERF_RECORD_HEADER_EVENT_TYPE;
+       size = strlen(name);
+       size = ALIGN(size, sizeof(u64));
+       ev.event_type.header.size = sizeof(ev.event_type) -
+               (sizeof(ev.event_type.event_type.name) - size);
+
+       err = process(&ev, session);
+
+       return err;
+}
+
+int event__synthesize_event_types(event__handler_t process,
+                                 struct perf_session *session)
+{
+       struct perf_trace_event_type *type;
+       int i, err = 0;
+
+       for (i = 0; i < event_count; i++) {
+               type = &events[i];
+
+               err = event__synthesize_event_type(type->event_id, type->name,
+                                                  process, session);
+               if (err) {
+                       pr_debug("failed to create perf header event type\n");
+                       return err;
+               }
+       }
+
+       return err;
+}
+
+int event__process_event_type(event_t *self,
+                             struct perf_session *session __unused)
+{
+       if (perf_header__push_event(self->event_type.event_type.event_id,
+                                   self->event_type.event_type.name) < 0)
+               return -ENOMEM;
+
+       return 0;
+}
+
+int event__synthesize_tracing_data(int fd, struct perf_event_attr *pattrs,
+                                  int nb_events,
+                                  event__handler_t process,
+                                  struct perf_session *session __unused)
+{
+       event_t ev;
+       ssize_t size = 0, aligned_size = 0, padding;
+       int err = 0;
+
+       memset(&ev, 0, sizeof(ev));
+
+       ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA;
+       size = read_tracing_data_size(fd, pattrs, nb_events);
+       if (size <= 0)
+               return size;
+       aligned_size = ALIGN(size, sizeof(u64));
+       padding = aligned_size - size;
+       ev.tracing_data.header.size = sizeof(ev.tracing_data);
+       ev.tracing_data.size = aligned_size;
+
+       process(&ev, session);
+
+       err = read_tracing_data(fd, pattrs, nb_events);
+       write_padded(fd, NULL, 0, padding);
+
+       return aligned_size;
+}
+
+int event__process_tracing_data(event_t *self,
+                               struct perf_session *session)
+{
+       ssize_t size_read, padding, size = self->tracing_data.size;
+       off_t offset = lseek(session->fd, 0, SEEK_CUR);
+       char buf[BUFSIZ];
+
+       /* setup for reading amidst mmap */
+       lseek(session->fd, offset + sizeof(struct tracing_data_event),
+             SEEK_SET);
+
+       size_read = trace_report(session->fd, session->repipe);
+
+       padding = ALIGN(size_read, sizeof(u64)) - size_read;
+
+       if (read(session->fd, buf, padding) < 0)
+               die("reading input file");
+       if (session->repipe) {
+               int retw = write(STDOUT_FILENO, buf, padding);
+               if (retw <= 0 || retw != padding)
+                       die("repiping tracing data padding");
+       }
+
+       if (size_read + padding != size)
+               die("tracing data size mismatch");
+
+       return size_read + padding;
+}
+
+int event__synthesize_build_id(struct dso *pos, u16 misc,
+                              event__handler_t process,
+                              struct machine *machine,
+                              struct perf_session *session)
+{
+       event_t ev;
+       size_t len;
+       int err = 0;
+
+       if (!pos->hit)
+               return err;
+
+       memset(&ev, 0, sizeof(ev));
+
+       len = pos->long_name_len + 1;
+       len = ALIGN(len, NAME_ALIGN);
+       memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id));
+       ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID;
+       ev.build_id.header.misc = misc;
+       ev.build_id.pid = machine->pid;
+       ev.build_id.header.size = sizeof(ev.build_id) + len;
+       memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len);
+
+       err = process(&ev, session);
+
+       return err;
+}
+
+int event__process_build_id(event_t *self,
+                           struct perf_session *session)
+{
+       __event_process_build_id(&self->build_id,
+                                self->build_id.filename,
+                                session);
+       return 0;
+}
index 82a6af72d4ccd7d1bac9d80d7e0fd7b2d0751a32..402ac2454cf8bcc664c3daf193119f470c77d7c3 100644 (file)
@@ -39,6 +39,11 @@ struct perf_file_header {
        DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS);
 };
 
+struct perf_pipe_file_header {
+       u64                             magic;
+       u64                             size;
+};
+
 struct perf_header;
 
 int perf_file_header__read(struct perf_file_header *self,
@@ -47,21 +52,22 @@ int perf_file_header__read(struct perf_file_header *self,
 struct perf_header {
        int                     frozen;
        int                     attrs, size;
+       bool                    needs_swap;
        struct perf_header_attr **attr;
        s64                     attr_offset;
        u64                     data_offset;
        u64                     data_size;
        u64                     event_offset;
        u64                     event_size;
-       bool                    needs_swap;
        DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS);
 };
 
 int perf_header__init(struct perf_header *self);
 void perf_header__exit(struct perf_header *self);
 
-int perf_header__read(struct perf_header *self, int fd);
+int perf_header__read(struct perf_session *session, int fd);
 int perf_header__write(struct perf_header *self, int fd, bool at_exit);
+int perf_header__write_pipe(int fd);
 
 int perf_header__add_attr(struct perf_header *self,
                          struct perf_header_attr *attr);
@@ -89,4 +95,33 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
                          const char *name, bool is_kallsyms);
 int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir);
 
+int event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id,
+                          event__handler_t process,
+                          struct perf_session *session);
+int event__synthesize_attrs(struct perf_header *self,
+                           event__handler_t process,
+                           struct perf_session *session);
+int event__process_attr(event_t *self, struct perf_session *session);
+
+int event__synthesize_event_type(u64 event_id, char *name,
+                                event__handler_t process,
+                                struct perf_session *session);
+int event__synthesize_event_types(event__handler_t process,
+                                 struct perf_session *session);
+int event__process_event_type(event_t *self,
+                             struct perf_session *session);
+
+int event__synthesize_tracing_data(int fd, struct perf_event_attr *pattrs,
+                                  int nb_events,
+                                  event__handler_t process,
+                                  struct perf_session *session);
+int event__process_tracing_data(event_t *self,
+                               struct perf_session *session);
+
+int event__synthesize_build_id(struct dso *pos, u16 misc,
+                              event__handler_t process,
+                              struct machine *machine,
+                              struct perf_session *session);
+int event__process_build_id(event_t *self, struct perf_session *session);
+
 #endif /* __PERF_HEADER_H */
index 44408c2621cf356a51d0fe5e6651ee26a75c3eeb..9a71c94f057ab47536070a6b3b386e7f68bf1982 100644 (file)
@@ -1,3 +1,4 @@
+#include "util.h"
 #include "hist.h"
 #include "session.h"
 #include "sort.h"
@@ -8,25 +9,69 @@ struct callchain_param        callchain_param = {
        .min_percent = 0.5
 };
 
+static void hist_entry__add_cpumode_period(struct hist_entry *self,
+                                          unsigned int cpumode, u64 period)
+{
+       switch (cpumode) {
+       case PERF_RECORD_MISC_KERNEL:
+               self->period_sys += period;
+               break;
+       case PERF_RECORD_MISC_USER:
+               self->period_us += period;
+               break;
+       case PERF_RECORD_MISC_GUEST_KERNEL:
+               self->period_guest_sys += period;
+               break;
+       case PERF_RECORD_MISC_GUEST_USER:
+               self->period_guest_us += period;
+               break;
+       default:
+               break;
+       }
+}
+
 /*
- * histogram, sorted on item, collects counts
+ * histogram, sorted on item, collects periods
  */
 
-struct hist_entry *__perf_session__add_hist_entry(struct perf_session *self,
-                                                 struct addr_location *al,
-                                                 struct symbol *sym_parent,
-                                                 u64 count, bool *hit)
+static struct hist_entry *hist_entry__new(struct hist_entry *template)
+{
+       size_t callchain_size = symbol_conf.use_callchain ? sizeof(struct callchain_node) : 0;
+       struct hist_entry *self = malloc(sizeof(*self) + callchain_size);
+
+       if (self != NULL) {
+               *self = *template;
+               self->nr_events = 1;
+               if (symbol_conf.use_callchain)
+                       callchain_init(self->callchain);
+       }
+
+       return self;
+}
+
+static void hists__inc_nr_entries(struct hists *self, struct hist_entry *entry)
 {
-       struct rb_node **p = &self->hists.rb_node;
+       if (entry->ms.sym && self->max_sym_namelen < entry->ms.sym->namelen)
+               self->max_sym_namelen = entry->ms.sym->namelen;
+       ++self->nr_entries;
+}
+
+struct hist_entry *__hists__add_entry(struct hists *self,
+                                     struct addr_location *al,
+                                     struct symbol *sym_parent, u64 period)
+{
+       struct rb_node **p = &self->entries.rb_node;
        struct rb_node *parent = NULL;
        struct hist_entry *he;
        struct hist_entry entry = {
                .thread = al->thread,
-               .map    = al->map,
-               .sym    = al->sym,
+               .ms = {
+                       .map    = al->map,
+                       .sym    = al->sym,
+               },
                .ip     = al->addr,
                .level  = al->level,
-               .count  = count,
+               .period = period,
                .parent = sym_parent,
        };
        int cmp;
@@ -38,8 +83,9 @@ struct hist_entry *__perf_session__add_hist_entry(struct perf_session *self,
                cmp = hist_entry__cmp(&entry, he);
 
                if (!cmp) {
-                       *hit = true;
-                       return he;
+                       he->period += period;
+                       ++he->nr_events;
+                       goto out;
                }
 
                if (cmp < 0)
@@ -48,13 +94,14 @@ struct hist_entry *__perf_session__add_hist_entry(struct perf_session *self,
                        p = &(*p)->rb_right;
        }
 
-       he = malloc(sizeof(*he));
+       he = hist_entry__new(&entry);
        if (!he)
                return NULL;
-       *he = entry;
        rb_link_node(&he->rb_node, parent, p);
-       rb_insert_color(&he->rb_node, &self->hists);
-       *hit = false;
+       rb_insert_color(&he->rb_node, &self->entries);
+       hists__inc_nr_entries(self, he);
+out:
+       hist_entry__add_cpumode_period(he, al->cpumode, period);
        return he;
 }
 
@@ -65,7 +112,7 @@ hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
        int64_t cmp = 0;
 
        list_for_each_entry(se, &hist_entry__sort_list, list) {
-               cmp = se->cmp(left, right);
+               cmp = se->se_cmp(left, right);
                if (cmp)
                        break;
        }
@@ -82,7 +129,7 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
        list_for_each_entry(se, &hist_entry__sort_list, list) {
                int64_t (*f)(struct hist_entry *, struct hist_entry *);
 
-               f = se->collapse ?: se->cmp;
+               f = se->se_collapse ?: se->se_cmp;
 
                cmp = f(left, right);
                if (cmp)
@@ -101,7 +148,7 @@ void hist_entry__free(struct hist_entry *he)
  * collapse the histogram
  */
 
-static void collapse__insert_entry(struct rb_root *root, struct hist_entry *he)
+static bool collapse__insert_entry(struct rb_root *root, struct hist_entry *he)
 {
        struct rb_node **p = &root->rb_node;
        struct rb_node *parent = NULL;
@@ -115,9 +162,9 @@ static void collapse__insert_entry(struct rb_root *root, struct hist_entry *he)
                cmp = hist_entry__collapse(iter, he);
 
                if (!cmp) {
-                       iter->count += he->count;
+                       iter->period += he->period;
                        hist_entry__free(he);
-                       return;
+                       return false;
                }
 
                if (cmp < 0)
@@ -128,9 +175,10 @@ static void collapse__insert_entry(struct rb_root *root, struct hist_entry *he)
 
        rb_link_node(&he->rb_node, parent, p);
        rb_insert_color(&he->rb_node, root);
+       return true;
 }
 
-void perf_session__collapse_resort(struct perf_session *self)
+void hists__collapse_resort(struct hists *self)
 {
        struct rb_root tmp;
        struct rb_node *next;
@@ -140,72 +188,77 @@ void perf_session__collapse_resort(struct perf_session *self)
                return;
 
        tmp = RB_ROOT;
-       next = rb_first(&self->hists);
+       next = rb_first(&self->entries);
+       self->nr_entries = 0;
+       self->max_sym_namelen = 0;
 
        while (next) {
                n = rb_entry(next, struct hist_entry, rb_node);
                next = rb_next(&n->rb_node);
 
-               rb_erase(&n->rb_node, &self->hists);
-               collapse__insert_entry(&tmp, n);
+               rb_erase(&n->rb_node, &self->entries);
+               if (collapse__insert_entry(&tmp, n))
+                       hists__inc_nr_entries(self, n);
        }
 
-       self->hists = tmp;
+       self->entries = tmp;
 }
 
 /*
- * reverse the map, sort on count.
+ * reverse the map, sort on period.
  */
 
-static void perf_session__insert_output_hist_entry(struct rb_root *root,
-                                                  struct hist_entry *he,
-                                                  u64 min_callchain_hits)
+static void __hists__insert_output_entry(struct rb_root *entries,
+                                        struct hist_entry *he,
+                                        u64 min_callchain_hits)
 {
-       struct rb_node **p = &root->rb_node;
+       struct rb_node **p = &entries->rb_node;
        struct rb_node *parent = NULL;
        struct hist_entry *iter;
 
        if (symbol_conf.use_callchain)
-               callchain_param.sort(&he->sorted_chain, &he->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)
+               if (he->period > iter->period)
                        p = &(*p)->rb_left;
                else
                        p = &(*p)->rb_right;
        }
 
        rb_link_node(&he->rb_node, parent, p);
-       rb_insert_color(&he->rb_node, root);
+       rb_insert_color(&he->rb_node, entries);
 }
 
-void perf_session__output_resort(struct perf_session *self, u64 total_samples)
+void hists__output_resort(struct hists *self)
 {
        struct rb_root tmp;
        struct rb_node *next;
        struct hist_entry *n;
        u64 min_callchain_hits;
 
-       min_callchain_hits =
-               total_samples * (callchain_param.min_percent / 100);
+       min_callchain_hits = self->stats.total_period * (callchain_param.min_percent / 100);
 
        tmp = RB_ROOT;
-       next = rb_first(&self->hists);
+       next = rb_first(&self->entries);
+
+       self->nr_entries = 0;
+       self->max_sym_namelen = 0;
 
        while (next) {
                n = rb_entry(next, struct hist_entry, rb_node);
                next = rb_next(&n->rb_node);
 
-               rb_erase(&n->rb_node, &self->hists);
-               perf_session__insert_output_hist_entry(&tmp, n,
-                                                      min_callchain_hits);
+               rb_erase(&n->rb_node, &self->entries);
+               __hists__insert_output_entry(&tmp, n, min_callchain_hits);
+               hists__inc_nr_entries(self, n);
        }
 
-       self->hists = tmp;
+       self->entries = tmp;
 }
 
 static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
@@ -237,7 +290,7 @@ 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,
+                                    int depth, int depth_mask, int period,
                                     u64 total_samples, int hits,
                                     int left_margin)
 {
@@ -250,7 +303,7 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
                        ret += fprintf(fp, "|");
                else
                        ret += fprintf(fp, " ");
-               if (!count && i == depth - 1) {
+               if (!period && i == depth - 1) {
                        double percent;
 
                        percent = hits * 100.0 / total_samples;
@@ -258,8 +311,8 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
                } else
                        ret += fprintf(fp, "%s", "          ");
        }
-       if (chain->sym)
-               ret += fprintf(fp, "%s\n", chain->sym->name);
+       if (chain->ms.sym)
+               ret += fprintf(fp, "%s\n", chain->ms.sym->name);
        else
                ret += fprintf(fp, "%p\n", (void *)(long)chain->ip);
 
@@ -278,7 +331,7 @@ static void init_rem_hits(void)
        }
 
        strcpy(rem_sq_bracket->name, "[...]");
-       rem_hits.sym = rem_sq_bracket;
+       rem_hits.ms.sym = rem_sq_bracket;
 }
 
 static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
@@ -293,6 +346,7 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
        u64 remaining;
        size_t ret = 0;
        int i;
+       uint entries_printed = 0;
 
        if (callchain_param.mode == CHAIN_GRAPH_REL)
                new_total = self->children_hit;
@@ -328,8 +382,6 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
                                                   left_margin);
                i = 0;
                list_for_each_entry(chain, &child->val, list) {
-                       if (chain->ip >= PERF_CONTEXT_MAX)
-                               continue;
                        ret += ipchain__fprintf_graph(fp, chain, depth,
                                                      new_depth_mask, i++,
                                                      new_total,
@@ -341,6 +393,8 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
                                                  new_depth_mask | (1 << depth),
                                                  left_margin);
                node = next;
+               if (++entries_printed == callchain_param.print_limit)
+                       break;
        }
 
        if (callchain_param.mode == CHAIN_GRAPH_REL &&
@@ -366,11 +420,9 @@ static size_t callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
        bool printed = false;
        int i = 0;
        int ret = 0;
+       u32 entries_printed = 0;
 
        list_for_each_entry(chain, &self->val, list) {
-               if (chain->ip >= PERF_CONTEXT_MAX)
-                       continue;
-
                if (!i++ && sort__first_dimension == SORT_SYM)
                        continue;
 
@@ -385,10 +437,13 @@ static size_t callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
                } else
                        ret += callchain__fprintf_left_margin(fp, left_margin);
 
-               if (chain->sym)
-                       ret += fprintf(fp, " %s\n", chain->sym->name);
+               if (chain->ms.sym)
+                       ret += fprintf(fp, " %s\n", chain->ms.sym->name);
                else
                        ret += fprintf(fp, " %p\n", (void *)(long)chain->ip);
+
+               if (++entries_printed == callchain_param.print_limit)
+                       break;
        }
 
        ret += __callchain__fprintf_graph(fp, self, total_samples, 1, 1, left_margin);
@@ -411,8 +466,8 @@ static size_t callchain__fprintf_flat(FILE *fp, struct callchain_node *self,
        list_for_each_entry(chain, &self->val, list) {
                if (chain->ip >= PERF_CONTEXT_MAX)
                        continue;
-               if (chain->sym)
-                       ret += fprintf(fp, "                %s\n", chain->sym->name);
+               if (chain->ms.sym)
+                       ret += fprintf(fp, "                %s\n", chain->ms.sym->name);
                else
                        ret += fprintf(fp, "                %p\n",
                                        (void *)(long)chain->ip);
@@ -427,6 +482,7 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
        struct rb_node *rb_node;
        struct callchain_node *chain;
        size_t ret = 0;
+       u32 entries_printed = 0;
 
        rb_node = rb_first(&self->sorted_chain);
        while (rb_node) {
@@ -449,55 +505,88 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
                        break;
                }
                ret += fprintf(fp, "\n");
+               if (++entries_printed == callchain_param.print_limit)
+                       break;
                rb_node = rb_next(rb_node);
        }
 
        return ret;
 }
 
-static size_t hist_entry__fprintf(struct hist_entry *self,
-                                 struct perf_session *session,
-                                 struct perf_session *pair_session,
-                                 bool show_displacement,
-                                 long displacement, FILE *fp)
+int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
+                        struct hists *pair_hists, bool show_displacement,
+                        long displacement, bool color, u64 session_total)
 {
        struct sort_entry *se;
-       u64 count, total;
+       u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us;
        const char *sep = symbol_conf.field_sep;
-       size_t ret;
+       int ret;
 
        if (symbol_conf.exclude_other && !self->parent)
                return 0;
 
-       if (pair_session) {
-               count = self->pair ? self->pair->count : 0;
-               total = pair_session->events_stats.total;
+       if (pair_hists) {
+               period = self->pair ? self->pair->period : 0;
+               total = pair_hists->stats.total_period;
+               period_sys = self->pair ? self->pair->period_sys : 0;
+               period_us = self->pair ? self->pair->period_us : 0;
+               period_guest_sys = self->pair ? self->pair->period_guest_sys : 0;
+               period_guest_us = self->pair ? self->pair->period_guest_us : 0;
        } else {
-               count = self->count;
-               total = session->events_stats.total;
+               period = self->period;
+               total = session_total;
+               period_sys = self->period_sys;
+               period_us = self->period_us;
+               period_guest_sys = self->period_guest_sys;
+               period_guest_us = self->period_guest_us;
        }
 
-       if (total)
-               ret = percent_color_fprintf(fp, sep ? "%.2f" : "   %6.2f%%",
-                                           (count * 100.0) / total);
-       else
-               ret = fprintf(fp, sep ? "%lld" : "%12lld ", count);
+       if (total) {
+               if (color)
+                       ret = percent_color_snprintf(s, size,
+                                                    sep ? "%.2f" : "   %6.2f%%",
+                                                    (period * 100.0) / total);
+               else
+                       ret = snprintf(s, size, sep ? "%.2f" : "   %6.2f%%",
+                                      (period * 100.0) / total);
+               if (symbol_conf.show_cpu_utilization) {
+                       ret += percent_color_snprintf(s + ret, size - ret,
+                                       sep ? "%.2f" : "   %6.2f%%",
+                                       (period_sys * 100.0) / total);
+                       ret += percent_color_snprintf(s + ret, size - ret,
+                                       sep ? "%.2f" : "   %6.2f%%",
+                                       (period_us * 100.0) / total);
+                       if (perf_guest) {
+                               ret += percent_color_snprintf(s + ret,
+                                               size - ret,
+                                               sep ? "%.2f" : "   %6.2f%%",
+                                               (period_guest_sys * 100.0) /
+                                                               total);
+                               ret += percent_color_snprintf(s + ret,
+                                               size - ret,
+                                               sep ? "%.2f" : "   %6.2f%%",
+                                               (period_guest_us * 100.0) /
+                                                               total);
+                       }
+               }
+       } else
+               ret = snprintf(s, size, sep ? "%lld" : "%12lld ", period);
 
        if (symbol_conf.show_nr_samples) {
                if (sep)
-                       fprintf(fp, "%c%lld", *sep, count);
+                       ret += snprintf(s + ret, size - ret, "%c%lld", *sep, period);
                else
-                       fprintf(fp, "%11lld", count);
+                       ret += snprintf(s + ret, size - ret, "%11lld", period);
        }
 
-       if (pair_session) {
+       if (pair_hists) {
                char bf[32];
                double old_percent = 0, new_percent = 0, diff;
 
                if (total > 0)
-                       old_percent = (count * 100.0) / total;
-               if (session->events_stats.total > 0)
-                       new_percent = (self->count * 100.0) / session->events_stats.total;
+                       old_percent = (period * 100.0) / total;
+               if (session_total > 0)
+                       new_percent = (self->period * 100.0) / session_total;
 
                diff = new_percent - old_percent;
 
@@ -507,9 +596,9 @@ static size_t hist_entry__fprintf(struct hist_entry *self,
                        snprintf(bf, sizeof(bf), " ");
 
                if (sep)
-                       ret += fprintf(fp, "%c%s", *sep, bf);
+                       ret += snprintf(s + ret, size - ret, "%c%s", *sep, bf);
                else
-                       ret += fprintf(fp, "%11.11s", bf);
+                       ret += snprintf(s + ret, size - ret, "%11.11s", bf);
 
                if (show_displacement) {
                        if (displacement)
@@ -518,9 +607,9 @@ static size_t hist_entry__fprintf(struct hist_entry *self,
                                snprintf(bf, sizeof(bf), " ");
 
                        if (sep)
-                               fprintf(fp, "%c%s", *sep, bf);
+                               ret += snprintf(s + ret, size - ret, "%c%s", *sep, bf);
                        else
-                               fprintf(fp, "%6.6s", bf);
+                               ret += snprintf(s + ret, size - ret, "%6.6s", bf);
                }
        }
 
@@ -528,32 +617,43 @@ static size_t hist_entry__fprintf(struct hist_entry *self,
                if (se->elide)
                        continue;
 
-               fprintf(fp, "%s", sep ?: "  ");
-               ret += se->print(fp, self, se->width ? *se->width : 0);
+               ret += snprintf(s + ret, size - ret, "%s", sep ?: "  ");
+               ret += se->se_snprintf(self, s + ret, size - ret,
+                                      se->se_width ? *se->se_width : 0);
        }
 
-       ret += fprintf(fp, "\n");
+       return ret;
+}
 
-       if (symbol_conf.use_callchain) {
-               int left_margin = 0;
+int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists,
+                       bool show_displacement, long displacement, FILE *fp,
+                       u64 session_total)
+{
+       char bf[512];
+       hist_entry__snprintf(self, bf, sizeof(bf), pair_hists,
+                            show_displacement, displacement,
+                            true, session_total);
+       return fprintf(fp, "%s\n", bf);
+}
 
-               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);
-               }
+static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp,
+                                           u64 session_total)
+{
+       int left_margin = 0;
 
-               hist_entry_callchain__fprintf(fp, self, session->events_stats.total,
-                                             left_margin);
+       if (sort__first_dimension == SORT_COMM) {
+               struct sort_entry *se = list_first_entry(&hist_entry__sort_list,
+                                                        typeof(*se), list);
+               left_margin = se->se_width ? *se->se_width : 0;
+               left_margin -= thread__comm_len(self->thread);
        }
 
-       return ret;
+       return hist_entry_callchain__fprintf(fp, self, session_total,
+                                            left_margin);
 }
 
-size_t perf_session__fprintf_hists(struct perf_session *self,
-                                  struct perf_session *pair,
-                                  bool show_displacement, FILE *fp)
+size_t hists__fprintf(struct hists *self, struct hists *pair,
+                     bool show_displacement, FILE *fp)
 {
        struct sort_entry *se;
        struct rb_node *nd;
@@ -562,7 +662,7 @@ size_t perf_session__fprintf_hists(struct perf_session *self,
        long displacement = 0;
        unsigned int width;
        const char *sep = symbol_conf.field_sep;
-       char *col_width = symbol_conf.col_width_list_str;
+       const char *col_width = symbol_conf.col_width_list_str;
 
        init_rem_hits();
 
@@ -575,6 +675,24 @@ size_t perf_session__fprintf_hists(struct perf_session *self,
                        fputs("  Samples  ", fp);
        }
 
+       if (symbol_conf.show_cpu_utilization) {
+               if (sep) {
+                       ret += fprintf(fp, "%csys", *sep);
+                       ret += fprintf(fp, "%cus", *sep);
+                       if (perf_guest) {
+                               ret += fprintf(fp, "%cguest sys", *sep);
+                               ret += fprintf(fp, "%cguest us", *sep);
+                       }
+               } else {
+                       ret += fprintf(fp, "  sys  ");
+                       ret += fprintf(fp, "  us  ");
+                       if (perf_guest) {
+                               ret += fprintf(fp, "  guest sys  ");
+                               ret += fprintf(fp, "  guest us  ");
+                       }
+               }
+       }
+
        if (pair) {
                if (sep)
                        ret += fprintf(fp, "%cDelta", *sep);
@@ -593,22 +711,22 @@ size_t perf_session__fprintf_hists(struct perf_session *self,
                if (se->elide)
                        continue;
                if (sep) {
-                       fprintf(fp, "%c%s", *sep, se->header);
+                       fprintf(fp, "%c%s", *sep, se->se_header);
                        continue;
                }
-               width = strlen(se->header);
-               if (se->width) {
+               width = strlen(se->se_header);
+               if (se->se_width) {
                        if (symbol_conf.col_width_list_str) {
                                if (col_width) {
-                                       *se->width = atoi(col_width);
+                                       *se->se_width = atoi(col_width);
                                        col_width = strchr(col_width, ',');
                                        if (col_width)
                                                ++col_width;
                                }
                        }
-                       width = *se->width = max(*se->width, width);
+                       width = *se->se_width = max(*se->se_width, width);
                }
-               fprintf(fp, "  %*s", width, se->header);
+               fprintf(fp, "  %*s", width, se->se_header);
        }
        fprintf(fp, "\n");
 
@@ -630,10 +748,10 @@ size_t perf_session__fprintf_hists(struct perf_session *self,
                        continue;
 
                fprintf(fp, "  ");
-               if (se->width)
-                       width = *se->width;
+               if (se->se_width)
+                       width = *se->se_width;
                else
-                       width = strlen(se->header);
+                       width = strlen(se->se_header);
                for (i = 0; i < width; i++)
                        fprintf(fp, ".");
        }
@@ -641,7 +759,7 @@ size_t perf_session__fprintf_hists(struct perf_session *self,
        fprintf(fp, "\n#\n");
 
 print_entries:
-       for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) {
+       for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
                struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
 
                if (show_displacement) {
@@ -652,11 +770,288 @@ print_entries:
                                displacement = 0;
                        ++position;
                }
-               ret += hist_entry__fprintf(h, self, pair, show_displacement,
-                                          displacement, fp);
+               ret += hist_entry__fprintf(h, pair, show_displacement,
+                                          displacement, fp, self->stats.total_period);
+
+               if (symbol_conf.use_callchain)
+                       ret += hist_entry__fprintf_callchain(h, fp, self->stats.total_period);
+
+               if (h->ms.map == NULL && verbose > 1) {
+                       __map_groups__fprintf_maps(&h->thread->mg,
+                                                  MAP__FUNCTION, verbose, fp);
+                       fprintf(fp, "%.10s end\n", graph_dotted_line);
+               }
        }
 
        free(rem_sq_bracket);
 
        return ret;
 }
+
+enum hist_filter {
+       HIST_FILTER__DSO,
+       HIST_FILTER__THREAD,
+};
+
+void hists__filter_by_dso(struct hists *self, const struct dso *dso)
+{
+       struct rb_node *nd;
+
+       self->nr_entries = self->stats.total_period = 0;
+       self->stats.nr_events[PERF_RECORD_SAMPLE] = 0;
+       self->max_sym_namelen = 0;
+
+       for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
+               struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
+
+               if (symbol_conf.exclude_other && !h->parent)
+                       continue;
+
+               if (dso != NULL && (h->ms.map == NULL || h->ms.map->dso != dso)) {
+                       h->filtered |= (1 << HIST_FILTER__DSO);
+                       continue;
+               }
+
+               h->filtered &= ~(1 << HIST_FILTER__DSO);
+               if (!h->filtered) {
+                       ++self->nr_entries;
+                       self->stats.total_period += h->period;
+                       self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events;
+                       if (h->ms.sym &&
+                           self->max_sym_namelen < h->ms.sym->namelen)
+                               self->max_sym_namelen = h->ms.sym->namelen;
+               }
+       }
+}
+
+void hists__filter_by_thread(struct hists *self, const struct thread *thread)
+{
+       struct rb_node *nd;
+
+       self->nr_entries = self->stats.total_period = 0;
+       self->stats.nr_events[PERF_RECORD_SAMPLE] = 0;
+       self->max_sym_namelen = 0;
+
+       for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
+               struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
+
+               if (thread != NULL && h->thread != thread) {
+                       h->filtered |= (1 << HIST_FILTER__THREAD);
+                       continue;
+               }
+               h->filtered &= ~(1 << HIST_FILTER__THREAD);
+               if (!h->filtered) {
+                       ++self->nr_entries;
+                       self->stats.total_period += h->period;
+                       self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events;
+                       if (h->ms.sym &&
+                           self->max_sym_namelen < h->ms.sym->namelen)
+                               self->max_sym_namelen = h->ms.sym->namelen;
+               }
+       }
+}
+
+static int symbol__alloc_hist(struct symbol *self)
+{
+       struct sym_priv *priv = symbol__priv(self);
+       const int size = (sizeof(*priv->hist) +
+                         (self->end - self->start) * sizeof(u64));
+
+       priv->hist = zalloc(size);
+       return priv->hist == NULL ? -1 : 0;
+}
+
+int hist_entry__inc_addr_samples(struct hist_entry *self, u64 ip)
+{
+       unsigned int sym_size, offset;
+       struct symbol *sym = self->ms.sym;
+       struct sym_priv *priv;
+       struct sym_hist *h;
+
+       if (!sym || !self->ms.map)
+               return 0;
+
+       priv = symbol__priv(sym);
+       if (priv->hist == NULL && symbol__alloc_hist(sym) < 0)
+               return -ENOMEM;
+
+       sym_size = sym->end - sym->start;
+       offset = ip - sym->start;
+
+       pr_debug3("%s: ip=%#Lx\n", __func__, self->ms.map->unmap_ip(self->ms.map, ip));
+
+       if (offset >= sym_size)
+               return 0;
+
+       h = priv->hist;
+       h->sum++;
+       h->ip[offset]++;
+
+       pr_debug3("%#Lx %s: period++ [ip: %#Lx, %#Lx] => %Ld\n", self->ms.sym->start,
+                 self->ms.sym->name, ip, ip - self->ms.sym->start, h->ip[offset]);
+       return 0;
+}
+
+static struct objdump_line *objdump_line__new(s64 offset, char *line)
+{
+       struct objdump_line *self = malloc(sizeof(*self));
+
+       if (self != NULL) {
+               self->offset = offset;
+               self->line = line;
+       }
+
+       return self;
+}
+
+void objdump_line__free(struct objdump_line *self)
+{
+       free(self->line);
+       free(self);
+}
+
+static void objdump__add_line(struct list_head *head, struct objdump_line *line)
+{
+       list_add_tail(&line->node, head);
+}
+
+struct objdump_line *objdump__get_next_ip_line(struct list_head *head,
+                                              struct objdump_line *pos)
+{
+       list_for_each_entry_continue(pos, head, node)
+               if (pos->offset >= 0)
+                       return pos;
+
+       return NULL;
+}
+
+static int hist_entry__parse_objdump_line(struct hist_entry *self, FILE *file,
+                                         struct list_head *head)
+{
+       struct symbol *sym = self->ms.sym;
+       struct objdump_line *objdump_line;
+       char *line = NULL, *tmp, *tmp2, *c;
+       size_t line_len;
+       s64 line_ip, offset = -1;
+
+       if (getline(&line, &line_len, file) < 0)
+               return -1;
+
+       if (!line)
+               return -1;
+
+       while (line_len != 0 && isspace(line[line_len - 1]))
+               line[--line_len] = '\0';
+
+       c = strchr(line, '\n');
+       if (c)
+               *c = 0;
+
+       line_ip = -1;
+
+       /*
+        * Strip leading spaces:
+        */
+       tmp = line;
+       while (*tmp) {
+               if (*tmp != ' ')
+                       break;
+               tmp++;
+       }
+
+       if (*tmp) {
+               /*
+                * Parse hexa addresses followed by ':'
+                */
+               line_ip = strtoull(tmp, &tmp2, 16);
+               if (*tmp2 != ':')
+                       line_ip = -1;
+       }
+
+       if (line_ip != -1) {
+               u64 start = map__rip_2objdump(self->ms.map, sym->start);
+               offset = line_ip - start;
+       }
+
+       objdump_line = objdump_line__new(offset, line);
+       if (objdump_line == NULL) {
+               free(line);
+               return -1;
+       }
+       objdump__add_line(head, objdump_line);
+
+       return 0;
+}
+
+int hist_entry__annotate(struct hist_entry *self, struct list_head *head)
+{
+       struct symbol *sym = self->ms.sym;
+       struct map *map = self->ms.map;
+       struct dso *dso = map->dso;
+       const char *filename = dso->long_name;
+       char command[PATH_MAX * 2];
+       FILE *file;
+       u64 len;
+
+       if (!filename)
+               return -1;
+
+       if (dso->origin == DSO__ORIG_KERNEL) {
+               if (dso->annotate_warned)
+                       return 0;
+               dso->annotate_warned = 1;
+               pr_err("Can't annotate %s: No vmlinux file was found in the "
+                      "path:\n", sym->name);
+               vmlinux_path__fprintf(stderr);
+               return -1;
+       }
+
+       pr_debug("%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));
+
+       len = sym->end - sym->start;
+
+       pr_debug("annotating [%p] %30s : [%p] %30s\n",
+                dso, dso->long_name, sym, sym->name);
+
+       snprintf(command, sizeof(command),
+                "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s|expand",
+                map__rip_2objdump(map, sym->start),
+                map__rip_2objdump(map, sym->end),
+                filename, filename);
+
+       pr_debug("Executing: %s\n", command);
+
+       file = popen(command, "r");
+       if (!file)
+               return -1;
+
+       while (!feof(file))
+               if (hist_entry__parse_objdump_line(self, file, head) < 0)
+                       break;
+
+       pclose(file);
+       return 0;
+}
+
+void hists__inc_nr_events(struct hists *self, u32 type)
+{
+       ++self->stats.nr_events[0];
+       ++self->stats.nr_events[type];
+}
+
+size_t hists__fprintf_nr_events(struct hists *self, FILE *fp)
+{
+       int i;
+       size_t ret = 0;
+
+       for (i = 0; i < PERF_RECORD_HEADER_MAX; ++i) {
+               if (!event__name[i])
+                       continue;
+               ret += fprintf(fp, "%10s events: %10d\n",
+                              event__name[i], self->stats.nr_events[i]);
+       }
+
+       return ret;
+}
index e5f99b24048b4574e410f9ee8621e0a1638545ac..6f17dcd8412c6c6e0894aa4b078f7982b10cd69a 100644 (file)
 
 extern struct callchain_param callchain_param;
 
-struct perf_session;
 struct hist_entry;
 struct addr_location;
 struct symbol;
+struct rb_root;
 
-struct hist_entry *__perf_session__add_hist_entry(struct perf_session *self,
-                                                 struct addr_location *al,
-                                                 struct symbol *parent,
-                                                 u64 count, bool *hit);
+struct objdump_line {
+       struct list_head node;
+       s64              offset;
+       char             *line;
+};
+
+void objdump_line__free(struct objdump_line *self);
+struct objdump_line *objdump__get_next_ip_line(struct list_head *head,
+                                              struct objdump_line *pos);
+
+struct sym_hist {
+       u64             sum;
+       u64             ip[0];
+};
+
+struct sym_ext {
+       struct rb_node  node;
+       double          percent;
+       char            *path;
+};
+
+struct sym_priv {
+       struct sym_hist *hist;
+       struct sym_ext  *ext;
+};
+
+/*
+ * The kernel collects the number of events it couldn't send in a stretch and
+ * when possible sends this number in a PERF_RECORD_LOST event. The number of
+ * such "chunks" of lost events is stored in .nr_events[PERF_EVENT_LOST] while
+ * total_lost tells exactly how many events the kernel in fact lost, i.e. it is
+ * the sum of all struct lost_event.lost fields reported.
+ *
+ * The total_period is needed because by default auto-freq is used, so
+ * multipling nr_events[PERF_EVENT_SAMPLE] by a frequency isn't possible to get
+ * the total number of low level events, it is necessary to to sum all struct
+ * sample_event.period and stash the result in total_period.
+ */
+struct events_stats {
+       u64 total_period;
+       u64 total_lost;
+       u32 nr_events[PERF_RECORD_HEADER_MAX];
+       u32 nr_unknown_events;
+};
+
+struct hists {
+       struct rb_node          rb_node;
+       struct rb_root          entries;
+       u64                     nr_entries;
+       struct events_stats     stats;
+       u64                     config;
+       u64                     event_stream;
+       u32                     type;
+       u32                     max_sym_namelen;
+};
+
+struct hist_entry *__hists__add_entry(struct hists *self,
+                                     struct addr_location *al,
+                                     struct symbol *parent, u64 period);
 extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *);
 extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *);
+int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists,
+                       bool show_displacement, long displacement, FILE *fp,
+                       u64 total);
+int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size,
+                        struct hists *pair_hists, bool show_displacement,
+                        long displacement, bool color, u64 total);
 void hist_entry__free(struct hist_entry *);
 
-void perf_session__output_resort(struct perf_session *self, u64 total_samples);
-void perf_session__collapse_resort(struct perf_session *self);
-size_t perf_session__fprintf_hists(struct perf_session *self,
-                                  struct perf_session *pair,
-                                  bool show_displacement, FILE *fp);
+void hists__output_resort(struct hists *self);
+void hists__collapse_resort(struct hists *self);
+
+void hists__inc_nr_events(struct hists *self, u32 type);
+size_t hists__fprintf_nr_events(struct hists *self, FILE *fp);
+
+size_t hists__fprintf(struct hists *self, struct hists *pair,
+                     bool show_displacement, FILE *fp);
+
+int hist_entry__inc_addr_samples(struct hist_entry *self, u64 ip);
+int hist_entry__annotate(struct hist_entry *self, struct list_head *head);
+
+void hists__filter_by_dso(struct hists *self, const struct dso *dso);
+void hists__filter_by_thread(struct hists *self, const struct thread *thread);
+
+#ifdef NO_NEWT_SUPPORT
+static inline int hists__browse(struct hists *self __used,
+                               const char *helpline __used,
+                               const char *input_name __used)
+{
+       return 0;
+}
+#else
+int hists__browse(struct hists *self, const char *helpline,
+                 const char *input_name);
+#endif
 #endif /* __PERF_HIST_H */
diff --git a/tools/perf/util/hweight.c b/tools/perf/util/hweight.c
new file mode 100644 (file)
index 0000000..5c1d0d0
--- /dev/null
@@ -0,0 +1,31 @@
+#include <linux/bitops.h>
+
+/**
+ * hweightN - returns the hamming weight of a N-bit word
+ * @x: the word to weigh
+ *
+ * The Hamming Weight of a number is the total number of bits set in it.
+ */
+
+unsigned int hweight32(unsigned int w)
+{
+       unsigned int res = w - ((w >> 1) & 0x55555555);
+       res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
+       res = (res + (res >> 4)) & 0x0F0F0F0F;
+       res = res + (res >> 8);
+       return (res + (res >> 16)) & 0x000000FF;
+}
+
+unsigned long hweight64(__u64 w)
+{
+#if BITS_PER_LONG == 32
+       return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
+#elif BITS_PER_LONG == 64
+       __u64 res = w - ((w >> 1) & 0x5555555555555555ul);
+       res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
+       res = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful;
+       res = res + (res >> 8);
+       res = res + (res >> 16);
+       return (res + (res >> 32)) & 0x00000000000000FFul;
+#endif
+}
diff --git a/tools/perf/util/include/asm/bitops.h b/tools/perf/util/include/asm/bitops.h
deleted file mode 100644 (file)
index 58e9817..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#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/hweight.h b/tools/perf/util/include/asm/hweight.h
new file mode 100644 (file)
index 0000000..36cf26d
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef PERF_HWEIGHT_H
+#define PERF_HWEIGHT_H
+
+#include <linux/types.h>
+unsigned int hweight32(unsigned int w);
+unsigned long hweight64(__u64 w);
+
+#endif /* PERF_HWEIGHT_H */
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
new file mode 100644 (file)
index 0000000..cf6727e
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _PERF_DWARF_REGS_H_
+#define _PERF_DWARF_REGS_H_
+
+#ifdef DWARF_SUPPORT
+const char *get_arch_regstr(unsigned int n);
+#endif
+
+#endif
index 94507639a8c41ce3947573669a4dc7ccd333231a..eda4416efa0a9819ad84a130132bd95d14f6b1a7 100644 (file)
@@ -1,3 +1,35 @@
-#include "../../../../include/linux/bitmap.h"
-#include "../../../../include/asm-generic/bitops/find.h"
-#include <linux/errno.h>
+#ifndef _PERF_BITOPS_H
+#define _PERF_BITOPS_H
+
+#include <string.h>
+#include <linux/bitops.h>
+
+int __bitmap_weight(const unsigned long *bitmap, int bits);
+
+#define BITMAP_LAST_WORD_MASK(nbits)                                   \
+(                                                                      \
+       ((nbits) % BITS_PER_LONG) ?                                     \
+               (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL               \
+)
+
+#define small_const_nbits(nbits) \
+       (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)
+
+static inline void bitmap_zero(unsigned long *dst, int nbits)
+{
+       if (small_const_nbits(nbits))
+               *dst = 0UL;
+       else {
+               int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
+               memset(dst, 0, len);
+       }
+}
+
+static inline int bitmap_weight(const unsigned long *src, int nbits)
+{
+       if (small_const_nbits(nbits))
+               return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits));
+       return __bitmap_weight(src, nbits);
+}
+
+#endif /* _PERF_BITOPS_H */
index 8d63116e9435be917354b94b42ef9e6c9d026caf..bb4ac2e053859482f98933b278a8d0adda71aa5a 100644 (file)
@@ -1,13 +1,12 @@
 #ifndef _PERF_LINUX_BITOPS_H_
 #define _PERF_LINUX_BITOPS_H_
 
-#define __KERNEL__
+#include <linux/kernel.h>
+#include <asm/hweight.h>
 
-#define CONFIG_GENERIC_FIND_NEXT_BIT
-#define CONFIG_GENERIC_FIND_FIRST_BIT
-#include "../../../../include/linux/bitops.h"
-
-#undef __KERNEL__
+#define BITS_PER_LONG __WORDSIZE
+#define BITS_PER_BYTE           8
+#define BITS_TO_LONGS(nr)       DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
 
 static inline void set_bit(int nr, unsigned long *addr)
 {
@@ -20,10 +19,9 @@ static __always_inline int test_bit(unsigned int nr, const unsigned long *addr)
                (((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);
+static inline unsigned long hweight_long(unsigned long w)
+{
+       return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
+}
 
 #endif
index dfb0713ed47ff97ec4f5e5f7af0d11a8fb7c6566..791f9dd27ebffd3166f6535c629c0595d073b3db 100644 (file)
@@ -7,4 +7,6 @@
 #define __user
 #define __attribute_const__
 
+#define __used         __attribute__((__unused__))
+
 #endif
index f2611655ab5176b09117aef19eba27f1f940e2be..1eb804fd3fbff078baa9e70f57d850676607c1b9 100644 (file)
@@ -28,6 +28,8 @@
        (type *)((char *)__mptr - offsetof(type, member)); })
 #endif
 
+#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
+
 #ifndef max
 #define max(x, y) ({                           \
        typeof(x) _max1 = (x);                  \
@@ -85,16 +87,19 @@ simple_strtoul(const char *nptr, char **endptr, int base)
        return strtoul(nptr, endptr, base);
 }
 
+int eprintf(int level,
+           const char *fmt, ...) __attribute__((format(printf, 2, 3)));
+
 #ifndef pr_fmt
 #define pr_fmt(fmt) fmt
 #endif
 
 #define pr_err(fmt, ...) \
-       do { fprintf(stderr, pr_fmt(fmt), ##__VA_ARGS__); } while (0)
+       eprintf(0, pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_warning(fmt, ...) \
-       do { fprintf(stderr, pr_fmt(fmt), ##__VA_ARGS__); } while (0)
+       eprintf(0, pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_info(fmt, ...) \
-       do { fprintf(stderr, pr_fmt(fmt), ##__VA_ARGS__); } while (0)
+       eprintf(0, pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_debug(fmt, ...) \
        eprintf(1, pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_debugN(n, fmt, ...) \
index e509cd59c67d985a2ecb9946b61e7ae7065efca4..e672f2fef65baaf62dd20d869bca33e027c1cfe6 100644 (file)
@@ -1,9 +1,11 @@
-#include "event.h"
 #include "symbol.h"
+#include <errno.h>
+#include <limits.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
-#include "debug.h"
+#include <unistd.h>
+#include "map.h"
 
 const char *map_type__name[MAP__NR_TYPES] = {
        [MAP__FUNCTION] = "Functions",
@@ -36,15 +38,16 @@ void map__init(struct map *self, enum map_type type,
        self->map_ip   = map__map_ip;
        self->unmap_ip = map__unmap_ip;
        RB_CLEAR_NODE(&self->rb_node);
+       self->groups   = NULL;
 }
 
-struct map *map__new(struct mmap_event *event, enum map_type type,
-                    char *cwd, int cwdlen)
+struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
+                    u64 pgoff, u32 pid, char *filename,
+                    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;
@@ -62,16 +65,15 @@ struct map *map__new(struct mmap_event *event, enum map_type type,
                anon = is_anon_memory(filename);
 
                if (anon) {
-                       snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid);
+                       snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
                        filename = newfilename;
                }
 
-               dso = dsos__findnew(filename);
+               dso = __dsos__findnew(dsos__list, filename);
                if (dso == NULL)
                        goto out_delete;
 
-               map__init(self, type, event->start, event->start + event->len,
-                         event->pgoff, dso);
+               map__init(self, type, start, start + len, pgoff, dso);
 
                if (anon) {
 set_identity:
@@ -235,3 +237,392 @@ u64 map__objdump_2ip(struct map *map, u64 addr)
                        map->unmap_ip(map, addr);       /* RIP -> IP */
        return ip;
 }
+
+void map_groups__init(struct map_groups *self)
+{
+       int i;
+       for (i = 0; i < MAP__NR_TYPES; ++i) {
+               self->maps[i] = RB_ROOT;
+               INIT_LIST_HEAD(&self->removed_maps[i]);
+       }
+       self->machine = NULL;
+}
+
+void map_groups__flush(struct map_groups *self)
+{
+       int type;
+
+       for (type = 0; type < MAP__NR_TYPES; type++) {
+               struct rb_root *root = &self->maps[type];
+               struct rb_node *next = rb_first(root);
+
+               while (next) {
+                       struct map *pos = rb_entry(next, struct map, rb_node);
+                       next = rb_next(&pos->rb_node);
+                       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[pos->type]);
+               }
+       }
+}
+
+struct symbol *map_groups__find_symbol(struct map_groups *self,
+                                      enum map_type type, u64 addr,
+                                      struct map **mapp,
+                                      symbol_filter_t filter)
+{
+       struct map *map = map_groups__find(self, type, addr);
+
+       if (map != NULL) {
+               if (mapp != NULL)
+                       *mapp = map;
+               return map__find_symbol(map, map->map_ip(map, addr), filter);
+       }
+
+       return NULL;
+}
+
+struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
+                                              enum map_type type,
+                                              const char *name,
+                                              struct map **mapp,
+                                              symbol_filter_t filter)
+{
+       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);
+               struct symbol *sym = map__find_symbol_by_name(pos, name, filter);
+
+               if (sym == NULL)
+                       continue;
+               if (mapp != NULL)
+                       *mapp = pos;
+               return sym;
+       }
+
+       return NULL;
+}
+
+size_t __map_groups__fprintf_maps(struct map_groups *self,
+                                 enum map_type type, int verbose, 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 > 2) {
+                       printed += dso__fprintf(pos->dso, type, fp);
+                       printed += fprintf(fp, "--\n");
+               }
+       }
+
+       return printed;
+}
+
+size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp)
+{
+       size_t printed = 0, i;
+       for (i = 0; i < MAP__NR_TYPES; ++i)
+               printed += __map_groups__fprintf_maps(self, i, verbose, fp);
+       return printed;
+}
+
+static size_t __map_groups__fprintf_removed_maps(struct map_groups *self,
+                                                enum map_type type,
+                                                int verbose, FILE *fp)
+{
+       struct map *pos;
+       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;
+}
+
+static size_t map_groups__fprintf_removed_maps(struct map_groups *self,
+                                              int verbose, FILE *fp)
+{
+       size_t printed = 0, i;
+       for (i = 0; i < MAP__NR_TYPES; ++i)
+               printed += __map_groups__fprintf_removed_maps(self, i, verbose, fp);
+       return printed;
+}
+
+size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp)
+{
+       size_t printed = map_groups__fprintf_maps(self, verbose, fp);
+       printed += fprintf(fp, "Removed maps:\n");
+       return printed + map_groups__fprintf_removed_maps(self, verbose, fp);
+}
+
+int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
+                                  int verbose, FILE *fp)
+{
+       struct rb_root *root = &self->maps[map->type];
+       struct rb_node *next = rb_first(root);
+
+       while (next) {
+               struct map *pos = rb_entry(next, struct map, rb_node);
+               next = rb_next(&pos->rb_node);
+
+               if (!map__overlap(pos, map))
+                       continue;
+
+               if (verbose >= 2) {
+                       fputs("overlapping maps:\n", fp);
+                       map__fprintf(map, fp);
+                       map__fprintf(pos, fp);
+               }
+
+               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]);
+               /*
+                * Now check if we need to create new maps for areas not
+                * overlapped by the new map:
+                */
+               if (map->start > pos->start) {
+                       struct map *before = map__clone(pos);
+
+                       if (before == NULL)
+                               return -ENOMEM;
+
+                       before->end = map->start - 1;
+                       map_groups__insert(self, before);
+                       if (verbose >= 2)
+                               map__fprintf(before, fp);
+               }
+
+               if (map->end < pos->end) {
+                       struct map *after = map__clone(pos);
+
+                       if (after == NULL)
+                               return -ENOMEM;
+
+                       after->start = map->end + 1;
+                       map_groups__insert(self, after);
+                       if (verbose >= 2)
+                               map__fprintf(after, fp);
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * XXX This should not really _copy_ te maps, but refcount them.
+ */
+int map_groups__clone(struct map_groups *self,
+                     struct map_groups *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 == NULL)
+                       return -ENOMEM;
+               map_groups__insert(self, new);
+       }
+       return 0;
+}
+
+static u64 map__reloc_map_ip(struct map *map, u64 ip)
+{
+       return ip + (s64)map->pgoff;
+}
+
+static u64 map__reloc_unmap_ip(struct map *map, u64 ip)
+{
+       return ip - (s64)map->pgoff;
+}
+
+void map__reloc_vmlinux(struct map *self)
+{
+       struct kmap *kmap = map__kmap(self);
+       s64 reloc;
+
+       if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->unrelocated_addr)
+               return;
+
+       reloc = (kmap->ref_reloc_sym->unrelocated_addr -
+                kmap->ref_reloc_sym->addr);
+
+       if (!reloc)
+               return;
+
+       self->map_ip   = map__reloc_map_ip;
+       self->unmap_ip = map__reloc_unmap_ip;
+       self->pgoff    = reloc;
+}
+
+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;
+       }
+
+       rb_link_node(&map->rb_node, parent, p);
+       rb_insert_color(&map->rb_node, maps);
+}
+
+struct map *maps__find(struct rb_root *maps, u64 ip)
+{
+       struct rb_node **p = &maps->rb_node;
+       struct rb_node *parent = NULL;
+       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 if (ip > m->end)
+                       p = &(*p)->rb_right;
+               else
+                       return m;
+       }
+
+       return NULL;
+}
+
+int machine__init(struct machine *self, const char *root_dir, pid_t pid)
+{
+       map_groups__init(&self->kmaps);
+       RB_CLEAR_NODE(&self->rb_node);
+       INIT_LIST_HEAD(&self->user_dsos);
+       INIT_LIST_HEAD(&self->kernel_dsos);
+
+       self->kmaps.machine = self;
+       self->pid           = pid;
+       self->root_dir      = strdup(root_dir);
+       return self->root_dir == NULL ? -ENOMEM : 0;
+}
+
+struct machine *machines__add(struct rb_root *self, pid_t pid,
+                             const char *root_dir)
+{
+       struct rb_node **p = &self->rb_node;
+       struct rb_node *parent = NULL;
+       struct machine *pos, *machine = malloc(sizeof(*machine));
+
+       if (!machine)
+               return NULL;
+
+       if (machine__init(machine, root_dir, pid) != 0) {
+               free(machine);
+               return NULL;
+       }
+
+       while (*p != NULL) {
+               parent = *p;
+               pos = rb_entry(parent, struct machine, rb_node);
+               if (pid < pos->pid)
+                       p = &(*p)->rb_left;
+               else
+                       p = &(*p)->rb_right;
+       }
+
+       rb_link_node(&machine->rb_node, parent, p);
+       rb_insert_color(&machine->rb_node, self);
+
+       return machine;
+}
+
+struct machine *machines__find(struct rb_root *self, pid_t pid)
+{
+       struct rb_node **p = &self->rb_node;
+       struct rb_node *parent = NULL;
+       struct machine *machine;
+       struct machine *default_machine = NULL;
+
+       while (*p != NULL) {
+               parent = *p;
+               machine = rb_entry(parent, struct machine, rb_node);
+               if (pid < machine->pid)
+                       p = &(*p)->rb_left;
+               else if (pid > machine->pid)
+                       p = &(*p)->rb_right;
+               else
+                       return machine;
+               if (!machine->pid)
+                       default_machine = machine;
+       }
+
+       return default_machine;
+}
+
+struct machine *machines__findnew(struct rb_root *self, pid_t pid)
+{
+       char path[PATH_MAX];
+       const char *root_dir;
+       struct machine *machine = machines__find(self, pid);
+
+       if (!machine || machine->pid != pid) {
+               if (pid == HOST_KERNEL_ID || pid == DEFAULT_GUEST_KERNEL_ID)
+                       root_dir = "";
+               else {
+                       if (!symbol_conf.guestmount)
+                               goto out;
+                       sprintf(path, "%s/%d", symbol_conf.guestmount, pid);
+                       if (access(path, R_OK)) {
+                               pr_err("Can't access file %s\n", path);
+                               goto out;
+                       }
+                       root_dir = path;
+               }
+               machine = machines__add(self, pid, root_dir);
+       }
+
+out:
+       return machine;
+}
+
+void machines__process(struct rb_root *self, machine__process_t process, void *data)
+{
+       struct rb_node *nd;
+
+       for (nd = rb_first(self); nd; nd = rb_next(nd)) {
+               struct machine *pos = rb_entry(nd, struct machine, rb_node);
+               process(pos, data);
+       }
+}
+
+char *machine__mmap_name(struct machine *self, char *bf, size_t size)
+{
+       if (machine__is_host(self))
+               snprintf(bf, size, "[%s]", "kernel.kallsyms");
+       else if (machine__is_default_guest(self))
+               snprintf(bf, size, "[%s]", "guest.kernel.kallsyms");
+       else
+               snprintf(bf, size, "[%s.%d]", "guest.kernel.kallsyms", self->pid);
+
+       return bf;
+}
index b756368076c6ce4478ccb18ccdd61bd45e2fd408..f39134512829c89c48662996d6a1a75f5d41deed 100644 (file)
@@ -4,7 +4,9 @@
 #include <linux/compiler.h>
 #include <linux/list.h>
 #include <linux/rbtree.h>
-#include <linux/types.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include "types.h"
 
 enum map_type {
        MAP__FUNCTION = 0,
@@ -18,6 +20,7 @@ extern const char *map_type__name[MAP__NR_TYPES];
 struct dso;
 struct ref_reloc_sym;
 struct map_groups;
+struct machine;
 
 struct map {
        union {
@@ -27,6 +30,7 @@ struct map {
        u64                     start;
        u64                     end;
        enum map_type           type;
+       u32                     priv;
        u64                     pgoff;
 
        /* ip -> dso rip */
@@ -35,6 +39,7 @@ struct map {
        u64                     (*unmap_ip)(struct map *, u64);
 
        struct dso              *dso;
+       struct map_groups       *groups;
 };
 
 struct kmap {
@@ -42,6 +47,32 @@ struct kmap {
        struct map_groups       *kmaps;
 };
 
+struct map_groups {
+       struct rb_root   maps[MAP__NR_TYPES];
+       struct list_head removed_maps[MAP__NR_TYPES];
+       struct machine   *machine;
+};
+
+/* Native host kernel uses -1 as pid index in machine */
+#define        HOST_KERNEL_ID                  (-1)
+#define        DEFAULT_GUEST_KERNEL_ID         (0)
+
+struct machine {
+       struct rb_node    rb_node;
+       pid_t             pid;
+       char              *root_dir;
+       struct list_head  user_dsos;
+       struct list_head  kernel_dsos;
+       struct map_groups kmaps;
+       struct map        *vmlinux_maps[MAP__NR_TYPES];
+};
+
+static inline
+struct map *machine__kernel_map(struct machine *self, enum map_type type)
+{
+       return self->vmlinux_maps[type];
+}
+
 static inline struct kmap *map__kmap(struct map *self)
 {
        return (struct kmap *)(self + 1);
@@ -68,14 +99,14 @@ u64 map__rip_2objdump(struct map *map, u64 rip);
 u64 map__objdump_2ip(struct map *map, u64 addr);
 
 struct symbol;
-struct mmap_event;
 
 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);
+struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
+                    u64 pgoff, u32 pid, char *filename,
+                    enum map_type 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);
@@ -91,4 +122,96 @@ void map__fixup_end(struct map *self);
 
 void map__reloc_vmlinux(struct map *self);
 
+size_t __map_groups__fprintf_maps(struct map_groups *self,
+                                 enum map_type type, int verbose, FILE *fp);
+void maps__insert(struct rb_root *maps, struct map *map);
+struct map *maps__find(struct rb_root *maps, u64 addr);
+void map_groups__init(struct map_groups *self);
+int map_groups__clone(struct map_groups *self,
+                     struct map_groups *parent, enum map_type type);
+size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp);
+size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp);
+
+typedef void (*machine__process_t)(struct machine *self, void *data);
+
+void machines__process(struct rb_root *self, machine__process_t process, void *data);
+struct machine *machines__add(struct rb_root *self, pid_t pid,
+                             const char *root_dir);
+struct machine *machines__find_host(struct rb_root *self);
+struct machine *machines__find(struct rb_root *self, pid_t pid);
+struct machine *machines__findnew(struct rb_root *self, pid_t pid);
+char *machine__mmap_name(struct machine *self, char *bf, size_t size);
+int machine__init(struct machine *self, const char *root_dir, pid_t pid);
+
+/*
+ * Default guest kernel is defined by parameter --guestkallsyms
+ * and --guestmodules
+ */
+static inline bool machine__is_default_guest(struct machine *self)
+{
+       return self ? self->pid == DEFAULT_GUEST_KERNEL_ID : false;
+}
+
+static inline bool machine__is_host(struct machine *self)
+{
+       return self ? self->pid == HOST_KERNEL_ID : false;
+}
+
+static inline void map_groups__insert(struct map_groups *self, struct map *map)
+{
+       maps__insert(&self->maps[map->type], map);
+       map->groups = self;
+}
+
+static inline struct map *map_groups__find(struct map_groups *self,
+                                          enum map_type type, u64 addr)
+{
+       return maps__find(&self->maps[type], addr);
+}
+
+struct symbol *map_groups__find_symbol(struct map_groups *self,
+                                      enum map_type type, u64 addr,
+                                      struct map **mapp,
+                                      symbol_filter_t filter);
+
+struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
+                                              enum map_type type,
+                                              const char *name,
+                                              struct map **mapp,
+                                              symbol_filter_t filter);
+
+static inline
+struct symbol *machine__find_kernel_symbol(struct machine *self,
+                                          enum map_type type, u64 addr,
+                                          struct map **mapp,
+                                          symbol_filter_t filter)
+{
+       return map_groups__find_symbol(&self->kmaps, type, addr, mapp, filter);
+}
+
+static inline
+struct symbol *machine__find_kernel_function(struct machine *self, u64 addr,
+                                            struct map **mapp,
+                                            symbol_filter_t filter)
+{
+       return machine__find_kernel_symbol(self, MAP__FUNCTION, addr, mapp, filter);
+}
+
+static inline
+struct symbol *map_groups__find_function_by_name(struct map_groups *self,
+                                                const char *name, struct map **mapp,
+                                                symbol_filter_t filter)
+{
+       return map_groups__find_symbol_by_name(self, MAP__FUNCTION, name, mapp, filter);
+}
+
+int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
+                                  int verbose, FILE *fp);
+
+struct map *map_groups__find_by_name(struct map_groups *self,
+                                    enum map_type type, const char *name);
+struct map *machine__new_module(struct machine *self, u64 start, const char *filename);
+
+void map_groups__flush(struct map_groups *self);
+
 #endif /* __PERF_MAP_H */
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c
new file mode 100644 (file)
index 0000000..ccb7c5b
--- /dev/null
@@ -0,0 +1,1084 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#undef _GNU_SOURCE
+
+#include <slang.h>
+#include <stdlib.h>
+#include <newt.h>
+#include <sys/ttydefaults.h>
+
+#include "cache.h"
+#include "hist.h"
+#include "pstack.h"
+#include "session.h"
+#include "sort.h"
+#include "symbol.h"
+
+#if SLANG_VERSION < 20104
+#define slsmg_printf(msg, args...) SLsmg_printf((char *)msg, ##args)
+#define slsmg_write_nstring(msg, len) SLsmg_write_nstring((char *)msg, len)
+#define sltt_set_color(obj, name, fg, bg) SLtt_set_color(obj,(char *)name,\
+                                                        (char *)fg, (char *)bg)
+#else
+#define slsmg_printf SLsmg_printf
+#define slsmg_write_nstring SLsmg_write_nstring
+#define sltt_set_color SLtt_set_color
+#endif
+
+struct ui_progress {
+       newtComponent form, scale;
+};
+
+struct ui_progress *ui_progress__new(const char *title, u64 total)
+{
+       struct ui_progress *self = malloc(sizeof(*self));
+
+       if (self != NULL) {
+               int cols;
+               newtGetScreenSize(&cols, NULL);
+               cols -= 4;
+               newtCenteredWindow(cols, 1, title);
+               self->form  = newtForm(NULL, NULL, 0);
+               if (self->form == NULL)
+                       goto out_free_self;
+               self->scale = newtScale(0, 0, cols, total);
+               if (self->scale == NULL)
+                       goto out_free_form;
+               newtFormAddComponent(self->form, self->scale);
+               newtRefresh();
+       }
+
+       return self;
+
+out_free_form:
+       newtFormDestroy(self->form);
+out_free_self:
+       free(self);
+       return NULL;
+}
+
+void ui_progress__update(struct ui_progress *self, u64 curr)
+{
+       newtScaleSet(self->scale, curr);
+       newtRefresh();
+}
+
+void ui_progress__delete(struct ui_progress *self)
+{
+       newtFormDestroy(self->form);
+       newtPopWindow();
+       free(self);
+}
+
+static void ui_helpline__pop(void)
+{
+       newtPopHelpLine();
+}
+
+static void ui_helpline__push(const char *msg)
+{
+       newtPushHelpLine(msg);
+}
+
+static void ui_helpline__vpush(const char *fmt, va_list ap)
+{
+       char *s;
+
+       if (vasprintf(&s, fmt, ap) < 0)
+               vfprintf(stderr, fmt, ap);
+       else {
+               ui_helpline__push(s);
+               free(s);
+       }
+}
+
+static void ui_helpline__fpush(const char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       ui_helpline__vpush(fmt, ap);
+       va_end(ap);
+}
+
+static void ui_helpline__puts(const char *msg)
+{
+       ui_helpline__pop();
+       ui_helpline__push(msg);
+}
+
+static char browser__last_msg[1024];
+
+int browser__show_help(const char *format, va_list ap)
+{
+       int ret;
+       static int backlog;
+
+        ret = vsnprintf(browser__last_msg + backlog,
+                       sizeof(browser__last_msg) - backlog, format, ap);
+       backlog += ret;
+
+       if (browser__last_msg[backlog - 1] == '\n') {
+               ui_helpline__puts(browser__last_msg);
+               newtRefresh();
+               backlog = 0;
+       }
+
+       return ret;
+}
+
+static void newt_form__set_exit_keys(newtComponent self)
+{
+       newtFormAddHotKey(self, NEWT_KEY_LEFT);
+       newtFormAddHotKey(self, NEWT_KEY_ESCAPE);
+       newtFormAddHotKey(self, 'Q');
+       newtFormAddHotKey(self, 'q');
+       newtFormAddHotKey(self, CTRL('c'));
+}
+
+static newtComponent newt_form__new(void)
+{
+       newtComponent self = newtForm(NULL, NULL, 0);
+       if (self)
+               newt_form__set_exit_keys(self);
+       return self;
+}
+
+static int popup_menu(int argc, char * const argv[])
+{
+       struct newtExitStruct es;
+       int i, rc = -1, max_len = 5;
+       newtComponent listbox, form = newt_form__new();
+
+       if (form == NULL)
+               return -1;
+
+       listbox = newtListbox(0, 0, argc, NEWT_FLAG_RETURNEXIT);
+       if (listbox == NULL)
+               goto out_destroy_form;
+
+       newtFormAddComponent(form, listbox);
+
+       for (i = 0; i < argc; ++i) {
+               int len = strlen(argv[i]);
+               if (len > max_len)
+                       max_len = len;
+               if (newtListboxAddEntry(listbox, argv[i], (void *)(long)i))
+                       goto out_destroy_form;
+       }
+
+       newtCenteredWindow(max_len, argc, NULL);
+       newtFormRun(form, &es);
+       rc = newtListboxGetCurrent(listbox) - NULL;
+       if (es.reason == NEWT_EXIT_HOTKEY)
+               rc = -1;
+       newtPopWindow();
+out_destroy_form:
+       newtFormDestroy(form);
+       return rc;
+}
+
+static int ui__help_window(const char *text)
+{
+       struct newtExitStruct es;
+       newtComponent tb, form = newt_form__new();
+       int rc = -1;
+       int max_len = 0, nr_lines = 0;
+       const char *t;
+
+       if (form == NULL)
+               return -1;
+
+       t = text;
+       while (1) {
+               const char *sep = strchr(t, '\n');
+               int len;
+
+               if (sep == NULL)
+                       sep = strchr(t, '\0');
+               len = sep - t;
+               if (max_len < len)
+                       max_len = len;
+               ++nr_lines;
+               if (*sep == '\0')
+                       break;
+               t = sep + 1;
+       }
+
+       tb = newtTextbox(0, 0, max_len, nr_lines, 0);
+       if (tb == NULL)
+               goto out_destroy_form;
+
+       newtTextboxSetText(tb, text);
+       newtFormAddComponent(form, tb);
+       newtCenteredWindow(max_len, nr_lines, NULL);
+       newtFormRun(form, &es);
+       newtPopWindow();
+       rc = 0;
+out_destroy_form:
+       newtFormDestroy(form);
+       return rc;
+}
+
+static bool dialog_yesno(const char *msg)
+{
+       /* newtWinChoice should really be accepting const char pointers... */
+       char yes[] = "Yes", no[] = "No";
+       return newtWinChoice(NULL, yes, no, (char *)msg) == 1;
+}
+
+#define HE_COLORSET_TOP                50
+#define HE_COLORSET_MEDIUM     51
+#define HE_COLORSET_NORMAL     52
+#define HE_COLORSET_SELECTED   53
+#define HE_COLORSET_CODE       54
+
+static int ui_browser__percent_color(double percent, bool current)
+{
+       if (current)
+               return HE_COLORSET_SELECTED;
+       if (percent >= MIN_RED)
+               return HE_COLORSET_TOP;
+       if (percent >= MIN_GREEN)
+               return HE_COLORSET_MEDIUM;
+       return HE_COLORSET_NORMAL;
+}
+
+struct ui_browser {
+       newtComponent   form, sb;
+       u64             index, first_visible_entry_idx;
+       void            *first_visible_entry, *entries;
+       u16             top, left, width, height;
+       void            *priv;
+       u32             nr_entries;
+};
+
+static void ui_browser__refresh_dimensions(struct ui_browser *self)
+{
+       int cols, rows;
+       newtGetScreenSize(&cols, &rows);
+
+       if (self->width > cols - 4)
+               self->width = cols - 4;
+       self->height = rows - 5;
+       if (self->height > self->nr_entries)
+               self->height = self->nr_entries;
+       self->top  = (rows - self->height) / 2;
+       self->left = (cols - self->width) / 2;
+}
+
+static void ui_browser__reset_index(struct ui_browser *self)
+{
+        self->index = self->first_visible_entry_idx = 0;
+        self->first_visible_entry = NULL;
+}
+
+static int objdump_line__show(struct objdump_line *self, struct list_head *head,
+                             int width, struct hist_entry *he, int len,
+                             bool current_entry)
+{
+       if (self->offset != -1) {
+               struct symbol *sym = he->ms.sym;
+               unsigned int hits = 0;
+               double percent = 0.0;
+               int color;
+               struct sym_priv *priv = symbol__priv(sym);
+               struct sym_ext *sym_ext = priv->ext;
+               struct sym_hist *h = priv->hist;
+               s64 offset = self->offset;
+               struct objdump_line *next = objdump__get_next_ip_line(head, self);
+
+               while (offset < (s64)len &&
+                      (next == NULL || offset < next->offset)) {
+                       if (sym_ext) {
+                               percent += sym_ext[offset].percent;
+                       } else
+                               hits += h->ip[offset];
+
+                       ++offset;
+               }
+
+               if (sym_ext == NULL && h->sum)
+                       percent = 100.0 * hits / h->sum;
+
+               color = ui_browser__percent_color(percent, current_entry);
+               SLsmg_set_color(color);
+               slsmg_printf(" %7.2f ", percent);
+               if (!current_entry)
+                       SLsmg_set_color(HE_COLORSET_CODE);
+       } else {
+               int color = ui_browser__percent_color(0, current_entry);
+               SLsmg_set_color(color);
+               slsmg_write_nstring(" ", 9);
+       }
+
+       SLsmg_write_char(':');
+       slsmg_write_nstring(" ", 8);
+       if (!*self->line)
+               slsmg_write_nstring(" ", width - 18);
+       else
+               slsmg_write_nstring(self->line, width - 18);
+
+       return 0;
+}
+
+static int ui_browser__refresh_entries(struct ui_browser *self)
+{
+       struct objdump_line *pos;
+       struct list_head *head = self->entries;
+       struct hist_entry *he = self->priv;
+       int row = 0;
+       int len = he->ms.sym->end - he->ms.sym->start;
+
+       if (self->first_visible_entry == NULL || self->first_visible_entry == self->entries)
+                self->first_visible_entry = head->next;
+
+       pos = list_entry(self->first_visible_entry, struct objdump_line, node);
+
+       list_for_each_entry_from(pos, head, node) {
+               bool current_entry = (self->first_visible_entry_idx + row) == self->index;
+               SLsmg_gotorc(self->top + row, self->left);
+               objdump_line__show(pos, head, self->width,
+                                  he, len, current_entry);
+               if (++row == self->height)
+                       break;
+       }
+
+       SLsmg_set_color(HE_COLORSET_NORMAL);
+       SLsmg_fill_region(self->top + row, self->left,
+                         self->height - row, self->width, ' ');
+
+       return 0;
+}
+
+static int ui_browser__run(struct ui_browser *self, const char *title,
+                          struct newtExitStruct *es)
+{
+       if (self->form) {
+               newtFormDestroy(self->form);
+               newtPopWindow();
+       }
+
+       ui_browser__refresh_dimensions(self);
+       newtCenteredWindow(self->width + 2, self->height, title);
+       self->form = newt_form__new();
+       if (self->form == NULL)
+               return -1;
+
+       self->sb = newtVerticalScrollbar(self->width + 1, 0, self->height,
+                                        HE_COLORSET_NORMAL,
+                                        HE_COLORSET_SELECTED);
+       if (self->sb == NULL)
+               return -1;
+
+       newtFormAddHotKey(self->form, NEWT_KEY_UP);
+       newtFormAddHotKey(self->form, NEWT_KEY_DOWN);
+       newtFormAddHotKey(self->form, NEWT_KEY_PGUP);
+       newtFormAddHotKey(self->form, NEWT_KEY_PGDN);
+       newtFormAddHotKey(self->form, NEWT_KEY_HOME);
+       newtFormAddHotKey(self->form, NEWT_KEY_END);
+
+       if (ui_browser__refresh_entries(self) < 0)
+               return -1;
+       newtFormAddComponent(self->form, self->sb);
+
+       while (1) {
+               unsigned int offset;
+
+               newtFormRun(self->form, es);
+
+               if (es->reason != NEWT_EXIT_HOTKEY)
+                       break;
+               switch (es->u.key) {
+               case NEWT_KEY_DOWN:
+                       if (self->index == self->nr_entries - 1)
+                               break;
+                       ++self->index;
+                       if (self->index == self->first_visible_entry_idx + self->height) {
+                               struct list_head *pos = self->first_visible_entry;
+                               ++self->first_visible_entry_idx;
+                               self->first_visible_entry = pos->next;
+                       }
+                       break;
+               case NEWT_KEY_UP:
+                       if (self->index == 0)
+                               break;
+                       --self->index;
+                       if (self->index < self->first_visible_entry_idx) {
+                               struct list_head *pos = self->first_visible_entry;
+                               --self->first_visible_entry_idx;
+                               self->first_visible_entry = pos->prev;
+                       }
+                       break;
+               case NEWT_KEY_PGDN:
+                       if (self->first_visible_entry_idx + self->height > self->nr_entries - 1)
+                               break;
+
+                       offset = self->height;
+                       if (self->index + offset > self->nr_entries - 1)
+                               offset = self->nr_entries - 1 - self->index;
+                       self->index += offset;
+                       self->first_visible_entry_idx += offset;
+
+                       while (offset--) {
+                               struct list_head *pos = self->first_visible_entry;
+                               self->first_visible_entry = pos->next;
+                       }
+
+                       break;
+               case NEWT_KEY_PGUP:
+                       if (self->first_visible_entry_idx == 0)
+                               break;
+
+                       if (self->first_visible_entry_idx < self->height)
+                               offset = self->first_visible_entry_idx;
+                       else
+                               offset = self->height;
+
+                       self->index -= offset;
+                       self->first_visible_entry_idx -= offset;
+
+                       while (offset--) {
+                               struct list_head *pos = self->first_visible_entry;
+                               self->first_visible_entry = pos->prev;
+                       }
+                       break;
+               case NEWT_KEY_HOME:
+                       ui_browser__reset_index(self);
+                       break;
+               case NEWT_KEY_END: {
+                       struct list_head *head = self->entries;
+                       offset = self->height - 1;
+
+                       if (offset > self->nr_entries)
+                               offset = self->nr_entries;
+
+                       self->index = self->first_visible_entry_idx = self->nr_entries - 1 - offset;
+                       self->first_visible_entry = head->prev;
+                       while (offset-- != 0) {
+                               struct list_head *pos = self->first_visible_entry;
+                               self->first_visible_entry = pos->prev;
+                       }
+               }
+                       break;
+               case NEWT_KEY_ESCAPE:
+               case NEWT_KEY_LEFT:
+               case CTRL('c'):
+               case 'Q':
+               case 'q':
+                       return 0;
+               default:
+                       continue;
+               }
+               if (ui_browser__refresh_entries(self) < 0)
+                       return -1;
+       }
+       return 0;
+}
+
+/*
+ * When debugging newt problems it was useful to be able to "unroll"
+ * the calls to newtCheckBoxTreeAdd{Array,Item}, so that we can generate
+ * a source file with the sequence of calls to these methods, to then
+ * tweak the arrays to get the intended results, so I'm keeping this code
+ * here, may be useful again in the future.
+ */
+#undef NEWT_DEBUG
+
+static void newt_checkbox_tree__add(newtComponent tree, const char *str,
+                                   void *priv, int *indexes)
+{
+#ifdef NEWT_DEBUG
+       /* Print the newtCheckboxTreeAddArray to tinker with its index arrays */
+       int i = 0, len = 40 - strlen(str);
+
+       fprintf(stderr,
+               "\tnewtCheckboxTreeAddItem(tree, %*.*s\"%s\", (void *)%p, 0, ",
+               len, len, " ", str, priv);
+       while (indexes[i] != NEWT_ARG_LAST) {
+               if (indexes[i] != NEWT_ARG_APPEND)
+                       fprintf(stderr, " %d,", indexes[i]);
+               else
+                       fprintf(stderr, " %s,", "NEWT_ARG_APPEND");
+               ++i;
+       }
+       fprintf(stderr, " %s", " NEWT_ARG_LAST);\n");
+       fflush(stderr);
+#endif
+       newtCheckboxTreeAddArray(tree, str, priv, 0, indexes);
+}
+
+static char *callchain_list__sym_name(struct callchain_list *self,
+                                     char *bf, size_t bfsize)
+{
+       if (self->ms.sym)
+               return self->ms.sym->name;
+
+       snprintf(bf, bfsize, "%#Lx", self->ip);
+       return bf;
+}
+
+static void __callchain__append_graph_browser(struct callchain_node *self,
+                                             newtComponent tree, u64 total,
+                                             int *indexes, int depth)
+{
+       struct rb_node *node;
+       u64 new_total, remaining;
+       int idx = 0;
+
+       if (callchain_param.mode == CHAIN_GRAPH_REL)
+               new_total = self->children_hit;
+       else
+               new_total = total;
+
+       remaining = new_total;
+       node = rb_first(&self->rb_root);
+       while (node) {
+               struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
+               struct rb_node *next = rb_next(node);
+               u64 cumul = cumul_hits(child);
+               struct callchain_list *chain;
+               int first = true, printed = 0;
+               int chain_idx = -1;
+               remaining -= cumul;
+
+               indexes[depth] = NEWT_ARG_APPEND;
+               indexes[depth + 1] = NEWT_ARG_LAST;
+
+               list_for_each_entry(chain, &child->val, list) {
+                       char ipstr[BITS_PER_LONG / 4 + 1],
+                            *alloc_str = NULL;
+                       const char *str = callchain_list__sym_name(chain, ipstr, sizeof(ipstr));
+
+                       if (first) {
+                               double percent = cumul * 100.0 / new_total;
+
+                               first = false;
+                               if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0)
+                                       str = "Not enough memory!";
+                               else
+                                       str = alloc_str;
+                       } else {
+                               indexes[depth] = idx;
+                               indexes[depth + 1] = NEWT_ARG_APPEND;
+                               indexes[depth + 2] = NEWT_ARG_LAST;
+                               ++chain_idx;
+                       }
+                       newt_checkbox_tree__add(tree, str, &chain->ms, indexes);
+                       free(alloc_str);
+                       ++printed;
+               }
+
+               indexes[depth] = idx;
+               if (chain_idx != -1)
+                       indexes[depth + 1] = chain_idx;
+               if (printed != 0)
+                       ++idx;
+               __callchain__append_graph_browser(child, tree, new_total, indexes,
+                                                 depth + (chain_idx != -1 ? 2 : 1));
+               node = next;
+       }
+}
+
+static void callchain__append_graph_browser(struct callchain_node *self,
+                                           newtComponent tree, u64 total,
+                                           int *indexes, int parent_idx)
+{
+       struct callchain_list *chain;
+       int i = 0;
+
+       indexes[1] = NEWT_ARG_APPEND;
+       indexes[2] = NEWT_ARG_LAST;
+
+       list_for_each_entry(chain, &self->val, list) {
+               char ipstr[BITS_PER_LONG / 4 + 1], *str;
+
+               if (chain->ip >= PERF_CONTEXT_MAX)
+                       continue;
+
+               if (!i++ && sort__first_dimension == SORT_SYM)
+                       continue;
+
+               str = callchain_list__sym_name(chain, ipstr, sizeof(ipstr));
+               newt_checkbox_tree__add(tree, str, &chain->ms, indexes);
+       }
+
+       indexes[1] = parent_idx;
+       indexes[2] = NEWT_ARG_APPEND;
+       indexes[3] = NEWT_ARG_LAST;
+       __callchain__append_graph_browser(self, tree, total, indexes, 2);
+}
+
+static void hist_entry__append_callchain_browser(struct hist_entry *self,
+                                                newtComponent tree, u64 total, int parent_idx)
+{
+       struct rb_node *rb_node;
+       int indexes[1024] = { [0] = parent_idx, };
+       int idx = 0;
+       struct callchain_node *chain;
+
+       rb_node = rb_first(&self->sorted_chain);
+       while (rb_node) {
+               chain = rb_entry(rb_node, struct callchain_node, rb_node);
+               switch (callchain_param.mode) {
+               case CHAIN_FLAT:
+                       break;
+               case CHAIN_GRAPH_ABS: /* falldown */
+               case CHAIN_GRAPH_REL:
+                       callchain__append_graph_browser(chain, tree, total, indexes, idx++);
+                       break;
+               case CHAIN_NONE:
+               default:
+                       break;
+               }
+               rb_node = rb_next(rb_node);
+       }
+}
+
+static size_t hist_entry__append_browser(struct hist_entry *self,
+                                        newtComponent tree, u64 total)
+{
+       char s[256];
+       size_t ret;
+
+       if (symbol_conf.exclude_other && !self->parent)
+               return 0;
+
+       ret = hist_entry__snprintf(self, s, sizeof(s), NULL,
+                                  false, 0, false, total);
+       if (symbol_conf.use_callchain) {
+               int indexes[2];
+
+               indexes[0] = NEWT_ARG_APPEND;
+               indexes[1] = NEWT_ARG_LAST;
+               newt_checkbox_tree__add(tree, s, &self->ms, indexes);
+       } else
+               newtListboxAppendEntry(tree, s, &self->ms);
+
+       return ret;
+}
+
+static void hist_entry__annotate_browser(struct hist_entry *self)
+{
+       struct ui_browser browser;
+       struct newtExitStruct es;
+       struct objdump_line *pos, *n;
+       LIST_HEAD(head);
+
+       if (self->ms.sym == NULL)
+               return;
+
+       if (hist_entry__annotate(self, &head) < 0)
+               return;
+
+       ui_helpline__push("Press <- or ESC to exit");
+
+       memset(&browser, 0, sizeof(browser));
+       browser.entries = &head;
+       browser.priv = self;
+       list_for_each_entry(pos, &head, node) {
+               size_t line_len = strlen(pos->line);
+               if (browser.width < line_len)
+                       browser.width = line_len;
+               ++browser.nr_entries;
+       }
+
+       browser.width += 18; /* Percentage */
+       ui_browser__run(&browser, self->ms.sym->name, &es);
+       newtFormDestroy(browser.form);
+       newtPopWindow();
+       list_for_each_entry_safe(pos, n, &head, node) {
+               list_del(&pos->node);
+               objdump_line__free(pos);
+       }
+       ui_helpline__pop();
+}
+
+static const void *newt__symbol_tree_get_current(newtComponent self)
+{
+       if (symbol_conf.use_callchain)
+               return newtCheckboxTreeGetCurrent(self);
+       return newtListboxGetCurrent(self);
+}
+
+static void hist_browser__selection(newtComponent self, void *data)
+{
+       const struct map_symbol **symbol_ptr = data;
+       *symbol_ptr = newt__symbol_tree_get_current(self);
+}
+
+struct hist_browser {
+       newtComponent           form, tree;
+       const struct map_symbol *selection;
+};
+
+static struct hist_browser *hist_browser__new(void)
+{
+       struct hist_browser *self = malloc(sizeof(*self));
+
+       if (self != NULL)
+               self->form = NULL;
+
+       return self;
+}
+
+static void hist_browser__delete(struct hist_browser *self)
+{
+       newtFormDestroy(self->form);
+       newtPopWindow();
+       free(self);
+}
+
+static int hist_browser__populate(struct hist_browser *self, struct hists *hists,
+                                 const char *title)
+{
+       int max_len = 0, idx, cols, rows;
+       struct ui_progress *progress;
+       struct rb_node *nd;
+       u64 curr_hist = 0;
+       char seq[] = ".", unit;
+       char str[256];
+       unsigned long nr_events = hists->stats.nr_events[PERF_RECORD_SAMPLE];
+
+       if (self->form) {
+               newtFormDestroy(self->form);
+               newtPopWindow();
+       }
+
+       nr_events = convert_unit(nr_events, &unit);
+       snprintf(str, sizeof(str), "Events: %lu%c                            ",
+                nr_events, unit);
+       newtDrawRootText(0, 0, str);
+
+       newtGetScreenSize(NULL, &rows);
+
+       if (symbol_conf.use_callchain)
+               self->tree = newtCheckboxTreeMulti(0, 0, rows - 5, seq,
+                                                  NEWT_FLAG_SCROLL);
+       else
+               self->tree = newtListbox(0, 0, rows - 5,
+                                       (NEWT_FLAG_SCROLL |
+                                        NEWT_FLAG_RETURNEXIT));
+
+       newtComponentAddCallback(self->tree, hist_browser__selection,
+                                &self->selection);
+
+       progress = ui_progress__new("Adding entries to the browser...",
+                                   hists->nr_entries);
+       if (progress == NULL)
+               return -1;
+
+       idx = 0;
+       for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
+               struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
+               int len;
+
+               if (h->filtered)
+                       continue;
+
+               len = hist_entry__append_browser(h, self->tree, hists->stats.total_period);
+               if (len > max_len)
+                       max_len = len;
+               if (symbol_conf.use_callchain)
+                       hist_entry__append_callchain_browser(h, self->tree,
+                                                            hists->stats.total_period, idx++);
+               ++curr_hist;
+               if (curr_hist % 5)
+                       ui_progress__update(progress, curr_hist);
+       }
+
+       ui_progress__delete(progress);
+
+       newtGetScreenSize(&cols, &rows);
+
+       if (max_len > cols)
+               max_len = cols - 3;
+
+       if (!symbol_conf.use_callchain)
+               newtListboxSetWidth(self->tree, max_len);
+
+       newtCenteredWindow(max_len + (symbol_conf.use_callchain ? 5 : 0),
+                          rows - 5, title);
+       self->form = newt_form__new();
+       if (self->form == NULL)
+               return -1;
+
+       newtFormAddHotKey(self->form, 'A');
+       newtFormAddHotKey(self->form, 'a');
+       newtFormAddHotKey(self->form, 'D');
+       newtFormAddHotKey(self->form, 'd');
+       newtFormAddHotKey(self->form, 'T');
+       newtFormAddHotKey(self->form, 't');
+       newtFormAddHotKey(self->form, '?');
+       newtFormAddHotKey(self->form, 'H');
+       newtFormAddHotKey(self->form, 'h');
+       newtFormAddHotKey(self->form, NEWT_KEY_F1);
+       newtFormAddHotKey(self->form, NEWT_KEY_RIGHT);
+       newtFormAddComponents(self->form, self->tree, NULL);
+       self->selection = newt__symbol_tree_get_current(self->tree);
+
+       return 0;
+}
+
+static struct hist_entry *hist_browser__selected_entry(struct hist_browser *self)
+{
+       int *indexes;
+
+       if (!symbol_conf.use_callchain)
+               goto out;
+
+       indexes = newtCheckboxTreeFindItem(self->tree, (void *)self->selection);
+       if (indexes) {
+               bool is_hist_entry = indexes[1] == NEWT_ARG_LAST;
+               free(indexes);
+               if (is_hist_entry)
+                       goto out;
+       }
+       return NULL;
+out:
+       return container_of(self->selection, struct hist_entry, ms);
+}
+
+static struct thread *hist_browser__selected_thread(struct hist_browser *self)
+{
+       struct hist_entry *he = hist_browser__selected_entry(self);
+       return he ? he->thread : NULL;
+}
+
+static int hist_browser__title(char *bf, size_t size, const char *input_name,
+                              const struct dso *dso, const struct thread *thread)
+{
+       int printed = 0;
+
+       if (thread)
+               printed += snprintf(bf + printed, size - printed,
+                                   "Thread: %s(%d)",
+                                   (thread->comm_set ?  thread->comm : ""),
+                                   thread->pid);
+       if (dso)
+               printed += snprintf(bf + printed, size - printed,
+                                   "%sDSO: %s", thread ? " " : "",
+                                   dso->short_name);
+       return printed ?: snprintf(bf, size, "Report: %s", input_name);
+}
+
+int hists__browse(struct hists *self, const char *helpline, const char *input_name)
+{
+       struct hist_browser *browser = hist_browser__new();
+       struct pstack *fstack = pstack__new(2);
+       const struct thread *thread_filter = NULL;
+       const struct dso *dso_filter = NULL;
+       struct newtExitStruct es;
+       char msg[160];
+       int err = -1;
+
+       if (browser == NULL)
+               return -1;
+
+       fstack = pstack__new(2);
+       if (fstack == NULL)
+               goto out;
+
+       ui_helpline__push(helpline);
+
+       hist_browser__title(msg, sizeof(msg), input_name,
+                           dso_filter, thread_filter);
+       if (hist_browser__populate(browser, self, msg) < 0)
+               goto out_free_stack;
+
+       while (1) {
+               const struct thread *thread;
+               const struct dso *dso;
+               char *options[16];
+               int nr_options = 0, choice = 0, i,
+                   annotate = -2, zoom_dso = -2, zoom_thread = -2;
+
+               newtFormRun(browser->form, &es);
+
+               thread = hist_browser__selected_thread(browser);
+               dso = browser->selection->map ? browser->selection->map->dso : NULL;
+
+               if (es.reason == NEWT_EXIT_HOTKEY) {
+                       if (es.u.key == NEWT_KEY_F1)
+                               goto do_help;
+
+                       switch (toupper(es.u.key)) {
+                       case 'A':
+                               goto do_annotate;
+                       case 'D':
+                               goto zoom_dso;
+                       case 'T':
+                               goto zoom_thread;
+                       case 'H':
+                       case '?':
+do_help:
+                               ui__help_window("->        Zoom into DSO/Threads & Annotate current symbol\n"
+                                               "<-        Zoom out\n"
+                                               "a         Annotate current symbol\n"
+                                               "h/?/F1    Show this window\n"
+                                               "d         Zoom into current DSO\n"
+                                               "t         Zoom into current Thread\n"
+                                               "q/CTRL+C  Exit browser");
+                               continue;
+                       default:;
+                       }
+                       if (toupper(es.u.key) == 'Q' ||
+                           es.u.key == CTRL('c'))
+                               break;
+                       if (es.u.key == NEWT_KEY_ESCAPE) {
+                               if (dialog_yesno("Do you really want to exit?"))
+                                       break;
+                               else
+                                       continue;
+                       }
+
+                       if (es.u.key == NEWT_KEY_LEFT) {
+                               const void *top;
+
+                               if (pstack__empty(fstack))
+                                       continue;
+                               top = pstack__pop(fstack);
+                               if (top == &dso_filter)
+                                       goto zoom_out_dso;
+                               if (top == &thread_filter)
+                                       goto zoom_out_thread;
+                               continue;
+                       }
+               }
+
+               if (browser->selection->sym != NULL &&
+                   asprintf(&options[nr_options], "Annotate %s",
+                            browser->selection->sym->name) > 0)
+                       annotate = nr_options++;
+
+               if (thread != NULL &&
+                   asprintf(&options[nr_options], "Zoom %s %s(%d) thread",
+                            (thread_filter ? "out of" : "into"),
+                            (thread->comm_set ? thread->comm : ""),
+                            thread->pid) > 0)
+                       zoom_thread = nr_options++;
+
+               if (dso != NULL &&
+                   asprintf(&options[nr_options], "Zoom %s %s DSO",
+                            (dso_filter ? "out of" : "into"),
+                            (dso->kernel ? "the Kernel" : dso->short_name)) > 0)
+                       zoom_dso = nr_options++;
+
+               options[nr_options++] = (char *)"Exit";
+
+               choice = popup_menu(nr_options, options);
+
+               for (i = 0; i < nr_options - 1; ++i)
+                       free(options[i]);
+
+               if (choice == nr_options - 1)
+                       break;
+
+               if (choice == -1)
+                       continue;
+
+               if (choice == annotate) {
+                       struct hist_entry *he;
+do_annotate:
+                       if (browser->selection->map->dso->origin == DSO__ORIG_KERNEL) {
+                               ui_helpline__puts("No vmlinux file found, can't "
+                                                "annotate with just a "
+                                                "kallsyms file");
+                               continue;
+                       }
+
+                       he = hist_browser__selected_entry(browser);
+                       if (he == NULL)
+                               continue;
+
+                       hist_entry__annotate_browser(he);
+               } else if (choice == zoom_dso) {
+zoom_dso:
+                       if (dso_filter) {
+                               pstack__remove(fstack, &dso_filter);
+zoom_out_dso:
+                               ui_helpline__pop();
+                               dso_filter = NULL;
+                       } else {
+                               if (dso == NULL)
+                                       continue;
+                               ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s DSO\"",
+                                                  dso->kernel ? "the Kernel" : dso->short_name);
+                               dso_filter = dso;
+                               pstack__push(fstack, &dso_filter);
+                       }
+                       hists__filter_by_dso(self, dso_filter);
+                       hist_browser__title(msg, sizeof(msg), input_name,
+                                           dso_filter, thread_filter);
+                       if (hist_browser__populate(browser, self, msg) < 0)
+                               goto out;
+               } else if (choice == zoom_thread) {
+zoom_thread:
+                       if (thread_filter) {
+                               pstack__remove(fstack, &thread_filter);
+zoom_out_thread:
+                               ui_helpline__pop();
+                               thread_filter = NULL;
+                       } else {
+                               ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s(%d) thread\"",
+                                                  thread->comm_set ? thread->comm : "",
+                                                  thread->pid);
+                               thread_filter = thread;
+                               pstack__push(fstack, &thread_filter);
+                       }
+                       hists__filter_by_thread(self, thread_filter);
+                       hist_browser__title(msg, sizeof(msg), input_name,
+                                           dso_filter, thread_filter);
+                       if (hist_browser__populate(browser, self, msg) < 0)
+                               goto out;
+               }
+       }
+       err = 0;
+out_free_stack:
+       pstack__delete(fstack);
+out:
+       hist_browser__delete(browser);
+       return err;
+}
+
+static struct newtPercentTreeColors {
+       const char *topColorFg, *topColorBg;
+       const char *mediumColorFg, *mediumColorBg;
+       const char *normalColorFg, *normalColorBg;
+       const char *selColorFg, *selColorBg;
+       const char *codeColorFg, *codeColorBg;
+} defaultPercentTreeColors = {
+       "red",       "lightgray",
+       "green",     "lightgray",
+       "black",     "lightgray",
+       "lightgray", "magenta",
+       "blue",      "lightgray",
+};
+
+void setup_browser(void)
+{
+       struct newtPercentTreeColors *c = &defaultPercentTreeColors;
+       if (!isatty(1))
+               return;
+
+       use_browser = true;
+       newtInit();
+       newtCls();
+       ui_helpline__puts(" ");
+       sltt_set_color(HE_COLORSET_TOP, NULL, c->topColorFg, c->topColorBg);
+       sltt_set_color(HE_COLORSET_MEDIUM, NULL, c->mediumColorFg, c->mediumColorBg);
+       sltt_set_color(HE_COLORSET_NORMAL, NULL, c->normalColorFg, c->normalColorBg);
+       sltt_set_color(HE_COLORSET_SELECTED, NULL, c->selColorFg, c->selColorBg);
+       sltt_set_color(HE_COLORSET_CODE, NULL, c->codeColorFg, c->codeColorBg);
+}
+
+void exit_browser(bool wait_for_ok)
+{
+       if (use_browser) {
+               if (wait_for_ok) {
+                       char title[] = "Fatal Error", ok[] = "Ok";
+                       newtWinMessage(title, ok, browser__last_msg);
+               }
+               newtFinished();
+       }
+}
index 05d0c5c2030cbd5d8bfac67c00fc341404419465..9bf0f402ca730a938d79ddf2121ed822ff12de92 100644 (file)
@@ -5,6 +5,7 @@
 #include "parse-events.h"
 #include "exec_cmd.h"
 #include "string.h"
+#include "symbol.h"
 #include "cache.h"
 #include "header.h"
 #include "debugfs.h"
@@ -409,7 +410,6 @@ static enum event_result
 parse_single_tracepoint_event(char *sys_name,
                              const char *evt_name,
                              unsigned int evt_length,
-                             char *flags,
                              struct perf_event_attr *attr,
                              const char **strp)
 {
@@ -418,14 +418,6 @@ parse_single_tracepoint_event(char *sys_name,
        u64 id;
        int fd;
 
-       if (flags) {
-               if (!strncmp(flags, "record", strlen(flags))) {
-                       attr->sample_type |= PERF_SAMPLE_RAW;
-                       attr->sample_type |= PERF_SAMPLE_TIME;
-                       attr->sample_type |= PERF_SAMPLE_CPU;
-               }
-       }
-
        snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path,
                 sys_name, evt_name);
 
@@ -444,6 +436,13 @@ parse_single_tracepoint_event(char *sys_name,
        attr->type = PERF_TYPE_TRACEPOINT;
        *strp = evt_name + evt_length;
 
+       attr->sample_type |= PERF_SAMPLE_RAW;
+       attr->sample_type |= PERF_SAMPLE_TIME;
+       attr->sample_type |= PERF_SAMPLE_CPU;
+
+       attr->sample_period = 1;
+
+
        return EVT_HANDLED;
 }
 
@@ -532,8 +531,7 @@ static enum event_result parse_tracepoint_event(const char **strp,
                                                       flags);
        } else
                return parse_single_tracepoint_event(sys_name, evt_name,
-                                                    evt_length, flags,
-                                                    attr, strp);
+                                                    evt_length, attr, strp);
 }
 
 static enum event_result
@@ -690,19 +688,29 @@ static enum event_result
 parse_event_modifier(const char **strp, struct perf_event_attr *attr)
 {
        const char *str = *strp;
-       int eu = 1, ek = 1, eh = 1;
+       int exclude = 0;
+       int eu = 0, ek = 0, eh = 0, precise = 0;
 
        if (*str++ != ':')
                return 0;
        while (*str) {
-               if (*str == 'u')
+               if (*str == 'u') {
+                       if (!exclude)
+                               exclude = eu = ek = eh = 1;
                        eu = 0;
-               else if (*str == 'k')
+               } else if (*str == 'k') {
+                       if (!exclude)
+                               exclude = eu = ek = eh = 1;
                        ek = 0;
-               else if (*str == 'h')
+               } else if (*str == 'h') {
+                       if (!exclude)
+                               exclude = eu = ek = eh = 1;
                        eh = 0;
-               else
+               } else if (*str == 'p') {
+                       precise++;
+               } else
                        break;
+
                ++str;
        }
        if (str >= *strp + 2) {
@@ -710,6 +718,7 @@ parse_event_modifier(const char **strp, struct perf_event_attr *attr)
                attr->exclude_user   = eu;
                attr->exclude_kernel = ek;
                attr->exclude_hv     = eh;
+               attr->precise_ip     = precise;
                return 1;
        }
        return 0;
@@ -934,7 +943,8 @@ void print_events(void)
 
        printf("\n");
        printf("  %-42s [%s]\n",
-               "rNNN", event_type_descriptors[PERF_TYPE_RAW]);
+               "rNNN (see 'perf list --help' on how to encode it)",
+              event_type_descriptors[PERF_TYPE_RAW]);
        printf("\n");
 
        printf("  %-42s [%s]\n",
index b8c1f64bc9351ac7f889340c20eb7755614f5227..fc4ab3fe877a22d191450a6bc4c75118cf71901d 100644 (file)
@@ -13,6 +13,7 @@ struct tracepoint_path {
 };
 
 extern struct tracepoint_path *tracepoint_id_to_path(u64 config);
+extern bool have_tracepoints(struct perf_event_attr *pattrs, int nb_events);
 
 extern int                     nr_counters;
 
index efebd5b476b320685178947332a48214d76529b5..99d02aa57dbf19a8c0cb1a1a3a900486ef956b65 100644 (file)
@@ -49,8 +49,9 @@ static int get_value(struct parse_opt_ctx_t *p,
                                break;
                        /* FALLTHROUGH */
                case OPTION_BOOLEAN:
+               case OPTION_INCR:
                case OPTION_BIT:
-               case OPTION_SET_INT:
+               case OPTION_SET_UINT:
                case OPTION_SET_PTR:
                        return opterror(opt, "takes no value", flags);
                case OPTION_END:
@@ -58,7 +59,9 @@ static int get_value(struct parse_opt_ctx_t *p,
                case OPTION_GROUP:
                case OPTION_STRING:
                case OPTION_INTEGER:
+               case OPTION_UINTEGER:
                case OPTION_LONG:
+               case OPTION_U64:
                default:
                        break;
                }
@@ -73,11 +76,15 @@ static int get_value(struct parse_opt_ctx_t *p,
                return 0;
 
        case OPTION_BOOLEAN:
+               *(bool *)opt->value = unset ? false : true;
+               return 0;
+
+       case OPTION_INCR:
                *(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
                return 0;
 
-       case OPTION_SET_INT:
-               *(int *)opt->value = unset ? 0 : opt->defval;
+       case OPTION_SET_UINT:
+               *(unsigned int *)opt->value = unset ? 0 : opt->defval;
                return 0;
 
        case OPTION_SET_PTR:
@@ -120,6 +127,22 @@ static int get_value(struct parse_opt_ctx_t *p,
                        return opterror(opt, "expects a numerical value", flags);
                return 0;
 
+       case OPTION_UINTEGER:
+               if (unset) {
+                       *(unsigned int *)opt->value = 0;
+                       return 0;
+               }
+               if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
+                       *(unsigned int *)opt->value = opt->defval;
+                       return 0;
+               }
+               if (get_arg(p, opt, flags, &arg))
+                       return -1;
+               *(unsigned int *)opt->value = strtol(arg, (char **)&s, 10);
+               if (*s)
+                       return opterror(opt, "expects a numerical value", flags);
+               return 0;
+
        case OPTION_LONG:
                if (unset) {
                        *(long *)opt->value = 0;
@@ -136,6 +159,22 @@ static int get_value(struct parse_opt_ctx_t *p,
                        return opterror(opt, "expects a numerical value", flags);
                return 0;
 
+       case OPTION_U64:
+               if (unset) {
+                       *(u64 *)opt->value = 0;
+                       return 0;
+               }
+               if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
+                       *(u64 *)opt->value = opt->defval;
+                       return 0;
+               }
+               if (get_arg(p, opt, flags, &arg))
+                       return -1;
+               *(u64 *)opt->value = strtoull(arg, (char **)&s, 10);
+               if (*s)
+                       return opterror(opt, "expects a numerical value", flags);
+               return 0;
+
        case OPTION_END:
        case OPTION_ARGUMENT:
        case OPTION_GROUP:
@@ -441,7 +480,10 @@ int usage_with_options_internal(const char * const *usagestr,
                switch (opts->type) {
                case OPTION_ARGUMENT:
                        break;
+               case OPTION_LONG:
+               case OPTION_U64:
                case OPTION_INTEGER:
+               case OPTION_UINTEGER:
                        if (opts->flags & PARSE_OPT_OPTARG)
                                if (opts->long_name)
                                        pos += fprintf(stderr, "[=<n>]");
@@ -473,14 +515,14 @@ int usage_with_options_internal(const char * const *usagestr,
                                        pos += fprintf(stderr, " ...");
                        }
                        break;
-               default: /* OPTION_{BIT,BOOLEAN,SET_INT,SET_PTR} */
+               default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
                case OPTION_END:
                case OPTION_GROUP:
                case OPTION_BIT:
                case OPTION_BOOLEAN:
-               case OPTION_SET_INT:
+               case OPTION_INCR:
+               case OPTION_SET_UINT:
                case OPTION_SET_PTR:
-               case OPTION_LONG:
                        break;
                }
 
@@ -500,6 +542,7 @@ int usage_with_options_internal(const char * const *usagestr,
 void usage_with_options(const char * const *usagestr,
                        const struct option *opts)
 {
+       exit_browser(false);
        usage_with_options_internal(usagestr, opts, 0);
        exit(129);
 }
index 948805af43c21e45296c6caa8adda25106a66423..c7d72dce54b2cf7c3f46042bd6ce6a68c941b4d6 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef __PERF_PARSE_OPTIONS_H
 #define __PERF_PARSE_OPTIONS_H
 
+#include <linux/kernel.h>
+#include <stdbool.h>
+
 enum parse_opt_type {
        /* special types */
        OPTION_END,
@@ -8,14 +11,17 @@ enum parse_opt_type {
        OPTION_GROUP,
        /* options with no arguments */
        OPTION_BIT,
-       OPTION_BOOLEAN, /* _INCR would have been a better name */
-       OPTION_SET_INT,
+       OPTION_BOOLEAN,
+       OPTION_INCR,
+       OPTION_SET_UINT,
        OPTION_SET_PTR,
        /* options with arguments (usually) */
        OPTION_STRING,
        OPTION_INTEGER,
        OPTION_LONG,
        OPTION_CALLBACK,
+       OPTION_U64,
+       OPTION_UINTEGER,
 };
 
 enum parse_opt_flags {
@@ -73,7 +79,7 @@ typedef int parse_opt_cb(const struct option *, const char *arg, int unset);
  *
  * `defval`::
  *   default value to fill (*->value) with for PARSE_OPT_OPTARG.
- *   OPTION_{BIT,SET_INT,SET_PTR} store the {mask,integer,pointer} to put in
+ *   OPTION_{BIT,SET_UINT,SET_PTR} store the {mask,integer,pointer} to put in
  *   the value when met.
  *   CALLBACKS can use it like they want.
  */
@@ -90,16 +96,21 @@ struct option {
        intptr_t defval;
 };
 
+#define check_vtype(v, type) ( BUILD_BUG_ON_ZERO(!__builtin_types_compatible_p(typeof(v), type)) + v )
+
 #define OPT_END()                   { .type = OPTION_END }
 #define OPT_ARGUMENT(l, h)          { .type = OPTION_ARGUMENT, .long_name = (l), .help = (h) }
 #define OPT_GROUP(h)                { .type = OPTION_GROUP, .help = (h) }
-#define OPT_BIT(s, l, v, h, b)      { .type = OPTION_BIT, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (b) }
-#define OPT_BOOLEAN(s, l, v, h)     { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), .value = (v), .help = (h) }
-#define OPT_SET_INT(s, l, v, h, i)  { .type = OPTION_SET_INT, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (i) }
+#define OPT_BIT(s, l, v, h, b)      { .type = OPTION_BIT, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h), .defval = (b) }
+#define OPT_BOOLEAN(s, l, v, h)     { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), .value = check_vtype(v, bool *), .help = (h) }
+#define OPT_INCR(s, l, v, h)        { .type = OPTION_INCR, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h) }
+#define OPT_SET_UINT(s, l, v, h, i)  { .type = OPTION_SET_UINT, .short_name = (s), .long_name = (l), .value = check_vtype(v, unsigned int *), .help = (h), .defval = (i) }
 #define OPT_SET_PTR(s, l, v, h, p)  { .type = OPTION_SET_PTR, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (p) }
-#define OPT_INTEGER(s, l, v, h)     { .type = OPTION_INTEGER, .short_name = (s), .long_name = (l), .value = (v), .help = (h) }
-#define OPT_LONG(s, l, v, h)        { .type = OPTION_LONG, .short_name = (s), .long_name = (l), .value = (v), .help = (h) }
-#define OPT_STRING(s, l, v, a, h)   { .type = OPTION_STRING,  .short_name = (s), .long_name = (l), .value = (v), (a), .help = (h) }
+#define OPT_INTEGER(s, l, v, h)     { .type = OPTION_INTEGER, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h) }
+#define OPT_UINTEGER(s, l, v, h)    { .type = OPTION_UINTEGER, .short_name = (s), .long_name = (l), .value = check_vtype(v, unsigned int *), .help = (h) }
+#define OPT_LONG(s, l, v, h)        { .type = OPTION_LONG, .short_name = (s), .long_name = (l), .value = check_vtype(v, long *), .help = (h) }
+#define OPT_U64(s, l, v, h)         { .type = OPTION_U64, .short_name = (s), .long_name = (l), .value = check_vtype(v, u64 *), .help = (h) }
+#define OPT_STRING(s, l, v, a, h)   { .type = OPTION_STRING,  .short_name = (s), .long_name = (l), .value = check_vtype(v, const char **), (a), .help = (h) }
 #define OPT_DATE(s, l, v, h) \
        { .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb }
 #define OPT_CALLBACK(s, l, v, a, h, f) \
index 53181dbfe4a8dae101a279a40f10654865c90796..914c67095d965d14ca7ca8b1c58f37ba83b9573c 100644 (file)
 #include <limits.h>
 
 #undef _GNU_SOURCE
+#include "util.h"
 #include "event.h"
 #include "string.h"
 #include "strlist.h"
 #include "debug.h"
 #include "cache.h"
 #include "color.h"
-#include "parse-events.h"  /* For debugfs_path */
+#include "symbol.h"
+#include "thread.h"
+#include "debugfs.h"
+#include "trace-event.h"       /* For __unused */
 #include "probe-event.h"
+#include "probe-finder.h"
 
 #define MAX_CMDLEN 256
 #define MAX_PROBE_ARGS 128
 #define PERFPROBE_GROUP "probe"
 
-#define semantic_error(msg ...) die("Semantic error :" msg)
+bool probe_event_dry_run;      /* Dry run flag */
+
+#define semantic_error(msg ...) pr_err("Semantic error :" msg)
 
 /* If there is no space to write, returns -E2BIG. */
 static int e_snprintf(char *str, size_t size, const char *format, ...)
@@ -64,7 +71,275 @@ static int e_snprintf(char *str, size_t size, const char *format, ...)
        return ret;
 }
 
-void parse_line_range_desc(const char *arg, struct line_range *lr)
+static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
+static struct machine machine;
+
+/* Initialize symbol maps and path of vmlinux */
+static int init_vmlinux(void)
+{
+       struct dso *kernel;
+       int ret;
+
+       symbol_conf.sort_by_name = true;
+       if (symbol_conf.vmlinux_name == NULL)
+               symbol_conf.try_vmlinux_path = true;
+       else
+               pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
+       ret = symbol__init();
+       if (ret < 0) {
+               pr_debug("Failed to init symbol map.\n");
+               goto out;
+       }
+
+       ret = machine__init(&machine, "/", 0);
+       if (ret < 0)
+               goto out;
+
+       kernel = dso__new_kernel(symbol_conf.vmlinux_name);
+       if (kernel == NULL)
+               die("Failed to create kernel dso.");
+
+       ret = __machine__create_kernel_maps(&machine, kernel);
+       if (ret < 0)
+               pr_debug("Failed to create kernel maps.\n");
+
+out:
+       if (ret < 0)
+               pr_warning("Failed to init vmlinux path.\n");
+       return ret;
+}
+
+#ifdef DWARF_SUPPORT
+static int open_vmlinux(void)
+{
+       if (map__load(machine.vmlinux_maps[MAP__FUNCTION], NULL) < 0) {
+               pr_debug("Failed to load kernel map.\n");
+               return -EINVAL;
+       }
+       pr_debug("Try to open %s\n", machine.vmlinux_maps[MAP__FUNCTION]->dso->long_name);
+       return open(machine.vmlinux_maps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
+}
+
+/* Convert trace point to probe point with debuginfo */
+static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
+                                      struct perf_probe_point *pp)
+{
+       struct symbol *sym;
+       int fd, ret = -ENOENT;
+
+       sym = map__find_symbol_by_name(machine.vmlinux_maps[MAP__FUNCTION],
+                                      tp->symbol, NULL);
+       if (sym) {
+               fd = open_vmlinux();
+               if (fd >= 0) {
+                       ret = find_perf_probe_point(fd,
+                                                sym->start + tp->offset, pp);
+                       close(fd);
+               }
+       }
+       if (ret <= 0) {
+               pr_debug("Failed to find corresponding probes from "
+                        "debuginfo. Use kprobe event information.\n");
+               pp->function = strdup(tp->symbol);
+               if (pp->function == NULL)
+                       return -ENOMEM;
+               pp->offset = tp->offset;
+       }
+       pp->retprobe = tp->retprobe;
+
+       return 0;
+}
+
+/* Try to find perf_probe_event with debuginfo */
+static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
+                                          struct kprobe_trace_event **tevs,
+                                          int max_tevs)
+{
+       bool need_dwarf = perf_probe_event_need_dwarf(pev);
+       int fd, ntevs;
+
+       fd = open_vmlinux();
+       if (fd < 0) {
+               if (need_dwarf) {
+                       pr_warning("Failed to open debuginfo file.\n");
+                       return fd;
+               }
+               pr_debug("Could not open vmlinux. Try to use symbols.\n");
+               return 0;
+       }
+
+       /* Searching trace events corresponding to probe event */
+       ntevs = find_kprobe_trace_events(fd, pev, tevs, max_tevs);
+       close(fd);
+
+       if (ntevs > 0) {        /* Succeeded to find trace events */
+               pr_debug("find %d kprobe_trace_events.\n", ntevs);
+               return ntevs;
+       }
+
+       if (ntevs == 0) {       /* No error but failed to find probe point. */
+               pr_warning("Probe point '%s' not found.\n",
+                          synthesize_perf_probe_point(&pev->point));
+               return -ENOENT;
+       }
+       /* Error path : ntevs < 0 */
+       pr_debug("An error occurred in debuginfo analysis (%d).\n", ntevs);
+       if (ntevs == -EBADF) {
+               pr_warning("Warning: No dwarf info found in the vmlinux - "
+                       "please rebuild kernel with CONFIG_DEBUG_INFO=y.\n");
+               if (!need_dwarf) {
+                       pr_debug("Trying to use symbols.\nn");
+                       return 0;
+               }
+       }
+       return ntevs;
+}
+
+#define LINEBUF_SIZE 256
+#define NR_ADDITIONAL_LINES 2
+
+static int show_one_line(FILE *fp, int l, bool skip, bool show_num)
+{
+       char buf[LINEBUF_SIZE];
+       const char *color = PERF_COLOR_BLUE;
+
+       if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
+               goto error;
+       if (!skip) {
+               if (show_num)
+                       fprintf(stdout, "%7d  %s", l, buf);
+               else
+                       color_fprintf(stdout, color, "         %s", buf);
+       }
+
+       while (strlen(buf) == LINEBUF_SIZE - 1 &&
+              buf[LINEBUF_SIZE - 2] != '\n') {
+               if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
+                       goto error;
+               if (!skip) {
+                       if (show_num)
+                               fprintf(stdout, "%s", buf);
+                       else
+                               color_fprintf(stdout, color, "%s", buf);
+               }
+       }
+
+       return 0;
+error:
+       if (feof(fp))
+               pr_warning("Source file is shorter than expected.\n");
+       else
+               pr_warning("File read error: %s\n", strerror(errno));
+
+       return -1;
+}
+
+/*
+ * Show line-range always requires debuginfo to find source file and
+ * line number.
+ */
+int show_line_range(struct line_range *lr)
+{
+       int l = 1;
+       struct line_node *ln;
+       FILE *fp;
+       int fd, ret;
+
+       /* Search a line range */
+       ret = init_vmlinux();
+       if (ret < 0)
+               return ret;
+
+       fd = open_vmlinux();
+       if (fd < 0) {
+               pr_warning("Failed to open debuginfo file.\n");
+               return fd;
+       }
+
+       ret = find_line_range(fd, lr);
+       close(fd);
+       if (ret == 0) {
+               pr_warning("Specified source line is not found.\n");
+               return -ENOENT;
+       } else if (ret < 0) {
+               pr_warning("Debuginfo analysis failed. (%d)\n", ret);
+               return ret;
+       }
+
+       setup_pager();
+
+       if (lr->function)
+               fprintf(stdout, "<%s:%d>\n", lr->function,
+                       lr->start - lr->offset);
+       else
+               fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);
+
+       fp = fopen(lr->path, "r");
+       if (fp == NULL) {
+               pr_warning("Failed to open %s: %s\n", lr->path,
+                          strerror(errno));
+               return -errno;
+       }
+       /* Skip to starting line number */
+       while (l < lr->start && ret >= 0)
+               ret = show_one_line(fp, l++, true, false);
+       if (ret < 0)
+               goto end;
+
+       list_for_each_entry(ln, &lr->line_list, list) {
+               while (ln->line > l && ret >= 0)
+                       ret = show_one_line(fp, (l++) - lr->offset,
+                                           false, false);
+               if (ret >= 0)
+                       ret = show_one_line(fp, (l++) - lr->offset,
+                                           false, true);
+               if (ret < 0)
+                       goto end;
+       }
+
+       if (lr->end == INT_MAX)
+               lr->end = l + NR_ADDITIONAL_LINES;
+       while (l <= lr->end && !feof(fp) && ret >= 0)
+               ret = show_one_line(fp, (l++) - lr->offset, false, false);
+end:
+       fclose(fp);
+       return ret;
+}
+
+#else  /* !DWARF_SUPPORT */
+
+static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
+                                       struct perf_probe_point *pp)
+{
+       pp->function = strdup(tp->symbol);
+       if (pp->function == NULL)
+               return -ENOMEM;
+       pp->offset = tp->offset;
+       pp->retprobe = tp->retprobe;
+
+       return 0;
+}
+
+static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
+                               struct kprobe_trace_event **tevs __unused,
+                               int max_tevs __unused)
+{
+       if (perf_probe_event_need_dwarf(pev)) {
+               pr_warning("Debuginfo-analysis is not supported.\n");
+               return -ENOSYS;
+       }
+       return 0;
+}
+
+int show_line_range(struct line_range *lr __unused)
+{
+       pr_warning("Debuginfo-analysis is not supported.\n");
+       return -ENOSYS;
+}
+
+#endif
+
+int parse_line_range_desc(const char *arg, struct line_range *lr)
 {
        const char *ptr;
        char *tmp;
@@ -75,29 +350,45 @@ void parse_line_range_desc(const char *arg, struct line_range *lr)
         */
        ptr = strchr(arg, ':');
        if (ptr) {
-               lr->start = (unsigned int)strtoul(ptr + 1, &tmp, 0);
-               if (*tmp == '+')
-                       lr->end = lr->start + (unsigned int)strtoul(tmp + 1,
-                                                                   &tmp, 0);
-               else if (*tmp == '-')
-                       lr->end = (unsigned int)strtoul(tmp + 1, &tmp, 0);
+               lr->start = (int)strtoul(ptr + 1, &tmp, 0);
+               if (*tmp == '+') {
+                       lr->end = lr->start + (int)strtoul(tmp + 1, &tmp, 0);
+                       lr->end--;      /*
+                                        * Adjust the number of lines here.
+                                        * If the number of lines == 1, the
+                                        * the end of line should be equal to
+                                        * the start of line.
+                                        */
+               } else if (*tmp == '-')
+                       lr->end = (int)strtoul(tmp + 1, &tmp, 0);
                else
-                       lr->end = 0;
-               pr_debug("Line range is %u to %u\n", lr->start, lr->end);
-               if (lr->end && lr->start > lr->end)
+                       lr->end = INT_MAX;
+               pr_debug("Line range is %d to %d\n", lr->start, lr->end);
+               if (lr->start > lr->end) {
                        semantic_error("Start line must be smaller"
-                                      " than end line.");
-               if (*tmp != '\0')
-                       semantic_error("Tailing with invalid character '%d'.",
+                                      " than end line.\n");
+                       return -EINVAL;
+               }
+               if (*tmp != '\0') {
+                       semantic_error("Tailing with invalid character '%d'.\n",
                                       *tmp);
+                       return -EINVAL;
+               }
                tmp = strndup(arg, (ptr - arg));
-       } else
+       } else {
                tmp = strdup(arg);
+               lr->end = INT_MAX;
+       }
+
+       if (tmp == NULL)
+               return -ENOMEM;
 
        if (strchr(tmp, '.'))
                lr->file = tmp;
        else
                lr->function = tmp;
+
+       return 0;
 }
 
 /* Check the name is good for event/group */
@@ -113,8 +404,9 @@ static bool check_event_name(const char *name)
 }
 
 /* Parse probepoint definition. */
-static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
+static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 {
+       struct perf_probe_point *pp = &pev->point;
        char *ptr, *tmp;
        char c, nc = 0;
        /*
@@ -129,13 +421,19 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
        if (ptr && *ptr == '=') {       /* Event name */
                *ptr = '\0';
                tmp = ptr + 1;
-               ptr = strchr(arg, ':');
-               if (ptr)        /* Group name is not supported yet. */
-                       semantic_error("Group name is not supported yet.");
-               if (!check_event_name(arg))
+               if (strchr(arg, ':')) {
+                       semantic_error("Group name is not supported yet.\n");
+                       return -ENOTSUP;
+               }
+               if (!check_event_name(arg)) {
                        semantic_error("%s is bad for event name -it must "
-                                      "follow C symbol-naming rule.", arg);
-               pp->event = strdup(arg);
+                                      "follow C symbol-naming rule.\n", arg);
+                       return -EINVAL;
+               }
+               pev->event = strdup(arg);
+               if (pev->event == NULL)
+                       return -ENOMEM;
+               pev->group = NULL;
                arg = tmp;
        }
 
@@ -145,12 +443,15 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
                *ptr++ = '\0';
        }
 
+       tmp = strdup(arg);
+       if (tmp == NULL)
+               return -ENOMEM;
+
        /* Check arg is function or file and copy it */
-       if (strchr(arg, '.'))   /* File */
-               pp->file = strdup(arg);
+       if (strchr(tmp, '.'))   /* File */
+               pp->file = tmp;
        else                    /* Function */
-               pp->function = strdup(arg);
-       DIE_IF(pp->file == NULL && pp->function == NULL);
+               pp->function = tmp;
 
        /* Parse other options */
        while (ptr) {
@@ -158,6 +459,8 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
                c = nc;
                if (c == ';') { /* Lazy pattern must be the last part */
                        pp->lazy_line = strdup(arg);
+                       if (pp->lazy_line == NULL)
+                               return -ENOMEM;
                        break;
                }
                ptr = strpbrk(arg, ";:+@%");
@@ -168,266 +471,658 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
                switch (c) {
                case ':':       /* Line number */
                        pp->line = strtoul(arg, &tmp, 0);
-                       if (*tmp != '\0')
+                       if (*tmp != '\0') {
                                semantic_error("There is non-digit char"
-                                              " in line number.");
+                                              " in line number.\n");
+                               return -EINVAL;
+                       }
                        break;
                case '+':       /* Byte offset from a symbol */
                        pp->offset = strtoul(arg, &tmp, 0);
-                       if (*tmp != '\0')
+                       if (*tmp != '\0') {
                                semantic_error("There is non-digit character"
-                                               " in offset.");
+                                               " in offset.\n");
+                               return -EINVAL;
+                       }
                        break;
                case '@':       /* File name */
-                       if (pp->file)
-                               semantic_error("SRC@SRC is not allowed.");
+                       if (pp->file) {
+                               semantic_error("SRC@SRC is not allowed.\n");
+                               return -EINVAL;
+                       }
                        pp->file = strdup(arg);
-                       DIE_IF(pp->file == NULL);
+                       if (pp->file == NULL)
+                               return -ENOMEM;
                        break;
                case '%':       /* Probe places */
                        if (strcmp(arg, "return") == 0) {
                                pp->retprobe = 1;
-                       } else  /* Others not supported yet */
-                               semantic_error("%%%s is not supported.", arg);
+                       } else {        /* Others not supported yet */
+                               semantic_error("%%%s is not supported.\n", arg);
+                               return -ENOTSUP;
+                       }
                        break;
-               default:
-                       DIE_IF("Program has a bug.");
+               default:        /* Buggy case */
+                       pr_err("This program has a bug at %s:%d.\n",
+                               __FILE__, __LINE__);
+                       return -ENOTSUP;
                        break;
                }
        }
 
        /* Exclusion check */
-       if (pp->lazy_line && pp->line)
+       if (pp->lazy_line && pp->line) {
                semantic_error("Lazy pattern can't be used with line number.");
+               return -EINVAL;
+       }
 
-       if (pp->lazy_line && pp->offset)
+       if (pp->lazy_line && pp->offset) {
                semantic_error("Lazy pattern can't be used with offset.");
+               return -EINVAL;
+       }
 
-       if (pp->line && pp->offset)
+       if (pp->line && pp->offset) {
                semantic_error("Offset can't be used with line number.");
+               return -EINVAL;
+       }
 
-       if (!pp->line && !pp->lazy_line && pp->file && !pp->function)
+       if (!pp->line && !pp->lazy_line && pp->file && !pp->function) {
                semantic_error("File always requires line number or "
                               "lazy pattern.");
+               return -EINVAL;
+       }
 
-       if (pp->offset && !pp->function)
+       if (pp->offset && !pp->function) {
                semantic_error("Offset requires an entry function.");
+               return -EINVAL;
+       }
 
-       if (pp->retprobe && !pp->function)
+       if (pp->retprobe && !pp->function) {
                semantic_error("Return probe requires an entry function.");
+               return -EINVAL;
+       }
 
-       if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe)
+       if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
                semantic_error("Offset/Line/Lazy pattern can't be used with "
                               "return probe.");
+               return -EINVAL;
+       }
 
-       pr_debug("symbol:%s file:%s line:%d offset:%d return:%d lazy:%s\n",
+       pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n",
                 pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
                 pp->lazy_line);
+       return 0;
 }
 
-/* Parse perf-probe event definition */
-void parse_perf_probe_event(const char *str, struct probe_point *pp,
-                           bool *need_dwarf)
+/* Parse perf-probe event argument */
+static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
 {
-       char **argv;
-       int argc, i;
+       char *tmp;
+       struct perf_probe_arg_field **fieldp;
+
+       pr_debug("parsing arg: %s into ", str);
 
-       *need_dwarf = false;
+       tmp = strchr(str, '=');
+       if (tmp) {
+               arg->name = strndup(str, tmp - str);
+               if (arg->name == NULL)
+                       return -ENOMEM;
+               pr_debug("name:%s ", arg->name);
+               str = tmp + 1;
+       }
 
-       argv = argv_split(str, &argc);
-       if (!argv)
-               die("argv_split failed.");
-       if (argc > MAX_PROBE_ARGS + 1)
-               semantic_error("Too many arguments");
+       tmp = strchr(str, ':');
+       if (tmp) {      /* Type setting */
+               *tmp = '\0';
+               arg->type = strdup(tmp + 1);
+               if (arg->type == NULL)
+                       return -ENOMEM;
+               pr_debug("type:%s ", arg->type);
+       }
 
+       tmp = strpbrk(str, "-.");
+       if (!is_c_varname(str) || !tmp) {
+               /* A variable, register, symbol or special value */
+               arg->var = strdup(str);
+               if (arg->var == NULL)
+                       return -ENOMEM;
+               pr_debug("%s\n", arg->var);
+               return 0;
+       }
+
+       /* Structure fields */
+       arg->var = strndup(str, tmp - str);
+       if (arg->var == NULL)
+               return -ENOMEM;
+       pr_debug("%s, ", arg->var);
+       fieldp = &arg->field;
+
+       do {
+               *fieldp = zalloc(sizeof(struct perf_probe_arg_field));
+               if (*fieldp == NULL)
+                       return -ENOMEM;
+               if (*tmp == '.') {
+                       str = tmp + 1;
+                       (*fieldp)->ref = false;
+               } else if (tmp[1] == '>') {
+                       str = tmp + 2;
+                       (*fieldp)->ref = true;
+               } else {
+                       semantic_error("Argument parse error: %s\n", str);
+                       return -EINVAL;
+               }
+
+               tmp = strpbrk(str, "-.");
+               if (tmp) {
+                       (*fieldp)->name = strndup(str, tmp - str);
+                       if ((*fieldp)->name == NULL)
+                               return -ENOMEM;
+                       pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref);
+                       fieldp = &(*fieldp)->next;
+               }
+       } while (tmp);
+       (*fieldp)->name = strdup(str);
+       if ((*fieldp)->name == NULL)
+               return -ENOMEM;
+       pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref);
+
+       /* If no name is specified, set the last field name */
+       if (!arg->name) {
+               arg->name = strdup((*fieldp)->name);
+               if (arg->name == NULL)
+                       return -ENOMEM;
+       }
+       return 0;
+}
+
+/* Parse perf-probe event command */
+int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev)
+{
+       char **argv;
+       int argc, i, ret = 0;
+
+       argv = argv_split(cmd, &argc);
+       if (!argv) {
+               pr_debug("Failed to split arguments.\n");
+               return -ENOMEM;
+       }
+       if (argc - 1 > MAX_PROBE_ARGS) {
+               semantic_error("Too many probe arguments (%d).\n", argc - 1);
+               ret = -ERANGE;
+               goto out;
+       }
        /* Parse probe point */
-       parse_perf_probe_probepoint(argv[0], pp);
-       if (pp->file || pp->line)
-               *need_dwarf = true;
+       ret = parse_perf_probe_point(argv[0], pev);
+       if (ret < 0)
+               goto out;
 
        /* 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 = true;
+       pev->nargs = argc - 1;
+       pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
+       if (pev->args == NULL) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       for (i = 0; i < pev->nargs && ret >= 0; i++) {
+               ret = parse_perf_probe_arg(argv[i + 1], &pev->args[i]);
+               if (ret >= 0 &&
+                   is_c_varname(pev->args[i].var) && pev->point.retprobe) {
+                       semantic_error("You can't specify local variable for"
+                                      " kretprobe.\n");
+                       ret = -EINVAL;
                }
        }
-
+out:
        argv_free(argv);
+
+       return ret;
+}
+
+/* Return true if this perf_probe_event requires debuginfo */
+bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
+{
+       int i;
+
+       if (pev->point.file || pev->point.line || pev->point.lazy_line)
+               return true;
+
+       for (i = 0; i < pev->nargs; i++)
+               if (is_c_varname(pev->args[i].var))
+                       return true;
+
+       return false;
 }
 
 /* Parse kprobe_events event into struct probe_point */
-void parse_trace_kprobe_event(const char *str, struct probe_point *pp)
+int parse_kprobe_trace_command(const char *cmd, struct kprobe_trace_event *tev)
 {
+       struct kprobe_trace_point *tp = &tev->point;
        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.");
+       pr_debug("Parsing kprobe_events: %s\n", cmd);
+       argv = argv_split(cmd, &argc);
+       if (!argv) {
+               pr_debug("Failed to split arguments.\n");
+               return -ENOMEM;
+       }
+       if (argc < 2) {
+               semantic_error("Too few probe arguments.\n");
+               ret = -ERANGE;
+               goto out;
+       }
 
        /* Scan event and group name. */
        ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]",
-                    &pr, (float *)(void *)&pp->group,
-                    (float *)(void *)&pp->event);
-       if (ret != 3)
-               semantic_error("Failed to parse event name: %s", argv[0]);
-       pr_debug("Group:%s Event:%s probe:%c\n", pp->group, pp->event, pr);
+                    &pr, (float *)(void *)&tev->group,
+                    (float *)(void *)&tev->event);
+       if (ret != 3) {
+               semantic_error("Failed to parse event name: %s\n", argv[0]);
+               ret = -EINVAL;
+               goto out;
+       }
+       pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr);
 
-       pp->retprobe = (pr == 'r');
+       tp->retprobe = (pr == 'r');
 
        /* Scan function name and offset */
-       ret = sscanf(argv[1], "%a[^+]+%d", (float *)(void *)&pp->function,
-                    &pp->offset);
+       ret = sscanf(argv[1], "%a[^+]+%lu", (float *)(void *)&tp->symbol,
+                    &tp->offset);
        if (ret == 1)
-               pp->offset = 0;
-
-       /* kprobe_events doesn't have this information */
-       pp->line = 0;
-       pp->file = NULL;
+               tp->offset = 0;
 
-       pp->nr_args = argc - 2;
-       pp->args = zalloc(sizeof(char *) * pp->nr_args);
-       for (i = 0; i < pp->nr_args; i++) {
+       tev->nargs = argc - 2;
+       tev->args = zalloc(sizeof(struct kprobe_trace_arg) * tev->nargs);
+       if (tev->args == NULL) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       for (i = 0; i < tev->nargs; 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.");
+                       *p++ = '\0';
+               else
+                       p = argv[i + 2];
+               tev->args[i].name = strdup(argv[i + 2]);
+               /* TODO: parse regs and offset */
+               tev->args[i].value = strdup(p);
+               if (tev->args[i].name == NULL || tev->args[i].value == NULL) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
        }
-
+       ret = 0;
+out:
        argv_free(argv);
+       return ret;
 }
 
-/* Synthesize only probe point (not argument) */
-int synthesize_perf_probe_point(struct probe_point *pp)
+/* Compose only probe arg */
+int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len)
 {
-       char *buf;
-       char offs[64] = "", line[64] = "";
+       struct perf_probe_arg_field *field = pa->field;
        int ret;
+       char *tmp = buf;
 
-       pp->probes[0] = buf = zalloc(MAX_CMDLEN);
-       pp->found = 1;
-       if (!buf)
-               die("Failed to allocate memory by zalloc.");
+       if (pa->name && pa->var)
+               ret = e_snprintf(tmp, len, "%s=%s", pa->name, pa->var);
+       else
+               ret = e_snprintf(tmp, len, "%s", pa->name ? pa->name : pa->var);
+       if (ret <= 0)
+               goto error;
+       tmp += ret;
+       len -= ret;
+
+       while (field) {
+               ret = e_snprintf(tmp, len, "%s%s", field->ref ? "->" : ".",
+                                field->name);
+               if (ret <= 0)
+                       goto error;
+               tmp += ret;
+               len -= ret;
+               field = field->next;
+       }
+
+       if (pa->type) {
+               ret = e_snprintf(tmp, len, ":%s", pa->type);
+               if (ret <= 0)
+                       goto error;
+               tmp += ret;
+               len -= ret;
+       }
+
+       return tmp - buf;
+error:
+       pr_debug("Failed to synthesize perf probe argument: %s",
+                strerror(-ret));
+       return ret;
+}
+
+/* Compose only probe point (not argument) */
+static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
+{
+       char *buf, *tmp;
+       char offs[32] = "", line[32] = "", file[32] = "";
+       int ret, len;
+
+       buf = zalloc(MAX_CMDLEN);
+       if (buf == NULL) {
+               ret = -ENOMEM;
+               goto error;
+       }
        if (pp->offset) {
-               ret = e_snprintf(offs, 64, "+%d", pp->offset);
+               ret = e_snprintf(offs, 32, "+%lu", pp->offset);
                if (ret <= 0)
                        goto error;
        }
        if (pp->line) {
-               ret = e_snprintf(line, 64, ":%d", pp->line);
+               ret = e_snprintf(line, 32, ":%d", pp->line);
+               if (ret <= 0)
+                       goto error;
+       }
+       if (pp->file) {
+               len = strlen(pp->file) - 31;
+               if (len < 0)
+                       len = 0;
+               tmp = strchr(pp->file + len, '/');
+               if (!tmp)
+                       tmp = pp->file + len;
+               ret = e_snprintf(file, 32, "@%s", tmp + 1);
                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);
+               ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s", pp->function,
+                                offs, pp->retprobe ? "%return" : "", line,
+                                file);
        else
-               ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", pp->file, line);
-       if (ret <= 0) {
+               ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", file, line);
+       if (ret <= 0)
+               goto error;
+
+       return buf;
 error:
-               free(pp->probes[0]);
-               pp->probes[0] = NULL;
-               pp->found = 0;
-       }
-       return ret;
+       pr_debug("Failed to synthesize perf probe point: %s",
+                strerror(-ret));
+       if (buf)
+               free(buf);
+       return NULL;
 }
 
-int synthesize_perf_probe_event(struct probe_point *pp)
+#if 0
+char *synthesize_perf_probe_command(struct perf_probe_event *pev)
 {
        char *buf;
        int i, len, ret;
 
-       len = synthesize_perf_probe_point(pp);
-       if (len < 0)
-               return 0;
+       buf = synthesize_perf_probe_point(&pev->point);
+       if (!buf)
+               return NULL;
 
-       buf = pp->probes[0];
-       for (i = 0; i < pp->nr_args; i++) {
+       len = strlen(buf);
+       for (i = 0; i < pev->nargs; i++) {
                ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
-                                pp->args[i]);
-               if (ret <= 0)
-                       goto error;
+                                pev->args[i].name);
+               if (ret <= 0) {
+                       free(buf);
+                       return NULL;
+               }
                len += ret;
        }
-       pp->found = 1;
 
-       return pp->found;
-error:
-       free(pp->probes[0]);
-       pp->probes[0] = NULL;
+       return buf;
+}
+#endif
+
+static int __synthesize_kprobe_trace_arg_ref(struct kprobe_trace_arg_ref *ref,
+                                            char **buf, size_t *buflen,
+                                            int depth)
+{
+       int ret;
+       if (ref->next) {
+               depth = __synthesize_kprobe_trace_arg_ref(ref->next, buf,
+                                                        buflen, depth + 1);
+               if (depth < 0)
+                       goto out;
+       }
+
+       ret = e_snprintf(*buf, *buflen, "%+ld(", ref->offset);
+       if (ret < 0)
+               depth = ret;
+       else {
+               *buf += ret;
+               *buflen -= ret;
+       }
+out:
+       return depth;
 
-       return ret;
 }
 
-int synthesize_trace_kprobe_event(struct probe_point *pp)
+static int synthesize_kprobe_trace_arg(struct kprobe_trace_arg *arg,
+                                      char *buf, size_t buflen)
 {
+       int ret, depth = 0;
+       char *tmp = buf;
+
+       /* Argument name or separator */
+       if (arg->name)
+               ret = e_snprintf(buf, buflen, " %s=", arg->name);
+       else
+               ret = e_snprintf(buf, buflen, " ");
+       if (ret < 0)
+               return ret;
+       buf += ret;
+       buflen -= ret;
+
+       /* Dereferencing arguments */
+       if (arg->ref) {
+               depth = __synthesize_kprobe_trace_arg_ref(arg->ref, &buf,
+                                                         &buflen, 1);
+               if (depth < 0)
+                       return depth;
+       }
+
+       /* Print argument value */
+       ret = e_snprintf(buf, buflen, "%s", arg->value);
+       if (ret < 0)
+               return ret;
+       buf += ret;
+       buflen -= ret;
+
+       /* Closing */
+       while (depth--) {
+               ret = e_snprintf(buf, buflen, ")");
+               if (ret < 0)
+                       return ret;
+               buf += ret;
+               buflen -= ret;
+       }
+       /* Print argument type */
+       if (arg->type) {
+               ret = e_snprintf(buf, buflen, ":%s", arg->type);
+               if (ret <= 0)
+                       return ret;
+               buf += ret;
+       }
+
+       return buf - tmp;
+}
+
+char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev)
+{
+       struct kprobe_trace_point *tp = &tev->point;
        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)
+       buf = zalloc(MAX_CMDLEN);
+       if (buf == NULL)
+               return NULL;
+
+       len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s+%lu",
+                        tp->retprobe ? 'r' : 'p',
+                        tev->group, tev->event,
+                        tp->symbol, tp->offset);
+       if (len <= 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]);
+       for (i = 0; i < tev->nargs; i++) {
+               ret = synthesize_kprobe_trace_arg(&tev->args[i], buf + len,
+                                                 MAX_CMDLEN - len);
                if (ret <= 0)
                        goto error;
                len += ret;
        }
-       pp->found = 1;
 
-       return pp->found;
+       return buf;
 error:
-       free(pp->probes[0]);
-       pp->probes[0] = NULL;
+       free(buf);
+       return NULL;
+}
+
+int convert_to_perf_probe_event(struct kprobe_trace_event *tev,
+                               struct perf_probe_event *pev)
+{
+       char buf[64] = "";
+       int i, ret;
+
+       /* Convert event/group name */
+       pev->event = strdup(tev->event);
+       pev->group = strdup(tev->group);
+       if (pev->event == NULL || pev->group == NULL)
+               return -ENOMEM;
+
+       /* Convert trace_point to probe_point */
+       ret = convert_to_perf_probe_point(&tev->point, &pev->point);
+       if (ret < 0)
+               return ret;
+
+       /* Convert trace_arg to probe_arg */
+       pev->nargs = tev->nargs;
+       pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
+       if (pev->args == NULL)
+               return -ENOMEM;
+       for (i = 0; i < tev->nargs && ret >= 0; i++) {
+               if (tev->args[i].name)
+                       pev->args[i].name = strdup(tev->args[i].name);
+               else {
+                       ret = synthesize_kprobe_trace_arg(&tev->args[i],
+                                                         buf, 64);
+                       pev->args[i].name = strdup(buf);
+               }
+               if (pev->args[i].name == NULL && ret >= 0)
+                       ret = -ENOMEM;
+       }
+
+       if (ret < 0)
+               clear_perf_probe_event(pev);
 
        return ret;
 }
 
-static int open_kprobe_events(int flags, int mode)
+void clear_perf_probe_event(struct perf_probe_event *pev)
+{
+       struct perf_probe_point *pp = &pev->point;
+       struct perf_probe_arg_field *field, *next;
+       int i;
+
+       if (pev->event)
+               free(pev->event);
+       if (pev->group)
+               free(pev->group);
+       if (pp->file)
+               free(pp->file);
+       if (pp->function)
+               free(pp->function);
+       if (pp->lazy_line)
+               free(pp->lazy_line);
+       for (i = 0; i < pev->nargs; i++) {
+               if (pev->args[i].name)
+                       free(pev->args[i].name);
+               if (pev->args[i].var)
+                       free(pev->args[i].var);
+               if (pev->args[i].type)
+                       free(pev->args[i].type);
+               field = pev->args[i].field;
+               while (field) {
+                       next = field->next;
+                       if (field->name)
+                               free(field->name);
+                       free(field);
+                       field = next;
+               }
+       }
+       if (pev->args)
+               free(pev->args);
+       memset(pev, 0, sizeof(*pev));
+}
+
+void clear_kprobe_trace_event(struct kprobe_trace_event *tev)
+{
+       struct kprobe_trace_arg_ref *ref, *next;
+       int i;
+
+       if (tev->event)
+               free(tev->event);
+       if (tev->group)
+               free(tev->group);
+       if (tev->point.symbol)
+               free(tev->point.symbol);
+       for (i = 0; i < tev->nargs; i++) {
+               if (tev->args[i].name)
+                       free(tev->args[i].name);
+               if (tev->args[i].value)
+                       free(tev->args[i].value);
+               if (tev->args[i].type)
+                       free(tev->args[i].type);
+               ref = tev->args[i].ref;
+               while (ref) {
+                       next = ref->next;
+                       free(ref);
+                       ref = next;
+               }
+       }
+       if (tev->args)
+               free(tev->args);
+       memset(tev, 0, sizeof(*tev));
+}
+
+static int open_kprobe_events(bool readwrite)
 {
        char buf[PATH_MAX];
+       const char *__debugfs;
        int ret;
 
-       ret = e_snprintf(buf, PATH_MAX, "%s/../kprobe_events", debugfs_path);
-       if (ret < 0)
-               die("Failed to make kprobe_events path.");
+       __debugfs = debugfs_find_mountpoint();
+       if (__debugfs == NULL) {
+               pr_warning("Debugfs is not mounted.\n");
+               return -ENOENT;
+       }
+
+       ret = e_snprintf(buf, PATH_MAX, "%stracing/kprobe_events", __debugfs);
+       if (ret >= 0) {
+               pr_debug("Opening %s write=%d\n", buf, readwrite);
+               if (readwrite && !probe_event_dry_run)
+                       ret = open(buf, O_RDWR, O_APPEND);
+               else
+                       ret = open(buf, O_RDONLY, 0);
+       }
 
-       ret = open(buf, flags, mode);
        if (ret < 0) {
                if (errno == ENOENT)
-                       die("kprobe_events file does not exist -"
-                           " please rebuild with CONFIG_KPROBE_EVENT.");
+                       pr_warning("kprobe_events file does not exist - please"
+                                " rebuild kernel with CONFIG_KPROBE_EVENT.\n");
                else
-                       die("Could not open kprobe_events file: %s",
-                           strerror(errno));
+                       pr_warning("Failed to open kprobe_events file: %s\n",
+                                  strerror(errno));
        }
        return ret;
 }
 
 /* Get raw string list of current kprobe_events */
-static struct strlist *get_trace_kprobe_event_rawlist(int fd)
+static struct strlist *get_kprobe_trace_command_rawlist(int fd)
 {
        int ret, idx;
        FILE *fp;
@@ -447,271 +1142,486 @@ static struct strlist *get_trace_kprobe_event_rawlist(int fd)
                if (p[idx] == '\n')
                        p[idx] = '\0';
                ret = strlist__add(sl, buf);
-               if (ret < 0)
-                       die("strlist__add failed: %s", strerror(-ret));
+               if (ret < 0) {
+                       pr_debug("strlist__add failed: %s\n", strerror(-ret));
+                       strlist__delete(sl);
+                       return NULL;
+               }
        }
        fclose(fp);
 
        return sl;
 }
 
-/* Free and zero clear probe_point */
-static void clear_probe_point(struct probe_point *pp)
-{
-       int i;
-
-       if (pp->event)
-               free(pp->event);
-       if (pp->group)
-               free(pp->group);
-       if (pp->function)
-               free(pp->function);
-       if (pp->file)
-               free(pp->file);
-       if (pp->lazy_line)
-               free(pp->lazy_line);
-       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));
-}
-
 /* Show an event */
-static void show_perf_probe_event(const char *event, const char *place,
-                                 struct probe_point *pp)
+static int show_perf_probe_event(struct perf_probe_event *pev)
 {
        int i, ret;
        char buf[128];
+       char *place;
+
+       /* Synthesize only event probe point */
+       place = synthesize_perf_probe_point(&pev->point);
+       if (!place)
+               return -EINVAL;
 
-       ret = e_snprintf(buf, 128, "%s:%s", pp->group, event);
+       ret = e_snprintf(buf, 128, "%s:%s", pev->group, pev->event);
        if (ret < 0)
-               die("Failed to copy event: %s", strerror(-ret));
-       printf("  %-40s (on %s", buf, place);
+               return ret;
+
+       printf("  %-20s (on %s", buf, place);
 
-       if (pp->nr_args > 0) {
+       if (pev->nargs > 0) {
                printf(" with");
-               for (i = 0; i < pp->nr_args; i++)
-                       printf(" %s", pp->args[i]);
+               for (i = 0; i < pev->nargs; i++) {
+                       ret = synthesize_perf_probe_arg(&pev->args[i],
+                                                       buf, 128);
+                       if (ret < 0)
+                               break;
+                       printf(" %s", buf);
+               }
        }
        printf(")\n");
+       free(place);
+       return ret;
 }
 
 /* List up current perf-probe events */
-void show_perf_probe_events(void)
+int show_perf_probe_events(void)
 {
-       int fd;
-       struct probe_point pp;
+       int fd, ret;
+       struct kprobe_trace_event tev;
+       struct perf_probe_event pev;
        struct strlist *rawlist;
        struct str_node *ent;
 
        setup_pager();
-       memset(&pp, 0, sizeof(pp));
+       ret = init_vmlinux();
+       if (ret < 0)
+               return ret;
+
+       memset(&tev, 0, sizeof(tev));
+       memset(&pev, 0, sizeof(pev));
 
-       fd = open_kprobe_events(O_RDONLY, 0);
-       rawlist = get_trace_kprobe_event_rawlist(fd);
+       fd = open_kprobe_events(false);
+       if (fd < 0)
+               return fd;
+
+       rawlist = get_kprobe_trace_command_rawlist(fd);
        close(fd);
+       if (!rawlist)
+               return -ENOENT;
 
        strlist__for_each(ent, rawlist) {
-               parse_trace_kprobe_event(ent->s, &pp);
-               /* Synthesize only event probe point */
-               synthesize_perf_probe_point(&pp);
-               /* Show an event */
-               show_perf_probe_event(pp.event, pp.probes[0], &pp);
-               clear_probe_point(&pp);
+               ret = parse_kprobe_trace_command(ent->s, &tev);
+               if (ret >= 0) {
+                       ret = convert_to_perf_probe_event(&tev, &pev);
+                       if (ret >= 0)
+                               ret = show_perf_probe_event(&pev);
+               }
+               clear_perf_probe_event(&pev);
+               clear_kprobe_trace_event(&tev);
+               if (ret < 0)
+                       break;
        }
-
        strlist__delete(rawlist);
+
+       return ret;
 }
 
 /* Get current perf-probe event names */
-static struct strlist *get_perf_event_names(int fd, bool include_group)
+static struct strlist *get_kprobe_trace_event_names(int fd, bool include_group)
 {
        char buf[128];
        struct strlist *sl, *rawlist;
        struct str_node *ent;
-       struct probe_point pp;
+       struct kprobe_trace_event tev;
+       int ret = 0;
 
-       memset(&pp, 0, sizeof(pp));
-       rawlist = get_trace_kprobe_event_rawlist(fd);
+       memset(&tev, 0, sizeof(tev));
 
+       rawlist = get_kprobe_trace_command_rawlist(fd);
        sl = strlist__new(true, NULL);
        strlist__for_each(ent, rawlist) {
-               parse_trace_kprobe_event(ent->s, &pp);
+               ret = parse_kprobe_trace_command(ent->s, &tev);
+               if (ret < 0)
+                       break;
                if (include_group) {
-                       if (e_snprintf(buf, 128, "%s:%s", pp.group,
-                                      pp.event) < 0)
-                               die("Failed to copy group:event name.");
-                       strlist__add(sl, buf);
+                       ret = e_snprintf(buf, 128, "%s:%s", tev.group,
+                                       tev.event);
+                       if (ret >= 0)
+                               ret = strlist__add(sl, buf);
                } else
-                       strlist__add(sl, pp.event);
-               clear_probe_point(&pp);
+                       ret = strlist__add(sl, tev.event);
+               clear_kprobe_trace_event(&tev);
+               if (ret < 0)
+                       break;
        }
-
        strlist__delete(rawlist);
 
+       if (ret < 0) {
+               strlist__delete(sl);
+               return NULL;
+       }
        return sl;
 }
 
-static void write_trace_kprobe_event(int fd, const char *buf)
+static int write_kprobe_trace_event(int fd, struct kprobe_trace_event *tev)
 {
-       int ret;
+       int ret = 0;
+       char *buf = synthesize_kprobe_trace_command(tev);
+
+       if (!buf) {
+               pr_debug("Failed to synthesize kprobe trace event.\n");
+               return -EINVAL;
+       }
 
        pr_debug("Writing event: %s\n", buf);
-       ret = write(fd, buf, strlen(buf));
-       if (ret <= 0)
-               die("Failed to write event: %s", strerror(errno));
+       if (!probe_event_dry_run) {
+               ret = write(fd, buf, strlen(buf));
+               if (ret <= 0)
+                       pr_warning("Failed to write event: %s\n",
+                                  strerror(errno));
+       }
+       free(buf);
+       return ret;
 }
 
-static void get_new_event_name(char *buf, size_t len, const char *base,
-                              struct strlist *namelist, bool allow_suffix)
+static int get_new_event_name(char *buf, size_t len, const char *base,
+                             struct strlist *namelist, bool allow_suffix)
 {
        int i, ret;
 
        /* Try no suffix */
        ret = e_snprintf(buf, len, "%s", base);
-       if (ret < 0)
-               die("snprintf() failed: %s", strerror(-ret));
+       if (ret < 0) {
+               pr_debug("snprintf() failed: %s\n", strerror(-ret));
+               return ret;
+       }
        if (!strlist__has_entry(namelist, buf))
-               return;
+               return 0;
 
        if (!allow_suffix) {
                pr_warning("Error: event \"%s\" already exists. "
                           "(Use -f to force duplicates.)\n", base);
-               die("Can't add new event.");
+               return -EEXIST;
        }
 
        /* Try to add suffix */
        for (i = 1; i < MAX_EVENT_INDEX; i++) {
                ret = e_snprintf(buf, len, "%s_%d", base, i);
-               if (ret < 0)
-                       die("snprintf() failed: %s", strerror(-ret));
+               if (ret < 0) {
+                       pr_debug("snprintf() failed: %s\n", strerror(-ret));
+                       return ret;
+               }
                if (!strlist__has_entry(namelist, buf))
                        break;
        }
-       if (i == MAX_EVENT_INDEX)
-               die("Too many events are on the same function.");
+       if (i == MAX_EVENT_INDEX) {
+               pr_warning("Too many events are on the same function.\n");
+               ret = -ERANGE;
+       }
+
+       return ret;
 }
 
-void add_trace_kprobe_events(struct probe_point *probes, int nr_probes,
-                            bool force_add)
+static int __add_kprobe_trace_events(struct perf_probe_event *pev,
+                                    struct kprobe_trace_event *tevs,
+                                    int ntevs, bool allow_suffix)
 {
-       int i, j, fd;
-       struct probe_point *pp;
-       char buf[MAX_CMDLEN];
-       char event[64];
+       int i, fd, ret;
+       struct kprobe_trace_event *tev = NULL;
+       char buf[64];
+       const char *event, *group;
        struct strlist *namelist;
-       bool allow_suffix;
 
-       fd = open_kprobe_events(O_RDWR, O_APPEND);
+       fd = open_kprobe_events(true);
+       if (fd < 0)
+               return fd;
        /* Get current event names */
-       namelist = get_perf_event_names(fd, false);
-
-       for (j = 0; j < nr_probes; j++) {
-               pp = probes + j;
-               if (!pp->event)
-                       pp->event = strdup(pp->function);
-               if (!pp->group)
-                       pp->group = strdup(PERFPROBE_GROUP);
-               DIE_IF(!pp->event || !pp->group);
-               /* If force_add is true, suffix search is allowed */
-               allow_suffix = force_add;
-               for (i = 0; i < pp->found; i++) {
-                       /* Get an unused new event name */
-                       get_new_event_name(event, 64, pp->event, namelist,
-                                          allow_suffix);
-                       snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s\n",
-                                pp->retprobe ? 'r' : 'p',
-                                pp->group, event,
-                                pp->probes[i]);
-                       write_trace_kprobe_event(fd, buf);
-                       printf("Added new event:\n");
-                       /* Get the first parameter (probe-point) */
-                       sscanf(pp->probes[i], "%s", buf);
-                       show_perf_probe_event(event, buf, pp);
-                       /* Add added event name to namelist */
-                       strlist__add(namelist, event);
-                       /*
-                        * Probes after the first probe which comes from same
-                        * user input are always allowed to add suffix, because
-                        * there might be several addresses corresponding to
-                        * one code line.
-                        */
-                       allow_suffix = true;
+       namelist = get_kprobe_trace_event_names(fd, false);
+       if (!namelist) {
+               pr_debug("Failed to get current event list.\n");
+               return -EIO;
+       }
+
+       ret = 0;
+       printf("Add new event%s\n", (ntevs > 1) ? "s:" : ":");
+       for (i = 0; i < ntevs; i++) {
+               tev = &tevs[i];
+               if (pev->event)
+                       event = pev->event;
+               else
+                       if (pev->point.function)
+                               event = pev->point.function;
+                       else
+                               event = tev->point.symbol;
+               if (pev->group)
+                       group = pev->group;
+               else
+                       group = PERFPROBE_GROUP;
+
+               /* Get an unused new event name */
+               ret = get_new_event_name(buf, 64, event,
+                                        namelist, allow_suffix);
+               if (ret < 0)
+                       break;
+               event = buf;
+
+               tev->event = strdup(event);
+               tev->group = strdup(group);
+               if (tev->event == NULL || tev->group == NULL) {
+                       ret = -ENOMEM;
+                       break;
                }
+               ret = write_kprobe_trace_event(fd, tev);
+               if (ret < 0)
+                       break;
+               /* Add added event name to namelist */
+               strlist__add(namelist, event);
+
+               /* Trick here - save current event/group */
+               event = pev->event;
+               group = pev->group;
+               pev->event = tev->event;
+               pev->group = tev->group;
+               show_perf_probe_event(pev);
+               /* Trick here - restore current event/group */
+               pev->event = (char *)event;
+               pev->group = (char *)group;
+
+               /*
+                * Probes after the first probe which comes from same
+                * user input are always allowed to add suffix, because
+                * there might be several addresses corresponding to
+                * one code line.
+                */
+               allow_suffix = true;
+       }
+
+       if (ret >= 0) {
+               /* Show how to use the event. */
+               printf("\nYou can now use it on all perf tools, such as:\n\n");
+               printf("\tperf record -e %s:%s -aR sleep 1\n\n", tev->group,
+                        tev->event);
        }
-       /* Show how to use the event. */
-       printf("\nYou can now use it on all perf tools, such as:\n\n");
-       printf("\tperf record -e %s:%s -a sleep 1\n\n", PERFPROBE_GROUP, event);
 
        strlist__delete(namelist);
        close(fd);
+       return ret;
+}
+
+static int convert_to_kprobe_trace_events(struct perf_probe_event *pev,
+                                         struct kprobe_trace_event **tevs,
+                                         int max_tevs)
+{
+       struct symbol *sym;
+       int ret = 0, i;
+       struct kprobe_trace_event *tev;
+
+       /* Convert perf_probe_event with debuginfo */
+       ret = try_to_find_kprobe_trace_events(pev, tevs, max_tevs);
+       if (ret != 0)
+               return ret;
+
+       /* Allocate trace event buffer */
+       tev = *tevs = zalloc(sizeof(struct kprobe_trace_event));
+       if (tev == NULL)
+               return -ENOMEM;
+
+       /* Copy parameters */
+       tev->point.symbol = strdup(pev->point.function);
+       if (tev->point.symbol == NULL) {
+               ret = -ENOMEM;
+               goto error;
+       }
+       tev->point.offset = pev->point.offset;
+       tev->nargs = pev->nargs;
+       if (tev->nargs) {
+               tev->args = zalloc(sizeof(struct kprobe_trace_arg)
+                                  * tev->nargs);
+               if (tev->args == NULL) {
+                       ret = -ENOMEM;
+                       goto error;
+               }
+               for (i = 0; i < tev->nargs; i++) {
+                       if (pev->args[i].name) {
+                               tev->args[i].name = strdup(pev->args[i].name);
+                               if (tev->args[i].name == NULL) {
+                                       ret = -ENOMEM;
+                                       goto error;
+                               }
+                       }
+                       tev->args[i].value = strdup(pev->args[i].var);
+                       if (tev->args[i].value == NULL) {
+                               ret = -ENOMEM;
+                               goto error;
+                       }
+                       if (pev->args[i].type) {
+                               tev->args[i].type = strdup(pev->args[i].type);
+                               if (tev->args[i].type == NULL) {
+                                       ret = -ENOMEM;
+                                       goto error;
+                               }
+                       }
+               }
+       }
+
+       /* Currently just checking function name from symbol map */
+       sym = map__find_symbol_by_name(machine.vmlinux_maps[MAP__FUNCTION],
+                                      tev->point.symbol, NULL);
+       if (!sym) {
+               pr_warning("Kernel symbol \'%s\' not found.\n",
+                          tev->point.symbol);
+               ret = -ENOENT;
+               goto error;
+       }
+
+       return 1;
+error:
+       clear_kprobe_trace_event(tev);
+       free(tev);
+       *tevs = NULL;
+       return ret;
+}
+
+struct __event_package {
+       struct perf_probe_event         *pev;
+       struct kprobe_trace_event       *tevs;
+       int                             ntevs;
+};
+
+int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
+                         bool force_add, int max_tevs)
+{
+       int i, j, ret;
+       struct __event_package *pkgs;
+
+       pkgs = zalloc(sizeof(struct __event_package) * npevs);
+       if (pkgs == NULL)
+               return -ENOMEM;
+
+       /* Init vmlinux path */
+       ret = init_vmlinux();
+       if (ret < 0)
+               return ret;
+
+       /* Loop 1: convert all events */
+       for (i = 0; i < npevs; i++) {
+               pkgs[i].pev = &pevs[i];
+               /* Convert with or without debuginfo */
+               ret  = convert_to_kprobe_trace_events(pkgs[i].pev,
+                                                     &pkgs[i].tevs, max_tevs);
+               if (ret < 0)
+                       goto end;
+               pkgs[i].ntevs = ret;
+       }
+
+       /* Loop 2: add all events */
+       for (i = 0; i < npevs && ret >= 0; i++)
+               ret = __add_kprobe_trace_events(pkgs[i].pev, pkgs[i].tevs,
+                                               pkgs[i].ntevs, force_add);
+end:
+       /* Loop 3: cleanup trace events  */
+       for (i = 0; i < npevs; i++)
+               for (j = 0; j < pkgs[i].ntevs; j++)
+                       clear_kprobe_trace_event(&pkgs[i].tevs[j]);
+
+       return ret;
 }
 
-static void __del_trace_kprobe_event(int fd, struct str_node *ent)
+static int __del_trace_kprobe_event(int fd, struct str_node *ent)
 {
        char *p;
        char buf[128];
+       int ret;
 
        /* Convert from perf-probe event to trace-kprobe event */
-       if (e_snprintf(buf, 128, "-:%s", ent->s) < 0)
-               die("Failed to copy event.");
+       ret = e_snprintf(buf, 128, "-:%s", ent->s);
+       if (ret < 0)
+               goto error;
+
        p = strchr(buf + 2, ':');
-       if (!p)
-               die("Internal error: %s should have ':' but not.", ent->s);
+       if (!p) {
+               pr_debug("Internal error: %s should have ':' but not.\n",
+                        ent->s);
+               ret = -ENOTSUP;
+               goto error;
+       }
        *p = '/';
 
-       write_trace_kprobe_event(fd, buf);
+       pr_debug("Writing event: %s\n", buf);
+       ret = write(fd, buf, strlen(buf));
+       if (ret < 0)
+               goto error;
+
        printf("Remove event: %s\n", ent->s);
+       return 0;
+error:
+       pr_warning("Failed to delete event: %s\n", strerror(-ret));
+       return ret;
 }
 
-static void del_trace_kprobe_event(int fd, const char *group,
-                                  const char *event, struct strlist *namelist)
+static int del_trace_kprobe_event(int fd, const char *group,
+                                 const char *event, struct strlist *namelist)
 {
        char buf[128];
        struct str_node *ent, *n;
-       int found = 0;
+       int found = 0, ret = 0;
 
-       if (e_snprintf(buf, 128, "%s:%s", group, event) < 0)
-               die("Failed to copy event.");
+       ret = e_snprintf(buf, 128, "%s:%s", group, event);
+       if (ret < 0) {
+               pr_err("Failed to copy event.");
+               return ret;
+       }
 
        if (strpbrk(buf, "*?")) { /* Glob-exp */
                strlist__for_each_safe(ent, n, namelist)
                        if (strglobmatch(ent->s, buf)) {
                                found++;
-                               __del_trace_kprobe_event(fd, ent);
+                               ret = __del_trace_kprobe_event(fd, ent);
+                               if (ret < 0)
+                                       break;
                                strlist__remove(namelist, ent);
                        }
        } else {
                ent = strlist__find(namelist, buf);
                if (ent) {
                        found++;
-                       __del_trace_kprobe_event(fd, ent);
-                       strlist__remove(namelist, ent);
+                       ret = __del_trace_kprobe_event(fd, ent);
+                       if (ret >= 0)
+                               strlist__remove(namelist, ent);
                }
        }
-       if (found == 0)
-               pr_info("Info: event \"%s\" does not exist, could not remove it.\n", buf);
+       if (found == 0 && ret >= 0)
+               pr_info("Info: Event \"%s\" does not exist.\n", buf);
+
+       return ret;
 }
 
-void del_trace_kprobe_events(struct strlist *dellist)
+int del_perf_probe_events(struct strlist *dellist)
 {
-       int fd;
+       int fd, ret = 0;
        const char *group, *event;
        char *p, *str;
        struct str_node *ent;
        struct strlist *namelist;
 
-       fd = open_kprobe_events(O_RDWR, O_APPEND);
+       fd = open_kprobe_events(true);
+       if (fd < 0)
+               return fd;
+
        /* Get current event names */
-       namelist = get_perf_event_names(fd, true);
+       namelist = get_kprobe_trace_event_names(fd, true);
+       if (namelist == NULL)
+               return -EINVAL;
 
        strlist__for_each(ent, dellist) {
                str = strdup(ent->s);
-               if (!str)
-                       die("Failed to copy event.");
+               if (str == NULL) {
+                       ret = -ENOMEM;
+                       break;
+               }
                pr_debug("Parsing: %s\n", str);
                p = strchr(str, ':');
                if (p) {
@@ -723,80 +1633,14 @@ void del_trace_kprobe_events(struct strlist *dellist)
                        event = str;
                }
                pr_debug("Group: %s, Event: %s\n", group, event);
-               del_trace_kprobe_event(fd, group, event, namelist);
+               ret = del_trace_kprobe_event(fd, group, event, namelist);
                free(str);
+               if (ret < 0)
+                       break;
        }
        strlist__delete(namelist);
        close(fd);
-}
 
-#define LINEBUF_SIZE 256
-#define NR_ADDITIONAL_LINES 2
-
-static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num)
-{
-       char buf[LINEBUF_SIZE];
-       const char *color = PERF_COLOR_BLUE;
-
-       if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
-               goto error;
-       if (!skip) {
-               if (show_num)
-                       fprintf(stdout, "%7u  %s", l, buf);
-               else
-                       color_fprintf(stdout, color, "         %s", buf);
-       }
-
-       while (strlen(buf) == LINEBUF_SIZE - 1 &&
-              buf[LINEBUF_SIZE - 2] != '\n') {
-               if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
-                       goto error;
-               if (!skip) {
-                       if (show_num)
-                               fprintf(stdout, "%s", buf);
-                       else
-                               color_fprintf(stdout, color, "%s", buf);
-               }
-       }
-       return;
-error:
-       if (feof(fp))
-               die("Source file is shorter than expected.");
-       else
-               die("File read error: %s", strerror(errno));
+       return ret;
 }
 
-void show_line_range(struct line_range *lr)
-{
-       unsigned int l = 1;
-       struct line_node *ln;
-       FILE *fp;
-
-       setup_pager();
-
-       if (lr->function)
-               fprintf(stdout, "<%s:%d>\n", lr->function,
-                       lr->start - lr->offset);
-       else
-               fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);
-
-       fp = fopen(lr->path, "r");
-       if (fp == NULL)
-               die("Failed to open %s: %s", lr->path, strerror(errno));
-       /* Skip to starting line number */
-       while (l < lr->start)
-               show_one_line(fp, l++, true, false);
-
-       list_for_each_entry(ln, &lr->line_list, list) {
-               while (ln->line > l)
-                       show_one_line(fp, (l++) - lr->offset, false, false);
-               show_one_line(fp, (l++) - lr->offset, false, true);
-       }
-
-       if (lr->end == INT_MAX)
-               lr->end = l + NR_ADDITIONAL_LINES;
-       while (l < lr->end && !feof(fp))
-               show_one_line(fp, (l++) - lr->offset, false, false);
-
-       fclose(fp);
-}
index 711287d4baead5024a3b48f41ad47d267e0124fd..e9db1a214ca4d9c4c7f9e3a46151070c6cd68ce7 100644 (file)
 #define _PROBE_EVENT_H
 
 #include <stdbool.h>
-#include "probe-finder.h"
 #include "strlist.h"
 
-extern void parse_line_range_desc(const char *arg, struct line_range *lr);
-extern void parse_perf_probe_event(const char *str, struct probe_point *pp,
-                                  bool *need_dwarf);
-extern int synthesize_perf_probe_point(struct probe_point *pp);
-extern int synthesize_perf_probe_event(struct probe_point *pp);
-extern void parse_trace_kprobe_event(const char *str, 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,
-                                   bool force_add);
-extern void del_trace_kprobe_events(struct strlist *dellist);
-extern void show_perf_probe_events(void);
-extern void show_line_range(struct line_range *lr);
+extern bool probe_event_dry_run;
+
+/* kprobe-tracer tracing point */
+struct kprobe_trace_point {
+       char            *symbol;        /* Base symbol */
+       unsigned long   offset;         /* Offset from symbol */
+       bool            retprobe;       /* Return probe flag */
+};
+
+/* kprobe-tracer tracing argument referencing offset */
+struct kprobe_trace_arg_ref {
+       struct kprobe_trace_arg_ref     *next;  /* Next reference */
+       long                            offset; /* Offset value */
+};
+
+/* kprobe-tracer tracing argument */
+struct kprobe_trace_arg {
+       char                            *name;  /* Argument name */
+       char                            *value; /* Base value */
+       char                            *type;  /* Type name */
+       struct kprobe_trace_arg_ref     *ref;   /* Referencing offset */
+};
+
+/* kprobe-tracer tracing event (point + arg) */
+struct kprobe_trace_event {
+       char                            *event; /* Event name */
+       char                            *group; /* Group name */
+       struct kprobe_trace_point       point;  /* Trace point */
+       int                             nargs;  /* Number of args */
+       struct kprobe_trace_arg         *args;  /* Arguments */
+};
+
+/* Perf probe probing point */
+struct perf_probe_point {
+       char            *file;          /* File path */
+       char            *function;      /* Function name */
+       int             line;           /* Line number */
+       bool            retprobe;       /* Return probe flag */
+       char            *lazy_line;     /* Lazy matching pattern */
+       unsigned long   offset;         /* Offset from function entry */
+};
+
+/* Perf probe probing argument field chain */
+struct perf_probe_arg_field {
+       struct perf_probe_arg_field     *next;  /* Next field */
+       char                            *name;  /* Name of the field */
+       bool                            ref;    /* Referencing flag */
+};
+
+/* Perf probe probing argument */
+struct perf_probe_arg {
+       char                            *name;  /* Argument name */
+       char                            *var;   /* Variable name */
+       char                            *type;  /* Type name */
+       struct perf_probe_arg_field     *field; /* Structure fields */
+};
+
+/* Perf probe probing event (point + arg) */
+struct perf_probe_event {
+       char                    *event; /* Event name */
+       char                    *group; /* Group name */
+       struct perf_probe_point point;  /* Probe point */
+       int                     nargs;  /* Number of arguments */
+       struct perf_probe_arg   *args;  /* Arguments */
+};
+
+
+/* Line number container */
+struct line_node {
+       struct list_head        list;
+       int                     line;
+};
+
+/* Line range */
+struct line_range {
+       char                    *file;          /* File name */
+       char                    *function;      /* Function name */
+       int                     start;          /* Start line number */
+       int                     end;            /* End line number */
+       int                     offset;         /* Start line offset */
+       char                    *path;          /* Real path name */
+       struct list_head        line_list;      /* Visible lines */
+};
+
+/* Command string to events */
+extern int parse_perf_probe_command(const char *cmd,
+                                   struct perf_probe_event *pev);
+extern int parse_kprobe_trace_command(const char *cmd,
+                                     struct kprobe_trace_event *tev);
+
+/* Events to command string */
+extern char *synthesize_perf_probe_command(struct perf_probe_event *pev);
+extern char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev);
+extern int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf,
+                                    size_t len);
+
+/* Check the perf_probe_event needs debuginfo */
+extern bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);
+
+/* Convert from kprobe_trace_event to perf_probe_event */
+extern int convert_to_perf_probe_event(struct kprobe_trace_event *tev,
+                                      struct perf_probe_event *pev);
+
+/* Release event contents */
+extern void clear_perf_probe_event(struct perf_probe_event *pev);
+extern void clear_kprobe_trace_event(struct kprobe_trace_event *tev);
+
+/* Command string to line-range */
+extern int parse_line_range_desc(const char *cmd, struct line_range *lr);
+
+
+extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
+                                bool force_add, int max_probe_points);
+extern int del_perf_probe_events(struct strlist *dellist);
+extern int show_perf_probe_events(void);
+extern int show_line_range(struct line_range *lr);
+
 
 /* Maximum index number of event-name postfix */
 #define MAX_EVENT_INDEX        1024
index e77dc886760e5350ea56d1043d400e914678b817..562b1443e785358c7c72a2fd55df0e76332a7d96 100644 (file)
@@ -31,6 +31,7 @@
 #include <string.h>
 #include <stdarg.h>
 #include <ctype.h>
+#include <dwarf-regs.h>
 
 #include "string.h"
 #include "event.h"
 #include "util.h"
 #include "probe-finder.h"
 
-
-/*
- * 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;
-}
+/* Kprobe tracer basic type is up to u64 */
+#define MAX_BASIC_TYPE_BITS    64
 
 /*
  * Compare the tail of two strings.
@@ -108,7 +60,7 @@ static int strtailcmp(const char *s1, const char *s2)
 /* Line number list operations */
 
 /* Add a line to line number list */
-static void line_list__add_line(struct list_head *head, unsigned int line)
+static int line_list__add_line(struct list_head *head, int line)
 {
        struct line_node *ln;
        struct list_head *p;
@@ -119,21 +71,23 @@ static void line_list__add_line(struct list_head *head, unsigned int line)
                        p = &ln->list;
                        goto found;
                } else if (ln->line == line)    /* Already exist */
-                       return ;
+                       return 1;
        }
        /* List is empty, or the smallest entry */
        p = head;
 found:
        pr_debug("line list: add a line %u\n", line);
        ln = zalloc(sizeof(struct line_node));
-       DIE_IF(ln == NULL);
+       if (ln == NULL)
+               return -ENOMEM;
        ln->line = line;
        INIT_LIST_HEAD(&ln->list);
        list_add(&ln->list, p);
+       return 0;
 }
 
 /* Check if the line in line number list */
-static int line_list__has_line(struct list_head *head, unsigned int line)
+static int line_list__has_line(struct list_head *head, int line)
 {
        struct line_node *ln;
 
@@ -169,7 +123,7 @@ static const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname)
 {
        Dwarf_Files *files;
        size_t nfiles, i;
-       const char *src;
+       const char *src = NULL;
        int ret;
 
        if (!fname)
@@ -184,9 +138,129 @@ static const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname)
                if (strtailcmp(src, fname) == 0)
                        break;
        }
+       if (i == nfiles)
+               return NULL;
        return src;
 }
 
+/* Compare diename and tname */
+static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
+{
+       const char *name;
+       name = dwarf_diename(dw_die);
+       return name ? strcmp(tname, name) : -1;
+}
+
+/* Get type die, but skip qualifiers and typedef */
+static Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
+{
+       Dwarf_Attribute attr;
+       int tag;
+
+       do {
+               if (dwarf_attr(vr_die, DW_AT_type, &attr) == NULL ||
+                   dwarf_formref_die(&attr, die_mem) == NULL)
+                       return NULL;
+
+               tag = dwarf_tag(die_mem);
+               vr_die = die_mem;
+       } while (tag == DW_TAG_const_type ||
+                tag == DW_TAG_restrict_type ||
+                tag == DW_TAG_volatile_type ||
+                tag == DW_TAG_shared_type ||
+                tag == DW_TAG_typedef);
+
+       return die_mem;
+}
+
+static bool die_is_signed_type(Dwarf_Die *tp_die)
+{
+       Dwarf_Attribute attr;
+       Dwarf_Word ret;
+
+       if (dwarf_attr(tp_die, DW_AT_encoding, &attr) == NULL ||
+           dwarf_formudata(&attr, &ret) != 0)
+               return false;
+
+       return (ret == DW_ATE_signed_char || ret == DW_ATE_signed ||
+               ret == DW_ATE_signed_fixed);
+}
+
+static int die_get_byte_size(Dwarf_Die *tp_die)
+{
+       Dwarf_Attribute attr;
+       Dwarf_Word ret;
+
+       if (dwarf_attr(tp_die, DW_AT_byte_size, &attr) == NULL ||
+           dwarf_formudata(&attr, &ret) != 0)
+               return 0;
+
+       return (int)ret;
+}
+
+/* Get data_member_location offset */
+static int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
+{
+       Dwarf_Attribute attr;
+       Dwarf_Op *expr;
+       size_t nexpr;
+       int ret;
+
+       if (dwarf_attr(mb_die, DW_AT_data_member_location, &attr) == NULL)
+               return -ENOENT;
+
+       if (dwarf_formudata(&attr, offs) != 0) {
+               /* DW_AT_data_member_location should be DW_OP_plus_uconst */
+               ret = dwarf_getlocation(&attr, &expr, &nexpr);
+               if (ret < 0 || nexpr == 0)
+                       return -ENOENT;
+
+               if (expr[0].atom != DW_OP_plus_uconst || nexpr != 1) {
+                       pr_debug("Unable to get offset:Unexpected OP %x (%zd)\n",
+                                expr[0].atom, nexpr);
+                       return -ENOTSUP;
+               }
+               *offs = (Dwarf_Word)expr[0].number;
+       }
+       return 0;
+}
+
+/* Return values for die_find callbacks */
+enum {
+       DIE_FIND_CB_FOUND = 0,          /* End of Search */
+       DIE_FIND_CB_CHILD = 1,          /* Search only children */
+       DIE_FIND_CB_SIBLING = 2,        /* Search only siblings */
+       DIE_FIND_CB_CONTINUE = 3,       /* Search children and siblings */
+};
+
+/* Search a child die */
+static Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
+                                int (*callback)(Dwarf_Die *, void *),
+                                void *data, Dwarf_Die *die_mem)
+{
+       Dwarf_Die child_die;
+       int ret;
+
+       ret = dwarf_child(rt_die, die_mem);
+       if (ret != 0)
+               return NULL;
+
+       do {
+               ret = callback(die_mem, data);
+               if (ret == DIE_FIND_CB_FOUND)
+                       return die_mem;
+
+               if ((ret & DIE_FIND_CB_CHILD) &&
+                   die_find_child(die_mem, callback, data, &child_die)) {
+                       memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
+                       return die_mem;
+               }
+       } while ((ret & DIE_FIND_CB_SIBLING) &&
+                dwarf_siblingof(die_mem, die_mem) == 0);
+
+       return NULL;
+}
+
 struct __addr_die_search_param {
        Dwarf_Addr      addr;
        Dwarf_Die       *die_mem;
@@ -205,8 +279,8 @@ static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
 }
 
 /* Search a real subprogram including this line, */
-static Dwarf_Die *die_get_real_subprogram(Dwarf_Die *cu_die, Dwarf_Addr addr,
-                                         Dwarf_Die *die_mem)
+static Dwarf_Die *die_find_real_subprogram(Dwarf_Die *cu_die, Dwarf_Addr addr,
+                                          Dwarf_Die *die_mem)
 {
        struct __addr_die_search_param ad;
        ad.addr = addr;
@@ -218,77 +292,64 @@ static Dwarf_Die *die_get_real_subprogram(Dwarf_Die *cu_die, Dwarf_Addr addr,
                return die_mem;
 }
 
-/* Similar to dwarf_getfuncs, but returns inlined_subroutine if exists. */
-static Dwarf_Die *die_get_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
-                                    Dwarf_Die *die_mem)
+/* die_find callback for inline function search */
+static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data)
 {
-       Dwarf_Die child_die;
-       int ret;
+       Dwarf_Addr *addr = data;
 
-       ret = dwarf_child(sp_die, die_mem);
-       if (ret != 0)
-               return NULL;
+       if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine &&
+           dwarf_haspc(die_mem, *addr))
+               return DIE_FIND_CB_FOUND;
 
-       do {
-               if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine &&
-                   dwarf_haspc(die_mem, addr))
-                       return die_mem;
-
-               if (die_get_inlinefunc(die_mem, addr, &child_die)) {
-                       memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
-                       return die_mem;
-               }
-       } while (dwarf_siblingof(die_mem, die_mem) == 0);
-
-       return NULL;
+       return DIE_FIND_CB_CONTINUE;
 }
 
-/* Compare diename and tname */
-static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
+/* Similar to dwarf_getfuncs, but returns inlined_subroutine if exists. */
+static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
+                                     Dwarf_Die *die_mem)
 {
-       const char *name;
-       name = dwarf_diename(dw_die);
-       DIE_IF(name == NULL);
-       return strcmp(tname, name);
+       return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem);
 }
 
-/* Get entry pc(or low pc, 1st entry of ranges)  of the die */
-static Dwarf_Addr die_get_entrypc(Dwarf_Die *dw_die)
+static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data)
 {
-       Dwarf_Addr epc;
-       int ret;
+       const char *name = data;
+       int tag;
 
-       ret = dwarf_entrypc(dw_die, &epc);
-       DIE_IF(ret == -1);
-       return epc;
+       tag = dwarf_tag(die_mem);
+       if ((tag == DW_TAG_formal_parameter ||
+            tag == DW_TAG_variable) &&
+           (die_compare_name(die_mem, name) == 0))
+               return DIE_FIND_CB_FOUND;
+
+       return DIE_FIND_CB_CONTINUE;
 }
 
-/* Get a variable die */
+/* Find a variable called 'name' */
 static Dwarf_Die *die_find_variable(Dwarf_Die *sp_die, const char *name,
                                    Dwarf_Die *die_mem)
 {
-       Dwarf_Die child_die;
-       int tag;
-       int ret;
+       return die_find_child(sp_die, __die_find_variable_cb, (void *)name,
+                             die_mem);
+}
 
-       ret = dwarf_child(sp_die, die_mem);
-       if (ret != 0)
-               return NULL;
+static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
+{
+       const char *name = data;
 
-       do {
-               tag = dwarf_tag(die_mem);
-               if ((tag == DW_TAG_formal_parameter ||
-                    tag == DW_TAG_variable) &&
-                   (die_compare_name(die_mem, name) == 0))
-                       return die_mem;
+       if ((dwarf_tag(die_mem) == DW_TAG_member) &&
+           (die_compare_name(die_mem, name) == 0))
+               return DIE_FIND_CB_FOUND;
 
-               if (die_find_variable(die_mem, name, &child_die)) {
-                       memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
-                       return die_mem;
-               }
-       } while (dwarf_siblingof(die_mem, die_mem) == 0);
+       return DIE_FIND_CB_SIBLING;
+}
 
-       return NULL;
+/* Find a member called 'name' */
+static Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
+                                 Dwarf_Die *die_mem)
+{
+       return die_find_child(st_die, __die_find_member_cb, (void *)name,
+                             die_mem);
 }
 
 /*
@@ -296,19 +357,22 @@ static Dwarf_Die *die_find_variable(Dwarf_Die *sp_die, const char *name,
  */
 
 /* Show a location */
-static void show_location(Dwarf_Op *op, struct probe_finder *pf)
+static int convert_location(Dwarf_Op *op, struct probe_finder *pf)
 {
        unsigned int regn;
        Dwarf_Word offs = 0;
-       int deref = 0, ret;
+       bool ref = false;
        const char *regs;
+       struct kprobe_trace_arg *tvar = pf->tvar;
 
-       /* TODO: support CFA */
        /* If this is based on frame buffer, set the offset */
        if (op->atom == DW_OP_fbreg) {
-               if (pf->fb_ops == NULL)
-                       die("The attribute of frame base is not supported.\n");
-               deref = 1;
+               if (pf->fb_ops == NULL) {
+                       pr_warning("The attribute of frame base is not "
+                                  "supported.\n");
+                       return -ENOTSUP;
+               }
+               ref = true;
                offs = op->number;
                op = &pf->fb_ops[0];
        }
@@ -316,35 +380,164 @@ static void show_location(Dwarf_Op *op, struct probe_finder *pf)
        if (op->atom >= DW_OP_breg0 && op->atom <= DW_OP_breg31) {
                regn = op->atom - DW_OP_breg0;
                offs += op->number;
-               deref = 1;
+               ref = true;
        } else if (op->atom >= DW_OP_reg0 && op->atom <= DW_OP_reg31) {
                regn = op->atom - DW_OP_reg0;
        } else if (op->atom == DW_OP_bregx) {
                regn = op->number;
                offs += op->number2;
-               deref = 1;
+               ref = true;
        } else if (op->atom == DW_OP_regx) {
                regn = op->number;
-       } else
-               die("DW_OP %d is not supported.", op->atom);
+       } else {
+               pr_warning("DW_OP %x is not supported.\n", op->atom);
+               return -ENOTSUP;
+       }
 
        regs = get_arch_regstr(regn);
-       if (!regs)
-               die("%u exceeds max register number.", regn);
+       if (!regs) {
+               pr_warning("Mapping for DWARF register number %u missing on this architecture.", regn);
+               return -ERANGE;
+       }
+
+       tvar->value = strdup(regs);
+       if (tvar->value == NULL)
+               return -ENOMEM;
+
+       if (ref) {
+               tvar->ref = zalloc(sizeof(struct kprobe_trace_arg_ref));
+               if (tvar->ref == NULL)
+                       return -ENOMEM;
+               tvar->ref->offset = (long)offs;
+       }
+       return 0;
+}
+
+static int convert_variable_type(Dwarf_Die *vr_die,
+                                struct kprobe_trace_arg *targ)
+{
+       Dwarf_Die type;
+       char buf[16];
+       int ret;
 
-       if (deref)
-               ret = snprintf(pf->buf, pf->len, " %s=+%ju(%s)",
-                              pf->var, (uintmax_t)offs, regs);
+       if (die_get_real_type(vr_die, &type) == NULL) {
+               pr_warning("Failed to get a type information of %s.\n",
+                          dwarf_diename(vr_die));
+               return -ENOENT;
+       }
+
+       ret = die_get_byte_size(&type) * 8;
+       if (ret) {
+               /* Check the bitwidth */
+               if (ret > MAX_BASIC_TYPE_BITS) {
+                       pr_info("%s exceeds max-bitwidth."
+                               " Cut down to %d bits.\n",
+                               dwarf_diename(&type), MAX_BASIC_TYPE_BITS);
+                       ret = MAX_BASIC_TYPE_BITS;
+               }
+
+               ret = snprintf(buf, 16, "%c%d",
+                              die_is_signed_type(&type) ? 's' : 'u', ret);
+               if (ret < 0 || ret >= 16) {
+                       if (ret >= 16)
+                               ret = -E2BIG;
+                       pr_warning("Failed to convert variable type: %s\n",
+                                  strerror(-ret));
+                       return ret;
+               }
+               targ->type = strdup(buf);
+               if (targ->type == NULL)
+                       return -ENOMEM;
+       }
+       return 0;
+}
+
+static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
+                                   struct perf_probe_arg_field *field,
+                                   struct kprobe_trace_arg_ref **ref_ptr,
+                                   Dwarf_Die *die_mem)
+{
+       struct kprobe_trace_arg_ref *ref = *ref_ptr;
+       Dwarf_Die type;
+       Dwarf_Word offs;
+       int ret;
+
+       pr_debug("converting %s in %s\n", field->name, varname);
+       if (die_get_real_type(vr_die, &type) == NULL) {
+               pr_warning("Failed to get the type of %s.\n", varname);
+               return -ENOENT;
+       }
+
+       /* Check the pointer and dereference */
+       if (dwarf_tag(&type) == DW_TAG_pointer_type) {
+               if (!field->ref) {
+                       pr_err("Semantic error: %s must be referred by '->'\n",
+                              field->name);
+                       return -EINVAL;
+               }
+               /* Get the type pointed by this pointer */
+               if (die_get_real_type(&type, &type) == NULL) {
+                       pr_warning("Failed to get the type of %s.\n", varname);
+                       return -ENOENT;
+               }
+               /* Verify it is a data structure  */
+               if (dwarf_tag(&type) != DW_TAG_structure_type) {
+                       pr_warning("%s is not a data structure.\n", varname);
+                       return -EINVAL;
+               }
+
+               ref = zalloc(sizeof(struct kprobe_trace_arg_ref));
+               if (ref == NULL)
+                       return -ENOMEM;
+               if (*ref_ptr)
+                       (*ref_ptr)->next = ref;
+               else
+                       *ref_ptr = ref;
+       } else {
+               /* Verify it is a data structure  */
+               if (dwarf_tag(&type) != DW_TAG_structure_type) {
+                       pr_warning("%s is not a data structure.\n", varname);
+                       return -EINVAL;
+               }
+               if (field->ref) {
+                       pr_err("Semantic error: %s must be referred by '.'\n",
+                              field->name);
+                       return -EINVAL;
+               }
+               if (!ref) {
+                       pr_warning("Structure on a register is not "
+                                  "supported yet.\n");
+                       return -ENOTSUP;
+               }
+       }
+
+       if (die_find_member(&type, field->name, die_mem) == NULL) {
+               pr_warning("%s(tyep:%s) has no member %s.\n", varname,
+                          dwarf_diename(&type), field->name);
+               return -EINVAL;
+       }
+
+       /* Get the offset of the field */
+       ret = die_get_data_member_location(die_mem, &offs);
+       if (ret < 0) {
+               pr_warning("Failed to get the offset of %s.\n", field->name);
+               return ret;
+       }
+       ref->offset += (long)offs;
+
+       /* Converting next field */
+       if (field->next)
+               return convert_variable_fields(die_mem, field->name,
+                                       field->next, &ref, die_mem);
        else
-               ret = snprintf(pf->buf, pf->len, " %s=%s", pf->var, regs);
-       DIE_IF(ret < 0);
-       DIE_IF(ret >= pf->len);
+               return 0;
 }
 
 /* Show a variables in kprobe event format */
-static void show_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
+static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
 {
        Dwarf_Attribute attr;
+       Dwarf_Die die_mem;
        Dwarf_Op *expr;
        size_t nexpr;
        int ret;
@@ -352,145 +545,195 @@ static void show_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
        if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
                goto error;
        /* TODO: handle more than 1 exprs */
-       ret = dwarf_getlocation_addr(&attr, (pf->addr - pf->cu_base),
-                                    &expr, &nexpr, 1);
+       ret = dwarf_getlocation_addr(&attr, pf->addr, &expr, &nexpr, 1);
        if (ret <= 0 || nexpr == 0)
                goto error;
 
-       show_location(expr, pf);
+       ret = convert_location(expr, pf);
+       if (ret == 0 && pf->pvar->field) {
+               ret = convert_variable_fields(vr_die, pf->pvar->var,
+                                             pf->pvar->field, &pf->tvar->ref,
+                                             &die_mem);
+               vr_die = &die_mem;
+       }
+       if (ret == 0) {
+               if (pf->pvar->type) {
+                       pf->tvar->type = strdup(pf->pvar->type);
+                       if (pf->tvar->type == NULL)
+                               ret = -ENOMEM;
+               } else
+                       ret = convert_variable_type(vr_die, pf->tvar);
+       }
        /* *expr will be cached in libdw. Don't free it. */
-       return ;
+       return ret;
 error:
        /* TODO: Support const_value */
-       die("Failed to find the location of %s at this address.\n"
-           " Perhaps, it has been optimized out.", pf->var);
+       pr_err("Failed to find the location of %s at this address.\n"
+              " Perhaps, it has been optimized out.\n", pf->pvar->var);
+       return -ENOENT;
 }
 
 /* Find a variable in a subprogram die */
-static void find_variable(Dwarf_Die *sp_die, struct probe_finder *pf)
+static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf)
 {
-       int ret;
        Dwarf_Die vr_die;
+       char buf[32], *ptr;
+       int ret;
 
-       /* TODO: Support struct members and arrays */
-       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 ;
+       /* TODO: Support arrays */
+       if (pf->pvar->name)
+               pf->tvar->name = strdup(pf->pvar->name);
+       else {
+               ret = synthesize_perf_probe_arg(pf->pvar, buf, 32);
+               if (ret < 0)
+                       return ret;
+               ptr = strchr(buf, ':'); /* Change type separator to _ */
+               if (ptr)
+                       *ptr = '_';
+               pf->tvar->name = strdup(buf);
+       }
+       if (pf->tvar->name == NULL)
+               return -ENOMEM;
+
+       if (!is_c_varname(pf->pvar->var)) {
+               /* Copy raw parameters */
+               pf->tvar->value = strdup(pf->pvar->var);
+               if (pf->tvar->value == NULL)
+                       return -ENOMEM;
+               else
+                       return 0;
        }
 
-       pr_debug("Searching '%s' variable in context.\n", pf->var);
+       pr_debug("Searching '%s' variable in context.\n",
+                pf->pvar->var);
        /* Search child die for local variables and parameters. */
-       if (!die_find_variable(sp_die, pf->var, &vr_die))
-               die("Failed to find '%s' in this function.", pf->var);
-
-       show_variable(&vr_die, pf);
+       if (!die_find_variable(sp_die, pf->pvar->var, &vr_die)) {
+               pr_warning("Failed to find '%s' in this function.\n",
+                          pf->pvar->var);
+               return -ENOENT;
+       }
+       return convert_variable(&vr_die, pf);
 }
 
 /* Show a probe point to output buffer */
-static void show_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf)
+static int convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf)
 {
-       struct probe_point *pp = pf->pp;
+       struct kprobe_trace_event *tev;
        Dwarf_Addr eaddr;
        Dwarf_Die die_mem;
        const char *name;
-       char tmp[MAX_PROBE_BUFFER];
-       int ret, i, len;
+       int ret, i;
        Dwarf_Attribute fb_attr;
        size_t nops;
 
+       if (pf->ntevs == pf->max_tevs) {
+               pr_warning("Too many( > %d) probe point found.\n",
+                          pf->max_tevs);
+               return -ERANGE;
+       }
+       tev = &pf->tevs[pf->ntevs++];
+
        /* If no real subprogram, find a real one */
        if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) {
-               sp_die = die_get_real_subprogram(&pf->cu_die,
+               sp_die = die_find_real_subprogram(&pf->cu_die,
                                                 pf->addr, &die_mem);
-               if (!sp_die)
-                       die("Probe point is not found in subprograms.");
+               if (!sp_die) {
+                       pr_warning("Failed to find probe point in any "
+                                  "functions.\n");
+                       return -ENOENT;
+               }
        }
 
-       /* Output name of probe point */
+       /* Copy the name of probe point */
        name = dwarf_diename(sp_die);
        if (name) {
-               dwarf_entrypc(sp_die, &eaddr);
-               ret = snprintf(tmp, MAX_PROBE_BUFFER, "%s+%lu", name,
-                               (unsigned long)(pf->addr - eaddr));
-               /* Copy the function name if possible */
-               if (!pp->function) {
-                       pp->function = strdup(name);
-                       pp->offset = (size_t)(pf->addr - eaddr);
+               if (dwarf_entrypc(sp_die, &eaddr) != 0) {
+                       pr_warning("Failed to get entry pc of %s\n",
+                                  dwarf_diename(sp_die));
+                       return -ENOENT;
                }
-       } else {
+               tev->point.symbol = strdup(name);
+               if (tev->point.symbol == NULL)
+                       return -ENOMEM;
+               tev->point.offset = (unsigned long)(pf->addr - eaddr);
+       } else
                /* This function has no name. */
-               ret = snprintf(tmp, MAX_PROBE_BUFFER, "0x%jx",
-                              (uintmax_t)pf->addr);
-               if (!pp->function) {
-                       /* TODO: Use _stext */
-                       pp->function = strdup("");
-                       pp->offset = (size_t)pf->addr;
-               }
-       }
-       DIE_IF(ret < 0);
-       DIE_IF(ret >= MAX_PROBE_BUFFER);
-       len = ret;
-       pr_debug("Probe point found: %s\n", tmp);
+               tev->point.offset = (unsigned long)pf->addr;
+
+       pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
+                tev->point.offset);
 
        /* Get the frame base attribute/ops */
        dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr);
-       ret = dwarf_getlocation_addr(&fb_attr, (pf->addr - pf->cu_base),
-                                    &pf->fb_ops, &nops, 1);
-       if (ret <= 0 || nops == 0)
+       ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1);
+       if (ret <= 0 || nops == 0) {
                pf->fb_ops = NULL;
+       } else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa &&
+                  pf->cfi != NULL) {
+               Dwarf_Frame *frame;
+               if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 ||
+                   dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) {
+                       pr_warning("Failed to get CFA on 0x%jx\n",
+                                  (uintmax_t)pf->addr);
+                       return -ENOENT;
+               }
+       }
 
        /* Find each argument */
-       /* TODO: use dwarf_cfi_addrframe */
-       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);
+       tev->nargs = pf->pev->nargs;
+       tev->args = zalloc(sizeof(struct kprobe_trace_arg) * tev->nargs);
+       if (tev->args == NULL)
+               return -ENOMEM;
+       for (i = 0; i < pf->pev->nargs; i++) {
+               pf->pvar = &pf->pev->args[i];
+               pf->tvar = &tev->args[i];
+               ret = find_variable(sp_die, pf);
+               if (ret != 0)
+                       return ret;
        }
 
        /* *pf->fb_ops will be cached in libdw. Don't free it. */
        pf->fb_ops = NULL;
-
-       pp->probes[pp->found] = strdup(tmp);
-       pp->found++;
+       return 0;
 }
 
 /* Find probe point from its line number */
-static void find_probe_point_by_line(struct probe_finder *pf)
+static int find_probe_point_by_line(struct probe_finder *pf)
 {
        Dwarf_Lines *lines;
        Dwarf_Line *line;
        size_t nlines, i;
        Dwarf_Addr addr;
        int lineno;
-       int ret;
+       int ret = 0;
 
-       ret = dwarf_getsrclines(&pf->cu_die, &lines, &nlines);
-       DIE_IF(ret != 0);
+       if (dwarf_getsrclines(&pf->cu_die, &lines, &nlines) != 0) {
+               pr_warning("No source lines found in this CU.\n");
+               return -ENOENT;
+       }
 
-       for (i = 0; i < nlines; i++) {
+       for (i = 0; i < nlines && ret == 0; i++) {
                line = dwarf_onesrcline(lines, i);
-               dwarf_lineno(line, &lineno);
-               if (lineno != pf->lno)
+               if (dwarf_lineno(line, &lineno) != 0 ||
+                   lineno != pf->lno)
                        continue;
 
                /* TODO: Get fileno from line, but how? */
                if (strtailcmp(dwarf_linesrc(line, NULL, NULL), pf->fname) != 0)
                        continue;
 
-               ret = dwarf_lineaddr(line, &addr);
-               DIE_IF(ret != 0);
+               if (dwarf_lineaddr(line, &addr) != 0) {
+                       pr_warning("Failed to get the address of the line.\n");
+                       return -ENOENT;
+               }
                pr_debug("Probe line found: line[%d]:%d addr:0x%jx\n",
                         (int)i, lineno, (uintmax_t)addr);
                pf->addr = addr;
 
-               show_probe_point(NULL, pf);
+               ret = convert_probe_point(NULL, pf);
                /* Continuing, because target line might be inlined. */
        }
+       return ret;
 }
 
 /* Find lines which match lazy pattern */
@@ -498,16 +741,27 @@ static int find_lazy_match_lines(struct list_head *head,
                                 const char *fname, const char *pat)
 {
        char *fbuf, *p1, *p2;
-       int fd, line, nlines = 0;
+       int fd, ret, line, nlines = 0;
        struct stat st;
 
        fd = open(fname, O_RDONLY);
-       if (fd < 0)
-               die("failed to open %s", fname);
-       DIE_IF(fstat(fd, &st) < 0);
-       fbuf = malloc(st.st_size + 2);
-       DIE_IF(fbuf == NULL);
-       DIE_IF(read(fd, fbuf, st.st_size) < 0);
+       if (fd < 0) {
+               pr_warning("Failed to open %s: %s\n", fname, strerror(-fd));
+               return fd;
+       }
+
+       ret = fstat(fd, &st);
+       if (ret < 0) {
+               pr_warning("Failed to get the size of %s: %s\n",
+                          fname, strerror(errno));
+               return ret;
+       }
+       fbuf = xmalloc(st.st_size + 2);
+       ret = read(fd, fbuf, st.st_size);
+       if (ret < 0) {
+               pr_warning("Failed to read %s: %s\n", fname, strerror(errno));
+               return ret;
+       }
        close(fd);
        fbuf[st.st_size] = '\n';        /* Dummy line */
        fbuf[st.st_size + 1] = '\0';
@@ -527,7 +781,7 @@ static int find_lazy_match_lines(struct list_head *head,
 }
 
 /* Find probe points from lazy pattern  */
-static void find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
+static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
 {
        Dwarf_Lines *lines;
        Dwarf_Line *line;
@@ -535,37 +789,46 @@ static void find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
        Dwarf_Addr addr;
        Dwarf_Die die_mem;
        int lineno;
-       int ret;
+       int ret = 0;
 
        if (list_empty(&pf->lcache)) {
                /* Matching lazy line pattern */
                ret = find_lazy_match_lines(&pf->lcache, pf->fname,
-                                           pf->pp->lazy_line);
-               if (ret <= 0)
-                       die("No matched lines found in %s.", pf->fname);
+                                           pf->pev->point.lazy_line);
+               if (ret == 0) {
+                       pr_debug("No matched lines found in %s.\n", pf->fname);
+                       return 0;
+               } else if (ret < 0)
+                       return ret;
        }
 
-       ret = dwarf_getsrclines(&pf->cu_die, &lines, &nlines);
-       DIE_IF(ret != 0);
-       for (i = 0; i < nlines; i++) {
+       if (dwarf_getsrclines(&pf->cu_die, &lines, &nlines) != 0) {
+               pr_warning("No source lines found in this CU.\n");
+               return -ENOENT;
+       }
+
+       for (i = 0; i < nlines && ret >= 0; i++) {
                line = dwarf_onesrcline(lines, i);
 
-               dwarf_lineno(line, &lineno);
-               if (!line_list__has_line(&pf->lcache, lineno))
+               if (dwarf_lineno(line, &lineno) != 0 ||
+                   !line_list__has_line(&pf->lcache, lineno))
                        continue;
 
                /* TODO: Get fileno from line, but how? */
                if (strtailcmp(dwarf_linesrc(line, NULL, NULL), pf->fname) != 0)
                        continue;
 
-               ret = dwarf_lineaddr(line, &addr);
-               DIE_IF(ret != 0);
+               if (dwarf_lineaddr(line, &addr) != 0) {
+                       pr_debug("Failed to get the address of line %d.\n",
+                                lineno);
+                       continue;
+               }
                if (sp_die) {
                        /* Address filtering 1: does sp_die include addr? */
                        if (!dwarf_haspc(sp_die, addr))
                                continue;
                        /* Address filtering 2: No child include addr? */
-                       if (die_get_inlinefunc(sp_die, addr, &die_mem))
+                       if (die_find_inlinefunc(sp_die, addr, &die_mem))
                                continue;
                }
 
@@ -573,27 +836,44 @@ static void find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
                         (int)i, lineno, (unsigned long long)addr);
                pf->addr = addr;
 
-               show_probe_point(sp_die, pf);
+               ret = convert_probe_point(sp_die, pf);
                /* Continuing, because target line might be inlined. */
        }
        /* TODO: deallocate lines, but how? */
+       return ret;
 }
 
+/* Callback parameter with return value */
+struct dwarf_callback_param {
+       void *data;
+       int retval;
+};
+
 static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
 {
-       struct probe_finder *pf = (struct probe_finder *)data;
-       struct probe_point *pp = pf->pp;
+       struct dwarf_callback_param *param = data;
+       struct probe_finder *pf = param->data;
+       struct perf_probe_point *pp = &pf->pev->point;
+       Dwarf_Addr addr;
 
        if (pp->lazy_line)
-               find_probe_point_lazy(in_die, pf);
+               param->retval = find_probe_point_lazy(in_die, pf);
        else {
                /* Get probe address */
-               pf->addr = die_get_entrypc(in_die);
+               if (dwarf_entrypc(in_die, &addr) != 0) {
+                       pr_warning("Failed to get entry pc of %s.\n",
+                                  dwarf_diename(in_die));
+                       param->retval = -ENOENT;
+                       return DWARF_CB_ABORT;
+               }
+               pf->addr = addr;
                pf->addr += pp->offset;
                pr_debug("found inline addr: 0x%jx\n",
                         (uintmax_t)pf->addr);
 
-               show_probe_point(in_die, pf);
+               param->retval = convert_probe_point(in_die, pf);
+               if (param->retval < 0)
+                       return DWARF_CB_ABORT;
        }
 
        return DWARF_CB_OK;
@@ -602,60 +882,88 @@ static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
 /* Search function from function name */
 static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
 {
-       struct probe_finder *pf = (struct probe_finder *)data;
-       struct probe_point *pp = pf->pp;
+       struct dwarf_callback_param *param = data;
+       struct probe_finder *pf = param->data;
+       struct perf_probe_point *pp = &pf->pev->point;
 
        /* Check tag and diename */
        if (dwarf_tag(sp_die) != DW_TAG_subprogram ||
            die_compare_name(sp_die, pp->function) != 0)
-               return 0;
+               return DWARF_CB_OK;
 
        pf->fname = dwarf_decl_file(sp_die);
        if (pp->line) { /* Function relative line */
                dwarf_decl_line(sp_die, &pf->lno);
                pf->lno += pp->line;
-               find_probe_point_by_line(pf);
+               param->retval = find_probe_point_by_line(pf);
        } else if (!dwarf_func_inline(sp_die)) {
                /* Real function */
                if (pp->lazy_line)
-                       find_probe_point_lazy(sp_die, pf);
+                       param->retval = find_probe_point_lazy(sp_die, pf);
                else {
-                       pf->addr = die_get_entrypc(sp_die);
+                       if (dwarf_entrypc(sp_die, &pf->addr) != 0) {
+                               pr_warning("Failed to get entry pc of %s.\n",
+                                          dwarf_diename(sp_die));
+                               param->retval = -ENOENT;
+                               return DWARF_CB_ABORT;
+                       }
                        pf->addr += pp->offset;
                        /* TODO: Check the address in this function */
-                       show_probe_point(sp_die, pf);
+                       param->retval = convert_probe_point(sp_die, pf);
                }
-       } else
+       } else {
+               struct dwarf_callback_param _param = {.data = (void *)pf,
+                                                     .retval = 0};
                /* Inlined function: search instances */
-               dwarf_func_inline_instances(sp_die, probe_point_inline_cb, pf);
+               dwarf_func_inline_instances(sp_die, probe_point_inline_cb,
+                                           &_param);
+               param->retval = _param.retval;
+       }
 
-       return 1; /* Exit; no same symbol in this CU. */
+       return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */
 }
 
-static void find_probe_point_by_func(struct probe_finder *pf)
+static int find_probe_point_by_func(struct probe_finder *pf)
 {
-       dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, pf, 0);
+       struct dwarf_callback_param _param = {.data = (void *)pf,
+                                             .retval = 0};
+       dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, &_param, 0);
+       return _param.retval;
 }
 
-/* Find a probe point */
-int find_probe_point(int fd, struct probe_point *pp)
+/* Find kprobe_trace_events specified by perf_probe_event from debuginfo */
+int find_kprobe_trace_events(int fd, struct perf_probe_event *pev,
+                            struct kprobe_trace_event **tevs, int max_tevs)
 {
-       struct probe_finder pf = {.pp = pp};
-       int ret;
+       struct probe_finder pf = {.pev = pev, .max_tevs = max_tevs};
+       struct perf_probe_point *pp = &pev->point;
        Dwarf_Off off, noff;
        size_t cuhl;
        Dwarf_Die *diep;
        Dwarf *dbg;
+       int ret = 0;
+
+       pf.tevs = zalloc(sizeof(struct kprobe_trace_event) * max_tevs);
+       if (pf.tevs == NULL)
+               return -ENOMEM;
+       *tevs = pf.tevs;
+       pf.ntevs = 0;
 
        dbg = dwarf_begin(fd, DWARF_C_READ);
-       if (!dbg)
-               return -ENOENT;
+       if (!dbg) {
+               pr_warning("No dwarf info found in the vmlinux - "
+                       "please rebuild with CONFIG_DEBUG_INFO=y.\n");
+               return -EBADF;
+       }
+
+       /* Get the call frame information from this dwarf */
+       pf.cfi = dwarf_getcfi(dbg);
 
-       pp->found = 0;
        off = 0;
        line_list__init(&pf.lcache);
        /* Loop on CUs (Compilation Unit) */
-       while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
+       while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) &&
+              ret >= 0) {
                /* Get the DIE(Debugging Information Entry) of this CU */
                diep = dwarf_offdie(dbg, off + cuhl, &pf.cu_die);
                if (!diep)
@@ -668,17 +976,13 @@ int find_probe_point(int fd, struct probe_point *pp)
                        pf.fname = NULL;
 
                if (!pp->file || pf.fname) {
-                       /* Save CU base address (for frame_base) */
-                       ret = dwarf_lowpc(&pf.cu_die, &pf.cu_base);
-                       if (ret != 0)
-                               pf.cu_base = 0;
                        if (pp->function)
-                               find_probe_point_by_func(&pf);
+                               ret = find_probe_point_by_func(&pf);
                        else if (pp->lazy_line)
-                               find_probe_point_lazy(NULL, &pf);
+                               ret = find_probe_point_lazy(NULL, &pf);
                        else {
                                pf.lno = pp->line;
-                               find_probe_point_by_line(&pf);
+                               ret = find_probe_point_by_line(&pf);
                        }
                }
                off = noff;
@@ -686,41 +990,169 @@ int find_probe_point(int fd, struct probe_point *pp)
        line_list__free(&pf.lcache);
        dwarf_end(dbg);
 
-       return pp->found;
+       return (ret < 0) ? ret : pf.ntevs;
+}
+
+/* Reverse search */
+int find_perf_probe_point(int fd, unsigned long addr,
+                         struct perf_probe_point *ppt)
+{
+       Dwarf_Die cudie, spdie, indie;
+       Dwarf *dbg;
+       Dwarf_Line *line;
+       Dwarf_Addr laddr, eaddr;
+       const char *tmp;
+       int lineno, ret = 0;
+       bool found = false;
+
+       dbg = dwarf_begin(fd, DWARF_C_READ);
+       if (!dbg)
+               return -EBADF;
+
+       /* Find cu die */
+       if (!dwarf_addrdie(dbg, (Dwarf_Addr)addr, &cudie)) {
+               ret = -EINVAL;
+               goto end;
+       }
+
+       /* Find a corresponding line */
+       line = dwarf_getsrc_die(&cudie, (Dwarf_Addr)addr);
+       if (line) {
+               if (dwarf_lineaddr(line, &laddr) == 0 &&
+                   (Dwarf_Addr)addr == laddr &&
+                   dwarf_lineno(line, &lineno) == 0) {
+                       tmp = dwarf_linesrc(line, NULL, NULL);
+                       if (tmp) {
+                               ppt->line = lineno;
+                               ppt->file = strdup(tmp);
+                               if (ppt->file == NULL) {
+                                       ret = -ENOMEM;
+                                       goto end;
+                               }
+                               found = true;
+                       }
+               }
+       }
+
+       /* Find a corresponding function */
+       if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) {
+               tmp = dwarf_diename(&spdie);
+               if (!tmp || dwarf_entrypc(&spdie, &eaddr) != 0)
+                       goto end;
+
+               if (ppt->line) {
+                       if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr,
+                                               &indie)) {
+                               /* addr in an inline function */
+                               tmp = dwarf_diename(&indie);
+                               if (!tmp)
+                                       goto end;
+                               ret = dwarf_decl_line(&indie, &lineno);
+                       } else {
+                               if (eaddr == addr) {    /* Function entry */
+                                       lineno = ppt->line;
+                                       ret = 0;
+                               } else
+                                       ret = dwarf_decl_line(&spdie, &lineno);
+                       }
+                       if (ret == 0) {
+                               /* Make a relative line number */
+                               ppt->line -= lineno;
+                               goto found;
+                       }
+               }
+               /* We don't have a line number, let's use offset */
+               ppt->offset = addr - (unsigned long)eaddr;
+found:
+               ppt->function = strdup(tmp);
+               if (ppt->function == NULL) {
+                       ret = -ENOMEM;
+                       goto end;
+               }
+               found = true;
+       }
+
+end:
+       dwarf_end(dbg);
+       if (ret >= 0)
+               ret = found ? 1 : 0;
+       return ret;
+}
+
+/* Add a line and store the src path */
+static int line_range_add_line(const char *src, unsigned int lineno,
+                              struct line_range *lr)
+{
+       /* Copy real path */
+       if (!lr->path) {
+               lr->path = strdup(src);
+               if (lr->path == NULL)
+                       return -ENOMEM;
+       }
+       return line_list__add_line(&lr->line_list, lineno);
+}
+
+/* Search function declaration lines */
+static int line_range_funcdecl_cb(Dwarf_Die *sp_die, void *data)
+{
+       struct dwarf_callback_param *param = data;
+       struct line_finder *lf = param->data;
+       const char *src;
+       int lineno;
+
+       src = dwarf_decl_file(sp_die);
+       if (src && strtailcmp(src, lf->fname) != 0)
+               return DWARF_CB_OK;
+
+       if (dwarf_decl_line(sp_die, &lineno) != 0 ||
+           (lf->lno_s > lineno || lf->lno_e < lineno))
+               return DWARF_CB_OK;
+
+       param->retval = line_range_add_line(src, lineno, lf->lr);
+       if (param->retval < 0)
+               return DWARF_CB_ABORT;
+       return DWARF_CB_OK;
+}
+
+static int find_line_range_func_decl_lines(struct line_finder *lf)
+{
+       struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0};
+       dwarf_getfuncs(&lf->cu_die, line_range_funcdecl_cb, &param, 0);
+       return param.retval;
 }
 
 /* Find line range from its line number */
-static void find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
+static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
 {
        Dwarf_Lines *lines;
        Dwarf_Line *line;
        size_t nlines, i;
        Dwarf_Addr addr;
-       int lineno;
-       int ret;
+       int lineno, ret = 0;
        const char *src;
        Dwarf_Die die_mem;
 
        line_list__init(&lf->lr->line_list);
-       ret = dwarf_getsrclines(&lf->cu_die, &lines, &nlines);
-       DIE_IF(ret != 0);
+       if (dwarf_getsrclines(&lf->cu_die, &lines, &nlines) != 0) {
+               pr_warning("No source lines found in this CU.\n");
+               return -ENOENT;
+       }
 
+       /* Search probable lines on lines list */
        for (i = 0; i < nlines; i++) {
                line = dwarf_onesrcline(lines, i);
-               ret = dwarf_lineno(line, &lineno);
-               DIE_IF(ret != 0);
-               if (lf->lno_s > lineno || lf->lno_e < lineno)
+               if (dwarf_lineno(line, &lineno) != 0 ||
+                   (lf->lno_s > lineno || lf->lno_e < lineno))
                        continue;
 
                if (sp_die) {
                        /* Address filtering 1: does sp_die include addr? */
-                       ret = dwarf_lineaddr(line, &addr);
-                       DIE_IF(ret != 0);
-                       if (!dwarf_haspc(sp_die, addr))
+                       if (dwarf_lineaddr(line, &addr) != 0 ||
+                           !dwarf_haspc(sp_die, addr))
                                continue;
 
                        /* Address filtering 2: No child include addr? */
-                       if (die_get_inlinefunc(sp_die, addr, &die_mem))
+                       if (die_find_inlinefunc(sp_die, addr, &die_mem))
                                continue;
                }
 
@@ -729,30 +1161,49 @@ static void find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
                if (strtailcmp(src, lf->fname) != 0)
                        continue;
 
-               /* Copy real path */
-               if (!lf->lr->path)
-                       lf->lr->path = strdup(src);
-               line_list__add_line(&lf->lr->line_list, (unsigned int)lineno);
+               ret = line_range_add_line(src, lineno, lf->lr);
+               if (ret < 0)
+                       return ret;
        }
+
+       /*
+        * Dwarf lines doesn't include function declarations. We have to
+        * check functions list or given function.
+        */
+       if (sp_die) {
+               src = dwarf_decl_file(sp_die);
+               if (src && dwarf_decl_line(sp_die, &lineno) == 0 &&
+                   (lf->lno_s <= lineno && lf->lno_e >= lineno))
+                       ret = line_range_add_line(src, lineno, lf->lr);
+       } else
+               ret = find_line_range_func_decl_lines(lf);
+
        /* Update status */
-       if (!list_empty(&lf->lr->line_list))
-               lf->found = 1;
+       if (ret >= 0)
+               if (!list_empty(&lf->lr->line_list))
+                       ret = lf->found = 1;
+               else
+                       ret = 0;        /* Lines are not found */
        else {
                free(lf->lr->path);
                lf->lr->path = NULL;
        }
+       return ret;
 }
 
 static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
 {
-       find_line_range_by_line(in_die, (struct line_finder *)data);
+       struct dwarf_callback_param *param = data;
+
+       param->retval = find_line_range_by_line(in_die, param->data);
        return DWARF_CB_ABORT;  /* No need to find other instances */
 }
 
 /* Search function from function name */
 static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
 {
-       struct line_finder *lf = (struct line_finder *)data;
+       struct dwarf_callback_param *param = data;
+       struct line_finder *lf = param->data;
        struct line_range *lr = lf->lr;
 
        if (dwarf_tag(sp_die) == DW_TAG_subprogram &&
@@ -761,44 +1212,55 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
                dwarf_decl_line(sp_die, &lr->offset);
                pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset);
                lf->lno_s = lr->offset + lr->start;
-               if (!lr->end)
+               if (lf->lno_s < 0)      /* Overflow */
+                       lf->lno_s = INT_MAX;
+               lf->lno_e = lr->offset + lr->end;
+               if (lf->lno_e < 0)      /* Overflow */
                        lf->lno_e = INT_MAX;
-               else
-                       lf->lno_e = lr->offset + lr->end;
+               pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e);
                lr->start = lf->lno_s;
                lr->end = lf->lno_e;
-               if (dwarf_func_inline(sp_die))
+               if (dwarf_func_inline(sp_die)) {
+                       struct dwarf_callback_param _param;
+                       _param.data = (void *)lf;
+                       _param.retval = 0;
                        dwarf_func_inline_instances(sp_die,
-                                                   line_range_inline_cb, lf);
-               else
-                       find_line_range_by_line(sp_die, lf);
-               return 1;
+                                                   line_range_inline_cb,
+                                                   &_param);
+                       param->retval = _param.retval;
+               } else
+                       param->retval = find_line_range_by_line(sp_die, lf);
+               return DWARF_CB_ABORT;
        }
-       return 0;
+       return DWARF_CB_OK;
 }
 
-static void find_line_range_by_func(struct line_finder *lf)
+static int find_line_range_by_func(struct line_finder *lf)
 {
-       dwarf_getfuncs(&lf->cu_die, line_range_search_cb, lf, 0);
+       struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0};
+       dwarf_getfuncs(&lf->cu_die, line_range_search_cb, &param, 0);
+       return param.retval;
 }
 
 int find_line_range(int fd, struct line_range *lr)
 {
        struct line_finder lf = {.lr = lr, .found = 0};
-       int ret;
+       int ret = 0;
        Dwarf_Off off = 0, noff;
        size_t cuhl;
        Dwarf_Die *diep;
        Dwarf *dbg;
 
        dbg = dwarf_begin(fd, DWARF_C_READ);
-       if (!dbg)
-               return -ENOENT;
+       if (!dbg) {
+               pr_warning("No dwarf info found in the vmlinux - "
+                       "please rebuild with CONFIG_DEBUG_INFO=y.\n");
+               return -EBADF;
+       }
 
        /* Loop on CUs (Compilation Unit) */
-       while (!lf.found) {
-               ret = dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL);
-               if (ret != 0)
+       while (!lf.found && ret >= 0) {
+               if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0)
                        break;
 
                /* Get the DIE(Debugging Information Entry) of this CU */
@@ -814,20 +1276,18 @@ int find_line_range(int fd, struct line_range *lr)
 
                if (!lr->file || lf.fname) {
                        if (lr->function)
-                               find_line_range_by_func(&lf);
+                               ret = find_line_range_by_func(&lf);
                        else {
                                lf.lno_s = lr->start;
-                               if (!lr->end)
-                                       lf.lno_e = INT_MAX;
-                               else
-                                       lf.lno_e = lr->end;
-                               find_line_range_by_line(NULL, &lf);
+                               lf.lno_e = lr->end;
+                               ret = find_line_range_by_line(NULL, &lf);
                        }
                }
                off = noff;
        }
        pr_debug("path: %lx\n", (unsigned long)lr->path);
        dwarf_end(dbg);
-       return lf.found;
+
+       return (ret < 0) ? ret : lf.found;
 }
 
index d1a651793ba6661bf88684e62978f697d5cbd9f6..66f1980e3855477c86602485e43803b98b0032a8 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <stdbool.h>
 #include "util.h"
+#include "probe-event.h"
 
 #define MAX_PATH_LEN            256
 #define MAX_PROBE_BUFFER       1024
@@ -14,68 +15,39 @@ static inline int is_c_varname(const char *name)
        return isalpha(name[0]) || name[0] == '_';
 }
 
-struct probe_point {
-       char                    *event;                 /* Event name */
-       char                    *group;                 /* Event group */
+#ifdef DWARF_SUPPORT
+/* Find kprobe_trace_events specified by perf_probe_event from debuginfo */
+extern int find_kprobe_trace_events(int fd, struct perf_probe_event *pev,
+                                   struct kprobe_trace_event **tevs,
+                                   int max_tevs);
 
-       /* Inputs */
-       char                    *file;                  /* File name */
-       int                     line;                   /* Line number */
-       char                    *lazy_line;             /* Lazy line pattern */
+/* Find a perf_probe_point from debuginfo */
+extern int find_perf_probe_point(int fd, unsigned long addr,
+                                struct perf_probe_point *ppt);
 
-       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)*/
-};
-
-/* Line number container */
-struct line_node {
-       struct list_head        list;
-       unsigned int            line;
-};
-
-/* Line range */
-struct line_range {
-       char                    *file;                  /* File name */
-       char                    *function;              /* Function name */
-       unsigned int            start;                  /* Start line number */
-       unsigned int            end;                    /* End line number */
-       int                     offset;                 /* Start line offset */
-       char                    *path;                  /* Real path name */
-       struct list_head        line_list;              /* Visible lines */
-};
-
-#ifndef NO_DWARF_SUPPORT
-extern int find_probe_point(int fd, struct probe_point *pp);
 extern int find_line_range(int fd, struct line_range *lr);
 
 #include <dwarf.h>
 #include <libdw.h>
 
 struct probe_finder {
-       struct probe_point      *pp;            /* Target probe point */
+       struct perf_probe_event *pev;           /* Target probe event */
+       struct kprobe_trace_event *tevs;        /* Result trace events */
+       int                     ntevs;          /* Number of trace events */
+       int                     max_tevs;       /* Max number of trace events */
 
        /* For function searching */
-       Dwarf_Addr              addr;           /* Address */
-       const char              *fname;         /* File name */
        int                     lno;            /* Line number */
+       Dwarf_Addr              addr;           /* Address */
+       const char              *fname;         /* Real file name */
        Dwarf_Die               cu_die;         /* Current CU */
+       struct list_head        lcache;         /* Line cache for lazy match */
 
        /* For variable searching */
+       Dwarf_CFI               *cfi;           /* Call Frame Information */
        Dwarf_Op                *fb_ops;        /* Frame base attribute */
-       Dwarf_Addr              cu_base;        /* Current CU base address */
-       const char              *var;           /* Current variable name */
-       char                    *buf;           /* Current output buffer */
-       int                     len;            /* Length of output buffer */
-       struct list_head        lcache;         /* Line cache for lazy match */
+       struct perf_probe_arg   *pvar;          /* Current target variable */
+       struct kprobe_trace_arg *tvar;          /* Current result variable */
 };
 
 struct line_finder {
@@ -88,6 +60,6 @@ struct line_finder {
        int                     found;
 };
 
-#endif /* NO_DWARF_SUPPORT */
+#endif /* DWARF_SUPPORT */
 
 #endif /*_PROBE_FINDER_H */
diff --git a/tools/perf/util/pstack.c b/tools/perf/util/pstack.c
new file mode 100644 (file)
index 0000000..13d36fa
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Simple pointer stack
+ *
+ * (c) 2010 Arnaldo Carvalho de Melo <acme@redhat.com>
+ */
+
+#include "util.h"
+#include "pstack.h"
+#include <linux/kernel.h>
+#include <stdlib.h>
+
+struct pstack {
+       unsigned short  top;
+       unsigned short  max_nr_entries;
+       void            *entries[0];
+};
+
+struct pstack *pstack__new(unsigned short max_nr_entries)
+{
+       struct pstack *self = zalloc((sizeof(*self) +
+                                    max_nr_entries * sizeof(void *)));
+       if (self != NULL)
+               self->max_nr_entries = max_nr_entries;
+       return self;
+}
+
+void pstack__delete(struct pstack *self)
+{
+       free(self);
+}
+
+bool pstack__empty(const struct pstack *self)
+{
+       return self->top == 0;
+}
+
+void pstack__remove(struct pstack *self, void *key)
+{
+       unsigned short i = self->top, last_index = self->top - 1;
+
+       while (i-- != 0) {
+               if (self->entries[i] == key) {
+                       if (i < last_index)
+                               memmove(self->entries + i,
+                                       self->entries + i + 1,
+                                       (last_index - i) * sizeof(void *));
+                       --self->top;
+                       return;
+               }
+       }
+       pr_err("%s: %p not on the pstack!\n", __func__, key);
+}
+
+void pstack__push(struct pstack *self, void *key)
+{
+       if (self->top == self->max_nr_entries) {
+               pr_err("%s: top=%d, overflow!\n", __func__, self->top);
+               return;
+       }
+       self->entries[self->top++] = key;
+}
+
+void *pstack__pop(struct pstack *self)
+{
+       void *ret;
+
+       if (self->top == 0) {
+               pr_err("%s: underflow!\n", __func__);
+               return NULL;
+       }
+
+       ret = self->entries[--self->top];
+       self->entries[self->top] = NULL;
+       return ret;
+}
diff --git a/tools/perf/util/pstack.h b/tools/perf/util/pstack.h
new file mode 100644 (file)
index 0000000..5ad0702
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _PERF_PSTACK_
+#define _PERF_PSTACK_
+
+struct pstack;
+struct pstack *pstack__new(unsigned short max_nr_entries);
+void pstack__delete(struct pstack *self);
+bool pstack__empty(const struct pstack *self);
+void pstack__remove(struct pstack *self, void *key);
+void pstack__push(struct pstack *self, void *key);
+void *pstack__pop(struct pstack *self);
+
+#endif /* _PERF_PSTACK_ */
index 5376378e0cfcaf25fef5e684b5e172785c7990cd..b059dc50cc2db9021b75435e9aac132174c6dbec 100644 (file)
@@ -371,7 +371,6 @@ static int perl_start_script(const char *script, int argc, const char **argv)
        run_start_sub();
 
        free(command_line);
-       fprintf(stderr, "perf trace started with Perl script %s\n\n", script);
        return 0;
 error:
        perl_free(my_perl);
@@ -394,8 +393,6 @@ static int perl_stop_script(void)
        perl_destruct(my_perl);
        perl_free(my_perl);
 
-       fprintf(stderr, "\nperf trace Perl script stopped\n");
-
        return 0;
 }
 
index 33a414bbba3e1e1bbf410d9f984e401dc555e2b9..81f39cab3aaa5981b60d38e7402e21d5a359e3b2 100644 (file)
@@ -208,7 +208,7 @@ static void python_process_event(int cpu, void *data,
                                 int size __unused,
                                 unsigned long long nsecs, char *comm)
 {
-       PyObject *handler, *retval, *context, *t;
+       PyObject *handler, *retval, *context, *t, *obj;
        static char handler_name[256];
        struct format_field *field;
        unsigned long long val;
@@ -256,16 +256,23 @@ static void python_process_event(int cpu, void *data,
                                offset &= 0xffff;
                        } else
                                offset = field->offset;
-                       PyTuple_SetItem(t, n++,
-                               PyString_FromString((char *)data + offset));
+                       obj = PyString_FromString((char *)data + offset);
                } else { /* FIELD_IS_NUMERIC */
                        val = read_size(data + field->offset, field->size);
                        if (field->flags & FIELD_IS_SIGNED) {
-                               PyTuple_SetItem(t, n++, PyInt_FromLong(val));
+                               if ((long long)val >= LONG_MIN &&
+                                   (long long)val <= LONG_MAX)
+                                       obj = PyInt_FromLong(val);
+                               else
+                                       obj = PyLong_FromLongLong(val);
                        } else {
-                               PyTuple_SetItem(t, n++, PyInt_FromLong(val));
+                               if (val <= LONG_MAX)
+                                       obj = PyInt_FromLong(val);
+                               else
+                                       obj = PyLong_FromUnsignedLongLong(val);
                        }
                }
+               PyTuple_SetItem(t, n++, obj);
        }
 
        if (_PyTuple_Resize(&t, n) == -1)
@@ -367,8 +374,6 @@ static int python_start_script(const char *script, int argc, const char **argv)
        }
 
        free(command_line);
-       fprintf(stderr, "perf trace started with Python script %s\n\n",
-               script);
 
        return err;
 error:
@@ -400,8 +405,6 @@ out:
        Py_XDECREF(main_module);
        Py_Finalize();
 
-       fprintf(stderr, "\nperf trace Python script stopped\n");
-
        return err;
 }
 
index 0de7258e70a5bfc2373bc73787b0da5e65ed4d76..25bfca4f10f0ff98a2ef06d90f1362424547e8d3 100644 (file)
@@ -14,6 +14,16 @@ static int perf_session__open(struct perf_session *self, bool force)
 {
        struct stat input_stat;
 
+       if (!strcmp(self->filename, "-")) {
+               self->fd_pipe = true;
+               self->fd = STDIN_FILENO;
+
+               if (perf_header__read(self, self->fd) < 0)
+                       pr_err("incompatible file format");
+
+               return 0;
+       }
+
        self->fd = open(self->filename, O_RDONLY);
        if (self->fd < 0) {
                pr_err("failed to open file: %s", self->filename);
@@ -38,7 +48,7 @@ static int perf_session__open(struct perf_session *self, bool force)
                goto out_close;
        }
 
-       if (perf_header__read(&self->header, self->fd) < 0) {
+       if (perf_header__read(self, self->fd) < 0) {
                pr_err("incompatible file format");
                goto out_close;
        }
@@ -52,12 +62,21 @@ out_close:
        return -1;
 }
 
-static inline int perf_session__create_kernel_maps(struct perf_session *self)
+void perf_session__update_sample_type(struct perf_session *self)
+{
+       self->sample_type = perf_header__sample_type(&self->header);
+}
+
+int perf_session__create_kernel_maps(struct perf_session *self)
 {
-       return map_groups__create_kernel_maps(&self->kmaps, self->vmlinux_maps);
+       int ret = machine__create_kernel_maps(&self->host_machine);
+
+       if (ret >= 0)
+               ret = machines__create_guest_kernel_maps(&self->machines);
+       return ret;
 }
 
-struct perf_session *perf_session__new(const char *filename, int mode, bool force)
+struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe)
 {
        size_t len = filename ? strlen(filename) + 1 : 0;
        struct perf_session *self = zalloc(sizeof(*self) + len);
@@ -70,12 +89,15 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
 
        memcpy(self->filename, filename, len);
        self->threads = RB_ROOT;
+       self->hists_tree = RB_ROOT;
        self->last_match = NULL;
        self->mmap_window = 32;
        self->cwd = NULL;
        self->cwdlen = 0;
-       self->unknown_events = 0;
-       map_groups__init(&self->kmaps);
+       self->machines = RB_ROOT;
+       self->repipe = repipe;
+       INIT_LIST_HEAD(&self->ordered_samples.samples_head);
+       machine__init(&self->host_machine, "", HOST_KERNEL_ID);
 
        if (mode == O_RDONLY) {
                if (perf_session__open(self, force) < 0)
@@ -89,7 +111,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
                        goto out_delete;
        }
 
-       self->sample_type = perf_header__sample_type(&self->header);
+       perf_session__update_sample_type(self);
 out:
        return self;
 out_free:
@@ -116,22 +138,17 @@ static bool symbol__match_parent_regex(struct symbol *sym)
        return 0;
 }
 
-struct symbol **perf_session__resolve_callchain(struct perf_session *self,
-                                               struct thread *thread,
-                                               struct ip_callchain *chain,
-                                               struct symbol **parent)
+struct map_symbol *perf_session__resolve_callchain(struct perf_session *self,
+                                                  struct thread *thread,
+                                                  struct ip_callchain *chain,
+                                                  struct symbol **parent)
 {
        u8 cpumode = PERF_RECORD_MISC_USER;
-       struct symbol **syms = NULL;
        unsigned int i;
+       struct map_symbol *syms = calloc(chain->nr, sizeof(*syms));
 
-       if (symbol_conf.use_callchain) {
-               syms = calloc(chain->nr, sizeof(*syms));
-               if (!syms) {
-                       fprintf(stderr, "Can't allocate memory for symbols\n");
-                       exit(-1);
-               }
-       }
+       if (!syms)
+               return NULL;
 
        for (i = 0; i < chain->nr; i++) {
                u64 ip = chain->ips[i];
@@ -151,15 +168,17 @@ struct symbol **perf_session__resolve_callchain(struct perf_session *self,
                        continue;
                }
 
+               al.filtered = false;
                thread__find_addr_location(thread, self, cpumode,
-                                          MAP__FUNCTION, ip, &al, NULL);
+                               MAP__FUNCTION, thread->pid, ip, &al, NULL);
                if (al.sym != NULL) {
                        if (sort__has_parent && !*parent &&
                            symbol__match_parent_regex(al.sym))
                                *parent = al.sym;
                        if (!symbol_conf.use_callchain)
                                break;
-                       syms[i] = al.sym;
+                       syms[i].map = al.map;
+                       syms[i].sym = al.sym;
                }
        }
 
@@ -173,6 +192,18 @@ static int process_event_stub(event_t *event __used,
        return 0;
 }
 
+static int process_finished_round_stub(event_t *event __used,
+                                      struct perf_session *session __used,
+                                      struct perf_event_ops *ops __used)
+{
+       dump_printf(": unhandled!\n");
+       return 0;
+}
+
+static int process_finished_round(event_t *event,
+                                 struct perf_session *session,
+                                 struct perf_event_ops *ops);
+
 static void perf_event_ops__fill_defaults(struct perf_event_ops *handler)
 {
        if (handler->sample == NULL)
@@ -193,29 +224,20 @@ static void perf_event_ops__fill_defaults(struct perf_event_ops *handler)
                handler->throttle = process_event_stub;
        if (handler->unthrottle == NULL)
                handler->unthrottle = process_event_stub;
-}
-
-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]);
+       if (handler->attr == NULL)
+               handler->attr = process_event_stub;
+       if (handler->event_type == NULL)
+               handler->event_type = process_event_stub;
+       if (handler->tracing_data == NULL)
+               handler->tracing_data = process_event_stub;
+       if (handler->build_id == NULL)
+               handler->build_id = process_event_stub;
+       if (handler->finished_round == NULL) {
+               if (handler->ordered_samples)
+                       handler->finished_round = process_finished_round;
+               else
+                       handler->finished_round = process_finished_round_stub;
+       }
 }
 
 void mem_bswap_64(void *src, int byte_size)
@@ -269,6 +291,37 @@ static void event__read_swap(event_t *self)
        self->read.id           = bswap_64(self->read.id);
 }
 
+static void event__attr_swap(event_t *self)
+{
+       size_t size;
+
+       self->attr.attr.type            = bswap_32(self->attr.attr.type);
+       self->attr.attr.size            = bswap_32(self->attr.attr.size);
+       self->attr.attr.config          = bswap_64(self->attr.attr.config);
+       self->attr.attr.sample_period   = bswap_64(self->attr.attr.sample_period);
+       self->attr.attr.sample_type     = bswap_64(self->attr.attr.sample_type);
+       self->attr.attr.read_format     = bswap_64(self->attr.attr.read_format);
+       self->attr.attr.wakeup_events   = bswap_32(self->attr.attr.wakeup_events);
+       self->attr.attr.bp_type         = bswap_32(self->attr.attr.bp_type);
+       self->attr.attr.bp_addr         = bswap_64(self->attr.attr.bp_addr);
+       self->attr.attr.bp_len          = bswap_64(self->attr.attr.bp_len);
+
+       size = self->header.size;
+       size -= (void *)&self->attr.id - (void *)self;
+       mem_bswap_64(self->attr.id, size);
+}
+
+static void event__event_type_swap(event_t *self)
+{
+       self->event_type.event_type.event_id =
+               bswap_64(self->event_type.event_type.event_id);
+}
+
+static void event__tracing_data_swap(event_t *self)
+{
+       self->tracing_data.size = bswap_32(self->tracing_data.size);
+}
+
 typedef void (*event__swap_op)(event_t *self);
 
 static event__swap_op event__swap_ops[] = {
@@ -279,9 +332,212 @@ static event__swap_op event__swap_ops[] = {
        [PERF_RECORD_LOST]   = event__all64_swap,
        [PERF_RECORD_READ]   = event__read_swap,
        [PERF_RECORD_SAMPLE] = event__all64_swap,
-       [PERF_RECORD_MAX]    = NULL,
+       [PERF_RECORD_HEADER_ATTR]   = event__attr_swap,
+       [PERF_RECORD_HEADER_EVENT_TYPE]   = event__event_type_swap,
+       [PERF_RECORD_HEADER_TRACING_DATA]   = event__tracing_data_swap,
+       [PERF_RECORD_HEADER_BUILD_ID]   = NULL,
+       [PERF_RECORD_HEADER_MAX]    = NULL,
 };
 
+struct sample_queue {
+       u64                     timestamp;
+       struct sample_event     *event;
+       struct list_head        list;
+};
+
+static void flush_sample_queue(struct perf_session *s,
+                              struct perf_event_ops *ops)
+{
+       struct list_head *head = &s->ordered_samples.samples_head;
+       u64 limit = s->ordered_samples.next_flush;
+       struct sample_queue *tmp, *iter;
+
+       if (!ops->ordered_samples || !limit)
+               return;
+
+       list_for_each_entry_safe(iter, tmp, head, list) {
+               if (iter->timestamp > limit)
+                       return;
+
+               if (iter == s->ordered_samples.last_inserted)
+                       s->ordered_samples.last_inserted = NULL;
+
+               ops->sample((event_t *)iter->event, s);
+
+               s->ordered_samples.last_flush = iter->timestamp;
+               list_del(&iter->list);
+               free(iter->event);
+               free(iter);
+       }
+}
+
+/*
+ * When perf record finishes a pass on every buffers, it records this pseudo
+ * event.
+ * We record the max timestamp t found in the pass n.
+ * Assuming these timestamps are monotonic across cpus, we know that if
+ * a buffer still has events with timestamps below t, they will be all
+ * available and then read in the pass n + 1.
+ * Hence when we start to read the pass n + 2, we can safely flush every
+ * events with timestamps below t.
+ *
+ *    ============ PASS n =================
+ *       CPU 0         |   CPU 1
+ *                     |
+ *    cnt1 timestamps  |   cnt2 timestamps
+ *          1          |         2
+ *          2          |         3
+ *          -          |         4  <--- max recorded
+ *
+ *    ============ PASS n + 1 ==============
+ *       CPU 0         |   CPU 1
+ *                     |
+ *    cnt1 timestamps  |   cnt2 timestamps
+ *          3          |         5
+ *          4          |         6
+ *          5          |         7 <---- max recorded
+ *
+ *      Flush every events below timestamp 4
+ *
+ *    ============ PASS n + 2 ==============
+ *       CPU 0         |   CPU 1
+ *                     |
+ *    cnt1 timestamps  |   cnt2 timestamps
+ *          6          |         8
+ *          7          |         9
+ *          -          |         10
+ *
+ *      Flush every events below timestamp 7
+ *      etc...
+ */
+static int process_finished_round(event_t *event __used,
+                                 struct perf_session *session,
+                                 struct perf_event_ops *ops)
+{
+       flush_sample_queue(session, ops);
+       session->ordered_samples.next_flush = session->ordered_samples.max_timestamp;
+
+       return 0;
+}
+
+static void __queue_sample_end(struct sample_queue *new, struct list_head *head)
+{
+       struct sample_queue *iter;
+
+       list_for_each_entry_reverse(iter, head, list) {
+               if (iter->timestamp < new->timestamp) {
+                       list_add(&new->list, &iter->list);
+                       return;
+               }
+       }
+
+       list_add(&new->list, head);
+}
+
+static void __queue_sample_before(struct sample_queue *new,
+                                 struct sample_queue *iter,
+                                 struct list_head *head)
+{
+       list_for_each_entry_continue_reverse(iter, head, list) {
+               if (iter->timestamp < new->timestamp) {
+                       list_add(&new->list, &iter->list);
+                       return;
+               }
+       }
+
+       list_add(&new->list, head);
+}
+
+static void __queue_sample_after(struct sample_queue *new,
+                                struct sample_queue *iter,
+                                struct list_head *head)
+{
+       list_for_each_entry_continue(iter, head, list) {
+               if (iter->timestamp > new->timestamp) {
+                       list_add_tail(&new->list, &iter->list);
+                       return;
+               }
+       }
+       list_add_tail(&new->list, head);
+}
+
+/* The queue is ordered by time */
+static void __queue_sample_event(struct sample_queue *new,
+                                struct perf_session *s)
+{
+       struct sample_queue *last_inserted = s->ordered_samples.last_inserted;
+       struct list_head *head = &s->ordered_samples.samples_head;
+
+
+       if (!last_inserted) {
+               __queue_sample_end(new, head);
+               return;
+       }
+
+       /*
+        * Most of the time the current event has a timestamp
+        * very close to the last event inserted, unless we just switched
+        * to another event buffer. Having a sorting based on a list and
+        * on the last inserted event that is close to the current one is
+        * probably more efficient than an rbtree based sorting.
+        */
+       if (last_inserted->timestamp >= new->timestamp)
+               __queue_sample_before(new, last_inserted, head);
+       else
+               __queue_sample_after(new, last_inserted, head);
+}
+
+static int queue_sample_event(event_t *event, struct sample_data *data,
+                             struct perf_session *s)
+{
+       u64 timestamp = data->time;
+       struct sample_queue *new;
+
+
+       if (timestamp < s->ordered_samples.last_flush) {
+               printf("Warning: Timestamp below last timeslice flush\n");
+               return -EINVAL;
+       }
+
+       new = malloc(sizeof(*new));
+       if (!new)
+               return -ENOMEM;
+
+       new->timestamp = timestamp;
+
+       new->event = malloc(event->header.size);
+       if (!new->event) {
+               free(new);
+               return -ENOMEM;
+       }
+
+       memcpy(new->event, event, event->header.size);
+
+       __queue_sample_event(new, s);
+       s->ordered_samples.last_inserted = new;
+
+       if (new->timestamp > s->ordered_samples.max_timestamp)
+               s->ordered_samples.max_timestamp = new->timestamp;
+
+       return 0;
+}
+
+static int perf_session__process_sample(event_t *event, struct perf_session *s,
+                                       struct perf_event_ops *ops)
+{
+       struct sample_data data;
+
+       if (!ops->ordered_samples)
+               return ops->sample(event, s);
+
+       bzero(&data, sizeof(struct sample_data));
+       event__parse_sample(event, s->sample_type, &data);
+
+       queue_sample_event(event, &data, s);
+
+       return 0;
+}
+
 static int perf_session__process_event(struct perf_session *self,
                                       event_t *event,
                                       struct perf_event_ops *ops,
@@ -289,12 +545,11 @@ static int perf_session__process_event(struct perf_session *self,
 {
        trace_event(event);
 
-       if (event->header.type < PERF_RECORD_MAX) {
+       if (event->header.type < PERF_RECORD_HEADER_MAX) {
                dump_printf("%#Lx [%#x]: PERF_RECORD_%s",
                            offset + head, event->header.size,
                            event__name[event->header.type]);
-               ++event__total[0];
-               ++event__total[event->header.type];
+               hists__inc_nr_events(&self->hists, event->header.type);
        }
 
        if (self->header.needs_swap && event__swap_ops[event->header.type])
@@ -302,7 +557,7 @@ static int perf_session__process_event(struct perf_session *self,
 
        switch (event->header.type) {
        case PERF_RECORD_SAMPLE:
-               return ops->sample(event, self);
+               return perf_session__process_sample(event, self, ops);
        case PERF_RECORD_MMAP:
                return ops->mmap(event, self);
        case PERF_RECORD_COMM:
@@ -319,8 +574,20 @@ static int perf_session__process_event(struct perf_session *self,
                return ops->throttle(event, self);
        case PERF_RECORD_UNTHROTTLE:
                return ops->unthrottle(event, self);
+       case PERF_RECORD_HEADER_ATTR:
+               return ops->attr(event, self);
+       case PERF_RECORD_HEADER_EVENT_TYPE:
+               return ops->event_type(event, self);
+       case PERF_RECORD_HEADER_TRACING_DATA:
+               /* setup for reading amidst mmap */
+               lseek(self->fd, offset + head, SEEK_SET);
+               return ops->tracing_data(event, self);
+       case PERF_RECORD_HEADER_BUILD_ID:
+               return ops->build_id(event, self);
+       case PERF_RECORD_FINISHED_ROUND:
+               return ops->finished_round(event, self, ops);
        default:
-               self->unknown_events++;
+               ++self->hists.stats.nr_unknown_events;
                return -1;
        }
 }
@@ -332,56 +599,114 @@ void perf_event_header__bswap(struct perf_event_header *self)
        self->size = bswap_16(self->size);
 }
 
-int perf_header__read_build_ids(struct perf_header *self,
-                               int input, u64 offset, u64 size)
+static struct thread *perf_session__register_idle_thread(struct perf_session *self)
 {
-       struct build_id_event bev;
-       char filename[PATH_MAX];
-       u64 limit = offset + size;
-       int err = -1;
-
-       while (offset < limit) {
-               struct dso *dso;
-               ssize_t len;
-               struct list_head *head = &dsos__user;
+       struct thread *thread = perf_session__findnew(self, 0);
 
-               if (read(input, &bev, sizeof(bev)) != sizeof(bev))
-                       goto out;
+       if (thread == NULL || thread__set_comm(thread, "swapper")) {
+               pr_err("problem inserting idle task.\n");
+               thread = NULL;
+       }
 
-               if (self->needs_swap)
-                       perf_event_header__bswap(&bev.header);
+       return thread;
+}
 
-               len = bev.header.size - sizeof(bev);
-               if (read(input, filename, len) != len)
-                       goto out;
+int do_read(int fd, void *buf, size_t size)
+{
+       void *buf_start = buf;
 
-               if (bev.header.misc & PERF_RECORD_MISC_KERNEL)
-                       head = &dsos__kernel;
+       while (size) {
+               int ret = read(fd, buf, size);
 
-               dso = __dsos__findnew(head, filename);
-               if (dso != NULL) {
-                       dso__set_build_id(dso, &bev.build_id);
-                       if (head == &dsos__kernel && filename[0] == '[')
-                               dso->kernel = 1;
-               }
+               if (ret <= 0)
+                       return ret;
 
-               offset += bev.header.size;
+               size -= ret;
+               buf += ret;
        }
-       err = 0;
-out:
-       return err;
+
+       return buf - buf_start;
 }
 
-static struct thread *perf_session__register_idle_thread(struct perf_session *self)
+#define session_done() (*(volatile int *)(&session_done))
+volatile int session_done;
+
+static int __perf_session__process_pipe_events(struct perf_session *self,
+                                              struct perf_event_ops *ops)
 {
-       struct thread *thread = perf_session__findnew(self, 0);
+       event_t event;
+       uint32_t size;
+       int skip = 0;
+       u64 head;
+       int err;
+       void *p;
 
-       if (thread == NULL || thread__set_comm(thread, "swapper")) {
-               pr_err("problem inserting idle task.\n");
-               thread = NULL;
+       perf_event_ops__fill_defaults(ops);
+
+       head = 0;
+more:
+       err = do_read(self->fd, &event, sizeof(struct perf_event_header));
+       if (err <= 0) {
+               if (err == 0)
+                       goto done;
+
+               pr_err("failed to read event header\n");
+               goto out_err;
        }
 
-       return thread;
+       if (self->header.needs_swap)
+               perf_event_header__bswap(&event.header);
+
+       size = event.header.size;
+       if (size == 0)
+               size = 8;
+
+       p = &event;
+       p += sizeof(struct perf_event_header);
+
+       if (size - sizeof(struct perf_event_header)) {
+               err = do_read(self->fd, p,
+                             size - sizeof(struct perf_event_header));
+               if (err <= 0) {
+                       if (err == 0) {
+                               pr_err("unexpected end of event stream\n");
+                               goto done;
+                       }
+
+                       pr_err("failed to read event data\n");
+                       goto out_err;
+               }
+       }
+
+       if (size == 0 ||
+           (skip = perf_session__process_event(self, &event, ops,
+                                               0, head)) < 0) {
+               dump_printf("%#Lx [%#x]: skipping unknown header type: %d\n",
+                           head, 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;
+
+       dump_printf("\n%#Lx [%#x]: event: %d\n",
+                   head, event.header.size, event.header.type);
+
+       if (skip > 0)
+               head += skip;
+
+       if (!session_done())
+               goto more;
+done:
+       err = 0;
+out_err:
+       return err;
 }
 
 int __perf_session__process_events(struct perf_session *self,
@@ -395,6 +720,10 @@ int __perf_session__process_events(struct perf_session *self,
        event_t *event;
        uint32_t size;
        char *buf;
+       struct ui_progress *progress = ui_progress__new("Processing events...",
+                                                       self->size);
+       if (progress == NULL)
+               return -1;
 
        perf_event_ops__fill_defaults(ops);
 
@@ -423,6 +752,7 @@ remap:
 
 more:
        event = (event_t *)(buf + head);
+       ui_progress__update(progress, offset);
 
        if (self->header.needs_swap)
                perf_event_header__bswap(&event->header);
@@ -472,7 +802,11 @@ more:
                goto more;
 done:
        err = 0;
+       /* do the final flush for ordered samples */
+       self->ordered_samples.next_flush = ULLONG_MAX;
+       flush_sample_queue(self, ops);
 out_err:
+       ui_progress__delete(progress);
        return err;
 }
 
@@ -501,9 +835,13 @@ out_getcwd_err:
                self->cwdlen = strlen(self->cwd);
        }
 
-       err = __perf_session__process_events(self, self->header.data_offset,
-                                            self->header.data_size,
-                                            self->size, ops);
+       if (!self->fd_pipe)
+               err = __perf_session__process_events(self,
+                                                    self->header.data_offset,
+                                                    self->header.data_size,
+                                                    self->size, ops);
+       else
+               err = __perf_session__process_pipe_events(self, ops);
 out_err:
        return err;
 }
@@ -518,56 +856,41 @@ bool perf_session__has_traces(struct perf_session *self, const char *msg)
        return true;
 }
 
-int perf_session__set_kallsyms_ref_reloc_sym(struct perf_session *self,
+int perf_session__set_kallsyms_ref_reloc_sym(struct map **maps,
                                             const char *symbol_name,
                                             u64 addr)
 {
        char *bracket;
        enum map_type i;
+       struct ref_reloc_sym *ref;
 
-       self->ref_reloc_sym.name = strdup(symbol_name);
-       if (self->ref_reloc_sym.name == NULL)
+       ref = zalloc(sizeof(struct ref_reloc_sym));
+       if (ref == NULL)
                return -ENOMEM;
 
-       bracket = strchr(self->ref_reloc_sym.name, ']');
+       ref->name = strdup(symbol_name);
+       if (ref->name == NULL) {
+               free(ref);
+               return -ENOMEM;
+       }
+
+       bracket = strchr(ref->name, ']');
        if (bracket)
                *bracket = '\0';
 
-       self->ref_reloc_sym.addr = addr;
+       ref->addr = addr;
 
        for (i = 0; i < MAP__NR_TYPES; ++i) {
-               struct kmap *kmap = map__kmap(self->vmlinux_maps[i]);
-               kmap->ref_reloc_sym = &self->ref_reloc_sym;
+               struct kmap *kmap = map__kmap(maps[i]);
+               kmap->ref_reloc_sym = ref;
        }
 
        return 0;
 }
 
-static u64 map__reloc_map_ip(struct map *map, u64 ip)
-{
-       return ip + (s64)map->pgoff;
-}
-
-static u64 map__reloc_unmap_ip(struct map *map, u64 ip)
-{
-       return ip - (s64)map->pgoff;
-}
-
-void map__reloc_vmlinux(struct map *self)
+size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp)
 {
-       struct kmap *kmap = map__kmap(self);
-       s64 reloc;
-
-       if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->unrelocated_addr)
-               return;
-
-       reloc = (kmap->ref_reloc_sym->unrelocated_addr -
-                kmap->ref_reloc_sym->addr);
-
-       if (!reloc)
-               return;
-
-       self->map_ip   = map__reloc_map_ip;
-       self->unmap_ip = map__reloc_unmap_ip;
-       self->pgoff    = reloc;
+       return __dsos__fprintf(&self->host_machine.kernel_dsos, fp) +
+              __dsos__fprintf(&self->host_machine.user_dsos, fp) +
+              machines__fprintf_dsos(&self->machines, fp);
 }
index 31950fcd8a4d4cfcb5db948ad41a7f7371c2b584..e7fce486ebe23a299d0a3b5a5240de0795a99ebc 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __PERF_SESSION_H
 #define __PERF_SESSION_H
 
+#include "hist.h"
 #include "event.h"
 #include "header.h"
 #include "symbol.h"
@@ -8,44 +9,69 @@
 #include <linux/rbtree.h>
 #include "../../../include/linux/perf_event.h"
 
+struct sample_queue;
 struct ip_callchain;
 struct thread;
 
+struct ordered_samples {
+       u64                     last_flush;
+       u64                     next_flush;
+       u64                     max_timestamp;
+       struct list_head        samples_head;
+       struct sample_queue     *last_inserted;
+};
+
 struct perf_session {
        struct perf_header      header;
        unsigned long           size;
        unsigned long           mmap_window;
-       struct map_groups       kmaps;
        struct rb_root          threads;
        struct thread           *last_match;
-       struct map              *vmlinux_maps[MAP__NR_TYPES];
-       struct events_stats     events_stats;
-       unsigned long           event_total[PERF_RECORD_MAX];
-       unsigned long           unknown_events;
-       struct rb_root          hists;
+       struct machine          host_machine;
+       struct rb_root          machines;
+       struct rb_root          hists_tree;
+       /*
+        * FIXME: should point to the first entry in hists_tree and
+        *        be a hists instance. Right now its only 'report'
+        *        that is using ->hists_tree while all the rest use
+        *        ->hists.
+        */
+       struct hists            hists;
        u64                     sample_type;
-       struct ref_reloc_sym    ref_reloc_sym;
        int                     fd;
+       bool                    fd_pipe;
+       bool                    repipe;
        int                     cwdlen;
        char                    *cwd;
+       struct ordered_samples  ordered_samples;
        char filename[0];
 };
 
+struct perf_event_ops;
+
 typedef int (*event_op)(event_t *self, struct perf_session *session);
+typedef int (*event_op2)(event_t *self, struct perf_session *session,
+                        struct perf_event_ops *ops);
 
 struct perf_event_ops {
-       event_op sample,
-                mmap,
-                comm,
-                fork,
-                exit,
-                lost,
-                read,
-                throttle,
-                unthrottle;
+       event_op        sample,
+                       mmap,
+                       comm,
+                       fork,
+                       exit,
+                       lost,
+                       read,
+                       throttle,
+                       unthrottle,
+                       attr,
+                       event_type,
+                       tracing_data,
+                       build_id;
+       event_op2       finished_round;
+       bool            ordered_samples;
 };
 
-struct perf_session *perf_session__new(const char *filename, int mode, bool force);
+struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe);
 void perf_session__delete(struct perf_session *self);
 
 void perf_event_header__bswap(struct perf_event_header *self);
@@ -56,33 +82,66 @@ int __perf_session__process_events(struct perf_session *self,
 int perf_session__process_events(struct perf_session *self,
                                 struct perf_event_ops *event_ops);
 
-struct symbol **perf_session__resolve_callchain(struct perf_session *self,
-                                               struct thread *thread,
-                                               struct ip_callchain *chain,
-                                               struct symbol **parent);
+struct map_symbol *perf_session__resolve_callchain(struct perf_session *self,
+                                                  struct thread *thread,
+                                                  struct ip_callchain *chain,
+                                                  struct symbol **parent);
 
 bool perf_session__has_traces(struct perf_session *self, const char *msg);
 
-int perf_header__read_build_ids(struct perf_header *self, int input,
-                               u64 offset, u64 file_size);
-
-int perf_session__set_kallsyms_ref_reloc_sym(struct perf_session *self,
+int perf_session__set_kallsyms_ref_reloc_sym(struct map **maps,
                                             const char *symbol_name,
                                             u64 addr);
 
 void mem_bswap_64(void *src, int byte_size);
 
-static inline int __perf_session__create_kernel_maps(struct perf_session *self,
-                                               struct dso *kernel)
+int perf_session__create_kernel_maps(struct perf_session *self);
+
+int do_read(int fd, void *buf, size_t size);
+void perf_session__update_sample_type(struct perf_session *self);
+
+static inline
+struct machine *perf_session__find_host_machine(struct perf_session *self)
+{
+       return &self->host_machine;
+}
+
+static inline
+struct machine *perf_session__find_machine(struct perf_session *self, pid_t pid)
+{
+       if (pid == HOST_KERNEL_ID)
+               return &self->host_machine;
+       return machines__find(&self->machines, pid);
+}
+
+static inline
+struct machine *perf_session__findnew_machine(struct perf_session *self, pid_t pid)
+{
+       if (pid == HOST_KERNEL_ID)
+               return &self->host_machine;
+       return machines__findnew(&self->machines, pid);
+}
+
+static inline
+void perf_session__process_machines(struct perf_session *self,
+                                   machine__process_t process)
+{
+       process(&self->host_machine, self);
+       return machines__process(&self->machines, process, self);
+}
+
+size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp);
+
+static inline
+size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp,
+                                         bool with_hits)
 {
-       return __map_groups__create_kernel_maps(&self->kmaps,
-                                               self->vmlinux_maps, kernel);
+       return machines__fprintf_dsos_buildid(&self->machines, fp, with_hits);
 }
 
-static inline struct map *
-       perf_session__new_module_map(struct perf_session *self,
-                                    u64 start, const char *filename)
+static inline
+size_t perf_session__fprintf_nr_events(struct perf_session *self, FILE *fp)
 {
-       return map_groups__new_module(&self->kmaps, start, filename);
+       return hists__fprintf_nr_events(&self->hists, fp);
 }
 #endif /* __PERF_SESSION_H */
index cb0f327de9e86f73f08c63cce689f63f5fb137fc..2316cb5a41164d4d99fbb289118def977b74cf5e 100644 (file)
@@ -1,10 +1,10 @@
 #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;
+const char     default_parent_pattern[] = "^sys_|^do_page_fault";
+const char     *parent_pattern = default_parent_pattern;
+const char     default_sort_order[] = "comm,dso,symbol";
+const char     *sort_order = default_sort_order;
 int            sort__need_collapse = 0;
 int            sort__has_parent = 0;
 
@@ -18,39 +18,50 @@ char * field_sep;
 
 LIST_HEAD(hist_entry__sort_list);
 
+static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
+                                      size_t size, unsigned int width);
+static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
+                                    size_t size, unsigned int width);
+static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf,
+                                   size_t size, unsigned int width);
+static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
+                                   size_t size, unsigned int width);
+static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
+                                      size_t size, unsigned int width);
+
 struct sort_entry sort_thread = {
-       .header = "Command:  Pid",
-       .cmp    = sort__thread_cmp,
-       .print  = sort__thread_print,
-       .width  = &threads__col_width,
+       .se_header      = "Command:  Pid",
+       .se_cmp         = sort__thread_cmp,
+       .se_snprintf    = hist_entry__thread_snprintf,
+       .se_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,
+       .se_header      = "Command",
+       .se_cmp         = sort__comm_cmp,
+       .se_collapse    = sort__comm_collapse,
+       .se_snprintf    = hist_entry__comm_snprintf,
+       .se_width       = &comms__col_width,
 };
 
 struct sort_entry sort_dso = {
-       .header = "Shared Object",
-       .cmp    = sort__dso_cmp,
-       .print  = sort__dso_print,
-       .width  = &dsos__col_width,
+       .se_header      = "Shared Object",
+       .se_cmp         = sort__dso_cmp,
+       .se_snprintf    = hist_entry__dso_snprintf,
+       .se_width       = &dsos__col_width,
 };
 
 struct sort_entry sort_sym = {
-       .header = "Symbol",
-       .cmp    = sort__sym_cmp,
-       .print  = sort__sym_print,
+       .se_header      = "Symbol",
+       .se_cmp         = sort__sym_cmp,
+       .se_snprintf    = hist_entry__sym_snprintf,
 };
 
 struct sort_entry sort_parent = {
-       .header = "Parent symbol",
-       .cmp    = sort__parent_cmp,
-       .print  = sort__parent_print,
-       .width  = &parent_symbol__col_width,
+       .se_header      = "Parent symbol",
+       .se_cmp         = sort__parent_cmp,
+       .se_snprintf    = hist_entry__parent_snprintf,
+       .se_width       = &parent_symbol__col_width,
 };
 
 struct sort_dimension {
@@ -85,45 +96,38 @@ 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, ...)
+static int repsep_snprintf(char *bf, size_t size, 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 = '.';
-                       }
+       n = vsnprintf(bf, size, fmt, ap);
+       if (field_sep && 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)
+static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
+                                      size_t size, unsigned int width)
 {
-       return repsep_fprintf(fp, "%*s:%5d", width - 6,
+       return repsep_snprintf(bf, size, "%*s:%5d", width,
                              self->thread->comm ?: "", self->thread->pid);
 }
 
-size_t
-sort__comm_print(FILE *fp, struct hist_entry *self, unsigned int width)
+static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
+                                    size_t size, unsigned int width)
 {
-       return repsep_fprintf(fp, "%*s", width, self->thread->comm);
+       return repsep_snprintf(bf, size, "%*s", width, self->thread->comm);
 }
 
 /* --sort dso */
@@ -131,8 +135,8 @@ sort__comm_print(FILE *fp, struct hist_entry *self, unsigned int width)
 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;
+       struct dso *dso_l = left->ms.map ? left->ms.map->dso : NULL;
+       struct dso *dso_r = right->ms.map ? right->ms.map->dso : NULL;
        const char *dso_name_l, *dso_name_r;
 
        if (!dso_l || !dso_r)
@@ -149,16 +153,16 @@ sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
        return strcmp(dso_name_l, dso_name_r);
 }
 
-size_t
-sort__dso_print(FILE *fp, struct hist_entry *self, unsigned int width)
+static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf,
+                                   size_t size, 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);
+       if (self->ms.map && self->ms.map->dso) {
+               const char *dso_name = !verbose ? self->ms.map->dso->short_name :
+                                                 self->ms.map->dso->long_name;
+               return repsep_snprintf(bf, size, "%-*s", width, dso_name);
        }
 
-       return repsep_fprintf(fp, "%*llx", width, (u64)self->ip);
+       return repsep_snprintf(bf, size, "%*Lx", width, self->ip);
 }
 
 /* --sort symbol */
@@ -168,31 +172,31 @@ sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
 {
        u64 ip_l, ip_r;
 
-       if (left->sym == right->sym)
+       if (left->ms.sym == right->ms.sym)
                return 0;
 
-       ip_l = left->sym ? left->sym->start : left->ip;
-       ip_r = right->sym ? right->sym->start : right->ip;
+       ip_l = left->ms.sym ? left->ms.sym->start : left->ip;
+       ip_r = right->ms.sym ? right->ms.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)
+static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
+                                   size_t size, 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);
+               char o = self->ms.map ? dso__symtab_origin(self->ms.map->dso) : '!';
+               ret += repsep_snprintf(bf, size, "%#018llx %c ", self->ip, o);
        }
 
-       ret += repsep_fprintf(fp, "[%c] ", self->level);
-       if (self->sym)
-               ret += repsep_fprintf(fp, "%s", self->sym->name);
+       ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", self->level);
+       if (self->ms.sym)
+               ret += repsep_snprintf(bf + ret, size - ret, "%s",
+                                      self->ms.sym->name);
        else
-               ret += repsep_fprintf(fp, "%#016llx", (u64)self->ip);
+               ret += repsep_snprintf(bf + ret, size - ret, "%#016llx", self->ip);
 
        return ret;
 }
@@ -231,10 +235,10 @@ sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
        return strcmp(sym_l->name, sym_r->name);
 }
 
-size_t
-sort__parent_print(FILE *fp, struct hist_entry *self, unsigned int width)
+static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
+                                      size_t size, unsigned int width)
 {
-       return repsep_fprintf(fp, "%-*s", width,
+       return repsep_snprintf(bf, size, "%-*s", width,
                              self->parent ? self->parent->name : "[other]");
 }
 
@@ -251,7 +255,7 @@ int sort_dimension__add(const char *tok)
                if (strncasecmp(tok, sd->name, strlen(tok)))
                        continue;
 
-               if (sd->entry->collapse)
+               if (sd->entry->se_collapse)
                        sort__need_collapse = 1;
 
                if (sd->entry == &sort_parent) {
@@ -260,9 +264,8 @@ int sort_dimension__add(const char *tok)
                                char err[BUFSIZ];
 
                                regerror(ret, &parent_regex, err, sizeof(err));
-                               fprintf(stderr, "Invalid regex: %s\n%s",
-                                       parent_pattern, err);
-                               exit(-1);
+                               pr_err("Invalid regex: %s\n%s", parent_pattern, err);
+                               return -EINVAL;
                        }
                        sort__has_parent = 1;
                }
index 753f9ea99fb0a72ebdec32aedbe5dc55df8dedc1..0d61c4082f43849ddfe4ac1f6cb1cf9841009dd8 100644 (file)
 #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 const char *sort_order;
+extern const char default_parent_pattern[];
+extern const char *parent_pattern;
+extern const char default_sort_order[];
 extern int sort__need_collapse;
 extern int sort__has_parent;
 extern char *field_sep;
@@ -43,19 +43,24 @@ extern enum sort_type sort__first_dimension;
 
 struct hist_entry {
        struct rb_node          rb_node;
-       u64                     count;
+       u64                     period;
+       u64                     period_sys;
+       u64                     period_us;
+       u64                     period_guest_sys;
+       u64                     period_guest_us;
+       struct map_symbol       ms;
        struct thread           *thread;
-       struct map              *map;
-       struct symbol           *sym;
        u64                     ip;
+       u32                     nr_events;
        char                    level;
-       struct symbol     *parent;
-       struct callchain_node   callchain;
+       u8                      filtered;
+       struct symbol           *parent;
        union {
                unsigned long     position;
                struct hist_entry *pair;
                struct rb_root    sorted_chain;
        };
+       struct callchain_node   callchain[0];
 };
 
 enum sort_type {
@@ -73,12 +78,13 @@ enum sort_type {
 struct sort_entry {
        struct list_head list;
 
-       const char *header;
+       const char *se_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;
+       int64_t (*se_cmp)(struct hist_entry *, struct hist_entry *);
+       int64_t (*se_collapse)(struct hist_entry *, struct hist_entry *);
+       int     (*se_snprintf)(struct hist_entry *self, char *bf, size_t size,
+                              unsigned int width);
+       unsigned int *se_width;
        bool    elide;
 };
 
@@ -87,7 +93,6 @@ extern struct list_head hist_entry__sort_list;
 
 void setup_sorting(const char * const usagestr[], const struct option *opts);
 
-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);
index a175949ed21643e1ebbb595f0212227a3c8c4f7d..0409fc7c0058809f01da646c4d5ee98c21f69b1d 100644 (file)
@@ -1,48 +1,5 @@
-#include "string.h"
 #include "util.h"
-
-static int hex(char ch)
-{
-       if ((ch >= '0') && (ch <= '9'))
-               return ch - '0';
-       if ((ch >= 'a') && (ch <= 'f'))
-               return ch - 'a' + 10;
-       if ((ch >= 'A') && (ch <= 'F'))
-               return ch - 'A' + 10;
-       return -1;
-}
-
-/*
- * While we find nice hex chars, build a long_val.
- * Return number of chars processed.
- */
-int hex2u64(const char *ptr, u64 *long_val)
-{
-       const char *p = ptr;
-       *long_val = 0;
-
-       while (*p) {
-               const int hex_val = hex(*p);
-
-               if (hex_val < 0)
-                       break;
-
-               *long_val = (*long_val << 4) | hex_val;
-               p++;
-       }
-
-       return p - ptr;
-}
-
-char *strxfrchar(char *s, char from, char to)
-{
-       char *p = s;
-
-       while ((p = strchr(p, from)) != NULL)
-               *p++ = to;
-
-       return s;
-}
+#include "string.h"
 
 #define K 1024LL
 /*
diff --git a/tools/perf/util/string.h b/tools/perf/util/string.h
deleted file mode 100644 (file)
index 542e44d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef __PERF_STRING_H_
-#define __PERF_STRING_H_
-
-#include <stdbool.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);
-bool strglobmatch(const char *str, const char *pat);
-bool strlazymatch(const char *str, const char *pat);
-
-#define _STR(x) #x
-#define STR(x) _STR(x)
-
-#endif /* __PERF_STRING_H */
index 323c0aea0a91172cced9261cdfd966cd2c0aa57d..a06131f6259a1dd5b65fee74d73a0de33eaa0d03 100644 (file)
@@ -1,13 +1,19 @@
-#include "util.h"
-#include "../perf.h"
-#include "sort.h"
-#include "string.h"
+#define _GNU_SOURCE
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <libgen.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <unistd.h>
 #include "symbol.h"
-#include "thread.h"
+#include "strlist.h"
 
-#include "debug.h"
-
-#include <asm/bug.h>
 #include <libelf.h>
 #include <gelf.h>
 #include <elf.h>
 #define NT_GNU_BUILD_ID 3
 #endif
 
-enum dso_origin {
-       DSO__ORIG_KERNEL = 0,
-       DSO__ORIG_JAVA_JIT,
-       DSO__ORIG_BUILD_ID_CACHE,
-       DSO__ORIG_FEDORA,
-       DSO__ORIG_UBUNTU,
-       DSO__ORIG_BUILDID,
-       DSO__ORIG_DSO,
-       DSO__ORIG_KMODULE,
-       DSO__ORIG_NOT_FOUND,
-};
-
 static void dsos__add(struct list_head *head, struct dso *dso);
 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
 static int dso__load_kernel_sym(struct dso *self, struct map *map,
                                symbol_filter_t filter);
+static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
+                       symbol_filter_t filter);
 static int vmlinux_path__nr_entries;
 static char **vmlinux_path;
 
@@ -126,16 +122,17 @@ static void map_groups__fixup_end(struct map_groups *self)
 static struct symbol *symbol__new(u64 start, u64 len, const char *name)
 {
        size_t namelen = strlen(name) + 1;
-       struct symbol *self = zalloc(symbol_conf.priv_size +
-                                    sizeof(*self) + namelen);
+       struct symbol *self = calloc(1, (symbol_conf.priv_size +
+                                        sizeof(*self) + namelen));
        if (self == NULL)
                return NULL;
 
        if (symbol_conf.priv_size)
                self = ((void *)self) + symbol_conf.priv_size;
 
-       self->start = start;
-       self->end   = len ? start + len - 1 : start;
+       self->start   = start;
+       self->end     = len ? start + len - 1 : start;
+       self->namelen = namelen - 1;
 
        pr_debug4("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end);
 
@@ -163,20 +160,28 @@ void dso__set_long_name(struct dso *self, char *name)
        self->long_name_len = strlen(name);
 }
 
+static void dso__set_short_name(struct dso *self, const char *name)
+{
+       if (name == NULL)
+               return;
+       self->short_name = name;
+       self->short_name_len = strlen(name);
+}
+
 static void dso__set_basename(struct dso *self)
 {
-       self->short_name = basename(self->long_name);
+       dso__set_short_name(self, basename(self->long_name));
 }
 
 struct dso *dso__new(const char *name)
 {
-       struct dso *self = zalloc(sizeof(*self) + strlen(name) + 1);
+       struct dso *self = calloc(1, sizeof(*self) + strlen(name) + 1);
 
        if (self != NULL) {
                int i;
                strcpy(self->name, name);
                dso__set_long_name(self, self->name);
-               self->short_name = self->name;
+               dso__set_short_name(self, self->name);
                for (i = 0; i < MAP__NR_TYPES; ++i)
                        self->symbols[i] = self->symbol_names[i] = RB_ROOT;
                self->slen_calculated = 0;
@@ -184,6 +189,8 @@ struct dso *dso__new(const char *name)
                self->loaded = 0;
                self->sorted_by_name = 0;
                self->has_build_id = 0;
+               self->kernel = DSO_TYPE_USER;
+               INIT_LIST_HEAD(&self->node);
        }
 
        return self;
@@ -400,12 +407,9 @@ int kallsyms__parse(const char *filename, void *arg,
                char *symbol_name;
 
                line_len = getline(&line, &n, file);
-               if (line_len < 0)
+               if (line_len < 0 || !line)
                        break;
 
-               if (!line)
-                       goto out_failure;
-
                line[--line_len] = '\0'; /* \n */
 
                len = hex2u64(line, &start);
@@ -457,6 +461,7 @@ static int map__process_kallsym_symbol(void *arg, const char *name,
         * map__split_kallsyms, when we have split the maps per module
         */
        symbols__insert(root, sym);
+
        return 0;
 }
 
@@ -481,6 +486,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
                               symbol_filter_t filter)
 {
        struct map_groups *kmaps = map__kmap(map)->kmaps;
+       struct machine *machine = kmaps->machine;
        struct map *curr_map = map;
        struct symbol *pos;
        int count = 0;
@@ -502,15 +508,33 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
                        *module++ = '\0';
 
                        if (strcmp(curr_map->dso->short_name, module)) {
-                               curr_map = map_groups__find_by_name(kmaps, map->type, module);
+                               if (curr_map != map &&
+                                   self->kernel == DSO_TYPE_GUEST_KERNEL &&
+                                   machine__is_default_guest(machine)) {
+                                       /*
+                                        * We assume all symbols of a module are
+                                        * continuous in * kallsyms, so curr_map
+                                        * points to a module and all its
+                                        * symbols are in its kmap. Mark it as
+                                        * loaded.
+                                        */
+                                       dso__set_loaded(curr_map->dso,
+                                                       curr_map->type);
+                               }
+
+                               curr_map = map_groups__find_by_name(kmaps,
+                                                       map->type, module);
                                if (curr_map == NULL) {
-                                       pr_debug("/proc/{kallsyms,modules} "
+                                       pr_debug("%s/proc/{kallsyms,modules} "
                                                 "inconsistency while looking "
-                                                "for \"%s\" module!\n", module);
-                                       return -1;
+                                                "for \"%s\" module!\n",
+                                                machine->root_dir, module);
+                                       curr_map = map;
+                                       goto discard_symbol;
                                }
 
-                               if (curr_map->dso->loaded)
+                               if (curr_map->dso->loaded &&
+                                   !machine__is_default_guest(machine))
                                        goto discard_symbol;
                        }
                        /*
@@ -523,13 +547,21 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
                        char dso_name[PATH_MAX];
                        struct dso *dso;
 
-                       snprintf(dso_name, sizeof(dso_name), "[kernel].%d",
-                                kernel_range++);
+                       if (self->kernel == DSO_TYPE_GUEST_KERNEL)
+                               snprintf(dso_name, sizeof(dso_name),
+                                       "[guest.kernel].%d",
+                                       kernel_range++);
+                       else
+                               snprintf(dso_name, sizeof(dso_name),
+                                       "[kernel].%d",
+                                       kernel_range++);
 
                        dso = dso__new(dso_name);
                        if (dso == NULL)
                                return -1;
 
+                       dso->kernel = self->kernel;
+
                        curr_map = map__new2(pos->start, dso, map->type);
                        if (curr_map == NULL) {
                                dso__delete(dso);
@@ -553,6 +585,12 @@ discard_symbol:            rb_erase(&pos->rb_node, root);
                }
        }
 
+       if (curr_map != map &&
+           self->kernel == DSO_TYPE_GUEST_KERNEL &&
+           machine__is_default_guest(kmaps->machine)) {
+               dso__set_loaded(curr_map->dso, curr_map->type);
+       }
+
        return count;
 }
 
@@ -563,7 +601,10 @@ int dso__load_kallsyms(struct dso *self, const char *filename,
                return -1;
 
        symbols__fixup_end(&self->symbols[map->type]);
-       self->origin = DSO__ORIG_KERNEL;
+       if (self->kernel == DSO_TYPE_GUEST_KERNEL)
+               self->origin = DSO__ORIG_GUEST_KERNEL;
+       else
+               self->origin = DSO__ORIG_KERNEL;
 
        return dso__split_kallsyms(self, map, filter);
 }
@@ -862,8 +903,8 @@ out_close:
        if (err == 0)
                return nr;
 out:
-       pr_warning("%s: problems reading %s PLT info.\n",
-                  __func__, self->long_name);
+       pr_debug("%s: problems reading %s PLT info.\n",
+                __func__, self->long_name);
        return 0;
 }
 
@@ -897,7 +938,6 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
        struct kmap *kmap = self->kernel ? map__kmap(map) : NULL;
        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;
@@ -951,7 +991,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
        nr_syms = shdr.sh_size / shdr.sh_entsize;
 
        memset(&sym, 0, sizeof(sym));
-       if (!self->kernel) {
+       if (self->kernel == DSO_TYPE_USER) {
                self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
                                elf_section_by_name(elf, &ehdr, &shdr,
                                                     ".gnu.prelink_undo",
@@ -983,11 +1023,12 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
 
                section_name = elf_sec__name(&shdr, secstrs);
 
-               if (self->kernel || kmodule) {
+               if (self->kernel != DSO_TYPE_USER || kmodule) {
                        char dso_name[PATH_MAX];
 
                        if (strcmp(section_name,
-                                  curr_dso->short_name + dso_name_len) == 0)
+                                  (curr_dso->short_name +
+                                   self->short_name_len)) == 0)
                                goto new_symbol;
 
                        if (strcmp(section_name, ".text") == 0) {
@@ -1009,6 +1050,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
                                curr_dso = dso__new(dso_name);
                                if (curr_dso == NULL)
                                        goto out_elf_end;
+                               curr_dso->kernel = self->kernel;
                                curr_map = map__new2(start, curr_dso,
                                                     map->type);
                                if (curr_map == NULL) {
@@ -1017,9 +1059,9 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
                                }
                                curr_map->map_ip = identity__map_ip;
                                curr_map->unmap_ip = identity__map_ip;
-                               curr_dso->origin = DSO__ORIG_KERNEL;
+                               curr_dso->origin = self->origin;
                                map_groups__insert(kmap->kmaps, curr_map);
-                               dsos__add(&dsos__kernel, curr_dso);
+                               dsos__add(&self->node, curr_dso);
                                dso__set_loaded(curr_dso, map->type);
                        } else
                                curr_dso = curr_map->dso;
@@ -1081,7 +1123,7 @@ 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 bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
+bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
 {
        bool have_build_id = false;
        struct dso *pos;
@@ -1099,13 +1141,6 @@ static bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
        return have_build_id;
 }
 
-bool dsos__read_build_ids(bool with_hits)
-{
-       bool kbuildids = __dsos__read_build_ids(&dsos__kernel, with_hits),
-            ubuildids = __dsos__read_build_ids(&dsos__user, with_hits);
-       return kbuildids || ubuildids;
-}
-
 /*
  * Align offset to 4 bytes as needed for note name and descriptor data.
  */
@@ -1240,6 +1275,8 @@ char dso__symtab_origin(const struct dso *self)
                [DSO__ORIG_BUILDID] =  'b',
                [DSO__ORIG_DSO] =      'd',
                [DSO__ORIG_KMODULE] =  'K',
+               [DSO__ORIG_GUEST_KERNEL] =  'g',
+               [DSO__ORIG_GUEST_KMODULE] =  'G',
        };
 
        if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND)
@@ -1255,11 +1292,20 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
        char build_id_hex[BUILD_ID_SIZE * 2 + 1];
        int ret = -1;
        int fd;
+       struct machine *machine;
+       const char *root_dir;
 
        dso__set_loaded(self, map->type);
 
-       if (self->kernel)
+       if (self->kernel == DSO_TYPE_KERNEL)
                return dso__load_kernel_sym(self, map, filter);
+       else if (self->kernel == DSO_TYPE_GUEST_KERNEL)
+               return dso__load_guest_kernel_sym(self, map, filter);
+
+       if (map->groups && map->groups->machine)
+               machine = map->groups->machine;
+       else
+               machine = NULL;
 
        name = malloc(size);
        if (!name)
@@ -1313,6 +1359,13 @@ more:
                case DSO__ORIG_DSO:
                        snprintf(name, size, "%s", self->long_name);
                        break;
+               case DSO__ORIG_GUEST_KMODULE:
+                       if (map->groups && map->groups->machine)
+                               root_dir = map->groups->machine->root_dir;
+                       else
+                               root_dir = "";
+                       snprintf(name, size, "%s%s", root_dir, self->long_name);
+                       break;
 
                default:
                        goto out;
@@ -1366,7 +1419,8 @@ struct map *map_groups__find_by_name(struct map_groups *self,
        return NULL;
 }
 
-static int dso__kernel_module_get_build_id(struct dso *self)
+static int dso__kernel_module_get_build_id(struct dso *self,
+                               const char *root_dir)
 {
        char filename[PATH_MAX];
        /*
@@ -1376,8 +1430,8 @@ static int dso__kernel_module_get_build_id(struct dso *self)
        const char *name = self->short_name + 1;
 
        snprintf(filename, sizeof(filename),
-                "/sys/module/%.*s/notes/.note.gnu.build-id",
-                (int)strlen(name - 1), name);
+                "%s/sys/module/%.*s/notes/.note.gnu.build-id",
+                root_dir, (int)strlen(name) - 1, name);
 
        if (sysfs__read_build_id(filename, self->build_id,
                                 sizeof(self->build_id)) == 0)
@@ -1386,26 +1440,33 @@ static int dso__kernel_module_get_build_id(struct dso *self)
        return 0;
 }
 
-static int map_groups__set_modules_path_dir(struct map_groups *self, char *dirname)
+static int map_groups__set_modules_path_dir(struct map_groups *self,
+                               const char *dir_name)
 {
        struct dirent *dent;
-       DIR *dir = opendir(dirname);
+       DIR *dir = opendir(dir_name);
 
        if (!dir) {
-               pr_debug("%s: cannot open %s dir\n", __func__, dirname);
+               pr_debug("%s: cannot open %s dir\n", __func__, dir_name);
                return -1;
        }
 
        while ((dent = readdir(dir)) != NULL) {
                char path[PATH_MAX];
+               struct stat st;
+
+               /*sshfs might return bad dent->d_type, so we have to stat*/
+               sprintf(path, "%s/%s", dir_name, dent->d_name);
+               if (stat(path, &st))
+                       continue;
 
-               if (dent->d_type == DT_DIR) {
+               if (S_ISDIR(st.st_mode)) {
                        if (!strcmp(dent->d_name, ".") ||
                            !strcmp(dent->d_name, ".."))
                                continue;
 
                        snprintf(path, sizeof(path), "%s/%s",
-                                dirname, dent->d_name);
+                                dir_name, dent->d_name);
                        if (map_groups__set_modules_path_dir(self, path) < 0)
                                goto failure;
                } else {
@@ -1425,13 +1486,13 @@ static int map_groups__set_modules_path_dir(struct map_groups *self, char *dirna
                                continue;
 
                        snprintf(path, sizeof(path), "%s/%s",
-                                dirname, dent->d_name);
+                                dir_name, dent->d_name);
 
                        long_name = strdup(path);
                        if (long_name == NULL)
                                goto failure;
                        dso__set_long_name(map->dso, long_name);
-                       dso__kernel_module_get_build_id(map->dso);
+                       dso__kernel_module_get_build_id(map->dso, "");
                }
        }
 
@@ -1441,18 +1502,47 @@ failure:
        return -1;
 }
 
-static int map_groups__set_modules_path(struct map_groups *self)
+static char *get_kernel_version(const char *root_dir)
 {
-       struct utsname uts;
+       char version[PATH_MAX];
+       FILE *file;
+       char *name, *tmp;
+       const char *prefix = "Linux version ";
+
+       sprintf(version, "%s/proc/version", root_dir);
+       file = fopen(version, "r");
+       if (!file)
+               return NULL;
+
+       version[0] = '\0';
+       tmp = fgets(version, sizeof(version), file);
+       fclose(file);
+
+       name = strstr(version, prefix);
+       if (!name)
+               return NULL;
+       name += strlen(prefix);
+       tmp = strchr(name, ' ');
+       if (tmp)
+               *tmp = '\0';
+
+       return strdup(name);
+}
+
+static int machine__set_modules_path(struct machine *self)
+{
+       char *version;
        char modules_path[PATH_MAX];
 
-       if (uname(&uts) < 0)
+       version = get_kernel_version(self->root_dir);
+       if (!version)
                return -1;
 
-       snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel",
-                uts.release);
+       snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel",
+                self->root_dir, version);
+       free(version);
 
-       return map_groups__set_modules_path_dir(self, modules_path);
+       return map_groups__set_modules_path_dir(&self->kmaps, modules_path);
 }
 
 /*
@@ -1462,8 +1552,8 @@ static int map_groups__set_modules_path(struct map_groups *self)
  */
 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
 {
-       struct map *self = zalloc(sizeof(*self) +
-                                 (dso->kernel ? sizeof(struct kmap) : 0));
+       struct map *self = calloc(1, (sizeof(*self) +
+                                     (dso->kernel ? sizeof(struct kmap) : 0)));
        if (self != NULL) {
                /*
                 * ->end will be filled after we load all the symbols
@@ -1474,11 +1564,11 @@ static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
        return self;
 }
 
-struct map *map_groups__new_module(struct map_groups *self, u64 start,
-                                  const char *filename)
+struct map *machine__new_module(struct machine *self, u64 start,
+                               const char *filename)
 {
        struct map *map;
-       struct dso *dso = __dsos__findnew(&dsos__kernel, filename);
+       struct dso *dso = __dsos__findnew(&self->kernel_dsos, filename);
 
        if (dso == NULL)
                return NULL;
@@ -1487,18 +1577,31 @@ struct map *map_groups__new_module(struct map_groups *self, u64 start,
        if (map == NULL)
                return NULL;
 
-       dso->origin = DSO__ORIG_KMODULE;
-       map_groups__insert(self, map);
+       if (machine__is_host(self))
+               dso->origin = DSO__ORIG_KMODULE;
+       else
+               dso->origin = DSO__ORIG_GUEST_KMODULE;
+       map_groups__insert(&self->kmaps, map);
        return map;
 }
 
-static int map_groups__create_modules(struct map_groups *self)
+static int machine__create_modules(struct machine *self)
 {
        char *line = NULL;
        size_t n;
-       FILE *file = fopen("/proc/modules", "r");
+       FILE *file;
        struct map *map;
+       const char *modules;
+       char path[PATH_MAX];
+
+       if (machine__is_default_guest(self))
+               modules = symbol_conf.default_guest_modules;
+       else {
+               sprintf(path, "%s/proc/modules", self->root_dir);
+               modules = path;
+       }
 
+       file = fopen(modules, "r");
        if (file == NULL)
                return -1;
 
@@ -1530,16 +1633,16 @@ static int map_groups__create_modules(struct map_groups *self)
                *sep = '\0';
 
                snprintf(name, sizeof(name), "[%s]", line);
-               map = map_groups__new_module(self, start, name);
+               map = machine__new_module(self, start, name);
                if (map == NULL)
                        goto out_delete_line;
-               dso__kernel_module_get_build_id(map->dso);
+               dso__kernel_module_get_build_id(map->dso, self->root_dir);
        }
 
        free(line);
        fclose(file);
 
-       return map_groups__set_modules_path(self);
+       return machine__set_modules_path(self);
 
 out_delete_line:
        free(line);
@@ -1706,8 +1809,56 @@ out_fixup:
        return err;
 }
 
-LIST_HEAD(dsos__user);
-LIST_HEAD(dsos__kernel);
+static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
+                               symbol_filter_t filter)
+{
+       int err;
+       const char *kallsyms_filename = NULL;
+       struct machine *machine;
+       char path[PATH_MAX];
+
+       if (!map->groups) {
+               pr_debug("Guest kernel map hasn't the point to groups\n");
+               return -1;
+       }
+       machine = map->groups->machine;
+
+       if (machine__is_default_guest(machine)) {
+               /*
+                * if the user specified a vmlinux filename, use it and only
+                * it, reporting errors to the user if it cannot be used.
+                * Or use file guest_kallsyms inputted by user on commandline
+                */
+               if (symbol_conf.default_guest_vmlinux_name != NULL) {
+                       err = dso__load_vmlinux(self, map,
+                               symbol_conf.default_guest_vmlinux_name, filter);
+                       goto out_try_fixup;
+               }
+
+               kallsyms_filename = symbol_conf.default_guest_kallsyms;
+               if (!kallsyms_filename)
+                       return -1;
+       } else {
+               sprintf(path, "%s/proc/kallsyms", machine->root_dir);
+               kallsyms_filename = path;
+       }
+
+       err = dso__load_kallsyms(self, kallsyms_filename, map, filter);
+       if (err > 0)
+               pr_debug("Using %s for symbols\n", kallsyms_filename);
+
+out_try_fixup:
+       if (err > 0) {
+               if (kallsyms_filename != NULL) {
+                       machine__mmap_name(machine, path, sizeof(path));
+                       dso__set_long_name(self, strdup(path));
+               }
+               map__fixup_start(map);
+               map__fixup_end(map);
+       }
+
+       return err;
+}
 
 static void dsos__add(struct list_head *head, struct dso *dso)
 {
@@ -1739,21 +1890,32 @@ struct dso *__dsos__findnew(struct list_head *head, const char *name)
        return dso;
 }
 
-static void __dsos__fprintf(struct list_head *head, FILE *fp)
+size_t __dsos__fprintf(struct list_head *head, FILE *fp)
 {
        struct dso *pos;
+       size_t ret = 0;
 
        list_for_each_entry(pos, head, node) {
                int i;
                for (i = 0; i < MAP__NR_TYPES; ++i)
-                       dso__fprintf(pos, i, fp);
+                       ret += dso__fprintf(pos, i, fp);
        }
+
+       return ret;
 }
 
-void dsos__fprintf(FILE *fp)
+size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp)
 {
-       __dsos__fprintf(&dsos__kernel, fp);
-       __dsos__fprintf(&dsos__user, fp);
+       struct rb_node *nd;
+       size_t ret = 0;
+
+       for (nd = rb_first(self); nd; nd = rb_next(nd)) {
+               struct machine *pos = rb_entry(nd, struct machine, rb_node);
+               ret += __dsos__fprintf(&pos->kernel_dsos, fp);
+               ret += __dsos__fprintf(&pos->user_dsos, fp);
+       }
+
+       return ret;
 }
 
 static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
@@ -1771,10 +1933,17 @@ static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
        return ret;
 }
 
-size_t dsos__fprintf_buildid(FILE *fp, bool with_hits)
+size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits)
 {
-       return (__dsos__fprintf_buildid(&dsos__kernel, fp, with_hits) +
-               __dsos__fprintf_buildid(&dsos__user, fp, with_hits));
+       struct rb_node *nd;
+       size_t ret = 0;
+
+       for (nd = rb_first(self); nd; nd = rb_next(nd)) {
+               struct machine *pos = rb_entry(nd, struct machine, rb_node);
+               ret += __dsos__fprintf_buildid(&pos->kernel_dsos, fp, with_hits);
+               ret += __dsos__fprintf_buildid(&pos->user_dsos, fp, with_hits);
+       }
+       return ret;
 }
 
 struct dso *dso__new_kernel(const char *name)
@@ -1782,56 +1951,99 @@ struct dso *dso__new_kernel(const char *name)
        struct dso *self = dso__new(name ?: "[kernel.kallsyms]");
 
        if (self != NULL) {
-               self->short_name = "[kernel]";
-               self->kernel     = 1;
+               dso__set_short_name(self, "[kernel]");
+               self->kernel = DSO_TYPE_KERNEL;
+       }
+
+       return self;
+}
+
+static struct dso *dso__new_guest_kernel(struct machine *machine,
+                                       const char *name)
+{
+       char bf[PATH_MAX];
+       struct dso *self = dso__new(name ?: machine__mmap_name(machine, bf, sizeof(bf)));
+
+       if (self != NULL) {
+               dso__set_short_name(self, "[guest.kernel]");
+               self->kernel = DSO_TYPE_GUEST_KERNEL;
        }
 
        return self;
 }
 
-void dso__read_running_kernel_build_id(struct dso *self)
+void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine)
 {
-       if (sysfs__read_build_id("/sys/kernel/notes", self->build_id,
+       char path[PATH_MAX];
+
+       if (machine__is_default_guest(machine))
+               return;
+       sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
+       if (sysfs__read_build_id(path, self->build_id,
                                 sizeof(self->build_id)) == 0)
                self->has_build_id = true;
 }
 
-static struct dso *dsos__create_kernel(const char *vmlinux)
+static struct dso *machine__create_kernel(struct machine *self)
 {
-       struct dso *kernel = dso__new_kernel(vmlinux);
+       const char *vmlinux_name = NULL;
+       struct dso *kernel;
 
-       if (kernel != NULL) {
-               dso__read_running_kernel_build_id(kernel);
-               dsos__add(&dsos__kernel, kernel);
+       if (machine__is_host(self)) {
+               vmlinux_name = symbol_conf.vmlinux_name;
+               kernel = dso__new_kernel(vmlinux_name);
+       } else {
+               if (machine__is_default_guest(self))
+                       vmlinux_name = symbol_conf.default_guest_vmlinux_name;
+               kernel = dso__new_guest_kernel(self, vmlinux_name);
        }
 
+       if (kernel != NULL) {
+               dso__read_running_kernel_build_id(kernel, self);
+               dsos__add(&self->kernel_dsos, kernel);
+       }
        return kernel;
 }
 
-int __map_groups__create_kernel_maps(struct map_groups *self,
-                                    struct map *vmlinux_maps[MAP__NR_TYPES],
-                                    struct dso *kernel)
+int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
 {
        enum map_type type;
 
        for (type = 0; type < MAP__NR_TYPES; ++type) {
                struct kmap *kmap;
 
-               vmlinux_maps[type] = map__new2(0, kernel, type);
-               if (vmlinux_maps[type] == NULL)
+               self->vmlinux_maps[type] = map__new2(0, kernel, type);
+               if (self->vmlinux_maps[type] == NULL)
                        return -1;
 
-               vmlinux_maps[type]->map_ip =
-                       vmlinux_maps[type]->unmap_ip = identity__map_ip;
+               self->vmlinux_maps[type]->map_ip =
+                       self->vmlinux_maps[type]->unmap_ip = identity__map_ip;
 
-               kmap = map__kmap(vmlinux_maps[type]);
-               kmap->kmaps = self;
-               map_groups__insert(self, vmlinux_maps[type]);
+               kmap = map__kmap(self->vmlinux_maps[type]);
+               kmap->kmaps = &self->kmaps;
+               map_groups__insert(&self->kmaps, self->vmlinux_maps[type]);
        }
 
        return 0;
 }
 
+int machine__create_kernel_maps(struct machine *self)
+{
+       struct dso *kernel = machine__create_kernel(self);
+
+       if (kernel == NULL ||
+           __machine__create_kernel_maps(self, kernel) < 0)
+               return -1;
+
+       if (symbol_conf.use_modules && machine__create_modules(self) < 0)
+               pr_debug("Problems creating module maps, continuing anyway...\n");
+       /*
+        * Now that we have all the maps created, just set the ->end of them:
+        */
+       map_groups__fixup_end(&self->kmaps);
+       return 0;
+}
+
 static void vmlinux_path__exit(void)
 {
        while (--vmlinux_path__nr_entries >= 0) {
@@ -1887,6 +2099,17 @@ out_fail:
        return -1;
 }
 
+size_t vmlinux_path__fprintf(FILE *fp)
+{
+       int i;
+       size_t printed = 0;
+
+       for (i = 0; i < vmlinux_path__nr_entries; ++i)
+               printed += fprintf(fp, "[%d] %s\n", i, vmlinux_path[i]);
+
+       return printed;
+}
+
 static int setup_list(struct strlist **list, const char *list_str,
                      const char *list_name)
 {
@@ -1937,22 +2160,129 @@ out_free_comm_list:
        return -1;
 }
 
-int map_groups__create_kernel_maps(struct map_groups *self,
-                                  struct map *vmlinux_maps[MAP__NR_TYPES])
+int machines__create_kernel_maps(struct rb_root *self, pid_t pid)
 {
-       struct dso *kernel = dsos__create_kernel(symbol_conf.vmlinux_name);
+       struct machine *machine = machines__findnew(self, pid);
 
-       if (kernel == NULL)
+       if (machine == NULL)
                return -1;
 
-       if (__map_groups__create_kernel_maps(self, vmlinux_maps, kernel) < 0)
-               return -1;
+       return machine__create_kernel_maps(machine);
+}
 
-       if (symbol_conf.use_modules && map_groups__create_modules(self) < 0)
-               pr_debug("Problems creating module maps, continuing anyway...\n");
-       /*
-        * Now that we have all the maps created, just set the ->end of them:
-        */
-       map_groups__fixup_end(self);
-       return 0;
+static int hex(char ch)
+{
+       if ((ch >= '0') && (ch <= '9'))
+               return ch - '0';
+       if ((ch >= 'a') && (ch <= 'f'))
+               return ch - 'a' + 10;
+       if ((ch >= 'A') && (ch <= 'F'))
+               return ch - 'A' + 10;
+       return -1;
+}
+
+/*
+ * While we find nice hex chars, build a long_val.
+ * Return number of chars processed.
+ */
+int hex2u64(const char *ptr, u64 *long_val)
+{
+       const char *p = ptr;
+       *long_val = 0;
+
+       while (*p) {
+               const int hex_val = hex(*p);
+
+               if (hex_val < 0)
+                       break;
+
+               *long_val = (*long_val << 4) | hex_val;
+               p++;
+       }
+
+       return p - ptr;
+}
+
+char *strxfrchar(char *s, char from, char to)
+{
+       char *p = s;
+
+       while ((p = strchr(p, from)) != NULL)
+               *p++ = to;
+
+       return s;
+}
+
+int machines__create_guest_kernel_maps(struct rb_root *self)
+{
+       int ret = 0;
+       struct dirent **namelist = NULL;
+       int i, items = 0;
+       char path[PATH_MAX];
+       pid_t pid;
+
+       if (symbol_conf.default_guest_vmlinux_name ||
+           symbol_conf.default_guest_modules ||
+           symbol_conf.default_guest_kallsyms) {
+               machines__create_kernel_maps(self, DEFAULT_GUEST_KERNEL_ID);
+       }
+
+       if (symbol_conf.guestmount) {
+               items = scandir(symbol_conf.guestmount, &namelist, NULL, NULL);
+               if (items <= 0)
+                       return -ENOENT;
+               for (i = 0; i < items; i++) {
+                       if (!isdigit(namelist[i]->d_name[0])) {
+                               /* Filter out . and .. */
+                               continue;
+                       }
+                       pid = atoi(namelist[i]->d_name);
+                       sprintf(path, "%s/%s/proc/kallsyms",
+                               symbol_conf.guestmount,
+                               namelist[i]->d_name);
+                       ret = access(path, R_OK);
+                       if (ret) {
+                               pr_debug("Can't access file %s\n", path);
+                               goto failure;
+                       }
+                       machines__create_kernel_maps(self, pid);
+               }
+failure:
+               free(namelist);
+       }
+
+       return ret;
+}
+
+int machine__load_kallsyms(struct machine *self, const char *filename,
+                          enum map_type type, symbol_filter_t filter)
+{
+       struct map *map = self->vmlinux_maps[type];
+       int ret = dso__load_kallsyms(map->dso, filename, map, filter);
+
+       if (ret > 0) {
+               dso__set_loaded(map->dso, type);
+               /*
+                * Since /proc/kallsyms will have multiple sessions for the
+                * kernel, with modules between them, fixup the end of all
+                * sections.
+                */
+               __map_groups__fixup_end(&self->kmaps, type);
+       }
+
+       return ret;
+}
+
+int machine__load_vmlinux_path(struct machine *self, enum map_type type,
+                              symbol_filter_t filter)
+{
+       struct map *map = self->vmlinux_maps[type];
+       int ret = dso__load_vmlinux_path(map->dso, map, filter);
+
+       if (ret > 0) {
+               dso__set_loaded(map->dso, type);
+               map__reloc_vmlinux(map);
+       }
+
+       return ret;
 }
index 280dadd32a08972f59bde677d4f7bc6c14a0da36..032469e4187615fb25357fefa047854640a0e88a 100644 (file)
@@ -3,10 +3,11 @@
 
 #include <linux/types.h>
 #include <stdbool.h>
-#include "types.h"
+#include <stdint.h>
+#include "map.h"
 #include <linux/list.h>
 #include <linux/rbtree.h>
-#include "event.h"
+#include <stdio.h>
 
 #define DEBUG_CACHE_DIR ".debug"
 
@@ -29,6 +30,9 @@ static inline char *bfd_demangle(void __used *v, const char __used *c,
 #endif
 #endif
 
+int hex2u64(const char *ptr, u64 *val);
+char *strxfrchar(char *s, char from, char to);
+
 /*
  * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
  * for newer versions we can use mmap to reduce memory usage:
@@ -44,10 +48,13 @@ static inline char *bfd_demangle(void __used *v, const char __used *c,
 #define DMGL_ANSI        (1 << 1)       /* Include const, volatile, etc */
 #endif
 
+#define BUILD_ID_SIZE 20
+
 struct symbol {
        struct rb_node  rb_node;
        u64             start;
        u64             end;
+       u16             namelen;
        char            name[0];
 };
 
@@ -63,10 +70,15 @@ struct symbol_conf {
                        show_nr_samples,
                        use_callchain,
                        exclude_other,
-                       full_paths;
+                       full_paths,
+                       show_cpu_utilization;
        const char      *vmlinux_name,
                        *field_sep;
-       char            *dso_list_str,
+       const char      *default_guest_vmlinux_name,
+                       *default_guest_kallsyms,
+                       *default_guest_modules;
+       const char      *guestmount;
+       const char      *dso_list_str,
                        *comm_list_str,
                        *sym_list_str,
                        *col_width_list_str;
@@ -88,6 +100,11 @@ struct ref_reloc_sym {
        u64             unrelocated_addr;
 };
 
+struct map_symbol {
+       struct map    *map;
+       struct symbol *sym;
+};
+
 struct addr_location {
        struct thread *thread;
        struct map    *map;
@@ -95,6 +112,13 @@ struct addr_location {
        u64           addr;
        char          level;
        bool          filtered;
+       unsigned int  cpumode;
+};
+
+enum dso_kernel_type {
+       DSO_TYPE_USER = 0,
+       DSO_TYPE_KERNEL,
+       DSO_TYPE_GUEST_KERNEL
 };
 
 struct dso {
@@ -104,15 +128,17 @@ struct dso {
        u8               adjust_symbols:1;
        u8               slen_calculated:1;
        u8               has_build_id:1;
-       u8               kernel:1;
+       enum dso_kernel_type    kernel;
        u8               hit:1;
+       u8               annotate_warned:1;
        unsigned char    origin;
        u8               sorted_by_name;
        u8               loaded;
        u8               build_id[BUILD_ID_SIZE];
-       u16              long_name_len;
        const char       *short_name;
        char             *long_name;
+       u16              long_name_len;
+       u16              short_name_len;
        char             name[0];
 };
 
@@ -130,42 +156,65 @@ static inline void dso__set_loaded(struct dso *self, enum map_type type)
 
 void dso__sort_by_name(struct dso *self, enum map_type type);
 
-extern struct list_head dsos__user, dsos__kernel;
-
 struct dso *__dsos__findnew(struct list_head *head, const char *name);
 
-static inline struct dso *dsos__findnew(const char *name)
-{
-       return __dsos__findnew(&dsos__user, name);
-}
-
 int dso__load(struct dso *self, struct map *map, symbol_filter_t filter);
 int dso__load_vmlinux_path(struct dso *self, struct map *map,
                           symbol_filter_t filter);
 int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map,
                       symbol_filter_t filter);
-void dsos__fprintf(FILE *fp);
-size_t dsos__fprintf_buildid(FILE *fp, bool with_hits);
+int machine__load_kallsyms(struct machine *self, const char *filename,
+                          enum map_type type, symbol_filter_t filter);
+int machine__load_vmlinux_path(struct machine *self, enum map_type type,
+                              symbol_filter_t filter);
+
+size_t __dsos__fprintf(struct list_head *head, FILE *fp);
+
+size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp);
+size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits);
 
 size_t dso__fprintf_buildid(struct dso *self, FILE *fp);
 size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp);
+
+enum dso_origin {
+       DSO__ORIG_KERNEL = 0,
+       DSO__ORIG_GUEST_KERNEL,
+       DSO__ORIG_JAVA_JIT,
+       DSO__ORIG_BUILD_ID_CACHE,
+       DSO__ORIG_FEDORA,
+       DSO__ORIG_UBUNTU,
+       DSO__ORIG_BUILDID,
+       DSO__ORIG_DSO,
+       DSO__ORIG_GUEST_KMODULE,
+       DSO__ORIG_KMODULE,
+       DSO__ORIG_NOT_FOUND,
+};
+
 char dso__symtab_origin(const struct dso *self);
 void dso__set_long_name(struct dso *self, char *name);
 void dso__set_build_id(struct dso *self, void *build_id);
-void dso__read_running_kernel_build_id(struct dso *self);
+void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine);
 struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr);
 struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type,
                                        const char *name);
 
 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(bool with_hits);
+bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
 int build_id__sprintf(const u8 *self, int len, char *bf);
 int kallsyms__parse(const char *filename, void *arg,
                    int (*process_symbol)(void *arg, const char *name,
                                          char type, u64 start));
 
+int __machine__create_kernel_maps(struct machine *self, struct dso *kernel);
+int machine__create_kernel_maps(struct machine *self);
+
+int machines__create_kernel_maps(struct rb_root *self, pid_t pid);
+int machines__create_guest_kernel_maps(struct rb_root *self);
+
 int symbol__init(void);
 bool symbol_type__is_a(char symbol_type, enum map_type map_type);
 
+size_t vmlinux_path__fprintf(FILE *fp);
+
 #endif /* __PERF_SYMBOL */
index 21b92162282b8d70b23be3ef889bdf690b96070c..1f7ecd47f49942809d19b0be3f65d9fb1f904ebc 100644 (file)
@@ -7,13 +7,35 @@
 #include "util.h"
 #include "debug.h"
 
-void map_groups__init(struct map_groups *self)
+int find_all_tid(int pid, pid_t ** all_tid)
 {
+       char name[256];
+       int items;
+       struct dirent **namelist = NULL;
+       int ret = 0;
        int i;
-       for (i = 0; i < MAP__NR_TYPES; ++i) {
-               self->maps[i] = RB_ROOT;
-               INIT_LIST_HEAD(&self->removed_maps[i]);
+
+       sprintf(name, "/proc/%d/task", pid);
+       items = scandir(name, &namelist, NULL, NULL);
+       if (items <= 0)
+                return -ENOENT;
+       *all_tid = malloc(sizeof(pid_t) * items);
+       if (!*all_tid) {
+               ret = -ENOMEM;
+               goto failure;
        }
+
+       for (i = 0; i < items; i++)
+               (*all_tid)[i] = atoi(namelist[i]->d_name);
+
+       ret = items;
+
+failure:
+       for (i=0; i<items; i++)
+               free(namelist[i]);
+       free(namelist);
+
+       return ret;
 }
 
 static struct thread *thread__new(pid_t pid)
@@ -31,28 +53,6 @@ static struct thread *thread__new(pid_t pid)
        return self;
 }
 
-static void map_groups__flush(struct map_groups *self)
-{
-       int type;
-
-       for (type = 0; type < MAP__NR_TYPES; type++) {
-               struct rb_root *root = &self->maps[type];
-               struct rb_node *next = rb_first(root);
-
-               while (next) {
-                       struct map *pos = rb_entry(next, struct map, rb_node);
-                       next = rb_next(&pos->rb_node);
-                       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[pos->type]);
-               }
-       }
-}
-
 int thread__set_comm(struct thread *self, const char *comm)
 {
        int err;
@@ -79,69 +79,10 @@ int thread__comm_len(struct thread *self)
        return self->comm_len;
 }
 
-static size_t __map_groups__fprintf_maps(struct map_groups *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 map_groups__fprintf_maps(struct map_groups *self, FILE *fp)
-{
-       size_t printed = 0, i;
-       for (i = 0; i < MAP__NR_TYPES; ++i)
-               printed += __map_groups__fprintf_maps(self, i, fp);
-       return printed;
-}
-
-static size_t __map_groups__fprintf_removed_maps(struct map_groups *self,
-                                                enum map_type type, FILE *fp)
-{
-       struct map *pos;
-       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;
-}
-
-static size_t map_groups__fprintf_removed_maps(struct map_groups *self, FILE *fp)
-{
-       size_t printed = 0, i;
-       for (i = 0; i < MAP__NR_TYPES; ++i)
-               printed += __map_groups__fprintf_removed_maps(self, i, fp);
-       return printed;
-}
-
-static size_t map_groups__fprintf(struct map_groups *self, FILE *fp)
-{
-       size_t printed = map_groups__fprintf_maps(self, fp);
-       printed += fprintf(fp, "Removed maps:\n");
-       return printed + map_groups__fprintf_removed_maps(self, fp);
-}
-
 static size_t thread__fprintf(struct thread *self, FILE *fp)
 {
        return fprintf(fp, "Thread %d %s\n", self->pid, self->comm) +
-              map_groups__fprintf(&self->mg, fp);
+              map_groups__fprintf(&self->mg, verbose, fp);
 }
 
 struct thread *perf_session__findnew(struct perf_session *self, pid_t pid)
@@ -183,98 +124,12 @@ struct thread *perf_session__findnew(struct perf_session *self, pid_t pid)
        return th;
 }
 
-static void map_groups__remove_overlappings(struct map_groups *self,
-                                           struct map *map)
-{
-       struct rb_root *root = &self->maps[map->type];
-       struct rb_node *next = rb_first(root);
-
-       while (next) {
-               struct map *pos = rb_entry(next, struct map, rb_node);
-               next = rb_next(&pos->rb_node);
-
-               if (!map__overlap(pos, map))
-                       continue;
-
-               if (verbose >= 2) {
-                       fputs("overlapping maps:\n", stderr);
-                       map__fprintf(map, stderr);
-                       map__fprintf(pos, stderr);
-               }
-
-               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]);
-       }
-}
-
-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;
-       }
-
-       rb_link_node(&map->rb_node, parent, p);
-       rb_insert_color(&map->rb_node, maps);
-}
-
-struct map *maps__find(struct rb_root *maps, u64 ip)
-{
-       struct rb_node **p = &maps->rb_node;
-       struct rb_node *parent = NULL;
-       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 if (ip > m->end)
-                       p = &(*p)->rb_right;
-               else
-                       return m;
-       }
-
-       return NULL;
-}
-
 void thread__insert_map(struct thread *self, struct map *map)
 {
-       map_groups__remove_overlappings(&self->mg, map);
+       map_groups__fixup_overlappings(&self->mg, map, verbose, stderr);
        map_groups__insert(&self->mg, map);
 }
 
-/*
- * XXX This should not really _copy_ te maps, but refcount them.
- */
-static int map_groups__clone(struct map_groups *self,
-                            struct map_groups *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 == NULL)
-                       return -ENOMEM;
-               map_groups__insert(self, new);
-       }
-       return 0;
-}
-
 int thread__fork(struct thread *self, struct thread *parent)
 {
        int i;
@@ -307,15 +162,3 @@ size_t perf_session__fprintf(struct perf_session *self, FILE *fp)
 
        return ret;
 }
-
-struct symbol *map_groups__find_symbol(struct map_groups *self,
-                                      enum map_type type, u64 addr,
-                                      symbol_filter_t filter)
-{
-       struct map *map = map_groups__find(self, type, addr);
-
-       if (map != NULL)
-               return map__find_symbol(map, map->map_ip(map, addr), filter);
-
-       return NULL;
-}
index 0a28f39de545f5810893fe44b87af0f895000037..1dfd9ff8bdcdfc7d290c9e9f686875cd107dd4d7 100644 (file)
@@ -5,11 +5,6 @@
 #include <unistd.h>
 #include "symbol.h"
 
-struct map_groups {
-       struct rb_root          maps[MAP__NR_TYPES];
-       struct list_head        removed_maps[MAP__NR_TYPES];
-};
-
 struct thread {
        struct rb_node          rb_node;
        struct map_groups       mg;
@@ -20,29 +15,16 @@ struct thread {
        int                     comm_len;
 };
 
-void map_groups__init(struct map_groups *self);
+struct perf_session;
+
+int find_all_tid(int pid, pid_t ** all_tid);
 int thread__set_comm(struct thread *self, const char *comm);
 int thread__comm_len(struct thread *self);
 struct thread *perf_session__findnew(struct perf_session *self, pid_t pid);
 void thread__insert_map(struct thread *self, struct map *map);
 int thread__fork(struct thread *self, struct thread *parent);
-size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp);
 size_t perf_session__fprintf(struct perf_session *self, FILE *fp);
 
-void maps__insert(struct rb_root *maps, struct map *map);
-struct map *maps__find(struct rb_root *maps, u64 addr);
-
-static inline void map_groups__insert(struct map_groups *self, struct map *map)
-{
-        maps__insert(&self->maps[map->type], map);
-}
-
-static inline struct map *map_groups__find(struct map_groups *self,
-                                          enum map_type type, u64 addr)
-{
-       return maps__find(&self->maps[type], addr);
-}
-
 static inline struct map *thread__find_map(struct thread *self,
                                           enum map_type type, u64 addr)
 {
@@ -51,34 +33,12 @@ static inline struct map *thread__find_map(struct thread *self,
 
 void thread__find_addr_map(struct thread *self,
                           struct perf_session *session, u8 cpumode,
-                          enum map_type type, u64 addr,
+                          enum map_type type, pid_t pid, u64 addr,
                           struct addr_location *al);
 
 void thread__find_addr_location(struct thread *self,
                                struct perf_session *session, u8 cpumode,
-                               enum map_type type, u64 addr,
+                               enum map_type type, pid_t pid, u64 addr,
                                struct addr_location *al,
                                symbol_filter_t filter);
-struct symbol *map_groups__find_symbol(struct map_groups *self,
-                                      enum map_type type, u64 addr,
-                                      symbol_filter_t filter);
-
-static inline struct symbol *map_groups__find_function(struct map_groups *self,
-                                                      u64 addr,
-                                                      symbol_filter_t filter)
-{
-       return map_groups__find_symbol(self, MAP__FUNCTION, addr, filter);
-}
-
-struct map *map_groups__find_by_name(struct map_groups *self,
-                                    enum map_type type, const char *name);
-
-int __map_groups__create_kernel_maps(struct map_groups *self,
-                                    struct map *vmlinux_maps[MAP__NR_TYPES],
-                                    struct dso *kernel);
-int map_groups__create_kernel_maps(struct map_groups *self,
-                                  struct map *vmlinux_maps[MAP__NR_TYPES]);
-
-struct map *map_groups__new_module(struct map_groups *self, u64 start,
-                                  const char *filename);
 #endif /* __PERF_THREAD_H */
index 5ea8973ad331d48e1d4d9e9c94cc65d27a816599..b1572601286cad7020c323d175177d0445eb806f 100644 (file)
@@ -154,10 +154,17 @@ static void put_tracing_file(char *file)
        free(file);
 }
 
+static ssize_t calc_data_size;
+
 static ssize_t write_or_die(const void *buf, size_t len)
 {
        int ret;
 
+       if (calc_data_size) {
+               calc_data_size += len;
+               return len;
+       }
+
        ret = write(output_fd, buf, len);
        if (ret < 0)
                die("writing to '%s'", output_file);
@@ -480,6 +487,17 @@ get_tracepoints_path(struct perf_event_attr *pattrs, int nb_events)
        return nr_tracepoints > 0 ? path.next : NULL;
 }
 
+bool have_tracepoints(struct perf_event_attr *pattrs, int nb_events)
+{
+       int i;
+
+       for (i = 0; i < nb_events; i++)
+               if (pattrs[i].type == PERF_TYPE_TRACEPOINT)
+                       return true;
+
+       return false;
+}
+
 int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events)
 {
        char buf[BUFSIZ];
@@ -526,3 +544,20 @@ int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events)
 
        return 0;
 }
+
+ssize_t read_tracing_data_size(int fd, struct perf_event_attr *pattrs,
+                              int nb_events)
+{
+       ssize_t size;
+       int err = 0;
+
+       calc_data_size = 1;
+       err = read_tracing_data(fd, pattrs, nb_events);
+       size = calc_data_size - 1;
+       calc_data_size = 0;
+
+       if (err < 0)
+               return err;
+
+       return size;
+}
index 9b3c20f42f98a2ab0b4157ca8f03d0f0477c7b75..73a02223c62922125b0dddb97e8a26099d8fdcd8 100644 (file)
@@ -37,10 +37,12 @@ int header_page_ts_offset;
 int header_page_ts_size;
 int header_page_size_offset;
 int header_page_size_size;
+int header_page_overwrite_offset;
+int header_page_overwrite_size;
 int header_page_data_offset;
 int header_page_data_size;
 
-int latency_format;
+bool latency_format;
 
 static char *input_buf;
 static unsigned long long input_buf_ptr;
@@ -628,23 +630,32 @@ static int test_type(enum event_type type, enum event_type expect)
        return 0;
 }
 
-static int test_type_token(enum event_type type, char *token,
-                   enum event_type expect, const char *expect_tok)
+static int __test_type_token(enum event_type type, char *token,
+                            enum event_type expect, const char *expect_tok,
+                            bool warn)
 {
        if (type != expect) {
-               warning("Error: expected type %d but read %d",
-                   expect, type);
+               if (warn)
+                       warning("Error: expected type %d but read %d",
+                               expect, type);
                return -1;
        }
 
        if (strcmp(token, expect_tok) != 0) {
-               warning("Error: expected '%s' but read '%s'",
-                   expect_tok, token);
+               if (warn)
+                       warning("Error: expected '%s' but read '%s'",
+                               expect_tok, token);
                return -1;
        }
        return 0;
 }
 
+static int test_type_token(enum event_type type, char *token,
+                          enum event_type expect, const char *expect_tok)
+{
+       return __test_type_token(type, token, expect, expect_tok, true);
+}
+
 static int __read_expect_type(enum event_type expect, char **tok, int newline_ok)
 {
        enum event_type type;
@@ -661,7 +672,8 @@ 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, const char *str, int newline_ok)
+static int __read_expected(enum event_type expect, const char *str,
+                          int newline_ok, bool warn)
 {
        enum event_type type;
        char *token;
@@ -672,7 +684,7 @@ static int __read_expected(enum event_type expect, const char *str, int newline_
        else
                type = read_token_item(&token);
 
-       ret = test_type_token(type, token, expect, str);
+       ret = __test_type_token(type, token, expect, str, warn);
 
        free_token(token);
 
@@ -681,12 +693,12 @@ static int __read_expected(enum event_type expect, const char *str, int newline_
 
 static int read_expected(enum event_type expect, const char *str)
 {
-       return __read_expected(expect, str, 1);
+       return __read_expected(expect, str, 1, true);
 }
 
 static int read_expected_item(enum event_type expect, const char *str)
 {
-       return __read_expected(expect, str, 0);
+       return __read_expected(expect, str, 0, true);
 }
 
 static char *event_read_name(void)
@@ -744,7 +756,7 @@ static int field_is_string(struct format_field *field)
 
 static int field_is_dynamic(struct format_field *field)
 {
-       if (!strcmp(field->type, "__data_loc"))
+       if (!strncmp(field->type, "__data_loc", 10))
                return 1;
 
        return 0;
@@ -1925,7 +1937,7 @@ void *raw_field_ptr(struct event *event, const char *name, void *data)
        if (!field)
                return NULL;
 
-       if (field->flags & FIELD_IS_STRING) {
+       if (field->flags & FIELD_IS_DYNAMIC) {
                int offset;
 
                offset = *(int *)(data + field->offset);
@@ -3087,88 +3099,6 @@ static void print_args(struct print_arg *args)
        }
 }
 
-static void parse_header_field(const char *field,
-                              int *offset, int *size)
-{
-       char *token;
-       int type;
-
-       if (read_expected(EVENT_ITEM, "field") < 0)
-               return;
-       if (read_expected(EVENT_OP, ":") < 0)
-               return;
-
-       /* type */
-       if (read_expect_type(EVENT_ITEM, &token) < 0)
-               goto fail;
-       free_token(token);
-
-       if (read_expected(EVENT_ITEM, field) < 0)
-               return;
-       if (read_expected(EVENT_OP, ";") < 0)
-               return;
-       if (read_expected(EVENT_ITEM, "offset") < 0)
-               return;
-       if (read_expected(EVENT_OP, ":") < 0)
-               return;
-       if (read_expect_type(EVENT_ITEM, &token) < 0)
-               goto fail;
-       *offset = atoi(token);
-       free_token(token);
-       if (read_expected(EVENT_OP, ";") < 0)
-               return;
-       if (read_expected(EVENT_ITEM, "size") < 0)
-               return;
-       if (read_expected(EVENT_OP, ":") < 0)
-               return;
-       if (read_expect_type(EVENT_ITEM, &token) < 0)
-               goto fail;
-       *size = atoi(token);
-       free_token(token);
-       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);
-}
-
-int parse_header_page(char *buf, unsigned long size)
-{
-       init_input_buf(buf, size);
-
-       parse_header_field("timestamp", &header_page_ts_offset,
-                          &header_page_ts_size);
-       parse_header_field("commit", &header_page_size_offset,
-                          &header_page_size_size);
-       parse_header_field("data", &header_page_data_offset,
-                          &header_page_data_size);
-
-       return 0;
-}
-
 int parse_ftrace_file(char *buf, unsigned long size)
 {
        struct format_field *field;
index 7cd1193918c76ccef904e03c7ed6f37fcc66a5b8..cb54cd002f49b3e8abb45e55b8906af3bb66467c 100644 (file)
@@ -50,14 +50,51 @@ static int long_size;
 
 static unsigned long   page_size;
 
+static ssize_t calc_data_size;
+static bool repipe;
+
+/* If it fails, the next read will report it */
+static void skip(int size)
+{
+       lseek(input_fd, size, SEEK_CUR);
+}
+
+static int do_read(int fd, void *buf, int size)
+{
+       int rsize = size;
+
+       while (size) {
+               int ret = read(fd, buf, size);
+
+               if (ret <= 0)
+                       return -1;
+
+               if (repipe) {
+                       int retw = write(STDOUT_FILENO, buf, ret);
+
+                       if (retw <= 0 || retw != ret)
+                               die("repiping input file");
+               }
+
+               size -= ret;
+               buf += ret;
+       }
+
+       return rsize;
+}
+
 static int read_or_die(void *data, int size)
 {
        int r;
 
-       r = read(input_fd, data, size);
-       if (r != size)
+       r = do_read(input_fd, data, size);
+       if (r <= 0)
                die("reading input file (size expected=%d received=%d)",
                    size, r);
+
+       if (calc_data_size)
+               calc_data_size += r;
+
        return r;
 }
 
@@ -82,57 +119,36 @@ static char *read_string(void)
        char buf[BUFSIZ];
        char *str = NULL;
        int size = 0;
-       int i;
        off_t r;
+       char c;
 
        for (;;) {
-               r = read(input_fd, buf, BUFSIZ);
+               r = read(input_fd, &c, 1);
                if (r < 0)
                        die("reading input file");
 
                if (!r)
                        die("no data");
 
-               for (i = 0; i < r; i++) {
-                       if (!buf[i])
-                               break;
-               }
-               if (i < r)
-                       break;
+               if (repipe) {
+                       int retw = write(STDOUT_FILENO, &c, 1);
 
-               if (str) {
-                       size += BUFSIZ;
-                       str = realloc(str, size);
-                       if (!str)
-                               die("malloc of size %d", size);
-                       memcpy(str + (size - BUFSIZ), buf, BUFSIZ);
-               } else {
-                       size = BUFSIZ;
-                       str = malloc_or_die(size);
-                       memcpy(str, buf, size);
+                       if (retw <= 0 || retw != r)
+                               die("repiping input file string");
                }
-       }
 
-       /* trailing \0: */
-       i++;
-
-       /* move the file descriptor to the end of the string */
-       r = lseek(input_fd, -(r - i), SEEK_CUR);
-       if (r == (off_t)-1)
-               die("lseek");
-
-       if (str) {
-               size += i;
-               str = realloc(str, size);
-               if (!str)
-                       die("malloc of size %d", size);
-               memcpy(str + (size - i), buf, i);
-       } else {
-               size = i;
-               str = malloc_or_die(i);
-               memcpy(str, buf, i);
+               buf[size++] = c;
+
+               if (!c)
+                       break;
        }
 
+       if (calc_data_size)
+               calc_data_size += size;
+
+       str = malloc_or_die(size);
+       memcpy(str, buf, size);
+
        return str;
 }
 
@@ -174,7 +190,6 @@ static void read_ftrace_printk(void)
 static void read_header_files(void)
 {
        unsigned long long size;
-       char *header_page;
        char *header_event;
        char buf[BUFSIZ];
 
@@ -184,10 +199,7 @@ static void read_header_files(void)
                die("did not read header page");
 
        size = read8();
-       header_page = malloc_or_die(size);
-       read_or_die(header_page, size);
-       parse_header_page(header_page, size);
-       free(header_page);
+       skip(size);
 
        /*
         * The size field in the page is of type long,
@@ -459,7 +471,7 @@ struct record *trace_read_data(int cpu)
        return data;
 }
 
-void trace_report(int fd)
+ssize_t trace_report(int fd, bool __repipe)
 {
        char buf[BUFSIZ];
        char test[] = { 23, 8, 68 };
@@ -467,6 +479,10 @@ void trace_report(int fd)
        int show_version = 0;
        int show_funcs = 0;
        int show_printk = 0;
+       ssize_t size;
+
+       calc_data_size = 1;
+       repipe = __repipe;
 
        input_fd = fd;
 
@@ -499,14 +515,18 @@ void trace_report(int fd)
        read_proc_kallsyms();
        read_ftrace_printk();
 
+       size = calc_data_size - 1;
+       calc_data_size = 0;
+       repipe = false;
+
        if (show_funcs) {
                print_funcs();
-               return;
+               return size;
        }
        if (show_printk) {
                print_printk();
-               return;
+               return size;
        }
 
-       return;
+       return size;
 }
index c3269b937db42d103d2bd3a37789d535445a8153..406d452956db1f15e1026d97b56a7991e6b4f8c3 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __PERF_TRACE_EVENTS_H
 #define __PERF_TRACE_EVENTS_H
 
+#include <stdbool.h>
 #include "parse-events.h"
 
 #define __unused __attribute__((unused))
@@ -162,7 +163,7 @@ struct record *trace_read_data(int cpu);
 
 void parse_set_info(int nr_cpus, int long_sz);
 
-void trace_report(int fd);
+ssize_t trace_report(int fd, bool repipe);
 
 void *malloc_or_die(unsigned int size);
 
@@ -241,9 +242,8 @@ extern int header_page_size_size;
 extern int header_page_data_offset;
 extern int header_page_data_size;
 
-extern int latency_format;
+extern bool 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);
@@ -258,6 +258,8 @@ 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);
+ssize_t read_tracing_data_size(int fd, struct perf_event_attr *pattrs,
+                              int nb_events);
 
 /* taken from kernel/trace/trace.h */
 enum trace_flag_type {
index f9b890fde681931eaaa8089705cf06f7b90f6ac1..214265674ddda0a59488cc0871a0943b20fc6bd4 100644 (file)
@@ -92,3 +92,25 @@ out_close_from:
 out:
        return err;
 }
+
+unsigned long convert_unit(unsigned long value, char *unit)
+{
+       *unit = ' ';
+
+       if (value > 1000) {
+               value /= 1000;
+               *unit = 'K';
+       }
+
+       if (value > 1000) {
+               value /= 1000;
+               *unit = 'M';
+       }
+
+       if (value > 1000) {
+               value /= 1000;
+               *unit = 'G';
+       }
+
+       return value;
+}
index 0f5b2a6f1080f6cd6a75f265ea2aa20787fc98e2..0795bf304b19495b0b7f88ca366fcace7302f1fa 100644 (file)
 #define _ALL_SOURCE 1
 #define _GNU_SOURCE 1
 #define _BSD_SOURCE 1
+#define HAS_BOOL
 
 #include <unistd.h>
 #include <stdio.h>
 #include <sys/stat.h>
 #include <sys/statfs.h>
 #include <fcntl.h>
+#include <stdbool.h>
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -78,6 +80,7 @@
 #include <pwd.h>
 #include <inttypes.h>
 #include "../../../include/linux/magic.h"
+#include "types.h"
 
 
 #ifndef NO_ICONV
@@ -295,6 +298,13 @@ 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) __attribute__((weak));
 
+static inline void *xzalloc(size_t size)
+{
+       void *buf = xmalloc(size);
+
+       return memset(buf, 0, size);
+}
+
 static inline void *zalloc(size_t size)
 {
        return calloc(1, size);
@@ -309,6 +319,7 @@ static inline int has_extension(const char *filename, const char *ext)
 {
        size_t len = strlen(filename);
        size_t extlen = strlen(ext);
+
        return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
 }
 
@@ -322,6 +333,7 @@ static inline int has_extension(const char *filename, const char *ext)
 #undef isalnum
 #undef tolower
 #undef toupper
+
 extern unsigned char sane_ctype[256];
 #define GIT_SPACE              0x01
 #define GIT_DIGIT              0x02
@@ -406,4 +418,14 @@ void git_qsort(void *base, size_t nmemb, size_t size,
 int mkdir_p(char *path, mode_t mode);
 int copyfile(const char *from, const char *to);
 
+s64 perf_atoll(const char *str);
+char **argv_split(const char *str, int *argcp);
+void argv_free(char **argv);
+bool strglobmatch(const char *str, const char *pat);
+bool strlazymatch(const char *str, const char *pat);
+unsigned long convert_unit(unsigned long value, char *unit);
+
+#define _STR(x) #x
+#define STR(x) _STR(x)
+
 #endif
index 057e2cca6af5ed7a8c8cbdf4aa7c236713b3bf8f..02ff2b19dbe242a5033da435998a19f1fc4e52ed 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/spinlock.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include "irq.h"
 
 static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head,
index 5169736377a3b88cb6d2c7abc7639e2da439cf64..36e258029649c719fec91a1feb7306604ae90ab9 100644 (file)
@@ -10,6 +10,7 @@
 #include "iodev.h"
 
 #include <linux/kvm_host.h>
+#include <linux/slab.h>
 #include <linux/kvm.h>
 
 #include "coalesced_mmio.h"
index 7016319b1ec0590513ba1886ede37982c39e71b4..b81f0ebbaaadb6db5c62ef3d8078117630152b35 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/list.h>
 #include <linux/eventfd.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include "iodev.h"
 
index 3db15a807f8064149a8b3bf5f4fcdd349697cdc5..7c79c1d76d0c13e72463fcddc00cf845ad63ca87 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/smp.h>
 #include <linux/hrtimer.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/current.h>
@@ -196,7 +197,7 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
        union kvm_ioapic_redirect_entry entry;
        int ret = 1;
 
-       mutex_lock(&ioapic->lock);
+       spin_lock(&ioapic->lock);
        if (irq >= 0 && irq < IOAPIC_NUM_PINS) {
                entry = ioapic->redirtbl[irq];
                level ^= entry.fields.polarity;
@@ -213,7 +214,7 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
                }
                trace_kvm_ioapic_set_irq(entry.bits, irq, ret == 0);
        }
-       mutex_unlock(&ioapic->lock);
+       spin_unlock(&ioapic->lock);
 
        return ret;
 }
@@ -237,9 +238,9 @@ static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int vector,
                 * is dropped it will be put into irr and will be delivered
                 * after ack notifier returns.
                 */
-               mutex_unlock(&ioapic->lock);
+               spin_unlock(&ioapic->lock);
                kvm_notify_acked_irq(ioapic->kvm, KVM_IRQCHIP_IOAPIC, i);
-               mutex_lock(&ioapic->lock);
+               spin_lock(&ioapic->lock);
 
                if (trigger_mode != IOAPIC_LEVEL_TRIG)
                        continue;
@@ -258,9 +259,9 @@ void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode)
        smp_rmb();
        if (!test_bit(vector, ioapic->handled_vectors))
                return;
-       mutex_lock(&ioapic->lock);
+       spin_lock(&ioapic->lock);
        __kvm_ioapic_update_eoi(ioapic, vector, trigger_mode);
-       mutex_unlock(&ioapic->lock);
+       spin_unlock(&ioapic->lock);
 }
 
 static inline struct kvm_ioapic *to_ioapic(struct kvm_io_device *dev)
@@ -286,7 +287,7 @@ static int ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len,
        ASSERT(!(addr & 0xf));  /* check alignment */
 
        addr &= 0xff;
-       mutex_lock(&ioapic->lock);
+       spin_lock(&ioapic->lock);
        switch (addr) {
        case IOAPIC_REG_SELECT:
                result = ioapic->ioregsel;
@@ -300,7 +301,7 @@ static int ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len,
                result = 0;
                break;
        }
-       mutex_unlock(&ioapic->lock);
+       spin_unlock(&ioapic->lock);
 
        switch (len) {
        case 8:
@@ -337,7 +338,7 @@ static int ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len,
        }
 
        addr &= 0xff;
-       mutex_lock(&ioapic->lock);
+       spin_lock(&ioapic->lock);
        switch (addr) {
        case IOAPIC_REG_SELECT:
                ioapic->ioregsel = data;
@@ -355,7 +356,7 @@ static int ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len,
        default:
                break;
        }
-       mutex_unlock(&ioapic->lock);
+       spin_unlock(&ioapic->lock);
        return 0;
 }
 
@@ -385,7 +386,7 @@ int kvm_ioapic_init(struct kvm *kvm)
        ioapic = kzalloc(sizeof(struct kvm_ioapic), GFP_KERNEL);
        if (!ioapic)
                return -ENOMEM;
-       mutex_init(&ioapic->lock);
+       spin_lock_init(&ioapic->lock);
        kvm->arch.vioapic = ioapic;
        kvm_ioapic_reset(ioapic);
        kvm_iodevice_init(&ioapic->dev, &ioapic_mmio_ops);
@@ -418,9 +419,9 @@ int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
        if (!ioapic)
                return -EINVAL;
 
-       mutex_lock(&ioapic->lock);
+       spin_lock(&ioapic->lock);
        memcpy(state, ioapic, sizeof(struct kvm_ioapic_state));
-       mutex_unlock(&ioapic->lock);
+       spin_unlock(&ioapic->lock);
        return 0;
 }
 
@@ -430,9 +431,9 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
        if (!ioapic)
                return -EINVAL;
 
-       mutex_lock(&ioapic->lock);
+       spin_lock(&ioapic->lock);
        memcpy(ioapic, state, sizeof(struct kvm_ioapic_state));
        update_handled_vectors(ioapic);
-       mutex_unlock(&ioapic->lock);
+       spin_unlock(&ioapic->lock);
        return 0;
 }
index 8a751b78a4301bffda6139ce92cfda2c5d7317f5..0b190c34ccc31bd398d4549996c57c3203952a82 100644 (file)
@@ -45,7 +45,7 @@ struct kvm_ioapic {
        struct kvm_io_device dev;
        struct kvm *kvm;
        void (*ack_notifier)(void *opaque, int irq);
-       struct mutex lock;
+       spinlock_t lock;
        DECLARE_BITMAP(handled_vectors, 256);
 };
 
index 80fd3ad3b2de77d246fe8cb9a5df5714609735c3..11692b9e8830a6e99538556bfeee2ea9d7d74817 100644 (file)
@@ -32,12 +32,30 @@ static int kvm_iommu_unmap_memslots(struct kvm *kvm);
 static void kvm_iommu_put_pages(struct kvm *kvm,
                                gfn_t base_gfn, unsigned long npages);
 
+static pfn_t kvm_pin_pages(struct kvm *kvm, struct kvm_memory_slot *slot,
+                          gfn_t gfn, unsigned long size)
+{
+       gfn_t end_gfn;
+       pfn_t pfn;
+
+       pfn     = gfn_to_pfn_memslot(kvm, slot, gfn);
+       end_gfn = gfn + (size >> PAGE_SHIFT);
+       gfn    += 1;
+
+       if (is_error_pfn(pfn))
+               return pfn;
+
+       while (gfn < end_gfn)
+               gfn_to_pfn_memslot(kvm, slot, gfn++);
+
+       return pfn;
+}
+
 int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
 {
-       gfn_t gfn = slot->base_gfn;
-       unsigned long npages = slot->npages;
+       gfn_t gfn, end_gfn;
        pfn_t pfn;
-       int i, r = 0;
+       int r = 0;
        struct iommu_domain *domain = kvm->arch.iommu_domain;
        int flags;
 
@@ -45,31 +63,62 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
        if (!domain)
                return 0;
 
+       gfn     = slot->base_gfn;
+       end_gfn = gfn + slot->npages;
+
        flags = IOMMU_READ | IOMMU_WRITE;
        if (kvm->arch.iommu_flags & KVM_IOMMU_CACHE_COHERENCY)
                flags |= IOMMU_CACHE;
 
-       for (i = 0; i < npages; i++) {
-               /* check if already mapped */
-               if (iommu_iova_to_phys(domain, gfn_to_gpa(gfn)))
+
+       while (gfn < end_gfn) {
+               unsigned long page_size;
+
+               /* Check if already mapped */
+               if (iommu_iova_to_phys(domain, gfn_to_gpa(gfn))) {
+                       gfn += 1;
+                       continue;
+               }
+
+               /* Get the page size we could use to map */
+               page_size = kvm_host_page_size(kvm, gfn);
+
+               /* Make sure the page_size does not exceed the memslot */
+               while ((gfn + (page_size >> PAGE_SHIFT)) > end_gfn)
+                       page_size >>= 1;
+
+               /* Make sure gfn is aligned to the page size we want to map */
+               while ((gfn << PAGE_SHIFT) & (page_size - 1))
+                       page_size >>= 1;
+
+               /*
+                * Pin all pages we are about to map in memory. This is
+                * important because we unmap and unpin in 4kb steps later.
+                */
+               pfn = kvm_pin_pages(kvm, slot, gfn, page_size);
+               if (is_error_pfn(pfn)) {
+                       gfn += 1;
                        continue;
+               }
 
-               pfn = gfn_to_pfn_memslot(kvm, slot, gfn);
-               r = iommu_map_range(domain,
-                                   gfn_to_gpa(gfn),
-                                   pfn_to_hpa(pfn),
-                                   PAGE_SIZE, flags);
+               /* Map into IO address space */
+               r = iommu_map(domain, gfn_to_gpa(gfn), pfn_to_hpa(pfn),
+                             get_order(page_size), flags);
                if (r) {
                        printk(KERN_ERR "kvm_iommu_map_address:"
                               "iommu failed to map pfn=%lx\n", pfn);
                        goto unmap_pages;
                }
-               gfn++;
+
+               gfn += page_size >> PAGE_SHIFT;
+
+
        }
+
        return 0;
 
 unmap_pages:
-       kvm_iommu_put_pages(kvm, slot->base_gfn, i);
+       kvm_iommu_put_pages(kvm, slot->base_gfn, gfn);
        return r;
 }
 
@@ -189,27 +238,47 @@ out_unmap:
        return r;
 }
 
+static void kvm_unpin_pages(struct kvm *kvm, pfn_t pfn, unsigned long npages)
+{
+       unsigned long i;
+
+       for (i = 0; i < npages; ++i)
+               kvm_release_pfn_clean(pfn + i);
+}
+
 static void kvm_iommu_put_pages(struct kvm *kvm,
                                gfn_t base_gfn, unsigned long npages)
 {
-       gfn_t gfn = base_gfn;
+       struct iommu_domain *domain;
+       gfn_t end_gfn, gfn;
        pfn_t pfn;
-       struct iommu_domain *domain = kvm->arch.iommu_domain;
-       unsigned long i;
        u64 phys;
 
+       domain  = kvm->arch.iommu_domain;
+       end_gfn = base_gfn + npages;
+       gfn     = base_gfn;
+
        /* check if iommu exists and in use */
        if (!domain)
                return;
 
-       for (i = 0; i < npages; i++) {
+       while (gfn < end_gfn) {
+               unsigned long unmap_pages;
+               int order;
+
+               /* Get physical address */
                phys = iommu_iova_to_phys(domain, gfn_to_gpa(gfn));
-               pfn = phys >> PAGE_SHIFT;
-               kvm_release_pfn_clean(pfn);
-               gfn++;
-       }
+               pfn  = phys >> PAGE_SHIFT;
+
+               /* Unmap address from IO address space */
+               order       = iommu_unmap(domain, gfn_to_gpa(gfn), PAGE_SIZE);
+               unmap_pages = 1ULL << order;
 
-       iommu_unmap_range(domain, gfn_to_gpa(base_gfn), PAGE_SIZE * npages);
+               /* Unpin all pages we just unmapped to not leak any memory */
+               kvm_unpin_pages(kvm, pfn, unmap_pages);
+
+               gfn += unmap_pages;
+       }
 }
 
 static int kvm_iommu_unmap_memslots(struct kvm *kvm)
index 9fd5b3ebc5175b193e083e45d594dcf34c4e04ab..a0e88809e45e7468d9c2439d638f2dc18502d128 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/kvm_host.h>
+#include <linux/slab.h>
 #include <trace/events/kvm.h>
 
 #include <asm/msidef.h>
index 548f9253c1957f2d0088b74c01c015fee1e79b45..c82ae24926340cfa40ad8c3bbc9f65dd79c32fff 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/percpu.h>
-#include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/miscdevice.h>
 #include <linux/vmalloc.h>
@@ -46,6 +45,7 @@
 #include <linux/compat.h>
 #include <linux/srcu.h>
 #include <linux/hugetlb.h>
+#include <linux/slab.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
@@ -341,7 +341,11 @@ static void kvm_mmu_notifier_release(struct mmu_notifier *mn,
                                     struct mm_struct *mm)
 {
        struct kvm *kvm = mmu_notifier_to_kvm(mn);
+       int idx;
+
+       idx = srcu_read_lock(&kvm->srcu);
        kvm_arch_flush_shadow(kvm);
+       srcu_read_unlock(&kvm->srcu, idx);
 }
 
 static const struct mmu_notifier_ops kvm_mmu_notifier_ops = {
@@ -648,7 +652,7 @@ skip_lpage:
 
        /* Allocate page dirty bitmap if needed */
        if ((new.flags & KVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) {
-               unsigned dirty_bytes = ALIGN(npages, BITS_PER_LONG) / 8;
+               unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(&new);
 
                new.dirty_bitmap = vmalloc(dirty_bytes);
                if (!new.dirty_bitmap)
@@ -768,7 +772,7 @@ int kvm_get_dirty_log(struct kvm *kvm,
 {
        struct kvm_memory_slot *memslot;
        int r, i;
-       int n;
+       unsigned long n;
        unsigned long any = 0;
 
        r = -EINVAL;
@@ -780,7 +784,7 @@ int kvm_get_dirty_log(struct kvm *kvm,
        if (!memslot->dirty_bitmap)
                goto out;
 
-       n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+       n = kvm_dirty_bitmap_bytes(memslot);
 
        for (i = 0; !any && i < n/sizeof(long); ++i)
                any = memslot->dirty_bitmap[i];
@@ -1186,10 +1190,13 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
        memslot = gfn_to_memslot_unaliased(kvm, gfn);
        if (memslot && memslot->dirty_bitmap) {
                unsigned long rel_gfn = gfn - memslot->base_gfn;
+               unsigned long *p = memslot->dirty_bitmap +
+                                       rel_gfn / BITS_PER_LONG;
+               int offset = rel_gfn % BITS_PER_LONG;
 
                /* avoid RMW */
-               if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap))
-                       generic___set_le_bit(rel_gfn, memslot->dirty_bitmap);
+               if (!generic_test_le_bit(offset, p))
+                       generic___set_le_bit(offset, p);
        }
 }